Merge branch 'GT-2817_emteere_StartPatternAtZero' into Ghidra_9.2

This commit is contained in:
ghidra1
2020-11-02 14:52:27 -05:00
4 changed files with 109 additions and 34 deletions

View File

@@ -21,8 +21,7 @@ import ghidra.app.cmd.disassemble.DisassembleCommand;
import ghidra.app.util.PseudoDisassembler;
import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryBlock;
@@ -266,12 +265,11 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand {
boolean isValidFunctionStart(TaskMonitor monitor, Address address) {
// instruction above falls into this one
// could be non-returning function, but we can't tell now
Instruction instructionBefore =
program.getListing().getInstructionContaining(address.subtract(1));
if (instructionBefore != null && address.equals(instructionBefore.getFallThrough())) {
Instruction instrBefore = getInstructionBefore(address);
if (instrBefore != null && address.equals(instrBefore.getFallThrough())) {
return false;
}
// check if part of a larger code-block
ReferenceIterator referencesTo = program.getReferenceManager().getReferencesTo(address);
for (Reference reference : referencesTo) {
@@ -290,6 +288,30 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand {
return true;
}
/**
* Get the instruction directly before this address, makeing sure it is the
* head instruction in a delayslot
*
* @param address to get instruction before
* @return instruction if found, null otherwise
*/
Instruction getInstructionBefore(Address address) {
Address addrBefore = address.previous();
Instruction instrBefore = null;
while (addrBefore != null) {
instrBefore = program.getListing().getInstructionContaining(addrBefore);
if (instrBefore == null) {
break;
}
if (!instrBefore.isInDelaySlot()) {
break;
}
addrBefore = instrBefore.getMinAddress().previous();
}
return instrBefore;
}
private void applyFunction(Symbol sym, FunctionDefinition fdef) {
if (fdef == null) {
Msg.info(this, "Multiple function definitions for " + sym.getName() + " at " +

View File

@@ -304,7 +304,13 @@ public class FrameDescriptionEntry extends GccAnalysisClass {
String comment = "(FDE) PcRange";
intPcRange = (int) GccAnalysisUtils.readDWord(program, addr);
if (intPcRange < 0) {
return null;
}
if (intPcRange == 0) {
intPcRange = 1;
}
pcEndAddr = pcBeginAddr.add(intPcRange - 1);
DataType dataType = getAddressSizeDataType();

View File

@@ -871,9 +871,14 @@ public class DIEAggregate {
// else it was a DW_FORM_data value and is relative to the lowPC value
DWARFNumericAttribute low =
getAttribute(DWARFAttribute.DW_AT_low_pc, DWARFNumericAttribute.class);
if (low != null && highVal.getUnsignedValue() > 0) {
long lhighVal = highVal.getUnsignedValue();
if (lhighVal == 0) {
lhighVal = 1;
}
if (low != null && lhighVal > 0) {
return low.getUnsignedValue() + getProgram().getProgramBaseAddressFixup() +
highVal.getUnsignedValue() - 1;
lhighVal - 1;
}
}
throw new IOException("Bad/unsupported DW_AT_high_pc attribute value or type");

View File

@@ -365,7 +365,11 @@ public class FunctionStartAnalyzer extends AbstractAnalyzer implements PatternFa
// if this place is already in a function, we shouldn't start one
if (name.startsWith("func")) {
if (checkAlreadyInFunctionAbove(program, addr)) {
Function funcAbove = getFunctionAbove(program, addr);
if (funcAbove == null) {
return false;
}
if (checkAlreadyInFunctionAbove(program, addr, funcAbove)) {
return false;
}
}
@@ -402,39 +406,77 @@ public class FunctionStartAnalyzer extends AbstractAnalyzer implements PatternFa
return true;
}
/*
* Check if address if addr is already part of a function just preceding this address.
* If the address is part of another function that is different than the function right
* above, then the pattern should be applied, because it is most likely a unique function
* that is being used by another function as a shared return.
*/
private boolean checkAlreadyInFunctionAbove(Program program, Address addr) {
// make sure there is an end of function before this one, and if just an instruction, doesn't fall into this one.
Function func = null;
Function funcAbove = getFunctionAbove(program, addr);
return checkAlreadyInFunctionAbove(program, addr, funcAbove);
}
/*
* Check if in a function above
* return true if already in function above, false otherwise even if in another function
*/
private boolean checkAlreadyInFunctionAbove(Program program, Address addr, Function funcAbove) {
// if no funcAbove, make sure an instruction, doesn't fall into this one.
Address addrBefore = addr.previous();
func = program.getFunctionManager().getFunctionContaining(addrBefore);
if (func == null) {
Instruction instr = program.getListing().getInstructionContaining(addrBefore);
if (instr != null && addr.equals(instr.getFallThrough())) {
return true;
}
// check for references to this function, address
ReferenceIterator referencesTo =
program.getReferenceManager().getReferencesTo(addr);
for (Reference reference : referencesTo) {
// someone flows to or reads/writes this location, shouldn't be a start
RefType referenceType = reference.getReferenceType();
if (referenceType.isData() &&
!(referenceType.isRead() || referenceType.isWrite())) {
continue;
}
// any other reference to here is bad, since a function or other flow should
// have created the location
return true;
}
if (addrBefore == null) {
return false;
}
// don't do it if I'm in a function
Function myfunc = program.getFunctionManager().getFunctionContaining(addr);
if (myfunc != null && myfunc.getEntryPoint().equals(func.getEntryPoint())) {
if (funcAbove != null) {
// check if in function right above
Function myfunc = program.getFunctionManager().getFunctionContaining(addr);
if (myfunc != null && myfunc.getEntryPoint().equals(funcAbove.getEntryPoint())) {
return true;
}
// I could be in a different function, just not one above
return false;
}
// no function above, but check for references, that would make this a function
// or references that would imply it is part of another function.
Instruction instr = program.getListing().getInstructionContaining(addrBefore);
if (instr != null && addr.equals(instr.getFallThrough())) {
return true;
}
// check for references to this function, address
ReferenceIterator referencesTo =
program.getReferenceManager().getReferencesTo(addr);
for (Reference reference : referencesTo) {
// someone flows to or reads/writes this location, shouldn't be a start
RefType referenceType = reference.getReferenceType();
if (referenceType.isData() &&
!(referenceType.isRead() || referenceType.isWrite())) {
continue;
}
// any other reference to here is bad, since a function or other flow should
// have created the location
return true;
}
return false;
}
/**
* Get an existing function right above the addr.
* @param program program to check
* @param addr address to check
* @return true if there is an existing function above addr
*/
private Function getFunctionAbove(Program program, Address addr) {
// make sure there is an end of function before this one, and addr is not in the function
Function func = null;
Address addrBefore = addr.previous();
if (addrBefore == null) {
return null;
}
func = program.getFunctionManager().getFunctionContaining(addrBefore);
return func;
}
void bookmarkAction(Program program, Address addr, Match match) {
if (setbookmark) {