2017-10-10 28 views
4

如何使用最近(使用PIC啓用)gcc創建不可重定位符號? 我基本上要具備以下C程序打印NULL:如何創建不可重定位的符號

#include <stdio.h> 

extern int mem_; 

int main(void) { 
    printf("%p\n", &mem_); 
    return 0; 
} 

我想什麼是一個小的彙編文件:

.data 
    .globl mem_ 
    .type mem_,@object 
    .set mem_, 0 

但是這創造了一個重​​新定位的符號,它在運行時不具備值爲0.

背景:我試圖讓一箇舊的程序運行,它使用這個技巧以一個數組的形式從Fortran直接訪問(分配)內存。由於該程序具有»10 5 LOC,因此重寫所有內容都是不可行的。

[編輯] GNU彙編手冊documents an "absolute section"作爲

絕對段:本節始終是「搬遷」到運行地址0。這是有用的,如果你想引用一個地址的地址0搬遷時ld不得改變。從這個意義上說,我們所說的絕對地址是「不可重新定位的」:它們在重定位期間不會改變。

這可能是我在這裏需要的(對吧?),但我找不到啓用此部分的方法。 .struct指令是documented to switch to the "absolute section";然而,下面的彙編程序無法正常工作或:

.globl mem_ 
    .struct 0 
mem_: 

的符號出現在這種情況下*ABS*objdump

$ objdump -t memc 

memc:  file format elf64-x86-64 
[...] 
0000000000000540 g  F .text 000000000000002b    _start 
0000000000201030 g  .bss 0000000000000000    __bss_start 
000000000000064a g  F .text 000000000000003c    main 
0000000000000000 g  *ABS* 0000000000000000    mem_ 
[...] 

,但它仍然是搬遷。

+1

使用['-fno-pie -no-pie']製作一個依賴於位置的可執行文件會不會很容易*(https://stackoverflow.com/questions/43367427/32-bit-絕對地址,不再視爲允許合的x86-64 Linux的)? –

+0

如果這是一個Fortran程序,爲什麼標記爲C而不是Fortran?如果你想從C傳遞數組到Fortran,爲什麼不通過'NULL'? – fuz

+0

Fortran只是問題背後的基本原理,但問題與其無關。基本上,我想通過NULL,但問題是如何做到這一點。只是'mem_ = NULL'不起作用,因爲它將符號的值設置爲NULL,而不是符號本身。 – olebole

回答

4

您可以在鏈接時把你的符號的節「fixedloc」,並指定地址:

#include <stdio.h> 
int mem_ __attribute__ ((section ("fixedloc"))); 

int main (void) { 
     printf("%p\n", &mem_); 
     return 0; 
} 

而且編譯

gcc -O2 mem.c -o mem -Wl,--section-start=fixedloc=0x1230000 

$ nm mem 
... 
00000000D mem 
... 
$ ./mem 
0x1230000 

注意,它不會與工作/掛靠如果/ proc/sys/vm/mmap_min_addr未設置爲0(默認值爲65536),並且即使如此,動態鏈接程序在其上扼殺,最近的linux內核上的位置0也是如此。但其他地址的工作完美無瑕。

+0

我認爲OP使用'_mem'作爲在Fortran中使用整數作爲指針的基地址。如果他們可以在源代碼中添加一個常量偏移量,那麼如果沒有辦法讓動態鏈接程序接受它,那麼可以繞過對_mem使用非零值(地址)。但可能更容易使用['-fno-pie -no-pie'](https://stackoverflow.com/questions/43367427/32-bit-absolute-addresses-no-longer-allowed-in-x86-64-如果這是一個選項,可以創建一個依賴於位置的可執行文件。 –

+0

不幸的是,這也行不通。我仍然獲得了mem_的另一個地址。我不明白'mmap_min'地址在這裏的作用:我當然不會直接訪問地址'0'。在Fortran中,mem_總是用於非零索引的數組。 – olebole

+0

@olebole我不明白這是行不通的。你在哪裏偏離了我在答案中出現的步驟?如果你完全重現它,你將不得不得到相同的結果。 – Ctx

相關問題