public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH: Fix -Ttext and friends for ELF systems
@ 2004-10-23  1:12 Mark Mitchell
  2004-10-23  1:38 ` Ian Lance Taylor
  0 siblings, 1 reply; 7+ messages in thread
From: Mark Mitchell @ 2004-10-23  1:12 UTC (permalink / raw)
  To: binutils


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)

This is a proto-patch that fixes this problem for ARM BPABI.  The key
idea is that, rather than setting the section address directly, these
options define symbols like "__text_segment_start".  Then, the linker
script uses the value of these symbols to set the location counter at
the start of particular segments.  The linker script also marks these
symbols as local so that they do not actually show up in the generated
executable or shared object.

What do people think of this approach?  My biggest concern so far is
that I've probably broken these options on non-ELF systems due to the
change in lexsup.c which no longer sets the section address.  I don't
know how to check whether I'm on an ELF section at runtime in the
linker.  I suppose that I could add a hook in the non-ELF *.em files;
would that make the most sense?  (I'm not worried about breaking these
options on ELF systems, since they are already broken.)

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

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	23 Oct 2004 01:03:49 -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: 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	23 Oct 2004 01:03:50 -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_symbol (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_symbol ("__bss_segment_start", optarg);
  	  break;
  	case OPTION_TDATA:
! 	  set_symbol ("__data_segment_start", optarg);
  	  break;
  	case OPTION_TTEXT:
! 	  set_symbol ("__text_segment_start", optarg);
  	  break;
  	case OPTION_TRADITIONAL_FORMAT:
  	  link_info.traditional_format = TRUE;
  	  break;
  	case OPTION_TASK_LINK:
*************** set_section_start (char *sect, char *val
*** 1374,1383 ****
--- 1375,1399 ----
    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));
  }
+ 
+ static void
+ set_symbol (char *symbol, char *valstr)
+ {
+   bfd_vma val;
+   const char *end;
+   char *buf;
+ 
+   val = bfd_scan_vma (valstr, &end, 16);
+   if (*end)
+     einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
+   buf = strdup (symbol);
+   lang_add_assignment (exp_assop ('=', buf, exp_intop (val)));
+ }
+ 
  \f
  /* 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	23 Oct 2004 01:03:50 -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	23 Oct 2004 01:03:59 -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,132 ----
    {
      ${RELOCATING+_stack = .;}
      *(.stack)
    }"
  
+ # Make all segment markers local.
+ cat <<EOF
+ VERSION {
+   {
+     local: __*_segment_start;
+   };
+ }
+ EOF
+ 
+ TEXT_START_ADDR="(DEFINED(__text_segment_start) ? __text_segment_start : ${TEXT_START_ADDR})"
+ SHLIB_TEXT_START_ADDR="(DEFINED(__text_segment_start) ? __text_segment_start : ${SHLIB_TEXT_START_ADDR:-0})"
+ DATA_ADDR="(DEFINED(__data_segment_start) ? __data_segment_start : ${DATA_ADDR-${DATA_SEGMENT_ALIGN}})"
+ SHLIB_DATA_ADDR="(DEFINED(__data_segment_start) ? __data_segment_start : ${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}}
--- 145,160 ----
  
  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.*) }
  
--- 188,200 ----
    .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 ****
--- 244,254 ----
    ${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 ****
--- 321,385 ----
  
    ${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	23 Oct 2004 01:03:59 -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.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: Fix -Ttext and friends for ELF systems
  2004-10-23  1:12 PATCH: Fix -Ttext and friends for ELF systems Mark Mitchell
@ 2004-10-23  1:38 ` Ian Lance Taylor
  2004-10-23  1:47   ` Mark Mitchell
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Ian Lance Taylor @ 2004-10-23  1:38 UTC (permalink / raw)
  To: mark; +Cc: binutils

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)
> 
> This is a proto-patch that fixes this problem for ARM BPABI.  The key
> idea is that, rather than setting the section address directly, these
> options define symbols like "__text_segment_start".  Then, the linker
> script uses the value of these symbols to set the location counter at
> the start of particular segments.  The linker script also marks these
> symbols as local so that they do not actually show up in the generated
> executable or shared object.
> 
> What do people think of this approach?  My biggest concern so far is
> that I've probably broken these options on non-ELF systems due to the
> change in lexsup.c which no longer sets the section address.  I don't
> know how to check whether I'm on an ELF section at runtime in the
> linker.  I suppose that I could add a hook in the non-ELF *.em files;
> would that make the most sense?  (I'm not worried about breaking these
> options on ELF systems, since they are already broken.)

One problem with this approach is that if the linker script does not
cooperate by actually using __text_segment_start, this will be
ineffective.  The result will be that -Ttext silently fails for no
obvious reason (as opposed to the current situation, where it loudly
fails for no obvious reason, or (in cases where the linker script does
not use SIZEOF_HEADERS) quietly does something unexpected).

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})'

SEGMENT_START would, of course, return the value of the -T{NAME}
option if defined, or DEFAULT otherwise.  When using -T{NAME}, it
marks it as having been used.

Then somewhere after parsing the whole script, you walk through the
list of all defined -T... options, and give a warning for each one
which was ignored by the linker script.

We should naturally leave the path open for defining more -T options;
the three usual ones were, of course, designed for a.out, and one
could imagine breaking out more aspects of an ELF file on an embedded
system.

Ian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: Fix -Ttext and friends for ELF systems
  2004-10-23  1:38 ` Ian Lance Taylor
@ 2004-10-23  1:47   ` Mark Mitchell
  2004-10-25 13:20   ` E. Weddington
  2004-10-25 19:46   ` Mark Mitchell
  2 siblings, 0 replies; 7+ messages in thread
From: Mark Mitchell @ 2004-10-23  1:47 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: binutils

Ian Lance Taylor wrote:

> <>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})'

OK, I can try that.

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: Fix -Ttext and friends for ELF systems
  2004-10-23  1:38 ` Ian Lance Taylor
  2004-10-23  1:47   ` Mark Mitchell
@ 2004-10-25 13:20   ` E. Weddington
  2004-10-25 19:46   ` Mark Mitchell
  2 siblings, 0 replies; 7+ messages in thread
From: E. Weddington @ 2004-10-25 13:20 UTC (permalink / raw)
  To: mark, Ian Lance Taylor; +Cc: binutils

On 22 Oct 2004 at 21:38, Ian Lance Taylor wrote:

> > We should naturally leave the path open for defining more -T options;
> the three usual ones were, of course, designed for a.out, and one
> could imagine breaking out more aspects of an ELF file on an embedded
> system.
> 

Yes. 
Note that -Ttext is used commonly on the AVR to relocate the program to the bootloader area. 
It would be nice if any changes to -Ttext do not significantly impact this target.

Thanks
Eric

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: Fix -Ttext and friends for ELF systems
  2004-10-23  1:38 ` Ian Lance Taylor
  2004-10-23  1:47   ` Mark Mitchell
  2004-10-25 13:20   ` E. Weddington
@ 2004-10-25 19:46   ` Mark Mitchell
  2004-10-26 15:55     ` Ian Lance Taylor
  2 siblings, 1 reply; 7+ messages in thread
From: Mark Mitchell @ 2004-10-25 19:46 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 1189 bytes --]

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


[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 34449 bytes --]

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));
  }
  \f
  /* 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);
+ }
+ 
  \f
  /* 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.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: Fix -Ttext and friends for ELF systems
  2004-10-25 19:46   ` Mark Mitchell
@ 2004-10-26 15:55     ` Ian Lance Taylor
  2004-10-26 18:53       ` Mark Mitchell
  0 siblings, 1 reply; 7+ messages in thread
From: Ian Lance Taylor @ 2004-10-26 15:55 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: binutils

Mark Mitchell <mark@codesourcery.com> writes:

> >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?

> --- 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);}

Looks like an accidental line break in the SIZEOF_HEADERS line.

Please add an entry to ld/NEWS.

OK with those changes.

Could you look into fixing up scripttempl/elf.sc to use SEGMENT_START?

Ian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: Fix -Ttext and friends for ELF systems
  2004-10-26 15:55     ` Ian Lance Taylor
@ 2004-10-26 18:53       ` Mark Mitchell
  0 siblings, 0 replies; 7+ messages in thread
From: Mark Mitchell @ 2004-10-26 18:53 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: binutils

Ian Lance Taylor wrote:

> Looks like an accidental line break in the SIZEOF_HEADERS line.

Indeed, good catch.

> Please add an entry to ld/NEWS.

Done.

> OK with those changes.

Thank you for the review.

> Could you look into fixing up scripttempl/elf.sc to use SEGMENT_START?

I will try to do that, but it may not be for a bit.

Thanks,

-- 
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-10-26 18:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-23  1:12 PATCH: Fix -Ttext and friends for ELF systems Mark Mitchell
2004-10-23  1:38 ` Ian Lance Taylor
2004-10-23  1:47   ` Mark Mitchell
2004-10-25 13:20   ` E. Weddington
2004-10-25 19:46   ` Mark Mitchell
2004-10-26 15:55     ` Ian Lance Taylor
2004-10-26 18:53       ` Mark Mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).