GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux Objcopy-Befehlsbeispiele zum Kopieren und Übersetzen von Objektdateien

Es gibt Zeiten, in denen Sie eine Objektdatei, die für eine Art von Plattform (wie ARM oder x86) verfügbar ist, auf eine andere Art von Plattform portieren müssen. Wenn der Quellcode verfügbar ist, ist es relativ einfach, da er auf der Zielplattform neu kompiliert werden kann. Was aber, wenn der Quellcode nicht verfügbar ist und Sie dennoch eine Objektdatei von einem Plattformtyp auf einen anderen portieren müssen? Nun, wenn Sie Linux verwenden, dann macht der Befehl objcopy genau das Erforderliche. In diesem Artikel lernen wir die grundlegende Verwendung dieses Befehls anhand einiger Beispiele kennen.

Da ich nur auf x86_64-Plattformen arbeite, werde ich versuchen, einige plattformneutrale Funktionen dieses Befehls in diesem Tutorial zu behandeln.

Die Syntax dieses Befehls lautet:

objcopy [options] infile [outfile]...

Beachten Sie, dass die „Optionen“ und „Ausgabedatei“ keine obligatorischen Argumente sind, sondern ihre eigene Bedeutung haben.

Beispiele

1. Kopieren Sie einfach die Objektdatei von der Quelle zum Ziel

Betrachten Sie das folgende Beispiel:

$ objcopy test new_test
$

Der obige Befehl kopiert also „test“ in eine neue Datei „new_test“. Beachten Sie, dass „test“ in diesem Fall auf derselben Plattform kompiliert wurde, sodass sich die Ausgabe „new_test“ nicht unterscheidet.

Wenn Sie eine Binärdatei disassemblieren und mehr Details zu Ihren Objektdateien erhalten möchten, sollten Sie den objdump-Befehl verwenden, wie wir zuvor erklärt haben.

2. Kopieren Sie die Objektdatei, ohne den neuen Dateinamen anzugeben

Im obigen Beispiel wurde die kopierte Datei „new_test“ genannt, da sie zusammen mit Optionen für den Befehl bereitgestellt wurde. Wenn jedoch kein Zieldateiname angegeben wird, ersetzt der objcopy-Befehl die Originaldatei durch die kopierte Datei.

Betrachten Sie das folgende Beispiel:

$ 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

Wir sehen also, dass die Statistik der Objektdatei „test“ komplett geändert wurde, da objcopy sie als komplett neue Datei erstellt hat.

3. Kopieren Sie nur einen bestimmten Abschnitt mit der Option -j

Wenn Sie nur einen Abschnitt von der Quellobjektdatei in die Zielobjektdatei kopieren möchten, wird in diesem Fall die Option -j verwendet.

Betrachten Sie das folgende Beispiel:

$ objcopy -j.interp test new_test
$

Der obige Befehl kopiert tatsächlich nur den .interp-Abschnitt in die leere new_test-Datei.

Wenn wir es bestätigen:

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

Wir sehen also, dass diese Datei nur den .interp-Abschnitt enthält (den wir von ‚test‘ kopiert haben).

4. Entfernen Sie nur einen bestimmten Abschnitt aus der kopierten Datei mit der Option -R

Diese Option lässt den objdump-Befehl die komplette Quelldatei außer den Abschnitten kopieren, die zusammen mit dieser Option angegeben werden.

Betrachten Sie das folgende Beispiel:

$ objcopy -R.interp test new_test

Wenn wir bestätigen:

$ objdump -s -j.interp new_test 

new_test:     file format elf64-x86-64

Wir sehen also, dass sich in der neuen Datei „new_test“ kein .interp-Abschnitt befindet.

5. Bewahren Sie die Zugriffs- und Änderungsdaten mit der Option -p auf

Die Zugriffs- und Änderungsdaten der kopierten Datei können beibehalten werden (können gleich wie die Quelle bleiben), indem Sie die Option -p zusammen mit diesem Befehl verwenden.

Betrachten Sie das folgende Beispiel:

$ objcopy -p test new_tst

Der obige Befehl behält das Zugriffs- und Änderungsdatum/-zeit bei.

Wenn wir bestätigen:

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

Wir sehen also, dass sowohl Zugriffs- als auch Änderungszeit/-datum beibehalten wurden.

6. Ändern Sie alle globalen Symbole mit der Option –weaken

auf schwach

Dies kann beim Erstellen einer Objektdatei nützlich sein, die mit anderen Objektdateien verknüpft werden kann, indem die Option -R für den Linker verwendet wird.

Betrachten Sie das folgende Beispiel:

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

Wir sehen also, dass nach dem Ausführen des Befehls objcopy mit dem Flag –weaken alle GLOBAL-Symbole in WEAK konvertiert wurden.

7. Stellen Sie Symbole mit einer Zeichenfolge voran, indem Sie die Option –prefix-symbols

verwenden

Betrachten Sie das folgende Beispiel, in dem eine Zeichenfolge „TGS“ vor Symbolnamen vorangestellt werden soll:

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

Wir sehen also, dass „TGS“ vor Symbolnamen vorangestellt wurde.

8. Entfernen Sie ein bestimmtes Symbol mit der Option –strip-symbols

Falls einige Symbole entfernt werden müssen, kann die Option –strip-symbols zusammen mit einem Dateinamen verwendet werden. Dieser Dateiname enthält die zu entfernenden Symbolnamen (einer in jeder Zeile).

Betrachten Sie das folgende Beispiel, in dem der Symbolname „call_gmon_start“ entfernt wird, wie er in einer Datei angegeben ist (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
    ...

Wir sehen also, dass das Symbol „call_gmon_start“ erfolgreich entfernt wurde.

9. Stellen Sie den Abschnittsnamen eine Zeichenfolge voran, indem Sie die Option –prefix-sections

verwenden

Betrachten Sie das folgende Beispiel:

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

Wir sehen also, dass dem Abschnittsnamen unsere bereitgestellte Zeichenfolge TGS.

vorangestellt wurde

10. Behalten Sie das Symbol des Quelldateinamens mit der Option –keep-file-symbols

bei

Immer wenn das –strip-debug-Symbol verwendet wird (das viele Debugging-bezogene Symbole zusammen mit dem Symbol, das den Dateinamen angibt), verwendet wird, wenn es notwendig ist, das Symbol für den Quelldateinamen beizubehalten, kann –keep-file-symbols verwendet werden.

Betrachten Sie das folgende Beispiel:

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

Im obigen Beispiel wurde zunächst objcopy mit der Option –strip-debug ausgeführt, die (zusammen mit vielen anderen Symbolen) das Symbol entfernte, das den Namen der Quelldatei (test.c) erwähnte. Als nächstes führen wir den Befehl objcopy zusammen mit der Option –keep-file-symbols erneut aus und stellen fest (in Fettschrift), dass das Symbol für den Quelldateinamen nicht entfernt wurde.


Linux
  1. 5 Wget-Befehlsbeispiele zum Herunterladen von Dateien unter Linux.

  2. 6 mv-Befehlsbeispiele zum Verschieben oder Umbenennen von Linux-Dateien und -Verzeichnissen

  3. Wie kopiert man Dateien unter Linux und Unix? 10 cp Befehlsbeispiele

  4. ln-Befehlsbeispiele in Linux

  5. file Befehlsbeispiele in Linux

So verschieben Sie Dateien und Verzeichnisse in Linux (mv-Befehl)

Cp-Befehl in Linux (Dateien kopieren)

lsof-Befehl unter Linux (10 Beispiele)

So kopieren Sie Dateien und Verzeichnisse im Linux-Terminal

Cat-Befehl in Linux:Wesentliche und erweiterte Beispiele

Linux-tar-Befehl zum Komprimieren und Extrahieren von Dateien