2016-07-01 12 views
4

現在、LLVM's stackmap featureを使用して、基本的なCスタックウォーカーを作成しようとしています。私はスタックマップを生成したので、スタックマップをC関数に渡そうとしていますので、私はそれを扱うことができます。asm/CからのLLVM StackMapsとのリンクエラー

特に、私はスタックウォーカーに__LLVM_StackMapsを渡すのに問題があります。私は、アセンブリ関数からパラメータとして渡す試してみました:

 .text 
    .globl stackHelper 
    .extern stackWalker 
    .extern __LLVM_StackMaps 
stackHelper: 
    mov %rsp, %rdi 
    mov __LLVM_StackMaps, %rsi 
    jmp stackWalker 

私はエラー (.text+0x7): undefined reference to ``__LLVM_StackMaps'を取得します。

objdumpは__LLVM_StackMapsは.textまたは.dataではなく、カスタム.llvm_stackmapsセクションにあります。ここにobjdumpの出力があります:

factorial.o:  file format elf64-x86-64 
factorial.o 
architecture: i386:x86-64, flags 0x00000011: 
HAS_RELOC, HAS_SYMS 
start address 0x0000000000000000 

Sections: 
Idx Name   Size  VMA    LMA    File off Algn 
    0 .text   00000067 0000000000000000 0000000000000000 00000040 2**4 
        CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 
    1 .rodata.str1.1 00000005 0000000000000000 0000000000000000 000000a7 2**0 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    2 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000ac 2**0 
        CONTENTS, READONLY 
    3 .llvm_stackmaps 00000050 0000000000000000 0000000000000000 000000b0 2**3 
        CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA 
    4 .eh_frame  00000050 0000000000000000 0000000000000000 00000100 2**3 
        CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA 
SYMBOL TABLE: 
0000000000000000 l df *ABS* 0000000000000000 factorial.ll 
0000000000000000 l  .llvm_stackmaps 0000000000000000 __LLVM_StackMaps 
0000000000000000 l d .text 0000000000000000 .text 
0000000000000000 l d .rodata.str1.1 0000000000000000 .rodata.str1.1 
0000000000000030 g  F .text 0000000000000037 fact 
0000000000000000 g  F .text 0000000000000023 main 
0000000000000000   *UND* 0000000000000000 printf 
0000000000000000   *UND* 0000000000000000 stackHelper 


RELOCATION RECORDS FOR [.text]: 
OFFSET   TYPE    VALUE 
0000000000000011 R_X86_64_32  .rodata.str1.1 
000000000000001b R_X86_64_PC32  printf-0x0000000000000004 
000000000000004e R_X86_64_PC32  stackHelper-0x0000000000000004 


RELOCATION RECORDS FOR [.llvm_stackmaps]: 
OFFSET   TYPE    VALUE 
0000000000000010 R_X86_64_64  fact 


RELOCATION RECORDS FOR [.eh_frame]: 
OFFSET   TYPE    VALUE 
0000000000000020 R_X86_64_PC32  .text 
0000000000000034 R_X86_64_PC32  .text+0x0000000000000030 

私の推測では、このテーブルのシンボルにアクセスできないと考えられます。私のアセンブリ関数からこのデータにアクセスする方法はありますか、またはリンクステージでこれを正しくアクセスできるようにする必要がありますか?

+0

通常外部にアクセスするには、ライブラリコードに参加するか、共有ライブラリにアクセスしてリンクする必要があります。また、変数名の先頭に正しいアンダースコア数があることを確認してください。それはしばしば人々を動かすことができます。 – querist

+0

正しいアンダースコア数はいくつですか? スクリプトを一緒にリンクしようとすると、定義されていない参照のエラーが発生しています。アセンブリの異なるセクションのデータにアクセスする方法はありますか? – AbelianGrape

+1

セクションは、目に見える記号であれば問題ありません。もっとよく聞こえるのは、何もかもが「.mov」なので – Jester

答えて

4

問題@Jesterが指摘するように、シンボルがローカルマークされていることであるので、それはで表示されるファイルにのみ表示されます。最初の列のアドレスの後

0000000000000000 l  .llvm_stackmaps 0000000000000000 __LLVM_StackMaps 

lシンボルがLOCALであることを意味します。 gは、それがGLOBALであり、外部オブジェクトに見えることを意味します。

あなたは、あなたが直接オブジェクトファイル内のシンボルの可視性を変更するobjcopyをを使用することができ、ソースコードを非静的であることを階乗でシンボルを変更できない場合は、次の

objcopy --globalize-symbol=__LLVM_StackMaps factorial.o factorial.o 

最初のオブジェクトファイルfactorial.oが処理する入力ファイルで、2番目のファイルfactorial.oが出力ファイルです。必要に応じて、別の出力オブジェクトを指定することができます。私の例では、元のfactorial.oを上書きしています。 --globalize-symbolOBJCOPY documentationように記述されている

0000000000000000 g  .llvm_stackmaps 0000000000000000 __LLVM_StackMaps 

オプション:結果factorial.oは今のようなものに見えるエントリーが必要です

--globalizeシンボル=にSymbolNameを

シンボルsymbolnameグローバルスコープを与え、それが定義されているファイルの外に見えるようにします。このオプションは複数回指定できます。

+1

素晴らしい、これは働いた。ありがとうございました。 – AbelianGrape