与链接器脚本链接时无法执行可执行文件

标签 c segmentation-fault clang linker-scripts

我不熟悉链接描述文件的概念。 所以我自己尝试使用简单的 C 程序和链接器脚本以及内存文件。

我试图为 c 程序传递自定义链接描述文件, 当我查看生成的内存文件时,我可以看到已初始化的变量位于链接描述文件中提到的地址。

但问题是我无法执行为 c 程序生成的可执行文件

这是我的c文件simpleHello.c

#include<stdio.h>
int g1 = 100;
int main(int argc , char *argv[])
{
printf("value of g1 is %d",g1);
return 0;
}

这是我的链接描述文件文件名 linker.ld

ENTRY(main)
SECTIONS
{
  . = ALIGN(4);
  . = 0x0000000000400410;
  .text : { *(.text) }
  . = 0x0000000000601038;
  .data : { *(.data) }
  .bss : { *(.bss) }
}

我正在运行下面的命令

clang simpleHello.c -g -Wl,-emain,-Map=o.map,-Tlinker.ld -ffreestanding -nostartfiles -nodefaultlibs -L/usr/lib/x86_64-linux-gnu -lc -o simple

如果我运行 ./simple

Segmentation fault (core dumped)

所以我用 gdb 调试了可执行文件,我得到了下面的结果。

gdb ./simple

Reading symbols from ./simple...done.
(gdb) b main
Breakpoint 1 at 0x40041f: file simpleHello.c, line 9.
(gdb) r
Starting program: Desktop/Memory-Map/programs/simple 

Breakpoint 1, main (argc=-134225560, argv=0x1) at simpleHello.c:9
9   printf("value of g1 is %d",g1);
(gdb) bt
#0  main (argc=-134225560, argv=0x1) at simpleHello.c:9
(gdb) 

所以问题与 argc 和 argv 或我传递的链接器文件有关。?

请针对此问题提出一些解决方案。

最佳答案

  1. 可执行文件的链接描述文件并不那么简单。您需要为应用程序和操作系统提供各种部分来加载和运行应用程序。

    请查看默认链接描述文件:

    • 在 Linux 上它们位于 /usr/lib/ldscripts - 至少在我尝试过的发行版中。
    • 在 Windows 上,它们在 <your-installation-path>\mingw64\x86_64-w64-mingw32\lib\ldscripts 中- 至少在我尝试过的安装中。
  2. 你把硬编码地址写成0x0000000000400410对于 .text在你的脚本中。你不能这样做,因为我们的临时操作系统会自行决定在何处加载这些部分。

因此,如果您喜欢使用链接描述文件,我建议您复制一个系统的链接描述文件并对其进行编辑。你需要哪一个,我不知道。

可能有一些选项可以让链接器显示它使用的是哪一个。您可以从标准编译命令和选项 -v 开始这会给你很多细节。但是您肯定需要阅读链接器的文档。

关于与链接器脚本链接时无法执行可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57488182/

相关文章:

c - 宏中的参数计数

C程序链表添加到末尾

c - 如何区分单位数和多位数作为C中的字符?

c++ - Clang 3.1 + libc++ 编译错误

c++ - 构建共享库时 G++ 和 clang++ 与标准库不兼容?

clang - clang 编译器中的堆栈保护等价物?

c++ - C 和 C++11 中系统时钟的性能

opengl - 与 OpenGL、SDL 和图形驱动程序相关的内存泄漏和错误

c++ - 为什么我的字符串分配会导致段错误?

c++ - C++ 中 pop_front() 的段错误