解释一个ldscript资料.docx
- 文档编号:30119182
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:21
- 大小:21.92KB
解释一个ldscript资料.docx
《解释一个ldscript资料.docx》由会员分享,可在线阅读,更多相关《解释一个ldscript资料.docx(21页珍藏版)》请在冰豆网上搜索。
解释一个ldscript资料
解释一个ld.script资料
GNUld(GNUBinutilsforUbuntu)
Supportedemulations:
elf_i386
i386linux
elf_x86_64
elf_l1om
usinginternallinkerscript:
==================================================
/*Scriptfor-zcombreloc:
combineandsortrelocsections*/
OUTPUT_FORMAT("elf32-i386","elf32-i386",
"elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR("/usr/i486-linux-gnu/lib32");SEARCH_DIR("/usr/local/lib32");
SEARCH_DIR("/lib32");SEARCH_DIR("/usr/lib32");SEARCH_DIR("/usr/i486-linux-gnu/lib");
SEARCH_DIR("/usr/local/lib");SEARCH_DIR("/lib");SEARCH_DIR("/usr/lib");
SECTIONS
{
/*Read-onlysections,mergedintotextsegment:
*/
PROVIDE(__executable_start=SEGMENT_START("text-segment",0x08048000));
.=SEGMENT_START("text-segment",0x08048000)+SIZEOF_HEADERS;
.interp:
{*(.interp)}
.:
{*(.}
.hash:
{*(.hash)}
.gnu.hash:
{*(.gnu.hash)}
.dynsym:
{*(.dynsym)}
.dynstr:
{*(.dynstr)}
.gnu.version:
{*(.gnu.version)}
.gnu.version_d:
{*(.gnu.version_d)}
.gnu.version_r:
{*(.gnu.version_r)}
.rel.dyn:
{
*(.rel.init)
*(.rel.text.rel.text.*.
*(.rel.fini)
*(.rel.rodata.rel.rodata.*.
*(..
*(.rel.data.rel.data.*.
*(.rel.tdata.rel.tdata.*.
*(.rel.tbss.rel.tbss.*.
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.bss.rel.bss.*.
*(.rel.ifunc)
}
.rel.plt:
{
*(.rel.plt)
PROVIDE_HIDDEN(__rel_iplt_start=.);
*(.rel.iplt)
PROVIDE_HIDDEN(__rel_iplt_end=.);
}
.init:
{
KEEP(*(.init))
}=0x
.plt:
{*(.plt)*(.iplt)}
.text:
{
*(.text.unlikely.text.*_unlikely)
*(.text.stub.text.*.
/*.gnu.warningsectionsarehandledspeciallybyelf32.em.*/
*(.gnu.warning)
}=0x
.fini:
{
KEEP(*(.fini))
}=0x
PROVIDE(__etext=.);
PROVIDE(_etext=.);
PROVIDE(etext=.);
.rodata:
{*(.rodata.rodata.*.}
.rodata1:
{*(.rodata1)}
.eh_frame_hdr:
{*(.eh_frame_hdr)}
.eh_frame:
ONLY_IF_RO{KEEP(*(.eh_frame))}
.gcc_except_table:
ONLY_IF_RO{*(.gcc_except_table.gcc_except_table.*)}
/*Adjusttheaddressforthedatasegment.Wewanttoadjustupto
thesameaddresswithinthepageonthenextpageup.*/
.=ALIGN(CONSTANT(MAXPAGESIZE))-((CONSTANT(MAXPAGESIZE)-.)&(CONSTANT(MAXPAGESIZE)-1));.=DATA_SEGMENT_ALIGN(CONSTANT(MAXPAGESIZE),CONSTANT(COMMONPAGESIZE));
/*Exceptionhandling*/
.eh_frame:
ONLY_IF_RW{KEEP(*(.eh_frame))}
.gcc_except_table:
ONLY_IF_RW{*(.gcc_except_table.gcc_except_table.*)}
/*ThreadLocalStoragesections*/
.tdata:
{*(.tdata.tdata.*.}
.tbss:
{*(.tbss.tbss.*.*(.tcommon)}
.preinit_array:
{
PROVIDE_HIDDEN(__preinit_array_start=.);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN(__preinit_array_end=.);
}
.init_array:
{
PROVIDE_HIDDEN(__init_array_start=.);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN(__init_array_end=.);
}
.fini_array:
{
PROVIDE_HIDDEN(__fini_array_start=.);
KEEP(*(.fini_array))
KEEP(*(SORT(.fini_array.*)))
PROVIDE_HIDDEN(__fini_array_end=.);
}
.ctors:
{
/*gccusescrtbegin.otofindthestartof
theconstructors,sowemakesureitis
first.Becausethisisawildcard,it
doesn'tmatteriftheuserdoesnot
actuallylinkagainstcrtbegin.o;the
linkerwon'tlookforafiletomatcha
wildcard.Thewildcardalsomeansthatit
doesn'tmatterwhichdirectorycrtbegin.o
isin.*/
KEEP(*crtbegin.o(.ctors))
KEEP(*crtbegin?
.o(.ctors))
/*Wedon'twanttoincludethe.ctorsectionfrom
thecrtend.ofileuntilafterthesortedctors.
The.ctorsectionfromthecrtendfilecontainsthe
endofctorsmarkeranditmustbelast*/
KEEP(*(EXCLUDE_FILE(*crtend.o*crtend?
.o).ctors))
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
}
.dtors:
{
KEEP(*crtbegin.o(.dtors))
KEEP(*crtbegin?
.o(.dtors))
KEEP(*(EXCLUDE_FILE(*crtend.o*crtend?
.o).dtors))
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
}
.jcr:
{KEEP(*(.jcr))}
.:
{*(..*(..}
.dynamic:
{*(.dynamic)}
.got:
{*(.got)*(.igot)}
.=DATA_SEGMENT_RELRO_END(12,.);
.got.plt:
{*(.got.plt)*(.igot.plt)}
.data:
{
*(.data.data.*.
SORT(CONSTRUCTORS)
}
.data1:
{*(.data1)}
_edata=.;PROVIDE(edata=.);
__bss_start=.;
.bss:
{
*(.dynbss)
*(.bss.bss.*.
*(COMMON)
/*Alignheretoensurethatthe.bsssectionoccupiesspaceupto
_end.Alignafter.bsstoensurecorrectalignmentevenifthe
.bsssectiondisappearsbecausetherearenoinputsections.
FIXME:
Whydoweneedit?
Whenthereisno.bsssection,wedon't
padthe.datasection.*/
.=ALIGN(.!
=0?
32/8:
1);
}
.=ALIGN(32/8);
.=ALIGN(32/8);
_end=.;PROVIDE(end=.);
.=DATA_SEGMENT_END(.);
/*Stabsdebuggingsections.*/
.stab0:
{*(.stab)}
.stabstr0:
{*(.stabstr)}
.stab.excl0:
{*(.stab.excl)}
.stab.exclstr0:
{*(.stab.exclstr)}
.stab.index0:
{*(.stab.index)}
.stab.indexstr0:
{*(.stab.indexstr)}
.comment0:
{*(.comment)}
/*DWARFdebugsections.
SymbolsintheDWARFdebuggingsectionsarerelativetothebeginning
ofthesectionsowebeginthemat0.*/
/*DWARF1*/
.debug0:
{*(.debug)}
.line0:
{*(.line)}
/*GNUDWARF1extensions*/
.debug_srcinfo0:
{*(.debug_srcinfo)}
.debug_sfnames0:
{*(.debug_sfnames)}
/*DWARF1.1andDWARF2*/
.debug_aranges0:
{*(.debug_aranges)}
.debug_pubnames0:
{*(.debug_pubnames)}
/*DWARF2*/
.debug_info0:
{*(.debug_info.}
.debug_abbrev0:
{*(.debug_abbrev)}
.debug_line0:
{*(.debug_line)}
.debug_frame0:
{*(.debug_frame)}
.debug_str0:
{*(.debug_str)}
.debug_loc0:
{*(.debug_loc)}
.debug_macinfo0:
{*(.debug_macinfo)}
/*SGI/MIPSDWARF2extensions*/
.debug_weaknames0:
{*(.debug_weaknames)}
.debug_funcnames0:
{*(.debug_funcnames)}
.debug_typenames0:
{*(.debug_typenames)}
.debug_varnames0:
{*(.debug_varnames)}
/*DWARF3*/
.debug_pubtypes0:
{*(.debug_pubtypes)}
.debug_ranges0:
{*(.debug_ranges)}
.gnu.attributes0:
{KEEP(*(.gnu.attributes))}
/DISCARD/:
{*(.note.GNU-stack)*(.gnu_debuglink)*(.gnu.lto_*)}
}
==================================================下面逐句解释。
OUTPUT_FORMAT("elf32-i386","elf32-i386",
"elf32-i386")
OUTPUT_ARCH(i386)OUTPUT_FORMAT和OUTPUT_ARCH都是ld脚本的保留字命令。
OUTPUT_FORMAT说明输出二进制文件的格式。
OUTPUT_ARCH说明输出文件系统平台。
ENTRY(_start)ENTRY命令的作用是,将后面括号中的符号值设置成入口地址。
入口地址(entrypoint)的定义是这样的──进程执行的第一条用户空间的指令在进程地址空间中的地址。
ld有多种方法设置进程入口地址,通常它按以下顺序:
(编号越前,优先级越高)
1,ld命令行的-e选项
2,连接脚本的ENTRY(SYMBOL)命令
3,如果定义了start符号,使用start符号值
4,如果存在.textsection,使用.textsection的第一字节的位置值
5,使用值0
SEARCH_DIR("/usr/i486-linux-gnu/lib32");
设置链接时搜寻库文件目录.
SECTIONS
{然后,接下来是一大段的SECTIONS,对应的右大括号直到脚本的末尾。
SECTIONS命令告诉ld如何把输入文件的sections映射到输出文件的各个section:
即是如何将输入section
合为输出section;如何把输出section放入程序地址空间(VMA)和进程地址空间(LMA)。
该命令格式如下:
SECTIONS
{
….
}/*Read-onlysections,mergedintotextsegment:
*/
PROVIDE(__executable_start=SEGMENT_START("text-segment",0x08048000));PROVIDE定义的变量如果源文件中已经定义值那么用源文件中的,如果没有定义则用脚本中定义的。
并设定该变量的值为0x08048000.=SEGMENT_START("text-segment",0x08048000)+SIZEOF_HEADERS;
这句把定位器符号置为0x08048000+SIZE_HEADERS(若不指定,则该符号的初始值为0)。
SIZE_HEADERS为输出文件的文件头.
.是一个特殊的符号,它是定位器,一个位置指针,指向程序地址空间内的某位置(或某section内的偏移,如果它在SECTIONS命令内的某section描述内),该符号只能在SECTIONS命令内使用。
.rel.dyn:
{
*(.rel.init)
*(.rel.text.rel.text.*.
*(.rel.fini)
*(.rel.rodata.rel.rodata.*.
*(..
*(.rel.data.rel.data.*.
*(.rel.tdata.rel.tdata.*.
*(.rel.tbss.rel.tbss.*.
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.bss.rel.bss.*.
*(.rel.ifunc)
}
.rel.plt:
{
*(.rel.plt)
PROVIDE_HIDDEN(__rel_iplt_start=.);
*(.rel.iplt)
PROVIDE_HIDDEN(__rel_iplt_end=.);
}
以上这些段主要用于重定位.具体的内容还需进一步学习.先不做介绍..init:
{
KEEP(*(.init))
}=0x
.plt:
{*(.plt)*(.iplt)}
.text:
{
*(.text.unlikely.text.*_unlikely)
*(.text.stub.text.*.
/*.gnu.warningsectionsarehandledspeciallybyelf32.em.*/
*(.gnu.warning)
}=0x.init将在下文与.fini一起介绍..text:
表示text段开始.
*(.text)将所有(*符号代表任意输入文件)输入文件的.textsection合并成一个.textsection,该section的地址由定位器符号的值指定,即0x08048000.
*(.text.unlikely.text.*_unlikely)
*(.text.stub.text.*.
/*.gnu.warningsectionsarehandledspeciallybyelf32.em.*/
*(.gnu.warning).fini:
{
KEEP(*(.fini))#
KEEP()强制连接器保留一些特定的section
}=0xELF文件中定义了.init和.fini两个特殊的段,其中.init段中的代码会在main之前被执行,.fini段中的代码会在main退出之后被执行.默认用NOP(0x90)字段进行填充.PROVIDE(__etext=.);
PROVIDE(_etext=.);
PROVIDE(etext=.);__etext=._etext=.etext=.;我们看到,很多变量都定义成等于这个.符,实际上这个符号所代表的值是在变化的,随着越往后走,值越增加,根据前面填充的多少自动往后加。
即指定当前地址值为代码段结束位置.
这里就定义了一个etext符号,当目标文件内引用了etext符号,却没有定义它时,etext符号对应的地址被定义为.textsection之后的第一个字节的地址。
.rodata:
{*(.rodata.rodata.*.}
.rodata1:
{*(.rodata1)}
数据段终于来到了,意思很容易理解的了(用于只读数据段)。
/*Adjusttheaddressforthedatasegment.Wewanttoadjustupto
thesameaddresswithinthepageonthenextpageup.*/
.=ALIGN(CONSTANT(MAXPAGESIZE))-((CONSTANT(MAXPAGESIZE)-.)&(CONSTANT(MAXPAGESIZE)-1));
.=DATA_SEGMENT_ALIGN(CONSTANT(MAXPAGESIZE),CONSTANT(COMMONPAGESIZE));
如注释所述用于地址调整,为数据段作相应的地址对齐./*ThreadLocalStoragesections*/
.tdata:
{*(.tdata.tdata.*.}
.tbss:
{*(.tbss.tbss.*.*(.tcommon)}
正如注释所描述,这两个段用于线程的局部数据段(包括data及bss)CONSTRUCTORS是一个保留字命令。
与c++内的(全局对象的)构造函数和(全局对像的)析构函数相关。
.ctors:
{
/*gccusescrtbegin.otofindthestartof
theconstructors,sowemakesureitis
first.Becausethisisawildcard,it
doesn'tmatteriftheuserdoesnot
actuallylinkagainstcrtbegin.o;the
linkerwon'tlookforafiletomatcha
wildcard.Thewildcardalsomeansthatit
doesn'tmatterwhichdirectorycrtbegin.o
isin.*/
KEEP(*crtbegin.o(.cto
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 解释 一个 ldscript 资料