ld: Add --warn-textrel and obsolete --warn-shared-textrel

Message ID 20200525135126.485985-1-hjl.tools@gmail.com
State New
Headers show
Series
  • ld: Add --warn-textrel and obsolete --warn-shared-textrel
Related show

Commit Message

--warn-shared-textrel and -z text apply to both shared object and PIE.
But include/elf/common.h has

 #define ET_EXEC         2       /* Executable file */
 #define ET_DYN          3       /* Shared object file */

These predate PIE:

https://groups.google.com/forum/#!topic/generic-abi/mBKlSNldFW4

Updated comments to

 #define ET_EXEC         2       /* Position-dependent executable file */
 #define ET_DYN          3       /* Position-independent executable or
                                    shared object file */

Add --warn-textrel and obsolete --warn-shared-textrel.  Consolidate
--warn-textrel and -z text/notext/textoff implementation.

bfd/

	PR ld/22909
	* elflink.c (bfd_elf_final_link): Use bfd_link_textrel_check.
	Check bfd_link_dll when issue a DT_TEXTREL warning.
	* elfxx-x86.c (maybe_set_textrel): Likewise.
	(_bfd_x86_elf_size_dynamic_sections): Likewise.

include/

	PR ld/22909
	* bfdlink.h (textrel_check_method): New enum.
	(bfd_link_textrel_check): New.
	(bfd_link_info): Replace warn_shared_textrel and error_textrel
	with textrel_check.
	* elf/common.h: Update comments for ET_EXEC and ET_DYN.

ld/

	PR ld/22909
	* NEWS: Mention --warn-textrel.
	* ld.texi: Update -z text/notext/textoff.  Add --warn-textrel.
	Remove --warn-shared-textrel.
	* ldlex.h (option_values): Rename OPTION_WARN_SHARED_TEXTREL to
	OPTION_WARN_TEXTREL.
	* lexsup.c (ld_options): Add --warn-textrel.  Obsolete
	--warn-shared-textrel.
	(parse_args): Updated.
	(elf_shlib_list_options): Check link_info.textrel_check.
	* emultempl/elf.em: Updated.
	* testsuite/ld-elf/pr19539.d: Replace -z notext with
	--warn-textrel.  Expect a warning.
	* testsuite/ld-i386/warn1.d: Update expected warning.
---
 bfd/elflink.c                 | 10 ++++++----
 bfd/elfxx-x86.c               |  6 ++----
 include/bfdlink.h             | 19 +++++++++++++-----
 include/elf/common.h          |  5 +++--
 ld/NEWS                       |  3 +++
 ld/emultempl/elf.em           |  6 +++---
 ld/ld.texi                    | 13 +++++++------
 ld/ldlex.h                    |  2 +-
 ld/lexsup.c                   | 36 +++++++++++++++++++++++++----------
 ld/testsuite/ld-elf/pr19539.d |  3 ++-
 ld/testsuite/ld-i386/warn1.d  |  2 +-
 11 files changed, 68 insertions(+), 37 deletions(-)

-- 
2.26.2

Comments

On Mon, May 25, 2020 at 06:51:26AM -0700, H.J. Lu via Binutils wrote:
> bfd/

> 

> 	PR ld/22909

> 	* elflink.c (bfd_elf_final_link): Use bfd_link_textrel_check.

> 	Check bfd_link_dll when issue a DT_TEXTREL warning.

> 	* elfxx-x86.c (maybe_set_textrel): Likewise.

> 	(_bfd_x86_elf_size_dynamic_sections): Likewise.

> 

> include/

> 

> 	PR ld/22909

> 	* bfdlink.h (textrel_check_method): New enum.

> 	(bfd_link_textrel_check): New.

> 	(bfd_link_info): Replace warn_shared_textrel and error_textrel

> 	with textrel_check.

> 	* elf/common.h: Update comments for ET_EXEC and ET_DYN.

> 

> ld/

> 

> 	PR ld/22909

> 	* NEWS: Mention --warn-textrel.

> 	* ld.texi: Update -z text/notext/textoff.  Add --warn-textrel.

> 	Remove --warn-shared-textrel.

> 	* ldlex.h (option_values): Rename OPTION_WARN_SHARED_TEXTREL to

> 	OPTION_WARN_TEXTREL.

> 	* lexsup.c (ld_options): Add --warn-textrel.  Obsolete

> 	--warn-shared-textrel.

> 	(parse_args): Updated.

> 	(elf_shlib_list_options): Check link_info.textrel_check.

> 	* emultempl/elf.em: Updated.

> 	* testsuite/ld-elf/pr19539.d: Replace -z notext with

> 	--warn-textrel.  Expect a warning.

> 	* testsuite/ld-i386/warn1.d: Update expected warning.


Looks good.

-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/elflink.c b/bfd/elflink.c
index c157aea90d..f87927f0bd 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12896,8 +12896,7 @@  bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	goto error_return;
 
       /* Check for DT_TEXTREL (late, in case the backend removes it).  */
-      if (((info->warn_shared_textrel && bfd_link_pic (info))
-	   || info->error_textrel)
+      if (bfd_link_textrel_check (info)
 	  && (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL)
 	{
 	  bfd_byte *dyncon, *dynconend;
@@ -12912,12 +12911,15 @@  bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
 	      if (dyn.d_tag == DT_TEXTREL)
 		{
-		  if (info->error_textrel)
+		  if (info->textrel_check == textrel_check_error)
 		    info->callbacks->einfo
 		      (_("%P%X: read-only segment has dynamic relocations\n"));
+		  else if (bfd_link_dll (info))
+		    info->callbacks->einfo
+		      (_("%P: warning: creating DT_TEXTREL in a shared object\n"));
 		  else
 		    info->callbacks->einfo
-		      (_("%P: warning: creating a DT_TEXTREL in a shared object\n"));
+		      (_("%P: warning: creating DT_TEXTREL in a PIE\n"));
 		  break;
 		}
 	    }
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 9679dca981..6cc47afd7e 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -575,8 +575,7 @@  maybe_set_textrel (struct elf_link_hash_entry *h, void *inf)
 				"in read-only section `%pA'\n"),
 			      sec->owner, h->root.root.string, sec);
 
-      if ((info->warn_shared_textrel && bfd_link_pic (info))
-	  || info->error_textrel)
+      if (bfd_link_textrel_check (info))
 	/* xgettext:c-format */
 	info->callbacks->einfo (_("%P: %pB: warning: relocation against `%s' "
 				  "in read-only section `%pA'\n"),
@@ -1117,8 +1116,7 @@  _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
 		      && (info->flags & DF_TEXTREL) == 0)
 		    {
 		      info->flags |= DF_TEXTREL;
-		      if ((info->warn_shared_textrel && bfd_link_pic (info))
-			  || info->error_textrel)
+		      if (bfd_link_textrel_check (info))
 			/* xgettext:c-format */
 			info->callbacks->einfo
 			  (_("%P: %pB: warning: relocation "
diff --git a/include/bfdlink.h b/include/bfdlink.h
index ec97679e6f..34a0d2ec4e 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -273,6 +273,18 @@  enum report_method
   RM_DIAGNOSE,
 };
 
+/* How to handle DT_TEXTREL.  */
+
+enum textrel_check_method
+{
+  textrel_check_none,
+  textrel_check_warning,
+  textrel_check_error
+};
+
+#define bfd_link_textrel_check(info) \
+  (info->textrel_check != textrel_check_none)
+
 typedef enum {with_flags, without_flags} flag_type;
 
 /* A section flag list.  */
@@ -410,11 +422,8 @@  struct bfd_link_info
      should be created.  1 for DWARF2 tables, 2 for compact tables.  */
   unsigned int eh_frame_hdr_type: 2;
 
-  /* TRUE if we should warn when adding a DT_TEXTREL to a shared object.  */
-  unsigned int warn_shared_textrel: 1;
-
-  /* TRUE if we should error when adding a DT_TEXTREL.  */
-  unsigned int error_textrel: 1;
+  /* What to do with DT_TEXTREL in output.  */
+  ENUM_BITFIELD (textrel_check_method) textrel_check: 2;
 
   /* TRUE if .hash section should be created.  */
   unsigned int emit_hash: 1;
diff --git a/include/elf/common.h b/include/elf/common.h
index 26e6fbc8e6..4d94c4fd5b 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -91,8 +91,9 @@ 
 
 #define ET_NONE		0	/* No file type */
 #define ET_REL		1	/* Relocatable file */
-#define ET_EXEC		2	/* Executable file */
-#define ET_DYN		3	/* Shared object file */
+#define ET_EXEC		2	/* Position-dependent executable file */
+#define ET_DYN		3	/* Position-independent executable or
+				   shared object file */
 #define ET_CORE		4	/* Core file */
 #define ET_LOOS		0xFE00	/* Operating system-specific */
 #define ET_HIOS		0xFEFF	/* Operating system-specific */
diff --git a/ld/NEWS b/ld/NEWS
index 9f5bbe51cf..0aaa13d487 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@ 
 -*- text -*-
 
+* Add a command-line option for ELF linker, --warn-textrel, to warn that
+  DT_TEXTREL is set in a position-independent executable or shared object.
+
 * Add command-line options --enable-non-contiguous-regions and
   --enable-non-contiguous-regions-warnings.
 
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index 4fd6fdffe7..c4979eb953 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -803,11 +803,11 @@  fragment <<EOF
       else if (strcmp (optarg, "nocommon") == 0)
 	link_info.elf_stt_common = no_elf_stt_common;
       else if (strcmp (optarg, "text") == 0)
-	link_info.error_textrel = TRUE;
+	link_info.textrel_check = textrel_check_error;
       else if (strcmp (optarg, "notext") == 0)
-	link_info.error_textrel = FALSE;
+	link_info.textrel_check = textrel_check_none;
       else if (strcmp (optarg, "textoff") == 0)
-	link_info.error_textrel = FALSE;
+	link_info.textrel_check = textrel_check_none;
 EOF
 fi
 
diff --git a/ld/ld.texi b/ld/ld.texi
index 4dc78e65fa..a7ec0d01b3 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1358,9 +1358,9 @@  Specifying zero will override any default non-zero sized
 @item text
 @itemx notext
 @itemx textoff
-Report an error if DT_TEXTREL is set, i.e., if the binary has dynamic
-relocations in read-only sections.  Don't report an error if
-@samp{notext} or @samp{textoff}.
+Report an error if DT_TEXTREL is set, i.e., if the position-independent
+or shared object has dynamic relocations in read-only sections.  Don't
+report an error if @samp{notext} or @samp{textoff}.
 
 @item undefs
 Do not report unresolved symbol references from regular object files,
@@ -2404,9 +2404,10 @@  The address will only be changed if it not explicitly specified; that
 is, if the @code{SECTIONS} command does not specify a start address for
 the section (@pxref{SECTIONS}).
 
-@kindex --warn-shared-textrel
-@item --warn-shared-textrel
-Warn if the linker adds a DT_TEXTREL to a shared object.
+@kindex --warn-textrel
+@item --warn-textrel
+Warn if the linker adds DT_TEXTREL to a position-independent executable
+or shared object.
 
 @kindex --warn-alternate-em
 @item --warn-alternate-em
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 22b928d2d9..318ac7a789 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -130,7 +130,7 @@  enum option_values
   OPTION_UNRESOLVED_SYMBOLS,
   OPTION_WARN_UNRESOLVED_SYMBOLS,
   OPTION_ERROR_UNRESOLVED_SYMBOLS,
-  OPTION_WARN_SHARED_TEXTREL,
+  OPTION_WARN_TEXTREL,
   OPTION_WARN_ALTERNATE_EM,
   OPTION_REDUCE_MEMORY_OVERHEADS,
 #ifdef ENABLE_PLUGINS
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 04db2f129f..3733a7c893 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -516,9 +516,11 @@  static const struct ld_option ld_options[] =
   { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
     '\0', NULL, N_("Warn if start of section changes due to alignment"),
     TWO_DASHES },
-  { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_SHARED_TEXTREL},
-    '\0', NULL, N_("Warn if shared object has DT_TEXTREL"),
+  { {"warn-textrel", no_argument, NULL, OPTION_WARN_TEXTREL},
+    '\0', NULL, N_("Warn if outpout has DT_TEXTREL"),
     TWO_DASHES },
+  { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_TEXTREL},
+    '\0', NULL, NULL, NO_HELP },
   { {"warn-alternate-em", no_argument, NULL, OPTION_WARN_ALTERNATE_EM},
     '\0', NULL, N_("Warn if an object has alternate ELF machine code"),
     TWO_DASHES },
@@ -1438,8 +1440,8 @@  parse_args (unsigned argc, char **argv)
 	case OPTION_WARN_SECTION_ALIGN:
 	  config.warn_section_align = TRUE;
 	  break;
-	case OPTION_WARN_SHARED_TEXTREL:
-	  link_info.warn_shared_textrel = TRUE;
+	case OPTION_WARN_TEXTREL:
+	  link_info.textrel_check = textrel_check_warning;
 	  break;
 	case OPTION_WARN_ALTERNATE_EM:
 	  link_info.warn_alternate_em = TRUE;
@@ -1846,12 +1848,26 @@  elf_shlib_list_options (FILE *file)
   -z nocommon                 Generate common symbols with STT_OBJECT type\n"));
   fprintf (file, _("\
   -z stack-size=SIZE          Set size of stack segment\n"));
-  fprintf (file, _("\
-  -z text                     Treat DT_TEXTREL in shared object as error\n"));
-  fprintf (file, _("\
-  -z notext                   Don't treat DT_TEXTREL in shared object as error\n"));
-  fprintf (file, _("\
-  -z textoff                  Don't treat DT_TEXTREL in shared object as error\n"));
+  if (link_info.textrel_check == textrel_check_error)
+    fprintf (file, _("\
+  -z text                     Treat DT_TEXTREL in output as error (default)\n"));
+  else
+    fprintf (file, _("\
+  -z text                     Treat DT_TEXTREL in output as error\n"));
+  if (link_info.textrel_check == textrel_check_none)
+    {
+      fprintf (file, _("\
+  -z notext                   Don't treat DT_TEXTREL in output as error (default)\n"));
+      fprintf (file, _("\
+  -z textoff                  Don't treat DT_TEXTREL in output as error (default)\n"));
+    }
+  else
+    {
+      fprintf (file, _("\
+  -z notext                   Don't treat DT_TEXTREL in output as error\n"));
+      fprintf (file, _("\
+  -z textoff                  Don't treat DT_TEXTREL in output as error\n"));
+    }
 }
 
 static void
diff --git a/ld/testsuite/ld-elf/pr19539.d b/ld/testsuite/ld-elf/pr19539.d
index 56e6502ca6..211d3e1639 100644
--- a/ld/testsuite/ld-elf/pr19539.d
+++ b/ld/testsuite/ld-elf/pr19539.d
@@ -1,7 +1,8 @@ 
 #source: start.s
 #source: pr19539.s
-#ld: -pie -T pr19539.t -z notext
+#ld: -pie -T pr19539.t --warn-textrel
 #readelf : --dyn-syms --wide
+#warning: .*: creating DT_TEXTREL in a PIE
 #target: *-*-linux* *-*-gnu* *-*-solaris* arm*-*-uclinuxfdpiceabi
 #xfail: cris*-*-* ![check_pie_support] 
 
diff --git a/ld/testsuite/ld-i386/warn1.d b/ld/testsuite/ld-i386/warn1.d
index 3c78f31efd..c00fdb36dc 100644
--- a/ld/testsuite/ld-i386/warn1.d
+++ b/ld/testsuite/ld-i386/warn1.d
@@ -1,4 +1,4 @@ 
 #name: --warn-shared-textrel --fatal-warnings
 #as: --32
 #ld: -shared -melf_i386 --warn-shared-textrel --fatal-warnings
-#error: .*warning: creating a DT_TEXTREL in a shared object
+#error: .*warning: creating DT_TEXTREL in a shared object