Skip to content

Commit efe029d

Browse files
committed
Move indirect flag into ValueLocation
1 parent 13a5c00 commit efe029d

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
@@ -3873,12 +3873,9 @@ class X86SystemVCallingConvention: public X86BaseCallingConvention
38733873
{
38743874
if (!returnValue.has_value())
38753875
return 0;
3876-
for (auto& component: returnValue->components)
3877-
{
3878-
// Indirect return values have the pointer popped off the stack by the called function
3879-
if (component.indirect)
3880-
return 4;
3881-
}
3876+
// Indirect return values have the pointer popped off the stack by the called function
3877+
if (returnValue->indirect)
3878+
return 4;
38823879
return 0;
38833880
}
38843881
};
@@ -4742,9 +4739,7 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
47424739
if (!components.has_value())
47434740
{
47444741
// Value doesn't work in a register, return through an indirect pointer
4745-
ValueLocationComponent indirect(
4746-
GetIndirectReturnValueLocation(), 0, type->GetWidth(), true, GetReturnedIndirectReturnValuePointer());
4747-
return ValueLocation({indirect});
4742+
return ValueLocation({GetIndirectReturnValueLocation()}, true, GetReturnedIndirectReturnValuePointer());
47484743
}
47494744

47504745
ValueLocation result;
@@ -4826,9 +4821,7 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
48264821
return result;
48274822

48284823
// Value doesn't work in a register, return through an indirect pointer
4829-
ValueLocationComponent indirect(
4830-
GetIndirectReturnValueLocation(), 0, type->GetWidth(), true, GetReturnedIndirectReturnValuePointer());
4831-
return ValueLocation({indirect});
4824+
return ValueLocation({GetIndirectReturnValueLocation()}, true, GetReturnedIndirectReturnValuePointer());
48324825
}
48334826

48344827
Variable GetIndirectReturnValueLocation() override { return Variable::Register(XED_REG_RDI); }
@@ -4849,15 +4842,12 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
48494842
size_t addrSize = GetArchitecture()->GetAddressSize();
48504843
int64_t stackOffset = addrSize;
48514844

4852-
if (returnValue.has_value())
4845+
if (returnValue.has_value() && returnValue->indirect)
48534846
{
48544847
// If the return value is stored as an indirect location parameter, ensure that the normal parameters
48554848
// don't overlap with it.
48564849
for (auto& component : returnValue->components)
48574850
{
4858-
if (!component.indirect)
4859-
continue;
4860-
48614851
if (component.variable.type == RegisterVariableSourceType)
48624852
{
48634853
if (intArgIter != intArgs.end() && *intArgIter == component.variable.storage)
@@ -4883,9 +4873,6 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
48834873
result.push_back(param.location);
48844874
for (auto& component : param.location.components)
48854875
{
4886-
if (component.indirect)
4887-
continue;
4888-
48894876
if (component.variable.type == RegisterVariableSourceType)
48904877
{
48914878
// If the non-default location matches the next register in the register parameter
@@ -4962,19 +4949,19 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
49624949
}
49634950
}
49644951

4965-
// Single component values shouldn't have the size set, otherwise heuristically determined locations
4966-
// will not match.
4967-
if (!indirect && location.components.size() == 1)
4968-
location.components[0].size.reset();
4969-
49704952
if (indirect)
49714953
{
4954+
location.indirect = true;
49724955
std::ranges::for_each(location.components, [&](auto& component) {
4973-
component.indirect = true;
49744956
component.size = param.type->GetWidth();
49754957
});
49764958
}
49774959

4960+
// Single component values shouldn't have the size set, otherwise heuristically determined locations
4961+
// will not match.
4962+
if (location.components.size() == 1)
4963+
location.components[0].size.reset();
4964+
49784965
if (valid)
49794966
{
49804967
// Value fit in registers

binaryninjaapi.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10556,13 +10556,10 @@ namespace BinaryNinja {
1055610556
Variable variable;
1055710557
int64_t offset = 0;
1055810558
std::optional<uint64_t> size;
10559-
bool indirect = false;
10560-
std::optional<Variable> returnedPointer;
1056110559

1056210560
ValueLocationComponent() = default;
10563-
ValueLocationComponent(Variable var, int64_t ofs = 0, std::optional<uint64_t> sz = std::nullopt,
10564-
bool indir = false, std::optional<Variable> retPtr = std::nullopt)
10565-
: variable(var), offset(ofs), size(sz), indirect(indir), returnedPointer(retPtr)
10561+
ValueLocationComponent(Variable var, int64_t ofs = 0, std::optional<uint64_t> sz = std::nullopt) :
10562+
variable(var), offset(ofs), size(sz)
1056610563
{}
1056710564

1056810565
ValueLocationComponent RemapVariables(const std::function<Variable(Variable)>& remap) const;
@@ -10579,15 +10576,20 @@ namespace BinaryNinja {
1057910576
struct ValueLocation
1058010577
{
1058110578
std::vector<ValueLocationComponent> components;
10579+
bool indirect = false;
10580+
std::optional<Variable> returnedPointer;
1058210581

1058310582
ValueLocation() {}
10584-
ValueLocation(Variable var) : components {var} {}
10585-
ValueLocation(const std::vector<ValueLocationComponent>& components) : components(components) {}
10586-
ValueLocation(std::vector<ValueLocationComponent>&& components) : components(std::move(components)) {}
10587-
10588-
ValueLocation(BNVariableSourceType type, uint64_t storage) : components {Variable(type, storage)} {}
10589-
ValueLocation(BNVariableSourceType type, uint32_t index, uint64_t storage) :
10590-
components {Variable(type, index, storage)}
10583+
ValueLocation(Variable var, bool indir = false, std::optional<Variable> retPtr = std::nullopt) :
10584+
components {var}, indirect(indir), returnedPointer(retPtr)
10585+
{}
10586+
ValueLocation(const std::vector<ValueLocationComponent>& components, bool indir = false,
10587+
std::optional<Variable> retPtr = std::nullopt) :
10588+
components(components), indirect(indir), returnedPointer(retPtr)
10589+
{}
10590+
ValueLocation(std::vector<ValueLocationComponent>&& components, bool indir = false,
10591+
std::optional<Variable> retPtr = std::nullopt) :
10592+
components(std::move(components)), indirect(indir), returnedPointer(retPtr)
1059110593
{}
1059210594

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

binaryninjacore.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,15 +2613,15 @@ extern "C"
26132613
int64_t offset;
26142614
bool sizeValid;
26152615
uint64_t size;
2616-
bool indirect;
2617-
bool returnedPointerValid;
2618-
BNVariable returnedPointer;
26192616
} BNValueLocationComponent;
26202617

26212618
typedef struct BNValueLocation
26222619
{
26232620
size_t count;
26242621
BNValueLocationComponent* components;
2622+
bool indirect;
2623+
bool returnedPointerValid;
2624+
BNVariable returnedPointer;
26252625
} BNValueLocation;
26262626

26272627
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
@@ -444,8 +444,6 @@ class ValueLocationComponent:
444444
var: 'variable.CoreVariable'
445445
offset: int = 0
446446
size: Optional[int] = None
447-
indirect: bool = False
448-
returned_pointer: Optional['variable.CoreVariable'] = None
449447

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

469460
def _to_core_struct(self) -> core.BNValueLocationComponent:
470461
struct = core.BNValueLocationComponent()
@@ -473,10 +464,6 @@ def _to_core_struct(self) -> core.BNValueLocationComponent:
473464
struct.sizeValid = self.size is not None
474465
if self.size is not None:
475466
struct.size = self.size
476-
struct.indirect = self.indirect
477-
struct.returnedPointerValid = self.returned_pointer is not None
478-
if self.returned_pointer is not None:
479-
struct.returnedPointer = self.returned_pointer.to_BNVariable()
480467
return struct
481468

482469
def to_string(self, arch: Optional['architecture.Architecture']):
@@ -508,13 +495,22 @@ def __repr__(self):
508495
@dataclass
509496
class ValueLocation:
510497
components: List['ValueLocationComponent']
498+
indirect: bool = False
499+
returned_pointer: Optional['variable.CoreVariable'] = None
511500

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

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

528528
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)