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]
Other format: [Raw text]

problem relocating weak symbol on ARM


Hi,

I'm trying to get profiling working on ARM
(also see here : <http://gcc.gnu.org/ml/gcc/2002-09/msg00230.html> )

When I'm using shared libraries (glibc-2.2.5), I'm seeing strange results :

A small test file is compiled as follows :

root:~/tmp2# gcc -v -g -pg -fno-omit-frame-pointer -O3 gprof-test.c
Reading specs from /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/specs
Configured with: ../gcc-3.0.4/configure --prefix=/usr --with-cpu=xscale
Thread model: posix
gcc version 3.0.4
/usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/cc1 -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__=0 -D__GNUC_PATCHLEVEL__=4 -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__ELF__ -D__unix -D__linux -Asystem=unix -Asystem=posix -Acpu=arm -Amachine=arm -D__CHAR_UNSIGNED__ -D__OPTIMIZE__ -D__STDC_HOSTED__=1 -D__ARM_ARCH_5TE__ -D__XSCALE__ -D__APCS_32__ -D__ARMEL__ -D__arm__ gprof-test.c -quiet -dumpbase gprof-test.c -g -O3 -version -p -fno-omit-frame-pointer -o /tmp/cc5oLUJK.s
GNU CPP version 3.0.4 (cpplib) (ARM GNU/Linux with ELF)
GNU C version 3.0.4 (armv5l-unknown-linux-gnu)
compiled by GNU C version 3.0.4.
ignoring nonexistent directory "/usr/armv5l-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/include
/usr/include
End of search list.
/usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/../../../../armv5l-unknown-linux-gnu/bin/as -o /tmp/ccad2aLA.o /tmp/cc5oLUJK.s
/usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/collect2 -dynamic-linker /lib/ld-linux.so.2 -X -m armelf_linux -p /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/../../../gcrt1.o /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/../../../crti.o /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/crtbegin.o -L/usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4 -L/usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/../../../../armv5l-unknown-linux-gnu/lib -L/usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/../../.. /tmp/ccad2aLA.o -lgcc -lc -lgcc /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/crtend.o /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/../../../crtn.o




Following code is executed at the beginning of the executable :

[from glibc-2.2.5 ]
call_gmon_start(void)
{
extern void __gmon_start__ (void) __attribute__ ((weak)); /*weak_extern (__gmon_start__);*/
void (*gmon_start) (void) = __gmon_start__;

if (gmon_start)
gmon_start ();
}

In assembly, this looks like (using objdump --disassemble-all) :




Disassembly of section .init:

0000846c <_init>:
846c: e52de004 str lr, [sp, -#4]!
8470: eb000058 bl 85d8 <call_gmon_start>
8474: eb00008e bl 86b4 <frame_dummy>
8478: eb0000dd bl 87f4 <__do_global_ctors_aux>
847c: e49df004 ldr pc, [sp], #4
[...]

00008594 <__gmon_start__>:
8594: e52de004 str lr, [sp, -#4]!
8598: e59f2028 ldr r2, [pc, #40] ; 85c8 <__gmon_start__+0x34>
859c: e59f0028 ldr r0, [pc, #40] ; 85cc <__gmon_start__+0x38>
85a0: e59f1028 ldr r1, [pc, #40] ; 85d0 <__gmon_start__+0x3c>
85a4: e5923000 ldr r3, [r2]
85a8: e3530000 cmp r3, #0 ; 0x0
85ac: 149df004 ldrne pc, [sp], #4
85b0: e3a03001 mov r3, #1 ; 0x1
85b4: e5823000 str r3, [r2]
85b8: ebffffd4 bl 8510 <_init+0xa4>
85bc: e59f0010 ldr r0, [pc, #16] ; 85d4 <__gmon_start__+0x40>
85c0: e49de004 ldr lr, [sp], #4
85c4: ea00007e b 87c4 <atexit>
85c8: 000109e8 andeq r0, r1, r8, ror #19
85cc: 00008560 andeq r8, r0, r0, ror #10
85d0: 00008868 andeq r8, r0, r8, ror #16
85d4: 000084d0 ldreqd r8, [r0], -r0

000085d8 <call_gmon_start>:
85d8: e92d4400 stmdb sp!, {sl, lr}
85dc: e59fa01c ldr sl, [pc, #28] ; 8600 <call_gmon_start+0x28>
85e0: e59f301c ldr r3, [pc, #28] ; 8604 <call_gmon_start+0x2c>
85e4: e08fa00a add sl, pc, sl
85e8: e79a3003 ldr r3, [sl, r3] (************)
85ec: e3530000 cmp r3, #0 ; 0x0
85f0: 0a000001 beq 85fc <call_gmon_start+0x24>
85f4: e1a0e00f mov lr, pc
85f8: e1a0f003 mov pc, r3
85fc: e8bd8400 ldmia sp!, {sl, pc}
8600: 000083b4 streqh r8, [r0], -r4
8604: 00000040 andeq r0, r0, r0, asr #32


sl = 0x83b4 + 0x85ec = 0x109a0
r3 = 0x40
[sl, r3] = [0x109a0+0x40] = 109e0

At code 85e8 (marked **********), for some reason, r3 is filled with 0x00000000 :

(using objdump -s) :

Contents of section .got:
109a0 c8080100 00000000 00000000 80840000 ................
109b0 80840000 80840000 80840000 80840000 ................
109c0 80840000 80840000 80840000 80840000 ................
109d0 80840000 80840000 80840000 80840000 ................
109e0 00000000 00000000 ........


Where it should have been filled in with the address of __gmon_start__ ...
(which is known in this executable (!))

readelf -a gives :

[...]
Relocation section '.rel.plt' at offset 0x404 contains 13 entries:
Offset Info Type Sym.Value Sym. Name
000109ac 00000116 R_ARM_JUMP_SLOT 00008490 mcount
000109b0 00000216 R_ARM_JUMP_SLOT 00000000 __register_frame_info
000109b4 00000316 R_ARM_JUMP_SLOT 000084b0 __cxa_atexit
000109b8 00000416 R_ARM_JUMP_SLOT 00000000 __deregister_frame_inf
000109bc 00000516 R_ARM_JUMP_SLOT 000084d0 _mcleanup
000109c0 00000616 R_ARM_JUMP_SLOT 000084e0 puts
000109c4 00000716 R_ARM_JUMP_SLOT 00000000 __deregister_frame_inf
000109c8 00000816 R_ARM_JUMP_SLOT 00008500 abort
000109cc 00000916 R_ARM_JUMP_SLOT 00008510 __monstartup
000109d0 00000a16 R_ARM_JUMP_SLOT 00000000 __register_frame_info_
000109d4 00000b16 R_ARM_JUMP_SLOT 00008530 __libc_start_main
000109d8 00000c16 R_ARM_JUMP_SLOT 00008540 printf
000109dc 00000d16 R_ARM_JUMP_SLOT 00000000 __cxa_finalize

There are no unwind sections in this file.

Symbol table '.dynsym' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00008490 56 FUNC GLOBAL DEFAULT UND mcount@GLIBC_2.0 (2)
2: 00000000 20 FUNC WEAK DEFAULT UND __register_frame_info@GLIBC_2.0 (2)
3: 000084b0 56 FUNC GLOBAL DEFAULT UND __cxa_atexit@GLIBC_2.1.3 (3)
4: 00000000 340 FUNC WEAK DEFAULT UND __deregister_frame_info_b@GCC_3.0 (4)
5: 000084d0 76 FUNC GLOBAL DEFAULT UND _mcleanup@GLIBC_2.0 (2)
6: 000084e0 396 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.0 (2)
7: 00000000 12 FUNC WEAK DEFAULT UND __deregister_frame_info@GLIBC_2.0 (2)
8: 00008500 484 FUNC GLOBAL DEFAULT UND abort@GLIBC_2.0 (2)
9: 00008510 392 FUNC GLOBAL DEFAULT UND __monstartup@GLIBC_2.0 (2)
10: 00000000 184 FUNC WEAK DEFAULT UND __register_frame_info_bas@GCC_3.0 (4)
11: 00008530 256 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2)
12: 00008540 60 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.0 (2)
13: 00000000 188 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.1.3 (3)
14: 00008868 4 OBJECT GLOBAL DEFAULT 13 _IO_stdin_used
15: 00008594 68 FUNC GLOBAL DEFAULT 11 __gmon_start__
[...]

What could be the reason that __gmon_start__ is not being resolved ??
Could it be that an entry for it is missing in the above .rel.plt ??

Greetings,
--
Jeroen Dobbelaere
Embedded Software Engineer

ACUNIA Embedded Solutions
http://www.acunia.com/aes



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