@@ -54,6 +54,13 @@ CallingConvention::CallingConvention(Architecture* arch, const string& name)
5454 cc.getIncomingFlagValue = GetIncomingFlagValueCallback;
5555 cc.getIncomingVariableForParameterVariable = GetIncomingVariableForParameterVariableCallback;
5656 cc.getParameterVariableForIncomingVariable = GetParameterVariableForIncomingVariableCallback;
57+ cc.getRegisterArgumentClasses = GetRegisterArgumentClassesCallback;
58+ cc.getRegisterArgumentClassLists = GetRegisterArgumentClassListsCallback;
59+ cc.getRegisterArgumentLists = GetRegisterArgumentListsCallback;
60+ cc.getRegisterArgumentListRegs = GetRegisterArgumentListRegsCallback;
61+ cc.getRegisterArgumentListKind = GetRegisterArgumentListKindCallback;
62+ cc.getVariablesForParameters = GetVariablesForParametersCallback;
63+ cc.freeVariableList = FreeVariableListCallback;
5764
5865 AddRefForRegistration ();
5966 m_object = BNCreateCallingConvention (arch->GetObject (), name.c_str (), &cc);
@@ -125,6 +132,12 @@ void CallingConvention::FreeRegisterListCallback(void*, uint32_t* regs, size_t)
125132}
126133
127134
135+ void CallingConvention::FreeVariableListCallback (void *, BNVariable* vars, size_t )
136+ {
137+ delete[] vars;
138+ }
139+
140+
128141bool CallingConvention::AreArgumentRegistersSharedIndexCallback (void * ctxt)
129142{
130143 CallbackRef<CallingConvention> cc (ctxt);
@@ -283,6 +296,65 @@ vector<uint32_t> CallingConvention::GetFloatArgumentRegisters()
283296 return vector<uint32_t >();
284297}
285298
299+ vector<uint32_t > CallingConvention::GetRegisterArgumentClasses ()
300+ {
301+ size_t count;
302+ uint32_t * classes = BNGetRegisterArgumentClasses (GetObject (), &count);
303+ vector<uint32_t > result;
304+ for (size_t i = 0 ; i < count; i++)
305+ result.push_back (classes[i]);
306+ BNFreeRegisterList (classes);
307+ return result;
308+ }
309+
310+
311+ vector<uint32_t > CallingConvention::GetRegisterArgumentClassLists (uint32_t classId)
312+ {
313+ size_t count;
314+ uint32_t * lists = BNGetRegisterArgumentClassLists (GetObject (), classId, &count);
315+ vector<uint32_t > result;
316+ for (size_t i = 0 ; i < count; i++)
317+ result.push_back (lists[i]);
318+ BNFreeRegisterList (lists);
319+ return result;
320+ }
321+
322+
323+ vector<uint32_t > CallingConvention::GetRegisterArgumentLists ()
324+ {
325+ size_t count;
326+ uint32_t * lists = BNGetRegisterArgumentLists (GetObject (), &count);
327+ vector<uint32_t > result;
328+ for (size_t i = 0 ; i < count; i++)
329+ result.push_back (lists[i]);
330+ BNFreeRegisterList (lists);
331+ return result;
332+ }
333+
334+
335+ vector<uint32_t > CallingConvention::GetRegisterArgumentListRegs (uint32_t regListId)
336+ {
337+ size_t count;
338+ uint32_t * regs = BNGetRegisterArgumentListRegs (GetObject (), regListId, &count);
339+ vector<uint32_t > result;
340+ for (size_t i = 0 ; i < count; i++)
341+ result.push_back (regs[i]);
342+ BNFreeRegisterList (regs);
343+ return result;
344+ }
345+
346+
347+ BNRegisterListKind CallingConvention::GetRegisterArgumentListKind (uint32_t regListId)
348+ {
349+ return BNGetRegisterArgumentListKind (GetObject (), regListId);
350+ }
351+
352+
353+ vector<Variable> CallingConvention::GetVariablesForParameters (const vector<FunctionParameter>& paramTypes,
354+ const std::set<uint32_t >* permittedRegs)
355+ {
356+ return vector<Variable>();
357+ }
286358
287359bool CallingConvention::AreArgumentRegistersSharedIndex ()
288360{
@@ -504,3 +576,202 @@ Variable CoreCallingConvention::GetParameterVariableForIncomingVariable(const Va
504576{
505577 return BNGetParameterVariableForIncomingVariable (m_object, &var, func ? func->GetObject () : nullptr );
506578}
579+
580+
581+ vector<uint32_t > CoreCallingConvention::GetRegisterArgumentClasses ()
582+ {
583+ size_t count;
584+ uint32_t * classes = BNGetRegisterArgumentClasses (m_object, &count);
585+ vector<uint32_t > result;
586+ result.insert (result.end (), classes, &classes[count]);
587+ BNFreeRegisterList (classes);
588+ return result;
589+ }
590+
591+
592+ vector<uint32_t > CoreCallingConvention::GetRegisterArgumentClassLists (uint32_t classId)
593+ {
594+ size_t count;
595+ uint32_t * lists = BNGetRegisterArgumentClassLists (m_object, classId, &count);
596+ vector<uint32_t > result;
597+ result.insert (result.end (), lists, &lists[count]);
598+ BNFreeRegisterList (lists);
599+ return result;
600+ }
601+
602+
603+ vector<uint32_t > CoreCallingConvention::GetRegisterArgumentLists ()
604+ {
605+ size_t count;
606+ uint32_t * lists = BNGetRegisterArgumentLists (m_object, &count);
607+ vector<uint32_t > result;
608+ result.insert (result.end (), lists, &lists[count]);
609+ BNFreeRegisterList (lists);
610+ return result;
611+ }
612+
613+
614+ vector<uint32_t > CoreCallingConvention::GetRegisterArgumentListRegs (uint32_t regListId)
615+ {
616+ size_t count;
617+ uint32_t * regs = BNGetRegisterArgumentListRegs (m_object, regListId, &count);
618+ vector<uint32_t > result;
619+ result.insert (result.end (), regs, ®s[count]);
620+ BNFreeRegisterList (regs);
621+ return result;
622+ }
623+
624+
625+ BNRegisterListKind CoreCallingConvention::GetRegisterArgumentListKind (uint32_t regListId)
626+ {
627+ return BNGetRegisterArgumentListKind (m_object, regListId);
628+ }
629+
630+
631+ vector<Variable> CoreCallingConvention::GetVariablesForParameters (const vector<FunctionParameter>& paramTypes,
632+ const std::set<uint32_t >* permittedRegs)
633+ {
634+ BNFunctionParameter* params = new BNFunctionParameter[paramTypes.size ()];
635+ for (size_t i = 0 ; i < paramTypes.size (); i++)
636+ {
637+ params[i].name = (char *)paramTypes[i].name .c_str ();
638+ params[i].type = paramTypes[i].type ->GetObject ();
639+ params[i].typeConfidence = paramTypes[i].type .GetConfidence ();
640+ params[i].defaultLocation = paramTypes[i].defaultLocation ;
641+ params[i].location .type = paramTypes[i].location .type ;
642+ params[i].location .index = paramTypes[i].location .index ;
643+ params[i].location .storage = paramTypes[i].location .storage ;
644+ }
645+
646+ uint32_t * permittedRegsArray = nullptr ;
647+ size_t permittedRegsCount = 0 ;
648+ if (permittedRegs != nullptr )
649+ {
650+ permittedRegsCount = permittedRegs->size ();
651+ permittedRegsArray = new uint32_t [permittedRegsCount];
652+ size_t j = 0 ;
653+ for (auto reg : *permittedRegs)
654+ permittedRegsArray[j++] = reg;
655+ }
656+
657+ size_t count;
658+ BNVariable* vars = BNGetVariablesForParameters (m_object, params, paramTypes.size (),
659+ permittedRegsArray, permittedRegsCount, &count);
660+
661+ vector<Variable> result;
662+ for (size_t i = 0 ; i < count; i++)
663+ result.push_back (vars[i]);
664+
665+ delete[] params;
666+ if (permittedRegsArray)
667+ delete[] permittedRegsArray;
668+ BNFreeVariableList (vars);
669+ return result;
670+ }
671+
672+
673+ uint32_t * CallingConvention::GetRegisterArgumentClassesCallback (void * ctxt, size_t * count)
674+ {
675+ CallbackRef<CallingConvention> cc (ctxt);
676+ vector<uint32_t > classes = cc->GetRegisterArgumentClasses ();
677+ *count = classes.size ();
678+
679+ uint32_t * result = new uint32_t [classes.size ()];
680+ for (size_t i = 0 ; i < classes.size (); i++)
681+ result[i] = classes[i];
682+ return result;
683+ }
684+
685+
686+ uint32_t * CallingConvention::GetRegisterArgumentClassListsCallback (void * ctxt, uint32_t classId, size_t * count)
687+ {
688+ CallbackRef<CallingConvention> cc (ctxt);
689+ vector<uint32_t > lists = cc->GetRegisterArgumentClassLists (classId);
690+ *count = lists.size ();
691+
692+ uint32_t * result = new uint32_t [lists.size ()];
693+ for (size_t i = 0 ; i < lists.size (); i++)
694+ result[i] = lists[i];
695+ return result;
696+ }
697+
698+
699+ uint32_t * CallingConvention::GetRegisterArgumentListsCallback (void * ctxt, size_t * count)
700+ {
701+ CallbackRef<CallingConvention> cc (ctxt);
702+ vector<uint32_t > lists = cc->GetRegisterArgumentLists ();
703+ *count = lists.size ();
704+
705+ uint32_t * result = new uint32_t [lists.size ()];
706+ for (size_t i = 0 ; i < lists.size (); i++)
707+ result[i] = lists[i];
708+ return result;
709+ }
710+
711+
712+ uint32_t * CallingConvention::GetRegisterArgumentListRegsCallback (void * ctxt, uint32_t regListId, size_t * count)
713+ {
714+ CallbackRef<CallingConvention> cc (ctxt);
715+ vector<uint32_t > regs = cc->GetRegisterArgumentListRegs (regListId);
716+ *count = regs.size ();
717+
718+ uint32_t * result = new uint32_t [regs.size ()];
719+ for (size_t i = 0 ; i < regs.size (); i++)
720+ result[i] = regs[i];
721+ return result;
722+ }
723+
724+
725+ BNRegisterListKind CallingConvention::GetRegisterArgumentListKindCallback (void * ctxt, uint32_t regListId)
726+ {
727+ CallbackRef<CallingConvention> cc (ctxt);
728+ return cc->GetRegisterArgumentListKind (regListId);
729+ }
730+
731+
732+ BNVariable* CallingConvention::GetVariablesForParametersCallback (void * ctxt, const BNFunctionParameter* paramTypes, size_t paramCount, const uint32_t * permittedRegs, size_t permittedRegCount, size_t * resultCount)
733+ {
734+ CallbackRef<CallingConvention> cc (ctxt);
735+
736+ vector<FunctionParameter> params;
737+ for (size_t i = 0 ; i < paramCount; i++)
738+ {
739+ FunctionParameter param;
740+ param.name = paramTypes[i].name ;
741+ param.type = Confidence<Ref<Type>>(new Type (BNNewTypeReference (paramTypes[i].type )), paramTypes[i].typeConfidence );
742+ param.defaultLocation = paramTypes[i].defaultLocation ;
743+ param.location = paramTypes[i].location ;
744+ params.push_back (param);
745+ }
746+
747+ std::set<uint32_t >* permittedRegsSet = nullptr ;
748+ if (permittedRegs && permittedRegCount > 0 )
749+ {
750+ permittedRegsSet = new std::set<uint32_t >();
751+ for (size_t i = 0 ; i < permittedRegCount; i++)
752+ permittedRegsSet->insert (permittedRegs[i]);
753+ }
754+
755+ vector<Variable> variables = cc->GetVariablesForParameters (params, permittedRegsSet);
756+
757+ // If the calling convention doesn't implement this method, it returns an empty vector
758+ // Signal fallback to core implementation by returning NULL with count 0
759+ if (variables.empty ())
760+ {
761+ *resultCount = 0 ;
762+ if (permittedRegsSet)
763+ delete permittedRegsSet;
764+ return nullptr ;
765+ }
766+
767+ *resultCount = variables.size ();
768+
769+ BNVariable* result = new BNVariable[variables.size ()];
770+ for (size_t i = 0 ; i < variables.size (); i++)
771+ result[i] = variables[i];
772+
773+ if (permittedRegsSet)
774+ delete permittedRegsSet;
775+
776+ return result;
777+ }
0 commit comments