mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Merge branch 'GT-2817_emteere_StartPatternAtZero' into Ghidra_9.2
This commit is contained in:
@@ -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 " +
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user