这取决于使用的编译器。这将是关于 gcc 和 binutils。
- 找到您的项目链接描述文件。链接描述文件通常具有
.ld 文件扩展名。如果没有链接描述文件,您的项目将使用默认链接描述文件。要查看默认链接器脚本,您需要传递-Wl,--verbose。您会看到很多信息,但我们正在寻找类似的信息(这是我的):
/* Default linker script, for normal executables */
/* Copyright (C) 2014 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT(pei-i386)
SEARCH_DIR("/mingw/mingw32/lib"); SEARCH_DIR("/mingw/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
SECTIONS
{
/* Make the virtual address and file offset synced if the alignment is
lower than the target page size. */
. = SIZEOF_HEADERS;
. = ALIGN(__section_alignment__);
.text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
{
*(.init)
*(.text)
*(SORT(.text$*))
*(.text.*)
*(.gnu.linkonce.t.*)
*(.glue_7t)
*(.glue_7)
___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0);
___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0);
*(.fini)
/* ??? Why is .gcc_exc here? */
*(.gcc_exc)
PROVIDE (etext = .);
PROVIDE (_etext = .);
*(.gcc_except_table)
}
/* The Cygwin32 library uses a section to avoid copying certain data
on fork. This used to be named ".data". The linker used
to include this between __data_start__ and __data_end__, but that
breaks building the cygwin32 dll. Instead, we name the section
".data_cygwin_nocopy" and explicitly include it after __data_end__. */
.data BLOCK(__section_alignment__) :
{
__data_start__ = . ;
*(.data)
*(.data2)
*(SORT(.data$*))
*(.jcr)
__data_end__ = . ;
*(.data_cygwin_nocopy)
}
.rdata BLOCK(__section_alignment__) :
{
*(.rdata)
*(SORT(.rdata$*))
__rt_psrelocs_start = .;
*(.rdata_runtime_pseudo_reloc)
__rt_psrelocs_end = .;
}
__rt_psrelocs_size = __rt_psrelocs_end - __rt_psrelocs_start;
___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
___RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
__RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
.eh_frame BLOCK(__section_alignment__) :
{
*(.eh_frame*)
}
.pdata BLOCK(__section_alignment__) :
{
*(.pdata)
}
.bss BLOCK(__section_alignment__) :
{
__bss_start__ = . ;
*(.bss)
*(COMMON)
__bss_end__ = . ;
}
.edata BLOCK(__section_alignment__) :
{
*(.edata)
}
/DISCARD/ :
{
*(.debug$S)
*(.debug$T)
*(.debug$F)
*(.drectve)
*(.note.GNU-stack)
*(.gnu.lto_*)
}
.idata BLOCK(__section_alignment__) :
{
/* This cannot currently be handled with grouped sections.
See pe.em:sort_sections. */
SORT(*)(.idata$2)
SORT(*)(.idata$3)
/* These zeroes mark the end of the import list. */
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
SORT(*)(.idata$4)
__IAT_start__ = .;
SORT(*)(.idata$5)
__IAT_end__ = .;
SORT(*)(.idata$6)
SORT(*)(.idata$7)
}
.CRT BLOCK(__section_alignment__) :
{
___crt_xc_start__ = . ;
*(SORT(.CRT$XC*)) /* C initialization */
___crt_xc_end__ = . ;
___crt_xi_start__ = . ;
*(SORT(.CRT$XI*)) /* C++ initialization */
___crt_xi_end__ = . ;
___crt_xl_start__ = . ;
*(SORT(.CRT$XL*)) /* TLS callbacks */
/* ___crt_xl_end__ is defined in the TLS Directory support code */
___crt_xp_start__ = . ;
*(SORT(.CRT$XP*)) /* Pre-termination */
___crt_xp_end__ = . ;
___crt_xt_start__ = . ;
*(SORT(.CRT$XT*)) /* Termination */
___crt_xt_end__ = . ;
}
/* Windows TLS expects .tls$AAA to be at the start and .tls$ZZZ to be
at the end of section. This is important because _tls_start MUST
be at the beginning of the section to enable SECREL32 relocations with TLS
data. */
.tls BLOCK(__section_alignment__) :
{
___tls_start__ = . ;
*(.tls$AAA)
*(.tls)
*(.tls$)
*(SORT(.tls$*))
*(.tls$ZZZ)
___tls_end__ = . ;
}
.endjunk BLOCK(__section_alignment__) :
{
/* end is deprecated, don't use it */
PROVIDE (end = .);
PROVIDE ( _end = .);
__end__ = .;
}
.rsrc BLOCK(__section_alignment__) : SUBALIGN(4)
{
*(.rsrc)
*(.rsrc$*)
}
.reloc BLOCK(__section_alignment__) :
{
*(.reloc)
}
.stab BLOCK(__section_alignment__) (NOLOAD) :
{
*(.stab)
}
.stabstr BLOCK(__section_alignment__) (NOLOAD) :
{
*(.stabstr)
}
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section. Unlike other targets that fake this by putting the
section VMA at 0, the PE format will not allow it. */
/* DWARF 1.1 and DWARF 2. */
.debug_aranges BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_aranges)
}
.zdebug_aranges BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_aranges)
}
.debug_pubnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_pubnames)
}
.zdebug_pubnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_pubnames)
}
.debug_pubtypes BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_pubtypes)
}
.zdebug_pubtypes BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_pubtypes)
}
/* DWARF 2. */
.debug_info BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_info .gnu.linkonce.wi.*)
}
.zdebug_info BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_info .zdebug.gnu.linkonce.wi.*)
}
.debug_abbrev BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_abbrev)
}
.zdebug_abbrev BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_abbrev)
}
.debug_line BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_line)
}
.zdebug_line BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_line)
}
.debug_frame BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_frame*)
}
.zdebug_frame BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_frame*)
}
.debug_str BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_str)
}
.zdebug_str BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_str)
}
.debug_loc BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_loc)
}
.zdebug_loc BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_loc)
}
.debug_macinfo BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_macinfo)
}
.zdebug_macinfo BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_macinfo)
}
/* SGI/MIPS DWARF 2 extensions. */
.debug_weaknames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_weaknames)
}
.zdebug_weaknames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_weaknames)
}
.debug_funcnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_funcnames)
}
.zdebug_funcnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_funcnames)
}
.debug_typenames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_typenames)
}
.zdebug_typenames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_typenames)
}
.debug_varnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_varnames)
}
.zdebug_varnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_varnames)
}
.debug_macro BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_macro)
}
.zdebug_macro BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_macro)
}
/* DWARF 3. */
.debug_ranges BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_ranges)
}
.zdebug_ranges BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_ranges)
}
/* DWARF 4. */
.debug_types BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_types .gnu.linkonce.wt.*)
}
.zdebug_types BLOCK(__section_alignment__) (NOLOAD) :
{
*(.zdebug_types .gnu.linkonce.wt.*)
}
}
将其复制并粘贴到文本文件中(.ld 扩展名将帮助您或其他人了解此文件的作用)。
正如我们所见,.text 部分的末尾确实提供了两个符号,但开头没有符号。我们可以自己添加这个符号:
.text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
{
.__text_start__ = .;
*(.init)
您需要将-Tpath_to_your_ld_file 传递给链接器
然后在.c文件中我们可以测试它:
extern char _text_start__, etext, _data_start__, _data_end__, _bss_start__, _bss_end__;
int main()
{
printf("Text start: %p Text end: %p\n", (void *)&_text_start__, (void *)&etext);
printf("Data start: %p Data end: %p\n", (void *)&_data_start__, (void *)&_data_end__);
printf("BSS start: %p BSS end: %p\n", (void *)&_bss_start__, (void *)&_bss_end__);
}
在我的电脑上是:
Text start: 00401000 Text end: 00408FF4
Data start: 00409000 Data end: 0040902C
BSS start: 0040D000 BSS end: 0040DA34