Skip to content

Commit 539d5b2

Browse files
committed
Merge remote-tracking branch 'origin/patch'
2 parents 7890f1e + 4603b36 commit 539d5b2

File tree

4 files changed

+50
-12
lines changed

4 files changed

+50
-12
lines changed

Ghidra/Features/Decompiler/src/decompile/cpp/dynamic.cc

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ void DynamicHash::pieceTogetherHash(const Varnode *root,uint4 method)
364364
hash <<= 4;
365365
hash |= method; // 4-bits
366366
hash <<= 7;
367-
hash |= (uint8)op->code(); // 7-bits
367+
hash |= (uint8)transtable[op->code()]; // 7-bits
368368
hash <<= 5;
369369
hash |= (uint8)(slot & 0x1f); // 5-bits
370370

@@ -607,6 +607,25 @@ PcodeOp *DynamicHash::findOp(const Funcdata *fd,const Address &addr,uint8 h)
607607
return oplist2[pos];
608608
}
609609

610+
/// Otherwise preserve the order of the list.
611+
/// \param varlist is the given list of Varnodes to check
612+
void DynamicHash::dedupVarnodes(vector<Varnode *> &varlist)
613+
614+
{
615+
if (varlist.size() < 2) return;
616+
vector<Varnode *> resList;
617+
for(int4 i=0;i<varlist.size();++i) {
618+
Varnode *vn = varlist[i];
619+
if (!vn->isMark()) {
620+
vn->setMark();
621+
resList.push_back(vn);
622+
}
623+
}
624+
for(int4 i=0;i<resList.size();++i)
625+
resList[i]->clearMark();
626+
varlist.swap(resList);
627+
}
628+
610629
/// \brief Get the Varnodes immediately attached to PcodeOps at the given address
611630
///
612631
/// Varnodes can be either inputs or outputs to the PcodeOps. The op-code, slot, and
@@ -619,7 +638,7 @@ PcodeOp *DynamicHash::findOp(const Funcdata *fd,const Address &addr,uint8 h)
619638
void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata *fd,const Address &addr,uint8 h)
620639

621640
{
622-
OpCode opc = getOpCodeFromHash(h);
641+
uint4 opcVal = getOpCodeFromHash(h);
623642
int4 slot = getSlotFromHash(h);
624643
bool isnotattached = getIsNotAttached(h);
625644
PcodeOpTree::const_iterator iter = fd->beginOp(addr);
@@ -629,7 +648,7 @@ void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata
629648
PcodeOp *op = (*iter).second;
630649
++iter;
631650
if (op->isDead()) continue;
632-
if (op->code() != opc) continue;
651+
if (transtable[op->code()] != opcVal) continue;
633652
if (slot <0) {
634653
Varnode *vn = op->getOut();
635654
if (vn != (Varnode *)0) {
@@ -655,6 +674,7 @@ void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata
655674
varlist.push_back(vn);
656675
}
657676
}
677+
dedupVarnodes(varlist);
658678
}
659679

660680
/// \brief Place all PcodeOps at the given address in the provided container
@@ -697,11 +717,11 @@ uint4 DynamicHash::getMethodFromHash(uint8 h)
697717

698718
/// The hash encodes the op-code of the p-code op attached to the root Varnode
699719
/// \param h is the hash value
700-
/// \return the op-code
701-
OpCode DynamicHash::getOpCodeFromHash(uint8 h)
720+
/// \return the op-code as an integer
721+
uint4 DynamicHash::getOpCodeFromHash(uint8 h)
702722

703723
{
704-
return (OpCode)((h>>37)&0x7f);
724+
return (h>>37)&0x7f;
705725
}
706726

707727
/// The hash encodes the position of the root Varnode within the list of hash collisions

Ghidra/Features/Decompiler/src/decompile/cpp/dynamic.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class DynamicHash {
7777
void gatherUnmarkedOp(void); ///< Mark any new PcodeOps in the sub-graph
7878
void pieceTogetherHash(const Varnode *root,uint4 method); ///< Clean-up and piece together formal hash value
7979
static void moveOffSkip(const PcodeOp *&op,int4 &slot); ///< Convert given PcodeOp to a non-skip op by following data-flow
80+
static void dedupVarnodes(vector<Varnode *> &varlist); ///< Remove any duplicate Varnodes in given list
8081
public:
8182
void clear(void); ///< Called for each additional hash (after the first)
8283
void calcHash(const Varnode *root,uint4 method); ///< Calculate the hash for given Varnode and method
@@ -92,7 +93,7 @@ public:
9293
static void gatherOpsAtAddress(vector<PcodeOp *> &opList,const Funcdata *fd,const Address &addr);
9394
static int4 getSlotFromHash(uint8 h); ///< Retrieve the encoded slot from a hash
9495
static uint4 getMethodFromHash(uint8 h); ///< Retrieve the encoded method from a hash
95-
static OpCode getOpCodeFromHash(uint8 h); ///< Retrieve the encoded op-code from a hash
96+
static uint4 getOpCodeFromHash(uint8 h); ///< Retrieve the encoded op-code from a hash
9697
static uint4 getPositionFromHash(uint8 h); ///< Retrieve the encoded position from a hash
9798
static uint4 getTotalFromHash(uint8 h); ///< Retrieve the encoded collision total from a hash
9899
static bool getIsNotAttached(uint8 h); ///< Retrieve the attachment boolean from a hash

Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_block.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -570,10 +570,11 @@ bool Funcdata::earlyJumpTableFail(PcodeOp *op)
570570
OpCode opc = op->code();
571571
if (opc == CPUI_CALLOTHER) {
572572
int4 id = (int4)op->getIn(0)->getOffset();
573-
InjectedUserOp *userOp = dynamic_cast<InjectedUserOp *>(glb->userops.getOp(id));
574-
if (userOp != (InjectedUserOp *)0) {
573+
UserPcodeOp *userOp = glb->userops.getOp(id);
574+
if (dynamic_cast<InjectedUserOp *>(userOp) != (InjectedUserOp *)0)
575575
return false; // Don't try to back track through injection
576-
}
576+
if (dynamic_cast<JumpAssistOp *>(userOp) != (JumpAssistOp *)0)
577+
return false;
577578
if (outhit)
578579
return true; // Address formed via uninjected CALLOTHER, analysis will fail
579580
// Assume CALLOTHER will not interfere with address and continue backtracking

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/DynamicHash.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ private void pieceTogetherHash(Varnode root, int method) {
415415
hash <<= 4;
416416
hash |= method; // 4-bits
417417
hash <<= 7;
418-
hash |= op.getOpcode(); // 7-bits
418+
hash |= transtable[op.getOpcode()]; // 7-bits
419419
hash <<= 5;
420420
hash |= slot & 0x1f; // 5-bits
421421

@@ -705,6 +705,21 @@ public static void gatherOpsAtAddress(ArrayList<PcodeOp> oplist, PcodeSyntaxTree
705705
}
706706
}
707707

708+
private static void dedupVarnodes(ArrayList<Varnode> varlist) {
709+
if (varlist.size() < 2) {
710+
return;
711+
}
712+
ArrayList<Varnode> resList = new ArrayList<>();
713+
HashSet<Varnode> hashSet = new HashSet<>();
714+
for (Varnode vn : varlist) {
715+
if (hashSet.add(vn)) {
716+
resList.add(vn);
717+
}
718+
}
719+
varlist.clear();
720+
varlist.addAll(resList);
721+
}
722+
708723
public static void gatherFirstLevelVars(ArrayList<Varnode> varlist, PcodeSyntaxTree fd,
709724
Address addr, long h) {
710725
int opc = getOpCodeFromHash(h);
@@ -714,7 +729,7 @@ public static void gatherFirstLevelVars(ArrayList<Varnode> varlist, PcodeSyntaxT
714729

715730
while (iter.hasNext()) {
716731
PcodeOp op = iter.next();
717-
if (op.getOpcode() != opc) {
732+
if (transtable[op.getOpcode()] != opc) {
718733
continue;
719734
}
720735
if (slot < 0) {
@@ -745,6 +760,7 @@ else if (slot < op.getNumInputs()) {
745760
varlist.add(vn);
746761
}
747762
}
763+
dedupVarnodes(varlist);
748764
}
749765

750766
public static int getSlotFromHash(long h) {

0 commit comments

Comments
 (0)