Link issue (relocation truncated to fit) with large data offset

516 views
Skip to first unread message

Sober Liu

unread,
Aug 24, 2018, 1:52:04 AM8/24/18
to RISC-V SW Dev (sw-dev@groups.riscv.org)

Hi all,

I am facing a link issue when trying to use SV48. I am not sure whether it’s expected to be working with the release on 20180629 at https://www.sifive.com/products/tools/ ?

 

I create a demo program like following:

b.c:

int x[0x40000000];           // 4GB

int y;

 

main.c:

extern int x[0x40000000];

extern int y;

__attribute__((noinline)) void fooA(long a, long b) {

  asm volatile(""::"r"(a), "r"(b));  // to notify gcc that a/b are depended

}

 

int main() {

  fooA((long)x, y);             // to try both address access and load on an address

  return 0;

}

 

Then compile and link:

  • …/riscv64-unknown-elf-gcc main.c b.c -mcmodel=medany -save-temps -Os

I see following error:

main.o: In function `main':

main.c:(.text.startup+0x0): relocation truncated to fit: R_RISCV_PCREL_HI20 against symbol `y' defined in COMMON section in b.o

Here compiler generates “lla a5,y” and turn into “auipc” from objdump result with main.o. It looks a little bit strange with disassembly on relocators.

   0:   00000797                auipc   a5,0x0

   4:   00078793                mv      a5,a5

 

I see with -fPIC or -fPIE the build pass with -nostdlib. Here compiler generates “la a5,y” and turn into a “ld” for the symbol address:

   100b0:       00001797                auipc   a5,0x1

   100b4:       0587b783                ld      a5,88(a5) # 11108 <_GLOBAL_OFFSET_TABLE_+0x10>

 

While anyway we need std-libs in real projects and cannot go with -nostdlib. Is it expected to rebuild libraries instead?

 

Thanks and best regards.

 


This email message is for the sole use of the intended recipient(s) and may contain confidential information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.

Andrew Waterman

unread,
Aug 24, 2018, 2:08:22 AM8/24/18
to Sober Liu, RISC-V SW Dev (sw-dev@groups.riscv.org)
This is the expected behavior. If you want to have binaries with more than 2 GiB of static data, you must use PIC (including for library code you link against).

Of course, PIC imparts a code-size and performance degradation. You’re probably better off using malloc or mmap to allocate such large amounts of memory.

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/CY4PR12MB1221B633BC02CC6DB2D57A13AD360%40CY4PR12MB1221.namprd12.prod.outlook.com.

Sober Liu

unread,
Aug 24, 2018, 3:38:07 AM8/24/18
to Andrew Waterman, RISC-V SW Dev (sw-dev@groups.riscv.org)
Hi Andrew,
Thanks for the reply. I used a huge array here to simplify the demo. In our case we have linkscripts like following:
MEMORY {
code : ORIGIN = 0x00000000, LENGTH = 0x00010000
data : ORIGIN = 0x100000000, LENGTH = 0x00010000
}
The physical address for data memory starts from 4GB. And PA=VA in mbare mode.

Then I can revert b.c to normal size:
int x[0x10];
int y;

Build: riscv64-unknown-elf-gcc main.c b.c -mcmodel=medany -save-temps -Os -march=rv64imafd -nostdlib -T test.ld
The problem is same:
main.o: In function `main':
main.c:(.text.startup+0x0): relocation truncated to fit: R_RISCV_PCREL_HI20 against symbol `y' defined in COMMON section in b.o

Does it means for a binary to be linked, the address offset should be restricted to 2GB, for both code and data?

Best regards

From: Andrew Waterman <and...@sifive.com>
Sent: Friday, August 24, 2018 2:08 PM
To: Sober Liu <sob...@nvidia.com>
Cc: RISC-V SW Dev (sw-...@groups.riscv.org) <sw-...@groups.riscv.org>
Subject: Re: [sw-dev] Link issue (relocation truncated to fit) with large data offset

This is the expected behavior. If you want to have binaries with more than 2 GiB of static data, you must use PIC (including for library code you link against).

Of course, PIC imparts a code-size and performance degradation. You’re probably better off using malloc or mmap to allocate such large amounts of memory.

________________________________________
This email message is for the sole use of the intended recipient(s) and may contain confidential information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.
________________________________________
--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mailto:sw-dev+un...@groups.riscv.org.
To post to this group, send email to mailto:sw-...@groups.riscv.org.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/CY4PR12MB1221B633BC02CC6DB2D57A13AD360%40CY4PR12MB1221.namprd12.prod.outlook.com?utm_medium=email&utm_source=footer.

Andrew Waterman

unread,
Aug 24, 2018, 4:38:14 AM8/24/18
to Sober Liu, RISC-V SW Dev (sw-dev@groups.riscv.org)
On Fri, Aug 24, 2018 at 12:38 AM, Sober Liu <sob...@nvidia.com> wrote:
Hi Andrew,
Thanks for the reply. I used a huge array here to simplify the demo. In our case we have linkscripts like following:
MEMORY {
    code :  ORIGIN = 0x00000000, LENGTH = 0x00010000
    data :  ORIGIN = 0x100000000, LENGTH = 0x00010000
}
The physical address for data memory starts from 4GB. And PA=VA in mbare mode.

Then I can revert b.c to normal size:
int x[0x10];
int y;

Build: riscv64-unknown-elf-gcc main.c b.c -mcmodel=medany -save-temps -Os -march=rv64imafd -nostdlib -T test.ld
The problem is same:
main.o: In function `main':
main.c:(.text.startup+0x0): relocation truncated to fit: R_RISCV_PCREL_HI20 against symbol `y' defined in COMMON section in b.o

Does it means for a binary to be linked, the address offset should be restricted to 2GB, for both code and data?

Yes, that's right.  Part of this is fundamental to RISC-V.  It takes a bunch of instructions to implement PC-relative addressing (or even absolute addressing) with larger offsets.  Because of this, and the perceived lack of need, we haven't yet made a "large" code model.

We should do that eventually, but in the mean time, the best workaround is to put the code and the data closer together somehow.  PIC is not a great workaround, because it won't handle static variables the way you want (the compiler will use PC-relative addressing for these, rather than GOT-indirect addressing).

To unsubscribe from this group and stop receiving emails from it, send an email to mailto:sw-dev+unsubscribe@groups.riscv.org.

Sober Liu

unread,
Aug 24, 2018, 4:55:39 AM8/24/18
to Andrew Waterman, RISC-V SW Dev (sw-dev@groups.riscv.org)

Hi Andrew,

Thanks for the confirmation.

It’s clear for us now. We will think about whether to update the PA layout to make code/data region closer, or to avoid PA=VA in big address mode.

 

Best regards.

To unsubscribe from this group and stop receiving emails from it, send an email to mailto:sw-dev+un...@groups.riscv.org.

Reply all
Reply to author
Forward
0 new messages