diff --git a/.elfutils.metadata b/.elfutils.metadata index c3c4d0e..3ee22bb 100644 --- a/.elfutils.metadata +++ b/.elfutils.metadata @@ -1 +1 @@ -95899ce5fa55002e46bf4e02d01a249516e296fd SOURCES/elfutils-0.174.tar.bz2 +6511203cae7225ae780501834a7ccd234b14889a SOURCES/elfutils-0.176.tar.bz2 diff --git a/.gitignore b/.gitignore index f5938a4..89b10d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/elfutils-0.174.tar.bz2 +SOURCES/elfutils-0.176.tar.bz2 diff --git a/SOURCES/elfutils-0.173-new-notes-hack.patch b/SOURCES/elfutils-0.173-new-notes-hack.patch deleted file mode 100644 index 8e607fa..0000000 --- a/SOURCES/elfutils-0.173-new-notes-hack.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/src/elflint.c b/src/elflint.c -index eec799b2..31092f2e 100644 ---- a/src/elflint.c -+++ b/src/elflint.c -@@ -3905,10 +3905,11 @@ section [%2zu] '%s': size not multiple of entry size\n"), - cnt, section_name (ebl, cnt), - (int) shdr->sh_type); - -+#define SHF_GNU_BUILD_NOTE (1 << 20) - #define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ - | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ - | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS \ -- | SHF_COMPRESSED) -+ | SHF_COMPRESSED | SHF_GNU_BUILD_NOTE) - if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS) - { - GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS; diff --git a/SOURCES/elfutils-0.174-ar-sh_entsize-zero.patch b/SOURCES/elfutils-0.174-ar-sh_entsize-zero.patch deleted file mode 100644 index 0040033..0000000 --- a/SOURCES/elfutils-0.174-ar-sh_entsize-zero.patch +++ /dev/null @@ -1,27 +0,0 @@ -commit 2b16a9be69939822dcafe075413468daac98b327 -Author: Mark Wielaard -Date: Thu Oct 18 19:01:52 2018 +0200 - - arlib: Check that sh_entsize isn't zero. - - A bogus ELF file could have sh_entsize as zero. Don't divide by zero, - but just assume there are no symbols in the section. - - https://sourceware.org/bugzilla/show_bug.cgi?id=23786 - - Signed-off-by: Mark Wielaard - -diff --git a/src/arlib.c b/src/arlib.c -index 778e087..a6521e3 100644 ---- a/src/arlib.c -+++ b/src/arlib.c -@@ -252,6 +252,9 @@ arlib_add_symbols (Elf *elf, const char *arfname, const char *membername, - if (data == NULL) - continue; - -+ if (shdr->sh_entsize == 0) -+ continue; -+ - int nsyms = shdr->sh_size / shdr->sh_entsize; - for (int ndx = shdr->sh_info; ndx < nsyms; ++ndx) - { diff --git a/SOURCES/elfutils-0.174-gnu-attribute-note.patch b/SOURCES/elfutils-0.174-gnu-attribute-note.patch deleted file mode 100644 index ae884a6..0000000 --- a/SOURCES/elfutils-0.174-gnu-attribute-note.patch +++ /dev/null @@ -1,373 +0,0 @@ -commit 72e30c2e0cb49a9a300667fdd5ff09082f717950 -Author: Mark Wielaard -Date: Mon Nov 12 23:34:24 2018 +0100 - - Handle GNU Build Attribute ELF Notes. - - GNU Build Attribute ELF Notes are generated by the GCC annobin plugin - and described at https://fedoraproject.org/wiki/Toolchain/Watermark - - Unfortunately the constants aren't yet described in the standard glibc - elf.h so they have been added to the elfutils specific elf-knowledge.h. - - The notes abuse the name owner field to encode some data not in the - description. This makes it a bit hard to parse. We have to match the - note owner name prefix (to "GA") to be sure the type is valid. We also - cannot rely on the owner name being a valid C string since the attribute - name and value can contain zero (terminators). So pass around namesz - to the ebl note parsing functions. - - eu-elflint will recognize and eu-readelf -n will now show the notes: - - Note section [27] '.gnu.build.attributes' of 56080 bytes at offset 0x114564: - Owner Data size Type - GA 16 GNU Build Attribute OPEN - Address Range: 0x2f30f - 0x2f30f - VERSION: "3p8" - GA 0 GNU Build Attribute OPEN - TOOL: "gcc 8.2.1 20180801" - GA 0 GNU Build Attribute OPEN - "GOW": 45 - GA 0 GNU Build Attribute OPEN - STACK_PROT: 0 - GA 0 GNU Build Attribute OPEN - "stack_clash": TRUE - GA 0 GNU Build Attribute OPEN - "cf_protection": 0 - GA 0 GNU Build Attribute OPEN - "GLIBCXX_ASSERTIONS": TRUE - GA 0 GNU Build Attribute OPEN - "FORTIFY": 0 - GA 0 GNU Build Attribute OPEN - PIC: 3 - GA 0 GNU Build Attribute OPEN - SHORT_ENUM: FALSE - GA 0 GNU Build Attribute OPEN - ABI: c001100000012 - GA 0 GNU Build Attribute OPEN - "stack_realign": FALSE - - A new test was added to run-readelf -n for the existing annobin file. - - Signed-off-by: Mark Wielaard - -diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c -index 8fda7d9..58ac86d 100644 ---- a/libebl/eblobjnote.c -+++ b/libebl/eblobjnote.c -@@ -37,11 +37,14 @@ - #include - #include - -+#include "common.h" - #include "libelfP.h" -+#include "libdwP.h" -+#include "memory-access.h" - - - void --ebl_object_note (Ebl *ebl, const char *name, uint32_t type, -+ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, - uint32_t descsz, const char *desc) - { - if (! ebl->object_note (name, type, descsz, desc)) -@@ -135,6 +138,152 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type, - return; - } - -+ if (strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX, -+ strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0 -+ && (type == NT_GNU_BUILD_ATTRIBUTE_OPEN -+ || type == NT_GNU_BUILD_ATTRIBUTE_FUNC)) -+ { -+ /* There might or might not be a pair of addresses in the desc. */ -+ if (descsz > 0) -+ { -+ printf (" Address Range: "); -+ -+ union -+ { -+ Elf64_Addr a64[2]; -+ Elf32_Addr a32[2]; -+ } addrs; -+ -+ size_t addr_size = gelf_fsize (ebl->elf, ELF_T_ADDR, -+ 2, EV_CURRENT); -+ if (descsz != addr_size) -+ printf ("\n"); -+ else -+ { -+ Elf_Data src = -+ { -+ .d_type = ELF_T_ADDR, .d_version = EV_CURRENT, -+ .d_buf = (void *) desc, .d_size = descsz -+ }; -+ -+ Elf_Data dst = -+ { -+ .d_type = ELF_T_ADDR, .d_version = EV_CURRENT, -+ .d_buf = &addrs, .d_size = descsz -+ }; -+ -+ if (gelf_xlatetom (ebl->elf, &dst, &src, -+ elf_getident (ebl->elf, -+ NULL)[EI_DATA]) == NULL) -+ printf ("%s\n", elf_errmsg (-1)); -+ else -+ { -+ if (addr_size == 4) -+ printf ("%#" PRIx32 " - %#" PRIx32 "\n", -+ addrs.a32[0], addrs.a32[1]); -+ else -+ printf ("%#" PRIx64 " - %#" PRIx64 "\n", -+ addrs.a64[0], addrs.a64[1]); -+ } -+ } -+ } -+ -+ /* Most data actually is inside the name. -+ https://fedoraproject.org/wiki/Toolchain/Watermark */ -+ -+ /* We need at least 2 chars of data to describe the -+ attribute and value encodings. */ -+ const char *data = (name -+ + strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)); -+ if (namesz < 2) -+ { -+ printf ("\n"); -+ return; -+ } -+ -+ printf (" "); -+ -+ /* In most cases the value comes right after the encoding bytes. */ -+ const char *value = &data[2]; -+ switch (data[1]) -+ { -+ case GNU_BUILD_ATTRIBUTE_VERSION: -+ printf ("VERSION: "); -+ break; -+ case GNU_BUILD_ATTRIBUTE_STACK_PROT: -+ printf ("STACK_PROT: "); -+ break; -+ case GNU_BUILD_ATTRIBUTE_RELRO: -+ printf ("RELRO: "); -+ break; -+ case GNU_BUILD_ATTRIBUTE_STACK_SIZE: -+ printf ("STACK_SIZE: "); -+ break; -+ case GNU_BUILD_ATTRIBUTE_TOOL: -+ printf ("TOOL: "); -+ break; -+ case GNU_BUILD_ATTRIBUTE_ABI: -+ printf ("ABI: "); -+ break; -+ case GNU_BUILD_ATTRIBUTE_PIC: -+ printf ("PIC: "); -+ break; -+ case GNU_BUILD_ATTRIBUTE_SHORT_ENUM: -+ printf ("SHORT_ENUM: "); -+ break; -+ case 32 ... 126: -+ printf ("\"%s\": ", &data[1]); -+ value += strlen (&data[1]) + 1; -+ break; -+ default: -+ printf (": "); -+ break; -+ } -+ -+ switch (data[0]) -+ { -+ case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC: -+ { -+ /* Any numbers are always in (unsigned) little endian. */ -+ static const Dwarf dbg -+ = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB }; -+ size_t bytes = namesz - (value - name); -+ uint64_t val; -+ if (bytes == 1) -+ val = *(unsigned char *) value; -+ else if (bytes == 2) -+ val = read_2ubyte_unaligned (&dbg, value); -+ else if (bytes == 4) -+ val = read_4ubyte_unaligned (&dbg, value); -+ else if (bytes == 8) -+ val = read_8ubyte_unaligned (&dbg, value); -+ else -+ goto unknown; -+ printf ("%" PRIx64, val); -+ } -+ break; -+ case GNU_BUILD_ATTRIBUTE_TYPE_STRING: -+ printf ("\"%s\"", value); -+ break; -+ case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE: -+ printf ("TRUE"); -+ break; -+ case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE: -+ printf ("FALSE"); -+ break; -+ default: -+ { -+ unknown: -+ printf (""); -+ } -+ break; -+ } -+ -+ printf ("\n"); -+ -+ return; -+ } -+ - /* NT_VERSION doesn't have any info. All data is in the name. */ - if (descsz == 0 && type == NT_VERSION) - return; -diff --git a/libebl/eblobjnotetypename.c b/libebl/eblobjnotetypename.c -index 8cdd781..29a5391 100644 ---- a/libebl/eblobjnotetypename.c -+++ b/libebl/eblobjnotetypename.c -@@ -1,5 +1,5 @@ - /* Return note type name. -- Copyright (C) 2002, 2007, 2009, 2011, 2016 Red Hat, Inc. -+ Copyright (C) 2002, 2007, 2009, 2011, 2016, 2018 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper , 2002. - -@@ -79,6 +79,29 @@ ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type, - } - } - -+ if (strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX, -+ strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0) -+ { -+ /* GNU Build Attribute notes (ab)use the owner name to store -+ most of their data. Don't decode everything here. Just -+ the type.*/ -+ char *t = buf; -+ const char *gba = "GNU Build Attribute"; -+ int w = snprintf (t, len, "%s ", gba); -+ t += w; -+ len -= w; -+ if (type == NT_GNU_BUILD_ATTRIBUTE_OPEN) -+ w = snprintf (t, len, "OPEN"); -+ else if (type == NT_GNU_BUILD_ATTRIBUTE_FUNC) -+ w = snprintf (t, len, "FUNC"); -+ else -+ w = snprintf (t, len, "%x", type); -+ t += w; -+ len -= w; -+ -+ return buf; -+ } -+ - if (strcmp (name, "GNU") != 0) - { - /* NT_VERSION is special, all data is in the name. */ -diff --git a/libebl/libebl.h b/libebl/libebl.h -index 5830654..ca9b9fe 100644 ---- a/libebl/libebl.h -+++ b/libebl/libebl.h -@@ -179,8 +179,8 @@ extern const char *ebl_object_note_type_name (Ebl *ebl, const char *name, - char *buf, size_t len); - - /* Print information about object note if available. */ --extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type, -- uint32_t descsz, const char *desc); -+extern void ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, -+ uint32_t type, uint32_t descsz, const char *desc); - - /* Check whether an attribute in a .gnu_attributes section is recognized. - Fills in *TAG_NAME with the name for this tag. -diff --git a/libelf/elf-knowledge.h b/libelf/elf-knowledge.h -index 64f5887..9d3be0f 100644 ---- a/libelf/elf-knowledge.h -+++ b/libelf/elf-knowledge.h -@@ -77,4 +77,25 @@ - || ((Ehdr)->e_machine == EM_S390 \ - && (Ehdr)->e_ident[EI_CLASS] == ELFCLASS64) ? 8 : 4) - -+/* GNU Annobin notes are not fully standardized and abuses the owner name. */ -+ -+#define ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX "GA" -+ -+#define NT_GNU_BUILD_ATTRIBUTE_OPEN 0x100 -+#define NT_GNU_BUILD_ATTRIBUTE_FUNC 0x101 -+ -+#define GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC '*' -+#define GNU_BUILD_ATTRIBUTE_TYPE_STRING '$' -+#define GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE '+' -+#define GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE '!' -+ -+#define GNU_BUILD_ATTRIBUTE_VERSION 1 -+#define GNU_BUILD_ATTRIBUTE_STACK_PROT 2 -+#define GNU_BUILD_ATTRIBUTE_RELRO 3 -+#define GNU_BUILD_ATTRIBUTE_STACK_SIZE 4 -+#define GNU_BUILD_ATTRIBUTE_TOOL 5 -+#define GNU_BUILD_ATTRIBUTE_ABI 6 -+#define GNU_BUILD_ATTRIBUTE_PIC 7 -+#define GNU_BUILD_ATTRIBUTE_SHORT_ENUM 8 -+ - #endif /* elf-knowledge.h */ -diff --git a/src/elflint.c b/src/elflint.c -index dff74ee..184ca12 100644 ---- a/src/elflint.c -+++ b/src/elflint.c -@@ -4344,6 +4344,19 @@ section [%2d] '%s': unknown core file note type %" PRIu32 - } - goto unknown_note; - -+ case NT_GNU_BUILD_ATTRIBUTE_OPEN: -+ case NT_GNU_BUILD_ATTRIBUTE_FUNC: -+ /* GNU Build Attributes store most data in the owner -+ name, which must start with the -+ ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX "GA". */ -+ if (nhdr.n_namesz >= sizeof ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX -+ && strncmp (data->d_buf + name_offset, -+ ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX, -+ strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0) -+ break; -+ else -+ goto unknown_note; -+ - case 0: - /* Linux vDSOs use a type 0 note for the kernel version word. */ - if (nhdr.n_namesz == sizeof "Linux" -diff --git a/src/readelf.c b/src/readelf.c -index 659e34f..3a73710 100644 ---- a/src/readelf.c -+++ b/src/readelf.c -@@ -12193,10 +12193,21 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr, - const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset; - const char *desc = data->d_buf + desc_offset; - -+ /* GNU Build Attributes are weird, they store most of their data -+ into the owner name field. Extract just the owner name -+ prefix here, then use the rest later as data. */ -+ bool is_gnu_build_attr -+ = strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX, -+ strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0; -+ const char *print_name = (is_gnu_build_attr -+ ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name); -+ size_t print_namesz = (is_gnu_build_attr -+ ? strlen (print_name) : nhdr.n_namesz); -+ - char buf[100]; - char buf2[100]; - printf (gettext (" %-13.*s %9" PRId32 " %s\n"), -- (int) nhdr.n_namesz, name, nhdr.n_descsz, -+ (int) print_namesz, print_name, nhdr.n_descsz, - ehdr->e_type == ET_CORE - ? ebl_core_note_type_name (ebl, nhdr.n_type, - buf, sizeof (buf)) -@@ -12237,7 +12248,8 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr, - handle_core_note (ebl, &nhdr, name, desc); - } - else -- ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc); -+ ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type, -+ nhdr.n_descsz, desc); - } - } - diff --git a/SOURCES/elfutils-0.174-gnu-property-note.patch b/SOURCES/elfutils-0.174-gnu-property-note.patch deleted file mode 100644 index e511ed0..0000000 --- a/SOURCES/elfutils-0.174-gnu-property-note.patch +++ /dev/null @@ -1,820 +0,0 @@ -commit 5199e15870e05e5b0b9f98c20fc9b5427aa6dd6a -Author: Mark Wielaard -Date: Mon Oct 15 23:35:47 2018 +0200 - - Recognize and parse GNU Property notes. - - GNU Property notes are different from normal notes because they use - variable alignment/padding of their fields. They are 8 byte aligned, - but use 4 byte fields. The name is aligned at 4 bytes and padded so - that, the desc is aligned at 8 bytes. The whole note is padded to - 8 bytes again. For normal notes all fields are both 4 bytes wide and - 4 bytes aligned. - - To recognize these new kind of ELF Notes a new Elf_Type is introduced, - ELF_T_NHDR8. This type is used in the xlate functions to determine - how to align and pad the various fields. Since the fields themselves - can now have different alignments we will have to keep track of the - current alignement and use either NOTE_ALIGN4 or NOTE_ALIGN8 to - determine the padding. - - To set the correct Elf_Type on the Elf_Data we use either the section - sh_addralign or the segment p_align values. Assuming 8 means the - section or segment contains the new style notes, otherwise normal - notes. - - When we cannot determine the "alignment" directly, like when parsing - special kernel sys files, we check the name "GNU" and type - "GNU_PROPERTY_TYPE_0" fields. - - ebl_object_note now parses the new NT_GNU_PROPERTY_TYPE_0 and can - extract the GNU_PROPERTY_STACK_SIZE, GNU_PROPERTY_NO_COPY_ON_PROTECTED - and GNU_PROPERTY_X86_FEATURE_1_AND types GNU_PROPERTY_X86_FEATURE_1_IBT - and GNU_PROPERTY_X86_FEATURE_1_SHSTK. - - Tests are added for extracting the note from sections or segments - as set by gcc -fcf-protection. - - Signed-off-by: Mark Wielaard - -diff --git a/libdwelf/dwelf_elf_gnu_build_id.c b/libdwelf/dwelf_elf_gnu_build_id.c -index 8c78c70..dbcfc82 100644 ---- a/libdwelf/dwelf_elf_gnu_build_id.c -+++ b/libdwelf/dwelf_elf_gnu_build_id.c -@@ -88,7 +88,9 @@ find_elf_build_id (Dwfl_Module *mod, int e_type, Elf *elf, - result = check_notes (elf_getdata_rawchunk (elf, - phdr->p_offset, - phdr->p_filesz, -- ELF_T_NHDR), -+ (phdr->p_align == 8 -+ ? ELF_T_NHDR8 -+ : ELF_T_NHDR)), - phdr->p_vaddr, - build_id_bits, - build_id_elfaddr, -diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c -index 84cb89a..01109f4 100644 ---- a/libdwfl/core-file.c -+++ b/libdwfl/core-file.c -@@ -496,7 +496,9 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable) - Elf_Data *notes = elf_getdata_rawchunk (elf, - notes_phdr.p_offset, - notes_phdr.p_filesz, -- ELF_T_NHDR); -+ (notes_phdr.p_align == 8 -+ ? ELF_T_NHDR8 -+ : ELF_T_NHDR)); - if (likely (notes != NULL)) - { - size_t pos = 0; -diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c -index 8749884..0d633ff 100644 ---- a/libdwfl/dwfl_segment_report_module.c -+++ b/libdwfl/dwfl_segment_report_module.c -@@ -27,7 +27,7 @@ - not, see . */ - - #include --#include "../libelf/libelfP.h" /* For NOTE_ALIGN. */ -+#include "../libelf/libelfP.h" /* For NOTE_ALIGN4 and NOTE_ALIGN8. */ - #undef _ - #include "libdwflP.h" - #include "common.h" -@@ -451,7 +451,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, - GElf_Addr build_id_vaddr = 0; - - /* Consider a PT_NOTE we've found in the image. */ -- inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz) -+ inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz, -+ GElf_Xword align) - { - /* If we have already seen a build ID, we don't care any more. */ - if (build_id != NULL || filesz == 0) -@@ -478,7 +479,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, - notes = malloc (filesz); - if (unlikely (notes == NULL)) - return; -- xlatefrom.d_type = xlateto.d_type = ELF_T_NHDR; -+ xlatefrom.d_type = xlateto.d_type = (align == 8 -+ ? ELF_T_NHDR8 : ELF_T_NHDR); - xlatefrom.d_buf = (void *) data; - xlatefrom.d_size = filesz; - xlateto.d_buf = notes; -@@ -489,15 +491,23 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, - } - - const GElf_Nhdr *nh = notes; -- while ((const void *) nh < (const void *) notes + filesz) -- { -- const void *note_name = nh + 1; -- const void *note_desc = note_name + NOTE_ALIGN (nh->n_namesz); -- if (unlikely ((size_t) ((const void *) notes + filesz -- - note_desc) < nh->n_descsz)) -+ size_t len = 0; -+ while (filesz > len + sizeof (*nh)) -+ { -+ const void *note_name; -+ const void *note_desc; -+ -+ len += sizeof (*nh); -+ note_name = notes + len; -+ -+ len += nh->n_namesz; -+ len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len); -+ note_desc = notes + len; -+ -+ if (unlikely (filesz < len + nh->n_descsz)) - break; - -- if (nh->n_type == NT_GNU_BUILD_ID -+ if (nh->n_type == NT_GNU_BUILD_ID - && nh->n_descsz > 0 - && nh->n_namesz == sizeof "GNU" - && !memcmp (note_name, "GNU", sizeof "GNU")) -@@ -510,7 +520,9 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, - break; - } - -- nh = note_desc + NOTE_ALIGN (nh->n_descsz); -+ len += nh->n_descsz; -+ len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len); -+ nh = (void *) notes + len; - } - - done: -@@ -535,7 +547,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, - case PT_NOTE: - /* We calculate from the p_offset of the note segment, - because we don't yet know the bias for its p_vaddr. */ -- consider_notes (start + offset, filesz); -+ consider_notes (start + offset, filesz, align); - break; - - case PT_LOAD: -diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c -index 9f05f72..6c99b9e 100644 ---- a/libdwfl/linux-core-attach.c -+++ b/libdwfl/linux-core-attach.c -@@ -355,7 +355,9 @@ dwfl_core_file_attach (Dwfl *dwfl, Elf *core) - if (phdr != NULL && phdr->p_type == PT_NOTE) - { - note_data = elf_getdata_rawchunk (core, phdr->p_offset, -- phdr->p_filesz, ELF_T_NHDR); -+ phdr->p_filesz, (phdr->p_align == 8 -+ ? ELF_T_NHDR8 -+ : ELF_T_NHDR)); - break; - } - } -diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c -index 9d0fef2..360e4ee 100644 ---- a/libdwfl/linux-kernel-modules.c -+++ b/libdwfl/linux-kernel-modules.c -@@ -39,6 +39,7 @@ - #include - #include - -+#include "libelfP.h" - #include "libdwflP.h" - #include - #include -@@ -554,15 +555,41 @@ check_notes (Dwfl_Module *mod, const char *notesfile, - return 1; - - unsigned char *p = buf.data; -+ size_t len = 0; - while (p < &buf.data[n]) - { - /* No translation required since we are reading the native kernel. */ - GElf_Nhdr *nhdr = (void *) p; -- p += sizeof *nhdr; -+ len += sizeof *nhdr; -+ p += len; - unsigned char *name = p; -- p += (nhdr->n_namesz + 3) & -4U; -- unsigned char *bits = p; -- p += (nhdr->n_descsz + 3) & -4U; -+ unsigned char *bits; -+ /* This is somewhat ugly, GNU Property notes use different padding, -+ but all we have is the file content, so we have to actually check -+ the name and type. */ -+ if (nhdr->n_type == NT_GNU_PROPERTY_TYPE_0 -+ && nhdr->n_namesz == sizeof "GNU" -+ && name + nhdr->n_namesz < &buf.data[n] -+ && !memcmp (name, "GNU", sizeof "GNU")) -+ { -+ len += nhdr->n_namesz; -+ len = NOTE_ALIGN8 (len); -+ p = buf.data + len; -+ bits = p; -+ len += nhdr->n_descsz; -+ len = NOTE_ALIGN8 (len); -+ p = buf.data + len; -+ } -+ else -+ { -+ len += nhdr->n_namesz; -+ len = NOTE_ALIGN4 (len); -+ p = buf.data + len; -+ bits = p; -+ len += nhdr->n_descsz; -+ len = NOTE_ALIGN4 (len); -+ p = buf.data + len; -+ } - - if (p <= &buf.data[n] - && nhdr->n_type == NT_GNU_BUILD_ID -diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c -index ca4f155..57e9f52 100644 ---- a/libebl/eblobjnote.c -+++ b/libebl/eblobjnote.c -@@ -1,5 +1,5 @@ - /* Print contents of object file note. -- Copyright (C) 2002, 2007, 2009, 2011, 2015, 2016 Red Hat, Inc. -+ Copyright (C) 2002, 2007, 2009, 2011, 2015, 2016, 2018 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper , 2002. - -@@ -37,6 +37,8 @@ - #include - #include - -+#include "libelfP.h" -+ - - void - ebl_object_note (Ebl *ebl, const char *name, uint32_t type, -@@ -153,6 +155,187 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type, - (int) descsz, desc); - break; - -+ case NT_GNU_PROPERTY_TYPE_0: -+ if (strcmp (name, "GNU") == 0 && descsz > 0) -+ { -+ /* There are at least 2 words. type and datasz. */ -+ while (descsz >= 8) -+ { -+ struct pr_prop -+ { -+ GElf_Word pr_type; -+ GElf_Word pr_datasz; -+ } prop; -+ -+ Elf_Data in = -+ { -+ .d_version = EV_CURRENT, -+ .d_type = ELF_T_WORD, -+ .d_size = 8, -+ .d_buf = (void *) desc -+ }; -+ Elf_Data out = -+ { -+ .d_version = EV_CURRENT, -+ .d_type = ELF_T_WORD, -+ .d_size = descsz, -+ .d_buf = (void *) &prop -+ }; -+ -+ if (gelf_xlatetom (ebl->elf, &out, &in, -+ elf_getident (ebl->elf, -+ NULL)[EI_DATA]) == NULL) -+ { -+ printf ("%s\n", elf_errmsg (-1)); -+ return; -+ } -+ -+ desc += 8; -+ descsz -= 8; -+ -+ int elfclass = gelf_getclass (ebl->elf); -+ char *elfident = elf_getident (ebl->elf, NULL); -+ GElf_Ehdr ehdr; -+ gelf_getehdr (ebl->elf, &ehdr); -+ -+ /* Prefix. */ -+ printf (" "); -+ if (prop.pr_type == GNU_PROPERTY_STACK_SIZE) -+ { -+ printf ("STACK_SIZE "); -+ if (prop.pr_datasz == 4 || prop.pr_datasz == 8) -+ { -+ GElf_Addr addr; -+ in.d_type = ELF_T_ADDR; -+ out.d_type = ELF_T_ADDR; -+ in.d_size = prop.pr_datasz; -+ out.d_size = sizeof (addr); -+ in.d_buf = (void *) desc; -+ out.d_buf = (void *) &addr; -+ -+ if (gelf_xlatetom (ebl->elf, &out, &in, -+ elfident[EI_DATA]) == NULL) -+ { -+ printf ("%s\n", elf_errmsg (-1)); -+ return; -+ } -+ printf ("%#" PRIx64 "\n", addr); -+ } -+ else -+ printf (" (garbage datasz: %" PRIx32 ")\n", -+ prop.pr_datasz); -+ } -+ else if (prop.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED) -+ { -+ printf ("NO_COPY_ON_PROTECTION"); -+ if (prop.pr_datasz == 0) -+ printf ("\n"); -+ else -+ printf (" (garbage datasz: %" PRIx32 ")\n", -+ prop.pr_datasz); -+ } -+ else if (prop.pr_type >= GNU_PROPERTY_LOPROC -+ && prop.pr_type <= GNU_PROPERTY_HIPROC -+ && (ehdr.e_machine == EM_386 -+ || ehdr.e_machine == EM_X86_64)) -+ { -+ printf ("X86 "); -+ if (prop.pr_type == GNU_PROPERTY_X86_FEATURE_1_AND) -+ { -+ printf ("FEATURE_1_AND: "); -+ -+ if (prop.pr_datasz == 4) -+ { -+ GElf_Word data; -+ in.d_type = ELF_T_WORD; -+ out.d_type = ELF_T_WORD; -+ in.d_size = 4; -+ out.d_size = 4; -+ in.d_buf = (void *) desc; -+ out.d_buf = (void *) &data; -+ -+ if (gelf_xlatetom (ebl->elf, &out, &in, -+ elfident[EI_DATA]) == NULL) -+ { -+ printf ("%s\n", elf_errmsg (-1)); -+ return; -+ } -+ printf ("%08" PRIx32 " ", data); -+ -+ if ((data & GNU_PROPERTY_X86_FEATURE_1_IBT) -+ != 0) -+ { -+ printf ("IBT"); -+ data &= ~GNU_PROPERTY_X86_FEATURE_1_IBT; -+ if (data != 0) -+ printf (" "); -+ } -+ -+ if ((data & GNU_PROPERTY_X86_FEATURE_1_SHSTK) -+ != 0) -+ { -+ printf ("SHSTK"); -+ data &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK; -+ if (data != 0) -+ printf (" "); -+ } -+ -+ if (data != 0) -+ printf ("UNKNOWN"); -+ } -+ else -+ printf ("", -+ prop.pr_datasz); -+ -+ printf ("\n"); -+ } -+ else -+ { -+ printf ("%#" PRIx32, prop.pr_type); -+ if (prop.pr_datasz > 0) -+ { -+ printf (" data: "); -+ size_t i; -+ for (i = 0; i < prop.pr_datasz - 1; i++) -+ printf ("%02" PRIx8 " ", (uint8_t) desc[i]); -+ printf ("%02" PRIx8 "\n", (uint8_t) desc[i]); -+ } -+ } -+ } -+ else -+ { -+ if (prop.pr_type >= GNU_PROPERTY_LOPROC -+ && prop.pr_type <= GNU_PROPERTY_HIPROC) -+ printf ("proc_type %#" PRIx32, prop.pr_type); -+ else if (prop.pr_type >= GNU_PROPERTY_LOUSER -+ && prop.pr_type <= GNU_PROPERTY_HIUSER) -+ printf ("app_type %#" PRIx32, prop.pr_type); -+ else -+ printf ("unknown_type %#" PRIx32, prop.pr_type); -+ -+ if (prop.pr_datasz > 0) -+ { -+ printf (" data: "); -+ size_t i; -+ for (i = 0; i < prop.pr_datasz - 1; i++) -+ printf ("%02" PRIx8 " ", (uint8_t) desc[i]); -+ printf ("%02" PRIx8 "\n", (uint8_t) desc[i]); -+ } -+ } -+ if (elfclass == ELFCLASS32) -+ { -+ desc += NOTE_ALIGN4 (prop.pr_datasz); -+ descsz -= NOTE_ALIGN4 (prop.pr_datasz); -+ } -+ else -+ { -+ desc += NOTE_ALIGN8 (prop.pr_datasz); -+ descsz -= NOTE_ALIGN8 (prop.pr_datasz); -+ } -+ } -+ } -+ break; -+ - case NT_GNU_ABI_TAG: - if (strcmp (name, "GNU") == 0 && descsz >= 8 && descsz % 4 == 0) - { -diff --git a/libebl/eblobjnotetypename.c b/libebl/eblobjnotetypename.c -index db040d2..af23cae 100644 ---- a/libebl/eblobjnotetypename.c -+++ b/libebl/eblobjnotetypename.c -@@ -91,6 +91,7 @@ ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type, - KNOWNSTYPE (GNU_HWCAP), - KNOWNSTYPE (GNU_BUILD_ID), - KNOWNSTYPE (GNU_GOLD_VERSION), -+ KNOWNSTYPE (GNU_PROPERTY_TYPE_0), - }; - - /* Handle standard names. */ -diff --git a/libelf/elf32_xlatetom.c b/libelf/elf32_xlatetom.c -index 13cd485..3b94cac 100644 ---- a/libelf/elf32_xlatetom.c -+++ b/libelf/elf32_xlatetom.c -@@ -60,7 +60,7 @@ elfw2(LIBELFBITS, xlatetom) (Elf_Data *dest, const Elf_Data *src, - /* We shouldn't require integer number of records when processing - notes. Payload bytes follow the header immediately, it's not an - array of records as is the case otherwise. */ -- if (src->d_type != ELF_T_NHDR -+ if (src->d_type != ELF_T_NHDR && src->d_type != ELF_T_NHDR8 - && src->d_size % recsize != 0) - { - __libelf_seterrno (ELF_E_INVALID_DATA); -diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c -index 711be59..fd412e8 100644 ---- a/libelf/elf_compress.c -+++ b/libelf/elf_compress.c -@@ -513,7 +513,8 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags) - - __libelf_reset_rawdata (scn, scn->zdata_base, - scn->zdata_size, scn->zdata_align, -- __libelf_data_type (elf, sh_type)); -+ __libelf_data_type (elf, sh_type, -+ scn->zdata_align)); - - return 1; - } -diff --git a/libelf/elf_compress_gnu.c b/libelf/elf_compress_gnu.c -index dfa7c57..198dc7d 100644 ---- a/libelf/elf_compress_gnu.c -+++ b/libelf/elf_compress_gnu.c -@@ -196,7 +196,7 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags) - } - - __libelf_reset_rawdata (scn, buf_out, size, sh_addralign, -- __libelf_data_type (elf, sh_type)); -+ __libelf_data_type (elf, sh_type, sh_addralign)); - - scn->zdata_base = buf_out; - -diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c -index 278dfa8..4f80aaf 100644 ---- a/libelf/elf_getdata.c -+++ b/libelf/elf_getdata.c -@@ -65,7 +65,7 @@ static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] = - [SHT_PREINIT_ARRAY] = ELF_T_ADDR, - [SHT_GROUP] = ELF_T_WORD, - [SHT_SYMTAB_SHNDX] = ELF_T_WORD, -- [SHT_NOTE] = ELF_T_NHDR, -+ [SHT_NOTE] = ELF_T_NHDR, /* Need alignment to guess ELF_T_NHDR8. */ - [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF, - [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED, - [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF, -@@ -106,6 +106,7 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] - [ELF_T_GNUHASH] = __alignof__ (Elf32_Word), \ - [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)), \ - [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)), \ -+ [ELF_T_NHDR8] = 8 /* Special case for GNU Property note. */ \ - } - [EV_CURRENT - 1] = - { -@@ -118,7 +119,7 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] - - Elf_Type - internal_function --__libelf_data_type (Elf *elf, int sh_type) -+__libelf_data_type (Elf *elf, int sh_type, GElf_Xword align) - { - /* Some broken ELF ABI for 64-bit machines use the wrong hash table - entry size. See elf-knowledge.h for more information. */ -@@ -129,7 +130,13 @@ __libelf_data_type (Elf *elf, int sh_type) - return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD); - } - else -- return shtype_map[LIBELF_EV_IDX][TYPEIDX (sh_type)]; -+ { -+ Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (sh_type)]; -+ /* Special case for GNU Property notes. */ -+ if (t == ELF_T_NHDR && align == 8) -+ t = ELF_T_NHDR8; -+ return t; -+ } - } - - /* Convert the data in the current section. */ -@@ -272,7 +279,9 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn) - else - { - Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)]; -- if (t == ELF_T_VDEF || t == ELF_T_NHDR -+ if (t == ELF_T_NHDR && align == 8) -+ t = ELF_T_NHDR8; -+ if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8 - || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64)) - entsize = 1; - else -@@ -357,7 +366,7 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn) - if ((flags & SHF_COMPRESSED) != 0) - scn->rawdata.d.d_type = ELF_T_CHDR; - else -- scn->rawdata.d.d_type = __libelf_data_type (elf, type); -+ scn->rawdata.d.d_type = __libelf_data_type (elf, type, align); - scn->rawdata.d.d_off = 0; - - /* Make sure the alignment makes sense. d_align should be aligned both -diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c -index 0c50926..d04ec5d 100644 ---- a/libelf/gelf_fsize.c -+++ b/libelf/gelf_fsize.c -@@ -64,6 +64,8 @@ const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] = - [ELF_T_VNEED] = sizeof (ElfW2(LIBELFBITS, Ext_Verneed)), \ - [ELF_T_VNAUX] = sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)), \ - [ELF_T_NHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)), \ -+ /* Note the header size is the same, but padding is different. */ \ -+ [ELF_T_NHDR8] = sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)), \ - [ELF_T_SYMINFO] = sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)), \ - [ELF_T_MOVE] = sizeof (ElfW2(LIBELFBITS, Ext_Move)), \ - [ELF_T_LIB] = sizeof (ElfW2(LIBELFBITS, Ext_Lib)), \ -diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c -index c75edda..6d33b35 100644 ---- a/libelf/gelf_getnote.c -+++ b/libelf/gelf_getnote.c -@@ -1,5 +1,5 @@ - /* Get note information at the supplied offset. -- Copyright (C) 2007, 2014, 2015 Red Hat, Inc. -+ Copyright (C) 2007, 2014, 2015, 2018 Red Hat, Inc. - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify -@@ -43,7 +43,7 @@ gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result, - if (data == NULL) - return 0; - -- if (unlikely (data->d_type != ELF_T_NHDR)) -+ if (unlikely (data->d_type != ELF_T_NHDR && data->d_type != ELF_T_NHDR8)) - { - __libelf_seterrno (ELF_E_INVALID_HANDLE); - return 0; -@@ -69,27 +69,42 @@ gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result, - const GElf_Nhdr *n = data->d_buf + offset; - offset += sizeof *n; - -- /* Include padding. Check below for overflow. */ -- GElf_Word namesz = NOTE_ALIGN (n->n_namesz); -- GElf_Word descsz = NOTE_ALIGN (n->n_descsz); -- -- if (unlikely (offset > data->d_size -- || data->d_size - offset < namesz -- || (namesz == 0 && n->n_namesz != 0))) -+ if (offset > data->d_size) - offset = 0; - else - { -+ /* This is slightly tricky, offset is guaranteed to be 4 -+ byte aligned, which is what we need for the name_offset. -+ And normally desc_offset is also 4 byte aligned, but not -+ for GNU Property notes, then it should be 8. So align -+ the offset, after adding the namesz, and include padding -+ in descsz to get to the end. */ - *name_offset = offset; -- offset += namesz; -- if (unlikely (offset > data->d_size -- || data->d_size - offset < descsz -- || (descsz == 0 && n->n_descsz != 0))) -+ offset += n->n_namesz; -+ if (offset > data->d_size) - offset = 0; - else - { -- *desc_offset = offset; -- offset += descsz; -- *result = *n; -+ /* Include padding. Check below for overflow. */ -+ GElf_Word descsz = (data->d_type == ELF_T_NHDR8 -+ ? NOTE_ALIGN8 (n->n_descsz) -+ : NOTE_ALIGN4 (n->n_descsz)); -+ -+ if (data->d_type == ELF_T_NHDR8) -+ offset = NOTE_ALIGN8 (offset); -+ else -+ offset = NOTE_ALIGN4 (offset); -+ -+ if (unlikely (offset > data->d_size -+ || data->d_size - offset < descsz -+ || (descsz == 0 && n->n_descsz != 0))) -+ offset = 0; -+ else -+ { -+ *desc_offset = offset; -+ offset += descsz; -+ *result = *n; -+ } - } - } - } -diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c -index 479f143..b5d6ef3 100644 ---- a/libelf/gelf_xlate.c -+++ b/libelf/gelf_xlate.c -@@ -195,7 +195,8 @@ const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] - [ELF_T_VDAUX] = elf_cvt_Verdef, \ - [ELF_T_VNEED] = elf_cvt_Verneed, \ - [ELF_T_VNAUX] = elf_cvt_Verneed, \ -- [ELF_T_NHDR] = elf_cvt_note, \ -+ [ELF_T_NHDR] = elf_cvt_note4, \ -+ [ELF_T_NHDR8] = elf_cvt_note8, \ - [ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo), \ - [ELF_T_MOVE] = ElfW2(Bits, cvt_Move), \ - [ELF_T_LIB] = ElfW2(Bits, cvt_Lib), \ -diff --git a/libelf/libelf.h b/libelf/libelf.h -index d11358c..1ff11c9 100644 ---- a/libelf/libelf.h -+++ b/libelf/libelf.h -@@ -117,6 +117,8 @@ typedef enum - ELF_T_GNUHASH, /* GNU-style hash section. */ - ELF_T_AUXV, /* Elf32_auxv_t, Elf64_auxv_t, ... */ - ELF_T_CHDR, /* Compressed, Elf32_Chdr, Elf64_Chdr, ... */ -+ ELF_T_NHDR8, /* Special GNU Properties note. Same as Nhdr, -+ except padding. */ - /* Keep this the last entry. */ - ELF_T_NUM - } Elf_Type; -diff --git a/libelf/libelfP.h b/libelf/libelfP.h -index ed216c8..fa6d55d 100644 ---- a/libelf/libelfP.h -+++ b/libelf/libelfP.h -@@ -452,7 +452,8 @@ extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_ - /* Given an Elf handle and a section type returns the Elf_Data d_type. - Should not be called when SHF_COMPRESSED is set, the d_type should - be ELF_T_BYTE. */ --extern Elf_Type __libelf_data_type (Elf *elf, int sh_type) internal_function; -+extern Elf_Type __libelf_data_type (Elf *elf, int sh_type, GElf_Xword align) -+ internal_function; - - /* The libelf API does not have such a function but it is still useful. - Get the memory size for the given type. -@@ -624,8 +625,13 @@ extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, - } \ - } while (0) - --/* Align offset to 4 bytes as needed for note name and descriptor data. */ --#define NOTE_ALIGN(n) (((n) + 3) & -4U) -+/* Align offset to 4 bytes as needed for note name and descriptor data. -+ This is almost always used, except for GNU Property notes, which use -+ 8 byte padding... */ -+#define NOTE_ALIGN4(n) (((n) + 3) & -4U) -+ -+/* Special note padding rule for GNU Property notes. */ -+#define NOTE_ALIGN8(n) (((n) + 7) & -8U) - - /* Convenience macro. */ - #define INVALID_NDX(ndx, type, data) \ -diff --git a/libelf/note_xlate.h b/libelf/note_xlate.h -index 62c6f63..9bdc3e2 100644 ---- a/libelf/note_xlate.h -+++ b/libelf/note_xlate.h -@@ -1,5 +1,5 @@ - /* Conversion functions for notes. -- Copyright (C) 2007, 2009, 2014 Red Hat, Inc. -+ Copyright (C) 2007, 2009, 2014, 2018 Red Hat, Inc. - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify -@@ -27,38 +27,60 @@ - not, see . */ - - static void --elf_cvt_note (void *dest, const void *src, size_t len, int encode) -+elf_cvt_note (void *dest, const void *src, size_t len, int encode, -+ bool nhdr8) - { -+ /* Note that the header is always the same size, but the padding -+ differs for GNU Property notes. */ - assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); - - while (len >= sizeof (Elf32_Nhdr)) - { -+ /* Convert the header. */ - (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr), - encode); - const Elf32_Nhdr *n = encode ? src : dest; -- Elf32_Word namesz = NOTE_ALIGN (n->n_namesz); -- Elf32_Word descsz = NOTE_ALIGN (n->n_descsz); - -- len -= sizeof *n; -- src += sizeof *n; -- dest += sizeof *n; -+ size_t note_len = sizeof *n; - -- if (namesz > len) -+ /* desc needs to be aligned. */ -+ note_len += n->n_namesz; -+ note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len); -+ if (note_len > len || note_len < 8) - break; -- len -= namesz; -- if (descsz > len) -+ -+ /* data as a whole needs to be aligned. */ -+ note_len += n->n_descsz; -+ note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len); -+ if (note_len > len || note_len < 8) - break; -- len -= descsz; - -+ /* Copy or skip the note data. */ -+ size_t note_data_len = note_len - sizeof *n; -+ src += sizeof *n; -+ dest += sizeof *n; - if (src != dest) -- memcpy (dest, src, namesz + descsz); -+ memcpy (dest, src, note_data_len); - -- src += namesz + descsz; -- dest += namesz + descsz; -+ src += note_data_len; -+ dest += note_data_len; -+ len -= note_len; - } - -- /* Copy opver any leftover data unconcerted. Probably part of -+ /* Copy over any leftover data unconverted. Probably part of - truncated name/desc data. */ - if (unlikely (len > 0) && src != dest) - memcpy (dest, src, len); - } -+ -+static void -+elf_cvt_note4 (void *dest, const void *src, size_t len, int encode) -+{ -+ elf_cvt_note (dest, src, len, encode, false); -+} -+ -+static void -+elf_cvt_note8 (void *dest, const void *src, size_t len, int encode) -+{ -+ elf_cvt_note (dest, src, len, encode, true); -+} -diff --git a/src/elflint.c b/src/elflint.c -index 3d44595..fa3af4c 100644 ---- a/src/elflint.c -+++ b/src/elflint.c -@@ -4331,6 +4331,7 @@ section [%2d] '%s': unknown core file note type %" PRIu32 - case NT_GNU_HWCAP: - case NT_GNU_BUILD_ID: - case NT_GNU_GOLD_VERSION: -+ case NT_GNU_PROPERTY_TYPE_0: - break; - - case 0: -@@ -4376,7 +4377,8 @@ phdr[%d]: no note entries defined for the type of file\n"), - GElf_Off notes_size = 0; - Elf_Data *data = elf_getdata_rawchunk (ebl->elf, - phdr->p_offset, phdr->p_filesz, -- ELF_T_NHDR); -+ (phdr->p_align == 8 -+ ? ELF_T_NHDR8 : ELF_T_NHDR)); - if (data != NULL && data->d_buf != NULL) - notes_size = check_note_data (ebl, ehdr, data, 0, cnt, phdr->p_offset); - -diff --git a/src/readelf.c b/src/readelf.c -index 72ae04e..ccd07eb 100644 ---- a/src/readelf.c -+++ b/src/readelf.c -@@ -12300,7 +12300,8 @@ handle_notes (Ebl *ebl, GElf_Ehdr *ehdr) - handle_notes_data (ebl, ehdr, phdr->p_offset, - elf_getdata_rawchunk (ebl->elf, - phdr->p_offset, phdr->p_filesz, -- ELF_T_NHDR)); -+ (phdr->p_align == 8 -+ ? ELF_T_NHDR8 : ELF_T_NHDR))); - } - } - diff --git a/SOURCES/elfutils-0.174-gnu-props-32.patch b/SOURCES/elfutils-0.174-gnu-props-32.patch deleted file mode 100644 index ff9305b..0000000 --- a/SOURCES/elfutils-0.174-gnu-props-32.patch +++ /dev/null @@ -1,58 +0,0 @@ -commit e8b9832af19e5975fb2a9dbe729eaba0373c781f -Author: Mark Wielaard -Date: Mon Dec 3 00:03:39 2018 +0100 - - libebl: Fix reading GNU_PROPERTY_STACK_SIZE reading from 32bit notes. - - When reading a GNU_PROPERTY_STACK_SIZE we need to use the proper data - type. GElf_Addr is 64bit always and when reading a 32bit size part of - it would not be initialized. Use either Elf32_Addr or Elf64_Addr to - read and print the data. - - Add 32bit and 64bit, little and big endian testcases. - - Signed-off-by: Mark Wielaard - -diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c -index 58ac86d..c19ea37 100644 ---- a/libebl/eblobjnote.c -+++ b/libebl/eblobjnote.c -@@ -360,15 +360,22 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, - if (prop.pr_type == GNU_PROPERTY_STACK_SIZE) - { - printf ("STACK_SIZE "); -- if (prop.pr_datasz == 4 || prop.pr_datasz == 8) -+ union -+ { -+ Elf64_Addr a64; -+ Elf32_Addr a32; -+ } addr; -+ if ((elfclass == ELFCLASS32 && prop.pr_datasz == 4) -+ || (elfclass == ELFCLASS64 && prop.pr_datasz == 8)) - { -- GElf_Addr addr; - in.d_type = ELF_T_ADDR; - out.d_type = ELF_T_ADDR; - in.d_size = prop.pr_datasz; -- out.d_size = sizeof (addr); -+ out.d_size = prop.pr_datasz; - in.d_buf = (void *) desc; -- out.d_buf = (void *) &addr; -+ out.d_buf = (elfclass == ELFCLASS32 -+ ? (void *) &addr.a32 -+ : (void *) &addr.a64); - - if (gelf_xlatetom (ebl->elf, &out, &in, - elfident[EI_DATA]) == NULL) -@@ -376,7 +383,10 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, - printf ("%s\n", elf_errmsg (-1)); - return; - } -- printf ("%#" PRIx64 "\n", addr); -+ if (elfclass == ELFCLASS32) -+ printf ("%#" PRIx32 "\n", addr.a32); -+ else -+ printf ("%#" PRIx64 "\n", addr.a64); - } - else - printf (" (garbage datasz: %" PRIx32 ")\n", diff --git a/SOURCES/elfutils-0.174-libdwfl-sanity-check-core-reads.patch b/SOURCES/elfutils-0.174-libdwfl-sanity-check-core-reads.patch deleted file mode 100644 index 19dda87..0000000 --- a/SOURCES/elfutils-0.174-libdwfl-sanity-check-core-reads.patch +++ /dev/null @@ -1,51 +0,0 @@ -commit 20f9de9b5f704cec55df92406a50bcbcfca96acd -Author: Mark Wielaard -Date: Sun Oct 14 16:45:48 2018 +0200 - - libdwfl: Sanity check partial core file data reads. - - There were two issues when reading note data from a core file. - We didn't check if the data we already had in a buffer was big - enough. And if we did get the data, we should check if we got - everything, or just a part of the data. - - https://sourceware.org/bugzilla/show_bug.cgi?id=23752 - - Signed-off-by: Mark Wielaard - -diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c -index 36e5c82..8749884 100644 ---- a/libdwfl/dwfl_segment_report_module.c -+++ b/libdwfl/dwfl_segment_report_module.c -@@ -1,5 +1,5 @@ - /* Sniff out modules from ELF headers visible in memory segments. -- Copyright (C) 2008-2012, 2014, 2015 Red Hat, Inc. -+ Copyright (C) 2008-2012, 2014, 2015, 2018 Red Hat, Inc. - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify -@@ -301,7 +301,10 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, - inline bool read_portion (void **data, size_t *data_size, - GElf_Addr vaddr, size_t filesz) - { -- if (vaddr - start + filesz > buffer_available -+ /* Check whether we will have to read the segment data, or if it -+ can be returned from the existing buffer. */ -+ if (filesz > buffer_available -+ || vaddr - start > buffer_available - filesz - /* If we're in string mode, then don't consider the buffer we have - sufficient unless it contains the terminator of the string. */ - || (filesz == 0 && memchr (vaddr - start + buffer, '\0', -@@ -459,6 +462,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, - if (read_portion (&data, &data_size, vaddr, filesz)) - return; - -+ /* data_size will be zero if we got everything from the initial -+ buffer, otherwise it will be the size of the new buffer that -+ could be read. */ -+ if (data_size != 0) -+ filesz = data_size; -+ - assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); - - void *notes; diff --git a/SOURCES/elfutils-0.174-size-rec-ar.patch b/SOURCES/elfutils-0.174-size-rec-ar.patch deleted file mode 100644 index 091fa49..0000000 --- a/SOURCES/elfutils-0.174-size-rec-ar.patch +++ /dev/null @@ -1,31 +0,0 @@ -commit 22d2d082d57a7470fadc0eae67179553f4919209 -Author: Mark Wielaard -Date: Thu Oct 18 23:15:48 2018 +0200 - - size: Handle recursive ELF ar files. - - eu-size didn't handle an ELF ar file that contained an ar file itself - correctly. handle_ar would recursively call itself but close the ELF - file before returning. Only close the ELF file at the top-level. - - https://sourceware.org/bugzilla/show_bug.cgi?id=23787 - - Signed-off-by: Mark Wielaard - -diff --git a/src/size.c b/src/size.c -index 5ff3f2a..f01fd88 100644 ---- a/src/size.c -+++ b/src/size.c -@@ -374,8 +374,10 @@ handle_ar (int fd, Elf *elf, const char *prefix, const char *fname) - INTERNAL_ERROR (fname); - } - -- if (unlikely (elf_end (elf) != 0)) -- INTERNAL_ERROR (fname); -+ /* Only close ELF handle if this was a "top level" ar file. */ -+ if (prefix == NULL) -+ if (unlikely (elf_end (elf) != 0)) -+ INTERNAL_ERROR (fname); - - return result; - } diff --git a/SOURCES/elfutils-0.174-strip-unstrip-group.patch b/SOURCES/elfutils-0.174-strip-unstrip-group.patch deleted file mode 100644 index 2fd9919..0000000 --- a/SOURCES/elfutils-0.174-strip-unstrip-group.patch +++ /dev/null @@ -1,226 +0,0 @@ -commit c06ab0bbb4761a69d2f188675d21d1a9131e9ecb -Author: Mark Wielaard -Date: Sat Oct 13 10:27:47 2018 +0200 - - strip, unstrip: Handle SHT_GROUP correctly. - - The usage of annobin in Fedora showed a couple of bugs when using - eu-strip and eu-unstrip on ET_REL files that contain multiple group - sections. - - When stripping we should not remove the SHF_GROUP flag from sections - even if the group section itself might be removed. Either the section - itself gets removed, and so the flag doesn't matter. Or it gets moved - together with the group section into the debug file, and then it still - needs to have the flag set. Also we would "renumber" the section group - flag field (which isn't a section index, and so shouldn't be changed). - - Often the group sections have the exact same name (".group"), flags - (none) and sometimes the same sizes. Which makes matching them hard. - Extract the group signature and compare those when comparing two - group sections. - - Signed-off-by: Mark Wielaard - -diff --git a/src/strip.c b/src/strip.c -index 1f7b3ca..fdebc5e 100644 ---- a/src/strip.c -+++ b/src/strip.c -@@ -792,9 +792,13 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, - - if (shdr_info[shdr_info[cnt].group_idx].idx == 0) - { -- /* The section group section will be removed. */ -+ /* The section group section might be removed. -+ Don't remove the SHF_GROUP flag. The section is -+ either also removed, in which case the flag doesn't matter. -+ Or it moves with the group into the debug file, then -+ it will be reconnected with the new group and should -+ still have the flag set. */ - shdr_info[cnt].group_idx = 0; -- shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP; - } - } - -@@ -1368,7 +1372,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, - && shdr_info[cnt].data->d_buf != NULL); - - Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; -- for (size_t inner = 0; -+ /* First word is the section group flag. -+ Followed by section indexes, that need to be renumbered. */ -+ for (size_t inner = 1; - inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); - ++inner) - if (grpref[inner] < shnum) -diff --git a/src/unstrip.c b/src/unstrip.c -index e6f0947..03a0346 100644 ---- a/src/unstrip.c -+++ b/src/unstrip.c -@@ -696,6 +696,7 @@ struct section - { - Elf_Scn *scn; - const char *name; -+ const char *sig; - Elf_Scn *outscn; - Dwelf_Strent *strent; - GElf_Shdr shdr; -@@ -720,7 +721,8 @@ compare_alloc_sections (const struct section *s1, const struct section *s2, - - static int - compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2, -- const char *name1, const char *name2) -+ const char *name1, const char *name2, -+ const char *sig1, const char *sig2) - { - /* Sort by sh_flags as an arbitrary ordering. */ - if (shdr1->sh_flags < shdr2->sh_flags) -@@ -734,6 +736,10 @@ compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2, - if (shdr1->sh_size > shdr2->sh_size) - return 1; - -+ /* Are they both SHT_GROUP sections? Then compare signatures. */ -+ if (sig1 != NULL && sig2 != NULL) -+ return strcmp (sig1, sig2); -+ - /* Sort by name as last resort. */ - return strcmp (name1, name2); - } -@@ -751,7 +757,8 @@ compare_sections (const void *a, const void *b, bool rel) - return ((s1->shdr.sh_flags & SHF_ALLOC) - ? compare_alloc_sections (s1, s2, rel) - : compare_unalloc_sections (&s1->shdr, &s2->shdr, -- s1->name, s2->name)); -+ s1->name, s2->name, -+ s1->sig, s2->sig)); - } - - static int -@@ -986,6 +993,44 @@ get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab) - return shstrtab->d_buf + shdr->sh_name; - } - -+/* Returns the signature of a group section, or NULL if the given -+ section isn't a group. */ -+static const char * -+get_group_sig (Elf *elf, GElf_Shdr *shdr) -+{ -+ if (shdr->sh_type != SHT_GROUP) -+ return NULL; -+ -+ Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link); -+ if (symscn == NULL) -+ error (EXIT_FAILURE, 0, _("bad sh_link for group section: %s"), -+ elf_errmsg (-1)); -+ -+ GElf_Shdr symshdr_mem; -+ GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); -+ if (symshdr == NULL) -+ error (EXIT_FAILURE, 0, _("couldn't get shdr for group section: %s"), -+ elf_errmsg (-1)); -+ -+ Elf_Data *symdata = elf_getdata (symscn, NULL); -+ if (symdata == NULL) -+ error (EXIT_FAILURE, 0, _("bad data for group symbol section: %s"), -+ elf_errmsg (-1)); -+ -+ GElf_Sym sym_mem; -+ GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem); -+ if (sym == NULL) -+ error (EXIT_FAILURE, 0, _("couldn't get symbol for group section: %s"), -+ elf_errmsg (-1)); -+ -+ const char *sig = elf_strptr (elf, symshdr->sh_link, sym->st_name); -+ if (sig == NULL) -+ error (EXIT_FAILURE, 0, _("bad symbol name for group section: %s"), -+ elf_errmsg (-1)); -+ -+ return sig; -+} -+ - /* Fix things up when prelink has moved some allocated sections around - and the debuginfo file's section headers no longer match up. - This fills in SECTIONS[0..NALLOC-1].outscn or exits. -@@ -1111,6 +1156,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, - sec->scn = elf_getscn (main, i + 1); /* Really just for ndx. */ - sec->outscn = NULL; - sec->strent = NULL; -+ sec->sig = get_group_sig (main, &sec->shdr); - ++undo_nalloc; - } - } -@@ -1336,6 +1382,7 @@ more sections in stripped file than debug file -- arguments reversed?")); - sections[i].scn = scn; - sections[i].outscn = NULL; - sections[i].strent = NULL; -+ sections[i].sig = get_group_sig (stripped, shdr); - } - - const struct section *stripped_symtab = NULL; -@@ -1354,7 +1401,8 @@ more sections in stripped file than debug file -- arguments reversed?")); - - /* Locate a matching unallocated section in SECTIONS. */ - inline struct section *find_unalloc_section (const GElf_Shdr *shdr, -- const char *name) -+ const char *name, -+ const char *sig) - { - size_t l = nalloc, u = stripped_shnum - 1; - while (l < u) -@@ -1362,7 +1410,8 @@ more sections in stripped file than debug file -- arguments reversed?")); - size_t i = (l + u) / 2; - struct section *sec = §ions[i]; - int cmp = compare_unalloc_sections (shdr, &sec->shdr, -- name, sec->name); -+ name, sec->name, -+ sig, sec->sig); - if (cmp < 0) - u = i; - else if (cmp > 0) -@@ -1435,7 +1484,8 @@ more sections in stripped file than debug file -- arguments reversed?")); - else - { - /* Look for the section that matches. */ -- sec = find_unalloc_section (shdr, name); -+ sec = find_unalloc_section (shdr, name, -+ get_group_sig (unstripped, shdr)); - if (sec == NULL) - { - /* An additional unallocated section is fine if not SHT_NOBITS. - -commit eee4269e53154daaf0251371aacd91ec5db3eb30 -Author: Mark Wielaard -Date: Sat Oct 13 10:27:47 2018 +0200 - - unstrip: Renumber the group section indexes. - - When unstripping we might need to renumber the group section indexes. - Just like we do when stripping. - - Signed-off-by: Mark Wielaard - -diff --git a/src/unstrip.c b/src/unstrip.c -index 03a0346..2cfd3b3 100644 ---- a/src/unstrip.c -+++ b/src/unstrip.c -@@ -1708,6 +1708,20 @@ more sections in stripped file than debug file -- arguments reversed?")); - if (shdr_mem.sh_type == SHT_DYNSYM) - stripped_dynsym = sec; - } -+ -+ if (shdr_mem.sh_type == SHT_GROUP) -+ { -+ /* We must adjust all the section indices in the group. -+ Skip the first word, which is the section group flag. -+ Everything else is a section index. */ -+ Elf32_Word *shndx = (Elf32_Word *) outdata->d_buf; -+ for (size_t i = 1; i < shdr_mem.sh_size / sizeof (Elf32_Word); ++i) -+ if (shndx[i] == SHN_UNDEF || shndx[i] >= stripped_shnum) -+ error (EXIT_FAILURE, 0, -+ _("group has invalid section index [%zd]"), i); -+ else -+ shndx[i] = ndx_section[shndx[i] - 1]; -+ } - } - - /* We may need to update the symbol table. */ diff --git a/SOURCES/elfutils-0.174-version-note.patch b/SOURCES/elfutils-0.174-version-note.patch deleted file mode 100644 index fb33d83..0000000 --- a/SOURCES/elfutils-0.174-version-note.patch +++ /dev/null @@ -1,156 +0,0 @@ -commit 7a3f6fe60b8519b5372f5a5521ccbac59411f33f -Author: Mark Wielaard -Date: Sun Nov 11 23:50:41 2018 +0100 - - Recognize NT_VERSION notes. - - NT_VERSION notes are emitted by the gas .version directive. - They have an empty description and (ab)use the owner name to store the - version data string. - - Signed-off-by: Mark Wielaard - -diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c -index 57e9f52..8fda7d9 100644 ---- a/libebl/eblobjnote.c -+++ b/libebl/eblobjnote.c -@@ -135,6 +135,14 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type, - return; - } - -+ /* NT_VERSION doesn't have any info. All data is in the name. */ -+ if (descsz == 0 && type == NT_VERSION) -+ return; -+ -+ /* Everything else should have the "GNU" owner name. */ -+ if (strcmp ("GNU", name) != 0) -+ return; -+ - switch (type) - { - case NT_GNU_BUILD_ID: -@@ -337,7 +345,7 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type, - break; - - case NT_GNU_ABI_TAG: -- if (strcmp (name, "GNU") == 0 && descsz >= 8 && descsz % 4 == 0) -+ if (descsz >= 8 && descsz % 4 == 0) - { - Elf_Data in = - { -diff --git a/libebl/eblobjnotetypename.c b/libebl/eblobjnotetypename.c -index af23cae..8cdd781 100644 ---- a/libebl/eblobjnotetypename.c -+++ b/libebl/eblobjnotetypename.c -@@ -39,6 +39,7 @@ - - const char * - ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type, -+ GElf_Word descsz, - char *buf, size_t len) - { - const char *res = ebl->object_note_type_name (name, type, buf, len); -@@ -80,14 +81,19 @@ ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type, - - if (strcmp (name, "GNU") != 0) - { -+ /* NT_VERSION is special, all data is in the name. */ -+ if (descsz == 0 && type == NT_VERSION) -+ return "VERSION"; -+ - snprintf (buf, len, "%s: %" PRIu32, gettext (""), type); - return buf; - } - -+ /* And finally all the "GNU" note types. */ - static const char *knowntypes[] = - { - #define KNOWNSTYPE(name) [NT_##name] = #name -- KNOWNSTYPE (VERSION), -+ KNOWNSTYPE (GNU_ABI_TAG), - KNOWNSTYPE (GNU_HWCAP), - KNOWNSTYPE (GNU_BUILD_ID), - KNOWNSTYPE (GNU_GOLD_VERSION), -diff --git a/libebl/libebl.h b/libebl/libebl.h -index a34fe48..5830654 100644 ---- a/libebl/libebl.h -+++ b/libebl/libebl.h -@@ -175,8 +175,8 @@ extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf, - - /* Return name of the note section type for an object file. */ - extern const char *ebl_object_note_type_name (Ebl *ebl, const char *name, -- uint32_t type, char *buf, -- size_t len); -+ uint32_t type, GElf_Word descsz, -+ char *buf, size_t len); - - /* Print information about object note if available. */ - extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type, -diff --git a/src/elflint.c b/src/elflint.c -index fa3af4c..dff74ee 100644 ---- a/src/elflint.c -+++ b/src/elflint.c -@@ -1,5 +1,5 @@ - /* Pedantic checking of ELF files compliance with gABI/psABI spec. -- Copyright (C) 2001-2015, 2017 Red Hat, Inc. -+ Copyright (C) 2001-2015, 2017, 2018 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper , 2001. - -@@ -4332,7 +4332,17 @@ section [%2d] '%s': unknown core file note type %" PRIu32 - case NT_GNU_BUILD_ID: - case NT_GNU_GOLD_VERSION: - case NT_GNU_PROPERTY_TYPE_0: -- break; -+ if (nhdr.n_namesz == sizeof ELF_NOTE_GNU -+ && strcmp (data->d_buf + name_offset, ELF_NOTE_GNU) == 0) -+ break; -+ else -+ { -+ /* NT_VERSION is 1, same as NT_GNU_ABI_TAG. It has no -+ descriptor and (ab)uses the name as version string. */ -+ if (nhdr.n_descsz == 0 && nhdr.n_type == NT_VERSION) -+ break; -+ } -+ goto unknown_note; - - case 0: - /* Linux vDSOs use a type 0 note for the kernel version word. */ -@@ -4341,16 +4351,21 @@ section [%2d] '%s': unknown core file note type %" PRIu32 - break; - FALLTHROUGH; - default: -+ { -+ unknown_note: - if (shndx == 0) - ERROR (gettext ("\ --phdr[%d]: unknown object file note type %" PRIu32 " at offset %zu\n"), -- phndx, (uint32_t) nhdr.n_type, offset); -+phdr[%d]: unknown object file note type %" PRIu32 " with owner name '%s' at offset %zu\n"), -+ phndx, (uint32_t) nhdr.n_type, -+ (char *) data->d_buf + name_offset, offset); - else - ERROR (gettext ("\ - section [%2d] '%s': unknown object file note type %" PRIu32 -- " at offset %zu\n"), -+ " with owner name '%s' at offset %zu\n"), - shndx, section_name (ebl, shndx), -- (uint32_t) nhdr.n_type, offset); -+ (uint32_t) nhdr.n_type, -+ (char *) data->d_buf + name_offset, offset); -+ } - } - } - -diff --git a/src/readelf.c b/src/readelf.c -index c6c3fb3..659e34f 100644 ---- a/src/readelf.c -+++ b/src/readelf.c -@@ -12201,6 +12201,7 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr, - ? ebl_core_note_type_name (ebl, nhdr.n_type, - buf, sizeof (buf)) - : ebl_object_note_type_name (ebl, name, nhdr.n_type, -+ nhdr.n_descsz, - buf2, sizeof (buf2))); - - /* Filter out invalid entries. */ diff --git a/SOURCES/elfutils-0.174-x86_64_unwind.patch b/SOURCES/elfutils-0.174-x86_64_unwind.patch deleted file mode 100644 index b766517..0000000 --- a/SOURCES/elfutils-0.174-x86_64_unwind.patch +++ /dev/null @@ -1,127 +0,0 @@ -commit 825e48c4e942e3cbdab1b75c04b8c014867d66ab -Author: Milian Wolff -Date: Mon Oct 29 16:21:26 2018 +0100 - - Also find CFI in sections of type SHT_X86_64_UNWIND - - On my system with g++ (GCC) 8.2.1 20180831 with GNU gold (GNU Binutils - 2.31.1) 1.16, the .eh_frame section does not have type PROGBITS - but rather is using X86_64_UNWIND nowadays: - - ``` - $ echo "int main(){ return 0; }" > test.c - $ gcc test.c - $ readelf --sections a.out | grep .eh_frame - [14] .eh_frame X86_64_UNWIND 0000000000000670 00000670 - [15] .eh_frame_hdr X86_64_UNWIND 0000000000000724 00000724 - ``` - - Without this patch, libdw refuses to use the available unwind - information, leading to broken backtraces while unwinding. With the - patch applied, unwinding works once more in such situations. - - Signed-off-by: Milian Wolff - Signed-off-by: Mark Wielaard - Tested-by: Milian Wolff - -diff --git a/libdw/dwarf_getcfi_elf.c b/libdw/dwarf_getcfi_elf.c -index 315cc02..adcaea0 100644 ---- a/libdw/dwarf_getcfi_elf.c -+++ b/libdw/dwarf_getcfi_elf.c -@@ -298,7 +298,7 @@ getcfi_shdr (Elf *elf, const GElf_Ehdr *ehdr) - } - else if (!strcmp (name, ".eh_frame")) - { -- if (shdr->sh_type == SHT_PROGBITS) -+ if (shdr->sh_type != SHT_NOBITS) - return getcfi_scn_eh_frame (elf, ehdr, scn, shdr, - hdr_scn, hdr_vaddr); - else - -commit 4b0342b85b5b1a3d3636e06e3b5320954828dfb1 -Author: Mark Wielaard -Date: Tue Nov 6 12:01:25 2018 +0100 - - backends: Add x86_64 section_type_name for SHT_X86_64_UNWIND. - - Makes sure that eu-readelf and eu-elflint recognize and show the - x86_64 specific section type correctly. - - Signed-off-by: Mark Wielaard - Tested-by: Milian Wolff - -diff --git a/backends/x86_64_init.c b/backends/x86_64_init.c -index adfa479..49f6c6c 100644 ---- a/backends/x86_64_init.c -+++ b/backends/x86_64_init.c -@@ -1,5 +1,5 @@ - /* Initialization of x86-64 specific backend library. -- Copyright (C) 2002-2009, 2013 Red Hat, Inc. -+ Copyright (C) 2002-2009, 2013, 2018 Red Hat, Inc. - Copyright (C) H.J. Lu , 2015. - This file is part of elfutils. - Written by Ulrich Drepper , 2002. -@@ -55,6 +55,7 @@ x86_64_init (Elf *elf __attribute__ ((unused)), - eh->name = "AMD x86-64"; - x86_64_init_reloc (eh); - HOOK (eh, reloc_simple_type); -+ HOOK (eh, section_type_name); - if (eh->class == ELFCLASS32) - eh->core_note = x32_core_note; - else -diff --git a/backends/x86_64_symbol.c b/backends/x86_64_symbol.c -index e07b180..98457bc 100644 ---- a/backends/x86_64_symbol.c -+++ b/backends/x86_64_symbol.c -@@ -1,5 +1,5 @@ - /* x86_64 specific symbolic name handling. -- Copyright (C) 2002, 2005 Red Hat, Inc. -+ Copyright (C) 2002, 2005, 2018 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper , 2002. - -@@ -59,3 +59,15 @@ x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, - return ELF_T_NUM; - } - } -+ -+/* Return symbolic representation of section type. */ -+const char * -+x86_64_section_type_name (int type, -+ char *buf __attribute__ ((unused)), -+ size_t len __attribute__ ((unused))) -+{ -+ if (type == SHT_X86_64_UNWIND) -+ return "X86_64_UNWIND"; -+ -+ return NULL; -+} - -commit 22ec8efc1dd87cdc7892523457eb55990b967224 -Author: Mark Wielaard -Date: Sat Nov 10 23:33:03 2018 +0100 - - elflint: Allow PT_GNU_EH_FRAME segment to match SHT_X86_64_UNWIND section. - - The gold linker might generate an .eh_frame_hdr with a SHT_X86_64_UNWIND - type instead of a SHT_PROGBITS type. - - Signed-off-by: Mark Wielaard - -diff --git a/src/elflint.c b/src/elflint.c -index 184ca12..810c8bd 100644 ---- a/src/elflint.c -+++ b/src/elflint.c -@@ -4633,8 +4633,10 @@ program header offset in ELF header and PHDR entry do not match")); - any = true; - shdr = gelf_getshdr (scn, &shdr_mem); - if (shdr != NULL -- && shdr->sh_type == (is_debuginfo -- ? SHT_NOBITS : SHT_PROGBITS) -+ && ((is_debuginfo && shdr->sh_type == SHT_NOBITS) -+ || (! is_debuginfo -+ && (shdr->sh_type == SHT_PROGBITS -+ || shdr->sh_type == SHT_X86_64_UNWIND))) - && elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL - && ! strcmp (".eh_frame_hdr", - elf_strptr (ebl->elf, shstrndx, shdr->sh_name))) diff --git a/SOURCES/elfutils-0.176-elf-update.patch b/SOURCES/elfutils-0.176-elf-update.patch new file mode 100644 index 0000000..501c103 --- /dev/null +++ b/SOURCES/elfutils-0.176-elf-update.patch @@ -0,0 +1,664 @@ +commit d7193bd7c9dc2a979352eee7fc446dacd3e97779 +Author: Mark Wielaard +Date: Sun May 12 00:37:45 2019 +0200 + + libelf: Mark shdr_flags dirty if offset or size changes during update. + + We forgot to mark the shdr_flags dirty when only the sh_size or + sh_offset changed during elf_update (). This meant that if there were + no other shdr changes we only wrote out the section data, but didn't + write out the shdr table to the file. + + Add a testcase that puts some sections in the reverse order and then + writes out the resulting file again without doing any other + updates. This would show the issue after write out of the + (re-reversed) ELF file (the .shstrtab section offset would be wrong + causing all section names to be garbage). Also run a self test. + + Signed-off-by: Mark Wielaard + +diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c +index 2ce6a59..303055a 100644 +--- a/libelf/elf32_updatenull.c ++++ b/libelf/elf32_updatenull.c +@@ -366,12 +366,15 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) + } + + /* See whether the section size is correct. */ ++ int size_changed = 0; + update_if_changed (shdr->sh_size, (GElf_Word) offset, +- changed); ++ size_changed); ++ changed |= size_changed; + + if (shdr->sh_type != SHT_NOBITS) + size += offset; + ++ scn->shdr_flags |= (offset_changed | size_changed); + scn->flags |= changed; + } + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 80900e4..87428aa 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -60,7 +60,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ + fillfile dwarf_default_lower_bound dwarf-die-addr-die \ + get-units-invalid get-units-split attr-integrate-skel \ + all-dwarf-ranges unit-info next_cfi \ +- elfcopy addsections xlate_notes ++ elfcopy addsections xlate_notes elfrdwrnop + + asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ + asm-tst6 asm-tst7 asm-tst8 asm-tst9 +@@ -157,6 +157,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ + run-all-dwarf-ranges.sh run-unit-info.sh \ + run-reloc-bpf.sh \ + run-next-cfi.sh run-next-cfi-self.sh \ ++ run-reverse-sections.sh run-reverse-sections-self.sh \ + run-copyadd-sections.sh run-copymany-sections.sh \ + run-typeiter-many.sh run-strip-test-many.sh \ + run-strip-version.sh run-xlate-note.sh +@@ -419,6 +420,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ + run-unit-info.sh run-next-cfi.sh run-next-cfi-self.sh \ + testfile-riscv64.bz2 testfile-riscv64-s.bz2 \ + testfile-riscv64-core.bz2 \ ++ run-reverse-sections.sh run-reverse-sections-self.sh \ + run-copyadd-sections.sh run-copymany-sections.sh \ + run-typeiter-many.sh run-strip-test-many.sh \ + testfile-debug-rel-ppc64-g.o.bz2 \ +@@ -598,6 +600,7 @@ next_cfi_LDADD = $(libelf) $(libdw) + elfcopy_LDADD = $(libelf) + addsections_LDADD = $(libelf) + xlate_notes_LDADD = $(libelf) ++elfrdwrnop_LDADD = $(libelf) + + # We want to test the libelf header against the system elf.h header. + # Don't include any -I CPPFLAGS. Except when we install our own elf.h. +diff --git a/tests/elfcopy.c b/tests/elfcopy.c +index 9000cc9..d457bad 100644 +--- a/tests/elfcopy.c ++++ b/tests/elfcopy.c +@@ -69,9 +69,11 @@ setshstrndx (Elf *elf, size_t ndx) + + /* Copies all elements of an ELF file either using mmap or read. */ + static void +-copy_elf (const char *in, const char *out, bool use_mmap) ++copy_elf (const char *in, const char *out, bool use_mmap, bool reverse_offs) + { +- printf ("\ncopy_elf: %s -> %s (%s)\n", in, out, use_mmap ? "mmap" : "read"); ++ printf ("\ncopy_elf: %s -> %s (%s,%s)\n", in, out, ++ use_mmap ? "mmap" : "read", ++ reverse_offs ? "reverse" : "same"); + + /* Existing ELF file. */ + int fda = open (in, O_RDONLY); +@@ -182,8 +184,28 @@ copy_elf (const char *in, const char *out, bool use_mmap) + } + } + ++ GElf_Off *offs = NULL; ++ size_t shnum; ++ if (reverse_offs) ++ { ++ if (elf_getshdrnum (elfa, &shnum) < 0) ++ { ++ printf ("couldn't get shdrnum: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ offs = (GElf_Off *) malloc (shnum * sizeof (GElf_Off)); ++ if (offs == NULL) ++ { ++ printf ("couldn't allocate memory for offs\n"); ++ exit (1); ++ } ++ } ++ + /* Copy all sections, headers and data. */ + Elf_Scn *scn = NULL; ++ size_t last_off = 0; ++ GElf_Shdr last_shdr = { .sh_type = SHT_NULL }; + while ((scn = elf_nextscn (elfa, scn)) != NULL) + { + /* Get the header. */ +@@ -194,6 +216,34 @@ copy_elf (const char *in, const char *out, bool use_mmap) + exit (1); + } + ++ if (reverse_offs) ++ { ++ offs[last_off] = shdr.sh_offset; ++ ++ if (last_shdr.sh_type != SHT_NULL ++ && last_shdr.sh_addralign == shdr.sh_addralign ++ && shdr.sh_addralign == 1 ++ && last_shdr.sh_type != SHT_NOBITS ++ && shdr.sh_type != SHT_NOBITS ++ && (phnum == 0 ++ || ((shdr.sh_flags & SHF_ALLOC) == 0 ++ && (last_shdr.sh_flags & SHF_ALLOC) == 0))) ++ { ++ printf ("Swapping offsets of section %zd and %zd\n", ++ last_off, last_off + 1); ++ GElf_Word off = offs[last_off - 1]; ++ offs[last_off - 1] = off + shdr.sh_size; ++ offs[last_off] = off; ++ last_shdr.sh_type = SHT_NULL; ++ } ++ else ++ { ++ last_shdr = shdr; ++ offs[last_off] = shdr.sh_offset; ++ } ++ last_off++; ++ } ++ + /* Create new section. */ + Elf_Scn *new_scn = elf_newscn (elfb); + if (new_scn == NULL) +@@ -223,9 +273,34 @@ copy_elf (const char *in, const char *out, bool use_mmap) + } + } + +- /* Write everything to disk. If there are any phdrs then we want +- the exact same layout. Do we want ELF_F_PERMISSIVE? */ +- if (phnum > 0) ++ if (reverse_offs) ++ { ++ last_off = 0; ++ scn = NULL; ++ while ((scn = elf_nextscn (elfb, scn)) != NULL) ++ { ++ GElf_Shdr shdr; ++ if (gelf_getshdr (scn, &shdr) == NULL) ++ { ++ printf ("couldn't get shdr for updating: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ shdr.sh_offset = offs[last_off++]; ++ ++ if (gelf_update_shdr (scn, &shdr) == 0) ++ { ++ printf ("couldn't update shdr sh_off: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ } ++ free (offs); ++ } ++ ++ /* Write everything to disk. If there are any phdrs, or we want to ++ update the offsets, then we want the exact same layout. Do we ++ want ELF_F_PERMISSIVE? */ ++ if (phnum > 0 || reverse_offs) + elf_flagelf (elfb, ELF_C_SET, ELF_F_LAYOUT); + if (elf_update (elfb, ELF_C_WRITE) < 0) + { +@@ -264,9 +339,9 @@ main (int argc, const char *argv[]) + elf_version (EV_CURRENT); + + /* Takes the given file, and create a new identical one. */ +- if (argc < 3 || argc > 4) ++ if (argc < 3 || argc > 5) + { +- fprintf (stderr, "elfcopy [--mmap] in.elf out.elf\n"); ++ fprintf (stderr, "elfcopy [--mmap] [--reverse-offs] in.elf out.elf\n"); + exit (1); + } + +@@ -278,9 +353,16 @@ main (int argc, const char *argv[]) + argn++; + } + ++ bool reverse_offs = false; ++ if (strcmp (argv[argn], "--reverse-offs") == 0) ++ { ++ reverse_offs = true; ++ argn++; ++ } ++ + const char *in = argv[argn++]; + const char *out = argv[argn]; +- copy_elf (in, out, use_mmap); ++ copy_elf (in, out, use_mmap, reverse_offs); + + return 0; + } +diff --git a/tests/elfrdwrnop.c b/tests/elfrdwrnop.c +new file mode 100644 +index 0000000..997150b +--- /dev/null ++++ b/tests/elfrdwrnop.c +@@ -0,0 +1,100 @@ ++/* Test program for reading and writing out the same file in-place ++ Copyright (C) 2019 Red Hat, Inc. ++ This file is part of elfutils. ++ ++ This file is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ elfutils is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++ ++#ifdef HAVE_CONFIG_H ++# include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ELFUTILS_HEADER(elf) ++#include ++ ++ ++int ++main (int argc, const char *argv[]) ++{ ++ /* Takes the given file, and create a new identical one. */ ++ if (argc != 2) ++ { ++ fprintf (stderr, "elfrdwrnop elf-file\n"); ++ exit (1); ++ } ++ ++ elf_version (EV_CURRENT); ++ ++ const char *name = argv[1]; ++ printf ("elfrdwrdnop %s\n", name); ++ ++ int fd = open (name, O_RDWR); ++ if (fd < 0) ++ { ++ fprintf (stderr, "Couldn't open file '%s': %s\n", ++ name, strerror (errno)); ++ exit (1); ++ } ++ ++ Elf *elf = elf_begin (fd, ELF_C_RDWR, NULL); ++ if (elf == NULL) ++ { ++ fprintf (stderr, "Couldn't open ELF file '%s': %s\n", ++ name, elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ /* Write everything to disk. If there are any phdrs, then we want ++ the exact same layout. */ ++ size_t phnum; ++ if (elf_getphdrnum (elf, &phnum) != 0) ++ { ++ printf ("cannot get phdrs: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ if (phnum > 0) ++ elf_flagelf (elf, ELF_C_SET, ELF_F_LAYOUT); ++ ++ if (elf_update (elf, ELF_C_WRITE) < 0) ++ { ++ printf ("failure in elf_update: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ if (elf_end (elf) != 0) ++ { ++ printf ("couldn't cleanup elf '%s': %s\n", name, elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ if (close (fd) != 0) ++ { ++ printf ("couldn't close '%s': %s\n", name, strerror (errno)); ++ exit (1); ++ } ++ ++ return 0; ++} +diff --git a/tests/run-reverse-sections-self.sh b/tests/run-reverse-sections-self.sh +new file mode 100755 +index 0000000..71afd6a +--- /dev/null ++++ b/tests/run-reverse-sections-self.sh +@@ -0,0 +1,45 @@ ++#! /bin/sh ++# Copyright (C) 2019 Red Hat, Inc. ++# This file is part of elfutils. ++# ++# This file is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# elfutils is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. $srcdir/test-subr.sh ++ ++test_reverse_self () ++{ ++ in_file="$1" ++ base_name="$(basename ${in_file})" ++ out_file="${base_name}.rev" ++ out_file_mmap="${out_file}.mmap" ++ ++ tempfiles ${out_file} ${out_file_mmap} ++ ++ # Reverse the offsets (the files should still be the same otherwise) ++ testrun ${abs_builddir}/elfcopy --reverse-offs ${in_file} ${out_file} ++ testrun ${abs_top_builddir}/src/elfcmp ${in_file} ${out_file} ++ testrun ${abs_top_builddir}/src/elflint --gnu ${out_file} ++ # An in-place nop will likely revert them back ++ testrun ${abs_builddir}/elfrdwrnop ${out_file} ++ testrun ${abs_top_builddir}/src/elfcmp ${in_file} ${out_file} ++ testrun ${abs_top_builddir}/src/elflint --gnu ${out_file} ++} ++ ++# Only really makes sense for ET_REL files, but try all, just to check ++# it also works if we keep the order for the allocated sections. ++for file in $self_test_files; do ++ test_reverse_self $file ++done ++ ++exit 0 +diff --git a/tests/run-reverse-sections.sh b/tests/run-reverse-sections.sh +new file mode 100755 +index 0000000..102a126 +--- /dev/null ++++ b/tests/run-reverse-sections.sh +@@ -0,0 +1,69 @@ ++#! /bin/sh ++# Copyright (C) 2019 Red Hat, Inc. ++# This file is part of elfutils. ++# ++# This file is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# elfutils is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. $srcdir/test-subr.sh ++ ++test_reverse () ++{ ++ in_file="$1" ++ out_file="${in_file}.rev" ++ out_file_mmap="${out_file}.mmap" ++ ++ testfiles ${in_file} ++ tempfiles ${out_file} ${out_file_mmap} ++ ++ # Reverse the offsets (the files should still be the same otherwise) ++ testrun ${abs_builddir}/elfcopy --reverse-offs ${in_file} ${out_file} ++ testrun ${abs_top_builddir}/src/elfcmp ${in_file} ${out_file} ++ testrun ${abs_top_builddir}/src/elflint --gnu ${out_file} ++ # An in-place nop will likely revert them back ++ testrun ${abs_builddir}/elfrdwrnop ${out_file} ++ testrun ${abs_top_builddir}/src/elfcmp ${in_file} ${out_file} ++ testrun ${abs_top_builddir}/src/elflint --gnu ${out_file} ++} ++ ++# A collection of random testfiles to test 32/64bit, little/big endian ++# and non-ET_REL (with phdrs)/ET_REL (without phdrs). ++ ++# 32bit, big endian, rel ++test_reverse testfile29 ++ ++# 64bit, big endian, rel ++test_reverse testfile23 ++ ++# 32bit, little endian, rel ++test_reverse testfile9 ++ ++# 64bit, little endian, rel ++test_reverse testfile38 ++ ++# 32bit, big endian, non-rel ++test_reverse testfile26 ++ ++# 64bit, big endian, non-rel ++test_reverse testfile27 ++ ++# 32bit, little endian, non-rel ++test_reverse testfile ++ ++# 64bit, little endian, non-rel ++# Don't use testfile10. It has section headers in the middle of the file. ++# Same for testfile12. It is legal, but not the point of this testcase. ++# test_reverse testfile10 ++test_reverse testfile13 ++ ++exit 0 +diff -ru elfutils-0.176.orig/tests/Makefile.in elfutils-0.176/tests/Makefile.in +--- elfutils-0.176.orig/tests/Makefile.in 2019-06-03 14:57:17.223607024 +0200 ++++ elfutils-0.176/tests/Makefile.in 2019-06-03 14:58:32.671049626 +0200 +@@ -131,8 +131,8 @@ + get-units-invalid$(EXEEXT) get-units-split$(EXEEXT) \ + attr-integrate-skel$(EXEEXT) all-dwarf-ranges$(EXEEXT) \ + unit-info$(EXEEXT) next_cfi$(EXEEXT) elfcopy$(EXEEXT) \ +- addsections$(EXEEXT) xlate_notes$(EXEEXT) $(am__EXEEXT_1) \ +- $(am__EXEEXT_2) $(am__EXEEXT_4) ++ addsections$(EXEEXT) xlate_notes$(EXEEXT) elfrdwrnop$(EXEEXT) \ ++ $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_4) + @BIARCH_TRUE@am__append_5 = backtrace-child-biarch + TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile$(EXEEXT) \ + test-nlist$(EXEEXT) update1$(EXEEXT) update2$(EXEEXT) \ +@@ -209,7 +209,8 @@ + run-get-units-invalid.sh run-get-units-split.sh \ + run-attr-integrate-skel.sh run-all-dwarf-ranges.sh \ + run-unit-info.sh run-reloc-bpf.sh run-next-cfi.sh \ +- run-next-cfi-self.sh run-copyadd-sections.sh \ ++ run-next-cfi-self.sh run-reverse-sections.sh \ ++ run-reverse-sections-self.sh run-copyadd-sections.sh \ + run-copymany-sections.sh run-typeiter-many.sh \ + run-strip-test-many.sh run-strip-version.sh run-xlate-note.sh \ + $(am__EXEEXT_2) $(am__append_8) $(am__EXEEXT_5) +@@ -451,6 +452,9 @@ + elfputzdata_SOURCES = elfputzdata.c + elfputzdata_OBJECTS = elfputzdata.$(OBJEXT) + elfputzdata_DEPENDENCIES = $(am__DEPENDENCIES_2) ++elfrdwrnop_SOURCES = elfrdwrnop.c ++elfrdwrnop_OBJECTS = elfrdwrnop.$(OBJEXT) ++elfrdwrnop_DEPENDENCIES = $(am__DEPENDENCIES_2) + elfshphehdr_SOURCES = elfshphehdr.c + elfshphehdr_OBJECTS = elfshphehdr.$(OBJEXT) + elfshphehdr_DEPENDENCIES = $(am__DEPENDENCIES_2) +@@ -660,13 +664,13 @@ + ./$(DEPDIR)/early-offscn.Po ./$(DEPDIR)/ecp.Po \ + ./$(DEPDIR)/elfcopy.Po ./$(DEPDIR)/elfgetchdr.Po \ + ./$(DEPDIR)/elfgetzdata.Po ./$(DEPDIR)/elfputzdata.Po \ +- ./$(DEPDIR)/elfshphehdr.Po ./$(DEPDIR)/elfstrmerge.Po \ +- ./$(DEPDIR)/elfstrtab.Po ./$(DEPDIR)/emptyfile.Po \ +- ./$(DEPDIR)/fillfile.Po ./$(DEPDIR)/find-prologues.Po \ +- ./$(DEPDIR)/funcretval.Po ./$(DEPDIR)/funcscopes.Po \ +- ./$(DEPDIR)/get-aranges.Po ./$(DEPDIR)/get-files.Po \ +- ./$(DEPDIR)/get-lines.Po ./$(DEPDIR)/get-pubnames.Po \ +- ./$(DEPDIR)/get-units-invalid.Po \ ++ ./$(DEPDIR)/elfrdwrnop.Po ./$(DEPDIR)/elfshphehdr.Po \ ++ ./$(DEPDIR)/elfstrmerge.Po ./$(DEPDIR)/elfstrtab.Po \ ++ ./$(DEPDIR)/emptyfile.Po ./$(DEPDIR)/fillfile.Po \ ++ ./$(DEPDIR)/find-prologues.Po ./$(DEPDIR)/funcretval.Po \ ++ ./$(DEPDIR)/funcscopes.Po ./$(DEPDIR)/get-aranges.Po \ ++ ./$(DEPDIR)/get-files.Po ./$(DEPDIR)/get-lines.Po \ ++ ./$(DEPDIR)/get-pubnames.Po ./$(DEPDIR)/get-units-invalid.Po \ + ./$(DEPDIR)/get-units-split.Po ./$(DEPDIR)/getsrc_die.Po \ + ./$(DEPDIR)/hash.Po ./$(DEPDIR)/line2addr.Po \ + ./$(DEPDIR)/low_high_pc.Po ./$(DEPDIR)/msg_tst.Po \ +@@ -718,19 +722,19 @@ + dwfl-bug-getmodules.c dwfl-bug-report.c dwfl-proc-attach.c \ + dwfl-report-elf-align.c dwfllines.c dwflmodtest.c dwflsyms.c \ + early-offscn.c ecp.c elfcopy.c elfgetchdr.c elfgetzdata.c \ +- elfputzdata.c elfshphehdr.c elfstrmerge.c elfstrtab.c \ +- emptyfile.c fillfile.c find-prologues.c funcretval.c \ +- funcscopes.c get-aranges.c get-files.c get-lines.c \ +- get-pubnames.c get-units-invalid.c get-units-split.c \ +- getsrc_die.c hash.c line2addr.c low_high_pc.c msg_tst.c \ +- newdata.c newfile.c newscn.c next-files.c next-lines.c \ +- next_cfi.c peel_type.c rdwrmmap.c rerequest_tag.c saridx.c \ +- scnnames.c sectiondump.c show-abbrev.c show-die-info.c \ +- showptable.c strptr.c system-elf-libelf-test.c \ +- test-elf_cntl_gelf_getshdr.c test-flag-nobits.c test-nlist.c \ +- typeiter.c typeiter2.c unit-info.c update1.c update2.c \ +- update3.c update4.c varlocs.c vdsosyms.c vendorelf.c \ +- xlate_notes.c zstrptr.c ++ elfputzdata.c elfrdwrnop.c elfshphehdr.c elfstrmerge.c \ ++ elfstrtab.c emptyfile.c fillfile.c find-prologues.c \ ++ funcretval.c funcscopes.c get-aranges.c get-files.c \ ++ get-lines.c get-pubnames.c get-units-invalid.c \ ++ get-units-split.c getsrc_die.c hash.c line2addr.c \ ++ low_high_pc.c msg_tst.c newdata.c newfile.c newscn.c \ ++ next-files.c next-lines.c next_cfi.c peel_type.c rdwrmmap.c \ ++ rerequest_tag.c saridx.c scnnames.c sectiondump.c \ ++ show-abbrev.c show-die-info.c showptable.c strptr.c \ ++ system-elf-libelf-test.c test-elf_cntl_gelf_getshdr.c \ ++ test-flag-nobits.c test-nlist.c typeiter.c typeiter2.c \ ++ unit-info.c update1.c update2.c update3.c update4.c varlocs.c \ ++ vdsosyms.c vendorelf.c xlate_notes.c zstrptr.c + DIST_SOURCES = addrcfi.c addrscopes.c addsections.c aggregate_size.c \ + all-dwarf-ranges.c alldts.c allfcts.c allregs.c arextract.c \ + arls.c arsymtest.c asm-tst1.c asm-tst2.c asm-tst3.c asm-tst4.c \ +@@ -745,19 +749,19 @@ + dwfl-bug-getmodules.c dwfl-bug-report.c dwfl-proc-attach.c \ + dwfl-report-elf-align.c dwfllines.c dwflmodtest.c dwflsyms.c \ + early-offscn.c ecp.c elfcopy.c elfgetchdr.c elfgetzdata.c \ +- elfputzdata.c elfshphehdr.c elfstrmerge.c elfstrtab.c \ +- emptyfile.c fillfile.c find-prologues.c funcretval.c \ +- funcscopes.c get-aranges.c get-files.c get-lines.c \ +- get-pubnames.c get-units-invalid.c get-units-split.c \ +- getsrc_die.c hash.c line2addr.c low_high_pc.c msg_tst.c \ +- newdata.c newfile.c newscn.c next-files.c next-lines.c \ +- next_cfi.c peel_type.c rdwrmmap.c rerequest_tag.c saridx.c \ +- scnnames.c sectiondump.c show-abbrev.c show-die-info.c \ +- showptable.c strptr.c system-elf-libelf-test.c \ +- test-elf_cntl_gelf_getshdr.c test-flag-nobits.c test-nlist.c \ +- typeiter.c typeiter2.c unit-info.c update1.c update2.c \ +- update3.c update4.c varlocs.c vdsosyms.c vendorelf.c \ +- xlate_notes.c zstrptr.c ++ elfputzdata.c elfrdwrnop.c elfshphehdr.c elfstrmerge.c \ ++ elfstrtab.c emptyfile.c fillfile.c find-prologues.c \ ++ funcretval.c funcscopes.c get-aranges.c get-files.c \ ++ get-lines.c get-pubnames.c get-units-invalid.c \ ++ get-units-split.c getsrc_die.c hash.c line2addr.c \ ++ low_high_pc.c msg_tst.c newdata.c newfile.c newscn.c \ ++ next-files.c next-lines.c next_cfi.c peel_type.c rdwrmmap.c \ ++ rerequest_tag.c saridx.c scnnames.c sectiondump.c \ ++ show-abbrev.c show-die-info.c showptable.c strptr.c \ ++ system-elf-libelf-test.c test-elf_cntl_gelf_getshdr.c \ ++ test-flag-nobits.c test-nlist.c typeiter.c typeiter2.c \ ++ unit-info.c update1.c update2.c update3.c update4.c varlocs.c \ ++ vdsosyms.c vendorelf.c xlate_notes.c zstrptr.c + am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ +@@ -1405,6 +1409,7 @@ + run-unit-info.sh run-next-cfi.sh run-next-cfi-self.sh \ + testfile-riscv64.bz2 testfile-riscv64-s.bz2 \ + testfile-riscv64-core.bz2 \ ++ run-reverse-sections.sh run-reverse-sections-self.sh \ + run-copyadd-sections.sh run-copymany-sections.sh \ + run-typeiter-many.sh run-strip-test-many.sh \ + testfile-debug-rel-ppc64-g.o.bz2 \ +@@ -1566,6 +1571,7 @@ + elfcopy_LDADD = $(libelf) + addsections_LDADD = $(libelf) + xlate_notes_LDADD = $(libelf) ++elfrdwrnop_LDADD = $(libelf) + + # We want to test the libelf header against the system elf.h header. + # Don't include any -I CPPFLAGS. Except when we install our own elf.h. +@@ -1822,6 +1828,10 @@ + @rm -f elfputzdata$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfputzdata_OBJECTS) $(elfputzdata_LDADD) $(LIBS) + ++elfrdwrnop$(EXEEXT): $(elfrdwrnop_OBJECTS) $(elfrdwrnop_DEPENDENCIES) $(EXTRA_elfrdwrnop_DEPENDENCIES) ++ @rm -f elfrdwrnop$(EXEEXT) ++ $(AM_V_CCLD)$(LINK) $(elfrdwrnop_OBJECTS) $(elfrdwrnop_LDADD) $(LIBS) ++ + elfshphehdr$(EXEEXT): $(elfshphehdr_OBJECTS) $(elfshphehdr_DEPENDENCIES) $(EXTRA_elfshphehdr_DEPENDENCIES) + @rm -f elfshphehdr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfshphehdr_OBJECTS) $(elfshphehdr_LDADD) $(LIBS) +@@ -2086,6 +2096,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfgetchdr.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfgetzdata.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfputzdata.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfrdwrnop.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfshphehdr.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfstrmerge.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfstrtab.Po@am__quote@ # am--include-marker +@@ -3709,6 +3720,20 @@ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) ++run-reverse-sections.sh.log: run-reverse-sections.sh ++ @p='run-reverse-sections.sh'; \ ++ b='run-reverse-sections.sh'; \ ++ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ ++ --log-file $$b.log --trs-file $$b.trs \ ++ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ ++ "$$tst" $(AM_TESTS_FD_REDIRECT) ++run-reverse-sections-self.sh.log: run-reverse-sections-self.sh ++ @p='run-reverse-sections-self.sh'; \ ++ b='run-reverse-sections-self.sh'; \ ++ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ ++ --log-file $$b.log --trs-file $$b.trs \ ++ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ ++ "$$tst" $(AM_TESTS_FD_REDIRECT) + run-copyadd-sections.sh.log: run-copyadd-sections.sh + @p='run-copyadd-sections.sh'; \ + b='run-copyadd-sections.sh'; \ +@@ -3997,6 +4022,7 @@ + -rm -f ./$(DEPDIR)/elfgetchdr.Po + -rm -f ./$(DEPDIR)/elfgetzdata.Po + -rm -f ./$(DEPDIR)/elfputzdata.Po ++ -rm -f ./$(DEPDIR)/elfrdwrnop.Po + -rm -f ./$(DEPDIR)/elfshphehdr.Po + -rm -f ./$(DEPDIR)/elfstrmerge.Po + -rm -f ./$(DEPDIR)/elfstrtab.Po +@@ -4147,6 +4173,7 @@ + -rm -f ./$(DEPDIR)/elfgetchdr.Po + -rm -f ./$(DEPDIR)/elfgetzdata.Po + -rm -f ./$(DEPDIR)/elfputzdata.Po ++ -rm -f ./$(DEPDIR)/elfrdwrnop.Po + -rm -f ./$(DEPDIR)/elfshphehdr.Po + -rm -f ./$(DEPDIR)/elfstrmerge.Po + -rm -f ./$(DEPDIR)/elfstrtab.Po +diff --git a/tests/elfcopy.c b/tests/elfcopy.c +index d457bad..4542222 100644 +--- a/tests/elfcopy.c ++++ b/tests/elfcopy.c +@@ -225,6 +225,7 @@ copy_elf (const char *in, const char *out, bool use_mmap, bool reverse_offs) + && shdr.sh_addralign == 1 + && last_shdr.sh_type != SHT_NOBITS + && shdr.sh_type != SHT_NOBITS ++ && last_shdr.sh_offset + last_shdr.sh_size == shdr.sh_offset + && (phnum == 0 + || ((shdr.sh_flags & SHF_ALLOC) == 0 + && (last_shdr.sh_flags & SHF_ALLOC) == 0))) diff --git a/SOURCES/elfutils-0.176-gcc-pr88835.patch b/SOURCES/elfutils-0.176-gcc-pr88835.patch new file mode 100644 index 0000000..6571f49 --- /dev/null +++ b/SOURCES/elfutils-0.176-gcc-pr88835.patch @@ -0,0 +1,28 @@ +Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88835 + +diff --git a/src/readelf.c b/src/readelf.c +index 33706bd..b55844c 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -10143,7 +10143,7 @@ print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + ++digits; + tmp >>= 4; + } +- digits = MAX (4, digits); ++ digits = MIN (16, MAX (4, digits)); + + printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n" + " %*s String\n"), +diff --git a/tests/backtrace.c b/tests/backtrace.c +index 05e8ef8..d621fbf 100644 +--- a/tests/backtrace.c ++++ b/tests/backtrace.c +@@ -185,7 +185,7 @@ frame_callback (Dwfl_Frame *state, void *frame_arg) + symname = dwfl_module_addrname (mod, pc_adjusted); + + printf ("#%2d %#" PRIx64 "%4s\t%s\n", *framenop, (uint64_t) pc, +- ! isactivation ? "- 1" : "", symname); ++ ! isactivation ? "- 1" : "", symname ?: ""); + pid_t tid = dwfl_thread_tid (thread); + callback_verify (tid, *framenop, pc, symname, dwfl); + (*framenop)++; diff --git a/SOURCES/elfutils-0.176-strip-symbols-illformed.patch b/SOURCES/elfutils-0.176-strip-symbols-illformed.patch new file mode 100644 index 0000000..a0f22c8 --- /dev/null +++ b/SOURCES/elfutils-0.176-strip-symbols-illformed.patch @@ -0,0 +1,26 @@ +commit f03ac75239e0981deaf4aa18f66f423bcc5ce051 +Author: Mark Wielaard +Date: Wed Mar 27 21:54:06 2019 +0100 + + strip: Files with symbols referring to non-existing sections are illformed + + The check added in commit 4540ea98c "strip: Fix check test for SHN_XINDEX + symbol" was not complete. The (extended) section index should also exist. + If it doesn't exist, mark the file as illformed. + + https://sourceware.org/bugzilla/show_bug.cgi?id=24385 + + Signed-off-by: Mark Wielaard + +diff --git a/src/strip.c b/src/strip.c +index a73009d9..4cd87506 100644 +--- a/src/strip.c ++++ b/src/strip.c +@@ -1975,6 +1975,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, + && shndxdata->d_buf != NULL); + size_t sidx = (sym->st_shndx != SHN_XINDEX + ? sym->st_shndx : xshndx); ++ elf_assert (sidx < shnum); + sec = shdr_info[sidx].idx; + + if (sec != 0) diff --git a/SOURCES/elfutils-0.176-xlate-note.patch b/SOURCES/elfutils-0.176-xlate-note.patch new file mode 100644 index 0000000..e3bbf48 --- /dev/null +++ b/SOURCES/elfutils-0.176-xlate-note.patch @@ -0,0 +1,486 @@ +commit 28b5f578ae772bb2404c3847e4e22ad1c407af54 +Author: Mark Wielaard +Date: Tue Apr 30 13:00:17 2019 +0200 + + libelf: If xlate can only convert the ELF note header, just do that. + + When we started parsing new style ELF_T_NHDR8 notes we added extra + checks on alignment and padding. When those failed we would stop + converting and just return the rest of the ELF Note unconverted. + In the case were we just had enough data for just the ELF Note header + and the destionation and source weren't the same we would then + accidentially throw away the Note header conversion we just did. + + Fix that by indicating we did correctly convert just the header. + + Adds testcase that compares parsing ELF notes with gelf_getnote + and parsing the raw data by hand using elf32_xlatetom using just + the Note header and ignoring the (raw) note data. + + Signed-off-by: Mark Wielaard + +diff --git a/libelf/note_xlate.h b/libelf/note_xlate.h +index bc9950f..7e2784b 100644 +--- a/libelf/note_xlate.h ++++ b/libelf/note_xlate.h +@@ -47,13 +47,25 @@ elf_cvt_note (void *dest, const void *src, size_t len, int encode, + note_len += n->n_namesz; + note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len); + if (note_len > len || note_len < sizeof *n) +- break; ++ { ++ /* Header was translated, nothing else. */ ++ len -= sizeof *n; ++ src += sizeof *n; ++ dest += sizeof *n; ++ break; ++ } + + /* data as a whole needs to be aligned. */ + note_len += n->n_descsz; + note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len); + if (note_len > len || note_len < sizeof *n) +- break; ++ { ++ /* Header was translated, nothing else. */ ++ len -= sizeof *n; ++ src += sizeof *n; ++ dest += sizeof *n; ++ break; ++ } + + /* Copy or skip the note data. */ + size_t note_data_len = note_len - sizeof *n; +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 1b0c7d3..498c1db 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -60,7 +60,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ + fillfile dwarf_default_lower_bound dwarf-die-addr-die \ + get-units-invalid get-units-split attr-integrate-skel \ + all-dwarf-ranges unit-info next_cfi \ +- elfcopy addsections ++ elfcopy addsections xlate_notes + + asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ + asm-tst6 asm-tst7 asm-tst8 asm-tst9 +@@ -159,7 +159,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ + run-next-cfi.sh run-next-cfi-self.sh \ + run-copyadd-sections.sh run-copymany-sections.sh \ + run-typeiter-many.sh run-strip-test-many.sh \ +- run-strip-version.sh ++ run-strip-version.sh run-xlate-note.sh + + if !BIARCH + export ELFUTILS_DISABLE_BIARCH = 1 +@@ -423,7 +423,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ + testfile-debug-rel-ppc64-g.o.bz2 \ + testfile-debug-rel-ppc64-z.o.bz2 \ + testfile-debug-rel-ppc64.o.bz2 \ +- run-strip-version.sh testfile-version.bz2 ++ run-strip-version.sh testfile-version.bz2 \ ++ run-xlate-note.sh + + if USE_VALGRIND + valgrind_cmd='valgrind -q --leak-check=full --error-exitcode=1' +@@ -593,6 +594,7 @@ unit_info_LDADD = $(libdw) + next_cfi_LDADD = $(libelf) $(libdw) + elfcopy_LDADD = $(libelf) + addsections_LDADD = $(libelf) ++xlate_notes_LDADD = $(libelf) + + # We want to test the libelf header against the system elf.h header. + # Don't include any -I CPPFLAGS. Except when we install our own elf.h. +diff --git a/tests/run-xlate-note.sh b/tests/run-xlate-note.sh +new file mode 100755 +index 0000000..a907418 +--- /dev/null ++++ b/tests/run-xlate-note.sh +@@ -0,0 +1,93 @@ ++# Copyright (C) 2019 Red Hat, Inc. ++# This file is part of elfutils. ++# ++# This file is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# elfutils is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. $srcdir/test-subr.sh ++ ++testfiles testfileppc32 ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfileppc32 << EOF ++Notes in section 2: ++type: 1,1, namesz: 4,4, descsz: 16,16 ++Notes in section 3: ++type: 3,3, namesz: 4,4, descsz: 20,20 ++EOF ++ ++testfiles testfileppc64 ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfileppc64 << EOF ++Notes in section 2: ++type: 1,1, namesz: 4,4, descsz: 16,16 ++Notes in section 3: ++type: 3,3, namesz: 4,4, descsz: 20,20 ++EOF ++ ++testfiles testfiles390 ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfiles390 << EOF ++Notes in section 2: ++type: 1,1, namesz: 4,4, descsz: 16,16 ++Notes in section 3: ++type: 3,3, namesz: 4,4, descsz: 20,20 ++EOF ++ ++testfiles testfiles390x ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfiles390x << EOF ++Notes in section 2: ++type: 1,1, namesz: 4,4, descsz: 16,16 ++Notes in section 3: ++type: 3,3, namesz: 4,4, descsz: 20,20 ++EOF ++ ++testfiles testfileaarch64 ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfileaarch64 << EOF ++Notes in section 2: ++type: 1,1, namesz: 4,4, descsz: 16,16 ++Notes in section 3: ++type: 3,3, namesz: 4,4, descsz: 20,20 ++EOF ++ ++testfiles testfilearm ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfilearm << EOF ++Notes in section 2: ++type: 1,1, namesz: 4,4, descsz: 16,16 ++Notes in section 3: ++type: 3,3, namesz: 4,4, descsz: 20,20 ++EOF ++ ++testfiles testfile_gnu_props.32be.o ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfile_gnu_props.32be.o << EOF ++Notes in section 4: ++type: 5,5, namesz: 4,4, descsz: 12,12 ++type: 5,5, namesz: 4,4, descsz: 8,8 ++EOF ++ ++testfiles testfile_gnu_props.32le.o ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfile_gnu_props.32le.o << EOF ++Notes in section 4: ++type: 5,5, namesz: 4,4, descsz: 12,12 ++type: 5,5, namesz: 4,4, descsz: 8,8 ++EOF ++ ++testfiles testfile_gnu_props.64be.o ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfile_gnu_props.64be.o << EOF ++Notes in section 4: ++type: 5,5, namesz: 4,4, descsz: 16,16 ++type: 5,5, namesz: 4,4, descsz: 8,8 ++EOF ++ ++testfiles testfile_gnu_props.64le.o ++testrun_compare ${abs_top_builddir}/tests/xlate_notes testfile_gnu_props.64le.o << EOF ++Notes in section 4: ++type: 5,5, namesz: 4,4, descsz: 16,16 ++type: 5,5, namesz: 4,4, descsz: 8,8 ++EOF +diff --git a/tests/xlate_notes.c b/tests/xlate_notes.c +new file mode 100644 +index 0000000..90a4ae2 +--- /dev/null ++++ b/tests/xlate_notes.c +@@ -0,0 +1,157 @@ ++/* Test program for extracting ELF Note headers and getting whole notes. ++ Copyright (C) 2019 Red Hat, Inc. ++ This file is part of elfutils. ++ ++ This file is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ elfutils is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#ifdef HAVE_CONFIG_H ++# include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ELFUTILS_HEADER(elf) ++#include ++ ++int ++main (int argc, char *argv[]) ++{ ++ if (argc != 2) ++ { ++ printf ("No ELF file given as argument\n"); ++ exit (1); ++ } ++ ++ const char *fname = argv[1]; ++ ++ // Initialize libelf. ++ elf_version (EV_CURRENT); ++ ++ /* Read the ELF from disk now. */ ++ int fd = open (fname, O_RDONLY); ++ if (fd == -1) ++ { ++ printf ("cannot open '%s': %s\n", fname, strerror (errno)); ++ exit (1); ++ } ++ ++ Elf *elf = elf_begin (fd, ELF_C_READ, NULL); ++ if (elf == NULL) ++ { ++ printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ GElf_Ehdr ehdr; ++ if (gelf_getehdr (elf, &ehdr) == NULL) ++ { ++ printf ("cannot get Ehdr: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ /* Search for all SHT_NOTE sections. */ ++ Elf_Scn *scn = NULL; ++ while ((scn = elf_nextscn (elf, scn)) != NULL) ++ { ++ /* Get the header. */ ++ GElf_Shdr shdr; ++ if (gelf_getshdr (scn, &shdr) == NULL) ++ { ++ printf ("couldn't get shdr: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ if (shdr.sh_type == SHT_NOTE) ++ { ++ printf ("Notes in section %zd:\n", elf_ndxscn (scn)); ++ ++ Elf_Data *raw = elf_rawdata (scn, NULL); ++ if (raw == NULL) ++ { ++ printf ("couldn't get raw data: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ Elf_Data *data = elf_getdata (scn, NULL); ++ if (data == NULL) ++ { ++ printf ("couldn't get data: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ size_t off = 0; ++ size_t next; ++ GElf_Nhdr nhdr; ++ size_t n_off; ++ size_t d_off; ++ while ((next = gelf_getnote (data, off, &nhdr, &n_off, &d_off)) > 0) ++ { ++ /* Now just get the note header "raw" (don't ++ copy/translate the note data). This only handles ++ traditional GNU ELF Notes, so we still use the next ++ from gelf_getnote (padding is different for new style ++ ELF_T_NHDR8 notes). */ ++ Elf32_Nhdr nh; ++ Elf_Data src = ++ { ++ .d_version = EV_CURRENT, .d_type = ELF_T_NHDR, ++ .d_size = sizeof nh ++ }; ++ Elf_Data dst = src; ++ src.d_buf = raw->d_buf + off; ++ dst.d_buf = &nh; ++ ++ if (elf32_xlatetom (&dst, &src, ehdr.e_ident[EI_DATA]) == NULL) ++ { ++ printf ("couldn't xlate note: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ printf ("type: %" PRId32 ",%" PRId32 ++ ", namesz: %" PRId32 ",%" PRId32 ++ ", descsz: %" PRId32 ",%" PRId32 "\n", ++ nhdr.n_type, nh.n_type, ++ nhdr.n_namesz, nh.n_namesz, ++ nhdr.n_descsz, nh.n_descsz); ++ ++ if (nhdr.n_type != nh.n_type ++ || nhdr.n_namesz != nh.n_namesz ++ || nhdr.n_descsz != nh.n_descsz) ++ { ++ printf ("Nhdrs not equal!\n"); ++ exit (1); ++ } ++ ++ off = next; ++ } ++ } ++ ++ } ++ ++ if (elf_end (elf) != 0) ++ { ++ printf ("failure in elf_end: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } ++ ++ close (fd); ++ ++ return 0; ++} +diff -ur elfutils-0.176.orig/tests/Makefile.in elfutils-0.176/tests/Makefile.in +--- elfutils-0.176.orig/tests/Makefile.in 2019-04-30 22:42:49.534655124 +0200 ++++ elfutils-0.176/tests/Makefile.in 2019-04-30 22:46:30.046656790 +0200 +@@ -131,8 +131,8 @@ + get-units-invalid$(EXEEXT) get-units-split$(EXEEXT) \ + attr-integrate-skel$(EXEEXT) all-dwarf-ranges$(EXEEXT) \ + unit-info$(EXEEXT) next_cfi$(EXEEXT) elfcopy$(EXEEXT) \ +- addsections$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \ +- $(am__EXEEXT_4) ++ addsections$(EXEEXT) xlate_notes$(EXEEXT) $(am__EXEEXT_1) \ ++ $(am__EXEEXT_2) $(am__EXEEXT_4) + @BIARCH_TRUE@am__append_5 = backtrace-child-biarch + TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile$(EXEEXT) \ + test-nlist$(EXEEXT) update1$(EXEEXT) update2$(EXEEXT) \ +@@ -211,8 +211,8 @@ + run-unit-info.sh run-reloc-bpf.sh run-next-cfi.sh \ + run-next-cfi-self.sh run-copyadd-sections.sh \ + run-copymany-sections.sh run-typeiter-many.sh \ +- run-strip-test-many.sh run-strip-version.sh $(am__EXEEXT_2) \ +- $(am__append_8) $(am__EXEEXT_5) ++ run-strip-test-many.sh run-strip-version.sh run-xlate-note.sh \ ++ $(am__EXEEXT_2) $(am__append_8) $(am__EXEEXT_5) + @STANDALONE_FALSE@am__append_6 = msg_tst system-elf-libelf-test + @STANDALONE_FALSE@am__append_7 = msg_tst system-elf-libelf-test + @LZMA_TRUE@am__append_8 = run-readelf-s.sh run-dwflsyms.sh +@@ -606,6 +606,9 @@ + vendorelf_SOURCES = vendorelf.c + vendorelf_OBJECTS = vendorelf.$(OBJEXT) + vendorelf_DEPENDENCIES = $(am__DEPENDENCIES_2) ++xlate_notes_SOURCES = xlate_notes.c ++xlate_notes_OBJECTS = xlate_notes.$(OBJEXT) ++xlate_notes_DEPENDENCIES = $(am__DEPENDENCIES_2) + zstrptr_SOURCES = zstrptr.c + zstrptr_OBJECTS = zstrptr.$(OBJEXT) + zstrptr_DEPENDENCIES = $(am__DEPENDENCIES_2) +@@ -683,7 +686,7 @@ + ./$(DEPDIR)/update2.Po ./$(DEPDIR)/update3.Po \ + ./$(DEPDIR)/update4.Po ./$(DEPDIR)/varlocs.Po \ + ./$(DEPDIR)/vdsosyms.Po ./$(DEPDIR)/vendorelf.Po \ +- ./$(DEPDIR)/zstrptr.Po ++ ./$(DEPDIR)/xlate_notes.Po ./$(DEPDIR)/zstrptr.Po + am__mv = mv -f + AM_V_lt = $(am__v_lt_@AM_V@) + am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +@@ -726,7 +729,8 @@ + showptable.c strptr.c system-elf-libelf-test.c \ + test-elf_cntl_gelf_getshdr.c test-flag-nobits.c test-nlist.c \ + typeiter.c typeiter2.c unit-info.c update1.c update2.c \ +- update3.c update4.c varlocs.c vdsosyms.c vendorelf.c zstrptr.c ++ update3.c update4.c varlocs.c vdsosyms.c vendorelf.c \ ++ xlate_notes.c zstrptr.c + DIST_SOURCES = addrcfi.c addrscopes.c addsections.c aggregate_size.c \ + all-dwarf-ranges.c alldts.c allfcts.c allregs.c arextract.c \ + arls.c arsymtest.c asm-tst1.c asm-tst2.c asm-tst3.c asm-tst4.c \ +@@ -752,7 +756,8 @@ + showptable.c strptr.c system-elf-libelf-test.c \ + test-elf_cntl_gelf_getshdr.c test-flag-nobits.c test-nlist.c \ + typeiter.c typeiter2.c unit-info.c update1.c update2.c \ +- update3.c update4.c varlocs.c vdsosyms.c vendorelf.c zstrptr.c ++ update3.c update4.c varlocs.c vdsosyms.c vendorelf.c \ ++ xlate_notes.c zstrptr.c + am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ +@@ -1405,7 +1410,8 @@ + testfile-debug-rel-ppc64-g.o.bz2 \ + testfile-debug-rel-ppc64-z.o.bz2 \ + testfile-debug-rel-ppc64.o.bz2 \ +- run-strip-version.sh testfile-version.bz2 ++ run-strip-version.sh testfile-version.bz2 \ ++ run-xlate-note.sh + + @USE_VALGRIND_TRUE@valgrind_cmd = 'valgrind -q --leak-check=full --error-exitcode=1' + installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir); \ +@@ -1559,6 +1565,7 @@ + next_cfi_LDADD = $(libelf) $(libdw) + elfcopy_LDADD = $(libelf) + addsections_LDADD = $(libelf) ++xlate_notes_LDADD = $(libelf) + + # We want to test the libelf header against the system elf.h header. + # Don't include any -I CPPFLAGS. Except when we install our own elf.h. +@@ -2011,6 +2018,10 @@ + @rm -f vendorelf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(vendorelf_OBJECTS) $(vendorelf_LDADD) $(LIBS) + ++xlate_notes$(EXEEXT): $(xlate_notes_OBJECTS) $(xlate_notes_DEPENDENCIES) $(EXTRA_xlate_notes_DEPENDENCIES) ++ @rm -f xlate_notes$(EXEEXT) ++ $(AM_V_CCLD)$(LINK) $(xlate_notes_OBJECTS) $(xlate_notes_LDADD) $(LIBS) ++ + zstrptr$(EXEEXT): $(zstrptr_OBJECTS) $(zstrptr_DEPENDENCIES) $(EXTRA_zstrptr_DEPENDENCIES) + @rm -f zstrptr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(zstrptr_OBJECTS) $(zstrptr_LDADD) $(LIBS) +@@ -2124,6 +2135,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varlocs.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vdsosyms.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vendorelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlate_notes.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zstrptr.Po@am__quote@ # am--include-marker + + $(am__depfiles_remade): +@@ -3732,6 +3744,13 @@ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) ++run-xlate-note.sh.log: run-xlate-note.sh ++ @p='run-xlate-note.sh'; \ ++ b='run-xlate-note.sh'; \ ++ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ ++ --log-file $$b.log --trs-file $$b.trs \ ++ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ ++ "$$tst" $(AM_TESTS_FD_REDIRECT) + msg_tst.log: msg_tst$(EXEEXT) + @p='msg_tst$(EXEEXT)'; \ + b='msg_tst'; \ +@@ -4027,6 +4046,7 @@ + -rm -f ./$(DEPDIR)/varlocs.Po + -rm -f ./$(DEPDIR)/vdsosyms.Po + -rm -f ./$(DEPDIR)/vendorelf.Po ++ -rm -f ./$(DEPDIR)/xlate_notes.Po + -rm -f ./$(DEPDIR)/zstrptr.Po + -rm -f Makefile + distclean-am: clean-am distclean-compile distclean-generic \ +@@ -4176,6 +4196,7 @@ + -rm -f ./$(DEPDIR)/varlocs.Po + -rm -f ./$(DEPDIR)/vdsosyms.Po + -rm -f ./$(DEPDIR)/vendorelf.Po ++ -rm -f ./$(DEPDIR)/xlate_notes.Po + -rm -f ./$(DEPDIR)/zstrptr.Po + -rm -f Makefile + maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/SPECS/elfutils.spec b/SPECS/elfutils.spec index c1a4cad..1d1464a 100644 --- a/SPECS/elfutils.spec +++ b/SPECS/elfutils.spec @@ -1,7 +1,7 @@ Name: elfutils Summary: A collection of utilities and DSOs to handle ELF files and DWARF data -Version: 0.174 -%global baserelease 6 +Version: 0.176 +%global baserelease 5 URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ License: GPLv3+ and (GPLv2+ or LGPLv3+) @@ -20,16 +20,10 @@ Release: %{baserelease}%{?dist} Source: %{?source_url}%{name}-%{version}.tar.bz2 # Patches -Patch1: elfutils-0.173-new-notes-hack.patch -Patch2: elfutils-0.174-strip-unstrip-group.patch -Patch3: elfutils-0.174-libdwfl-sanity-check-core-reads.patch -Patch4: elfutils-0.174-size-rec-ar.patch -Patch5: elfutils-0.174-ar-sh_entsize-zero.patch -Patch6: elfutils-0.174-x86_64_unwind.patch -Patch7: elfutils-0.174-gnu-property-note.patch -Patch8: elfutils-0.174-version-note.patch -Patch9: elfutils-0.174-gnu-attribute-note.patch -Patch10: elfutils-0.174-gnu-props-32.patch +Patch1: elfutils-0.176-gcc-pr88835.patch +Patch2: elfutils-0.176-xlate-note.patch +Patch3: elfutils-0.176-elf-update.patch +Patch4: elfutils-0.176-strip-symbols-illformed.patch Requires: elfutils-libelf%{depsuffix} = %{version}-%{release} Requires: elfutils-libs%{depsuffix} = %{version}-%{release} @@ -198,25 +192,15 @@ profiling) of processes. %setup -q # Apply patches -%patch1 -p1 -b .notes_hack -%patch2 -p1 -b .strip_unstrip_group -%patch3 -p1 -b .sanity_check_core_reads -%patch4 -p1 -b .size_rec_ar -%patch5 -p1 -b .ar_sh_entsize_zero -%patch6 -p1 -b .x86_64_unwind -%patch7 -p1 -b .gnu_prop_note -%patch8 -p1 -b .version_note -%patch9 -p1 -b .gnu_attr_note -%patch10 -p1 -b .gnu_prop_32 +%patch1 -p1 -b .gcc-pr88835 +%patch2 -p1 -b .xlate-note +%patch3 -p1 -b .elf-update +%patch4 -p1 -b .strip-illformed # In case the above patches added any new test scripts, make sure they # are executable. find . -name \*.sh ! -perm -0100 -print | xargs chmod +x -%ifarch %{arm} -echo -e '"dwarf: arm needs debuginfo installed for all libraries"\nexit 77' > tests/run-backtrace-native-core.sh -%endif - %build # Remove -Wall from default flags. The makefiles enable enough warnings # themselves, and they use -Werror. Appending -Wall defeats the cases where @@ -226,6 +210,7 @@ echo -e '"dwarf: arm needs debuginfo installed for all libraries"\nexit 77' > te RPM_OPT_FLAGS="${RPM_OPT_FLAGS/-Wall/}" RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -Wformat" + trap 'cat config.log' EXIT %configure CFLAGS="$RPM_OPT_FLAGS -fexceptions" trap '' EXIT @@ -344,8 +329,23 @@ fi %endif %changelog -* Wed May 22 2019 Pablo Greco - 0.174-6 -- Disable failing test on arm +* Fri Jul 5 2019 Mark Wielaard - 0.176-5 +- Add elfutils-0.176-strip-symbols-illformed.patch + +* Wed Jun 5 2019 Mark Wielaard - 0.176-4 +- Add elfutils-0.176-elf-update.patch (#1717349) + +* Mon May 13 2019 Mark Wielaard - 0.176-3 +- Rebuilt for annobin change. + +* Fri May 10 2019 Mark Wielaard - 0.176-2 +- Add elfutils-0.176-xlate-note.patch (#1705138) + +* Tue May 7 2019 Mark Wielaard - 0.176-1 +- New upstream release. + - backends: riscv improved core file and return value location support. + - Fixes CVE-2019-7146, CVE-2019-7148, CVE-2019-7149, CVE-2019-7150, + CVE-2019-7664, CVE-2019-7665. * Mon Dec 3 2018 Mark Wielaard - 0.174-6 - Add elfutils-0.174-gnu-props-32.patch.