2013-04-21 78 views
2

我正在学习ELF.I想要在链接共享库时找到位置依赖的可执行文件和位置无关的可执行文件之间的elf格式的区别。如何在与gcc中的共享库链接时生成可执行文件的位置相关代码?

但是,当与共享库链接时,我无法生成可执行文件的位置相关代码。

/*Lib.c*/ 
static int a; 
extern int b; 
int c=1; 
extern void exit(); 
void set_value() 
{ 
    a=1; 
    b=1; 
    c=1; 
} 
void run() 
{ 
    set_value(); 
    exit(); 
} 

拳,使用GCC到genrnate共享动态库:

gcc -m32 -nostdlib -o Lib.so Lib.c 

请注意,我不使用-fpic产生的Lib.so.位置无关的代码

现在,我有需要Lib.so链接另一个main.c文件:

/*main.c*/ 
extern void run(); 
int b=2; 
void nomain() 
{ 
    run(); 
} 
void exit() 
{ 
    asm("int $0x80 \n\t" 
     ::"a"(1),"b"(42)); 

} 

使用下列命令来与Lib.so链接的main.c:

gcc -m32 -e nomain -nostartfiles -fno-builtin -o a.out main.c ./Lib.so 

Howerve ,gcc会在与共享库链接时默认地将main.c编译为与位置无关的代码,即使该库不使用pic。

我不知道是否gcc有一些选项,以genernate位置相关的可执行文件?

我发布了Lib.so和a.out的部分信息。我们可以看到a.out中有'.plt'和'.got.plt'部分,这意味着a.out使用PIC。

/*Section for Lib.so*/ 
    Section Headers: 
    [Nr] Name    Type   Addr  Off Size ES Flg Lk Inf Al 
    [ 0]     NULL   00000000 000000 000000 00  0 0 0 
    [ 1] .gnu.hash   GNU_HASH  000000b4 0000b4 00003c 04 A 2 0 4 
    [ 2] .dynsym   DYNSYM   000000f0 0000f0 000090 10 A 3 1 4 
    [ 3] .dynstr   STRTAB   00000180 000180 000030 00 A 0 0 1 
    [ 4] .rel.dyn   REL    000001b0 0001b0 000028 08 A 2 0 4 
    [ 5] .text    PROGBITS  000001d8 0001d8 000033 00 AX 0 0 4 
    [ 6] .dynamic   DYNAMIC   0000120c 00020c 000078 08 WA 3 0 4 
    [ 7] .got.plt   PROGBITS  00001284 000284 00000c 04 WA 0 0 4 
    [ 8] .data    PROGBITS  00001290 000290 000004 00 WA 0 0 4 
    [ 9] .bss    NOBITS   00001294 000294 000004 00 WA 0 0 4 
    [10] .comment   PROGBITS  00000000 000294 00002e 00  0 0 1 
    [11] .shstrtab   STRTAB   00000000 0002c2 00006a 00  0 0 1 
    [12] .symtab   SYMTAB   00000000 00055c 000170 10  13 15 4 
    [13] .strtab   STRTAB   00000000 0006cc 000057 00  0 0 1 
    /*Section for a.out*/ 
    Section Headers: 
    [Nr] Name    Type   Addr  Off Size ES Flg Lk Inf Al 
    [ 0]     NULL   00000000 000000 000000 00  0 0 0 
    [ 1] .interp   PROGBITS  080480f4 0000f4 000013 00 A 0 0 1 
    [ 2] .gnu.hash   GNU_HASH  08048108 000108 000034 04 A 3 0 4 
    [ 3] .dynsym   DYNSYM   0804813c 00013c 000070 10 A 4 1 4 
    [ 4] .dynstr   STRTAB   080481ac 0001ac 000037 00 A 0 0 1 
    [ 5] .rel.plt   REL    080481e4 0001e4 000008 08 A 3 6 4 
    [ 6] .plt    PROGBITS  080481ec 0001ec 000020 04 AX 0 0 4 
    [ 7] .text    PROGBITS  0804820c 00020c 000020 00 AX 0 0 4 
    [ 8] .dynamic   DYNAMIC   0804922c 00022c 000090 08 WA 4 0 4 
    [ 9] .got.plt   PROGBITS  080492bc 0002bc 000010 04 WA 0 0 4 
    [10] .data    PROGBITS  080492cc 0002cc 000004 00 WA 0 0 4 
    [11] .comment   PROGBITS  00000000 0002d0 00002e 00  0 0 1 
    [12] .shstrtab   STRTAB   00000000 0002fe 00006d 00  0 0 1 
    [13] .symtab   SYMTAB   00000000 0005c4 000160 10  14 15 4 
    [14] .strtab   STRTAB   00000000 000724 000051 00  0 0 1 
+1

你想在这里解决什么问题? – NPE 2013-04-21 06:44:10

+0

我正在学习ELF.I想要在链接共享库时找到位置依赖的可执行文件和位置无关的可执行文件之间的elf格式的区别。 – 2013-04-21 06:57:10

+0

您的平台的'strip' * *可能*能够移除重定位信息。 – NPE 2013-04-21 06:58:09

回答

0

你应该编译Lib.sogcc -Wall -Wextra -m32 -shared -Wl,-soname,Lib.so -o Lib.so Lib.c

你在这里做的只是生成一个没有重定位信息的普通程序。

看看这tutorial了解更多关于动态库。

注意另外,不要忘记设置您的LD_LIBRARY_PATH环境变量,以指向Lib.so

+0

你是什么意思“没有重定位信息的正常程序”,实际上在a.out和Lib.so中存在.rela.dyn。 – 2013-04-21 07:23:46

+0

对不起,但我想你可能不了解我的问题。 – 2013-04-21 07:30:20

+0

我真的没有看到你的观点......此外,在程序中使用'asm'原语不能与生成PIC代码一起完成。这个解释很简单。这是因为编译器不能控制你在'asm(...)'中写的内容,所以它不能确保你生成'-fPIC'代码。 – perror 2013-04-21 07:42:48

相关问题