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]

New INSERT linker script command


This implements a new INSERT linker command for those who want to
tweak the default linker script a little but can't lay their hands on
an editor, or for whatever reason don't find it convenient to modify
the default linker script.  More than that actually.  It also provides
a way to specify output sections that are placed later in the binary
whose input section patterns match earlier.

	* ld.texinfo (INSERT): Describe.
	* ldgram.y (ldgram_in_script, ldgram_had_equals): Delete.
	(INSERT_K, AFTER, BEFORE): Add as tokens.
	(ifile_p1): Handle INSERT statements.
	(saved_script_handle, force_make_executable): Move to..
	* ldmain.c: ..here.
	(previous_script_handle): New global var.
	* ldmain.h (saved_script_handle, force_make_executable): Declare.
	(previous_script_handle): Likewise.
	* ldlex.l (INSERT_K, AFTER, BEFORE): Add tokens.
	* lexsup.c (parge_args <-T>): Set previous_script_handle.
	* ldlang.c (lang_for_each_statement_worker): Handle insert statement.
	(map_input_to_output_sections, print_statement): Likewise.
	(lang_size_sections_1, lang_do_assignments_1): Likewise.
	(insert_os_after): New function, extracted from..
	(lang_insert_orphan): ..here.
	(process_insert_statements): New function.
	(lang_process): Call it.
	(lang_add_insert): New function.
	* ldlang.h (lang_insert_statement_enum): New.
	(lang_insert_statement_type): New.
	(lang_statement_union_type): Add insert_statement.
	(lang_add_insert): Declare.

Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.205
diff -u -p -r1.205 ld.texinfo
--- ld/ld.texinfo	11 Jan 2008 09:11:17 -0000	1.205
+++ ld/ld.texinfo	25 Jan 2008 03:01:09 -0000
@@ -297,10 +297,11 @@ augments the main linker script used for
 linker script or the one specified by using @samp{-T}).  This feature
 permits the linker to link against a file which appears to be an object
 or an archive, but actually merely defines some symbol values, or uses
-@code{INPUT} or @code{GROUP} to load other objects.  Note that
-specifying a script in this way merely augments the main linker script;
-use the @samp{-T} option to replace the default linker script entirely.
-@xref{Scripts}.
+@code{INPUT} or @code{GROUP} to load other objects.  Specifying a
+script in this way merely augments the main linker script, with the
+extra commands placed after the main script; use the @samp{-T} option
+to replace the default linker script entirely, but note the effect of
+the @code{INSERT} command.  @xref{Scripts}.
 
 For options whose names are a single letter,
 option arguments must either follow the option letter without intervening
@@ -2903,6 +2904,35 @@ This command has the same effect as the 
 command-line option: to make @code{ld} omit the assignment of addresses
 to common symbols even for a non-relocatable output file.
 
+@item INSERT [ AFTER | BEFORE ] @var{output_section}
+@kindex INSERT
+@cindex insert user script into default script
+This command is typically used in a script specified by @samp{-T} to
+augment the default @code{SECTIONS} with, for example, overlays.  It
+inserts all prior linker script statements after (or before)
+@var{output_section}, and also causes @samp{-T} to not override the
+default linker script.  The exact insertion point is as for orphan
+sections.  @xref{Location Counter}.  The insertion happens after the
+linker has mapped input sections to output sections.  Prior to the
+insertion, since @samp{-T} scripts are parsed before the default
+linker script, statements in the @samp{-T} script occur before the
+default linker script statements in the internal linker representation
+of the script.  In particular, input section assignments will be made
+to @samp{-T} output sections before those in the default script.  Here
+is an example of how a @samp{-T} script using @code{INSERT} might look:
+
+@smallexample
+SECTIONS
+@{
+  OVERLAY :
+  @{
+    .ov1 @{ ov1*(.text) @}
+    .ov2 @{ ov2*(.text) @}
+  @}
+@}
+INSERT AFTER .text;
+@end smallexample
+
 @item NOCROSSREFS(@var{section} @var{section} @dots{})
 @kindex NOCROSSREFS(@var{sections})
 @cindex cross references
Index: ld/ldgram.y
===================================================================
RCS file: /cvs/src/src/ld/ldgram.y,v
retrieving revision 1.56
diff -u -p -r1.56 ldgram.y
--- ld/ldgram.y	6 Jul 2007 14:09:41 -0000	1.56
+++ ld/ldgram.y	24 Jan 2008 01:54:53 -0000
@@ -49,11 +49,6 @@
 static enum section_type sectype;
 static lang_memory_region_type *region;
 
-FILE *saved_script_handle = NULL;
-bfd_boolean force_make_executable = FALSE;
-
-bfd_boolean ldgram_in_script = FALSE;
-bfd_boolean ldgram_had_equals = FALSE;
 bfd_boolean ldgram_had_keep = FALSE;
 char *ldgram_vers_current_lang = NULL;
 
@@ -127,7 +122,8 @@ static int error_index;
 %token END
 %left <token> '('
 %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
-%token SECTIONS PHDRS DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
+%token SECTIONS PHDRS INSERT_K AFTER BEFORE
+%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
 %token SORT_BY_NAME SORT_BY_ALIGNMENT
 %token '{' '}'
 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
@@ -352,6 +348,10 @@ ifile_p1:
 		  lang_add_nocrossref ($3);
 		}
 	|	EXTERN '(' extern_name_list ')'
+	|	INSERT_K AFTER NAME
+		{ lang_add_insert ($3, 0); }
+	|	INSERT_K BEFORE NAME
+		{ lang_add_insert ($3, 1); }
 	;
 
 input_list:
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.126
diff -u -p -r1.126 ldmain.c
--- ld/ldmain.c	11 Jan 2008 09:11:17 -0000	1.126
+++ ld/ldmain.c	24 Jan 2008 01:54:58 -0000
@@ -60,6 +60,10 @@ extern void *sbrk ();
 
 /* EXPORTS */
 
+FILE *saved_script_handle = NULL;
+FILE *previous_script_handle = NULL;
+bfd_boolean force_make_executable = FALSE;
+
 char *default_target;
 const char *output_filename = "a.out";
 
Index: ld/ldmain.h
===================================================================
RCS file: /cvs/src/src/ld/ldmain.h,v
retrieving revision 1.13
diff -u -p -r1.13 ldmain.h
--- ld/ldmain.h	6 Jul 2007 14:09:41 -0000	1.13
+++ ld/ldmain.h	24 Jan 2008 01:54:58 -0000
@@ -26,6 +26,9 @@ extern char *program_name;
 extern const char *ld_sysroot;
 extern char *ld_canon_sysroot;
 extern int ld_canon_sysroot_len;
+extern FILE *saved_script_handle;
+extern FILE *previous_script_handle;
+extern bfd_boolean force_make_executable;
 extern bfd *output_bfd;
 extern char *default_target;
 extern bfd_boolean trace_files;
Index: ld/ldlex.l
===================================================================
RCS file: /cvs/src/src/ld/ldlex.l,v
retrieving revision 1.39
diff -u -p -r1.39 ldlex.l
--- ld/ldlex.l	6 Jul 2007 14:09:41 -0000	1.39
+++ ld/ldlex.l	24 Jan 2008 01:54:58 -0000
@@ -274,6 +274,9 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
 <BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION"	{ RTOKEN(FORCE_COMMON_ALLOCATION);}
 <BOTH,SCRIPT>"INHIBIT_COMMON_ALLOCATION" { RTOKEN(INHIBIT_COMMON_ALLOCATION);}
 <BOTH,SCRIPT>"SECTIONS"			{ RTOKEN(SECTIONS);}
+<BOTH,SCRIPT>"INSERT"			{ RTOKEN(INSERT_K);}
+<BOTH,SCRIPT>"AFTER"			{ RTOKEN(AFTER);}
+<BOTH,SCRIPT>"BEFORE"			{ RTOKEN(BEFORE);}
 <BOTH,SCRIPT>"FILL"			{ RTOKEN(FILL);}
 <BOTH,SCRIPT>"STARTUP"			{ RTOKEN(STARTUP);}
 <BOTH,SCRIPT>"OUTPUT_FORMAT"		{ RTOKEN(OUTPUT_FORMAT);}
Index: ld/lexsup.c
===================================================================
RCS file: /cvs/src/src/ld/lexsup.c,v
retrieving revision 1.102
diff -u -p -r1.102 lexsup.c
--- ld/lexsup.c	17 Aug 2007 13:23:08 -0000	1.102
+++ ld/lexsup.c	24 Jan 2008 01:54:59 -0000
@@ -1166,9 +1166,11 @@ parse_args (unsigned argc, char **argv)
 	  trace_files = TRUE;
 	  break;
 	case 'T':
+	  previous_script_handle = saved_script_handle;
 	  ldfile_open_command_file (optarg);
 	  parser_input = input_script;
 	  yyparse ();
+	  previous_script_handle = NULL;
 	  break;
 	case OPTION_DEFAULT_SCRIPT:
 	  command_line.default_script = optarg;
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.278
diff -u -p -r1.278 ldlang.c
--- ld/ldlang.c	16 Jan 2008 01:28:21 -0000	1.278
+++ ld/ldlang.c	24 Jan 2008 01:54:56 -0000
@@ -845,6 +845,7 @@ lang_for_each_statement_worker (void (*f
 	case lang_padding_statement_enum:
 	case lang_address_statement_enum:
 	case lang_fill_statement_enum:
+	case lang_insert_statement_enum:
 	  break;
 	default:
 	  FAIL ();
@@ -1451,6 +1452,73 @@ output_prev_sec_find (lang_output_sectio
   return NULL;
 }
 
+/* Look for a suitable place for a new output section statement.  The
+   idea is to skip over anything that might be inside a SECTIONS {}
+   statement in a script, before we find another output section
+   statement.  Assignments to "dot" before an output section statement
+   are assumed to belong to it.  An exception to this rule is made for
+   the first assignment to dot, otherwise we might put an orphan
+   before . = . + SIZEOF_HEADERS or similar assignments that set the
+   initial address.  */
+
+static lang_statement_union_type **
+insert_os_after (lang_output_section_statement_type *after)
+{
+  lang_statement_union_type **where;
+  lang_statement_union_type **assign = NULL;
+  bfd_boolean ignore_first;
+
+  ignore_first
+    = after == &lang_output_section_statement.head->output_section_statement;
+
+  for (where = &after->header.next;
+       *where != NULL;
+       where = &(*where)->header.next)
+    {
+      switch ((*where)->header.type)
+	{
+	case lang_assignment_statement_enum:
+	  if (assign == NULL)
+	    {
+	      lang_assignment_statement_type *ass;
+
+	      ass = &(*where)->assignment_statement;
+	      if (ass->exp->type.node_class != etree_assert
+		  && ass->exp->assign.dst[0] == '.'
+		  && ass->exp->assign.dst[1] == 0
+		  && !ignore_first)
+		assign = where;
+	    }
+	  ignore_first = FALSE;
+	  continue;
+	case lang_wild_statement_enum:
+	case lang_input_section_enum:
+	case lang_object_symbols_statement_enum:
+	case lang_fill_statement_enum:
+	case lang_data_statement_enum:
+	case lang_reloc_statement_enum:
+	case lang_padding_statement_enum:
+	case lang_constructors_statement_enum:
+	  assign = NULL;
+	  continue;
+	case lang_output_section_statement_enum:
+	  if (assign != NULL)
+	    where = assign;
+	  break;
+	case lang_input_statement_enum:
+	case lang_address_statement_enum:
+	case lang_target_statement_enum:
+	case lang_output_statement_enum:
+	case lang_group_statement_enum:
+	case lang_insert_statement_enum:
+	  continue;
+	}
+      break;
+    }
+
+  return where;
+}
+
 lang_output_section_statement_type *
 lang_insert_orphan (asection *s,
 		    const char *secname,
@@ -1606,64 +1674,7 @@ lang_insert_orphan (asection *s,
 
 	  if (place->stmt == NULL)
 	    {
-	      lang_statement_union_type **where;
-	      lang_statement_union_type **assign = NULL;
-	      bfd_boolean ignore_first;
-
-	      /* Look for a suitable place for the new statement list.
-		 The idea is to skip over anything that might be inside
-		 a SECTIONS {} statement in a script, before we find
-		 another output_section_statement.  Assignments to "dot"
-		 before an output section statement are assumed to
-		 belong to it.  An exception to this rule is made for
-		 the first assignment to dot, otherwise we might put an
-		 orphan before . = . + SIZEOF_HEADERS or similar
-		 assignments that set the initial address.  */
-
-	      ignore_first = after == (&lang_output_section_statement.head
-				       ->output_section_statement);
-	      for (where = &after->header.next;
-		   *where != NULL;
-		   where = &(*where)->header.next)
-		{
-		  switch ((*where)->header.type)
-		    {
-		    case lang_assignment_statement_enum:
-		      if (assign == NULL)
-			{
-			  lang_assignment_statement_type *ass;
-			  ass = &(*where)->assignment_statement;
-			  if (ass->exp->type.node_class != etree_assert
-			      && ass->exp->assign.dst[0] == '.'
-			      && ass->exp->assign.dst[1] == 0
-			      && !ignore_first)
-			    assign = where;
-			}
-		      ignore_first = FALSE;
-		      continue;
-		    case lang_wild_statement_enum:
-		    case lang_input_section_enum:
-		    case lang_object_symbols_statement_enum:
-		    case lang_fill_statement_enum:
-		    case lang_data_statement_enum:
-		    case lang_reloc_statement_enum:
-		    case lang_padding_statement_enum:
-		    case lang_constructors_statement_enum:
-		      assign = NULL;
-		      continue;
-		    case lang_output_section_statement_enum:
-		      if (assign != NULL)
-			where = assign;
-		      break;
-		    case lang_input_statement_enum:
-		    case lang_address_statement_enum:
-		    case lang_target_statement_enum:
-		    case lang_output_statement_enum:
-		    case lang_group_statement_enum:
-		      continue;
-		    }
-		  break;
-		}
+	      lang_statement_union_type **where = insert_os_after (after);
 
 	      *add.tail = *where;
 	      *where = add.head;
@@ -3312,6 +3323,154 @@ map_input_to_output_sections
 	      aos->addr_tree = s->address_statement.address;
 	    }
 	  break;
+	case lang_insert_statement_enum:
+	  break;
+	}
+    }
+}
+
+/* An insert statement snips out all the linker statements from the
+   start of the list and places them after the output section
+   statement specified by the insert.  This operation is complicated
+   by the fact that we keep a doubly linked list of output section
+   statements as well as the singly linked list of all statements.  */
+
+static void
+process_insert_statements (void)
+{
+  lang_statement_union_type **s;
+  lang_output_section_statement_type *first_os = NULL;
+  lang_output_section_statement_type *last_os = NULL;
+
+  /* "start of list" is actually the statement immediately after
+     the special abs_section output statement, so that it isn't
+     reordered.  */
+  s = &lang_output_section_statement.head;
+  while (*(s = &(*s)->header.next) != NULL)
+    {
+      if ((*s)->header.type == lang_output_section_statement_enum)
+	{
+	  /* Keep pointers to the first and last output section
+	     statement in the sequence we may be about to move.  */
+	  last_os = &(*s)->output_section_statement;
+	  if (first_os == NULL)
+	    first_os = last_os;
+	}
+      else if ((*s)->header.type == lang_insert_statement_enum)
+	{
+	  lang_insert_statement_type *i = &(*s)->insert_statement;
+	  lang_output_section_statement_type *where;
+	  lang_output_section_statement_type *os;
+	  lang_statement_union_type **ptr;
+	  lang_statement_union_type *first;
+
+	  where = lang_output_section_find (i->where);
+	  if (where != NULL && i->is_before)
+	    {
+	      do 
+		where = where->prev;
+	      while (where != NULL && where->constraint == -1);
+	    }
+	  if (where == NULL)
+	    {
+	      einfo (_("%X%P: %s not found for insert\n"), i->where);
+	      continue;
+	    }
+	  /* You can't insert into the list you are moving.  */
+	  for (os = first_os; os != NULL; os = os->next)
+	    if (os == where || os == last_os)
+	      break;
+	  if (os == where)
+	    {
+	      einfo (_("%X%P: %s not found for insert\n"), i->where);
+	      continue;
+	    }
+
+	  /* Deal with reordering the output section statement list.  */
+	  if (last_os != NULL)
+	    {
+	      asection *first_sec, *last_sec;
+
+	      /* Snip out the output sections we are moving.  */
+	      first_os->prev->next = last_os->next;
+	      if (last_os->next == NULL)
+		lang_output_section_statement.tail
+		  = (union lang_statement_union **) &first_os->prev->next;
+	      else
+		last_os->next->prev = first_os->prev;
+	      /* Add them in at the new position.  */
+	      last_os->next = where->next;
+	      if (where->next == NULL)
+		lang_output_section_statement.tail
+		  = (union lang_statement_union **) &last_os->next;
+	      else
+		where->next->prev = last_os;
+	      first_os->prev = where;
+	      where->next = first_os;
+
+	      /* Move the bfd sections in the same way.  */
+	      first_sec = NULL;
+	      last_sec = NULL;
+	      for (os = first_os; os != NULL; os = os->next)
+		{
+		  if (os->bfd_section != NULL
+		      && os->bfd_section->owner != NULL)
+		    {
+		      last_sec = os->bfd_section;
+		      if (first_sec == NULL)
+			first_sec = last_sec;
+		    }
+		  if (os == last_os)
+		    break;
+		}
+	      if (last_sec != NULL)
+		{
+		  asection *sec = where->bfd_section;
+		  if (sec == NULL)
+		    sec = output_prev_sec_find (where);
+
+		  /* The place we want to insert must come after the
+		     sections we are moving.  So if we find no
+		     section or if the section is the same as our
+		     last section, then no move is needed.  */
+		  if (sec != NULL && sec != last_sec)
+		    {
+		      /* Trim them off.  */
+		      if (first_sec->prev != NULL)
+			first_sec->prev->next = last_sec->next;
+		      else
+			output_bfd->sections = last_sec->next;
+		      if (last_sec->next != NULL)
+			last_sec->next->prev = first_sec->prev;
+		      else
+			output_bfd->section_last = first_sec->prev;
+		      /* Add back.  */
+		      last_sec->next = sec->next;
+		      if (sec->next != NULL)
+			sec->next->prev = last_sec;
+		      else
+			output_bfd->section_last = last_sec;
+		      first_sec->prev = sec;
+		      sec->next = first_sec;
+		    }
+		}
+
+	      first_os = NULL;
+	      last_os = NULL;
+	    }
+
+	  ptr = insert_os_after (where);
+	  /* Snip everything after the abs_section output statement we
+	     know is at the start of the list, up to and including
+	     the insert statement we are currently processing.  */
+	  first = lang_output_section_statement.head->header.next;
+	  lang_output_section_statement.head->header.next = (*s)->header.next;
+	  /* Add them back where they belong.  */
+	  *s = *ptr;
+	  if (*s == NULL)
+	    statement_list.tail = s;
+	  *ptr = first;
+	  s = &lang_output_section_statement.head;
 	}
     }
 }
@@ -3954,6 +4113,11 @@ print_statement (lang_statement_union_ty
     case lang_group_statement_enum:
       print_group (&s->group_statement, os);
       break;
+    case lang_insert_statement_enum:
+      minfo ("INSERT %s %s\n",
+	     s->insert_statement.is_before ? "BEFORE" : "AFTER",
+	     s->insert_statement.where);
+      break;
     }
 }
 
@@ -4734,13 +4898,16 @@ lang_size_sections_1
 				      fill, dot, relax, check_regions);
 	  break;
 
-	default:
-	  FAIL ();
+	case lang_insert_statement_enum:
 	  break;
 
 	  /* We can only get here when relaxing is turned on.  */
 	case lang_address_statement_enum:
 	  break;
+
+	default:
+	  FAIL ();
+	  break;
 	}
       prev = &s->header.next;
     }
@@ -4999,12 +5166,15 @@ lang_do_assignments_1 (lang_statement_un
 				       current_os, fill, dot);
 	  break;
 
-	default:
-	  FAIL ();
+	case lang_insert_statement_enum:
 	  break;
 
 	case lang_address_statement_enum:
 	  break;
+
+	default:
+	  FAIL ();
+	  break;
 	}
     }
   return dot;
@@ -5853,6 +6023,8 @@ lang_process (void)
      to the correct output sections.  */
   map_input_to_output_sections (statement_list.head, NULL, NULL);
 
+  process_insert_statements ();
+
   /* Find any sections not attached explicitly and handle them.  */
   lang_place_orphans ();
 
@@ -6269,6 +6441,17 @@ lang_add_output_format (const char *form
     }
 }
 
+void
+lang_add_insert (const char *where, int is_before)
+{
+  lang_insert_statement_type *new;
+
+  new = new_stat (lang_insert_statement, stat_ptr);
+  new->where = where;
+  new->is_before = is_before;
+  saved_script_handle = previous_script_handle;
+}
+
 /* Enter a group.  This creates a new lang_group_statement, and sets
    stat_ptr to build new statements within the group.  */
 
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.76
diff -u -p -r1.76 ldlang.h
--- ld/ldlang.h	16 Jan 2008 01:29:42 -0000	1.76
+++ ld/ldlang.h	24 Jan 2008 01:54:57 -0000
@@ -79,6 +79,7 @@ typedef struct lang_statement_header_str
     lang_output_statement_enum,
     lang_padding_statement_enum,
     lang_group_statement_enum,
+    lang_insert_statement_enum,
     lang_constructors_statement_enum
   } type;
 } lang_statement_header_type;
@@ -352,6 +353,13 @@ typedef struct
   lang_statement_list_type children;
 } lang_group_statement_type;
 
+typedef struct
+{
+  lang_statement_header_type header;
+  const char *where;
+  bfd_boolean is_before;
+} lang_insert_statement_type;
+
 typedef union lang_statement_union
 {
   lang_statement_header_type header;
@@ -370,6 +378,7 @@ typedef union lang_statement_union
   lang_fill_statement_type fill_statement;
   lang_padding_statement_type padding_statement;
   lang_group_statement_type group_statement;
+  lang_insert_statement_type insert_statement;
 } lang_statement_union_type;
 
 /* This structure holds information about a program header, from the
@@ -565,6 +574,8 @@ extern void lang_size_sections
   (bfd_boolean *, bfd_boolean);
 extern void one_lang_size_sections_pass
   (bfd_boolean *, bfd_boolean);
+extern void lang_add_insert
+  (const char *, int);
 extern void lang_enter_group
   (void);
 extern void lang_leave_group
Index: ld/testsuite/ld-spu/ovl.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-spu/ovl.d,v
retrieving revision 1.4
diff -u -p -r1.4 ovl.d
--- ld/testsuite/ld-spu/ovl.d	25 Sep 2007 08:27:39 -0000	1.4
+++ ld/testsuite/ld-spu/ovl.d	24 Jan 2008 01:55:03 -0000
@@ -1,5 +1,5 @@
 #source: ovl.s
-#ld: -N -T ovl.lnk --emit-relocs
+#ld: -N -T ovl1.lnk -T ovl.lnk --emit-relocs
 #objdump: -D -r
 
 .*elf32-spu
Index: ld/testsuite/ld-spu/ovl.lnk
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-spu/ovl.lnk,v
retrieving revision 1.2
diff -u -p -r1.2 ovl.lnk
--- ld/testsuite/ld-spu/ovl.lnk	18 Apr 2007 03:55:10 -0000	1.2
+++ ld/testsuite/ld-spu/ovl.lnk	24 Jan 2008 01:55:03 -0000
@@ -2,13 +2,6 @@ SECTIONS
 {
   . = SIZEOF_HEADERS;
   .text : { *(.text) *(.stub) }
-
-  OVERLAY 0x400 :
-  {
-    .ov_a1 { *(.ov_a1) }
-    .ov_a2 { *(.ov_a2) }
-  }
-
   .data : { *(.data) *(.ovtab) }
   .bss : { *(.bss) }
 }
Index: ld/testsuite/ld-spu/ovl2.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-spu/ovl2.d,v
retrieving revision 1.4
diff -u -p -r1.4 ovl2.d
--- ld/testsuite/ld-spu/ovl2.d	25 Sep 2007 08:27:39 -0000	1.4
+++ ld/testsuite/ld-spu/ovl2.d	24 Jan 2008 01:55:03 -0000
@@ -1,5 +1,5 @@
 #source: ovl2.s
-#ld: -N -T ovl.lnk --emit-relocs
+#ld: -N -T ovl2.lnk -T ovl.lnk --emit-relocs
 #objdump: -D -r
 
 .*elf32-spu
Index: ld/testsuite/ld-spu/ovl1.lnk
===================================================================
RCS file: ld/testsuite/ld-spu/ovl1.lnk
diff -N ld/testsuite/ld-spu/ovl1.lnk
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-spu/ovl1.lnk	24 Jan 2008 06:27:41 -0000
@@ -0,0 +1,9 @@
+SECTIONS
+{
+  OVERLAY 0x400 :
+  {
+    .ov_a1 { *(.ov_a1) }
+    .ov_a2 { *(.ov_a2) }
+  }
+}
+INSERT AFTER .text;
Index: ld/testsuite/ld-spu/ovl2.lnk
===================================================================
RCS file: ld/testsuite/ld-spu/ovl2.lnk
diff -N ld/testsuite/ld-spu/ovl2.lnk
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-spu/ovl2.lnk	24 Jan 2008 06:27:41 -0000
@@ -0,0 +1,10 @@
+SECTIONS
+{
+  OVERLAY 0x400 :
+  {
+    .ov_a1 { *(.ov_a1) }
+    .ov_a2 { *(.ov_a2) }
+    .empty { empty.o?(.text) }
+  }
+}
+INSERT BEFORE .data;

-- 
Alan Modra
Australia Development Lab, IBM


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