Subject: Re: kern/21844: netwinder kernal cannot be linked because link_set_* sections overlap with .data
To: Christos Zoulas <christos@zoulas.com>
From: Ian Lance Taylor <ian@airs.com>
List: tech-toolchain
Date: 06/12/2003 20:27:24
christos@zoulas.com (Christos Zoulas) writes:

> Well, as long as we are on the subject of gld, I have a question:
> I am trying to put a NetBSD ident section in the kernel. The code
> is #ifdef notyet in /usr/src/sys/conf/newvers.sh because I don't
> know how to convince the linker to work. When I enable it, the
> linker prints:
> 
>     ld: netbsd: Not enough room for program headers (allocated 3, need 4)
>     ld: final link failed: Bad value
> 
> This is because the ident section is:
> 
> __asm(
>         ".section\t\".note.netbsd.ident\", \"a\"\n"
>         "\t.p2align\t2\n"
>         "\t.long\t" _S(ELF_NOTE_NETBSD_NAMESZ) "\n"
>         "\t.long\t" _S(ELF_NOTE_NETBSD_DESCSZ) "\n"
>         "\t.long\t" _S(ELF_NOTE_TYPE_NETBSD_TAG) "\n"
>         "\t.ascii\t" _S(ELF_NOTE_NETBSD_NAME) "\n"
>         "\t.long\t" _S(__NetBSD_Version__) "\n"
>         "\t.p2align\t2\n"
> );
> 
> And this ident section causes another program header to be allocated?!?
> How do I fix this?

I assume that you intentionally want the section to be loaded into
memory at runtime.  If you don't need the section to be loaded into
memory, then remove the "a" from the initial .section pseudo-op.  That
should fix the problem.

Otherwise, the basic problem is that the linker counts the number of
segments when it sees SIZEOF_HEADERS in the linker script, before it
knows how many segments it really needs.

So, hmmm.  You have a loadable .note section, so the linker will want
to create a PT_NOTE segment.  You are linking statically, so the
linker is only allocating two other segments when it sees
SIZEOF_HEADERS, plus the PT_NOTE segment.  It turns out that you need
another segment.  You should only need three segments if the .note
section gets merged into the text segment.  Evidently this isn't
happening--the linker is putting the .note section somewhere else.

Since the kernel build process uses its own linker script, certainly
the easy way to handle this is to change the linker script to
explicitly put the .note section somewhere near the .text section.

The linker will normally put a loadable .note section immediately
after the .interp section.  However, in a static link there is no
.interp section.  So another fix would be more intelligent handling of
.note sections in that case.  This would be a change to
gld${EMULATION_NAME}_place_orphan() in ld/emultempl/elf32.em.  Perhaps
I'll look into that.

Ian