From 62589988718e8fac4fb39ec5037f51839f05951b Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 24 Aug 2023 00:16:51 +0200 Subject: [PATCH] 0.189-5 - Add elfutils-0.189-relr.patch --- elfutils-0.189-relr.patch | 446 ++++++++++++++++++++++++++++++++++++++ elfutils.spec | 7 +- 2 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 elfutils-0.189-relr.patch diff --git a/elfutils-0.189-relr.patch b/elfutils-0.189-relr.patch new file mode 100644 index 0000000..29a7b73 --- /dev/null +++ b/elfutils-0.189-relr.patch @@ -0,0 +1,446 @@ +commit 6ba977ed6c7ac6e51350f2093ebe0b90ff89f90c +Author: Mark Wielaard +Date: Sun Jul 23 23:14:31 2023 +0200 + + libelf, readelf, elflint: Add RELR support + + Handle RELR as defined here: + https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/YT2RrjpMAwAJ + + Introduce new ELF_T_RELR Elf_Type and handle it for SHT_RELR. Check + various properties in elflint. Print RELR relocations in + readelf. Just the entries with -U. Just the addresses with -N. And + addresses pluse symbol/offsets by default. + + * libebl/eblsectiontypename.c (ebl_section_type_name): Add RELR + to knownstype. + * libelf/elf32_updatenull.c (updatenull_wrlock): Handle + sh_entsize for SHT_RELR. + * libelf/gelf.h (Gelf_Relr): New typedef for Elf64_Relr. + * libelf/gelf_fsize.c (__libelf_type_sizes): Add ELF_T_RELR. + * libelf/gelf_xlate.c (__elf_xfctstom): Likewise. + * libelf/gelf_xlate.h: Add RELR as FUNDAMENTAL. + * libelf/libelf.h (Elf_Type): Add ELF_T_RELR. + * libelf/libelfP.h: Define ELF32_FSZ_RELR and ELF64_FSZ_RELR. + * src/elflint.c (check_reloc_shdr): Check she_entsize for + ELF_T_RELR. + (check_relr): New function. + (check_dynamic): Handle DT_RELR. + (special_sections): Add SHT_RELR. + (check_sections): Call check_relr. + * src/readelf.c (print_relocs): Also accept a Dwfl_Module. + (handle_relocs_relr): New function. + (print_dwarf_addr): Make static and declare early. + (process_elf_file): Pass dwflmod to print_relocs. + (handle_dynamic): Handle DT_RELRSZ and DTRELRENT. + + Signed-off-by: Mark Wielaard + +diff --git a/libebl/eblsectiontypename.c b/libebl/eblsectiontypename.c +index 2008b95a..ade25d4a 100644 +--- a/libebl/eblsectiontypename.c ++++ b/libebl/eblsectiontypename.c +@@ -61,7 +61,8 @@ ebl_section_type_name (Ebl *ebl, int section, char *buf, size_t len) + KNOWNSTYPE (FINI_ARRAY), + KNOWNSTYPE (PREINIT_ARRAY), + KNOWNSTYPE (GROUP), +- KNOWNSTYPE (SYMTAB_SHNDX) ++ KNOWNSTYPE (SYMTAB_SHNDX), ++ KNOWNSTYPE (RELR) + }; + + /* Handle standard names. */ +diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c +index 6c06e5e4..c5d26b00 100644 +--- a/libelf/elf32_updatenull.c ++++ b/libelf/elf32_updatenull.c +@@ -256,6 +256,9 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) + case SHT_SUNW_syminfo: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1); + break; ++ case SHT_RELR: ++ sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELR, 1); ++ break; + default: + break; + } +diff --git a/libelf/gelf.h b/libelf/gelf.h +index 7a3c87aa..f032d7e1 100644 +--- a/libelf/gelf.h ++++ b/libelf/gelf.h +@@ -82,6 +82,9 @@ typedef Elf64_Rel GElf_Rel; + /* Relocation table entry with addend (in section of type SHT_RELA). */ + typedef Elf64_Rela GElf_Rela; + ++/* Relative relocation entry (in section of type SHT_RELR). */ ++typedef Elf64_Relr Gelf_Relr; ++ + /* Program segment header. */ + typedef Elf64_Phdr GElf_Phdr; + +diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c +index 493d7916..63bcbae5 100644 +--- a/libelf/gelf_fsize.c ++++ b/libelf/gelf_fsize.c +@@ -69,7 +69,8 @@ const size_t __libelf_type_sizes[ELFCLASSNUM - 1][ELF_T_NUM] = + [ELF_T_LIB] = sizeof (ElfW2(LIBELFBITS, Ext_Lib)), \ + [ELF_T_AUXV] = sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)), \ + [ELF_T_CHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Chdr)), \ +- [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD) ++ [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD), \ ++ [ELF_T_RELR] = ELFW2(LIBELFBITS, FSZ_RELR) + TYPE_SIZES (32) + }, + [ELFCLASS64 - 1] = { +diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c +index d8ad0634..749da1a1 100644 +--- a/libelf/gelf_xlate.c ++++ b/libelf/gelf_xlate.c +@@ -204,7 +204,8 @@ const xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM] = + [ELF_T_MOVE] = ElfW2(Bits, cvt_Move), \ + [ELF_T_LIB] = ElfW2(Bits, cvt_Lib), \ + [ELF_T_AUXV] = ElfW2(Bits, cvt_auxv_t), \ +- [ELF_T_CHDR] = ElfW2(Bits, cvt_chdr) ++ [ELF_T_CHDR] = ElfW2(Bits, cvt_chdr), \ ++ [ELF_T_RELR] = ElfW2(Bits, cvt_Relr) + define_xfcts (32), + [ELF_T_GNUHASH] = Elf32_cvt_Word + }, +diff --git a/libelf/gelf_xlate.h b/libelf/gelf_xlate.h +index 3c0e4bf6..d5511c34 100644 +--- a/libelf/gelf_xlate.h ++++ b/libelf/gelf_xlate.h +@@ -36,6 +36,7 @@ FUNDAMENTAL (WORD, Word, LIBELFBITS); + FUNDAMENTAL (SWORD, Sword, LIBELFBITS); + FUNDAMENTAL (XWORD, Xword, LIBELFBITS); + FUNDAMENTAL (SXWORD, Sxword, LIBELFBITS); ++FUNDAMENTAL (RELR, Relr, LIBELFBITS); + + /* The structured types. */ + TYPE (Ehdr, LIBELFBITS) +diff --git a/libelf/libelf.h b/libelf/libelf.h +index 2374a48a..2837db72 100644 +--- a/libelf/libelf.h ++++ b/libelf/libelf.h +@@ -124,6 +124,7 @@ typedef enum + ELF_T_CHDR, /* Compressed, Elf32_Chdr, Elf64_Chdr, ... */ + ELF_T_NHDR8, /* Special GNU Properties note. Same as Nhdr, + except padding. */ ++ ELF_T_RELR, /* Relative relocation entry. */ + /* Keep this the last entry. */ + ELF_T_NUM + } Elf_Type; +diff --git a/libelf/libelfP.h b/libelf/libelfP.h +index d3c241e5..96476064 100644 +--- a/libelf/libelfP.h ++++ b/libelf/libelfP.h +@@ -63,6 +63,7 @@ + #define ELF32_FSZ_SWORD 4 + #define ELF32_FSZ_XWORD 8 + #define ELF32_FSZ_SXWORD 8 ++#define ELF32_FSZ_RELR 4 + + /* Same for 64 bits objects. */ + #define ELF64_FSZ_ADDR 8 +@@ -72,6 +73,7 @@ + #define ELF64_FSZ_SWORD 4 + #define ELF64_FSZ_XWORD 8 + #define ELF64_FSZ_SXWORD 8 ++#define ELF64_FSZ_RELR 8 + + + /* This is an extension of the ELF_F_* enumeration. The values here are +diff --git a/src/elflint.c b/src/elflint.c +index dd42dcb4..864de710 100644 +--- a/src/elflint.c ++++ b/src/elflint.c +@@ -1,5 +1,6 @@ + /* Pedantic checking of ELF files compliance with gABI/psABI spec. + Copyright (C) 2001-2015, 2017, 2018 Red Hat, Inc. ++ Copyright (C) 2023 Mark J. Wielaard + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + +@@ -1291,10 +1292,20 @@ section [%2d] '%s': no relocations for merge-able string sections possible\n"), + + size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT); + if (shdr->sh_entsize != sh_entsize) +- ERROR (_(reltype == ELF_T_RELA ? "\ +-section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ +-section [%2d] '%s': section entry size does not match ElfXX_Rel\n"), +- idx, section_name (ebl, idx)); ++ { ++ if (reltype == ELF_T_RELA) ++ ERROR ("\ ++section [%2d] '%s': section entry size does not match ElfXX_Rela\n", ++ idx, section_name (ebl, idx)); ++ else if (reltype == ELF_T_REL) ++ ERROR ("\ ++section [%2d] '%s': section entry size does not match ElfXX_Rel\n", ++ idx, section_name (ebl, idx)); ++ else ++ ERROR ("\ ++section [%2d] '%s': section entry size does not match ElfXX_Relr\n", ++ idx, section_name (ebl, idx)); ++ } + + /* In preparation of checking whether relocations are text + relocations or not we need to determine whether the file is +@@ -1590,6 +1601,32 @@ section [%2d] '%s': cannot get relocation %zu: %s\n"), + } + } + ++static void ++check_relr (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) ++{ ++ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); ++ if (data == NULL) ++ { ++ ERROR (_("section [%2d] '%s': cannot get section data\n"), ++ idx, section_name (ebl, idx)); ++ return; ++ } ++ ++ /* Check the fields of the section header. */ ++ GElf_Shdr destshdr_mem; ++ GElf_Shdr *destshdr = NULL; ++ struct loaded_segment *loaded = NULL; ++ check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELR, &destshdr, ++ &destshdr_mem, &loaded); ++ ++ /* Just throw them away. */ ++ while (loaded != NULL) ++ { ++ struct loaded_segment *old = loaded; ++ loaded = loaded->next; ++ free (old); ++ } ++} + + /* Number of dynamic sections. */ + static int ndynamic; +@@ -1780,6 +1817,7 @@ section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] ' + case DT_PLTGOT: + case DT_REL: + case DT_RELA: ++ case DT_RELR: + case DT_SYMBOLIC: + case DT_SYMTAB: + case DT_VERDEF: +@@ -3660,6 +3698,7 @@ static const struct + { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests + { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, + { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests ++ { ".relr", 5, SHT_RELR, atleast, 0, SHF_ALLOC }, // XXX more tests + { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests + { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, + { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, +@@ -4182,6 +4221,10 @@ section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), + check_rel (ebl, ehdr, shdr, cnt); + break; + ++ case SHT_RELR: ++ check_relr (ebl, ehdr, shdr, cnt); ++ break; ++ + case SHT_DYNAMIC: + check_dynamic (ebl, ehdr, shdr, cnt); + break; +diff --git a/src/readelf.c b/src/readelf.c +index eda0ce09..db31ad09 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -1,5 +1,6 @@ + /* Print information from ELF file in human-readable form. + Copyright (C) 1999-2018 Red Hat, Inc. ++ Copyright (C) 2023 Mark J. Wielaard + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify +@@ -302,11 +302,13 @@ + static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); + static void print_scngrp (Ebl *ebl); + static void print_dynamic (Ebl *ebl); +-static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); ++static void print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr); + static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, + GElf_Shdr *shdr); + static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, + GElf_Shdr *shdr); ++static void handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, ++ GElf_Shdr *shdr); + static bool print_symtab (Ebl *ebl, int type); + static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); + static void print_verinfo (Ebl *ebl); +@@ -336,6 +339,8 @@ static void dump_data (Ebl *ebl); + static void dump_strings (Ebl *ebl); + static void print_strings (Ebl *ebl); + static void dump_archive_index (Elf *, const char *); ++static void print_dwarf_addr (Dwfl_Module *dwflmod, int address_size, ++ Dwarf_Addr address, Dwarf_Addr raw); + + enum dyn_idx + { +@@ -1052,7 +1057,7 @@ process_elf_file (Dwfl_Module *dwflmod, int fd) + if (print_dynamic_table) + print_dynamic (ebl); + if (print_relocations) +- print_relocs (pure_ebl, ehdr); ++ print_relocs (pure_ebl, dwflmod, ehdr); + if (print_histogram) + handle_hash (ebl); + if (print_symbol_table || print_dynsym_table) +@@ -1971,9 +1976,11 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) + case DT_RELASZ: + case DT_STRSZ: + case DT_RELSZ: ++ case DT_RELRSZ: + case DT_RELAENT: + case DT_SYMENT: + case DT_RELENT: ++ case DT_RELRENT: + case DT_PLTPADSZ: + case DT_MOVEENT: + case DT_MOVESZ: +@@ -2049,7 +2056,7 @@ print_dynamic (Ebl *ebl) + + /* Print relocations. */ + static void +-print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) ++print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr) + { + /* Find all relocation sections and handle them. */ + Elf_Scn *scn = NULL; +@@ -2066,6 +2073,8 @@ print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) + handle_relocs_rel (ebl, ehdr, scn, shdr); + else if (shdr->sh_type == SHT_RELA) + handle_relocs_rela (ebl, ehdr, scn, shdr); ++ else if (shdr->sh_type == SHT_RELR) ++ handle_relocs_relr (ebl, mod, scn, shdr); + } + } + } +@@ -2454,6 +2463,114 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) + } + } + ++/* Handle a relocation section. */ ++static void ++handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, GElf_Shdr *shdr) ++{ ++ int class = gelf_getclass (ebl->elf); ++ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELR, 1, EV_CURRENT); ++ int nentries = shdr->sh_size / sh_entsize; ++ ++ /* Get the data of the section. */ ++ Elf_Data *data = elf_getdata (scn, NULL); ++ if (data == NULL) ++ return; ++ ++ /* Get the section header string table index. */ ++ size_t shstrndx; ++ if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) ++ error_exit (0, _("cannot get section header string table index")); ++ ++ /* A .relr.dyn section does not refer to a specific section. */ ++ printf (ngettext ("\ ++\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", ++ "\ ++\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", ++ nentries), ++ (unsigned int) elf_ndxscn (scn), ++ elf_strptr (ebl->elf, shstrndx, shdr->sh_name), ++ shdr->sh_offset, ++ nentries); ++ ++ if (class == ELFCLASS32) ++ { ++ uint32_t base = 0; ++ for (int cnt = 0; cnt < nentries; ++cnt) ++ { ++ Elf32_Word *words = data->d_buf; ++ Elf32_Word entry = words[cnt]; ++ ++ /* Just the raw entries? */ ++ if (print_unresolved_addresses) ++ printf (" %#010" PRIx32 "%s\n", entry, ++ (entry & 1) == 0 ? " *" : ""); ++ else ++ { ++ /* A real address, also sets base. */ ++ if ((entry & 1) == 0) ++ { ++ printf (" "); ++ print_dwarf_addr (mod, 4, entry, entry); ++ printf (" *\n"); ++ ++ base = entry + 4; ++ } ++ else ++ { ++ /* Untangle address from base and bits. */ ++ uint32_t addr; ++ for (addr = base; (entry >>= 1) != 0; addr += 4) ++ if ((entry & 1) != 0) ++ { ++ printf (" "); ++ print_dwarf_addr (mod, 4, addr, addr); ++ printf ("\n"); ++ } ++ base += 4 * (4 * 8 - 1); ++ } ++ } ++ } ++ } ++ else ++ { ++ uint64_t base = 0; ++ for (int cnt = 0; cnt < nentries; ++cnt) ++ { ++ Elf64_Xword *xwords = data->d_buf; ++ Elf64_Xword entry = xwords[cnt]; ++ ++ /* Just the raw entries? */ ++ if (print_unresolved_addresses) ++ printf (" %#018" PRIx64 "%s\n", entry, ++ (entry & 1) == 0 ? " *" : ""); ++ else ++ { ++ /* A real address, also sets base. */ ++ if ((entry & 1) == 0) ++ { ++ printf (" "); ++ print_dwarf_addr (mod, 8, entry, entry); ++ printf (" *\n"); ++ ++ base = entry + 8; ++ } ++ else ++ { ++ /* Untangle address from base and bits. */ ++ uint64_t addr; ++ for (addr = base; (entry >>= 1) != 0; addr += 8) ++ if ((entry & 1) != 0) ++ { ++ printf (" "); ++ print_dwarf_addr (mod, 8, addr, addr); ++ printf ("\n"); ++ } ++ base += 8 * (8 * 8 - 1); ++ } ++ } ++ } ++ } ++} + + /* Print the program header. Return true if a symtab is printed, + false otherwise. */ +@@ -4107,7 +4224,7 @@ get_debug_elf_data (Dwarf *dbg, Ebl *ebl, int idx, Elf_Scn *scn) + return elf_getdata (scn, NULL); + } + +-void ++static void + print_dwarf_addr (Dwfl_Module *dwflmod, + int address_size, Dwarf_Addr address, Dwarf_Addr raw) + { diff --git a/elfutils.spec b/elfutils.spec index 24dc195..2b4cb14 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.189 -%global baserelease 4 +%global baserelease 5 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -82,6 +82,8 @@ Patch3: elfutils-0.189-elfcompress.patch Patch4: elfutils-0.189-elf_getdata_rawchunk.patch # PR29696: Removed secondary fd close in cache config causing race condition Patch5: elfutils-0.189-debuginfod_config_cache-double-close.patch +# Bug 28495 - Add support for SHT_RELR to eu-readelf +Patch6: elfutils-0.189-relr.patch %description Elfutils is a collection of utilities, including stack (to show @@ -450,6 +452,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Wed Aug 23 2023 Mark Wielaard - 0.189-5 +- Add elfutils-0.189-relr.patch + * Wed Jul 19 2023 Fedora Release Engineering - 0.189-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild