2017-10-14 183 views
0

"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提供更具啓發性的錯誤信息是適當的。

回答

2

相關計算機具有> 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中不允許,但在_...中使用' –