diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/MemoryByteProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/MemoryByteProvider.java index fc43a0592f..ab737e220f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/MemoryByteProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/MemoryByteProvider.java @@ -46,6 +46,17 @@ public class MemoryByteProvider implements ByteProvider { this.baseAddress = baseAddress; } + /** + * Converts an index into this ByteProvider into an {@link Address}. + *

+ * + * @param index absolute index in this ByteProvider to convert into an Address + * @return {@link Address} + */ + public Address getAddress(long index) { + return baseAddress.add(index); + } + @Override public InputStream getInputStream(long index) throws IOException { return new MemoryByteProviderInputStream(memory, baseAddress.add(index)); 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 e1f5e5dd1c..a6eca8c239 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 @@ -21,7 +21,6 @@ import java.util.*; import org.apache.commons.lang3.ArrayUtils; import ghidra.app.util.bin.BinaryReader; -import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.bin.format.dwarf4.attribs.*; import ghidra.app.util.bin.format.dwarf4.encoding.*; import ghidra.app.util.bin.format.dwarf4.expression.*; @@ -804,10 +803,7 @@ public class DIEAggregate { */ public List parseDebugRange(int attribute) throws IOException { byte pointerSize = getCompilationUnit().getPointerSize(); - boolean isLittleEndian = getCompilationUnit().getProgram().isLittleEndian(); - - ByteProvider debug_ranges = getCompilationUnit().getProgram().getDebugRanges(); - BinaryReader reader = new BinaryReader(debug_ranges, isLittleEndian); + BinaryReader reader = getCompilationUnit().getProgram().getDebugRanges(); long offset = getUnsignedLong(attribute, -1); if (offset == -1) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFProgram.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFProgram.java index bd43b25aed..a6cbd19b48 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFProgram.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFProgram.java @@ -22,8 +22,7 @@ import java.util.*; import org.apache.commons.collections4.ListValuedMap; import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; -import ghidra.app.util.bin.BinaryReader; -import ghidra.app.util.bin.ByteProvider; +import ghidra.app.util.bin.*; import ghidra.app.util.bin.format.dwarf4.*; import ghidra.app.util.bin.format.dwarf4.attribs.DWARFAttributeFactory; import ghidra.app.util.bin.format.dwarf4.encoding.*; @@ -31,6 +30,8 @@ import ghidra.app.util.bin.format.dwarf4.expression.DWARFExpressionException; import ghidra.app.util.bin.format.dwarf4.next.sectionprovider.*; import ghidra.app.util.opinion.ElfLoader; import ghidra.app.util.opinion.MachoLoader; +import ghidra.program.model.address.Address; +import ghidra.program.model.address.AddressSet; import ghidra.program.model.data.CategoryPath; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.SymbolUtilities; @@ -108,7 +109,7 @@ public class DWARFProgram implements Closeable { new HashMap<>(); private BinaryReader debugLocation; - private ByteProvider debugRanges; + private BinaryReader debugRanges; private BinaryReader debugInfoBR; private BinaryReader debugLineBR; private BinaryReader debugAbbrBR; @@ -185,10 +186,7 @@ public class DWARFProgram implements Closeable { this.importOptions = importOptions; this.nameLengthCutoffSize = Math.max(MIN_NAME_LENGTH_CUTOFF, Math.min(importOptions.getNameLengthCutoff(), MAX_NAME_LENGTH_CUTOFF)); - Long oib = ElfLoader.getElfOriginalImageBase(program); - if (oib != null && oib.longValue() != program.getImageBase().getOffset()) { - this.programBaseAddressFixup = program.getImageBase().getOffset() - oib.longValue(); - } + monitor.setMessage("Reading DWARF debug string table"); this.debugStrings = StringTable.readStringTable( @@ -201,7 +199,17 @@ public class DWARFProgram implements Closeable { this.debugInfoBR = getBinaryReaderFor(DWARFSectionNames.DEBUG_INFO); this.debugLineBR = getBinaryReaderFor(DWARFSectionNames.DEBUG_LINE); this.debugAbbrBR = getBinaryReaderFor(DWARFSectionNames.DEBUG_ABBREV); - this.debugRanges = sectionProvider.getSectionAsByteProvider(DWARFSectionNames.DEBUG_RANGES); + this.debugRanges = getBinaryReaderFor(DWARFSectionNames.DEBUG_RANGES);// sectionProvider.getSectionAsByteProvider(DWARFSectionNames.DEBUG_RANGES); + + // if there are relocations (already handled by the ghidra loader) anywhere in the debuginfo or debugrange sections, then + // we don't need to manually fix up addresses extracted from DWARF data. + boolean hasRelocations = hasRelocations(debugInfoBR) || hasRelocations(debugRanges); + if (!hasRelocations) { + Long oib = ElfLoader.getElfOriginalImageBase(program); + if (oib != null && oib.longValue() != program.getImageBase().getOffset()) { + this.programBaseAddressFixup = program.getImageBase().getOffset() - oib.longValue(); + } + } dwarfRegisterMappings = DWARFRegisterMappingsManager.hasDWARFRegisterMapping(program.getLanguage()) @@ -219,10 +227,7 @@ public class DWARFProgram implements Closeable { debugInfoBR = null; debugLineBR = null; debugLocation = null; - if (debugRanges != null) { - debugRanges.close(); - debugRanges = null; - } + debugRanges = null; debugStrings.clear(); dniCache.clear(); clearDIEIndexes(); @@ -249,6 +254,23 @@ public class DWARFProgram implements Closeable { return (bp != null) ? new BinaryReader(bp, !isBigEndian()) : null; } + private boolean hasRelocations(BinaryReader br) throws IOException { + if (br == null) { + return false; + } + ByteProvider bp = br.getByteProvider(); + if (bp instanceof MemoryByteProvider && bp.length() > 0) { + MemoryByteProvider mbp = (MemoryByteProvider) bp; + Address startAddr = mbp.getAddress(0); + Address endAddr = mbp.getAddress(mbp.length() - 1); + if (program.getRelocationTable().getRelocations( + new AddressSet(startAddr, endAddr)).hasNext()) { + return true; + } + } + return false; + } + //------------------------------------------------------------------------- private static boolean isAnonDWARFName(String name) { return (name == null) || name.startsWith("._") || name.startsWith("