[cfe-dev] clang: inline asm compatibility with gcc

Stephan Mueller sm at eperm.de
Fri Apr 10 08:33:27 PDT 2015


Hi,

for the Linux kernel development we currently have a discussion about a 
memset(0) helper function that in all cirumstances implement memset(0). See 
[1].

We identified the following differences between gcc and clang. According to 
the clang documentation, clang wants to be highly compatible to gcc. 
Therefore, this issue may be of interest.

/*
 * Tested following code:
 *
 * (1) __asm__ __volatile__("" : "=r" (s) : "0" (s));
 * (2) __asm__ __volatile__("": : :"memory");
 * (3) __asm__ __volatile__("" : "=r" (s) : "0" (s) : "memory");
 *
 * Requred result:
 *
 * gcc -O3: objdump -d shows the following:
 *
 * 0000000000400440 <main>:
 * ...
 *   400469:       48 c7 04 24 00 00 00    movq   $0x0,(%rsp)
 *   400470:       00
 *   400471:       48 c7 44 24 08 00 00    movq   $0x0,0x8(%rsp)
 *   400478:       00 00
 *   40047a:       c7 44 24 10 00 00 00    movl   $0x0,0x10(%rsp)
 *   400481:       00
 *
 * clang -O3: objdump -d shows the following:
 *
 * 0000000000400590 <main>:
 * ...
 *   4005c3:       c7 44 24 10 00 00 00    movl   $0x0,0x10(%rsp)
 *   4005ca:       00
 *
 *
 * Test results:
 *
 * The following table marks an X when the aforementioned movq/movl code is
 * present (or an invocation of memset at plt) in the object code
 * (i.e. the code we want). Contrary, the table marks - where the code is not
 * present (i.e. the code we do not want):
 *
 *          | BARRIER  | (1) | (2) | (3)
 * ---------+----------+     |     |
 * Compiler |          |     |     |
 * =========+==========+==================
 *                     |     |     |
 * gcc -O0             |  X  |  X  |  X
 *                     |     |     |
 * gcc -O2             |  -  |  X  |  X
 *                     |     |     |
 * gcc -O3             |  -  |  X  |  X
 *                     |     |     |
 * clang -00           |  X  |  X  |  X
 *                     |     |     |
 * clang -02           |  X  |  -  |  X
 *                     |     |     |
 * clang -03           |  -  |  -  |  X
 */

static inline void memset_secure(void *s, int c, size_t n)
{
        memset(s, c, n);
        __asm__ __volatile__("" : "=r" (s) : "0" (s) : "memory");
}

#include <stdio.h>

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

        snprintf(buf, sizeof(buf) - 1, "test");
        printf("%s\n", buf);

        memset_secure(buf, 0, sizeof(buf));
        return 0;
}

[1] https://lkml.org/lkml/2015/4/10/418

Ciao
Stephan



More information about the cfe-dev mailing list