GP-5931 fix problem reading dwarf file info in a DWARF64 file

Deserialization was using the dwarf intSize from the containing compile
unit instead of the dwarf intSize from the DWARFLine unit header.  When
this disagreed with the compUnit's intSize, we would read too much or
too little.
This commit is contained in:
dev747368 2025-08-14 13:35:57 -04:00
parent c0127326f8
commit 46b0b17c74
4 changed files with 31 additions and 17 deletions

View file

@ -177,8 +177,8 @@ public enum DWARFForm {
DWARFForm indirectForm = DWARFForm.of(indirectFormInt);
DWARFAttributeDef<?> indirectAS = context.def().withForm(indirectForm);
DWARFFormContext indirectContext =
new DWARFFormContext(context.reader(), context.compUnit(), indirectAS);
DWARFFormContext indirectContext = new DWARFFormContext(context.reader(),
context.compUnit(), indirectAS, context.dwarfIntSize());
long indirectSize = indirectForm.getSize(indirectContext);
return firstSize + indirectSize;
@ -189,8 +189,8 @@ public enum DWARFForm {
int indirectFormInt = context.reader().readNextUnsignedVarIntExact(LEB128::unsigned);
DWARFForm indirectForm = DWARFForm.of(indirectFormInt);
DWARFAttributeDef<?> indirectAS = context.def().withForm(indirectForm);
DWARFFormContext indirectContext =
new DWARFFormContext(context.reader(), context.compUnit(), indirectAS);
DWARFFormContext indirectContext = new DWARFFormContext(context.reader(),
context.compUnit(), indirectAS, context.dwarfIntSize());
return indirectForm.readValue(indirectContext);
}
},
@ -335,7 +335,7 @@ public enum DWARFForm {
public long getSize(DWARFFormContext context) throws IOException {
switch (size) {
case DWARF_INTSIZE:
return context.compUnit().getIntSize();
return context.dwarfIntSize();
case LEB128_SIZE:
return context.reader().readNext(LEB128::getLength);
case DYNAMIC_SIZE:

View file

@ -16,7 +16,8 @@
package ghidra.app.util.bin.format.dwarf.attribs;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.dwarf.*;
import ghidra.app.util.bin.format.dwarf.DWARFCompilationUnit;
import ghidra.app.util.bin.format.dwarf.DWARFProgram;
/**
* Context given to the {@link DWARFForm#readValue(DWARFFormContext)} method to enable it to
@ -25,15 +26,27 @@ import ghidra.app.util.bin.format.dwarf.*;
* @param reader {@link BinaryReader}
* @param compUnit {@link DWARFCompilationUnit}
* @param def {@link DWARFAttributeDef}
* @param dwarfIntSize size of dwarf serialization ints, either 4 (32 bit dwarf) or
* 8 (64 bit dwarf). Can be different from compUnit's intSize if this context is being used
* to read values from a non-".debuginfo" section that has unit headers that specify an
* independent intSize.
*/
public record DWARFFormContext(BinaryReader reader, DWARFCompilationUnit compUnit,
DWARFAttributeDef<?> def) {
DWARFAttributeDef<?> def, int dwarfIntSize) {
/**
* Creates a new DWARFFormContext, using the compUnit's int size
*
* @param reader stream that will be used to read the dwarf form value
* @param compUnit {@link DWARFCompilationUnit} that contains the value
* @param def identity info about the attribute being read
*/
public DWARFFormContext(BinaryReader reader, DWARFCompilationUnit compUnit,
DWARFAttributeDef<?> def) {
this(reader, compUnit, def, compUnit.getIntSize());
}
DWARFProgram dprog() {
return compUnit.getProgram();
}
int dwarfIntSize() {
return compUnit.getIntSize();
}
}

View file

@ -59,12 +59,13 @@ public class DWARFFile {
* @param reader BinaryReader
* @param defs similar to a DIE's attributespec, a list of DWARFForms that define how values
* will be deserialized from the stream
* @param dwarfIntSize size of serialized dwarf ints (might be different than the CU's dwarfIntSize)
* @param cu {@link DWARFCompilationUnit}
* @return new DWARFFile
* @throws IOException if error reading
*/
public static DWARFFile readV5(BinaryReader reader, List<DWARFLineContentType.Def> defs,
DWARFCompilationUnit cu) throws IOException {
int dwarfIntSize, DWARFCompilationUnit cu) throws IOException {
String name = null;
int directoryIndex = -1;
@ -72,7 +73,7 @@ public class DWARFFile {
long length = 0;
byte[] md5 = null;
for (DWARFLineContentType.Def def : defs) {
DWARFFormContext context = new DWARFFormContext(reader, cu, def);
DWARFFormContext context = new DWARFFormContext(reader, cu, def, dwarfIntSize);
DWARFAttributeValue val = def.getAttributeForm().readValue(context);
switch (def.getAttributeId()) {

View file

@ -168,7 +168,7 @@ public class DWARFLine {
// read the directories, which are defined the same way files are
int directories_count = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
for (int i = 0; i < directories_count; i++) {
DWARFFile dir = DWARFFile.readV5(reader, dirFormatDefs, cu);
DWARFFile dir = DWARFFile.readV5(reader, dirFormatDefs, result.intSize, cu);
dir = fixupDir(dir, defaultCompDir);
result.directories.add(dir);
}
@ -182,7 +182,7 @@ public class DWARFLine {
int file_names_count = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
for (int i = 0; i < file_names_count; i++) {
DWARFFile dir = DWARFFile.readV5(reader, fileFormatDefs, cu);
DWARFFile dir = DWARFFile.readV5(reader, fileFormatDefs, result.intSize, cu);
result.files.add(dir);
}
}