Bug 24983 - RISC-V GP linker relaxation is not performed with -nostdlib
Summary: RISC-V GP linker relaxation is not performed with -nostdlib
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.30
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 24992 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-09-10 05:07 UTC by Bin Meng
Modified: 2022-08-19 23:50 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2019-09-10 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bin Meng 2019-09-10 05:07:54 UTC
See the following test case
$ cat test.c
int a = 1;

int main()
{
    return a;
}

Building the test case with "-nostdlib" seems to disable the GP linker relaxation:
$ riscv64-unknown-linux-gnu-gcc test.c -o test -nostdlib
$ riscv64-unknown-linux-gnu-objdump -d test | grep gp
<return nothing>

But if we compile test.c without "-nostdlib":
$ riscv64-unknown-linux-gnu-gcc test.c -o test
$ riscv64-unknown-linux-gnu-objdump -d test | grep gp
   103bc:       00002197                auipc   gp,0x2
   103c0:       46418193                addi    gp,gp,1124 # 12820 <__global_pointer$>
   1041c:       8141c783                lbu     a5,-2028(gp) # 12034 <_edata>
   1042a:       80f18a23                sb      a5,-2028(gp) # 12034 <_edata>
   10440:       8101a783                lw      a5,-2032(gp) # 12030 <a>

Note: this bug was previously filed in GCC bugzila, and it was suggested it should be filed against binutils.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91713
Comment 1 Jim Wilson 2019-09-10 18:25:26 UTC
Commentary copied from the gcc bug report...

This is an edge condition and an accident of circumstances.  When you link with the default libraries, other stuff gets put in sdata before a, and so the variable a is in range of gp because it is at -0x7f0.  When you link with -nostdlib, a is the only thing in sdata, and we run into an edge condition where a is -0x800 from gp, which is at the extreme limit, but the linker relaxation has to limit the range to deal with section alignment issues that may changes addresses after relaxation, and so we have to assume that a is out of range.

If you change the example to
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;

int main()
{
    return a + b + c + d + e;
}
then we see that all 5 variables use gp address with default libraries, and only the last 3 with -nostdlib, so we are losing the first two variables due to address range limitation at linker relaxation time.

There is a somewhat related open binutils bug report
  https://sourceware.org/bugzilla/show_bug.cgi?id=24678
and another somewhat related binutils bug report I recently fixed
  https://sourceware.org/ml/binutils/2019-08/msg00244.html
if gp was still computed inside the .sdata section we wouldn't have this problem, but that means undoing a change that reduced code size for most applications.  Maybe there is a different way to solve the earlier problem that doesn't cause this problem.
Comment 2 Jim Wilson 2019-09-11 23:37:15 UTC
*** Bug 24992 has been marked as a duplicate of this bug. ***
Comment 3 Jim Wilson 2019-09-12 16:50:39 UTC
There is another related problem reported here
https://github.com/riscv/riscv-gnu-toolchain/issues/497