标签: elf

32位x86代码是否需要针对共享库文件进行特殊的PIC编译?

如果要将目标文件作为共享库(.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 linux shared-libraries elf pic

13
推荐指数
2
解决办法
1106
查看次数

使用C获取从核心转储导致分段错误的地址

我正在尝试编写一个可以解析核心转储文件的C程序.我的问题是,如何在C中获取导致核心转储的地址?我知道可以从这个答案中使用gdb获取地址:

我怎样才能让GDB告诉我哪个地址导致了段错?

但我想直接在C中检索地址.任何信息都将受到高度赞赏.谢谢!

注意:我知道如何将核心转储解析为精灵.但我不知道如何获得导致段错误的地址.

c coredump elf

13
推荐指数
2
解决办法
2756
查看次数

可执行文件中常见字符串的含义?

似乎有一些类似的长字母数字字符串,通常出现在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个结果.

在此输入图像描述

这些字符串是什么?

macos executable elf binary-data mach

13
推荐指数
1
解决办法
2111
查看次数

如何找到未满足的ELF依赖项?

我使用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)

linux elf dynamic-linking

12
推荐指数
1
解决办法
2万
查看次数

编译的C++类是什么样的?

有了汇编指令和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)

但是我得到的东西很难理解.

有人可以解释一下或提出一些好的起点.

c++ compiler-construction linker elf

12
推荐指数
2
解决办法
5311
查看次数

从ELF目标文件转储C结构大小

如何从带有调试符号的ELF目标文件中提取所有C结构的大小?

可以使用"print sizeof(some_struct)"从GDB获得单个结构大小,但我需要的是获取所有结构的列表.

我看过"nm"和"objdump",但我看不到做我正在寻找的选项.有没有办法用标准的Unix工具做到这一点,或者我是否需要从ELF文件中提取调试符号部分并自行处理?我希望不是后者.

提前感谢任何建议.射线

c size struct elf

12
推荐指数
4
解决办法
1万
查看次数

是否可以在C中编写零成本异常处理?

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中的嵌套函数.他们能做什么?

  • 有权访问局部变量,
  • 有可能在父函数中转到本地标签!
  • 只要我们传递指向嵌套函数的指针,我们函数的被调用者就可以调用它,因此它可以被被调用者中的指针使用.

下行阻止我做任何零成本的事情:

  • 如果它们未使用,它们甚至会在-O0级别进行优化.我可以对此做些什么吗?如果可以的话,我可以在抛出异常时通过符号名称获取地址,并且它只是执行实现异常的工作,这些异常在不抛出时会花费成本...

c optimization exception-handling gnu-assembler elf

12
推荐指数
1
解决办法
1260
查看次数

为什么objdump不显示.bss,.shstratab,.symtab和.strtab部分?

我目前正在C中执行自己的objdump实现.

对于我的-s选项,我必须显示ELF文件部分的全部内容.

我做得很好,但我显示的部分比"真正的"objdump更多.

实际上,它不会输出.bss,.shstrtab,.symtab和.strtab部分.

我正在环顾Shdr结构上的sh_flags值,但我找不到任何逻辑......

为什么objdump -s没有显示这些部分?

c elf objdump

12
推荐指数
1
解决办法
3296
查看次数

阅读ELF部分的内容(以编程方式)

我试图检索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)

c linux ubuntu file elf

12
推荐指数
1
解决办法
8057
查看次数

在Ubuntu 14.04下链接错误与`libopencv_highgui.so`,与`libtiff.so.5的奇怪结果

问题

我正在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 …

c++ opencv elf dynamic-linking unresolved-external

12
推荐指数
1
解决办法
6879
查看次数