[root@wdctc1281 bin]# ldd node
linux-vdso.so.1 => (0x00007fffd33f2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f70f7855000)
librt.so.1 => /lib64/librt.so.1 (0x00007f70f764d000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f70f7345000)
libm.so.6 => /lib64/libm.so.6 (0x00007f70f7043000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f70f6e2d000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f70f6c10000)
libc.so.6 => /lib64/libc.so.6 (0x00007f70f684f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f70f7a61000)
Run Code Online (Sandbox Code Playgroud)
第一行和最后一行是什么意思?它们看起来不像正常
xxxx.so => /lib64/xxxxx.so (0xxxxxxxxxxxxxxxxxxxx)
Run Code Online (Sandbox Code Playgroud)
格式.
在现代linux中,几乎所有对象都被剥离并分成两部分(两个文件).第一个是可执行的,第二个是调试符号,从原始ELF中删除.这样的文件是用
objcopy --only-keep-debug original.elf binary.dbg
mv original.elf binary
objcopy --strip-debug binary
Run Code Online (Sandbox Code Playgroud)
我该如何合并binary和binary.dbg成ELF文件,调试信息?我想重新创建未经剥离的原始二进制文件.它可以不是与原始字节相同的字节到字节,但必须在其中包含调试符号.
PS是的,我知道gnu.debuglink部分,但它不适用于某些调试器(etnus)和反汇编程序(objdump无法恢复符号信息)
我正在将现有系统从Windows移植到Linux.构建由多个静态库构成.我遇到了一个链接错误,其中在libB的对象中找不到符号(在libA中定义).链接器行看起来像
g ++ test_obj.o -lA -lB -o test
当然是由时间链接器找到它需要从利巴符号的问题,它已经过去了吧,不会重新扫描,因此它只是出现了错误,即使符号是有服用.
我最初的想法当然是简单地交换链接(到-lB -lA),以便之后扫描libA,并且拾取libA中缺少的任何符号.但后来我发现libA和libB之间实际上存在递归依赖关系!我假设Visual C++链接器以某种方式处理它(默认情况下是否重新扫描?).
处理这个问题的方法我考虑过:
使用共享对象.不幸的是,从需要PIC补偿的角度来看这是不可取的(这是性能敏感的代码并且丢失%ebx以保持GOT真的会受到伤害),并且不需要共享对象.
构建所有对象的一个巨大的ar,避免问题.
重构代码以避免递归依赖(这显然是正确的事情,但我试图用最小的更改来做这个端口).
你有其他想法来解决这个问题吗?有没有什么方法可以说服binutils链接器执行它已经在缺少符号时已经查看过的库的重新扫描?
他们的位置是硬编码为gcc代码还是gcc只是调用as,我们必须as在PATH变量中有位置?
在后一种情况下,我们如何创建两个完全独立的gcc工具链?我的意思是,我们怎样才能使gcc-A调用as-A和gcc-B调用as-B,如果as-A和as-B都称为as?
我需要在我的应用程序中使用objdump和readelf命令在Windows上运行.我知道我可以安装cygwin以便使用它们.我之所以不想使用cygwin是因为我想让它的文章部署.另外我不知道如何安装cygwin.因此,我认为我需要的是GNU Utilities For Win32,因为链接声明这些库是无服务器的."可执行文件仅依赖于Microsoft C-runtime(msvcrt.dll),而不依赖于Cygwin工具提供的仿真层"
无论如何,一旦我去那个链接,我不知道如何安装它.具体来说,我想使用>这个工具<
如果有人可以指出我将如何在我的应用程序中使用objdump和readelf(binutils in cygwin),我将不胜感激.
我正在尝试使用BFD库,所以我已经安装了包binutils-dev并且包括:
#include <bfd.h>
Run Code Online (Sandbox Code Playgroud)
和我打电话bfd_openr,并bfd_close从我的代码等等.
最近我升级了包,现在我从这里得到一个错误:
bfd.h:
/* PR 14072: Ensure that config.h is included first. */
#if !defined PACKAGE && !defined PACKAGE_VERSION
#error config.h must be included before this header
#endif
Run Code Online (Sandbox Code Playgroud)
......我应该包括config.h- 但我没有使用autoconf.
我是否包含错误的头文件?你怎么用binutils-dev?
这是一个演示程序:
#include <stdio.h>
#include <bfd.h>
int main()
{
bfd_init();
bfd* file = bfd_openr("a.out", 0);
if (!file)
return -1;
if (bfd_check_format(file, bfd_object))
printf("object file\n");
else
printf("not object file\n");
bfd_close(file);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尝试编译并运行如下:
$ sudo apt-get install binutils-dev
$ …Run Code Online (Sandbox Code Playgroud) 我已经更新了我的arm-none-eabi GCC 和相关工具,并重建了我开发的嵌入式项目。
$ arm-none-eabi-ld --version
GNU ld (GNU Binutils) 2.39
Run Code Online (Sandbox Code Playgroud)
突然,我收到警告
/usr/lib/gcc/arm-none-eabi/12.1.0/../../../../arm-none-eabi/bin/ld: warning: my_elf_file.elf has a LOAD segment with RWX permissions。
这个警告似乎是新引入的。我最近没有更改源/链接描述文件。(编辑:我检查了使用先前版本创建的旧 ELF 文件。它在链接过程中没有打印警告,但有相同的问题)。我为 STM32F407 微控制器进行开发。我的链接器脚本中的内存配置如下:
MEMORY
{
FLASH (xr) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
Run Code Online (Sandbox Code Playgroud)
查看链接的 ELF 我看到:
$ readelf -l my_elf_file.elf
Elf file type is EXEC (Executable file)
Entry point 0x800b1f1
There are 5 program headers, …Run Code Online (Sandbox Code Playgroud) 作为一个练习来更准确地学习c程序如何工作以及程序能够使用libc必须存在的最低内容级别,我自己尝试使用gas和ld主要在x86程序集中进行编程.
作为一个有趣的小挑战,我已成功组装并链接了几个链接到不同自制动态库的程序,但是我无法从头开始编写程序以使用libc函数调用而无需直接使用gcc.
我了解单个c库函数的调用约定,并通过使用objdump和readelf彻底检查了gcc编译的程序,但是在气体汇编文件中包含哪些信息以及要调用的参数方面没有任何进展在ld中成功链接到libc.有人对此有任何见解吗?
我在x86机器上运行Linux.
我正在构建类似于如何将来自不同.a文件的数据收集到一个数组中的问题?如何使用ld脚本保留.a文件中的节?,即在链接时组成的数组,来自不同目标文件的元素.
在我的例子中,有几个数组,每个数组都进入它自己的部分,.ld_comp_array_*,其中*匹配数组的名称.然后我使用ld --verbose获取默认链接描述文件,并通过将所有这些部分(排序,以便不同数组的元素不混合)修改为输出部分来修改它:
KEEP (*(SORT_BY_NAME(.ld_comp_array*)))
Run Code Online (Sandbox Code Playgroud)
一切正常.
事情变得有点复杂,因为使用这个功能的应用程序可以为各种平台构建 - 到目前为止,我已成功尝试AVR Xmega作为目标平台,以及Windows 32位和Linux 32-和64位用于单元测试,列表是开放的(新平台很可能在不久的将来添加).
但是,对于每个特定平台,默认链接器脚本与其他平台上的不同,目前我手动插入.ld_comp_array*部分 - 是否可以以某种方式自动执行?我想到的唯一解决方案是解析默认脚本并粘贴上面的输入节描述,但这看起来太沉重了.
如果没有相对简单的解决方案,我可以手动完成它,但我不确定从本地版本的ld获得的默认脚本是否可能在不同版本的binutils上中断.任何人都可以澄清这是否安全?
如果它可以自动完成,是否可以将输入节规范"直接"注入到.text部分,假设数组应该是"不可变的"?
查看手册,objdump并nm具有重叠功能.
你什么时候使用每一个?每个命令的最初目的是什么?