Linux命令是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。本文主要介绍Linux objcopy 命令。

1、命令简介

objcopy:用于复制目标文件的一部分或将目标文件转换为不同的格式。它通常用于处理二进制可执行文件、目标文件和共享库等文件。objcopy 的主要功能包括复制、转换和修改二进制文件。

2、命令语法

objcopy [-F bfdname|--target=bfdname]
[-I bfdname|--input-target=bfdname]
[-O bfdname|--output-target=bfdname]
[-B bfdarch|--binary-architecture=bfdarch]
[-S|--strip-all]
[-g|--strip-debug]
[-K symbolname|--keep-symbol=symbolname]
[-N symbolname|--strip-symbol=symbolname]
[--strip-unneeded-symbol=symbolname]
[-G symbolname|--keep-global-symbol=symbolname]
[--localize-hidden]
[-L symbolname|--localize-symbol=symbolname]
[--globalize-symbol=symbolname]
[-W symbolname|--weaken-symbol=symbolname]
[-w|--wildcard]
[-x|--discard-all]
[-X|--discard-locals]
[-b byte|--byte=byte]
[-i interleave|--interleave=interleave]
[-j sectionname|--only-section=sectionname]
[-R sectionname|--remove-section=sectionname]
[-p|--preserve-dates]
[--debugging]
[--gap-fill=val]
[--pad-to=address]
[--set-start=val]
[--adjust-start=incr]
[--change-addresses=incr]
[--change-section-address section{=,+,-}val]
[--change-section-lma section{=,+,-}val]
[--change-section-vma section{=,+,-}val]
[--change-warnings] [--no-change-warnings]
[--set-section-flags section=flags]
[--add-section sectionname=filename]
[--rename-section oldname=newname[,flags]]
[--change-leading-char] [--remove-leading-char]
[--srec-len=ival] [--srec-forceS3]
[--redefine-sym old=new]
[--redefine-syms=filename]
[--weaken]
[--keep-symbols=filename]
[--strip-symbols=filename]
[--strip-unneeded-symbols=filename]
[--keep-global-symbols=filename]
[--localize-symbols=filename]
[--globalize-symbols=filename]
[--weaken-symbols=filename]
[--alt-machine-code=index]
[--prefix-symbols=string]
[--prefix-sections=string]
[--prefix-alloc-sections=string]
[--add-gnu-debuglink=path-to-file]
[--keep-file-symbols]
[--only-keep-debug]
[--writable-text]
[--readonly-text]
[--pure]
[--impure]
[-v|--verbose]
[-V|--version]
[--help] [--info]
infile [outfile]

3、命令描述

GNU objcopy 实用程序将一个目标文件的内容复制到另一个目标文件中。objcopy 使用 GNU BFD 库来读取和写入目标文件。它可以将目标对象文件写入与源对象文件不同的格式。objcopy 的确切行为由命令行选项控制。请注意,objcopy 应该能够在任何两种格式之间复制一个完全链接的文件。但是,在任何两种格式之间复制一个可重定位的目标文件可能无法按预期工作。

objcopy 创建临时文件来执行翻译操作,并在之后将其删除。objcopy 使用 BFD 来执行所有的翻译工作;它可以访问 BFD 中描述的所有格式,因此通常能够在不需要显式指定的情况下识别大多数格式。

objcopy 可以通过使用输出目标为 srec(例如,使用 -O srec)来生成 S-records。

objcopy 可以通过使用输出目标为 binary(例如,使用 -O binary)来生成原始二进制文件。当 objcopy 生成原始二进制文件时,它实际上会产生输入对象文件内容的内存转储。所有符号和重定位信息将被丢弃。内存转储将从复制到输出文件中的最低部分的加载地址开始。

在生成 S-record 或原始二进制文件时,使用 -S 可能有助于删除包含调试信息的部分。在某些情况下,-R 可以用于删除不需要的二进制文件的部分。

注意:objcopy 无法更改其输入文件的字节顺序。如果输入格式具有字节顺序(某些格式没有),那么 objcopy 只能将输入复制到具有相同字节顺序或没有字节顺序的文件格式中(例如,srec)。

4、命令选项

选项

描述

-I bfdname

指定输入文件的bfdname,

可取值为elf32-little、elf32-big等。

--input-target=bfdname

-O bfdname

指定输出文件的bfdname。

--output-target=bfdname

-F bfdname

指定输入和输出文件的bfdname,

用于在目标和源之间传输数据,不进行转换。

--target=bfdname

-j sectionname

只拷贝由sectionname指定的section到输出文件,

可以多次指定,注意不当使用可能导致输出文件无效。

--only-section=sectionname

-R sectionname

从输出文件中去除由sectionname指定的section,

可以多次指定,注意不当使用可能导致输出文件无效。

--remove-section=sectionname

-S

不拷贝源文件的符号信息和重定位信息。

--strip-all

-g

不拷贝源文件的调试符号信息和相关段,

对使用-g编译生成的可执行文件执行后,

生成的结果几乎与不使用-g编译生成可执行文件一样。

--strip-debug

--strip-unneeded

去除所重定位处理不需要的符号。

-K symbolname

在strip时保留由symbolname指定的符号信息,可以多次指定。

--keep-symbol=symbolname

-N symbolname

不拷贝由symbolname指定的符号信息,可以多次指定。

--strip-symbol=symbolname

-G symbolname

只保留全局的symbolname,使其他变量成为文件局部变量,

这个选项可以多次指定。

--keep-global-symbol=symbolname

-L symbolname

将变量symbolname变成文件局部变量,可以多次指定。

--localize-symbol=symbolname

-W symbolname

弱化变量symbolname。

--weaken-symbol=symbolname

--globalize-symbol=symbolname

让变量symbolname成为全局变量,

使其在定义它的文件之外可见,可以多次指定。

-w

允许在其他命令行选项中

使用正则表达式对symbolnames进行匹配。

可以使用问号(?)、星号(

)、反斜线()和中括号([])操作。

如果标号的第一个字符是感叹号(!),

表示相反的含义。例如:-w -W !foo -W fo

表示弱化所有以"fo"开头的标号,但保留标号"foo"。

--wildcard

-x

不拷贝源文件中的非全局变量。

--discard-all

-X

不拷贝源文件生成的局部变量(通常以L或..开头)。

--discard-locals

-b byte

仅保留输入文件的每第byte个字节(不影响头部数据)。

byte的范围可以是0到interleave-1。

在创建ROM程序文件时非常有用,

通常用于SREC输出目标。

--byte=byte

-i interleave

每隔interleave字节拷贝1个字节。

通过-b选项选择要拷贝的字节,默认为4。

如果未指定-b,objcopy将忽略此选项。

--interleave=interleave

--gap-fill val

在section之间的空隙中填充val。

--set-start val

设定新文件的起始地址为val,

并不是所有格式的目标文件都支持设置起始地址。

--change-start incr
--adjust-start incr

通过增加incr量来调整起始地址,

并不是所有格式的目标文件都支持设置起始地址。

--change-address incr
--adjust-vma incr

--change-section-address section{=,+,-}val
--adjust-section-vma section{=,+,-}val

调整指定section的VMA/LMA地址。

--set-section-flags section=flag

指定指定section的flag,flag的取值可以是alloc、

contents、load、noload、readonly、

code、data、rom、share、debug。

我们可以设置一个没有内容的节的flag,

但是清除一个有内容的节的flag是没有意义的,

应当把相应的节移除。

并不是所有的flags对于所有的目标文件都有意义。

--add-section sectionname=filename

在拷贝文件的时候,添加一个名为sectionname的section,

该section的内容为filename的内容,大小为文件大小。

这个选项只在那些可以支持任意名称section的文件中好用。

--rename-section oldname=newname[,flags]

更改section的名字。

将一个section的名字从oldname更改为newname,

同时也可以指定更改其flags。

这个在执行linker脚本进行重命名的时候,

并且输出文件还是一个目标文件并不成为可执行的连接文件,

这个时候很有优势。这个项在输入文件是binary的时候很有用,

因为这经常会创建一个名称为.data的section,

例如,你想创建一个名称为.rodata的包含二进制数据的section,

这时候,你可以使用如下命令:
objcopy -I binary -O -B --rename-section .data=.rodata,alloc,load,readonly,data,contents

--add-gnu-debuglink=path-to-file

创建一个.gnu_debuglink节,

这个节包含一个特定路径的文件引用,

并且把它添加到输出文件中。

--only-keep-debug

对文件进行strip,

移走所有不会被--strip-debug移走的section,

并且保持调试相关的section原封不动。

5、使用示例

1)复制一个 ELF 可执行文件的一个节到另一个文件中:

objcopy --only-section=.text input.bin output.bin

2)将一个 ELF 可执行文件转换为另一种目标格式(例如,将 ELF 转换为 Intel Hex 格式)

objcopy -I elf32-i386 -O ihex input.elf output.hex

3)剥离一个可执行文件中的调试信息:

objcopy --strip-debug input.bin output.bin

4)重命名一个 ELF 文件中的一个节

objcopy --rename-section .old_section=.new_section input.elf output.elf

5)添加一个新的节到目标文件中:

objcopy --add-section .new_section=input.bin output.bin

推荐文档