From 70fcbcf54bbb039abee6f4bbb3e125dc9b118dc4 Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Tue, 4 Jul 2023 10:17:16 +0200 Subject: [PATCH] LibELF+readelf: Add missing constants for dynamic relocations These should cover all relocation types we can possibly see in an x86_64 or AArch64 final linked ELF image. --- Userland/Libraries/LibELF/DynamicLoader.cpp | 2 +- Userland/Libraries/LibELF/ELFABI.h | 38 +++++++++++++++++++- Userland/Utilities/readelf.cpp | 40 ++++++++++----------- 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index 718a9406c2..cb9a9fea79 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -599,7 +599,7 @@ DynamicLoader::RelocationResult DynamicLoader::do_direct_relocation(DynamicObjec *patch_ptr += m_dynamic_object->base_address().get(); break; } - case R_AARCH64_TLS_TPREL64: + case R_AARCH64_TLS_TPREL: case R_X86_64_TPOFF64: { auto symbol = relocation.symbol(); FlatPtr symbol_value; diff --git a/Userland/Libraries/LibELF/ELFABI.h b/Userland/Libraries/LibELF/ELFABI.h index bc5f9c5f6d..1f54afe89f 100644 --- a/Userland/Libraries/LibELF/ELFABI.h +++ b/Userland/Libraries/LibELF/ELFABI.h @@ -816,15 +816,51 @@ struct elf_args { #define R_X86_64_NONE 0 #define R_X86_64_64 1 +#define R_X86_64_COPY 5 #define R_X86_64_GLOB_DAT 6 #define R_X86_64_JUMP_SLOT 7 #define R_X86_64_RELATIVE 8 +#define R_X86_64_DTPMOD64 16 +#define R_X86_64_DTPOFF64 17 #define R_X86_64_TPOFF64 18 +#define R_X86_64_TLSDESC 36 #define R_X86_64_IRELATIVE 37 +#define __ENUMERATE_X86_64_DYNAMIC_RELOCS(R) \ + R(R_X86_64_NONE) \ + R(R_X86_64_64) \ + R(R_X86_64_COPY) \ + R(R_X86_64_GLOB_DAT) \ + R(R_X86_64_JUMP_SLOT) \ + R(R_X86_64_RELATIVE) \ + R(R_X86_64_DTPMOD64) \ + R(R_X86_64_DTPOFF64) \ + R(R_X86_64_TPOFF64) \ + R(R_X86_64_TLSDESC) \ + R(R_X86_64_IRELATIVE) + +/* 5.7.12 Dynamic relocations https://github.com/ARM-software/abi-aa/blob/2023q1-release/aaelf64/aaelf64.rst#dynamic-relocations */ +#define R_AARCH64_NONE 0 #define R_AARCH64_ABS64 257 +#define R_AARCH64_COPY 1024 #define R_AARCH64_GLOB_DAT 1025 #define R_AARCH64_JUMP_SLOT 1026 #define R_AARCH64_RELATIVE 1027 -#define R_AARCH64_TLS_TPREL64 1030 +#define R_AARCH64_TLS_DTPMOD 1028 +#define R_AARCH64_TLS_DTPREL 1029 +#define R_AARCH64_TLS_TPREL 1030 +#define R_AARCH64_TLSDESC 1031 #define R_AARCH64_IRELATIVE 1032 + +#define __ENUMERATE_AARCH64_DYNAMIC_RELOCS(R) \ + R(R_AARCH64_NONE) \ + R(R_AARCH64_ABS64) \ + R(R_AARCH64_COPY) \ + R(R_AARCH64_GLOB_DAT) \ + R(R_AARCH64_JUMP_SLOT) \ + R(R_AARCH64_RELATIVE) \ + R(R_AARCH64_TLS_DTPMOD) \ + R(R_AARCH64_TLS_DTPREL) \ + R(R_AARCH64_TLS_TPREL) \ + R(R_AARCH64_TLSDESC) \ + R(R_AARCH64_IRELATIVE) diff --git a/Userland/Utilities/readelf.cpp b/Userland/Utilities/readelf.cpp index 97cbabb408..bbfb5e6990 100644 --- a/Userland/Utilities/readelf.cpp +++ b/Userland/Utilities/readelf.cpp @@ -184,26 +184,22 @@ static char const* object_symbol_binding_to_string(ElfW(Word) type) } } -static char const* object_relocation_type_to_string(ElfW(Word) type) +static char const* object_relocation_type_to_string(ElfW(Half) machine, ElfW(Word) type) { - switch (type) { -#if ARCH(X86_64) - case R_X86_64_NONE: - return "R_X86_64_NONE"; - case R_X86_64_64: - return "R_X86_64"; - case R_X86_64_GLOB_DAT: - return "R_x86_64_GLOB_DAT"; - case R_X86_64_JUMP_SLOT: - return "R_X86_64_JUMP_SLOT"; - case R_X86_64_RELATIVE: - return "R_X86_64_RELATIVE"; - case R_X86_64_TPOFF64: - return "R_X86_64_TPOFF64"; -#endif - default: - return "(?)"; +#define ENUMERATE_RELOCATION(name) \ + case name: \ + return #name; + if (machine == EM_X86_64) { + switch (type) { + __ENUMERATE_X86_64_DYNAMIC_RELOCS(ENUMERATE_RELOCATION) + } + } else if (machine == EM_AARCH64) { + switch (type) { + __ENUMERATE_AARCH64_DYNAMIC_RELOCS(ENUMERATE_RELOCATION) + } } +#undef ENUMERATE_RELOCATION + return "(?)"; } ErrorOr serenity_main(Main::Arguments arguments) @@ -483,9 +479,9 @@ ErrorOr serenity_main(Main::Arguments arguments) } else { outln("Relocation section '{}' at offset {:#08x} contains {} entries:", object->relocation_section().name(), object->relocation_section().offset(), object->relocation_section().entry_count()); outln(" Offset{} Type Sym Value{} Sym Name", addr_padding, addr_padding); - object->relocation_section().for_each_relocation([](const ELF::DynamicObject::Relocation& reloc) { + object->relocation_section().for_each_relocation([&](const ELF::DynamicObject::Relocation& reloc) { out(" {:p} ", reloc.offset()); - out(" {:18} ", object_relocation_type_to_string(reloc.type())); + out(" {:18} ", object_relocation_type_to_string(header.e_machine, reloc.type())); out(" {:p} ", reloc.symbol().value()); out(" {}", reloc.symbol().name()); outln(); @@ -498,9 +494,9 @@ ErrorOr serenity_main(Main::Arguments arguments) } else { outln("Relocation section '{}' at offset {:#08x} contains {} entries:", object->plt_relocation_section().name(), object->plt_relocation_section().offset(), object->plt_relocation_section().entry_count()); outln(" Offset{} Type Sym Value{} Sym Name", addr_padding, addr_padding); - object->plt_relocation_section().for_each_relocation([](const ELF::DynamicObject::Relocation& reloc) { + object->plt_relocation_section().for_each_relocation([&](const ELF::DynamicObject::Relocation& reloc) { out(" {:p} ", reloc.offset()); - out(" {:18} ", object_relocation_type_to_string(reloc.type())); + out(" {:18} ", object_relocation_type_to_string(header.e_machine, reloc.type())); out(" {:p} ", reloc.symbol().value()); out(" {}", reloc.symbol().name()); outln();