1.命令簡介
將目標文件的一部分或者全部內容拷貝到另外一個目標文件中,或者實現目標文件的格式轉換,是 GNU Binutils 的一員。
objcopy 工具使用 BFD 庫讀寫目標文件,它可以將一個目標文件的內容拷貝到另外一個目標文件。objcopy 通過它的選項來控制其不同的動作,它可以將目標文件拷貝成和原來的文件不一樣的格式。需要注意的是 objcopy 能夠在兩種格式之間拷貝一個完全鏈接的文件,在兩種格式之間拷貝一個可重定位的目標文件可能不會正常地工作。
objcopy 在做轉換的時候會創建臨時文件,然后將這些臨時文件刪除。objcopy 使用 BFD 來做它所有的轉換工作;它訪問 BFD 中描述的所有格式,可以不必指定就識別大多數的格式。
通過指定輸出目標為 srec(例如 -O srec),objcopy 可以用來生成 S-record 文件。
通過指定輸入目標為二進制文件(例如-O binary),objcopy 可以生成原始格式的二進制文件。當 objcopy 生成一個原始格式的二進制文件的時候,它會生成輸入的目標文件的基本內存拷貝,然后所有的符號和可重定位信息都會被去掉。內存拷貝開始于最低段的加載地址,拷貝到輸出文件。
當生成一個 S-record 或者原始的二進制文件的時候,可以使用-S選項來移除一些調試信息。有時-R可以用來移除一些二進制文件不需要的段。
注意:objcopy 不能用來改變文件的大小端屬性。
2.命令格式
objcopy [OPTION] [INFILE] [OUTFILE]
3.選項說明
-I bfdname, --input-target=bfdname
指定輸入文件的格式 bfdname,可取值 elf32-little,elf32-big 等,而不是讓 objcopy 去推測
-O bfdname, --output-target=bfdname
指定輸出文件的的格式 bfdname
-F bfdname, --target=bfdname
指定輸入、輸出文件的 bfdname,目標文件格式,只用于在目標和源文件之間傳輸數據,不轉換
-B bfdarch, --binary-architecture=bfdarch
將無架構的輸入文件轉換為目標文件時很有用,輸出體系結構可以設置為 bfdarch。如果輸入文件具有已知的架構,將忽略此選項??梢栽诔绦騼韧ㄟ^引用轉換過程創建的特殊符號來訪問二進制數據。這些符號稱為 _binary_objfile_start、_binary_objfile_end 和 _binary_objfile_size。例如,您可以將圖片文件轉換為對象文件,然后使用這些符號在代碼中訪問它
-j sectionname, --only-section=sectionname
只將由 sectionname 指定的 section 拷貝到輸出文件,可以多次指定,并且注意如果使用不當會導致輸出文件不可用
-R sectionname, --remove-section=sectionname
從輸出文件中去除掉指定的 section,可以多次指定,并且注意如果使用不當會導致輸出文件不可用
-S, --strip-all
不從源文件拷貝符號信息和relocation信息。
-g, --strip-debug
不從源文件拷貝調試符號信息和相關的段。對使用 -g 編譯生成的可執行文件執行該選項后,生成的結果文件幾乎和不用 -g 編譯生成的可執行文件一樣
--strip-unneeded
去掉所有重定位處理不需要的符號
-K symbolname, --keep-symbol=symbolname
strip 的時候,保留由 symbolname 指定的符號信息。該選項可以多次指定
-N symbolname, --strip-symbol=symbolname
不拷貝由 symbolname 指定的符號信息。該選項可以多次指定
--strip-unneeded-symbol=symbolname
不拷貝重定位不需要的符號。該選項可以多次指定
-G symbolname, --keep-global-symbol=symbolname
只保留 symbolname 為全局的,讓其他符號均為局部符號,外部不可見。該選項可以多次指定
--localize-hidden
在 ELF 目標文件中,將所有具有隱藏或內部可見性的符號標記為“局部”。此選項適用于特定的符號本地化的選項,如 -L
-L symbolname, --localize-symbol=symbolname
將變量 symbolname 變成文件局部的變量。該選項可以多次指定
-W symbolname, --weaken-symbol=symbolname
將指定符號變為弱符號。該選項可以多次指定
--globalize-symbol=symbolname
讓變量symbolname變成全局范圍,這樣它可以在定義它的文件外部可見??梢远啻沃付ā?/p>
-w, --wildcard
允許對其他選項中的 symbolname 使用正則表達式。問號(?),星號(*),反斜線(),和中括號([])可以出現在 symbolname 的任何位置。如果 symbolname
的第一個字符是感嘆號(?。?,那么表示相反的含義,例如
-w -W !foo -W fo*
表示將要弱化所有以 “fo” 開頭的符號,但是除了符號 “foo”
-x, --discard-all
不從源文件中拷貝非全局符號
-X, --discard-locals
不拷貝編譯器生成的局部變量(一般以 L 或者 。. 開頭)
-b byte, --byte=byte
只保留輸入文件的每個第 byte 個字節(不會影響頭部數據)。byte 的范圍可以是 0 到 interleave-1。這里,interleave 通過 -i 選項指定,默認為 4。將文件創建成程序 rom 的時候,這個命令很有用。它經常用于 srec 輸出目標
-i interleave, --interleave=interleave
每隔 interleave 字節拷貝 1 byte,interleave 默認為 4。通過 -b 選項指定選擇哪個字節如果不指定 -b 那么 objcopy 會忽略這個選項
--interleave-width=width
與 --interleave 配合使用,-b 指定起始下標,--interleave-width 則指定每次拷貝的字節數為 width,width 默認為 1。注意 -b 指定的下標與 --interleave-width 指定的字節數相加不能超過 -i 設定的寬度
-p, --preserve-dates
將輸出文件的訪問和修改日期設置為與輸入文件的訪問和修改日期相同
-D, --enable-deterministic-archives
以確定性模式操作。復制存檔成員和寫入存檔索引時,對 uid、gid、時間戳使用零,對所有文件使用一致的文件模式。如果 binutils 配置了 --enable-deterministic-archives,那么這個模式是打開的,可以使用 -U 來禁止
-U, --disable-deterministic-archives
與 -D 作用相反。復制存檔成員和寫入存檔索引時,復制存檔成員和寫入存檔索引時,使用他們實際的 uid、gid、時間戳和文件模式。這個選項是默認的,除非 binutils 配置了 --enable-deterministic-archives
--debugging
如果可能,轉換調試信息。這不是默認設置,因為只支持某些調試格式,而且轉換過程可能很耗時
--gap-fill val
在 section 之間的空隙中填充 val
--pad-to address
將輸出文件填充到加載地址 address。這是通過增加最后一段的大小來完成的。用 --gap-fill 指定的值(默認為零)填充額外的空間
--set-start val
設定新文件的起始地址為 val,并不是所有格式的目標文件都支持設置起始地址
--change-start INCR, --adjust-start INCR
通過增加指定的值 INCR來調整起始地址,并不是所有格式的目標文件都支持設置起始地址
--change-addresses INCR, --adjust-vma INCR
通過增加 INCR 調整所有 sections 的 VMA(virtual memory address)和 LMA(load memory address)以及起始地址。有些目標文件格式不支持對段地址的任意改動。注意,這不會重新定位分區
--change-section-address sectionpattern{=,+,-}val, --adjust-section-vma sectionpattern{=,+,-}val
調整指定 section 的 VMA/LMA 地址。如果 sectionpattern 未匹配到 section,則會引發告警,除非使用 --no-change-warnings 抑制告警
--change-section-lma sectionpattern{=,+,-}val
調整指定 section 的 LMA 地址
--change-section-vma sectionpattern{=,+,-}val
調整指定 section 的 VMA 地址
--change-warnings, --adjust-warnings
使用 --change-section-address、--adjust-section-lma、--adjust-section-vma,如果 section pattern 沒有匹配到 section,引發告警。該選項為默認選項
--no-change-warnings, --no-adjust-warnings
使用 --change-section-address、--adjust-section-lma、--adjust-section-vma,如果 section pattern 沒有匹配到 section,不引發告警
--set-section-flags sectionpattern=flag
為指定的 section 設置 flag,flag 是一個逗號分隔的由 flag name 組成的字符串,取值可以為 alloc, contents, load, noload, readonly, code, data, rom, share, debug。我們可以為一個沒有內容的 section 設置 contents flag,但是清除一個有內容的 section 的 contents flag 是沒有意義的--應當把相應的 section 移除。并不是所有的 flags 對所有格式的目標文件都有意義
--add-section sectionname=filename
在拷貝文件的時候,添加一個名為 sectionname 的 section,該 section 的內容為 filename 的內容,大小為文件大小。這個選項只在那些可以支持任意名稱 section 的文件格式上生效
--rename-section oldname=newname[,flags]
將一個 section 的名字從 oldname 更改為 newname,同時也可以更改其 flags。這個在執行 linker 腳本進行重命名的時候,并且輸出文件還是一個目標文件且不會是可執行文件的時候很有優勢。
這個項在輸入文件格式是 binary 的時候很有用,因為這經常會創建一個名稱為 .data 的 section,例如,你想創建一個名稱為 .rodata 的包含二進制數據的 section,這時候,你可以使用如下命令:
objcopy -I binary -O 《output_format》 -B 《architecture》 --rename-section .data=.rodata,alloc,load,readonly,data,contents 《input_binary_file》 《output_object_file》
--long-section-names {enable,disable,keep}
在處理 COFF 和 PE-COFF 格式目標文件時,控制對長段名稱的處理。默認行為是 keep,保留長段名稱(如果有)。enable 和 disable 分別強制啟用或禁用在輸出目標文件中使用長段名稱
--change-leading-char
有些格式的目標文件在符號前使用特殊的前導字符,最常用的是下劃線。此選項告訴 objcopy 在目標文件格式之間轉換時更改每個符號的前導字符。如果不同的目標文件使用相同的前導字符,則此選項無效。否則,它將根據需要添加字符、刪除字符或更改字符
--remove-leading-char
移除目標文件全局符號前的前導字符
--reverse-bytes=num
反轉段中的字節。注意,段的大小必須可以被指定的數值 num 均分。該選項一般用于產生 ROM 映像用于在有問題的目標系統上進行調試。假如一個段的內容只有 8 個字節,為 12345678。
使用 --reverse-bytes=2 ,輸出文件中的結果是 21436587
使用 --reverse-bytes=4,輸出文件中的結果是 43218765
使用 --reverse-bytes=2,接著再對輸出文件使用 --reverse-bytes=4,再第二個輸出文件中的結果將是 34127856
--srec-len=ival
只對輸出目標文件格式 SREC 有意義。指定生成 SREC 文件的最大長度為 ival
--srec-forceS3
只對輸出目標文件格式是 SREC 有意義。避免產生 S1/S2 記錄,只產生 S3 格式的記錄
--redefine-sym old=new
變更符號名稱。當鏈接兩個目標文件產生符號名稱沖突時,可以使用該選項來解決
--redefine-syms=filename
將 --redefine-sym 選項應用于指定的文件 filename。該選項可以多次出現
--weaken
將所有全局符號變更為弱符號。改選只對在支持弱符號的目標文件格式有效
--keep-symbols=filename
將 --keep-symbol 選項應用于指定的文件 filename。該選項可以多次出現
--strip-symbols=filename
將 --strip-symbol 選項應用于指定的文件 filename。該選項可以多次出現
--strip-unneeded-symbols=filename
將 --strip-unneeded-symbol 選項應用于指定的文件 filename。該選項可以多次出現
--keep-global-symbols=filename
將 --keep-global-symbol 選項應用于指定的文件 filename。該選項可以多次出現
--localize-symbols=filename
將 --localize-symbol 選項應用于指定的文件 filename。該選項可以多次出現
--globalize-symbols=filename
將 --globalize-symbol 選項應用于指定的文件 filename。該選項可以多次出現
--weaken-symbols=filename
將 --weaken-symbol 選項應用于指定的文件 filename。該選項可以多次出現
--alt-machine-code=index
果輸出體系結構具有備用機器代碼,請使用 indexth 代碼而不是默認代碼
--add-gnu-debuglink=path-to-file
為輸出文件創建一個.gnu_debuglink 段,該段包含對一個調試信息文件 path-to-file 的引用
--writable-text
將輸出文本標記為可寫。此選項對所有目標文件格式都沒有意義
--readonly-text
將輸出文本標記為只讀。此選項對所有目標文件格式都沒有意義
--pure
將輸出文件標記為按需分頁。此選項對所有目標文件格式都沒有意義
--impure
將輸出文件標記為不純。此選項對所有對象文件格式都沒有意義
--prefix-symbols=string
在輸出文件中使用指定的字符串作為符號的前綴
--prefix-sections=string
在輸出文件中使用指定的字符串作為所有段名的前綴
--prefix-alloc-sections=string
在輸出文件中使用指定的字符串作為所有分配的段名的前綴
--add-gnu-debuglink=path-to-file
創建一個 .gnu-debuglink 段,該段包含一個特定路徑的文件引用,并且把它添加到輸出文件中
--only-keep-debug
對文件進行 strip,移走所有不會被 --strip-debug 移走的 section,并且保持調試相關的 section 原封不動
--strip-dwo
刪除所有 DWARF .dwo 段的內容,保留其余調試段和所有符號的完整性
--extract-dwo
提取所有 DWARF .dwo 段的內容
--file-alignment num
指定文件對齊方式。文件中的段始終相對于文件起始部分的偏移量是數值 num 的整數倍,默認值為512。此選項特定于 PE 文件
--heap reserve, --heap reserve,commit
指定要保留的內存字節數,以用作此程序的堆。此選項特定于 PE 文件
--image-base value
使用指定的值 value 作為程序或 dll 的基地址。這是加載程序或 dll 時使用的最低內存位置。為了減少重新定位進而提高 dll 性能,每個 dll 都應該有一個唯一的基地址,且不應與其他 dll 重疊。對于可執行文件,默認值為 0x400000,對于 dll,默認值為 0x10000000。此選項特定于 PE 文件
--section-alignment num
設置段的對齊方式。段在內存中的起始地址是指定數值 num 的整數倍。num 默認為 0x1000。此選項特定于 PE 文件
--stack reserve, --stack reserve,commit
指定要保留的內存字節數,以用作此程序的棧。此選項特定于 PE 文件
--subsystem which, --subsystem which:major, --subsystem which:major.minor
指定程序執行的子系統。which 的合法值為 “native”、“windows”、“console”、“posix”、“efi-app”、“efi-bsd”、“efi-rtd”、“sal-rtd” 和 “xbox”。您也可以選擇性地設置子系統版本。此選項特定于 PE 文件
--extract-symbol
保留文件的段標志和符號,但刪除段的數據
--compress-debug-sections
使用 zlib 壓縮 DWARF 調試部分
-V, --version
顯示版本
-v,--verbose
冗余輸出
--help
顯示幫助
--info
顯示所有可用架構和目標文件格式
@file
從文件中讀取命令行選項
4.常用示例
為了后面的示例,先看一下源碼。
//
//@file: main.cpp
//
#include 《iostream》
using namespace std;
void my_print() {
cout《《“print”《《endl;
}
int main(int argc, char *argv[]) {
my_print();
cout《《“hello”《《endl;
return 0;
}
通過 g++ 分別生成帶調試信息與不帶調試信息的可執行文件 main.debug 和 main。
g++ -g -o main.debug main.cpp
g++ -o main main.cpp
(1)分離可執行文件中的調試信息后并將兩者關聯。
#1.生成調試信息文件,將其中的調試信息提取出來之后保存成一個文件
objcopy --only-keep-debug main.debug main.debuginfo
#2.將調試信息從可執行文件中剝離
objcopy --strip-debug main.debug main.stripdebug
#3.為不含調試信息的可執行文件添加調試信息
objcopy --add-gnu-debuglink=main.debuginfo main.stripdebug
(2)添加一個自定義的段到可執行文件,段的內容由一個文件指定。
objcopy --add-section mysection=text.txt main main.add
使用命令 readelf -S main.add 可以看到可執行文件 main.add 中多出來了一個段 mysection。
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Alig
[27] mysection PROGBITS 0000000000000000 00001088
0000000000000006 0000000000000000 0 0 1
(3)將指定的段拷貝出來。這里拷貝出我們新增的段 mysetion。
objcopy --only-section=mysection main.add section_hello
(4)去掉指定名稱的段。去掉我們新增的段 mysection。
objcopy -R mysection main.add main.remove
使用命令 readelf -S main.remove 可以看到可執行文件 main.remove 中的段 mysection 已經不見了。
原文標題:每天一個 Linux 命令(136):objcopy 命令
文章出處:【微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。
責任編輯:haq
-
Linux
+關注
關注
87文章
11456瀏覽量
212726 -
命令
+關注
關注
5文章
726瀏覽量
22663
原文標題:每天一個 Linux 命令(136):objcopy 命令
文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
Linux常用命令大全
Linux系統中最重要的三個命令
Linux ip命令常用操作
Linux grep命令詳解
Linux系統中shell命令解析
Linux lsof命令的基本用法

Linux系統中man命令的基本使用

shell基本介紹及常用命令之shell介紹
SDRAM中的active命令介紹

評論