使用 LLVM 工具將二進制數據嵌入到執行檔中
過去,我首先
.o
使用 GNU 連結器將資源文件(圖像)轉換為文件,從而將資源文件(圖像)嵌入到程序中。例如:ld -r -b binary -o file.o file.svg
從 FreeBSD 12 開始,預設連結器已從 GNU 更改為 LLVM。儘管連結器似乎理解命令行選項,但它會導致錯誤。例如:
ld -r -b binary -o file.o file.svg ld: error: target emulation unknown: -m or at least one .o file required
還嘗試使用ld.lld(1)手冊頁中的命令行選項:
ld --relocatable --format=binary -o file.o file.svg ld: error: target emulation unknown: -m or at least one .o file required
我使用了正確的工具嗎?我需要為
-m
選項指定一個值嗎?
看來您需要添加
-z noexecstack
(這也是在LLD 7.0.0中為 ELF 二進製文件添加的)。預設設置是有一個可執行的堆棧區域,該區域易受堆棧記憶體的利用。您的二進制映像沒有可執行堆棧,我相信這就是它失敗的原因。該錯誤會讓你失望,因為它要求你告訴你的堆棧使用什麼目標仿真(你沒有)。David Herrmann做了所有艱苦的工作,並找到了一個跨平台的解決方案,其中包括:
- GNU-ld
- GNU-黃金
- GNU-libtool
- 使用交叉編譯
- 使用 LLVM
- 不需要任何外部非標準工具
魔術呼叫是:
$(LD) -r -o "src/mydata.bin.o" -z noexecstack --format=binary "src/mydata.bin"
大多數情況下,您希望該二進制段是只讀的:
$(OBJCOPY) --rename-section .data=.rodata,alloc,load,readonly,data,contents "src/mydata.bin.o"
更新:
我無法測試,因為我的系統是:
$ uname -r 11.2-STABLE $ ld -V GNU ld 2.17.50 [FreeBSD] 2007-07-03 Supported emulations: elf_x86_64_fbsd elf_i386_fbsd
我用 FreeBSD 12.0 啟動了一個虛擬機來測試它並發現了這個:
$ uname -r 12.0-RELEASE $ ld -V LLD 6.0.1 (FreeBSD 335540-1200005) (compatible with GNU linkers)
僅在 7.0.0中
-z noexecstack
添加,並且未在6.0.1的手冊頁中列出。更煩人的指定不支持的值-z
不會觸發錯誤!我還沒有升級到 LLVM 7 來測試這是否有效。@Richard Smith 通過
-m
在另一個答案中指定仿真自己找到了一個合適的解決方案。如果 LLD 列出了支持的仿真,那麼這條路線會容易得多-V
。如果您使用該
file
命令,file.o
您將看到它標識為 SYSV ELF。這對你來說可能已經足夠好了。但是,如果您想要與系統完全相同,請使用whichelf_amd64_fbsd
是. Annoyingly不像 GNU ld 那樣輸出受支持的 LLD 仿真。elf_x86_64_fbsd``ld -V
$ file /bin/cat /bin/cat: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 12.0 (1200086), FreeBSD-style, stripped $ ld -r -b binary -m elf_amd64 -o data.o data.bin $ file data.o data.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped $ ld -r -b binary -m elf_amd64_fbsd -o data.o data.bin $ file data.o data.o: ELF 64-bit LSB relocatable, x86-64, version 1 (FreeBSD), not stripped
elf_amd64_fbsd
是elf_x86_64_fbsd
(參見D7837和D24356)的別名。希望 LLD 將仿真添加到-V
輸出中。