This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Invalid executable being created by custom linker scripts
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Mon, 24 Nov 2008 18:24:33 +1030
- Subject: Re: Invalid executable being created by custom linker scripts
- References: <OFD1314998.284D1EEA-ON80257508.0057A6C7-80257508.00598544@ie.ibm.com> <OF77F72174.E4F0E19A-ONCA257508.0080045C-E9257508.00823274@au1.ibm.com>
On Sat, Nov 22, 2008 at 10:12:06AM +1030, Alan Modra wrote:
> Mel Gorman wrote on 22/11/2008 02:47:48 AM:
> > INTERP 0x0000000000000200 0x0000000001000200 0x0000000001000200
> > 0x0000000000000040 0x0000000000000040 R 4
> > [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
> >
> > At first glance, it looks ok, but the length is different. On working
> > binaries, it's 0x1c corresponding to the full length of the path, but
> here
> > it is 0x40. Do you think the different length is the problem and if so,
> > have you any idea why this might occur?
>
> You are asking a kernel question here, since it is the kernel that looks at
> this header. On investigating fs/binfmt_elf.c, I find that the kernel
> checks that the string is NULL terminated. It does so by testing the last
> byte covered by the PT_INTERP header, ie. at a file offset of 0x23f in this
> case. But this is not even in the .interp section! It's somewhere in
> .note.gnu.build-id and most likely non-zero. So this is indeed why your
> executable does not run.
>
> The solution to your problem is to add .note.gnu.build-id to your linker
> script, and specify the correct phdrs for the section. When
> .note.gnu.build-id is an orphan, the linker looks through existing sections
> to find one like it, and in this case chooses to place the orphan
> .note.gnu.build-id after .interp. The orphan section also inherits the
> phdr assignment, if any, of the previous section, which is why PT_INTERP
> wrongly has both .interp and .note.gnu.build-id.
>
> Custom linker scripts are a pain..
It's probably worth special casing PT_INTERP in the linker to stop
this happening, since orphan loadable note sections tend to be placed
after .interp.
* ldlang.c (lang_record_phdrs): Don't add orphans to PT_INTERP header.
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.296
diff -u -p -r1.296 ldlang.c
--- ld/ldlang.c 25 Oct 2008 09:54:01 -0000 1.296
+++ ld/ldlang.c 24 Nov 2008 07:50:10 -0000
@@ -6669,6 +6669,10 @@ lang_record_phdrs (void)
|| (os->bfd_section->flags & SEC_ALLOC) == 0)
continue;
+ /* Don't add orphans to PT_INTERP header. */
+ if (l->type == 3)
+ continue;
+
if (last == NULL)
{
lang_output_section_statement_type * tmp_os;
--
Alan Modra
Australia Development Lab, IBM