ld:简单gcc程序中的32位RIP相对引用超出范围

问题描述:

"ld: 32-bit RIP relative reference out of range" on Mac OSX相关但尚未解决且处于更复杂的上下文中。相关的计算机具有> 32GB的RAM。ld:简单gcc程序中的32位RIP相对引用超出范围

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。编译该程序不是在OSX产量

LD:32位RIP相对参考超出范围(4294967395 max是 +/- 2GB):从_main(0x100000F92)从_used(0x200001000)在 '_main'的/ var /文件夹/基/ 8gp3pgbn1l562ywg_q86rk6800 \ 00z9/T /测试b3bebf.o为架构x86_64的

在Linux ,有一个类似的错误

test.cc:(.text+ 0x18):重定位被截断以适合:R_X86_64_32针对已定义的符号`used'在/tmp/ccqcNh2C.o

.bss节我首先想到的编译标志-Os可以解决这个问题,但事实并非如此。 gcc或clang提供更具启发性的错误信息是适当的。

相关计算机具有> 32GB的RAM。

这实际上并不十分相关。问题是64位GCC默认为-mcmodel=small,并且您尝试访问距基本符号4GiB以外的数据,该符号与小型模型不兼容。

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. 

要正确链接程序,你需要使用-mcmodel=large

但是请注意,这不是很好的测试(几乎没有人认为做),以及所有代码你(静态)链接到你的程序将需要建立这种方式。

改为动态分配数组可能好得多。

我首先想到的编译标志-Os可以解决这个问题

这不可能:-Os减少代码大小。你的程序是你迫使编译器分配非常大的连续的数据数组。编译器无法在其中优化大小。

+0

更复杂的代码,它然后抱怨'ld:警告:禁用PIE。绝对寻址(可能是-mdynamic-no-pic)在代码签名PIE中不允许,但在_...中使用' –