标签: binutils

为什么GNU ld在链接可执行文件与共享对象时以不同方式解析符号?

我有一个简单的C++代码,看起来像这样:

#include <boost/timer/timer.hpp>

int main(void) {
    boost::timer::auto_cpu_timer t;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我尝试编译并链接它(使用gcc 4.8.1和GNU ld 2.23.52.20130828),如下所示:

$ g++ -o test test.cc -lboost_timer
/usr/bin/ld: /tmp/cc2jP1jv.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

一种解决方案是-lboost_system在命令行上明确提及,这是有效的.但是,我也可以这样做:

$ g++ -Wl,--copy-dt-needed-entries -o test test.cc -lboost_timer
Run Code Online (Sandbox Code Playgroud)

根据ld文档"with --copy-dt-needed-entries命令行中提到的动态库将被递归搜索,跟随其DT_NEEDED标记到其他库,以便解析输出二进制文件所需的符号",所以这一切都有意义:ld正在从boost_timer中找出它还需要链接boost_system以解析所有符号.

但是,我意识到这也有效:

$ g++ -fPIC -shared -o test test.cc -lboost_timer
Run Code Online (Sandbox Code Playgroud)

显然,我现在已经生成了一个共享对象而不是一个可执行文件.显然,ld能够弄清楚它需要将该共享对象与boost_system链接:

$ ldd test | grep boost_system
        libboost_system.so.1.54.0 => /usr/lib/libboost_system.so.1.54.0 (0x00007f385246e000)
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:为什么在构建共享对象与可执行文件时,符号解析会有所不同?如何在没有指定的情况下ld能够确定我的共享对象应该与boost_system链接--copy-dt-needed-entries

c++ linker gcc ld binutils

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

为什么GNU binutils和GDB合并为一个包?

请参阅标签部分.

这个决定背后的理由是什么?合并是否会影响构建最新binutils和GDB的建议方式?(事实上​​当我检查binutils-2_25_1并跑步时make all && make install,我也得到了gdb.)

c++ linux gdb gnu-toolchain binutils

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

如何使用 autoconf 指定 #define 的值?

我正在尝试构建 Gnu binutils,通过定义宏SYSV386_COMPAT 0来改变它生成一些 FPU 操作码的方式,从而解锁行为。

我可以轻松地进入头文件并手动设置值,但是如何调用配置脚本才能#define SYSV386_COMPAT 0在命令行上指定等效项?如果可能的话,我更愿意在命令行上指定一些内容(只是因为该功能是可传递的,而且我认为我不应该破解源代码)。话虽如此,我已经尝试阅读至少一些 FM,但未能在或AC_DEFINE(SYSV386_COMPAT, 0)中插入。binutils/configure.ingas/configure.in

autoconf gnu-assembler fpu binutils c-preprocessor

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

使用 binutils 在目标文件之间复制 ELF 部分

由于错误,ld我需要将 ELF 部分从一个目标文件复制到另一个目标文件。我可以将所需的部分转储到文件中,但问题是该objcopy选项--add-section需要二进制文件,因此部分类型信息会丢失。据我所知,我无法使用 binutils 设置部分的类型,但我希望我错了:)

我可以手动编辑二进制文件以设置节类型并解决根本问题,但我很好奇是否有基于标准工具的解决方案。

对于好奇的人来说,潜在的问题是,当 GNUld链接没有该部分的 ARM 目标文件.ARM.attributes(例如在其自己的部分中只有一个二进制 blob 的文件)时,它会选择一些默认值,导致它甚至为 RAM 函数生成无效的胶合板当包含调用的文件有好的.ARM.attributes 部分时。我能想到的唯一解决方案(待定 https://sourceware.org/bugzilla/show_bug.cgi?id=11897.ARM.attributes )是向二进制 blob 对象文件添加一个部分。.ARM.attributes但是,只有当该部分的类型为时,这才有效ARM_ATTRIBUTES

linker elf binutils

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

如何找到全局静态初始化

我刚刚阅读了这篇出色的文章:http : //neugierig.org/software/chromium/notes/2011/08/static-initializers.html 然后我尝试了:https : //gcc.gnu.org/onlinedocs/gccint/Initialization .html

不过,它关于查找初始化程序的内容对我不起作用。该.ctors部分不可用,但我可以找到.init_array(另请参阅Can't find .dtors and .ctors in binary)。但是我如何解释输出?我的意思是,总结页面的大小也可以由size命令及其.bss列处理 - 或者我错过了什么?

此外,nm不报告任何*_GLOBAL__I_*符号,仅报告*_GLOBAL__N_*函数和 - 更有趣的 -_GLOBAL__sub_I_somefile.cpp条目。后者可能表示具有全局初始化的文件。但是我能以某种方式获得正在运行的构造函数列表吗?理想情况下,一个工具会给我一个列表

Foo::Foo in file1.cpp:12
Bar::Bar in file2.cpp:45
...
Run Code Online (Sandbox Code Playgroud)

(假设我有可用的调试符号)。有这样的工具吗?如果不是,那怎么写呢?该.init_array部分是否包含指向可以通过一些 DWARF 魔法转换为上述代码的指针?

c++ linux initialization global-variables binutils

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

objdump 不适用于 ELF 64 位 x86-64,

我有一个来自 Tiny C 编译器的 64 位 ELF 目标代码。我无法让 gobjdump 显示反汇编代码。我使用的是 OS X 10.10.5。

$ file hello.o 
hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
$ gobjdump -d hello.o
gobjdump: hello.o: File format not recognized

$ greadelf -h hello.o
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL …
Run Code Online (Sandbox Code Playgroud)

c binutils

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

Glibc vs GCC vs binutils 兼容性

是否有某种关于 binutils、glibc 和 GCC 之间版本兼容性的官方文档?我找到了这个用于 binutils 与 GCC 版本兼容性的矩阵。对于 GCC 与 glibc 也有这样的东西会很好。

我问这个问题的重点是,我需要知道我是否可以使用“嵌入式”glibc 2.2.4 构建跨 GCC 4.9.2,以便能够支持像 CentOS 5 这样的旧目标。

谢谢你。

c++ gcc glibc binutils

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

构建 binutils 时使用了哪些配置选项?

我有一个由某人编译的 binutils 版本。我需要使用相同的选项重新编译一个新的 binutils。

我知道这会gcc -v打印出配置选项。那么也许有什么方法可以读取binutils?

c linux gcc binutils toolchain

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

将 32 位和 64 位代码链接到一个二进制文件中

在对此问题的评论中, Unexpected Behaviour in simple Pointer Algoriths in kernel space C code 中,Michael Petch 写道,“64 位 ELF 格式支持 32 位代码段。”

我有一个工作程序,其中包含 32 位和 64 位代码以及它们之间的切换。我一直无法弄清楚如何将编译器生成的 32 位和 64 位代码链接在一起而不出现链接器错误,因此所有 32 位代码都是用汇编语言编写的。随着项目变得越来越复杂,32位汇编代码的维护也变得更加繁重。

这是我所拥有的:

test32.cc 是用-m32.
所有其他源文件都是在没有该标志的情况下使用-mcmodel=kernel.

在链接描述文件中:

OUTPUT_FORMAT("elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
Run Code Online (Sandbox Code Playgroud)

在生成文件中:

LD := ld
LDFLAGS := -Map $(TARGET).map -n --script $(LDSCRIPT)
$(LD) $(LDFLAGS) -b elf32-x86-64 $(OBJS64) -b elf32-i386 $(OBJS32) -o $@
Run Code Online (Sandbox Code Playgroud)

我收到错误:

ld: i386 architecture of input file 'test32.o' is incompatible with i386:x86-64 output
Run Code Online (Sandbox Code Playgroud)

将 OUTPUT_ARCH 更改为 …

gcc x86-64 osdev binutils

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

Alpine Linux 上的符号版本控制

musl C 库只有符号版本控制的近似实现。这可能导致具有不同符号版本的符号绑定在一起,这在完整实现中不会发生。因此,希望使用 musl 构建的项目最好完全避免符号版本控制。(不支持符号版本控制本身对于工具链来说不一定是一个糟糕的选择;这完全取决于目标受众。)

但是,Alpine Linux 工具链编译 binutils 时具有完整的符号版本支持:GAS 支持该.symver指令,链接编辑器处理版本脚本并分配符号版本(就像在 GNU/Linux 上一样)。一个简单的编译器/汇编器或链接检查显示符号版本支持。因此,Alpine Linux 在发行版中包含的一些共享对象实际上使用了符号版本控制,尽管 musl 动态加载器会忽略这些数据。(数据只会使二进制文件膨胀。)

在某些情况下,软件无法运行(在构建正常之后),因为它以 musl 动态链接器不支持的方式使用兼容性符号(没有默认版本的符号)。这是一个不起作用的小例子:

cat > symver.c <<EOF
void
compat_function (void)
{
}
__asm__ (".symver compat_function,compat_function@SYMVER");

void
call_compat_function (void)
{
  return compat_function ();
}
EOF

echo "SYMVER { };" > symver.map

cat > main.c <<EOF
extern void call_compat_function (void);

int
main (void)
{
  call_compat_function ();
}
EOF

gcc -fpic -shared -o symver.so -Wl,--version-script=symver.map symver.c
gcc -Wl,--rpath=. -o main …
Run Code Online (Sandbox Code Playgroud)

binutils musl alpine-linux

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