Skip to content

Commit 8db9dfb

Browse files
committed
Ensure we separate out platform/arch from initial Demangling phase
1 parent dfc95ea commit 8db9dfb

5 files changed

Lines changed: 252 additions & 90 deletions

File tree

demangler/gnu3/demangle_gnu3.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -692,8 +692,8 @@ DemangledTypeNode DemangleGNU3::DemangleType()
692692
else if (m_reader.Peek() == 'e')
693693
{
694694
m_reader.Consume();
695-
type = DemangledTypeNode::NamedType(EnumNamedTypeClass, StringList{DemangleSourceName()},
696-
m_arch->GetDefaultIntegerSize());
695+
type = DemangledTypeNode::NamedTypeWithDefaultIntegerWidth(
696+
EnumNamedTypeClass, StringList{DemangleSourceName()});
697697
break;
698698
}
699699

@@ -718,21 +718,21 @@ DemangledTypeNode DemangleGNU3::DemangleType()
718718
case 'P':
719719
{
720720
DemangledTypeNode child = DemangleType();
721-
type = DemangledTypeNode::PointerType(m_arch, std::move(child), cnst, vltl, PointerReferenceType);
721+
type = DemangledTypeNode::PointerType(std::move(child), cnst, vltl, PointerReferenceType);
722722
substitute = true;
723723
break;
724724
}
725725
case 'R':
726726
{
727727
DemangledTypeNode child = DemangleType();
728-
type = DemangledTypeNode::PointerType(m_arch, std::move(child), cnst, vltl, ReferenceReferenceType);
728+
type = DemangledTypeNode::PointerType(std::move(child), cnst, vltl, ReferenceReferenceType);
729729
substitute = true;
730730
break;
731731
}
732732
case 'O':
733733
{
734734
DemangledTypeNode child = DemangleType();
735-
type = DemangledTypeNode::PointerType(m_arch, std::move(child), cnst, vltl, RValueReferenceType);
735+
type = DemangledTypeNode::PointerType(std::move(child), cnst, vltl, RValueReferenceType);
736736
substitute = true;
737737
break;
738738
}
@@ -785,8 +785,8 @@ DemangledTypeNode DemangleGNU3::DemangleType()
785785
case 't': type = DemangledTypeNode::IntegerType(2, false); break;
786786
case 'i': type = DemangledTypeNode::IntegerType(4, true); break;
787787
case 'j': type = DemangledTypeNode::IntegerType(4, false); break;
788-
case 'l': type = DemangledTypeNode::IntegerType(m_arch->GetAddressSize(), true); break; //long
789-
case 'm': type = DemangledTypeNode::IntegerType(m_arch->GetAddressSize(), false); break; //ulong
788+
case 'l': type = DemangledTypeNode::AddressSizedIntegerType(true); break; //long
789+
case 'm': type = DemangledTypeNode::AddressSizedIntegerType(false); break; //ulong
790790
case 'x': type = DemangledTypeNode::IntegerType(8, true); break;
791791
case 'y': type = DemangledTypeNode::IntegerType(8, false); break;
792792
case 'n': type = DemangledTypeNode::IntegerType(16, true); break;
@@ -802,7 +802,7 @@ DemangledTypeNode DemangleGNU3::DemangleType()
802802
DemangledTypeNode member = DemangleType();
803803
string fullName = member.GetStringBeforeName() + "(" + memberName.GetString() + "::*)" + member.GetStringAfterName();
804804
//member.SetScope(NonStaticScope);
805-
//DemangledTypeNode ptr = DemangledTypeNode::PointerType(m_arch, member, cnst, vltl);
805+
//DemangledTypeNode ptr = DemangledTypeNode::PointerType(member, cnst, vltl, PointerReferenceType);
806806
type = CreateUnknownType(fullName);
807807
substitute = true;
808808
break;
@@ -2785,7 +2785,7 @@ DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName)
27852785
else
27862786
{
27872787
isReturnTypeUnknown = true;
2788-
returnType = DemangledTypeNode::IntegerType(m_arch->GetAddressSize(), true);
2788+
returnType = DemangledTypeNode::AddressSizedIntegerType(true);
27892789
}
27902790

27912791
m_functionSubstitute.push_back({});
@@ -2988,7 +2988,7 @@ namespace
29882988
outVarName.clear();
29892989
outVarName.push_back(header);
29902990
outVarName.push_back(encoding);
2991-
outType = DemangledTypeNode::NamedType(UnknownNamedTypeClass, outVarName).Finalize();
2991+
outType = DemangledTypeNode::NamedType(UnknownNamedTypeClass, outVarName).Finalize(arch);
29922992
return true;
29932993
}
29942994
else
@@ -2998,7 +2998,7 @@ namespace
29982998
demangle.Reset(arch, encoding);
29992999
try
30003000
{
3001-
outType = demangle.DemangleSymbol(outVarName).Finalize();
3001+
outType = demangle.DemangleSymbol(outVarName).Finalize(arch);
30023002

30033003
if (outVarName.size() == 0)
30043004
{

demangler/gnu3/demangled_type_node.cpp

Lines changed: 153 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
// limitations under the License.
1414

1515
#include "demangled_type_node.h"
16+
#ifdef BINARYNINJACORE_LIBRARY
17+
#include "binaryview.h"
18+
#endif
1619
#include <cinttypes>
1720

1821
#ifdef BINARYNINJACORE_LIBRARY
@@ -60,6 +63,101 @@ namespace
6063
return out;
6164
}
6265

66+
static size_t ResolveAddressWidth(Architecture* arch, Platform* platform)
67+
{
68+
if (arch)
69+
return arch->GetAddressSize();
70+
if (platform)
71+
return platform->GetAddressSize();
72+
return 8;
73+
}
74+
75+
static size_t ResolveDefaultIntegerWidth(Architecture* arch, Platform* platform)
76+
{
77+
if (arch)
78+
return arch->GetDefaultIntegerSize();
79+
if (platform)
80+
{
81+
#ifdef BINARYNINJACORE_LIBRARY
82+
Architecture* platformArch = platform->GetArchitecture();
83+
#else
84+
Ref<Architecture> platformArch = platform->GetArchitecture();
85+
#endif
86+
if (platformArch)
87+
return platformArch->GetDefaultIntegerSize();
88+
}
89+
return 4;
90+
}
91+
92+
static Ref<CallingConvention> ResolveCallingConvention(
93+
BNCallingConventionName cc, Architecture* arch, Platform* platform)
94+
{
95+
#ifndef BINARYNINJACORE_LIBRARY
96+
Ref<Architecture> platformArch;
97+
#endif
98+
if (!arch && platform)
99+
{
100+
#ifdef BINARYNINJACORE_LIBRARY
101+
arch = platform->GetArchitecture();
102+
#else
103+
platformArch = platform->GetArchitecture();
104+
arch = platformArch.GetPtr();
105+
#endif
106+
}
107+
108+
switch (cc)
109+
{
110+
case CdeclCallingConvention:
111+
if (platform)
112+
{
113+
auto platformCC = platform->GetCdeclCallingConvention();
114+
if (platformCC)
115+
return platformCC;
116+
}
117+
if (arch)
118+
{
119+
auto archCC = arch->GetCdeclCallingConvention();
120+
if (archCC)
121+
return archCC;
122+
}
123+
return arch ? arch->GetCallingConventionByName("cdecl") : nullptr;
124+
case STDCallCallingConvention:
125+
if (platform)
126+
{
127+
auto platformCC = platform->GetStdcallCallingConvention();
128+
if (platformCC)
129+
return platformCC;
130+
}
131+
if (arch)
132+
{
133+
auto archCC = arch->GetStdcallCallingConvention();
134+
if (archCC)
135+
return archCC;
136+
}
137+
return arch ? arch->GetCallingConventionByName("stdcall") : nullptr;
138+
case FastcallCallingConvention:
139+
if (platform)
140+
{
141+
auto platformCC = platform->GetFastcallCallingConvention();
142+
if (platformCC)
143+
return platformCC;
144+
}
145+
if (arch)
146+
{
147+
auto archCC = arch->GetFastcallCallingConvention();
148+
if (archCC)
149+
return archCC;
150+
}
151+
return arch ? arch->GetCallingConventionByName("fastcall") : nullptr;
152+
case ThisCallCallingConvention:
153+
if (arch)
154+
return arch->GetCallingConventionByName("thiscall");
155+
return nullptr;
156+
default:
157+
return nullptr;
158+
}
159+
}
160+
63161
}
64162

65163
#define HAS_POINTER_SUFFIX(bit) ((m_pointerSuffixBits & (bit)) != 0)
@@ -86,7 +184,7 @@ DemangledTypeNode::DemangledTypeNode()
86184
m_callingConventionName(NoCallingConvention), m_pointerSuffixBits(0),
87185
m_returnTypeConfidence(BN_FULL_CONFIDENCE),
88186
m_const(false), m_volatile(false), m_signed(false), m_hasVariableArgs(false),
89-
m_hasTemplateArgs(false), m_width(0),
187+
m_hasTemplateArgs(false), m_width(0), m_widthKind(FixedWidth),
90188
m_isMemberPointer(false),
91189
m_elements(0)
92190
{
@@ -121,6 +219,14 @@ DemangledTypeNode DemangledTypeNode::IntegerType(size_t width, bool isSigned, co
121219
}
122220

123221

222+
DemangledTypeNode DemangledTypeNode::AddressSizedIntegerType(bool isSigned, const string& altName)
223+
{
224+
DemangledTypeNode n = IntegerType(0, isSigned, altName);
225+
n.m_widthKind = AddressWidth;
226+
return n;
227+
}
228+
229+
124230
DemangledTypeNode DemangledTypeNode::FloatType(size_t width, const string& altName)
125231
{
126232
DemangledTypeNode n;
@@ -158,12 +264,11 @@ DemangledTypeNode DemangledTypeNode::VarArgsType()
158264
}
159265

160266

161-
DemangledTypeNode DemangledTypeNode::PointerType(Architecture* arch, DemangledTypeNode child,
162-
bool cnst, bool vltl, BNReferenceType refType)
267+
DemangledTypeNode DemangledTypeNode::PointerType(DemangledTypeNode child, bool cnst, bool vltl, BNReferenceType refType)
163268
{
164269
DemangledTypeNode n;
165270
n.m_typeClass = PointerTypeClass;
166-
n.m_width = arch->GetAddressSize();
271+
n.m_widthKind = AddressWidth;
167272
n.m_childType = std::make_shared<DemangledTypeNode>(std::move(child));
168273
n.m_const = cnst;
169274
n.m_volatile = vltl;
@@ -172,12 +277,11 @@ DemangledTypeNode DemangledTypeNode::PointerType(Architecture* arch, DemangledTy
172277
}
173278

174279

175-
DemangledTypeNode DemangledTypeNode::MemberPointerType(Architecture* arch, DemangledTypeNode child,
176-
StringList ownerName, bool cnst, bool vltl)
280+
DemangledTypeNode DemangledTypeNode::MemberPointerType(DemangledTypeNode child, StringList ownerName, bool cnst, bool vltl)
177281
{
178282
DemangledTypeNode n;
179283
n.m_typeClass = PointerTypeClass;
180-
n.m_width = arch->GetAddressSize();
284+
n.m_widthKind = AddressWidth;
181285
n.m_childType = std::make_shared<DemangledTypeNode>(std::move(child));
182286
n.m_const = cnst;
183287
n.m_volatile = vltl;
@@ -227,6 +331,14 @@ DemangledTypeNode DemangledTypeNode::NamedType(BNNamedTypeReferenceClass cls,
227331
return n;
228332
}
229333

334+
DemangledTypeNode DemangledTypeNode::NamedTypeWithDefaultIntegerWidth(BNNamedTypeReferenceClass cls,
335+
StringList nameSegments, bool isSigned)
336+
{
337+
DemangledTypeNode n = NamedType(cls, std::move(nameSegments), 0, isSigned);
338+
n.m_widthKind = DefaultIntegerWidth;
339+
return n;
340+
}
341+
230342
uint8_t DemangledTypeNode::PointerSuffixBit(BNPointerSuffix ps)
231343
{
232344
switch (ps)
@@ -247,6 +359,21 @@ uint8_t DemangledTypeNode::PointerSuffixBit(BNPointerSuffix ps)
247359
}
248360

249361

362+
size_t DemangledTypeNode::ResolveWidth(Architecture* arch, Platform* platform) const
363+
{
364+
switch (m_widthKind)
365+
{
366+
case AddressWidth:
367+
return ResolveAddressWidth(arch, platform);
368+
case DefaultIntegerWidth:
369+
return ResolveDefaultIntegerWidth(arch, platform);
370+
case FixedWidth:
371+
default:
372+
return m_width;
373+
}
374+
}
375+
376+
250377
void DemangledTypeNode::AddPointerSuffixes(TypeBuilder& tb, bool omitPtr64) const
251378
{
252379
if (HAS_POINTER_SUFFIX(DemangledPtr64Bit) && !omitPtr64)
@@ -388,18 +515,18 @@ void DemangledTypeNode::AppendBeforeName(string& out, const DemangledTypeNode* p
388515
case IntegerTypeClass:
389516
if (!m_altName.empty())
390517
out += m_altName;
391-
else if (m_signed && m_width == 1)
518+
else if (m_signed && ResolveWidth() == 1)
392519
out += "char";
393520
else if (m_signed)
394521
{
395522
out += "int";
396-
out += to_string(m_width * 8);
523+
out += to_string(ResolveWidth() * 8);
397524
out += "_t";
398525
}
399526
else
400527
{
401528
out += "uint";
402-
out += to_string(m_width * 8);
529+
out += to_string(ResolveWidth() * 8);
403530
out += "_t";
404531
}
405532
AppendModifiers(out);
@@ -609,7 +736,7 @@ string DemangledTypeNode::GetTypeAndName(const StringList& name) const
609736
}
610737

611738

612-
Ref<Type> DemangledTypeNode::Finalize() const
739+
Ref<Type> DemangledTypeNode::Finalize(Architecture* arch, Platform* platform) const
613740
{
614741
switch (m_typeClass)
615742
{
@@ -636,8 +763,8 @@ Ref<Type> DemangledTypeNode::Finalize() const
636763
case IntegerTypeClass:
637764
{
638765
if (!m_const && !m_volatile)
639-
return Type::IntegerType(m_width, m_signed, m_altName);
640-
TypeBuilder tb = TypeBuilder::IntegerType(m_width, m_signed, m_altName);
766+
return Type::IntegerType(ResolveWidth(arch, platform), m_signed, m_altName);
767+
TypeBuilder tb = TypeBuilder::IntegerType(ResolveWidth(arch, platform), m_signed, m_altName);
641768
tb.SetConst(m_const);
642769
tb.SetVolatile(m_volatile);
643770
return tb.Finalize();
@@ -671,8 +798,9 @@ Ref<Type> DemangledTypeNode::Finalize() const
671798

672799
case PointerTypeClass:
673800
{
674-
Ref<Type> child = m_childType ? m_childType->Finalize() : Ref<Type>(Type::VoidType());
675-
TypeBuilder tb = TypeBuilder::PointerType(m_width, child, m_const, m_volatile, m_pointerReference);
801+
Ref<Type> child = m_childType ? m_childType->Finalize(arch, platform) : Ref<Type>(Type::VoidType());
802+
TypeBuilder tb = TypeBuilder::PointerType(
803+
ResolveWidth(arch, platform), child, m_const, m_volatile, m_pointerReference);
676804
AddPointerSuffixes(tb, true);
677805
Ref<Type> normalized = tb.Finalize();
678806
if (m_isMemberPointer)
@@ -682,7 +810,7 @@ Ref<Type> DemangledTypeNode::Finalize() const
682810

683811
case ArrayTypeClass:
684812
{
685-
Ref<Type> child = m_childType ? m_childType->Finalize() : Ref<Type>(Type::VoidType());
813+
Ref<Type> child = m_childType ? m_childType->Finalize(arch, platform) : Ref<Type>(Type::VoidType());
686814
TypeBuilder tb = TypeBuilder::ArrayType(child, m_elements);
687815
if (m_const)
688816
tb.SetConst(m_const);
@@ -693,19 +821,24 @@ Ref<Type> DemangledTypeNode::Finalize() const
693821

694822
case FunctionTypeClass:
695823
{
696-
Ref<Type> retType = m_childType ? m_childType->Finalize() : Ref<Type>(Type::VoidType());
824+
Ref<Type> retType = m_childType ? m_childType->Finalize(arch, platform) : Ref<Type>(Type::VoidType());
697825
vector<FunctionParameter> finalParams;
698826
finalParams.reserve(m_params.size() + (m_implicitThisParameterType ? 1 : 0));
699827
if (m_implicitThisParameterType)
700-
finalParams.push_back({"this", m_implicitThisParameterType->Finalize(), true, Variable()});
828+
finalParams.push_back({"this", m_implicitThisParameterType->Finalize(arch, platform), true, Variable()});
701829
for (auto& p : m_params)
702830
{
703-
Ref<Type> pType = p.type ? p.type->Finalize() : Ref<Type>(Type::VoidType());
831+
Ref<Type> pType = p.type ? p.type->Finalize(arch, platform) : Ref<Type>(Type::VoidType());
704832
finalParams.push_back({p.name, pType, true, Variable()});
705833
}
706834
Confidence<Ref<CallingConvention>> callingConvention;
707835
if (m_callingConvention)
708836
callingConvention = Confidence<Ref<CallingConvention>>(m_callingConvention, BN_FULL_CONFIDENCE);
837+
else if (m_callingConventionName != NoCallingConvention)
838+
{
839+
if (auto resolvedCallingConvention = ResolveCallingConvention(m_callingConventionName, arch, platform))
840+
callingConvention = Confidence<Ref<CallingConvention>>(resolvedCallingConvention, BN_FULL_CONFIDENCE);
841+
}
709842
TypeBuilder tb = TypeBuilder::FunctionType(
710843
retType->WithConfidence(static_cast<uint8_t>(m_returnTypeConfidence)), callingConvention, finalParams,
711844
Confidence<bool>(m_hasVariableArgs, m_hasVariableArgs ? BN_DEFAULT_CONFIDENCE : 0));
@@ -722,7 +855,7 @@ Ref<Type> DemangledTypeNode::Finalize() const
722855
{
723856
QualifiedName name(m_nameSegments);
724857
TypeBuilder tb = TypeBuilder::NamedType(
725-
NamedTypeReference::GenerateAutoDemangledTypeReference(m_ntrClass, name), m_width, 1);
858+
NamedTypeReference::GenerateAutoDemangledTypeReference(m_ntrClass, name), ResolveWidth(arch, platform), 1);
726859
tb.SetConst(m_const);
727860
tb.SetVolatile(m_volatile);
728861
AddPointerSuffixes(tb);

0 commit comments

Comments
 (0)