标签: elf

哪个部分的ELF文件必须加载到内存中?

可执行文件的ELF文件有一个程序(段)标题和一个节头,可以看到readelf -a,这是一个例子:

在此输入图像描述

在此输入图像描述

上面的两张图分别是节标题和节目(段)标题.可以看出,段头由若干段头组成,用于将程序加载到存储器中.

是否只需将.text,.rodata,.data,.bss部分加载到内存中?

段中的所有其他部分(例如,第3段中的.ctors,.dtors .jcr)是否用于对齐?

c linux memory elf

17
推荐指数
1
解决办法
6383
查看次数

强制GNU链接器生成32位ELF可执行文件

嗨我正在为我正在编写的编译器生成x86程序集,并且在我的64位VM上链接文件时遇到一些问题(汇编代码是32位).

我能够使用此命令组合目标文件:

as --32 mult.S -o mult.o
Run Code Online (Sandbox Code Playgroud)

但我似乎无法找到任何选项ld,使它生成一个32位的ELF文件:

ld <some-option?> mult.o -o mult
Run Code Online (Sandbox Code Playgroud)

任何帮助都会很棒.

linux x86 assembly elf ld

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

elf格式的可执行文件和可重定位文件有什么区别?

elf格式的可执行文件和elf格式的可重定位文件有什么区别?

elf

17
推荐指数
4
解决办法
8580
查看次数

为什么Linux/gnu链接器选择地址0x400000?

我在Linux x86_64上试验ELF可执行文件和gnu工具链:

我已经链接并剥离(手工)"Hello World"测试.:

        .global _start
        .text
_start:
        mov     $1, %rax
        ...
Run Code Online (Sandbox Code Playgroud)

到一个267字节的ELF64可执行文件...

0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 3e00 0100 0000 d400 4000 0000 0000  ..>.......@.....
0000020: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
0000030: 0000 0000 4000 3800 0100 4000 0000 0000  ....@.8...@.....
0000040: 0100 0000 0500 0000 0000 0000 0000 0000  ................
0000050: 0000 4000 0000 0000 0000 4000 0000 0000  ..@.......@.....
0000060: 0b01 0000 0000 0000 0b01 0000 …
Run Code Online (Sandbox Code Playgroud)

linux x86 x86-64 elf ld

16
推荐指数
2
解决办法
3347
查看次数

使用clang ++,-fvisibility = hidden,typeinfo和type-erasure

这是我在Mac OS X上使用clang ++面临的问题的缩小版本.这是经过严格编辑以更好地反映真正的问题(第一次尝试描述问题并没有表现出问题).

失败

我在C++中有一大块软件,在目标文件中有大量符号,所以我-fvisibility=hidden用来保持我的符号表小.众所周知,在这种情况下,必须特别注意vtable,我想我遇到了这个问题.然而,我不知道如何以一种令gcc和clang取悦的方式优雅地解决它.

考虑一个base具有向下转换运算符asderived类,以及包含一些有效负载的类模板.pair base/ derived<T>用于实现类型擦除:

// foo.hh

#define API __attribute__((visibility("default")))

struct API base
{
  virtual ~base() {}

  template <typename T>
  const T& as() const
  {
    return dynamic_cast<const T&>(*this);
  }
};

template <typename T>
struct API derived: base
{};

struct payload {}; // *not* flagged as "default visibility".

API void bar(const base& b);
API void baz(const base& b);
Run Code Online (Sandbox Code Playgroud)

然后我有两个不同的编译单元提供类似的服务,我可以将其近似为相同功能的两倍:向下转换basederive<payload>:

// bar.cc
#include "foo.hh" …
Run Code Online (Sandbox Code Playgroud)

c++ visibility g++ elf clang++

16
推荐指数
1
解决办法
6856
查看次数

内联静态数据会导致节类型冲突

我想将一些用户定义的数据放入自定义部分,以便同时由应用程序和离线分析器读取.假设以下示例:

const int* get_data()
{
  __attribute__((section(".custom")))
  static const int data = 123;

  return & data;
}

inline const int* inline_get_data()
{
  __attribute__((section(".custom")))
  static const int inline_data = 123;

  return & inline_data;
}

int main()
{
  (void) get_data();
  (void) inline_get_data();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

的价值datainline_data将出现在部分.custom.Clang编译此示例并生成正确的结果,就像MSVC一样,当它__attributes__相应的编译指示替换时.

不幸的是,GCC 5.2给出了以下错误:

error: inline_data causes a section type conflict with data
Run Code Online (Sandbox Code Playgroud)

这个问题归结为一个事实,即这两个变量具有不同的链接(data在一节标记a,的部分inline_data将被标记aG).如果第二个函数没有标记为内联但是模板(GCC 5.2编译它),则GCC 4.9会以相同的方式失败.

如果临时更改了一个部分名称并在生成的程序集中手动修复,GCC 5.2也会编译正常.

这个问题有没有已知的解决方法?我无法控制函数签名, …

c++ linker gcc elf

16
推荐指数
1
解决办法
2277
查看次数

如何知道ELF目标文件中的调试信息类型?

我有一个ELF目标文件.我想知道它包含哪种类型的调试信息.它是用PPC架构的Diab编译器(C源代码)编译的.我很确定它是用调试符号构建的.

我试过提取调试信息,dwarfdump但我不工作,所以我猜调试信息不​​是DWARF类型.

$ dwarfdump file.elf
No DWARF information present in file.elf
Run Code Online (Sandbox Code Playgroud)

使用objdump显示调试信息是空的.

$ objdump -g file.elf 
file.elf:     file format elf32-powerpc
Run Code Online (Sandbox Code Playgroud)

可能是这个ELF文件不包含调试信息,即使ELF文件中有调用的部分.debug_sfnames,.debug_srcinfo并且.debug.srcinfo?或者调试信息是以objdump无法处理的格式存储的?

c powerpc elf debug-symbols

15
推荐指数
3
解决办法
1万
查看次数

C中的函数指针相等

我的问题:

  1. 函数指针是否由C标准保证?
  2. 如果(1)的答案是肯定的.是不是在不同的最终编译单元(例如主可执行文件和共享库)中获得指针的情况?
  3. 动态加载器如何处理?(我可以考虑一些可能导致棘手问题的原因,所有这些都与PIC代码有关(例如,精灵中的GOT表和COFF使用的等效表格)).无论(1)和(2)如何,linux加载器似乎都能保证这一点.

这是一个例子.上面的问题归结为C是否保证main.c打印: "Function equality: 1"或者"Function equality: 0",在第一种情况下,动态加载器如何实现这一点.

common.h:

extern void * getc_main;
extern void * getc_shared;
void assign_getc_shared(); 
Run Code Online (Sandbox Code Playgroud)

main.c:

#include <stdio.h>
#include "common.h"

int main()
{
  getc_main = (void*) getc;
  assign_getc_shared();
  printf("Function equality: %d\n", getc_main == getc_shared);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

shared.c:

#include <stdio.h>
#include "common.h"

void assign_getc_shared()
{
   getc_shared = (void*) getc;
}
Run Code Online (Sandbox Code Playgroud)

在Unix中,这将使用以下命令进行编译:

cc -shared -fPIC -o libshared.so shared.c
cc -o main main.c -L. -lshared
Run Code Online (Sandbox Code Playgroud)

并执行:

LD_LIBRARY_PATH=. ./main
Run Code Online (Sandbox Code Playgroud)

c unix function-pointers elf dynamic-loading

15
推荐指数
1
解决办法
1554
查看次数

如何在C(gcc)中获取自定义ELF部分的起始和结束地址?

我已经看到使用gcc __section__属性(特别是在Linux内核中)将数据(通常是函数指针)收集到自定义ELF部分中.如何检索和使用这些自定义部分中的"东西"?

c gcc elf

15
推荐指数
3
解决办法
1万
查看次数

在64位x86平台上比较PIE,PIC代码和可执行文件有什么区别?

测试是在Ubuntu 12.04 64位上进行的.x86架构.

我对位置独立可执行(PIE)和位置无关代码(PIC)的概念感到困惑,我猜它们不是正交的.

这是我的快速实验.

gcc -fPIC -pie quickSort.c -o a_pie.out
gcc -fPIC      quickSort.c -o a_pic.out
gcc                           a.out

objdump -Dr -j .text a.out > a1.temp
objdump -Dr -j .text a_pic.out > a2.temp
objdump -Dr -j .text a_pie.out > a3.temp
Run Code Online (Sandbox Code Playgroud)

我有以下发现.

A. a.out包含一些PIC代码,但在libc序言和结尾函数中有效,如下所示:

4004d0:       48 83 3d 70 09 20 00    cmpq   $0x0,0x200970(%rip)        # 600e48 <__JCR_END__> 
Run Code Online (Sandbox Code Playgroud)

在我的简单快速排序程序的汇编指令中,我没有找到任何PIC指令.

B. a_pic.out包含PIC代码,我没有找到任何非PIC指令...在我的快速排序程序的指令中,所有全局数据都由PIC指令访问,如下所示:

  40053b:       48 8d 05 ea 02 00 00    lea    0x2ea(%rip),%rax        # 40082c <_IO_stdin_used+0x4>
Run Code Online (Sandbox Code Playgroud)

C. a_pie.out包含与a_pic.out比较的语法相同的指令.但是,a_pie.out的.text段的内存地址范围为0x630到0xa57,而a_pic.out的相同部分的范围是0x400410到0x400817.

谁能给我一些关于这些现象的解释?特别是发现 …

c linux x86 assembly elf

15
推荐指数
1
解决办法
5517
查看次数