Skip to content

Instantly share code, notes, and snippets.

@tianyicui
Created January 1, 2011 16:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tianyicui/761825 to your computer and use it in GitHub Desktop.
Save tianyicui/761825 to your computer and use it in GitHub Desktop.
#include <string.h>
void gao(char *src, char *dst, int count) {
memcpy(dst, src, count);
}
.section __TEXT,__text,regular,pure_instructions
.globl _gao
.align 4, 0x90
_gao: ## @gao
## BB#0:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movb $1, %al
testb %al, %al
movl 16(%ebp), %eax
movl 12(%ebp), %ecx
movl 8(%ebp), %edx
movl %eax, 8(%esp)
movl %edx, 4(%esp)
movl %ecx, (%esp)
calll _memcpy
addl $24, %esp
popl %ebp
ret
.subsections_via_symbols
# 1 "memcpy.c"
# 1 "memcpy.c" 1
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 138 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "memcpy.c" 2
# 1 "/usr/include/string.h" 1 3 4
# 60 "/usr/include/string.h" 3 4
# 1 "/usr/include/_types.h" 1 3 4
# 27 "/usr/include/_types.h" 3 4
# 1 "/usr/include/sys/_types.h" 1 3 4
# 32 "/usr/include/sys/_types.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 33 "/usr/include/sys/_types.h" 2 3 4
# 1 "/usr/include/machine/_types.h" 1 3 4
# 34 "/usr/include/machine/_types.h" 3 4
# 1 "/usr/include/i386/_types.h" 1 3 4
# 37 "/usr/include/i386/_types.h" 3 4
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef short __int16_t;
typedef unsigned short __uint16_t;
typedef int __int32_t;
typedef unsigned int __uint32_t;
typedef long long __int64_t;
typedef unsigned long long __uint64_t;
typedef long __darwin_intptr_t;
typedef unsigned int __darwin_natural_t;
# 70 "/usr/include/i386/_types.h" 3 4
typedef int __darwin_ct_rune_t;
typedef union {
char __mbstate8[128];
long long _mbstateL;
} __mbstate_t;
typedef __mbstate_t __darwin_mbstate_t;
typedef long int __darwin_ptrdiff_t;
typedef long unsigned int __darwin_size_t;
typedef __builtin_va_list __darwin_va_list;
typedef int __darwin_wchar_t;
typedef __darwin_wchar_t __darwin_rune_t;
typedef int __darwin_wint_t;
typedef unsigned long __darwin_clock_t;
typedef __uint32_t __darwin_socklen_t;
typedef long __darwin_ssize_t;
typedef long __darwin_time_t;
# 35 "/usr/include/machine/_types.h" 2 3 4
# 34 "/usr/include/sys/_types.h" 2 3 4
# 58 "/usr/include/sys/_types.h" 3 4
struct __darwin_pthread_handler_rec
{
void (*__routine)(void *);
void *__arg;
struct __darwin_pthread_handler_rec *__next;
};
struct _opaque_pthread_attr_t { long __sig; char __opaque[56]; };
struct _opaque_pthread_cond_t { long __sig; char __opaque[40]; };
struct _opaque_pthread_condattr_t { long __sig; char __opaque[8]; };
struct _opaque_pthread_mutex_t { long __sig; char __opaque[56]; };
struct _opaque_pthread_mutexattr_t { long __sig; char __opaque[8]; };
struct _opaque_pthread_once_t { long __sig; char __opaque[8]; };
struct _opaque_pthread_rwlock_t { long __sig; char __opaque[192]; };
struct _opaque_pthread_rwlockattr_t { long __sig; char __opaque[16]; };
struct _opaque_pthread_t { long __sig; struct __darwin_pthread_handler_rec *__cleanup_stack; char __opaque[1168]; };
# 94 "/usr/include/sys/_types.h" 3 4
typedef __int64_t __darwin_blkcnt_t;
typedef __int32_t __darwin_blksize_t;
typedef __int32_t __darwin_dev_t;
typedef unsigned int __darwin_fsblkcnt_t;
typedef unsigned int __darwin_fsfilcnt_t;
typedef __uint32_t __darwin_gid_t;
typedef __uint32_t __darwin_id_t;
typedef __uint64_t __darwin_ino64_t;
typedef __darwin_ino64_t __darwin_ino_t;
typedef __darwin_natural_t __darwin_mach_port_name_t;
typedef __darwin_mach_port_name_t __darwin_mach_port_t;
typedef __uint16_t __darwin_mode_t;
typedef __int64_t __darwin_off_t;
typedef __int32_t __darwin_pid_t;
typedef struct _opaque_pthread_attr_t
__darwin_pthread_attr_t;
typedef struct _opaque_pthread_cond_t
__darwin_pthread_cond_t;
typedef struct _opaque_pthread_condattr_t
__darwin_pthread_condattr_t;
typedef unsigned long __darwin_pthread_key_t;
typedef struct _opaque_pthread_mutex_t
__darwin_pthread_mutex_t;
typedef struct _opaque_pthread_mutexattr_t
__darwin_pthread_mutexattr_t;
typedef struct _opaque_pthread_once_t
__darwin_pthread_once_t;
typedef struct _opaque_pthread_rwlock_t
__darwin_pthread_rwlock_t;
typedef struct _opaque_pthread_rwlockattr_t
__darwin_pthread_rwlockattr_t;
typedef struct _opaque_pthread_t
*__darwin_pthread_t;
typedef __uint32_t __darwin_sigset_t;
typedef __int32_t __darwin_suseconds_t;
typedef __uint32_t __darwin_uid_t;
typedef __uint32_t __darwin_useconds_t;
typedef unsigned char __darwin_uuid_t[16];
typedef char __darwin_uuid_string_t[37];
# 28 "/usr/include/_types.h" 2 3 4
# 39 "/usr/include/_types.h" 3 4
typedef int __darwin_nl_item;
typedef int __darwin_wctrans_t;
typedef __uint32_t __darwin_wctype_t;
# 61 "/usr/include/string.h" 2 3 4
typedef __darwin_size_t size_t;
typedef __darwin_ssize_t ssize_t;
# 81 "/usr/include/string.h" 3 4
void *memchr(const void *, int, size_t);
int memcmp(const void *, const void *, size_t);
void *memcpy(void *, const void *, size_t);
void *memmove(void *, const void *, size_t);
void *memset(void *, int, size_t);
char *stpcpy(char *, const char *);
char *strcasestr(const char *, const char *);
char *strcat(char *, const char *);
char *strchr(const char *, int);
int strcmp(const char *, const char *);
int strcoll(const char *, const char *);
char *strcpy(char *, const char *);
size_t strcspn(const char *, const char *);
char *strerror(int) __asm("_" "strerror" );
int strerror_r(int, char *, size_t);
size_t strlen(const char *);
char *strncat(char *, const char *, size_t);
int strncmp(const char *, const char *, size_t);
char *strncpy(char *, const char *, size_t);
char *strnstr(const char *, const char *, size_t);
char *strpbrk(const char *, const char *);
char *strrchr(const char *, int);
size_t strspn(const char *, const char *);
char *strstr(const char *, const char *);
char *strtok(char *, const char *);
size_t strxfrm(char *, const char *, size_t);
void *memccpy(void *, const void *, int, size_t);
char *strtok_r(char *, const char *, char **);
char *strdup(const char *);
int bcmp(const void *, const void *, size_t);
void bcopy(const void *, void *, size_t);
void bzero(void *, size_t);
int ffs(int);
int ffsl(long);
int fls(int);
int flsl(long);
char *index(const char *, int);
void memset_pattern4(void *, const void *, size_t);
void memset_pattern8(void *, const void *, size_t);
void memset_pattern16(void *, const void *, size_t);
char *rindex(const char *, int);
int strcasecmp(const char *, const char *);
size_t strlcat(char *, const char *, size_t);
size_t strlcpy(char *, const char *, size_t);
void strmode(int, char *);
int strncasecmp(const char *, const char *, size_t);
char *strsep(char **, const char *);
char *strsignal(int sig);
void swab(const void * restrict, void * restrict, ssize_t);
# 148 "/usr/include/string.h" 3 4
# 1 "/usr/include/secure/_string.h" 1 3 4
# 32 "/usr/include/secure/_string.h" 3 4
# 1 "/usr/include/secure/_common.h" 1 3 4
# 33 "/usr/include/secure/_string.h" 2 3 4
# 55 "/usr/include/secure/_string.h" 3 4
static __inline void *
__inline_memcpy_chk (void *__dest, const void *__src, size_t __len)
{
return __builtin___memcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0));
}
static __inline void *
__inline_memmove_chk (void *__dest, const void *__src, size_t __len)
{
return __builtin___memmove_chk (__dest, __src, __len, __builtin_object_size (__dest, 0));
}
static __inline void *
__inline_memset_chk (void *__dest, int __val, size_t __len)
{
return __builtin___memset_chk (__dest, __val, __len, __builtin_object_size (__dest, 0));
}
static __inline char *
__inline_strcpy_chk (char *restrict __dest, const char *restrict __src)
{
return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
}
static __inline char *
__inline_stpcpy_chk (char *__dest, const char *__src)
{
return __builtin___stpcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
}
static __inline char *
__inline_strncpy_chk (char *restrict __dest, const char *restrict __src,
size_t __len)
{
return __builtin___strncpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 2 > 1));
}
static __inline char *
__inline_strcat_chk (char *restrict __dest, const char *restrict __src)
{
return __builtin___strcat_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
}
static __inline char *
__inline_strncat_chk (char *restrict __dest, const char *restrict __src,
size_t __len)
{
return __builtin___strncat_chk (__dest, __src, __len, __builtin_object_size (__dest, 2 > 1));
}
# 149 "/usr/include/string.h" 2 3 4
# 2 "memcpy.c" 2
void gao(char *src, char *dst, int count) {
((__builtin_object_size (dst, 0) != (size_t) -1) ? __builtin___memcpy_chk (dst, src, count, __builtin_object_size (dst, 0)) : __inline_memcpy_chk (dst, src, count));
}
@tianyicui
Copy link
Author

This is compiled using clang trunk (issue is reproducible in release 2.8) using on Mac OS X 10.6:

clang -m32 -O3 -S memcpy.c

I don't understand the link 9 and 10 in the generated x86 assembly. Why are they there? Can this be considered as a bug of clang or llvm?

The configure parameters are --disable-assertions --enable-libffi --enable-optimized --enable-shared --enable-targets=all.

@tianyicui
Copy link
Author

BTW, the assembly code generated by apple-gcc 4.2:

    .text
    .align 4,0x90
.globl _gao
_gao:
    pushl   %ebp
    movl    %esp, %ebp
    movl    12(%ebp), %edx
    movl    8(%ebp), %eax
    movl    %eax, 12(%ebp)
    movl    %edx, 8(%ebp)
    leave
    jmp _memcpy
    .subsections_via_symbols

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment