标签: relocation

谁执行运行时重定位?

我试图更好地理解 Linux 中的运行时重定位,特别是谁在不同情况下执行它们。以下是我目前的理解,是否准确?

  • 位置相关的静态链接可执行文件 - 无需运行时重定位
  • 动态链接的可执行文件 - 动态链接器 ( ld.so) 加载库,然后执行重定位
  • 静态链接 PIE - libc 启动代码执行重定位
  • 动态链接器本身 -ld.so是一个自重定位的二进制文件

谢谢

linux elf relocation dynamic-linking

7
推荐指数
1
解决办法
491
查看次数

我对符号表和重定位表的使用的理解是否正确?

我目前很难理解链接/加载概念。

您能告诉我以下关于符号和重定位表的使用的陈述是否正确?

  1. 在可重定位目标文件中,符号表必须包含从其他目标文件访问/调用的变量和函数的条目。未在目标文件外部使用的变量和函数的列表是可选的。
    • 这意味着如果程序仅包含一个目标文件,则可以省略符号表。
  2. 在可重定位目标文件中,重定位表保存在加载期间必须更新的汇编代码的所有位置的地址。
  3. 在不可重定位目标文件中,可以省略重定位表。但是,然后必须将对象加载到硬编码到指令中的地址空间中。

谢谢你的时间!

c symbols object relocation

6
推荐指数
1
解决办法
1276
查看次数

GCC 链接器:在指定部分移动一个符号

是否可以将代码中的某些功能移动到可执行文件的特定部分中?如果是这样,如何?

对于使用 gcc 编译的应用程序,我们有更多的源文件,包括 Xc 每个对象都是从关联的源(Xo 是从 Xc 获得的)编译的,并且链接器生成一个大的可执行文件。

我需要来自 Xc 的两个函数位于可执行文件的特定部分,例如 .magic_section。我想要这个的原因是该部分将被加载到另一个内存区域而不是其余部分。

我的问题是我不能更改源 Xc,否则我会使用特定的标志,例如__attribute__ ((section ("magic_section")))函数。

我在链接器的文档中阅读了一些内容并为链接器编写了一个自定义脚本,但是我没有指定必须将特定符号放置在哪个部分。我只设法移动了整个部分。

c linker gcc symbols relocation

6
推荐指数
1
解决办法
4451
查看次数

奇怪的链接器行为:重定位被截断以适应

我有一个带有两个绝对符号的内核的链接描述文件:_kernel_start_kernel_end.但是,我只收到链接器重定位错误_kernel_end:

In function `kernel::mem::mm::setup_memorymap':
/home/virtlink/kernel/src/mem/mm.rs:25:(.text._ZN3mem2mm15setup_memorymap):
  relocation truncated to fit: R_X86_64_PC32 against symbol `_kernel_end'
  defined in *ABS* section in ./kernel.bin
Run Code Online (Sandbox Code Playgroud)

这里有很多关于这个错误的问题,但我没有找到解决我特定问题的问题.

显然,这个:

_kernel_start = .;
Run Code Online (Sandbox Code Playgroud)

...被视为32位,而这:

. += KERNEL_BASE;
_kernel_end = . - KERNEL_BASE;
Run Code Online (Sandbox Code Playgroud)

...被视为64位.如果我将_kernel_end符号移动到. += KERNEL_BASE线上方,如下所示:

_kernel_end = .;
. += KERNEL_BASE;
Run Code Online (Sandbox Code Playgroud)

......然后再次运作.但我想_kernel_end在我的链接器脚本的末尾.

链接描述文件将引导代码放在内存开头,其余代码放在64位虚拟内存空间的上半部分.它看起来像这样:

OUTPUT_FORMAT(elf64-x86-64)

KERNEL_BASE = 0xFFFFFFFF80000000;

SECTIONS
{
    /* Boot code at 1 MiB */
    . = 1M;
    _kernel_start = .;
    .boot :
    {
        KEEP( *(.multiboot) …
Run Code Online (Sandbox Code Playgroud)

linker relocation osdev rust

6
推荐指数
0
解决办法
548
查看次数

解决部分链接中的相对重定位

我注意到使用-r部分链接实际上并没有解决任何重定位问题,即使它们可以通过相对寻址解决。例如,考虑f.og.of.of()这就要求g()g.o。在链接之前,拆卸和重定位按预期进行。然而,在部分链接到一个新文件h.o(通过ld -r -o h.o f.o g.o)之后,仍然存在对调用的重定位g(),即使理论上它可以用相对地址解析。

这是h.o( objdump -d h.o)的反汇编,包含f()g()。您可以看到对 的调用g()仍未解决:

h.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <f>:
   0:       55                      push   %rbp
   1:       48 89 e5                mov    %rsp,%rbp
   4:       e8 00 00 00 00          callq  9 <f+0x9>
   9:       90                      nop
   a:       5d                      pop    %rbp
   b:       c3                      retq

000000000000000c …
Run Code Online (Sandbox Code Playgroud)

linux relocation ld

6
推荐指数
1
解决办法
481
查看次数

编译错误:针对未定义的符号重新定位R_X86_64_PC32

我尝试用汇编语言创建函数并将它们放在动态库中,因此我使用此命令创建带有.S的.o
nasm -f elf64 hello.S -o hello.o
但是当我想用gcc创建lib时:
gcc -fPIC -shared hello.o -o libasm.so
它会显示以下错误:
/usr/bin/ld: hello.o: relocation R_X86_64_PC32 against undefined symbol printf@@GLIBC_2.2.5 can not be used when making a shared object; recompile with -fPIC

assembly makefile compilation dynamic relocation

6
推荐指数
1
解决办法
2806
查看次数

Cmake:将子项目目标导出到主项目

我目前有一个名为LIBS的项目,其结构如下:

??? Lib1
?   ??? CMakeLists.txt
?   ??? lib1-class.cpp
?   ??? lib1-class.h
??? lib2
?   ??? CMakeLists.txt
?   ??? lib2-class.cpp
?   ??? lib2-class.h
??? cmake
?   ??? LIBSConfig.cmake.in
??? CMakeLists.txt                                                           
Run Code Online (Sandbox Code Playgroud)

在主cmake文件中,我有:

install(
        TARGETS
        lib1
        lib2
        DESTINATION
        ${PROJECT_DIRNAME_lib}
        EXPORT
        ${PROJECT_NAME}Exports
)

install(
        EXPORT
        ${PROJECT_NAME}Exports
        DESTINATION
        ${PROJECT_DIRNAME_lib}
)
Run Code Online (Sandbox Code Playgroud)

因为我想将它们导出到find_package()可以发现的包中.

我的问题是我生成lib1lib2在各自的目录中安装它们时,Cmake告诉我

Error:install TARGETS given target "lib1" which does not exist in this directory.
Run Code Online (Sandbox Code Playgroud)

正如这里所建议的,我的理解是我应该Export()在lib1和lib2中使用以下形式的东西:

export(TARGETS lib1 FILE lib1Exports.cmake)
Run Code Online (Sandbox Code Playgroud)

LIBS项目中,有这样的事情:

ADD_LIBRARY(lib1 UNKNOWN …
Run Code Online (Sandbox Code Playgroud)

c++ cmake relocation

6
推荐指数
1
解决办法
3665
查看次数

目标文件重定位表中条目的含义

我在理解从 C 源文件编译的重定位表的条目时遇到了一些问题。我的程序如下:

//a.c
extern int shared;
int main(){
    int a = 100;
    swap(&a, &shared);
    a = 200;
    shared = 1;
    swap(&a, &shared);
}
//b.c
int shared = 1;
void swap(int* a, int* b) {
    if (a != b)
        *b ^= *a ^= *b, *a ^= *b;
}
Run Code Online (Sandbox Code Playgroud)

我使用以下命令gcc -c -fno-stack-protector a.c b.cld a.o b.o -e main -o ab. 然后我objdump -r a.o检查它的重定位表。

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE 
0000000000000014 R_X86_64_32       shared
0000000000000021 R_X86_64_PC32 …
Run Code Online (Sandbox Code Playgroud)

c linker x86-64 relocation

6
推荐指数
1
解决办法
1297
查看次数

如何区分.data.rel节中的可重定位符号和不可重定位符号

我正在尝试为准系统ARM应用程序创建一个简单的链接器。当前,加载模块的加载器只会将偏移量添加到.got.data.rel部分中的所有记录中。这适用于.got所有需要重定位的符号.data.rel。对于所有不可重定位的数据,它都会中断,因为那些数据也将获得此偏移量。

例:

void some_function() { return; }

struct a {
    void* fptr;
    int number;
};

static struct a = {
   .fptr = some_function,
   .number = 0x1000,
};
Run Code Online (Sandbox Code Playgroud)

此处a.fptr将正确解决该函数的实际位置,但a.number将错误地保持0x1000 + offset,而不是0x1000

我应该如何区分两者?.symtab仅检查该部分并仅重定位在此找到的地址就足够了吗?但是,如果符号实际上位于该位置0x1000怎么办?还是链接程序解决了这个问题(因此它将不会在address放置函数0x1000)?.symtabs实际上是否包含在.got和中可以找到的所有符号.data.rel

linker arm dynamic relocation

5
推荐指数
1
解决办法
1080
查看次数

什么是绝对符号以及如何在 C 中定义它?

在手册页中nm。它说

\n\n
\n

\xe2\x80\x9cA\xe2\x80\x9d 符号的值是绝对的,不会因进一步链接而改变。

\n
\n\n

但是,我不知道这意味着什么。如何在 C 中定义一个变量或其他东西以使其值绝对?

\n\n

test.c如果我在其文件范围内声明一个变量

\n\n
int a;\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在 的输出中nm,a 的条目在我的机器上将如下

\n\n
int a;\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我想知道我该怎么做才能使nm变量的输出 \xe2\x80\x9cA\xe2\x80\x9d 。而且我不知道 \xe2\x80\x9cabsolute\xe2\x80\x9d 是什么意思。

\n

c linker relocation ld linker-scripts

5
推荐指数
1
解决办法
3592
查看次数