mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GT-3330 DWARF address double relocation fixup
DWARF was applying a fixup value to address values in the DWARF data to compensate for the Ghidra base-address being different than the program's requested base address. In binaries (mostly .o files) that contain Elf fixups that reach into the DWARF debug sections and rewrite the address values, the Ghidra importer would handle fixing the address values to point to the non-standard Ghidra base-address, and then the global fixup would be applied to the already correct value, causing it to be incorrect. This change checks to see if any relocations are present in the DWARF debug data and disables its address fixups if found.
This commit is contained in:
parent
76bd653deb
commit
c7cdaaf07a
3 changed files with 47 additions and 18 deletions
|
@ -46,6 +46,17 @@ public class MemoryByteProvider implements ByteProvider {
|
|||
this.baseAddress = baseAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an index into this ByteProvider into an {@link Address}.
|
||||
* <p>
|
||||
*
|
||||
* @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));
|
||||
|
|
|
@ -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<DWARFRange> 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) {
|
||||
|
|
|
@ -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("<anonymous");
|
||||
|
@ -594,7 +616,7 @@ public class DWARFProgram implements Closeable {
|
|||
return debugLocation;
|
||||
}
|
||||
|
||||
public ByteProvider getDebugRanges() {
|
||||
public BinaryReader getDebugRanges() {
|
||||
return debugRanges;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue