2009-10-30 8 views
28

gccが自己完結型ソースファイルからフラットバイナリファイルを生成するようにする一連のコマンドラインオプションがありますか?たとえば、foo.cの内容がgccにrawバイナリを出力させる方法はありますか?

static int f(int x) 
{ 
    int y = x*x; 
    return y+2; 
} 

であるとし、リンカーには何もエクスポートしないとします。私はこの機能のための機械命令だけで、他の装飾なしで小さなファイルを取得したいと思います。 32ビット保護モードを除く、一種の(DOS).COMファイル。

+1

2つの細かい回答が同時に送信されました。私は、どちらにチェックマークを付けるか分からない。 –

+0

あなたの質問に直接答える[より最近の回答](純粋なコンパイラ/リンカーの回答)を受け入れることを検討できます(http://stackoverflow.com/a/23502466/1483676)。 – cubuspl42

答えて

30

これを試してみてください:

$ cc -c test.c 
$ objcopy -O binary test.o binfile 

をあなたはそれがobjdumpで正しいだことを確認することができます

$ objdump -d test.o 
test.o:  file format pe-i386 


Disassembly of section .text: 

00000000 <_f>: 
    0: 55      push %ebp 
    1: 89 e5     mov %esp,%ebp 
    3: 83 ec 04    sub $0x4,%esp 
    6: 8b 45 08    mov 0x8(%ebp),%eax 
    9: 0f af 45 08    imul 0x8(%ebp),%eax 
    d: 89 45 fc    mov %eax,-0x4(%ebp) 
    10: 8b 45 fc    mov -0x4(%ebp),%eax 
    13: 83 c0 02    add $0x2,%eax 
    16: c9      leave 
    17: c3      ret 

とバイナリファイルと比較:

$ hexdump -C binfile 
00000000 55 89 e5 83 ec 04 8b 45 08 0f af 45 08 89 45 fc |U......E...E..E.| 
00000010 8b 45 fc 83 c0 02 c9 c3       |.E......| 
00000018 
+1

正しい結果を得るために、 'objcopy'のパラメータとして' -j .text'を含める必要がありました。 – SpellingD

+0

なぜですか?あなたがしなかったとき何が起こったのですか? –

+0

.oファイルから間違った(.textではなく)セクションをコピーしました。バージョン: 'GNU objcopy version 2.22.52.0.1-10.fc17 20120131' – SpellingD

15

objcopyを使用すると、テキストセグメントを.oファイルまたはa.outファイルから取り出すことができます。

$ cat q.c 
f() {} 
$ cc -S -O q.c 
$ cat q.s 
     .file "q.c" 
     .text 
.globl f 
     .type f, @function 
f: 
     pushl %ebp 
     movl %esp, %ebp 
     popl %ebp 
     ret 
     .size f, .-f 
     .ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3" 
     .section  .note.GNU-stack,"",@progbits 
$ cc -c -O q.c 
$ objcopy -O binary q.o q.bin 
$ od -X q.bin 
0000000 5de58955 000000c3 
0000005 
$ objdump -d q.o 
q.o:  file format elf32-i386 
Disassembly of section .text: 
00000000 <f>: 
    0: 55      push %ebp 
    1: 89 e5     mov %esp,%ebp 
    3: 5d      pop %ebp 
    4: c3      ret  
+1

あなたはリンクを失ったようです。 –

+0

固定、ありがとう.... – DigitalRoss

11

他答えは間違いない行く道。しかし、出力を期待どおりにするためには、objcopyに追加のコマンドライン引数を指定する必要がありました。私は64ビットマシン上で32ビットコードを開発しているので、-m32引数に注意してください。また、私はintelアセンブリの構文がより好きなので、あなたも引数でそれを見るでしょう。

$ objcopy --only-section=.text --output-target binary test.o test.bin 
$ hexdump -C test.bin 
00000000 55 89 e5 b8 00 00 00 00 5d c3 |U.......].| 
0000000a 

私はこれを考え出した前に、それは私の読書と異なるオプションをしようとして約2時間かかった。

$ cat test.c 
int main() { return 0; } 
$ gcc -nostdinc -m32 -masm=intel -Wall -c test.c -o test.o 
$ objdump --disassemble --disassembler-options intel test.o 

test.o:  file format elf32-i386 


Disassembly of section .text: 

00000000 <main>: 
    0: 55      push ebp 
    1: 89 e5     mov ebp,esp 
    3: b8 00 00 00 00   mov eax,0x0 
    8: 5d      pop ebp 
    9: c3      ret  

OK]をクリックして、ここで私は、具体的にのみ.textセクションを望んでいたことを指定する必要がありましたところです。うまくいけば、これで他の誰かがその時間を節約できます。

9

あなたは-Wl,<linker option>

と直接リンカにオプションを渡すことができ、関連するドキュメントは、リンカにオプションとしてオプション
パスオプション、man gcc

-Wlから下にコピーされます。オプションにコンマが含まれている場合、コンマで複数のオプションに分割されます。 この構文を使用して、オプションに引数を渡すことができます。たとえば、 -Wl、-Map、output.mapは、output.mapをリンカに渡します。 GNUリンカを使用する場合、 -Wl、-Map = output.mapと同じ効果を得ることもできます。

したがって、-Wl,--oformat=binaryを渡すとgccでコンパイルすると、elf形式の代わりにバイナリファイルが生成されます。 --oformat=binaryは、ldにバイナリファイルを生成するよう指示します。

これにより、別途objcopyの必要性がなくなります。

--oformat=binarylinker scriptからOUTPUT_FORMAT("binary")と表現できます。フラットなバイナリを処理したい場合、リンカスクリプトが提供する高度な制御の恩恵を受ける可能性があります。

+0

実際、この答えはここの唯一の正当な答えです...私は他のものが許容可能な回避策であると言います。 – cubuspl42

+0

将来参照するために、 '--oformat = binary'の解決策が間違ったマシンコードを出すように見えるかもしれません。*または*何かを認識していませんが、万が一外的シンボルの動作が奇妙な場合は、 'objcopy'ソリューションです。 – cubuspl42

関連する問題