Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

objcopy 實用指南:目標文件格式轉換與二進制提取

編輯:Linux 教學

工具定位

objcopy 是 GNU Binutils 套件核心工具,用於**目標文件間的內容複製與格式轉換**。基於 BFD (Binary File Descriptor) 庫,支援 50+ 種目標格式 (ELF、COFF、a.out、S-record、Intel Hex、Binary 等)。

核心用法速查表

任務命令範例關鍵選項
ELF → 純二進制objcopy -O binary app.elf app.bin-O binary
ELF → S-record (燒錄)objcopy -O srec app.elf app.srec-O srec
ELF → Intel Hexobjcopy -O ihex app.elf app.hex-O ihex
去除符號/調試資訊objcopy -S -g app.elf app_stripped.elf-S -g
僅保留特定段objcopy -j .text -j .data -O binary app.elf firmware.bin-j section
移除特定段objcopy -R .comment -R .note app.elf-R section
重定位段地址objcopy --change-section-address .text=0x8000 app.elf--change-section-address
添加二進制資源段objcopy --add-section .mydata=data.bin app.elf--add-section
格式轉換 (ELF32→ELF64)objcopy -O elf64-x86-64 app32.elf app64.elf-O bfdname

嵌入式開發高頻場景

場景一:生產裸機燒錄映像


# 1. 編譯鏈接生成 ELF
arm-none-eabi-gcc -mcpu=cortex-m4 -T linker.ld -o app.elf src/*.c

# 2. 提取 .text .data .rodata 生成二進制
arm-none-eabi-objcopy -O binary \
  -j .text -j .data -j .rodata -j .vectors \
  app.elf app.bin

# 3. 驗證
arm-none-eabi-objdump -h app.elf
ls -l app.bin

注意:Binary 格式**不包含**符號表、重定位資訊、段屬性。起始地址為被複製段的最小虛擬地址 (VMA)。燒錄器需知晓載入地址 (通常來自鏈接腳本 ENTRY 或向量表)。

場景二:減小釋出版體積


# 去除所有符號與調試資訊
objcopy -S -g --strip-unneeded app.elf app.release.elf

# 進一步:僅保留必要段
objcopy -R .comment -R .note -R .note.gnu.build-id \
  -R .eh_frame -R .eh_frame_hdr \
  app.release.elf app.minimal.elf

場景三:將資源文件嵌入程式


# 將圖片/字體/配置文件嵌入為只讀數據段
objcopy --add-section .firmware_logo=logo.png \
  --set-section-flags .firmware_logo=readonly,data \
  --change-section-vma .firmware_logo=0x08020000 \
  app.elf app_with_logo.elf

C 代碼中訪問:


extern const unsigned char _binary_firmware_logo_start[];
extern const unsigned char _binary_firmware_logo_end[];
size_t logo_size = _binary_firmware_logo_end - _binary_firmware_logo_start;

場景四:Bootloader + Application 合併燒錄


# 1. 分別編譯
arm-none-eabi-gcc -T boot.ld -o boot.elf boot/*.c
arm-none-eabi-gcc -T app.ld -o app.elf app/*.c

# 2. 提取二進制
arm-none-eabi-objcopy -O binary -j .text -j .data boot.elf boot.bin
arm-none-eabi-objcopy -O binary -j .text -j .data -j .rodata app.elf app.bin

# 3. 合併 (假設 Bootloader 佔 32KB,App 從 0x08008000 開始)
cat boot.bin app.bin > full_image.bin
# 或使用 objcopy 精確控制地址
objcopy -I binary -O binary --pad-to=0x8000 --gap-fill=0xFF boot.bin boot_padded.bin
cat boot_padded.bin app.bin > full_image.bin

進階選項深度解析

符號操作

  • -K symbol / --keep-symbol:僅保留指定符號 (可多次使用)
  • -N symbol / --strip-symbol:移除指定符號
  • -L symbol / --localize-symbol:將全局符號設為局部 (隱藏)
  • -W symbol / --weaken-symbol:將符號標記為弱符號
  • -x / --discard-all:移除所有非全局符號
  • -X / --discard-locals:移除編譯器生成的局部符號 (以 L 或 . 開頭)

段屬性修改

  • --set-section-flags .name=alloc,load,readonly,data,contents
  • --change-section-vma .name=0xADDR:修改虛擬地址 (VMA)
  • --change-section-lma .name=0xADDR:修改載入地址 (LMA)
  • --change-section-address .name=0xADDR:同時修改 VMA/LMA

填充與對齊

  • --gap-fill=0xFF:段間隙填充值 (燒錄常用 0xFF/0x00)
  • --pad-to=0x10000:輸出文件填充至指定地址
  • --set-start=0xADDR:設定入口點地址
  • --adjust-start=0xOFFSET:調整入口點偏移

常見陷阱與避坑

問題原因解決
Binary 輸出檔案大小異常大段間隙被填充、VMA 不連續使用 --gap-fill=0 --pad-to=0 或調整鏈接腳本
符號在 Binary 中丟失Binary 格式不保存符號保留 ELF 供調試,僅發布 Binary
交叉編譯 objcopy 無法識別目標格式BFD 未支援該架構/格式組合確認 objcopy --help 列表、更新 Binutils
--add-section 後段不可讀未設定 alloc/load/readonly flags加上 --set-section-flags .sec=alloc,load,readonly,data

對比:objcopy vs objdump vs readelf

工具核心功能典型用途
objcopy複製、轉換、修改目標文件格式轉換、裁剪、嵌入資源、地址調整
objdump反組裝、顯示段/符號/重定位代碼審計、調試、檢查指令編碼
readelf解析 ELF 結構 (程序頭、段頭、符號表)ELF 結構分析、動態鏈接檢查、ABI 驗證
Copyright © Windows教程網 All Rights Reserved