mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Merge remote-tracking branch 'origin/caheckman_bugfixes' into Ghidra_9.1
This commit is contained in:
commit
cf0f981c7f
4 changed files with 79 additions and 33 deletions
|
@ -213,6 +213,7 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand {
|
||||||
}
|
}
|
||||||
if (repairFunctions) {
|
if (repairFunctions) {
|
||||||
repairFunctions(program, clearSet, monitor);
|
repairFunctions(program, clearSet, monitor);
|
||||||
|
monitor.setIndeterminate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -147,6 +147,8 @@ public class GccExceptionAnalyzer extends AbstractAnalyzer {
|
||||||
// handleArmSections(program, monitor, log);
|
// handleArmSections(program, monitor, log);
|
||||||
|
|
||||||
visitedPrograms.add(program);
|
visitedPrograms.add(program);
|
||||||
|
monitor.setIndeterminate(false);
|
||||||
|
monitor.setShowProgressValue(true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,22 +202,27 @@ public class MzLoader extends AbstractLibrarySupportLoader {
|
||||||
|
|
||||||
MemoryBlock[] blocks = mem.getBlocks();
|
MemoryBlock[] blocks = mem.getBlocks();
|
||||||
for (int i = 1; i < blocks.length; i++) {
|
for (int i = 1; i < blocks.length; i++) {
|
||||||
if (!blocks[i].isInitialized()) {
|
MemoryBlock block = blocks[i];
|
||||||
|
if (!block.isInitialized()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//scan the first 0x10 bytes of this block
|
//scan the first 0x10 bytes of this block
|
||||||
//if a FAR RETURN exists, then move that code
|
//if a FAR RETURN exists, then move that code
|
||||||
//to the preceding block...
|
//to the preceding block...
|
||||||
for (int mIndex = 15; mIndex >= 0; mIndex--) {
|
int mIndex = 15;
|
||||||
|
if (block.getSize() <= 16) {
|
||||||
|
mIndex = (int) block.getSize() - 2;
|
||||||
|
}
|
||||||
|
for (; mIndex >= 0; mIndex--) {
|
||||||
try {
|
try {
|
||||||
Address offAddr = blocks[i].getStart().add(mIndex);
|
Address offAddr = block.getStart().add(mIndex);
|
||||||
int val = blocks[i].getByte(offAddr);
|
int val = block.getByte(offAddr);
|
||||||
val &= 0xff;
|
val &= 0xff;
|
||||||
if (val == FAR_RETURN_OPCODE) {
|
if (val == FAR_RETURN_OPCODE) {
|
||||||
// split here and join to previous
|
// split here and join to previous
|
||||||
Address splitAddr = offAddr.add(1);
|
Address splitAddr = offAddr.add(1);
|
||||||
String oldName = blocks[i].getName();
|
String oldName = block.getName();
|
||||||
mem.split(blocks[i], splitAddr);
|
mem.split(block, splitAddr);
|
||||||
mem.join(blocks[i - 1], blocks[i]);
|
mem.join(blocks[i - 1], blocks[i]);
|
||||||
blocks = mem.getBlocks();
|
blocks = mem.getBlocks();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -290,7 +290,6 @@ Varnode *Funcdata::findSpacebaseInput(AddrSpace *id) const
|
||||||
void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Address &rampoint,uintb origval,int4 origsize)
|
void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Address &rampoint,uintb origval,int4 origsize)
|
||||||
|
|
||||||
{
|
{
|
||||||
PcodeOp *addop;
|
|
||||||
int4 sz = rampoint.getAddrSize();
|
int4 sz = rampoint.getAddrSize();
|
||||||
AddrSpace *spaceid = rampoint.getSpace();
|
AddrSpace *spaceid = rampoint.getSpace();
|
||||||
Datatype *sb_type = glb->types->getTypeSpacebase(spaceid,Address());
|
Datatype *sb_type = glb->types->getTypeSpacebase(spaceid,Address());
|
||||||
|
@ -300,21 +299,47 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const
|
||||||
uintb extra = rampoint.getOffset() - entry->getAddr().getOffset(); // Offset from beginning of entry
|
uintb extra = rampoint.getOffset() - entry->getAddr().getOffset(); // Offset from beginning of entry
|
||||||
extra = AddrSpace::byteToAddress(extra,rampoint.getSpace()->getWordSize()); // Convert to address units
|
extra = AddrSpace::byteToAddress(extra,rampoint.getSpace()->getWordSize()); // Convert to address units
|
||||||
|
|
||||||
|
PcodeOp *addOp = (PcodeOp *)0;
|
||||||
|
PcodeOp *extraOp = (PcodeOp *)0;
|
||||||
|
PcodeOp *zextOp = (PcodeOp *)0;
|
||||||
|
PcodeOp *subOp = (PcodeOp *)0;
|
||||||
|
bool isCopy = false;
|
||||||
|
if (op->code() == CPUI_COPY) { // We replace COPY with final op of this calculation
|
||||||
|
isCopy = true;
|
||||||
|
if (sz < origsize)
|
||||||
|
zextOp = op;
|
||||||
|
else {
|
||||||
|
op->insertInput(1); // PTRSUB, ADD, SUBPIECE all take 2 parameters
|
||||||
|
if (origsize < sz)
|
||||||
|
subOp = op;
|
||||||
|
else if (extra != 0)
|
||||||
|
extraOp = op;
|
||||||
|
else
|
||||||
|
addOp = op;
|
||||||
|
}
|
||||||
|
}
|
||||||
spacebase_vn = newConstant(sz,0);
|
spacebase_vn = newConstant(sz,0);
|
||||||
spacebase_vn->updateType(sb_type,true,true);
|
spacebase_vn->updateType(sb_type,true,true);
|
||||||
spacebase_vn->setFlags(Varnode::spacebase);
|
spacebase_vn->setFlags(Varnode::spacebase);
|
||||||
addop = newOp(2,op->getAddr());
|
if (addOp == (PcodeOp *)0) {
|
||||||
opSetOpcode(addop,CPUI_PTRSUB);
|
addOp = newOp(2,op->getAddr());
|
||||||
outvn = newUniqueOut(sz,addop);
|
opSetOpcode(addOp,CPUI_PTRSUB);
|
||||||
|
newUniqueOut(sz,addOp);
|
||||||
|
opInsertBefore(addOp,op);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
opSetOpcode(addOp,CPUI_PTRSUB);
|
||||||
|
}
|
||||||
|
outvn = addOp->getOut();
|
||||||
// Make sure newconstant and extra preserve origval in address units
|
// Make sure newconstant and extra preserve origval in address units
|
||||||
uintb newconstoff = origval - extra; // everything is already in address units
|
uintb newconstoff = origval - extra; // everything is already in address units
|
||||||
newconst = newConstant(sz,newconstoff);
|
newconst = newConstant(sz,newconstoff);
|
||||||
newconst->setPtrCheck(); // No longer need to check this constant as a pointer
|
newconst->setPtrCheck(); // No longer need to check this constant as a pointer
|
||||||
if (spaceid->isTruncated())
|
if (spaceid->isTruncated())
|
||||||
addop->setPtrFlow();
|
addOp->setPtrFlow();
|
||||||
opSetInput(addop,spacebase_vn,0);
|
opSetInput(addOp,spacebase_vn,0);
|
||||||
opSetInput(addop,newconst,1);
|
opSetInput(addOp,newconst,1);
|
||||||
opInsertBefore(addop,op);
|
|
||||||
Symbol *sym = entry->getSymbol();
|
Symbol *sym = entry->getSymbol();
|
||||||
Datatype *entrytype = sym->getType();
|
Datatype *entrytype = sym->getType();
|
||||||
Datatype *ptrentrytype = glb->types->getTypePointer(sz,entrytype,spaceid->getWordSize());
|
Datatype *ptrentrytype = glb->types->getTypePointer(sz,entrytype,spaceid->getWordSize());
|
||||||
|
@ -323,34 +348,47 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const
|
||||||
typelock = false;
|
typelock = false;
|
||||||
outvn->updateType(ptrentrytype,typelock,true);
|
outvn->updateType(ptrentrytype,typelock,true);
|
||||||
if (extra != 0) {
|
if (extra != 0) {
|
||||||
PcodeOp *extraop = newOp(2,op->getAddr());
|
if (extraOp == (PcodeOp *)0) {
|
||||||
opSetOpcode(extraop,CPUI_INT_ADD);
|
extraOp = newOp(2,op->getAddr());
|
||||||
Varnode *outvn2 = newUniqueOut(sz,extraop);
|
opSetOpcode(extraOp,CPUI_INT_ADD);
|
||||||
|
newUniqueOut(sz,extraOp);
|
||||||
|
opInsertBefore(extraOp,op);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
opSetOpcode(extraOp,CPUI_INT_ADD);
|
||||||
Varnode *extconst = newConstant(sz,extra);
|
Varnode *extconst = newConstant(sz,extra);
|
||||||
extconst->setPtrCheck();
|
extconst->setPtrCheck();
|
||||||
opSetInput(extraop,outvn,0);
|
opSetInput(extraOp,outvn,0);
|
||||||
opSetInput(extraop,extconst,1);
|
opSetInput(extraOp,extconst,1);
|
||||||
outvn = outvn2;
|
outvn = extraOp->getOut();
|
||||||
opInsertBefore(extraop,op);
|
|
||||||
}
|
}
|
||||||
if (sz < origsize) { // The new constant is smaller than the original varnode, so we extend it
|
if (sz < origsize) { // The new constant is smaller than the original varnode, so we extend it
|
||||||
PcodeOp *zextop = newOp(1,op->getAddr());
|
if (zextOp == (PcodeOp *)0) {
|
||||||
Varnode *outvn2 = newUniqueOut(origsize,zextop);
|
zextOp = newOp(1,op->getAddr());
|
||||||
opSetOpcode(zextop,CPUI_INT_ZEXT); // Create an extension to get back to original varnode size
|
opSetOpcode(zextOp,CPUI_INT_ZEXT); // Create an extension to get back to original varnode size
|
||||||
opSetInput(zextop,outvn,0);
|
newUniqueOut(origsize,zextOp);
|
||||||
opInsertBefore(zextop,op);
|
opInsertBefore(zextOp,op);
|
||||||
outvn = outvn2;
|
}
|
||||||
|
else
|
||||||
|
opSetOpcode(extraOp,CPUI_INT_ZEXT);
|
||||||
|
opSetInput(zextOp,outvn,0);
|
||||||
|
outvn = zextOp->getOut();
|
||||||
}
|
}
|
||||||
else if (origsize < sz) { // The new constant is bigger than the original varnode, truncate it
|
else if (origsize < sz) { // The new constant is bigger than the original varnode, truncate it
|
||||||
PcodeOp *subOp = newOp(2,op->getAddr());
|
if (subOp == (PcodeOp *)0) {
|
||||||
Varnode *outvn3 = newUniqueOut(origsize,subOp);
|
subOp = newOp(2,op->getAddr());
|
||||||
opSetOpcode(subOp,CPUI_SUBPIECE);
|
opSetOpcode(subOp,CPUI_SUBPIECE);
|
||||||
|
newUniqueOut(origsize,subOp);
|
||||||
|
opInsertBefore(subOp,op);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
opSetOpcode(subOp,CPUI_SUBPIECE);
|
||||||
opSetInput(subOp,outvn,0);
|
opSetInput(subOp,outvn,0);
|
||||||
opSetInput(subOp,newConstant(4, 0), 1); // Take least significant piece
|
opSetInput(subOp,newConstant(4, 0), 1); // Take least significant piece
|
||||||
opInsertBefore(subOp,op);
|
outvn = subOp->getOut();
|
||||||
outvn = outvn3;
|
|
||||||
}
|
}
|
||||||
opSetInput(op,outvn,slot);
|
if (!isCopy)
|
||||||
|
opSetInput(op,outvn,slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Funcdata::clearCallSpecs(void)
|
void Funcdata::clearCallSpecs(void)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue