gpt4 book ai didi

c - 与gcc中的共享库链接时如何为可执行文件生成位置相关代码?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:10:32 25 4
gpt4 key购买 nike

我正在学习ELF,我想在链接共享库时找到位置相关的可执行文件和位置无关的可执行文件的elf格式的区别。

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

/*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生成共享动态库:

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

请注意,我没有使用 -fpic 为 Lib.so 生成与位置无关的代码。

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

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

}

使用以下命令将 main.c 与 Lib.so 链接起来:

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

但是,即使这个库不使用 pic,gcc 也会默认将 main.c 编译为与共享库链接时与位置无关的代码。

我想知道 gcc 是否有一些选项来生成可执行文件的位置相关?

我贴出lib.so和a.out的section信息,可以看到a.out中有'.plt'和'.got.plt'section,表示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

最佳答案

您应该使用 gcc -Wall -Wextra -m32 -shared -Wl,-soname,Lib.so -o Lib.so Lib.c 编译您的 Lib.so >.

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

看看这个tutorial了解有关动态库的更多信息。

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

关于c - 与gcc中的共享库链接时如何为可执行文件生成位置相关代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16128617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com