Removed uefi_call_wrapper

This commit is contained in:
bzt 2021-02-02 01:26:30 +01:00
parent 69b6c8f003
commit 1bebb7ce51
18 changed files with 376 additions and 1512 deletions

11
Makefile Normal file
View file

@ -0,0 +1,11 @@
OVMF = /usr/share/qemu/bios-TianoCoreEFI.bin
all: $(wildcard examples/*)
.PHONY: Makefile
%: Makefile
@test -f $@/Makefile && make -C $@ all 2>/dev/null
test:
qemu-system-x86_64 -bios $(OVMF) -m 64 -enable-kvm -hda fat:rw:examples

View file

@ -5,11 +5,11 @@ POSIX-UEFI
We hate that horrible and ugly UEFI API, we want POSIX!
```
This is a very small library (32k) that helps you to develop for UEFI under Linux (and other POSIX systems). It was greatly
inspired by [gnu-efi](https://sourceforge.net/projects/gnu-efi) (big big kudos to those guys), but it is a lot smaller,
easier to integrate (works with Clang and GNU gcc both) and easier to use because it provides a POSIX like API.
This is a very small build environment that helps you to develop for UEFI under Linux (and other POSIX systems). It was
greatly inspired by [gnu-efi](https://sourceforge.net/projects/gnu-efi) (big big kudos to those guys), but it is a lot
smaller, easier to integrate (works with Clang and GNU gcc both) and easier to use because it provides a POSIX like API.
To use it, you have two options:
You have two options on how to integrate it into your project:
Distributing as Static Library
------------------------------
@ -36,8 +36,8 @@ Distributing as Source
This is the preferred way, as it also provides a Makefile to set up your toolchain properly.
1. simply copy the `uefi` directory into your source tree (or set up a git submodule). A dozen files, about 140K in total.
2. create an extremely simple **Makefile** like below
1. simply copy the `uefi` directory into your source tree (or set up a git submodule). A dozen files, about 96K in total.
2. create an extremely simple **Makefile** like the one below
3. compile your code for UEFI by running `make`
```
@ -55,6 +55,8 @@ int main(int argc, wchar_t **argv)
return 0;
}
```
By default it uses the host native's GNU gcc + ld, creates a shared object and converts that into .efi file. If `USE_LLVM`
is given, then LLVM CLang + lld used, and native PE is generated, no conversion involved.
### Available Makefile Options
@ -62,10 +64,10 @@ int main(int argc, wchar_t **argv)
|------------|------------------------------------------------------------------------------------------------------|
| `TARGET` | the target application (required) |
| `SRCS` | list of source files you want to compile (defaults to \*.c \*.S) |
| `CFALGS` | compiler flags you want to use (empty by default, like "-Wall -pedantic -std=c99") |
| `CFLAGS` | compiler flags you want to use (empty by default, like "-Wall -pedantic -std=c99") |
| `LDFLAGS` | linker flags you want to use (I don't think you'll ever need this, just in case) |
| `LIBS` | additional libraries you want to link with (like "-lm", only static .a libraries allowed) |
| `USE_LLVM` | set this if you want LLVM Clang / Lld instead of GNU gcc / ld |
| `USE_LLVM` | set this if you want LLVM Clang + Lld instead of GNU gcc + ld |
| `ARCH` | the target architecture (only x86_64 supported for now, but the toolchain can handle multiple archs) |
Here's a more advanced **Makefile** example:
@ -98,32 +100,31 @@ The EFI structures, enums, typedefs and defines are all converted to ANSI C stan
BOOLEAN -> boolean_t, UINTN -> uintn_t, EFI_MEMORY_DESCRIPTOR -> efi_memory_descriptor_t, and of course
EFI_BOOT_SERVICES -> efi_boot_services_t.
That header also provides an UEFI ABI wrapper, exactly the same as in gnu-efi, and functions to exit Boot Services
and to dump memory for your convenience.
Calling UEFI functions is as simple as with EDK II, just do the call, no need for "uefi_call_wrapper":
```c
ST->ConOut->OutputString(ST->ConOut, L"Hello World!\r\n");
```
| Function | Description |
|-----------------------|----------------------------------------------------|
| `uefi_call_wrapper()` | call a function with UEFI ABI (provided by crt0) |
| `uefi_exit_bs()` | leave this UEFI bullshit behind (provided by crt0) |
| `uefi_dumpmem()` | dump memory (provided by libuefi.a) |
There are two additional, non-POSIX calls in the library. One is `exit_bs()` to exit Boot Services, and the other is
a non-blocking `getchar_ifany()`.
Unlike gnu-efi, POSIX-UEFI does not pollute your application with unused GUID variables. It only provides header definitions,
so you must create each GUID instance if and when you need them.
Unlike gnu-efi, POSIX-UEFI does not pollute your application's namespace with unused GUID variables. It only provides
header definitions, so you must create each GUID instance if and when you need them.
Example:
```c
efi_guid_t gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
efi_gop_t *gop = NULL;
status = uefi_call_wrapper(BS->LocateProtocol, 3, &gopGuid, NULL, (void**)&gop);
status = BS->LocateProtocol(&gopGuid, NULL, (void**)&gop);
```
Also unlike gnu-efi, POSIX-UEFI does not provide standard EFI headers. It expects that you have installed those under
/usr/include/efi from EDK II or gnu-efi with your distro's package management solution, and POSIX-UEFI makes it possible
for you to use those system wide headers. POSIX-UEFI itself ships the very minimum set of typedefs and structs.
/usr/include/efi from EDK II or gnu-efi, and POSIX-UEFI makes it possible to use those system wide headers without
naming conflicts. POSIX-UEFI itself ships the very minimum set of typedefs and structs (with POSIX-ized names).
```c
#include <efi.h>
#include <uefi.h> /* this will work as expected! Both POSIX-UEFI and EDK II / gnu-efi typedefs accessible */
#include <uefi.h> /* this will work as expected! Both POSIX-UEFI and EDK II / gnu-efi typedefs available */
```
Notable Differences to POSIX libc
@ -158,6 +159,7 @@ List of Provided POSIX Functions
| free | as usual |
| abort | as usual |
| exit | as usual |
| exit_bs | leave this entire UEFI bullshit behind (exit Boot Services) |
| mbtowc | as usual (UTF-8 char to wchar_t) |
| wctomb | as usual (wchar_t to UTF-8 char) |
| mbstowcs | as usual (UTF-8 string to wchar_t string) |
@ -189,8 +191,10 @@ List of Provided POSIX Functions
String formating is limited; only supports padding via number prefixes, `%d`, `%x`, `%X`, `%c`, `%s`, `%q` and
`%p`. Because it operates on wchar_t, it also supports the non-standard `%C` (printing an UTF-8 character, needs
char\*), `%S` (printing an UTF-8 string), `%Q` (printing an escaped UTF-8 string). These functions don't allocate
memory, but in return the total length of the output string cannot be longer than BUFSIZ (8k), except for the
variants which have a maxlen argument.
memory, but in return the total length of the output string cannot be longer than BUFSIZ (8k if you haven't
defined otherwise), except for the variants which have a maxlen argument. For convenience, `%D` requires
`efi_physical_address_t` as argument, and it dumps memory, 16 bytes or one line at once. With the padding
modifier you can dump more lines, for example `%5D`.
### string.h
@ -222,7 +226,7 @@ variants which have a maxlen argument.
| Function | Description |
|---------------|----------------------------------------------------------------------------|
| localtime | no arguments, always returns current time in struct tm |
| localtime | argument unused, always returns current time in struct tm |
### unistd.h

View file

@ -5,7 +5,7 @@ TARGET = helloworld.efi
#define your sources here
SRCS = $(wildcard *.c)
# define your default compiler flags
CFLAGS = -Wall -Wextra -Werror --std=c11 -O2
CFLAGS = -pedantic -Wall -Wextra -Werror --std=c11 -O2
# define your default linker flags
#LDFLAGS =
# define your additional libraries here

View file

@ -1,9 +1,13 @@
#include <uefi.h>
/**
* Classic Hello World example
*/
int main(int argc, wchar_t **argv)
{
(void)argc;
(void)argv;
printf(L"Hello World!\n");
return 0;
}

View file

@ -1,3 +1,4 @@
TARGET = args.efi
#USE_LLVM=1
include uefi/Makefile

View file

@ -1,10 +1,15 @@
#include <uefi.h>
/**
* Print out arguments
*/
int main(int argc, wchar_t **argv)
{
int i;
printf(L"I got %d arguments:\n", argc);
for(i = 0; i < argc + 1; i++)
printf(L" argv[%d] = '%s'\n", argv[i]);
printf(L"I got %d argument%s:\n", argc, argc > 1 ? L"s" : L"");
for(i = 0; i < argc; i++)
printf(L" argv[%d] = '%s'\n", i, argv[i]);
return 0;
}

View file

@ -1,3 +1,4 @@
TARGET = dumpmem.efi
#USE_LLVM=1
include uefi/Makefile

View file

@ -1,9 +1,13 @@
#include <uefi.h>
/* this should accept 0x prefixes from the command line */
/**
* Dump memory at given address, should accept 0x prefixes from the command line
*/
int main(int argc, wchar_t **argv)
{
efi_physical_address_t address = (argc < 2 ? (efi_physical_address_t)IM : (efi_physical_address_t)atol(argv[1]));
uefi_dumpmem(address);
efi_physical_address_t address =
(argc < 2 ? (efi_physical_address_t)IM : (efi_physical_address_t)atol(argv[1]));
printf(L"%4D", address);
return 0;
}

View file

@ -5,16 +5,18 @@ endif
SRCS ?= $(wildcard *.c) $(wildcard *.S)
TMP = $(SRCS:.c=.o)
OBJS = $(TMP:.S=.o)
CFLAGS += -mno-red-zone -fpic -fshort-wchar -fno-strict-aliasing -ffreestanding -fno-stack-protector -fno-stack-check \
-D__$(ARCH)__ -I/usr/include -I. -I./uefi -I/usr/include/efi -I/usr/include/efi/$(ARCH) -I/usr/include/efi/protocol
LDFLAGS += -nostdlib -shared -Bsymbolic
CFLAGS += -mno-red-zone -fshort-wchar -fno-strict-aliasing -ffreestanding -fno-stack-protector -fno-stack-check \
-D__$(ARCH)__ -DHAVE_USE_MS_ABI \
-I/usr/include -I. -I./uefi -I/usr/include/efi -I/usr/include/efi/$(ARCH) -I/usr/include/efi/protocol
LIBSRCS = $(filter-out crt_$(ARCH).c,$(wildcard *.c)) $(wildcard *.S)
TMP = $(LIBSRCS:.c=.o)
LIBOBJS = $(TMP:.S=.o)
ifeq ($(USE_LLVM),)
CFLAGS += -Wno-builtin-declaration-mismatch
CFLAGS += -Wno-builtin-declaration-mismatch -fpic -maccumulate-outgoing-args
LDFLAGS += -nostdlib -shared -Bsymbolic -Luefi uefi/crt_$(ARCH).o
LIBS += -o $(TARGET).so -luefi -T uefi/elf_$(ARCH)_efi.lds
# see if we're cross-compiling
ifeq ($(ARCH),$(MYARCH))
CC = $(ARCH)-elf-gcc
@ -23,15 +25,16 @@ else
CC = gcc
LD = ld
endif
else
CFLAGS += --target=$(ARCH)-elf -Wno-builtin-requires-header -Wno-incompatible-library-redeclaration
LDFLAGS += -m elf_$(ARCH)
CC = clang
LD = ld.lld
endif
# you will need this from GNU binutils, llvm-objcopy won't cut it
OBJCOPY ?= objcopy
AR ?= ar
else
CFLAGS += --target=$(ARCH)-pc-win32-coff -Wno-builtin-requires-header -Wno-incompatible-library-redeclaration
LDFLAGS += -subsystem:efi_application -nodefaultlib -dll -entry:uefi_init uefi/*.o
LIBS = -out:$(TARGET)
CC = clang
LD = lld-link
OBJCOPY = true
endif
ifeq ($(wildcard uefi/Makefile),)
ALLTARGETS = crt_$(ARCH).o libuefi.a build
@ -42,18 +45,27 @@ endif
all: $(ALLTARGETS)
uefi/libuefi.a:
@make --no-print-directory -C uefi libuefi.a
make --no-print-directory -C uefi libuefi.a USE_LLVM=$(USE_LLVM)
libuefi.lib: $(LIBOBJS)
libuefi.a: $(LIBOBJS)
ifeq ($(USE_LLVM),)
@rm $@ 2>/dev/null || true
$(AR) -frsv $@ $(LIBOBJS) >/dev/null
else
true
endif
$(TARGET): $(TARGET).so
ifeq ($(USE_LLVM),)
@$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target efi-app-$(ARCH) --subsystem=10 $^ $@
@rm $(TARGET).so
endif
$(TARGET).so: uefi/crt_$(ARCH).o $(OBJS)
$(LD) $(LDFLAGS) -Luefi $^ -o $@ $(LIBS) -luefi -T uefi/elf_$(ARCH)_efi.lds
$(TARGET).so: $(OBJS)
$(LD) $(LDFLAGS) $^ $(LIBS)
@rm *.lib 2>/dev/null || true
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
@ -68,7 +80,7 @@ build:
@cp libuefi.a uefi.h ../build/uefi
clean:
@rm $(TARGET) *.o *.a $(LIBOBJS) 2>/dev/null || true
@rm $(TARGET) *.o *.a *.lib $(LIBOBJS) 2>/dev/null || true
distclean: clean
ifeq ($(wildcard uefi/Makefile),)

View file

@ -29,11 +29,35 @@
*/
#include <uefi.h>
#include <uefielf.h>
/* this is implemented by the application */
extern int main(int argc, wchar_t **argv);
/* definitions for elf relocations */
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
typedef uint64_t Elf64_Addr;
typedef struct
{
Elf64_Sxword d_tag; /* Dynamic entry type */
union
{
Elf64_Xword d_val; /* Integer value */
Elf64_Addr d_ptr; /* Address value */
} d_un;
} Elf64_Dyn;
#define DT_NULL 0 /* Marks end of dynamic section */
#define DT_RELA 7 /* Address of Rela relocs */
#define DT_RELASZ 8 /* Total size of Rela relocs */
#define DT_RELAENT 9 /* Size of one Rela reloc */
typedef struct
{
Elf64_Addr r_offset; /* Address */
Elf64_Xword r_info; /* Relocation type and symbol index */
} Elf64_Rel;
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
#define R_X86_64_RELATIVE 8 /* Adjust by program base */
/* globals to store system table pointers */
efi_handle_t IM = NULL;
efi_system_table_t *ST = NULL;
@ -47,6 +71,7 @@ void bootstrap()
__asm__ __volatile__ (
/* call init in C */
" .align 4;"
#ifndef __clang__
" .globl _start;"
"_start:"
" lea ImageBase(%rip), %rdi;"
@ -54,7 +79,20 @@ void bootstrap()
" call uefi_init;"
" ret;"
/*** the following code snipplets are borrowed from gnu-efi ***/
/* fake a relocation record, so that EFI won't complain */
" .data;"
"dummy: .long 0;"
" .section .reloc, \"a\";"
"label1:;"
" .long dummy-label1;"
" .long 10;"
" .word 0;"
".text;"
#else
" .globl __chkstk;"
"__chkstk:"
" ret;"
#endif
/* setjmp and longjmp */
" .globl setjmp;"
"setjmp:"
@ -85,152 +123,32 @@ void bootstrap()
" cmp %rax,%rdx;"
" cmove %rcx,%rax;"
" jmp *0x38(%rdi);"
/* for uefi_call_wrapper */
" .globl uefi_call0;"
"uefi_call0:"
" subq $40, %rsp;"
" call *%rdi;"
" addq $40, %rsp;"
" ret;"
" .globl uefi_call1;"
"uefi_call1:"
" subq $40, %rsp;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $40, %rsp;"
" ret;"
" .globl uefi_call2;"
"uefi_call2:"
" subq $40, %rsp;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $40, %rsp;"
" ret;"
" .globl uefi_call3;"
"uefi_call3:"
" subq $40, %rsp;"
" mov %rcx, %r8;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $40, %rsp;"
" ret;"
" .globl uefi_call4;"
"uefi_call4:"
" subq $40, %rsp;"
" mov %r8, %r9;"
" mov %rcx, %r8;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $40, %rsp;"
" ret;"
" .globl uefi_call5;"
"uefi_call5:"
" subq $40, %rsp;"
" mov %r9, 32(%rsp);"
" mov %r8, %r9;"
" mov %rcx, %r8;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $40, %rsp;"
" ret;"
" .globl uefi_call6;"
"uefi_call6:"
" subq $56, %rsp;"
" mov 56+8(%rsp), %rax;"
" mov %rax, 40(%rsp);"
" mov %r9, 32(%rsp);"
" mov %r8, %r9;"
" mov %rcx, %r8;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $56, %rsp;"
" ret;"
" .globl uefi_call7;"
"uefi_call7:"
" subq $56, %rsp;"
" mov 56+16(%rsp), %rax;"
" mov %rax, 48(%rsp);"
" mov 56+8(%rsp), %rax;"
" mov %rax, 40(%rsp);"
" mov %r9, 32(%rsp);"
" mov %r8, %r9;"
" mov %rcx, %r8;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $56, %rsp;"
" ret;"
" .globl uefi_call8;"
"uefi_call8:"
" subq $72, %rsp;"
" mov 72+24(%rsp), %rax;"
" mov %rax, 56(%rsp);"
" mov 72+16(%rsp), %rax;"
" mov %rax, 48(%rsp);"
" mov 72+8(%rsp), %rax;"
" mov %rax, 40(%rsp);"
" mov %r9, 32(%rsp);"
" mov %r8, %r9;"
" mov %rcx, %r8;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $72, %rsp;"
" ret;"
" .globl uefi_call9;"
"uefi_call9:"
" subq $72, %rsp;"
" mov 72+32(%rsp), %rax;"
" mov %rax, 64(%rsp);"
" mov 72+24(%rsp), %rax;"
" mov %rax, 56(%rsp);"
" mov 72+16(%rsp), %rax;"
" mov %rax, 48(%rsp);"
" mov 72+8(%rsp), %rax;"
" mov %rax, 40(%rsp);"
" mov %r9, 32(%rsp);"
" mov %r8, %r9;"
" mov %rcx, %r8;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $72, %rsp;"
" ret;"
" .globl uefi_call10;"
"uefi_call10:"
" subq $88, %rsp;"
" mov 88+40(%rsp), %rax;"
" mov %rax, 72(%rsp);"
" mov 88+32(%rsp), %rax;"
" mov %rax, 64(%rsp);"
" mov 88+24(%rsp), %rax;"
" mov %rax, 56(%rsp);"
" mov 88+16(%rsp), %rax;"
" mov %rax, 48(%rsp);"
" mov 88+8(%rsp), %rax;"
" mov %rax, 40(%rsp);"
" mov %r9, 32(%rsp);"
" mov %r8, %r9;"
" mov %rcx, %r8;"
" mov %rsi, %rcx;"
" call *%rdi;"
" addq $88, %rsp;"
" ret;"
);
}
/**
* Initialize POSIX-UEFI and call teh application's main() function
* Initialize POSIX-UEFI and call the application's main() function
*/
int uefi_init (efi_handle_t image, efi_system_table_t *systab, uintptr_t ldbase, Elf64_Dyn *dyn) {
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
uintptr_t *addr;
int uefi_init (
#ifndef __clang__
uintptr_t ldbase, Elf64_Dyn *dyn, efi_system_table_t *systab, efi_handle_t image
#else
efi_handle_t image, efi_system_table_t *systab
#endif
) {
efi_guid_t shpGuid = EFI_SHELL_PARAMETERS_PROTOCOL_GUID;
efi_shell_parameters_protocol_t *shp = NULL;
efi_guid_t shiGuid = SHELL_INTERFACE_PROTOCOL_GUID;
efi_shell_interface_protocol_t *shi = NULL;
efi_guid_t lipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
efi_status_t status;
int i, argc = 0;
int argc = 0;
wchar_t **argv = NULL;
#ifndef __clang__
int i;
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
uintptr_t *addr;
/* handle relocations */
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
switch (dyn[i].d_tag) {
@ -248,39 +166,21 @@ int uefi_init (efi_handle_t image, efi_system_table_t *systab, uintptr_t ldbase,
relsz -= relent;
}
}
#endif
/* save EFI pointers and loaded image into globals */
IM = image;
ST = systab;
BS = systab->BootServices;
RT = systab->RuntimeServices;
uefi_call_wrapper(BS->HandleProtocol, 3, image, &lipGuid, (void **) &LIP);
BS->HandleProtocol(image, &lipGuid, (void **)&LIP);
/* get command line arguments */
status = uefi_call_wrapper(BS->OpenProtocol, 6, image, &shpGuid, &shp, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
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; }
else {
/* if shell 2.0 failed, fallback to shell 1.0 interface */
status = uefi_call_wrapper(BS->OpenProtocol, 6, image, &shiGuid, &shi, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
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; }
}
/* call main */
return main(argc, argv);
}
/**
* Exit Boot Services
*/
boolean_t uefi_exit_bs()
{
efi_status_t status;
efi_memory_descriptor_t *memory_map = NULL;
uintn_t cnt = 3, memory_map_size=0, map_key=0, desc_size=0;
while(cnt--) {
status = uefi_call_wrapper(BS->GetMemoryMap, 5, &memory_map_size, memory_map, &map_key, &desc_size, NULL);
if (status!=EFI_BUFFER_TOO_SMALL) break;
status = uefi_call_wrapper(BS->ExitBootServices, 2, IM, map_key);
if(!EFI_ERROR(status)) return 1;
}
return 0;
}

View file

@ -32,16 +32,27 @@
static efi_file_handle_t *__root_dir = NULL;
void __stdio_seterrno(efi_status_t status)
{
switch((int)(status & 0xffff)) {
case EFI_WRITE_PROTECTED & 0xffff: errno = EROFS; break;
case EFI_ACCESS_DENIED & 0xffff: errno = EACCES; break;
case EFI_VOLUME_FULL & 0xffff: errno = ENOSPC; break;
case EFI_NOT_FOUND & 0xffff: errno = ENOENT; break;
default: errno = EIO; break;
}
}
int fclose (FILE *__stream)
{
efi_status_t status = uefi_call_wrapper(__stream->Close, 1, __stream);
efi_status_t status = __stream->Close(__stream);
free(__stream);
return !EFI_ERROR(status);
}
int fflush (FILE *__stream)
{
efi_status_t status = uefi_call_wrapper(__stream->Flush, 1, __stream);
efi_status_t status = __stream->Flush(__stream);
return !EFI_ERROR(status);
}
@ -52,9 +63,9 @@ FILE *fopen (const wchar_t *__filename, const char *__modes)
efi_guid_t sfsGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
efi_simple_file_system_protocol_t *sfs = NULL;
if(!__root_dir && LIP) {
status = uefi_call_wrapper(BS->HandleProtocol, 3, LIP->DeviceHandle, &sfsGuid, &sfs);
status = BS->HandleProtocol(LIP->DeviceHandle, &sfsGuid, (void **)&sfs);
if(!EFI_ERROR(status))
status = uefi_call_wrapper(sfs->OpenVolume, 2, sfs, &__root_dir);
status = sfs->OpenVolume(sfs, &__root_dir);
}
if(!__root_dir) {
errno = ENODEV;
@ -63,16 +74,10 @@ FILE *fopen (const wchar_t *__filename, const char *__modes)
errno = 0;
ret = (FILE*)malloc(sizeof(FILE));
if(!ret) return NULL;
status = uefi_call_wrapper(__root_dir->Open, 5, __root_dir, ret, __filename,
status = __root_dir->Open(__root_dir, &ret, (wchar_t*)__filename,
__modes[0] == L'r' ? EFI_FILE_MODE_READ : (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE), 0);
if(EFI_ERROR(status)) {
switch((int)(status & 0xffff)) {
case EFI_WRITE_PROTECTED & 0xffff: errno = EROFS; break;
case EFI_ACCESS_DENIED & 0xffff: errno = EACCES; break;
case EFI_VOLUME_FULL & 0xffff: errno = ENOSPC; break;
case EFI_NOT_FOUND & 0xffff: errno = ENOENT; break;
default: errno = EIO; break;
}
__stdio_seterrno(status);
free(ret); ret = NULL;
}
if(__modes[0] == L'a') fseek(ret, 0, SEEK_END);
@ -82,7 +87,7 @@ FILE *fopen (const wchar_t *__filename, const char *__modes)
size_t fread (void *__ptr, size_t __size, size_t __n, FILE *__stream)
{
uintn_t bs = __size * __n;
efi_status_t status = uefi_call_wrapper(__stream->Read, 3, __stream, &bs, __ptr);
efi_status_t status = __stream->Read(__stream, &bs, __ptr);
if(status == EFI_END_OF_FILE) bs = 0;
return bs / __size;
}
@ -90,7 +95,7 @@ size_t fread (void *__ptr, size_t __size, size_t __n, FILE *__stream)
size_t fwrite (const void *__ptr, size_t __size, size_t __n, FILE *__stream)
{
uintn_t bs = __size * __n;
efi_status_t status = uefi_call_wrapper(__stream->Write, 3, __stream, &bs, __ptr);
efi_status_t status = __stream->Write(__stream, &bs, (void *)__ptr);
return bs / __size;
}
@ -103,21 +108,21 @@ int fseek (FILE *__stream, long int __off, int __whence)
uintn_t infosiz = sizeof(efi_file_info_t) + 16;
switch(__whence) {
case SEEK_END:
status = uefi_call_wrapper(__stream->GetInfo, 4, __stream, &infoGuid, &infosiz, info);
status = __stream->GetInfo(__stream, &infoGuid, &infosiz, info);
if(!EFI_ERROR(status)) {
off = info->FileSize + __off;
status = uefi_call_wrapper(__stream->SetPosition, 2, __stream, &off);
status = __stream->SetPosition(__stream, off);
}
break;
case SEEK_CUR:
status = uefi_call_wrapper(__stream->GetPosition, 2, __stream, &off);
status = __stream->GetPosition(__stream, &off);
if(!EFI_ERROR(status)) {
off += __off;
status = uefi_call_wrapper(__stream->SetPosition, 2, __stream, &off);
status = __stream->SetPosition(__stream, off);
}
break;
default:
status = uefi_call_wrapper(__stream->SetPosition, 2, __stream, &off);
status = __stream->SetPosition(__stream, off);
break;
}
return EFI_ERROR(status) ? -1 : 0;
@ -126,7 +131,7 @@ int fseek (FILE *__stream, long int __off, int __whence)
long int ftell (FILE *__stream)
{
uint64_t off = 0;
efi_status_t status = uefi_call_wrapper(__stream->GetPosition, 2, __stream, &off);
efi_status_t status = __stream->GetPosition(__stream, &off);
return EFI_ERROR(status) ? -1 : (long int)off;
}
@ -134,16 +139,18 @@ int vsnprintf(wchar_t *dst, size_t maxlen, const wchar_t *fmt, __builtin_va_list
{
#define needsescape(a) (a==L'\"' || a==L'\\' || a==L'\a' || a==L'\b' || a==L'\033' || a=='\f' || \
a==L'\r' || a==L'\n' || a==L'\t' || a=='\v')
long int arg;
int len, sign, i;
wchar_t *p, *orig=dst, tmpstr[19], pad=' ';
efi_physical_address_t m;
uint8_t *mem;
int64_t arg;
int len, sign, i, j;
wchar_t *p, *orig=dst, *end = dst + maxlen - 1, tmpstr[19], pad=' ', n;
char *c;
if(dst==NULL || fmt==NULL)
return 0;
arg = 0;
while(*fmt && (dst - orig) + 1 < maxlen) {
while(*fmt && dst < end) {
if(*fmt==L'%') {
fmt++;
if(*fmt==L'%') goto put;
@ -211,7 +218,7 @@ int vsnprintf(wchar_t *dst, size_t maxlen, const wchar_t *fmt, __builtin_va_list
hex: i=16;
tmpstr[i]=0;
do {
wchar_t n=arg & 0xf;
n=arg & 0xf;
/* 0-9 => '0'-'9', 10-15 => 'A'-'F' */
tmpstr[--i]=n+(n>9?(*fmt==L'X'?0x37:0x57):0x30);
arg>>=4;
@ -230,7 +237,7 @@ hex: i=16;
copystring: if(p==NULL) {
p=L"(null)";
}
while(*p && (dst - orig) + 2 < maxlen) {
while(*p && dst + 2 < end) {
if(*fmt==L'q' && needsescape(*p)) {
*dst++ = L'\\';
switch(*p) {
@ -251,7 +258,7 @@ copystring: if(p==NULL) {
if(*fmt==L'S' || *fmt==L'Q') {
c = __builtin_va_arg(args, char*);
if(c==NULL) goto copystring;
while(*p && (dst - orig) + 2 < maxlen) {
while(*p && dst + 2 < end) {
arg = *c;
if((*c & 128) != 0) {
if((*c & 32) == 0 ) {
@ -282,16 +289,44 @@ copystring: if(p==NULL) {
case L'\v': *dst++ = L'v'; break;
default: *dst++ = arg; break;
}
} else
} else {
if(arg == L'\n') *dst++ = L'\r';
*dst++ = (wchar_t)(arg & 0xffff);
}
}
} else
if(*fmt==L'D') {
m = __builtin_va_arg(args, efi_physical_address_t);
for(j = 0; j < (len < 1 ? 1 : (len > 16 ? 16 : len)); j++) {
for(i = 44; i >= 0; i -= 4) {
n = (m >> i) & 15; *dst++ = n + (n>9?0x37:0x30);
if(dst >= end) goto zro;
}
*dst++ = L':'; if(dst >= end) goto zro;
*dst++ = L' '; if(dst >= end) goto zro;
mem = (uint8_t*)m;
for(i = 0; i < 16; i++) {
n = (mem[i] >> 4) & 15; *dst++ = n + (n>9?0x37:0x30); if(dst >= end) goto zro;
n = mem[i] & 15; *dst++ = n + (n>9?0x37:0x30); if(dst >= end) goto zro;
*dst++ = L' ';if(dst >= end) goto zro;
}
*dst++ = L' '; if(dst >= end) goto zro;
for(i = 0; i < 16; i++) {
*dst++ = (mem[i] < 32 || mem[i] >= 127 ? L'.' : mem[i]);
if(dst >= end) goto zro;
}
*dst++ = L'\r'; if(dst >= end) goto zro;
*dst++ = L'\n'; if(dst >= end) goto zro;
m += 16;
}
}
} else {
put: *dst++ = *fmt;
put: if(*fmt == L'\n') *dst++ = L'\r';
*dst++ = *fmt;
}
fmt++;
}
*dst=0;
zro:*dst=0;
return dst-orig;
#undef needsescape
}
@ -320,7 +355,7 @@ int vprintf(const wchar_t* fmt, __builtin_va_list args)
wchar_t dst[BUFSIZ];
int ret;
ret = vsnprintf(dst, sizeof(dst), fmt, args);
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, &dst);
ST->ConOut->OutputString(ST->ConOut, (wchar_t *)&dst);
return ret;
}
@ -334,16 +369,16 @@ int printf(const wchar_t* fmt, ...)
int vfprintf (FILE *__stream, const wchar_t *__format, __builtin_va_list args)
{
wchar_t dst[BUFSIZ];
int ret;
uintn_t ret;
if(__stream == stdin) return 0;
ret = vsnprintf(dst, sizeof(dst), __format, args);
if(ret < 1) return 0;
if(__stream == stdout)
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, &dst);
ST->ConOut->OutputString(ST->ConOut, (wchar_t*)&dst);
else if(__stream == stderr)
uefi_call_wrapper(ST->StdErr->OutputString, 2, ST->StdErr, &dst);
ST->StdErr->OutputString(ST->StdErr, (wchar_t*)&dst);
else
uefi_call_wrapper(__stream->Write, 3, __stream, &ret, &dst);
__stream->Write(__stream, &ret, (wchar_t*)&dst);
return ret;
}
@ -357,7 +392,7 @@ int fprintf (FILE *__stream, const wchar_t *__format, ...)
int getchar (void)
{
efi_input_key_t key;
efi_status_t status = uefi_call_wrapper(ST->ConIn, 2, ST->ConIn, &key);
efi_status_t status = ST->ConIn->ReadKeyStroke(ST->ConIn, &key);
return EFI_ERROR(status) ? -1 : key.UnicodeChar;
}
@ -365,9 +400,9 @@ int getchar (void)
int getchar_ifany (void)
{
efi_input_key_t key;
efi_status_t status = uefi_call_wrapper(BS->CheckEvent, 1, ST->ConIn->WaitForKey);
efi_status_t status = BS->CheckEvent(ST->ConIn->WaitForKey);
if(!status) {
status = uefi_call_wrapper(ST->ConIn, 2, ST->ConIn, &key);
status = ST->ConIn->ReadKeyStroke(ST->ConIn, &key);
return EFI_ERROR(status) ? -1 : key.UnicodeChar;
}
return 0;
@ -378,23 +413,6 @@ int putchar (int __c)
wchar_t tmp[2];
tmp[0] = (wchar_t)__c;
tmp[1] = 0;
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, &tmp);
ST->ConOut->OutputString(ST->ConOut, (__c == L'\n' ? (wchar_t*)L"\r\n" : (wchar_t*)&tmp));
return (int)tmp[0];
}
/* this isn't POSIX, but also uses sprintf */
void uefi_dumpmem(efi_physical_address_t address)
{
uint8_t *mem = (uint8_t*)(address & ~0xF);
int i, j;
wchar_t tmp[128], *t;
for(j = 0; j < 8; j++) {
t = tmp + sprintf(tmp, L"%p: ");
for(i = 0; i < 16; i++)
t += sprintf(t, L"%02x %s", mem[i], i % 4 == 3 ? L" " : L"");
for(i = 0; i < 16; i++)
t += sprintf(t, L" %c", mem[i] < 32 || mem[i] >= 127 ? L'.' : mem[i]);
uefi_call_wrapper(ST->StdErr->OutputString, 2, ST->StdErr, &tmp);
mem += 16;
}
}

View file

@ -30,34 +30,36 @@
#include <uefi.h>
int errno = 0;
int atoi(const wchar_t *s)
{
return (int)atol(s);
}
long int atol(const wchar_t *s)
int64_t atol(const wchar_t *s)
{
long int sign = 1;
int64_t sign = 1;
if(!s || !*s) return 0;
if(*s == '-') { sign = -1; s++; }
if(s[0] == '0') {
if(s[1] == 'x')
if(*s == L'-') { sign = -1; s++; }
if(s[0] == L'0') {
if(s[1] == L'x')
return strtol(s + 2, NULL, 16);
if(s[1] >= '0' && s[1] <= '7')
if(s[1] >= L'0' && s[1] <= L'7')
return strtol(s, NULL, 8);
}
return strtol(s, NULL, 10) * sign;
}
long int strtol (const wchar_t *s, wchar_t **__endptr, int __base)
int64_t strtol (const wchar_t *s, wchar_t **__endptr, int __base)
{
long int v=0, sign = 1;
int64_t v=0, sign = 1;
if(!s || !*s) return 0;
if(*s == '-') { sign = -1; s++; }
while(*s < L'0' || (__base < 10 && *s >= __base + L'0') || (__base > 10 && ((*s > L'9' && *s < L'A') ||
(*s > L'F' && *s < L'a') || *s > L'f'))) {
if(*s == L'-') { sign = -1; s++; }
while(!(*s < L'0' || (__base < 10 && *s >= __base + L'0') || (__base >= 10 && ((*s > L'9' && *s < L'A') ||
(*s > L'F' && *s < L'a') || *s > L'f')))) {
v *= __base;
if(*s >= L'0' && *s < (__base < 10 ? __base + L'0' : L'9'))
if(*s >= L'0' && *s <= (__base < 10 ? __base + L'0' : L'9'))
v += (*s)-L'0';
else if(__base == 16 && *s >= L'a' && *s <= L'f')
v += (*s)-L'a'+10;
@ -72,7 +74,7 @@ long int strtol (const wchar_t *s, wchar_t **__endptr, int __base)
void *malloc (size_t __size)
{
void *ret = NULL;
efi_status_t status = uefi_call_wrapper(BS->AllocatePool, 3, LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
efi_status_t status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
if(!EFI_ERROR(status) || !ret) errno = ENOMEM;
return ret;
}
@ -80,7 +82,7 @@ void *malloc (size_t __size)
void *calloc (size_t __nmemb, size_t __size)
{
void *ret = malloc(__nmemb * __size);
if(ret) __builtin_memset(ret, 0, __nmemb * __size);
if(ret) memset(ret, 0, __nmemb * __size);
return ret;
}
@ -89,13 +91,13 @@ void *realloc (void *__ptr, size_t __size)
#if 1
void *ret = __ptr;
/* not sure if this works */
efi_status_t status = uefi_call_wrapper(BS->AllocatePool, 3, LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
efi_status_t status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
if(!EFI_ERROR(status) || !ret) errno = ENOMEM;
return ret;
#else
void *ret = malloc(__size);
/* this isn't perfect, because we don't know the original size... */
if(ret && __ptr) __builtin_memcpy(ret, __ptr, __size);
if(ret && __ptr) memcpy(ret, __ptr, __size);
if(__ptr) free(__ptr);
return ret;
#endif
@ -103,18 +105,33 @@ void *realloc (void *__ptr, size_t __size)
void free (void *__ptr)
{
efi_status_t status = uefi_call_wrapper(BS->FreePool, 1, __ptr);
efi_status_t status = BS->FreePool(__ptr);
if(!EFI_ERROR(status)) errno = ENOMEM;
}
void abort ()
{
uefi_call_wrapper(BS->Exit, 4, IM, EFI_ABORTED, 0, NULL);
BS->Exit(IM, EFI_ABORTED, 0, NULL);
}
void exit (int __status)
{
uefi_call_wrapper(BS->Exit, 4, IM, !__status ? 0 : (__status < 0 ? EFIERR(-__status) : EFIERR(__status)), 0, NULL);
BS->Exit(IM, !__status ? 0 : (__status < 0 ? EFIERR(-__status) : EFIERR(__status)), 0, NULL);
}
int exit_bs()
{
efi_status_t status;
efi_memory_descriptor_t *memory_map = NULL;
uintn_t cnt = 3, memory_map_size=0, map_key=0, desc_size=0;
while(cnt--) {
status = BS->GetMemoryMap(&memory_map_size, memory_map, &map_key, &desc_size, NULL);
if (status!=EFI_BUFFER_TOO_SMALL) break;
status = BS->ExitBootServices(IM, map_key);
if(!EFI_ERROR(status)) return 0;
}
return (int)(status & 0xffff);
}
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, __compar_fn_t cmp)
@ -174,7 +191,7 @@ int wctomb (char *s, wchar_t u)
*(s+0)=((u>>6)&0x1F)|0xC0;
*(s+1)=(u&0x3F)|0x80;
ret = 2;
} else if(u<0x10000) {
} else {
*(s+0)=((u>>12)&0x0F)|0xE0;
*(s+1)=((u>>6)&0x3F)|0x80;
*(s+2)=(u&0x3F)|0x80;
@ -211,4 +228,3 @@ size_t wcstombs (char *__s, const wchar_t *__pwcs, size_t __n)
};
return __s - orig;
}

View file

@ -30,9 +30,73 @@
#include <uefi.h>
/* for gcc we use the built-in variants, but clang doesn't have those */
#ifdef __clang__
void *memcpy(void *dst, const void *src, size_t n)
{
uint8_t *a=(uint8_t*)dst,*b=(uint8_t*)src;
if(src && dst && n>0) {
while(n--) *a++ = *b++;
}
return dst;
}
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)) {
a+=n-1; b+=n-1; while(n-->0) *a--=*b--;
} else {
while(n--) *a++ = *b++;
}
}
return dst;
}
void *memset(void *s, int c, size_t n)
{
uint8_t *p=(uint8_t*)s;
if(s && n>0) {
while(n--) *p++ = c;
}
return s;
}
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) {
while(n--) {
if(*a != *b) return *a - *b;
a++; b++;
}
}
return 0;
}
void *memchr (const void *s, int c, size_t n)
{
uint8_t *e, *p=(uint8_t*)s;
if(s && n>0) {
for(e=p+n; p<e; p++) if(*p==(uint8_t)c) return p;
}
return NULL;
}
void *memrchr (const void *s, int c, size_t n)
{
uint8_t *e, *p=(uint8_t*)s;
if(s && n>0) {
for(e=p+n; p<e; --e) if(*e==(uint8_t)c) return e;
}
return NULL;
}
#endif
void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl)
{
char *c = (char*)haystack;
uint8_t *c = (uint8_t*)haystack;
if(!haystack || !needle || !hl || !nl || nl > hl) return NULL;
hl -= nl;
while(hl) {
@ -44,7 +108,7 @@ void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl)
void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl)
{
char *c = (char*)haystack;
uint8_t *c = (uint8_t*)haystack;
if(!haystack || !needle || !hl || !nl || nl > hl) return NULL;
hl -= nl;
c += hl;

View file

@ -35,10 +35,11 @@ static struct tm __tm;
/**
* This isn't POSIX, no arguments. Just returns the current time in struct tm
*/
struct tm *localtime ()
struct tm *localtime (const time_t *__timer)
{
efi_time_t t;
uefi_call_wrapper(ST->RuntimeServices->GetTime, 2, &t, NULL);
efi_time_t t = {0};
(void)__timer;
ST->RuntimeServices->GetTime(&t, NULL);
__tm.tm_year = t.Year + 98;
__tm.tm_mon = t.Month - 1;
__tm.tm_mday = t.Day;

View file

@ -28,42 +28,6 @@
*
*/
/*
* Some parts (like the uefi_call_wrapper) are borrowed from gnu-efi (https://sourceforge.net/projects/gnu-efi)
* which are created by the following author and licensed under the following terms (from README.gnuefi and
* README.efilib, because there's no LICENSE file in gnu-efi's repo):
*
* David Mosberger <davidm@hpl.hp.com>
* 23 September 1999
* Copyright (c) 1999-2007 Hewlett-Packard Co.
* Copyright (c) 2006-2010 Intel Co.
*
* Copyright (c) 1998-2000 Intel Corporation
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and
* the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. THE EFI SPECIFICATION AND ALL OTHER INFORMATION
* ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO WARRANTIES, AND ARE SUBJECT
* TO CHANGE WITHOUT NOTICE.
*/
#ifndef _UEFI_H_
#define _UEFI_H_
@ -72,7 +36,21 @@ extern "C" {
#endif
/* get these from the compiler */
#include <stdint.h>
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
#ifndef __clang__
typedef long int int64_t;
typedef unsigned long int uint64_t;
typedef unsigned long int uintptr_t;
#else
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef unsigned long long uintptr_t;
#endif
#ifndef NULL
#define NULL ((void*)0)
@ -83,6 +61,7 @@ typedef uint8_t boolean_t;
typedef uint16_t wchar_t;
typedef uint64_t uintn_t;
typedef uint64_t size_t;
typedef uint64_t time_t;
typedef uint64_t efi_status_t;
typedef uint64_t efi_tpl_t;
typedef uint64_t efi_lba_t;
@ -91,77 +70,6 @@ typedef uint64_t efi_virtual_address_t;
typedef void *efi_handle_t;
typedef void *efi_event_t;
/* exit Boot Services function. Returns true on success. */
boolean_t uefi_exit_bs();
/* dump memory to stderr */
void uefi_dumpmem(efi_physical_address_t address);
/* Prototypes of EFI cdecl -> stdcall trampolines */
uint64_t uefi_call0(void *func);
uint64_t uefi_call1(void *func, uint64_t arg1);
uint64_t uefi_call2(void *func, uint64_t arg1, uint64_t arg2);
uint64_t uefi_call3(void *func, uint64_t arg1, uint64_t arg2, uint64_t arg3);
uint64_t uefi_call4(void *func, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);
uint64_t uefi_call5(void *func, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5);
uint64_t uefi_call6(void *func, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6);
uint64_t uefi_call7(void *func, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
uint64_t arg7);
uint64_t uefi_call8(void *func, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
uint64_t arg7, uint64_t arg8);
uint64_t uefi_call9(void *func, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
uint64_t arg7, uint64_t arg8, uint64_t arg9);
uint64_t uefi_call10(void *func, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
uint64_t arg7, uint64_t arg8, uint64_t arg9, uint64_t arg10);
#ifndef uefi_call_wrapper
/*
Credits for macro-magic:
https://groups.google.com/forum/?fromgroups#!topic/comp.std.c/d-6Mj5Lko_s
http://efesx.com/2010/08/31/overloading-macros/
*/
#define __VA_NARG__(...) __VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N())
#define __VA_NARG_(...) __VA_ARG_N(__VA_ARGS__)
#define __VA_ARG_N(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
#define __RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define __VA_ARG_NSUFFIX__(prefix,...) __VA_ARG_NSUFFIX_N(prefix, __VA_NARG__(__VA_ARGS__))
#define __VA_ARG_NSUFFIX_N(prefix,nargs) __VA_ARG_NSUFFIX_N_(prefix, nargs)
#define __VA_ARG_NSUFFIX_N_(prefix,nargs) prefix ## nargs
/* Front-ends to efi_callX to avoid compiler warnings */
#define _cast64_uefi_call0(f) \
uefi_call0(f)
#define _cast64_uefi_call1(f,a1) \
uefi_call1(f, (uint64_t)(a1))
#define _cast64_uefi_call2(f,a1,a2) \
uefi_call2(f, (uint64_t)(a1), (uint64_t)(a2))
#define _cast64_uefi_call3(f,a1,a2,a3) \
uefi_call3(f, (uint64_t)(a1), (uint64_t)(a2), (uint64_t)(a3))
#define _cast64_uefi_call4(f,a1,a2,a3,a4) \
uefi_call4(f, (uint64_t)(a1), (uint64_t)(a2), (uint64_t)(a3), (uint64_t)(a4))
#define _cast64_uefi_call5(f,a1,a2,a3,a4,a5) \
uefi_call5(f, (uint64_t)(a1), (uint64_t)(a2), (uint64_t)(a3), (uint64_t)(a4), \
(uint64_t)(a5))
#define _cast64_uefi_call6(f,a1,a2,a3,a4,a5,a6) \
uefi_call6(f, (uint64_t)(a1), (uint64_t)(a2), (uint64_t)(a3), (uint64_t)(a4), \
(uint64_t)(a5), (uint64_t)(a6))
#define _cast64_uefi_call7(f,a1,a2,a3,a4,a5,a6,a7) \
uefi_call7(f, (uint64_t)(a1), (uint64_t)(a2), (uint64_t)(a3), (uint64_t)(a4), \
(uint64_t)(a5), (uint64_t)(a6), (uint64_t)(a7))
#define _cast64_uefi_call8(f,a1,a2,a3,a4,a5,a6,a7,a8) \
uefi_call8(f, (uint64_t)(a1), (uint64_t)(a2), (uint64_t)(a3), (uint64_t)(a4), \
(uint64_t)(a5), (uint64_t)(a6), (uint64_t)(a7), (uint64_t)(a8))
#define _cast64_uefi_call9(f,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
uefi_call9(f, (uint64_t)(a1), (uint64_t)(a2), (uint64_t)(a3), (uint64_t)(a4), \
(uint64_t)(a5), (uint64_t)(a6), (uint64_t)(a7), (uint64_t)(a8), \
(uint64_t)(a9))
#define _cast64_uefi_call10(f,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
uefi_call10(f, (uint64_t)(a1), (uint64_t)(a2), (uint64_t)(a3), (uint64_t)(a4), \
(uint64_t)(a5), (uint64_t)(a6), (uint64_t)(a7), (uint64_t)(a8), \
(uint64_t)(a9), (uint64_t)(a10))
/* main wrapper (va_num ignored) */
#define uefi_call_wrapper(func,va_num,...) \
__VA_ARG_NSUFFIX__(_cast64_uefi_call, __VA_ARGS__) (func , ##__VA_ARGS__)
#endif
typedef struct {
uint32_t Data1;
uint16_t Data2;
@ -223,11 +131,10 @@ typedef struct {
/* efistdarg.h */
typedef __builtin_va_list va_list;
# define va_start(v,l) __builtin_va_start(v,l)
# define va_end(v) __builtin_va_end(v)
# define va_arg(v,l) __builtin_va_arg(v,l)
# define va_copy(d,s) __builtin_va_copy(d,s)
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#define va_copy(d,s) __builtin_va_copy(d,s)
/* efierr.h */
#define EFIWARN(a) (a)
@ -1247,14 +1154,16 @@ extern int errno;
/* stdlib.h */
typedef int (*__compar_fn_t) (const void *, const void *);
extern int atoi (const wchar_t *__nptr);
extern long int atol (const wchar_t *__nptr);
extern long int strtol (const wchar_t *__nptr, wchar_t **__endptr, int __base);
extern int64_t atol (const wchar_t *__nptr);
extern int64_t strtol (const wchar_t *__nptr, wchar_t **__endptr, int __base);
extern void *malloc (size_t __size);
extern void *calloc (size_t __nmemb, size_t __size);
extern void *realloc (void *__ptr, size_t __size);
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 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);
@ -1264,7 +1173,9 @@ extern size_t mbstowcs (wchar_t *__pwcs, const char *__s, size_t __n);
extern size_t wcstombs (char *__s, const wchar_t *__pwcs, size_t __n);
/* stdio.h */
#ifndef BUFSIZ
#define BUFSIZ 8192
#endif
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
@ -1289,15 +1200,26 @@ extern int vsprintf (wchar_t *__s, const wchar_t *__format, __builtin_va_list __
extern int snprintf (wchar_t *__s, size_t __maxlen, const wchar_t *__format, ...);
extern int vsnprintf (wchar_t *__s, size_t __maxlen, const wchar_t *__format, __builtin_va_list __arg);
extern int getchar (void);
/* non-blocking, only returns UNICODE if there's any key pressed, 0 otherwise */
extern int getchar_ifany (void);
extern int putchar (int __c);
/* string.h */
#ifndef __clang__
#define memcpy __builtin_memcpy
#define memmove __builtin_memmove
#define memset __builtin_memset
#define memcmp __builtin_memcmp
#define memchr __builtin_memchr
#define memrchr __builtin_memrchr
#else
extern void *memcpy (void *__dest, const void *__src, size_t __n);
extern void *memmove (void *__dest, const void *__src, size_t __n);
extern void *memset (void *__s, int __c, size_t __n);
extern int memcmp (const void *__s1, const void *__s2, size_t __n);
extern void *memchr (const void *__s, int __c, size_t __n);
extern void *memrchr (const void *__s, int __c, size_t __n);
#endif
void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl);
void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl);
extern wchar_t *strcpy (wchar_t *__dest, const wchar_t *__src);
@ -1322,11 +1244,11 @@ struct tm {
int tm_mday; /* Day. [1-31] */
int tm_mon; /* Month. [0-11] */
int tm_year; /* Year - 1900. */
int tm_wday; /* Day of week. [0-6] */
int tm_yday; /* Days in year.[0-365] */
int tm_wday; /* Day of week. [0-6] (not set) */
int tm_yday; /* Days in year.[0-365] (not set) */
int tm_isdst; /* DST. [-1/0/1]*/
};
extern struct tm *localtime ();
extern struct tm *localtime (const time_t *__timer);
/* unistd.h */
extern unsigned int sleep (unsigned int __seconds);

View file

@ -1,469 +0,0 @@
/*
* uefielf.h
*
* Copyright (C) 2021 bzt (bztsrc@gitlab)
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* This file is part of the POSIX-UEFI package.
* @brief Definitions for the Executable and Linkable Format
*
*/
#ifndef _UEFIELF_H
#define _UEFIELF_H 1
#ifndef _UEFI_H_
#error "include uefi.h instead"
#endif
/* Standard ELF types. */
/* Type for a 16-bit quantity. */
typedef uint16_t Elf64_Half;
/* Types for signed and unsigned 32-bit quantities. */
typedef uint32_t Elf64_Word;
typedef int32_t Elf64_Sword;
/* Types for signed and unsigned 64-bit quantities. */
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
/* Type of addresses. */
typedef uint64_t Elf64_Addr;
/* Type of file offsets. */
typedef uint64_t Elf64_Off;
/* Type for section indices, which are 16-bit quantities. */
typedef uint16_t Elf64_Section;
/* Type for version symbol information. */
typedef Elf64_Half Elf64_Versym;
/* The ELF file header. This appears at the start of every ELF file. */
#define EI_NIDENT (16)
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf64_Half e_type; /* Object file type */
Elf64_Half e_machine; /* Architecture */
Elf64_Word e_version; /* Object file version */
Elf64_Addr e_entry; /* Entry point virtual address */
Elf64_Off e_phoff; /* Program header table file offset */
Elf64_Off e_shoff; /* Section header table file offset */
Elf64_Word e_flags; /* Processor-specific flags */
Elf64_Half e_ehsize; /* ELF header size in bytes */
Elf64_Half e_phentsize; /* Program header table entry size */
Elf64_Half e_phnum; /* Program header table entry count */
Elf64_Half e_shentsize; /* Section header table entry size */
Elf64_Half e_shnum; /* Section header table entry count */
Elf64_Half e_shstrndx; /* Section header string table index */
} Elf64_Ehdr;
/* Fields in the e_ident array. The EI_* macros are indices into the
array. The macros under each EI_* macro are the values the byte
may have. */
#define EI_MAG0 0 /* File identification byte 0 index */
#define ELFMAG0 0x7f /* Magic number byte 0 */
#define EI_MAG1 1 /* File identification byte 1 index */
#define ELFMAG1 'E' /* Magic number byte 1 */
#define EI_MAG2 2 /* File identification byte 2 index */
#define ELFMAG2 'L' /* Magic number byte 2 */
#define EI_MAG3 3 /* File identification byte 3 index */
#define ELFMAG3 'F' /* Magic number byte 3 */
/* Conglomeration of the identification bytes, for easy testing as a word. */
#define ELFMAG "\177ELF"
#define SELFMAG 4
#define EI_CLASS 4 /* File class byte index */
#define ELFCLASSNONE 0 /* Invalid class */
#define ELFCLASS32 1 /* 32-bit objects */
#define ELFCLASS64 2 /* 64-bit objects */
#define ELFCLASSNUM 3
#define EI_DATA 5 /* Data encoding byte index */
#define ELFDATANONE 0 /* Invalid data encoding */
#define ELFDATA2LSB 1 /* 2's complement, little endian */
#define ELFDATA2MSB 2 /* 2's complement, big endian */
#define ELFDATANUM 3
#define EI_VERSION 6 /* File version byte index */
/* Value must be EV_CURRENT */
#define EI_OSABI 7 /* OS ABI identification */
#define ELFOSABI_NONE 0 /* UNIX System V ABI */
#define ELFOSABI_SYSV 0 /* Alias. */
#define ELFOSABI_HPUX 1 /* HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD. */
#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
#define ELFOSABI_OSZ 5 /* OS/Z. (86Open was dissolved in 1999) */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
#define ELFOSABI_AIX 7 /* IBM AIX. */
#define ELFOSABI_IRIX 8 /* SGI Irix. */
#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
#define EI_ABIVERSION 8 /* ABI version */
#define EI_PAD 9 /* Byte index of padding bytes */
/* Legal values for e_type (object file type). */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* Relocatable file */
#define ET_EXEC 2 /* Executable file */
#define ET_DYN 3 /* Shared object file */
#define ET_CORE 4 /* Core file */
#define ET_NUM 5 /* Number of defined types */
#define ET_LOOS 0xfe00 /* OS-specific range start */
#define ET_HIOS 0xfeff /* OS-specific range end */
#define ET_LOPROC 0xff00 /* Processor-specific range start */
#define ET_HIPROC 0xffff /* Processor-specific range end */
/* Legal values for e_machine (architecture). */
#define EM_NONE 0 /* No machine */
#define EM_X86_64 62 /* AMD x86-64 architecture */
#define EM_AARCH64 183 /* ARM aarch64 architecture */
/* Legal values for e_version (version). */
#define EV_NONE 0 /* Invalid ELF version */
#define EV_CURRENT 1 /* Current version */
#define EV_NUM 2
/* Section header. */
typedef struct
{
Elf64_Word sh_name; /* Section name (string tbl index) */
Elf64_Word sh_type; /* Section type */
Elf64_Xword sh_flags; /* Section flags */
Elf64_Addr sh_addr; /* Section virtual addr at execution */
Elf64_Off sh_offset; /* Section file offset */
Elf64_Xword sh_size; /* Section size in bytes */
Elf64_Word sh_link; /* Link to another section */
Elf64_Word sh_info; /* Additional section information */
Elf64_Xword sh_addralign; /* Section alignment */
Elf64_Xword sh_entsize; /* Entry size if section holds table */
} Elf64_Shdr;
/* Special section indices. */
#define SHN_UNDEF 0 /* Undefined section */
#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
#define SHN_LOPROC 0xff00 /* Start of processor-specific */
#define SHN_BEFORE 0xff00 /* Order section before all others
(Solaris). */
#define SHN_AFTER 0xff01 /* Order section after all others
(Solaris). */
#define SHN_HIPROC 0xff1f /* End of processor-specific */
#define SHN_LOOS 0xff20 /* Start of OS-specific */
#define SHN_HIOS 0xff3f /* End of OS-specific */
#define SHN_ABS 0xfff1 /* Associated symbol is absolute */
#define SHN_COMMON 0xfff2 /* Associated symbol is common */
#define SHN_XINDEX 0xffff /* Index is in extra table. */
#define SHN_HIRESERVE 0xffff /* End of reserved indices */
/* Legal values for sh_type (section type). */
#define SHT_NULL 0 /* Section header table entry unused */
#define SHT_PROGBITS 1 /* Program data */
#define SHT_SYMTAB 2 /* Symbol table */
#define SHT_STRTAB 3 /* String table */
#define SHT_RELA 4 /* Relocation entries with addends */
#define SHT_HASH 5 /* Symbol hash table */
#define SHT_DYNAMIC 6 /* Dynamic linking information */
#define SHT_NOTE 7 /* Notes */
#define SHT_NOBITS 8 /* Program space with no data (bss) */
#define SHT_REL 9 /* Relocation entries, no addends */
#define SHT_SHLIB 10 /* Reserved */
#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
#define SHT_INIT_ARRAY 14 /* Array of constructors */
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* Number of defined types. */
#define SHT_LOOS 0x60000000 /* Start OS-specific. */
#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
#define SHT_SUNW_move 0x6ffffffa
#define SHT_SUNW_COMDAT 0x6ffffffb
#define SHT_SUNW_syminfo 0x6ffffffc
#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
#define SHT_HIOS 0x6fffffff /* End OS-specific type */
#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
#define SHT_LOUSER 0x80000000 /* Start of application-specific */
#define SHT_HIUSER 0x8fffffff /* End of application-specific */
/* Legal values for sh_flags (section flags). */
#define SHF_WRITE (1 << 0) /* Writable */
#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
#define SHF_EXECINSTR (1 << 2) /* Executable */
#define SHF_MERGE (1 << 4) /* Might be merged */
#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling
required */
#define SHF_GROUP (1 << 9) /* Section is member of a group. */
#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
#define SHF_ORDERED (1 << 30) /* Special ordering requirement
(Solaris). */
#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless
referenced or allocated (Solaris).*/
/* Section compression header. Used when SHF_COMPRESSED is set. */
typedef struct
{
Elf64_Word ch_type; /* Compression format. */
Elf64_Word ch_reserved;
Elf64_Xword ch_size; /* Uncompressed data size. */
Elf64_Xword ch_addralign; /* Uncompressed data alignment. */
} Elf64_Chdr;
/* Legal values for ch_type (compression algorithm). */
#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE algorithm. */
#define ELFCOMPRESS_LOOS 0x60000000 /* Start of OS-specific. */
#define ELFCOMPRESS_HIOS 0x6fffffff /* End of OS-specific. */
#define ELFCOMPRESS_LOPROC 0x70000000 /* Start of processor-specific. */
#define ELFCOMPRESS_HIPROC 0x7fffffff /* End of processor-specific. */
/* Section group handling. */
#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */
/* Symbol table entry. */
typedef struct
{
Elf64_Word st_name; /* Symbol name (string tbl index) */
unsigned char st_info; /* Symbol type and binding */
unsigned char st_other; /* Symbol visibility */
Elf64_Section st_shndx; /* Section index */
Elf64_Addr st_value; /* Symbol value */
Elf64_Xword st_size; /* Symbol size */
} Elf64_Sym;
/* How to extract and insert information held in the st_info field. */
#define ELF64_ST_BIND(val) (((unsigned char) (val)) >> 4)
#define ELF64_ST_TYPE(val) ((val) & 0xf)
#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
/* Legal values for ST_BIND subfield of st_info (symbol binding). */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* Weak symbol */
#define STB_NUM 3 /* Number of defined types. */
/* Legal values for ST_TYPE subfield of st_info (symbol type). */
#define STT_NOTYPE 0 /* Symbol type is unspecified */
#define STT_OBJECT 1 /* Symbol is a data object */
#define STT_FUNC 2 /* Symbol is a code object */
#define STT_SECTION 3 /* Symbol associated with a section */
#define STT_FILE 4 /* Symbol's name is file name */
#define STT_COMMON 5 /* Symbol is a common data object */
#define STT_TLS 6 /* Symbol is thread-local data object*/
#define STT_NUM 7 /* Number of defined types. */
#define STT_LOOS 10 /* Start of OS-specific */
#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
#define STT_HIOS 12 /* End of OS-specific */
#define STT_LOPROC 13 /* Start of processor-specific */
#define STT_HIPROC 15 /* End of processor-specific */
/* How to extract and insert information held in the st_other field. */
#define ELF64_ST_VISIBILITY(o) ((o) & 0x03)
/* Symbol visibility specification encoded in the st_other field. */
#define STV_DEFAULT 0 /* Default symbol visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Sym unavailable in other modules */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
typedef struct
{
Elf64_Addr r_offset; /* Address */
Elf64_Xword r_info; /* Relocation type and symbol index */
} Elf64_Rel;
/* Relocation table entry with addend (in section of type SHT_RELA). */
typedef struct
{
Elf64_Addr r_offset; /* Address */
Elf64_Xword r_info; /* Relocation type and symbol index */
Elf64_Sxword r_addend; /* Addend */
} Elf64_Rela;
/* How to extract and insert information held in the r_info field. */
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
/* Values for ELF64_R_TYPE */
#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
#define R_X86_64_RELATIVE 8 /* Adjust by program base */
#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */
#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */
#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
/* Program segment header. */
typedef struct
{
Elf64_Word p_type; /* Segment type */
Elf64_Word p_flags; /* Segment flags */
Elf64_Off p_offset; /* Segment file offset */
Elf64_Addr p_vaddr; /* Segment virtual address */
Elf64_Addr p_paddr; /* Segment physical address */
Elf64_Xword p_filesz; /* Segment size in file */
Elf64_Xword p_memsz; /* Segment size in memory */
Elf64_Xword p_align; /* Segment alignment */
} Elf64_Phdr;
/* Special value for e_phnum. This indicates that the real number of
program headers is too large to fit into e_phnum. Instead the real
value is in the field sh_info of section 0. */
#define PN_XNUM 0xffff
/* Legal values for p_type (segment type). */
#define PT_NULL 0 /* Program header table entry unused */
#define PT_LOAD 1 /* Loadable program segment */
#define PT_DYNAMIC 2 /* Dynamic linking information */
#define PT_INTERP 3 /* Program interpreter */
#define PT_NOTE 4 /* Auxiliary information */
#define PT_SHLIB 5 /* Reserved */
#define PT_PHDR 6 /* Entry for header table itself */
#define PT_TLS 7 /* Thread-local storage segment */
#define PT_NUM 8 /* Number of defined types */
#define PT_LOOS 0x60000000 /* Start of OS-specific */
#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
#define PT_LOSUNW 0x6ffffffa
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
#define PT_HISUNW 0x6fffffff
#define PT_HIOS 0x6fffffff /* End of OS-specific */
#define PT_LOPROC 0x70000000 /* Start of processor-specific */
#define PT_HIPROC 0x7fffffff /* End of processor-specific */
/* Legal values for p_flags (segment flags). */
#define PF_X (1 << 0) /* Segment is executable */
#define PF_W (1 << 1) /* Segment is writable */
#define PF_R (1 << 2) /* Segment is readable */
#define PF_MASKOS 0x0ff00000 /* OS-specific */
#define PF_MASKPROC 0xf0000000 /* Processor-specific */
/* Dynamic section entry. */
typedef struct
{
Elf64_Sxword d_tag; /* Dynamic entry type */
union
{
Elf64_Xword d_val; /* Integer value */
Elf64_Addr d_ptr; /* Address value */
} d_un;
} Elf64_Dyn;
/* Legal values for d_tag (dynamic entry type). */
#define DT_NULL 0 /* Marks end of dynamic section */
#define DT_NEEDED 1 /* Name of needed library */
#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */
#define DT_PLTGOT 3 /* Processor defined value */
#define DT_HASH 4 /* Address of symbol hash table */
#define DT_STRTAB 5 /* Address of string table */
#define DT_SYMTAB 6 /* Address of symbol table */
#define DT_RELA 7 /* Address of Rela relocs */
#define DT_RELASZ 8 /* Total size of Rela relocs */
#define DT_RELAENT 9 /* Size of one Rela reloc */
#define DT_STRSZ 10 /* Size of string table */
#define DT_SYMENT 11 /* Size of one symbol table entry */
#define DT_INIT 12 /* Address of init function */
#define DT_FINI 13 /* Address of termination function */
#define DT_SONAME 14 /* Name of shared object */
#define DT_RPATH 15 /* Library search path (deprecated) */
#define DT_SYMBOLIC 16 /* Start symbol search here */
#define DT_REL 17 /* Address of Rel relocs */
#define DT_RELSZ 18 /* Total size of Rel relocs */
#define DT_RELENT 19 /* Size of one Rel reloc */
#define DT_PLTREL 20 /* Type of reloc in PLT */
#define DT_DEBUG 21 /* For debugging; unspecified */
#define DT_TEXTREL 22 /* Reloc might modify .text */
#define DT_JMPREL 23 /* Address of PLT relocs */
#define DT_BIND_NOW 24 /* Process relocations of object */
#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
#define DT_RUNPATH 29 /* Library search path */
#define DT_FLAGS 30 /* Flags for the object being loaded */
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
#define DT_NUM 34 /* Number used */
#define DT_LOOS 0x6000000d /* Start of OS-specific */
#define DT_HIOS 0x6ffff000 /* End of OS-specific */
#define DT_LOPROC 0x70000000 /* Start of processor-specific */
#define DT_HIPROC 0x7fffffff /* End of processor-specific */
#endif /* uefielf.h */

View file

@ -1,630 +0,0 @@
/*
* uefipe.h
*
* Copyright (C) 2021 bzt (bztsrc@gitlab)
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* This file is part of the POSIX-UEFI package.
* @brief Definitions for the Portable Executable 32+ format
*
*/
#ifndef _UEFIPE_H
#define _UEFIPE_H
#ifndef _UEFI_H_
#error "include uefi.h instead"
#endif
#ifndef IMAGE_DOS_SIGNATURE
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
#define IMAGE_OS2_SIGNATURE 0x454E // NE
#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
uint16_t e_magic; // Magic number
uint16_t e_cblp; // Bytes on last page of file
uint16_t e_cp; // Pages in file
uint16_t e_crlc; // Relocations
uint16_t e_cparhdr; // Size of header in paragraphs
uint16_t e_minalloc; // Minimum extra paragraphs needed
uint16_t e_maxalloc; // Maximum extra paragraphs needed
uint16_t e_ss; // Initial (relative) SS value
uint16_t e_sp; // Initial SP value
uint16_t e_csum; // Checksum
uint16_t e_ip; // Initial IP value
uint16_t e_cs; // Initial (relative) CS value
uint16_t e_lfarlc; // File address of relocation table
uint16_t e_ovno; // Overlay number
uint16_t e_res[4]; // Reserved words
uint16_t e_oemid; // OEM identifier (for e_oeminfo)
uint16_t e_oeminfo; // OEM information; e_oemid specific
uint16_t e_res2[10]; // Reserved words
uint32_t e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header
uint16_t ne_magic; // Magic number
uint8_t ne_ver; // Version number
uint8_t ne_rev; // Revision number
uint16_t ne_enttab; // Offset of Entry Table
uint16_t ne_cbenttab; // Number of bytes in Entry Table
uint32_t ne_crc; // Checksum of whole file
uint16_t ne_flags; // Flag uint16_t
uint16_t ne_autodata; // Automatic data segment number
uint16_t ne_heap; // Initial heap allocation
uint16_t ne_stack; // Initial stack allocation
uint32_t ne_csip; // Initial CS:IP setting
uint32_t ne_sssp; // Initial SS:SP setting
uint16_t ne_cseg; // Count of file segments
uint16_t ne_cmod; // Entries in Module Reference Table
uint16_t ne_cbnrestab; // Size of non-resident name table
uint16_t ne_segtab; // Offset of Segment Table
uint16_t ne_rsrctab; // Offset of Resource Table
uint16_t ne_restab; // Offset of resident name table
uint16_t ne_modtab; // Offset of Module Reference Table
uint16_t ne_imptab; // Offset of Imported Names Table
uint32_t ne_nrestab; // Offset of Non-resident Names Table
uint16_t ne_cmovent; // Count of movable entries
uint16_t ne_align; // Segment alignment shift count
uint16_t ne_cres; // Count of resource segments
uint8_t ne_exetyp; // Target Operating system
uint8_t ne_flagsothers; // Other .EXE flags
uint16_t ne_pretthunks; // offset to return thunks
uint16_t ne_psegrefbytes; // offset to segment ref. bytes
uint16_t ne_swaparea; // Minimum code swap area size
uint16_t ne_expver; // Expected Windows version number
} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
//
// File header format.
//
typedef struct _IMAGE_FILE_HEADER {
uint16_t Machine;
uint16_t NumberOfSections;
uint32_t TimeDateStamp;
uint32_t PointerToSymbolTable;
uint32_t NumberOfSymbols;
uint16_t SizeOfOptionalHeader;
uint16_t Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
#define IMAGE_SIZEOF_FILE_HEADER 20
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_SYSTEM 0x1000 // System File.
#define IMAGE_FILE_DLL 0x2000 // File is a DLL.
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
#define IMAGE_FILE_MACHINE_UNKNOWN 0
#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian
#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x1c2 // Arm/Thumb
#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_IA64 0x200 // IA-64
#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
#define IMAGE_FILE_MACHINE_EBC 0xebc // EFI Byte Code
#define IMAGE_FILE_MACHINE_X64 0x8664 // x86_64
//
// Directory format.
//
typedef struct _IMAGE_DATA_DIRECTORY {
uint32_t VirtualAddress;
uint32_t Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
//
// Optional header format.
//
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
uint32_t SizeOfCode;
uint32_t SizeOfInitializedData;
uint32_t SizeOfUninitializedData;
uint32_t AddressOfEntryPoint;
uint32_t BaseOfCode;
uint32_t BaseOfData;
//
// NT additional fields.
//
uint32_t ImageBase;
uint32_t SectionAlignment;
uint32_t FileAlignment;
uint16_t MajorOperatingSystemVersion;
uint16_t MinorOperatingSystemVersion;
uint16_t MajorImageVersion;
uint16_t MinorImageVersion;
uint16_t MajorSubsystemVersion;
uint16_t MinorSubsystemVersion;
uint32_t Reserved1;
uint32_t SizeOfImage;
uint32_t SizeOfHeaders;
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DllCharacteristics;
uint32_t SizeOfStackReserve;
uint32_t SizeOfStackCommit;
uint32_t SizeOfHeapReserve;
uint32_t SizeOfHeapCommit;
uint32_t LoaderFlags;
uint32_t NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
uint32_t SizeOfCode;
uint32_t SizeOfInitializedData;
uint32_t SizeOfUninitializedData;
uint32_t AddressOfEntryPoint;
uint32_t BaseOfCode;
uint32_t BaseOfData;
uint32_t BaseOfBss;
uint32_t GprMask;
uint32_t CprMask[4];
uint32_t GpValue;
} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;
#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
typedef struct _IMAGE_NT_HEADERS {
uint32_t Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
typedef struct _IMAGE_ROM_HEADERS {
IMAGE_FILE_HEADER FileHeader;
IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
((uint32_t)ntheader + \
FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \
))
// Subsystem Values
#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem.
#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem.
#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem.
// Directory Entries
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
//
// Section header format.
//
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER {
uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
union {
uint32_t PhysicalAddress;
uint32_t VirtualSize;
} Misc;
uint32_t VirtualAddress;
uint32_t SizeOfRawData;
uint32_t PointerToRawData;
uint32_t PointerToRelocations;
uint32_t PointerToLinenumbers;
uint16_t NumberOfRelocations;
uint16_t NumberOfLinenumbers;
uint32_t Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
#define IMAGE_SIZEOF_SECTION_HEADER 40
#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat.
#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 //
#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 //
#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 //
#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 //
#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified.
#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 //
#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 //
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
//
// Symbol format.
//
#define IMAGE_SIZEOF_SYMBOL 18
//
// Section values.
//
// Symbols have a section number of the section in which they are
// defined. Otherwise, section numbers have the following meanings:
//
#define IMAGE_SYM_UNDEFINED (uint16_t)0 // Symbol is undefined or is common.
#define IMAGE_SYM_ABSOLUTE (uint16_t)-1 // Symbol is an absolute value.
#define IMAGE_SYM_DEBUG (uint16_t)-2 // Symbol is a special debug item.
//
// Type (fundamental) values.
//
#define IMAGE_SYM_TYPE_NULL 0 // no type.
#define IMAGE_SYM_TYPE_VOID 1 //
#define IMAGE_SYM_TYPE_CHAR 2 // type character.
#define IMAGE_SYM_TYPE_SHORT 3 // type short integer.
#define IMAGE_SYM_TYPE_INT 4 //
#define IMAGE_SYM_TYPE_LONG 5 //
#define IMAGE_SYM_TYPE_FLOAT 6 //
#define IMAGE_SYM_TYPE_DOUBLE 7 //
#define IMAGE_SYM_TYPE_STRUCT 8 //
#define IMAGE_SYM_TYPE_UNION 9 //
#define IMAGE_SYM_TYPE_ENUM 10 // enumeration.
#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
#define IMAGE_SYM_TYPE_BYTE 12 //
#define IMAGE_SYM_TYPE_WORD 13 //
#define IMAGE_SYM_TYPE_UINT 14 //
#define IMAGE_SYM_TYPE_DWORD 15 //
//
// Type (derived) values.
//
#define IMAGE_SYM_DTYPE_NULL 0 // no derived type.
#define IMAGE_SYM_DTYPE_POINTER 1 // pointer.
#define IMAGE_SYM_DTYPE_FUNCTION 2 // function.
#define IMAGE_SYM_DTYPE_ARRAY 3 // array.
//
// Storage classes.
//
#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1
#define IMAGE_SYM_CLASS_NULL 0
#define IMAGE_SYM_CLASS_AUTOMATIC 1
#define IMAGE_SYM_CLASS_EXTERNAL 2
#define IMAGE_SYM_CLASS_STATIC 3
#define IMAGE_SYM_CLASS_REGISTER 4
#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5
#define IMAGE_SYM_CLASS_LABEL 6
#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
#define IMAGE_SYM_CLASS_ARGUMENT 9
#define IMAGE_SYM_CLASS_STRUCT_TAG 10
#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
#define IMAGE_SYM_CLASS_UNION_TAG 12
#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13
#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
#define IMAGE_SYM_CLASS_ENUM_TAG 15
#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
#define IMAGE_SYM_CLASS_REGISTER_PARAM 17
#define IMAGE_SYM_CLASS_BIT_FIELD 18
#define IMAGE_SYM_CLASS_BLOCK 100
#define IMAGE_SYM_CLASS_FUNCTION 101
#define IMAGE_SYM_CLASS_END_OF_STRUCT 102
#define IMAGE_SYM_CLASS_FILE 103
// new
#define IMAGE_SYM_CLASS_SECTION 104
#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
// type packing constants
#define N_BTMASK 017
#define N_TMASK 060
#define N_TMASK1 0300
#define N_TMASK2 0360
#define N_BTSHFT 4
#define N_TSHIFT 2
// MACROS
//
// Communal selection types.
//
#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
#define IMAGE_COMDAT_SELECT_ANY 2
#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
//
// Relocation format.
//
typedef struct _IMAGE_RELOCATION {
uint32_t VirtualAddress;
uint32_t SymbolTableIndex;
uint16_t Type;
} IMAGE_RELOCATION;
#define IMAGE_SIZEOF_RELOCATION 10
//
// I386 relocation types.
//
#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
#define IMAGE_REL_I386_SECTION 012
#define IMAGE_REL_I386_SECREL 013
#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address
//
// MIPS relocation types.
//
#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
#define IMAGE_REL_MIPS_REFHALF 01
#define IMAGE_REL_MIPS_REFWORD 02
#define IMAGE_REL_MIPS_JMPADDR 03
#define IMAGE_REL_MIPS_REFHI 04
#define IMAGE_REL_MIPS_REFLO 05
#define IMAGE_REL_MIPS_GPREL 06
#define IMAGE_REL_MIPS_LITERAL 07
#define IMAGE_REL_MIPS_SECTION 012
#define IMAGE_REL_MIPS_SECREL 013
#define IMAGE_REL_MIPS_REFWORDNB 042
#define IMAGE_REL_MIPS_PAIR 045
//
// Alpha Relocation types.
//
#define IMAGE_REL_ALPHA_ABSOLUTE 0x0
#define IMAGE_REL_ALPHA_REFLONG 0x1
#define IMAGE_REL_ALPHA_REFQUAD 0x2
#define IMAGE_REL_ALPHA_GPREL32 0x3
#define IMAGE_REL_ALPHA_LITERAL 0x4
#define IMAGE_REL_ALPHA_LITUSE 0x5
#define IMAGE_REL_ALPHA_GPDISP 0x6
#define IMAGE_REL_ALPHA_BRADDR 0x7
#define IMAGE_REL_ALPHA_HINT 0x8
#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9
#define IMAGE_REL_ALPHA_REFHI 0xA
#define IMAGE_REL_ALPHA_REFLO 0xB
#define IMAGE_REL_ALPHA_PAIR 0xC
#define IMAGE_REL_ALPHA_MATCH 0xD
#define IMAGE_REL_ALPHA_SECTION 0xE
#define IMAGE_REL_ALPHA_SECREL 0xF
#define IMAGE_REL_ALPHA_REFLONGNB 0x10
//
// IBM PowerPC relocation types.
//
#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP
#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address
#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address
#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute)
#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address
#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword)
#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative)
#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative)
#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base
#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword)
#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base
#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr)
#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number
#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code
#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction
#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type
// Flag bits in IMAGE_RELOCATION.TYPE
#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it
#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken
#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken
#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc)
//
// Based relocation format.
//
typedef struct _IMAGE_BASE_RELOCATION {
uint32_t VirtualAddress;
uint32_t SizeOfBlock;
// uint16_t TypeOffset[1];
} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
#define IMAGE_SIZEOF_BASE_RELOCATION 8
//
// Based relocation types.
//
#define IMAGE_REL_BASED_ABSOLUTE 0
#define IMAGE_REL_BASED_HIGH 1
#define IMAGE_REL_BASED_LOW 2
#define IMAGE_REL_BASED_HIGHLOW 3
#define IMAGE_REL_BASED_HIGHADJ 4
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_IA64_IMM64 9
#define IMAGE_REL_BASED_DIR64 10
//
// Line number format.
//
typedef struct _IMAGE_LINENUMBER {
union {
uint32_t SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
uint32_t VirtualAddress; // Virtual address of line number.
} Type;
uint16_t Linenumber; // Line number.
} IMAGE_LINENUMBER;
#define IMAGE_SIZEOF_LINENUMBER 6
//
// Archive format.
//
#define IMAGE_ARCHIVE_START_SIZE 8
#define IMAGE_ARCHIVE_START "!<arch>\n"
#define IMAGE_ARCHIVE_END "`\n"
#define IMAGE_ARCHIVE_PAD "\n"
#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
uint8_t Name[16]; // File member name - `/' terminated.
uint8_t Date[12]; // File member date - decimal.
uint8_t UserID[6]; // File member user id - decimal.
uint8_t GroupID[6]; // File member group id - decimal.
uint8_t Mode[8]; // File member mode - octal.
uint8_t Size[10]; // File member size - decimal.
uint8_t EndHeader[2]; // String to end header.
} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
//
// DLL support.
//
//
// Export Format
//
typedef struct _IMAGE_EXPORT_DIRECTORY {
uint32_t Characteristics;
uint32_t TimeDateStamp;
uint16_t MajorVersion;
uint16_t MinorVersion;
uint32_t Name;
uint32_t Base;
uint32_t NumberOfFunctions;
uint32_t NumberOfNames;
uint32_t *AddressOfFunctions;
uint32_t *AddressOfNames;
uint32_t *AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
//
// Import Format
//
typedef struct _IMAGE_IMPORT_BY_NAME {
uint16_t Hint;
uint8_t Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
typedef struct _IMAGE_THUNK_DATA {
union {
uint32_t Function;
uint32_t Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData;
} u1;
} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;
#define IMAGE_ORDINAL_FLAG 0x80000000
#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0)
#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
uint32_t Characteristics;
uint32_t TimeDateStamp;
uint32_t ForwarderChain;
uint32_t Name;
PIMAGE_THUNK_DATA FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
#endif
#endif /* uefipe.h */

View file

@ -32,12 +32,12 @@
int usleep (unsigned long int __useconds)
{
uefi_call_wrapper(BS->Stall, 1, __useconds);
BS->Stall(__useconds);
return 0;
}
unsigned int sleep (unsigned int __seconds)
{
uefi_call_wrapper(BS->Stall, 1, __seconds * 1000000);
BS->Stall((unsigned long int)__seconds * 1000000UL);
return 0;
}