0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux中objcopy命令介绍

Linux爱好者 来源:csdn 作者:恋猫大鲤鱼 2021-03-10 10:12 次阅读

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变成全局范围,这样它可以在定义它的文件外部可见。可以多次指定。

-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

    文章

    11217

    浏览量

    208827
  • 命令
    +关注

    关注

    5

    文章

    678

    浏览量

    21976

原文标题:每天一个 Linux 命令(136):objcopy 命令

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux系统shell命令解析

    shell是Linux系统的用户界面,提供了用户与内核交互的一种接口,它接收用户输入的命令并到送到内核去执行,因此也被称为Linux命令解释器。
    的头像 发表于 11-05 15:40 127次阅读

    Linux实用命令大全

    Linux实用命令大全
    的头像 发表于 10-23 13:50 178次阅读
    <b class='flag-5'>Linux</b>实用<b class='flag-5'>命令</b>大全

    Linux lsof命令的基本用法

    linux 系统,一切皆文件。通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以 lsof 命令不仅可以查看进程打开的文件、目录,还可以查看进程监听的端口等 socket 相关的信息。本文将
    的头像 发表于 10-23 11:52 166次阅读
    <b class='flag-5'>Linux</b> lsof<b class='flag-5'>命令</b>的基本用法

    Linuxcut命令的实用示例

    Linux command cut 用于文本处理。您可以使用此命令通过选择列从文件中提取部分文本。
    的头像 发表于 08-05 15:14 284次阅读

    util-linux修复WallEscape漏洞,影响Linux系统wall命令使用

    WallEscape 主要影响“wall”命令操作,Linux 系统的常规下,该指令被用作向系统所有登录用户的终端发布消息。然而在处理命令行参数输入时,过滤器未正确识别和过滤转义序列
    的头像 发表于 03-29 14:35 927次阅读

    linux命令概述

    电子发烧友网站提供《linux命令概述.pdf》资料免费下载
    发表于 03-11 09:18 3次下载

    Linux基本命令总结

    都说Linux命令多,实际工作我们又有多少命令会接触用到呢?本文跟大家分享Linux运维工作中常用的600个
    的头像 发表于 01-11 10:32 938次阅读

    linux上更新了最新版本的SDK软件后,出现\"/bin/sh:行1: riscv-nuclei-elf-objcopy:未找到命令\"怎么解决?

    linux上更新了最新版本的SDK软件后,执行编译出现了 riscv-nuclei-elf-objcopy -O verilog “NICE_Test.elf” “NICE_Test.verilog
    发表于 01-10 06:34

    深入了解Linuxvi命令的使用

    深入了解Linuxvi命令的使用 VI是一款在Linux系统中使用的文本编辑器,它是一款功能强大、灵活性高的编辑器。VI编辑器具有非常高效的命令
    的头像 发表于 12-25 11:15 430次阅读

    如何在Linux中使用htop命令

    本文介绍如何在 Linux 中使用 htop 命令
    的头像 发表于 12-04 14:45 1876次阅读
    如何在<b class='flag-5'>Linux</b>中使用htop<b class='flag-5'>命令</b>

    linux系统修改ip命令

    Linux系统修改IP命令是掌握Linux网络管理的基础之一。在Linux操作系统,我们可以使用命令
    的头像 发表于 11-27 15:17 2024次阅读

    linux更改ip步骤命令

    inux是一种广泛应用于服务器和嵌入式设备的操作系统,通过更改IP地址,可以对网络进行重新配置和优化,以满足不同的需求。在Linux,可以使用不同的命令和配置文件进行IP地址的更改。本文将详细
    的头像 发表于 11-27 14:38 1683次阅读

    linux的常用命令

    ,最上层根目录是“/”,在这个根目录/下创建其他目录。Linux一切皆文件 2.2 Linux目录介绍 第一行 (1)/bin:存放经常使用的命令 (2)/boot:启动
    的头像 发表于 11-24 16:04 561次阅读
    <b class='flag-5'>linux</b>的常用<b class='flag-5'>命令</b>

    linux备份文件命令bak

    Linux系统,备份文件是非常重要的,它可以防止数据丢失和损坏的风险。为了达到安全的目的,我们经常需要备份文件。在这篇文章,我们将详细介绍Li
    的头像 发表于 11-23 10:12 2496次阅读

    linux关闭docker的命令

    Linux 系统,关闭 Docker 的操作可以通过以下多种方式进行。本文将详细讲解每一种方式,并提供示例代码和命令,以帮助读者更好地理解和实践。 使用 docker 命令 最常
    的头像 发表于 11-23 09:39 2738次阅读