This is the mail archive of the binutils@sources.redhat.com 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]

Re: PATCH: Fix -Ttext and friends for ELF systems


Ian Lance Taylor wrote:

Mark Mitchell <mark@codesourcery.com> writes:



For a long time, -Ttext, -Tdata, and -Tbss have been useless (or
broken, depending on how you look at it) on ELF systems.  Rather than
setting the segment base address, these options set the address of a
particular section.  That tended to result in the linker putting that
section outside the relevant segment, without moving the rest of the
contents of the segment, and then issuing none-too-helpful errors
like:

Not enough room for program headers (allocated 3, need 4)



I do agree that the linker script has to cooperate. Suppose that,
rather than the simple mechanism of setting a symbol, you use the more
complex mechanism of adding a new expression to the linker script:
SEGMENT_START(NAME, DEFAULT). In your script, it might be used as
TEXT_START_ADDR='SEGMENT_START ("text", ${TEXT_START_ADDR})'


Here is a patch which implements your suggestion. In particular, for linker scripts which do not use SEGMENT_START, there will be no change in behavior.

Is this OK to commit?

--
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

2004-10-25  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (earmsymbian.c): Depend on armbpabi.sc, not elf.sc.
	* ldexp.h (segment_type): New type.
	(segments): New variable.
	* ldexp.c (segments): New variable.
	(exp_print_token): Handle SEGMENT_START.
	(fold_binary): Likewise.
	* ldgram.y (SEGMENT_START): Declare it as a token.
	(exp): Handle SEGMENT_START.
	* ldlang.h (lang_address_statement_type): Add segment field.
	(lang_section_start): Change prototype.
	* ldlang.c (map_input_to_output_sections): Do not process section
	assignments if a corresponding SEGMENT_START has already been
	seen.
	(lang_section_start): Add segment parameter.
	* ldlex.l (SEGMENT_START): Add it.
	* lexsup.c (seg_segment_start): New function.
	(parse_args): Use it for -Tbss, -Tdata, and -Ttext.
	* ld.texinfo (SEGMENT_START): Document it.
	* emulparams/armsymbian.sh (EMBEDDED): Set it.
	* scripttempl/armbpabi.sc: Use SEGMENT_START to control segment
	base addresses.  Do not map relocations.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/ld/Makefile.in,v
retrieving revision 1.173
diff -c -5 -p -r1.173 Makefile.in
*** Makefile.in	8 Oct 2004 00:22:13 -0000	1.173
--- Makefile.in	25 Oct 2004 19:29:12 -0000
*************** earm_epoc_pe.c: $(srcdir)/emulparams/arm
*** 1274,1284 ****
  earmpe.c: $(srcdir)/emulparams/armpe.sh \
    $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
  	${GENSCRIPTS} armpe "$(tdir_armpe)"
  earmsymbian.c: $(srcdir)/emulparams/armsymbian.sh \
    $(srcdir)/emulparams/armelf.sh $(srcdir)/emultempl/elf32.em \
!   $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc \
    ${GEN_DEPENDS}
  	${GENSCRIPTS} armsymbian "$(tdir_armelf)"
  eavr2.c: $(srcdir)/emulparams/avr2.sh \
    $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \
    ${GEN_DEPENDS}
--- 1274,1284 ----
  earmpe.c: $(srcdir)/emulparams/armpe.sh \
    $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
  	${GENSCRIPTS} armpe "$(tdir_armpe)"
  earmsymbian.c: $(srcdir)/emulparams/armsymbian.sh \
    $(srcdir)/emulparams/armelf.sh $(srcdir)/emultempl/elf32.em \
!   $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/armbpabi.sc \
    ${GEN_DEPENDS}
  	${GENSCRIPTS} armsymbian "$(tdir_armelf)"
  eavr2.c: $(srcdir)/emulparams/avr2.sh \
    $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \
    ${GEN_DEPENDS}
Index: ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.127
diff -c -5 -p -r1.127 ld.texinfo
*** ld.texinfo	16 Oct 2004 18:13:53 -0000	1.127
--- ld.texinfo	25 Oct 2004 19:29:12 -0000
*************** Returns the minimum of @var{exp1} and @v
*** 4673,4682 ****
--- 4673,4692 ----
  Return the next unallocated address that is a multiple of @var{exp}.
  This function is closely related to @code{ALIGN(@var{exp})}; unless you
  use the @code{MEMORY} command to define discontinuous memory for the
  output file, the two functions are equivalent.
  
+ @item SEGMENT_START(@var{segment}, @var{default})
+ @kindex SEGMENT_START(@var{segment}, @var{default})
+ Return the base address of the named @var{segment}.  If an explicit
+ value has been given for this segment (with a command-line @samp{-T}
+ option) that value will be returned; otherwise the value will be
+ @var{default}.  At present, the @samp{-T} command-line option can only
+ be used to set the base address for the ``text'', ``data'', and
+ ``bss'' sections, but you use @code{SEGMENT_START} with any segment
+ name.
+ 
  @item SIZEOF(@var{section})
  @kindex SIZEOF(@var{section})
  @cindex section size
  Return the size in bytes of the named @var{section}, if that section has
  been allocated.  If the section has not been allocated when this is
Index: ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.37
diff -c -5 -p -r1.37 ldexp.c
*** ldexp.c	15 Oct 2004 06:00:15 -0000	1.37
--- ldexp.c	25 Oct 2004 19:29:12 -0000
*************** static etree_value_type exp_fold_tree_no
*** 46,55 ****
--- 46,57 ----
  static bfd_vma align_n
    (bfd_vma, bfd_vma);
  
  struct exp_data_seg exp_data_seg;
  
+ segment_type *segments;
+ 
  /* Print the string representation of the given token.  Surround it
     with spaces if INFIX_P is TRUE.  */
  
  static void
  exp_print_token (token_code_type code, int infix_p)
*************** exp_print_token (token_code_type code, i
*** 100,110 ****
      { LOADADDR, "LOADADDR" },
      { MAX_K, "MAX_K" },
      { REL, "relocatable" },
      { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
      { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
!     { DATA_SEGMENT_END, "DATA_SEGMENT_END" }
    };
    unsigned int idx;
  
    for (idx = 0; idx < ARRAY_SIZE (table); idx++)
      if (table[idx].code == code)
--- 102,113 ----
      { LOADADDR, "LOADADDR" },
      { MAX_K, "MAX_K" },
      { REL, "relocatable" },
      { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
      { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
!     { DATA_SEGMENT_END, "DATA_SEGMENT_END" },
!     { SEGMENT_START, "SEGMENT_START" }
    };
    unsigned int idx;
  
    for (idx = 0; idx < ARRAY_SIZE (table); idx++)
      if (table[idx].code == code)
*************** fold_binary (etree_type *tree,
*** 303,313 ****
  {
    etree_value_type result;
  
    result = exp_fold_tree (tree->binary.lhs, current_section,
  			  allocation_done, dot, dotp);
!   if (result.valid_p)
      {
        etree_value_type other;
  
        other = exp_fold_tree (tree->binary.rhs,
  			     current_section,
--- 306,336 ----
  {
    etree_value_type result;
  
    result = exp_fold_tree (tree->binary.lhs, current_section,
  			  allocation_done, dot, dotp);
! 
!   /* The SEGMENT_START operator is special because its first
!      operand is a string, not the name of a symbol.  */
!   if (result.valid_p && tree->type.node_code == SEGMENT_START)
!     {
!       const char *segment_name;
!       segment_type *seg;
!       /* Check to see if the user has overridden the default
! 	 value.  */
!       segment_name = tree->binary.rhs->name.name;
!       for (seg = segments; seg; seg = seg->next) 
! 	if (strcmp (seg->name, segment_name) == 0)
! 	  {
! 	    seg->used = TRUE;
! 	    result.value = seg->value;
! 	    result.str = NULL;
! 	    result.section = NULL;
! 	    break;
! 	  }
!     }
!   else if (result.valid_p)
      {
        etree_value_type other;
  
        other = exp_fold_tree (tree->binary.rhs,
  			     current_section,
Index: ldexp.h
===================================================================
RCS file: /cvs/src/src/ld/ldexp.h,v
retrieving revision 1.12
diff -c -5 -p -r1.12 ldexp.h
*** ldexp.h	11 May 2004 17:08:34 -0000	1.12
--- ldexp.h	25 Oct 2004 19:29:12 -0000
*************** extern struct exp_data_seg {
*** 101,110 ****
--- 101,126 ----
      exp_dataseg_adjust
    } phase;
    bfd_vma base, relro_end, end, pagesize;
  } exp_data_seg;
  
+ /* A maps from a segment name to a base address.  */
+ typedef struct segment_struct {
+   /* The next segment in the linked list.  */
+   struct segment_struct *next;
+   /* The name of the sgement.  */
+   const char *name;
+   /* The base address for the segment.  */
+   bfd_vma value;
+   /* True if a SEGMENT_START directive corresponding to this segment
+      has been seen.  */
+   bfd_boolean used;
+ } segment_type;
+ 
+ /* The segments specified by the user on the command-line.  */
+ extern segment_type *segments;
+ 
  typedef struct _fill_type fill_type;
  
  etree_type *exp_intop
    (bfd_vma);
  etree_type *exp_bigintop
Index: ldgram.y
===================================================================
RCS file: /cvs/src/src/ld/ldgram.y,v
retrieving revision 1.36
diff -c -5 -p -r1.36 ldgram.y
*** ldgram.y	4 Oct 2004 16:45:50 -0000	1.36
--- ldgram.y	25 Oct 2004 19:29:12 -0000
*************** static int error_index;
*** 132,141 ****
--- 132,142 ----
  %token SORT_BY_NAME SORT_BY_ALIGNMENT
  %token '{' '}'
  %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
  %token INHIBIT_COMMON_ALLOCATION
  %token SIZEOF_HEADERS
+ %token SEGMENT_START
  %token INCLUDE
  %token MEMORY DEFSYMEND
  %token NOLOAD DSECT COPY INFO OVERLAY
  %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
  %token <integer> NEXT
*************** exp	:
*** 841,850 ****
--- 842,860 ----
  			{ $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); }
  	|	DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
  			{ $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
  	|	DATA_SEGMENT_END '(' exp ')'
  			{ $$ = exp_unop(DATA_SEGMENT_END, $3); }
+         |       SEGMENT_START '(' NAME ',' exp ')'
+                         { /* The operands to the expression node are
+ 			     placed in the opposite order from the way
+ 			     in which they appear in the script as
+ 			     that allows us to reuse more code in
+ 			     fold_binary.  */
+ 			  $$ = exp_binop (SEGMENT_START,
+ 					  $5,
+ 					  exp_nameop (NAME, $3)); }
  	|	BLOCK '(' exp ')'
  			{ $$ = exp_unop(ALIGN_K,$3); }
  	|	NAME
  			{ $$ = exp_nameop(NAME,$1); }
  	|	MAX_K '(' exp ',' exp ')'
Index: ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.167
diff -c -5 -p -r1.167 ldlang.c
*** ldlang.c	19 Oct 2004 15:44:58 -0000	1.167
--- ldlang.c	25 Oct 2004 19:29:12 -0000
*************** map_input_to_output_sections
*** 2650,2669 ****
  	  break;
  	case lang_afile_asection_pair_statement_enum:
  	  FAIL ();
  	  break;
  	case lang_address_statement_enum:
! 	  /* Mark the specified section with the supplied address.  */
! 	  {
! 	    lang_output_section_statement_type *aos
! 	      = (lang_output_section_statement_lookup
! 		 (s->address_statement.section_name));
! 
! 	    if (aos->bfd_section == NULL)
! 	      init_os (aos);
! 	    aos->addr_tree = s->address_statement.address;
! 	  }
  	  break;
  	}
      }
  }
  
--- 2650,2680 ----
  	  break;
  	case lang_afile_asection_pair_statement_enum:
  	  FAIL ();
  	  break;
  	case lang_address_statement_enum:
! 	  /* Mark the specified section with the supplied address.  
! 
! 	     If this section was actually a segment marker, then the
! 	     directive is ignored if the linker script explicitly
! 	     processed the segment marker.  Originally, the linker
! 	     treated segment directives (like -Ttext on the
! 	     command-line) as section directives.  We honor the
! 	     section directive semantics for backwards compatibilty;
! 	     linker scripts that do not specifically check for
! 	     SEGMENT_START automatically get the old semantics.  */
! 	  if (!s->address_statement.segment 
! 	      || !s->address_statement.segment->used)
! 	    {
! 	      lang_output_section_statement_type *aos
! 		= (lang_output_section_statement_lookup
! 		   (s->address_statement.section_name));
! 	      
! 	      if (aos->bfd_section == NULL)
! 		init_os (aos);
! 	      aos->addr_tree = s->address_statement.address;
! 	    }
  	  break;
  	}
      }
  }
  
*************** lang_add_wild (struct wildcard_spec *fil
*** 4969,4985 ****
    new->keep_sections = keep_sections;
    lang_list_init (&new->children);
  }
  
  void
! lang_section_start (const char *name, etree_type *address)
  {
    lang_address_statement_type *ad;
  
    ad = new_stat (lang_address_statement, stat_ptr);
    ad->section_name = name;
    ad->address = address;
  }
  
  /* Set the start symbol to NAME.  CMDLINE is nonzero if this is called
     because of a -e argument on the command line, or zero if this is
     called by ENTRY in a linker script.  Command line arguments take
--- 4980,4998 ----
    new->keep_sections = keep_sections;
    lang_list_init (&new->children);
  }
  
  void
! lang_section_start (const char *name, etree_type *address,
! 		    const segment_type *segment)
  {
    lang_address_statement_type *ad;
  
    ad = new_stat (lang_address_statement, stat_ptr);
    ad->section_name = name;
    ad->address = address;
+   ad->segment = segment;
  }
  
  /* Set the start symbol to NAME.  CMDLINE is nonzero if this is called
     because of a -e argument on the command line, or zero if this is
     called by ENTRY in a linker script.  Command line arguments take
Index: ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.41
diff -c -5 -p -r1.41 ldlang.h
*** ldlang.h	16 Oct 2004 18:13:53 -0000	1.41
--- ldlang.h	25 Oct 2004 19:29:12 -0000
*************** typedef struct lang_wild_statement_struc
*** 314,323 ****
--- 314,324 ----
  typedef struct lang_address_statement_struct
  {
    lang_statement_header_type header;
    const char *section_name;
    union etree_union *address;
+   const segment_type *segment;
  } lang_address_statement_type;
  
  typedef struct
  {
    lang_statement_header_type header;
*************** extern lang_output_section_statement_typ
*** 459,469 ****
  extern void lang_final
    (void);
  extern void lang_process
    (void);
  extern void lang_section_start
!   (const char *, union etree_union *);
  extern void lang_add_entry
    (const char *, bfd_boolean);
  extern void lang_add_target
    (const char *);
  extern void lang_add_wild
--- 460,470 ----
  extern void lang_final
    (void);
  extern void lang_process
    (void);
  extern void lang_section_start
!   (const char *, union etree_union *, const segment_type *);
  extern void lang_add_entry
    (const char *, bfd_boolean);
  extern void lang_add_target
    (const char *);
  extern void lang_add_wild
Index: ldlex.l
===================================================================
RCS file: /cvs/src/src/ld/ldlex.l,v
retrieving revision 1.26
diff -c -5 -p -r1.26 ldlex.l
*** ldlex.l	4 Oct 2004 16:45:51 -0000	1.26
--- ldlex.l	25 Oct 2004 19:29:12 -0000
*************** V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
*** 258,268 ****
  <EXPRESSION,BOTH>"ASSERT"		{ RTOKEN(ASSERT_K); }
  <BOTH,SCRIPT>"ENTRY"			{ RTOKEN(ENTRY);}
  <BOTH,SCRIPT,MRI>"EXTERN"		{ RTOKEN(EXTERN);}
  <EXPRESSION,BOTH,SCRIPT>"NEXT"			{ RTOKEN(NEXT);}
  <EXPRESSION,BOTH,SCRIPT>"sizeof_headers"	{ RTOKEN(SIZEOF_HEADERS);}
! <EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS"	{ RTOKEN(SIZEOF_HEADERS);}
  <BOTH,SCRIPT>"MAP"			{ RTOKEN(MAP);}
  <EXPRESSION,BOTH,SCRIPT>"SIZEOF"		{ RTOKEN(SIZEOF);}
  <BOTH,SCRIPT>"TARGET"		{ RTOKEN(TARGET_K);}
  <BOTH,SCRIPT>"SEARCH_DIR"		{ RTOKEN(SEARCH_DIR);}
  <BOTH,SCRIPT>"OUTPUT"		{ RTOKEN(OUTPUT);}
--- 258,270 ----
  <EXPRESSION,BOTH>"ASSERT"		{ RTOKEN(ASSERT_K); }
  <BOTH,SCRIPT>"ENTRY"			{ RTOKEN(ENTRY);}
  <BOTH,SCRIPT,MRI>"EXTERN"		{ RTOKEN(EXTERN);}
  <EXPRESSION,BOTH,SCRIPT>"NEXT"			{ RTOKEN(NEXT);}
  <EXPRESSION,BOTH,SCRIPT>"sizeof_headers"	{ RTOKEN(SIZEOF_HEADERS);}
! <EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS"	{
! RTOKEN(SIZEOF_HEADERS);}
! <EXPRESSION,BOTH,SCRIPT>"SEGMENT_START" { RTOKEN(SEGMENT_START);}
  <BOTH,SCRIPT>"MAP"			{ RTOKEN(MAP);}
  <EXPRESSION,BOTH,SCRIPT>"SIZEOF"		{ RTOKEN(SIZEOF);}
  <BOTH,SCRIPT>"TARGET"		{ RTOKEN(TARGET_K);}
  <BOTH,SCRIPT>"SEARCH_DIR"		{ RTOKEN(SEARCH_DIR);}
  <BOTH,SCRIPT>"OUTPUT"		{ RTOKEN(OUTPUT);}
Index: lexsup.c
===================================================================
RCS file: /cvs/src/src/ld/lexsup.c,v
retrieving revision 1.78
diff -c -5 -p -r1.78 lexsup.c
*** lexsup.c	7 Oct 2004 14:45:22 -0000	1.78
--- lexsup.c	25 Oct 2004 19:29:12 -0000
***************
*** 53,62 ****
--- 53,63 ----
  #define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
  #endif
  
  static void set_default_dirlist (char *);
  static void set_section_start (char *, char *);
+ static void set_segment_start (const char *, char *);
  static void help (void);
  
  /* Non-zero if we are processing a --defsym from the command line.  */
  int parsing_defsym = 0;
  
*************** parse_args (unsigned argc, char **argv)
*** 1130,1146 ****
  	case OPTION_TARGET_HELP:
  	  /* Mention any target specific options.  */
  	  ldemul_list_emulation_options (stdout);
  	  exit (0);
  	case OPTION_TBSS:
! 	  set_section_start (".bss", optarg);
  	  break;
  	case OPTION_TDATA:
! 	  set_section_start (".data", optarg);
  	  break;
  	case OPTION_TTEXT:
! 	  set_section_start (".text", optarg);
  	  break;
  	case OPTION_TRADITIONAL_FORMAT:
  	  link_info.traditional_format = TRUE;
  	  break;
  	case OPTION_TASK_LINK:
--- 1131,1147 ----
  	case OPTION_TARGET_HELP:
  	  /* Mention any target specific options.  */
  	  ldemul_list_emulation_options (stdout);
  	  exit (0);
  	case OPTION_TBSS:
! 	  set_segment_start (".bss", optarg);
  	  break;
  	case OPTION_TDATA:
! 	  set_segment_start (".data", optarg);
  	  break;
  	case OPTION_TTEXT:
! 	  set_segment_start (".text", optarg);
  	  break;
  	case OPTION_TRADITIONAL_FORMAT:
  	  link_info.traditional_format = TRUE;
  	  break;
  	case OPTION_TASK_LINK:
*************** set_section_start (char *sect, char *val
*** 1372,1383 ****
  {
    const char *end;
    bfd_vma val = bfd_scan_vma (valstr, &end, 16);
    if (*end)
      einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
!   lang_section_start (sect, exp_intop (val));
  }
  
  /* Print help messages for the options.  */
  
  static void
  help (void)
--- 1373,1420 ----
  {
    const char *end;
    bfd_vma val = bfd_scan_vma (valstr, &end, 16);
    if (*end)
      einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
!   lang_section_start (sect, exp_intop (val), NULL);
  }
+ 
+ static void
+ set_segment_start (const char *section, char *valstr)
+ {
+   const char *name;
+   const char *end;
+   segment_type *seg;
+ 
+   bfd_vma val = bfd_scan_vma (valstr, &end, 16);
+   if (*end)
+     einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
+   /* If we already have an entry for this segment, update the existing
+      value.  */
+   name = section + 1;
+   for (seg = segments; seg; seg = seg->next)
+     if (strcmp (seg->name, name) == 0)
+       {
+ 	seg->value = val;
+ 	return;
+       }
+   /* There was no existing value so we must create a new segment
+      entry.  */
+   seg = stat_alloc (sizeof (*seg));
+   seg->name = name;
+   seg->value = val;
+   seg->used = FALSE;
+   /* Add it to the linked list of segments.  */
+   seg->next = segments;
+   segments = seg;
+   /* Historically, -Ttext and friends set the base address of a
+      particular section.  For backwards compatibility, we still do
+      that.  If a SEGMENT_START directive is seen, the section address
+      assignment will be disabled.  */
+   lang_section_start (section, exp_intop (val), seg);
+ }
+ 
  
  /* Print help messages for the options.  */
  
  static void
  help (void)
Index: emulparams/armsymbian.sh
===================================================================
RCS file: /cvs/src/src/ld/emulparams/armsymbian.sh,v
retrieving revision 1.4
diff -c -5 -p -r1.4 armsymbian.sh
*** emulparams/armsymbian.sh	30 Sep 2004 17:03:51 -0000	1.4
--- emulparams/armsymbian.sh	25 Oct 2004 19:29:12 -0000
*************** GENERATE_COMBRELOC_SCRIPT=1
*** 4,13 ****
--- 4,15 ----
  OUTPUT_FORMAT="elf32-littlearm-symbian"
  BIG_OUTPUT_FORMAT="elf32-bigarm-symbian"
  LITTLE_OUTPUT_FORMAT="$OUTPUT_FORMAT"
  TARGET1_IS_REL=1
  TARGET2_TYPE=abs
+ # On BPABI systems, program headers should not be mapped.
+ EMBEDDED=yes
  
  # This value should match ELF_MAXPAGESIZE in BFD.  Otherwise, elf.c
  # will not place read-write sections in a separate ELF segment from
  # the read-only sections.
  MAXPAGESIZE=0x8000
Index: scripttempl/armbpabi.sc
===================================================================
RCS file: /cvs/src/src/ld/scripttempl/armbpabi.sc,v
retrieving revision 1.2
diff -c -5 -p -r1.2 armbpabi.sc
*** scripttempl/armbpabi.sc	13 Oct 2004 17:45:31 -0000	1.2
--- scripttempl/armbpabi.sc	25 Oct 2004 19:29:19 -0000
***************
*** 1,80 ****
  # This variant of elf.sc is used for ARM BPABI platforms, like Symbian
  # OS, where a separate postlinker will operated on the generated
! # executable or shared object.
! 
! #
! # Unusual variables checked by this code:
! #	NOP - four byte opcode for no-op (defaults to 0)
! #	NO_SMALL_DATA - no .sbss/.sbss2/.sdata/.sdata2 sections if not
! #		empty.
! #	DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
! #	INITIAL_READONLY_SECTIONS - at start of text segment
! #	OTHER_READONLY_SECTIONS - other than .text .init .rodata ...
! #		(e.g., .PARISC.milli)
! #	OTHER_TEXT_SECTIONS - these get put in .text when relocating
! #	OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
! #		(e.g., .PARISC.global)
! #	OTHER_RELRO_SECTIONS - other than .data.rel.ro ...
! #		(e.g. PPC32 .fixup, .got[12])
! #	OTHER_BSS_SECTIONS - other than .bss .sbss ...
! #	OTHER_SECTIONS - at the end
! #	EXECUTABLE_SYMBOLS - symbols that must be defined for an
! #		executable (e.g., _DYNAMIC_LINK)
! #	TEXT_START_SYMBOLS - symbols that appear at the start of the
! #		.text section.
! #	DATA_START_SYMBOLS - symbols that appear at the start of the
! #		.data section.
! #	OTHER_SDATA_SECTIONS - sections just after .sdata.
! #	OTHER_BSS_SYMBOLS - symbols that appear at the start of the
! #		.bss section besides __bss_start.
! #	DATA_PLT - .plt should be in data segment, not text segment.
! #	PLT_BEFORE_GOT - .plt just before .got when .plt is in data segement.
! #	BSS_PLT - .plt should be in bss segment
! #	TEXT_DYNAMIC - .dynamic in text segment, not data segment.
! #	EMBEDDED - whether this is for an embedded system. 
! #	SHLIB_TEXT_START_ADDR - if set, add to SIZEOF_HEADERS to set
! #		start address of shared library.
! #	INPUT_FILES - INPUT command of files to always include
! #	WRITABLE_RODATA - if set, the .rodata section should be writable
! #	INIT_START, INIT_END -  statements just before and just after
! # 	combination of .init sections.
! #	FINI_START, FINI_END - statements just before and just after
! # 	combination of .fini sections.
! #	STACK_ADDR - start of a .stack section.
! #	OTHER_END_SYMBOLS - symbols to place right at the end of the script.
! #	SEPARATE_GOTPLT - if set, .got.plt should be separate output section,
! #		so that .got can be in the RELRO area.  It should be set to
! #		the number of bytes in the beginning of .got.plt which can be
! #		in the RELRO area as well.
! #
! # When adding sections, do note that the names of some sections are used
! # when specifying the start address of the next.
! #
! 
! #  Many sections come in three flavours.  There is the 'real' section,
! #  like ".data".  Then there are the per-procedure or per-variable
! #  sections, generated by -ffunction-sections and -fdata-sections in GCC,
! #  and useful for --gc-sections, which for a variable "foo" might be
! #  ".data.foo".  Then there are the linkonce sections, for which the linker
! #  eliminates duplicates, which are named like ".gnu.linkonce.d.foo".
! #  The exact correspondences are:
! #
! #  Section	Linkonce section
! #  .text	.gnu.linkonce.t.foo
! #  .rodata	.gnu.linkonce.r.foo
! #  .data	.gnu.linkonce.d.foo
! #  .bss		.gnu.linkonce.b.foo
! #  .sdata	.gnu.linkonce.s.foo
! #  .sbss	.gnu.linkonce.sb.foo
! #  .sdata2	.gnu.linkonce.s2.foo
! #  .sbss2	.gnu.linkonce.sb2.foo
! #  .debug_info	.gnu.linkonce.wi.foo
! #  .tdata	.gnu.linkonce.td.foo
! #  .tbss	.gnu.linkonce.tb.foo
! #
! #  Each of these can also have corresponding .rel.* and .rela.* sections.
  
  test -z "$ENTRY" && ENTRY=_start
  test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
  test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
  if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi
--- 1,9 ----
  # This variant of elf.sc is used for ARM BPABI platforms, like Symbian
  # OS, where a separate postlinker will operated on the generated
! # executable or shared object.  See elf.sc for configuration variables
! # that apply; only BPABI-specific variables will be noted here.
  
  test -z "$ENTRY" && ENTRY=_start
  test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
  test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
  if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi
*************** STACK="  .stack        ${RELOCATING-0}${
*** 173,187 ****
--- 102,123 ----
    {
      ${RELOCATING+_stack = .;}
      *(.stack)
    }"
  
+ TEXT_START_ADDR="SEGMENT_START(\"text\", ${TEXT_START_ADDR})"
+ SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text\", ${SHLIB_TEXT_START_ADDR:-0})"
+ DATA_ADDR="SEGMENT_START(\"data\", ${DATA_ADDR-${DATA_SEGMENT_ALIGN}})"
+ SHLIB_DATA_ADDR="SEGMENT_START(\"data\", ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}})"
+ 
  # if this is for an embedded system, don't add SIZEOF_HEADERS.
  if [ -z "$EMBEDDED" ]; then
     test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR} + SIZEOF_HEADERS"
+    SHLIB_BASE_ADDRESS="${SHLIB_TEXT_START_ADDR} + SIZEOF_HEADERS"
  else
     test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}"
+    SHLIB_BASE_ADDRESS="${SHLIB_TEXT_START_ADDR}"
  fi
  
  cat <<EOF
  OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
  	      "${LITTLE_OUTPUT_FORMAT}")
*************** ${RELOCATING- /* For some reason, the So
*** 200,269 ****
  
  SECTIONS
  {
    /* Read-only sections, merged into text segment: */
    ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+PROVIDE (__executable_start = ${TEXT_START_ADDR}); . = ${TEXT_BASE_ADDRESS};}}}
!   ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}}
!   ${CREATE_PIE+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}}
    ${INITIAL_READONLY_SECTIONS}
  
  EOF
- if [ "x$COMBRELOC" = x ]; then
-   COMBRELOCCAT=cat
- else
-   COMBRELOCCAT="cat > $COMBRELOC"
- fi
- eval $COMBRELOCCAT <<EOF
-   .rel.init     ${RELOCATING-0} : { *(.rel.init) }
-   .rela.init    ${RELOCATING-0} : { *(.rela.init) }
-   .rel.text     ${RELOCATING-0} : { *(.rel.text${RELOCATING+ .rel.text.* .rel.gnu.linkonce.t.*}) }
-   .rela.text    ${RELOCATING-0} : { *(.rela.text${RELOCATING+ .rela.text.* .rela.gnu.linkonce.t.*}) }
-   .rel.fini     ${RELOCATING-0} : { *(.rel.fini) }
-   .rela.fini    ${RELOCATING-0} : { *(.rela.fini) }
-   .rel.rodata   ${RELOCATING-0} : { *(.rel.rodata${RELOCATING+ .rel.rodata.* .rel.gnu.linkonce.r.*}) }
-   .rela.rodata  ${RELOCATING-0} : { *(.rela.rodata${RELOCATING+ .rela.rodata.* .rela.gnu.linkonce.r.*}) }
-   ${OTHER_READONLY_RELOC_SECTIONS}
-   .rel.data.rel.ro ${RELOCATING-0} : { *(.rel.data.rel.ro${RELOCATING+*}) }
-   .rela.data.rel.ro ${RELOCATING-0} : { *(.rel.data.rel.ro${RELOCATING+*}) }
-   .rel.data     ${RELOCATING-0} : { *(.rel.data${RELOCATING+ .rel.data.* .rel.gnu.linkonce.d.*}) }
-   .rela.data    ${RELOCATING-0} : { *(.rela.data${RELOCATING+ .rela.data.* .rela.gnu.linkonce.d.*}) }
-   .rel.tdata	${RELOCATING-0} : { *(.rel.tdata${RELOCATING+ .rel.tdata.* .rel.gnu.linkonce.td.*}) }
-   .rela.tdata	${RELOCATING-0} : { *(.rela.tdata${RELOCATING+ .rela.tdata.* .rela.gnu.linkonce.td.*}) }
-   .rel.tbss	${RELOCATING-0} : { *(.rel.tbss${RELOCATING+ .rel.tbss.* .rel.gnu.linkonce.tb.*}) }
-   .rela.tbss	${RELOCATING-0} : { *(.rela.tbss${RELOCATING+ .rela.tbss.* .rela.gnu.linkonce.tb.*}) }
-   .rel.ctors    ${RELOCATING-0} : { *(.rel.ctors) }
-   .rela.ctors   ${RELOCATING-0} : { *(.rela.ctors) }
-   .rel.dtors    ${RELOCATING-0} : { *(.rel.dtors) }
-   .rela.dtors   ${RELOCATING-0} : { *(.rela.dtors) }
-   ${REL_SDATA}
-   ${REL_SBSS}
-   ${REL_SDATA2}
-   ${REL_SBSS2}
-   .rel.bss      ${RELOCATING-0} : { *(.rel.bss${RELOCATING+ .rel.bss.* .rel.gnu.linkonce.b.*}) }
-   .rela.bss     ${RELOCATING-0} : { *(.rela.bss${RELOCATING+ .rela.bss.* .rela.gnu.linkonce.b.*}) }
- EOF
- if [ -n "$COMBRELOC" ]; then
- cat <<EOF
-   .rel.dyn      ${RELOCATING-0} :
-     {
- EOF
- sed -e '/^[ 	]*[{}][ 	]*$/d;/:[ 	]*$/d;/\.rela\./d;s/^.*: { *\(.*\)}$/      \1/' $COMBRELOC
  cat <<EOF
-     }
-   .rela.dyn     ${RELOCATING-0} :
-     {
- EOF
- sed -e '/^[ 	]*[{}][ 	]*$/d;/:[ 	]*$/d;/\.rel\./d;s/^.*: { *\(.*\)}/      \1/' $COMBRELOC
- cat <<EOF
-     }
- EOF
- fi
- cat <<EOF
-   .rel.plt      ${RELOCATING-0} : { *(.rel.plt) }
-   .rela.plt     ${RELOCATING-0} : { *(.rela.plt) }
-   ${OTHER_PLT_RELOC_SECTIONS}
- 
    .init         ${RELOCATING-0} : 
    { 
      ${RELOCATING+${INIT_START}}
      KEEP (*(.init))
      ${RELOCATING+${INIT_END}}
--- 136,151 ----
  
  SECTIONS
  {
    /* Read-only sections, merged into text segment: */
    ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+PROVIDE (__executable_start = ${TEXT_START_ADDR}); . = ${TEXT_BASE_ADDRESS};}}}
!   ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_BASE_ADDRESS};}}
!   ${CREATE_PIE+${RELOCATING+. = ${SHLIB_BASE_ADDRESS};}}
    ${INITIAL_READONLY_SECTIONS}
  
  EOF
  cat <<EOF
    .init         ${RELOCATING-0} : 
    { 
      ${RELOCATING+${INIT_START}}
      KEEP (*(.init))
      ${RELOCATING+${INIT_END}}
*************** cat <<EOF
*** 297,309 ****
    .eh_frame     ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.eh_frame)) }
    .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
  
    /* Adjust the address for the data segment.  We want to adjust up to
       the same address within the page on the next page up.  */
!   ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}}
!   ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
!   ${CREATE_PIE+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
  
    /* Exception handling  */
    .eh_frame     ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.eh_frame)) }
    .gcc_except_table ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
  
--- 179,191 ----
    .eh_frame     ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.eh_frame)) }
    .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
  
    /* Adjust the address for the data segment.  We want to adjust up to
       the same address within the page on the next page up.  */
!   ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${DATA_ADDR};}}}
!   ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR};}}
!   ${CREATE_PIE+${RELOCATING+. = ${SHLIB_DATA_ADDR};}}
  
    /* Exception handling  */
    .eh_frame     ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.eh_frame)) }
    .gcc_except_table ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
  
*************** cat <<EOF
*** 353,362 ****
--- 235,245 ----
    ${CREATE_SHLIB+${SBSS2}}
    ${SDATA}
    ${OTHER_SDATA_SECTIONS}
    ${RELOCATING+_edata = .;}
    ${RELOCATING+PROVIDE (edata = .);}
+   ${RELOCATING+. = DEFINED(__bss_segment_start) ? __bss_segment_start : .;}
    ${RELOCATING+__bss_start = .;}
    ${RELOCATING+${OTHER_BSS_SYMBOLS}}
    ${SBSS}
    ${BSS_PLT+${PLT}}
    .bss          ${RELOCATING-0} :
*************** cat <<EOF
*** 429,435 ****
--- 312,376 ----
  
    ${STACK_ADDR+${STACK}}
    ${OTHER_SECTIONS}
    ${RELOCATING+${OTHER_END_SYMBOLS}}
    ${RELOCATING+${STACKNOTE}}
+ EOF
+ 
+ # These relocations sections are part of the read-only segment in SVR4
+ # executables, but are not mapped in BPABI executables.
+ if [ "x$COMBRELOC" = x ]; then
+   COMBRELOCCAT=cat
+ else
+   COMBRELOCCAT="cat > $COMBRELOC"
+ fi
+ eval $COMBRELOCCAT <<EOF
+   .rel.init     0 : { *(.rel.init) }
+   .rela.init    0 : { *(.rela.init) }
+   .rel.text     0 : { *(.rel.text${RELOCATING+ .rel.text.* .rel.gnu.linkonce.t.*}) }
+   .rela.text    0 : { *(.rela.text${RELOCATING+ .rela.text.* .rela.gnu.linkonce.t.*}) }
+   .rel.fini     0 : { *(.rel.fini) }
+   .rela.fini    0 : { *(.rela.fini) }
+   .rel.rodata   0 : { *(.rel.rodata${RELOCATING+ .rel.rodata.* .rel.gnu.linkonce.r.*}) }
+   .rela.rodata  0 : { *(.rela.rodata${RELOCATING+ .rela.rodata.* .rela.gnu.linkonce.r.*}) }
+   ${OTHER_READONLY_RELOC_SECTIONS}
+   .rel.data.rel.ro 0 : { *(.rel.data.rel.ro${RELOCATING+*}) }
+   .rela.data.rel.ro 0 : { *(.rel.data.rel.ro${RELOCATING+*}) }
+   .rel.data     0 : { *(.rel.data${RELOCATING+ .rel.data.* .rel.gnu.linkonce.d.*}) }
+   .rela.data    0 : { *(.rela.data${RELOCATING+ .rela.data.* .rela.gnu.linkonce.d.*}) }
+   .rel.tdata	0 : { *(.rel.tdata${RELOCATING+ .rel.tdata.* .rel.gnu.linkonce.td.*}) }
+   .rela.tdata	0 : { *(.rela.tdata${RELOCATING+ .rela.tdata.* .rela.gnu.linkonce.td.*}) }
+   .rel.tbss	0 : { *(.rel.tbss${RELOCATING+ .rel.tbss.* .rel.gnu.linkonce.tb.*}) }
+   .rela.tbss	0 : { *(.rela.tbss${RELOCATING+ .rela.tbss.* .rela.gnu.linkonce.tb.*}) }
+   .rel.ctors    0 : { *(.rel.ctors) }
+   .rela.ctors   0 : { *(.rela.ctors) }
+   .rel.dtors    0 : { *(.rel.dtors) }
+   .rela.dtors   0 : { *(.rela.dtors) }
+   ${REL_SDATA}
+   ${REL_SBSS}
+   ${REL_SDATA2}
+   ${REL_SBSS2}
+   .rel.bss      0 : { *(.rel.bss${RELOCATING+ .rel.bss.* .rel.gnu.linkonce.b.*}) }
+   .rela.bss     0 : { *(.rela.bss${RELOCATING+ .rela.bss.* .rela.gnu.linkonce.b.*}) }
+ EOF
+ if [ -n "$COMBRELOC" ]; then
+ cat <<EOF
+   .rel.dyn      0 :
+     {
+ EOF
+ sed -e '/^[ 	]*[{}][ 	]*$/d;/:[ 	]*$/d;/\.rela\./d;s/^.*: { *\(.*\)}$/      \1/' $COMBRELOC
+ cat <<EOF
+     }
+   .rela.dyn     0 :
+     {
+ EOF
+ sed -e '/^[ 	]*[{}][ 	]*$/d;/:[ 	]*$/d;/\.rel\./d;s/^.*: { *\(.*\)}/      \1/' $COMBRELOC
+ cat <<EOF
+     }
+ EOF
+ fi
+ cat <<EOF
+   .rel.plt      0 : { *(.rel.plt) }
+   .rela.plt     0 : { *(.rela.plt) }
+   ${OTHER_PLT_RELOC_SECTIONS}
  }
  EOF
Index: scripttempl/elf.sc
===================================================================
RCS file: /cvs/src/src/ld/scripttempl/elf.sc,v
retrieving revision 1.49
diff -c -5 -p -r1.49 elf.sc
*** scripttempl/elf.sc	14 Oct 2004 17:00:16 -0000	1.49
--- scripttempl/elf.sc	25 Oct 2004 19:29:19 -0000
***************
*** 16,25 ****
--- 16,28 ----
  #		(e.g. PPC32 .fixup, .got[12])
  #	OTHER_BSS_SECTIONS - other than .bss .sbss ...
  #	OTHER_SECTIONS - at the end
  #	EXECUTABLE_SYMBOLS - symbols that must be defined for an
  #		executable (e.g., _DYNAMIC_LINK)
+ #       TEXT_START_ADDR - the first byte of the text segment, after any
+ #               headers.
+ #       TEXT_BASE_ADDRESS - the first byte of the text segment.
  #	TEXT_START_SYMBOLS - symbols that appear at the start of the
  #		.text section.
  #	DATA_START_SYMBOLS - symbols that appear at the start of the
  #		.data section.
  #	OTHER_GOT_SYMBOLS - symbols defined just before .got.

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