This is a forward/summary of https://bugs.linaro.org/show_bug.cgi?id=2562 Since GCC 5, on ARM a code fragment like: some_module.c: int __attribute__((weak)) some_weak_func(void) { return 10; } void save_weak_func_pointer(void) { __weak_func_ptr = some_weak_func; } saves the address of the weak implementation in __weak_func_ptr even though the function can be overridden by a strong implementation in another object file. so even if main.c has: int some_weak_func(void) { return 11; } when calling through __weak_func_ptr(), we end up calling the weak implementation.
Created attachment 39993 [details] main.c
Created attachment 39994 [details] some_module.c
Compile the attached code with: CFLAGS="-marm -fpie" arm-linux-gnueabi-gcc $CFLAGS -c main.c -o main.o arm-linux-gnueabi-gcc $CFLAGS -c some_module.c -o some_module.o Link with arm-linux-gnueabi-gcc -pie -o test_weak main.o some_module.o Correct execution should show: Entering test_weak_funcion_call This line is to avoid optimization in further call_weak_by_pointer res_pointer_call = 11 res_direct_call = 11 All Ok But instead we have: Entering test_weak_funcion_call This line is to avoid optimization in further call_weak_by_pointer res_pointer_call = 10 res_direct_call = 11 ERROR: Results from direct call and from call via pointer differs The behaviour changed with r220674.
With gcc 4.9, the generated code looks like: save_weak_func_pointer: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 1, uses_anonymous_args = 0 @ link register save eliminated. str fp, [sp, #-4]! add fp, sp, #0 ldr r3, .L7 .LPIC1: add r3, pc, r3 ldr r2, .L7+4 ldr r2, [r3, r2] ldr r1, .L7+8 ldr r3, [r3, r1] str r3, [r2] sub sp, fp, #0 @ sp needed ldr fp, [sp], #4 bx lr .L8: .align 2 .L7: .word _GLOBAL_OFFSET_TABLE_-(.LPIC1+8) .word __weak_func_ptr(GOT) .word some_weak_func(GOT) With gcc 5.3: save_weak_func_pointer: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 1, uses_anonymous_args = 0 @ link register save eliminated. str fp, [sp, #-4]! add fp, sp, #0 ldr r2, .L7 .LPIC1: add r2, pc, r2 ldr r3, .L7+4 ldr r3, [r2, r3] ldr r2, .L7+8 .LPIC2: add r2, pc, r2 str r2, [r3] nop sub sp, fp, #0 @ sp needed ldr fp, [sp], #4 bx lr .L8: .align 2 .L7: .word _GLOBAL_OFFSET_TABLE_-(.LPIC1+8) .word __weak_func_ptr(GOT) .word some_weak_func-(.LPIC2+8) That is, some_weak_func is not referenced through the got anymore. I've noticed that r220674 introduced a new param to default_binds_local_p: weak_dominates, which is true when called via default_binds_local_p_2. I am not sure what "weak_dominates", and I couldn't find a description in the gcc-patches thread where r220674 and more recent updates were discussed. I am wondering whether have weak_dominates=false on arm is the right fix, as it does not explain why the sample code works on x86_64 and aarch64.
Author: clyon Date: Wed Jan 11 16:13:14 2017 New Revision: 244320 URL: https://gcc.gnu.org/viewcvs?rev=244320&root=gcc&view=rev Log: [ARM] PR target/78253 Call weak function instead of strong when called through pointer. 2017-01-11 Christophe Lyon <christophe.lyon@linaro.org> PR target/78253 * config/arm/arm.c (legitimize_pic_address): Handle reference to weak symbol. (arm_assemble_integer): Likewise. Modified: trunk/gcc/ChangeLog trunk/gcc/config/arm/arm.c
Author: clyon Date: Fri Jan 13 13:09:30 2017 New Revision: 244437 URL: https://gcc.gnu.org/viewcvs?rev=244437&root=gcc&view=rev Log: 2017-01-13 Christophe Lyon <christophe.lyon@linaro.org> Backport from mainline r244320. 2017-01-11 Christophe Lyon <christophe.lyon@linaro.org> PR target/78253 * config/arm/arm.c (legitimize_pic_address): Handle reference to weak symbol. (arm_assemble_integer): Likewise. Modified: branches/gcc-6-branch/gcc/ChangeLog branches/gcc-6-branch/gcc/config/arm/arm.c
Author: clyon Date: Fri Jan 13 13:11:07 2017 New Revision: 244438 URL: https://gcc.gnu.org/viewcvs?rev=244438&root=gcc&view=rev Log: 2017-01-11 Christophe Lyon <christophe.lyon@linaro.org> Backport from mainline r244320. 2017-01-11 Christophe Lyon <christophe.lyon@linaro.org> PR target/78253 * config/arm/arm.c (legitimize_pic_address): Handle reference to weak symbol. (arm_assemble_integer): Likewise. Modified: branches/gcc-5-branch/gcc/ChangeLog branches/gcc-5-branch/gcc/config/arm/arm.c
Fixed on trunk and affected branches.
*** Bug 68178 has been marked as a duplicate of this bug. ***