This is the mail archive of the binutils-cvs@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]

[binutils-gdb] ld: Extend options for altering orphan handling behaviour.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c005eb9e34ac08be0cd40e19a741d345bd43eab9

commit c005eb9e34ac08be0cd40e19a741d345bd43eab9
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Tue Jul 28 19:20:37 2015 +0100

    ld: Extend options for altering orphan handling behaviour.
    
    Replace the options --warn-orphan and --no-warn-orphan with a single
    option --orphan-handling=MODE, where mode can be place, warn, error, and
    discard.
    
    Mode 'place' is the default, and is the current behaviour, placing the
    orphan section into a suitable output section.
    
    Mode 'warn' is the same as '--warn-orphan'.  The orphan is also placed
    using the same algorithm as for 'place'.
    
    Mode 'error' is the same as '--warn-orphan' and '--fatal-warnings'.
    
    Mode 'discard' assigns all output sections to the /DISCARD/ section.
    
    ld/ChangeLog:
    
    	* ld.h (enum orphan_handling_enum): New.
    	(ld_config_type): Remove warn_orphan, add orphan_handling.
    	* ldemul.c (ldemul_place_orphan): Remove warning about orphan
    	sections.
    	* ldlang.c (ldlang_place_orphan): New function.
    	(lang_place_orphans): Call ldlang_place_orphan.
    	* ldlex.h (enum option_values): Remove OPTION_WARN_ORPHAN and
    	OPTION_NO_WARN_ORPHAN, add OPTION_ORPHAN_HANDLING.
    	* lexsup.c (ld_options): Remove 'warn-orphan' and
    	'no-warn-orphan', add 'orphan-handling'.
    	(parse_args): Remove handling for OPTION_WARN_ORPHAN and
    	OPTION_NO_WARN_ORPHAN, add handling for OPTION_ORPHAN_HANDLING.
    	* NEWS: Replace text about --warn-orphan with --orphan-handling.
    	* ld.texinfo (Options): Remove --warn-orphan entry and add
    	entry on --orphan-handling.
    	(Orphan Sections): Add reference to relevant command line options.
    
    ld/testsuite/ChangeLog:
    
    	* ld-elf/elf.exp: Switch to rely on run_dump_test.
    	* ld-elf/orphan-5.l: Update expected output.
    	* ld-elf/orphan-5.d: New file.
    	* ld-elf/orphan-6.d: New file.
    	* ld-elf/orphan-6.l: New file.
    	* ld-elf/orphan-7.d: New file.
    	* ld-elf/orphan-7.map: New file.
    	* ld-elf/orphan-8.d: New file.
    	* ld-elf/orphan-8.map: New file.

Diff:
---
 ld/ChangeLog                     | 19 +++++++++++
 ld/NEWS                          |  6 +++-
 ld/ld.h                          | 23 +++++++++++--
 ld/ld.texinfo                    | 44 ++++++++++++++++++-------
 ld/ldemul.c                      |  4 ---
 ld/ldlang.c                      | 71 ++++++++++++++++++++++++++++------------
 ld/ldlex.h                       |  3 +-
 ld/lexsup.c                      | 27 +++++++++------
 ld/testsuite/ChangeLog           | 12 +++++++
 ld/testsuite/ld-elf/elf.exp      | 12 -------
 ld/testsuite/ld-elf/orphan-5.d   |  4 +++
 ld/testsuite/ld-elf/orphan-5.l   |  4 +--
 ld/testsuite/ld-elf/orphan-6.d   |  4 +++
 ld/testsuite/ld-elf/orphan-6.l   |  5 +++
 ld/testsuite/ld-elf/orphan-7.d   |  4 +++
 ld/testsuite/ld-elf/orphan-7.map |  7 ++++
 ld/testsuite/ld-elf/orphan-8.d   |  4 +++
 ld/testsuite/ld-elf/orphan-8.map |  7 ++++
 18 files changed, 195 insertions(+), 65 deletions(-)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 7c60d9b..a9eb7c8 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,22 @@
+2015-07-28  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* ld.h (enum orphan_handling_enum): New.
+	(ld_config_type): Remove warn_orphan, add orphan_handling.
+	* ldemul.c (ldemul_place_orphan): Remove warning about orphan
+	sections.
+	* ldlang.c (ldlang_place_orphan): New function.
+	(lang_place_orphans): Call ldlang_place_orphan.
+	* ldlex.h (enum option_values): Remove OPTION_WARN_ORPHAN and
+	OPTION_NO_WARN_ORPHAN, add OPTION_ORPHAN_HANDLING.
+	* lexsup.c (ld_options): Remove 'warn-orphan' and
+	'no-warn-orphan', add 'orphan-handling'.
+	(parse_args): Remove handling for OPTION_WARN_ORPHAN and
+	OPTION_NO_WARN_ORPHAN, add handling for OPTION_ORPHAN_HANDLING.
+	* NEWS: Replace text about --warn-orphan with --orphan-handling.
+	* ld.texinfo (Options): Remove --warn-orphan entry and add
+	entry on --orphan-handling.
+	(Orphan Sections): Add reference to relevant command line options.
+
 2015-09-03  Nick Clifton  <nickc@redhat.com>
 
 	* ld.texinfo (--build-id): Fix typo.  The COFF/PE build-id section
diff --git a/ld/NEWS b/ld/NEWS
index f9ef88d..864384b 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -6,7 +6,11 @@
 * New command line option for ELF targets to compress DWARF debug
   sections, --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi].
 
-* Add --warn-orphan option to report orphan sections.
+* New command line option, --orphan-handling=[place|warn|error|discard], to
+  adjust how orphan sections are handled.  The default is 'place' which gives
+  the current behaviour, 'warn' and 'error' issue a warning or error
+  respectively when orphan sections are found, and 'discard' will discard all
+  orphan sections.
 
 * Add support for LLVM plugin.
 
diff --git a/ld/ld.h b/ld/ld.h
index e6ebaae..d84ec4e 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -207,6 +207,25 @@ extern args_type command_line;
 
 typedef int token_code_type;
 
+/* Different ways we can handle orphan sections.  */
+
+enum orphan_handling_enum {
+  /* The classic strategy, find a suitable section to place the orphan
+     into.  */
+  orphan_handling_place = 0,
+
+  /* Discard any orphan sections as though they were assign to the section
+     /DISCARD/.  */
+  orphan_handling_discard,
+
+  /* Find somewhere to place the orphan section, as with
+     ORPHAN_HANDLING_PLACE, but also issue a warning.  */
+  orphan_handling_warn,
+
+  /* Issue a fatal error if any orphan sections are found.  */
+  orphan_handling_error,
+};
+
 typedef struct {
   bfd_boolean magic_demand_paged;
   bfd_boolean make_executable;
@@ -229,8 +248,8 @@ typedef struct {
   /* If TRUE, only warn once about a particular undefined symbol.  */
   bfd_boolean warn_once;
 
-  /* If TRUE, issue warning messages when orphan sections are encountered.  */
-  bfd_boolean warn_orphan;
+  /* How should we deal with orphan sections.  */
+  enum orphan_handling_enum orphan_handling;
 
   /* If TRUE, warn if multiple global-pointers are needed (Alpha
      only).  */
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 2c78a07..d20a59f 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -1001,6 +1001,35 @@ with @samp{-Ur}; once the constructor table has been built, it cannot
 be added to.  Use @samp{-Ur} only for the last partial link, and
 @samp{-r} for the others.
 
+@kindex --orphan-handling=@var{MODE}
+@cindex orphan sections
+@cindex sections, orphan
+@item --orphan-handling=@var{MODE}
+Control how orphan sections are handled.  An orphan section is one not
+specifically mentioned in a linker script.  @xref{Orphan Sections}.
+
+@var{MODE} can have any of the following values:
+
+@table @code
+@item place
+Orphan sections are placed into a suitable output section following
+the strategy described in @ref{Orphan Sections}.  The option
+@samp{--unique} also effects how sections are placed.
+
+@item discard
+All orphan sections are discarded, by placing them in the
+@samp{/DISCARD/} section (@pxref{Output Section Discarding}).
+
+@item warn
+The linker will place the orphan section as for @code{place} and also
+issue a warning.
+
+@item error
+The linker will exit with an error if any orphan section is found.
+@end table
+
+The default if @samp{--orphan-handling} is not given is @code{place}.
+
 @kindex --unique[=@var{SECTION}]
 @item --unique[=@var{SECTION}]
 Creates a separate output section for every input section matching
@@ -2105,17 +2134,6 @@ option causes a warning to be issued whenever this case occurs.
 Only warn once for each undefined symbol, rather than once per module
 which refers to it.
 
-@kindex --warn-orphan
-@kindex --no-warn-orphan
-@cindex warnings, on orphan sections
-@cindex orphan sections, warnings on
-@item --warn-orphan
-The @option{--warn-orphan} option tells the linker to generate a
-warning message whenever it has to place an orphan section into the
-output file.  @xref{Orphan Sections}.  The @option{--no-warn-orphan}
-option restores the default behaviour of just silently placing these
-sections.
-
 @kindex --warn-section-align
 @cindex warnings, on section alignment
 @cindex section alignment, warnings on
@@ -5569,6 +5587,10 @@ at the end of the file.
 For ELF targets, the attribute of the section includes section type as
 well as section flag.
 
+The command line options @samp{--orphan-handling} and @samp{--unique}
+(@pxref{Options,,Command Line Options}) can be used to control which
+output sections an orphan is placed in.
+
 If an orphaned section's name is representable as a C identifier then
 the linker will automatically @pxref{PROVIDE} two symbols:
 __start_SECNAME and __stop_SECNAME, where SECNAME is the name of the
diff --git a/ld/ldemul.c b/ld/ldemul.c
index 596418e..22c7974 100644
--- a/ld/ldemul.c
+++ b/ld/ldemul.c
@@ -120,10 +120,6 @@ ldemul_open_dynamic_archive (const char *arch, search_dirs_type *search,
 lang_output_section_statement_type *
 ldemul_place_orphan (asection *s, const char *name, int constraint)
 {
-  if (config.warn_orphan)
-    einfo (_("%P: Warning: input section '%s' from file '%B' is not mentioned in linker script\n"),
-	   name, s->owner);
-
   if (ld_emulation->place_orphan)
     return (*ld_emulation->place_orphan) (s, name, constraint);
   return NULL;
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 6ee3f84..3d2cc99 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -6102,6 +6102,55 @@ lang_one_common (struct bfd_link_hash_entry *h, void *info)
   return TRUE;
 }
 
+/* Handle a single orphan section S, placing the orphan into an appropriate
+   output section.  The effects of the --orphan-handling command line
+   option are handled here.  */
+
+static void
+ldlang_place_orphan (asection *s)
+{
+  if (config.orphan_handling == orphan_handling_discard)
+    {
+      lang_output_section_statement_type *os;
+      os = lang_output_section_statement_lookup (DISCARD_SECTION_NAME, 0,
+						 TRUE);
+      if (os->addr_tree == NULL
+	  && (bfd_link_relocatable (&link_info)
+	      || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0))
+	os->addr_tree = exp_intop (0);
+      lang_add_section (&os->children, s, NULL, os);
+    }
+  else
+    {
+      lang_output_section_statement_type *os;
+      const char *name = s->name;
+      int constraint = 0;
+
+      if (config.orphan_handling == orphan_handling_error)
+	einfo ("%X%P: error: unplaced orphan section `%A' from `%B'.\n",
+	       s, s->owner);
+
+      if (config.unique_orphan_sections || unique_section_p (s, NULL))
+	constraint = SPECIAL;
+
+      os = ldemul_place_orphan (s, name, constraint);
+      if (os == NULL)
+	{
+	  os = lang_output_section_statement_lookup (name, constraint, TRUE);
+	  if (os->addr_tree == NULL
+	      && (bfd_link_relocatable (&link_info)
+		  || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0))
+	    os->addr_tree = exp_intop (0);
+	  lang_add_section (&os->children, s, NULL, os);
+	}
+
+      if (config.orphan_handling == orphan_handling_warn)
+	einfo ("%P: warning: orphan section `%A' from `%B' being "
+	       "placed in section `%s'.\n",
+	       s, s->owner, os->name);
+    }
+}
+
 /* Run through the input files and ensure that every input section has
    somewhere to go.  If one is found without a destination then create
    an input request and place it into the statement tree.  */
@@ -6141,27 +6190,7 @@ lang_place_orphans (void)
 		    }
 		}
 	      else
-		{
-		  const char *name = s->name;
-		  int constraint = 0;
-
-		  if (config.unique_orphan_sections
-		      || unique_section_p (s, NULL))
-		    constraint = SPECIAL;
-
-		  if (!ldemul_place_orphan (s, name, constraint))
-		    {
-		      lang_output_section_statement_type *os;
-		      os = lang_output_section_statement_lookup (name,
-								 constraint,
-								 TRUE);
-		      if (os->addr_tree == NULL
-			  && (bfd_link_relocatable (&link_info)
-			      || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0))
-			os->addr_tree = exp_intop (0);
-		      lang_add_section (&os->children, s, NULL, os);
-		    }
-		}
+		ldlang_place_orphan (s);
 	    }
 	}
     }
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 59bd14f..5629ef1 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -85,8 +85,6 @@ enum option_values
   OPTION_NO_WARN_FATAL,
   OPTION_WARN_MULTIPLE_GP,
   OPTION_WARN_ONCE,
-  OPTION_WARN_ORPHAN,
-  OPTION_NO_WARN_ORPHAN,
   OPTION_WARN_SECTION_ALIGN,
   OPTION_SPLIT_BY_RELOC,
   OPTION_SPLIT_BY_FILE ,
@@ -144,6 +142,7 @@ enum option_values
   OPTION_POP_STATE,
   OPTION_PRINT_MEMORY_USAGE,
   OPTION_REQUIRE_DEFINED_SYMBOL,
+  OPTION_ORPHAN_HANDLING,
 };
 
 /* The initial parser states.  */
diff --git a/ld/lexsup.c b/ld/lexsup.c
index ace1803..5dc56dc 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -492,10 +492,6 @@ static const struct ld_option ld_options[] =
     '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES },
   { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
     '\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES },
-  { {"warn-orphan", no_argument, NULL, OPTION_WARN_ORPHAN},
-    '\0', NULL, N_("Warn if any orphan sections are encountered"), TWO_DASHES },
-  { {"no-warn-orphan", no_argument, NULL, OPTION_NO_WARN_ORPHAN},
-    '\0', NULL, N_("Do not warn if orphan sections are encountered (default)"), TWO_DASHES },
   { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
     '\0', NULL, N_("Warn if start of section changes due to alignment"),
     TWO_DASHES },
@@ -528,6 +524,9 @@ static const struct ld_option ld_options[] =
     TWO_DASHES },
   { {"print-memory-usage", no_argument, NULL, OPTION_PRINT_MEMORY_USAGE},
     '\0', NULL, N_("Report target memory usage"), TWO_DASHES },
+  { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING},
+    '\0', N_("=MODE"), N_("Control how orphan sections are handled."),
+    TWO_DASHES },
 };
 
 #define OPTION_COUNT ARRAY_SIZE (ld_options)
@@ -1375,12 +1374,6 @@ parse_args (unsigned argc, char **argv)
 	case OPTION_WARN_ONCE:
 	  config.warn_once = TRUE;
 	  break;
-	case OPTION_WARN_ORPHAN:
-	  config.warn_orphan = TRUE;
-	  break;
-	case OPTION_NO_WARN_ORPHAN:
-	  config.warn_orphan = FALSE;
-	  break;
 	case OPTION_WARN_SECTION_ALIGN:
 	  config.warn_section_align = TRUE;
 	  break;
@@ -1515,6 +1508,20 @@ parse_args (unsigned argc, char **argv)
 	case OPTION_PRINT_MEMORY_USAGE:
 	  command_line.print_memory_usage = TRUE;
 	  break;
+
+	case OPTION_ORPHAN_HANDLING:
+	  if (strcasecmp (optarg, "place") == 0)
+	    config.orphan_handling = orphan_handling_place;
+	  else if (strcasecmp (optarg, "warn") == 0)
+	    config.orphan_handling = orphan_handling_warn;
+	  else if (strcasecmp (optarg, "error") == 0)
+	    config.orphan_handling = orphan_handling_error;
+	  else if (strcasecmp (optarg, "discard") == 0)
+	    config.orphan_handling = orphan_handling_discard;
+	  else
+	    einfo (_("%P%F: invalid argument to option"
+		     " \"--orphan-handling\"\n"));
+	  break;
 	}
     }
 
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 34ed02d..5ca0f6c 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2015-07-28  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* ld-elf/elf.exp: Switch to rely on run_dump_test.
+	* ld-elf/orphan-5.l: Update expected output.
+	* ld-elf/orphan-5.d: New file.
+	* ld-elf/orphan-6.d: New file.
+	* ld-elf/orphan-6.l: New file.
+	* ld-elf/orphan-7.d: New file.
+	* ld-elf/orphan-7.map: New file.
+	* ld-elf/orphan-8.d: New file.
+	* ld-elf/orphan-8.map: New file.
+
 2015-09-03  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* ld-ifunc/ifunc-21-i386.s: Add tests for call, jmp, add, test.
diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp
index 55bcb72..e56c205 100644
--- a/ld/testsuite/ld-elf/elf.exp
+++ b/ld/testsuite/ld-elf/elf.exp
@@ -124,18 +124,6 @@ foreach t $test_list {
     run_dump_test [file rootname $t]
 }
 
-# Check that the --warn-orphan option works correctly.
-run_ld_link_tests {
-    {"Report orphan sections"
-	"--script orphan.ld --warn-orphan"
-	""
-	""
-	{orphan.s}
-	{ { ld "orphan-5.l" } }
-	"orphan"
-    }
-}
-
 if { [istarget *-*-linux*]
      || [istarget *-*-nacl*]
      || [istarget *-*-gnu*] } {
diff --git a/ld/testsuite/ld-elf/orphan-5.d b/ld/testsuite/ld-elf/orphan-5.d
new file mode 100644
index 0000000..4f99cd0
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-5.d
@@ -0,0 +1,4 @@
+#name: Report warning for orphan sections
+#ld: --script orphan.ld --orphan-handling=warn
+#source: orphan.s
+#warning_output: orphan-5.l
diff --git a/ld/testsuite/ld-elf/orphan-5.l b/ld/testsuite/ld-elf/orphan-5.l
index 7b65af2..20a9fe7 100644
--- a/ld/testsuite/ld-elf/orphan-5.l
+++ b/ld/testsuite/ld-elf/orphan-5.l
@@ -1,5 +1,5 @@
 #...
-.*Warning: input section '.notbad' from file 'tmpdir/orphan.o' is not mentioned in linker script
+.*warning: orphan section `\.notbad' from `tmpdir/orphan\.o' being placed in section `\.notbad'\.
 #...
-.*Warning: input section '.note.bar' from file 'tmpdir/orphan.o' is not mentioned in linker script
+.*warning: orphan section `\.note\.bar' from `tmpdir/orphan\.o' being placed in section `\.note\.bar'\.
 #...
diff --git a/ld/testsuite/ld-elf/orphan-6.d b/ld/testsuite/ld-elf/orphan-6.d
new file mode 100644
index 0000000..c6565fb
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-6.d
@@ -0,0 +1,4 @@
+#name: Report error for orphan sections
+#ld: --script orphan.ld --orphan-handling=error
+#source: orphan.s
+#error_output: orphan-6.l
diff --git a/ld/testsuite/ld-elf/orphan-6.l b/ld/testsuite/ld-elf/orphan-6.l
new file mode 100644
index 0000000..5ac7895
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-6.l
@@ -0,0 +1,5 @@
+#...
+.*error: unplaced orphan section `\.notbad' from `tmpdir/orphan\.o'\.
+#...
+.*error: unplaced orphan section `\.note\.bar' from `tmpdir/orphan\.o'\.
+#...
diff --git a/ld/testsuite/ld-elf/orphan-7.d b/ld/testsuite/ld-elf/orphan-7.d
new file mode 100644
index 0000000..01d6e80
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-7.d
@@ -0,0 +1,4 @@
+#name: Discard orphan sections
+#ld: --script orphan.ld --orphan-handling=discard
+#source: orphan.s
+#map: orphan-7.map
diff --git a/ld/testsuite/ld-elf/orphan-7.map b/ld/testsuite/ld-elf/orphan-7.map
new file mode 100644
index 0000000..52cc359
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-7.map
@@ -0,0 +1,7 @@
+
+Discarded input sections
+
+ \.notbad        0x0+        0x4 tmpdir/.*\.o
+ \.note\.bar      0x0+        0x4 tmpdir/.*\.o
+
+#...
diff --git a/ld/testsuite/ld-elf/orphan-8.d b/ld/testsuite/ld-elf/orphan-8.d
new file mode 100644
index 0000000..bbd7288
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-8.d
@@ -0,0 +1,4 @@
+#name: Place orphan sections
+#ld: --script orphan.ld --orphan-handling=place
+#source: orphan.s
+#map: orphan-8.map
diff --git a/ld/testsuite/ld-elf/orphan-8.map b/ld/testsuite/ld-elf/orphan-8.map
new file mode 100644
index 0000000..b672978
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-8.map
@@ -0,0 +1,7 @@
+#...
+.notbad         0x0000000000000004        0x4
+ .notbad        0x0000000000000004        0x4 tmpdir/dump0.o
+#...
+.note.bar       0x0000000000000010        0x4
+ .note.bar      0x0000000000000010        0x4 tmpdir/dump0.o
+#...


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