Skip to content

Commit 5ea5954

Browse files
committed
Move indirect flag into ValueLocation
1 parent c990453 commit 5ea5954

7 files changed

Lines changed: 107 additions & 118 deletions

File tree

arch/x86/arch_x86.cpp

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3869,12 +3869,9 @@ class X86SystemVCallingConvention: public X86BaseCallingConvention
38693869
{
38703870
if (!returnValue.has_value())
38713871
return 0;
3872-
for (auto& component: returnValue->components)
3873-
{
3874-
// Indirect return values have the pointer popped off the stack by the called function
3875-
if (component.indirect)
3876-
return 4;
3877-
}
3872+
// Indirect return values have the pointer popped off the stack by the called function
3873+
if (returnValue->indirect)
3874+
return 4;
38783875
return 0;
38793876
}
38803877
};
@@ -4738,9 +4735,7 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
47384735
if (!components.has_value())
47394736
{
47404737
// Value doesn't work in a register, return through an indirect pointer
4741-
ValueLocationComponent indirect(
4742-
GetIndirectReturnValueLocation(), 0, type->GetWidth(), true, GetReturnedIndirectReturnValuePointer());
4743-
return ValueLocation({indirect});
4738+
return ValueLocation({GetIndirectReturnValueLocation()}, true, GetReturnedIndirectReturnValuePointer());
47444739
}
47454740

47464741
ValueLocation result;
@@ -4822,9 +4817,7 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
48224817
return result;
48234818

48244819
// Value doesn't work in a register, return through an indirect pointer
4825-
ValueLocationComponent indirect(
4826-
GetIndirectReturnValueLocation(), 0, type->GetWidth(), true, GetReturnedIndirectReturnValuePointer());
4827-
return ValueLocation({indirect});
4820+
return ValueLocation({GetIndirectReturnValueLocation()}, true, GetReturnedIndirectReturnValuePointer());
48284821
}
48294822

48304823
Variable GetIndirectReturnValueLocation() override { return Variable::Register(XED_REG_RDI); }
@@ -4845,15 +4838,12 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
48454838
size_t addrSize = GetArchitecture()->GetAddressSize();
48464839
int64_t stackOffset = addrSize;
48474840

4848-
if (returnValue.has_value())
4841+
if (returnValue.has_value() && returnValue->indirect)
48494842
{
48504843
// If the return value is stored as an indirect location parameter, ensure that the normal parameters
48514844
// don't overlap with it.
48524845
for (auto& component : returnValue->components)
48534846
{
4854-
if (!component.indirect)
4855-
continue;
4856-
48574847
if (component.variable.type == RegisterVariableSourceType)
48584848
{
48594849
if (intArgIter != intArgs.end() && *intArgIter == component.variable.storage)
@@ -4879,9 +4869,6 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
48794869
result.push_back(param.location);
48804870
for (auto& component : param.location.components)
48814871
{
4882-
if (component.indirect)
4883-
continue;
4884-
48854872
if (component.variable.type == RegisterVariableSourceType)
48864873
{
48874874
// If the non-default location matches the next register in the register parameter
@@ -4958,19 +4945,19 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
49584945
}
49594946
}
49604947

4961-
// Single component values shouldn't have the size set, otherwise heuristically determined locations
4962-
// will not match.
4963-
if (!indirect && location.components.size() == 1)
4964-
location.components[0].size.reset();
4965-
49664948
if (indirect)
49674949
{
4950+
location.indirect = true;
49684951
std::ranges::for_each(location.components, [&](auto& component) {
4969-
component.indirect = true;
49704952
component.size = param.type->GetWidth();
49714953
});
49724954
}
49734955

4956+
// Single component values shouldn't have the size set, otherwise heuristically determined locations
4957+
// will not match.
4958+
if (location.components.size() == 1)
4959+
location.components[0].size.reset();
4960+
49744961
if (valid)
49754962
{
49764963
// Value fit in registers

binaryninjaapi.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10546,13 +10546,10 @@ namespace BinaryNinja {
1054610546
Variable variable;
1054710547
int64_t offset = 0;
1054810548
std::optional<uint64_t> size;
10549-
bool indirect = false;
10550-
std::optional<Variable> returnedPointer;
1055110549

1055210550
ValueLocationComponent() = default;
10553-
ValueLocationComponent(Variable var, int64_t ofs = 0, std::optional<uint64_t> sz = std::nullopt,
10554-
bool indir = false, std::optional<Variable> retPtr = std::nullopt)
10555-
: variable(var), offset(ofs), size(sz), indirect(indir), returnedPointer(retPtr)
10551+
ValueLocationComponent(Variable var, int64_t ofs = 0, std::optional<uint64_t> sz = std::nullopt) :
10552+
variable(var), offset(ofs), size(sz)
1055610553
{}
1055710554

1055810555
ValueLocationComponent RemapVariables(const std::function<Variable(Variable)>& remap) const;
@@ -10569,15 +10566,20 @@ namespace BinaryNinja {
1056910566
struct ValueLocation
1057010567
{
1057110568
std::vector<ValueLocationComponent> components;
10569+
bool indirect = false;
10570+
std::optional<Variable> returnedPointer;
1057210571

1057310572
ValueLocation() {}
10574-
ValueLocation(Variable var) : components {var} {}
10575-
ValueLocation(const std::vector<ValueLocationComponent>& components) : components(components) {}
10576-
ValueLocation(std::vector<ValueLocationComponent>&& components) : components(std::move(components)) {}
10577-
10578-
ValueLocation(BNVariableSourceType type, uint64_t storage) : components {Variable(type, storage)} {}
10579-
ValueLocation(BNVariableSourceType type, uint32_t index, uint64_t storage) :
10580-
components {Variable(type, index, storage)}
10573+
ValueLocation(Variable var, bool indir = false, std::optional<Variable> retPtr = std::nullopt) :
10574+
components {var}, indirect(indir), returnedPointer(retPtr)
10575+
{}
10576+
ValueLocation(const std::vector<ValueLocationComponent>& components, bool indir = false,
10577+
std::optional<Variable> retPtr = std::nullopt) :
10578+
components(components), indirect(indir), returnedPointer(retPtr)
10579+
{}
10580+
ValueLocation(std::vector<ValueLocationComponent>&& components, bool indir = false,
10581+
std::optional<Variable> retPtr = std::nullopt) :
10582+
components(std::move(components)), indirect(indir), returnedPointer(retPtr)
1058110583
{}
1058210584

1058310585
std::optional<Variable> GetVariableForReturnValue() const;

binaryninjacore.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,15 +2611,15 @@ extern "C"
26112611
int64_t offset;
26122612
bool sizeValid;
26132613
uint64_t size;
2614-
bool indirect;
2615-
bool returnedPointerValid;
2616-
BNVariable returnedPointer;
26172614
} BNValueLocationComponent;
26182615

26192616
typedef struct BNValueLocation
26202617
{
26212618
size_t count;
26222619
BNValueLocationComponent* components;
2620+
bool indirect;
2621+
bool returnedPointerValid;
2622+
BNVariable returnedPointer;
26232623
} BNValueLocation;
26242624

26252625
typedef struct BNValueLocationWithConfidence

plugins/pdb-ng/src/type_parser.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,11 +2423,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
24232423
let default_return_location = convention
24242424
.contents
24252425
.return_value_location(self.bv, return_value.clone());
2426-
let default_return_indrect = default_return_location
2427-
.components
2428-
.iter()
2429-
.any(|c| c.indirect);
2430-
if default_return_indrect {
2426+
if default_return_location.indirect {
24312427
None
24322428
} else {
24332429
let variable = if let Some(reg) = convention.contents.int_arg_registers().get(0) {
@@ -2449,13 +2445,15 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
24492445
variable,
24502446
offset: 0,
24512447
size: Some(return_value.ty.contents.width()),
2452-
indirect: true,
2453-
returned_pointer: convention.contents.return_int_reg().map(|reg| Variable::new(
2448+
}],
2449+
indirect: true,
2450+
returned_pointer: convention.contents.return_int_reg().map(|reg| {
2451+
Variable::new(
24542452
VariableSourceType::RegisterVariableSourceType,
24552453
0,
24562454
reg.0 as i64,
2457-
)),
2458-
}],
2455+
)
2456+
}),
24592457
},
24602458
MAX_CONFIDENCE,
24612459
))

python/types.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,6 @@ class ValueLocationComponent:
443443
var: 'variable.CoreVariable'
444444
offset: int = 0
445445
size: Optional[int] = None
446-
indirect: bool = False
447-
returned_pointer: Optional['variable.CoreVariable'] = None
448446

449447
@staticmethod
450448
def _from_core_struct(struct: core.BNValueLocationComponent, arch: Optional['architecture.Architecture'] = None):
@@ -456,14 +454,7 @@ def _from_core_struct(struct: core.BNValueLocationComponent, arch: Optional['arc
456454
size = None
457455
if struct.sizeValid:
458456
size = struct.size
459-
indirect = struct.indirect
460-
returned_pointer = None
461-
if struct.returnedPointerValid:
462-
if arch is None:
463-
returned_pointer = variable.CoreVariable.from_BNVariable(struct.returnedPointer)
464-
else:
465-
returned_pointer = variable.ArchitectureVariable.from_BNVariable(arch, struct.returnedPointer)
466-
return ValueLocationComponent(var, offset, size, indirect, returned_pointer)
457+
return ValueLocationComponent(var, offset, size)
467458

468459
def _to_core_struct(self) -> core.BNValueLocationComponent:
469460
struct = core.BNValueLocationComponent()
@@ -472,10 +463,6 @@ def _to_core_struct(self) -> core.BNValueLocationComponent:
472463
struct.sizeValid = self.size is not None
473464
if self.size is not None:
474465
struct.size = self.size
475-
struct.indirect = self.indirect
476-
struct.returnedPointerValid = self.returned_pointer is not None
477-
if self.returned_pointer is not None:
478-
struct.returnedPointer = self.returned_pointer.to_BNVariable()
479466
return struct
480467

481468
def to_string(self, arch: Optional['architecture.Architecture']):
@@ -507,13 +494,22 @@ def __repr__(self):
507494
@dataclass
508495
class ValueLocation:
509496
components: List['ValueLocationComponent']
497+
indirect: bool = False
498+
returned_pointer: Optional['variable.CoreVariable'] = None
510499

511500
@staticmethod
512501
def _from_core_struct(struct: core.BNValueLocation, arch: Optional['architecture.Architecture'] = None):
513502
components = []
514503
for i in range(struct.count):
515504
components.append(ValueLocationComponent._from_core_struct(struct.components[i], arch))
516-
return ValueLocation(components)
505+
indirect = struct.indirect
506+
returned_pointer = None
507+
if struct.returnedPointerValid:
508+
if arch is None:
509+
returned_pointer = variable.CoreVariable.from_BNVariable(struct.returnedPointer)
510+
else:
511+
returned_pointer = variable.ArchitectureVariable.from_BNVariable(arch, struct.returnedPointer)
512+
return ValueLocation(components, indirect, returned_pointer)
517513

518514
def _to_core_struct(self) -> core.BNValueLocation:
519515
struct = core.BNValueLocation()
@@ -522,6 +518,10 @@ def _to_core_struct(self) -> core.BNValueLocation:
522518
for i in range(len(self.components)):
523519
components[i] = self.components[i]._to_core_struct()
524520
struct.components = components
521+
struct.indirect = self.indirect
522+
struct.returnedPointerValid = self.returned_pointer is not None
523+
if self.returned_pointer is not None:
524+
struct.returnedPointer = self.returned_pointer.to_BNVariable()
525525
return struct
526526

527527
def with_confidence(self, confidence: int) -> 'ValueLocationWithConfidence':

rust/src/types.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,8 +1173,6 @@ pub struct ValueLocationComponent {
11731173
pub variable: Variable,
11741174
pub offset: i64,
11751175
pub size: Option<u64>,
1176-
pub indirect: bool,
1177-
pub returned_pointer: Option<Variable>,
11781176
}
11791177

11801178
impl ValueLocationComponent {
@@ -1189,12 +1187,6 @@ impl ValueLocationComponent {
11891187
variable,
11901188
offset: value.offset,
11911189
size,
1192-
indirect: value.indirect,
1193-
returned_pointer: if value.returnedPointerValid {
1194-
Some(Variable::from(&value.returnedPointer))
1195-
} else {
1196-
None
1197-
},
11981190
}
11991191
}
12001192

@@ -1204,20 +1196,15 @@ impl ValueLocationComponent {
12041196
offset: value.offset,
12051197
sizeValid: value.size.is_some(),
12061198
size: value.size.unwrap_or(0),
1207-
indirect: value.indirect,
1208-
returnedPointerValid: value.returned_pointer.is_some(),
1209-
returnedPointer: if let Some(ptr) = value.returned_pointer {
1210-
ptr.into()
1211-
} else {
1212-
Variable::new(VariableSourceType::RegisterVariableSourceType, 0, 0).into()
1213-
},
12141199
}
12151200
}
12161201
}
12171202

12181203
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
12191204
pub struct ValueLocation {
12201205
pub components: Vec<ValueLocationComponent>,
1206+
pub indirect: bool,
1207+
pub returned_pointer: Option<Variable>,
12211208
}
12221209

12231210
impl ValueLocation {
@@ -1227,9 +1214,9 @@ impl ValueLocation {
12271214
variable: var,
12281215
offset: 0,
12291216
size: None,
1230-
indirect: false,
1231-
returned_pointer: None,
12321217
}],
1218+
indirect: false,
1219+
returned_pointer: None,
12331220
}
12341221
}
12351222

@@ -1274,20 +1261,20 @@ impl ValueLocation {
12741261
}
12751262
}
12761263

1277-
pub(crate) fn from_raw(components: &BNValueLocation) -> Self {
1278-
if components.count == 0 {
1279-
return Self {
1280-
components: Vec::new(),
1281-
};
1282-
}
1283-
1264+
pub(crate) fn from_raw(loc: &BNValueLocation) -> Self {
12841265
let components_raw: &[BNValueLocationComponent] =
1285-
unsafe { std::slice::from_raw_parts(components.components, components.count) };
1266+
unsafe { crate::ffi::slice_from_raw_parts(loc.components, loc.count) };
12861267
Self {
12871268
components: components_raw
12881269
.iter()
12891270
.map(|component| ValueLocationComponent::from_raw(component))
12901271
.collect(),
1272+
indirect: loc.indirect,
1273+
returned_pointer: if loc.returnedPointerValid {
1274+
Some(Variable::from(&loc.returnedPointer))
1275+
} else {
1276+
None
1277+
},
12911278
}
12921279
}
12931280

@@ -1300,6 +1287,13 @@ impl ValueLocation {
13001287
BNValueLocation {
13011288
count: components.len(),
13021289
components: Box::leak(components).as_mut_ptr(),
1290+
indirect: value.indirect,
1291+
returnedPointerValid: value.returned_pointer.is_some(),
1292+
returnedPointer: if let Some(ptr) = value.returned_pointer {
1293+
ptr.into()
1294+
} else {
1295+
Variable::new(VariableSourceType::RegisterVariableSourceType, 0, 0).into()
1296+
},
13031297
}
13041298
}
13051299

@@ -1318,9 +1312,9 @@ impl Into<ValueLocation> for Variable {
13181312
variable: self,
13191313
offset: 0,
13201314
size: None,
1321-
indirect: false,
1322-
returned_pointer: None,
13231315
}],
1316+
indirect: false,
1317+
returned_pointer: None,
13241318
}
13251319
}
13261320
}
@@ -1367,6 +1361,8 @@ impl ReturnValue {
13671361
.map(|v| &v.contents)
13681362
.unwrap_or(&ValueLocation {
13691363
components: Vec::new(),
1364+
indirect: false,
1365+
returned_pointer: None,
13701366
}),
13711367
),
13721368
locationConfidence: value.location.as_ref().map(|v| v.confidence).unwrap_or(0),
@@ -1476,6 +1472,8 @@ impl FunctionParameter {
14761472
defaultLocation: value.location.is_none(),
14771473
location: ValueLocation::into_rust_raw(&value.location.unwrap_or(ValueLocation {
14781474
components: Vec::new(),
1475+
indirect: false,
1476+
returned_pointer: None,
14791477
})),
14801478
}
14811479
}

0 commit comments

Comments
 (0)