问题标签 [position-independent-code]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
53 浏览

assembly - RIP 在编译时注册

链接器或编译器在编译期间是否计算 RIP?如果不是,该指令如何工作?链接时地址会被硬编码,还是处理器架构的特殊功能允许在运行时进行指针运算?

0 投票
1 回答
120 浏览

gcc - 为什么动态库源代码应该使用与位置无关的代码编译?

我对与位置无关的代码及其在动态库中的使用感到非常困惑。

我发现了这个关于 GCC 的 -fPIC 选项的好例子:GCC -fPIC 选项 ,我弄清楚了它是如何工作的。

但是,我很难理解为什么动态库需要独立于特定地址的代码。加载动态库时,为什么我们不能只保存其绝对地址(例如库中函数的地址)并使用它们?为什么在这种情况下必须使用相对地址?

用“gcc main.c”编译的简单程序int main() { return 0; }总是依赖于位置?

0 投票
0 回答
37 浏览

assembly - nasm:“符号 rip 未定义” - 如何使用相对于“rip”寄存器的 lea 指令?

我想将指令lea rax, [rip + 0x1020304]与 NASM 一起使用,但似乎它不允许使用rip.

GAS(GNU 汇编程序)确实允许数字和符号的这种语法(如何在 x86-64 GAS 英特尔语法中使用 RIP 相对变量引用,如“[RIP + _a]”?)。如何使用 NASM 实现这一目标?

0 投票
1 回答
149 浏览

assembly - nasm:在运行时从 rip(指令指针)获取重定位二进制文​​件的偏移量

我有一个适用于 x86_64 的 multiboot2 兼容 ELF 文件,其中开始符号在start.asmNASM 程序集文件中定义。multiboot2 标头包含relocatable标记。

因为 GRUB 不支持 multiboot2 + 可重定位的 ELF(至少在 2021 年 7 月 [ 3 ]),所以我想自己解决一些重定位问题以解决此问题并仅加载静态 ELF。

为此,我需要在运行时在我的第一个条目符号(在 ELF 标头中指定)中获取偏移量,以便手动解决重定位问题。偏移量是指 GRUB 在内存中定位二进制文​​件的位置与 ELF 文件中符号的静态地址之间的差异。

在我的输入符号中,我处于 ​​64 位长模式。无法直接rip以 NASM 语法访问,因此我需要某种解决方法。

[ 1 ] [ 2 ] 之类的解决方案不起作用,因为rip关键字/寄存器在 NASM 中不可用。因此我不能使用

我该如何解决这个问题?

0 投票
0 回答
58 浏览

assembly - NASM 如何找到这个标签地址?

我想知道 NASM 如何处理这段代码:

只需让您知道它是由引导加载程序在 0x1000 加载的,并且引导加载程序在跳转到 0x1000(这段代码)之前进入保护模式(设置 GDT 的段覆盖整个内存,设置段寄存器......):

当我在单独的文件中编译这段代码时,NASM如何知道内存中测试标签的地址进行跳转(应该是0x1000 +文件差异)?因为它有效,但我不明白如何。

0 投票
0 回答
81 浏览

gcc - 如何使用 nasm 和 ld 生成与位置无关的可执行文件?

我有一个简单的 nasm 代码:

test.nasm

我构建它如下:

然后我尝试运行它:

它给了我这个:

所以我检查了文件头:

它显示了这一点:

但是我可以很容易地使用 GCC 为以下程序创建一个与位置无关的可执行文件:

测试2.c

我用以下方式构建它:

它像这样运行:

那么如何使用而不是共享对象创建与位置无关的可执行文件nasmld

加 1

我检查了test2ELF 标头。它也是一个共享对象。所以这可能不是问题。(感谢@Nate Eldredge)

那么如何使用ld生成的目标文件获取与位置无关的可执行文件nasm

0 投票
1 回答
144 浏览

gcc - 位置无关的可执行文件和固定入口点地址

可以从虚拟地址空间内的任意地址加载和运行与位置无关的 ELF 可执行文件。

我尝试构建以下简单程序:

馅饼.c

构建命令:

可执行文件的 ELF 标头是:

馅饼

所以入口点地址是固定的。

它是_start那里的符号:

所以这意味着_start必须放在0x530.

这与位置独立不是矛盾的吗?

2021 年 8 月 16 日上午 10 点 44 分添加

我试图在没有-pie标志的情况下构建相同的程序:

生成的 ELF 头是:

pie_not

我进一步比较了构建的结果piepie_not. 它们的二进制文件是相同的。

那么操作系统如何判断哪一个应该被视为与位置无关的代码呢?

添加 2 - 2021 年 8 月 16 日上午 10:56

我想我想通了。似乎 gcc-pie默认使用。为避免这种情况,我必须-no-pie明确添加标志。

而生成的ELF头是这样的:

pie_not

我相信加载器依赖于 ELF 标头中的类型来决定如何处理二进制文件。

0 投票
0 回答
12 浏览

linux - 在 PIC(位置无关代码)中编译的可执行文件的行为

我以前在 Linux 中编译共享库时使用了-fPIC选项,但当时我对 PIC 了解不多,所以我只是把它当作约定来输入。

最近我在wiki和几个网站上读到了PIC,我想我现在理解了一般概念。但是,我发现-fPIC不仅在编译和链接共享库时包含选项,而且在可执行文件a.out(例如,我用 C++ 测试了一个简单的 Hello world 程序,有无-fPIC选项,两者都运行良好,没有任何错误。

在这种情况下,我想知道-fPIC行为上的差异是什么。我所得到的只是地址和_GLOBAL__sub_I_(sth)检查的细微差别objdump -t-fPIC另外,我很好奇在使用选项编译可执行文件时是否会有任何有害影响。

提前致谢!

0 投票
0 回答
17 浏览

gcc - 在 GCC 中创建和上传 PIC

假设我希望创建将由 MCU 动态加载的与位置无关的代码。

GCC 允许编译 PIC,但我不确定获得最终二进制输出的过程是什么。

为了澄清,假设我已经实现了一个自包含的 C 函数(没有全局变量)。我的 MCU 上有一个单独的 RTOS,它将下载此功能并在特定地址运行它。

编译这个函数并获取二进制图像上传到MCU的过程是什么?在这种情况下,我的链接器脚本会是什么样子?