Linux鏈結指令碼學習 lds 轉)

2022-06-21 08:30:12 字數 4223 閱讀 5921

一、概論

ld:

gnu的鏈結器.

用來把一定量的目標檔案跟檔案檔案鏈結在一起,並重新定位它們的資料,鏈結符號引用.

一般編譯乙個程式時,最後一步就是執行ld進行鏈結

每乙個鏈結都被乙個鏈結指令碼所控制,這個指令碼是用鏈結命令語言書寫的.

二、鏈結指令碼

鏈結指令碼的乙個主要目的是描述輸入檔案中的各個段(資料段,**段,堆,棧,bss)如何被對映到輸出檔案中,並控制輸出檔案的記憶體排布.

鏈結器總是使用鏈結指令碼的,如果你不提供,則鏈結器會使用乙個預設的指令碼,這個指令碼是被編譯進鏈結器可執行檔案的.

可以使用--verbose命令列顯示預設的鏈結器指令碼的內容.

你可以使用-t命令列來提供你自己的鏈結指令碼來替換預設的鏈結指令碼.

三、簡單的鏈結指令碼示例.

許多指令碼是相當簡單的.

可能最簡單的指令碼只含有乙個命令:』sections』.

你可以使用』sections』來描述輸出檔案的記憶體布局.

『sections』是乙個功能很強大的命令.

假設你的程式只有**段,初始化過的資料段,和未初始化過的資料段.這些會存在於』.text』,』data』,』bss』段中.

對於這個例子,假設**應該被載入到位址0x1000處,而資料應該從0x8000000開始,如下是實現這個功能的指令碼:

sections

.=0x8000000;

.data:

.bss:

}具體分析:

關鍵字』sections』開始於這個配置.後面跟有一串放在花括號中的符號賦值和輸出端描述的內容.

第一行是對乙個特殊的符號』.』賦值,這是乙個定位標識器.如果你沒有以其他的方式制定輸出段的位址,那位址值就會被設為定位標識器的現有值,即0x1000.

第二行定義乙個輸出段,』.text』.冒號』:』是語法需要,現在可以被忽略.段後面的花括號中,應該列出所有應該放入這個輸出段中的輸入端的名字.』*』是萬用字元,匹配所有檔名.即將所有輸入檔案中的.text段都儲存在此段中.

餘下的是.data和.bss段,同理,鏈結器會把所有.data段從位址0x8000000開始處放置.

最後,定位標識器的值變為0x8000000加上所有.data段的位址.此時鏈結器把所有.bss放在此處開始的位址.

四、簡單的鏈結指令碼命令

設定入口點

在執行乙個程式時,第乙個被執行到的指令成為」入口點」.你可以使用」entry」鏈結指令碼命令來設定入口點.引數是乙個符號名,如下:

entry(symbol)

有很多不同的方法來設定入口點.鏈結器會通過按順序嘗試一下方法來設定入口點,如果成功了,就會停止.

1,』-e』 入口命令列選項

2,鏈結指令碼中的entry(symbol)命令

3,如果定義了start,就使用start的值

4,如果存在就使用』.text』段的首位址

5,位址』0』

五、命令列設定鏈結位址

ld用於將多個obj或者so(庫)檔案鏈結成可執行檔案.

使用-t選項可以指定資料段,**段,bss段起始位置.(-t只用於鏈結bootloader、核心等沒有底層軟體支援的軟體.鏈結執行於作業系統之上的應用程式時,一般使用預設方式鏈結).

1,直接指定**段、資料段、bss段起始位址

如下:-ttext startaddr

-tdata startaddr

-tbss  startaddr

例如:ld –ttext 0x00000000 –g led_on.o –o led_on_elf

ld –ttimer.lds –o timer_elf a.o b.o

鏈結指令碼timer.lds內容如下:

sections

.rodata align(4) :

.data align(4) :

.bss align(4) :

}乙個sections命令內部包含乙個或多個段,段(section)是連線指令碼的基本單元,它表示輸入檔案中的某部分怎麼放置.

**:

一、概論

ld:

gnu的鏈結器.

用來把一定量的目標檔案跟檔案檔案鏈結在一起,並重新定位它們的資料,鏈結符號引用.

一般編譯乙個程式時,最後一步就是執行ld進行鏈結

每乙個鏈結都被乙個鏈結指令碼所控制,這個指令碼是用鏈結命令語言書寫的.

二、鏈結指令碼

鏈結指令碼的乙個主要目的是描述輸入檔案中的各個段(資料段,**段,堆,棧,bss)如何被對映到輸出檔案中,並控制輸出檔案的記憶體排布.

鏈結器總是使用鏈結指令碼的,如果你不提供,則鏈結器會使用乙個預設的指令碼,這個指令碼是被編譯進鏈結器可執行檔案的.

可以使用--verbose命令列顯示預設的鏈結器指令碼的內容.

你可以使用-t命令列來提供你自己的鏈結指令碼來替換預設的鏈結指令碼.

三、簡單的鏈結指令碼示例.

許多指令碼是相當簡單的.

可能最簡單的指令碼只含有乙個命令:』sections』.

你可以使用』sections』來描述輸出檔案的記憶體布局.

『sections』是乙個功能很強大的命令.

假設你的程式只有**段,初始化過的資料段,和未初始化過的資料段.這些會存在於』.text』,』data』,』bss』段中.

對於這個例子,假設**應該被載入到位址0x1000處,而資料應該從0x8000000開始,如下是實現這個功能的指令碼:

sections

.=0x8000000;

.data:

.bss:

}具體分析:

關鍵字』sections』開始於這個配置.後面跟有一串放在花括號中的符號賦值和輸出端描述的內容.

第一行是對乙個特殊的符號』.』賦值,這是乙個定位標識器.如果你沒有以其他的方式制定輸出段的位址,那位址值就會被設為定位標識器的現有值,即0x1000.

第二行定義乙個輸出段,』.text』.冒號』:』是語法需要,現在可以被忽略.段後面的花括號中,應該列出所有應該放入這個輸出段中的輸入端的名字.』*』是萬用字元,匹配所有檔名.即將所有輸入檔案中的.text段都儲存在此段中.

餘下的是.data和.bss段,同理,鏈結器會把所有.data段從位址0x8000000開始處放置.

最後,定位標識器的值變為0x8000000加上所有.data段的位址.此時鏈結器把所有.bss放在此處開始的位址.

四、簡單的鏈結指令碼命令

設定入口點

在執行乙個程式時,第乙個被執行到的指令成為」入口點」.你可以使用」entry」鏈結指令碼命令來設定入口點.引數是乙個符號名,如下:

entry(symbol)

有很多不同的方法來設定入口點.鏈結器會通過按順序嘗試一下方法來設定入口點,如果成功了,就會停止.

1,』-e』 入口命令列選項

2,鏈結指令碼中的entry(symbol)命令

3,如果定義了start,就使用start的值

4,如果存在就使用』.text』段的首位址

5,位址』0』

五、命令列設定鏈結位址

ld用於將多個obj或者so(庫)檔案鏈結成可執行檔案.

使用-t選項可以指定資料段,**段,bss段起始位置.(-t只用於鏈結bootloader、核心等沒有底層軟體支援的軟體.鏈結執行於作業系統之上的應用程式時,一般使用預設方式鏈結).

1,直接指定**段、資料段、bss段起始位址

如下:-ttext startaddr

-tdata startaddr

-tbss  startaddr

例如:ld –ttext 0x00000000 –g led_on.o –o led_on_elf

ld –ttimer.lds –o timer_elf a.o b.o

鏈結指令碼timer.lds內容如下:

sections

.rodata align(4) :

.data align(4) :

.bss align(4) :

}乙個sections命令內部包含乙個或多個段,段(section)是連線指令碼的基本單元,它表示輸入檔案中的某部分怎麼放置.

**:

Linux鏈結指令碼學習 lds

l一 概論 ld gnu的鏈結器.用來把一定量的目標檔案跟檔案檔案鏈結在一起,並重新定位它們的資料,鏈結符號引用.一般編譯乙個程式時,最後一步就是執行ld進行鏈結 每乙個鏈結都被乙個鏈結指令碼所控制,這個指令碼是用鏈結命令語言書寫的.二 鏈結指令碼 鏈結指令碼的乙個主要目的是描述輸入檔案中的各個段 ...

Linux下的lds鏈結指令碼簡介(四)

十一 表示式 lds中表示式的文法與c語言的表示式文法一致,表示式的值都是整型,如果ld的執行主機和生成檔案的目標機都是32位,則表示式是32位資料,否則是64位資料。以下是一些常用的表示式 fourk 1 4k k m單位 fourk 2 4096 整數 fourk 3 0 1000 16 進製 ...

Linux下的lds鏈結指令碼簡介(四)

linux下的lds鏈結指令碼簡介 四 小狼 十一 表示式 lds中表示式的文法與c語言的表示式文法一致,表示式的值都是整型,如果ld的執行主機和生成檔案的目標機都是32位,則表示式是32位資料,否則是64位資料。以下是一些常用的表示式 fourk 1 4k k m單位 fourk 2 4096 整...