* Makefile.in (earmsymbian.c): Depend on armbpabi.sc, not elf.sc.
authorMark Mitchell <mark@codesourcery.com>
Tue, 26 Oct 2004 18:41:52 +0000 (18:41 +0000)
committerMark Mitchell <mark@codesourcery.com>
Tue, 26 Oct 2004 18:41:52 +0000 (18:41 +0000)
* 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.
* NEWS: Mention SEGMENT_START.

14 files changed:
ld/ChangeLog
ld/Makefile.in
ld/NEWS
ld/emulparams/armsymbian.sh
ld/ld.texinfo
ld/ldexp.c
ld/ldexp.h
ld/ldgram.y
ld/ldlang.c
ld/ldlang.h
ld/ldlex.l
ld/lexsup.c
ld/scripttempl/armbpabi.sc
ld/scripttempl/elf.sc

index 8641359..757860d 100644 (file)
@@ -1,3 +1,28 @@
+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.
+       * NEWS: Mention SEGMENT_START.
+
 2004-10-26  Paul Brook  <paul@codesourcery.com>
 
        * ld.texinfo: Document --default-symver.
index 10a3c9f..9997034 100644 (file)
@@ -1276,7 +1276,7 @@ earmpe.c: $(srcdir)/emulparams/armpe.sh \
        ${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 \
+  $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/armbpabi.sc \
   ${GEN_DEPENDS}
        ${GENSCRIPTS} armsymbian "$(tdir_armelf)"
 eavr2.c: $(srcdir)/emulparams/avr2.sh \
diff --git a/ld/NEWS b/ld/NEWS
index 403b823..03bd4f6 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Added SEGMENT_START to the linker script language to permit the user to
+  override the base address for a segment from the command-line.
+
 * ELF: --warn-shared-textrel option to warn if adding a DT_TEXTREL to a shared
   object.
 
index 6fd1d15..a5c3eb5 100644 (file)
@@ -6,6 +6,8 @@ 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
index 5944f44..597c705 100644 (file)
@@ -4680,6 +4680,16 @@ 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
index 57968a2..103b615 100644 (file)
@@ -48,6 +48,8 @@ static bfd_vma align_n
 
 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.  */
 
@@ -102,7 +104,8 @@ exp_print_token (token_code_type code, int infix_p)
     { REL, "relocatable" },
     { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
     { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
-    { DATA_SEGMENT_END, "DATA_SEGMENT_END" }
+    { DATA_SEGMENT_END, "DATA_SEGMENT_END" },
+    { SEGMENT_START, "SEGMENT_START" }
   };
   unsigned int idx;
 
@@ -305,7 +308,27 @@ fold_binary (etree_type *tree,
 
   result = exp_fold_tree (tree->binary.lhs, current_section,
                          allocation_done, dot, dotp);
-  if (result.valid_p)
+
+  /* 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;
 
index a90f1ef..addf834 100644 (file)
@@ -103,6 +103,22 @@ extern struct exp_data_seg {
   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
index bdfdcd5..13e4ca6 100644 (file)
@@ -134,6 +134,7 @@ static int error_index;
 %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
@@ -843,6 +844,15 @@ 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
index 3d1e5a4..c3a4934 100644 (file)
@@ -2652,16 +2652,27 @@ map_input_to_output_sections
          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;
-         }
+         /* 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;
        }
     }
@@ -4971,13 +4982,15 @@ lang_add_wild (struct wildcard_spec *filespec,
 }
 
 void
-lang_section_start (const char *name, etree_type *address)
+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
index d6b9a79..0862191 100644 (file)
@@ -316,6 +316,7 @@ 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
@@ -461,7 +462,7 @@ extern void lang_final
 extern void lang_process
   (void);
 extern void lang_section_start
-  (const char *, union etree_union *);
+  (const char *, union etree_union *, const segment_type *);
 extern void lang_add_entry
   (const char *, bfd_boolean);
 extern void lang_add_target
index e01332a..0ace6ec 100644 (file)
@@ -261,6 +261,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
 <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);}
index be7c0a9..28f28ff 100644 (file)
@@ -55,6 +55,7 @@
 
 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.  */
@@ -1138,13 +1139,13 @@ parse_args (unsigned argc, char **argv)
          ldemul_list_emulation_options (stdout);
          exit (0);
        case OPTION_TBSS:
-         set_section_start (".bss", optarg);
+         set_segment_start (".bss", optarg);
          break;
        case OPTION_TDATA:
-         set_section_start (".data", optarg);
+         set_segment_start (".data", optarg);
          break;
        case OPTION_TTEXT:
-         set_section_start (".text", optarg);
+         set_segment_start (".text", optarg);
          break;
        case OPTION_TRADITIONAL_FORMAT:
          link_info.traditional_format = TRUE;
@@ -1380,8 +1381,44 @@ set_section_start (char *sect, char *valstr)
   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));
+  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);
+}
+
 \f
 /* Print help messages for the options.  */
 
index 6904ca9..33fae97 100644 (file)
@@ -1,78 +1,7 @@
 # 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.
+# 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}
@@ -175,11 +104,18 @@ STACK="  .stack        ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} :
     *(.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
@@ -202,66 +138,12 @@ 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;}}
+  ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_BASE_ADDRESS};}}
+  ${CREATE_PIE+${RELOCATING+. = ${SHLIB_BASE_ADDRESS};}}
   ${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}}
@@ -299,9 +181,9 @@ cat <<EOF
 
   /* 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}};}}
+  ${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)) }
@@ -355,6 +237,7 @@ cat <<EOF
   ${OTHER_SDATA_SECTIONS}
   ${RELOCATING+_edata = .;}
   ${RELOCATING+PROVIDE (edata = .);}
+  ${RELOCATING+. = DEFINED(__bss_segment_start) ? __bss_segment_start : .;}
   ${RELOCATING+__bss_start = .;}
   ${RELOCATING+${OTHER_BSS_SYMBOLS}}
   ${SBSS}
@@ -431,5 +314,63 @@ cat <<EOF
   ${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 c7311b1..e92bd6c 100644 (file)
@@ -18,6 +18,9 @@
 #      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