This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


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

chained AT() in linker scripts?


[ This concerns local changes to the GNU linker included with Wind River's
Tornado 3.0 IDE and VxWorks AE(tm) RTOS, which were released last week. ]

I have a question about using the AT() directive to create a "chain" of
output sections which are all offset together. Specifically, how can it
be done in a general way so that elf.sc can be macro-configured to use
AT() appropriately for "ROMable" program builds.

History: I have a RAM-loadable program (OS kernel + user app) which uses a
lightly modified elf.sc to link. I am now re-linking it to boot from ROM.
The ROM startup code copies writable sections to their runtime positions,
presuming their initial images are stored in ROM after _etext (thanks to
the AT() directive). The code address in ROM is set with -Ttext and the
RAM address of the writable sections is set with -Tdata.

After linking with ld, I use objcopy -O srec --gap-fill=0 to produce a
single blob of contiguous S-Records that represents the desired ROM image.
This S-Record file is then programmed onto an embedded board. (Sometimes
the addresses must be shifted before programming; I use an additional
objcopy run to accomplish this, because --gap-fill and --ignore-vma do not
interact well when used together.)

Here is a fragment of elf.sc with AT() directives added to show my intent:

  .data  ${RELOCATING-0} : AT ( _etext )
  {
    ${RELOCATING+${DATA_START_SYMBOLS}}
    *(.data)
    ${RELOCATING+*(.data.*)}
    ${RELOCATING+*(.gnu.linkonce.d*)}
    ${CONSTRUCTING+SORT(CONSTRUCTORS)}
  }
  .data1 ${RELOCATING-0} : AT ( LOADADDR (.data) + SIZEOF (.data) )
	{ *(.data1) }
  .eh_frame : AT ( LOADADDR (.data1) + SIZEOF (.data1) )
	{ *(.eh_frame) }
  .gcc_except_table : AT ( LOADADDR (.eh_frame) + SIZEOF (.eh_frame) )
	{ *(.gcc_except_table) }

Looks good so far. But how do I apply it to the next portion of elf.sc?

  ${WRITABLE_RODATA+${RODATA}}
  ${RELOCATING+${OTHER_READWRITE_SECTIONS}}
  ${RELOCATING+${CTOR}}
  ${RELOCATING+${DTOR}}
  ${DATA_PLT+${PLT}}
  ${RELOCATING+${OTHER_GOT_SYMBOLS}}
  .got         ${RELOCATING-0} : { *(.got.plt) *(.got) }
  ${TEXT_DYNAMIC-${DYNAMIC}}
  /* We want the small data sections together, so single-instruction offsets
     can access them all, and initialized data all before uninitialized, so
     we can shorten the on-disk segment size.  */
  .sdata   ${RELOCATING-0} : { *(.sdata) *(.sdata.*) }
  ${RELOCATING+${OTHER_GOT_SECTIONS}}
  ${RELOCATING+_edata = .;}
  ${RELOCATING+PROVIDE (edata = .);}

Many of the above sections are optional. If I were to add AT() directives
everywhere (each naming the previous section!) they would all cease to be
optional.

The following fragment is what we actually shipped. Note that certain macros
(OTHER_READWRITE_SECTIONS, CTOR, DTOR, OTHER_GOT_SECTIONS) must expand to
something nonstandard in order to live within this paradigm.

  .data  ${RELOCATING-0} : AT ( _etext )
  {
    ${RELOCATING+${DATA_START_SYMBOLS}}
    *(.data)
    ${RELOCATING+*(.data.*)}
    ${RELOCATING+*(.gnu.linkonce.d*)}
    ${CONSTRUCTING+SORT(CONSTRUCTORS)}
    /* Input sections after this point used to be in separate sections, however
       many of these sections are optional and that fouls up the cascaded use
       of AT ( LOADADDR (.previous) + SIZEOF (.previous) ) which was how we
       first implemented this. If anyone depends on these sections retaining
       their independent identities, then we will have to rethink this and
       maybe enhance the linker to handle the situation more gracefully. */
    ${RELOCATING+*(.data1)}
    ${RELOCATING+*(.eh_frame)}
    ${RELOCATING+*(.gcc_except_table)}
    /* FIXME! We put OTHER_READWRITE_SECTIONS _inside_ a section, not outside
       as it normally is, because of the AT/SIZEOF/LOADADDR issue discussed
       above. This means that if any of our emulations supply these, they must
       use a different convention from everyone else. Currently, none do. */
    ${RELOCATING+${OTHER_READWRITE_SECTIONS}}
    ${RELOCATING+${CTOR}}
    ${RELOCATING+${DTOR}}
    ${DATA_PLT+${PLT_D}}
    ${RELOCATING+${OTHER_GOT_SYMBOLS}}
    *(.got.plt) *(.got)
    ${TEXT_DYNAMIC-${DYNAMIC_D}}
    /* Currently on vxWorks we do not support sdata/sbss, but if someone tries
       to use them, make sure they get put in sane places and not piled at the
       end of the memory map, where they will be useless to a ROM image. */
    *(.sdata) *(.sdata.*)
    /* FIXME! We put OTHER_GOT_SECTIONS _inside_ a section, not outside
       as it normally is, because of the AT/SIZEOF/LOADADDR issue discussed
       above. This means that vxr6ebmip.sh has to use a unique convention. */
    ${RELOCATING+${OTHER_GOT_SECTIONS}}
    ${RELOCATING+. = ALIGN(${ALIGNMENT});}
  }
  ${RELOCATING+. = ALIGN(${ALIGNMENT});}
  ${RELOCATING+_edata = .;}
  ${RELOCATING+PROVIDE (edata = .);}

As the FIXME's explain, this is ... suboptimal.

I tried submitting the full set of changes back in March 2000, but they were
soundly rejected by Ian on the grounds that "Copying elf.sc is bad, M'Kay".

Since then I have not been able to find a method which avoids all of:
  a) copying elf.sc
  b) grouping lots of sections into .data in elf.sc, where it impacts everyone
  c) making lots of currently optional sections non-optional or semi-optional

Now that this is shipping, I have to stop waiting for inspiration to hit.

If I can't find a way to make these changes submittable soon, then I will
recommend that all of our future maintenance releases use external linker
scripts and completely ignore the linker's built-in script. Using a stale
elf.sc with a newer gcc/binutils is far less likely to blow chunks than
using a vanilla elf.sc (because our local patches couldn't be submitted).

And even if it does blow chunks, odds are that the offending feature won't
be supported in the RTOS environment, and will need to be disabled anyway.

Comments/ideas/flames welcome...

-- 
Todd Whitesel
toddpw @ windriver.com

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