ivo Welch
ivo Welch

Reputation: 2876

ld: 32-bit RIP relative reference out of range in simple gcc program

related to "ld: 32-bit RIP relative reference out of range" on Mac OSX but not solved and in a more complex context. the relevant computer(s) have >32GB of RAM.

static const int K=1024;
static const int M=K*K;
static const int G=K*M;

const int MC = G;

void donada(float *rvec, const int MC) { rvec[MC-1]= 1.0; return; }

float notused[1][MC]; // 4GB, ramp up with first index
float used[MC]; // 4GB

int main() {
  donada( used, MC );
  donada( notused[1], MC );
}

and gcc -Wall -o test test.cc. compiling this program not on osx yields

ld: 32-bit RIP relative reference out of range (4294967395 max is +/-2GB): from _main (0x100000F92) to _used (0x200001000) in '_main' from /var/folders/yl/8gp3pgbn1l562ywg_q86rk6800\ 00z9/T/test-b3bebf.o for architecture x86_64

on linux, there is a similar error

test.cc:(.text+0x18): relocation truncated to fit: R_X86_64_32 against symbol `used' defined in .bss section in /tmp/ccqcNh2C.o

I first thought compiler flag -Os would fix this, but it does not. It would be appropriate for gcc or clang to provide a more suggestive error message.

Upvotes: 0

Views: 4106

Answers (1)

Employed Russian
Employed Russian

Reputation: 213887

the relevant computer(s) have >32GB of RAM.

That's actually not very relevant. The issue is that 64-bit GCC defaults to -mcmodel=small, and you are trying to access data that is 4GiB away from its base symbol, which is not comatible with the small model.

From documentation:

-mcmodel=small
Generate code for the small code model: the program and its symbols
must be linked in the lower 2 GB of the address space. Pointers are 64 bits.
Programs can be statically or dynamically linked. This is the default code model. 

-mcmodel=medium
Generate code for the medium model: The program is linked in the lower 2 GB
of the address space. Small symbols are also placed there.
Symbols with sizes larger than -mlarge-data-threshold are put into large data
or bss sections and can be located above 2GB. 
Programs can be statically or dynamically linked.

-mcmodel=large
Generate code for the large model: This model makes no assumptions about addresses
and sizes of sections.

To correctly link your program, you need to use -mcmodel=large.

However note that this is not well tested (almost nobody does that), and that all code you (statically) link into your program will need to be built that way.

It is probably much better to dynamically allocate your arrays instead.

I first thought compiler flag -Os would fix this

It can't: -Os minimizes code size. Your program is that you are forcing the compiler to allocate very large contiguous data array. There is nothing the compiler could optimize for size there.

Upvotes: 3

Related Questions