LLD-LLVM鏈接器


LLD-LLVM鏈接器

LLD是LLVM項目中的鏈接器,是系統鏈接器的直接替代,並且運行速度比它們快得多。它還提供了對工具鏈開發人員有用的功能。

鏈接器按完整性降序支持ELF(Unix),PE / COFF(Windows),Mach-O(macOS)和WebAssembly。在內部,LLD由幾個不同的鏈接器組成。ELF端口是本文檔中將要描述的端口。PE / COFF端口已完成,包括Windows調試信息(PDB)支持。WebAssembly端口仍在開發中(請參閱WebAssembly lld port)。Mach-O端口是基於與其他端口不同的體系結構構建的。有關Mach-O的詳細信息,請閱讀ATOM-based lld

特征功能

  • LLD是GNU鏈接器的直接替代,它接受與GNU相同的命令行參數和鏈接器腳本。

目前正在與FreeBSD項目緊密合作,以使LLD在操作系統的未來版本中成為默認系統鏈接器,因此非常重視解決兼容性問題。LLD能夠鏈接包括內核在內的整個FreeBSD / amd64基本系統。使用一些正在進行的補丁程序,它可以鏈接AMD64上大約95%的端口集合。有關詳細信息,請參見FreeBSD quarterly status report

  • LLD非常快。在多核計算機上鏈接大型程序時,可以預期LLD的運行速度是GNU gold鏈接器的兩倍以上。但是,里程可能會有所不同。
  • 它支持各種CPU / ABI,包括AArch64,AMDGPU,ARM,Hexagon,MIPS 32/64大/小端,PowerPC,PowerPC64,RISC-V,SPARC V9,x86-32和x86-64。其中,AArch64,ARM(> = v6),PowerPC,PowerPC64,x86-32和x86-64具有生產質量。MIPS似乎也不錯。
  • 它始終是交叉鏈接器,這意味着無論它是如何構建的,它始終支持上述所有目標。實際上,沒有提供構建時選項來啟用/禁用每個目標。鏈接器輕松用作交叉編譯工具鏈的一部分很容易。
  • 可以將LLD嵌入程序中,以消除對外部鏈接程序的依賴。要做的就是構造目標文件和命令行參數,就像調用外部鏈接器然后lld::elf::link從代碼中調用鏈接器的主要功能一樣 。
  • 正在使用LLVM libObject庫從目標文件讀取數據,因此這並不是一個完全公平的比較,LLD / ELF僅包含2萬1千行C ++代碼,而GNU gold由19.8萬行C ++代碼構成。
  • 默認情況下支持鏈接時間優化(LTO)。本質上,要做LTO所需要做的就是將-flto選項傳遞給clang。然后clang創建的對象文件不是本機目標文件格式,而是LLVM位碼格式。LLD讀取位碼目標文件,使用LLVM對其進行編譯並發出輸出文件。因為以這種方式LLD可以看到整個程序,所以它可以對整個程序進行優化。
  • 古老的Unix系統(90年代以前甚至更早)的一些非常古老的功能已被刪除。一些默認設置已進行了調整。例如,默認情況下,將堆棧標記為不可執行以加強安全性。

性能

這是在2插槽20核40線程Xeon E5-2680 2.80 GHz帶有SSD驅動器的計算機上的鏈接時間比較。在有或沒有多線程支持的情況下都發揮了作用。為了禁用多線程,添加-no-threads了命令行。

 

如表所見,lld的速度明顯快於GNU鏈接器。請注意,這只是環境的基准結果。根據可用核心數,可用內存量或磁盤延遲/吞吐量,結果可能會有所不同。

由於GNU ld不支持-icf=all and -gdb-index選項,因此從GNU ld的命令行中刪除了。如果擁有這些選項,GNU ld將會比這慢。

構建

如果已經使用SVN檢出了LLVM,則可以在tools中像clang一樣檢出目錄下的LLD 。有關詳細信息,請參閱Getting Started with the LLVM System

如果尚未簽出LLVM,構建LLD的最簡單方法是,從git鏡像簽出整個LLVM項目/子項目並構建該樹。需要cmake,當然也需要C ++編譯器。

$ git clone https://github.com/llvm/llvm-project llvm-project

$ mkdir build

$ cd build

$ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=lld -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-project/llvm

$ make install

使用LLD 

LLD安裝為ld.lld。在Unix上,鏈接器由編譯器驅動程序調用,因此不希望直接使用該命令。編譯器驅動程序有幾種方法可以使用ld.lld而不是默認鏈接器。

最簡單的方法是覆蓋默認鏈接器。將LLD安裝到磁盤上的某個位置后,可以通過創建符號鏈接來將-s /path/to/ld.lld /usr/bin/ld so that /usr/bin/ld is resolved to LLD其解析為LLD。

如果不想更改系統設置,則可以使用clang的 -fuse-ld選項。這樣,-fuse-ld=lld在構建程序時要設置為LDFLAGS。

LLD將其名稱和版本號留.comment在輸出中的某個部分。如果不確定是否成功使用LLD,運行並檢查輸出。如果輸出中包含字符串“ Linker:LLD”,則說明正在使用LLD。readelf --string-dump .comment <output-file>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM