mirror of
https://github.com/86Box/probing-tools.git
synced 2026-02-21 09:05:34 -07:00
pcireg: Update POSIX-UEFI tree
This commit is contained in:
@@ -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),)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <uefi.h>
|
||||
|
||||
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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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((a<b && a+n>b) || (b<a && b+n>a)) {
|
||||
if(src && dst && src != dst && n>0) {
|
||||
if(a>b && a<b+n) {
|
||||
a+=n-1; b+=n-1; while(n-->0) *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 && src<e) {*dst++=*src++;} *dst=0;
|
||||
}
|
||||
return dst;
|
||||
return s;
|
||||
}
|
||||
|
||||
char_t *strcat(char_t *dst, const char_t *src)
|
||||
{
|
||||
char_t *s = dst;
|
||||
if(src && dst) {
|
||||
dst += strlen(dst);
|
||||
while(*src) {*dst++=*src++;} *dst=0;
|
||||
}
|
||||
return dst;
|
||||
return s;
|
||||
}
|
||||
|
||||
int strcmp(const char_t *s1, const char_t *s2)
|
||||
{
|
||||
if(s1 && s2 && s1!=s2) {
|
||||
do{if(*s1!=*s2){return *s1-*s2;}s1++;s2++;}while(*s1!=0);
|
||||
while(*s1 && *s1==*s2){s1++;s2++;}
|
||||
return *s1-*s2;
|
||||
}
|
||||
return 0;
|
||||
@@ -153,19 +156,20 @@ int strcmp(const char_t *s1, const char_t *s2)
|
||||
|
||||
char_t *strncat(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) {
|
||||
dst += strlen(dst);
|
||||
while(*src && src<e) {*dst++=*src++;} *dst=0;
|
||||
}
|
||||
return dst;
|
||||
return s;
|
||||
}
|
||||
|
||||
int strncmp(const char_t *s1, const char_t *s2, size_t n)
|
||||
{
|
||||
const char_t *e = s1+n;
|
||||
if(s1 && s2 && s1!=s2 && n>0) {
|
||||
do{if(*s1!=*s2){return *s1-*s2;}s1++;s2++;}while(*s1!=0 && s1<e);
|
||||
while(s1<e && *s1 && *s1==*s2){s1++;s2++;}
|
||||
return *s1-*s2;
|
||||
}
|
||||
return 0;
|
||||
@@ -173,9 +177,9 @@ int strncmp(const char_t *s1, const char_t *s2, size_t n)
|
||||
|
||||
char_t *strdup(const char_t *s)
|
||||
{
|
||||
int i = (strlen(s)+1) * sizeof(char_t);
|
||||
size_t 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) memcpy(s2, (const void*)s, i);
|
||||
return s2;
|
||||
}
|
||||
|
||||
@@ -195,9 +199,9 @@ char_t *strrchr(const char_t *s, int c)
|
||||
char_t *e;
|
||||
if(s) {
|
||||
e = (char_t*)s + strlen(s) - 1;
|
||||
while(s < e) {
|
||||
while(s <= e) {
|
||||
if(*e == (char_t)c) return e;
|
||||
s--;
|
||||
e--;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -208,16 +212,16 @@ char_t *strstr(const char_t *haystack, const char_t *needle)
|
||||
return memmem(haystack, strlen(haystack) * sizeof(char_t), needle, strlen(needle) * sizeof(char_t));
|
||||
}
|
||||
|
||||
char_t *_strtok_r(char_t *s, const char_t *d, char_t **p)
|
||||
static char_t *_strtok_r(char_t *s, const char_t *d, char_t **p)
|
||||
{
|
||||
int c, sc;
|
||||
char_t *tok, *sp;
|
||||
|
||||
if(d == NULL || (s == NULL && (s=*p) == NULL)) return NULL;
|
||||
|
||||
again:
|
||||
c = *s++;
|
||||
for(sp = (char_t *)d; (sc=*sp++)!=0;) {
|
||||
if(c == sc) { *p=s; *(s-1)=0; return s-1; }
|
||||
if(c == sc) goto again;
|
||||
}
|
||||
|
||||
if (c == 0) { *p=NULL; return NULL; }
|
||||
@@ -239,7 +243,7 @@ char_t *_strtok_r(char_t *s, const char_t *d, char_t **p)
|
||||
|
||||
char_t *strtok(char_t *s, const char_t *delim)
|
||||
{
|
||||
char_t *p = s;
|
||||
static char_t *p;
|
||||
return _strtok_r (s, delim, &p);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,24 +31,25 @@
|
||||
#include <uefi.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user