web-dev-qa-db-ja.com

gccmingwを使用したバイナリブロブの埋め込み

バイナリブロブをexeファイルに埋め込もうとしています。私はmingwgccを使用しています。

オブジェクトファイルを次のように作成します。

ld -r -b binary -o binary.o input.txt

次に、objdumpの出力を調べて、シンボルを取得します。

objdump -x binary.o

そしてそれは名前のシンボルを与えます:

_binary_input_txt_start
_binary_input_txt_end
_binary_input_txt_size

次に、Cプログラムでそれらにアクセスしようとします。

#include <stdlib.h>
#include <stdio.h>

extern char _binary_input_txt_start[];

int main (int argc, char *argv[])
{
    char *p;
    p = _binary_input_txt_start;

    return 0;
}

次に、次のようにコンパイルします。

gcc -o test.exe test.c binary.o

しかし、私はいつも得ます:

undefined reference to _binary_input_txt_start

誰かが私が間違っていることを知っていますか?

47
myforwik

Cプログラムで、先頭の下線を削除します。

#include <stdlib.h>
#include <stdio.h>

extern char binary_input_txt_start[];

int main (int argc, char *argv[])
{
    char *p;
    p = binary_input_txt_start;

    return 0;
}

Cコンパイラは、多くの場合(常に?)extern名の前にアンダースコアを付けるようです。それがなぜなのか完全にはわかりません-私はいくつかの真実があると思います このウィキペディアの記事の それを主張する

Cコンパイラでは、ランタイム言語サポートからの寄与との衝突を回避するために、すべての外部スコーププログラム識別子の前に先頭の下線を付けるのが一般的でした。

しかし、すべての外部にアンダースコアが付加されている場合は、名前空間をあまり分割していないことに気づきます。とにかく、それは別の日の質問です、そして実際にはアンダースコアが追加されます。

31
Michael Burr

Linux(Ubuntu 10.10)でテストしました。

  1. リソースファイル:
    input.txt

  2. gcc(Ubuntu/Linaro 4.4.4-14ubuntu5)4.4.5 [Linux用のELF実行可能ファイルを生成します]
    シンボルを生成します_binary__input_txt_start
    記号を受け入れる_binary__input_txt_start(下線付き)。

  3. i586-mingw32msvc-gcc(GCC)4.2.1-sjlj(mingw32-2)[Windows用のPE実行可能ファイルを生成します]
    シンボルを生成します_binary__input_txt_start
    記号を受け入れるbinary__input_txt_start(下線なし)。

5
user1742529

から ld man page

-leading-underscore

-no-leading-underscore

ほとんどのターゲットでは、デフォルトのシンボルプレフィックスはアンダースコアであり、ターゲットの説明で定義されています。このオプションにより、デフォルトのアンダースコア記号プレフィックスを無効/有効にすることができます。

そう

ld -r -b binary -o binary.o input.txt --leading-underscore

解決策でなければなりません。

4
Matěj Pokorný

どうやらこの機能はOSXのldには存在しないので、追加するカスタムgccフラグを使用して実行する必要があります まったく異なる データを直接参照することはできませんが、ランタイムの初期化を行う必要がありますアドレスを取得します。

したがって、ビルド時にバイナリを含むアセンブラソースファイルを自分で作成する方が移植性が高い可能性があります。la この回答

0
Josh Grams