2012-01-25 9 views
1

glibc関数呼び出しに関する質問があります。 gccに特定のglibc関数をインライン化させないように指示するフラグがありますか? memcpy?glibc - force関数呼び出し(インライン展開なし)

-fno-builtin-memcpyと他のフラグを試しましたが、動作しませんでした。目標は、実際のglibc memcpy関数が呼び出され、インラインコードがないことです(コンパイル時のglibcのバージョンと実行時のglibcのバージョンが異なるため)。これはテスト目的のみのものです。通常、私はそれをしません。

すべてのソリューションはありますか?

UPDATE:

ちょうどそれをより明確にする:過去にはmemcpyのは、オーバーラップ領域でさえも動作します。これは一方で変更され、異なるglibcのバージョンでコンパイルするときにこの変更を見ることができます。だから私は古いコード(memmoveを使ったはずのmemcpyを使ってください)が新しいglibc(例えば2.14)のシステムで正しいかどうかをテストしたいと思います。しかし、これを行うには、新しいmemcpyが呼び出され、インラインコードがないことを確認する必要があります。

敬具理論的には

+0

としてyour_memcpy_replacementをマーク( params ..) ' – osgx

+0

@osgx:これは' memcpy() 'マクロの展開を防ぎますが、実際の関数のインライン展開には影響しません。 –

答えて

2

:その後、

gcc -fno-inline -fno-builtin-inline ... 

しかし、あなたは-fno-builtin-memcpyがそれをインライン化コンパイラを停止していないと述べたので、これは、任意のより良い動作するはず理由は明白な理由はありません。

+0

[GCCマニュアル](http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options)によれば、 '-fno-inline'は、ソースの' inline'キーワードを無視するために適用されますコード。私は希望するパラメータが '' -fno-builtin'(http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options)と組み合わせた '-fno-inline-functions'だと信じています。html#C-Dialect-Options)。私は 'nm'を使用して、アセンブリのソースコード内の割り込み呼び出しをチェックするのではなくチェックしました。 – mctylr

+0

-fno-inline-functionsと-fno-builtinを使うと、バイナリは小さくなりますので、フラグは効果を持ちますが、プログラムの結果には影響しません(私が期待したように)。 – user1169333

3

これはまさにあなたが探しているものではないかもしれないが、、間接コールmemcpy()に生成するGCCを強制するようだ:

#include <stdio.h> 
#include <string.h> 
#include <time.h> 

// void *memcpy(void *dest, const void *src, size_t n) 

unsigned int x = 0xdeadbeef; 
unsigned int y; 

int main(void) { 
    void *(*memcpy_ptr)(void *, const void *, size_t) = memcpy; 
    if (time(NULL) == 1) { 
     memcpy_ptr = NULL; 
    } 
    memcpy_ptr(&y, &x, sizeof y); 
    printf("y = 0x%x\n", y); 
    return 0; 
} 

生成されたアセンブリを(gccは、Ubuntuの、x86の)が含まれcall *%edx命令。 if (time(NULL) == 1)テストなし

(成功することはありませんが、コンパイラはそれを知らない)、gcc -O3は、間接的な呼び出しは常に、その後movl命令に置き換えることができmemcpy()を呼び出すことを認識してくれています。コンパイラmovl命令で、その後memcpy_ptr == NULLが、その後の動作は未定義であり、場合には、再度直接呼び出しと間接呼び出しを置き換えることを認識し、できること

注意。 gcc 4.5.2と-O3はそれほど巧妙ではないようです。 gccのそれ以降のバージョンがある場合は、を、memcpy()とは異なる動作をする実際の関数の割り当てに置き換えることができます。

上部ではなく、明らかにする#include

後にどこか

+0

コードは機能しますが、目的の効果はありません。 – user1169333

+1

@ user1169333:いいえ、希望の効果はどういうものですか?なぜ間接呼出があなたの要求を満たさないのですか? –

0
#undef memcpy 
#define mempcy your_memcpy_replacement 

とのmemcpy(のparams ...) ``へ(memcpyの) `書き換え属性((NOINLINE))

関連する問題