Skip to content

Commit 0498fe8

Browse files
committed
[PDB Import] Improve recovery of sp-based locals
1 parent 8e7535e commit 0498fe8

1 file changed

Lines changed: 65 additions & 5 deletions

File tree

plugins/pdb-ng/src/symbol_parser.rs

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,15 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
15941594
data: &DefRangeFramePointerRelativeSymbol,
15951595
) -> Result<Option<ParsedSymbol>> {
15961596
self.log(|| format!("Got DefRangeFramePointerRelative symbol: {:?}", data));
1597-
Ok(None)
1597+
Ok(Some(ParsedSymbol::Location(ParsedLocation {
1598+
location: Variable {
1599+
ty: VariableSourceType::StackVariableSourceType,
1600+
index: 0,
1601+
storage: data.offset as i64,
1602+
},
1603+
base_relative: true,
1604+
stack_relative: false,
1605+
})))
15981606
}
15991607

16001608
fn handle_def_range_frame_pointer_relative_full_scope_symbol(
@@ -1608,7 +1616,15 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
16081616
data
16091617
)
16101618
});
1611-
Ok(None)
1619+
Ok(Some(ParsedSymbol::Location(ParsedLocation {
1620+
location: Variable {
1621+
ty: VariableSourceType::StackVariableSourceType,
1622+
index: 0,
1623+
storage: data.offset as i64,
1624+
},
1625+
base_relative: true,
1626+
stack_relative: false,
1627+
})))
16121628
}
16131629

16141630
fn handle_def_range_sub_field_register_symbol(
@@ -1626,7 +1642,31 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
16261642
data: &DefRangeRegisterRelativeSymbol,
16271643
) -> Result<Option<ParsedSymbol>> {
16281644
self.log(|| format!("Got DefRangeRegisterRelative symbol: {:?}", data));
1629-
Ok(None)
1645+
match self.lookup_register(data.base_register) {
1646+
Some(X86(X86Register::EBP)) | Some(AMD64(AMD64Register::RBP)) => {
1647+
Ok(Some(ParsedSymbol::Location(ParsedLocation {
1648+
location: Variable {
1649+
ty: VariableSourceType::StackVariableSourceType,
1650+
index: 0,
1651+
storage: data.offset_base_pointer as i64,
1652+
},
1653+
base_relative: true,
1654+
stack_relative: false,
1655+
})))
1656+
}
1657+
Some(X86(X86Register::ESP)) | Some(AMD64(AMD64Register::RSP)) => {
1658+
Ok(Some(ParsedSymbol::Location(ParsedLocation {
1659+
location: Variable {
1660+
ty: VariableSourceType::StackVariableSourceType,
1661+
index: 0,
1662+
storage: data.offset_base_pointer as i64,
1663+
},
1664+
base_relative: false,
1665+
stack_relative: true,
1666+
})))
1667+
}
1668+
_ => Ok(None),
1669+
}
16301670
}
16311671

16321672
fn handle_base_pointer_relative_symbol(
@@ -1678,9 +1718,29 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
16781718
is_param,
16791719
..
16801720
})) => {
1721+
// Adjust RSP-relative locations to RSP_entry-relative before param detection
1722+
let adjusted_storage: Vec<ParsedLocation> = storage
1723+
.iter()
1724+
.map(|loc| {
1725+
if loc.stack_relative {
1726+
ParsedLocation {
1727+
location: Variable {
1728+
storage: loc.location.storage
1729+
- data.frame_byte_count as i64,
1730+
..loc.location
1731+
},
1732+
stack_relative: false,
1733+
..*loc
1734+
}
1735+
} else {
1736+
*loc
1737+
}
1738+
})
1739+
.collect();
1740+
16811741
// See if the parameter really is a parameter. Sometimes they don't say they are
16821742
let mut really_is_param = *is_param;
1683-
for loc in storage.iter() {
1743+
for loc in adjusted_storage.iter() {
16841744
match loc.location {
16851745
Variable {
16861746
ty: VariableSourceType::RegisterVariableSourceType,
@@ -1711,7 +1771,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
17111771
let var = ParsedVariable {
17121772
name: name.clone(),
17131773
type_: type_.clone(),
1714-
storage: storage.clone(),
1774+
storage: adjusted_storage,
17151775
is_param: really_is_param,
17161776
};
17171777
if really_is_param {

0 commit comments

Comments
 (0)