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]

[PATCH] ELF: Hide .startof.SECNAME and .sizeof.SECNAME


Exporting .startof.SECNAME and .sizeof.SECNAME as dynamic symbols may
lead to unexpected behavior.  Reference to .startof.SECNAME and
.sizeof.SECNAME to section SECNAME within a DSO will be resolved to
.startof.SECNAME and .sizeof.SECNAME in another DSO or executable.
This patch marks .startof.SECNAME and .sizeof.SECNAME as hidden.

OK for master?

H.J.
---
bfd/

	PR ld/21593
	* elf-bfd.h (_bfd_elf_link_setup_section_symbols): New.
	* elflink.c (elf_lookup_and_hide_section_symbol): New function.
	(_bfd_elf_link_setup_section_symbols): Likewise.

ld/

	PR ld/21593
	* emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Call
	_bfd_elf_link_setup_section_symbols.
	* testsuite/ld-elf/sizeofb.d: Expect local .sizeof.scnfoo.
	* testsuite/ld-elf/startofb.d: Expect local .startof.scnfoo.
---
 bfd/elf-bfd.h                  |  3 ++
 bfd/elflink.c                  | 67 ++++++++++++++++++++++++++++++++++++++++++
 ld/emultempl/elf32.em          | 57 +----------------------------------
 ld/testsuite/ld-elf/sizeofb.d  |  2 +-
 ld/testsuite/ld-elf/startofb.d |  2 +-
 5 files changed, 73 insertions(+), 58 deletions(-)

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index fe15b93..bc7e128 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2273,6 +2273,9 @@ extern bfd_reloc_status_type bfd_elf_perform_complex_relocation
 extern bfd_boolean _bfd_elf_setup_sections
   (bfd *);
 
+extern void _bfd_elf_link_setup_section_symbols
+  (struct bfd_link_info *);
+
 extern void _bfd_elf_post_process_headers (bfd * , struct bfd_link_info *);
 
 extern const bfd_target *bfd_elf32_object_p
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 9b0f544..ff1fc44 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -14193,3 +14193,70 @@ elf_append_rel (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
   BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size);
   bed->s->swap_reloc_out (abfd, rel, loc);
 }
+
+/* Lookup and hide SYMBOL for section SEC.  */
+
+static void
+elf_lookup_and_hide_section_symbol (struct bfd_link_info *info,
+				    const char *symbol, asection *sec)
+{
+  struct elf_link_hash_entry *h
+    = elf_link_hash_lookup (elf_hash_table (info), symbol, FALSE,
+			    FALSE, TRUE);
+  if (h != NULL
+      && (h->root.type == bfd_link_hash_undefined
+	  || h->root.type == bfd_link_hash_undefweak)
+      && h->u2.start_stop_section == NULL)
+    {
+      h->start_stop = 1;
+      h->u2.start_stop_section = sec;
+      _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
+      if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+	h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
+		    | STV_HIDDEN);
+    }
+}
+
+/* Check for input sections whose names match references to
+   __start_SECNAME, __stop_SECNAME, .startof.SECNAME or
+   .sizeof.SECNAME symbols.  Mark the matched symbols as hidden
+   and set start_stop for garbage collection.  */
+
+void
+_bfd_elf_link_setup_section_symbols (struct bfd_link_info *info)
+{
+  bfd *abfd;
+  asection *s;
+  char leading_char = bfd_get_symbol_leading_char (info->output_bfd);
+
+  for (abfd = info->input_bfds; abfd; abfd = abfd->link.next)
+    for (s = abfd->sections; s; s = s->next)
+      {
+	const char *ps;
+	const char *name = bfd_get_section_name (abfd, s);
+	char *symbol = (char *) xmalloc (strlen (name) + 10);
+
+	sprintf (symbol, ".startof.%s", name);
+	elf_lookup_and_hide_section_symbol (info, symbol, s);
+
+	sprintf (symbol, ".sizeof.%s", name);
+	elf_lookup_and_hide_section_symbol (info, symbol, s);
+
+	for (ps = name; *ps != '\0'; ps++)
+	  if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
+	    break;
+	if (*ps == '\0')
+	  {
+
+	    symbol[0] = leading_char;
+	    sprintf (symbol + (leading_char != 0), "__start_%s", name);
+	    elf_lookup_and_hide_section_symbol (info, symbol, s);
+
+	    symbol[0] = leading_char;
+	    sprintf (symbol + (leading_char != 0), "__stop_%s", name);
+	    elf_lookup_and_hide_section_symbol (info, symbol, s);
+	  }
+
+	free (symbol);
+      }
+}
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 9468f7d..27300a3 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1218,7 +1218,6 @@ gld${EMULATION_NAME}_after_open (void)
   struct elf_link_hash_table *htab;
   asection *s;
   bfd *abfd;
-  char leading_char;
 
   after_open_default ();
 
@@ -1277,61 +1276,7 @@ gld${EMULATION_NAME}_after_open (void)
       return;
     }
 
-  leading_char = bfd_get_symbol_leading_char (link_info.output_bfd);
-
-  /* Check for input sections whose names match references to
-     __start_SECNAME or __stop_SECNAME symbols.  Mark the matched
-     symbols as hidden and set start_stop for garbage collection.  */
-  for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
-    for (s = abfd->sections; s; s = s->next)
-      {
-	const char *name = bfd_get_section_name (abfd, s);
-	const char *ps;
-
-	for (ps = name; *ps != '\0'; ps++)
-	  if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
-	    break;
-	if (*ps == '\0')
-	  {
-	    struct elf_link_hash_entry *h;
-	    char *symbol = (char *) xmalloc (ps - name
-					     + sizeof "__start_" + 1);
-
-	    symbol[0] = leading_char;
-	    sprintf (symbol + (leading_char != 0), "__start_%s", name);
-	    h = elf_link_hash_lookup (elf_hash_table (&link_info),
-				      symbol, FALSE, FALSE, TRUE);
-	    if (h != NULL
-		&& (h->root.type == bfd_link_hash_undefined
-		    || h->root.type == bfd_link_hash_undefweak)
-		&& h->u2.start_stop_section == NULL)
-	      {
-		h->start_stop = 1;
-		h->u2.start_stop_section = s;
-		_bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
-		if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
-		  h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
-			      | STV_HIDDEN);
-	      }
-
-	    symbol[0] = leading_char;
-	    sprintf (symbol + (leading_char != 0), "__stop_%s", name);
-	    h = elf_link_hash_lookup (elf_hash_table (&link_info),
-				      symbol, FALSE, FALSE, TRUE);
-	    if (h != NULL
-		&& (h->root.type == bfd_link_hash_undefined
-		    || h->root.type == bfd_link_hash_undefweak)
-		&& h->u2.start_stop_section == NULL)
-	      {
-		h->start_stop = 1;
-		h->u2.start_stop_section = s;
-		_bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
-		if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
-		  h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
-			      | STV_HIDDEN);
-	      }
-	  }
-      }
+  _bfd_elf_link_setup_section_symbols (&link_info);
 
   if (!link_info.traditional_format)
     {
diff --git a/ld/testsuite/ld-elf/sizeofb.d b/ld/testsuite/ld-elf/sizeofb.d
index cd3920b..15f46c3 100644
--- a/ld/testsuite/ld-elf/sizeofb.d
+++ b/ld/testsuite/ld-elf/sizeofb.d
@@ -13,5 +13,5 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
 #...
  +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
 #...
- +[0-9]+: 0+10 + +0 +NOTYPE +GLOBAL +DEFAULT +ABS +.sizeof.scnfoo
+ +[0-9]+: 0+10 + +0 +NOTYPE +LOCAL +DEFAULT +ABS +.sizeof.scnfoo
 #pass
diff --git a/ld/testsuite/ld-elf/startofb.d b/ld/testsuite/ld-elf/startofb.d
index 0d1da66..477e9c7 100644
--- a/ld/testsuite/ld-elf/startofb.d
+++ b/ld/testsuite/ld-elf/startofb.d
@@ -11,7 +11,7 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
  +Num: +Value +Size Type +Bind +Vis +Ndx Name
  +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
 #...
- +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +.startof.scnfoo
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +.startof.scnfoo
 #...
  +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
 #pass
-- 
2.9.4


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