![鏈接腳本語(yǔ)言的編寫(xiě)_第1頁(yè)](http://file4.renrendoc.com/view/acc9939fcaffeab03c76b3cb2aaad7aa/acc9939fcaffeab03c76b3cb2aaad7aa1.gif)
![鏈接腳本語(yǔ)言的編寫(xiě)_第2頁(yè)](http://file4.renrendoc.com/view/acc9939fcaffeab03c76b3cb2aaad7aa/acc9939fcaffeab03c76b3cb2aaad7aa2.gif)
![鏈接腳本語(yǔ)言的編寫(xiě)_第3頁(yè)](http://file4.renrendoc.com/view/acc9939fcaffeab03c76b3cb2aaad7aa/acc9939fcaffeab03c76b3cb2aaad7aa3.gif)
![鏈接腳本語(yǔ)言的編寫(xiě)_第4頁(yè)](http://file4.renrendoc.com/view/acc9939fcaffeab03c76b3cb2aaad7aa/acc9939fcaffeab03c76b3cb2aaad7aa4.gif)
![鏈接腳本語(yǔ)言的編寫(xiě)_第5頁(yè)](http://file4.renrendoc.com/view/acc9939fcaffeab03c76b3cb2aaad7aa/acc9939fcaffeab03c76b3cb2aaad7aa5.gif)
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
本文格式為Word版,下載可任意編輯——鏈接腳本語(yǔ)言的編寫(xiě)0.Contents1.概論2.基本概念3.腳本格式4.簡(jiǎn)單例子5.簡(jiǎn)單腳本命令6.對(duì)符號(hào)的賦值7.SECTIONS命令8.MEMORY命令9.PHDRS命令10.VERSION命令11.腳本內(nèi)的表達(dá)式12.暗含的連接腳本1.概論
編譯的過(guò)程得到的obj文件,是完全和地址無(wú)關(guān)的,例如,每個(gè)源文件對(duì)應(yīng)的obj文件,地址都是從0開(kāi)始的,它真正連接的時(shí)候才由連接器
linker分派真正運(yùn)行時(shí)候的地址,所以,你要想處理每個(gè)具體的代碼段運(yùn)行的時(shí)候應(yīng)當(dāng)在什么地方,就要注意學(xué)習(xí)link了。
每一個(gè)鏈接過(guò)程都由鏈接腳本(linkerscript,一般以lds作為文件的后綴名)控制.鏈接腳本主要用于規(guī)定如何把輸入文件內(nèi)的section放入輸出文件內(nèi),并控制輸出文件內(nèi)各部分在程序地址空間內(nèi)的布局.但你也可以用連接命令做一些其他事情.
連接器有個(gè)默認(rèn)的內(nèi)置連接腳本,可用ld--verbose查看.連接選項(xiàng)-r和-N可以影響默認(rèn)的連接腳本(如何影響?).
-T選項(xiàng)用以指定自己的鏈接腳本,它將代替默認(rèn)的連接腳本。你也可以使用以增加自定義的鏈接命令.
以下沒(méi)有特別說(shuō)明,連接器指的是靜態(tài)連接器.2.基本概念
鏈接器把一個(gè)或多個(gè)輸入文件合成一個(gè)輸出文件.輸入文件:目標(biāo)文件或鏈接腳本文件.輸出文件:目標(biāo)文件或可執(zhí)行文件.
目標(biāo)文件(包括可執(zhí)行文件)具有固定的格式,在UNIX或GNU/Linux平臺(tái)下,一般為ELF格式.若想了解更多,可參考UNIX/Linux平臺(tái)可執(zhí)行文件格式分析
有時(shí)把輸入文件內(nèi)的section稱(chēng)為輸入section(inputsection),把輸出文件內(nèi)的section稱(chēng)為輸出section(outputsectin).
目標(biāo)文件的每個(gè)section至少包含兩個(gè)信息:名字和大小.大部分section還包含與它相關(guān)聯(lián)的一塊數(shù)據(jù),稱(chēng)為sectioncontents(section內(nèi)容).一個(gè)section可被標(biāo)記為“l(fā)oadable(可加載的)〞或“allocatable(可分派的)〞.
loadablesection:在輸出文件運(yùn)行時(shí),相應(yīng)的section內(nèi)容將被載入進(jìn)程地址空間中.
allocatablesection:內(nèi)容為空的section可被標(biāo)記為“可分派的〞.在輸出文件運(yùn)行時(shí),在進(jìn)程地址空間中空出大小同section指定大小的部分.某些狀況下,這塊內(nèi)存必需被置零.
假使一個(gè)section不是“可加載的〞或“可分派的〞,那么該section尋常包含了調(diào)試信息.可用
objdump-h命令查看相關(guān)信息.
每個(gè)“可加載的〞或“可分派的〞輸出section尋常包含兩個(gè)地址:VMA(virtualmemoryaddress虛擬內(nèi)存地址或程序地址空間地址)和LMA(loadmemoryaddress加載內(nèi)存地址或進(jìn)程地址空間地址).尋常VMA和LMA是一致的.
在目標(biāo)文件中,loadable或allocatable的輸出section有兩種地址:VMA(virtualMemoryAddress)和LMA(LoadMemoryAddress).VMA是執(zhí)行輸出文件時(shí)section所在的地址,而LMA是加載輸出文件時(shí)section所在的地址.一般而言,某section的VMA==LMA.但在嵌入式系統(tǒng)中,經(jīng)常存在加載地址和執(zhí)行地址不同的狀況:譬如將輸出文件加載到開(kāi)發(fā)板的flash中(由LMA指定),而在運(yùn)行時(shí)將位于flash中的輸出文件復(fù)制到SDRAM中(由VMA指定).
可這樣來(lái)理解VMA和LMA,假設(shè):
(1).datasection對(duì)應(yīng)的VMA地址是0x08050000,該section內(nèi)包含了3個(gè)32位全局變量,i、j和k,分別為1,2,3.
(2).textsection內(nèi)包含由\程序片段產(chǎn)生的代碼.
連接時(shí)指定.datasection的VMA為0x08050000,產(chǎn)生的printf指令是將地址為0x08050004處的4字節(jié)內(nèi)容作為一個(gè)整數(shù)打印出來(lái)。
假使.datasection的LMA為0x08050000,顯然結(jié)果是j=2假使.datasection的LMA為0x08050004,顯然結(jié)果是j=1還可這樣理解LMA:
.textsection內(nèi)容的開(kāi)始處包含如下兩條指令(inteli386指令是10字節(jié),每行對(duì)應(yīng)5字節(jié)):jmp0x08048285movl$0x1,êx
假使.textsection的LMA為0x08048280,那么在進(jìn)程地址空間內(nèi)0x08048280處為“jmp0x08048285〞指令,0x08048285處為movl$0x1,êx指令.假設(shè)某指令跳轉(zhuǎn)到地址0x08048280,顯然它的執(zhí)行將導(dǎo)致êx寄放器被賦值為1.
假使.textsection的LMA為0x08048285,那么在進(jìn)程地址空間內(nèi)0x08048285處為“jmp0x08048285〞指令,0x0804828a處為movl$0x1,êx指令.假設(shè)某指令跳轉(zhuǎn)到地址0x08048285,顯然它的執(zhí)行又跳轉(zhuǎn)到進(jìn)程地址空間內(nèi)0x08048285處,造成死循環(huán).
符號(hào)(symbol):每個(gè)目標(biāo)文件都有符號(hào)表(SYMBOLTABLE),包含已定義的符號(hào)(對(duì)應(yīng)全局變量和static變量和定義的函數(shù)的名字)和未定義符號(hào)(未定義的函數(shù)的名字和引用但沒(méi)定義的符號(hào))信息.
符號(hào)值:每個(gè)符號(hào)對(duì)應(yīng)一個(gè)地址,即符號(hào)值(這與c程序內(nèi)變量的值不一樣,某種狀況下可以把它看成變量的地址).可用nm命令查看它們.(nm的使用方法可參考本blog的GNUbinutils筆記)
3.腳本格式
鏈接腳本由一系列命令組成,每個(gè)命令由一個(gè)關(guān)鍵字(一般在其后緊跟相關(guān)參數(shù))或一條對(duì)符號(hào)的賦值語(yǔ)句組成.命令由分號(hào)?;?分隔開(kāi).
文件名或格式名內(nèi)假使包含分號(hào)';'或其他分隔符,則要用引號(hào)?\將名字全稱(chēng)引用起來(lái).無(wú)法處理含引號(hào)的文件名./**/之間的是解釋。4.簡(jiǎn)單例子
在介紹鏈接描述文件的命令之前,先看看下述的簡(jiǎn)單例子:
以下腳本將輸出文件的textsection定位在0x10000,datasection定位在0x8000000:SECTIONS{
.=0x10000;.text:{*(.text)}.=0x8000000;.data:{*(.data)}.bss:{*(.bss)}}
解釋一下上述的例子:
.=0x10000:把定位器符號(hào)置為0x10000(若不指定,則該符號(hào)的初始值為0).
.text:{*(.text)}:將所有(*符號(hào)代表任意輸入文件)輸入文件的.textsection合并成一個(gè).textsection,該section的地址由定位器符號(hào)的值指定,即0x10000..=0x8000000:把定位器符號(hào)置為0x8000000
.data:{*(.data)}:將所有輸入文件的.textsection合并成一個(gè).datasection,該section的地址被置為0x8000000.
.bss:{*(.bss)}:將所有輸入文件的.bsssection合并成一個(gè).bsssection,該section的地址被置為0x8000000+.datasection的大小.
連接器每讀完一個(gè)section描述后,將定位器符號(hào)的值*增加*該section的大小.注意:此處沒(méi)有考慮對(duì)齊約束.5.簡(jiǎn)單腳本命令
-1-
ENTRY(SYMBOL):將符號(hào)SYMBOL的值設(shè)置成入口地址。
入口地址(entrypoint):進(jìn)程執(zhí)行的第一條用戶(hù)空間的指令在進(jìn)程地址空間的地址)ld有多種方法設(shè)置進(jìn)程入口地址,按一下順序:(編號(hào)越前,優(yōu)先級(jí)越高)1,ld命令行的-e選項(xiàng)
2,連接腳本的ENTRY(SYMBOL)命令3,假使定義了start符號(hào),使用start符號(hào)值
4,假使存在.textsection,使用.textsection的第一字節(jié)的位置值5,使用值0-2-
INCLUDEfilename:包含其他名為filename的鏈接腳本
相當(dāng)于c程序內(nèi)的的#include指令,用以包含另一個(gè)鏈接腳本.
腳本探尋路徑由-L選項(xiàng)指定.INCLUDE指令可以嵌套使用,最大深度為10.即:文件1內(nèi)INCLUDE文件2,文件2內(nèi)INCLUDE文件3...,文件10內(nèi)INCLUDE文件11.那么文件11內(nèi)不能再出現(xiàn)INCLUDE指令了.-3-
INPUT(files):將括號(hào)內(nèi)的文件做為鏈接過(guò)程的輸入文件
ld首先在當(dāng)前目錄下尋覓該文件,假使沒(méi)找到,則在由-L指定的探尋路徑下探尋.file可以為-lfile形式,就象命令行的-l選項(xiàng)一樣.假使該命令出現(xiàn)在暗含的腳本內(nèi),則該命令內(nèi)的file在鏈接過(guò)程中的順序由該暗含的腳本在命令行內(nèi)的順序決定.-4-
GROUP(files):指定需要重復(fù)探尋符號(hào)定義的多個(gè)輸入文件
file必需是庫(kù)文件,且file文件作為一組被ld重復(fù)掃描,直到不在有新的未定義的引用出現(xiàn)。-5-
OUTPUT(FILENAME):定義輸出文件的名字
同ld的-o選項(xiàng),不過(guò)-o選項(xiàng)的優(yōu)先級(jí)更高.所以它可以用來(lái)定義默認(rèn)的輸出文件名.如a.out-6-
SEARCH_DIR(PATH):定義探尋路徑,
同ld的-L選項(xiàng),不過(guò)由-L指定的路徑要比它定義的優(yōu)先被探尋。-7-
STARTUP(filename):指定filename為第一個(gè)輸入文件
在鏈接過(guò)程中,每個(gè)輸入文件是有順序的.此命令設(shè)置文件filename為第一個(gè)輸入文件。-8-
OUTPUT_FORMAT(BFDNAME):設(shè)置輸出文件使用的BFD格式
同ld選項(xiàng)-oformatBFDNAME,不過(guò)ld選項(xiàng)優(yōu)先級(jí)更高.-9-
OUTPUT_FORMAT(DEFAULT,BIG,LITTLE):定義三種輸出文件的格式(大小端)
若有命令行選項(xiàng)-EB,則使用第2個(gè)BFD格式;若有命令行選項(xiàng)-EL,則使用第3個(gè)BFD格式.否則默認(rèn)選第一個(gè)BFD格式.
TARGET(BFDNAME):設(shè)置輸入文件的BFD格式
同ld選項(xiàng)-bBFDNAME.若使用了TARGET命令,但未使用OUTPUT_FORMAT命令,則最用一個(gè)TARGET命令設(shè)置的BFD格式將被作為輸出文件的BFD格式.另外還有一些:
ASSERT(EXP,MESSAGE):假使EXP不為真,終止連接過(guò)程
EXTERN(SYMBOLSYMBOL...):在輸出文件中增加未定義的符號(hào),宛如連接器選項(xiàng)-uFORCE_COMMON_ALLOCATION:為commonsymbol(通用符號(hào))分派空間,即使用了-r連接選項(xiàng)也為其分派
NOCROSSREFS(SECTIONSECTION...):檢查列出的輸出section,假使發(fā)現(xiàn)他們之間有相互引用,則報(bào)錯(cuò)。對(duì)于某些系統(tǒng),特別是內(nèi)存較緊張的嵌入式系統(tǒng),某些section是不能同時(shí)存在內(nèi)存中的,所以他們之間不能相互引用。
OUTPUT_ARCH(BFDARCH):設(shè)置輸出文件的machinearchitecture(體系結(jié)構(gòu)),BFDARCH為被BFD庫(kù)使用的名字之一。可以用命令objdump-f查看。
可通過(guò)man-S1ld查看ld的聯(lián)機(jī)幫助,里面也包括了對(duì)這些命令的介紹.6.對(duì)符號(hào)的賦值
在目標(biāo)文件內(nèi)定義的符號(hào)可以在鏈接腳本內(nèi)被賦值.(注意和C語(yǔ)言中賦值的不同!)此時(shí)該符號(hào)被定義為全局的.每個(gè)符號(hào)都對(duì)應(yīng)了一個(gè)地址,此處的賦值是更改這個(gè)符號(hào)對(duì)應(yīng)的地址.e.g.通過(guò)下面的程序查看變量a的地址:/*a.c*/
#includeinta=100;intmain(void){
printf(\return0;}
/*a.lds*/a=3;
$gcc-Wall-oa-without-ldsa.cSYMBOL+=EXPRESSION;SYMBOL-=EXPRESSION;SYMBOL*=EXPRESSION;SYMBOL/=EXPRESSION;SYMBOL>=EXPRESSION;SYMBOLSYMBOL|=EXPRESSION;
除了第一類(lèi)表達(dá)式外,使用其他表達(dá)式需要SYMBOL被定義于某目標(biāo)文件。.是一個(gè)特別的符號(hào),它是定位器,一個(gè)位置指針,指向程序地址空間內(nèi)的某位置(或某section內(nèi)的偏移,假使它在SECTIONS命令內(nèi)的某section描述內(nèi)),該符號(hào)只能在SECTIONS命令內(nèi)使用。
注意:賦值語(yǔ)句包含4個(gè)語(yǔ)法元素:符號(hào)名、操作符、表達(dá)式、分號(hào);一個(gè)也不能少。被賦值后,符號(hào)所屬的section被設(shè)值為表達(dá)式EXPRESSION所屬的SECTION(參看11.腳本內(nèi)的表達(dá)式)
賦值語(yǔ)句可以出現(xiàn)在連接腳本的三處地方:SECTIONS命令內(nèi),SECTIONS命令內(nèi)的section描述內(nèi)和全局位置;如下,
floating_point=0;/*全局位置*/SECTIONS
{.text:{
*(.text)
_etext=.;/*section描述內(nèi)*/}
_bdata=(.+3)/*SECTIONS命令內(nèi)*/.data:{*(.data)}}
PROVIDE關(guān)鍵字
該關(guān)鍵字用于定義這類(lèi)符號(hào):在目標(biāo)文件內(nèi)被引用,但沒(méi)有在任何目標(biāo)文件內(nèi)被定義的符號(hào)。例子:SECTIONS{.text:{
*(.text)_etext=.;
PROVIDE(etext=.);}}
當(dāng)目標(biāo)文件內(nèi)引用了etext符號(hào),確沒(méi)有定義它時(shí),etext符號(hào)對(duì)應(yīng)的地址被定義為.textsection之后的第一個(gè)字節(jié)的地址。7.SECTIONS命令
SECTIONS命令告訴ld如何把輸入文件的sections映射到輸出文件的各個(gè)section:如何將輸入section合為輸出section;如何把輸出section放入程序地址空間(VMA)和進(jìn)程地址空間(LMA).該命令格式如下:SECTIONS{
SECTIONS-COMMANDSECTIONS-COMMAND...}
SECTION-COMMAND有四種:(1)ENTRY命令(2)符號(hào)賦值語(yǔ)句
(3)一個(gè)輸出section的描述(outputsectiondescription)(4)一個(gè)section疊加描述(overlaydescription)
假使整個(gè)連接腳本內(nèi)沒(méi)有SECTIONS命令,那么ld將所有同名輸入section合成為一個(gè)輸出section內(nèi),各輸入section的順序?yàn)樗鼈儽贿B接器發(fā)現(xiàn)的順序.
假使某輸入section沒(méi)有在SECTIONS命令中提到,那么該section將被直接拷貝成輸出section。
輸出section描述
輸出section描述具有如下格式:
SECTION[ADDRESS][(TYPE)]:[AT(LMA)]{
OUTPUT-SECTION-COMMANDOUTPUT-SECTION-COMMAND...
}[>REGION][AT>LMA_REGION][:PHDR:PHDR...][=FILLEXP][]內(nèi)的內(nèi)容為可選選項(xiàng),一般不需要.SECTION:section名字
SECTION左右的空白、圓括號(hào)、冒號(hào)是必需的,換行符和其他空格是可選的。每個(gè)OUTPUT-SECTION-COMMAND為以下四種之一,符號(hào)賦值語(yǔ)句
一個(gè)輸入section描述直接包含的數(shù)據(jù)值
一個(gè)特別的輸出section關(guān)鍵字輸出section名字(SECTION):
輸出section名字必需符合輸出文件格式要求,譬如:a.out格式的文件只允許存在.text、.data和.bsssection名。而有的格式只允許存在數(shù)字名字,那么此時(shí)應(yīng)當(dāng)用引號(hào)將所有名字內(nèi)的數(shù)字組合在一起;另外,還有一些格式允許任何序列的字符存在于section名字內(nèi),此時(shí)假使名字內(nèi)包含特別字符(譬如空格、逗號(hào)等),那么需要用引號(hào)將其組合在一起。輸出section地址(ADDRESS):
ADDRESS是一個(gè)表達(dá)式,它的值用于設(shè)置VMA。假使沒(méi)有該選項(xiàng)且有REGION選項(xiàng),那么連接器將根據(jù)REGION設(shè)置VMA;假使也沒(méi)有REGION選項(xiàng),那么連接器將根據(jù)定位符號(hào)?.?的值設(shè)置該section的VMA,將定位符號(hào)的值調(diào)整到滿(mǎn)足輸出section對(duì)齊要求后的值,輸出section的對(duì)齊要求為:該輸出section描述內(nèi)用到的所有輸入section的對(duì)齊要求中最嚴(yán)格的。例子:
.text.:{*(.text)}和
.text:{*(.text)}
這兩個(gè)描述是截然不同的,第一個(gè)將.textsection的VMA設(shè)置為定位符號(hào)的值,而其次個(gè)則是設(shè)置成定位符號(hào)的修調(diào)值,滿(mǎn)足對(duì)齊要求后的。ADDRESS可以是一個(gè)任意表達(dá)式,譬如ALIGN(0x10)這將把該section的VMA設(shè)置成定位符號(hào)的修調(diào)值,滿(mǎn)足16字節(jié)對(duì)齊后的。
注意:設(shè)置ADDRESS值,將更改定位符號(hào)的值。輸入section描述:
最常見(jiàn)的輸出section描述命令是輸入section描述。輸入section描述是最基本的連接腳本描述。輸入section描述基礎(chǔ):
基本語(yǔ)法:FILENAME([EXCLUDE_FILE(FILENAME1FILENAME2...)SECTION1SECTION2...)
FILENAME文件名,可以是一個(gè)特定的文件的名字,也可以是一個(gè)字符串模式。SECTION名字,可以是一個(gè)特定的section名字,也可以是一個(gè)字符串模式例子是最能說(shuō)明問(wèn)題的,
*(.text):表示所有輸入文件的.textsection
(*(EXCLUDE_FILE(*crtend.o*otherfile.o).ctors)):表示除crtend.o、otherfile.o文件外的所有輸入文件的.ctorssection。
data.o(.data):表示data.o文件的.datasectiondata.o:表示data.o文件的所有section*(.text.data):表示所有文件的.textsection和.datasection,順序是:第一個(gè)文件的.textsection,第一個(gè)文件的.datasection,其次個(gè)文件的.textsection,其次個(gè)文件的.datasection,...
*(.text)*(.data):表示所有文件的.textsection和.datasection,順序是:第一個(gè)文件的.textsection,其次個(gè)文件的.textsection,...,最終一個(gè)文件的.textsection,第一個(gè)文件的.datasection,其次個(gè)文件的.datasection,...,最終一個(gè)文件的.datasection下面看連接器是如何找到對(duì)應(yīng)的文件的。
當(dāng)FILENAME是一個(gè)特定的文件名時(shí),連接器會(huì)查看它是否在連接命令行內(nèi)出現(xiàn)或在INPUT命令中出現(xiàn)。
當(dāng)FILENAME是一個(gè)字符串模式時(shí),連接器僅僅只查看它是否在連接命令行內(nèi)出現(xiàn)。注意:假使連接器發(fā)現(xiàn)某文件在INPUT命令內(nèi)出現(xiàn),那么它會(huì)在-L指定的路徑內(nèi)搜尋該文件。
字符串模式內(nèi)可存在以下通配符:*:表示任意多個(gè)字符?:表示任意一個(gè)字符
[CHARS]:表示任意一個(gè)CHARS內(nèi)的字符,可用-號(hào)表示范圍,如:a-z:表示引用下一個(gè)緊跟的字符
在文件名內(nèi),通配符不匹配文件夾分隔符/,但當(dāng)字符串模式僅包含通配符*時(shí)除外。任何一個(gè)文件的任意section只能在SECTIONS命令內(nèi)出現(xiàn)一次??慈缦吕樱琒ECTIONS{.data:{*(.data)}
.data1:{data.o(.data)}}
data.o文件的.datasection在第一個(gè)OUTPUT-SECTION-COMMAND命令內(nèi)被使用了,那么在其次個(gè)OUTPUT-SECTION-COMMAND命令內(nèi)將不會(huì)再被使用,也就是說(shuō)即使連接器不報(bào)錯(cuò),輸出文件的.data1section的內(nèi)容也是空的。
再次強(qiáng)調(diào):連接器依次掃描每個(gè)OUTPUT-SECTION-COMMAND命令內(nèi)的文件名,任何一個(gè)文件的任何一個(gè)section都只能使用一次。
讀者可以用-M連接命令選項(xiàng)來(lái)產(chǎn)生一個(gè)map文件,它包含了所有輸入section到輸出section的組合信息。再看個(gè)例子,SECTIONS{.text:{*(.text)}
.DATA:{[A-Z]*(.data)}.data:{*(.data)}.bss:{*(.bss)}}
這個(gè)例子中說(shuō)明,所有文件的輸入.textsection組成輸出.textsection;所有以大寫(xiě)字母開(kāi)頭的文件的.datasection組成輸出.DATAsection,其他文件的.datasection組成輸出.datasection;所有文件的輸入.bsssection組成輸出.bsssection。
可以用SORT()關(guān)鍵字對(duì)滿(mǎn)足字符串模式的所有名字進(jìn)行遞增排序,如SORT(.text*)。通用符號(hào)(commonsymbol)的輸入section:
在大量目標(biāo)文件格式中,通用符號(hào)并沒(méi)有占用一個(gè)section。連接器認(rèn)為:輸入文件的所有通用符號(hào)在名為COMMON的section內(nèi)。例子,
.bss{*(.bss)*(COMMON)}
這個(gè)例子中將所有輸入文件的所有通用符號(hào)放入輸出.bsssection內(nèi)??梢钥吹紺OMMOMsection的使用方法跟其他section的使用方法是一樣的。
有些目標(biāo)文件格式把通用符號(hào)分成幾類(lèi)。例如,在MIPSelf目標(biāo)文件格式中,把通用符號(hào)分成standardcommonsymbols(標(biāo)準(zhǔn)通用符號(hào))和smallcommonsymbols(微通用符號(hào),不知道這么譯對(duì)不對(duì)?),此時(shí)連接器認(rèn)為所有standardcommonsymbols在COMMONsection內(nèi),而smallcommonsymbols在.scommonsection內(nèi)。
在一些以前的連接腳本內(nèi)可以看見(jiàn)[COMMON],相當(dāng)于*(COMMON),不建議繼續(xù)使用這種陳舊的方式。
輸入section和垃圾回收:
在連接命令行內(nèi)使用了選項(xiàng)--gc-sections后,連接器可能將某些它認(rèn)為沒(méi)用的section過(guò)濾掉,此時(shí)就有必要強(qiáng)制連接器保存一些特定的section,可用KEEP()關(guān)鍵字達(dá)此目的。如KEEP(*(.text))或KEEP(SORT(*)(.text))最終看個(gè)簡(jiǎn)單的輸入section相關(guān)例子:SECTIONS{outputa0x10000:{all.o
foo.o(.input1)}
outputb:{
foo.o(.input2)foo1.o(.input1)}
outputc:{
*(.input1)*(.input2)}}
本例中,將all.o文件的所有section和foo.o文件的所有(一個(gè)文件內(nèi)可以有多個(gè)同名section).input1section依次放入輸出outputasection內(nèi),該section的VMA是0x10000;將foo.o文件的所有.input2section和foo1.o文件的所有.input1section依次放入輸出outputbsection內(nèi),該section的VMA是當(dāng)前定位器符號(hào)的修調(diào)值(對(duì)齊后);將其他文件(非all.o、foo.o、foo1.o)文件的.input1section和.input2section放入輸出outputcsection內(nèi)。在輸出section存放數(shù)據(jù)命令:
能夠顯示地在輸出section內(nèi)填入你想要填入的信息(這樣是不是可以自己通過(guò)連接腳本寫(xiě)程序?當(dāng)然是簡(jiǎn)單的程序)。
BYTE(EXPRESSION)1字節(jié)SHORT(EXPRESSION)2字節(jié)LOGN(EXPRESSION)4字節(jié)QUAD(EXPRESSION)8字節(jié)
SQUAD(EXPRESSION)64位處理器的代碼時(shí),8字節(jié)
輸出文件的字節(jié)順序bigendianness或littleendianness,可以由輸出目標(biāo)文件的格式?jīng)Q定;假使輸出目標(biāo)文件的格式不能決定字節(jié)順序,那么字節(jié)順序與第一個(gè)輸入文件的字節(jié)順序一致。
如:BYTE(1)、LANG(addr)。
注意,這些命令只能放在輸出section描述內(nèi),其他地方不行。錯(cuò)誤:SECTIONS{.text:{*(.text)}LONG(1).data:{*(.data)}}正確:SECTIONS{.text:{*(.text)LONG(1)}.data:{*(.data)}}
在當(dāng)前輸出section內(nèi)可能存在未描述的存儲(chǔ)區(qū)域(譬如由于對(duì)齊造成的空隙),可以用FILL(EXPRESSION)命令決定這些存儲(chǔ)區(qū)域的內(nèi)容,EXPRESSION的前兩字節(jié)有效,這兩字節(jié)在必要時(shí)可以重復(fù)被使用以填充這類(lèi)存儲(chǔ)區(qū)域。如FILE(0x9090)。在輸出section描述中可以有=FILEEXP屬性,它的作用宛如FILE()命令,但是FILE命令只作用于該FILE指令之后的section區(qū)域,而=FILEEXP屬性作用于整個(gè)輸出section區(qū)域,且FILE命令的優(yōu)先級(jí)更高?。?!
輸出section內(nèi)命令的關(guān)鍵字:CREATE_OBJECT_SYMBOLS:為每個(gè)輸入文件建立一個(gè)符號(hào),符號(hào)名為輸入文件的名字。每個(gè)符號(hào)所在的section是出現(xiàn)該關(guān)鍵字的section。
CONSTRUCTORS:與c++內(nèi)的(全局對(duì)象的)構(gòu)造函數(shù)和(全局對(duì)像的)析構(gòu)函數(shù)相關(guān),下面將它們簡(jiǎn)稱(chēng)為全局構(gòu)造和全局析構(gòu)。
對(duì)于a.out目標(biāo)文件格式,連接器用一些不尋常的方法實(shí)現(xiàn)c++的全局構(gòu)造和全局析構(gòu)。當(dāng)連接器生成的目標(biāo)文件格式不支持任意section名字時(shí),譬如說(shuō)ECOFF、XCOFF格式,連接器將通過(guò)名字來(lái)識(shí)別全局構(gòu)造和全局析構(gòu),對(duì)于這些文件格式,連接器把與全局構(gòu)造和全局析構(gòu)的相關(guān)信息放入出現(xiàn)CONSTRUCTORS關(guān)鍵字的輸出section內(nèi)。
符號(hào)__CTORS_LIST__表示全局構(gòu)造信息的的開(kāi)始處,__CTORS_END__表示全局構(gòu)造信息的終止處。
符號(hào)__DTORS_LIST__表示全局構(gòu)造信息的的開(kāi)始處,__DTORS_END__表示全局構(gòu)造信息的終止處。
這兩塊信息的開(kāi)始處是一字長(zhǎng)的信息,表示該塊信息有多少項(xiàng)數(shù)據(jù),然后以值為零的一字長(zhǎng)數(shù)據(jù)終止。
一般來(lái)說(shuō),GNUC++在函數(shù)__main內(nèi)安排全局構(gòu)造代碼的運(yùn)行,而__main函數(shù)被初始化代碼(在main函數(shù)調(diào)用之前執(zhí)行)調(diào)用。是不是對(duì)于某些目標(biāo)文件格式才這樣???
對(duì)于支持任意section名的目標(biāo)文件格式,譬如COFF、ELF格式,GNUC++將全局構(gòu)造和全局析構(gòu)信息分別放入.ctorssection和.dtorssection內(nèi),然后在連接腳本內(nèi)參與如下,__CTOR_LIST__=.;
LONG((__CTOR_END__-__CTOR_LIST__)/4-2)*(.ctors)LONG(0)
__CTOR_END__=.;__DTOR_LIST__=.;
LONG((__DTOR_END__-__DTOR_LIST__)/4-2)
*(.dtors)LONG(0)
__DTOR_END__=.;
假使使用GNUC++提供的初始化優(yōu)先級(jí)支持(它能控制每個(gè)全局構(gòu)造函數(shù)調(diào)用的先后順序),那么請(qǐng)?jiān)谶B接腳本內(nèi)把CONSTRUCTORS替換成SORT(CONSTRUCTS),把*(.ctors)換成*(SORT(.ctors)),把*(.dtors)換成*(SORT(.dtors))。一般來(lái)說(shuō),默認(rèn)的連接腳本已作好的這些工作。
輸出section的丟棄:
例子,.foo{*(.foo)},假使沒(méi)有任何一個(gè)輸入文件包含.foosection,那么連接器將不會(huì)創(chuàng)立.foo輸出section。但是假使在這些輸出section描述內(nèi)包含了非輸入section描述命令(如符號(hào)賦值語(yǔ)句),那么連接器將總是創(chuàng)立該輸出section。
有一個(gè)特別的輸出section,名為/DISCARD/,被該section引用的任何輸入section將不會(huì)出現(xiàn)在輸出文件內(nèi),這就是DISCARD的意思吧。假使/DISCARD/section被它自己引用呢?想想看。
輸出section屬性:
終究講到這里了,呵呵。
我們?cè)倩叵胍韵螺敵鰏ection描述的文法:SECTION[ADDRESS][(TYPE)]:[AT(LMA)]{
OUTPUT-SECTION-COMMANDOUTPUT-SECTION-COMMAND...
}[>REGION][AT>LMA_REGION][:PHDR:PHDR...][=FILLEXP]
前面我們?yōu)g覽了SECTION、ADDRESS、OUTPUT-SECTION-COMMAND相關(guān)信息,下面我們將瀏覽其他屬性。
TYPE:每個(gè)輸出section都有一個(gè)類(lèi)型,假使沒(méi)有指定TYPE類(lèi)型,那么連接器根據(jù)輸出section引用的輸入section的類(lèi)型設(shè)置該輸出section的類(lèi)型。它可以為以下五種值,NOLOAD:該section在程序運(yùn)行時(shí),不被載入內(nèi)存。
DSECT,COPY,INFO,OVERLAY:這些類(lèi)型很少被使用,為了向后兼容才被保存下來(lái)。這種類(lèi)型的section必需被標(biāo)記為“不可加載的〞,以便在程序運(yùn)行不為它們分派內(nèi)存。
輸出section的LMA:默認(rèn)狀況下,LMA等于VMA,但可以通過(guò)關(guān)鍵字AT()指定LMA。用關(guān)鍵字AT()指定,括號(hào)內(nèi)包含表達(dá)式,表達(dá)式的值用于設(shè)置LMA。假使不用AT()關(guān)鍵字,那么可用AT>LMA_REGION表達(dá)式設(shè)置指定該section加載地址的范圍。這個(gè)屬性主要用于構(gòu)件ROM境象。例子,SECTIONS{
.text0x1000:{*(.text)_etext=.;}.mdata0x2000:
AT(ADDR(.text)+SIZEOF(.text)){_data=.;*(.data);_edata=.;}.bss0x3000:
{_bstart=.;*(.bss)*(COMMON);_bend=.;}}
程序如下,
externchar_etext,_data,_edata,_bstart,_bend;char*src=char*dst=
/*ROMhasdataatendoftext;copyit.*/while(dstrom}輸出section所在的程序段:可以將輸出section放入預(yù)先定義的程序段(programsegment)內(nèi)。假使某個(gè)輸出section設(shè)置了它所在的一個(gè)或多個(gè)程序段,那么接下來(lái)定義的輸出section的默認(rèn)程序段與該輸出section的一致。除非再次顯示地指定。例子,PHDRS{textPT_LOAD;}
SECTIONS{.text:{*(.text)}:text}
可以通過(guò):NONE指定連接器不把該section放入任何程序段內(nèi)。詳情請(qǐng)查看PHDRS命令輸出section的填充模版:這個(gè)在前面提到過(guò),任何輸出section描述內(nèi)的未指定的內(nèi)存區(qū)域,連接器用該模版填充該區(qū)域。用法:=FILEEXP,前兩字節(jié)有效,當(dāng)區(qū)域大于兩字節(jié)時(shí),重復(fù)使用這兩字節(jié)以將其填滿(mǎn)。例子,SECTIONS{.text:{*(.text)}=0x9090}覆蓋圖(overlay)描述:
覆蓋圖描述使兩個(gè)或多個(gè)不同的section占用同一塊程序地址空間。覆蓋圖管理代碼負(fù)責(zé)將section的拷入和拷出。考慮這種狀況,當(dāng)某存儲(chǔ)塊的訪問(wèn)速度比其他存儲(chǔ)塊要快時(shí),那么假使將section拷到該存儲(chǔ)塊來(lái)執(zhí)行或訪問(wèn),那么速度將會(huì)有所提高,覆蓋圖描述就很適合這種情形。文法如下,SECTIONS{...
OVERLAY[START]:[NOCROSSREFS][AT(LDADDR)]{
SECNAME1{
OUTPUT-SECTION-COMMANDOUTPUT-SECTION-COMMAND...
}[:PHDR...][=FILL]SECNAME2{
OUTPUT-SECTION-COMMANDOUTPUT-SECTION-COMMAND...
}[:PHDR...][=FILL]...
}[>REGION][:PHDR...][=FILL]...}
由以上文法可以看出,同一覆蓋圖內(nèi)的section具有一致的VMA。SECNAME2的LMA為SECTNAME1的LMA加上SECNAME1的大小,同理計(jì)算SECNAME2,3,4...的LMA。SECNAME1的LMA由LDADDR決定,假使它沒(méi)有被指定,那么由START決定,假使它也沒(méi)有被指定,那么由當(dāng)前定位符號(hào)的值決定。
NOCROSSREFS關(guān)鍵字指定各section之間不能交織引用,否則報(bào)錯(cuò)。
對(duì)于OVERLAY描述的每個(gè)section,連接器將定義兩個(gè)符號(hào)__load_start_SECNAME和__load_stop_SECNAME,這兩個(gè)符號(hào)的值分別代表SECNAMEsection的LMA地址的開(kāi)始和終止。
連接器處理完OVERLAY描述語(yǔ)句后,將定位符號(hào)的值加上所有覆蓋圖內(nèi)section大小的最大值。
看個(gè)例子吧,SECTIONS{...
OVERLAY0x1000:AT(0x4000){
.text0{o1/*.o(.text)}.text1{o2/*.o(.text)}}...}
.text0section和.text1section的VMA地址是0x1000,.text0section加載于地址0x4000,.text1section緊跟在其后。
程序代碼,拷貝.text1section代碼,
externchar__load_start_text1,__load_stop_text1;memcpy((char*)0x1000,8.內(nèi)存區(qū)域命令
注意:以下存儲(chǔ)區(qū)域指的是在程序地址空間內(nèi)的。
在默認(rèn)情形下,連接器可以為section分派任意位置的存儲(chǔ)區(qū)域。你也可以用MEMORY命令定義存儲(chǔ)區(qū)域,并通過(guò)輸出section描述的>REGION屬性顯示地將該輸出section限定于某塊存儲(chǔ)區(qū)域,當(dāng)存儲(chǔ)區(qū)域大小不能滿(mǎn)足要求時(shí),連接器會(huì)報(bào)告該錯(cuò)誤。MEMORY命令的文法如下,MEMORY{
NAME1[(ATTR)]:ORIGIN=ORIGIN1,LENGTH=LEN2NAME2[(ATTR)]:ORIGIN=ORIGIN2,LENGTH=LEN2
...}
NAME:存儲(chǔ)區(qū)域的名字,這個(gè)名字可以與符號(hào)名、文件名、section名重復(fù),由于它處于一個(gè)獨(dú)立的名字空間。
ATTR:定義該存儲(chǔ)區(qū)域的屬性,在陳述SECTIONS命令時(shí)提到,當(dāng)某輸入section沒(méi)有在SECTIONS命令內(nèi)引用時(shí),連接器會(huì)把該輸入section直接拷貝成輸出section,然后將該輸出section放入內(nèi)存區(qū)域內(nèi)。假使設(shè)置了內(nèi)存區(qū)域設(shè)置了ATTR屬性,那么該區(qū)域只接受滿(mǎn)足該屬性的section(怎么判斷該section是否滿(mǎn)足?輸出section描述內(nèi)好象沒(méi)有記錄該section的讀寫(xiě)執(zhí)行屬性)。ATTR屬性?xún)?nèi)可以出現(xiàn)以下7個(gè)字符,R只讀sectionW讀/寫(xiě)sectionX可執(zhí)行sectionA?可分派的?sectionI初始化了的sectionL同I
!不滿(mǎn)足該字符之后的任何一個(gè)屬性的section
ORIGIN:關(guān)鍵字,區(qū)域的開(kāi)始地址,可簡(jiǎn)寫(xiě)成org或oLENGTH:關(guān)鍵字,區(qū)域的大小,可簡(jiǎn)寫(xiě)成len或l例子,MEMORY{
rom(rx):ORIGIN=0,LENGTH=256Kram(!rx):org=0x40000000,l=4M}
此例中,把在SECTIONS命令內(nèi)*未*引用的且具有讀屬性或?qū)憣傩缘妮斎雜ection放入rom區(qū)域內(nèi),把其他未引用的輸入section放入ram。假使某輸出section要被放入某內(nèi)存區(qū)域內(nèi),而該輸出section又沒(méi)有指明ADDRESS屬性,那么連接器將該輸出section放在該區(qū)域內(nèi)下一個(gè)能使用位置。9.PHDRS命令
該命令僅在產(chǎn)生ELF目標(biāo)文件時(shí)有效。
ELF目標(biāo)文件格式用programheaders程序頭(程序頭內(nèi)包含一個(gè)或多個(gè)segment程序段描述)來(lái)描述程序如何被載入內(nèi)存??梢杂胦bjdump-p命令查看。
當(dāng)在本地ELF系統(tǒng)運(yùn)行ELF目標(biāo)文件格式的程序時(shí),系統(tǒng)加載器通過(guò)讀取程序頭信息以知道如何將程序加載到內(nèi)存。要了解系統(tǒng)加載器如何解析程序頭,請(qǐng)參考ELFABI文檔。在連接腳本內(nèi)不指定PHDRS命令時(shí),連接器能夠很好的創(chuàng)立程序頭,但是有時(shí)需要更確切的描述程序頭,那么PAHDRS命令就派上用場(chǎng)了。
注意:一旦在連接腳本內(nèi)使用了PHDRS命令,那么連接器**僅會(huì)**創(chuàng)立PHDRS命令指定的信息,所以使用時(shí)須提防。PHDRS命令文法如下,PHDRS{
NAMETYPE[FILEHDR][PHDRS][AT(ADDRESS)][FLAGS(FLAGS)];
}
其中FILEHDR、PHDRS、AT、FLAGS為關(guān)鍵字。
NAME:為程序段名,此名字可以與符號(hào)名、section名、文件名重復(fù),由于它在一個(gè)獨(dú)立的名字空間內(nèi)。此名字只能在SECTIONS命令內(nèi)使用。
一個(gè)程序段可以由多個(gè)?可加載?的section組成。通過(guò)輸出section描述的屬性:PHDRS可以將輸出section參與一個(gè)程序段,:PHDRS中的PHDRS為程序段名。在一個(gè)輸出section描述內(nèi)可以屢屢使用:PHDRS命令,也即可以將一個(gè)section參與多個(gè)程序段。
假使在一個(gè)輸出section描述內(nèi)指定了:PHDRS屬性,那么其后的輸出section描述將默認(rèn)使用該屬性,除非它也定義了:PHDRS屬性。顯然當(dāng)多個(gè)輸出section屬于同一程序段時(shí)可簡(jiǎn)化書(shū)寫(xiě)。
在TYPE屬性后存在FILEHDR關(guān)鍵字,表示該段包含ELF文件頭信息;存在PHDRS關(guān)鍵字,表示該段包含ELF程序頭信息。TYPE可以是以下八種形式,PT_NULL0
表示未被使用的程序段PT_LOAD1
表示該程序段在程序運(yùn)行時(shí)應(yīng)當(dāng)被加載PT_DYNAMIC2
表示該程序段包含動(dòng)態(tài)連接信息PT_INTERP3
表示該程序段內(nèi)包含程序加載器的名字,在linux下常見(jiàn)的程序加載器是ld-linux.so.2PT_NOTE4
表示該程序段內(nèi)包含程序的說(shuō)明信息PT_SHLIB5
一個(gè)保存的程序頭類(lèi)型,沒(méi)有在ELFABI文檔內(nèi)定義PT_PHDR6
表示該程序段包含程序頭信息。EXPRESSION表達(dá)式值
以上每個(gè)類(lèi)型都對(duì)應(yīng)一個(gè)數(shù)字,該表達(dá)式定義一個(gè)用戶(hù)自定的程序頭。
AT(ADDRESS)屬性定義該程序段的加載位置(LMA),該屬性將**覆蓋**該程序段內(nèi)的section的AT()屬性。
默認(rèn)狀況下,連接器會(huì)根據(jù)該程序段包含的section的屬性(什么屬性?好象在輸出section描述內(nèi)沒(méi)有看到)設(shè)置FLAGS標(biāo)志,該標(biāo)志用于設(shè)置程序段描述的p_flags域。下面看一個(gè)典型的PHDRS設(shè)置,PHDRS{
headersPT_PHDRPHDRS;interpPT_INTERP;
textPT_LOADFILEHDRPHDRS;dataPT_LOAD;
dynamicPT_DYNAMIC;}
SECTIONS{
.=SIZEOF_HEADERS;
.interp:{*(.interp)}:text:interp.text:{*(.text)}:text
.rodata:{*(.rodata)}/*defaultsto:text*/...
.=.+0x1000;/*movetoanewpageinmemory*/.data:{*(.data)}:data
.dynamic:{*(.dynamic)}:data:dynamic...}
10.版本號(hào)命令
當(dāng)使用ELF目標(biāo)文件格式時(shí),連接器支持帶版本號(hào)的符號(hào)。讀者可以發(fā)現(xiàn)僅僅在共享庫(kù)中,符號(hào)的版本號(hào)屬性才有意義。
動(dòng)態(tài)加載器使用符號(hào)的版本號(hào)為應(yīng)用程序選擇共享庫(kù)內(nèi)的一個(gè)函數(shù)的特定實(shí)現(xiàn)版本。可以在連接腳本內(nèi)直接使用版本號(hào)命令,也可以將版本號(hào)命令實(shí)現(xiàn)于一個(gè)特定版本號(hào)描述文件(用連接選項(xiàng)--version-script指定該文件)。該命令的文法如下,
VERSION{version-script-commands}以下內(nèi)容直接拷貝于以前的文檔,
=====================開(kāi)始==================================內(nèi)容簡(jiǎn)介0前提
1帶版本號(hào)的符號(hào)的定義2連接到帶版本的符號(hào)3GNU擴(kuò)展4我的疑問(wèn)
5英文探尋關(guān)鍵字6我的參考0.前提
--只限于ELF文件格式--以下探討用gcc
1.帶版本號(hào)的符號(hào)的定義(共享庫(kù)內(nèi))文件b.c內(nèi)容如下,intold_true(){
return1;}
intnew_true(){
return2;}
寫(xiě)連接器的版本控制腳本,本例中為b.lds,內(nèi)容如下
VER1.0{new_true;};
VER2.0{};
$gcc-cb.c
$gcc-shared-Wl,--version-script=b.lds-olibb.sob.o
可以在{}內(nèi)填入要綁定的符號(hào),本例中new_true符號(hào)就與VER1.0綁定了。
那么假使有一個(gè)應(yīng)用程序連接到該庫(kù)的new_true符號(hào),那么它連接的就是VER1.0版本的new_true符號(hào)
假使把b.lds更改為,VER1.0{};
VER2.0{new_true;};
然后在生成libb.so文件,在運(yùn)行那個(gè)連接到VER1.0版本的new_true符號(hào)的應(yīng)用程序,可以發(fā)現(xiàn)該應(yīng)用程序不能運(yùn)行了,
由于庫(kù)內(nèi)沒(méi)有VER1.0版本的new_true,只有VER2.0版本的new_true。2.連接到帶版本的符號(hào)
寫(xiě)一個(gè)簡(jiǎn)單的應(yīng)用(名為app)連接到libb.so,應(yīng)用符號(hào)new_true假設(shè)libb.so的版本控制文件為,VER1.0{};
VER2.0{new_true;};
$nmapp|grepnew_trueUnew_true@@VER1.0$
用nm命令發(fā)現(xiàn)app連接到VER1.0版本的new_true3.GNU的擴(kuò)展
它允許在程序文件內(nèi)綁定*符號(hào)*到*帶版本號(hào)的別名符號(hào)*文件b.c內(nèi)容如下,intold_true(){
return1;}
intnew_true(){
return2;}
__asm__(\__asm__(\
其中,帶版本號(hào)的別名符號(hào)是true,其默認(rèn)的版本號(hào)為VER2.0供連接器用的版本控制腳本b.lds內(nèi)容如下,VER1.0{};
VER2.0{};
版本控制文件內(nèi)必需包含版本VER1.0和版本VER2.0的定義,由于在b.c文件內(nèi)有對(duì)他們的引用
******假定libb.so與app.c在同一目錄下********以下應(yīng)用程序app.c連接到該庫(kù),inttrue();intmain(){
printf(\}
$gccapp.clibb.so
$LD_LIBRARY_PATH=../app2
$nmapp|greptrueUtrue@@VER2.0$
很明顯,程序app使用的是VER2.0版本的別名符號(hào)true,假使在b.c內(nèi)沒(méi)有指明別名符號(hào)true的默認(rèn)版本,
那么gccapp.clibb.so將出現(xiàn)連接錯(cuò)誤,提醒true沒(méi)有定義。也可以在程序內(nèi)指定特定版本的別名符號(hào)true,程序如下,__asm__(\inttrue();intmain(){
printf(\}
$gccapp.clibb.so
$LD_LIBRARY_PATH=../app1
$nmapp|greptrueUtrue@VER1.0$
顯然,連接到了版本號(hào)為VER1.0的別名符號(hào)true。其中只有一個(gè)@表示,該版本不是默認(rèn)的版本我的疑問(wèn):
版本控制腳本文件中,各版本號(hào)節(jié)點(diǎn)之間的依靠關(guān)系英文探尋關(guān)鍵字:.symver
versionedsymbol
versionasharedlibrary參考:
infold,Scriptsnode
=====================終止==================================11.表達(dá)式
表達(dá)式的文法與C語(yǔ)言的表達(dá)式文法一致,表達(dá)式的值都是整型,假使ld的運(yùn)行主機(jī)和生成文件的目標(biāo)機(jī)都是32位,則表達(dá)式是32位數(shù)據(jù),否則是64位數(shù)據(jù)。能夠在表達(dá)式內(nèi)使用符號(hào)的值,設(shè)置符號(hào)的值。下面看六項(xiàng)表達(dá)式相關(guān)內(nèi)容,常表達(dá)式:
_fourk_1=4K;/*K、M單位*/_fourk_2=4096;/*整數(shù)*/
_fourk_3=0x1000;/*16進(jìn)位
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025委托招標(biāo)代理合同
- 2025【合同范本】建筑工程施工合同示本
- 2025二手空調(diào)購(gòu)銷(xiāo)合同范本
- 促銷(xiāo)活動(dòng)合同范例
- 2024年六年級(jí)品社下冊(cè)《去中學(xué)看看》說(shuō)課稿2 蘇教版
- 配件報(bào)價(jià)實(shí)施方案
- 2024年五年級(jí)英語(yǔ)下冊(cè) Unit 4 Did You Have a Nice Trip Lesson 19 Li Ming Goes Home說(shuō)課稿 冀教版(三起)
- 貴州籠式球場(chǎng)護(hù)欄施工方案
- 砂石加工賬目處理方案
- 城市道路智慧路燈項(xiàng)目 投標(biāo)方案(技術(shù)標(biāo))
- 水泥采購(gòu)?fù)稑?biāo)方案(技術(shù)標(biāo))
- 醫(yī)院招標(biāo)采購(gòu)管理辦法及實(shí)施細(xì)則(試行)
- 初中英語(yǔ)-Unit2 My dream job(writing)教學(xué)設(shè)計(jì)學(xué)情分析教材分析課后反思
- 廣州市勞動(dòng)仲裁申請(qǐng)書(shū)
- 江西省上饒市高三一模理綜化學(xué)試題附參考答案
- 23-張方紅-IVF的治療流程及護(hù)理
- 頂部板式吊耳計(jì)算HGT-20574-2018
- 因數(shù)和倍數(shù)復(fù)習(xí)思維導(dǎo)圖
- LY/T 2986-2018流動(dòng)沙地沙障設(shè)置技術(shù)規(guī)程
- 三級(jí)教育考試卷(電工)答案
評(píng)論
0/150
提交評(píng)論