1

I have a question regarding glibc function calls. Is there a flag to tell gcc not to inline a certain glibc function, e.g. memcpy?

I've tried -fno-builtin-memcpy and other flags, but they didn't work. The goal is that the actual glibc memcpy function is called and no inlined code (since the glibc version at compile time differs from the one at runtime). It's for testing purposes only. Normally I wan't do that.

Any solutions?

UPDATE:

Just to make it clearer: In the past memcpy works even with overlapping areas. This has changed meanwhile and I can see this changes when compiling with different glibc versions. So now I want to test if my old code (using memcpy where memmove should have been used) works correct or not on a system with a newer glibc (e.g. 2.14). But to do that, I have to make sure, that the new memcpy is called and no inlined code.

Best regards

3 Answers3

3

This may not be exactly what you're looking for, but it seems to force gcc to generate an indirect call to 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;
}

The generated assembly (gcc, Ubuntu, x86) includes a call *%edx instruction.

Without the if (time(NULL) == 1) test (which should never succeed, but the compiler doesn't know that), gcc -O3 is clever enough to recognize that the indirect call always calls memcpy(), which can then be replaced by a movl instruction.

Note that the compiler could recognize that if memcpy_ptr == NULL then the behavior is undefined, and again replace the indirect call with a direct call, and then with a movl instruction. gcc 4.5.2 with -O3 doesn't appear to be that clever. If a later version of gcc is, you could replace the memcpy_ptr = NULL with an assignment of some actual function that behaves differently than memcpy().

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

In theory:

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

But then you said -fno-builtin-memcpy didn't stop the compiler from inlining it, so there's no obvious reason why this should work any better.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    According the [GCC manual](http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options) the `-fno-inline` applies to ignoring the `inline` keyword in the source code. I believe the desired parameter is `-fno-inline-functions` combined with [`-fno-builtin`](http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options). I checked using `nm` rather than checking the interrupt calls in the assembly source code. – mctylr Jan 25 '12 at 22:32
  • With -fno-inline-functions and -fno-builtin the binary becomes smaller so the flags had an effect but not on the result of the program (as I would expect). – user1169333 Jan 26 '12 at 09:01
0
#undef memcpy
#define mempcy your_memcpy_replacement

Somewhere at the top but after #include obviously

And mark your_memcpy_replacement as attribute((noinline))

Pierre Habouzit
  • 690
  • 4
  • 6