如果没有挖掘GDB源代码,我在哪里可以找到有关用于创建核心文件的格式的文档?
在ELF规范离开核心文件格式打开,所以我想这应该是GDB规范的一部分!遗憾的是,我没有从GNU的gdb文档中找到任何帮助.
这就是我要做的事情:将虚拟地址映射到包含正在运行的进程的可执行文件/库中的函数名称.为此,我首先要从核心文件中找出从虚拟地址空间到可执行文件/库的名称的映射,然后深入到相关文件中以获取符号信息.
现在'readelf -a core'告诉我核心文件中的几乎所有段都是'load'类型 - 我猜这些是来自所有参与文件的.text和.bss/.data段,加上堆栈段.除了这些加载段,有一个音符段,但似乎不包含地图.那么关于哪个文件段对应的信息如何存储在核心文件中?这些"加载"段是否以特定方式格式化以包含文件信息?
考虑 Linux 系统上的以下两个文件:
使用消息.cpp
#include <iostream>
extern const char* message;
void print_message();
int main() {
std::cout << message << '\n';
print_message();
}
Run Code Online (Sandbox Code Playgroud)
libmessage.cpp
#include <iostream>
const char* message = "Meow!"; // 1. absolute address of string literal
// needs runtime relocation in a .so
void print_message() {
std::cout << message << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我们可以将use_message.cpp编译为目标文件,将libmessage.cpp编译为共享库,并将它们链接在一起,如下所示:
$ g++ use_message.cpp -c -pie -o use_message.o
$ g++ libmessage.cpp -fPIC -shared -o libmessage.so
$ g++ use_message.o libmessage.so -o use_message
Run Code Online (Sandbox Code Playgroud)
的定义message …
说我有一个图书馆libfoo.so.1,依赖于(根据ldd)libbar.so.1.但是,libbar.so.1暂时不可用.我的应用需要调用一个libfoo.so.1根本不需要的功能libbar.so.1.
有没有办法加载libfoo.so.1,解析函数符号然后调用它而不必libbar.so.1满足依赖?这是"我知道我在做什么,只是让我这样做"的案例.我尝试了RTLD_LAZY标志,但它仍然尝试libbar.so.1在不加载符号之前加载库.
编辑
这是确切的情况.
我们有3名球员:
libbar.so.1,共享库位于路径没有LD_LIBRARY_PATH或ldconfig,且其相关性都得到解决libfoo.so.1, a shared library located in a different directory than libbar, but which depends on libbar. At runtime, libfoo will know where to locate libbar.App, a binary application which needs to load libfoo at some point during runtime.App doesn't know where to …
我在术语上很少混淆.
作为链接器输入的文件称为对象文件.链接器生成一个Image文件,该文件又被加载器用作输入.
我从"MS PE&COFF规范"中得到了这个
Q1.图像文件也被称为Binary Image,Binary File或只是Binary.对?
Q2.因此,根据上述术语,PE/ELF/COFF是图像文件的格式而不是目标文件.对?但http://www.sco.com/developers/gabi/latest/ch4.intro.html说
本章介绍目标文件格式,称为ELF(可执行文件和链接格式).目标文件有三种主要类型.
可重定位文件包含适合与其他目标文件链接的代码和数据,以创建可执行文件或共享对象文件.
可执行文件包含适合执行的程序; 该文件指定exec(BA_OS)如何创建程序的过程映像.
共享对象文件包含适合在两个上下文中链接的代码和数据.首先,链接编辑器[请参阅ld(BA_OS)]使用其他可重定位和共享对象文件处理共享对象文件,以创建另一个目标文件.其次,动态链接器将其与可执行文件和其他共享对象相结合,以创建过程映像.
矛盾的是,他说对象文件和图像文件都是ELF格式,他根本不区分对象和图像文件,但通常将它们称为对象文件.不是吗?
Q3.我知道PE来自COFF.但为什么Microsoft格式的PE格式被命名为Microsoft Portable Executable"和Common Object File Format Specification".他们还支持COFF吗?如果他们,在哪个操作系统?我以为PE很久以前完全取代了COFF.
我想写一个小函数的跟踪器.我用ptrace.我在ubuntu x86_64上.我想找到共享库函数的地址(比如printf).
但我有一些问题和一些关于全球抵消表的问题.我有以下代码:
size_t baseAddress = this->getBaseAddress();
Elf_Ehdr const * headerElf = static_cast<Elf_Ehdr const *> (this->_manager.readMemory((void*) baseAddress, sizeof (Elf_Ehdr)));
Elf_Phdr const * headerProgram = static_cast<Elf_Phdr const *> (this->_manager.readMemory((void*) (baseAddress + headerElf->e_phoff), headerElf->e_phentsize * headerElf->e_phnum));
unsigned int i = 0;
while (headerProgram[i].p_type != PT_DYNAMIC)
{
++i;
}
size_t addrToRead = headerProgram[i].p_vaddr;
Elf_Dyn const * dynSection = static_cast<Elf_Dyn const *> (this->_manager.readMemory((void*) addrToRead, sizeof (Elf_Dyn)));
while (dynSection->d_tag != DT_PLTGOT)
{
addrToRead += sizeof (Elf_Dyn);
dynSection = static_cast<Elf_Dyn const *> (this->_manager.readMemory((void*) addrToRead, …Run Code Online (Sandbox Code Playgroud) 如果要将目标文件作为共享库(.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编译器)仍然附带了不同版本的库?
的平普尔成语,以便允许改变动态链接库的代码而不破坏ABI兼容性和重新编译所有依赖于库中的代码通常使用的.
我看到的大多数解释都提到添加一个新的私有成员变量会改变类中公共成员和私有成员的偏移量.这对我来说很有意义.我不明白的是,实际上这实际上打破了依赖库.
我已经做了很多的阅读ELF文件,以及如何动态链接实际工作,但我仍然没有看到如何在共享库改变类规模将破事.
例如,这是我编写的测试应用程序(a.out),它使用Interface::some_method来自测试共享库(libInterface.so)的code():
aguthrie@ana:~/pimpl$ objdump -d -j .text a.out
08048874 <main>:
...
8048891: e8 b2 fe ff ff call 8048748 <_ZN9Interface11some_methodEv@plt>
Run Code Online (Sandbox Code Playgroud)
some_method使用程序链接表(PLT)的调用:
aguthrie@ana:~/pimpl$ objdump -d -j .plt a.out
08048748 <_ZN9Interface11some_methodEv@plt>:
8048748: ff 25 1c a0 04 08 jmp *0x804a01c
804874e: 68 38 00 00 00 push $0x38
8048753: e9 70 ff ff ff jmp 80486c8 <_init+0x30>
Run Code Online (Sandbox Code Playgroud)
随后进入全局偏移表(GOT),其中包含地址0x804a01c:
aguthrie@ana:~/pimpl$ readelf -x 24 a.out
Hex dump of section '.got.plt':
0x08049ff4 089f0408 00000000 00000000 de860408 …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个可以解析核心转储文件的C程序.我的问题是,如何在C中获取导致核心转储的地址?我知道可以从这个答案中使用gdb获取地址:
但我想直接在C中检索地址.任何信息都将受到高度赞赏.谢谢!
注意:我知道如何将核心转储解析为精灵.但我不知道如何获得导致段错误的地址.
我正在尝试将一个elf文件放入内存然后执行它,这些是以下步骤:
1-文件放入内存
int main()
{
printf("Hello world! \n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
2-编译它 gcc -o hello hello.c -static
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x8120
Start of program headers: 52 (bytes into file)
Start of section headers: 119864 (bytes …Run Code Online (Sandbox Code Playgroud)