Workaround GCC builtin inlining bug

This commit is contained in:
bzt 2021-02-20 16:24:33 +01:00
parent bd5bf74c2d
commit 81a82cf366
7 changed files with 40 additions and 31 deletions

View file

@ -62,7 +62,7 @@ else
ALLTARGETS = uefi/crt_$(ARCH).o uefi/libuefi.a $(OBJS) $(TARGET)
endif
all: $(ALLTARGETS)
all: $(ALLTARGETS) $(EXTRA)
uefi/libuefi.a:
@make --no-print-directory -C uefi libuefi.a USE_GCC=$(USE_GCC) ARCH=$(ARCH)
@ -100,7 +100,7 @@ build:
@cp libuefi.a uefi.h ../build/uefi
clean:
@rm $(TARGET) *.o *.a *.lib $(LIBOBJS) 2>/dev/null || true
@rm $(TARGET) *.o *.a *.lib *.elf $(LIBOBJS) 2>/dev/null || true
distclean: clean
ifeq ($(wildcard uefi/Makefile),)

View file

@ -45,7 +45,7 @@ struct dirent *readdir (DIR *__dirp)
efi_status_t status;
efi_file_info_t info;
uintn_t bs = sizeof(efi_file_info_t);
memset(&__dirent, 0, sizeof(struct dirent));
MEMFNC(memset)(&__dirent, 0, sizeof(struct dirent));
status = __dirp->Read(__dirp, &bs, &info);
if(EFI_ERROR(status) || !bs) {
if(EFI_ERROR(status)) __stdio_seterrno(status);

View file

@ -43,7 +43,7 @@ int stat (const char_t *__file, struct stat *__buf)
}
f = fopen(__file, CL("*"));
if(!f) {
memset(__buf, 0, sizeof(struct stat));
MEMFNC(memset)(__buf, 0, sizeof(struct stat));
return -1;
}
ret = fstat(f, __buf);

View file

@ -73,7 +73,7 @@ int fstat (FILE *__f, struct stat *__buf)
errno = EINVAL;
return -1;
}
memset(__buf, 0, sizeof(struct stat));
MEMFNC(memset)(__buf, 0, sizeof(struct stat));
if(__f == stdin) {
__buf->st_mode = S_IREAD | S_IFIFO;
return 0;
@ -212,7 +212,7 @@ FILE *fopen (const char_t *__filename, const char_t *__modes)
if(__modes[0] == CL('r')) { errno = EPERM; return NULL; }
return stderr;
}
if(!memcmp(__filename, CL("/dev/serial"), 11 * sizeof(char_t))) {
if(!MEMFNC(memcmp)(__filename, CL("/dev/serial"), 11 * sizeof(char_t))) {
par = atol(__filename + 11);
if(!__ser) {
efi_guid_t serGuid = EFI_SERIAL_IO_PROTOCOL_GUID;
@ -222,7 +222,7 @@ FILE *fopen (const char_t *__filename, const char_t *__modes)
__ser->SetAttributes(__ser, par > 9600 ? par : 115200, 0, 1000, NoParity, 8, OneStopBit);
return (FILE*)__ser;
}
if(!memcmp(__filename, CL("/dev/disk"), 9 * sizeof(char_t))) {
if(!MEMFNC(memcmp)(__filename, CL("/dev/disk"), 9 * sizeof(char_t))) {
par = atol(__filename + 9);
if(!__blk_ndevs) {
efi_guid_t bioGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
@ -233,7 +233,7 @@ FILE *fopen (const char_t *__filename, const char_t *__modes)
handle_size /= (uintn_t)sizeof(efi_handle_t);
__blk_devs = (block_file_t*)malloc(handle_size * sizeof(block_file_t));
if(__blk_devs) {
memset(__blk_devs, 0, handle_size * sizeof(block_file_t));
MEMFNC(memset)(__blk_devs, 0, handle_size * sizeof(block_file_t));
for(i = __blk_ndevs = 0; i < handle_size; i++)
if(!EFI_ERROR(BS->HandleProtocol(handles[i], &bioGuid, (void **) &__blk_devs[__blk_ndevs].bio)) &&
__blk_devs[__blk_ndevs].bio && __blk_devs[__blk_ndevs].bio->Media &&

View file

@ -86,7 +86,7 @@ void *malloc (size_t __size)
if(i == __stdlib_numallocs) {
status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __stdlib_numallocs + 2, &ret);
if(EFI_ERROR(status) || !ret) { errno = ENOMEM; return NULL; }
if(__stdlib_allocs) memcpy(ret, __stdlib_allocs, __stdlib_numallocs * sizeof(uintptr_t));
if(__stdlib_allocs) MEMFNC(memcpy)(ret, __stdlib_allocs, __stdlib_numallocs * sizeof(uintptr_t));
__stdlib_allocs = (uintptr_t*)ret;
__stdlib_allocs[i] = __stdlib_allocs[i + 1] = 0;
__stdlib_numallocs += 2;
@ -102,7 +102,7 @@ void *malloc (size_t __size)
void *calloc (size_t __nmemb, size_t __size)
{
void *ret = malloc(__nmemb * __size);
if(ret) memset(ret, 0, __nmemb * __size);
if(ret) MEMFNC(memset)(ret, 0, __nmemb * __size);
return ret;
}
@ -117,8 +117,8 @@ void *realloc (void *__ptr, size_t __size)
status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
if(EFI_ERROR(status) || !ret) { errno = ENOMEM; ret = NULL; }
if(ret) {
memcpy(ret, (void*)__stdlib_allocs[i], __stdlib_allocs[i + 1] < __size ? __stdlib_allocs[i + 1] : __size);
if(__size > __stdlib_allocs[i + 1]) memset(ret + __stdlib_allocs[i + 1], 0, __size - __stdlib_allocs[i + 1]);
MEMFNC(memcpy)(ret, (void*)__stdlib_allocs[i], __stdlib_allocs[i + 1] < __size ? __stdlib_allocs[i + 1] : __size);
if(__size > __stdlib_allocs[i + 1]) MEMFNC(memset)(ret + __stdlib_allocs[i + 1], 0, __size - __stdlib_allocs[i + 1]);
}
BS->FreePool((void*)__stdlib_allocs[i]);
__stdlib_allocs[i] = (uintptr_t)ret;
@ -311,7 +311,7 @@ uint8_t *getenv(char_t *name, uintn_t *len)
*len = 0;
return NULL;
}
memcpy(ret, tmp, *len);
MEMFNC(memcpy)(ret, tmp, *len);
ret[*len] = 0;
return ret;
}

View file

@ -30,9 +30,7 @@
#include <uefi.h>
/* for gcc we use the built-in variants, but clang doesn't have those */
#ifdef __clang__
void *memcpy(void *dst, const void *src, size_t n)
void *MEMFNC(memcpy)(void *dst, const void *src, size_t n)
{
uint8_t *a=(uint8_t*)dst,*b=(uint8_t*)src;
if(src && dst && n>0) {
@ -41,7 +39,7 @@ void *memcpy(void *dst, const void *src, size_t n)
return dst;
}
void *memmove(void *dst, const void *src, size_t n)
void *MEMFNC(memmove)(void *dst, const void *src, size_t n)
{
uint8_t *a=(uint8_t*)dst,*b=(uint8_t*)src;
if(src && dst && n>0) {
@ -54,7 +52,7 @@ void *memmove(void *dst, const void *src, size_t n)
return dst;
}
void *memset(void *s, int c, size_t n)
void *MEMFNC(memset)(void *s, int c, size_t n)
{
uint8_t *p=(uint8_t*)s;
if(s && n>0) {
@ -63,7 +61,7 @@ void *memset(void *s, int c, size_t n)
return s;
}
int memcmp(const void *s1, const void *s2, size_t n)
int MEMFNC(memcmp)(const void *s1, const void *s2, size_t n)
{
uint8_t *a=(uint8_t*)s1,*b=(uint8_t*)s2;
if(s1 && s2 && n>0) {
@ -75,7 +73,7 @@ int memcmp(const void *s1, const void *s2, size_t n)
return 0;
}
void *memchr (const void *s, int c, size_t n)
void *MEMFNC(memchr)(const void *s, int c, size_t n)
{
uint8_t *e, *p=(uint8_t*)s;
if(s && n>0) {
@ -84,7 +82,7 @@ void *memchr (const void *s, int c, size_t n)
return NULL;
}
void *memrchr (const void *s, int c, size_t n)
void *MEMFNC(memrchr)(const void *s, int c, size_t n)
{
uint8_t *e, *p=(uint8_t*)s;
if(s && n>0) {
@ -92,7 +90,6 @@ void *memrchr (const void *s, int c, size_t n)
}
return NULL;
}
#endif
void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl)
{
@ -100,7 +97,7 @@ void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl)
if(!haystack || !needle || !hl || !nl || nl > hl) return NULL;
hl -= nl;
while(hl) {
if(!memcmp(c, needle, nl)) return c;
if(!MEMFNC(memcmp)(c, needle, nl)) return c;
c++; hl--;
}
return NULL;
@ -113,7 +110,7 @@ void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl)
hl -= nl;
c += hl;
while(hl) {
if(!memcmp(c, needle, nl)) return c;
if(!MEMFNC(memcmp)(c, needle, nl)) return c;
c--; hl--;
}
return NULL;
@ -178,7 +175,7 @@ char_t *strdup(const char_t *s)
{
int i = (strlen(s)+1) * sizeof(char_t);
char_t *s2 = (char_t *)malloc(i);
if(s2 != NULL) memcpy(s2, (void*)s, i);
if(s2 != NULL) MEMFNC(memcpy)(s2, (void*)s, i);
return s2;
}

View file

@ -1342,12 +1342,24 @@ extern int getchar_ifany (void);
extern int putchar (int __c);
/* string.h */
extern void *memcpy (void *__dest, const void *__src, size_t __n);
extern void *memmove (void *__dest, const void *__src, size_t __n);
extern void *memset (void *__s, int __c, size_t __n);
extern int memcmp (const void *__s1, const void *__s2, size_t __n);
extern void *memchr (const void *__s, int __c, size_t __n);
extern void *memrchr (const void *__s, int __c, size_t __n);
#ifdef __clang__
#define MEMFNC(a) a
#else
/* workaround an extremely annoying GCC bug with buggy builtins, incorrectly inlined even with -fno-builtin */
#define MEMFNC(a) __uefi_##a
#define memcpy __uefi_memcpy
#define memmove __uefi_memmove
#define memset __uefi_memset
#define memcmp __uefi_memcmp
#define memchr __uefi_memchr
#define memrchr __uefi_memrchr
#endif
extern void *MEMFNC(memcpy) (void *__dest, const void *__src, size_t __n);
extern void *MEMFNC(memmove) (void *__dest, const void *__src, size_t __n);
extern void *MEMFNC(memset) (void *__s, int __c, size_t __n);
extern int MEMFNC(memcmp) (const void *__s1, const void *__s2, size_t __n);
extern void *MEMFNC(memchr) (const void *__s, int __c, size_t __n);
extern void *MEMFNC(memrchr) (const void *__s, int __c, size_t __n);
void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl);
void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl);
extern char_t *strcpy (char_t *__dest, const char_t *__src);