glibc - 强制函数调用(无内联扩展)

时间:2012-01-25 14:20:01

标签: c gcc inline glibc

我有一个关于glibc函数调用的问题。是否有一个标志告诉gcc不要内联某个glibc函数,例如的memcpy?

我已尝试过-fno-builtin-memcpy和其他标志,但它们没有用。目标是调用实际的glibc memcpy函数并且没有内联代码(因为编译时的glibc版本与运行时的glibc版本不同)。它仅用于测试目的。通常我不会这样做。

任何解决方案?

更新:

只是为了让它更清晰:在过去,memcpy即使在重叠区域也能正常工作。这已经发生了变化,我可以在使用不同的glibc版本进行编译时看到这种变化。所以现在我想测试我的旧代码(使用memmove应该使用memmove)是否在具有更新glibc(例如2.14)的系统上正常工作。但要做到这一点,我必须确保调用新的memcpy并且没有内联代码。

祝你好运

3 个答案:

答案 0 :(得分:3)

这可能不是您正在寻找的,但它似乎迫使gcc生成对memcpy()间接调用:

#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足够聪明地认识到间接调用总是调用memcpy(),然后可以用movl指令替换。

请注意,编译器可以识别出memcpy_ptr == NULL,然后行为未定义,再次使用直接调用替换间接调用,然后使用movl指令。带有-O3的gcc 4.5.2似乎并不那么聪明。如果是gcc的更高版本,则可以将memcpy_ptr = NULL替换为某些实际函数的赋值,其行为与memcpy()不同。

答案 1 :(得分:2)

理论上:

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

但是你说-fno-builtin-memcpy没有阻止编译器内联它,所以没有明显的理由说明为什么它应该更好。

答案 2 :(得分:0)

#undef memcpy
#define mempcy your_memcpy_replacement

位于顶部但在#include明显

之后

将your_memcpy_replacement标记为属性((noinline))