- 論壇徽章:
- 0
|
title: the lds file of the Linux
refer to >, and translating it as following part.
OUTPUT_ARCH(arm)
/***************************************************************************
OUTPUT_ARCH(bfdarch)
Specify a particular output machine architecture, bfdarch. The argument is one of
the names used by the BFD library. You can see the architecture of an object file
by using the objdump program with the -f option.
(譯)
OUTPUT_ARCH(bfdarch)
指定的一個(gè)特定的輸出機(jī)器體系,bfdarch。參數(shù)名被BFD庫所使用。你能夠使用帶有-f選項(xiàng)的
objdump程序來查看object文件的體系結(jié)構(gòu)。
***************************************************************************/
ENTRY(stext)
/***************************************************************************
Setting the Entry Point
The first instruction to execute in a program is called the entry point. You can use the
ENTRY linker script command to set the entry point. The argument is a symbol name:
ENTRY (symbol)
There are several ways to set the entry point. The linker will set the entry point by
trying each of the following methods in order, and stopping when one of them
succeeds:
1) The -e entry command-line option;
2) The ENTRY (symbol) command in a linker script;
3) The value of the symbol, start, if defined;
4) The address of the first byte of the .text section, if present;
5) The address, 0.
(譯)
設(shè)置入口點(diǎn)
程序第一個(gè)指令的執(zhí)行被叫做入口點(diǎn)。你能夠使用ENTRY連接器腳本命令去設(shè)置入口點(diǎn)。參數(shù)是一個(gè)
符號名:
ENTRY (symbol)
有幾種方法去設(shè)置入口點(diǎn)。連接器將設(shè)置入口點(diǎn),通過順序的嘗試下面的方法和當(dāng)一旦有成功找到就
立即停止:
1) 通過命令行參數(shù)-e entry傳遞入口點(diǎn)。
2) 通過在鏈接腳本設(shè)置ENTRY (symbol)。
3) 符號值,start, 如果定義了。
4) 如果存在.text段,那么就默認(rèn)是.text段第一字節(jié)的地址。
5) 如果上面都找不到,那么默認(rèn)是地址 0 。
***************************************************************************/
jiffies = jiffies_64;
/***************************************************************************
(1)Assigning Values to Symbols
You may assign a value to a symbol in a linker script. This will define the symbol as a
global symbol. The following documentation discusses such assignments in more
detail.
1) “Simple Assignments” on page 35
2) “PROVIDE Keyword” on page 36
(1.1)Simple Assignments
You may assign to a symbol using any of the C assignment operators:
symbol = expression ;
symbol += expression ;
symbol -= expression ;
symbol *= expression ;
symbol /= expression ;
symbol >= expression ;
symbol &= expression ;
symbol |= expression ;
1) The first case will define symbol to the value of expression. In the other cases,
symbol must already be defined, and the value will be accordingly adjusted.
2) The special . symbol name indicates the location counter. You may only use this
within a SECTIONS command.
3) The semicolon after expression is required.
4) See “Expressions in Linker Scripts” on page 55.
5) You may write symbol assignments as commands in their own right, or as
statements within a SECTIONS command, or as part of an output section
description in a SECTIONS command.
6) The section of the symbol will be set from the section of the expression; for more
information, see “Expressions in Linker Scripts” on page 55.
7) The following is an example showing the three different places that symbol
assignments may be used:
floating_point = 0;
SECTIONS
{
.text :
{
*(.text)
_etext = .;
}
_bdata = (. + 3) & ~ 4;
.data : { *(.data) }
}
In the previous example, the floating_point symbol will be defined as zero. The
_etext symbol will be defined as the address following the last .text input section.
The symbol _bdata will be defined as the address following the .text output section
aligned upward to a 4 byte boundary.
(1.2)PROVIDE Keyword
In some cases, it is desirable for a linker script to define a symbol only if it is
referenced and is not defined by any object included in the link. For example,
traditional linkers defined the symbol etext. However, ANSI C requires that the user
be able to use etext as a function name without encountering an error. The PROVIDE
keyword may be used to define a symbol, such as etext, only if it is referenced but
not defined. The syntax is PROVIDE(symbol = expression).
Here is an example of using PROVIDE to define etext:
SECTIONS
{
.text :
{
*(.text)
_etext = .;
PROVIDE(etext = .);
}
}
In the previousexample, if the program defines _etext, the linker will give a multiple
definition error. If, on the other hand, the program defines etext, the linker will
silently use the definition in the program. If the program references etext but does not
define it, the linker will use the definition in the linker script.
(譯)
(1)符號賦值
你可以在鏈接腳本里賦值給一個(gè)符號變量。這將定義這個(gè)符號為全局的符號。下面的文檔更詳細(xì)的討論這樣的賦值:
(1.1) “簡單賦值“
(1.2) “PROVIDE關(guān)鍵字”
(1.1)簡單賦值
你可以使用任何的C賦值操作賦值給一個(gè)符號:
symbol = expression ;
symbol += expression ;
symbol -= expression ;
symbol *= expression ;
symbol /= expression ;
symbol >= expression ;
symbol &= expression ;
symbol |= expression ;
1) 第一種情況將定義符號為表達(dá)式的值。在另一種情況,符號必須已經(jīng)被定義,和這個(gè)值將相應(yīng)的被改變。
2) 特殊的 . 符號名指示了本地計(jì)數(shù)器。你可以僅僅在SECTIONS命令里使用它。
3) 表達(dá)式后面的分號是必須的。
4) 查看55頁的 “Expressions in Linker Scripts”。
5) 你可以在它們自己的權(quán)限里寫一個(gè)符號賦值語句作為命令,或者在一個(gè)SECTIONS命令里作為語句,或者在一個(gè)SECTIONS命令里
作為輸出段描述的一部分。
6) 符號段將從表達(dá)式段被設(shè)置,更詳細(xì)的信息,參見55頁的“Expressions in Linker Scripts”。
7) 下面例子示范了三個(gè)不同地方,符號賦值可以被使用到:
floating_point = 0;
SECTIONS
{
.text :
{
*(.text)
_etext = .;
}
_bdata = (. + 3) & ~ 4;
.data : { *(.data) }
}
在前面的例子,floating_point符號將被定義為0. 符號_etext將被定義為緊跟輸入段.text的最后地址。
符號 _bdata將被定義為緊跟輸出段.text的最后地址。賦值將是向上4字節(jié)邊界對齊。
(1.2) PROVIDE 關(guān)鍵字
在某些情況,渴望連接器定義一個(gè)符號,僅僅是如果它被引用到,和沒有被鏈接器里包含的任何object文件里定義到。
例如,傳統(tǒng)的連接器定義符號etext。然而,ANSI C在沒有遇到錯(cuò)誤的時(shí)候需要用戶能夠使用etext作為一個(gè)函數(shù)名。
關(guān)鍵字PROVIDE 可以常被用來定義一個(gè)符號,例如etext,僅僅如果它被引用到,但沒被定義。
語法PROVIDE(symbol = expression).
這里是一個(gè)使用PROVIDE的例子去定義了etext:
SECTIONS
{
.text :
{
*(.text)
_etext = .;
PROVIDE(etext = .);
}
}
在前面的例子里, 如果程序定義了 _etext, 鏈接器將給出一多個(gè)定義的錯(cuò)誤信息。如果,另一方面,
程序定義了etext,連接器將在程序里默認(rèn)的使用這個(gè)定義。如果程序引用引用etext,但沒有定義它,
連接器將在連接器腳本里使用這個(gè)定義。
***************************************************************************/
SECTIONS
{
. = 0xC0008000;
.init : { /* Init code and data */
_stext = .;
_sinittext = .;
*(.init.text)
/***************************************************************************
section (“section-name”)
Normally, the compiler places the code it generates in the text section.
Sometimes, however, you need additional sections, or you need certain particular
functions to appear in special sections. The section attribute specifies that a
function lives in a particular section. For example, the following declaration puts
the function, foobar, in the bar section.
extern void foobar (void) __attribute__ \
((section (“bar”)));
Some file formats do not support arbitrary sections so the section attribute is not
available on all platforms. If you need to map the entire contents of a module to a
particular section, consider using the facilities of the linker instead.
(譯)(注:這里小片段是引用gcc編譯器說明文檔的,因?yàn)檫@些產(chǎn)生的段名稱需要編譯器支持)
段 (“段名”)
一般地,編譯器放置它自己產(chǎn)生的代碼到text段。有時(shí)候,然而,你需要附加的段,或者你需要某個(gè)特殊函數(shù)出現(xiàn)
在特殊的段里。段屬性attribute指示了一個(gè)函數(shù)被放置在特定的段里。例如,下面的聲明把函數(shù)foobar放置在bar段。
extern void foobar (void) __attribute__ \
((section (“bar”)));
有些文件格式不支持任意段,這樣段屬性在所有的平臺都不起作用。如果你需要映射模塊的整個(gè)內(nèi)容到一個(gè)特殊的段,
考慮使用連接器機(jī)制來代替。
***************************************************************************/
_einittext = .;
__proc_info_begin = .;
*(.proc.info)
__proc_info_end = .;
__arch_info_begin = .;
*(.arch.info)
__arch_info_end = .;
__tagtable_begin = .;
*(.taglist)
__tagtable_end = .;
. = ALIGN(16);
/***************************************************************************
Builtin Functions
The linker script language includes the following builtin functions for use in linker
script expressions.
ABSOLUTE(exp)
Return the absolute (non-relocatable, as opposed to non-negative) value of the exp
expression. Primarily useful to assign an absolute value to a symbol within a
section definition, where symbol values are normally section relative. See
“Expressions in Linker Scripts” on page 55.
ADDR(section)
Return the absolute address (the VMA) of the named section. Your script must
previously have defined the location of that section. In the following example,
symbol_1 and symbol_2 are assigned identical values:
SECTIONS { ...
.output1 :
{
start_of_output_1 = ABSOLUTE(.);
...
}
.output :
{
symbol_1 = ADDR(.output1);
symbol_2 = start_of_output_1;
}
...
}
ALIGN(exp)
Return the location counter (.) aligned to the next exp boundary. exp must be an
expression whose value is a power of two. This is equivalent to:
(. + exp - 1) & ~(exp - 1)
ALIGN does not change the value of the location counter, it just does arithmetic on
it. Here is an example which aligns the output .data section to the next 0x2000
byte boundary after the preceding section and sets a variable within the section to
the next 0x8000 boundary after the input sections:
SECTIONS { ...
.data ALIGN(0x2000): {
*(.data)
variable = ALIGN(0x8000);
}
...
}
The first use of ALIGN in this example specifies the location of a section because it is
used as the optional ADDRESS attribute of a section definition. The second use of ALIGN
is to define the value of a symbol. The builtin function NEXT is closely related to
ALIGN. See “Output Section Address” on page 39.
BLOCK(exp)
This is a synonym for ALIGN, for compatibility with older linker scripts. It is most
often seen when setting the address of an output section.
DEFINED(symbol)
Return 1 if symbol is in the linker global symbol table and is defined, otherwise
return 0. You can use this function to provide default values for symbols. For
example, the following script fragment shows how to set a global symbol begin to
the first location in the .text section, but if a symbol called begin already
existed, its value is preserved:
SECTIONS{ ...
.text : {
begin = DEFINED(begin) ? begin : . ;
...
}
...
}
LOADADDR(section)
Return the absolute LMA of the named SECTION. This is normally the same as ADDR,
but it may be different if the AT attribute is used in the output section definition.
MAX(exp1, exp2)
Returns the maximum of exp1 and exp2.
MIN(exp1, exp2)
Returns the minimum of exp1 and exp2.
NEXT(exp)
Return the next unallocated address that is a multiple of exp. This function is
closely related to ALIGN(exp); unless you use the MEMORY command to define
discontinuous memory for the output file, the two functions are equivalent.
SIZEOF(section)
Return the size in bytes of the named section, if that section has been allocated.
If the section has not been allocated when this is evaluated, the linker will report
an error. See “PHDRS Command” on page 50. In the following example,
symbol_1 and symbol_2 are assigned identical values:
SECTIONS{ ...
.output {
.start = . ;
...
SIZEOF_HEADERS
Return the size in bytes of the output file’s headers. This is information which
appears at the start of the output file. You can use this number when setting the
start address of the first section, if you choose, to facilitate paging.
When producing an ELF output file, if the linker script uses the SIZEOF_HEADERS
builtin function, the linker must compute the number of program headers before it
has determined all the section addresses and sizes. If the linker later discovers that
it needs additional program headers, it will report an “not enough room for
program headers” error . To avoid this error, you must avoid using the
SIZEOF_HEADERS function, or you must rework your linker script to avoid forcing
the linker to use additional program headers, or you must define the program
headers yourself using the PHDRS command (see “PHDRS Command” on page
50).
(譯)
內(nèi)建函數(shù)
連接器腳本語言包含下面的內(nèi)建函數(shù),提供給連接器腳本表達(dá)式使用。
ABSOLUTE(exp)
返回一個(gè)絕對的(不可重定位的,與non-negative相對立) 表達(dá)式的值。主要用在一個(gè)段定義里賦值
一個(gè)絕對值給符號,這個(gè)符號值與正規(guī)段相關(guān)。參見55頁“Expressions in Linker Scripts”。
ADDR(section)
返回一個(gè)命名段的絕對地址(the VMA)。 你的腳本必須預(yù)先地在本地定義那個(gè)段。在下面的例子里,
symbol_1 和 symbol_2 被賦值為一值:
SECTIONS { ...
.output1 :
{
start_of_output_1 = ABSOLUTE(.);
...
}
.output :
{
symbol_1 = ADDR(.output1);
symbol_2 = start_of_output_1;
}
...
}
ALIGN(exp)
返回一個(gè)本地計(jì)數(shù)器(.) ,這數(shù)值與下一個(gè)exp邊界對齊。exp必須是一個(gè)值是2的指數(shù)的表達(dá)式。這相當(dāng)于:
(. + exp - 1) & ~(exp - 1)
ALIGN不會改變本地計(jì)數(shù)器的值,只是使用它計(jì)算。這里是一個(gè)例子,它使輸出段.data在前一個(gè)段之后對齊到下一個(gè)0x2000
字節(jié)邊界,和在這個(gè)段里設(shè)置一個(gè)變量,這變量對齊在輸入端之后的下一個(gè)0x8000的邊界:
SECTIONS { ...
.data ALIGN(0x2000): {
*(.data)
variable = ALIGN(0x8000);
}
...
}
在這個(gè)例子中,第一個(gè)ALIGN指定了一個(gè)段的位置,因?yàn)樗挥脕碜鳛橐粋(gè)可選的段定義的ADDRESS屬性。第二個(gè)ALIGN使用是
定義一個(gè)符號值。內(nèi)建函數(shù)NEXT跟ALIGN密切相關(guān)。參見“Output Section Address”。
BLOCK(exp)
這是一個(gè)ALIGN的近義詞,為了兼容老式的鏈接腳本。它常常在設(shè)定輸出段地址時(shí)候能看到。
DEFINED(symbol)
返回1,如果符號在連接器全局符號表里存在并定義了。否則返回0.你能夠使用這個(gè)函數(shù)去提供該符號的默認(rèn)值。例如,下面的腳本片段
示范了如何去設(shè)置一個(gè)全局符號begin為.text段的第一個(gè)位置,但是如果begin符號已經(jīng)存在,它的值將被保留。
SECTIONS{ ...
.text : {
begin = DEFINED(begin) ? begin : . ;
...
}
...
}
LOADADDR(section)
返回一個(gè)絕對的已命名段的LMA。這是常規(guī)地跟ADDR一樣,但它可以不同,當(dāng)AT屬性在輸出段定義里被使用到
MAX(exp1, exp2)
返回exp1和exp2中的最大值。
MIN(exp1, exp2)
返回exp1和exp2中的最小值。
NEXT(exp)
返回下一個(gè)沒被分配的地址,這地址是exp的倍數(shù)。這函數(shù)與ALIGN(exp)密切相關(guān);除非你 使用MEMORY命令去為
輸出文件定義不連續(xù)的內(nèi)存,否則這兩個(gè)函數(shù)是是相同的。
SIZEOF(section)
如果那段已經(jīng)被分配,返回命名段的字節(jié)數(shù)。當(dāng)這個(gè)被評估時(shí),如果這段還沒被分配,連接器將報(bào)告一個(gè)錯(cuò)誤。
參見50頁"PHDRS Command”。在如下的例子,symbol_1和symbol_2被賦唯一值:
SECTIONS{ ...
.output {
.start = . ;
...
SIZEOF_HEADERS
返回輸出文件頭部的字節(jié)數(shù)。這些信息出現(xiàn)在輸出文件的開始處。當(dāng)設(shè)置第一個(gè)段的開始地址時(shí),你能夠使用這個(gè)數(shù)字,
如果你選擇了加速分頁。當(dāng)產(chǎn)生一個(gè)ELF輸出文件時(shí),如果鏈接器腳本使用SIZEOF_HEADERS內(nèi)建函數(shù),連接器必須在它
算出所有段地址和長度之前計(jì)算程序頭部的數(shù)值。如果連接器后來發(fā)現(xiàn)它需要附加程序頭,它將報(bào)告一個(gè)“not enough room for
program headers”錯(cuò)誤。為了避免這樣的錯(cuò)誤,你必須避免使用SIZEOF_HEADERS函數(shù),或者你必須修改你的連接器腳本去避免強(qiáng)制
連接器去使用附加程序頭,或者你必須使用PHDRS命令去定義你自己的程序頭。(參見50頁“PHDRS Command”)。
***************************************************************************/
__setup_start = .;
*(.init.setup)
__setup_end = .;
__early_begin = .;
*(__early_param)
__early_end = .;
__initcall_start = .;
*(.initcall1.init)
*(.initcall2.init)
*(.initcall3.init)
*(.initcall4.init)
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
__initcall_end = .;
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
__security_initcall_start = .;
*(.security_initcall.init)
__security_initcall_end = .;
. = ALIGN(32);
__initramfs_start = .;
usr/built-in.o(.init.ramfs)
__initramfs_end = .;
. = ALIGN(64);
__per_cpu_start = .;
*(.data.percpu)
__per_cpu_end = .;
__init_begin = _stext;
*(.init.data)
. = ALIGN(4096);
__init_end = .;
}
/DISCARD/ : { /* Exit code and data */
*(.exit.text)
*(.exit.data)
*(.exitcall.exit)
}
.text : { /* Real text segment */
_text = .; /* Text and read-only data */
*(.text)
__sched_text_start = .; *(.sched.text) __sched_text_end = .;
__lock_text_start = .; *(.spinlock.text) __lock_text_end = .;
*(.fixup)
*(.gnu.warning)
*(.rodata)
*(.rodata.*)
*(.glue_7)
*(.glue_7t)
*(.got) /* Global offset table */
}
. = ALIGN(16);
__ex_table : { /* Exception table */
__start___ex_table = .;
*(__ex_table)
__stop___ex_table = .;
}
.rodata : AT(ADDR(.rodata) - 0) { *(.rodata) *(.rodata.*) *(__vermagic) } .rodata1 : AT(ADDR(.rodata1) - 0) { *(.rodata1) } .pci_fixup : AT(ADDR(.pci_fixup) - 0) { __start_pci_fixups_early = .; *(.pci_fixup_early) __end_pci_fixups_early = .; __start_pci_fixups_header = .; *(.pci_fixup_header) __end_pci_fixups_header = .; __start_pci_fixups_final = .; *(.pci_fixup_final) __end_pci_fixups_final = .; __start_pci_fixups_enable = .; *(.pci_fixup_enable) __end_pci_fixups_enable = .; } __ksymtab : AT(ADDR(__ksymtab) - 0) { __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; } __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - 0) { __start___ksymtab_gpl = .; *(__ksymtab_gpl) __stop___ksymtab_gpl = .; } __kcrctab : AT(ADDR(__kcrctab) - 0) { __start___kcrctab = .; *(__kcrctab) __stop___kcrctab = .; } __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - 0) { __start___kcrctab_gpl = .; *(__kcrctab_gpl) __stop___kcrctab_gpl = .; } __ksymtab_strings : AT(ADDR(__ksymtab_strings) - 0) { *(__ksymtab_strings) } __param : AT(ADDR(__param) - 0) { __start___param = .; *(__param) __stop___param = .; }
_etext = .; /* End of text and rodata section */
. = ALIGN(8192);
__data_loc = .;
.data : AT(__data_loc) {
__data_start = .; /* address in memory */
/*
* first, the init task union, aligned
* to an 8192 byte boundary.
*/
*(.init.task)
. = ALIGN(4096);
__nosave_begin = .;
*(.data.nosave)
. = ALIGN(4096);
__nosave_end = .;
/*
* then the cacheline aligned data
*/
. = ALIGN(32);
*(.data.cacheline_aligned)
/*
* and the usual data section
*/
*(.data)
CONSTRUCTORS
_edata = .;
}
.bss : {
__bss_start = .; /* BSS */
*(.bss)
*(COMMON)
_end = .;
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
}
/* those must never be empty */
ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
you can use the objdump tool to show all the header infomation, as below:
[root@localhost kernel-2.6.13]# objdump -h vmlinux
vmlinux: file format elf32-little
Sections:
Idx Name Size VMA LMA File off Algn
0 .init 00024000 c0008000 c0008000 00008000 2**5
CONTENTS, ALLOC, LOAD, CODE
1 .text 002693e4 c002c000 c002c000 0002c000 2**8
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 __ex_table 00000a50 c02953f0 c02953f0 002953f0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .pci_fixup 00000000 c0295e40 c0295e40 00331e40 2**0
CONTENTS
4 __ksymtab 00004380 c0295e40 c0295e40 00295e40 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 __ksymtab_gpl 000007d8 c029a1c0 c029a1c0 0029a1c0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 __kcrctab 00000000 c029a998 c029a998 00331e40 2**0
CONTENTS
7 __kcrctab_gpl 00000000 c029a998 c029a998 00331e40 2**0
CONTENTS
8 __ksymtab_strings 0000a884 c029a998 c029a998 0029a998 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 __param 0000071c c02a521c c02a521c 002a521c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .data 0008be40 c02a6000 c02a6000 002a6000 2**5
CONTENTS, ALLOC, LOAD, DATA
11 .bss 0006fa3c c0331e40 c0331e40 00331e40 2**5
ALLOC
12 .comment 000028b6 00000000 00000000 00331e40 2**0
CONTENTS, READONLY
本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u3/94861/showart_1935954.html |
|