GNU/Linux >> Linux の 問題 >  >> Linux

オブジェクト ファイルをコピーおよび変換するための Linux Objcopy コマンドの例

ある種類のプラットフォーム (ARM や x86 など) で使用可能なオブジェクト ファイルを別の種類のプラットフォームに移植する必要がある場合があります。ソース コードが利用可能であれば、ターゲット プラットフォームで再コンパイルできるため、作業は比較的簡単です。しかし、ソース コードが入手できず、オブジェクト ファイルを別のプラットフォームに移植する必要がある場合はどうすればよいでしょうか。 Linux を使用している場合は、コマンド objcopy が必要な処理を正確に実行します。この記事では、いくつかの例を通して、このコマンドの基本的な使い方を学びます。

私は x86_64 タイプのプラットフォームでしか作業していないため、このチュートリアルでは、このコマンドのプラットフォームに依存しない機能について説明します。

このコマンドの構文は次のとおりです:

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 オプションを使用して特定のセクションのみをコピー

ソース オブジェクト ファイルから宛先オブジェクト ファイルに 1 つのセクションのみをコピーする場合は、-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 オプションを使用して、すべてのグローバル シンボルを weak に変更します

これは、リンカーに -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 をファイル名とともに使用できます。このファイル名には、削除するシンボル名が含まれています (各行に 1 つ)。

次の例では、「call_gmon_start」シンボル名がファイル (symbolname) で指定されているため削除されます。

 $ 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
    ...

上記の例では、最初に objcopy が –strip-debug オプションで実行され、(他の多くのシンボルと共に) ソース ファイル (test.c) 名を示すシンボルが取り除かれました。次に、-keep-file-symbols オプションを指定して objcopy コマンドを再実行し、ソース ファイル名のシンボルが取り除かれていないことを確認しました (太字部分)。


Linux
  1. Linux および Unix でファイルをコピーする方法10 cp コマンドの例

  2. Linux / UNIX でファイルを管理する 10 の Cat コマンドの例

  3. 7 Linux で差分パッチ ファイルを適用するパッチ コマンドの例

  1. Linuxでファイルをダウンロードするための5つのWgetコマンドの例。

  2. 6 Linux のファイルとディレクトリを移動または名前変更する mv コマンドの例

  3. Linux での ln コマンドの例

  1. Linuxでのファイルのコピー

  2. Linuxでの8つのヘッドコマンドの例

  3. Linux での file コマンドの例