0.174-5 Add elfutils-0.174-gnu-attribute-note.patch
This commit is contained in:
parent
95b280f1eb
commit
a39405c33b
373
elfutils-0.174-gnu-attribute-note.patch
Normal file
373
elfutils-0.174-gnu-attribute-note.patch
Normal file
@ -0,0 +1,373 @@
|
||||
commit 72e30c2e0cb49a9a300667fdd5ff09082f717950
|
||||
Author: Mark Wielaard <mark@klomp.org>
|
||||
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 <mark@klomp.org>
|
||||
|
||||
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 <string.h>
|
||||
#include <libeblP.h>
|
||||
|
||||
+#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 ("<unknown data>\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 ("<insufficient data>\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 ("<unknown>: ");
|
||||
+ 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 ("<unknown>");
|
||||
+ }
|
||||
+ 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 <drepper@redhat.com>, 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);
|
||||
}
|
||||
}
|
||||
|
@ -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 4
|
||||
%global baserelease 5
|
||||
URL: http://elfutils.org/
|
||||
%global source_url ftp://sourceware.org/pub/elfutils/%{version}/
|
||||
License: GPLv3+ and (GPLv2+ or LGPLv3+)
|
||||
@ -28,6 +28,7 @@ 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
|
||||
|
||||
Requires: elfutils-libelf%{depsuffix} = %{version}-%{release}
|
||||
Requires: elfutils-libs%{depsuffix} = %{version}-%{release}
|
||||
@ -204,6 +205,7 @@ profiling) of processes.
|
||||
%patch6 -p1 -b .x86_64_unwind
|
||||
%patch7 -p1 -b .gnu_prop_note
|
||||
%patch8 -p1 -b .version_note
|
||||
%patch9 -p1 -b .gnu_attr_note
|
||||
|
||||
# In case the above patches added any new test scripts, make sure they
|
||||
# are executable.
|
||||
@ -336,10 +338,11 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Nov 14 2018 Mark Wielaard <mjw@fedoraproject.org>
|
||||
* Wed Nov 14 2018 Mark Wielaard <mjw@fedoraproject.org> - 0.174-5
|
||||
- Add elfutils-0.174-x86_64_unwind.patch.
|
||||
- Add elfutils-0.174-gnu-property-note.patch.
|
||||
- Add elfutils-0.174-version-note.patch.
|
||||
- Add elfutils-0.174-gnu-attribute-note.patch
|
||||
|
||||
* Tue Nov 6 2018 Mark Wielaard <mjw@fedoraproject.org> - 0.174-4
|
||||
- Add elfutils-0.174-size-rec-ar.patch
|
||||
|
Loading…
Reference in New Issue
Block a user