diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearFlowAndRepairCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearFlowAndRepairCmd.java index b0c288e9a7..f38a40b6f0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearFlowAndRepairCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearFlowAndRepairCmd.java @@ -213,6 +213,7 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand { } if (repairFunctions) { repairFunctions(program, clearSet, monitor); + monitor.setIndeterminate(false); } return true; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/exceptionhandlers/gcc/GccExceptionAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/exceptionhandlers/gcc/GccExceptionAnalyzer.java index 47f8ef027f..dac4588c0b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/exceptionhandlers/gcc/GccExceptionAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/exceptionhandlers/gcc/GccExceptionAnalyzer.java @@ -147,6 +147,8 @@ public class GccExceptionAnalyzer extends AbstractAnalyzer { // handleArmSections(program, monitor, log); visitedPrograms.add(program); + monitor.setIndeterminate(false); + monitor.setShowProgressValue(true); return true; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MzLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MzLoader.java index 65896e1cd9..a281102a3c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MzLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MzLoader.java @@ -202,22 +202,27 @@ public class MzLoader extends AbstractLibrarySupportLoader { MemoryBlock[] blocks = mem.getBlocks(); for (int i = 1; i < blocks.length; i++) { - if (!blocks[i].isInitialized()) { + MemoryBlock block = blocks[i]; + if (!block.isInitialized()) { continue; } //scan the first 0x10 bytes of this block //if a FAR RETURN exists, then move that code //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 { - Address offAddr = blocks[i].getStart().add(mIndex); - int val = blocks[i].getByte(offAddr); + Address offAddr = block.getStart().add(mIndex); + int val = block.getByte(offAddr); val &= 0xff; if (val == FAR_RETURN_OPCODE) { // split here and join to previous Address splitAddr = offAddr.add(1); - String oldName = blocks[i].getName(); - mem.split(blocks[i], splitAddr); + String oldName = block.getName(); + mem.split(block, splitAddr); mem.join(blocks[i - 1], blocks[i]); blocks = mem.getBlocks(); try { diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc index 1d0064ccf6..f8fb03b541 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc @@ -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) { - PcodeOp *addop; int4 sz = rampoint.getAddrSize(); AddrSpace *spaceid = rampoint.getSpace(); 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 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->updateType(sb_type,true,true); spacebase_vn->setFlags(Varnode::spacebase); - addop = newOp(2,op->getAddr()); - opSetOpcode(addop,CPUI_PTRSUB); - outvn = newUniqueOut(sz,addop); + if (addOp == (PcodeOp *)0) { + addOp = newOp(2,op->getAddr()); + 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 uintb newconstoff = origval - extra; // everything is already in address units newconst = newConstant(sz,newconstoff); newconst->setPtrCheck(); // No longer need to check this constant as a pointer if (spaceid->isTruncated()) - addop->setPtrFlow(); - opSetInput(addop,spacebase_vn,0); - opSetInput(addop,newconst,1); - opInsertBefore(addop,op); + addOp->setPtrFlow(); + opSetInput(addOp,spacebase_vn,0); + opSetInput(addOp,newconst,1); + Symbol *sym = entry->getSymbol(); Datatype *entrytype = sym->getType(); 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; outvn->updateType(ptrentrytype,typelock,true); if (extra != 0) { - PcodeOp *extraop = newOp(2,op->getAddr()); - opSetOpcode(extraop,CPUI_INT_ADD); - Varnode *outvn2 = newUniqueOut(sz,extraop); + if (extraOp == (PcodeOp *)0) { + extraOp = newOp(2,op->getAddr()); + opSetOpcode(extraOp,CPUI_INT_ADD); + newUniqueOut(sz,extraOp); + opInsertBefore(extraOp,op); + } + else + opSetOpcode(extraOp,CPUI_INT_ADD); Varnode *extconst = newConstant(sz,extra); extconst->setPtrCheck(); - opSetInput(extraop,outvn,0); - opSetInput(extraop,extconst,1); - outvn = outvn2; - opInsertBefore(extraop,op); + opSetInput(extraOp,outvn,0); + opSetInput(extraOp,extconst,1); + outvn = extraOp->getOut(); } if (sz < origsize) { // The new constant is smaller than the original varnode, so we extend it - PcodeOp *zextop = newOp(1,op->getAddr()); - Varnode *outvn2 = newUniqueOut(origsize,zextop); - opSetOpcode(zextop,CPUI_INT_ZEXT); // Create an extension to get back to original varnode size - opSetInput(zextop,outvn,0); - opInsertBefore(zextop,op); - outvn = outvn2; + if (zextOp == (PcodeOp *)0) { + zextOp = newOp(1,op->getAddr()); + opSetOpcode(zextOp,CPUI_INT_ZEXT); // Create an extension to get back to original varnode size + newUniqueOut(origsize,zextOp); + opInsertBefore(zextOp,op); + } + 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 - PcodeOp *subOp = newOp(2,op->getAddr()); - Varnode *outvn3 = newUniqueOut(origsize,subOp); - opSetOpcode(subOp,CPUI_SUBPIECE); + if (subOp == (PcodeOp *)0) { + subOp = newOp(2,op->getAddr()); + opSetOpcode(subOp,CPUI_SUBPIECE); + newUniqueOut(origsize,subOp); + opInsertBefore(subOp,op); + } + else + opSetOpcode(subOp,CPUI_SUBPIECE); opSetInput(subOp,outvn,0); opSetInput(subOp,newConstant(4, 0), 1); // Take least significant piece - opInsertBefore(subOp,op); - outvn = outvn3; + outvn = subOp->getOut(); } - opSetInput(op,outvn,slot); + if (!isCopy) + opSetInput(op,outvn,slot); } void Funcdata::clearCallSpecs(void)