在为本机平台开发时,我可以使用ldd列出所有共享库(.so文件)我构建的二进制可执行文件将在启动时尝试加载.但是当交叉编译时,我不知道如何获得相同的信息.这ldd
不是一个普通的binutils实用程序,比如strip
或者ar
,可以和gcc
交叉编译一起构建,但相反,它是一个神秘的shell脚本,显然只能在本机平台上运行.
那么,使用跨目标binutils工具,有没有办法获得外部二进制文件的动态链接依赖项列表?
是否可以清除gdb的命令窗口?我的意思是,在gdb中是否有一个命令与clear
bash终端中的命令一样(对于命令窗口)?
我希望有人能够帮助解决我认为是链接器脚本问题的问题.
在添加对新函数的调用后,我遇到了一个奇怪的问题.没有函数调用,我的目标文件链接正确,但是,添加了新的函数调用,我得到一个未定义的引用来自另一个目标文件的符号(我已经验证它实际上是使用objdump存在).
同样奇怪的是,在函数调用存在的情况下,如果我首先使用ld -r链接所有目标文件(以提供可重定位的输出)然后使用我的链接脚本,则没有未定义的引用,但似乎链接脚本被忽略,因为输出二进制文件没有正确的入口点.
我的(交叉编译器)ld版本:
> i586-elf-ld --version
GNU ld(GNU Binutils)2.20.1.20100303
我试图证明存在"缺失"符号:
> i586-elf-ld -T link.ld -o kernel32.bin kernel_loader.o main.o stdio.o common.o gdt.o gdt.bin -y putch
Run Code Online (Sandbox Code Playgroud)main.o: reference to putch stdio.o: definition of putch main.o: In function `main': main.c:(.text+0x1f): undefined reference to `putch'
NB(当我生成此输出时,我使用gdt.bin的文件名作为nasm编译的汇编程序,它只是另一个.o文件,真的)
我可以在相应的目标文件中看到"缺失"的符号:
> i586-elf-objdump -ht stdio.o
stdio.o:文件格式elf32-i386Run Code Online (Sandbox Code Playgroud)Sections: Idx Name Size VMA LMA File off Algn 0 .text 000002f9 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 0000000c 00000000 00000000 00000330 2**2 CONTENTS, …
我尝试了以下内容,但生成的文件仍然是ELF,而不仅仅是部分内容.
$ objcopy --only-section=<name> <infile> <outfile>
Run Code Online (Sandbox Code Playgroud)
我只想要该部分的内容.有没有可以做到这一点的实用工具?有任何想法吗?
根据gcc构建说明,您可以与构建gcc(以及gmp,mpc等)同时构建binutils.
这是该页面所说的内容:
如果您还打算构建binutils(升级现有安装或用于代替OS的相应工具),请将binutils发行版解压缩到同一目录或单独的目录中.在后一种情况下,添加符号链接到您打算与编译器(bfd,binutils,gas,gprof,ld,opcodes,...)一起构建的binutils的任何组件到包含GCC源的目录.
同样,GMP,MPFR和MPC库可以与GCC一起自动构建.将GMP,MPFR和/或MPC源代码发行版解压缩到包含GCC源的目录中,并将其目录重命名为gmp,mpfr和mpc(或使用具有相同名称的符号链接).
这适用于gmp,mpc,mpfr,但我似乎无法建立所有binutils.我也无法弄清楚如何从binutils构建新的黄金链接器.有问题的版本是gcc-4.4.2和binutils-2.20.
一步一步的指导会很棒(对我来说,也适用于遇到这个问题的其他人).
我想重命名目标文件(.o)中的符号,其中的东西可能是与binutils objcopy --redefine-syms
工具相当的Mac .
我找不到arm-apple-darwin10-objcopy
.我尝试了MacPorts的arm-elf-binutils
端口,也试着玩了一下有otool
和segedit
没有取得多大成功.
有什么想法吗?
我试图在C++程序中的回溯中找到确切的调用行.现在我正在使用这些行(来自backtrace的手册页)来获取跟踪:
void *bt_buffer[1000];
char **bt_strings;
int bt_nptrs = backtrace(bt_buffer, 1000);
bt_strings = backtrace_symbols(bt_buffer, bt_nptrs);
Run Code Online (Sandbox Code Playgroud)
在bt_strings中,我找到了表单的行
./prog() [0x402e42]
Run Code Online (Sandbox Code Playgroud)
现在我取地址(十六进制字符串)并将其提供给addr2line.这有时会导致明显错误的行号.互联网搜索让我看到这篇文章,其中显示了这一点
readelf -wl ./prog
Run Code Online (Sandbox Code Playgroud)
表示该行的确实位置,或者表示该符号移动到当前行的行数.
编辑:这种情况发生在我编译时-g -O0
,即明确没有优化.编译器gcc 4.6.3
是否有我错过的另一个编译器标志?
我的问题如下:我需要自动执行此操作.我需要我的程序来创建一个回溯(完成),提取文件(完成)和行号(失败).
我当然可以调用readelf
和解析输出,但这并不合适,因为输出因符号而异,具体取决于具体发生的情况.有时符号的地址在一行中,而在下一行中有关行偏移的信息......
总结一下:
有没有一种优雅的方法可以在运行时从程序中的回溯中获取函数调用的确切行号?
编辑:示例代码:
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <execinfo.h>
#include <iostream>
#include <stdlib.h>
void show_backtrace()
{
// get current address
void* p = __builtin_return_address(0);
std::cout << std::hex << p << std::endl;
// get callee addresses
p = __builtin_return_address(1);
std::cout << std::hex …
Run Code Online (Sandbox Code Playgroud) 我正在试验Linux上纯静态链接的PIE可执行文件的概念,但是遇到了GNU binutils链接器在使用时坚持在输出二进制文件中添加PT_INTERP头的问题-pie
,即使在给出时也是如此-static
.有没有办法抑制这种行为?也就是说,有没有办法告诉GNU ld具体不要将某些标题写入输出文件?也许使用链接器脚本?
(请不要回答声称它不起作用;我很清楚该程序仍然需要重定位处理 - 仅由于我的使用而导致的加载地址相对重定位-Bsymbolic
- 并且我有特殊的启动代码代替Scrt1.o
处理这个问题的标准.但是,如果没有动态链接器已经开始并且正在进行工作,除非PT_INTERP
将二进制文件中的标题变为十六进制,否则我无法调用它.)
我正在用gcc hello.c -o hello -O3编译这段代码
#include <stdio.h>
int main(void) {
printf("Hello world\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我列出我得到的重新安置时:
test@southpark$ readelf -r hello | grep gmon
080495a4 00000106 R_386_GLOB_DAT 00000000 __gmon_start__
080495b4 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__
Run Code Online (Sandbox Code Playgroud)
当我列出这个文件中的符号时,我得到:
test@southpark$ readelf -s hello | grep gmon
1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
48: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Run Code Online (Sandbox Code Playgroud)
gmon_start与gprof有什么共同点吗?即使我没有使用-pg或-g编译/链接,为什么还要对该符号进行重定位?哪个库可以解析这个符号?
-l选项告诉链接器搜索标准目录中的库.使用-L,我们可以指定自己的库目录进行搜索.
问题:顺序顺序是否也与-L选项有关,就像-l wrt链接器一样?
这个链接:http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html没有多说-L的序列.
编辑 另外,
在默认目录之前搜索命令行中指定的目录
是来自手册页(正如Dmitry指出的那样),这是否意味着即使我指定的顺序如下:
gcc -lm hello.c -Lx
Run Code Online (Sandbox Code Playgroud)
仍然首先给出用-L指定的目录?