This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RFC: Add GNU_PROPERTY_NEED_PHDRS
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Rich Felker <dalias at libc dot org>
- Cc: Cary Coutant <ccoutant at gmail dot com>, "Carlos O'Donell" <carlos at redhat dot com>, Florian Weimer <fweimer at redhat dot com>, Szabolcs Nagy <nsz at port70 dot net>, Jan Beulich <JBeulich at suse dot com>, Binutils <binutils at sourceware dot org>, gnu-gabi at sourceware dot org
- Date: Fri, 28 Sep 2018 16:05:11 -0700
- Subject: RFC: Add GNU_PROPERTY_NEED_PHDRS
On Fri, Sep 28, 2018 at 7:30 AM, Rich Felker <dalias@libc.org> wrote:
> On Fri, Sep 28, 2018 at 06:42:52AM -0700, H.J. Lu wrote:
>
>> Dynamic loader has no problem. The problem is kernel passes
>> AT_PHDR to main, which points to the unmmaped address. We can
>> ask for kernel change or make kernel happy.
>
> Kernel change does not help because nobody is obligated to use a new
> kernel. Binutils would be producing binaries that don't work on
> existing kernels (if the note hack were reverted or if similar changes
> were added to other archs without a note hack; right now of course
> it's working again).
True.
>> My current .note.gnu.property patch only works for x86. We can
>> add
>>
>> #define GNU_PROPERTY_PHDRS 3
>>
>> so that it can be used for all targets.
>
> What would this do?
>
These are what I have in mind.
--
H.J.
From ad8ef2328b42ee040bac68d9736867a0551497b5 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 25 Sep 2018 12:33:59 -0700
Subject: [PATCH 1/2] Don't add GNU_PROPERTY_X86_FEATURE_2_NEEDED
FAIL: Run PR ld/23428 test
---
bfd/elfxx-x86.c | 45 --------------------
ld/testsuite/ld-i386/property-x86-4a.d | 3 +-
ld/testsuite/ld-x86-64/property-x86-4a-x32.d | 3 +-
ld/testsuite/ld-x86-64/property-x86-4a.d | 3 +-
4 files changed, 3 insertions(+), 51 deletions(-)
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index fc99b28c07..05f5c6a2f9 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -2542,7 +2542,6 @@ _bfd_x86_elf_link_setup_gnu_properties
const struct elf_backend_data *bed;
unsigned int class_align = ABI_64_P (info->output_bfd) ? 3 : 2;
unsigned int got_align;
- bfd_boolean has_text = FALSE;
features = 0;
if (info->ibt)
@@ -2557,14 +2556,6 @@ _bfd_x86_elf_link_setup_gnu_properties
if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
&& bfd_count_sections (pbfd) != 0)
{
- if (!has_text)
- {
- /* Check if there is no non-empty text section. */
- sec = bfd_get_section_by_name (pbfd, ".text");
- if (sec != NULL && sec->size != 0)
- has_text = TRUE;
- }
-
ebfd = pbfd;
if (elf_properties (pbfd) != NULL)
@@ -2590,42 +2581,6 @@ _bfd_x86_elf_link_setup_gnu_properties
prop->u.number |= features;
prop->pr_kind = property_number;
}
- else if (has_text
- && elf_tdata (info->output_bfd)->o->build_id.sec == NULL
- && !htab->elf.dynamic_sections_created
- && !info->traditional_format
- && (info->output_bfd->flags & D_PAGED) != 0
- && info->separate_code)
- {
- /* If the separate code program header is needed, make sure
- that the first read-only PT_LOAD segment has no code by
- adding a GNU_PROPERTY_X86_FEATURE_2_NEEDED note. */
- elf_property_list *list;
- bfd_boolean need_property = TRUE;
-
- for (list = elf_properties (ebfd); list; list = list->next)
- {
- unsigned int pr_type = list->property.pr_type;
- if (pr_type == GNU_PROPERTY_STACK_SIZE
- || pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED
- || pr_type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED
- || (pr_type >= GNU_PROPERTY_X86_UINT32_OR_LO
- && pr_type <= GNU_PROPERTY_X86_UINT32_OR_HI))
- {
- /* These properties won't be removed during merging. */
- need_property = FALSE;
- break;
- }
- }
-
- if (need_property)
- {
- prop = _bfd_elf_get_property
- (ebfd, GNU_PROPERTY_X86_FEATURE_2_NEEDED, 4);
- prop->u.number = GNU_PROPERTY_X86_FEATURE_2_X86;
- prop->pr_kind = property_number;
- }
- }
/* Create the GNU property note section if needed. */
if (prop != NULL && pbfd == NULL)
diff --git a/ld/testsuite/ld-i386/property-x86-4a.d b/ld/testsuite/ld-i386/property-x86-4a.d
index 8ab0115cdd..5e2b4689f8 100644
--- a/ld/testsuite/ld-i386/property-x86-4a.d
+++ b/ld/testsuite/ld-i386/property-x86-4a.d
@@ -6,8 +6,7 @@
Displaying notes found in: .note.gnu.property
Owner Data size Description
- GNU 0x0000002c NT_GNU_PROPERTY_TYPE_0
+ GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
Properties: no copy on protected
- x86 feature needed: x86
x86 ISA used: <None>
x86 feature used: x86
diff --git a/ld/testsuite/ld-x86-64/property-x86-4a-x32.d b/ld/testsuite/ld-x86-64/property-x86-4a-x32.d
index 9dd6e3540e..76f74e5ded 100644
--- a/ld/testsuite/ld-x86-64/property-x86-4a-x32.d
+++ b/ld/testsuite/ld-x86-64/property-x86-4a-x32.d
@@ -6,8 +6,7 @@
Displaying notes found in: .note.gnu.property
Owner Data size Description
- GNU 0x0000002c NT_GNU_PROPERTY_TYPE_0
+ GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
Properties: no copy on protected
- x86 feature needed: x86
x86 ISA used: <None>
x86 feature used: x86
diff --git a/ld/testsuite/ld-x86-64/property-x86-4a.d b/ld/testsuite/ld-x86-64/property-x86-4a.d
index 4dc87acd56..e76be796a6 100644
--- a/ld/testsuite/ld-x86-64/property-x86-4a.d
+++ b/ld/testsuite/ld-x86-64/property-x86-4a.d
@@ -6,8 +6,7 @@
Displaying notes found in: .note.gnu.property
Owner Data size Description
- GNU 0x00000038 NT_GNU_PROPERTY_TYPE_0
+ GNU 0x00000028 NT_GNU_PROPERTY_TYPE_0
Properties: no copy on protected
- x86 feature needed: x86
x86 ISA used: <None>
x86 feature used: x86
--
2.17.1
From fe965abfab6908a2de0ea888cdfbaa0352d9ce02 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 28 Sep 2018 15:58:09 -0700
Subject: [PATCH 2/2] Add GNU_PROPERTY_NEED_PHDRS
---
bfd/elf-properties.c | 127 +++++++++++++++++++++++++++++++++++--------
binutils/readelf.c | 6 ++
include/elf/common.h | 1 +
3 files changed, 110 insertions(+), 24 deletions(-)
diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c
index 861db73170..d92ffc3ce5 100644
--- a/bfd/elf-properties.c
+++ b/bfd/elf-properties.c
@@ -177,6 +177,19 @@ bad_size:
prop->pr_kind = property_number;
goto next;
+ case GNU_PROPERTY_NEED_PHDRS:
+ if (datasz != 0)
+ {
+ _bfd_error_handler
+ (_("warning: %pB: corrupt need phdrs size: 0x%x"),
+ abfd, datasz);
+ /* Clear all properties. */
+ elf_properties (abfd) = NULL;
+ return FALSE;
+ }
+ /* Ignore GNU_PROPERTY_NEED_PHDRS in input files. */
+ goto next;
+
default:
break;
}
@@ -224,6 +237,7 @@ elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd,
/* FALLTHROUGH */
case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
+ case GNU_PROPERTY_NEED_PHDRS:
/* Return TRUE if APROP is NULL to indicate that BPROP should
be added to ABFD. */
return aprop == NULL;
@@ -414,34 +428,62 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
= get_elf_backend_data (info->output_bfd);
unsigned int elfclass = bed->s->elfclass;
int elf_machine_code = bed->elf_machine_code;
-
- /* Find the first relocatable ELF input with GNU properties. */
+ bfd_boolean has_text = FALSE;
+ bfd *elf_bfd = NULL;
+ asection *first_psec = NULL;
+ bfd_boolean need_phdrs = FALSE;
+
+ /* Find the first relocatable ELF input and the first relocatable ELF
+ input with GNU properties. Ignore GNU properties from ELF objects
+ with different machine code or class. */
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
&& (abfd->flags & DYNAMIC) == 0
- && elf_properties (abfd) != NULL)
+ && (elf_machine_code
+ == get_elf_backend_data (abfd)->elf_machine_code)
+ && elfclass == get_elf_backend_data (abfd)->s->elfclass)
{
- has_properties = TRUE;
-
- /* Ignore GNU properties from ELF objects with different machine
- code or class. Also skip objects without a GNU_PROPERTY note
- section. */
- if ((elf_machine_code
- == get_elf_backend_data (abfd)->elf_machine_code)
- && (elfclass
- == get_elf_backend_data (abfd)->s->elfclass)
- && bfd_get_section_by_name (abfd,
- NOTE_GNU_PROPERTY_SECTION_NAME) != NULL
- )
+ elf_bfd = abfd;
+
+ if (!has_text)
+ {
+ /* Check if there is no non-empty text section. */
+ sec = bfd_get_section_by_name (abfd, ".text");
+ if (sec != NULL && sec->size != 0)
+ has_text = TRUE;
+ }
+
+ if (elf_properties (abfd) != NULL)
{
- /* Keep .note.gnu.property section in FIRST_PBFD. */
- first_pbfd = abfd;
- break;
+ has_properties = TRUE;
+
+ /* Skip objects without a GNU_PROPERTY note section. */
+ sec = bfd_get_section_by_name (abfd,
+ NOTE_GNU_PROPERTY_SECTION_NAME);
+ if (sec)
+ {
+ first_psec = sec;
+ /* Keep .note.gnu.property section in FIRST_PBFD. */
+ first_pbfd = abfd;
+ break;
+ }
}
}
- /* Do nothing if there is no .note.gnu.property section. */
- if (!has_properties)
+ /* If the separate code program header is needed, make sure
+ that the first read-only PT_LOAD segment has no code by
+ adding a GNU_PROPERTY_NEED_PHDRS property. */
+ if (has_text
+ && elf_tdata (info->output_bfd)->o->build_id.sec == NULL
+ && !elf_hash_table (info)->dynamic_sections_created
+ && !info->traditional_format
+ && (info->output_bfd->flags & D_PAGED) != 0
+ && info->separate_code)
+ need_phdrs = TRUE;
+
+ /* Do nothing if there is no .note.gnu.property section and we don't
+ need a GNU_PROPERTY_NEED_PHDRS property. */
+ if (!has_properties && !need_phdrs)
return NULL;
/* Merge .note.gnu.property sections. */
@@ -484,15 +526,52 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
/* Rewrite .note.gnu.property section so that GNU properties are
always sorted by type even if input GNU properties aren't sorted. */
- if (first_pbfd != NULL)
+ if (first_pbfd != NULL || need_phdrs)
{
bfd_size_type size;
bfd_byte *contents;
unsigned int align_size = elfclass == ELFCLASS64 ? 8 : 4;
- sec = bfd_get_section_by_name (first_pbfd,
- NOTE_GNU_PROPERTY_SECTION_NAME);
- BFD_ASSERT (sec != NULL);
+ if (need_phdrs)
+ {
+ elf_property *prop;
+
+ if (first_pbfd)
+ sec = first_psec;
+ else
+ {
+ /* Create the GNU property note section if needed. */
+ sec = bfd_make_section_with_flags (elf_bfd,
+ NOTE_GNU_PROPERTY_SECTION_NAME,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS
+ | SEC_DATA));
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F%P: failed to create GNU property section\n"));
+
+ if (!bfd_set_section_alignment (elf_bfd, sec,
+ (elfclass == ELFCLASS64
+ ? 3 : 2)))
+ info->callbacks->einfo (_("%F%pA: failed to align section\n"),
+ first_psec);
+
+ elf_section_type (sec) = SHT_NOTE;
+ first_pbfd = elf_bfd;
+ }
+
+ if (elf_properties (first_pbfd) == NULL)
+ {
+ prop = _bfd_elf_get_property (first_pbfd,
+ GNU_PROPERTY_NEED_PHDRS,
+ 0);
+ prop->pr_kind = property_number;
+ }
+ }
+ else
+ sec = first_psec;
/* Update stack size in .note.gnu.property with -z stack-size=N
if N > 0. */
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 91f4c12286..e54f401f0d 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -17378,6 +17378,12 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
printf (_("<corrupt length: %#x> "), datasz);
goto next;
+ case GNU_PROPERTY_NEED_PHDRS:
+ printf ("need phdrs ");
+ if (datasz)
+ printf (_("<corrupt length: %#x> "), datasz);
+ goto next;
+
default:
break;
}
diff --git a/include/elf/common.h b/include/elf/common.h
index e194274305..149dd91e4e 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -738,6 +738,7 @@
/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */
#define GNU_PROPERTY_STACK_SIZE 1
#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
+#define GNU_PROPERTY_NEED_PHDRS 3
/* Processor-specific semantics, lo */
#define GNU_PROPERTY_LOPROC 0xc0000000
--
2.17.1