User account creation filtered due to spam.

Bug 78253 - [5/6/7 Regression] [ARM] call weak function instead of strong when called through pointer
Summary: [5/6/7 Regression] [ARM] call weak function instead of strong when called thr...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 5.4.0
: P2 normal
Target Milestone: 5.5
Assignee: Christophe Lyon
URL: https://bugs.linaro.org/show_bug.cgi?...
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2016-11-08 14:51 UTC by Christophe Lyon
Modified: 2017-01-13 13:13 UTC (History)
1 user (show)

See Also:
Host:
Target: arm
Build:
Known to work: 4.9.4
Known to fail: 5.4.0
Last reconfirmed: 2016-11-08 00:00:00


Attachments
main.c (187 bytes, text/plain)
2016-11-08 14:52 UTC, Christophe Lyon
Details
some_module.c (355 bytes, text/plain)
2016-11-08 14:52 UTC, Christophe Lyon
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Christophe Lyon 2016-11-08 14:51:25 UTC
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.
Comment 1 Christophe Lyon 2016-11-08 14:52:15 UTC
Created attachment 39993 [details]
main.c
Comment 2 Christophe Lyon 2016-11-08 14:52:45 UTC
Created attachment 39994 [details]
some_module.c
Comment 3 Christophe Lyon 2016-11-08 14:54:55 UTC
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.
Comment 4 Christophe Lyon 2016-11-08 14:59:55 UTC
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.
Comment 5 Christophe Lyon 2017-01-11 16:13:46 UTC
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
Comment 6 Christophe Lyon 2017-01-13 13:10:01 UTC
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
Comment 7 Christophe Lyon 2017-01-13 13:11:39 UTC
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
Comment 8 Christophe Lyon 2017-01-13 13:13:30 UTC
Fixed on trunk and affected branches.