用于复制和翻译目标文件的 Linux Objcopy 命令示例

举报
Tiamo_T 发表于 2022/07/15 19:34:40 2022/07/15
【摘要】 有时您需要将可用于一种平台的目标文件移植到另一种平台。如果源代码可用,事情就相对容易了,因为它可以在目标平台上重新编译。但是,如果源代码不可用并且您仍然需要将目标文件从平台类型移植到其他平台怎么办?如果您使用的是 Linux,那么命令 objcopy 完全可以满足您的要求。在本文中,我们将通过一些示例来了解该命令的基本用法。

有时您需要将可用于一种平台的目标文件移植到另一种平台。如果源代码可用,事情就相对容易了,因为它可以在目标平台上重新编译。但是,如果源代码不可用并且您仍然需要将目标文件从平台类型移植到其他平台怎么办?如果您使用的是 Linux,那么命令 objcopy 完全可以满足您的要求。在本文中,我们将通过一些示例来了解该命令的基本用法。

该命令的语法是:

objcopy [options] infile [outfile]...

请注意,'options' 和 'outfile' 不是强制性参数,但有其自身的意义。

例子

1.简单地将目标文件从源复制到目标

考虑以下示例:

$ objcopy test new_test
$

所以上面的命令会将'test'复制到一个新文件'new_test'中。请注意,由于在这种情况下,“test”是在同一平台上编译的,因此输出“new_test”将没有什么不同。

此外,如果您想反汇编二进制文件并获取有关目标文件的更多详细信息,则应使用objdump 命令,如前所述。


2.复制目标文件而不提供新文件名

在上面的示例中,复制的文件被命名为“new_test”,因为它与命令的选项一起提供。但是,如果没有提供目标文件名,则 objcopy 命令将原始文件替换为复制的文件。

考虑以下示例:

$ stat test
  File: `test'
  Size: 8498      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1442357     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/himanshu)   Gid: ( 1001/  family)
Access: 2012-08-31 21:25:54.828808055 +0530
Modify: 2012-08-31 21:25:50.498614487 +0530
Change: 2012-08-31 21:25:50.498614487 +0530

$ objcopy test

$ stat test
  File: `test'
  Size: 8498      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1459714     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/himanshu)   Gid: ( 1001/  family)
Access: 2012-08-31 21:30:04.108833244 +0530
Modify: 2012-08-31 21:30:04.108833244 +0530
Change: 2012-08-31 21:30:04.108833244 +0530

所以我们看到目标文件“test”的统计数据完全改变了,因为 objcopy 将它创建为一个全新的文件。

3. 使用 -j 选项仅复制特定部分

如果您只想将源目标文件中的一个部分复制到目标目标文件,则在这种情况下使用 -j 选项。

考虑以下示例:

$ objcopy -j.interp test new_test
$

上面的命令实际上只会将 .interp 部分复制到空的 new_test 文件中。

如果我们确认:

$ objdump -s new_test 

new_test:     file format elf64-x86-64

Contents of section .interp:
 400238 2f6c6962 36342f6c 642d6c69 6e75782d  /lib64/ld-linux-
 400248 7838362d 36342e73 6f2e3200           x86-64.so.2.

所以我们看到这个文件只包含 .interp 部分(我们从 'test' 复制的)。

4. 使用 -R 选项从复制的文件中仅删除特定部分

此选项允许 objdump 命令复制完整的源文件,除了与此选项一起指定的部分。

考虑以下示例:

$ objcopy -R.interp test new_test

如果我们确认:

$ objdump -s -j.interp new_test 

new_test:     file format elf64-x86-64

所以我们看到新文件“new_test”中没有.interp 部分。

5. 使用 -p 选项保留访问和修改日期

通过使用 -p 选项和此命令,可以保留复制文件的访问和修改日期(可以与源保持相同)。

考虑以下示例:

$ objcopy -p test new_tst

上述命令将保留访问和修改日期/时间。

如果我们确认:

$ $ stat test
  File: `test'
  Size: 8498      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1459714     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/himanshu)   Gid: ( 1001/  family)
Access: 2012-08-31 21:32:32.458629723 +0530
Modify: 2012-08-31 21:30:04.108833244 +0530
Change: 2012-08-31 21:30:04.108833244 +0530

$ stat new_tst
  File: `new_tst'
  Size: 8498      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1442650     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/himanshu)   Gid: ( 1001/  family)
Access: 2012-08-31 21:32:32.000000000 +0530
Modify: 2012-08-31 21:30:04.000000000 +0530
Change: 2012-08-31 21:42:25.938657423 +0530

所以我们看到访问和修改时间/日期都被保留了。

6. 使用–weaken 选项将所有全局符号更改为弱

这在构建可以使用链接器的 -R 选项与其他目标文件链接的目标文件时很有用。

考虑以下示例:

$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     ..
    27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27
    28: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 call_gmon_start
    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    ..
    49: 0000000000400550     2 FUNC    GLOBAL DEFAULT   14 __libc_csu_fini
    50: 0000000000400440     0 FUNC    GLOBAL DEFAULT   14 _start
    51: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    52: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    53: 0000000000400628     0 FUNC    GLOBAL DEFAULT   15 _fini
    54: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    55: 0000000000400638     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
    ..
$ objcopy --weaken test new_test

$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     ..
    28: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 call_gmon_start
    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    30: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
    31: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
    32: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
    ...
    49: 0000000000400550     2 FUNC    WEAK   DEFAULT   14 __libc_csu_fini
    50: 0000000000400440     0 FUNC    WEAK   DEFAULT   14 _start
    51: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    52: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    53: 0000000000400628     0 FUNC    WEAK   DEFAULT   15 _fini
    54: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    55: 0000000000400638     4 OBJECT  WEAK   DEFAULT   16 _IO_stdin_used
    56: 0000000000601010     0 NOTYPE  WEAK   DEFAULT   25 __data_start
    ..
$

所以我们看到,在运行带有 –weaken 标志的 objcopy 命令后,所有 GLOBAL 符号都被转换为 WEAK。

7. 使用 --prefix-symbols 选项为字符串添加前缀

考虑以下示例,其中需要在符号名称之前添加字符串“TGS”:

$ objcopy --prefix-symbols="TGS" test new_test
$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     ...
    28: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 TGScall_gmon_start
    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS TGScrtstuff.c
    30: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 TGS__CTOR_LIST__
    31: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 TGS__DTOR_LIST__
    32: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 TGS__JCR_LIST__
    33: 0000000000400490     0 FUNC    LOCAL  DEFAULT   14 TGS__do_global_dtors_aux
    ...

所以我们看到'TGS' 在符号名称之前有前缀。

8. 使用 –strip-symbols 选项去除特定符号

如果需要去除某些符号,则可以将选项 –strip-symbols 与文件名一起使用。此文件名包含要剥离的符号名称(每行一个)。

考虑以下示例,其中将删除“call_gmon_start”符号名称,因为它是在文件(符号名称)中指定的。

 $ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     .....
    28: 000000000040046c 0 FUNC LOCAL DEFAULT 14 call_gmon_start
    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    30: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
    31: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
    32: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
    33: 0000000000400490     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
    ...

$ objcopy --strip-symbols=symbolname test new_test

$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 64 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     ...
    26: 0000000000601020     0 SECTION LOCAL  DEFAULT   26
    27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27
    28: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    29: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
    30: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
    31: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
    32: 0000000000400490     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
    ...

所以我们看到符号“call_gmon_start”被成功剥离。

9. 使用 –prefix-sections 选项为部分名称添加前缀

考虑以下示例:

$ objcopy --prefix-sections="TGS" test new_test
$ readelf -s new_test
readelf: Error: no .dynamic section in the dynamic segment

Symbol table 'TGS.dynsym' contains 4 entries:
Num: Value          Size Type    Bind  Vis     Ndx Name
0: 0000000000000000 0    NOTYPE  LOCAL DEFAULT UND

所以我们看到部分名称以我们提供的字符串 TGS 为前缀。

10. 使用 –keep-file-symbols 选项保留源文件名符号

每当使用 –strip-debug 符号(它会剥离许多与调试相关的符号以及指定文件名的符号),如果需要保留源文件名符号,则可以使用 –keep-file-symbols。

考虑以下示例:

$ objcopy --strip-debug test new_test
$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 62 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 call_gmon_start
     2: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
     3: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
     4: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
     ...
    10: 00000000004006e8     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
    11: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_END__
    12: 00000000004005f0     0 FUNC    LOCAL  DEFAULT   14 __do_global_ctors_aux
    13: 0000000000600fe8     0 OBJECT  LOCAL  HIDDEN   24 _GLOBAL_OFFSET_TABLE_
    14: 0000000000600e14     0 NOTYPE  LOCAL  HIDDEN   19 __init_array_end
    15: 0000000000600e14     0 NOTYPE  LOCAL  HIDDEN   19 __init_array_start
    ...

$ objcopy --strip-debug --keep-file-symbols test new_test

$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 call_gmon_start
     2: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
     3: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
     4: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
     ...
    12: 00000000004006e8     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
    13: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_END__
    14: 00000000004005f0     0 FUNC    LOCAL  DEFAULT   14 __do_global_ctors_aux
    15: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
    16: 0000000000600fe8     0 OBJECT  LOCAL  HIDDEN   24 _GLOBAL_OFFSET_TABLE_
    17: 0000000000600e14     0 NOTYPE  LOCAL  HIDDEN   19 __init_array_end
    18: 0000000000600e14     0 NOTYPE  LOCAL  HIDDEN   19 __init_array_start

在上面的示例中,首先使用 –strip-debug 选项运行 objcopy,该选项(以及许多其他符号)剥离了提及源文件 (test.c) 名称的符号。接下来,我们重新运行 objcopy 命令以及 –keep-file-symbols 选项,并观察到(粗体)源文件名的符号没有被删除。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。