2

acプログラムをc++に変換しようとしています。このプログラムは、llvmによって生成された別のプログラムで使用される「*.so」ファイルのセットを生成します。基本的に、llvmで生成されたコードには、現在のコードへのコールバックがあります。LDPRELOADを使用してこれらをロードしています

最初のステップとして、c++でコードをコンパイルしています。コンパイルは正常に機能していました。しかし、実行すると、segfaultsになります。dec_blk関数のアドレスを含むはずのラベルがありますdec_blk()。私はextern "C"その関数とそのプロトタイプを使用して、解きほぐしを防ぎます。cバージョンで実行すると、ラベルのアドレスは正しくなりますが、c ++バージョンで実行すると、そのラベルの値は0になります。以下に詳細を示します。

LLVMコード

subq    $24, %rsp
movq    dec_blk, %rax
movq    dec_blk+8, %rcx
movq    %rdi, 16(%rsp)
movq    %rcx, %rdi
movq    16(%rsp), %rcx
movq    %rsi, 8(%rsp)
movq    %rcx, %rsi
movq    8(%rsp), %rdx
callq   *%rax # segfaults here

関数宣言

extern "C"
{
long int dec_blk(void*, long int*, long int* );
}

何を探すべきか手伝っていただけませんか。gdbを使用してデバッグしています

4

1 に答える 1

0

関数 dec_blk() のアドレスを含むことになっているラベル dec_blk があります。...しかし、C++バージョンで実行すると、そのラベルの値は0です

説明は次のコードと一致します (表示されませんでした):

extern "C" long int dec_blk(...);
int main() {
  return dec_blk();
}

しかし、あなたの質問の逆アセンブリは、代わりにこの(別の)コードと一致します:

extern "C" long int (*dec_blk)(...);
int main() {
  return dec_blk();
}

これら 2 つのスニペットはまったく同じではありません。最初の関数を使用するつもりだったときに、2 番目の関数を使用したと推測しています。

于 2013-02-25T16:43:15.713 に答える