http://sourceware.org/bugzilla/show_bug.cgi?id=15302
Terry Guo <terry.guo at arm dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Last reconfirmed| |2013-06-21 Resolution|FIXED |--- Ever confirmed|0 |1 --- Comment #7 from Terry Guo <terry.guo at arm dot com> --- I am sorry that I have to reopen it. The proposed patch will cause below issue. In the below concrete case, the __init_array_start is allocated at address 0x11a40 actually. But any relocations using address of __init_array_start will be resolved to use address 0x11a41 by linker, thus the subsequential deference on __init_array_start is a deference on wrong address (0x11a41). This is because the proposed patch set ST_BRANCH_TO_THUMB to the symbol __init_array_start, then the last bit of its address is set by the linker function elf32_arm_swap_symbol_out. To reproduce this issue, an ARM baremetal toolchain using Newlib as C library is needed. Then use below command to build a project with empty main function: arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -O2 -lc -lrdimon -specs=rdimon.specs test.c -o test.out -Wl,-verbose -Wl,-Map=test.map Then run test.out on QEMU, a Segmentation falut will be reported. qemu-system-arm -cpu cortex-m3 -nographic -monitor null -serial null -semihosting -kernel ./test.out This QEMU segmentation fault is caused by deference of __init_array_start in function __libc_init_array. Here are some investigations: Disassemble the test.out with command "arm-none-eabi-objdump -D test.out" and we will see: Disassembly of section .init_array: 00011a40 <__init_array_start>: 11a40: 0000802d andeq r8, r0, sp, lsr #32 The __init_array_start is allocated at address 0x11a40 actually. Meanwhile the command "arm-none-eabi-readelf -s test.out", we will get symbol table: 222: 00011a41 0 FUNC LOCAL DEFAULT 7 __init_array_start Thus any instructions using __init_array_start will be resolved to 0x11a41 instead of 0x11a40. movw r5, #:lower16:__init_array_start movt r5, #:upper16:__init_array_start ldr r3, [r5, #4]! blx r3 in the above case, the r5 will get wrong value 0x11a41, then r3 will get wrong value, finally the blx will cause the fault. Here are some background on Newlib: In Newlib init.c we have code: extern void (*__init_array_start []) (void) __attribute__((weak)); extern void (*__init_array_end []) (void) __attribute__((weak)); void __libc_init_array (void) { size_t count; size_t i; ................ count = __init_array_end - __init_array_start; for (i = 0; i < count; i++) __init_array_start[i] (); } Both __init_array_start and __init_array_end are defined in linker script as: .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array )) PROVIDE_HIDDEN (__init_array_end = .); } -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils