mirror of
https://gitlab.com/bztsrc/posix-uefi.git
synced 2024-12-28 06:55:08 +01:00
Removed uefi_call_wrapper
This commit is contained in:
parent
69b6c8f003
commit
1bebb7ce51
18 changed files with 376 additions and 1512 deletions
11
Makefile
Normal file
11
Makefile
Normal 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
|
52
README.md
52
README.md
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
TARGET = args.efi
|
||||
|
||||
#USE_LLVM=1
|
||||
include uefi/Makefile
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
TARGET = dumpmem.efi
|
||||
|
||||
#USE_LLVM=1
|
||||
include uefi/Makefile
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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),)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
130
uefi/stdio.c
130
uefi/stdio.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
172
uefi/uefi.h
172
uefi/uefi.h
|
@ -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);
|
||||
|
@ -1316,17 +1238,17 @@ extern size_t strlen (const wchar_t *__s);
|
|||
|
||||
/* time.h */
|
||||
struct tm {
|
||||
int tm_sec; /* Seconds. [0-60] (1 leap second) */
|
||||
int tm_min; /* Minutes. [0-59] */
|
||||
int tm_hour; /* Hours. [0-23] */
|
||||
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_isdst; /* DST. [-1/0/1]*/
|
||||
int tm_sec; /* Seconds. [0-60] (1 leap second) */
|
||||
int tm_min; /* Minutes. [0-59] */
|
||||
int tm_hour; /* Hours. [0-23] */
|
||||
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] (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);
|
||||
|
|
469
uefi/uefielf.h
469
uefi/uefielf.h
|
@ -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 */
|
630
uefi/uefipe.h
630
uefi/uefipe.h
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue