为什么 gcc 在显然不需要时生成 PLT?

问题描述

考虑这个代码:

int foo()

gcc -o main main.c -lfoo -nostdlib -m32 -O2 -e main --no-pic -L./shared 在共享对象中实现。

使用 $ objdump -d ./main ./main: file format elf32-i386 Disassembly of section .plt: 00000240 <.plt>: 240: ff b3 04 00 00 00 pushl 0x4(%ebx) 246: ff a3 08 00 00 00 jmp *0x8(%ebx) 24c: 00 00 add %al,(%eax) ... 00000250 <foo@plt>: 250: ff a3 0c 00 00 00 jmp *0xc(%ebx) 256: 68 00 00 00 00 push $0x0 25b: e9 e0 ff ff ff jmp 240 <.plt> Disassembly of section .text: 00000260 <main>: 260: 8d 4c 24 04 lea 0x4(%esp),%ecx 264: 83 e4 f0 and $0xfffffff0,%esp 267: ff 71 fc pushl -0x4(%ecx) 26a: 55 push %ebp 26b: 89 e5 mov %esp,%ebp 26d: 51 push %ecx 26e: 83 ec 04 sub $0x4,%esp 271: e8 fc ff ff ff call 272 <main+0x12> 276: eb fe jmp 276 <main+0x16> 编译此代码会产生以下结构:

$ objdump -R ./main

./main:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE 
00000272 R_386_PC32        foo
00001ffc R_386_JUMP_SLOT   foo

具有以下重定位:

--no-pic

注意:

  1. 代码是用 foo() 编译的,所以它不是 PIC
  2. .text 部分(main 函数)中对 R_386_PC32 的调用通过 PLT。相反,它只是一个简单的 foo 重定位,我认为它会在加载时直接重定位到 foo 函数的地址。这对我来说很有意义,因为代码不是 PIC,所以不需要通过 PLT 添加额外的间接。
  3. 即使没有被使用,PLT 仍在生成。 R_386_JUMP_SLOT 的条目存在于那里,我们甚至有一个 foo 重定位来在加载时(PLT 指向的)在 GOT 中设置 xpath=//android.view.ViewGroup[@index='${StoryPhotonumber}'] 条目。

我的问题很简单:我没有看到在代码中的任何地方使用了 PLT,我也认为这里没有必要,那么为什么 gcc 会创建它?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)