Skip to content

Commit f24f8f5

Browse files
committed
Allow function parameters to specify they need to be passed by reference/value without specifying an exact location
1 parent 33b6579 commit f24f8f5

14 files changed

Lines changed: 122 additions & 59 deletions

File tree

arch/x86/arch_x86.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4867,7 +4867,7 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
48674867

48684868
for (auto& param : params)
48694869
{
4870-
if (!param.defaultLocation)
4870+
if (param.locationSource == CustomLocationSource)
48714871
{
48724872
// Parameter is not stored in a normal location, use custom variable
48734873
result.push_back(param.location);
@@ -4891,7 +4891,8 @@ class X64SystemVCallingConvention: public X64BaseCallingConvention
48914891
size_t width = type->GetWidth();
48924892
bool indirect = false;
48934893

4894-
if (type->GetClass() == ArrayTypeClass)
4894+
if ((type->GetClass() == ArrayTypeClass || param.locationSource == PassByReferenceLocationSource)
4895+
&& param.locationSource != PassByValueLocationSource)
48954896
{
48964897
type = Type::PointerType(GetArchitecture(), type);
48974898
indirect = true;

binaryninjaapi.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10614,16 +10614,16 @@ namespace BinaryNinja {
1061410614
{
1061510615
std::string name;
1061610616
Confidence<Ref<Type>> type;
10617-
bool defaultLocation;
10617+
BNValueLocationSource locationSource;
1061810618
ValueLocation location;
1061910619

1062010620
FunctionParameter() = default;
10621-
FunctionParameter(const std::string& name, Confidence<Ref<Type>> type): name(name), type(type), defaultLocation(true)
10621+
FunctionParameter(const std::string& name, Confidence<Ref<Type>> type): name(name), type(type), locationSource(DefaultLocationSource)
1062210622
{}
1062310623

10624-
FunctionParameter(const std::string& name, const Confidence<Ref<Type>>& type, bool defaultLocation,
10624+
FunctionParameter(const std::string& name, const Confidence<Ref<Type>>& type, BNValueLocationSource source,
1062510625
const ValueLocation& location) :
10626-
name(name), type(type), defaultLocation(defaultLocation), location(location)
10626+
name(name), type(type), locationSource(source), location(location)
1062710627
{}
1062810628

1062910629
static FunctionParameter FromAPIObject(const BNFunctionParameter* param);

binaryninjacore.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2639,12 +2639,20 @@ extern "C"
26392639
uint8_t confidence;
26402640
} BNValueLocationListWithConfidence;
26412641

2642+
BN_ENUM(uint8_t, BNValueLocationSource)
2643+
{
2644+
DefaultLocationSource,
2645+
PassByValueLocationSource,
2646+
PassByReferenceLocationSource,
2647+
CustomLocationSource
2648+
};
2649+
26422650
typedef struct BNFunctionParameter
26432651
{
26442652
char* name;
26452653
BNType* type;
26462654
uint8_t typeConfidence;
2647-
bool defaultLocation;
2655+
BNValueLocationSource locationSource;
26482656
BNValueLocation location;
26492657
} BNFunctionParameter;
26502658

demangler/gnu3/demangled_type_node.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ Ref<Type> DemangledTypeNode::Finalize() const
502502
for (auto& p : m_params)
503503
{
504504
Ref<Type> pType = p.type ? p.type->Finalize() : Ref<Type>(Type::VoidType());
505-
finalParams.push_back({p.name, pType, true, Variable()});
505+
finalParams.push_back({p.name, pType, DefaultLocationSource, Variable()});
506506
}
507507
TypeBuilder tb = TypeBuilder::FunctionType(retType->WithConfidence(m_returnTypeConfidence), nullptr, finalParams);
508508
tb.SetConst(m_const);

demangler/msvc/demangle_msvc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ void Demangle::DemangleVariableList(vector<FunctionParameter>& paramList, Backre
732732
}
733733
vt.name = name.GetString();
734734
vt.type = type.Finalize();
735-
vt.defaultLocation = true;
735+
vt.locationSource = DefaultLocationSource;
736736

737737
paramList.push_back(vt);
738738
m_logger->LogDebug("Argument %zu: '%s' - '%s'\n", i, vt.type->GetString().c_str(), reader.GetRaw());
@@ -1607,7 +1607,7 @@ TypeBuilder Demangle::DemangleFunction(BNNameType classFunctionType, bool pointe
16071607
QualifiedName thisName = m_varName;
16081608
if (thisName.size() > 0)
16091609
thisName.erase(thisName.end() - 1);
1610-
params.push_back(FunctionParameter("this", Type::PointerType(m_arch, Type::NamedType(thisName, Type::VoidType())), true, {}));
1610+
params.push_back(FunctionParameter("this", Type::PointerType(m_arch, Type::NamedType(thisName, Type::VoidType())), DefaultLocationSource, {}));
16111611
}
16121612

16131613
DemangleVariableList(params, m_backrefList);

lang/rust/rusttypes.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,13 @@ vector<InstructionTextToken> RustTypePrinter::GetTypeTokensAfterNameInternal(
173173
}
174174
tokens.push_back(nameToken);
175175
tokens.emplace_back(TextToken, ": ");
176+
177+
if (params[i].locationSource == PassByReferenceLocationSource || params[i].location.indirect)
178+
tokens.emplace_back(baseConfidence, OperationToken, "&");
179+
176180
tokens.insert(tokens.end(), paramTokens.begin(), paramTokens.end());
177181

178-
if (!params[i].defaultLocation && platform && var.has_value())
182+
if (params[i].locationSource == CustomLocationSource && platform && var.has_value())
179183
{
180184
switch (var->type)
181185
{

objectivec/objc.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,9 +1256,9 @@ bool ObjCProcessor::ApplyMethodType(Class& cls, Method& method, bool isInstanceM
12561256
cls.associatedName.IsEmpty() ?
12571257
m_types.id :
12581258
Type::PointerType(m_data->GetAddressSize(), Type::NamedType(m_data, cls.associatedName)),
1259-
true, BinaryNinja::Variable()});
1259+
DefaultLocationSource, BinaryNinja::Variable()});
12601260

1261-
params.push_back({"sel", m_types.sel, true, BinaryNinja::Variable()});
1261+
params.push_back({"sel", m_types.sel, DefaultLocationSource, BinaryNinja::Variable()});
12621262

12631263
for (size_t i = 3; i < typeTokens.size(); i++)
12641264
{
@@ -1268,7 +1268,7 @@ bool ObjCProcessor::ApplyMethodType(Class& cls, Method& method, bool isInstanceM
12681268
else
12691269
name = "arg";
12701270

1271-
params.push_back({std::move(name), typeForQualifiedNameOrType(typeTokens[i]), true, BinaryNinja::Variable()});
1271+
params.push_back({std::move(name), typeForQualifiedNameOrType(typeTokens[i]), DefaultLocationSource, BinaryNinja::Variable()});
12721272
}
12731273

12741274
auto funcType = BinaryNinja::Type::FunctionType(retType, cc, params);

plugins/workflow_swift/src/demangler/function_type.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use binaryninja::architecture::{ArchitectureExt, CoreArchitecture};
22
use binaryninja::confidence::Conf;
33
use binaryninja::rc::Ref;
4-
use binaryninja::types::{FunctionParameter, Type, ValueLocation};
4+
use binaryninja::types::{FunctionParameter, Type, ValueLocation, ValueLocationSource};
55
use swift_demangler::{
66
Accessor, AccessorKind, ConstructorKind, HasFunctionSignature, HasModule, Metadata,
77
MetadataKind, Symbol,
@@ -78,7 +78,7 @@ impl CallingConvention {
7878
self.leading_params.push(FunctionParameter {
7979
ty: self_ty.into(),
8080
name: "self".to_string(),
81-
location: None,
81+
location: ValueLocationSource::Default,
8282
});
8383
}
8484

@@ -98,12 +98,12 @@ impl CallingConvention {
9898
self.trailing_params.push(FunctionParameter {
9999
ty: void_ptr.clone().into(),
100100
name: "selfMetadata".to_string(),
101-
location: None,
101+
location: ValueLocationSource::Default,
102102
});
103103
self.trailing_params.push(FunctionParameter {
104104
ty: void_ptr.into(),
105105
name: "selfWitnessTable".to_string(),
106-
location: None,
106+
location: ValueLocationSource::Default,
107107
});
108108
}
109109

@@ -139,7 +139,7 @@ impl CallingConvention {
139139
all_params.push(FunctionParameter {
140140
ty: error_ty.into(),
141141
name: "error".to_string(),
142-
location: self.abi.as_ref().and_then(|a| a.error_location()),
142+
location: self.abi.as_ref().and_then(|a| a.error_location()).into(),
143143
});
144144
}
145145

@@ -148,7 +148,11 @@ impl CallingConvention {
148148
all_params.push(FunctionParameter {
149149
ty: ptr_ty.into(),
150150
name: "asyncContext".to_string(),
151-
location: self.abi.as_ref().and_then(|a| a.async_context_location()),
151+
location: self
152+
.abi
153+
.as_ref()
154+
.and_then(|a| a.async_context_location())
155+
.into(),
152156
});
153157
}
154158

@@ -240,7 +244,7 @@ pub fn build_function_type(symbol: &Symbol, arch: &CoreArchitecture) -> Option<R
240244
Some(FunctionParameter {
241245
ty: ty.into(),
242246
name,
243-
location: None,
247+
location: ValueLocationSource::Default,
244248
})
245249
})
246250
.collect();
@@ -283,7 +287,7 @@ fn build_accessor_type(accessor: &Accessor, arch: &CoreArchitecture) -> Option<R
283287
let params = vec![FunctionParameter {
284288
ty: prop_ty.into(),
285289
name: "newValue".to_string(),
286-
location: None,
290+
location: ValueLocationSource::Default,
287291
}];
288292
Some(cc.build_type(&Type::void(), params))
289293
}
@@ -309,12 +313,12 @@ fn build_metadata_function_type(metadata: &Metadata, arch: &CoreArchitecture) ->
309313
FunctionParameter {
310314
ty: void_ptr.clone().into(),
311315
name: "metadata".to_string(),
312-
location: None,
316+
location: ValueLocationSource::Default,
313317
},
314318
FunctionParameter {
315319
ty: void_ptr.clone().into(),
316320
name: "method".to_string(),
317-
location: None,
321+
location: ValueLocationSource::Default,
318322
},
319323
];
320324
Some(Type::function(&void_ptr, params, false))

plugins/workflow_swift/src/demangler/type_reconstruction.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use binaryninja::architecture::{Architecture, CoreArchitecture};
22
use binaryninja::rc::Ref;
3-
use binaryninja::types::{NamedTypeReference, NamedTypeReferenceClass, QualifiedName, Type};
3+
use binaryninja::types::{
4+
NamedTypeReference, NamedTypeReferenceClass, QualifiedName, Type, ValueLocationSource,
5+
};
46
use swift_demangler::{TypeKind, TypeRef};
57

68
pub(crate) trait TypeRefExt {
@@ -57,7 +59,7 @@ impl TypeRefExt for TypeRef<'_> {
5759
Some(binaryninja::types::FunctionParameter {
5860
ty: ty.into(),
5961
name,
60-
location: None,
62+
location: ValueLocationSource::Default,
6163
})
6264
})
6365
.collect();

python/types.py

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from . import _binaryninjacore as core
2929
from .enums import (
3030
InlineDuringAnalysis, StructureVariant, SymbolType, SymbolBinding, TypeClass, NamedTypeReferenceClass,
31-
ReferenceType, VariableSourceType,
31+
ReferenceType, VariableSourceType, ValueLocationSource,
3232
TypeReferenceType, MemberAccess, MemberScope, TypeDefinitionLineType,
3333
TokenEscapingType,
3434
NameType, PointerSuffix, PointerBaseType,
@@ -625,16 +625,21 @@ def _to_core_struct(self) -> core.BNReturnValue:
625625
class FunctionParameter:
626626
type: SomeType
627627
name: str = ""
628+
location_source: ValueLocationSource = ValueLocationSource.DefaultLocationSource
628629
location: Optional['ValueLocation'] = None
629630

630-
def __init__(self, type: SomeType, name: str = "", location: OptionalLocation = None):
631+
def __init__(self, type: SomeType, name: str = "", location: OptionalLocation = None, source: Optional['ValueLocationSource'] = None):
631632
self.type = type
632633
self.name = name
633634
location = ValueLocationWithConfidence.from_optional_location(location)
634635
if location is not None:
635636
self.location = location.location
637+
self.location_source = ValueLocationSource.CustomLocationSource
636638
else:
637639
self.location = None
640+
self.location_source = ValueLocationSource.DefaultLocationSource
641+
if source is not None:
642+
self.location_source = source
638643

639644
def __repr__(self):
640645
ic = self.type.immutable_copy()
@@ -652,11 +657,12 @@ def mutable_copy(self) -> 'FunctionParameter':
652657
def _from_core_struct(struct: 'core.BNFunctionParameter', arch: Optional['architecture.Architecture'] = None) -> 'FunctionParameter':
653658
name = struct.name
654659
ty = Type.from_core_struct(struct.type).with_confidence(struct.typeConfidence)
655-
if struct.defaultLocation:
656-
location = None
657-
else:
660+
source = ValueLocationSource(struct.locationSource)
661+
if source == ValueLocationSource.CustomLocationSource:
658662
location = ValueLocation._from_core_struct(struct.location, arch)
659-
return FunctionParameter(ty, name, location)
663+
else:
664+
location = None
665+
return FunctionParameter(ty, name, location, source)
660666

661667

662668
@dataclass(frozen=True)
@@ -1584,10 +1590,11 @@ def parameters(self) -> List[FunctionParameter]:
15841590
param_type = Type.create(
15851591
core.BNNewTypeReference(params[i].type), platform=self.platform, confidence=params[i].typeConfidence
15861592
)
1587-
if params[i].defaultLocation:
1588-
param_location = None
1589-
else:
1593+
source = ValueLocationSource(params[i].locationSource)
1594+
if source == ValueLocationSource.CustomLocationSource:
15901595
param_location = ValueLocation._from_core_struct(params[i].location, arch)
1596+
else:
1597+
param_location = None
15911598
result.append(FunctionParameter(param_type, params[i].name, param_location))
15921599
core.BNFreeTypeParameterList(params, count.value)
15931600
return result
@@ -1616,7 +1623,7 @@ def _to_core_struct(params: Optional[ParamsType] = None):
16161623
core_param.name = ""
16171624
core_param.type = param.handle
16181625
core_param.typeConfidence = param.confidence
1619-
core_param.defaultLocation = True
1626+
core_param.locationSource = int(ValueLocationSource.DefaultLocationSource)
16201627
core_param.location.count = 0
16211628
elif isinstance(param, FunctionParameter):
16221629
assert param.type is not None, "Attempting to construct function parameter without properly constructed type"
@@ -1625,11 +1632,10 @@ def _to_core_struct(params: Optional[ParamsType] = None):
16251632
core_param.name = param.name
16261633
core_param.type = param_type.handle
16271634
core_param.typeConfidence = param_type.confidence
1635+
core_param.locationSource = int(param.location_source)
16281636
if param.location is None:
1629-
core_param.defaultLocation = True
16301637
core_param.location.count = 0
16311638
else:
1632-
core_param.defaultLocation = False
16331639
if isinstance(param.location, ValueLocation):
16341640
core_param.location = param.location._to_core_struct()
16351641
elif isinstance(param.location, variable.CoreVariable):
@@ -1645,7 +1651,7 @@ def _to_core_struct(params: Optional[ParamsType] = None):
16451651
core_param.name = name
16461652
core_param.type = _type.handle
16471653
core_param.typeConfidence = _type.confidence
1648-
core_param.defaultLocation = True
1654+
core_param.locationSource = int(ValueLocationSource.DefaultLocationSource)
16491655
core_param.location.count = 0
16501656
else:
16511657
raise ValueError(f"Conversion from unsupported function parameter type {type(param)}")
@@ -3543,11 +3549,12 @@ def parameters(self) -> List[FunctionParameter]:
35433549
param_type = Type.create(
35443550
core.BNNewTypeReference(params[i].type), platform=self._platform, confidence=params[i].typeConfidence
35453551
)
3546-
if params[i].defaultLocation:
3547-
param_location = None
3548-
else:
3552+
source = ValueLocationSource(params[i].locationSource)
3553+
if source == ValueLocationSource.CustomLocationSource:
35493554
param_location = ValueLocation._from_core_struct(params[i].location, arch)
3550-
result.append(FunctionParameter(param_type, params[i].name, param_location))
3555+
else:
3556+
param_location = None
3557+
result.append(FunctionParameter(param_type, params[i].name, param_location, source))
35513558
core.BNFreeTypeParameterList(params, count.value)
35523559
return result
35533560

0 commit comments

Comments
 (0)