2011-02-03 2 views
3

私は、特別なセクション(__dlog)に文字列を格納することによってELF実行可能ファイルにメタデータを追加しようとしています。現在のアプローチでは、文字列を格納するためにインラインアセンブリを使用し(乱用する)、ほぼ必要に応じて動作します。インラインアセンブリで__func__を使用する方法

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

#define DLOG(proto...) \ 
     __asm__(".pushsection __dlog, \"S\", @note\n\t" \ 
       ".asciz \"" __FILE__ ":function_name_here:" #proto "\"\n\t" \ 
       ".popsection\n\t") 

int 
foo(int bar) 
{ 
    int baz = bar/2; 
    DLOG(int baz); 
    return baz; 
} 

int 
main(int argc, char *argv[]) 
{ 
    foo(argc); 
    return EXIT_SUCCESS; 
} 

しかし、理想的には、マクロが自動的に__func__識別子を利用することによって、文字列の一部として、関数名を含める必要があります。最終結果は、__dlogという部分に文字列

file.c:foo:int baz\0 

とする必要があります。 __func__は文字列リテラルではありませんので、しかし、GCCは__func__の内容を文字列に追加取得するにはとにかくがあります。このコード

".asciz \"" __FILE__ ":" __func__ ":" #proto "\"\n\t" 

と不平を言いますか?ソリューションがカスタムビルドオプションや後処理ステップを必要としない場合のボーナスポイント。コンパイラはgcc 4.4と4.5です。

答えて

3

編集:これは動作しているようですが、それは完全に非マングルされた名前を与えるものではありませんが、関数名が

#define DLOG(proto...) \ 
__asm__(".pushsection __dlog, \"S\", @note\n\t" \ 
       ".asciz \"" __FILE__ ":%0:" #proto "\"\n\t" \ 
       ".popsection\n\t" \ 
: \ 
: "s" (__func__)) 


int main(int argc, char*argv[]) { 
DLOG(int argc, char*argv[]); 

return 0; 
} 

extern "C" void test(int bar) { 
DLOG(bar); 
} 

グラム++である - 4.4 TEST.CPP & & XXD a.outの|以下-p TEST.CPP

0001020: 7465 7374 2e63 7070 3a24 5f5a 5a34 6d61 test.cpp:$_ZZ4ma 
0001030: 696e 4538 5f5f 6675 6e63 5f5f 3a69 6e74 inE8__func__:int 
0001040: 2061 7267 632c 2063 6861 722a 6172 6776 argc, char*argv 
0001050: 5b5d 0074 6573 742e 6370 703a 245f 5a5a [].test.cpp:$_ZZ 
0001060: 3474 6573 7445 385f 5f66 756e 635f 5f3a 4testE8__func__: 
0001070: 6261 7200 4743 433a 2028 5562 756e 7475 bar.GCC: (Ubuntu 

オリジナル回答:Cモードを使用してGCC-3.3

__func__const char []のように扱われます。 C++モードの場合、gcc> 3.3の場合、__func__は常に変数です。

これを達成するために、古いバージョンのgccをc-modeで使用できると思います。

あなたはunmangled C++の名前を望んでいた場合は、 `__PRETTY_FUNCTION__`を使用する必要があると思いますまあhttp://gcc.gnu.org/onlinedocs/gcc/Function-Names.html

+0

上の最後の段落を参照してください。 – user562374

+0

@userが動作しません。とにかく 'printf("%s \ n "、__ func __)'は、(関数が 'extern" C "'なので)名前のない名前を表示します。名前を変更しているのはアセンブラです。おそらくそれがdllだった場合(したがって、輸出されたシンボルを保存しなければならない) – KitsuneYMG

+0

nope。 '--shared'は問題を解決しません – KitsuneYMG

関連する問題