-
Notifications
You must be signed in to change notification settings - Fork 0
Reduce far pointers to near in segmented code #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
133c1cf
019daaa
1d975bb
40ae483
b56d0bb
4aea5d6
ed765ca
3298e4b
c92b7ad
df639b5
a018e19
7318b17
97a372d
d72a2ee
0288c7b
e1245cb
deb5261
3f039d9
2775aa1
2e4cc70
cc7e98b
6a1b8ce
d7ab5f6
72923b9
1dde9ec
f0eb342
fb2c20f
3934d71
26d65c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1223,6 +1223,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), op->getIn(op->numInput() - 1), false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (spacebase != (AddrSpace *)0) { // If we need it, create the stackplaceholder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1251,6 +1252,7 @@ void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int4 sz = outparam->getSize(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Address addr = outparam->getAddress(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data.newVarnodeOut(sz,addr,fc->getOp()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data.segmentizeFarPtr(outparam->getType(), outparam->isTypeLocked(), fc->getOp()->getOut(), false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
VarnodeData vdata; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OpCode res = fc->assumedOutputExtension(addr,sz,vdata); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (res == CPUI_PIECE) { // Pick an extension based on type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -4282,6 +4284,23 @@ int4 ActionInferTypes::apply(Funcdata &data) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (localcount == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Datatype* ct; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Varnode* vn; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
VarnodeLocSet::const_iterator iter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (iter = data.beginLoc(); iter != data.endLoc(); ++iter) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vn = *iter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (vn->isAnnotation()) continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ((!vn->isWritten()) && (vn->hasNoDescend())) continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ct = vn->getLocalType(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bool bBegin = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (iter == data.beginLoc()) bBegin = true; else iter--; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Readability: The variable name |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data.segmentizeFarPtr(ct, vn->isTypeLock(), vn, true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optimization: The iterator manipulation in the |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (bBegin) iter = data.beginLoc(); else iter++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+4287
to
+4302
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Iterator manipulation is unsafe and may skip / duplicate elements Inside the newly-added initialisation block you mutate the
A safer pattern is to take a copy of the container up-front (or cache - for (iter = data.beginLoc(); iter != data.endLoc(); ++iter) {
- vn = *iter;
- ...
- bool bBegin = false;
- if (iter == data.beginLoc()) bBegin = true; else iter--;
- data.segmentizeFarPtr(ct, vn->isTypeLock(), vn, true);
- if (bBegin) iter = data.beginLoc(); else iter++;
- }
+ std::vector<Varnode*> snapshot;
+ snapshot.reserve(std::distance(data.beginLoc(), data.endLoc()));
+
+ for (auto it = data.beginLoc(); it != data.endLoc(); ++it) {
+ Varnode* vn = *it;
+ if (vn->isAnnotation()) continue;
+ if (!vn->isWritten() && vn->hasNoDescend()) continue;
+ snapshot.push_back(vn);
+ }
+
+ for (Varnode* vn : snapshot) {
+ data.segmentizeFarPtr(vn->getLocalType(), vn->isTypeLock(), vn, true);
+ } This avoids iterator invalidation and keeps the logic simple and deterministic. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
buildLocaltypes(data); // Set up initial types (based on local info) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for(iter=data.beginLoc();iter!=data.endLoc();++iter) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vn = *iter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -343,6 +343,71 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const | |||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(op,outvn,slot); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
void Funcdata::segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize) | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question: This new method There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Consider adding a detailed comment block above this new method explaining its purpose and how it handles far pointers. This would help future maintainers understand the intent and behavior of this complex operation. |
||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
SegmentOp* segdef = (SegmentOp*)0; | ||||||||||||||||||||||||||||||||||||||||||||||||||
if ((ct->getMetatype() == TYPE_PTR || | ||||||||||||||||||||||||||||||||||||||||||||||||||
ct->getMetatype() == TYPE_CODE) && locked) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+348
to
+350
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's crucial to check if
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
Architecture* glb = getArch(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
AddrSpace* rspc = glb->getDefaultSpace(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
bool arenearpointers = glb->hasNearPointers(rspc); | ||||||||||||||||||||||||||||||||||||||||||||||||||
if (arenearpointers && rspc->getAddrSize() == vn->getSize()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential bug: The condition |
||||||||||||||||||||||||||||||||||||||||||||||||||
segdef = glb->userops.getSegmentOp(rspc->getIndex()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
//need to go through every single time this varnode is written to | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+348
to
+357
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Null-pointer check & type-safety missing
- SegmentOp* segdef = (SegmentOp*)0;
- if ((ct->getMetatype() == TYPE_PTR ||
+ if (ct == nullptr) // defensive guard
+ return;
+
+ SegmentOp* segdef = nullptr;
+ if ((ct->getMetatype() == TYPE_PTR ||
ct->getMetatype() == TYPE_CODE) && locked) { 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
if (segdef != (SegmentOp*)0 && vn->getDef() != (PcodeOp*)0 && !vn->isPtrCheck() && | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style suggestion: Consider breaking this complex conditional into multiple lines or separate checks for better readability. This long condition is difficult to parse at a glance. |
||||||||||||||||||||||||||||||||||||||||||||||||||
vn->getDef()->code() != CPUI_SEGMENTOP && vn->getDef()->code() != CPUI_CALLOTHER) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
PcodeOp* segroot = vn->getDef(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
Varnode* outvn = newUnique(vn->getSize()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetOutput(segroot, outvn); | ||||||||||||||||||||||||||||||||||||||||||||||||||
PcodeOp* piece1 = newOp(2, segroot->getAddr()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetOpcode(piece1, CPUI_SUBPIECE); | ||||||||||||||||||||||||||||||||||||||||||||||||||
Varnode* vn1 = newUniqueOut(segdef->getBaseSize(), piece1); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(piece1, outvn, 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(piece1, newConstant(outvn->getSize(), segdef->getInnerSize()), 1); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opInsertAfter(piece1, segroot); | ||||||||||||||||||||||||||||||||||||||||||||||||||
PcodeOp* piece2 = newOp(2, segroot->getAddr()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetOpcode(piece2, CPUI_SUBPIECE); | ||||||||||||||||||||||||||||||||||||||||||||||||||
Varnode* vn2 = newUniqueOut(segdef->getInnerSize(), piece2); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(piece2, outvn, 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(piece2, newConstant(outvn->getSize(), 0), 1); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opInsertAfter(piece2, piece1); | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+364
to
+374
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion SUBPIECE constants use pointer-size; should use arch default (usually 4/addrSize 1) The second input of - opSetInput(piece1, newConstant(outvn->getSize(), segdef->getInnerSize()), 1);
+ opSetInput(piece1,
+ newConstant(glb->getDefaultSize(), segdef->getInnerSize()), 1);
...
- opSetInput(piece2, newConstant(outvn->getSize(), 0), 1);
+ opSetInput(piece2,
+ newConstant(glb->getDefaultSize(), 0), 1); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
PcodeOp* newop = newOp(3, segroot->getAddr()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetOutput(newop, vn); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetOpcode(newop, CPUI_CALLOTHER); | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improvement: The comment |
||||||||||||||||||||||||||||||||||||||||||||||||||
//endianness could matter here - e.g. CALLF addr16 on x86 uses segment(*:2 (ptr+2),*:2 ptr) | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(newop, newConstant(4, segdef->getIndex()), 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(newop, vn1, 1); //need to check size of segment | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(newop, vn2, 2); //need to check size of offset | ||||||||||||||||||||||||||||||||||||||||||||||||||
opInsertAfter(newop, piece2); | ||||||||||||||||||||||||||||||||||||||||||||||||||
vn->setPtrCheck(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential issue: The comment |
||||||||||||||||||||||||||||||||||||||||||||||||||
outvn->setPtrCheck(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
if (segmentize) {//FuncLinkInput/FuncLinkOutput come before segmentize, the rest require at least Spacebase for type locks | ||||||||||||||||||||||||||||||||||||||||||||||||||
segroot = vn->getDef(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
vector<Varnode*> bindlist; | ||||||||||||||||||||||||||||||||||||||||||||||||||
bindlist.push_back((Varnode*)0); | ||||||||||||||||||||||||||||||||||||||||||||||||||
bindlist.push_back((Varnode*)0); | ||||||||||||||||||||||||||||||||||||||||||||||||||
if (!segdef->unify(*this, segroot, bindlist)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
ostringstream err; | ||||||||||||||||||||||||||||||||||||||||||||||||||
err << "Segment op in wrong form at "; | ||||||||||||||||||||||||||||||||||||||||||||||||||
segroot->getAddr().printRaw(err); | ||||||||||||||||||||||||||||||||||||||||||||||||||
throw LowlevelError(err.str()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
if (segdef->getNumVariableTerms() == 1) | ||||||||||||||||||||||||||||||||||||||||||||||||||
bindlist[1] = newConstant(4, 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||
// Redefine the op as a segmentop | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetOpcode(segroot, CPUI_SEGMENTOP); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(segroot, newVarnodeSpace(segdef->getSpace()), 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(segroot, bindlist[1], 1); | ||||||||||||||||||||||||||||||||||||||||||||||||||
opSetInput(segroot, bindlist[0], 2); | ||||||||||||||||||||||||||||||||||||||||||||||||||
for (int4 j = segroot->numInput() - 1; j > 2; --j) // Remove anything else | ||||||||||||||||||||||||||||||||||||||||||||||||||
opRemoveInput(segroot, j); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+346
to
+409
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is quite complex and lacks detailed comments. Adding comments to explain the purpose and functionality of each code block would greatly improve its readability and maintainability. For example, what are the conditions under which the |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
void Funcdata::clearCallSpecs(void) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug risk: In the
ActionInferTypes::apply
method, there's a potentially dangerous iterator manipulation withif (iter == data.beginLoc()) bBegin = true; else iter--;
. This pattern of decrementing and incrementing iterators can lead to subtle bugs. Consider refactoring to a clearer approach.