如果要将目标文件作为共享库(.so)加载,则编译代码到目标文件需要与位置无关,因为在不同进程中加载共享对象文件的基本虚拟地址可能不同.
现在,当我尝试在32位x86计算机上加载.so没有-fpicGCC选项编译和链接的文件时,我没有遇到错误,而在64位x86计算机上它失败了.
我发现的随机网站说我不需要-fpic在32位上,因为-fpic根据X86 32位ABI 编译而没有巧合的代码也是以与位置无关的方式使用的.但我仍然发现软件在32位版本中附带了不同版本的库:一个用于PIC,另一个用于非PIC.例如,intel编译器随附,libirc.a并且libirc_pic.a后者被编译为与位置无关的模式(如果想要将该.a文件链接到.so文件中).
我想知道使用-fpic和不使用它的确切区别是32位代码,以及为什么有些软件包(如intel编译器)仍然附带了不同版本的库?
我正在尝试编写一个可以解析核心转储文件的C程序.我的问题是,如何在C中获取导致核心转储的地址?我知道可以从这个答案中使用gdb获取地址:
但我想直接在C中检索地址.任何信息都将受到高度赞赏.谢谢!
注意:我知道如何将核心转储解析为精灵.但我不知道如何获得导致段错误的地址.
似乎有一些类似的长字母数字字符串,通常出现在Mach-O 64位可执行文件和ELF 64位LSB可执行文件以及其他不是字母数字的符号中:
cat /bin/bash | grep -c "AWAVAUATSH"
Run Code Online (Sandbox Code Playgroud)
有181个结果,和
cat /usr/bin/gzip | grep -c "AWAVAUATSH"
Run Code Online (Sandbox Code Playgroud)
有9个结果.
这些字符串是什么?
我使用LSB SDK构建了一个测试ELF程序(注意我的问题不是LSB特有的):
$ /opt/lsb/bin/lsbcc tst.c
$ ls -l a.out
-rwxr-xr-x 1 math math 10791 2009-10-13 20:13 a.out
$ file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
Run Code Online (Sandbox Code Playgroud)
但我无法启动它(是的,我向你保证,该文件是在目录...):
$ ./a.out
bash: ./a.out: No such file or directory
$ uname -a
Linux math 2.6.28-15-generic #52-Ubuntu SMP Wed Sep 9 10:48:52 UTC 2009 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
我认为有一个ELF依赖不能实现,但我不知道如何找到它.是否有一个类似于ldd的工具库可用于找到缺失的链接?
我不认为它与2.6.15/2.6.28-15的区别有关,因为LSB编译器正在工作:
$ file /opt/lsb/bin/lsbcc
/opt/lsb/bin/lsbcc: ELF 64-bit LSB …Run Code Online (Sandbox Code Playgroud) 有了汇编指令和C程序的一些背景知识,我可以看到编译函数的样子,但有趣的是我从来没有仔细考虑过编译后的C++类是什么样的.
bash$ cat class.cpp
#include<iostream>
class Base
{
int i;
float f;
};
bash$ g++ -c class.cpp
Run Code Online (Sandbox Code Playgroud)
我跑了:
bash$objdump -d class.o
bash$readelf -a class.o
Run Code Online (Sandbox Code Playgroud)
但是我得到的东西很难理解.
有人可以解释一下或提出一些好的起点.
如何从带有调试符号的ELF目标文件中提取所有C结构的大小?
可以使用"print sizeof(some_struct)"从GDB获得单个结构大小,但我需要的是获取所有结构的列表.
我看过"nm"和"objdump",但我看不到做我正在寻找的选项.有没有办法用标准的Unix工具做到这一点,或者我是否需要从ELF文件中提取调试符号部分并自行处理?我希望不是后者.
提前感谢任何建议.射线
g ++编译器具有零成本异常处理功能.据我所知,try什么都不做,但是当抛出异常时,会执行异常处理程序的子例程.像这样:
void foo() {
try {
bar(); // throws.
} catch (Type exc) {
baz();
}
}
Run Code Online (Sandbox Code Playgroud)
伪代码(c-stylish)看起来像这样:
void foo() {
bar();
return;
catch1_Type:
baz();
}
Run Code Online (Sandbox Code Playgroud)
bar()抛出.例程例程执行以下操作:
啊,返回地址是函数foo()!并且返回地址在第一个try-catch块中,我们抛出类型Type,因此异常处理程序例程位于地址foo + catch1_Type.所以清理堆栈让我们最终到达那里!
现在我的问题是:有没有办法在C中实现它?(可以是C99或更新,虽然我对gcc支持的C语言感兴趣).我知道我可以使用例如libunwind进行堆栈检查和遍历,虽然我不知道如何获取catch1_Type标签的地址.这可能是不可能的.
异常处理程序可能是一个不同的函数,同样可以,但是如何foo在另一个函数中获取stackframe的局部变量的地址?这似乎也是不可能的.
所以...有什么办法吗?我不想用这个进入汇编程序,但如果其他一切都失败也是可以接受的(尽管局部变量 - 伙计,如果使用不同的优化级别,你永远不会知道它们在哪里).
并且要明确 - 这个问题的目的是避免使用 setjmp/longjmp方法.
编辑:我发现了一个非常酷的想法,但完全不起作用:
gcc中的嵌套函数.他们能做什么?
下行阻止我做任何零成本的事情:
我目前正在C中执行自己的objdump实现.
对于我的-s选项,我必须显示ELF文件部分的全部内容.
我做得很好,但我显示的部分比"真正的"objdump更多.
实际上,它不会输出.bss,.shstrtab,.symtab和.strtab部分.
我正在环顾Shdr结构上的sh_flags值,但我找不到任何逻辑......
为什么objdump -s没有显示这些部分?
我试图检索ELF二进制文件中的附加部分的内容.此时,我使用以下代码检索每个部分的名称:
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#pragma pack(push,1)
#pragma pack(pop)
#define EI_NIDENT 16
/* 32-bit ELF base types. */
typedef unsigned int Elf32_Addr;
typedef unsigned short Elf32_Half;
typedef unsigned int Elf32_Off;
typedef signed int Elf32_Sword;
typedef unsigned int Elf32_Word;
/* 64-bit ELF base types. */
typedef unsigned long long Elf64_Addr;
typedef unsigned short Elf64_Half;
typedef signed short Elf64_SHalf;
typedef unsigned long long Elf64_Off;
typedef signed int Elf64_Sword;
typedef unsigned int Elf64_Word;
typedef unsigned long long Elf64_Xword;
typedef …Run Code Online (Sandbox Code Playgroud) 我正在Ubuntu 14.04(64位)编译深度学习库Caffe.
Version: 2.4.8+dfsg1-2ubuntu1从ubuntu软件包服务器安装OpenCV():
sudo apt-get install libopencv-dev
Caffe使用CMake 2.8 编译.
链接错误:
链接CXX可执行文件
/usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8:未定义引用`TIFFOpen@LIBTIFF_4.0'
似乎找不到TIFF库的一些符号.我努力找到原因(没有运气).这是关于库的一些信息.
TIFF库链接 libopencv_highgui.so.2.4.8
$ ldd libopencv_highgui.so.2.4.8 | grep tiff
libtiff.so.5 => /usr/lib/x86_64-linux-gnu/libtiff.so.5(0x00007f978313b000)
导入符号 libopencv_highgui.so.2.4.8
$ readelf -s libopencv_highgui.so.2.4.8 | grep TIFFOpen
62:0000000000000000 0 FUNC GLOBAL DEFAULT UND TIFFOpen@LIBTIFF_4.0(9)
注意:@符号名称中只有一个.
$ nm -D libopencv_highgui.so.2.4.8 | grep TIFFOpen
你TIFFOpen
出口符号libtiff.so.5:
$ nm -D /usr/lib/x86_64-linux-gnu/libtiff.so.5
0000000000000000 A LIBTIFF_4.0
...
00000000000429f0 T TIFFOpen
...
$ readelf -s /usr/lib/x86_64-linux-gnu/libtiff.so.5|grep TIFFOpen …