mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-22 10:02:49 +08:00
GP-5977 refactor DWARF DIE serialization into its own class
This will allow reading DIEs from multiple files.
This commit is contained in:
@@ -21,7 +21,6 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.*;
|
||||
import ghidra.app.util.bin.format.dwarf.line.DWARFLine.SourceFileAddr;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionProvider;
|
||||
@@ -42,25 +41,23 @@ public class DWARFLineInfoCommentScript extends GhidraScript {
|
||||
}
|
||||
|
||||
DWARFImportOptions importOptions = new DWARFImportOptions();
|
||||
try (DWARFProgram dprog = new DWARFProgram(currentProgram, importOptions, monitor, dsp)) {
|
||||
try (DWARFProgram dprog = new DWARFProgram(currentProgram, importOptions, dsp)) {
|
||||
dprog.init(monitor);
|
||||
addSourceLineInfo(dprog);
|
||||
}
|
||||
}
|
||||
|
||||
private void addSourceLineInfo(DWARFProgram dprog) throws CancelledException, IOException {
|
||||
BinaryReader reader = dprog.getDebugLineBR();
|
||||
if (reader == null) {
|
||||
if (!dprog.getDIEContainer().hasLineInfo()) {
|
||||
return;
|
||||
}
|
||||
int count = 0;
|
||||
monitor.initialize(reader.length(), "DWARF Source Line Info");
|
||||
List<DWARFCompilationUnit> compUnits = dprog.getCompilationUnits();
|
||||
for (DWARFCompilationUnit cu : compUnits) {
|
||||
monitor.initialize(dprog.getDIEContainer().getLineDataSize(), "DWARF Source Line Info");
|
||||
for (DWARFCompilationUnit cu : dprog.getDIEContainer().getCompilationUnits()) {
|
||||
try {
|
||||
monitor.checkCancelled();
|
||||
monitor.setProgress(cu.getLine().getStartOffset());
|
||||
List<SourceFileAddr> allSFA = cu.getLine().getAllSourceFileAddrInfo(cu, reader);
|
||||
List<SourceFileAddr> allSFA = cu.getLine().getAllSourceFileAddrInfo(cu);
|
||||
for (SourceFileAddr sfa : allSFA) {
|
||||
Address addr = dprog.getCodeAddress(sfa.address());
|
||||
DWARFUtil.appendComment(currentProgram, addr, CommentType.EOL, "",
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.*;
|
||||
import ghidra.app.util.bin.format.dwarf.external.*;
|
||||
import ghidra.app.util.bin.format.dwarf.line.DWARFLine;
|
||||
@@ -65,7 +64,7 @@ public class DWARFLineInfoSourceMapScript extends GhidraScript {
|
||||
}
|
||||
|
||||
DWARFImportOptions importOptions = new DWARFImportOptions();
|
||||
try (DWARFProgram dprog = new DWARFProgram(currentProgram, importOptions, monitor, dsp)) {
|
||||
try (DWARFProgram dprog = new DWARFProgram(currentProgram, importOptions, dsp)) {
|
||||
dprog.init(monitor);
|
||||
addSourceLineInfo(dprog);
|
||||
}
|
||||
@@ -73,8 +72,7 @@ public class DWARFLineInfoSourceMapScript extends GhidraScript {
|
||||
|
||||
private void addSourceLineInfo(DWARFProgram dprog)
|
||||
throws CancelledException, IOException, LockException, AddressOverflowException {
|
||||
BinaryReader reader = dprog.getDebugLineBR();
|
||||
if (reader == null) {
|
||||
if (!dprog.getDIEContainer().hasLineInfo()) {
|
||||
popup("Unable to get reader for debug line info");
|
||||
return;
|
||||
}
|
||||
@@ -127,7 +125,7 @@ public class DWARFLineInfoSourceMapScript extends GhidraScript {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
sourceInfo.addAll(cu.getLine().getAllSourceFileAddrInfo(cu, reader));
|
||||
sourceInfo.addAll(cu.getLine().getAllSourceFileAddrInfo(cu));
|
||||
}
|
||||
|
||||
monitor.setIndeterminate(true);
|
||||
|
||||
@@ -37,8 +37,7 @@ public class DWARFMacroScript extends GhidraScript {
|
||||
return;
|
||||
}
|
||||
|
||||
try (DWARFProgram dprog =
|
||||
new DWARFProgram(currentProgram, new DWARFImportOptions(), monitor, dsp)) {
|
||||
try (DWARFProgram dprog = new DWARFProgram(currentProgram, new DWARFImportOptions(), dsp)) {
|
||||
dprog.init(monitor);
|
||||
for (DWARFCompilationUnit cu : dprog.getCompilationUnits()) {
|
||||
dumpMacros(cu.getMacros(), 0);
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ public class DWARFAnalyzer extends AbstractAnalyzer {
|
||||
extDFSI.importSymbols(log);
|
||||
}
|
||||
|
||||
try (DWARFProgram prog = new DWARFProgram(program, importOptions, monitor, dsp)) {
|
||||
try (DWARFProgram prog = new DWARFProgram(program, importOptions, dsp)) {
|
||||
if (prog.getRegisterMappings() == null && importOptions.isImportFuncs()) {
|
||||
log.appendMsg("No DWARF to Ghidra register mappings found for this program's " +
|
||||
"language [%s], function information may be incorrect / incomplete."
|
||||
|
||||
@@ -201,9 +201,8 @@ public class BinaryReader {
|
||||
* Returns the length of the underlying file.
|
||||
*
|
||||
* @return returns the length of the underlying file
|
||||
* @exception IOException if an I/O error occurs
|
||||
*/
|
||||
public long length() throws IOException {
|
||||
public long length() {
|
||||
return provider.length();
|
||||
}
|
||||
|
||||
|
||||
+18
-11
@@ -231,6 +231,13 @@ public class DIEAggregate {
|
||||
return getHeadFragment().getProgram();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the program's single {@link DIEContainer}}
|
||||
*/
|
||||
public DIEContainer getDIEContainer() {
|
||||
return getProgram().getDIEContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last {@link DebugInfoEntry DIE} fragment, ie. the decl DIE.
|
||||
* @return last DIE of this aggregate
|
||||
@@ -251,13 +258,13 @@ public class DIEAggregate {
|
||||
public DIEAggregate getDeclParent() {
|
||||
DebugInfoEntry declDIE = getLastFragment();
|
||||
DebugInfoEntry declParent = declDIE.getParent();
|
||||
return getProgram().getAggregate(declParent);
|
||||
return getDIEContainer().getAggregate(declParent);
|
||||
}
|
||||
|
||||
public DIEAggregate getParent() {
|
||||
DebugInfoEntry die = getHeadFragment();
|
||||
DebugInfoEntry parent = die.getParent();
|
||||
return getProgram().getAggregate(parent);
|
||||
return getDIEContainer().getAggregate(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,7 +281,7 @@ public class DIEAggregate {
|
||||
* that this instance was already the root of the compUnit
|
||||
*/
|
||||
public int getDepth() {
|
||||
return getProgram().getParentDepth(getHeadFragment().getIndex());
|
||||
return getHeadFragment().getDepth();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,7 +301,7 @@ public class DIEAggregate {
|
||||
return attributeValue;
|
||||
}
|
||||
for (DebugInfoEntry childDIE : getChildren(childTag)) {
|
||||
DIEAggregate childDIEA = getProgram().getAggregate(childDIE);
|
||||
DIEAggregate childDIEA = getDIEContainer().getAggregate(childDIE);
|
||||
attributeValue = childDIEA.findValue(attrId, clazz);
|
||||
if (attributeValue != null) {
|
||||
return attributeValue;
|
||||
@@ -428,7 +435,7 @@ public class DIEAggregate {
|
||||
}
|
||||
|
||||
try {
|
||||
return getProgram().getDIE(foundAttr.getAttributeForm(), val.getUnsignedValue(),
|
||||
return getDIEContainer().getDIE(foundAttr.getAttributeForm(), val.getUnsignedValue(),
|
||||
foundAttr.getDIE().getCompilationUnit());
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -449,7 +456,7 @@ public class DIEAggregate {
|
||||
*/
|
||||
public DIEAggregate getRef(DWARFAttributeId attrId) {
|
||||
DebugInfoEntry die = getRefDIE(attrId);
|
||||
return getProgram().getAggregate(die);
|
||||
return getDIEContainer().getAggregate(die);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -650,7 +657,7 @@ public class DIEAggregate {
|
||||
* @throws IOException if error reading data
|
||||
*/
|
||||
public DWARFLocationList getLocationList(DWARFAttributeId attrId) throws IOException {
|
||||
return getProgram().getLocationList(this, attrId);
|
||||
return getDIEContainer().getLocationList(this, attrId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -708,7 +715,7 @@ public class DIEAggregate {
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public DWARFRangeList getRangeList(DWARFAttributeId attrId) throws IOException {
|
||||
return getProgram().getRangeList(this, attrId);
|
||||
return getDIEContainer().getRangeList(this, attrId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -723,7 +730,7 @@ public class DIEAggregate {
|
||||
try {
|
||||
// TODO: previous code excluded lowPc values that were == 0 as invalid.
|
||||
long rawLowPc = lowPcAttrVal.getUnsignedValue();
|
||||
long lowPcOffset = getProgram().getAddress(lowPc.getAttributeForm(), rawLowPc,
|
||||
long lowPcOffset = getDIEContainer().getAddress(lowPc.getAttributeForm(), rawLowPc,
|
||||
getCompilationUnit());
|
||||
long highPcOffset = lowPcOffset;
|
||||
|
||||
@@ -758,7 +765,7 @@ public class DIEAggregate {
|
||||
// build list of params, as seen by the function's DIEA
|
||||
List<DIEAggregate> params = new ArrayList<>();
|
||||
for (DebugInfoEntry paramDIE : getChildren(DW_TAG_formal_parameter)) {
|
||||
DIEAggregate paramDIEA = getProgram().getAggregate(paramDIE);
|
||||
DIEAggregate paramDIEA = getDIEContainer().getAggregate(paramDIE);
|
||||
params.add(paramDIEA);
|
||||
}
|
||||
|
||||
@@ -777,7 +784,7 @@ public class DIEAggregate {
|
||||
}
|
||||
else {
|
||||
// add generic (abstract) definition of the param to the list
|
||||
newParams.add(getProgram().getAggregate(paramDIE));
|
||||
newParams.add(getDIEContainer().getAggregate(paramDIE));
|
||||
}
|
||||
}
|
||||
if (!params.isEmpty()) {
|
||||
|
||||
+1097
File diff suppressed because it is too large
Load Diff
+6
-15
@@ -23,8 +23,6 @@ import ghidra.app.util.bin.format.dwarf.attribs.*;
|
||||
import ghidra.app.util.bin.format.dwarf.attribs.DWARFAttributeId.AttrDef;
|
||||
import ghidra.program.model.data.LEB128;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents the 'schema' for a DWARF DIE record.
|
||||
@@ -45,14 +43,12 @@ public class DWARFAbbreviation {
|
||||
* Reads a {@link DWARFAbbreviation} from the stream.
|
||||
*
|
||||
* @param reader {@link BinaryReader} stream
|
||||
* @param prog {@link DWARFProgram}
|
||||
* @param monitor {@link TaskMonitor}
|
||||
* @param dieContainer {@link DIEContainer}
|
||||
* @return {@link DWARFAbbreviation}, or null if the stream was at a end-of-list marker
|
||||
* @throws IOException if error reading
|
||||
* @throws CancelledException if canceled
|
||||
*/
|
||||
public static DWARFAbbreviation read(BinaryReader reader, DWARFProgram prog,
|
||||
TaskMonitor monitor) throws IOException, CancelledException {
|
||||
public static DWARFAbbreviation read(BinaryReader reader, DIEContainer dieContainer)
|
||||
throws IOException {
|
||||
|
||||
int ac = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
if (ac == EOL) {
|
||||
@@ -65,8 +61,6 @@ public class DWARFAbbreviation {
|
||||
List<AttrDef> tmpAttrSpecs = new ArrayList<>();
|
||||
AttrDef attrSpec;
|
||||
while ((attrSpec = AttrDef.read(reader)) != null) {
|
||||
monitor.checkCancelled();
|
||||
attrSpec = prog.internAttributeSpec(attrSpec);
|
||||
tmpAttrSpecs.add(attrSpec);
|
||||
warnIfMismatchedForms(attrSpec);
|
||||
}
|
||||
@@ -99,20 +93,17 @@ public class DWARFAbbreviation {
|
||||
* encountered.
|
||||
*
|
||||
* @param reader {@link BinaryReader} .debug_abbr stream
|
||||
* @param prog {@link DWARFProgram}
|
||||
* @param monitor {@link TaskMonitor}
|
||||
* @param dieContainer {@link DIEContainer}
|
||||
* @return map of abbrCode -> abbr instance
|
||||
* @throws IOException if error reading
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
public static Map<Integer, DWARFAbbreviation> readAbbreviations(BinaryReader reader,
|
||||
DWARFProgram prog, TaskMonitor monitor) throws IOException, CancelledException {
|
||||
DIEContainer dieContainer) throws IOException {
|
||||
Map<Integer, DWARFAbbreviation> result = new HashMap<>();
|
||||
|
||||
// Read a list of abbreviations, terminated by a marker value that returns null from read()
|
||||
DWARFAbbreviation abbrev = null;
|
||||
while ((abbrev = DWARFAbbreviation.read(reader, prog, monitor)) != null) {
|
||||
monitor.checkCancelled();
|
||||
while ((abbrev = DWARFAbbreviation.read(reader, dieContainer)) != null) {
|
||||
result.put(abbrev.getAbbreviationCode(), abbrev);
|
||||
}
|
||||
|
||||
|
||||
+18
-33
@@ -24,8 +24,6 @@ import java.util.Map;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.line.DWARFLine;
|
||||
import ghidra.app.util.bin.format.dwarf.macro.DWARFMacroHeader;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* A DWARF CompilationUnit is a contiguous block of {@link DebugInfoEntry DIE} records found
|
||||
@@ -39,8 +37,7 @@ import ghidra.util.task.TaskMonitor;
|
||||
public class DWARFCompilationUnit extends DWARFUnitHeader {
|
||||
/**
|
||||
* Creates a new {@link DWARFCompilationUnit} by reading a compilationUnit's header data
|
||||
* from the debug_info section and the debug_abbr section and its compileUnit DIE (ie.
|
||||
* the first DIE right after the header).
|
||||
* from the debug_info section.
|
||||
* <p>
|
||||
* Returns {@code NULL} if there was an ignorable error while reading the compilation unit (and
|
||||
* leaves the input stream at the next compilation unit to read), otherwise throws
|
||||
@@ -51,17 +48,13 @@ public class DWARFCompilationUnit extends DWARFUnitHeader {
|
||||
*
|
||||
* @param partial already read partial unit header
|
||||
* @param reader .debug_info BinaryReader
|
||||
* @param abbrReader .debug_abbr BinaryReader
|
||||
* @param monitor the current task monitor
|
||||
* @return the read compilation unit, or null if the compilation unit was bad/empty and should
|
||||
* be ignored
|
||||
* @throws DWARFException if an invalid or unsupported DWARF version is read.
|
||||
* @throws IOException if the length of the compilation unit is invalid.
|
||||
* @throws CancelledException if the task has been canceled.
|
||||
*/
|
||||
public static DWARFCompilationUnit readV4(DWARFUnitHeader partial, BinaryReader reader,
|
||||
BinaryReader abbrReader, TaskMonitor monitor)
|
||||
throws DWARFException, IOException, CancelledException {
|
||||
public static DWARFCompilationUnit readV4(DWARFUnitHeader partial, BinaryReader reader)
|
||||
throws DWARFException, IOException {
|
||||
|
||||
long abbreviationOffset = reader.readNextUnsignedValue(partial.getIntSize());
|
||||
byte pointerSize = reader.readNextByte();
|
||||
@@ -76,19 +69,17 @@ public class DWARFCompilationUnit extends DWARFUnitHeader {
|
||||
return null;
|
||||
}
|
||||
|
||||
abbrReader.setPointerIndex(abbreviationOffset);
|
||||
Map<Integer, DWARFAbbreviation> abbrMap =
|
||||
DWARFAbbreviation.readAbbreviations(abbrReader, partial.dprog, monitor);
|
||||
Map<Integer, DWARFAbbreviation> abbrevs =
|
||||
partial.getDIEContainer().getAbbrevs(abbreviationOffset);
|
||||
|
||||
DWARFCompilationUnit cu =
|
||||
new DWARFCompilationUnit(partial, pointerSize, firstDIEOffset, abbrMap);
|
||||
new DWARFCompilationUnit(partial, pointerSize, firstDIEOffset, abbrevs);
|
||||
return cu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DWARFCompilationUnit} by reading a compilationUnit's header data
|
||||
* from the debug_info section and the debug_abbr section and its compileUnit DIE (ie.
|
||||
* the first DIE right after the header).
|
||||
* from the debug_info section.
|
||||
* <p>
|
||||
* Returns {@code NULL} if there was an ignorable error while reading the compilation unit (and
|
||||
* leaves the input stream at the next compilation unit to read), otherwise throws
|
||||
@@ -99,17 +90,13 @@ public class DWARFCompilationUnit extends DWARFUnitHeader {
|
||||
*
|
||||
* @param partial already read partial unit header
|
||||
* @param reader .debug_info BinaryReader
|
||||
* @param abbrReader .debug_abbr BinaryReader
|
||||
* @param monitor the current task monitor
|
||||
* @return the read compilation unit, or null if the compilation unit was bad/empty and should
|
||||
* be ignored
|
||||
* @throws DWARFException if an invalid or unsupported DWARF version is read.
|
||||
* @throws IOException if the length of the compilation unit is invalid.
|
||||
* @throws CancelledException if the task has been canceled.
|
||||
*/
|
||||
public static DWARFCompilationUnit readV5(DWARFUnitHeader partial, BinaryReader reader,
|
||||
BinaryReader abbrReader, TaskMonitor monitor)
|
||||
throws DWARFException, IOException, CancelledException {
|
||||
public static DWARFCompilationUnit readV5(DWARFUnitHeader partial, BinaryReader reader)
|
||||
throws DWARFException, IOException {
|
||||
|
||||
byte pointerSize = reader.readNextByte();
|
||||
long abbreviationOffset = reader.readNextUnsignedValue(partial.getIntSize());
|
||||
@@ -125,12 +112,10 @@ public class DWARFCompilationUnit extends DWARFUnitHeader {
|
||||
return null;
|
||||
}
|
||||
|
||||
abbrReader.setPointerIndex(abbreviationOffset);
|
||||
Map<Integer, DWARFAbbreviation> abbrMap =
|
||||
DWARFAbbreviation.readAbbreviations(abbrReader, partial.dprog, monitor);
|
||||
|
||||
Map<Integer, DWARFAbbreviation> abbrevs =
|
||||
partial.getDIEContainer().getAbbrevs(abbreviationOffset);
|
||||
DWARFCompilationUnit cu =
|
||||
new DWARFCompilationUnit(partial, pointerSize, firstDIEOffset, abbrMap);
|
||||
new DWARFCompilationUnit(partial, pointerSize, firstDIEOffset, abbrevs);
|
||||
return cu;
|
||||
}
|
||||
|
||||
@@ -168,20 +153,20 @@ public class DWARFCompilationUnit extends DWARFUnitHeader {
|
||||
/**
|
||||
* This ctor is public only for junit tests. Do not use directly.
|
||||
*
|
||||
* @param dwarfProgram {@link DWARFProgram}
|
||||
* @param dieContainer holds all DIE records and related serialization info
|
||||
* @param startOffset offset in provider where it starts
|
||||
* @param endOffset offset in provider where it ends
|
||||
* @param intSize 4 (DWARF_32) or 8 (DWARF_64)
|
||||
* @param dwarfVersion 2-5
|
||||
* @param pointerSize default size of pointers
|
||||
* @param unitNumber this compunits ordinal in the file
|
||||
* @param unitNumber this compunit's ordinal in the file
|
||||
* @param firstDIEOffset start of DIEs in the provider
|
||||
* @param codeToAbbreviationMap map of abbreviation numbers to {@link DWARFAbbreviation} instances
|
||||
*/
|
||||
public DWARFCompilationUnit(DWARFProgram dwarfProgram, long startOffset, long endOffset,
|
||||
public DWARFCompilationUnit(DIEContainer dieContainer, long startOffset, long endOffset,
|
||||
int intSize, short dwarfVersion, byte pointerSize, int unitNumber,
|
||||
long firstDIEOffset, Map<Integer, DWARFAbbreviation> codeToAbbreviationMap) {
|
||||
super(dwarfProgram, startOffset, endOffset, intSize, dwarfVersion, unitNumber);
|
||||
super(dieContainer, startOffset, endOffset, intSize, dwarfVersion, unitNumber);
|
||||
this.pointerSize = pointerSize;
|
||||
this.firstDIEOffset = firstDIEOffset;
|
||||
this.codeToAbbreviationMap =
|
||||
@@ -197,7 +182,7 @@ public class DWARFCompilationUnit extends DWARFUnitHeader {
|
||||
*/
|
||||
public void init(DebugInfoEntry rootDIE) throws IOException {
|
||||
diea = DIEAggregate.createSingle(rootDIE);
|
||||
line = getProgram().getLine(diea, DW_AT_stmt_list);
|
||||
line = getDIEContainer().getLine(diea, DW_AT_stmt_list);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,7 +222,7 @@ public class DWARFCompilationUnit extends DWARFUnitHeader {
|
||||
public DWARFMacroHeader getMacros() {
|
||||
long macrosOffset = diea.getUnsignedLong(DW_AT_macros, -1);
|
||||
return macrosOffset != -1
|
||||
? diea.getProgram().getMacroHeader(macrosOffset, this)
|
||||
? getDIEContainer().getMacroHeader(macrosOffset, this)
|
||||
: DWARFMacroHeader.EMTPY;
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -467,7 +467,7 @@ public class DWARFDataTypeImporter {
|
||||
// NOTE: gcc tends to emit values without an explicit signedness. The caller
|
||||
// can specify a default signedness, but this should probably always be unsigned.
|
||||
for (DebugInfoEntry childEntry : diea.getChildren(DW_TAG_enumerator)) {
|
||||
DIEAggregate childDIEA = prog.getAggregate(childEntry);
|
||||
DIEAggregate childDIEA = prog.getDIEContainer().getAggregate(childEntry);
|
||||
String valueName = childDIEA.getName();
|
||||
|
||||
DWARFNumericAttribute enumValAttr = childDIEA
|
||||
@@ -642,7 +642,7 @@ public class DWARFDataTypeImporter {
|
||||
|
||||
UnionDataType union = (UnionDataType) ddt.dataType;
|
||||
for (DebugInfoEntry childEntry : diea.getChildren(DW_TAG_member)) {
|
||||
DIEAggregate childDIEA = prog.getAggregate(childEntry);
|
||||
DIEAggregate childDIEA = prog.getDIEContainer().getAggregate(childEntry);
|
||||
|
||||
// skip static member vars as they do not have storage in the structure
|
||||
// C does not allow static member vars in unions
|
||||
@@ -836,7 +836,7 @@ public class DWARFDataTypeImporter {
|
||||
|
||||
for (DebugInfoEntry childEntry : diea.getChildren(childTagType)) {
|
||||
|
||||
DIEAggregate childDIEA = prog.getAggregate(childEntry);
|
||||
DIEAggregate childDIEA = prog.getDIEContainer().getAggregate(childEntry);
|
||||
// skip static member vars as they do not have storage in the structure
|
||||
if (childDIEA.hasAttribute(DW_AT_external)) {
|
||||
continue;
|
||||
@@ -1099,7 +1099,8 @@ public class DWARFDataTypeImporter {
|
||||
List<Integer> dimensions = new ArrayList<>();
|
||||
List<DebugInfoEntry> subrangeDIEs = diea.getChildren(DW_TAG_subrange_type);
|
||||
for (int subRangeDIEIndex = 0; subRangeDIEIndex < subrangeDIEs.size(); subRangeDIEIndex++) {
|
||||
DIEAggregate subrangeAggr = prog.getAggregate(subrangeDIEs.get(subRangeDIEIndex));
|
||||
DIEAggregate subrangeAggr =
|
||||
prog.getDIEContainer().getAggregate(subrangeDIEs.get(subRangeDIEIndex));
|
||||
long numElements = -1;
|
||||
try {
|
||||
if (subrangeAggr.hasAttribute(DW_AT_count)) {
|
||||
|
||||
+1
-1
@@ -331,7 +331,7 @@ public class DWARFFunctionImporter {
|
||||
// offsetFromFuncStart will be -1 if the containing block didn't have location info
|
||||
|
||||
for (DebugInfoEntry childEntry : diea.getHeadFragment().getChildren()) {
|
||||
DIEAggregate childDIEA = prog.getAggregate(childEntry);
|
||||
DIEAggregate childDIEA = prog.getDIEContainer().getAggregate(childEntry);
|
||||
|
||||
switch (childDIEA.getTag()) {
|
||||
case DW_TAG_variable: {
|
||||
|
||||
+6
-14
@@ -21,7 +21,6 @@ import java.util.*;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import ghidra.app.plugin.core.datamgr.util.DataTypeUtils;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.DWARFImportOptions.MacroEnumSetting;
|
||||
import ghidra.app.util.bin.format.dwarf.line.DWARFLine;
|
||||
import ghidra.app.util.bin.format.dwarf.line.DWARFLine.SourceFileAddr;
|
||||
@@ -39,7 +38,6 @@ import ghidra.program.model.sourcemap.SourceFileManager;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import utility.function.Dummy;
|
||||
|
||||
/**
|
||||
* Performs a DWARF datatype import and a DWARF function import, under the control of the
|
||||
@@ -102,7 +100,7 @@ public class DWARFImporter {
|
||||
|
||||
if ((monitor.getProgress() % 5) == 0) {
|
||||
/* balance between getting work done and pampering the swing thread */
|
||||
Swing.runNow(Dummy.runnable());
|
||||
Swing.allowSwingToProcessEvents();
|
||||
}
|
||||
|
||||
DataType dataType =
|
||||
@@ -199,17 +197,11 @@ public class DWARFImporter {
|
||||
* "." and "/../" entries stripped and then be placed under artificial directories based on
|
||||
* {@code DEFAULT_COMPILATION_DIR}.
|
||||
*
|
||||
* @param reader reader
|
||||
* @throws CancelledException if cancelled by user
|
||||
* @throws IOException if error during reading
|
||||
* @throws LockException if invoked without exclusive access
|
||||
*/
|
||||
private void addSourceLineInfo(BinaryReader reader)
|
||||
throws CancelledException, IOException, LockException {
|
||||
if (reader == null) {
|
||||
Msg.warn(this, "Can't add source line info - reader is null");
|
||||
return;
|
||||
}
|
||||
private void addSourceLineInfo() throws CancelledException, IOException, LockException {
|
||||
int entryCount = 0;
|
||||
Program ghidraProgram = prog.getGhidraProgram();
|
||||
long maxLength = prog.getImportOptions().getMaxSourceMapEntryLength();
|
||||
@@ -223,7 +215,7 @@ public class DWARFImporter {
|
||||
List<SourceFileAddr> sourceInfo = new ArrayList<>();
|
||||
for (DWARFCompilationUnit cu : compUnits) {
|
||||
DWARFLine dLine = cu.getLine();
|
||||
monitor.increment(1);
|
||||
monitor.increment();
|
||||
for (SourceFileInfo sfi : dLine.getAllSourceFileInfos()) {
|
||||
if (sourceFileInfoToSourceFile.containsKey(sfi)) {
|
||||
continue;
|
||||
@@ -249,7 +241,7 @@ public class DWARFImporter {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
sourceInfo.addAll(cu.getLine().getAllSourceFileAddrInfo(cu, reader));
|
||||
sourceInfo.addAll(cu.getLine().getAllSourceFileAddrInfo(cu));
|
||||
}
|
||||
|
||||
int sourceInfoSize = sourceInfo.size();
|
||||
@@ -263,7 +255,7 @@ public class DWARFImporter {
|
||||
|
||||
AddressSet warnedAddresses = new AddressSet();
|
||||
for (int i = 0; i < sourceInfo.size(); i++) {
|
||||
monitor.increment(1);
|
||||
monitor.increment();
|
||||
SourceFileAddr sfa = sourceInfo.get(i);
|
||||
if (SOURCEFILENAMES_IGNORE.contains(sfa.fileName()) ||
|
||||
SOURCEFILENAMES_IGNORE.contains(FilenameUtils.getName(sfa.fileName())) ||
|
||||
@@ -424,7 +416,7 @@ public class DWARFImporter {
|
||||
}
|
||||
else {
|
||||
try {
|
||||
addSourceLineInfo(prog.getDebugLineBR());
|
||||
addSourceLineInfo();
|
||||
}
|
||||
catch (LockException e) {
|
||||
throw new AssertException("LockException after exclusive access verified");
|
||||
|
||||
+5
-5
@@ -102,7 +102,7 @@ public class DWARFLocationList {
|
||||
public static DWARFLocationList readV5(BinaryReader reader, DWARFCompilationUnit cu)
|
||||
throws IOException {
|
||||
long baseAddr = cu.getPCRange().getFrom();
|
||||
DWARFProgram dprog = cu.getProgram();
|
||||
DIEContainer dieContainer = cu.getDIEContainer();
|
||||
|
||||
List<DWARFLocation> list = new ArrayList<>();
|
||||
while (reader.hasNext()) {
|
||||
@@ -113,15 +113,15 @@ public class DWARFLocationList {
|
||||
switch (lleId) {
|
||||
case DW_LLE_base_addressx: {
|
||||
int addrIndex = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
baseAddr = dprog.getAddress(DW_FORM_addrx, addrIndex, cu);
|
||||
baseAddr = dieContainer.getAddress(DW_FORM_addrx, addrIndex, cu);
|
||||
break;
|
||||
}
|
||||
case DW_LLE_startx_endx: {
|
||||
int startAddrIndex = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
int endAddrIndex = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
byte[] expr = reader.readNext(DWARFLocationList::uleb128SizedByteArray);
|
||||
long start = dprog.getAddress(DW_FORM_addrx, startAddrIndex, cu);
|
||||
long end = dprog.getAddress(DW_FORM_addrx, endAddrIndex, cu);
|
||||
long start = dieContainer.getAddress(DW_FORM_addrx, startAddrIndex, cu);
|
||||
long end = dieContainer.getAddress(DW_FORM_addrx, endAddrIndex, cu);
|
||||
list.add(new DWARFLocation(start, end, expr));
|
||||
break;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class DWARFLocationList {
|
||||
int startAddrIndex = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
int len = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
byte[] expr = reader.readNext(DWARFLocationList::uleb128SizedByteArray);
|
||||
long start = dprog.getAddress(DW_FORM_addrx, startAddrIndex, cu);
|
||||
long start = dieContainer.getAddress(DW_FORM_addrx, startAddrIndex, cu);
|
||||
list.add(new DWARFLocation(start, start + len, expr));
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,11 +18,11 @@ package ghidra.app.util.bin.format.dwarf;
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionNames;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionId;
|
||||
|
||||
/**
|
||||
* Header found at the start of a set of DWARFLocationList entries, which are stored sequentially
|
||||
* in the {@link DWARFSectionNames#DEBUG_LOCLISTS .debug_loclists} section.
|
||||
* in the {@link DWARFSectionId#DEBUG_LOCLISTS .debug_loclists} section.
|
||||
*/
|
||||
public class DWARFLocationListHeader extends DWARFIndirectTableHeader {
|
||||
|
||||
|
||||
+35
-951
File diff suppressed because it is too large
Load Diff
+7
-7
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -83,7 +83,7 @@ public class DWARFRangeList {
|
||||
|
||||
List<DWARFRange> list = new ArrayList<>();
|
||||
|
||||
DWARFProgram dprog = cu.getProgram();
|
||||
DIEContainer dieContainer = cu.getDIEContainer();
|
||||
long baseAddr = cu.getPCRange().getFrom();
|
||||
|
||||
while (reader.hasNext()) {
|
||||
@@ -94,21 +94,21 @@ public class DWARFRangeList {
|
||||
switch (rleId) {
|
||||
case DW_RLE_base_addressx: {
|
||||
int addrIndex = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
baseAddr = dprog.getAddress(DW_FORM_addrx, addrIndex, cu);
|
||||
baseAddr = dieContainer.getAddress(DW_FORM_addrx, addrIndex, cu);
|
||||
break;
|
||||
}
|
||||
case DW_RLE_startx_endx: {
|
||||
int startAddrIndex = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
int endAddrIndex = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
long start = dprog.getAddress(DW_FORM_addrx, startAddrIndex, cu);
|
||||
long end = dprog.getAddress(DW_FORM_addrx, endAddrIndex, cu);
|
||||
long start = dieContainer.getAddress(DW_FORM_addrx, startAddrIndex, cu);
|
||||
long end = dieContainer.getAddress(DW_FORM_addrx, endAddrIndex, cu);
|
||||
list.add(new DWARFRange(start, end));
|
||||
break;
|
||||
}
|
||||
case DW_RLE_startx_length: {
|
||||
int startAddrIndex = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
int len = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
long start = dprog.getAddress(DW_FORM_addrx, startAddrIndex, cu);
|
||||
long start = dieContainer.getAddress(DW_FORM_addrx, startAddrIndex, cu);
|
||||
list.add(new DWARFRange(start, start + len));
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,11 +18,11 @@ package ghidra.app.util.bin.format.dwarf;
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionNames;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionId;
|
||||
|
||||
/**
|
||||
* Header found at the start of a set of DWARFRangeList entries, which are stored sequentially
|
||||
* in the {@link DWARFSectionNames#DEBUG_RNGLISTS .debug_rnglists} section.
|
||||
* in the {@link DWARFSectionId#DEBUG_RNGLISTS .debug_rnglists} section.
|
||||
*/
|
||||
public class DWARFRangeListHeader extends DWARFIndirectTableHeader {
|
||||
|
||||
|
||||
+2
-2
@@ -20,11 +20,11 @@ import java.io.IOException;
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.attribs.DWARFAttributeId;
|
||||
import ghidra.app.util.bin.format.dwarf.attribs.DWARFForm;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionNames;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionId;
|
||||
|
||||
/**
|
||||
* Table of offsets that point into the string table. These tables are stored sequentially in the
|
||||
* {@link DWARFSectionNames#DEBUG_STROFFSETS .debug_str_offsets} section.
|
||||
* {@link DWARFSectionId#DEBUG_STROFFSETS .debug_str_offsets} section.
|
||||
* <p>
|
||||
* Elements in the table are referred to by index via {@link DWARFForm#DW_FORM_strx} and friends.
|
||||
* <p>
|
||||
|
||||
+20
-17
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -18,8 +18,6 @@ package ghidra.app.util.bin.format.dwarf;
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* The base class for a set of headers that share a common field layout.
|
||||
@@ -28,23 +26,20 @@ public class DWARFUnitHeader {
|
||||
/**
|
||||
* Reads the initial fields found in a unit header.
|
||||
*
|
||||
* @param dprog {@link DWARFProgram}
|
||||
* @param dieContainer {@link DIEContainer}
|
||||
* @param reader {@link BinaryReader} stream
|
||||
* @param abbrReader {@link BinaryReader} .debug_abbr stream
|
||||
* @param unitNumber ordinal of this item
|
||||
* @param monitor {@link TaskMonitor}
|
||||
* @return a unit header (only comp units for now), or null if at end-of-list
|
||||
* @throws DWARFException if invalid dwarf data
|
||||
* @throws IOException if error reading data
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
public static DWARFUnitHeader read(DWARFProgram dprog, BinaryReader reader,
|
||||
BinaryReader abbrReader, int unitNumber, TaskMonitor monitor)
|
||||
throws DWARFException, IOException, CancelledException {
|
||||
public static DWARFUnitHeader read(DIEContainer dieContainer, BinaryReader reader,
|
||||
int unitNumber) throws DWARFException, IOException {
|
||||
// unit_length : dwarf_length
|
||||
// version : 2 bytes
|
||||
// unit type : 1 byte [ version >= 5 ]
|
||||
|
||||
DWARFProgram dprog = dieContainer.getProgram();
|
||||
long startOffset = reader.getPointerIndex();
|
||||
DWARFLengthValue lengthInfo = DWARFLengthValue.read(reader, dprog.getDefaultIntSize());
|
||||
if (lengthInfo == null) {
|
||||
@@ -57,16 +52,16 @@ public class DWARFUnitHeader {
|
||||
throw new DWARFException("Unsupported DWARF version [%d]".formatted(version));
|
||||
}
|
||||
|
||||
DWARFUnitHeader partial = new DWARFUnitHeader(dprog, startOffset, endOffset,
|
||||
DWARFUnitHeader partial = new DWARFUnitHeader(dieContainer, startOffset, endOffset,
|
||||
lengthInfo.intSize(), version, unitNumber);
|
||||
|
||||
if (2 <= version && version <= 4) {
|
||||
return DWARFCompilationUnit.readV4(partial, reader, abbrReader, monitor);
|
||||
return DWARFCompilationUnit.readV4(partial, reader);
|
||||
}
|
||||
int unitType = reader.readNextUnsignedByte();
|
||||
switch (unitType) {
|
||||
case DWARFUnitType.DW_UT_compile:
|
||||
return DWARFCompilationUnit.readV5(partial, reader, abbrReader, monitor);
|
||||
return DWARFCompilationUnit.readV5(partial, reader);
|
||||
case DWARFUnitType.DW_UT_type:
|
||||
case DWARFUnitType.DW_UT_partial:
|
||||
case DWARFUnitType.DW_UT_skeleton:
|
||||
@@ -83,6 +78,8 @@ public class DWARFUnitHeader {
|
||||
*/
|
||||
protected final DWARFProgram dprog;
|
||||
|
||||
protected final DIEContainer dieContainer;
|
||||
|
||||
/**
|
||||
* Offset in the section of this header
|
||||
*/
|
||||
@@ -111,6 +108,7 @@ public class DWARFUnitHeader {
|
||||
|
||||
protected DWARFUnitHeader(DWARFUnitHeader other) {
|
||||
this.dprog = other.dprog;
|
||||
this.dieContainer = other.dieContainer;
|
||||
this.startOffset = other.startOffset;
|
||||
this.endOffset = other.endOffset;
|
||||
this.intSize = other.intSize;
|
||||
@@ -118,9 +116,10 @@ public class DWARFUnitHeader {
|
||||
this.unitNumber = other.unitNumber;
|
||||
}
|
||||
|
||||
protected DWARFUnitHeader(DWARFProgram dprog, long startOffset, long endOffset, int intSize,
|
||||
short version, int unitNumber) {
|
||||
this.dprog = dprog;
|
||||
protected DWARFUnitHeader(DIEContainer dieContainer, long startOffset, long endOffset,
|
||||
int intSize, short version, int unitNumber) {
|
||||
this.dieContainer = dieContainer;
|
||||
this.dprog = dieContainer.getProgram();
|
||||
this.startOffset = startOffset;
|
||||
this.endOffset = endOffset;
|
||||
this.intSize = intSize;
|
||||
@@ -132,6 +131,10 @@ public class DWARFUnitHeader {
|
||||
return dprog;
|
||||
}
|
||||
|
||||
public DIEContainer getDIEContainer() {
|
||||
return dieContainer;
|
||||
}
|
||||
|
||||
public short getDWARFVersion() {
|
||||
return dwarfVersion;
|
||||
}
|
||||
|
||||
@@ -145,9 +145,8 @@ public class DWARFUtil {
|
||||
* name.
|
||||
*/
|
||||
public static List<String> findLinkageNameInChildren(DebugInfoEntry die) {
|
||||
DWARFProgram prog = die.getProgram();
|
||||
for (DebugInfoEntry childDIE : die.getChildren(DWARFTag.DW_TAG_subprogram)) {
|
||||
DIEAggregate childDIEA = prog.getAggregate(childDIE);
|
||||
DIEAggregate childDIEA = die.getContainer().getAggregate(childDIE);
|
||||
String linkage = childDIEA.getString(DW_AT_linkage_name, null);
|
||||
if (linkage == null) {
|
||||
linkage = childDIEA.getString(DW_AT_MIPS_linkage_name, null);
|
||||
@@ -202,7 +201,7 @@ public class DWARFUtil {
|
||||
DWARFProgram prog = diea.getProgram();
|
||||
int typeDefCount = 0;
|
||||
for (DebugInfoEntry childDIE : parent.getChildren()) {
|
||||
DIEAggregate childDIEA = prog.getAggregate(childDIE);
|
||||
DIEAggregate childDIEA = diea.getDIEContainer().getAggregate(childDIE);
|
||||
if (diea == childDIEA || diea.getOffset() == childDIEA.getOffset()) {
|
||||
return "anon_%s_%d".formatted(childDIEA.getTag().getContainerTypeName(),
|
||||
typeDefCount);
|
||||
@@ -230,10 +229,9 @@ public class DWARFUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
DWARFProgram prog = diea.getProgram();
|
||||
List<String> users = new ArrayList<>();
|
||||
for (DebugInfoEntry childDIE : parent.getChildren()) {
|
||||
DIEAggregate childDIEA = prog.getAggregate(childDIE);
|
||||
DIEAggregate childDIEA = diea.getDIEContainer().getAggregate(childDIE);
|
||||
|
||||
String childName = childDIEA.getName();
|
||||
DIEAggregate type = childDIEA.getTypeRef();
|
||||
@@ -273,7 +271,7 @@ public class DWARFUtil {
|
||||
childEntry.getTag() == DWARFTag.DW_TAG_inheritance)) {
|
||||
continue;
|
||||
}
|
||||
DIEAggregate childDIEA = diea.getProgram().getAggregate(childEntry);
|
||||
DIEAggregate childDIEA = diea.getDIEContainer().getAggregate(childEntry);
|
||||
if (childDIEA.hasAttribute(DW_AT_external)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+14
-5
@@ -17,6 +17,7 @@ package ghidra.app.util.bin.format.dwarf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.attribs.*;
|
||||
@@ -126,7 +127,7 @@ public class DebugInfoEntry {
|
||||
* @return list of child DIE's
|
||||
*/
|
||||
public List<DebugInfoEntry> getChildren() {
|
||||
return getProgram().getChildrenOf(dieIndex);
|
||||
return getContainer().getChildrenOf(dieIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +153,7 @@ public class DebugInfoEntry {
|
||||
* @return the parent DIE, or null if this DIE is the root of the compilation unit
|
||||
*/
|
||||
public DebugInfoEntry getParent() {
|
||||
return getProgram().getParentOf(dieIndex);
|
||||
return getContainer().getParentOf(dieIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,7 +189,7 @@ public class DebugInfoEntry {
|
||||
*/
|
||||
public DWARFAttributeValue getAttributeValue(int attribIndex) {
|
||||
if (attributes[attribIndex] == null) {
|
||||
BinaryReader reader = getProgram().getReaderForCompUnit(compilationUnit)
|
||||
BinaryReader reader = getContainer().getReaderForCompUnit(compilationUnit)
|
||||
.clone(offset + attrOffsets[attribIndex]);
|
||||
DWARFFormContext context = new DWARFFormContext(reader, compilationUnit,
|
||||
abbreviation.getAttributeAt(attribIndex));
|
||||
@@ -259,12 +260,20 @@ public class DebugInfoEntry {
|
||||
return compilationUnit;
|
||||
}
|
||||
|
||||
public DIEContainer getContainer() {
|
||||
return compilationUnit.getDIEContainer();
|
||||
}
|
||||
|
||||
public DWARFProgram getProgram() {
|
||||
return getCompilationUnit().getProgram();
|
||||
}
|
||||
|
||||
public int getDepth() {
|
||||
return getProgram().getParentDepth(dieIndex);
|
||||
return getContainer().getParentDepth(dieIndex);
|
||||
}
|
||||
|
||||
public int getPositionInParent(Predicate<DWARFTag> dwTagFilter) {
|
||||
return getContainer().getPositionInParent(this, dwTagFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -291,7 +300,7 @@ public class DebugInfoEntry {
|
||||
DWARFTag tag = getTag();
|
||||
int tagNum = tag != null ? tag.getId() : 0;
|
||||
int abbrNum = abbreviation != null ? abbreviation.getAbbreviationCode() : 0;
|
||||
int childCount = getProgram().getChildCount(dieIndex);
|
||||
int childCount = getContainer().getChildCount(dieIndex);
|
||||
|
||||
buffer.append("<%d><%x>: %s [abbrev %d, tag %d, index %d, children %d]\n".formatted(
|
||||
getDepth(), offset, tag, abbrNum, tagNum, dieIndex, childCount));
|
||||
|
||||
+3
-6
@@ -356,23 +356,20 @@ public enum DWARFForm {
|
||||
case DW_FORM_strx3:
|
||||
case DW_FORM_strx4: {
|
||||
long index = context.reader().readNextUnsignedValue(size);
|
||||
String s =
|
||||
context.compUnit().getProgram().getString(this, index, context.compUnit());
|
||||
String s = context.dieContainer().getString(this, index, context.compUnit());
|
||||
return new DWARFStringAttribute(s);
|
||||
}
|
||||
case DW_FORM_strp:
|
||||
case DW_FORM_line_strp:
|
||||
case DW_FORM_gnu_strp_alt: {
|
||||
long offset = context.reader().readNextUnsignedValue(context.dwarfIntSize());
|
||||
String s =
|
||||
context.compUnit().getProgram().getString(this, offset, context.compUnit());
|
||||
String s = context.dieContainer().getString(this, offset, context.compUnit());
|
||||
return new DWARFStringAttribute(s);
|
||||
}
|
||||
case DW_FORM_strx:
|
||||
case DW_FORM_gnu_str_index: {
|
||||
int index = context.reader().readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
String s =
|
||||
context.compUnit().getProgram().getString(this, index, context.compUnit());
|
||||
String s = context.dieContainer().getString(this, index, context.compUnit());
|
||||
return new DWARFStringAttribute(s);
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -16,8 +16,7 @@
|
||||
package ghidra.app.util.bin.format.dwarf.attribs;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.DWARFCompilationUnit;
|
||||
import ghidra.app.util.bin.format.dwarf.DWARFProgram;
|
||||
import ghidra.app.util.bin.format.dwarf.*;
|
||||
|
||||
/**
|
||||
* Context given to the {@link DWARFForm#readValue(DWARFFormContext)} method to enable it to
|
||||
@@ -49,4 +48,8 @@ public record DWARFFormContext(BinaryReader reader, DWARFCompilationUnit compUni
|
||||
DWARFProgram dprog() {
|
||||
return compUnit.getProgram();
|
||||
}
|
||||
|
||||
DIEContainer dieContainer() {
|
||||
return compUnit.getDIEContainer();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf.attribs;
|
||||
|
||||
import static ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionId.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.format.dwarf.DWARFCompilationUnit;
|
||||
import ghidra.app.util.bin.format.dwarf.DWARFProgram;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionNames;
|
||||
|
||||
/**
|
||||
* DWARF numeric attribute value that is an index into a lookup table
|
||||
@@ -36,20 +36,19 @@ public class DWARFIndirectAttribute extends DWARFNumericAttribute {
|
||||
|
||||
@Override
|
||||
public String getValueString(DWARFCompilationUnit cu, DWARFAttributeDef<?> def) {
|
||||
DWARFProgram dprog = cu.getProgram();
|
||||
DWARFForm form = def.getAttributeForm();
|
||||
try {
|
||||
int index = getIndex();
|
||||
long offset = dprog.getOffsetOfIndexedElement(form, index, cu);
|
||||
long offset = cu.getDIEContainer().getOffsetOfIndexedElement(form, index, cu);
|
||||
if (form.isClass(DWARFAttributeClass.address)) {
|
||||
return "addr v%d 0x%x (idx %d)".formatted(cu.getDWARFVersion(), offset, index);
|
||||
}
|
||||
else if (form.isClass(DWARFAttributeClass.rnglist)) {
|
||||
return toElementLocationString("rnglist", DWARFSectionNames.DEBUG_RNGLISTS, index,
|
||||
return toElementLocationString("rnglist", DEBUG_RNGLISTS.getSectionName(), index,
|
||||
offset, cu.getDWARFVersion());
|
||||
}
|
||||
else if (form.isClass(DWARFAttributeClass.loclist)) {
|
||||
return toElementLocationString("loclist", DWARFSectionNames.DEBUG_LOCLISTS, index,
|
||||
return toElementLocationString("loclist", DEBUG_LOCLISTS.getSectionName(), index,
|
||||
offset, cu.getDWARFVersion());
|
||||
}
|
||||
else if (form.isClass(DWARFAttributeClass.string)) {
|
||||
|
||||
+4
-5
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf.attribs;
|
||||
|
||||
import static ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionId.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.InvalidDataException;
|
||||
import ghidra.app.util.bin.format.dwarf.DWARFCompilationUnit;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionNames;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
|
||||
/**
|
||||
@@ -118,14 +119,12 @@ public class DWARFNumericAttribute implements DWARFAttributeValue {
|
||||
return "addr v%d 0x%x".formatted(ver, getUnsignedValue());
|
||||
}
|
||||
else if (form.isClass(DWARFAttributeClass.rnglist)) {
|
||||
String sectionName =
|
||||
ver < 5 ? DWARFSectionNames.DEBUG_RANGES : DWARFSectionNames.DEBUG_RNGLISTS;
|
||||
String sectionName = (ver < 5 ? DEBUG_RANGES : DEBUG_RNGLISTS).getSectionName();
|
||||
return toElementLocationString("rnglist", sectionName, -1, getUnsignedValue(), ver) +
|
||||
" offset: " + getUnsignedValue();
|
||||
}
|
||||
else if (form.isClass(DWARFAttributeClass.loclist)) {
|
||||
String sectionName =
|
||||
ver < 5 ? DWARFSectionNames.DEBUG_LOC : DWARFSectionNames.DEBUG_LOCLISTS;
|
||||
String sectionName = (ver < 5 ? DEBUG_LOC : DEBUG_LOCLISTS).getSectionName();
|
||||
return toElementLocationString("loclist", sectionName, -1, getUnsignedValue(), ver);
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf.expression;
|
||||
|
||||
import static ghidra.app.util.bin.format.dwarf.attribs.DWARFForm.*;
|
||||
import static ghidra.app.util.bin.format.dwarf.expression.DWARFExpressionOpCode.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.util.bin.format.dwarf.*;
|
||||
import ghidra.app.util.bin.format.dwarf.attribs.DWARFForm;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.Register;
|
||||
@@ -658,8 +658,8 @@ public class DWARFExpressionEvaluator {
|
||||
throw new DWARFExpressionUnsupportedOpException(instr);
|
||||
case DW_OP_addrx:
|
||||
try {
|
||||
long addr = dprog.getAddress(DWARFForm.DW_FORM_addrx,
|
||||
instr.getOperandValue(0), cu);
|
||||
long addr = cu.getDIEContainer()
|
||||
.getAddress(DW_FORM_addrx, instr.getOperandValue(0), cu);
|
||||
push(addr);
|
||||
break;
|
||||
}
|
||||
@@ -669,8 +669,8 @@ public class DWARFExpressionEvaluator {
|
||||
}
|
||||
case DW_OP_constx: // same as addrx, but different relocation-able specifications
|
||||
try {
|
||||
long addr = dprog.getAddress(DWARFForm.DW_FORM_addrx,
|
||||
instr.getOperandValue(0), cu);
|
||||
long addr = cu.getDIEContainer()
|
||||
.getAddress(DW_FORM_addrx, instr.getOperandValue(0), cu);
|
||||
push(addr);
|
||||
break;
|
||||
}
|
||||
|
||||
+11
-8
@@ -264,11 +264,11 @@ public class DWARFLine {
|
||||
return endOffset;
|
||||
}
|
||||
|
||||
public DWARFLineProgramExecutor getLineProgramexecutor(DWARFCompilationUnit cu,
|
||||
BinaryReader reader) {
|
||||
DWARFLineProgramExecutor lpe = new DWARFLineProgramExecutor(reader.clone(opcodes_start),
|
||||
endOffset, cu.getPointerSize(), opcode_base, line_base, line_range,
|
||||
minimum_instruction_length, default_is_stmt);
|
||||
public DWARFLineProgramExecutor getLineProgramExecutor(DWARFCompilationUnit cu) {
|
||||
DWARFLineProgramExecutor lpe = new DWARFLineProgramExecutor(
|
||||
cu.getDIEContainer().getDebugLineReader().clone(opcodes_start), endOffset,
|
||||
cu.getPointerSize(), opcode_base, line_base, line_range, minimum_instruction_length,
|
||||
default_is_stmt);
|
||||
|
||||
return lpe;
|
||||
}
|
||||
@@ -278,9 +278,12 @@ public class DWARFLine {
|
||||
public record SourceFileAddr(long address, String fileName, byte[] md5, int lineNum,
|
||||
boolean isEndSequence) {}
|
||||
|
||||
public List<SourceFileAddr> getAllSourceFileAddrInfo(DWARFCompilationUnit cu,
|
||||
BinaryReader reader) throws IOException {
|
||||
try (DWARFLineProgramExecutor lpe = getLineProgramexecutor(cu, reader)) {
|
||||
public List<SourceFileAddr> getAllSourceFileAddrInfo(DWARFCompilationUnit cu)
|
||||
throws IOException {
|
||||
if (cu.getDIEContainer().getDebugLineReader() == null) {
|
||||
return List.of();
|
||||
}
|
||||
try (DWARFLineProgramExecutor lpe = getLineProgramExecutor(cu)) {
|
||||
List<SourceFileAddr> results = new ArrayList<>();
|
||||
for (DWARFLineProgramState row : lpe.allRows()) {
|
||||
try {
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ public class DWARFMacroHeader {
|
||||
long debug_line_offset = -1;
|
||||
if ((flags & DEBUG_LINE_OFFSET_FLAG_MASK) != 0) {
|
||||
debug_line_offset = reader.readNextUnsignedValue(intSize);
|
||||
line = cu.getProgram().getLine(debug_line_offset, cu, false);
|
||||
line = cu.getDIEContainer().getLine(debug_line_offset, cu, false);
|
||||
}
|
||||
Map<Integer, List<DWARFForm>> opcodeMap = DWARFMacroOpcode.defaultOpcodeOperandMap;
|
||||
if ((flags & OPCODE_OPERANDS_TABLE_FLAG_MASK) != 0) {
|
||||
@@ -135,7 +135,7 @@ public class DWARFMacroHeader {
|
||||
}
|
||||
|
||||
public List<DWARFMacroInfoEntry> getEntries() throws IOException {
|
||||
return cu.getProgram().getMacroEntries(this);
|
||||
return cu.getDIEContainer().getMacroEntries(this);
|
||||
}
|
||||
|
||||
public DWARFCompilationUnit getCompilationUnit() {
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class DWARFMacroImport extends DWARFMacroInfoEntry {
|
||||
public DWARFMacroHeader getImportedMacroHeader() throws IOException {
|
||||
long offset = getOffset();
|
||||
DWARFCompilationUnit cu = macroHeader.getCompilationUnit();
|
||||
return cu.getProgram().getMacroHeader(offset, cu);
|
||||
return cu.getDIEContainer().getMacroHeader(offset, cu);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf.sectionprovider;
|
||||
|
||||
/**
|
||||
* Enum specifying common DWARF sections
|
||||
*/
|
||||
public enum DWARFSectionId {
|
||||
DEBUG_INFO("debug_info"),
|
||||
DEBUG_TYPES("debug_types"),
|
||||
DEBUG_ABBREV("debug_abbrev"),
|
||||
DEBUG_ARRANGES("debug_arranges"),
|
||||
DEBUG_LINE("debug_line"),
|
||||
DEBUG_LINE_STR("debug_line_str"), // v5+
|
||||
DEBUG_FRAME("debug_frame"),
|
||||
DEBUG_LOC("debug_loc"),
|
||||
DEBUG_LOCLISTS("debug_loclists"), // v5+
|
||||
DEBUG_STR("debug_str"),
|
||||
DEBUG_STROFFSETS("debug_str_offsets"), // v5+
|
||||
DEBUG_RANGES("debug_ranges"),
|
||||
DEBUG_RNGLISTS("debug_rnglists"), // v5+
|
||||
DEBUG_PUBNAMES("debug_pubnames"),
|
||||
DEBUG_PUBTYPES("debug_pubtypes"),
|
||||
DEBUG_MACINFO("debug_macinfo"),
|
||||
DEBUG_MACRO("debug_macro"), // v5+
|
||||
DEBUG_ADDR("debug_addr");
|
||||
|
||||
public static final String[] MINIMAL_DWARF_SECTIONS =
|
||||
new String[] { DEBUG_INFO.getSectionName(), DEBUG_ABBREV.getSectionName() };
|
||||
|
||||
private final String name;
|
||||
|
||||
private DWARFSectionId(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSectionName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf.sectionprovider;
|
||||
|
||||
public final class DWARFSectionNames {
|
||||
public static final String DEBUG_INFO = "debug_info";
|
||||
public static final String DEBUG_TYPES = "debug_types";
|
||||
public static final String DEBUG_ABBREV = "debug_abbrev";
|
||||
public static final String DEBUG_ARRANGES = "debug_arranges";
|
||||
public static final String DEBUG_LINE = "debug_line";
|
||||
public static final String DEBUG_LINE_STR = "debug_line_str"; // v5+
|
||||
public static final String DEBUG_FRAME = "debug_frame";
|
||||
public static final String DEBUG_LOC = "debug_loc";
|
||||
public static final String DEBUG_LOCLISTS = "debug_loclists"; // v5+
|
||||
public static final String DEBUG_STR = "debug_str";
|
||||
public static final String DEBUG_STROFFSETS = "debug_str_offsets"; // v5+
|
||||
public static final String DEBUG_RANGES = "debug_ranges";
|
||||
public static final String DEBUG_RNGLISTS = "debug_rnglists"; // v5+
|
||||
public static final String DEBUG_PUBNAMES = "debug_pubnames";
|
||||
public static final String DEBUG_PUBTYPES = "debug_pubtypes";
|
||||
public static final String DEBUG_MACINFO = "debug_macinfo";
|
||||
public static final String DEBUG_MACRO = "debug_macro"; // v5+
|
||||
public static final String DEBUG_ADDR = "debug_addr";
|
||||
|
||||
public static final String[] MINIMAL_DWARF_SECTIONS = { DEBUG_INFO, DEBUG_ABBREV };
|
||||
|
||||
}
|
||||
+5
-3
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf.sectionprovider;
|
||||
|
||||
import static ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionId.*;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -48,7 +50,7 @@ public class DWARFSectionProviderFactory {
|
||||
/**
|
||||
* Iterates through the statically registered {@link #sectionProviderFactoryFuncs factory funcs},
|
||||
* trying each factory method until one returns a {@link DWARFSectionProvider}
|
||||
* that can successfully retrieve the {@link DWARFSectionNames#MINIMAL_DWARF_SECTIONS minimal}
|
||||
* that can successfully retrieve the {@link DWARFSectionId#MINIMAL_DWARF_SECTIONS minimal}
|
||||
* sections we need to do a DWARF import.
|
||||
* <p>
|
||||
* The resulting {@link DWARFSectionProvider} is {@link Closeable} and it is the caller's
|
||||
@@ -65,14 +67,14 @@ public class DWARFSectionProviderFactory {
|
||||
DWARFSectionProvider sp = factoryFunc.apply(program, monitor);
|
||||
if (sp != null) {
|
||||
try {
|
||||
if (sp.hasSection(DWARFSectionNames.MINIMAL_DWARF_SECTIONS)) {
|
||||
if (sp.hasSection(MINIMAL_DWARF_SECTIONS)) {
|
||||
return sp;
|
||||
}
|
||||
|
||||
// if normal sections were not found, look for compressed sections in the
|
||||
// same provider
|
||||
sp = new CompressedSectionProvider(sp);
|
||||
if (sp.hasSection(DWARFSectionNames.MINIMAL_DWARF_SECTIONS)) {
|
||||
if (sp.hasSection(MINIMAL_DWARF_SECTIONS)) {
|
||||
return sp;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-9
@@ -172,14 +172,6 @@ public class PortableExecutable {
|
||||
}
|
||||
|
||||
public long getFileLength() {
|
||||
if (reader != null) {
|
||||
try {
|
||||
return reader.length();
|
||||
} catch (IOException e) {
|
||||
// IGNORE
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return reader != null ? reader.length() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -195,12 +195,7 @@ public class DebugDirectoryParser implements OffsetValidator {
|
||||
|
||||
@Override
|
||||
public boolean checkPointer(long ptr) {
|
||||
try {
|
||||
return ptr > 0 && ptr < reader.length();
|
||||
}
|
||||
catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
return ptr > 0 && ptr < reader.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -278,7 +278,7 @@ public class DWARFDataTypeImporterTest extends DWARFTestBase {
|
||||
// test that cached types are handled correctly.
|
||||
DebugInfoEntry int2DIE = addInt();
|
||||
DebugInfoEntry structB_cu2 = newStruct("structB", 20).create();
|
||||
long structA_cu2_offset = dwarfProg.getRelativeDIEOffset(2);
|
||||
long structA_cu2_offset = dieContainer.getRelativeDIEOffset(2);
|
||||
newMember(structB_cu2, "structAfield", structA_cu2_offset, 0).create();
|
||||
newMember(structB_cu2, "guardfield", int2DIE, 16).create();
|
||||
|
||||
@@ -1289,7 +1289,7 @@ public class DWARFDataTypeImporterTest extends DWARFTestBase {
|
||||
|
||||
// hack to make a forward reference to a DIE that hasn't been created yet.
|
||||
// This creates a hostile loop in the data type references.
|
||||
long fwdDIE = dwarfProg.getRelativeDIEOffset(1);
|
||||
long fwdDIE = dieContainer.getRelativeDIEOffset(1);
|
||||
DebugInfoEntry constDIE =
|
||||
new DIECreator(dwarfProg, DWARFTag.DW_TAG_const_type).addRef(DW_AT_type, fwdDIE)
|
||||
.create();
|
||||
|
||||
+1
-1
@@ -265,7 +265,7 @@ public class DWARFFunctionImporterTest extends DWARFTestBase {
|
||||
DebugInfoEntry floatDIE = addFloat();
|
||||
DebugInfoEntry struct1PtrDIE = addFwdPtr(1);
|
||||
DebugInfoEntry struct1DIE = newStruct("mystruct", 100).create();
|
||||
long formalParamDIEOffset = dwarfProg.getRelativeDIEOffset(2);
|
||||
long formalParamDIEOffset = dieContainer.getRelativeDIEOffset(2);
|
||||
DebugInfoEntry fooDIE = newSubprogram("foo", intDIE, 0x410, 10)
|
||||
.addRef(DW_AT_object_pointer, formalParamDIEOffset)
|
||||
.setParent(struct1DIE)
|
||||
|
||||
+11
-9
@@ -29,12 +29,14 @@ public class DIECreator {
|
||||
record AttrInfo(DWARFAttributeId attribute, AttrDef spec, DWARFAttributeValue value) {}
|
||||
|
||||
private MockDWARFProgram dwarfProg;
|
||||
private MockDIEContainer dieContainer;
|
||||
private DWARFTag tag;
|
||||
private Map<DWARFAttributeId, AttrInfo> attributes = new HashMap<>();
|
||||
private DebugInfoEntry parent;
|
||||
|
||||
public DIECreator(MockDWARFProgram dwarfProg, DWARFTag tag) {
|
||||
this.dwarfProg = dwarfProg;
|
||||
public DIECreator(MockDWARFProgram dprog, DWARFTag tag) {
|
||||
this.dieContainer = dprog.getDIEContainer();
|
||||
this.dwarfProg = dprog;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@@ -64,14 +66,14 @@ public class DIECreator {
|
||||
public DIECreator addRef(DWARFAttributeId attribute, DebugInfoEntry die) {
|
||||
AttrDef attrSpec = new AttrDef(attribute, attribute.getId(), DW_FORM_ref8, 0);
|
||||
add(attrSpec, new DWARFNumericAttribute(
|
||||
die.getOffset() - dwarfProg.getCurrentCompUnit().getStartOffset()));
|
||||
die.getOffset() - dieContainer.getCurrentCompUnit().getStartOffset()));
|
||||
return this;
|
||||
}
|
||||
|
||||
public DIECreator addRef(DWARFAttributeId attribute, long offset) {
|
||||
AttrDef attrSpec = new AttrDef(attribute, attribute.getId(), DW_FORM_ref8, 0);
|
||||
add(attrSpec, new DWARFNumericAttribute(
|
||||
offset - dwarfProg.getCurrentCompUnit().getStartOffset()));
|
||||
offset - dieContainer.getCurrentCompUnit().getStartOffset()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -112,9 +114,9 @@ public class DIECreator {
|
||||
}
|
||||
|
||||
public DebugInfoEntry createRootDIE() {
|
||||
MockDWARFCompilationUnit cu = dwarfProg.getCurrentCompUnit();
|
||||
MockDWARFCompilationUnit cu = dieContainer.getCurrentCompUnit();
|
||||
DWARFAbbreviation abbr = cu.createAbbreviation(makeAttrSpecArray(), tag);
|
||||
DebugInfoEntry die = dwarfProg.addDIE(abbr, null);
|
||||
DebugInfoEntry die = dieContainer.addDIE(abbr, null);
|
||||
|
||||
int attrNum = 0;
|
||||
for (AttrInfo attrInfo : attributes.values()) {
|
||||
@@ -125,13 +127,13 @@ public class DIECreator {
|
||||
}
|
||||
|
||||
public DebugInfoEntry create() {
|
||||
MockDWARFCompilationUnit cu = dwarfProg.getCurrentCompUnit();
|
||||
MockDWARFCompilationUnit cu = dieContainer.getCurrentCompUnit();
|
||||
if (cu == null) {
|
||||
cu = dwarfProg.addCompUnit();
|
||||
cu = dieContainer.addCompUnit();
|
||||
}
|
||||
DWARFAbbreviation abbr = cu.createAbbreviation(makeAttrSpecArray(), tag);
|
||||
DebugInfoEntry die =
|
||||
dwarfProg.addDIE(abbr, parent != null ? parent : cu.getCompileUnitDIE());
|
||||
dieContainer.addDIE(abbr, parent != null ? parent : cu.getCompileUnitDIE());
|
||||
|
||||
int attrNum = 0;
|
||||
for (AttrInfo attrInfo : attributes.values()) {
|
||||
|
||||
+4
-7
@@ -63,7 +63,7 @@ public class DIECreatorTest extends DWARFTestBase {
|
||||
|
||||
buildMockDIEIndexes();
|
||||
|
||||
DIEAggregate struct_via_ao = dwarfProg.getAggregate(aoStruct);
|
||||
DIEAggregate struct_via_ao = dwarfProg.getDIEContainer().getAggregate(aoStruct);
|
||||
|
||||
assertEquals("MyStruct aggregate should have 3 fragments", 3,
|
||||
struct_via_ao.getOffsets().length);
|
||||
@@ -73,7 +73,7 @@ public class DIECreatorTest extends DWARFTestBase {
|
||||
struct_via_ao.getString(DW_AT_description, null));
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Tests the creation of DIEAggregates when there is a many-to-one layout of
|
||||
* abstractorigin -> spec -> decl links.
|
||||
* <pre>
|
||||
@@ -83,9 +83,6 @@ public class DIECreatorTest extends DWARFTestBase {
|
||||
* \
|
||||
* mystruct ao2
|
||||
* </pre>
|
||||
* @throws DWARFException
|
||||
* @throws IOException
|
||||
* @throws CancelledException
|
||||
*/
|
||||
@Test
|
||||
public void testDIEAggregateMulti() throws DWARFException, CancelledException, IOException {
|
||||
@@ -126,8 +123,8 @@ public class DIECreatorTest extends DWARFTestBase {
|
||||
|
||||
buildMockDIEIndexes();
|
||||
|
||||
DIEAggregate ao1 = dwarfProg.getAggregate(ao1Struct);
|
||||
DIEAggregate ao2 = dwarfProg.getAggregate(ao2Struct);
|
||||
DIEAggregate ao1 = dwarfProg.getDIEContainer().getAggregate(ao1Struct);
|
||||
DIEAggregate ao2 = dwarfProg.getDIEContainer().getAggregate(ao2Struct);
|
||||
|
||||
assertEquals("Should have 3 fragments", 3, ao1.getOffsets().length);
|
||||
assertEquals("Should have 3 fragments", 3, ao2.getOffsets().length);
|
||||
|
||||
+12
-12
@@ -56,8 +56,8 @@ public class DWARFTestBase extends AbstractGhidraHeadedIntegrationTest {
|
||||
protected int transactionID;
|
||||
protected TaskMonitor monitor = TaskMonitor.DUMMY;
|
||||
|
||||
protected DWARFImportOptions importOptions;
|
||||
protected MockDWARFProgram dwarfProg;
|
||||
protected MockDIEContainer dieContainer;
|
||||
protected MockDWARFCompilationUnit cu;
|
||||
protected DWARFDataTypeManager dwarfDTM;
|
||||
protected MockStringTable stringTable;
|
||||
@@ -80,11 +80,11 @@ public class DWARFTestBase extends AbstractGhidraHeadedIntegrationTest {
|
||||
DataTypeManagerService dtms = mgr.getDataTypeManagerService();
|
||||
builtInDTM = dtms.getBuiltInDataTypesManager();
|
||||
|
||||
importOptions = new DWARFImportOptions();
|
||||
dwarfProg = new MockDWARFProgram(program, importOptions, TaskMonitor.DUMMY,
|
||||
new NullSectionProvider());
|
||||
stringTable = new MockStringTable(br());
|
||||
dwarfProg.setStringTable(stringTable);
|
||||
dwarfProg =
|
||||
new MockDWARFProgram(program, new DWARFImportOptions(), new NullSectionProvider());
|
||||
dwarfProg.init(monitor);
|
||||
dieContainer = dwarfProg.getDIEContainer();
|
||||
stringTable = dieContainer.getStringTable();
|
||||
|
||||
dwarfDTM = dwarfProg.getDwarfDTM();
|
||||
dwarfRootCP = dwarfProg.getRootDNI().asCategoryPath();
|
||||
@@ -115,8 +115,8 @@ public class DWARFTestBase extends AbstractGhidraHeadedIntegrationTest {
|
||||
}
|
||||
|
||||
protected void buildMockDIEIndexes() throws CancelledException, DWARFException {
|
||||
dwarfProg.buildMockDIEIndexes();
|
||||
//dwarfProg.dumpDIEs(System.out);
|
||||
dieContainer.buildMockDIEIndexes();
|
||||
//dieContainer.dumpDIEs(System.out);
|
||||
}
|
||||
|
||||
protected void importAllDataTypes() throws CancelledException, IOException, DWARFException {
|
||||
@@ -133,7 +133,7 @@ public class DWARFTestBase extends AbstractGhidraHeadedIntegrationTest {
|
||||
}
|
||||
|
||||
protected DIEAggregate getAggregate(DebugInfoEntry die) {
|
||||
return dwarfProg.getAggregate(die);
|
||||
return dieContainer.getAggregate(die);
|
||||
}
|
||||
|
||||
protected void ensureCompUnit() {
|
||||
@@ -147,12 +147,12 @@ public class DWARFTestBase extends AbstractGhidraHeadedIntegrationTest {
|
||||
}
|
||||
|
||||
protected MockDWARFCompilationUnit addCompUnit64() {
|
||||
setCompUnit(dwarfProg.addCompUnit(DWARFSourceLanguage.DW_LANG_C, 8 /* dwarf64 */));
|
||||
setCompUnit(dieContainer.addCompUnit(DWARFSourceLanguage.DW_LANG_C, 8 /* dwarf64 */));
|
||||
return cu;
|
||||
}
|
||||
|
||||
protected MockDWARFCompilationUnit addCompUnit(int cuLang) {
|
||||
setCompUnit(dwarfProg.addCompUnit(cuLang));
|
||||
setCompUnit(dieContainer.addCompUnit(cuLang));
|
||||
return cu;
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ public class DWARFTestBase extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
protected DebugInfoEntry addFwdPtr(int fwdRecordOffset) {
|
||||
ensureCompUnit();
|
||||
long absOffset = dwarfProg
|
||||
long absOffset = dieContainer
|
||||
.getRelativeDIEOffset(fwdRecordOffset + /* the ptr die we are about to add */ 1);
|
||||
return new DIECreator(dwarfProg, DW_TAG_pointer_type).addRef(DW_AT_type, absOffset)
|
||||
.create();
|
||||
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.ByteArrayProvider;
|
||||
import ghidra.app.util.bin.format.dwarf.attribs.DWARFAttributeId;
|
||||
import ghidra.util.datastruct.IntArrayList;
|
||||
import ghidra.util.datastruct.LongArrayList;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class MockDIEContainer extends DIEContainer {
|
||||
private MockDWARFCompilationUnit currentCompUnit;
|
||||
private List<DebugInfoEntry> dies = new ArrayList<>();
|
||||
|
||||
public MockDIEContainer(MockDWARFProgram dprog) {
|
||||
super(dprog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(TaskMonitor monitor) throws IOException, DWARFException {
|
||||
super.init(monitor);
|
||||
debugStrings = new MockStringTable(
|
||||
new BinaryReader(new ByteArrayProvider(new byte[0]), dprog.isLittleEndian()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MockDWARFProgram getProgram() {
|
||||
return (MockDWARFProgram) super.getProgram();
|
||||
}
|
||||
|
||||
public MockDWARFCompilationUnit getCurrentCompUnit() {
|
||||
return currentCompUnit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MockStringTable getStringTable() {
|
||||
return (MockStringTable) super.getStringTable();
|
||||
}
|
||||
|
||||
public MockDWARFCompilationUnit addCompUnit() {
|
||||
return addCompUnit(DWARFSourceLanguage.DW_LANG_C);
|
||||
}
|
||||
|
||||
public MockDWARFCompilationUnit addCompUnit(int cuLang) {
|
||||
return addCompUnit(cuLang, 4 /* dwarf32 */);
|
||||
}
|
||||
|
||||
public MockDWARFCompilationUnit addCompUnit(int cuLang, int dwarfIntSize) {
|
||||
if (currentCompUnit == null && !compUnitDieIndex.isEmpty()) {
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
if (currentCompUnit != null) {
|
||||
compUnitDieIndex.put(dieOffsets.length - 1, currentCompUnit);
|
||||
}
|
||||
long start = compUnits.size() * 0x1000;
|
||||
currentCompUnit = new MockDWARFCompilationUnit(this, start, start + 0x1000, dwarfIntSize,
|
||||
(short) 4, (byte) 8, 0);
|
||||
compUnits.add(currentCompUnit);
|
||||
compUnitDieIndex.put(dieOffsets.length - 1, currentCompUnit);
|
||||
|
||||
DebugInfoEntry compUnitRootDIE = new DIECreator(getProgram(), DWARFTag.DW_TAG_compile_unit)
|
||||
.addInt(DWARFAttributeId.DW_AT_language, cuLang)
|
||||
.createRootDIE();
|
||||
try {
|
||||
currentCompUnit.init(compUnitRootDIE);
|
||||
}
|
||||
catch (IOException e) {
|
||||
fail();
|
||||
}
|
||||
|
||||
return currentCompUnit;
|
||||
}
|
||||
|
||||
public long getRelativeDIEOffset(int count) {
|
||||
int cuDIECount = currentCompUnit.incDIECount();
|
||||
return currentCompUnit.getStartOffset() + cuDIECount + count;
|
||||
}
|
||||
|
||||
public DebugInfoEntry addDIE(DWARFAbbreviation abbr, DebugInfoEntry parent) {
|
||||
LongArrayList dieOffsetList = new LongArrayList(dieOffsets);
|
||||
IntArrayList siblingIndexList = new IntArrayList(siblingIndexes);
|
||||
IntArrayList parentIndexList = new IntArrayList(parentIndexes);
|
||||
|
||||
int dieIndex = dieOffsetList.size();
|
||||
int cuDIECount = currentCompUnit.incDIECount();
|
||||
DebugInfoEntry die =
|
||||
new DebugInfoEntry(currentCompUnit, currentCompUnit.getStartOffset() + cuDIECount,
|
||||
dieIndex, abbr, new int[abbr.getAttributeCount()]);
|
||||
|
||||
diesByOffset.put(die.getOffset(), die);
|
||||
dieOffsetList.add(die.getOffset());
|
||||
parentIndexList.add(parent != null ? parent.getIndex() : -1);
|
||||
siblingIndexList.add(dieIndex + 1);
|
||||
|
||||
updateSiblingIndexes(siblingIndexList, parentIndexList, dieIndex);
|
||||
|
||||
dieOffsets = dieOffsetList.toLongArray();
|
||||
siblingIndexes = siblingIndexList.toArray();
|
||||
parentIndexes = parentIndexList.toArray();
|
||||
|
||||
dies.add(die);
|
||||
|
||||
return die;
|
||||
}
|
||||
|
||||
public void buildMockDIEIndexes() throws CancelledException, DWARFException {
|
||||
if (currentCompUnit == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
compUnitDieIndex.put(dieOffsets.length - 1, currentCompUnit);
|
||||
currentCompUnit = null;
|
||||
|
||||
LongArrayList aggrTargets = new LongArrayList();
|
||||
for (DebugInfoEntry die : dies) {
|
||||
DIEAggregate diea = DIEAggregate.createSingle(die);
|
||||
for (DWARFAttributeId attr : REF_ATTRS) {
|
||||
long refdOffset = diea.getUnsignedLong(attr, -1);
|
||||
if (refdOffset != -1) {
|
||||
aggrTargets.add(refdOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
indexDIEAggregates(aggrTargets, TaskMonitor.DUMMY); // after this point, DIEAggregates are functional
|
||||
indexDIEATypeRefs(TaskMonitor.DUMMY);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -23,9 +23,9 @@ public class MockDWARFCompilationUnit extends DWARFCompilationUnit {
|
||||
|
||||
private int dieCount;
|
||||
|
||||
public MockDWARFCompilationUnit(MockDWARFProgram dwarfProgram, long startOffset, long endOffset,
|
||||
public MockDWARFCompilationUnit(MockDIEContainer dieContainer, long startOffset, long endOffset,
|
||||
int intSize, short version, byte pointerSize, int compUnitNumber) {
|
||||
super(dwarfProgram, startOffset, endOffset, intSize, version, pointerSize,
|
||||
super(dieContainer, startOffset, endOffset, intSize, version, pointerSize,
|
||||
compUnitNumber, startOffset, null);
|
||||
}
|
||||
|
||||
|
||||
+11
-112
@@ -15,130 +15,29 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import ghidra.app.util.bin.format.dwarf.attribs.DWARFAttributeId;
|
||||
import ghidra.app.util.bin.format.dwarf.sectionprovider.DWARFSectionProvider;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.datastruct.IntArrayList;
|
||||
import ghidra.util.datastruct.LongArrayList;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class MockDWARFProgram extends DWARFProgram {
|
||||
|
||||
private MockDWARFCompilationUnit currentCompUnit;
|
||||
private List<DebugInfoEntry> dies = new ArrayList<>();
|
||||
|
||||
public MockDWARFProgram(Program program, DWARFImportOptions importOptions, TaskMonitor monitor)
|
||||
throws CancelledException, IOException, DWARFException {
|
||||
super(program, importOptions, monitor);
|
||||
public MockDWARFProgram(Program program, DWARFImportOptions importOptions,
|
||||
DWARFSectionProvider sectionProvider) throws IOException {
|
||||
super(program, importOptions, sectionProvider);
|
||||
this.dieContainer = new MockDIEContainer(this);
|
||||
}
|
||||
|
||||
public MockDWARFProgram(Program program, DWARFImportOptions importOptions, TaskMonitor monitor,
|
||||
DWARFSectionProvider sectionProvider)
|
||||
throws CancelledException, IOException, DWARFException {
|
||||
super(program, importOptions, monitor, sectionProvider);
|
||||
@Override
|
||||
public void init(TaskMonitor monitor) throws IOException {
|
||||
dieContainer.init(monitor);
|
||||
// dieContainer.indexData() is not called, data is added by caller manually
|
||||
}
|
||||
|
||||
public MockDWARFCompilationUnit getCurrentCompUnit() {
|
||||
return currentCompUnit;
|
||||
}
|
||||
|
||||
public MockDWARFCompilationUnit addCompUnit() {
|
||||
return addCompUnit(DWARFSourceLanguage.DW_LANG_C);
|
||||
}
|
||||
|
||||
public MockDWARFCompilationUnit addCompUnit(int cuLang) {
|
||||
return addCompUnit(cuLang, 4 /* dwarf32 */);
|
||||
}
|
||||
|
||||
public MockDWARFCompilationUnit addCompUnit(int cuLang, int dwarfIntSize) {
|
||||
if (currentCompUnit == null && !compUnitDieIndex.isEmpty()) {
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
if (currentCompUnit != null) {
|
||||
compUnitDieIndex.put(dieOffsets.length - 1, currentCompUnit);
|
||||
}
|
||||
long start = compUnits.size() * 0x1000;
|
||||
currentCompUnit = new MockDWARFCompilationUnit(this, start, start + 0x1000, dwarfIntSize,
|
||||
(short) 4, (byte) 8, 0);
|
||||
compUnits.add(currentCompUnit);
|
||||
compUnitDieIndex.put(dieOffsets.length - 1, currentCompUnit);
|
||||
|
||||
DebugInfoEntry compUnitRootDIE = new DIECreator(this, DWARFTag.DW_TAG_compile_unit)
|
||||
.addInt(DWARFAttributeId.DW_AT_language, cuLang)
|
||||
.createRootDIE();
|
||||
try {
|
||||
currentCompUnit.init(compUnitRootDIE);
|
||||
}
|
||||
catch (IOException e) {
|
||||
fail();
|
||||
}
|
||||
|
||||
return currentCompUnit;
|
||||
}
|
||||
|
||||
public long getRelativeDIEOffset(int count) {
|
||||
int cuDIECount = currentCompUnit.incDIECount();
|
||||
return currentCompUnit.getStartOffset() + cuDIECount + count;
|
||||
}
|
||||
|
||||
public DebugInfoEntry addDIE(DWARFAbbreviation abbr, DebugInfoEntry parent) {
|
||||
LongArrayList dieOffsetList = new LongArrayList(dieOffsets);
|
||||
IntArrayList siblingIndexList = new IntArrayList(siblingIndexes);
|
||||
IntArrayList parentIndexList = new IntArrayList(parentIndexes);
|
||||
|
||||
int dieIndex = dieOffsetList.size();
|
||||
int cuDIECount = currentCompUnit.incDIECount();
|
||||
DebugInfoEntry die =
|
||||
new DebugInfoEntry(currentCompUnit, currentCompUnit.getStartOffset() + cuDIECount,
|
||||
dieIndex, abbr, new int[abbr.getAttributeCount()]);
|
||||
|
||||
diesByOffset.put(die.getOffset(), die);
|
||||
dieOffsetList.add(die.getOffset());
|
||||
parentIndexList.add(parent != null ? parent.getIndex() : -1);
|
||||
siblingIndexList.add(dieIndex + 1);
|
||||
|
||||
updateSiblingIndexes(siblingIndexList, parentIndexList, dieIndex);
|
||||
|
||||
dieOffsets = dieOffsetList.toLongArray();
|
||||
siblingIndexes = siblingIndexList.toArray();
|
||||
parentIndexes = parentIndexList.toArray();
|
||||
|
||||
dies.add(die);
|
||||
|
||||
return die;
|
||||
}
|
||||
|
||||
public void buildMockDIEIndexes() throws CancelledException, DWARFException {
|
||||
if (currentCompUnit == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
compUnitDieIndex.put(dieOffsets.length - 1, currentCompUnit);
|
||||
currentCompUnit = null;
|
||||
|
||||
LongArrayList aggrTargets = new LongArrayList();
|
||||
for (DebugInfoEntry die : dies) {
|
||||
DIEAggregate diea = DIEAggregate.createSingle(die);
|
||||
for (DWARFAttributeId attr : REF_ATTRS) {
|
||||
long refdOffset = diea.getUnsignedLong(attr, -1);
|
||||
if (refdOffset != -1) {
|
||||
aggrTargets.add(refdOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
indexDIEAggregates(aggrTargets, TaskMonitor.DUMMY); // after this point, DIEAggregates are functional
|
||||
indexDIEATypeRefs(TaskMonitor.DUMMY);
|
||||
|
||||
@Override
|
||||
public MockDIEContainer getDIEContainer() {
|
||||
return (MockDIEContainer) super.getDIEContainer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-2
@@ -23,8 +23,7 @@ import ghidra.app.util.bin.*;
|
||||
public class MockStringTable extends StringTable {
|
||||
|
||||
public MockStringTable(BinaryReader reader) {
|
||||
super(new BinaryReader(new ByteArrayProvider(new byte[4 * 1024]), true /* LE */),
|
||||
StandardCharsets.UTF_8);
|
||||
super(reader, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public void add(int index, String s) throws IOException {
|
||||
|
||||
+2
-2
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package ghidra.app.util.bin.format.dwarf.attribs;
|
||||
|
||||
import static ghidra.app.util.bin.format.dwarf.DWARFSourceLanguage.*;
|
||||
import static ghidra.app.util.bin.format.dwarf.attribs.DWARFAttributeId.*;
|
||||
import static ghidra.app.util.bin.format.dwarf.attribs.DWARFForm.*;
|
||||
import static org.junit.Assert.*;
|
||||
@@ -24,7 +25,6 @@ import java.io.IOException;
|
||||
import org.junit.Test;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.dwarf.DWARFSourceLanguage;
|
||||
import ghidra.app.util.bin.format.dwarf.DWARFTestBase;
|
||||
import ghidra.app.util.bin.format.dwarf.attribs.DWARFAttributeId.AttrDef;
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
@@ -115,7 +115,7 @@ public class DWARFAttributeFactoryTest extends DWARFTestBase {
|
||||
/* guard byte for test */ 0xff);
|
||||
// @formatter:on
|
||||
|
||||
setCompUnit(dwarfProg.addCompUnit(DWARFSourceLanguage.DW_LANG_C, 8 /* dwarf64 */));
|
||||
setCompUnit(dieContainer.addCompUnit(DW_LANG_C, 8 /* dwarf64 */));
|
||||
|
||||
DWARFAttributeValue result1 = read(br, DW_AT_name, DW_FORM_strp);
|
||||
assertTrue("Should be string", result1 instanceof DWARFStringAttribute);
|
||||
|
||||
Reference in New Issue
Block a user