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+
124230DemangledTypeNode 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+
230342uint8_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+
250377void 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