Tag: 精灵

在Linux体系结构中使用C代码动态列出所有函数/符号?

假设main.c使用来自main.c声明的共享库和本地函数的符号。 是否有一种漂亮而优雅的方式在运行时打印所有可用function名称和符号的列表? 应该可以,因为数据被加载到.code段。

如何从内部获取指向程序的特定可执行文件部分的指针? (也许和libelf一起)

我在Linux环境中,我需要创建一个程序来检索放置在其可执行文件的一个部分中的一些数据。 那么,如何从内部获取指向程序某一部分(通过其名称)的指针? 我知道可以使用elf_getdata()传递section的索引作为get和Elf_Data结构的参数,这个结构的一个字段是d_buf ,它是指向实际数据的指针。 但是,似乎elf_getdata()函数将段数据的副本从文件复制到内存中,这不是我想要的。 我想要一个指向加载时加载到内存中的数据的指针。 伙计们,任何想法?

Clang使用-nostdlib生成崩溃代码

我正在为可执行文件设置我自己的运行时环境,我不能得到clang(v3.4-1ubuntu1,target:x86_64-pc-linux-gnu)来生成一个不会发生段错误的可执行文件。 我已将问题减少到以下几点: 如果我有一个文件crt1.c除了满足_start符号的链接器要求之外什么都不做: void _start(char *arguments, …) { } 然后我用clang -nostdlib crt1.c编译它,它产生以下可执行文件(来自objdump -d a.out ): a.out: file format elf64-x86-64 Disassembly of section .text: 0000000000400150 : 400150: 55 push %rbp 400151: 48 89 e5 mov %rsp,%rbp 400154: 48 81 ec f0 00 00 00 sub $0xf0,%rsp 40015b: 84 c0 test %al,%al 40015d: 0f 29 bd 30 […]

声明为“const”的全局初始化变量转到文本段,而声明为“Static”的全局初始化变量转到数据段。 为什么?

#include const int str[1000] = {0}; int main(void) { printf(“arr is %d\n”, str[0]); return 0; } 有以下输出: [-exercises/adam/stack2]:size a.out text data bss dec hex filename 5133 272 24 5429 1535 a.out 鉴于: #include static int str[1000] = {0}; int main(void) { printf(“arr is %d\n”, str[0]); return 0; } 有以下输出: [-exercises/adam/stack2]:size a.out text data bss dec […]

如何将来自不同.a文件的数据收集到一个数组中? 如何使用ld脚本保留.a文件中的节?

我需要从不同的.a文件中收集一些数据到一个数组。 我通过收集数据到一个部分来做到这一点 第一个.c文件 TArElement __attribute__((section(“.my.special.section”))) uwiveuve = { … 第二个.c文件 TArElement __attribute__((section(“.my.special.section”))) egwegwxb = { … 等等 在ld脚本中 __my_mega_array_begin = ABSOLUTE(.); KEEP(*(.my.special.section)) __my_mega_array_end = ABSOLUTE(.); 在主.c文件中 extern TArElement *__my_mega_array_begin extern TArElement *__my_mega_array_end const t_size array_size = __my_mega_array_end – __my_mega_array_begin; 所以任何人都可以将他的代码链接到我的代码,我的代码将知道他的代码中的数据。 好吧,它可以工作,但实际上并不…问题是KEEP指令完全与.o文件一起工作,但不是.a。 如果在.a文件中的特定.o文件中没有使用任何部分,那么即使使用KEEP指令,整个.o文件也将从链接中丢弃。 对ld使用–whole-arhive选项会有所帮助,但出于某些原因我不允许使用此选项。 我应该只使用ld脚本文件… 解决问题的另一种方法是通过创建可重定位文件来使用部分链接。 因此.a文件中的所有.o文件都将链接到一个.o文件。 但我也不允许使用部分链接。 所以我应该只使用ld脚本并使用.a文件。

将某些编译器生成的变量强制转换为特定的ELF节(使用gcc)

我将从最终的问题开始:在C中使用gcc,是否有可能获得__func__ (或等效地, __FUNCTION__ )的值存储在除.rodata (或者任何地方-mrodata= points)或子部分之外的部分中其? 完整的解释: 假设我有一个记录宏: #define LOG(fmt, …) log_internal(__FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__) (当且仅当__VA_ARGS__列表为空时,在该一元上下文中使用的字符串连接运算符##使用前面的逗号,从而允许使用带或不带参数的格式字符串。) 然后我可以正常使用宏: void my_function(void) { LOG(“foo!”); LOG(“bar: %p”, &bar); } 可能打印(显然取决于log_internal的实现): foo.c:201(my_function) foo! foo.c:202(my_function) bar: 0x12345678 在这种情况下,格式字符串( “foo”和”bar: %p” )和预处理器字符串( “foo.c”和”my_function” )是匿名只读数据,它们会自动放入.rodata部分。 但是说我希望他们去另一个地方(我在一个嵌入式平台上运行几乎所有内存来自RAM以获得速度,但内存限制正在推动将一些东西转移到ROM中)。 移动__FILE__和格式字符串“很容易”: #define ROM_STR(str) (__extension__({static const __attribute__((__section__(“.rom_data”))) char __c[] = (str); (const char *)&__c;})) #define LOG(fmt, …) […]

如何打印像nm这样的ELF文件的符号名称?

我知道符号的名称在shstrtab中。 但我不明白如何捕捉它们。 我应该将我的shstrab转换为Elf64_Sym,以便我可以使用st_name吗? Elf64_Shdr *shdr = (Elf64_Shdr *) (data + elf->e_shoff); Elf64_Shdr *symtab; Elf64_Shdr *shstrtab; Elf64_Shdr *strtab; char *str = (char *) (data + shdr[elf->e_shstrndx].sh_offset); for (int i = 0; i e_shnum; i++) { if (shdr[i].sh_size) { printf(“%s\n”, &str[shdr[i].sh_name]); if (strcmp(&str[shdr[i].sh_name], “.symtab”) == 0) symtab = (Elf64_Shdr *) &shdr[i]; if (strcmp(&str[shdr[i].sh_name], “.shstrtab”) == 0) shstrtab […]

堆,堆栈,文本等不同的段如何与物理内存相关?

编译C程序并创建目标文件(ELF)时。 目标文件包含不同的部分,如bss,数据,文本和其他段。 我知道ELF的这些部分是虚拟内存地址空间的一部分。 我对吗? 如果我错了,请纠正我。 此外,将存在与编译的程序相关联的虚拟存储器和页表。 页表在加载程序时将ELF中存在的虚拟内存地址与实际物理内存地址相关联。 我的理解是否正确? 我在创建的ELF文件中读到,bss部分只保留未初始化的全局变量的引用。 这里未初始化的全局变量是指在声明期间未初始化的变量? 另外,我读到局部变量将在运行时(即堆栈中)分配空间。 那么它们将如何在目标文件中引用? 如果在程序中,有特定的代码段可用于动态分配内存。 如何在目标文件中引用这些变量? 我很困惑,目标文件的这些不同段(如文本,rodata,数据,bss,堆栈和堆)是物理内存(RAM)的一部分,其中所有程序都被执行。 但我觉得我的理解是错误的。 当进程或程序执行时,这些不同的段如何与物理内存相关?

`-rdynamic’究竟做了什么以及何时需要它?

-rdynamic (或–export-dynamic器级别的–export-dynamic )究竟做了什么以及它如何与-fvisibility* flags或visibility pragma s和__attribute__ s定义的符号可见性相关? 对于–export-dynamic , ld(1)提到: …如果使用“dlopen”加载需要引用程序定义的符号的动态对象,而不是某些其他动态对象,则在链接程序本身时可能需要使用此选项。 … 我不确定我完全明白这一点。 你能否提供一个例子,如果没有-rdynamic ,它会不起作用,但是呢? 编辑 :我实际上尝试编译了几个虚拟库(单个文件,多个文件,各种-O级别,一些函数间调用,一些隐藏符号,一些可见),有和没有-rdynamic ,到目前为止我已经得到字节相同的输出(当然保持所有其他标志不变),这是非常令人费解的。

.bss vs COMMON:到底是什么?

从我的书: .bss段: 未初始化的全局C变量 共同: 尚未分配的未经初始化的数据对象 我不得不说,我看不出明显的区别。 我甚至不太明白什么是无限制的,未分配的数据对象……似乎什么也没有。 我使用GNU的readelf工具试着看一些简单的C代码,但是找不到一个COMMON符号。 我读过像FORTRAN的COMMON类型的东西是一个COMMON符号的例子 – 但我不知道FORTRAN 有人可以为我区分这两个吗? 如果可能的话,希望用C的例子? 非常感激。 编辑 :从这篇文章中,变量c在这里: int c; int main() {} … 应该是COMMON。 但是使用objdump -t显示c在.bss中… 困惑