diff --git a/pcireg/uefi/Makefile b/pcireg/uefi/Makefile index d4bc02c..2210d23 100644 --- a/pcireg/uefi/Makefile +++ b/pcireg/uefi/Makefile @@ -8,8 +8,14 @@ endif ifeq ($(SRCS),) SRCS = $(wildcard *.c) $(wildcard *.S) endif +ifeq ($(OBJS),) TMP = $(SRCS:.c=.o) -OBJS2 = $(TMP:.S=.o) +OBJS = $(TMP:.S=.o) +endif +ifneq ($(OUTDIR),) +# OUTDIR is not used with uefi/*.o deliberately +OUTDIR:=$(addsuffix /,$(OUTDIR)) +endif CFLAGS += -fshort-wchar -fno-strict-aliasing -ffreestanding -fno-stack-protector -fno-stack-check -I. -I./uefi \ -I/usr/include -I/usr/include/efi -I/usr/include/efi/protocol -I/usr/include/efi/$(ARCH) -D__$(ARCH)__ ifeq ($(ARCH),x86_64) @@ -19,10 +25,10 @@ endif # for libuefi.a LIBSRCS = $(filter-out $(wildcard crt_*.c),$(wildcard *.c)) $(wildcard *.S) TMP2 = $(LIBSRCS:.c=.o) -LIBOBJS2 = $(TMP2:.S=.o) +LIBOBJS = $(TMP2:.S=.o) # detect toolchain -ifeq ($(wildcard /usr/bin/clang),) +ifeq ($(wildcard /usr/bin/clang)$(wildcard /usr/local/bin/clang)$(wildcard /usr/lib/llvm/*/bin/clang),) USE_GCC = 1 endif ifneq ($(USE_GCC),) @@ -31,7 +37,7 @@ CFLAGS += -maccumulate-outgoing-args endif CFLAGS += -Wno-builtin-declaration-mismatch -fpic -fPIC LDFLAGS += -nostdlib -shared -Bsymbolic -Luefi uefi/crt_$(ARCH).o -LIBS += -o $(TARGET).so -luefi -T uefi/elf_$(ARCH)_efi.lds +LIBS += -o $(addprefix $(OUTDIR),$(TARGET).so) -luefi -T uefi/elf_$(ARCH)_efi.lds # see if we're cross-compiling ifneq ($(ARCH),$(MYARCH)) CC = $(ARCH)-elf-gcc @@ -51,58 +57,69 @@ AR ?= ar else CFLAGS += --target=$(ARCH)-pc-win32-coff -Wno-builtin-requires-header -Wno-incompatible-library-redeclaration -Wno-long-long LDFLAGS += -subsystem:efi_application -nodefaultlib -dll -entry:uefi_init uefi/*.o -LIBS = -out:$(TARGET) +LIBS = -out:$(addprefix $(OUTDIR),$(TARGET)) CC = clang -LD = lld-link +LD = lld -flavor link OBJCOPY = true endif # recipies ifeq ($(wildcard uefi/Makefile),) -ALLTARGETS = crt_$(ARCH).o libuefi.a build +ALLTARGETS = crt_$(ARCH).o libuefi.a buildlib else -ALLTARGETS = uefi/crt_$(ARCH).o uefi/libuefi.a $(OBJS2) $(TARGET) +ALLTARGETS = uefi/crt_$(ARCH).o uefi/libuefi.a $(OBJS) $(TARGET) endif -all: $(ALLTARGETS) $(EXTRA) +all: $(OUTDIR) $(EXTRA) $(ALLTARGETS) $(ALSO) + +ifneq ($(OUTDIR),) +$(OUTDIR): + @mkdir -p $(OUTDIR) +endif uefi/libuefi.a: @make --no-print-directory -C uefi libuefi.a USE_GCC=$(USE_GCC) ARCH=$(ARCH) -libuefi.lib: $(LIBOBJS2) +libuefi.lib: $(LIBOBJS) -libuefi.a: $(LIBOBJS2) +libuefi.a: $(LIBOBJS) ifneq ($(USE_GCC),) @rm $@ 2>/dev/null || true - $(AR) -frsv $@ $(LIBOBJS2) >/dev/null + $(AR) -frsv $@ $(LIBOBJS) >/dev/null else @true endif -$(TARGET): $(TARGET).so +$(TARGET): $(addprefix $(OUTDIR),$(TARGET).so) ifneq ($(USE_GCC),) - @$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target $(EFIARCH) --subsystem=10 $^ $@ || echo target: $(EFIARCH) - @rm $(TARGET).so + $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target $(EFIARCH) --subsystem=10 $^ $(addprefix $(OUTDIR),$@) || echo target: $(EFIARCH) + @rm $(addprefix $(OUTDIR),$(TARGET).so) endif -$(TARGET).so: $(OBJS2) +$(addprefix $(OUTDIR),$(TARGET).so): $(addprefix $(OUTDIR),$(OBJS)) $(EXTRA) $(LD) $(LDFLAGS) $^ $(LIBS) - @rm *.lib 2>/dev/null || true + @rm $(addprefix $(OUTDIR),*.lib) 2>/dev/null || true + +uefi/%.o: uefi/%.c + $(CC) $(CFLAGS) -c $< -o $@ %.o: %.c - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -c $< -o $(addprefix $(OUTDIR),$@) %.o: %.S - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -c $< -o $(addprefix $(OUTDIR),$@) -build: +buildlib: @mkdir ../build ../build/uefi 2>/dev/null || true @cp crt_$(ARCH).o ../build/uefi/crt0.o @cp elf_$(ARCH)_efi.lds ../build/uefi/link.ld @cp libuefi.a uefi.h ../build/uefi clean: - @rm $(TARGET) *.o *.a *.lib *.elf $(LIBOBJS2) 2>/dev/null || true + @rm $(addprefix $(OUTDIR),$(TARGET)) *.o *.a *.lib *.elf $(LIBOBJS) 2>/dev/null || true +ifneq ($(OUTDIR),) + @rm -rf $(OUTDIR) +endif distclean: clean ifeq ($(wildcard uefi/Makefile),) diff --git a/pcireg/uefi/crt_aarch64.c b/pcireg/uefi/crt_aarch64.c index f7ed6bf..82324a5 100644 --- a/pcireg/uefi/crt_aarch64.c +++ b/pcireg/uefi/crt_aarch64.c @@ -34,6 +34,7 @@ extern int main(int argc, char_t **argv); /* definitions for elf relocations */ +#ifndef __clang__ typedef uint64_t Elf64_Xword; typedef int64_t Elf64_Sxword; typedef uint64_t Elf64_Addr; @@ -57,6 +58,7 @@ typedef struct } Elf64_Rel; #define ELF64_R_TYPE(i) ((i) & 0xffffffff) #define R_AARCH64_RELATIVE 1027 /* Adjust by program base */ +#endif /* globals to store system table pointers */ efi_handle_t IM = NULL; @@ -64,12 +66,12 @@ efi_system_table_t *ST = NULL; efi_boot_services_t *BS = NULL; efi_runtime_services_t *RT = NULL; efi_loaded_image_protocol_t *LIP = NULL; -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 char *__argvutf8 = NULL; #endif /* we only need one .o file, so use inline Assembly here */ -void bootstrap() +void bootstrap(void) { __asm__ __volatile__ ( /* call init in C */ @@ -144,7 +146,7 @@ void bootstrap() /** * Initialize POSIX-UEFI and call the application's main() function */ -int uefi_init ( +efi_status_t uefi_init ( efi_handle_t image, efi_system_table_t *systab #ifndef __clang__ , uintptr_t ldbase, Elf64_Dyn *dyn @@ -156,10 +158,10 @@ int uefi_init ( efi_shell_interface_protocol_t *shi = NULL; efi_guid_t lipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; efi_status_t status; - int argc = 0, i; + int argc = 0, i, ret; wchar_t **argv = NULL; -#if USE_UTF8 - int ret, j; +#ifndef UEFI_NO_UTF8 + int j; char *s; #endif #ifndef __clang__ @@ -178,7 +180,7 @@ int uefi_init ( if (rel && relent) { while (relsz > 0) { if(ELF64_R_TYPE (rel->r_info) == R_AARCH64_RELATIVE) - { addr = (unsigned long *)(ldbase + rel->r_offset); *addr += ldbase; break; } + { addr = (unsigned long *)(ldbase + rel->r_offset); *addr += ldbase; } rel = (Elf64_Rel*) ((char *) rel + relent); relsz -= relent; } @@ -186,6 +188,10 @@ int uefi_init ( #else (void)i; #endif + /* failsafes, should never happen */ + if(!image || !systab || !systab->BootServices || !systab->BootServices->HandleProtocol || + !systab->BootServices->OpenProtocol || !systab->BootServices->AllocatePool || !systab->BootServices->FreePool) + return EFI_UNSUPPORTED; /* save EFI pointers and loaded image into globals */ IM = image; ST = systab; @@ -194,26 +200,26 @@ int uefi_init ( BS->HandleProtocol(image, &lipGuid, (void **)&LIP); /* get command line arguments */ status = BS->OpenProtocol(image, &shpGuid, (void **)&shp, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shp) { argc = shp->Argc; argv = shp->Argv; } + if(!EFI_ERROR(status) && shp) { argc = (int)shp->Argc; argv = shp->Argv; } else { /* if shell 2.0 failed, fallback to shell 1.0 interface */ status = BS->OpenProtocol(image, &shiGuid, (void **)&shi, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shi) { argc = shi->Argc; argv = shi->Argv; } + if(!EFI_ERROR(status) && shi) { argc = (int)shi->Argc; argv = shi->Argv; } } /* call main */ -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 if(argc && argv) { - ret = (argc + 1) * (sizeof(uintptr_t) + 1); + ret = (argc + 1) * ((int)sizeof(uintptr_t) + 1); for(i = 0; i < argc; i++) for(j = 0; argv[i] && argv[i][j]; j++) ret += argv[i][j] < 0x80 ? 1 : (argv[i][j] < 0x800 ? 2 : 3); - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, ret, (void **)&__argvutf8); + status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, (uintn_t)ret, (void **)&__argvutf8); if(EFI_ERROR(status) || !__argvutf8) { argc = 0; __argvutf8 = NULL; } else { - s = __argvutf8 + argc * sizeof(uintptr_t); + s = __argvutf8 + argc * (int)sizeof(uintptr_t); *((uintptr_t*)s) = (uintptr_t)0; s += sizeof(uintptr_t); for(i = 0; i < argc; i++) { - *((uintptr_t*)(__argvutf8 + i * sizeof(uintptr_t))) = (uintptr_t)s; + *((uintptr_t*)(__argvutf8 + i * (int)sizeof(uintptr_t))) = (uintptr_t)s; for(j = 0; argv[i] && argv[i][j]; j++) { if(argv[i][j]<0x80) { *s++ = argv[i][j]; } else if(argv[i][j]<0x800) { *s++ = ((argv[i][j]>>6)&0x1F)|0xC0; *s++ = (argv[i][j]&0x3F)|0x80; } else @@ -227,6 +233,7 @@ int uefi_init ( if(__argvutf8) BS->FreePool(__argvutf8); return ret; #else - return main(argc, argv); + ret = main(argc, argv); #endif + return ret ? EFIERR(ret) : EFI_SUCCESS; } diff --git a/pcireg/uefi/crt_x86_64.c b/pcireg/uefi/crt_x86_64.c index 2597adf..b146bb3 100644 --- a/pcireg/uefi/crt_x86_64.c +++ b/pcireg/uefi/crt_x86_64.c @@ -34,6 +34,7 @@ extern int main(int argc, char_t **argv); /* definitions for elf relocations */ +#ifndef __clang__ typedef uint64_t Elf64_Xword; typedef int64_t Elf64_Sxword; typedef uint64_t Elf64_Addr; @@ -57,6 +58,7 @@ typedef struct } Elf64_Rel; #define ELF64_R_TYPE(i) ((i) & 0xffffffff) #define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#endif /* globals to store system table pointers */ efi_handle_t IM = NULL; @@ -64,12 +66,12 @@ efi_system_table_t *ST = NULL; efi_boot_services_t *BS = NULL; efi_runtime_services_t *RT = NULL; efi_loaded_image_protocol_t *LIP = NULL; -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 char *__argvutf8 = NULL; #endif /* we only need one .o file, so use inline Assembly here */ -void bootstrap() +void bootstrap(void) { __asm__ __volatile__ ( /* call init in C */ @@ -137,7 +139,7 @@ void bootstrap() /** * Initialize POSIX-UEFI and call the application's main() function */ -int uefi_init ( +efi_status_t uefi_init ( #ifndef __clang__ uintptr_t ldbase, Elf64_Dyn *dyn, efi_system_table_t *systab, efi_handle_t image #else @@ -150,10 +152,10 @@ int uefi_init ( efi_shell_interface_protocol_t *shi = NULL; efi_guid_t lipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; efi_status_t status; - int argc = 0, i; + int argc = 0, i, ret; wchar_t **argv = NULL; -#if USE_UTF8 - int ret, j; +#ifndef UEFI_NO_UTF8 + int j; char *s; #endif #ifndef __clang__ @@ -172,7 +174,7 @@ int uefi_init ( if (rel && relent) { while (relsz > 0) { if(ELF64_R_TYPE (rel->r_info) == R_X86_64_RELATIVE) - { addr = (unsigned long *)(ldbase + rel->r_offset); *addr += ldbase; break; } + { addr = (unsigned long *)(ldbase + rel->r_offset); *addr += ldbase; } rel = (Elf64_Rel*) ((char *) rel + relent); relsz -= relent; } @@ -189,6 +191,10 @@ int uefi_init ( " orw $3 << 9, %ax\n" " mov %rax, %cr4\n" ); + /* failsafes, should never happen */ + if(!image || !systab || !systab->BootServices || !systab->BootServices->HandleProtocol || + !systab->BootServices->OpenProtocol || !systab->BootServices->AllocatePool || !systab->BootServices->FreePool) + return EFI_UNSUPPORTED; /* save EFI pointers and loaded image into globals */ IM = image; ST = systab; @@ -197,26 +203,26 @@ int uefi_init ( BS->HandleProtocol(image, &lipGuid, (void **)&LIP); /* get command line arguments */ status = BS->OpenProtocol(image, &shpGuid, (void **)&shp, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shp) { argc = shp->Argc; argv = shp->Argv; } + if(!EFI_ERROR(status) && shp) { argc = (int)shp->Argc; argv = shp->Argv; } else { /* if shell 2.0 failed, fallback to shell 1.0 interface */ status = BS->OpenProtocol(image, &shiGuid, (void **)&shi, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shi) { argc = shi->Argc; argv = shi->Argv; } + if(!EFI_ERROR(status) && shi) { argc = (int)shi->Argc; argv = shi->Argv; } } /* call main */ -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 if(argc && argv) { - ret = (argc + 1) * (sizeof(uintptr_t) + 1); + ret = (argc + 1) * ((int)sizeof(uintptr_t) + 1); for(i = 0; i < argc; i++) for(j = 0; argv[i] && argv[i][j]; j++) ret += argv[i][j] < 0x80 ? 1 : (argv[i][j] < 0x800 ? 2 : 3); - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, ret, (void **)&__argvutf8); + status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, (uintn_t)ret, (void **)&__argvutf8); if(EFI_ERROR(status) || !__argvutf8) { argc = 0; __argvutf8 = NULL; } else { - s = __argvutf8 + argc * sizeof(uintptr_t); + s = __argvutf8 + argc * (int)sizeof(uintptr_t); *((uintptr_t*)s) = (uintptr_t)0; s += sizeof(uintptr_t); for(i = 0; i < argc; i++) { - *((uintptr_t*)(__argvutf8 + i * sizeof(uintptr_t))) = (uintptr_t)s; + *((uintptr_t*)(__argvutf8 + i * (int)sizeof(uintptr_t))) = (uintptr_t)s; for(j = 0; argv[i] && argv[i][j]; j++) { if(argv[i][j]<0x80) { *s++ = argv[i][j]; } else if(argv[i][j]<0x800) { *s++ = ((argv[i][j]>>6)&0x1F)|0xC0; *s++ = (argv[i][j]&0x3F)|0x80; } else @@ -228,8 +234,8 @@ int uefi_init ( } ret = main(argc, (char**)__argvutf8); if(__argvutf8) BS->FreePool(__argvutf8); - return ret; #else - return main(argc, argv); + ret = main(argc, argv); #endif + return ret ? EFIERR(ret) : EFI_SUCCESS; } diff --git a/pcireg/uefi/dirent.c b/pcireg/uefi/dirent.c index 320b190..402011c 100644 --- a/pcireg/uefi/dirent.c +++ b/pcireg/uefi/dirent.c @@ -31,7 +31,7 @@ #include extern void __stdio_seterrno(efi_status_t status); -struct dirent __dirent; +static struct dirent __dirent; DIR *opendir (const char_t *__name) { @@ -53,8 +53,8 @@ struct dirent *readdir (DIR *__dirp) return NULL; } __dirent.d_type = info.Attribute & EFI_FILE_DIRECTORY ? DT_DIR : DT_REG; -#if USE_UTF8 - __dirent.d_reclen = wcstombs(__dirent.d_name, info.FileName, FILENAME_MAX - 1); +#ifndef UEFI_NO_UTF8 + __dirent.d_reclen = (unsigned short int)wcstombs(__dirent.d_name, info.FileName, FILENAME_MAX - 1); #else __dirent.d_reclen = strlen(info.FileName); strncpy(__dirent.d_name, info.FileName, FILENAME_MAX - 1); diff --git a/pcireg/uefi/stdio.c b/pcireg/uefi/stdio.c index dd0004d..350ff7b 100644 --- a/pcireg/uefi/stdio.c +++ b/pcireg/uefi/stdio.c @@ -35,10 +35,13 @@ static efi_serial_io_protocol_t *__ser = NULL; static block_file_t *__blk_devs = NULL; static uintn_t __blk_ndevs = 0; extern time_t __mktime_efi(efi_time_t *t); +void __stdio_cleanup(void); +void __stdio_seterrno(efi_status_t status); +int __remove (const char_t *__filename, int isdir); -void __stdio_cleanup() +void __stdio_cleanup(void) { -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 if(__argvutf8) BS->FreePool(__argvutf8); #endif @@ -67,7 +70,7 @@ int fstat (FILE *__f, struct stat *__buf) efi_file_info_t info; uintn_t fsiz = (uintn_t)sizeof(efi_file_info_t); efi_status_t status; - int i; + uintn_t i; if(!__f || !__buf) { errno = EINVAL; @@ -89,8 +92,8 @@ int fstat (FILE *__f, struct stat *__buf) for(i = 0; i < __blk_ndevs; i++) if(__f == (FILE*)__blk_devs[i].bio) { __buf->st_mode = S_IREAD | S_IWRITE | S_IFBLK; - __buf->st_size = (off_t)__blk_devs[i].bio->Media->BlockSize * (off_t)__blk_devs[i].bio->Media->LastBlock; - __buf->st_blocks = __blk_devs[i].bio->Media->LastBlock; + __buf->st_size = (off_t)__blk_devs[i].bio->Media->BlockSize * ((off_t)__blk_devs[i].bio->Media->LastBlock + 1); + __buf->st_blocks = __blk_devs[i].bio->Media->LastBlock + 1; return 0; } status = __f->GetInfo(__f, &infGuid, &fsiz, &info); @@ -153,7 +156,10 @@ int __remove (const char_t *__filename, int isdir) efi_guid_t infGuid = EFI_FILE_INFO_GUID; efi_file_info_t info; uintn_t fsiz = (uintn_t)sizeof(efi_file_info_t), i; - FILE *f = fopen(__filename, CL("r")); + /* little hack to support read and write mode for Delete() and stat() without create mode or checks */ + FILE *f = fopen(__filename, CL("*")); + if(errno) + return 1; if(!f || f == stdin || f == stdout || f == stderr || (__ser && f == (FILE*)__ser)) { errno = EBADF; return 1; @@ -200,10 +206,12 @@ FILE *fopen (const char_t *__filename, const char_t *__modes) efi_guid_t infGuid = EFI_FILE_INFO_GUID; efi_file_info_t info; uintn_t fsiz = (uintn_t)sizeof(efi_file_info_t), par, i; -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 wchar_t wcname[BUFSIZ]; #endif - if(!__filename || !*__filename || !__modes || !*__modes) { + errno = 0; + if(!__filename || !*__filename || !__modes || (__modes[0] != CL('r') && __modes[0] != CL('w') && __modes[0] != CL('a') && + __modes[0] != CL('*')) || (__modes[1] != 0 && __modes[1] != CL('d') && __modes[1] != CL('+'))) { errno = EINVAL; return NULL; } @@ -221,7 +229,7 @@ FILE *fopen (const char_t *__filename, const char_t *__modes) return stderr; } if(!memcmp(__filename, CL("/dev/serial"), 11 * sizeof(char_t))) { - par = atol(__filename + 11); + par = (uintn_t)atol(__filename + 11); if(!__ser) { efi_guid_t serGuid = EFI_SERIAL_IO_PROTOCOL_GUID; status = BS->LocateProtocol(&serGuid, NULL, (void**)&__ser); @@ -231,19 +239,22 @@ FILE *fopen (const char_t *__filename, const char_t *__modes) return (FILE*)__ser; } if(!memcmp(__filename, CL("/dev/disk"), 9 * sizeof(char_t))) { - par = atol(__filename + 9); + par = (uintn_t)atol(__filename + 9); if(!__blk_ndevs) { efi_guid_t bioGuid = EFI_BLOCK_IO_PROTOCOL_GUID; efi_handle_t handles[128]; uintn_t handle_size = sizeof(handles); - status = BS->LocateHandle(ByProtocol, &bioGuid, NULL, handle_size, (efi_handle_t*)&handles); + status = BS->LocateHandle(ByProtocol, &bioGuid, NULL, &handle_size, (efi_handle_t*)&handles); if(!EFI_ERROR(status)) { handle_size /= (uintn_t)sizeof(efi_handle_t); + /* workaround a bug in TianoCore, it reports zero size even though the data is in the buffer */ + if(handle_size < 1) + handle_size = (uintn_t)sizeof(handles) / 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)); for(i = __blk_ndevs = 0; i < handle_size; i++) - if(!EFI_ERROR(BS->HandleProtocol(handles[i], &bioGuid, (void **) &__blk_devs[__blk_ndevs].bio)) && + if(handles[i] && !EFI_ERROR(BS->HandleProtocol(handles[i], &bioGuid, (void **) &__blk_devs[__blk_ndevs].bio)) && __blk_devs[__blk_ndevs].bio && __blk_devs[__blk_ndevs].bio->Media && __blk_devs[__blk_ndevs].bio->Media->BlockSize > 0) __blk_ndevs++; @@ -251,7 +262,7 @@ FILE *fopen (const char_t *__filename, const char_t *__modes) __blk_ndevs = 0; } } - if(__blk_ndevs && par >= 0 && par < __blk_ndevs) + if(__blk_ndevs && par < __blk_ndevs) return (FILE*)__blk_devs[par].bio; errno = ENOENT; return NULL; @@ -265,30 +276,41 @@ FILE *fopen (const char_t *__filename, const char_t *__modes) errno = ENODEV; return NULL; } - errno = 0; ret = (FILE*)malloc(sizeof(FILE)); if(!ret) return NULL; -#if USE_UTF8 + /* normally write means read,write,create. But for remove (internal '*' mode), we need read,write without create + * also mode 'w' in POSIX means write-only (without read), but that's not working on certain firmware, we must + * pass read too. This poses a problem of truncating a write-only file, see issue #26, we have to do that manually */ +#ifndef UEFI_NO_UTF8 mbstowcs((wchar_t*)&wcname, __filename, BUFSIZ - 1); status = __root_dir->Open(__root_dir, &ret, (wchar_t*)&wcname, #else status = __root_dir->Open(__root_dir, &ret, (wchar_t*)__filename, #endif - __modes[0] == CL('w') ? (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ | EFI_FILE_MODE_CREATE) : EFI_FILE_MODE_READ, + __modes[0] == CL('w') || __modes[0] == CL('a') ? (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ | EFI_FILE_MODE_CREATE) : + EFI_FILE_MODE_READ | (__modes[0] == CL('*') || __modes[1] == CL('+') ? EFI_FILE_MODE_WRITE : 0), __modes[1] == CL('d') ? EFI_FILE_DIRECTORY : 0); if(EFI_ERROR(status)) { err: __stdio_seterrno(status); free(ret); return NULL; } + if(__modes[0] == CL('*')) return ret; status = ret->GetInfo(ret, &infGuid, &fsiz, &info); if(EFI_ERROR(status)) goto err; if(__modes[1] == CL('d') && !(info.Attribute & EFI_FILE_DIRECTORY)) { - free(ret); errno = ENOTDIR; return NULL; + ret->Close(ret); free(ret); errno = ENOTDIR; return NULL; } if(__modes[1] != CL('d') && (info.Attribute & EFI_FILE_DIRECTORY)) { - free(ret); errno = EISDIR; return NULL; + ret->Close(ret); free(ret); errno = EISDIR; return NULL; } if(__modes[0] == CL('a')) fseek(ret, 0, SEEK_END); + if(__modes[0] == CL('w')) { + /* manually truncate file size + * See https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.c + * function FileHandleSetSize */ + info.FileSize = 0; + ret->SetInfo(ret, &infGuid, fsiz, &info); + } return ret; } @@ -493,8 +515,8 @@ int vsnprintf(char_t *dst, size_t maxlen, const char_t *fmt, __builtin_va_list a uint8_t *mem; int64_t arg; int len, sign, i, j; - char_t *p, *orig=dst, *end = dst + maxlen - 1, tmpstr[19], pad, n; -#if !defined(USE_UTF8) || !USE_UTF8 + char_t *p, *orig=dst, *end = dst + maxlen - 1, tmpstr[24], pad, n; +#ifdef UEFI_NO_UTF8 char *c; #endif if(dst==NULL || fmt==NULL) @@ -514,8 +536,8 @@ int vsnprintf(char_t *dst, size_t maxlen, const char_t *fmt, __builtin_va_list a } if(*fmt==CL('l')) fmt++; if(*fmt==CL('c')) { - arg = __builtin_va_arg(args, int); -#if USE_UTF8 + arg = __builtin_va_arg(args, uint32_t); +#ifndef UEFI_NO_UTF8 if(arg<0x80) { *dst++ = arg; } else if(arg<0x800) { *dst++ = ((arg>>6)&0x1F)|0xC0; *dst++ = (arg&0x3F)|0x80; } else { *dst++ = ((arg>>12)&0x0F)|0xE0; *dst++ = ((arg>>6)&0x3F)|0x80; *dst++ = (arg&0x3F)|0x80; } @@ -525,17 +547,14 @@ int vsnprintf(char_t *dst, size_t maxlen, const char_t *fmt, __builtin_va_list a fmt++; continue; } else - if(*fmt==CL('d')) { - arg = __builtin_va_arg(args, int); + if(*fmt==CL('d') || *fmt==CL('i')) { + arg = __builtin_va_arg(args, int64_t); sign=0; - if((int)arg<0) { + if(arg<0) { arg*=-1; sign++; } - if(arg>99999999999999999L) { - arg=99999999999999999L; - } - i=18; + i=23; tmpstr[i]=0; do { tmpstr[--i]=CL('0')+(arg%10); @@ -544,8 +563,8 @@ int vsnprintf(char_t *dst, size_t maxlen, const char_t *fmt, __builtin_va_list a if(sign) { tmpstr[--i]=CL('-'); } - if(len>0 && len<18) { - while(i>18-len) { + if(len>0 && len<23) { + while(i && i>23-len) { tmpstr[--i]=pad; } } @@ -557,7 +576,7 @@ int vsnprintf(char_t *dst, size_t maxlen, const char_t *fmt, __builtin_va_list a len = 16; pad = CL('0'); goto hex; } else if(*fmt==CL('x') || *fmt==CL('X')) { - arg = __builtin_va_arg(args, long int); + arg = __builtin_va_arg(args, int64_t); hex: i=16; tmpstr[i]=0; do { @@ -600,7 +619,7 @@ copystring: if(p==NULL) { } } } else -#if !defined(USE_UTF8) || !USE_UTF8 +#ifdef UEFI_NO_UTF8 if(*fmt==L'S' || *fmt==L'Q') { c = __builtin_va_arg(args, char*); if(c==NULL) goto copystring; @@ -659,7 +678,7 @@ copystring: if(p==NULL) { } *dst++ = CL(' '); if(dst >= end) goto zro; for(i = 0; i < 16; i++) { - *dst++ = (mem[i] < 32 || mem[i] >= 127 ? CL('.') : mem[i]); + *dst++ = (mem[i] < 32 || mem[i] >= 127 ? CL('.') : (char_t)mem[i]); if(dst >= end) goto zro; } *dst++ = CL('\r'); if(dst >= end) goto zro; @@ -674,7 +693,7 @@ put: if(*fmt == CL('\n') && (orig == dst || *(dst - 1) != CL('\r'))) *dst fmt++; } zro:*dst=0; - return dst-orig; + return (int)(dst-orig); #undef needsescape } @@ -685,23 +704,29 @@ int vsprintf(char_t *dst, const char_t *fmt, __builtin_va_list args) int sprintf(char_t *dst, const char_t* fmt, ...) { + int ret; __builtin_va_list args; __builtin_va_start(args, fmt); - return vsnprintf(dst, BUFSIZ, fmt, args); + ret = vsnprintf(dst, BUFSIZ, fmt, args); + __builtin_va_end(args); + return ret; } int snprintf(char_t *dst, size_t maxlen, const char_t* fmt, ...) { + int ret; __builtin_va_list args; __builtin_va_start(args, fmt); - return vsnprintf(dst, maxlen, fmt, args); + ret = vsnprintf(dst, maxlen, fmt, args); + __builtin_va_end(args); + return ret; } int vprintf(const char_t* fmt, __builtin_va_list args) { int ret; wchar_t dst[BUFSIZ]; -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 char_t tmp[BUFSIZ]; ret = vsnprintf(tmp, BUFSIZ, fmt, args); mbstowcs(dst, tmp, BUFSIZ - 1); @@ -714,9 +739,12 @@ int vprintf(const char_t* fmt, __builtin_va_list args) int printf(const char_t* fmt, ...) { + int ret; __builtin_va_list args; __builtin_va_start(args, fmt); - return vprintf(fmt, args); + ret = vprintf(fmt, args); + __builtin_va_end(args); + return ret; } int vfprintf (FILE *__stream, const char_t *__format, __builtin_va_list args) @@ -724,8 +752,8 @@ int vfprintf (FILE *__stream, const char_t *__format, __builtin_va_list args) wchar_t dst[BUFSIZ]; char_t tmp[BUFSIZ]; uintn_t ret, i; -#if USE_UTF8 - ret = vsnprintf(tmp, BUFSIZ, __format, args); +#ifndef UEFI_NO_UTF8 + ret = (uintn_t)vsnprintf(tmp, BUFSIZ, __format, args); ret = mbstowcs(dst, tmp, BUFSIZ - 1); #else ret = vsnprintf(dst, BUFSIZ, __format, args); @@ -741,43 +769,41 @@ int vfprintf (FILE *__stream, const char_t *__format, __builtin_va_list args) else if(__stream == stderr) ST->StdErr->OutputString(ST->StdErr, (wchar_t*)&dst); else if(__ser && __stream == (FILE*)__ser) { -#if !defined(USE_UTF8) || !USE_UTF8 +#ifdef UEFI_NO_UTF8 wcstombs((char*)&tmp, dst, BUFSIZ - 1); #endif __ser->Write(__ser, &ret, (void*)&tmp); } else -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 __stream->Write(__stream, &ret, (void*)&tmp); #else __stream->Write(__stream, &ret, (void*)&dst); #endif - return ret; + return (int)ret; } int fprintf (FILE *__stream, const char_t *__format, ...) { + int ret; __builtin_va_list args; __builtin_va_start(args, __format); - return vfprintf(__stream, __format, args); -} - -int getchar (void) -{ - efi_input_key_t key; - efi_status_t status = ST->ConIn->ReadKeyStroke(ST->ConIn, &key); - return EFI_ERROR(status) ? -1 : key.UnicodeChar; - + ret = vfprintf(__stream, __format, args); + __builtin_va_end(args); + return ret; } int getchar_ifany (void) { - efi_input_key_t key; - efi_status_t status = BS->CheckEvent(ST->ConIn->WaitForKey); - if(!status) { - status = ST->ConIn->ReadKeyStroke(ST->ConIn, &key); - return EFI_ERROR(status) ? -1 : key.UnicodeChar; - } - return 0; + efi_input_key_t key = { 0 }; + efi_status_t status = ST->ConIn->ReadKeyStroke(ST->ConIn, &key); + return EFI_ERROR(status) ? 0 : key.UnicodeChar; +} + +int getchar (void) +{ + uintn_t idx; + BS->WaitForEvent(1, &ST->ConIn->WaitForKey, &idx); + return getchar_ifany(); } int putchar (int __c) diff --git a/pcireg/uefi/stdlib.c b/pcireg/uefi/stdlib.c index efd706d..81b33df 100644 --- a/pcireg/uefi/stdlib.c +++ b/pcireg/uefi/stdlib.c @@ -32,9 +32,11 @@ int errno = 0; static uint64_t __srand_seed = 6364136223846793005ULL; -extern void __stdio_cleanup(); +extern void __stdio_cleanup(void); +#ifndef UEFI_NO_TRACK_ALLOC static uintptr_t *__stdlib_allocs = NULL; static uintn_t __stdlib_numallocs = 0; +#endif int atoi(const char_t *s) { @@ -70,7 +72,7 @@ int64_t strtol (const char_t *s, char_t **__endptr, int __base) else if(__base == 16 && *s >= CL('A') && *s <= CL('F')) v += (*s)-CL('A')+10; s++; - }; + } if(__endptr) *__endptr = (char_t*)s; return v * sign; } @@ -79,12 +81,12 @@ void *malloc (size_t __size) { void *ret = NULL; efi_status_t status; +#ifndef UEFI_NO_TRACK_ALLOC uintn_t i; - /* this is so fucked up. UEFI firmware must keep track of allocated sizes internally, yet we must - * too, because realloc won't work otherwise... Why can't AllocatePool accept input addresses? */ for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != 0; i += 2); if(i == __stdlib_numallocs) { - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __stdlib_numallocs + 2, &ret); + /* no free slots found, (re)allocate the housekeeping array */ + status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, (__stdlib_numallocs + 2) * sizeof(uintptr_t), &ret); if(EFI_ERROR(status) || !ret) { errno = ENOMEM; return NULL; } if(__stdlib_allocs) memcpy(ret, __stdlib_allocs, __stdlib_numallocs * sizeof(uintptr_t)); __stdlib_allocs = (uintptr_t*)ret; @@ -92,10 +94,13 @@ void *malloc (size_t __size) __stdlib_numallocs += 2; ret = NULL; } +#endif status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret); if(EFI_ERROR(status) || !ret) { errno = ENOMEM; ret = NULL; } +#ifndef UEFI_NO_TRACK_ALLOC __stdlib_allocs[i] = (uintptr_t)ret; __stdlib_allocs[i + 1] = (uintptr_t)__size; +#endif return ret; } @@ -110,62 +115,92 @@ void *realloc (void *__ptr, size_t __size) { void *ret = NULL; efi_status_t status; +#ifndef UEFI_NO_TRACK_ALLOC uintn_t i; +#endif if(!__ptr) return malloc(__size); + if(!__size) { free(__ptr); return NULL; } +#ifndef UEFI_NO_TRACK_ALLOC + /* get the slot which stores the old size for this buffer */ for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != (uintptr_t)__ptr; i += 2); if(i == __stdlib_numallocs) { errno = ENOMEM; return NULL; } + /* allocate a new buffer and copy data from old buffer */ status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret); if(EFI_ERROR(status) || !ret) { errno = ENOMEM; ret = NULL; } - if(ret) { + else { memcpy(ret, (void*)__stdlib_allocs[i], __stdlib_allocs[i + 1] < __size ? __stdlib_allocs[i + 1] : __size); if(__size > __stdlib_allocs[i + 1]) memset((uint8_t*)ret + __stdlib_allocs[i + 1], 0, __size - __stdlib_allocs[i + 1]); + /* free old buffer and store new buffer in slot */ + BS->FreePool((void*)__stdlib_allocs[i]); + __stdlib_allocs[i] = (uintptr_t)ret; + __stdlib_allocs[i + 1] = (uintptr_t)__size; } - BS->FreePool((void*)__stdlib_allocs[i]); - __stdlib_allocs[i] = (uintptr_t)ret; - __stdlib_allocs[i + 1] = (uintptr_t)__size; +#else + status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret); + if(EFI_ERROR(status) || !ret) { errno = ENOMEM; return NULL; } + /* this means out of bounds read, but fine with POSIX as the end of new buffer supposed to be left uninitialized) */ + memcpy(ret, (void*)__ptr, __size); + BS->FreePool((void*)__ptr); +#endif return ret; } void free (void *__ptr) { efi_status_t status; +#ifndef UEFI_NO_TRACK_ALLOC uintn_t i; +#endif + if(!__ptr) { errno = ENOMEM; return; } +#ifndef UEFI_NO_TRACK_ALLOC + /* find and clear the slot */ for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != (uintptr_t)__ptr; i += 2); if(i == __stdlib_numallocs) { errno = ENOMEM; return; } __stdlib_allocs[i] = 0; __stdlib_allocs[i + 1] = 0; + /* if there are only empty slots, free the housekeeping array too */ for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] == 0; i += 2); if(i == __stdlib_numallocs) { BS->FreePool(__stdlib_allocs); __stdlib_allocs = NULL; __stdlib_numallocs = 0; } +#endif status = BS->FreePool(__ptr); if(EFI_ERROR(status)) errno = ENOMEM; } void abort () { +#ifndef UEFI_NO_TRACK_ALLOC if(__stdlib_allocs) BS->FreePool(__stdlib_allocs); + __stdlib_allocs = NULL; __stdlib_numallocs = 0; +#endif __stdio_cleanup(); BS->Exit(IM, EFI_ABORTED, 0, NULL); } void exit (int __status) { +#ifndef UEFI_NO_TRACK_ALLOC if(__stdlib_allocs) BS->FreePool(__stdlib_allocs); + __stdlib_allocs = NULL; __stdlib_numallocs = 0; +#endif __stdio_cleanup(); BS->Exit(IM, !__status ? 0 : (__status < 0 ? EFIERR(-__status) : EFIERR(__status)), 0, NULL); } int exit_bs() { - efi_status_t status; + efi_status_t status = 0; efi_memory_descriptor_t *memory_map = NULL; uintn_t cnt = 3, memory_map_size=0, map_key=0, desc_size=0; +#ifndef UEFI_NO_TRACK_ALLOC if(__stdlib_allocs) BS->FreePool(__stdlib_allocs); + __stdlib_allocs = NULL; __stdlib_numallocs = 0; +#endif __stdio_cleanup(); while(cnt--) { status = BS->GetMemoryMap(&memory_map_size, memory_map, &map_key, &desc_size, NULL); @@ -249,13 +284,13 @@ size_t mbstowcs (wchar_t *__pwcs, const char *__s, size_t __n) wchar_t *orig = __pwcs; if(!__s || !*__s) return 0; while(*__s) { - r = mbtowc(__pwcs, __s, __n - (__pwcs - orig)); + r = mbtowc(__pwcs, __s, __n - (size_t)(__pwcs - orig)); if(r < 0) return (size_t)-1; __pwcs++; __s += r; } *__pwcs = 0; - return __pwcs - orig; + return (size_t)(__pwcs - orig); } size_t wcstombs (char *__s, const wchar_t *__pwcs, size_t __n) @@ -263,14 +298,14 @@ size_t wcstombs (char *__s, const wchar_t *__pwcs, size_t __n) int r; char *orig = __s; if(!__s || !__pwcs || !*__pwcs) return 0; - while(*__pwcs && (__s - orig + 4 < __n)) { + while(*__pwcs && ((size_t)(__s - orig + 4) < __n)) { r = wctomb(__s, *__pwcs); if(r < 0) return (size_t)-1; __pwcs++; __s += r; } *__s = 0; - return __s - orig; + return (size_t)(__s - orig); } void srand(unsigned int __seed) @@ -299,7 +334,7 @@ uint8_t *getenv(char_t *name, uintn_t *len) uint8_t tmp[EFI_MAXIMUM_VARIABLE_SIZE], *ret; uint32_t attr; efi_status_t status; -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 wchar_t wcname[256]; mbstowcs((wchar_t*)&wcname, name, 256); status = RT->GetVariable((wchar_t*)&wcname, &globGuid, &attr, len, &tmp); @@ -319,7 +354,7 @@ int setenv(char_t *name, uintn_t len, uint8_t *data) { efi_guid_t globGuid = EFI_GLOBAL_VARIABLE; efi_status_t status; -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 wchar_t wcname[256]; mbstowcs((wchar_t*)&wcname, name, 256); status = RT->SetVariable(wcname, &globGuid, 0, len, data); diff --git a/pcireg/uefi/string.c b/pcireg/uefi/string.c index 3286e7b..5a00aa6 100644 --- a/pcireg/uefi/string.c +++ b/pcireg/uefi/string.c @@ -33,7 +33,7 @@ void *memcpy(void *dst, const void *src, size_t n) { uint8_t *a=(uint8_t*)dst,*b=(uint8_t*)src; - if(src && dst && n>0) { + if(src && dst && src != dst && n>0) { while(n--) *a++ = *b++; } return dst; @@ -42,8 +42,8 @@ void *memcpy(void *dst, const void *src, size_t n) void *memmove(void *dst, const void *src, size_t n) { uint8_t *a=(uint8_t*)dst,*b=(uint8_t*)src; - if(src && dst && n>0) { - if((ab) || (ba)) { + if(src && dst && src != dst && n>0) { + if(a>b && a0) *a--=*b--; } else { while(n--) *a++ = *b++; @@ -56,7 +56,7 @@ void *memset(void *s, int c, size_t n) { uint8_t *p=(uint8_t*)s; if(s && n>0) { - while(n--) *p++ = c; + while(n--) *p++ = (uint8_t)c; } return s; } @@ -64,7 +64,7 @@ void *memset(void *s, int c, size_t n) int 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) { + if(s1 && s2 && s1 != s2 && n>0) { while(n--) { if(*a != *b) return *a - *b; a++; b++; @@ -95,7 +95,7 @@ void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl) { uint8_t *c = (uint8_t*)haystack; if(!haystack || !needle || !hl || !nl || nl > hl) return NULL; - hl -= nl; + hl -= nl - 1; while(hl) { if(!memcmp(c, needle, nl)) return c; c++; hl--; @@ -118,34 +118,37 @@ void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl) char_t *strcpy(char_t *dst, const char_t *src) { - if(src && dst) { + char_t *s = dst; + if(src && dst && src != dst) { while(*src) {*dst++=*src++;} *dst=0; } - return dst; + return s; } char_t *strncpy(char_t *dst, const char_t *src, size_t n) { + char_t *s = dst; const char_t *e = src+n; - if(src && dst && n>0) { + if(src && dst && src != dst && n>0) { while(*src && src0) { dst += strlen(dst); while(*src && src0) { - do{if(*s1!=*s2){return *s1-*s2;}s1++;s2++;}while(*s1!=0 && s1 static struct tm __tm; +time_t __mktime_efi(efi_time_t *t); /* from musl */ -uint64_t __year_to_secs(uint64_t year, int *is_leap) +static uint64_t __year_to_secs(uint64_t year, int *is_leap) { int y, cycles, centuries, leaps, rem; if (year-2ULL <= 136) { - y = year; + y = (int)year; leaps = (y-68)>>2; if (!((y-68)&3)) { leaps--; if (is_leap) *is_leap = 1; } else if (is_leap) *is_leap = 0; - return 31536000*(y-70) + 86400*leaps; + return 31536000ULL*(uint64_t)(y-70) + 86400ULL*(uint64_t)leaps; } if (!is_leap) is_leap = &(int){0}; - cycles = (year-100) / 400; + cycles = (int)((year-100) / 400); rem = (year-100) % 400; if (rem < 0) { cycles--; @@ -60,30 +61,30 @@ uint64_t __year_to_secs(uint64_t year, int *is_leap) leaps = 0; } else { if (rem >= 200) { - if (rem >= 300) centuries = 3, rem -= 300; - else centuries = 2, rem -= 200; + if (rem >= 300) { centuries = 3; rem -= 300; } + else { centuries = 2; rem -= 200; } } else { - if (rem >= 100) centuries = 1, rem -= 100; + if (rem >= 100) { centuries = 1; rem -= 100; } else centuries = 0; } if (!rem) { *is_leap = 0; leaps = 0; } else { - leaps = rem / 4U; - rem %= 4U; + leaps = rem / 4; + rem %= 4; *is_leap = !rem; } } leaps += 97*cycles + 24*centuries - *is_leap; - return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400; + return (uint64_t)(year-100) * 31536000ULL + (uint64_t)leaps * 86400ULL + 946684800ULL + 86400ULL; } time_t __mktime_efi(efi_time_t *t) { - __tm.tm_year = t->Year + 98; + __tm.tm_year = t->Year + (/* workaround some buggy firmware*/ t->Year > 2000 ? -1900 : 98); __tm.tm_mon = t->Month - 1; __tm.tm_mday = t->Day; __tm.tm_hour = t->Hour; @@ -107,15 +108,15 @@ struct tm *localtime (const time_t *__timer) time_t mktime(const struct tm *tm) { - static const int secs_through_month[] = { + static const uint64_t secs_through_month[] = { 0, 31*86400, 59*86400, 90*86400, 120*86400, 151*86400, 181*86400, 212*86400, 243*86400, 273*86400, 304*86400, 334*86400 }; int is_leap; - uint64_t year = tm->tm_year, t; + uint64_t year = (uint64_t)tm->tm_year, t, adj; int month = tm->tm_mon; if (month >= 12 || month < 0) { - int adj = month / 12; + adj = (uint64_t)month / 12; month %= 12; if (month < 0) { adj--; @@ -126,10 +127,10 @@ time_t mktime(const struct tm *tm) t = __year_to_secs(year, &is_leap); t += secs_through_month[month]; if (is_leap && month >= 2) t += 86400; - t += 86400LL * (tm->tm_mday-1); - t += 3600LL * tm->tm_hour; - t += 60LL * tm->tm_min; - t += tm->tm_sec; + t += 86400ULL * (uint64_t)(tm->tm_mday-1); + t += 3600ULL * (uint64_t)tm->tm_hour; + t += 60ULL * (uint64_t)tm->tm_min; + t += (uint64_t)tm->tm_sec; return (time_t)t; } diff --git a/pcireg/uefi/uefi.h b/pcireg/uefi/uefi.h index 836281d..dc7b9c5 100644 --- a/pcireg/uefi/uefi.h +++ b/pcireg/uefi/uefi.h @@ -32,15 +32,17 @@ #ifndef _UEFI_H_ #define _UEFI_H_ +/*** configuration ***/ +/* #define UEFI_NO_UTF8 */ /* use wchar_t in your application */ +/* #define UEFI_NO_TRACK_ALLOC */ /* do not track allocated buffers' size */ +/*** configuration ends ***/ + #ifdef __cplusplus extern "C" { #endif -/* comment out this if you want to use wchar_t in your application */ -#define USE_UTF8 1 - -/* get these from the compiler */ -#ifndef _STDINT_H +/* get these from the compiler or the efi headers, only define if we have neither */ +#if !defined(_STDINT_H) && !defined(_GCC_STDINT_H) && !defined(_EFI_INCLUDE_) #define _STDINT_H typedef char int8_t; typedef unsigned char uint8_t; @@ -82,7 +84,7 @@ typedef uint64_t efi_physical_address_t; typedef uint64_t efi_virtual_address_t; typedef void *efi_handle_t; typedef void *efi_event_t; -#if USE_UTF8 +#ifndef UEFI_NO_UTF8 typedef char char_t; #define CL(a) a extern char *__argvutf8; @@ -129,9 +131,9 @@ typedef struct { #ifndef __WCHAR_TYPE__ # define __WCHAR_TYPE__ short #endif -#define EFIERR(a) (0x8000000000000000 | a) +#define EFIERR(a) (0x8000000000000000 | (unsigned int)(a)) #define EFI_ERROR_MASK 0x8000000000000000 -#define EFIERR_OEM(a) (0xc000000000000000 | a) +#define EFIERR_OEM(a) (0xc000000000000000 | (unsigned int)(a)) #define BAD_POINTER 0xFBFBFBFBFBFBFBFB #define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF @@ -520,6 +522,8 @@ typedef enum { EfiMemoryMappedIO, EfiMemoryMappedIOPortSpace, EfiPalCode, + EfiPersistentMemory, + EfiUnacceptedMemoryType, EfiMaxMemoryType } efi_memory_type_t; @@ -704,19 +708,19 @@ typedef void (EFIAPI *efi_event_notify_t)(efi_event_t Event, void *Context); typedef efi_status_t (EFIAPI *efi_create_event_t)(uint32_t Type, efi_tpl_t NotifyTpl, efi_event_notify_t NotifyFunction, void *NextContext, efi_event_t *Event); typedef efi_status_t (EFIAPI *efi_set_timer_t)(efi_event_t Event, efi_timer_delay_t Type, uint64_t TriggerTime); -typedef efi_status_t (EFIAPI *efi_wait_for_event_t)(uintn_t NumberOfEvents, efi_event_t *Event, uintn_t Index); +typedef efi_status_t (EFIAPI *efi_wait_for_event_t)(uintn_t NumberOfEvents, efi_event_t *Event, uintn_t *Index); typedef efi_status_t (EFIAPI *efi_signal_event_t)(efi_event_t Event); typedef efi_status_t (EFIAPI *efi_close_event_t)(efi_event_t Event); typedef efi_status_t (EFIAPI *efi_check_event_t)(efi_event_t Event); typedef efi_status_t (EFIAPI *efi_handle_protocol_t)(efi_handle_t Handle, efi_guid_t *Protocol, void **Interface); typedef efi_status_t (EFIAPI *efi_register_protocol_notify_t)(efi_guid_t *Protocol, efi_event_t Event, void **Registration); typedef efi_status_t (EFIAPI *efi_locate_handle_t)(efi_locate_search_type_t SearchType, efi_guid_t *Protocol, - void *SearchKey, uintn_t BufferSize, efi_handle_t *Buffer); + void *SearchKey, uintn_t *BufferSize, efi_handle_t *Buffer); typedef efi_status_t (EFIAPI *efi_locate_device_path_t)(efi_guid_t *Protocol, efi_device_path_t **DevicePath, efi_handle_t *Device); typedef efi_status_t (EFIAPI *efi_install_configuration_table_t)(efi_guid_t *Guid, void *Table); typedef efi_status_t (EFIAPI *efi_image_load_t)(boolean_t BootPolicy, efi_handle_t ParentImageHandle, efi_device_path_t *FilePath, - void *SourceBuffer, uintn_t SourceSie, efi_handle_t *ImageHandle); + void *SourceBuffer, uintn_t SourceSize, efi_handle_t *ImageHandle); typedef efi_status_t (EFIAPI *efi_image_start_t)(efi_handle_t ImageHandle, uintn_t *ExitDataSize, wchar_t **ExitData); typedef efi_status_t (EFIAPI *efi_exit_t)(efi_handle_t ImageHandle, efi_status_t ExitStatus, uintn_t ExitDataSize, wchar_t *ExitData); @@ -738,7 +742,7 @@ typedef efi_status_t (EFIAPI *efi_open_protocol_information_t)(efi_handle_t Hand typedef efi_status_t (EFIAPI *efi_protocols_per_handle_t)(efi_handle_t Handle, efi_guid_t ***ProtocolBuffer, uintn_t *ProtocolBufferCount); typedef efi_status_t (EFIAPI *efi_locate_handle_buffer_t)(efi_locate_search_type_t SearchType, efi_guid_t *Protocol, - void *SearchKey, uintn_t NoHandles, efi_handle_t **Handles); + void *SearchKey, uintn_t *NoHandles, efi_handle_t **Handles); typedef efi_status_t (EFIAPI *efi_locate_protocol_t)(efi_guid_t *Protocol, void *Registration, void **Interface); typedef efi_status_t (EFIAPI *efi_calculate_crc32_t)(void *Data, uintn_t DataSize, uint32_t *Crc32); @@ -1296,7 +1300,7 @@ extern void free (void *__ptr); extern void abort (void); extern void exit (int __status); /* exit Boot Services function. Returns 0 on success. */ -extern int exit_bs(); +extern int exit_bs(void); extern void *bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar); extern void qsort (void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar); extern int mblen (const char *__s, size_t __n); @@ -1412,6 +1416,7 @@ extern time_t time(time_t *__timer); extern unsigned int sleep (unsigned int __seconds); extern int usleep (unsigned long int __useconds); extern int unlink (const wchar_t *__filename); +extern int rmdir (const wchar_t *__filename); #ifdef __cplusplus }