日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

make的使用和Makefile规则和编程及其基本命令(简单)

發(fā)布時(shí)間:2025/5/22 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 make的使用和Makefile规则和编程及其基本命令(简单) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
轉(zhuǎn)自:http://blog.chinaunix.net/uid-23929712-id-2650328.html 概述: make從Makefile中文件中獲取模塊間的依賴關(guān)系,判斷哪些文件已經(jīng)過時(shí),根據(jù)這些信息make確定哪些文件需要重新編譯,然后使用Makefile中的編譯命令進(jìn)行編譯 make命令參數(shù)詳解? -C dir:在讀取Makefile文件前,先切換到“dir”目錄下,也就是把dir作為當(dāng)前目錄 -d ? ? :make執(zhí)行時(shí)打印出所有的調(diào)試信息 -e ? ? :不允許在Makefile中對(duì)系統(tǒng)環(huán)境變量進(jìn)行重新賦值 -f filename:使用指定文件作為Makefile文件 -i ? ? ?:忽略執(zhí)行Makefile中命令時(shí)產(chǎn)生的錯(cuò)誤,不退出make -h ? ? :打印出幫助信息 -k?? ? :執(zhí)行命令遇到錯(cuò)誤時(shí),不終止make的執(zhí)行,make盡最大的可能執(zhí)行所有的命令,知道出現(xiàn)致命錯(cuò)誤才終止 -n ? ? :只打印出要執(zhí)行的命令,但不執(zhí)行命令 -o filename :指定文件filename不需要重建 -p ? ? :執(zhí)行命令之前,打印出make讀取的makefile的所有數(shù)據(jù),同時(shí)打印出make 的版本信息 -t ? ? ?:將所有的目標(biāo)文件的最后修改時(shí)間設(shè)置為當(dāng)前系統(tǒng)時(shí)間 顯式規(guī)則 foo.o : foo.c defs.h gcc -c -g foo.c 在第一行中,文件foo.o是規(guī)則的“目標(biāo)文件”,foo.c和defs.h是生成foo.o所要使用的文件,成為依賴文件 規(guī)則中的第二行g(shù)cc -c -g foo.c是規(guī)則的命令,他描述了如何使用規(guī)則中的依賴文件來生成目標(biāo)文件 書寫規(guī)則: 1,規(guī)則的命令部分由兩種書寫方式,當(dāng)和“目標(biāo)文件 : 依賴文件”為一行時(shí),可以用“;”來分來,當(dāng)另取一行時(shí)需要用TAB開始 2,Makefile中$有特殊的含義,當(dāng)要使用$時(shí),可以用$$ 3,當(dāng)Makefile中一行過長時(shí)可以用“\”將其書寫到幾個(gè)獨(dú)立的物理行上 命令行屬性? 一條規(guī)則可以有一個(gè)或者多個(gè)命令行,每個(gè)命令行以TAB開始。可以在TAB后加上“+”,“-”,“@”。 “-”執(zhí)行本命令行的命令時(shí)如果遇到錯(cuò)誤,繼續(xù)執(zhí)行而不退出make “+”本行命令始終被執(zhí)行,即使運(yùn)行make命令時(shí)使用了-n,-q,-t選項(xiàng)(前提是本行命令所在規(guī)則的目標(biāo)文件已經(jīng)過時(shí)) “@”執(zhí)行本命令時(shí)不再屏幕上打印命令的內(nèi)容 在這里“@”需要注意,在vivi的Makefile中,有使用。當(dāng)然其他的特殊符號(hào)也可在特定的時(shí)候使用 偽目標(biāo) .PHONY : clean clean: -rm -f *.o? .PHONY ?目標(biāo)“.PHONY”的所有依賴被作為偽目標(biāo),偽目標(biāo)是這樣一個(gè)目標(biāo):當(dāng)使用make命令制定此目標(biāo)時(shí),這個(gè)目標(biāo)躲在規(guī)則中的命令無論目標(biāo)文件是否存在都會(huì)被無條件執(zhí)行 特殊目標(biāo) .PHONY ?偽目標(biāo) .IGNORE ?對(duì)于目標(biāo)“.IGNORE”后面跟的依賴文件,生成這些依賴文件的命令在執(zhí)行時(shí)如果遇到錯(cuò)誤,make將忽略錯(cuò)誤繼續(xù)執(zhí)行。當(dāng)此目標(biāo)沒有依賴文件時(shí),將忽略所有命令執(zhí)行時(shí)的錯(cuò)誤 ?,相當(dāng)于“-” .SUFFIXES: 該目標(biāo)的依賴被認(rèn)為是一個(gè)后綴列表,在檢查后綴規(guī)則時(shí)使用 .SILENT:對(duì)于該目標(biāo)的依賴文件,執(zhí)行生成依賴文件的命令時(shí),make不會(huì)打印出所執(zhí)行的命令,相當(dāng)于“@” .PRECIOUS :該目標(biāo)的依賴文件會(huì)受到特別對(duì)待。這些依賴不會(huì)被刪除 .INTERMEDIATE:它的依賴文件在執(zhí)行make時(shí)被當(dāng)做中間文件對(duì)待 使用變量? 變量名習(xí)慣上只使用字母,數(shù)字和下劃線,并且不以數(shù)字開頭。 賦值符主要有四個(gè):=,:=,+=,?= = ? ? 賦值變量是遞歸展開變量 := 賦值變量是直接展開變量 ?= 條件賦值,只有變量在之前沒有賦值的情況下才會(huì)對(duì)這個(gè)變量進(jìn)行賦值? += ?實(shí)現(xiàn)對(duì)一個(gè)變量值得追加操作,并用空格和原有值分開 常用的自動(dòng)變量:$@,$%,$<,$>,$?,$^,$+,$* $@:表示一個(gè)規(guī)則中的目標(biāo)文件名 $%:當(dāng)規(guī)則的目標(biāo)文件時(shí)一個(gè)靜態(tài)庫文件時(shí),$%代表靜態(tài)庫的一個(gè)成員名 $<:規(guī)則中的第一個(gè)依賴文件 $>:他和$%一樣適合于庫文件,它的值是庫名 $?:所有比目標(biāo)文件新的依賴文件列表,以空格分隔 $^:規(guī)則的所有依賴文件列表,使用空格分隔 $+:類似"$^",但是它保留了依賴文件中重復(fù)出現(xiàn)的文件 $*:它的值是目標(biāo)文件去掉后綴后的名稱 使用庫 建立和維護(hù)一個(gè)庫時(shí),將庫名作為目標(biāo)文件,把希望放到庫中的文件作為依賴文件,格式為: 庫名:庫名(成員1 成員2 ....) 后面加上ar -ruv 庫名 目標(biāo)文件名 ps:?mylib:mylib(file1.o file2.o file3.o) ar -ruv $@ $? rm -f $? 下面介紹解個(gè)常用的命令的一些簡單的使用方法: 一.objdump
-a 文檔頭文件信息
-d 可執(zhí)行代碼的反匯編
-D 反匯編可執(zhí)行代碼及數(shù)據(jù)
-f 完整文件頭的內(nèi)容
-h section表
-p 目標(biāo)格式的文件頭內(nèi)容

objdump - 顯示二進(jìn)制文件信息

objdump
?????? [-a] [-b bfdname |
?????? --target=bfdname] [-C] [--debugging]
?????? [-d] [-D]
?????? [--disassemble-zeroes]
?????? [-EB|-EL|--endian={big|little}] [-f]
?????? [-h] [-i|--info]
?????? [-j section | --section=section]
?????? [-l] [-m machine ] [--prefix-addresses]
?????? [-r] [-R]
?????? [-s|--full-contents] [-S|--source]
?????? [--[no-]show-raw-insn] [--stabs] [-t]
?????? [-T] [-x]
?????? [--start-address=address] [--stop-address=address]
?????? [--adjust-vma=offset] [--version] [--help]
?????? objfile...?
??
? -a, --archive-headers??? Display archive header information
? -f, --file-headers?????? Display the contents of the overall file header
? -p, --private-headers??? Display object format specific file header contents
? -h, --[section-]headers? Display the contents of the section headers
? -x, --all-headers??????? Display the contents of all headers
? -d, --disassemble??????? Display assembler contents of executable sections
? -D, --disassemble-all??? Display assembler contents of all sections
? -S, --source???????????? Intermix source code with disassembly
? -s, --full-contents????? Display the full contents of all sections requested
? -g, --debugging????????? Display debug information in object file
? -e, --debugging-tags???? Display debug information using ctags style
? -G, --stabs????????????? Display (in raw form) any STABS info in the file
? -W, --dwarf????????????? Display DWARF info in the file
? -t, --syms?????????????? Display the contents of the symbol table(s)
? -T, --dynamic-syms?????? Display the contents of the dynamic symbol table
? -r, --reloc????????????? Display the relocation entries in the file
? -R, --dynamic-reloc????? Display the dynamic relocation entries in the file
? @????????????????? Read options from?
? -v, --version??????????? Display this program's version number
? -i, --info?????????????? List object formats and architectures supported
? -H, --help?????????????? Display this information 二:objcopy GNU實(shí)用工具程序objcopy的作用是拷貝一個(gè)目標(biāo)文件的內(nèi)容到另一個(gè)目標(biāo)文件中。Objcopy使用GNU BFD庫去讀或?qū)懩繕?biāo)文件。Objcopy可以使用不同于源目標(biāo)文件的格式來寫目的目標(biāo)文件(也即是說可以將一種格式的目標(biāo)文件轉(zhuǎn)換成另一種格式的目標(biāo)文件)。通過以上命令行選項(xiàng)可以控制Objcopy的具體操作。
Objcopy在進(jìn)行目標(biāo)文件的轉(zhuǎn)換時(shí),將生成一個(gè)臨時(shí)文件,轉(zhuǎn)換完成后就將這個(gè)臨時(shí)文件刪掉。Objcopy使用BFD做轉(zhuǎn)換工作。如果沒有明確地格式要求,則Objcopy將訪問所有在BFD庫中已經(jīng)描述了的并且它可以識(shí)別的格式,請(qǐng)參見《GNUpro Decelopment Tools》中“using ld”一章中“BFD庫”部分和“BFD庫中規(guī)范的目標(biāo)文件格式”部分。
通過使用srec作為輸出目標(biāo)(使用命令行選項(xiàng)-o srec),Objcopy可以產(chǎn)生S記錄格式文件。
通過使用binary作為輸出目標(biāo)(使用命令行選項(xiàng)-o binary),Objcopy可以產(chǎn)生原始的二進(jìn)制文件。使用Objcopy產(chǎn)生一個(gè)原始的二進(jìn)制文件,實(shí)質(zhì)上是進(jìn)行了一回輸入目標(biāo)文件內(nèi)容的內(nèi)存轉(zhuǎn)儲(chǔ)。所有的符號(hào)和重定位信息都將被丟棄。內(nèi)存轉(zhuǎn)儲(chǔ)起始于輸入目標(biāo)文件中那些將要拷貝到輸出目標(biāo)文件去的部分的最小虛地址處。
使用Objcopy生成S記錄格式文件或者原始的二進(jìn)制文件的過程中,-S選項(xiàng)和-R選項(xiàng)可能會(huì)比較有用。-S選項(xiàng)是用來刪掉包含調(diào)試信息的部分,-R選項(xiàng)是用來刪掉包含了二進(jìn)制文件不需要的內(nèi)容的那些部分。
objcopy -O binary -s $@-elf $@ $(objcopyflags) objcopy Utility
objcopy [ -F bfdname | --target=bfdname ]
[ -I bfdname | --input-target=bfdname ]
[ -O bfdname | --output-target= bfdname ]
[ -S | --strip-all ] [ -g | --strip-debug ]
[ -K symbolname | --keep-symbol= symbolname ]
[ -N symbolname | --strip-symbol= symbolname ]
[ -L symbolname | --localize-symbol= symbolname ]
[ -W symbolname | --weaken-symbol= symbolname ]
[ -x | --discard-all ] [ -X | --discard-locals ]
[ -b byte | --byte= byte ]
[ -i interleave | --interleave= interleave ]
[ -R sectionname | --remove-section= sectionname ]
[ -p | --preserve-dates ] [ --debugging ]
[ --gap-fill= val ] [ --pad-to= address ]
[ --set-start= val ] [ --adjust-start= incr ]
[ --change-address= incr ]
[ --change-section-address= section{=,+,-} val ]
[ --change-warnings ] [ --no-change-warnings ]
[ --set-section-flags= section= flags ]
[ --add-section= sectionname= filename ]
[ --change-leading char ] [--remove-leading-char ]
[ --weaken ]
[ -v | --verbose ] [ -V | --version ] [ --help ]
input-file [ outfile ] 三:NM -a或--debug-syms:顯示調(diào)試符號(hào)。 ??
? -B:等同于--format=bsd,用來兼容MIPS的nm。 ??
? -C或--demangle:將低級(jí)符號(hào)名解碼(demangle)成用戶級(jí)名字。這樣可以使得C++函數(shù)名具有可讀性。 ??
? -D或--dynamic:顯示動(dòng)態(tài)符號(hào)。該任選項(xiàng)僅對(duì)于動(dòng)態(tài)目標(biāo)(例如特定類型的共享庫)有意義。 ??
? -f ? format:使用format格式輸出。format可以選取bsd、sysv或posix,該選項(xiàng)在GNU的nm中有用。默認(rèn)為bsd。 ??
? -g或--extern-only:僅顯示外部符號(hào)。 ??
? -n、-v或--numeric-sort:按符號(hào)對(duì)應(yīng)地址的順序排序,而非按符號(hào)名的字符順序。 ??
? -p或--no-sort:按目標(biāo)文件中遇到的符號(hào)順序顯示,不排序。 ??
? -P或--portability:使用POSIX.2標(biāo)準(zhǔn)輸出格式代替默認(rèn)的輸出格式。等同于使用任選項(xiàng)-f ? posix。 ??
? -s或--print-armap:當(dāng)列出庫中成員的符號(hào)時(shí),包含索引。索引的內(nèi)容包含:哪些模塊包含哪些名字的映射。 ??
? -r或--reverse-sort:反轉(zhuǎn)排序的順序(例如,升序變?yōu)榻敌?。 ??
? --size-sort:按大小排列符號(hào)順序。該大小是按照一個(gè)符號(hào)的值與它下一個(gè)符號(hào)的值進(jìn)行計(jì)算的。 ??
? -t ? radix或--radix=radix:使用radix進(jìn)制顯示符號(hào)值。radix只能為“d”表示十進(jìn)制、“o”表示八進(jìn)制或“x”表示十六進(jìn)制。 ??
? --target=bfdname:指定一個(gè)目標(biāo)代碼的格式,而非使用系統(tǒng)的默認(rèn)格式。 ??
? -u或--undefined-only:僅顯示沒有定義的符號(hào)(那些外部符號(hào))。 ??
? -l或--line-numbers:對(duì)每個(gè)符號(hào),使用調(diào)試信息來試圖找到文件名和行號(hào)。對(duì)于已定義的符號(hào),查找符號(hào)地址的行號(hào)。對(duì)于未定義符號(hào),查找指向符號(hào)重定位入口的行號(hào)。如果可以找到行號(hào)信息,顯示在符號(hào)信息之后。 ??
? -V或--version:顯示nm的版本號(hào)。 ??
? --help:顯示nm的任選項(xiàng)。 $(NM) -v -l vivi-elf > vivi.map(這是在vivi—-Makefile中的一行) 按照上面的命令,則是將vivi中所有的符號(hào),查找到行號(hào),然后將這些信息重定向到vivi.map文件中 ? 四:AR
  ar命令可以用來創(chuàng)建、修改庫,也可以從庫中提出單個(gè)模塊。庫是一單獨(dú)的文件,里面包含了按照特定的結(jié)構(gòu)組織起來的其它的一些文件(稱做此庫文件的member)。原始文件的內(nèi)容、模式、時(shí)間戳、屬主、組等屬性都保留在庫文件中。

  下面是ar命令的格式:

  ar[-][abcfilNoPsSuvV][membername][count]archivefiles...

  例如我們可以用ar rvl ibtest.a hello.o hello1.o來生成一個(gè)庫,庫名字是test,鏈接時(shí)可以用-ltest鏈接。該庫中存放了兩個(gè)模塊hello.o和hello1.o。選項(xiàng)前可以有 ‘-’字符,也可以沒有。下面我們來看看命令的操作選項(xiàng)和任選項(xiàng)。現(xiàn)在我們把部分稱為操作選項(xiàng),而[abcfilNoPsSuvV]部分稱為任選項(xiàng)。

  中的操作選項(xiàng)在命令中只能并且必須使用其中一個(gè),它們的含義如下:

  d:從庫中刪除模塊。按模塊原來的文件名指定要?jiǎng)h除的模塊。如果使用了任選項(xiàng)v則列出被刪除的每個(gè)模塊。

  m:該操作是在一個(gè)庫中移動(dòng)成員。當(dāng)庫中如果有若干模塊有相同的符號(hào)定義(如函數(shù)定義),則成員的位置順序很重要。如果沒有指定任選項(xiàng),任何指定的成員將移到庫的最后。也可以使用’a’,’b’,或’I’任選項(xiàng)移動(dòng)到指定的位置。

  p:顯示庫中指定的成員到標(biāo)準(zhǔn)輸出。如果指定任選項(xiàng)v,則在輸出成員的內(nèi)容前,將顯示成員的名字。如果沒有指定成員的名字,所有庫中的文件將顯示出來。

  q:快速追加。增加新模塊到庫的結(jié)尾處。并不檢查是否需要替換。’a’,’b’,或’I’任選項(xiàng)對(duì)此操作沒有影響,模塊總是追加的庫的結(jié)尾處。如果使用了任選項(xiàng)v則列出每個(gè)模塊。這時(shí),庫的符號(hào)表沒有更新,可以用’ars’或ranlib來更新庫的符號(hào)表索引。

  r:在庫中插入模塊(替換)。當(dāng)插入的模塊名已經(jīng)在庫中存在,則替換同名的模塊。如果若干模塊中有一個(gè)模塊在庫中不存在,ar顯示一個(gè)錯(cuò)誤消息,并不替換其他同名模塊。默認(rèn)的情況下,新的成員增加在庫的結(jié)尾處,可以使用其他任選項(xiàng)來改變?cè)黾拥奈恢谩?br />
  t:顯示庫的模塊表清單。一般只顯示模塊名。

  x:從庫中提取一個(gè)成員。如果不指定要提取的模塊,則提取庫中所有的模塊。

  下面在看看可與操作選項(xiàng)結(jié)合使用的任選項(xiàng):

  a:在庫的一個(gè)已經(jīng)存在的成員后面增加一個(gè)新的文件。如果使用任選項(xiàng)a,則應(yīng)該為命令行中membername參數(shù)指定一個(gè)已經(jīng)存在的成員名。

  b:在庫的一個(gè)已經(jīng)存在的成員前面增加一個(gè)新的文件。如果使用任選項(xiàng)b,則應(yīng)該為命令行中membername參數(shù)指定一個(gè)已經(jīng)存在的成員名。

  c:創(chuàng)建一個(gè)庫。不管庫是否存在,都將創(chuàng)建。

  f:在庫中截短指定的名字。缺省情況下,文件名的長度是不受限制的,可以使用此參數(shù)將文件名截短,以保證與其它系統(tǒng)的兼容。

  i:在庫的一個(gè)已經(jīng)存在的成員前面增加一個(gè)新的文件。如果使用任選項(xiàng)i,則應(yīng)該為命令行中membername參數(shù)指定一個(gè)已經(jīng)存在的成員名(類似任選項(xiàng)b)。

  l:暫未使用

  N:與count參數(shù)一起使用,在庫中有多個(gè)相同的文件名時(shí)指定提取或輸出的個(gè)數(shù)。

  o:當(dāng)提取成員時(shí),保留成員的原始數(shù)據(jù)。如果不指定該任選項(xiàng),則提取出的模塊的時(shí)間將標(biāo)為提取出的時(shí)間。

  P:進(jìn)行文件名匹配時(shí)使用全路徑名。ar在創(chuàng)建庫時(shí)不能使用全路徑名(這樣的庫文件不符合POSIX標(biāo)準(zhǔn)),但是有些工具可以。

  s:寫入一個(gè)目標(biāo)文件索引到庫中,或者更新一個(gè)存在的目標(biāo)文件索引。甚至對(duì)于沒有任何變化的庫也作該動(dòng)作。對(duì)一個(gè)庫做ars等同于對(duì)該庫做ranlib。

  S:不創(chuàng)建目標(biāo)文件索引,這在創(chuàng)建較大的庫時(shí)能加快時(shí)間。

  u:一般說來,命令arr…插入所有列出的文件到庫中,如果你只想插入列出文件中那些比庫中同名文件新的文件,就可以使用該任選項(xiàng)。該任選項(xiàng)只用于r操作選項(xiàng)。

  v:該選項(xiàng)用來顯示執(zhí)行操作選項(xiàng)的附加信息。

  V:顯示ar的版本。
? ? 五:LD ?? ?'ld'把一定量的目標(biāo)文件跟檔案文件連接起來,并重定位它們的數(shù)據(jù),連接符號(hào)引用.一般,在編譯一個(gè)程序時(shí),最后一步就是運(yùn)行'ld'. 命令行選項(xiàng)?: 連接器提供大量的命令行選項(xiàng),但是,在實(shí)際使用中,只有少數(shù)被經(jīng)常使用.比如,'ld'的一個(gè)經(jīng)常的使用場合是在一個(gè)標(biāo)準(zhǔn)的Unix系統(tǒng)上連接標(biāo)準(zhǔn)的Unix目標(biāo)文件.在這樣的一個(gè)系統(tǒng)上,連接件'hello.o'如下: ld -o OUTPUT /lib/crt0.o hello.o -lc? 這告訴'ld'產(chǎn)生一個(gè)叫OUTPUT的文件,作為連接文件'/lib/crt0.o'和'hello.o'和庫'libc.a'的結(jié)果.'libc.a'來自標(biāo)準(zhǔn)的搜索路徑.(參閱下文的關(guān)于'-l'選項(xiàng)的討論). ? 有些命令行選項(xiàng)可以在命令行的任何位置出現(xiàn).但是,那些帶有文件名的選項(xiàng),比如'-l'或者'-T',會(huì)讓文件在選?
項(xiàng)出現(xiàn)的位置上被讀取. 對(duì)于非文件選項(xiàng),以帶不同的參數(shù)重復(fù)它,不會(huì)有進(jìn)一步的效果,或者覆蓋掉前面的相同?
項(xiàng).那些多次出現(xiàn)時(shí)具有特殊含義的選項(xiàng)會(huì)在下文的描述中指出.?

無參數(shù)選項(xiàng)是那些被連接的目標(biāo)文件和檔案文件.它們可能緊隨命令行選項(xiàng),或在它們前面,或者跟它們夾雜在一?
起,但是一個(gè)目標(biāo)文件參數(shù)是不會(huì)出現(xiàn)在一個(gè)選項(xiàng)跟它的參數(shù)之間的.?

通常,連接器至少引用一個(gè)目標(biāo)文件,但是你可指定其它形式的二進(jìn)制輸入文件,這可以通過'-l','-R'或者腳本?
命令語言來實(shí)現(xiàn).如果沒有任何二進(jìn)制文件被指定,連接器不會(huì)產(chǎn)生任何輸出,并給出信息:"缺少輸入文件."?

如果連接器不能識(shí)別目標(biāo)文件的格式,它會(huì)假設(shè)這些只是連接腳本.以這種方式指定的腳本增加了連接用的主連?
接腳本的內(nèi)容(主連接腳本即缺省連接腳本或使用'-T'指定的腳本). 這個(gè)特性可以允許連接器連接一些文件,?
它們看上去既像目標(biāo)文件,又像檔案文件,但實(shí)際上只是定義了一些符號(hào)值,或者使用'INPUT'或'GROUP'來載入其?
它的目標(biāo)文件.需要注意的是,用這種方式指定一個(gè)腳本只是增加了主連接腳本的內(nèi)容;要完全替換掉主連接腳本?
,需要使用'-T'.?

對(duì)于名稱是單個(gè)字符的選項(xiàng),選項(xiàng)參數(shù)必須緊跟在選項(xiàng)字母后面,中間不留空,或者也可留有一個(gè)空格.?

對(duì)于名稱是多個(gè)字符的選項(xiàng),選項(xiàng)前可以有一個(gè)或兩個(gè)破折號(hào);比如,'-trace-symbol'和`--trace-symbol'是等價(jià)?
的. 注意,對(duì)于這條規(guī)則有一個(gè)例外.那些以小寫字母'o'開頭的多字符選項(xiàng)前面只能是兩個(gè)破折號(hào),這是為了避免?
跟選項(xiàng)'-o'混淆. 比如'-omagic'把輸出文件的名字定為'magic',而'--omagic'在輸出文件中設(shè)置NMAGIC標(biāo)志.?

多字符選項(xiàng)的參數(shù)必須跟選項(xiàng)名間以一個(gè)等于號(hào)分開,或者以一個(gè)空格分開.比如:`--trace-symbol foo'和?
`--trace-symbol=foo'是等價(jià)的. 多字符選項(xiàng)的名字唯一縮寫符也是可以被接受的.?

注意,如果連接器通過被編譯器驅(qū)動(dòng)來間接引用(比如gcc), 那所有的連接器命令行選項(xiàng)前必須加上前綴'-Wl'?
(或者能被特定編譯器驅(qū)動(dòng)接受的其他前綴),就像下面這樣:?

gcc -Wl,--startgroup foo.o bar.o -Wl,--endgroup?

這很重要,因?yàn)榉駝t的話,編譯器驅(qū)動(dòng)程序會(huì)默認(rèn)丟掉這些連接選項(xiàng),產(chǎn)生一個(gè)錯(cuò)誤的連接.?

下面是關(guān)于被GNU連接器接受的常用命令行開關(guān)的一個(gè)列表:?

`-aKEYWORD'?
這個(gè)選項(xiàng)在HP/UX兼容系統(tǒng)上被支持. 參數(shù)KEYWORD必須是下面字符串中的一個(gè):`archive',?
`shared', or `default'. `-aarchive'在功能上跟`-Bstatic'相同,而另外兩個(gè)關(guān)鍵字功能上跟?
`-Bdynamic'相同. 這個(gè)選項(xiàng)可被多次使用.?

`-AARCHITECTURE'?
`--architecture=ARCHITECTURE'?
在最近發(fā)行版本的'ld'中,這個(gè)選項(xiàng)只在Intel 960系列架構(gòu)上有用. 在那種'ld'配置中,參數(shù)?
ARCHITECTURE確定960系列的某一特定架構(gòu),啟用某些安全措施,并修改檔案庫的搜索路徑.?

將來的'ld'發(fā)行版可能為其它架構(gòu)系列支持相似的功能.?

`-b INPUT-formAT'?
`--format=INPUT-formAT'?
'ld'可以被配置為支持多于一種的目標(biāo)文件.如果你的'ld'以這種方式被配置,你可以使用'-b'選?
項(xiàng)為輸入目標(biāo)文件指定二進(jìn)制格式. 就算'ld'被配置為支持可選目標(biāo)格式,你不必經(jīng)常指定這一項(xiàng),?
因?yàn)?#39;ld'被配置為在每一臺(tái)機(jī)子上把最常用的格式作為默認(rèn)輸入格式. INPUT-formAT是一個(gè)字符串,?

你可能在連接一個(gè)不常用的二進(jìn)制格式文件時(shí)需要這個(gè)參數(shù).你也可使用'-b'來顯式切換格式(在連接?
不同格式的目標(biāo)文件時(shí)),方法是在每一組特定格式的目標(biāo)前使用'-b INPUT-formAT'.?

缺省的格式是從環(huán)境變量'GNUTARGET'中得到的.你也可以從一個(gè)腳本中定義輸入格式,使用的命令是?
'TARGET'.?

`-c MRI-COMMANDFILE'?
`--mri-script=MRI-COMMANDFILE'?
為了跟MRI生產(chǎn)的連接器兼容,'ld'接受另一種用受限命令語言寫成的腳本文件,通過選項(xiàng)'-c'引入MRI?
腳本文件;使用'-T'選項(xiàng)是運(yùn)行用普通'ld'腳本語言寫的連接腳本.如果MRI-CMDFILE不存在,'ld'在'-L'?
指定的目錄中尋找.?

`-d'?
`-dc'?
`-dp'?
這三個(gè)選項(xiàng)是等價(jià)的; 多字符形式是為了跟其他連接器兼容才被支持的.它們給普通符號(hào)分配空間,即?
使一個(gè)重定位輸出文件已經(jīng)被指定(通過'-r'). 腳本命令`FORCE_COMMON_ALLOCATION'具有同樣的效果.?

`-e ENTRY'?
`--entry=ENTRY'?
使用符號(hào)ENTRY作為你的程序的開始執(zhí)行點(diǎn),而不是使用缺省的進(jìn)入點(diǎn).如果沒有叫做ENTRY的符號(hào),連接器?
會(huì)企圖把ENTRY作為一個(gè)數(shù)字進(jìn)行分析,并使用它作為入口地址(數(shù)字會(huì)被解釋為10進(jìn)制的;你可以使用前?
導(dǎo)的'0x'強(qiáng)制為16進(jìn)制,或'0'作為8進(jìn)制.)?

`-E'?
`--export-dynamic'?
當(dāng)創(chuàng)建一個(gè)動(dòng)態(tài)連接的可執(zhí)行程序時(shí), 把所有的符號(hào)加到動(dòng)態(tài)符號(hào)表中.動(dòng)態(tài)符號(hào)表是一個(gè)符號(hào)集,這?
些符號(hào)對(duì)于運(yùn)行時(shí)的動(dòng)態(tài)對(duì)象是可見的.?

如果你不使用這個(gè)選項(xiàng),動(dòng)態(tài)符號(hào)表中就會(huì)只含有那些連接進(jìn)來的動(dòng)態(tài)對(duì)象中用到的符號(hào)?

如果你使用'dlopen'來載入動(dòng)態(tài)對(duì)象,它需要引用程序中的符號(hào),那你可能需要在連接程序時(shí)用到這個(gè)?
選項(xiàng).?

你也可以使用版本腳本來控制哪些符號(hào)應(yīng)當(dāng)被加到動(dòng)態(tài)符號(hào)表中.?

`-EB'?
連接big-endian對(duì)象. 這會(huì)影響缺省輸出格式.?

`-EL'?
連接little-endian對(duì)象. 這會(huì)影響缺省輸出格式.?

`-g'?
忽略. 為了跟其它工具兼容而提供.?

`-i'?
執(zhí)行一個(gè)增量連接(跟'-r'等同)?

`-init NAME'?
當(dāng)創(chuàng)建一個(gè)ELF可執(zhí)行文件或共享對(duì)象時(shí),當(dāng)可執(zhí)行文件或共享對(duì)象被加載時(shí),調(diào)用NAME, 這是通過把?
DT_INIT設(shè)置成函數(shù)的地址實(shí)現(xiàn)的. 缺省情況下,連接器使用'_init'作為調(diào)用的函數(shù).?

`-lARCHIVE'?
`--library=ARCHIVE'?
增加一個(gè)檔案文件ARCHIVE到連接的文件列表中.這個(gè)選項(xiàng)可以被多次使用. 'ld'會(huì)為每一個(gè)指定的?
ARCHIVE搜索它的路徑列表,尋找`libARCHIVE.a'?

對(duì)于支持共享庫的系統(tǒng), 'ld'可能還會(huì)搜索擴(kuò)展名不是'.a'庫.特別的,在ELF和SunOS系統(tǒng)上,'ld'會(huì)?
在搜索帶有'.a'擴(kuò)展名的庫前搜索帶'.so'擴(kuò)展名的庫.?

`-M'?
`--print-map'?
打印一個(gè)連接位圖到標(biāo)準(zhǔn)輸出.一個(gè)連接位圖提供的關(guān)于連接的信息有如下一些:?

* 目標(biāo)文件和符號(hào)被映射到內(nèi)存的哪些地方.?

* 普通符號(hào)如何被分配空間.?

* 所有被連接進(jìn)來的檔案文件,還有導(dǎo)致檔案文件被包含進(jìn)來的那個(gè)符號(hào).?

`-n'?
`--nmagic'?
關(guān)閉所有節(jié)的頁對(duì)齊,如果可能,把輸出格式標(biāo)識(shí)為'NMAGIC'.?

`-N'?
`--omagic'?
把text和data節(jié)設(shè)置為可讀寫.同時(shí),取消數(shù)據(jù)節(jié)的頁對(duì)齊,同時(shí),取消對(duì)共享庫的連接.如果輸出格式?
支持Unix風(fēng)格的magic number, 把輸出標(biāo)志為'OMAGIC'.?

`--no-omagic'?
這個(gè)選項(xiàng)執(zhí)行的操作大部分正好跟'-N'相反.它設(shè)置text節(jié)只讀,強(qiáng)制data節(jié)頁對(duì)齊. 但是,這個(gè)選項(xiàng)?
并不開啟連接共享庫的功能. 使用'-Bdynamic'開啟這個(gè)功能.?

`-o OUTPUT'?
`--output=OUTPUT'?
使用OUTPUT作為'ld'產(chǎn)生的程序的名字;如果這個(gè)選項(xiàng)沒有指定,缺省的輸出文件名是'a.out'.腳本命?
令'OUTPUT'也可以被用來指定輸出文件的文件名.?

`-O LEVEL'?
如果LEVEL是一個(gè)比0大的數(shù)值, 'ld'優(yōu)化輸出.這可能會(huì)明顯多占用時(shí)間,所以只有在生成最后的文件?
時(shí)使用.?

`-q'?
`--emit-relocs'?
把重定位節(jié)和內(nèi)容留在完全連接后的可執(zhí)行文件中. 連接分析和優(yōu)化工具可能需要這些信息用來進(jìn)行?
正確的修改與執(zhí)行. 這在大的可執(zhí)行文件中有用.?

這個(gè)選項(xiàng)目前只支持ELF平臺(tái).?
`-r'?
`--relocateable'?
產(chǎn)生可重定位的輸出, 比如,產(chǎn)生一個(gè)輸出文件它可再次作為'ld'的輸入.這經(jīng)常被叫做"部分連接".?
作為一個(gè)副作用,在支持標(biāo)準(zhǔn)Unix魔數(shù)的環(huán)境中,這個(gè)選項(xiàng)會(huì)把輸出文件的魔數(shù)設(shè)置為'OMAGIC'. 如?
果這個(gè)選項(xiàng)沒有被指定,一個(gè)絕對(duì)文件就會(huì)被產(chǎn)生.當(dāng)連接C++程序時(shí),這個(gè)選項(xiàng)就不會(huì)解析構(gòu)造函數(shù)的?
引用;要解析,必須使用'-Ur'?

如果輸入文件跟輸出文件的格式不同,只有在輸入文件不含有重定位信息的時(shí)候部分連接才被支持.輸?
出格式不同的時(shí)候會(huì)有更多的限制.比如,有些'a.out'的格式在輸入文件是其他格式的時(shí)候完全不支?
持部分連接.?

這個(gè)選項(xiàng)跟'-i'等效.?

`-R FILENAME'?
`--just-symbols=FILENAME'?
從FILENAME中讀取符號(hào)名跟它們的值,但不重位這個(gè)文件,或者根本不把它包含在輸出文件中.這就允?
許你的輸出文件引用其它程序中定義的絕對(duì)內(nèi)存地址.你可以多次使用這個(gè)選項(xiàng).?

為了跟其他ELF連接器兼容,如果'-R'選項(xiàng)后面跟有一個(gè)目錄名,而不是一個(gè)文件名,它會(huì)被處理成?
'-rpath'選項(xiàng).?

`-s'?
`--strip-all'?
忽略輸出文件中所有的符號(hào)信息.?

`-S'?
`--strip-debug'?
忽略輸出文件中所有的調(diào)試符號(hào)信息(但不是所有符號(hào)).?

`-t'?
`--trace'?
打印'ld'處理的所有輸入文件的名字.?

`-T SCRIPTFILE'?
`--script=SCRIPTFILE'?
把SCRIPTFILE作為連接腳本使用. 這個(gè)腳本會(huì)替代'ld'的缺省連接腳本(而不是增加它的內(nèi)容),所以?
命令文件必須指定所有需要的東西以精確描述輸出文件. 如果SCRIPTFILE在當(dāng)前目錄下不存在,'ld'?
會(huì)在'-L'選項(xiàng)指定的所有目錄下去尋找.多個(gè)'-T'選項(xiàng)會(huì)使內(nèi)容累積.?

`-u SYMBOL'?
`--undefined=SYMBOL'?
強(qiáng)制SYMBOL在輸出文件中作為一個(gè)無定義的符號(hào)被輸入.這樣做會(huì)有一些效果,比如,會(huì)引發(fā)從標(biāo)準(zhǔn)庫?
中連接更多的模塊. '-u'可以以不同的參數(shù)反復(fù)使用,以輸入多個(gè)無定義的符號(hào).這個(gè)選項(xiàng)跟連接腳?
本命令中的'EXTERN'是等效的.?

`-Ur'?
對(duì)于不是C++的程序,這個(gè)選項(xiàng)跟'-r'是等效的: 它產(chǎn)生可重定位的輸出,比如,一個(gè)輸出文件它可以再?
次作為'ld'的輸入. 當(dāng)連接C++程序時(shí),'-Ur'解析構(gòu)造函數(shù)的引用,跟'-r'不同. 但如果在一些用'-Ur'?
連接過的文件上再次使用'-Ur',它不會(huì)工作,因?yàn)橐坏?gòu)造函數(shù)表被建立,它不能被添加內(nèi)容.請(qǐng)只在?
最后一遍連接的時(shí)候使用'-Ur', 對(duì)其它的,只使用'-r'.?

`--unique[=SECTION]'?
對(duì)于所有匹配SECTION的輸入節(jié),在輸出文件中都各自創(chuàng)建單獨(dú)的節(jié),或者,如果可選的通配符SECTION?
參數(shù)丟失了,為每一個(gè)孤兒輸入節(jié)創(chuàng)建一個(gè)輸出節(jié). 一個(gè)孤兒節(jié)是一個(gè)連接腳本中沒有指定的節(jié).你?
可以在命令行上多次使用這個(gè)選項(xiàng); 它阻止對(duì)同名輸入節(jié)的合并,在連接腳本中重載輸出節(jié)分配.?

`-v'?
`--version'?
`-V'?
顯示'ld'的版本. '-V'選項(xiàng)同時(shí)會(huì)列出支持的模擬器.?

`-x'?
`--discard-all'?
刪除所有的本地符號(hào).?

`-X'?
`--discard-locals'?
刪除所有的臨時(shí)本地符號(hào).對(duì)于大多數(shù)目標(biāo)平臺(tái),就是所有的名字以'L'開頭的本地符號(hào).?

`-y SYMBOL'?
`--trace-symbol=SYMBOL'?
打印出所有SYMBOL出現(xiàn)的被連接文件的名字. 這個(gè)選項(xiàng)可以被多次使用. 在很多系統(tǒng)中,這在預(yù)先確定底?
線時(shí)很有必要.?

當(dāng)你擁有一個(gè)未定義的符號(hào),但不知道這個(gè)引用出自哪里的時(shí)候,這個(gè)選項(xiàng)很有用.?

`-Y PATH'?
為缺省的庫搜索路徑增加一條路徑.這個(gè)選項(xiàng)是為了跟Solaris兼容.?

`-z KEYWORD'?
能被識(shí)別的關(guān)鍵字包括'initfirst', 'interpose', 'loadfltr',`nodefaultlib', `nodelete',?
`nodlopen', `nodump', `now', `origin',`combreloc', `nocombreloc' and `nocopyreloc'. 為了跟?
Solaris兼容,所有其它的關(guān)鍵字都被忽略. 'initfirst'標(biāo)志一個(gè)對(duì)象,使它在運(yùn)行時(shí),在所有其他對(duì)象之?
前被初始化. 'interpose'標(biāo)志一個(gè)對(duì)象,使它的符號(hào)表放在所有其他符號(hào)之前,作為主要的執(zhí)行者.?
'loadfltr'標(biāo)志一個(gè)對(duì)象, 使它的過濾器在運(yùn)行時(shí)立即被處理.'nodefaultlib'標(biāo)志一個(gè)對(duì)象,使在搜索?
本對(duì)象所依賴的庫時(shí),忽略所有缺省庫搜索路徑. 'nodelete'標(biāo)志一個(gè)對(duì)象,使它在運(yùn)行時(shí)不會(huì)被從內(nèi)存?
中刪除.'nodlopen'標(biāo)志一個(gè)對(duì)象,使這個(gè)對(duì)象不可以通過'dlopen'載入.'nodump'標(biāo)志一個(gè)對(duì)象,使它不能?
被'dldump'轉(zhuǎn)儲(chǔ). 'now'標(biāo)志一個(gè)對(duì)象,使它成為非懶惰運(yùn)行時(shí)綁定對(duì)象. 'origin'標(biāo)志一些可能含有?
$ORIGIN的對(duì)象,'defs'不允許無定義符號(hào). 'muldefs'允許重定義. 'comberloc'組合多個(gè)重定位節(jié),重新?
排布它們,讓動(dòng)態(tài)符號(hào)可見. 'nocomberloc'使多個(gè)重定位節(jié)組合無效. 'nocopyreloc'使重定位拷貝后的?
結(jié)果無效.?

`-( ARCHIVES -)'?
`--start-group ARCHIVES --end-group'?
ARCHIVES應(yīng)當(dāng)是一個(gè)關(guān)于檔案文件的列表. 它們可以是顯式的文件名,或者'-l'選項(xiàng).?

這些指定的檔案文件會(huì)被多遍搜索,直到?jīng)]有新的無定義引用被創(chuàng)建. 通常,一個(gè)檔案文件只會(huì)被搜索一?
次. 但如果這個(gè)檔案文件中的一個(gè)符號(hào)需要被用來解析一個(gè)檔案中的目標(biāo)引用到的無定義的符號(hào),而這個(gè)?
符號(hào)在命令行上的后面某個(gè)檔案文件中出現(xiàn), 連接器不能解析這個(gè)引用. 把這些檔案文件分組后,它們都?
可被反復(fù)搜索直到所有可能的引用都被解析了為止.?

使用這個(gè)選項(xiàng)有一個(gè)很大的運(yùn)行開銷. 只有在無法避免在多個(gè)檔案文件中使用循環(huán)引用時(shí)才用它.?

`--accept-unknown-input-arch'?
`--no-accept-unknown-input-arch'?
告訴連接器接受那些架構(gòu)不能被識(shí)別的輸入文件. 但前提假設(shè)是用戶知道他們?cè)谧鍪裁?并且是故意要連?
接這些未知的輸入文件. 在版本2.14之前,這個(gè)是連接器的缺省行為. 從版本2.14以后的,缺省行為是拒?
絕這類輸入文件, 所以`--accept-unknown-input-arch'選項(xiàng)被用來恢復(fù)舊的行為.?

`-assert KEYWORD'?
這個(gè)選項(xiàng)被忽略,只是用來跟SunOS保持兼容.?

`-Bdynamic'?
`-dy'?
`-call_shared'?
連接動(dòng)態(tài)鏈接庫. 這個(gè)僅僅在支持共享庫的平臺(tái)上有用.在這些平臺(tái)上,這個(gè)選項(xiàng)通常是默認(rèn)行為. 這個(gè)選?
項(xiàng)的不同形式是為了跟不同的系統(tǒng)保持兼容. 你可以在命令行上多次使用這個(gè)選項(xiàng):它影響緊隨其后的'-l'?
選項(xiàng)的庫搜索.?

`-Bgroup'?
在動(dòng)態(tài)節(jié)的'DT_FLAGS_1'入口上設(shè)置'DF_1_GROUP'標(biāo)志.這會(huì)讓運(yùn)行時(shí)連接器在處理在這個(gè)對(duì)象和它的相?
關(guān)部分搜索時(shí)只在組中. '--no-undefined'是隱式的. 這個(gè)選項(xiàng)只在支持共享庫的ELF平臺(tái)上有用.?

`-Bstatic'?
`-dn'?
`-non_shared'?
`-static'?
不連接共享庫. 這個(gè)僅僅在支持共享庫的平臺(tái)上有用. 這個(gè)選項(xiàng)的不同形式是為了跟不同的系統(tǒng)保持兼?
容. 你可以在命令行上多次使用這個(gè)選項(xiàng):它影響緊隨其后的'-l'選項(xiàng)的庫搜索.?

`-Bsymbolic'?
當(dāng)創(chuàng)建一個(gè)共享庫時(shí), 把對(duì)全局符號(hào)的引用綁定到共享庫中的定義(如果有), 通常, 一個(gè)連接共享庫的程?
序重載共享庫中的定義是可能的. 這個(gè)選項(xiàng)只在支持共享庫的ELF平臺(tái)上有用.?

`--check-sections'?
`--no-check-sections'?
讓連接器在節(jié)地址被分配后不要去檢查節(jié)地址是否重疊.通常,連接器會(huì)執(zhí)行這種檢查,如果它發(fā)現(xiàn)了任何?
重疊,它會(huì)產(chǎn)生相應(yīng)的錯(cuò)誤信息. 連接器知道也允許節(jié)的重疊. 缺省的行為可以使用命令行開關(guān)?
`--check-sections'來恢復(fù).?

`--cref'?
輸出一個(gè)交叉引用表. 如果一個(gè)連接器位圖文件被產(chǎn)生, 交叉引用表被打印到位圖文件. 否則, 它被打印?
到標(biāo)準(zhǔn)輸出.?

表的格式相當(dāng)?shù)暮唵? 所以,如果需要,可以通過一個(gè)腳本很輕易地處理它. 符號(hào)是以名字被打印輸出,存?
儲(chǔ). 對(duì)于每一個(gè)符號(hào),給出一個(gè)文件名列表. 如果符號(hào)被定義了, 列出的第一個(gè)文件是符號(hào)定義的所在.?
接下來的文件包含符號(hào)的引用.?

`--no-define-common'?
這個(gè)選項(xiàng)限制對(duì)普通符號(hào)的地址分配. 腳本命令`INHIBIT_COMMON_ALLOCATION'具有同等的效果.?

`--no-define-common'選項(xiàng)允許從輸出文件的類型選擇中確定對(duì)普通符號(hào)的地址分配; 否則, 一個(gè)非重定?
位輸出類型強(qiáng)制為普通符號(hào)分配地址. 使用'--no-define-common'允許那些從共享庫中引用的普通符號(hào)只?
在主程序中被分配地址. 這會(huì)消除在共享庫中的無用的副本的空間, 同時(shí),也防止了在有多個(gè)指定了搜索?
路徑的動(dòng)態(tài)模塊在進(jìn)行運(yùn)行時(shí)符號(hào)解析時(shí)引起的混亂.?

`--defsym SYMBOL=EXPRESSION'?
在輸出文件中建立一個(gè)全局符號(hào),這個(gè)符號(hào)擁有一個(gè)EXPRESSION指定的絕對(duì)地址. 你可以多次使用這個(gè)選?
項(xiàng)定義多個(gè)符號(hào). EXPRESSION支持一個(gè)受限形式的算術(shù)運(yùn)算:你可以給出一個(gè)十六進(jìn)制常數(shù)或者一個(gè)已存?
在符號(hào)的名字,或者使用'+'和'-'來加或減十六進(jìn)制常數(shù)或符號(hào). 如果你需要更多的表達(dá)式,可以考慮在腳?
本中使用連接器命令語言, 注意在SYMBOL,=和EXPRESSION之間不允許有空格.?

`--demangle[=style]'?
`--no-demangle'?
這些選項(xiàng)控制是否在錯(cuò)誤信息和其它的輸出中重組符號(hào)名. 當(dāng)連接器被告知要重組, 它會(huì)試圖把符號(hào)名以?
一種可讀的形式的展現(xiàn): 如果符號(hào)被以目標(biāo)文件格式使用,它剝?nèi)デ皩?dǎo)的下劃線,并且把C++形式的符號(hào)名?
轉(zhuǎn)換成用戶可讀的名字. 不同的編譯器有不同的重組形式. 可選的重組形式參數(shù)可以被用來為你的編譯器?
選擇一個(gè)相應(yīng)的重組形式. 連接器會(huì)以缺省形式重組直至環(huán)境變量`COLLECT_NO_DEMANGLE'被設(shè)置. 這些?
選項(xiàng)可以被用來重載缺省的設(shè)置.?

`--dynamic-linker FILE'?
設(shè)置動(dòng)態(tài)連接器的名字. 這個(gè)只在產(chǎn)生動(dòng)態(tài)連接的ELF可執(zhí)行文件時(shí)有效. 缺省的動(dòng)態(tài)連接器通常是正確?
的; 除非你知道你在干什么,不要使用這個(gè)選項(xiàng).?

`--embedded-relocs'?
這個(gè)選項(xiàng)只在連接MIPS嵌入式PIC代碼時(shí)有效, 這些代碼必須是由GNU的編譯器跟匯編器通過-membedded-pic?
選項(xiàng)生成的. 它導(dǎo)致連接器產(chǎn)生一個(gè)表,這個(gè)表被用來在運(yùn)行時(shí)重定位所有的被靜態(tài)初始化為指針值的數(shù)?
據(jù).?

`--fatal-warnings'?
把所有的警告視為錯(cuò)誤.?

`--force-exe-suffix'?
確保輸出文件有一個(gè).exe后綴.?

如果一個(gè)被成功完整連接的輸出文件不帶有一個(gè)'.exe'或'.dll'后綴, 這個(gè)選項(xiàng)確保連接器把輸出文件?
拷貝成帶有'.exe'后綴的同名文件. 這個(gè)選項(xiàng)在使用微軟系統(tǒng)來編譯未經(jīng)修改的Unix的makefile時(shí)很有?
用, 因?yàn)橛行┌姹镜膚indows不會(huì)運(yùn)行一個(gè)不帶有'.exe'后綴的映像.?

`--no-gc-sections'?
`--gc-sections'?
允許對(duì)未使用的輸入節(jié)的碎片收集. 在不支持這個(gè)選項(xiàng)的平臺(tái)上,被忽略. 這個(gè)選項(xiàng)不能跟 '-r'選項(xiàng)共存?
也不能被用來進(jìn)行動(dòng)態(tài)連接. 缺省行為可以用`--no-gc-sections'進(jìn)行恢復(fù).?

`--help'?
在標(biāo)準(zhǔn)輸出上打印一個(gè)命令行選項(xiàng)概要,然后退出.?

`--target-help'?
打印一個(gè)所有目標(biāo)平臺(tái)相關(guān)的選項(xiàng)的概要,然后退出.?

`-Map MAPFILE'?
打印一個(gè)連接位圖到文件MAPFILE中. 參閱上面關(guān)于'-M'選項(xiàng)的描述.?

`--no-keep-memory'?
'ld'通常會(huì)以速度優(yōu)先于內(nèi)存使用的方式優(yōu)化程序,這是通過把輸入文件的符號(hào)表放在內(nèi)存緩沖中實(shí)現(xiàn)的,?
這個(gè)選項(xiàng)告訴'ld'以內(nèi)存使用優(yōu)先來優(yōu)化, 盡可能的減小符號(hào)表的重讀. 這在'ld'在連接一個(gè)大文件時(shí)?
超出內(nèi)存限制時(shí)有用.?

`--no-undefined'?
`-z defs'?
通常,當(dāng)創(chuàng)建一個(gè)非符號(hào)共享庫時(shí), 無定義的符號(hào)允許出現(xiàn),并留待運(yùn)行時(shí)連接器去解決. 這個(gè)選項(xiàng)關(guān)閉這?
樣的無定義符號(hào)的使用. 開關(guān)`--no-allow-shlib-undefined'控制共享對(duì)象被連接進(jìn)共享庫時(shí)的行為.?

`--allow-multiple-definition'?
`-z muldefs'?
通常,當(dāng)一個(gè)符號(hào)被定義多次時(shí), 連接器會(huì)報(bào)告一個(gè)致命錯(cuò)誤. 這些選項(xiàng)允許重定義并且第一個(gè)定義被使?
用?


`--allow-shlib-undefined'?
`--no-allow-shlib-undefined'?
允許(缺省)或不允許無定義符號(hào)存在于共享對(duì)象中. 這個(gè)開關(guān)的設(shè)置會(huì)重載'--no-undefined',這里只關(guān)?
注共享對(duì)象. 這樣,如果'--no-undefined'被設(shè)置,但'--no-allow-shlib-undefined'未被設(shè)置, 連鎖反應(yīng)?
是存在于規(guī)則對(duì)象文件中的無定義的符號(hào)會(huì)引起一個(gè)錯(cuò)誤,但是在共享對(duì)象中的未定義的符號(hào)會(huì)被忽略.?

把`--allow-shlib-undefined'設(shè)置為缺省的原因是在連接時(shí)指定的共享對(duì)象并不一定是載入時(shí)可載入的?
那個(gè),所以,符號(hào)可能要到載入時(shí)間才被解析.?

`--no-undefined-version'?
通常當(dāng)一個(gè)符號(hào)有一個(gè)未定義的版本時(shí),連接器會(huì)忽略它. 這個(gè)選項(xiàng)不允許符號(hào)有未定義的版本,并且碰?
到這種情況,會(huì)報(bào)告一個(gè)嚴(yán)重錯(cuò)誤.?

`--no-warn-mismatch'?
通常, 如果你因?yàn)橐恍┰?企圖把一些不匹配的輸入文件連接起來的時(shí)候,'ld'會(huì)給出一個(gè)錯(cuò)誤,可能這?
些文件是因?yàn)橛刹煌奶幚砥骶幾g. 這個(gè)選項(xiàng)告訴'ld'應(yīng)當(dāng)對(duì)這樣的錯(cuò)誤默認(rèn)允許. 這個(gè)選項(xiàng)必須小心?
使用.?

`--no-whole-archive'?
為后面的檔案文件關(guān)閉'--whole-archive'選項(xiàng)的影響.?

`--noinhibit-exec'?
當(dāng)一個(gè)可執(zhí)行文件還可以使用時(shí),就保留它. 通常,連接器如果在連接過程中遇到了錯(cuò)誤,就不會(huì)產(chǎn)生輸出?
文件;當(dāng)它遇上錯(cuò)誤時(shí),它會(huì)退出而不寫輸出文件.?

`-nostdlib'?
僅搜索那些在命令行上顯式指定的庫路徑. 在連接腳本中(包含在命令行上指定的連接腳本)指定的庫路?
徑都被忽略.?

`--oformat OUTPUT-formAT'?
'ld'可以被配置為支持多于一種的目標(biāo)文件. 如果你的'ld'以這種方式被配置,你可以使用'--oformat'?
選項(xiàng)來指定輸出目標(biāo)文件的二進(jìn)制格式.就算'ld'被配置為支持多種目標(biāo)格式,你也不必指定這個(gè)項(xiàng),因?
為'ld'應(yīng)當(dāng)被配置為把最常用的輸出格式作為默認(rèn)格式. OUTPUT-formAT是一個(gè)文本串,是被BFD庫支持?
的一個(gè)特定格式的名字.腳本命令'OUTPUT_formAT'也可以指定輸出格式,但這個(gè)選項(xiàng)可以覆蓋它.?

`-qmagic'?
這個(gè)選項(xiàng)被忽略,只是為了跟Linux保持兼容.?

`-Qy'?
這個(gè)選項(xiàng)被忽略,只是為了跟SVR4保持兼容.?

`--relax'?
一個(gè)機(jī)器相關(guān)的選項(xiàng). 只有在少數(shù)平臺(tái)上,這個(gè)選項(xiàng)被支持.?

在某些平臺(tái)上,'--relax'選項(xiàng)在連接器解析程序中的地址時(shí)執(zhí)行可能的全局優(yōu)化, 比如松散地址模式和在輸出文件?
中合成新的指令.?

在某些平臺(tái)上,連接時(shí)全局優(yōu)化會(huì)進(jìn)行符號(hào)調(diào)試導(dǎo)致程序不能運(yùn)行.?

在不支持這個(gè)選項(xiàng)的平臺(tái)上,'--relax'被接受,但被忽略.?

`--retain-symbols-file FILENAME'?
只保留在FILENAME中列出的那些符號(hào),丟棄所有其他的. FILENAME是一個(gè)簡單地平坦模式文件, 一個(gè)符號(hào)占一行.?
這個(gè)選項(xiàng)在那些會(huì)逐步積累起一個(gè)大的全局符號(hào)表的系統(tǒng)中(比如 VxWorks)會(huì)很有用,它能有效地節(jié)約內(nèi)存空間.?

'--retain-symbols-file'不丟棄未定義的符號(hào),和需要重定位的符號(hào).?

你可能在命令行上只指定'--retain-symbol-file'一次, 它覆蓋'-s'和'-S'的功能.?

`-rpath DIR'?
為運(yùn)行時(shí)庫的搜索路徑增加一個(gè)目錄. 這個(gè)在連接帶有共享庫的ELF可執(zhí)行文件時(shí)有用. '-rpath'的所有參數(shù)會(huì)被?
連接起來傳遞給運(yùn)行時(shí)連接器, 運(yùn)行時(shí)連接器在運(yùn)行時(shí)用它們定位共享對(duì)象. '-rpath'選項(xiàng)在定位那些在連接參數(shù)?
指定的共享對(duì)象需要的共享對(duì)象時(shí)也很有用; 參閱關(guān)于'-rpath-link'選項(xiàng)的描述, 如果在連接一個(gè)ELF可執(zhí)行文件?
時(shí)不使用'-rpath'選項(xiàng),那些環(huán)境變量'LD_RUN_PATH'選項(xiàng)就會(huì)被使用.?

'-rptah'選項(xiàng)也可以使用在SunOS上. 缺省地,在SunOS上,連接器會(huì)從所有的'-L'選項(xiàng)中形成一個(gè)運(yùn)行時(shí)搜索路徑.?
如果使用了'-rpath'選項(xiàng), 那運(yùn)行時(shí)搜索路徑就只從'-rpath'選項(xiàng)中得到, 忽略'-L'選項(xiàng). 這在使用GCC時(shí)非常有?
用, 它會(huì)用上很多的'-L'選項(xiàng),而這些路徑很可能就是NFS掛上去的文件系統(tǒng)中.?

為了同ELF的連接器兼容, 如果'-R'選面后面跟有一個(gè)目錄名, 而不是一個(gè)文件名,那它也會(huì)被處理成'-rpath'選?
項(xiàng).?

`-rpath-link DIR'?
當(dāng)在SunOS上使用ELF時(shí),一個(gè)共享庫可能會(huì)用到另一個(gè)共享庫. 當(dāng)'ld -share'把一個(gè)共享庫作為一個(gè)輸入文件連接?
時(shí)就有可能發(fā)生這種情況.?

當(dāng)一個(gè)連接器在作非共享,不可重定位連接時(shí),如果遇上這種依賴情況,它會(huì)自動(dòng)定位需要的共享庫,然后把它包含在?
連接中, 如果在這種情況中,它沒有被顯式包含, 那'-rpath-link'選項(xiàng)指定優(yōu)先搜索的一組路徑名.?

這個(gè)選項(xiàng)必須小心使用,因?yàn)樗鼤?huì)覆蓋那些可能已經(jīng)被編譯進(jìn)共享庫中的搜索路徑. 在這種情況下,它就有可能使用?
一個(gè)非內(nèi)部的不同的搜索路徑.?

連接器使用下面的搜索路徑來定位需要的共享庫:?

1. 所有由'-rpath-link'選項(xiàng)指定的搜索路徑.?

2. 所有由'-rpath'指定的搜索路徑. '-rpath'跟'-rpath_link'的不同之處在于,由'-rpath'指定的路徑被包含在可?
執(zhí)行文件中,并在運(yùn)行時(shí)使用, 而'-rpath-link'選項(xiàng)僅僅在連接時(shí)起作用. 它只用于本地連接器.?

3. 在一個(gè)ELF系統(tǒng)中, 如果'-rpath'和'rpath-link'選項(xiàng)沒有被使用, 會(huì)搜索環(huán)境變量'LD_RUN_PATH'的內(nèi)容.它也只?
對(duì)本地連接器起作用.?

4. 在SunOS上, '-rpath'選項(xiàng)不使用, 只搜索所有由'-L'指定的目錄.?

5. 對(duì)于一個(gè)本地連接器,環(huán)境變量'LD_LIBRARY_PATH'的內(nèi)容被搜索.?

6. 對(duì)于一個(gè)本地ELF連接器,共享庫中的`DT_RUNPATH'和`DT_RPATH'操作符會(huì)被需要它的共享庫搜索. 如果'DT_RUNPATH'?
存在了, 那'DT_RPATH'就會(huì)被忽略.?

7. 缺省目錄, 常規(guī)的,如'/lib'和'/usr/lib'.?

8. 對(duì)于ELF系統(tǒng)上的本地連接器, 如果文件'/etc/ld.so.conf'存在, 這個(gè)文件中有的目錄會(huì)被搜索.?

如果需要的共享庫沒有被找到, 那連接器會(huì)發(fā)出一條警告信息,并繼續(xù)執(zhí)行連接.?

`-shared'?
`-Bshareable'?
創(chuàng)建一個(gè)共享庫. 這個(gè)選項(xiàng)只在ELF, XCOFF和SunOS平臺(tái)上有用。 在SunOS上,如果'-e'選項(xiàng)沒有被使用,并在連接?
中有未定義的符號(hào),連接器會(huì)自動(dòng)創(chuàng)建一個(gè)共享庫,?

`--sort-common'?
這個(gè)選項(xiàng)告訴'ld'當(dāng)它把普通符號(hào)放到相應(yīng)的輸出節(jié)中時(shí)按大小進(jìn)行排序。排在最前面的是所有的一字節(jié)符號(hào),然?
后是所有的二字節(jié),然后是所有的四字節(jié), 然后是其它的。 這是為了避免因?yàn)閷?duì)齊約束而在符號(hào)間產(chǎn)生的斷裂?

`--split-by-file [SIZE]'?
跟'--split-by-reloc'相似,但在SIZE達(dá)到時(shí),為每一個(gè)輸入文件創(chuàng)建一個(gè)新的輸出節(jié)。如果沒有給出,SIZE缺省?
地設(shè)置為1?

`--split-by-reloc [COUNT]'?
試圖在輸出文件中創(chuàng)建節(jié)外的節(jié),這樣就沒有單個(gè)的輸出節(jié)含有多于COUNT個(gè)重定位符。這在產(chǎn)生巨大的用于COFF格?
式的實(shí)時(shí)內(nèi)核的可重定位文件時(shí)非常有用;因?yàn)镃OFF不能在一個(gè)節(jié)中表示多于65535個(gè)重定位。 注意,這在不支持?
專有節(jié)的目標(biāo)文件格式中會(huì)失敗,連接器不會(huì)把單個(gè)輸入節(jié)分割進(jìn)行重分配, 所以,如果單個(gè)輸入節(jié)含有多于COUNT?
個(gè)重定位符, 那一個(gè)輸出節(jié)會(huì)含有同樣多的可重定位符。COUNT缺省被設(shè)為32768.?

`--stats'?
計(jì)算并顯示關(guān)于連接器操作的統(tǒng)計(jì)信息, 比如執(zhí)行時(shí)間,內(nèi)存占用等.?

`--traditional-format'?
對(duì)于某些目標(biāo)平臺(tái), 'ld'的輸出會(huì)跟某些面有的連接器的輸出有所不同. 這個(gè)開關(guān)要求'ld'使用傳?
統(tǒng)的格式.?

比如, 在SunOS上, 'ld'會(huì)把符號(hào)串表中的兩上完全相同的入口合并起來. 這可以把一個(gè)帶有調(diào)試信息?
的輸出文件的大小減小百發(fā)之三十. 不幸地是, SunOS的'dbx'程序不能讀取這個(gè)輸出的程序(gdb就沒?
有問題).'--trafitinal-format'開關(guān)告訴'ld'不要把相同的入口合并起來.?

`--section-start SECTIONNAME=ORG'?
通過指定ORG, 指定節(jié)在輸出文件中的絕對(duì)地址. 你可以多次使用這個(gè)選項(xiàng)來定位多個(gè)節(jié). ORG必須是?
一個(gè)十六進(jìn)制整數(shù); 為了跟基他的連接器兼容,你可以忽略前導(dǎo)'0x'. 注意,在SECTIONNAME,等號(hào),ORG?
之間不允許有空格出現(xiàn).?

`-Tbss ORG'?
`-Tdata ORG'?
`-Ttext ORG'?
跟-section-start同義, 不過把SECTIONNAME替換為'.bss', '.data'或'.text'.?

`--dll-verbose'?
`--verbose'?
顯示'ld'的版本號(hào),并列出支持的連接器模擬. 顯示哪些輸入文件能被打開,而哪些不能. 顯示連接器?
使用的連接腳本.?

`--version-script=VERSION-SCRIPTFILE'?
指定連接器的腳本的版本名. 這個(gè)常在創(chuàng)建一個(gè)需要指定附加的關(guān)于版本層次的信息的共享庫時(shí)使用,?
這個(gè)選項(xiàng)只有支持共享庫的ELF平臺(tái)上有效.?

`--warn-common'?
當(dāng)一個(gè)普通符號(hào)跟另一個(gè)普通符號(hào)或會(huì)號(hào)定義合并起來時(shí),警告. 類Unix連接器允許這個(gè)選項(xiàng),有時(shí)比?
較實(shí)用, 但是在其他的操作系統(tǒng)上的連接器不允許這個(gè). 這個(gè)選項(xiàng)可以讓你在合并全局符號(hào)時(shí)發(fā)現(xiàn)某?
些潛在的問題. 不幸的是,有些C庫使用這項(xiàng)特性,所以你可能會(huì)像在你的程序中一樣,在庫中得到一些?
警告信息.?

這里給出三種類型的全局符號(hào)的解釋(用C語言):?

`int i = 1;'?
一個(gè)定義, 它會(huì)存在于輸出文件中的已初始化數(shù)據(jù)節(jié).?

`extern int i;'?
一個(gè)未定義符號(hào),它不占用空間. 必須在另外某一處對(duì)它有一個(gè)定義,或一個(gè)普通符號(hào)?

`int i;'?
一個(gè)普通符號(hào).如果對(duì)于一個(gè)變量只有(一個(gè)或多個(gè))普通符號(hào), 它進(jìn)入輸出文件的未初始化數(shù)據(jù)域. 連?
接器會(huì)把同一變量的多個(gè)普通符號(hào)合并成一個(gè)單一的符號(hào). 如果他們有不同的大小, 它采用最大的一?
個(gè). 如果是對(duì)同一變量的定義,連接器把一個(gè)普通符號(hào)轉(zhuǎn)化為一個(gè)聲明.?

'--warn-common'選項(xiàng)可以產(chǎn)生五種類型的警告. 每種警告由兩行組成: 第一行描述遇到的符號(hào), 第二?
行描述遇到的前一個(gè)具有相同名字的符號(hào). 一個(gè)或兩個(gè)都可能成為普通符號(hào).?

1. 把一個(gè)普通符號(hào)轉(zhuǎn)化為一個(gè)引用, 因?yàn)檫@個(gè)符號(hào)已經(jīng)有一個(gè)定義了.?
FILE(SECTION): warning: common of `SYMBOL'?
overridden by definition?
FILE(SECTION): warning: defined here?

2. 把一個(gè)普通符號(hào)轉(zhuǎn)化為一個(gè)引用,因?yàn)橛龅搅说诙€(gè)關(guān)于符號(hào)的定義. 這跟前一種情況相同,除了符?
號(hào)遇到的順序相反.?
FILE(SECTION): warning: definition of `SYMBOL'?
overriding common?
FILE(SECTION): warning: common is here?

3. 把一個(gè)普通符號(hào)跟前一個(gè)相同大小的普通符號(hào)合并.?
FILE(SECTION): warning: multiple common?
of `SYMBOL'?
FILE(SECTION): warning: previous common is here?

4. 把一個(gè)普通符號(hào)跟前一個(gè)更大的普通符號(hào)合并.?
FILE(SECTION): warning: common of `SYMBOL'?
overridden by larger common?
FILE(SECTION): warning: larger common is here?

5. 把一個(gè)普通符號(hào)跟前一個(gè)更小的普通符號(hào)合并. 這跟前一種情況相同, 除了遇到的符號(hào)的順序不同.?
FILE(SECTION): warning: common of `SYMBOL'?
overriding smaller common?
FILE(SECTION): warning: smaller common is here?

`--warn-constructors'?
如果有全局結(jié)構(gòu)體被使用到了,警告. 這只對(duì)很少的一些目標(biāo)文件格式有用. 對(duì)于COFF或ELF格式, 連?
接器不同探測到全局結(jié)構(gòu)體的使用.?

`--warn-multiple-gp'?
如果在輸出文件中,需要多個(gè)全局指針值,警告. 這只對(duì)特定的處理器有意義, 比如Alpha. 特別的,有?
些處理器在特定的節(jié)中放入很大的常數(shù)值. 一個(gè)特殊的寄存器(全局指針)指向這個(gè)節(jié)的中間部分, 所?
以通過一個(gè)基地址寄存器相關(guān)的地址模式,這個(gè)常數(shù)可以很容易地被載入. 因?yàn)檫@個(gè)基寄存器相關(guān)模式?
的偏移值是固定的而且很小(比如,16位), 這會(huì)限制常量池的最大尺寸. 所以,一個(gè)很大的問題是,為了?
能夠定位所有可能的常數(shù),經(jīng)常需要使用多個(gè)全局指針值. 這個(gè)選項(xiàng)在這種情況發(fā)生時(shí)產(chǎn)生一條警告.?

`--warn-once'?
對(duì)于每一個(gè)未定義符號(hào)只警告一次, 而不是在每一個(gè)用到它的模塊中警告一次.?

`--warn-section-align'?
如果輸出節(jié)的地址因?yàn)閷?duì)齊被改變了,警告. 通常, 對(duì)齊會(huì)被輸入節(jié)設(shè)置. 如果'SECTION'命令沒有指?
定節(jié)的起始地址, 地址就會(huì)被隱式改變.?

`--whole-archive'?
對(duì)于每一個(gè)在命令行中'--whole-archive'選項(xiàng)后面出現(xiàn)的檔案文件, 在連接中包含檔案文件中的所有?
目標(biāo)文件, 而不是為需要的目標(biāo)文件搜索檔案文件. 這在把一個(gè)檔案文件轉(zhuǎn)化為一個(gè)共享庫時(shí)使用, 把?
所有的目標(biāo)放到最終的共享庫中. 這個(gè)選項(xiàng)可以被多次使用.?

在GCC中使用這個(gè)選項(xiàng)需要注意兩點(diǎn): 首先,GCC不知道這個(gè)選項(xiàng), 所以,你必須使用'-Wl, -whole-archive'.?
第二, 不要忘了在你的檔案文件列表的后面使用'-Wl, -no-whole-archive',因?yàn)镚CC會(huì)把它自己的檔?
案列表加到你的連接后面, 而這可能并不是你所預(yù)期的.?

`--wrap SYMBOL'?
對(duì)SYMBOL符號(hào)使用包裝函數(shù). 任何未定義的對(duì)SYMBOL符號(hào)的引用會(huì)被解析成'_wrap_SYMBOL'. 而任何?
未定義的對(duì)'_real_SYMBOL'的引用會(huì)被解析成SYMBOL.?

這可以用來為系統(tǒng)函靈敏提供一個(gè)包裝. 包裝函靈敏應(yīng)當(dāng)被叫做'__wrap_SYMBOL'. 如果需要調(diào)用這個(gè)?
函數(shù), 那就應(yīng)該調(diào)用'__real_SYMBOL'?

這里是一個(gè)沒什么實(shí)用價(jià)值的例子:?

void *?
__wrap_malloc (int c)?
{?
printf ("malloc called with %ld\n", c);?
return __real_malloc ?;?
}?

如果你使用'--wrap malloc'把這節(jié)代碼跟其他的代碼連接, 那所有的對(duì)'malloc'的調(diào)用都會(huì)調(diào)用?
'__wrap_malloc'函數(shù). 而在'__wrap_malloc'中的'__real_malloc'會(huì)調(diào)用真正的'malloc'函數(shù).?

你有可能也希望提供一個(gè)'__real_malloc'函數(shù), 這樣,不帶有'--wrap'的連接器也會(huì)成功連接.如果?
你這樣做了, 你不能把'__real_malloc'的定義跟'__wrap_malloc'放到同一個(gè)文件中;如果放在一起?
匯編器會(huì)在連接器之前把調(diào)用解析成真正的'malloc'.?

`--enable-new-dtags'?
`--disable-new-dtags'?
連接器可以在ELF中創(chuàng)建一個(gè)新的動(dòng)態(tài)標(biāo)簽. 但是舊的ELF系統(tǒng)可能不理解這個(gè). 如果你指定了?
'--enable-new-dtags',動(dòng)態(tài)標(biāo)簽會(huì)按需要被創(chuàng)建. 如果你指定了'--disable-new-dtags',那不會(huì)有?
新的動(dòng)態(tài)標(biāo)簽被創(chuàng)建. 缺省地,新的動(dòng)態(tài)標(biāo)簽不會(huì)被創(chuàng)建. 注意這些選項(xiàng)只在ELF系統(tǒng)中有效.?

i386 PE平臺(tái)的特定選項(xiàng).?
-----------------------------------?

i386 PE連接器支持'-shared'選項(xiàng), 它使輸出文件為一個(gè)動(dòng)態(tài)鏈接庫(DLL),而不是一個(gè)普通的可執(zhí)行文件. 在?
使用這個(gè)選項(xiàng)的時(shí)候,你應(yīng)當(dāng)為輸出文件取名'*.dll',另外, 連接器完全支持標(biāo)準(zhǔn)的'*.def'文件, 這類文件可?
以在連接器命令行上象一個(gè)目標(biāo)文件一樣被指定(實(shí)際上, 它應(yīng)當(dāng)被放在它從中導(dǎo)出符號(hào)的那個(gè)檔案文件前面,?
以保證它們象一個(gè)普通的目標(biāo)文件一樣被連接進(jìn)去.)?

除了對(duì)所有平臺(tái)通用的那些選項(xiàng)外,i386 PE連接器支持一些只對(duì)i386平臺(tái)專有的命令行選面. 帶有值的選項(xiàng)應(yīng)?
當(dāng)用空格或等號(hào)把它跟值分隔開.?

`--add-stdcall-alias'?
如果給出這個(gè)選項(xiàng), 帶有標(biāo)準(zhǔn)調(diào)用后綴(@NN)的符號(hào)會(huì)被剝掉后綴后導(dǎo)出.?

`--base-file FILE'?
使用FILE作為文件名,該文件是存放用'dlltool'產(chǎn)生 DLL文件時(shí)所需的所有重定位符的基地址的.(這?
個(gè)選面是i386 PE平臺(tái)所專有的]?

`--dll'?
創(chuàng)建一個(gè)DLL文件而不是一個(gè)常規(guī)可執(zhí)行文件. 你可能在一個(gè)給出的'.def'文件中使用'-shared'或指?
定'LIBRARY'.?

`--enable-stdcall-fixup'?
`--disable-stdcall-fixup'?
如果連接器發(fā)現(xiàn)有符號(hào)不能解析, 它會(huì)試圖進(jìn)行'失真連接',即尋找另一個(gè)定義的符號(hào),它們只是在?
符號(hào)名的格式上不同(cdecl vs stdcall),并把符號(hào)解析為找到的這個(gè)符號(hào). 比如, 一個(gè)未定義的符?
號(hào)'_foo'可能被連接到函數(shù)'_foo@12', 或者一個(gè)未定義的符號(hào)'_bar@16'可能被連接到函數(shù)'_bar'.?
如果連接器這么做了, 它會(huì)打印出一條警告信息, 因?yàn)樵谡G闆r下,這會(huì)連接失敗, 但有時(shí),由第三?
方庫產(chǎn)生的導(dǎo)入庫可能需要這個(gè)特性. 如果你指定了'--enable-stdcall-fixup', 這個(gè)特性會(huì)被完全?
開啟,警告信息也不會(huì)打印出來. 如果你指定了'--disable-stdcall-fixup',這個(gè)特性被關(guān)閉,而且這?
樣的錯(cuò)誤匹配會(huì)被認(rèn)為是個(gè)錯(cuò)誤.?

`--export-all-symbols'?
如果給出這個(gè)選項(xiàng),目標(biāo)中所有由DLL建立的全局符號(hào)會(huì)被DLL導(dǎo)出. 注意這是缺省情況,否則沒有任何?
符號(hào)被導(dǎo)出. 如果符號(hào)由DEF文件顯式地導(dǎo)出,或由函數(shù)本身的屬性隱式地導(dǎo)出, 缺省情況是除非選項(xiàng)?
給出,否則不導(dǎo)出任何其他的符號(hào). 注意符號(hào)`DllMain@12',`DllEntryPoint@0',?
`DllMainCRTStartup@12'和`impure_ptr'不會(huì)自動(dòng)被導(dǎo)出.而且,由其他的DLL導(dǎo)入的符號(hào)也不會(huì)被再?
次導(dǎo)出, 還有指定DLL內(nèi)部布局的符號(hào),比如那些以'_head_'開頭,或者以'_iname'結(jié)尾的符號(hào)也不會(huì)?
被導(dǎo)出.還有,'libgcc','libstd++','libmingw32'或'crtX.o'中的符號(hào)也不會(huì)被導(dǎo)出. ......?

環(huán)境變量?
=====================?

你可以通過環(huán)境變量`GNUTARGET', `LDEMULATION'和`COLLECT_NO_DEMANGLE'改變'ld'的行為.?

`GNUTARGET'在你沒有使用'-b'(或者它的同義詞'--format')的時(shí)候,決定輸入文件的格式. 它的值應(yīng)當(dāng)是BFD?
中關(guān)于輸入格式的一個(gè)名字. 如果環(huán)境中沒有'GNUTARGET'變量, 'ld'使用目標(biāo)平臺(tái)的缺省格式. 如果?
'GNUTARGET'被設(shè)為'default', 那BFD就會(huì)通過檢查二進(jìn)制的輸入文件來找到輸入格式; 這個(gè)方法通常會(huì)成功,?
但會(huì)有潛在的不明確性, 因?yàn)闆]有辦法保證指定一個(gè)目標(biāo)文件格式的魔數(shù)總是唯一的. 但是, 在每一個(gè)系統(tǒng)上?
的BFD配置程序會(huì)把這個(gè)系統(tǒng)的常規(guī)格式放在搜索列表的首位, 所以不明確性可以通過這種慣列來解決.?

`LDEMULATION'在你沒有使用'-m'選項(xiàng)的時(shí)候決定缺省的模擬器. 模擬器可以影響到連接器行為的很多方面,?
特別是連接器的缺省連接腳本. 你可以通過'--verbose'或'-V'選項(xiàng)列出所有可用的模擬器. 如果'-m'選項(xiàng)沒?
有使用, 而且`LDEMULATION'環(huán)境變量沒有定義, 缺省的模擬器跟連接器如何被配置有關(guān).?

一般地,連接器缺省狀況下會(huì)重構(gòu)符號(hào).但是,如果在環(huán)境中設(shè)置了`COLLECT_NO_DEMANGLE', 那缺省狀態(tài)下就不?
會(huì)重構(gòu)符號(hào).這個(gè)環(huán)境變量在GCC的連接包裝程序中會(huì)以相似的方式被使用. 這個(gè)缺省的行為可以被'--demangle'?
或'--no-demangle'選項(xiàng)覆蓋.?

連接腳本?
**************?

每個(gè)連接都被一個(gè)'連接腳本'所控制. 這個(gè)腳本是用連接命令語言書寫的.?

連接腳本的一個(gè)主要目的是描述輸入文件中的節(jié)如何被映射到輸出文件中,并控制輸出文件的內(nèi)存排布. 幾乎?
所有的連接腳本只做這兩件事情. 但是,在需要的時(shí)候,連接器腳本還可以指示連接器執(zhí)行很多其他的操作.這?
通過下面描述的命令實(shí)現(xiàn).?

連接器總是使用連接器腳本的.如果你自己不提供, 連接器會(huì)使用一個(gè)缺省的腳本,這個(gè)腳本是被編譯進(jìn)連接器?
可執(zhí)行文件的. 你可以使用'--verbose'命令行選項(xiàng)來顯示缺省的連接器腳本的內(nèi)容. 某些命令行選項(xiàng),比如?
'-r'或'-N', 會(huì)影響缺省的連接腳本.?

你可以過使用'-T'命令行選項(xiàng)來提供你自己的連接腳本. 當(dāng)你這么做的時(shí)候, 你的連接腳本會(huì)替換缺省的連?
接腳本.?

你也可以通過把連接腳本作為一個(gè)連接器的輸入文件來隱式地使用它,就象它們是一個(gè)被連接的文件一樣.?

基本的連接腳本的概念?
============================?

我們需要定義一些基本的概念與詞匯以描述連接腳本語言.?

連接器把多個(gè)輸入文件合并成單個(gè)輸出文件. 輸出文件和輸入文件都以一種叫做'目標(biāo)文件格式'的數(shù)據(jù)格式形?
式存在. 每一個(gè)文件被叫做'目標(biāo)文件'. 輸出文件經(jīng)常被叫做'可執(zhí)行文件',但是由于需要,我們也把它叫做目?
標(biāo)文件. 每一個(gè)目標(biāo)文件中,在其它東西之間,有一個(gè)節(jié)列表.我們有時(shí)把輸入文件的節(jié)叫做輸入節(jié); 相似的,輸?
出文件中的一個(gè)節(jié)經(jīng)常被叫做輸出節(jié).?

一個(gè)目標(biāo)文件中的每一個(gè)節(jié)都有一個(gè)名字和一個(gè)大小尺寸. 大多數(shù)節(jié)還有一個(gè)相關(guān)的數(shù)據(jù)塊, 稱為節(jié)內(nèi)容. 某?
一個(gè)節(jié)可能被標(biāo)式詎'loadable',含義是在輸出文件被執(zhí)行時(shí),這個(gè)節(jié)應(yīng)當(dāng)被載入到內(nèi)存中去. 一個(gè)沒有內(nèi)容的?
節(jié)可能是'allocatable', 含義是內(nèi)存中必須為這個(gè)節(jié)開辟一塊空間,但是沒有實(shí)際的內(nèi)容載入到這里(在某些?
情況下,這塊內(nèi)存必須被標(biāo)式詎零). 一個(gè)既不是loadable也不是allocatable的節(jié)一般含有一些調(diào)試信息.?

每一個(gè)loadable或allocatable的輸出節(jié)有兩個(gè)地址. 第一個(gè)是'VMA'或稱為虛擬內(nèi)存地址. 這是當(dāng)輸出文件運(yùn)?
行時(shí)節(jié)所擁有的地址. 第二個(gè)是"LMA', 或稱為載入內(nèi)存地址. 這個(gè)節(jié)即將要載入的內(nèi)存地址. 這大多數(shù)情況下?
這兩個(gè)地址是相同的. 它們兩個(gè)有可能不同的一個(gè)例子是當(dāng)一個(gè)數(shù)據(jù)節(jié)在ROM中時(shí), 當(dāng)程序啟動(dòng)時(shí),被拷貝到RAM?
中(這個(gè)技術(shù)經(jīng)常被用在基于ROM的系統(tǒng)中進(jìn)行全局變量的初始化). 在這種情況下, ROM地址就是LMA, 而RAM地?
址就是VMA.?

你可以通過使用帶有'-h'選項(xiàng)的'objdump'來察看目標(biāo)文件中的節(jié).?

每一個(gè)目標(biāo)文件還有一個(gè)關(guān)于符號(hào)的列表, 被稱為'符號(hào)表'. 一個(gè)符號(hào)可能是定義過了的,也可能是未定義的.?
每一個(gè)符號(hào)有一個(gè)名字, 而且每一個(gè)定義的符號(hào)有一個(gè)地址. 如果你把一個(gè)C/C++程序編譯為一個(gè)目標(biāo)文件,對(duì)?
于每一個(gè)定義的函數(shù)和全局或靜態(tài)變量,你為得到一個(gè)定義的符號(hào). 每一個(gè)在輸入文件中只是一個(gè)引用而未定義?
的函數(shù)或全局變量會(huì)變成一個(gè)未定義的符號(hào).?

你可以使用'nm'程序來看一個(gè)目標(biāo)文件中的符號(hào), 或者使用'objdump'程序帶有'-t'選項(xiàng).?

連接腳本的格式?
====================?

連接腳本是文本文件.?

你寫了一系列的命令作為一個(gè)連接腳本. 每一個(gè)命令是一個(gè)帶有參數(shù)的關(guān)鍵字,或者是一個(gè)對(duì)符號(hào)的賦值. 你可?
以用分號(hào)分隔命令. 空格一般被忽略.?

文件名或格式名之類的字符串一般可以被直接鍵入. 如果文件名含有特殊字符,比如一般作為分隔文件名用的逗?
號(hào), 你可以把文件名放到雙引號(hào)中. 文件名中間無法使用雙引號(hào).?

你可以象在C語言中一樣,在連接腳本中使用注釋, 用'/*'和'*/'隔開. 就像在C中,注釋在語法上等同于空格.?

簡單的連接腳本示例?
============================?

許多腳本是相當(dāng)?shù)暮唵蔚??

可能的最簡單的腳本只含有一個(gè)命令: 'SECTIONS'. 你可以使用'SECTIONS'來描述輸出文件的內(nèi)存布局.?

'SECTIONS'是一個(gè)功能很強(qiáng)大的命令. 這里這們會(huì)描述一個(gè)很簡單的使用. 讓我們假設(shè)你的程序只有代碼節(jié),?
初始化過的數(shù)據(jù)節(jié), 和未初始化過的數(shù)據(jù)節(jié). 這些會(huì)存在于'.text','.data'和'.bss'節(jié), 另外, 讓我們進(jìn)一?
步假設(shè)在你的輸入文件中只有這些節(jié).?

對(duì)于這個(gè)例子, 我們說代碼應(yīng)當(dāng)被載入到地址'0x10000'處, 而數(shù)據(jù)應(yīng)當(dāng)從0x8000000處開始. 下面是一個(gè)實(shí)現(xiàn)?
這個(gè)功能的腳本:?

SECTIONS?
{?
. = 0x10000;?
.text : { *(.text) }?
. = 0x8000000;?
.data : { *(.data) }?
.bss : { *(.bss) }?
}?

你使用關(guān)鍵字'SECTIONS'寫了這個(gè)SECTIONS命令, 后面跟有一串放在花括號(hào)中的符號(hào)賦值和輸出節(jié)描述的內(nèi)容.?

上例中, 在'SECTIONS'命令中的第一行是對(duì)一個(gè)特殊的符號(hào)'.'賦值, 這是一個(gè)定位計(jì)數(shù)器. 如果你沒有以其?
它的方式指定輸出節(jié)的地址(其他方式在后面會(huì)描述), 那地址值就會(huì)被設(shè)為定位計(jì)數(shù)器的現(xiàn)有值. 定位計(jì)數(shù)器?
然后被加上輸出節(jié)的尺寸. 在'SECTIONS'命令的開始處, 定位計(jì)數(shù)器擁有值'0'.?

第二行定義一個(gè)輸出節(jié),'.text'. 冒號(hào)是語法需要,現(xiàn)在可以被忽略. 節(jié)名后面的花括號(hào)中,你列出所有應(yīng)當(dāng)被?
放入到這個(gè)輸出節(jié)中的輸入節(jié)的名字. '*'是一個(gè)通配符,匹配任何文件名. 表達(dá)式'*(.text)'意思是所有的輸?
入文件中的'.text'輸入節(jié).?

因?yàn)楫?dāng)輸出節(jié)'.text'定義的時(shí)候, 定位計(jì)數(shù)器的值是'0x10000',連接器會(huì)把輸出文件中的'.text'節(jié)的地址設(shè)?
為'0x10000'.?

余下的內(nèi)容定義了輸出文件中的'.data'節(jié)和'.bss'節(jié). 連接器會(huì)把'.data'輸出節(jié)放到地址'0x8000000'處. 連接?
器放好'.data'輸出節(jié)之后, 定位計(jì)數(shù)器的值是'0x8000000'加上'.data'輸出節(jié)的長度. 得到的結(jié)果是連接器會(huì)?
把'.bss'輸出節(jié)放到緊接'.data'節(jié)后面的位置.?

連接器會(huì)通過在必要時(shí)增加定位計(jì)數(shù)器的值來保證每一個(gè)輸出節(jié)具有它所需的對(duì)齊. 在這個(gè)例子中, 為'.text'?
和'.data'節(jié)指定的地址會(huì)滿足對(duì)齊約束, 但是連接器可能會(huì)需要在'.data'和'.bss'節(jié)之間創(chuàng)建一個(gè)小的缺口.?

就這樣,這是一個(gè)簡單但完整的連接腳本.?

簡單的連接腳本命令.?
=============================?

在本章中,我們會(huì)描述一些簡單的腳本命令.?

設(shè)置入口點(diǎn).?
-----------------------?

在運(yùn)行一個(gè)程序時(shí)第一個(gè)被執(zhí)行到的指令稱為"入口點(diǎn)". 你可以使用'ENTRY'連接腳本命令來設(shè)置入口點(diǎn).參數(shù)?
是一個(gè)符號(hào)名:?
ENTRY(SYMBOL)?

有多種不同的方法來設(shè)置入口點(diǎn).連接器會(huì)通過按順序嘗試以下的方法來設(shè)置入口點(diǎn), 如果成功了,就會(huì)停止.?

* `-e'入口命令行選項(xiàng);?

* 連接腳本中的`ENTRY(SYMBOL)'命令;?

* 如果定義了start, 就使用start的值;?

* 如果存在,就使用'.text'節(jié)的首地址;?

* 地址`0'.?

處理文件的命令.?
---------------------------?

有幾個(gè)處理文件的連接腳本命令.?

`INCLUDE FILENAME'?
在當(dāng)前點(diǎn)包含連接腳本文件FILENAME. 在當(dāng)前路徑下或用'-L'選項(xiàng)指定的所有路徑下搜索這個(gè)文件,?
你可以嵌套使用'INCLUDE'達(dá)10層.?

`INPUT(FILE, FILE, ...)'?
`INPUT(FILE FILE ...)'?
'INPUT'命令指示連接器在連接時(shí)包含文件, 就像它們是在命令行上指定的一樣.?

比如,如果你在連接的時(shí)候總是要包含文件'subr.o',但是你對(duì)每次連接時(shí)要在命令行上輸入感到厭煩?
, 你就可以在你的連接腳本中輸入'INPUT (subr.o).?

事實(shí)上,如果你喜歡,你可以把你所有的輸入文件列在連接腳本中, 然后在連接的時(shí)候什么也不需要,?
只要一個(gè)'-T'選項(xiàng)就夠了.?

在一個(gè)'系統(tǒng)根前綴'被配置的情況下, 一個(gè)文件名如果以'/'字符打頭, 并且腳本也存放在系統(tǒng)根?
前綴的某個(gè)子目錄下, 文件名就會(huì)被在系統(tǒng)根前綴下搜索. 否則連接器就會(huì)企圖打開當(dāng)前目錄下的文?
件. 如果沒有發(fā)現(xiàn), 連接器會(huì)通過檔案庫搜索路徑進(jìn)行搜索.?

如果你使用了'INPUT (-lFILE)', 'ld'會(huì)把文件名轉(zhuǎn)換為'libFILE.a', 就象命令行參數(shù)'-l'一樣.?

當(dāng)你在一個(gè)隱式連接腳本中使用'INPUT'命令的時(shí)候, 文件就會(huì)在連接時(shí)連接腳本文件被包含的點(diǎn)上?
被包含進(jìn)來. 這會(huì)影響到檔案搜索.?

`GROUP(FILE, FILE, ...)'?
`GROUP(FILE FILE ...)'?
除了文件必須全是檔案文件之外, 'GROUP'命令跟'INPUT'相似, 它們會(huì)被反復(fù)搜索,直至沒有未定義?
的引用被創(chuàng)建.?

`OUTPUT(FILENAME)'?
'OUTPUT'命令命名輸出文件. 在連接腳本中使用'OUTPUT(FILENAME)'命令跟在命令行中使用'-o?
FILENAME'命令是完全等效的. 如果兩個(gè)都使用了, 那命令行選項(xiàng)優(yōu)先.?

你可以使用'OUTPUT'命令為輸出文件創(chuàng)建一個(gè)缺省的文件名,而不是常用的'a.out'.?

`SEARCH_DIR(PATH)'?
`SEARCH_DIR'命令給'ld'用于搜索檔案文件的路徑中再增加新的路徑. 使用`SEARCH_DIR(PATH)'跟在?
命令行上使用'-L PATH'選項(xiàng)是完全等效的. 如果兩個(gè)都使用了, 那連接器會(huì)兩個(gè)路徑都搜索. 用命?
令行選項(xiàng)指定的路徑首先被搜索.?

`STARTUP(FILENAME)'?
除了FILENAME會(huì)成為第一個(gè)被連接的輸入文件, 'STARTUP'命令跟'INPUT'命令完全相似, 就象這個(gè)文?
件是在命令行上第一個(gè)被指定的文件一樣. 如果在一個(gè)系統(tǒng)中, 入口點(diǎn)總是存在于第一個(gè)文件中,那?
這個(gè)就很有用.?

處理目標(biāo)文件格式的命令.?
-----------------------------------------?

有兩個(gè)處理目標(biāo)文件格式的連接腳本命令.?

`OUTPUT_formAT(BFDNAME)'?
`OUTPUT_formAT(DEFAULT, BIG, LITTLE)'?
`OUTPUT_formAT'命令為輸出文件使用的BFD格式命名. 使用`OUTPUT_formAT(BFDNAME)'跟在命令行上?
使用'-oformat BFDNAME'是完全等效的. 如果兩個(gè)都使用了, 命令行選項(xiàng)優(yōu)先.?

你可在使用`OUTPUT_formAT'時(shí)帶有三個(gè)參數(shù)以使用不同的基于'-EB'和'-EL'的命令行選項(xiàng)的格式.?

如果'-EB'和'-EL'都沒有使用, 那輸出格式會(huì)是第一個(gè)參數(shù)DEFAULT, 如果使用了'-EB',輸出格式會(huì)是?
第二個(gè)參數(shù)BIG, 如果使用了'-EL', 輸出格式會(huì)是第三個(gè)參數(shù), LITTLE.?

比如, 缺省的基于MIPS ELF平臺(tái)連接腳本使用如下命令:?

OUTPUT_formAT(elf32-bigmips, elf32-bigmips, elf32-littlemips)?
這表示缺省的輸出文件格式是'elf32-bigmips', 但是當(dāng)用戶使用'-EL'命令行選項(xiàng)的時(shí)候, 輸出文件就會(huì)?
被以`elf32-littlemips'格式創(chuàng)建.?

`TARGET(BFDNAME)'?
'TARGET'命令在讀取輸入文件時(shí)命名BFD格式. 它會(huì)影響到后來的'INPUT'和'GROUP'命令. 這個(gè)命令跟?
在命令行上使用`-b BFDNAME'相似. 如果使用了'TARGET'命令但`OUTPUT_formAT'沒有指定, 最后的?
'TARGET'命令也被用來設(shè)置輸出文件的格式.?

其它的連接腳本命令.?
----------------------------?

還有一些其它的連接腳本命令.?

`ASSERT(EXP, MESSAGE)'?
確保EXP不等于零,如果等于零, 連接器就會(huì)返回一個(gè)錯(cuò)誤碼退出,并打印出MESSAGE.?

`EXTERN(SYMBOL SYMBOL ...)'?
強(qiáng)制SYMBOL作為一個(gè)無定義的符號(hào)輸入到輸出文件中去. 這樣做了,可能會(huì)引發(fā)從標(biāo)準(zhǔn)庫中連接一些?
節(jié)外的庫. 你可以為每一個(gè)EXTERN'列出幾個(gè)符號(hào), 而且你可以多次使用'EXTERN'. 這個(gè)命令跟'-u'?
命令行選項(xiàng)具有相同的效果.?

`FORCE_COMMON_ALLOCATION'?
這個(gè)命令跟命令行選項(xiàng)'-d'具有相同的效果: 就算指定了一個(gè)可重定位的輸出文件('-r'),也讓'ld'?
為普通符號(hào)分配空間.?

`INHIBIT_COMMON_ALLOCATION'?
這個(gè)命令跟命令行選項(xiàng)`--no-define-common'具有相同的效果: 就算是一個(gè)不可重位輸出文件, 也讓?
'ld'忽略為普通符號(hào)分配的空間.?

`NOCROSSREFS(SECTION SECTION ...)'?
這個(gè)命令在遇到在某些特定的節(jié)之間引用的時(shí)候會(huì)產(chǎn)生一條錯(cuò)誤信息.?

在某些特定的程序中, 特別是在使用覆蓋技術(shù)的嵌入式系統(tǒng)中, 當(dāng)一個(gè)節(jié)被載入內(nèi)存時(shí),另外一個(gè)節(jié)?
就不會(huì)在內(nèi)存中. 任何在兩個(gè)節(jié)之間的直接引用都會(huì)是一個(gè)錯(cuò)誤. 比如, 如果節(jié)1中的代碼調(diào)用了另?
一個(gè)節(jié)中的一個(gè)函數(shù),這就會(huì)產(chǎn)生一個(gè)錯(cuò)誤.?

`NOCROSSREFS'命令帶有一個(gè)輸出節(jié)名字的列表. 如果'ld'遇到任何在這些節(jié)之間的交叉引用, 它就?
會(huì)報(bào)告一個(gè)錯(cuò)誤,并返回一個(gè)非零退出碼. 注意, `NOCROSSREFS'命令使用輸出節(jié)名,而不是輸入節(jié)名.?

`OUTPUT_ARCH(BFDARCH)'?
指定一個(gè)特定的輸出機(jī)器架構(gòu). 這個(gè)參數(shù)是BFD庫中使用的一個(gè)名字. 你可以通過使用帶有'-f'選項(xiàng)?
的'objdump'程序來查看一個(gè)目標(biāo)文件的架構(gòu).?

為符號(hào)賦值.?
===========================?

你可以在一個(gè)連接腳本中為一個(gè)符號(hào)賦一個(gè)值. 這會(huì)把一個(gè)符號(hào)定義為一個(gè)全局符號(hào).?

簡單的賦值.?
------------------?

你可以使用所有的C賦值符號(hào)為一個(gè)符號(hào)賦值.?

`SYMBOL = EXPRESSION ;'?
`SYMBOL += EXPRESSION ;'?
`SYMBOL -= EXPRESSION ;'?
`SYMBOL *= EXPRESSION ;'?
`SYMBOL /= EXPRESSION ;'?
`SYMBOL <<= EXPRESSION ;'?
`SYMBOL >>= EXPRESSION ;'?
`SYMBOL &= EXPRESSION ;'?
`SYMBOL |= EXPRESSION ;'?

第一個(gè)情況會(huì)把SYMBOL定義為值EXPRESSION. 其它情況下, SYMBOL必須是已經(jīng)定義了的, 而值會(huì)作出相應(yīng)的調(diào)?
整.?

特殊符號(hào)名'.'表示定位計(jì)數(shù)器. 你只可以在'SECTIONS'命令中使用它.?

EXPRESSION后面的分號(hào)是必須的.?

表達(dá)式下面會(huì)定義.?

你在寫表達(dá)式賦值的時(shí)候,可以把它們作為單獨(dú)的部分,也可以作為'SECTIONS'命令中的一個(gè)語句,或者作為?
'SECTIONS'命令中輸出節(jié)描述的一個(gè)部分.?

符號(hào)所在的節(jié)會(huì)被設(shè)置成表達(dá)式所在的節(jié).?

下面是一個(gè)關(guān)于在三處地方使用符號(hào)賦值的例子:?

floating_point = 0;?
SECTIONS?
{?
.text :?
{?
*(.text)?
_etext = .;?
}?
_bdata = (. + 3) & ~ 3;?
.data : { *(.data) }?
}?

在這個(gè)例子中, 符號(hào)`floating_point'被定義為零. 符號(hào)'-etext'會(huì)被定義為前面一個(gè)'.text'節(jié)尾部的地址.?
而符號(hào)'_bdata'會(huì)被定義為'.text'輸出節(jié)后面的一個(gè)向上對(duì)齊到4字節(jié)邊界的一個(gè)地址值.?

PROVIDE?
-------?

在某些情況下, 一個(gè)符號(hào)被引用到的時(shí)候只在連接腳本中定義,而不在任何一個(gè)被連接進(jìn)來的目標(biāo)文件中定?
義. 這種做法是比較明智的. 比如, 傳統(tǒng)的連接器定義了一個(gè)符號(hào)'etext'. 但是, ANSI C需要用戶能夠把?
'etext'作為一個(gè)函數(shù)使用而不會(huì)產(chǎn)生錯(cuò)誤. 'PROVIDE'關(guān)鍵字可以被用來定義一個(gè)符號(hào), 比如'etext', 這個(gè)?
定義只在它被引用到的時(shí)候有效,而在它被定義的時(shí)候無效.語法是 `PROVIDE(SYMBOL = EXPRESSION)'.?

下面是一個(gè)關(guān)于使用'PROVIDE'定義'etext'的例子:?

SECTIONS?
{?
.text :?
{?
*(.text)?
_etext = .;?
PROVIDE(etext = .);?
}?
}?

在這個(gè)例子中, 如果程序定義了一個(gè)'_etext'(帶有一個(gè)前導(dǎo)下劃線), 連接器會(huì)給出一個(gè)重定義錯(cuò)誤. 如果,?
程序定義了一個(gè)'etext'(不帶前導(dǎo)下劃線), 連接器會(huì)默認(rèn)使用程序中的定義. 如果程序引用了'etext'但不?
定義它, 連接器會(huì)使用連接腳本中的定義.?

SECTIONS命令?
================?

'SECTIONS'命令告訴連接器如何把輸入節(jié)映射到輸出節(jié), 并如何把輸出節(jié)放入到內(nèi)存中.?

'SECTIONS'命令的格式如下:?

SECTIONS?
{?
SECTIONS-COMMAND?
SECTIONS-COMMAND?
...?
}?

每一個(gè)SECTIONS-COMMAND可能是如下的一種:?

* 一個(gè)'ENTRY'命令.?

* 一個(gè)符號(hào)賦值.?

* 一個(gè)輸出節(jié)描述.?

* 一個(gè)重疊描述.?

'ENTRY'命令和符號(hào)賦值在'SECTIONS'命令中是允許的, 這是為了方便在這些命令中使用定位計(jì)數(shù)器. 這也可?
以讓連接腳本更容易理解, 因?yàn)槟憧梢栽诟幸饬x的地方使用這些命令來控制輸出文件的布局.?

輸出節(jié)描述和重疊描述在下面描述.?

如果你在連接腳本中不使用'SECTIONS'命令, 連接器會(huì)按在輸入文件中遇到的節(jié)的順序把每一個(gè)輸入節(jié)放到同?
名的輸出節(jié)中. 如果所有的輸入節(jié)都在第一個(gè)文件中存在,那輸出文件中的節(jié)的順序會(huì)匹配第一個(gè)輸入文件中?
的節(jié)的順序. 第一個(gè)節(jié)會(huì)在地址零處.?

輸出節(jié)描述?
--------------------------?

一個(gè)完整的輸出節(jié)的描述應(yīng)該是這個(gè)樣子的:?

SECTION [ADDRESS] [(TYPE)] : [AT(LMA)]?
{?
OUTPUT-SECTION-COMMAND?
OUTPUT-SECTION-COMMAND?
...?
} [>REGION] [AT>LMA_REGION] [:PHDR :PHDR ...] [=FILLEXP]?

大多數(shù)輸出節(jié)不使用這里的可選節(jié)屬性.?

SECTION邊上的空格是必須的, 所以節(jié)名是明確的. 冒號(hào)跟花括號(hào)也是必須的. 斷行和其他的空格是可選的.?

每一個(gè)OUTPUT-SECTION-COMMAND可能是如下的情況:?

* 一個(gè)符號(hào)賦值.?

* 一個(gè)輸入節(jié)描述.?

* 直接包含的數(shù)據(jù)值.?

* 一個(gè)特定的輸出節(jié)關(guān)鍵字.?

輸出節(jié)名.?
-------------------?

輸出節(jié)的名字是SECTION. SECTION必須滿足你的輸出格式的約束. 在一個(gè)只支持限制數(shù)量的節(jié)的格式中,比如?
'a.out',這個(gè)名字必須是格式支持的節(jié)名中的一個(gè)(比如, 'a.out'只允許'.text', '.data'或'.bss').如果?
輸出格式支持任意數(shù)量的節(jié), 但是只支持?jǐn)?shù)字,而沒有名字(就像Oasys中的情況), 名字應(yīng)當(dāng)以一個(gè)雙引號(hào)中的?
數(shù)值串的形式提供.一個(gè)節(jié)名可以由任意數(shù)量的字符組成,但是一個(gè)含有任意非常用字符(比如逗號(hào))的字句必須?
用雙引號(hào)引起來.?

輸出節(jié)描述?
--------------------------?

ADDRESS是關(guān)于輸出節(jié)中VMS的一個(gè)表達(dá)式. 如果你不提供ADDRESS, 連接器會(huì)基于REGION(如果存在)設(shè)置它,或?
者基于定位計(jì)數(shù)器的當(dāng)前值.?

如果你提供了ADDRESS, 那輸出節(jié)的地址會(huì)被精確地設(shè)為這個(gè)值. 如果你既不提供ADDRESS也不提供REGION, 那?
輸出節(jié)的地址會(huì)被設(shè)為當(dāng)前的定位計(jì)數(shù)器向上對(duì)齊到輸出節(jié)需要的對(duì)齊邊界的值. 輸出節(jié)的對(duì)齊要求是所有輸?
入節(jié)中含有的對(duì)齊要求中最嚴(yán)格的一個(gè).?

比如:?
.text . : { *(.text) }?

和?
.text : { *(.text) }?

有細(xì)微的不同. 第一個(gè)會(huì)把'.text'輸出節(jié)的地址設(shè)為當(dāng)前定位計(jì)數(shù)器的值. 第二個(gè)會(huì)把它設(shè)為定位計(jì)數(shù)器的?
當(dāng)前值向上對(duì)齊到'.text'輸入節(jié)中對(duì)齊要求最嚴(yán)格的一個(gè)邊界.?

ADDRESS可以是任意表達(dá)式; 比如,如果你需要把節(jié)對(duì)齊對(duì)0x10字節(jié)邊界,這樣就可以讓低四字節(jié)的節(jié)地址值為?
零, 你可以這樣做:?

.text ALIGN(0x10) : { *(.text) }?

這個(gè)語句可以正常工作,因?yàn)?#39;ALIGN'返回當(dāng)前的定位計(jì)數(shù)器,并向上對(duì)齊到指定的值.?

指定一個(gè)節(jié)的地址會(huì)改變定位計(jì)數(shù)器的值.?

輸入節(jié)描述?
-------------------------?

最常用的輸出節(jié)命令是輸入節(jié)描述.?

輸入節(jié)描述是最基本的連接腳本操作. 你使用輸出節(jié)來告訴連接器在內(nèi)存中如何布局你的程序. 你使用輸入節(jié)?
來告訴連接器如何把輸入文件映射到你的內(nèi)存中.?

輸入節(jié)基礎(chǔ)?
---------------------------?

一個(gè)輸入節(jié)描述由一個(gè)文件名后跟有可選的括號(hào)中的節(jié)名列表組成.?

文件名和節(jié)名可以通配符形式出現(xiàn), 這個(gè)我們以后再介紹.?

最常用的輸入節(jié)描述是包含在輸出節(jié)中的所有具有特定名字的輸入節(jié). 比如, 包含所有輸入'.text'節(jié),你可以?
這樣寫:?

*(.text)?

這里,'*'是一個(gè)通配符,匹配所有的文件名. 為把一部分文件排除在匹配的名字通配符之外, EXCLUDE_FILE可?
以用來匹配所有的除了在EXCLUDE_FILE列表中指定的文件.比如:?

(*(EXCLUDE_FILE (*crtend.o *otherfile.o) .ctors))?

會(huì)讓除了`crtend.o'文件和`otherfile.o'文件之外的所有的文件中的所有的.ctors節(jié)被包含進(jìn)來.?

有兩種方法包含多于一個(gè)的節(jié):?

*(.text .rdata)?
*(.text) *(.rdata)?

上面兩句的區(qū)別在于'.text'和'.rdata'輸入節(jié)的輸出節(jié)中出現(xiàn)的順序不同. 在第一個(gè)例子中, 兩種節(jié)會(huì)交替?
出現(xiàn),并以連接器的輸入順序排布. 在第二個(gè)例子中,所有的'.text'輸入節(jié)會(huì)先出現(xiàn),然后是所有的'.rdata'節(jié).?

你可以指定文件名,以從一個(gè)特定的文件中包含節(jié). 如果一個(gè)或多個(gè)你的文件含有特殊的數(shù)據(jù)在內(nèi)存中需要特?
殊的定位,你可以這樣做. 比如:?

data.o(.data)?

如果你使用一個(gè)不帶有節(jié)列表的文件名, 那輸入文件中的所有的節(jié)會(huì)被包含到輸出節(jié)中. 通常不會(huì)這樣做, 但?
是在某些場合下這個(gè)可能非常有用. 比如:?

data.o?

當(dāng)你使用一個(gè)不含有任何通配符的文件名時(shí), 連接器首先會(huì)查看你是否在連接命令行上指定了文件名或者在?
'INPUT'命令中. 如果你沒有, 連接器會(huì)試圖把這個(gè)文件作為一個(gè)輸入文件打開, 就像它在命令行上出現(xiàn)一樣.?
注意這跟'INPUT'命令不一樣, 因?yàn)檫B接器會(huì)在檔案搜索路徑中搜索文件.?

輸入節(jié)通配符?
---------------------------------?

在一個(gè)輸入節(jié)描述中, 文件名或者節(jié)名,或者兩者同時(shí)都可以是通配符形式.?

文件名通配符'*'在很多例子中都可以看到,這是一個(gè)簡單的文件名通配符形式.?

通配符形式跟Unix Shell中使用的一樣.?

`*'?
匹配任意數(shù)量的字符.?

`?'?
匹配單個(gè)字符.?

`[CHARS]'?
匹配CHARS中的任意單個(gè)字符; 字符'-'可以被用來指定字符的方訌, 比如[a-z]匹配任意小字字符.?

`\'?
轉(zhuǎn)義其后的字符.?

當(dāng)一個(gè)文件名跟一個(gè)通配符匹配時(shí), 通配符字符不會(huì)匹配一個(gè)'/'字符(在UNIX系統(tǒng)中用來分隔目錄名), 一個(gè)?
含有單個(gè)'*'字符的形式是個(gè)例外; 它總是匹配任意文件名, 不管它是否含有'/'. 在一個(gè)節(jié)名中, 通配符字?
符會(huì)匹配'/'字符.?

文件名通配符只匹配那些在命令行或在'INPUT'命令上顯式指定的文件. 連接器不會(huì)通過搜索目錄來展開通配?
符.?

如果一個(gè)文件名匹配多于一個(gè)通配符, 或者如果一個(gè)文件名顯式出現(xiàn)同時(shí)又匹配了一個(gè)通配符, 連接器會(huì)使用?
第一次匹配到的連接腳本. 比如, 下面的輸入節(jié)描述序列很可能就是錯(cuò)誤的,因?yàn)?#39;data.o'規(guī)則沒有被使用:?

.data : { *(.data) }?
.data1 : { data.o(.data) }?

通常, 連接器會(huì)把匹配通配符的文件和節(jié)按在連接中被看到的順序放置. 你可以通過'SORT'關(guān)鍵字改變它, 它?
出現(xiàn)在括號(hào)中的通配符之前(比如, 'SORT(.text*)'). 當(dāng)'SORT'關(guān)鍵字被使用時(shí), 連接器會(huì)在把文件和節(jié)放到?
輸出文件中之前按名字順序重新排列它們.?

如果你對(duì)于輸入節(jié)被放置到哪里去了感到很困惑, 那可以使用'-M'連接選項(xiàng)來產(chǎn)生一個(gè)位圖文件. 位圖文件會(huì)?
精確顯示輸入節(jié)是如何被映射到輸出節(jié)中的.?

這個(gè)例子顯示了通配符是如何被用來區(qū)分文件的. 這個(gè)連接腳本指示連接器把所有的'.text'節(jié)放到'.text'中, 把所有的'.bss'節(jié)放到'.bss'. 連接器會(huì)把所有的來自文件名以一個(gè)大寫字母開始的文件中的'.data'節(jié)放進(jìn)'.DATA'節(jié)中; 對(duì)于所有其他文件, 連接器會(huì)把'.data'節(jié)放進(jìn)'.data'節(jié)中.?

SECTIONS {?
.text : { *(.text) }?
.DATA : { [A-Z]*(.data) }?
.data : { *(.data) }?
.bss : { *(.bss) }?
}?

輸入節(jié)中的普通符號(hào).?
-----------------------------------?

對(duì)于普通符號(hào),需要一個(gè)特殊的標(biāo)識(shí), 因?yàn)樵诤芏嗄繕?biāo)格式中, 普通符號(hào)沒有一個(gè)特定的輸入節(jié). 連接器會(huì)把?
普通符號(hào)處理成好像它們?cè)谝粋€(gè)叫做'COMMON'的節(jié)中.?

你可能像使用帶有其他輸入節(jié)的文件名一樣使用帶有'COMMON'節(jié)的文件名。你可以通過這個(gè)把來自一個(gè)特定輸?
入文件的普通符號(hào)放入一個(gè)節(jié)中,同時(shí)把來自其它輸入文件的普通符號(hào)放入另一個(gè)節(jié)中。?

在大多數(shù)情況下,輸入文件中的普通符號(hào)會(huì)被放到輸出文件的'.bss'節(jié)中。比如:?

.bss { *(.bss) *(COMMON) }?

有些目標(biāo)文件格式具有多于一個(gè)的普通符號(hào)。比如,MIPS ELF目標(biāo)文件格式區(qū)分標(biāo)準(zhǔn)普通符號(hào)和小普通符號(hào)。?
在這種情況下,連接器會(huì)為其他類型的普通符號(hào)使用一個(gè)不同的特殊節(jié)名。 在MIPS ELF的情況中, 連接器?
為標(biāo)準(zhǔn)普通符號(hào)使用'COMMON',并且為小普通符號(hào)使用'.common'。這就允許你把不同類型的普通符號(hào)映射到?
內(nèi)存的不同位置。?

在一些老的連接腳本上,你有時(shí)會(huì)看到'[COMMON]'。這個(gè)符號(hào)現(xiàn)在已經(jīng)過時(shí)了, 它等效于'*(COMMON)'。?

輸入節(jié)和垃圾收集?
---------------------------------------?

當(dāng)連接時(shí)垃圾收集正在使用中時(shí)('--gc-sections'),這在標(biāo)識(shí)那些不應(yīng)該被排除在外的節(jié)時(shí)非常有用。這?
是通過在輸入節(jié)的通配符入口外面加上'KEEP()'實(shí)現(xiàn)的,比如'KEEP(*(.init))'或者'KEEP(SORT(*)(.sorts))?
'。?

輸入節(jié)示例?
---------------------?

接下來的例子是一個(gè)完整的連接腳本。它告訴連接器去讀取文件'all.o'中的所有節(jié),并把它們放到輸出節(jié)?
'outputa'的開始位置處, 該輸出節(jié)是從位置'0x10000'處開始的。 從文件'foo.o'中來的所有節(jié)'.input1'?
在同一個(gè)輸出節(jié)中緊密排列。 從文件'foo.o'中來的所有節(jié)'.input2'全部放入到輸出節(jié)'outputb'中,后面?
跟上從'foo1.o'中來的節(jié)'.input1'。來自所有文件的所有余下的'.input1'和'.input2'節(jié)被寫入到輸出節(jié)?
'outputc'中。?

SECTIONS {?
outputa 0x10000 :?
{?
all.o?
foo.o (.input1)?
}?
outputb :?
{?
foo.o (.input2)?
foo1.o (.input1)?
}?
outputc :?
{?
*(.input1)?
*(.input2)?
}?
}?

輸出節(jié)數(shù)據(jù)?
-------------------?

你可以通過使用輸出節(jié)命令'BYTE','SHORT','LONG','QUAD',或者'SQUAD'在輸出節(jié)中顯式包含幾個(gè)字節(jié)的數(shù)據(jù)?
每一個(gè)關(guān)鍵字后面都跟上一個(gè)圓括號(hào)中的要存入的值。表達(dá)式的值被存在當(dāng)前的定位計(jì)數(shù)器的值處。?

‘BYTE’,‘SHORT’,‘LONG’‘QUAD’命令分別存儲(chǔ)一個(gè),兩個(gè),四個(gè),八個(gè)字節(jié)。存入字節(jié)后,定位計(jì)?
數(shù)器的值加上被存入的字節(jié)數(shù)。?

比如,下面的命令會(huì)存入一字節(jié)的內(nèi)容1,后面跟上四字節(jié),其內(nèi)容是符號(hào)'addr'的值。?

BYTE(1)?
LONG(addr)?

當(dāng)使用64位系統(tǒng)時(shí),‘QUAD’和‘SQUAD’是相同的;它們都會(huì)存儲(chǔ)8字節(jié),或者說是64位的值。而如果軟硬件?
系統(tǒng)都是32位的,一個(gè)表達(dá)式就會(huì)被作為32位計(jì)算。在這種情況下,‘QUAD’存儲(chǔ)一個(gè)32位值,并把它零擴(kuò)展?
到64位, 而‘SQUAD’會(huì)把32位值符號(hào)擴(kuò)展到64位。?

如果輸出文件的目標(biāo)文件格式有一個(gè)顯式的endianness,它在正常的情況下,值就會(huì)被以這種endianness存儲(chǔ)?
當(dāng)一個(gè)目標(biāo)文件格式?jīng)]有一個(gè)顯式的endianness時(shí), 值就會(huì)被以第一個(gè)輸入目標(biāo)文件的endianness存儲(chǔ)。?

注意, 這些命令只在一個(gè)節(jié)描述內(nèi)部才有效,而不是在它們之間, 所以,下面的代碼會(huì)使連接器產(chǎn)生一個(gè)錯(cuò)?
誤信息:?

SECTIONS { .text : { *(.text) } LONG(1) .data : { *(.data) } }?

而這個(gè)才是有效的:?

SECTIONS { .text : { *(.text) ; LONG(1) } .data : { *(.data) } }?

你可能使用‘FILL’命令來為當(dāng)前節(jié)設(shè)置填充樣式。它后面跟有一個(gè)括號(hào)中的表達(dá)式。任何未指定的節(jié)內(nèi)內(nèi)存?
區(qū)域(比如,因?yàn)檩斎牍?jié)的對(duì)齊要求而造成的裂縫)會(huì)以這個(gè)表達(dá)式的值進(jìn)行填充。一個(gè)'FILL'語句會(huì)覆蓋到?
它本身在節(jié)定義中出現(xiàn)的位置后面的所有內(nèi)存區(qū)域;通過引入多個(gè)‘FILL’語句,你可以在輸出節(jié)的不同位置?
擁有不同的填充樣式。?

這個(gè)例子顯示如何在未被指定的內(nèi)存區(qū)域填充'0x90':?

FILL(0x90909090)?

‘FILL’命令跟輸出節(jié)的‘=FILLEXP’屬性相似,但它只影響到節(jié)內(nèi)跟在‘FILL’命令后面的部分,而不是?
整個(gè)節(jié)。如果兩個(gè)都用到了,那‘FILL’命令優(yōu)先。?

輸出節(jié)關(guān)鍵字?
-----------------------?

有兩個(gè)關(guān)鍵字作為輸出節(jié)命令的形式出現(xiàn)。?

`CREATE_OBJECT_SYMBOLS'?
這個(gè)命令告訴連接器為每一個(gè)輸入文件創(chuàng)建一個(gè)符號(hào)。而符號(hào)的名字正好就是相關(guān)輸入文件的名字。?
而每一個(gè)符號(hào)的節(jié)就是`CREATE_OBJECT_SYMBOLS'命令出現(xiàn)的那個(gè)節(jié)。?

這個(gè)命令一直是a.out目標(biāo)文件格式特有的。 它一般不為其它的目標(biāo)文件格式所使用。?

`CONSTRUCTORS'?
當(dāng)使用a.out目標(biāo)文件格式進(jìn)行連接的時(shí)候, 連接器使用一組不常用的結(jié)構(gòu)以支持C++的全局構(gòu)造函?
數(shù)和析構(gòu)函數(shù)。當(dāng)連接不支持專有節(jié)的目標(biāo)文件格式時(shí), 比如ECOFF和XCOFF,連接器會(huì)自動(dòng)辯識(shí)C++?
全局構(gòu)造函數(shù)和析構(gòu)函數(shù)的名字。對(duì)于這些目標(biāo)文件格式,‘CONSTRUCTORS’命令告訴連接器把構(gòu)造?
函數(shù)信息放到‘CONSTRUCTORS’命令出現(xiàn)的那個(gè)輸出節(jié)中。對(duì)于其它目標(biāo)文件格式,‘CONSTRUCTORS’?
命令被忽略。?

符號(hào)`__CTOR_LIST__'標(biāo)識(shí)全局構(gòu)造函數(shù)的開始,而符號(hào)`__DTOR_LIST'標(biāo)識(shí)結(jié)束。這個(gè)列表的第一個(gè)?
WORD是入口的數(shù)量,緊跟在后面的是每一個(gè)構(gòu)造函數(shù)和析構(gòu)函數(shù)的地址,再然后是一個(gè)零WORD。編譯?
器必須安排如何實(shí)際運(yùn)行代碼。對(duì)于這些目標(biāo)文件格式,GNU C++通常從一個(gè)`__main'子程序中調(diào)用?
構(gòu)造函數(shù),而對(duì)`__main'的調(diào)用自動(dòng)被插入到`main'的啟動(dòng)代碼中。GNU C++通常使用'atexit'運(yùn)行?
析構(gòu)函數(shù),或者直接從函數(shù)'exit'中運(yùn)行。?

對(duì)于像‘COFF’或‘ELF’這樣支持專有節(jié)名的目標(biāo)文件格式,GNU C++通常會(huì)把全局構(gòu)造函數(shù)與析構(gòu)?
函數(shù)的地址值放到'.ctors'和'.dtors'節(jié)中。把下面的代碼序列放到你的連接腳本中去,這樣會(huì)構(gòu)建?
出GNU C++運(yùn)行時(shí)代碼希望見到的表類型。?

__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__ = .;?

如果你正使用GNU C++支持來進(jìn)行優(yōu)先初始化,那它提供一些可以控制全局構(gòu)造函數(shù)運(yùn)行順序的功能,?
你必須在連接時(shí)給構(gòu)造函數(shù)排好序以保證它們以正確的順序被執(zhí)行。當(dāng)使用'CONSTRUCTORS'命令時(shí),?
替代為`SORT(CONSTRUCTORS)'。當(dāng)使用'.ctors'和'dtors'節(jié)時(shí),使用`*(SORT(.ctors))'和?
`*(SORT(.dtors))' 而不是`*(.ctors)'和`*(.dtors)'。?

通常,編譯器和連接器會(huì)自動(dòng)處理這些事情,并且你不必親自關(guān)心這些事情。但是,當(dāng)你正在使用?
C++,并自己編寫連接腳本時(shí),你可能就要考慮這些事情了。?

輸出節(jié)的丟棄。?
-------------------------?

連接器不會(huì)創(chuàng)建那些不含有任何內(nèi)容的輸出節(jié)。這是為了引用那些可能出現(xiàn)或不出現(xiàn)在任何輸入文件中的輸入?
節(jié)時(shí)方便。比如:?

.foo { *(.foo) }?

如果至少在一個(gè)輸入文件中有'.foo'節(jié),它才會(huì)在輸出文件中創(chuàng)建一個(gè)'.foo'節(jié)?

如果你使用了其它的而不是一個(gè)輸入節(jié)描述作為一個(gè)輸出節(jié)命令,比如一個(gè)符號(hào)賦值,那這個(gè)輸出節(jié)總是被?
創(chuàng)建,即使沒有匹配的輸入節(jié)也會(huì)被創(chuàng)建。?

一個(gè)特殊的輸出節(jié)名`/DISCARD/'可以被用來丟棄輸入節(jié)。任何被分配到名為`/DISCARD/'的輸出節(jié)中的輸入?
節(jié)不包含在輸出文件中。?

輸出節(jié)屬性?
-------------------------?

上面,我們已經(jīng)展示了一個(gè)完整的輸出節(jié)描述,看下去就象這樣:?

SECTION [ADDRESS] [(TYPE)] : [AT(LMA)]?
{?
OUTPUT-SECTION-COMMAND?
OUTPUT-SECTION-COMMAND?
...?
} [>REGION] [AT>LMA_REGION] [:PHDR :PHDR ...] [=FILLEXP]?

我們已經(jīng)介紹了SECTION, ADDRESS, 和OUTPUT-SECTION-COMMAND. 在這一節(jié)中,我們將介紹余下的節(jié)屬性。?

輸出節(jié)類型?
...................?

每一個(gè)輸出節(jié)可以有一個(gè)類型。類型是一個(gè)放在括號(hào)中的關(guān)鍵字,已定義的類型如下所示:?

`NOLOAD'?
這個(gè)節(jié)應(yīng)當(dāng)被標(biāo)式詎不可載入,所以當(dāng)程序運(yùn)行時(shí),它不會(huì)被載入到內(nèi)存中。?

`DSECT'?
`COPY'?
`INFO'?
`OVERLAY'?
支持這些類型名只是為了向下兼容,它們很少使用。它們都具有相同的效果:這個(gè)節(jié)應(yīng)當(dāng)被標(biāo)式詎不?
可分配,所以當(dāng)程序運(yùn)行時(shí),沒有內(nèi)存為這個(gè)節(jié)分配。?

連接器通常基于映射到輸出節(jié)的輸入節(jié)來設(shè)置輸出節(jié)的屬性。你可以通過使用節(jié)類型來重設(shè)這個(gè)屬性,?
比如,在下面的腳本例子中,‘ROM’節(jié)被定址在內(nèi)存地址零處,并且在程序運(yùn)行時(shí)不需要被載入。?
‘ROM’節(jié)的內(nèi)容會(huì)正常出現(xiàn)在連接輸出文件中。?

SECTIONS {?
ROM 0 (NOLOAD) : { ... }?
...?
}?

輸出節(jié)LMA?
..................?

每一個(gè)節(jié)有一個(gè)虛地址(VMA)和一個(gè)載入地址(LMA);出現(xiàn)在輸出節(jié)描述中的地址表達(dá)式設(shè)置VMS?

連接器通常把LMA跟VMA設(shè)成相等。你可以通過使用‘AT’關(guān)鍵字改變這個(gè)。跟在關(guān)鍵字‘AT’后面的表達(dá)式?
LMA指定節(jié)的載入地址。或者,通過`AT>LMA_REGION'表達(dá)式, 你可以為節(jié)的載入地址指定一個(gè)內(nèi)存區(qū)域。?

這個(gè)特性是為了便于建立ROM映像而設(shè)計(jì)的。比如,下面的連接腳本創(chuàng)建了三個(gè)輸出節(jié):一個(gè)叫做‘.text’?
從地址‘0x1000’處開始,一個(gè)叫‘.mdata’,盡管它的VMA是'0x2000',它會(huì)被載入到'.text'節(jié)的后面,最?
后一個(gè)叫做‘.bss’是用來放置未初始化的數(shù)據(jù)的,其地址從'0x3000'處開始。符號(hào)'_data'被定義為值?
'0x2000', 它表示定位計(jì)數(shù)器的值是VMA的值,而不是LMA。?

SECTIONS?
{?
.text 0x1000 : { *(.text) _etext = . ; }?
.mdata 0x2000 :?
AT ( ADDR (.text) + SIZEOF (.text) )?
{ _data = . ; *(.data); _edata = . ; }?
.bss 0x3000 :?
{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;}?
}?

這個(gè)連接腳本產(chǎn)生的程序使用的運(yùn)行時(shí)初始化代碼會(huì)包含象下面所示的一些東西,以把初始化后的數(shù)據(jù)從ROM?
映像中拷貝到它的運(yùn)行時(shí)地址中去。注意這節(jié)代碼是如何利用好連接腳本定義的符號(hào)的。?

extern char _etext, _data, _edata, _bstart, _bend;?
char *src = &_etext;?
char *dst = &_data;?

/* ROM has data at end of text; copy it. */?
while (dst < &_edata) {?
*dst++ = *src++;?
}?

/* Zero bss */?
for (dst = &_bstart; dst< &_bend; dst++)?
*dst = 0;?

輸出節(jié)區(qū)域?
.....................?

你可以通過使用`>REGION'把一個(gè)節(jié)賦給前面已經(jīng)定義的一個(gè)內(nèi)存區(qū)域。?

這里有一個(gè)簡單的例子:?

MEMORY { rom : ORIGIN = 0x1000, LENGTH = 0x1000 }?
SECTIONS { ROM : { *(.text) } >rom }?

輸出節(jié)Phdr?
... ?

轉(zhuǎn)載于:https://www.cnblogs.com/coolYuan/p/8653078.html

總結(jié)

以上是生活随笔為你收集整理的make的使用和Makefile规则和编程及其基本命令(简单)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。