From 781646e0effc964e573d51a8a5cc1969f9be0c3c Mon Sep 17 00:00:00 2001 From: Jonah Graham Date: Wed, 7 Dec 2022 20:12:27 -0500 Subject: [PATCH] Account for new header layout in DWARF v5 Fixes #198 --- .../org/eclipse/cdt/utils/elf/ElfTest.java | 57 ++++++++++++------ .../resources/elf/unit_test/Makefile | 11 +++- .../resources/elf/unit_test/simple-dwarf4.elf | Bin 0 -> 16736 bytes .../resources/elf/unit_test/simple-dwarf5.elf | Bin 0 -> 16824 bytes .../eclipse/cdt/utils/debug/dwarf/Dwarf.java | 35 ++++++++--- 5 files changed, 76 insertions(+), 27 deletions(-) create mode 100755 core/org.eclipse.cdt.core.tests/resources/elf/unit_test/simple-dwarf4.elf create mode 100755 core/org.eclipse.cdt.core.tests/resources/elf/unit_test/simple-dwarf5.elf diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/elf/ElfTest.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/elf/ElfTest.java index ba525d7db01..6bc84e7e2f2 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/elf/ElfTest.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/elf/ElfTest.java @@ -40,25 +40,41 @@ public class ElfTest { private static final String SYMTAB_NAME = ".symtab"; - @Parameters(name = "{0}") - public static Collection elfArchitectures() { - return Arrays.asList(new Object[][] { - { "BE32", "ppc", "resources/elf/unit_test/simple-be32.elf", 35, "0x00000000", "0x100001a8", 75, - "0x10000518" }, - { "BE64", "ppc64", "resources/elf/unit_test/simple-be64.elf", 34, "0x0000000000000000", - "0x0000000010000240", 69, "0x000000001001fea0" }, - { "LE32", "x86", "resources/elf/unit_test/simple-le32.elf", 36, "0x00000000", "0x080481cc", 70, - "0x080483e5" }, - { "LE64", "x86_64", "resources/elf/unit_test/simple-le64.elf", 36, "0x0000000000000000", - "0x00000000004002b8", 68, "0x00000000004004e4" }, }); - } - - private static final Collection functions = Arrays.asList("", "crtstuff.c", "simple.c", "crtstuff.c", + /** + * Different elfs, being built on different architectures, etc may have different + * contents in their symbol tables. + * + * See {@link #elfArchitectures()} for the mapping of which elf files contain which + * sets of functions + */ + private static final Collection functions1 = Arrays.asList("", "crtstuff.c", "simple.c", "crtstuff.c", "_ITM_deregisterTMCloneTable", "__gmon_start__", "_Jv_RegisterClasses", "_ITM_registerTMCloneTable", "_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__", "__JCR_LIST__", "__JCR_END__", "_DYNAMIC", "data_start", "__data_start", "__dso_handle", "_edata", "__bss_start", "__TMC_END__", "_end"); + private static final Collection 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 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 arch; @@ -68,9 +84,12 @@ public class ElfTest { private final String dynsymBaseAddress; private final int nbSymbols; private final String mainAddress; + private final int elfType; + private final Collection functions; - public ElfTest(String mArch, String architecture, String path, int sections, String symBaseAddress, - String dynBaseAddress, int symbolCount, String mainAddr) throws IOException { + public ElfTest(String testName, String mArch, String architecture, String path, int sections, String symBaseAddress, + String dynBaseAddress, int symbolCount, String mainAddr, int elfType, Collection functions) + throws IOException { memoryArchitecture = mArch; nbSections = sections; elf = new Elf(path); @@ -79,6 +98,8 @@ public class ElfTest { dynsymBaseAddress = dynBaseAddress; nbSymbols = symbolCount; mainAddress = mainAddr; + this.elfType = elfType; + this.functions = functions; } /** @@ -92,12 +113,10 @@ public class ElfTest { assertNotNull(sectionByName); assertEquals(arch + ": " + "symbol table", SYMTAB_NAME, sectionByName.toString()); assertEquals(arch + ": " + "binary address", symtabBaseAddress, sectionByName.sh_addr.toHexAddressString()); - assertEquals(arch + ": " + "sh_name", 1, sectionByName.sh_name); sectionByName = elf.getSectionByName(".dynsym"); assertNotNull(sectionByName); assertEquals(arch + ": " + "dynamic symbols", ".dynsym", sectionByName.toString()); 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, attributes.getAddressFactory().getMax().getValue()); 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 diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/unit_test/Makefile b/core/org.eclipse.cdt.core.tests/resources/elf/unit_test/Makefile index 3bf7cf61345..54f4f89646a 100644 --- a/core/org.eclipse.cdt.core.tests/resources/elf/unit_test/Makefile +++ b/core/org.eclipse.cdt.core.tests/resources/elf/unit_test/Makefile @@ -1,2 +1,11 @@ #just an example -gcc simple.c -g -o simple.elf \ No newline at end of file +# 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 diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/unit_test/simple-dwarf4.elf b/core/org.eclipse.cdt.core.tests/resources/elf/unit_test/simple-dwarf4.elf new file mode 100755 index 0000000000000000000000000000000000000000..021d2ab7ed199dc1db099b6e6450f7a817713fea GIT binary patch literal 16736 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 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) + header.abbreviationOffset = (int) read_8_bytes(data); + else + header.abbreviationOffset = read_4_bytes(data); + header.addressSize = data.get(); + } if (printEnabled) { 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 // contribution for that compilation unit, not including the length field itself. 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); - 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) System.out.println();