nm readelf objdump objcopy 命令之间的关系

本文详细解释了objdump、readelf、nm和objcopy这四个GNUBinutils工具在处理和分析ELF文件时的作用,包括它们之间的关系和各自的功能,以及在不同场景下的使用方法和典型用例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

nm readelf objdump objcopy 命令之间的关系

在解析可执行文件和链接库时,经常涉及到上述命令,但之前一直没有梳理清楚这几个命令之间的关系。如下整理了

概述

objdump, readelf, nm, 和 objcopy 是 GNU Binutils 套件的一部分,它们用于处理二进制文件。

  • objdump: 这是一个能够提供各种信息的程序,包括反汇编输出、源代码交叉引用等。更具体地说,它能够读取并解析二进制文件,然后以人类可读的形式显示这些信息。例如,它可以显示出二进制文件的所有头信息,包括文件的大小、段的数量和类型等。此外,它还能显示二进制文件的每个段的内容,包括段内的机器码和对应的汇编代码。
  • readelf: 这个程序用于显示 ELF 格式文件的详细信息。相比于 objdump,它提供的信息更为详尽,包括段头、符号表、重定位条目等。这意味着,除了能够显示文件的基本信息和段内容外,readelf 还能显示出文件中的符号和重定位信息。这对于理解程序的结构和行为具有重要的价值。
  • nm: 这是一个列出二进制对象文件(如 ELF、COFF)中的符号的程序。它可以扫描文件中的符号表,然后显示出符号的值、符号的类型以及符号的名称。这对于理解程序的结构和行为也十分有用。
  • objcopy: 这个程序用于复制和翻译二进制文件的内容。它可以读取一个二进制文件,然后生成一个新的文件,新文件的格式可以与原文件不同。例如,它可以将 ELF 格式的文件转换为 COFF 格式的文件。这对于程序的移植和分发具有重要意义。

关系图

在这里插入图片描述

个人理解针对elf文件而言。
objdump > readelf > nm
objdump可以查看各种类型的二进制文件,readelf主要时查看elf格式的二进制文件,而nm 主要是查看符号表,符号表属于elf格式文件内容的一部分。
objcopy则是负责在不同类型的二进制格式文件之间进行转换

介绍各个命令的典型使用场景

nm

-n 选项以地址的方式排列,而不是默认以 alphabet 字母顺序排序

	$nm -n -l -C a.out

                 w _ITM_deregisterTMCloneTable
00000000000004f0 T _init
0000000000000540 T _start
0000000000000570 t deregister_tm_clones
00000000000005b0 t register_tm_clones
0000000000000600 t __do_global_dtors_aux
0000000000000640 t frame_dummy
000000000000064a T main
00000000000006a0 T __libc_csu_init
0000000000000710 T __libc_csu_fini
0000000000000714 T _fini
0000000000000720 R _IO_stdin_used
000000000000072c r __GNU_EH_FRAME_HDR
000000000000086c r __FRAME_END__
0000000000200db8 t __frame_dummy_init_array_entry
0000000000200db8 t __init_array_start
0000000000200dc0 t __do_global_dtors_aux_fini_array_entry
0000000000200dc0 t __init_array_end
0000000000200dc8 d _DYNAMIC
0000000000200fb8 d _GLOBAL_OFFSET_TABLE_
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000201008 D __dso_handle
0000000000201010 D __TMC_END__
0000000000201010 B __bss_start
0000000000201010 D _edata
0000000000201010 b completed.7698
0000000000201018 B _end

readelf

readelf网上相关的资料很多,这里仅举一个常见的例子,不做赘述,后续以单独的文章整理

	readelf -a a.out ## 显示所有信息,-a --all               Equivalent to: -h -l -S -s -r -d -V -A -I
	

objdump

	objdump --help 
	 At least one of the following switches must be given:
	 The following switches are optional:
	选项分为两类,必须选项和可选选项。

作为必选选项

-f example命令,如果你想查看一个名为example的ELF文件的头部信息
-h example命令,如果你想查看该文件的节区头部信息
-d example命令,如果你想看到文件的反汇编输出
-x或-all-headers:显示所有头部信息,包括文件头、节区头、符号表头等。
-d或-disassemble:反汇编.text节区。
-s或-full-contents:显示所有节区的完整内容。

objdump查看elf格式文件的头部信息。

	$ objdump -f a.out
a.out:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000000540

objdump和readelf的差异如下:

objdump 主要用于显示二进制文件的各种信息,包括反汇编输出,头信息等。它的输出更为简洁,适用于需要快速理解二进制文件基本信息和结构的场景。
而 readelf 则提供了更为详细和深入的信息,包括段头、符号表、重定位条目等。它更适用于需要深入理解和分析 ELF 文件结构和行为的场景,例如进行二进制文件分析和调试。

objdump查看纯二进制格式文件

	objdump -b binary -m arm -D your_file

因为二进制BIN文件是一种更通用的二进制文件格式,它并没有特定的文件结构。BIN文件通常包含了纯粹的二进制数据,而无法提供ELF文件中包含的元数据。因此,BIN文件可以用于各种目的,包括固件更新,系统映像等。

需要通过-m 指定架构类型,架构类型需要提前在elf格式类型下进行确认。即下面的architecture 指定

$ objdump -f a.out

a.out:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000000540

如下可得到二进制的结果。

	objdump -b binary -m i386:x86-64 -D a.out

a.out:     file format binary


Disassembly of section .data:

0000000000000000 <.data>:
   0:   31 ed                   xor    %ebp,%ebp
   2:   49 89 d1                mov    %rdx,%r9
   5:   5e                      pop    %rsi
   6:   48 89 e2                mov    %rsp,%rdx
   9:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
   d:   50                      push   %rax
   e:   54                      push   %rsp


objcopy

	objcopy -O binary -j .abc $< $(OUT_PATH)/abc.bin;

示例为makefile中的objcopy语句,将来源文件中的 .abc段作为输入段,输出到二进制格式的abc.bin中。

-I或 -input-target:指定输入文件的格式。如果未指定此选项,objcopy将尝试自动确定输入文件的格式。

-O或 -output-target:指定输出文件的格式。如果未指定此选项,objcopy将默认输出格式与输入格式相同。

-B或-binary-architecture:当输入文件是二进制文件时,此选项用于指定目标架构。

-j或–only-section选项用于指定只复制输入文件中的特定段到输出文件。这个选项可以多次使用,每次指定一个要复制的段名。例如,objcopy -j .text -j .data inputfile outputfile将只会复制.text和.data段。如果没有使用此选项,objcopy将复制输入文件的所有段。

-strip-debug:删除所有的调试信息,从而减小输出文件的大小。

-rename-section oldname=newname:重命名一个节区。

-remove-section=sectionname:删除指定的节区。

objcopy -O 支持多种格式,包括:

  • a.out:Unix的标准二进制文件格式
  • COFF:Common Object File Format,常见对象文件格式
  • ELF:Executable and Linkable Format,可执行和链接格式
  • srec:Motorola S-Records
  • ihex:Intel Hex
  • binary:纯二进制格式
  • te pe:TE/PE,Windows的可执行文件格式

参考链接

https://blog.csdn.net/u014608280/article/details/81948141

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值