1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 06:02:11 +02:00

Account for new header layout in DWARF v5

Fixes #198
This commit is contained in:
Jonah Graham 2022-12-07 20:12:27 -05:00 committed by John Dallaway
parent ded8b708cc
commit 781646e0ef
5 changed files with 76 additions and 27 deletions

View file

@ -40,25 +40,41 @@ public class ElfTest {
private static final String SYMTAB_NAME = ".symtab"; private static final String SYMTAB_NAME = ".symtab";
@Parameters(name = "{0}") /**
public static Collection<Object[]> elfArchitectures() { * Different elfs, being built on different architectures, etc may have different
return Arrays.asList(new Object[][] { * contents in their symbol tables.
{ "BE32", "ppc", "resources/elf/unit_test/simple-be32.elf", 35, "0x00000000", "0x100001a8", 75, *
"0x10000518" }, * See {@link #elfArchitectures()} for the mapping of which elf files contain which
{ "BE64", "ppc64", "resources/elf/unit_test/simple-be64.elf", 34, "0x0000000000000000", * sets of functions
"0x0000000010000240", 69, "0x000000001001fea0" }, */
{ "LE32", "x86", "resources/elf/unit_test/simple-le32.elf", 36, "0x00000000", "0x080481cc", 70, private static final Collection<String> functions1 = Arrays.asList("", "crtstuff.c", "simple.c", "crtstuff.c",
"0x080483e5" },
{ "LE64", "x86_64", "resources/elf/unit_test/simple-le64.elf", 36, "0x0000000000000000",
"0x00000000004002b8", 68, "0x00000000004004e4" }, });
}
private static final Collection<String> functions = Arrays.asList("", "crtstuff.c", "simple.c", "crtstuff.c",
"_ITM_deregisterTMCloneTable", "__gmon_start__", "_Jv_RegisterClasses", "_ITM_registerTMCloneTable", "_ITM_deregisterTMCloneTable", "__gmon_start__", "_Jv_RegisterClasses", "_ITM_registerTMCloneTable",
"_init", "_start", "deregister_tm_clones", "register_tm_clones", "__do_global_dtors_aux", "frame_dummy", "_init", "_start", "deregister_tm_clones", "register_tm_clones", "__do_global_dtors_aux", "frame_dummy",
"function", "main", "__libc_csu_init", "__libc_csu_fini", "_fini", "_IO_stdin_used", "__FRAME_END__", "function", "main", "__libc_csu_init", "__libc_csu_fini", "_fini", "_IO_stdin_used", "__FRAME_END__",
"__JCR_LIST__", "__JCR_END__", "_DYNAMIC", "data_start", "__data_start", "__dso_handle", "_edata", "__JCR_LIST__", "__JCR_END__", "_DYNAMIC", "data_start", "__data_start", "__dso_handle", "_edata",
"__bss_start", "__TMC_END__", "_end"); "__bss_start", "__TMC_END__", "_end");
private static final Collection<String> functions2 = Arrays.asList("", "crtstuff.c", "simple.c", "crtstuff.c",
"_ITM_deregisterTMCloneTable", "__gmon_start__", "_ITM_registerTMCloneTable", "_init", "_start",
"deregister_tm_clones", "register_tm_clones", "__do_global_dtors_aux", "frame_dummy", "function", "main",
"_fini", "_IO_stdin_used", "__FRAME_END__", "_DYNAMIC", "data_start", "__data_start", "__dso_handle",
"_edata", "__bss_start", "__TMC_END__", "_end");
@Parameters(name = "{0}")
public static Collection<Object[]> elfArchitectures() {
return Arrays.asList(new Object[][] {
{ "BE32", "BE32", "ppc", "resources/elf/unit_test/simple-be32.elf", 35, "0x00000000", "0x100001a8", 75,
"0x10000518", Attribute.ELF_TYPE_EXE, functions1 },
{ "BE64", "BE64", "ppc64", "resources/elf/unit_test/simple-be64.elf", 34, "0x0000000000000000",
"0x0000000010000240", 69, "0x000000001001fea0", Attribute.ELF_TYPE_EXE, functions1 },
{ "LE32", "LE32", "x86", "resources/elf/unit_test/simple-le32.elf", 36, "0x00000000", "0x080481cc", 70,
"0x080483e5", Attribute.ELF_TYPE_EXE, functions1 },
{ "LE64", "LE64", "x86_64", "resources/elf/unit_test/simple-le64.elf", 36, "0x0000000000000000",
"0x00000000004002b8", 68, "0x00000000004004e4", Attribute.ELF_TYPE_EXE, functions1 },
{ "DWARF4", "LE64", "x86_64", "resources/elf/unit_test/simple-dwarf4.elf", 34, "0x0000000000000000",
"0x00000000000003d8", 34, "0x000000000000113b", Attribute.ELF_TYPE_SHLIB, functions2 },
{ "DWARF5", "LE64", "x86_64", "resources/elf/unit_test/simple-dwarf5.elf", 35, "0x0000000000000000",
"0x00000000000003d8", 34, "0x000000000000113b", Attribute.ELF_TYPE_SHLIB, functions2 }, });
}
private final String memoryArchitecture; private final String memoryArchitecture;
private final String arch; private final String arch;
@ -68,9 +84,12 @@ public class ElfTest {
private final String dynsymBaseAddress; private final String dynsymBaseAddress;
private final int nbSymbols; private final int nbSymbols;
private final String mainAddress; private final String mainAddress;
private final int elfType;
private final Collection<String> functions;
public ElfTest(String mArch, String architecture, String path, int sections, String symBaseAddress, public ElfTest(String testName, String mArch, String architecture, String path, int sections, String symBaseAddress,
String dynBaseAddress, int symbolCount, String mainAddr) throws IOException { String dynBaseAddress, int symbolCount, String mainAddr, int elfType, Collection<String> functions)
throws IOException {
memoryArchitecture = mArch; memoryArchitecture = mArch;
nbSections = sections; nbSections = sections;
elf = new Elf(path); elf = new Elf(path);
@ -79,6 +98,8 @@ public class ElfTest {
dynsymBaseAddress = dynBaseAddress; dynsymBaseAddress = dynBaseAddress;
nbSymbols = symbolCount; nbSymbols = symbolCount;
mainAddress = mainAddr; mainAddress = mainAddr;
this.elfType = elfType;
this.functions = functions;
} }
/** /**
@ -92,12 +113,10 @@ public class ElfTest {
assertNotNull(sectionByName); assertNotNull(sectionByName);
assertEquals(arch + ": " + "symbol table", SYMTAB_NAME, sectionByName.toString()); assertEquals(arch + ": " + "symbol table", SYMTAB_NAME, sectionByName.toString());
assertEquals(arch + ": " + "binary address", symtabBaseAddress, sectionByName.sh_addr.toHexAddressString()); assertEquals(arch + ": " + "binary address", symtabBaseAddress, sectionByName.sh_addr.toHexAddressString());
assertEquals(arch + ": " + "sh_name", 1, sectionByName.sh_name);
sectionByName = elf.getSectionByName(".dynsym"); sectionByName = elf.getSectionByName(".dynsym");
assertNotNull(sectionByName); assertNotNull(sectionByName);
assertEquals(arch + ": " + "dynamic symbols", ".dynsym", sectionByName.toString()); assertEquals(arch + ": " + "dynamic symbols", ".dynsym", sectionByName.toString());
assertEquals(arch + ": " + "binary address", dynsymBaseAddress, sectionByName.sh_addr.toHexAddressString()); assertEquals(arch + ": " + "binary address", dynsymBaseAddress, sectionByName.sh_addr.toHexAddressString());
assertEquals(arch + ": " + "sh_name", 78L, sectionByName.sh_name);
} }
/** /**
@ -150,7 +169,7 @@ public class ElfTest {
memoryArchitecture.endsWith("32") ? unsigned32BitAddress : unsigned64BitAddress, memoryArchitecture.endsWith("32") ? unsigned32BitAddress : unsigned64BitAddress,
attributes.getAddressFactory().getMax().getValue()); attributes.getAddressFactory().getMax().getValue());
assertEquals(arch + ": " + "debug type", Attribute.DEBUG_TYPE_DWARF, attributes.getDebugType()); assertEquals(arch + ": " + "debug type", Attribute.DEBUG_TYPE_DWARF, attributes.getDebugType());
assertEquals(arch + ": " + "elf type", Attribute.ELF_TYPE_EXE, attributes.getType()); assertEquals(arch + ": " + "elf type", elfType, attributes.getType());
} }
@Test @Test

View file

@ -1,2 +1,11 @@
#just an example #just an example
gcc simple.c -g -o simple.elf # gcc simple.c -g -o simple.elf
simple-dwarf4.elf:
gcc simple.c -g -gdwarf-4 -o simple-dwarf4.elf
# This needs to run on a GCC that fully supports DWARF v5, e.g. Ubuntu 22.04
# e.g. docker run --rm -it -v $PWD:/work -w /work ubuntu:22.04 /bin/bash
# apt-get update && apt-get install -y --no-install-recommends build-essential
simple-dwarf5.elf:
gcc simple.c -g -gdwarf-5 -o simple-dwarf5.elf

View file

@ -460,11 +460,22 @@ public class Dwarf implements AutoCloseable {
header.offsetSize = sectionLength.offsetSize; header.offsetSize = sectionLength.offsetSize;
header.version = read_2_bytes(data); header.version = read_2_bytes(data);
if (header.version >= 5) {
// XXX: We don't use this new field in DWARF v5 yet
var unit_type = data.get();
header.addressSize = data.get();
if (header.offsetSize == 8)
header.abbreviationOffset = (int) read_8_bytes(data);
else
header.abbreviationOffset = read_4_bytes(data);
} else {
if (header.offsetSize == 8) if (header.offsetSize == 8)
header.abbreviationOffset = (int) read_8_bytes(data); header.abbreviationOffset = (int) read_8_bytes(data);
else else
header.abbreviationOffset = read_4_bytes(data); header.abbreviationOffset = read_4_bytes(data);
header.addressSize = data.get(); header.addressSize = data.get();
}
if (printEnabled) { if (printEnabled) {
System.out.println("Compilation Unit @ " + Long.toHexString(data.position())); //$NON-NLS-1$ System.out.println("Compilation Unit @ " + Long.toHexString(data.position())); //$NON-NLS-1$
@ -476,10 +487,20 @@ public class Dwarf implements AutoCloseable {
// A 4-byte or 12-byte unsigned integer representing the length of the .debug_info // A 4-byte or 12-byte unsigned integer representing the length of the .debug_info
// contribution for that compilation unit, not including the length field itself. // contribution for that compilation unit, not including the length field itself.
ByteBuffer entryBuffer = data.slice(); ByteBuffer entryBuffer = data.slice();
entryBuffer.limit(((int) header.length) - (header.offsetSize == 8 ? 11 : 7)); int newLimit = ((int) header.length) - (header.offsetSize == 8 ? 11 : 7);
if (header.version >= 5) {
// account for new field in DWARF v5
newLimit -= 1;
}
entryBuffer.limit(newLimit);
parseDebugInfoEntry(requestor, entryBuffer, abbrevs, header); parseDebugInfoEntry(requestor, entryBuffer, abbrevs, header);
data.position(data.position() + ((int) header.length) - (header.offsetSize == 8 ? 11 : 7)); int newLimit2 = ((int) header.length) - (header.offsetSize == 8 ? 11 : 7);
if (header.version >= 5) {
// account for new field in DWARF v5
newLimit2 -= 1;
}
data.position(data.position() + newLimit2);
if (printEnabled) if (printEnabled)
System.out.println(); System.out.println();