‘Binary Hacks’의 hack #11에는 objcopy를 이용해서 실행파일에 binary를 추가하는 방법이 나온다. 이것을 따라 64 bits machine에서 build하면 i386:x86-64 출력물과 i386 출력물이 incompatible 해서 link할 수 없다는 오류가 발생한다.
$> objcopy -I binary -O elf32-i386 -B i386 binary.bmp binary.o $> gcc -c main.c $> gcc -o program main.o binary.o /usr/bin/ld: i386 architecture of input file 'binary.o' is incompatible with i386:x86-64 output collect2: error: ld returned 1 exit status
gcc로 만들어진 main.o는 ELF-64 format인데 objcopy로 생성한 ELF-32 format이어서 함께 link할 수 없다는 것이다. 이 문제는 동일한 ELF format이 되도록 하면 해결된다. 즉, gcc로 compile한 결과물이 objcopy의 결과물인 ELF-32와 동일하게 되도록 하거나 objcopy의 결과 물이 main.o와 동일한 ELF-64가 되도록 해야한다.
첫번째 방법 – ELF-32 format으로 object를 compile
gcc에 -m32 option을 추가하면 ELF32로 compile된 object file을 얻을 수 있다. 이것을 objcopy의 결과 물과 link한다.
$> objcopy -I binary -O elf32-i386 -B i386 binary.bmp binary.o $> gcc -m32 -c main.c $> gcc -m32 -o program main.o binary.o
두번째 방법 – ELF-64 format으로 binary를 생성
objcopy가 ELF64를 생성하도록 하면 gcc로 compile한 다른 object file들과 link할 수 있다.
$> objcopy -I binary -O elf64-x86-64 -B i386 binary.bmp binary.o $> gcc -c main.c $> gcc -o program main.o binary.o
* objcopy로 생성된 ELF object에서 담고 있는 symbol의 목록은 nm 명령어나 readelf -s option으로 볼 수 있다.
$> nm binary.o 00000000002fd036 D _binary_binary_bmp_end 00000000002fd036 A _binary_binary_bmp_size 0000000000000000 D _binary_binary_bmp_start $>readelf -s binary.o Symbol table '.symtab' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 _binary_binary_bmp_start 3: 00000000002fd036 0 NOTYPE GLOBAL DEFAULT 1 _binary_binary_bmp_end 4: 00000000002fd036 0 NOTYPE GLOBAL DEFAULT ABS _binary_binary_bmp_size