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

Linux常用命令大全
Linux常用命令行總結(jié)

Linux系統(tǒng)中最重要的三個(gè)命令
Linux ip命令常用操作
Linux實(shí)時(shí)查看日志的四種命令詳解

嵌入式開發(fā)必備-RK3562演示Linux常用系統(tǒng)查詢命令

Linux grep命令詳解
盤點(diǎn)Linux系統(tǒng)中的常見(jiàn)命令

Linux系統(tǒng)中shell命令解析
Linux lsof命令的基本用法

shell基本介紹及常用命令之shell介紹
Linux中cut命令的實(shí)用示例
SDRAM中的active命令介紹

評(píng)論