Re: BINFMT_FLAT: reloc outside program

Greg Ungerer <[email protected]> Fri, 19 Aug 2016 23:59:36 +1000
Newsgroups gmane.linux.uclinux.devel
Message-ID <[email protected]>
Hi Waldemar,

On 06/05/16 05:06, Waldemar Brodkorb wrote:
> Hi Greg,
> Waldemar Brodkorb wrote,
>
>> Hi Greg,
>> Greg Ungerer wrote,
>>
>>> Attached is a kernel patch that modifies binfmt_flat to print
>>> out the reloc number along with the reloc error. That way we can
>>> map that back to the reloc entry number printed out in the verbose
>>> output from elf2flt at compile time.
>>
>> The stm32 is now working, here is the output with patched
>> kernel:
>> ~ # /hello
>> [  162.460000] BINFMT_FLAT: Loading file: /hello
>> [  162.460000] Mapping is 90520000, Entry point is 45, data_start is 8984
>> [  162.460000] Load /hello: TEXT=90520040-90528984 DATA=905289a0-9052e1b0 BSS=9052e1b0-9053240c
>> [  162.460000] BINFMT_FLAT: reference 0x870000 to shared library 237, killing hello!
>> SEGV
>>
>>  /hello
>> [   11.230000] BINFMT_FLAT: reference 0x870000 to shared library 237, killing hello!
>> SEGV
>>
>> Hmm, on the stm32 with latest buildroot, I now get this errors.
>>
>> But I just use UCLIBC_FORMAT_FLAT. The kernel defconfig used has
>> CONFIG_BINFMT_SHARED_FLAT enabled.
>
> I disabled CONFIG_BINFMT_SHARED_FLAT in the kernel.
> And now I get:
> ~ # /hello
> [   90.830000] BINFMT_FLAT: reloc[405] outside program 0xed870000 (0
> - 0x123b0/0x8944), killing hello!
> SEGV
>
> Compiling with
> ./output/host/usr/bin/arm-buildroot-uclinux-uclibcgnueabi-gcc
> -Wl,-elf2flt=-v -o hello hello.c -lpthread :
> ..
> reloc[403] = 0xe140
>   RELOC[404]: offset=0x5724 symbol=frame_dummy+0x0 section=.text
> size=0 fixup=0xac (reloc=0xe144)
> reloc[404] = 0xe144
>   RELOC[405]: offset=0x5728 symbol=pthread_initialize+0x0
> section=.text size=0 fixup=0x87ec (reloc=0xe148)
> reloc[405] = 0xe148
>   RELOC[406]: offset=0x572c symbol=__do_global_dtors_aux+0x0
> section=.text size=0 fixup=0x80 (reloc=0xe14c)
> reloc[406] = 0xe14c
> ..
>
> So pthread_initialize() is the problem?

I have an idea what is broken here now.

I am able to run this same test on qemu/versatile and get the
same result as you above with "hello" pthread test.

I think elf2flt is not properly handling R_ARM_TARGET1 relocation
types. And this causes a bad relocation calculation at runtime.

Can you try the attached patch?

This fixes it for me, and I can run "hello" and get expected result.

Regards
Greg

_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev
0001-elf2flt-fix-relocation-support-for-R_ARM_TARGET-type.patch (text/x-patch, 1 KB)
From dedce8765d203c1c162a57e6259375e0b457173f Mon Sep 17 00:00:00 2001
From: Greg Ungerer <[email protected]>
Date: Fri, 19 Aug 2016 23:49:51 +1000
Subject: [PATCH] elf2flt: fix relocation support for R_ARM_TARGET types

R_ARM_TARGET1 (and I think R_ARM_TARGET2) relocation types should be
treated in the same way as R_ARM_ABS32. Fix them to write out the addend
to the flat binary in network byte order.

Signed-off-by: Greg Ungerer <[email protected]>
---
 elf2flt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/elf2flt.c b/elf2flt.c
index 5ae7dd9..3f31569 100644
--- a/elf2flt.c
+++ b/elf2flt.c
@@ -1505,7 +1505,9 @@ DIS29_RELOCATION:
 					(((*p)->howto->type != R_ARM_PC24) &&
 					((*p)->howto->type != R_ARM_PLT32)))
 					tmp.c[i3] = (hl >> 24) & 0xff;
-				if ((*p)->howto->type == R_ARM_ABS32)
+				if (((*p)->howto->type == R_ARM_ABS32) ||
+				    ((*p)->howto->type == R_ARM_TARGET1) ||
+				    ((*p)->howto->type == R_ARM_TARGET2))
 					*(uint32_t *)r_mem = htonl(hl);
 				else
 					*(uint32_t *)r_mem = tmp.l;
-- 
1.9.1