This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]