diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java index 883a5accdf..6bef7bc83e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java @@ -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,15 @@ 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())) { - return false; + Address addrBefore = address.previous(); + if (addrBefore != null) { + Instruction instrBefore; + instrBefore = program.getListing().getInstructionContaining(addrBefore); + 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) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/exceptionhandlers/gcc/structures/ehFrame/FrameDescriptionEntry.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/exceptionhandlers/gcc/structures/ehFrame/FrameDescriptionEntry.java index fb4b3ab504..30ef373b2f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/exceptionhandlers/gcc/structures/ehFrame/FrameDescriptionEntry.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/exceptionhandlers/gcc/structures/ehFrame/FrameDescriptionEntry.java @@ -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(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java index 7a160c2c9f..888e101975 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java @@ -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"); diff --git a/Ghidra/Features/BytePatterns/src/main/java/ghidra/app/analyzers/FunctionStartAnalyzer.java b/Ghidra/Features/BytePatterns/src/main/java/ghidra/app/analyzers/FunctionStartAnalyzer.java index 81e44397fe..858a149ecd 100644 --- a/Ghidra/Features/BytePatterns/src/main/java/ghidra/app/analyzers/FunctionStartAnalyzer.java +++ b/Ghidra/Features/BytePatterns/src/main/java/ghidra/app/analyzers/FunctionStartAnalyzer.java @@ -368,6 +368,9 @@ public class FunctionStartAnalyzer extends AbstractAnalyzer implements PatternFa if (checkAlreadyInFunctionAbove(program, addr)) { return false; } + if (!checkForFunctionAbove(program, addr)) { + return false; + } } else if (name.startsWith("inst")) { // make sure there is an end of function at location to check @@ -402,10 +405,35 @@ public class FunctionStartAnalyzer extends AbstractAnalyzer implements PatternFa return true; } + /** + * Check for an existing function above the addr. Addr should not be in the function. + * @param program prpgram to check in + * @param addr address to check + * @return true if there is an existing function above addr that doesn't contain addr + */ + private boolean checkForFunctionAbove(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(); + func = program.getFunctionManager().getFunctionContaining(addrBefore); + // no function above + if (func == null) { + return false; + } + // addr is in function above + if (func.getBody().contains(addr)) { + return false; + } + return true; + } + 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; Address addrBefore = addr.previous(); + if (addrBefore == null) { + return false; + } func = program.getFunctionManager().getFunctionContaining(addrBefore); if (func == null) { Instruction instr = program.getListing().getInstructionContaining(addrBefore);