我如何使用 objdump 之类的工具判断目标文件是否已使用 -fPIC 构建?

发布于 2024-08-02 14:46:24 字数 70 浏览 14 评论 0原文

如何使用 objdump 等工具判断目标文件是否已使用 -fPIC 构建?

How can I tell, with something like objdump, if an object file has been built with -fPIC?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

帝王念 2024-08-09 14:46:24

答案取决于平台。在大多数平台上,如果 from 的输出

readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'

为空,则说明 foo.o 未使用 -fPIC 进行编译,或者 foo.o 未使用 -fPIC 进行编译。包含 -fPIC 重要的任何代码。

The answer depends on the platform. On most platforms, if output from

readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'

is empty, then either foo.o was not compiled with -fPIC, or foo.o doesn't contain any code where -fPIC matters.

暮光沉寂 2024-08-09 14:46:24

我只需在 PowerPC 目标上执行此操作即可找到在没有 -fPIC 的情况下构建的共享对象 (.so)。我所做的是运行 readelf -d libMyLib1.so 并查找 TEXTREL。如果您看到 TEXTREL,则说明组成 .so 的一个或多个源文件不是使用 -fPIC 构建的。如有必要,您可以将 readelf 替换为 elfdump

例如,

[user@host lib]$ readelf -d libMyLib1.so | grep TEXT   # Bad, not -fPIC
 0x00000016 (TEXTREL)
[user@host lib]$ readelf -d libMyLib2.so | grep TEXT   # Good, -fPIC
[user@host lib]$

为了帮助人们寻找解决方案,我在运行可执行文件时遇到的错误是:

root@target:/# ./program: error while loading shared libraries: /usr/lib/libMyLi
b1.so:  R_PPC_REL24 relocation at 0x0fc5987c for symbol 'memcpy' out of range

我不知道此信息是否适用于所有体系结构。

来源:blogs.oracle.com/rie

I just had to do this on a PowerPC target to find which shared object (.so) was being built without -fPIC. What I did was run readelf -d libMyLib1.so and look for TEXTREL. If you see TEXTREL, one or more source files that make up your .so were not built with -fPIC. You can substitute readelf with elfdump if necessary.

E.g.,

[user@host lib]$ readelf -d libMyLib1.so | grep TEXT   # Bad, not -fPIC
 0x00000016 (TEXTREL)
[user@host lib]$ readelf -d libMyLib2.so | grep TEXT   # Good, -fPIC
[user@host lib]$

And to help people searching for solutions, the error I was getting when I ran my executable was this:

root@target:/# ./program: error while loading shared libraries: /usr/lib/libMyLi
b1.so:  R_PPC_REL24 relocation at 0x0fc5987c for symbol 'memcpy' out of range

I don't know whether this info applies to all architectures.

Source: blogs.oracle.com/rie

一枫情书 2024-08-09 14:46:24

我假设,您真正想知道的是共享库是否由使用 -fPIC 编译的目标文件组成。

正如已经提到的,如果有 TEXTREL,则不使用 -fPIC。

有一个很棒的工具,称为 scanelf,它可以向您显示导致 .text 重定位的符号。

更多信息请参阅如何定位和修复 .text 重定位 TEXTREL

I assume, what you really want to know is whether or not a shared library is composed from object files compiled with -fPIC.

As already mentioned, if there are TEXTRELs, then -fPIC was not used.

There is a great tool called scanelf which can show you the symbols that caused .text relocations.

More information can be found at HOWTO Locate and Fix .text Relocations TEXTRELs.

千鲤 2024-08-09 14:46:24

-fPIC 意味着代码将能够在与编译地址不同的地址中执行。

为此,反装器将如下所示......

call get_offset_from_compilation_address
get_offset_from_compilation_address: pop ax
sub ax, ax , &get_offset_from_compilation_address

现在在 axe 中,我们有一个偏移量,我们需要将其添加到对内存的任何访问中。

load bx, [ax + var_address}

-fPIC means that code will be able to execute in addresses different form the address that was compile for.

To do it , disasambler will look like this....

call get_offset_from_compilation_address
get_offset_from_compilation_address: pop ax
sub ax, ax , &get_offset_from_compilation_address

now in ax we have an offset that we need to add to any access to memory.

load bx, [ax + var_address}
人间☆小暴躁 2024-08-09 14:46:24
readelf -a *.so | grep Flags
  Flags:                             0x50001007, noreorder, pic, cpic, o32, mips32

这应该在大多数情况下都有效。

readelf -a *.so | grep Flags
  Flags:                             0x50001007, noreorder, pic, cpic, o32, mips32

This should work most of the time.

软的没边 2024-08-09 14:46:24

区分程序是否是通过 -fPIC 选项生成的另一个选项:

前提是您的代码在编译时启用了 -g3 -gdwarf-2 选项。

其他 gcc 调试格式也可能包含宏信息:

注意以下 $'..' 语法假定 bash

echo 

这样的方法有效,因为 gcc 手册声明如果使用 -fpic,则 PIC 定义为 1 , 和
如果使用-fPIC,PIC为2。

通过检查GOT的上述答案是更好的方法。因为我猜 -g3 -gdwarf-2 的预请求很少被使用。

main() { printf("%d\\n", \n#ifdef __PIC__\n__PIC__\n#else\n0\n#endif\n); }' | gcc -fPIC -g3 -gdwarf-2 -o test -x c - readelf --debug-dump=macro ./test | grep __PIC__

这样的方法有效,因为 gcc 手册声明如果使用 -fpic,则 PIC 定义为 1 , 和
如果使用-fPIC,PIC为2。

通过检查GOT的上述答案是更好的方法。因为我猜 -g3 -gdwarf-2 的预请求很少被使用。

Another option to distinguish whether your program is generated wit -fPIC option:

provided that your code has -g3 -gdwarf-2 option enabled when compiling.

other gcc debug format may also contains the macro info:

Note the following $'..' syntax is assumes bash

echo 

such a method works because gcc manual declares that if -fpic is used, PIC is defined to 1, and
if -fPIC used, PIC is 2.

The above answers by checking the GOT is the better way. Because the prerequest of -g3 -gdwarf-2 I guess seldom being used.

main() { printf("%d\\n", \n#ifdef __PIC__\n__PIC__\n#else\n0\n#endif\n); }' | gcc -fPIC -g3 -gdwarf-2 -o test -x c - readelf --debug-dump=macro ./test | grep __PIC__

such a method works because gcc manual declares that if -fpic is used, PIC is defined to 1, and
if -fPIC used, PIC is 2.

The above answers by checking the GOT is the better way. Because the prerequest of -g3 -gdwarf-2 I guess seldom being used.

分開簡單 2024-08-09 14:46:24

来自Linux 编程接口

在 Linux/x86-32 上,可以使用以下命令创建共享库
不使用 -fPIC 选项编译的模块。然而,这样做会失去
共享库的一些好处,因为程序文本页面
包含位置相关的内存引用不跨共享
流程。在某些架构上,不可能构建共享的
不带 -fPIC 选项的库。

为了确定现有的目标文件是否已被
使用 –fPIC 选项编译,我们可以检查是否存在
在目标文件的符号表中使用 _GLOBAL_OFFSET_TABLE_ 命名
以下任一命令:

<前><代码>$ nm mod1.o | grep _GLOBAL_OFFSET_TABLE_
$ readelf -s mod1.o | $ readelf -s mod1.o | grep _GLOBAL_OFFSET_TABLE_

相反,如果以下任一等效命令产生任何
输出,则指定的共享库至少包含一个对象
未使用 -fPIC 编译的模块:

$ objdump --all-headers libfoo.so | grep 文本
$ readelf -d libfoo.so | $ readelf -d libfoo.so | grep 文本

但是,上面的引用和这个问题的任何答案都不适用于 x86_64。

我在 x86_64 Ubuntu 机器上观察到的是,无论是否指定-fPIC,都会生成fPIC .o。这

gcc -g -Wall -c -o my_so.o my_so.c // has _GLOBAL_OFFSET_TABLE_
gcc -g -Wall -fPIC -c -o my_so_fpic.o my_so.c // has _GLOBAL_OFFSET_TABLE_

readelf -s my_so.o > 1.txt && readelf -s my_so_fpic > 2.txt && diff 1.txt 2.txt

没有区别,my_so.omy_so_fpic.o 都可以用来创建共享库。

为了生成非fpic目标文件,我在如何测试 Linux 二进制文件是否编译为位置无关代码? .

这有效,

gcc -g —Wall -fno-pic -c -o my_so_fnopic.o my_so.c // no _GLOBAL_OFFSET_TABLE_ 

gcc -g -Wall -shared -o libdemo.so my_so_fnopic.o 

给出错误:

/usr/bin/ld: my_so_fnopic.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
collect2: error: ld returned 1 exit status

无法使用非 pic .o 创建共享库。

From The Linux Programming Interface:

On Linux/x86-32, it is possible to create a shared library using
modules compiled without the –fPIC option. However, doing so loses
some of the benefits of shared libraries, since pages of program text
containing position-dependent memory references are not shared across
processes. On some architectures, it is impossible to build shared
libraries without the –fPIC option.

In order to determine whether an existing object file has been
compiled with the –fPIC option, we can check for the presence of the
name _GLOBAL_OFFSET_TABLE_ in the object file’s symbol table, using
either of the following commands:

$ nm mod1.o | grep _GLOBAL_OFFSET_TABLE_
$ readelf -s mod1.o | grep _GLOBAL_OFFSET_TABLE_

Conversely, if either of the following equivalent commands yields any
output, then the specified shared library includes at least one object
module that was not compiled with –fPIC:

$ objdump --all-headers libfoo.so | grep TEXTREL
$ readelf -d libfoo.so | grep TEXTREL

However, neither above quoting nor any answer of this question works for x86_64.

What I've observed on my x86_64 Ubuntu machine is that, whether specifying -fPIC or not, it would generate fPIC .o. That is

gcc -g -Wall -c -o my_so.o my_so.c // has _GLOBAL_OFFSET_TABLE_
gcc -g -Wall -fPIC -c -o my_so_fpic.o my_so.c // has _GLOBAL_OFFSET_TABLE_

readelf -s my_so.o > 1.txt && readelf -s my_so_fpic > 2.txt && diff 1.txt 2.txt

has no difference and both my_so.o and my_so_fpic.o can be used to create a shared library.

In order to generate non fpic object file, I found a gcc flag called -fno-pic in the first comment of How to test whether a Linux binary was compiled as position independent code? .

This works,

gcc -g —Wall -fno-pic -c -o my_so_fnopic.o my_so.c // no _GLOBAL_OFFSET_TABLE_ 

and

gcc -g -Wall -shared -o libdemo.so my_so_fnopic.o 

gives error:

/usr/bin/ld: my_so_fnopic.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
collect2: error: ld returned 1 exit status

can not create a shared library with non pic .o.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文