我的程序正在使用gcc处理linux。通过手册页,我找到了edata,它代表初始化数据段的第一个地址过去 结束。
但我想知道初始化数据段的第一个地址
我怎么才能得到它?
我尝试将 etext 作为初始化数据段的第一个地址。然后当我增加地址并访问存储在其中的变量时,我遇到了一个段错误。我认为etext和edata之间的一些地址空间没有映射到虚拟内存中。是吗?
答案 0 :(得分:4)
这取决于您的链接器脚本。例如,在某些平台上,您在BSS的开头有符号__bss_start
。它是一个没有任何与之关联的数据的符号,你可以通过extern
声明一个具有该名称的变量来获取指向它的指针(仅为了获取该变量的地址)。例如:
#include <stdio.h>
extern char __bss_start;
int main()
{
printf("%p\n", &__bss_start);
return 0;
}
您可以通过查看链接器脚本找到此信息,例如在/usr/lib/ldscripts/elf_x64_64.x
:
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
__bss_start = .; /* <<<<< this is what you're looking for /*
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
您还可以看到您提到的edata
,但由于edata
未保留用于实施(PROVIDE
仅表示创建此符号,否则不会你应该使用_edata
代替。
如果您希望地址到data
部分的开头,您可以修改链接描述文件:
__data_start = . ;
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
__bss_start = .; /* <<<<< this is what you're looking for /*
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
您可能希望制作链接器脚本的副本(在/usr/lib/ldscripts
中查找正确的脚本,它们根据您要定位的输出类型而有所不同)并在编译时提供它:
gcc -o execfile source.c -Wl,-T ldscript
如果您不想修改链接描述文件,另一个选择可能是使用__executable_start
并解析ELF头文件(希望可执行文件有足够的线性映射)
对于_etext
,它是text
部分的结尾(您也可以在链接描述文件中读取它,但我没有在摘录中包含它),但是text
部分后跟rodata
,尝试写入可能会出现段错误。
答案 1 :(得分:0)
您可以使用linux工具'fnDrawCallback': function(oSettings) {
$("<tr colspan='2'><td>Press Ctrl+Click To select</td></tr>").prependTo("table > tbody");
}
(Debian / Ubuntu中的binutils包)。
实施例
size
结果
size -A /usr/bin/gcc