Problem with referenceable sections ("link sets")

Jason R Thorpe thorpej@wasabisystems.com
Sat Nov 16 22:01:00 GMT 2002


I have an application which requires the referenceable sections that
were added in ld 2.6 -- here is the NEWS entry for reference:

 -- snip --

* When an ELF section name is representable as a C identifier (this is not true
of most ELF section names), the linker will automatically define symbols
__start_SECNAME and __stop_SECNAME, where SECNAME is the section name, at the
beginning and the end of the section.  This is used by glibc. 

 -- snip --

...I will refer to these as "link sets".

My problem is when using an "interesting" linker script.  I want the link
set to end up in .rodata.  Here is the relevant part of the linker script:

 -- snip --

ENTRY(KERNEL_BASE_phys)
SECTIONS
{
  KERNEL_BASE_phys = 0x00200000;
  KERNEL_BASE_virt = 0xc0200000;

  /* Kernel start: */
  .start (KERNEL_BASE_phys) :
  {
    *(.start)
  } =0

  /* Read-only sections, merged into text segment: */
  .text (KERNEL_BASE_virt + SIZEOF(.start)) :
  AT (LOADADDR(.start) + SIZEOF(.start))
  {
    *(.text)
    *(.text.*)
    *(.stub)
    *(.glue_7t) *(.glue_7)
  } =0
  .rodata  :
  AT (LOADADDR(.text) + SIZEOF(.text))
  { *(.rodata) *(.rodata.*) } =0
  .
  .
  .
}

 -- snip --

Now, the link set does end up getting assigned to .rodata in place_orphans,
but it doesn't seem to get merged with the rest of the .rodata section
correctly at all:

Program Header:
    LOAD off    0x00008000 vaddr 0x00200000 paddr 0x00200000 align 2**15
         filesz 0x000000c4 memsz 0x000000c4 flags r-x
    LOAD off    0x000080c4 vaddr 0xc02000c4 paddr 0x002000c4 align 2**15
         filesz 0x00121d74 memsz 0x00121d74 flags r-x
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    .rodata seems to have been properly merged into .text here.

    LOAD off    0x00130000 vaddr 0xc0328000 paddr 0x00328000 align 2**15
         filesz 0x000349f4 memsz 0x000349f4 flags rw-
    LOAD off    0x00169e38 vaddr 0xc0321e38 paddr 0xc0321e38 align 2**15
         filesz 0x00000018 memsz 0x00000018 flags r--
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    Why is this listed after .data's PHDR?  Why not merged with .rodata
    into .text's PHDR?

    LOAD off    0x0016ca00 vaddr 0xc035ca00 paddr 0xc035ca00 align 2**15
         filesz 0x00000000 memsz 0x0001ea90 flags rw-

.
.
.

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .start        000000c4  00200000  00200000  00008000  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .text         00106324  c02000c4  002000c4  000080c4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .rodata       0001ba50  c03063e8  003063e8  0010e3e8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 link_set      00000018  c0321e38  c0321e38  00169e38  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .data         000349f4  c0328000  00328000  00130000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  5 .sbss         00000000  c035c9f4  c035c9f4  0016ca00  2**0
                  CONTENTS
  6 .bss          0001ea90  c035ca00  c035ca00  0016ca00  2**4

It gets even worse when objcopy comes along to write out a flat
binary version of the image:

/usr/local/gnu/bin/arm-unknown-netbsdelf-objcopy -S -O binary netbsd netbsd.bin
BFD: Warning: Writing section `link_set' to huge (ie negative) file offset 0xc0121e38.
/usr/local/gnu/bin/arm-unknown-netbsdelf-objcopy: netbsd.bin: File truncated
*** Error code 1

This all works fine if I don't use the link set feature (unfortunately,
my application happens to need the feature).  It also "works" if the
"link_set" section is explicitly specified as an input to the .rodata output
section.  Unfortunately, the __start_SECNAME and __stop_SECNAME symbols are
only provided if the section is an orphan, so that is not particularly useful.

I have successfully used the link set feature for kernels which don't use
an "interesting" linker script (e.g. no use of AT, first VMA provided by
-Ttext ..., etc.)  That is to say, the "link_set" section appears to get
properly merged in with .rodata, which is in-turn properly merged with
.text.

I started to dig into ld to figure out what is going on, but my eyes quickly
glazed over.  

If anyone could at least point me in the right direction, that'd be much
appreciated.  Either of the following two solutions would be fine with me:

	* Make the __start_SECNAME and __stop_SECNAME symbols appear
	  for all C-referenceable sections, even if they are not orphans.

	* Make the C-referenceable section get properly merged with
	  .rodata in the presence of the "interesting" linker script.

Note that explicltly setting the __start_*/__stop_* symbols in the linker
script isn't an option for me...

Any help appreciated..

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>



More information about the Binutils mailing list