From 537c21338bc3722218a55766d8adb2908d8df987 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Feb 2021 16:26:36 -0800 Subject: [PATCH] Add UEFI support This is mutually exclusive with Windows support. Documentation for how to use it has been written in libc/runtime/efimain.c --- ape/ape.S | 49 ++- ape/ape.lds | 18 +- build/config.mk | 2 +- build/definitions.mk | 1 - libc/{runtime/exit3.S => calls/efi.c} | 36 +- libc/calls/efi.h | 12 + libc/calls/fstat.c | 4 +- libc/calls/g_fds.c | 2 +- libc/calls/internal.h | 7 + libc/calls/nanosleep-uefi.c | 35 ++ libc/calls/nanosleep.c | 7 +- libc/calls/readv.c | 3 +- libc/calls/sigaction.c | 2 +- libc/calls/writev.c | 3 +- libc/dce.h | 4 + libc/nexgen32e/vendor.internal.h | 2 +- libc/nt/efi.h | 424 ++++++++++++++++++ libc/nt/pedef.internal.h | 596 +++++++++++++------------- libc/runtime/efimain.c | 72 ++++ libc/runtime/{exit2.S => exit2.c} | 29 +- libc/runtime/exit3.c | 44 ++ libc/runtime/runtime.h | 6 - libc/sysv/systemfive.S | 29 +- tool/viz/printansi.c | 385 +++++++++++++++++ 24 files changed, 1381 insertions(+), 391 deletions(-) rename libc/{runtime/exit3.S => calls/efi.c} (67%) create mode 100644 libc/calls/efi.h create mode 100644 libc/calls/nanosleep-uefi.c create mode 100644 libc/nt/efi.h create mode 100644 libc/runtime/efimain.c rename libc/runtime/{exit2.S => exit2.c} (77%) create mode 100644 libc/runtime/exit3.c create mode 100644 tool/viz/printansi.c diff --git a/ape/ape.S b/ape/ape.S index b3ad01212..4c9714258 100644 --- a/ape/ape.S +++ b/ape/ape.S @@ -105,7 +105,7 @@ rlstr: .endobj rlstr,globl,hidden # ←for gdb readibility │ αcτµαlly pδrταblε εxεcµταblε § the old technology │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#if SupportsWindows() || SupportsXnu() +#if SupportsWindows() || SupportsUefi() || SupportsXnu() // MZ Literally Executable Header // @@ -131,14 +131,14 @@ ape_mz: .asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski .ascii "JT" # MZ: OEM identifier .short 0 # MZ: OEM information .org 0x40-4 # MZ: bytes reserved for you -#if SupportsWindows() +#if SupportsWindows() || SupportsUefi() .long RVA(ape_pe) # PE: the new technology #else .long 0 #endif .endfn ape_mz,globl,hidden -#else /* !(SupportsWindows() || SupportsXnu()) */ +#else /* !(SupportsWindows() || SupportsUefi() || SupportsXnu()) */ // ELF Literally Executable Header // @@ -168,7 +168,7 @@ ape_mz: .asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski .short ape_elf_shnum # 3c: e_shnum .short ape_elf_shstrndx # 3e: e_shstrndx -#endif /* SupportsWindows() || SupportsXnu() */ +#endif /* SupportsWindows() || SupportsUefi() || SupportsXnu() */ #if SupportsMetal() @@ -471,7 +471,7 @@ ape_disk: #if SupportsSystemv() -#if SupportsWindows() || SupportsXnu() +#if SupportsWindows() || SupportsUefi() || SupportsXnu() apesh: .ascii "'\n#'\"\n" # sixth edition shebang .ascii "o=\"$(command -v \"$0\")\"\n" #if SupportsXnu() @@ -526,7 +526,7 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang .ascii "fi\n" .ascii "exit $R\n" .endobj apesh -#endif /* SupportsWindows() || SupportsXnu() */ +#endif /* SupportsWindows() || SupportsUefi() || SupportsXnu() */ .section .elf.phdrs,"a",@progbits .long PT_LOAD # text segment @@ -812,7 +812,7 @@ PETEXT = 0b01110000000000000000000001100000 PEDATA = 0b11000000000000000000000011000000 PEIMPS = 0b11000000000000000000000001000000 -#if SupportsWindows() +#if SupportsWindows() || SupportsUefi() .section .pe.header,"a",@progbits .align __SIZEOF_POINTER__ @@ -830,23 +830,27 @@ ape_pe: .ascin "PE",4 .long 0 # SizeOfCode .long 0 # SizeOfInitializedData .long 0 # SizeOfUninitializedData - .long RVA(WinMain) # EntryPoint + .long RVA(ape_pe_entry) # EntryPoint .long 0 # BaseOfCode .quad IMAGE_BASE_VIRTUAL # ImageBase .long 4096 # SectionAlignment .long 4096 # FileAlignment - .short 6 # MajorOperatingSystemVersion + .short v_ntversion # MajorOperatingSystemVersion .short 0 # MinorOperatingSystemVersion .short 0 # MajorImageVersion .short 0 # MinorImageVersion - .short 6 # MajorSubsystemVersion + .short v_ntsubversion # MajorSubsystemVersion .short 0 # MinorSubsystemVersion .long 0 # Win32VersionValue .long RVA(_end) # SizeOfImage .long RVA(_ehead) # SizeOfHeaders .long 0 # Checksum .short v_ntsubsystem # Subsystem: 0=Neutral,2=GUI,3=Console +#if SupportsWindows() .short DLLEXE # DllCharacteristics +#else + .short 0 # DllCharacteristics +#endif .quad 0x0000000000100000 # StackReserve .quad 0x00000000000fc000 # StackCommit .quad 0 # HeapReserve @@ -854,8 +858,12 @@ ape_pe: .ascin "PE",4 .long 0 # LoaderFlags .long 16 # NumberOfDirectoryEntries .long 0,0 # ExportsDirectory +#if SupportsWindows() .long RVA(ape_idata_idt) # ImportsDirectory .stub ape_idata_idtsize,long # ImportsDirectorySize +#else + .long 0,0 # ImportsDirectory +#endif .long 0,0 # ResourcesDirectory .long 0,0 # ExceptionsDirectory .long 0,0 # SecurityDirectory @@ -866,8 +874,12 @@ ape_pe: .ascin "PE",4 .long 0,0 # ThreadLocalStorage .long 0,0 # LoadConfigurationDirectory .long 0,0 # BoundImportDirectory +#if SupportsWindows() .long RVA(ape_idata_iat) # ImportAddressDirectory .stub ape_idata_iatsize,long # ImportAddressDirectorySize +#else + .long 0,0 # ImportAddressDirectory +#endif .long 0,0 # DelayImportDescriptor .long 0,0 # ComPlusRuntimeHeader .long 0,0 # Reserved @@ -900,7 +912,7 @@ ape_pe: .ascin "PE",4 .long PEDATA # Flags .previous -#endif /* SupportsWindows() */ +#endif /* SupportsWindows() || SupportsUefi() */ .section .idata.ro.idt.1,"a",@progbits .type ape_idata_idtend,@object @@ -1524,22 +1536,21 @@ metal.thunk: #endif // 𝑠𝑙𝑖𝑑𝑒 .endfn metal.thunk -metal: - xor %eax,%eax # clear bss +metal: xor %eax,%eax # clear bss mov $ape_bss_vaddr,%edi mov $ape_bss_memsz,%ecx rep stosb - .weak __hostos +0: .weak __hostos ezlea __hostos,ax test %rax,%rax jz 1f movb $METAL,(%rax) -1: push $0 # auxv - push $0 - push $0 # envp - push $0 # auxv +1: push $0 # auxv[0][1] + push $0 # auxv[0][0] + push $0 # envp[0] + push $0 # argv[0] push $0 # argc - xor %edi,%edi + xor %edi,%edi # not freebsd jmp _start .endfn metal diff --git a/ape/ape.lds b/ape/ape.lds index d1b1db3e8..376cc9da7 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -229,7 +229,7 @@ SECTIONS { . += 1; KEEP(*(.ape.pad.head)) - . = ALIGN(SupportsWindows() ? PAGESIZE : 16); + . = ALIGN(SupportsWindows() || SupportsUefi() ? PAGESIZE : 16); HIDDEN(_ehead = .); } :Head @@ -500,15 +500,21 @@ SHSTUB2(ape_macho_dd_skip, RVA(ape_macho) / 8); SHSTUB2(ape_macho_dd_count, (ape_macho_end - ape_macho) / 8); #endif -#if SupportsWindows() +#if SupportsWindows() || SupportsUefi() +#define LINK_WINDOWS (SupportsWindows() && !DEFINED(EfiMain)) PFSTUB4(ape_pe_offset, ape_pe - ape_mz); HIDDEN(ape_pe_optsz = ape_pe_sections - (ape_pe + 24)); HIDDEN(ape_pe_shnum = (ape_pe_sections_end - ape_pe_sections) / 40); HIDDEN(ape_idata_idtsize = ape_idata_idtend - ape_idata_idt); HIDDEN(ape_idata_iatsize = ape_idata_iatend - ape_idata_iat); -HIDDEN(v_ntsubsystem = (DEFINED(GetMessage) - ? kNtImageSubsystemWindowsGui - : kNtImageSubsystemWindowsCui)); +HIDDEN(v_ntversion = LINK_WINDOWS ? 6 : 1); +HIDDEN(v_ntsubversion = LINK_WINDOWS ? 6 : 5); +HIDDEN(v_ntsubsystem = (LINK_WINDOWS + ? (DEFINED(GetMessage) + ? kNtImageSubsystemWindowsGui + : kNtImageSubsystemWindowsCui) + : kNtImageSubsystemEfiApplication)); +HIDDEN(ape_pe_entry = LINK_WINDOWS ? WinMain : EfiMain); #endif #if SupportsMetal() @@ -603,7 +609,7 @@ CHURN(v_ape_realsectors); #if SupportsXnu() CHURN(ape_macho); #endif -#if SupportsWindows() +#if SupportsWindows() || SupportsUefi() CHURN(ape_mz); CHURN(ape_pe); CHURN(ape_pe_offset); diff --git a/build/config.mk b/build/config.mk index 9b0e3d399..e94573246 100644 --- a/build/config.mk +++ b/build/config.mk @@ -95,7 +95,7 @@ CONFIG_COPTS += \ $(SANITIZER) TARGET_ARCH ?= \ - -msse3 + -march=native OVERRIDE_CCFLAGS += \ -fno-pie diff --git a/build/definitions.mk b/build/definitions.mk index 96f22072b..f2942a71c 100644 --- a/build/definitions.mk +++ b/build/definitions.mk @@ -91,7 +91,6 @@ FTRACE = \ -pg SANITIZER = \ - -fsanitize=leak \ -fsanitize=address NO_MAGIC = \ diff --git a/libc/runtime/exit3.S b/libc/calls/efi.c similarity index 67% rename from libc/runtime/exit3.S rename to libc/calls/efi.c index 62115fbb5..dca380c0a 100644 --- a/libc/runtime/exit3.S +++ b/libc/calls/efi.c @@ -1,7 +1,7 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ @@ -16,30 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" -#include "libc/runtime/internal.h" -#include "libc/macros.h" -.privileged +#include "libc/calls/efi.h" +#include "libc/nt/efi.h" -// Terminates process, ignoring destructors and atexit() handlers. -// -// @param edi is exit code ∈ [0,256) -// @asyncsignalsafe -// @vforksafe -// @noreturn -_Exit: push %rbp - mov %rsp,%rbp -#if SupportsWindows() - testb IsWindows() - jz 1f - sub $32,%rsp - movzbl %dil,%ecx # %ERRORLEVEL% is limitless - call *__imp_ExitProcess(%rip) -#endif -1: mov __NR_exit_group(%rip),%eax - syscall -#if SupportsMetal() - call triplf -#endif - .endfn _Exit,globl,protected - .hidden __NR_exit_group +EFI_HANDLE __efi_image_handle; +EFI_SYSTEM_TABLE *__efi_system_table; diff --git a/libc/calls/efi.h b/libc/calls/efi.h new file mode 100644 index 000000000..6131f3957 --- /dev/null +++ b/libc/calls/efi.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_EFI_H_ +#define COSMOPOLITAN_LIBC_CALLS_EFI_H_ +#include "libc/nt/efi.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern EFI_HANDLE __efi_image_handle; +extern EFI_SYSTEM_TABLE *__efi_system_table; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_EFI_H_ */ diff --git a/libc/calls/fstat.c b/libc/calls/fstat.c index b6c20fceb..4c2daa7c7 100644 --- a/libc/calls/fstat.c +++ b/libc/calls/fstat.c @@ -31,9 +31,9 @@ int fstat(int fd, struct stat *st) { if (__isfdkind(fd, kFdZip)) { return weaken(__zipos_fstat)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st); - } else if (!IsWindows() && !IsMetal()) { + } else if (!IsWindows() && !IsMetal() && !IsUefi()) { return sys_fstat(fd, st); - } else if (IsMetal()) { + } else if (IsMetal() || IsUefi()) { return fstat_metal(fd, st); } else { if (!__isfdkind(fd, kFdFile)) return ebadf(); diff --git a/libc/calls/g_fds.c b/libc/calls/g_fds.c index ab33efb7f..769ebae34 100644 --- a/libc/calls/g_fds.c +++ b/libc/calls/g_fds.c @@ -30,7 +30,7 @@ hidden textstartup void InitializeFileDescriptors(void) { fds = VEIL("r", &g_fds); pushmov(&fds->n, ARRAYLEN(fds->__init_p)); fds->p = fds->__init_p; - if (IsMetal()) { + if (IsMetal() || IsUefi()) { pushmov(&fds->f, 3ull); fds->__init_p[STDIN_FILENO].kind = pushpop(kFdSerial); fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdSerial); diff --git a/libc/calls/internal.h b/libc/calls/internal.h index 7c9334bea..f2d5deeb7 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -199,6 +199,7 @@ u32 sys_gettid(void) hidden; u32 sys_getuid(void) hidden; void *sys_mmap(void *, u64, u32, u32, i64, i64, i64) hidden; void *sys_mremap(void *, u64, u64, i32, void *) hidden; +void sys_exit(int) hidden; /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § syscalls » system five » support ─╬─│┼ @@ -294,6 +295,12 @@ unsigned __wincrash_nt(struct NtExceptionPointers *); int fstat_metal(int, struct stat *); +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § syscalls » uefi ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int sys_nanosleep_uefi(const struct timespec *, struct timespec *); + /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § syscalls » drivers ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ diff --git a/libc/calls/nanosleep-uefi.c b/libc/calls/nanosleep-uefi.c new file mode 100644 index 000000000..94b84164f --- /dev/null +++ b/libc/calls/nanosleep-uefi.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/efi.h" +#include "libc/nt/efi.h" +#include "libc/sysv/errfuns.h" + +int sys_nanosleep_uefi(const struct timespec *req, struct timespec *rem) { + if (__efi_system_table->BootServices->Stall( + req->tv_sec * 1000000 + req->tv_nsec / 1000) == EFI_SUCCESS) { + if (rem) { + rem->tv_sec = 0; + rem->tv_nsec = 0; + } + return 0; + } else { + return eintr(); + } +} diff --git a/libc/calls/nanosleep.c b/libc/calls/nanosleep.c index da817ad73..7276d848c 100644 --- a/libc/calls/nanosleep.c +++ b/libc/calls/nanosleep.c @@ -26,10 +26,15 @@ */ int nanosleep(const struct timespec *req, struct timespec *rem) { if (!req) return efault(); - if (!IsWindows() && !IsMetal() && !IsXnu()) { + if (req->tv_sec < 0 || !(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) { + return einval(); + } + if (!IsWindows() && !IsMetal() && !IsUefi() && !IsXnu()) { return sys_nanosleep(req, rem); } else if (IsXnu()) { return sys_nanosleep_xnu(req, rem); + } else if (IsUefi()) { + return sys_nanosleep_uefi(req, rem); } else if (IsMetal()) { return enosys(); /* TODO: Sleep on Metal */ } else { diff --git a/libc/calls/readv.c b/libc/calls/readv.c index a7e525d34..c38fab845 100644 --- a/libc/calls/readv.c +++ b/libc/calls/readv.c @@ -36,7 +36,8 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { return weaken(__zipos_read)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1); - } else if (SupportsMetal() && fd < g_fds.n && g_fds.p[fd].kind == kFdSerial) { + } else if ((SupportsMetal() || SupportsUefi()) && fd < g_fds.n && + g_fds.p[fd].kind == kFdSerial) { return readv_serial(&g_fds.p[fd], iov, iovlen); } else if (!IsWindows()) { return sys_readv(fd, iov, iovlen); diff --git a/libc/calls/sigaction.c b/libc/calls/sigaction.c index fbdda5854..4810c7331 100644 --- a/libc/calls/sigaction.c +++ b/libc/calls/sigaction.c @@ -144,7 +144,7 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { sizeof(struct sigaction) > sizeof(struct sigaction_freebsd) && sizeof(struct sigaction) > sizeof(struct sigaction_openbsd) && sizeof(struct sigaction) > sizeof(struct sigaction_netbsd)); - if (IsMetal()) return enosys(); /* TODO: Signals on Metal */ + if (IsMetal() || IsUefi()) return enosys(); /* TODO: Signals on Metal */ if (!(0 < sig && sig < NSIG)) return einval(); if (sig == SIGKILL || sig == SIGSTOP) return einval(); if (!act) { diff --git a/libc/calls/writev.c b/libc/calls/writev.c index b882f5350..3b4544fdd 100644 --- a/libc/calls/writev.c +++ b/libc/calls/writev.c @@ -39,7 +39,8 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { return weaken(__zipos_write)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1); - } else if (SupportsMetal() && fd < g_fds.n && g_fds.p[fd].kind == kFdSerial) { + } else if ((SupportsMetal() || SupportsUefi()) && fd < g_fds.n && + g_fds.p[fd].kind == kFdSerial) { return writev_serial(&g_fds.p[fd], iov, iovlen); } else if (!IsWindows()) { return sys_writev(fd, iov, iovlen); diff --git a/libc/dce.h b/libc/dce.h index e100c4da0..ba6c25fab 100644 --- a/libc/dce.h +++ b/libc/dce.h @@ -20,6 +20,7 @@ #define OPENBSD 16 #define FREEBSD 32 #define NETBSD 64 +#define UEFI 128 #ifdef NDEBUG #define NoDebug() 1 @@ -72,6 +73,7 @@ #define SupportsLinux() ((SUPPORT_VECTOR & LINUX) == LINUX) #define SupportsMetal() ((SUPPORT_VECTOR & METAL) == METAL) #define SupportsWindows() ((SUPPORT_VECTOR & WINDOWS) == WINDOWS) +#define SupportsUefi() ((SUPPORT_VECTOR & UEFI) == UEFI) #define SupportsXnu() ((SUPPORT_VECTOR & XNU) == XNU) #define SupportsFreebsd() ((SUPPORT_VECTOR & FREEBSD) == FREEBSD) #define SupportsOpenbsd() ((SUPPORT_VECTOR & OPENBSD) == OPENBSD) @@ -84,6 +86,7 @@ #define IsLinux() (SupportsLinux() && (__hostos & LINUX)) #define IsMetal() (SupportsMetal() && (__hostos & METAL)) #define IsWindows() (SupportsWindows() && (__hostos & WINDOWS)) +#define IsUefi() (SupportsUefi() && (__hostos & UEFI)) #define IsXnu() (SupportsXnu() && (__hostos & XNU)) #define IsFreebsd() (SupportsFreebsd() && (__hostos & FREEBSD)) #define IsOpenbsd() (SupportsOpenbsd() && (__hostos & OPENBSD)) @@ -94,6 +97,7 @@ #define IsLinux() $LINUX,__hostos(%rip) #define IsMetal() $METAL,__hostos(%rip) #define IsWindows() $WINDOWS,__hostos(%rip) +#define IsUefi() $UEFI,__hostos(%rip) #define IsBsd() $XNU|FREEBSD|OPENBSD|NETBSD,__hostos(%rip) #define IsXnu() $XNU,__hostos(%rip) #define IsFreebsd() $FREEBSD,__hostos(%rip) diff --git a/libc/nexgen32e/vendor.internal.h b/libc/nexgen32e/vendor.internal.h index 6b389ab2f..dc8916554 100644 --- a/libc/nexgen32e/vendor.internal.h +++ b/libc/nexgen32e/vendor.internal.h @@ -59,7 +59,7 @@ #define _KCPUIDS_VENDOR() \ (((kCpuids[KCPUIDS_0H][KCPUIDS_EBX] >> 000) & 0xff) ^ \ - ((kCpuids[KCPUIDS_0H][KCPUIDS_EDX] >> 010) & 0xff)) + ((kCpuids[KCPUIDS_0H][KCPUIDS_ECX] >> 010) & 0xff)) #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_NEXGEN32E_VENDOR_H_ */ diff --git a/libc/nt/efi.h b/libc/nt/efi.h new file mode 100644 index 000000000..1c6edd7d9 --- /dev/null +++ b/libc/nt/efi.h @@ -0,0 +1,424 @@ +#ifndef COSMOPOLITAN_LIBC_NT_EFI_H_ +#define COSMOPOLITAN_LIBC_NT_EFI_H_ +/* + ▐██ ░█████████▓ ▐██▌ ██▓░ ▐█▌ ▐██ ░██░ ▓█▌ ▓██▒ ▓██ + ▐██ ░██░ ▒█▓██░ ████░ ▐█▌ ▐██ ░██░ ▓█▌ ▓███░ ▓███ + ▐██ ░██░ ██░▐█▓ ██▒▓█░ ▐█▌ ▐██ ░██░ ▓█▌ ▓█▌▓█░ ▓█▒██ + ▐██ ░██░ ▐█▌ ▓█▌ ██░░▓█░▐█▌ ▐██ ░██░ ▓█▌ ▓█▌░█▓▓█▒░██ + ▐██ ░██░ ▒██▓█████░ ██░ ░▓▓▓█▌ ▐██ ░██░ ██░ ▓█▌ ░██▌ ░██ + ▐██ ░██░ ▓█▌ ▓█▓ ██░ ░███▌ ▐██ ▐██▄▄▄▓█▓ ▓█▌ ░██ +╔────────────────────────────────────────────────────────────────────────────│─╗ +│ αcτµαlly pδrταblε εxεcµταblε § the unified extensible firmware interface ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define EFI_SUCCESS 0x8000000000000000 +#define EFI_LOAD_ERROR 0x8000000000000001 +#define EFI_INVALID_PARAMETER 0x8000000000000002 +#define EFI_UNSUPPORTED 0x8000000000000003 +#define EFI_BAD_BUFFER_SIZE 0x8000000000000004 +#define EFI_BUFFER_TOO_SMALL 0x8000000000000005 +#define EFI_NOT_READY 0x8000000000000006 +#define EFI_DEVICE_ERROR 0x8000000000000007 +#define EFI_WRITE_PROTECTED 0x8000000000000008 +#define EFI_OUT_OF_RESOURCES 0x8000000000000009 +#define EFI_VOLUME_CORRUPTED 0x800000000000000a +#define EFI_VOLUME_FULL 0x800000000000000b +#define EFI_NO_MEDIA 0x800000000000000c +#define EFI_MEDIA_CHANGED 0x800000000000000d +#define EFI_NOT_FOUND 0x800000000000000e +#define EFI_ACCESS_DENIED 0x800000000000000f +#define EFI_NO_RESPONSE 0x8000000000000010 +#define EFI_NO_MAPPING 0x8000000000000011 +#define EFI_TIMEOUT 0x8000000000000012 +#define EFI_NOT_STARTED 0x8000000000000013 +#define EFI_ALREADY_STARTED 0x8000000000000014 +#define EFI_ABORTED 0x8000000000000015 +#define EFI_ICMP_ERROR 0x8000000000000016 +#define EFI_TFTP_ERROR 0x8000000000000017 +#define EFI_PROTOCOL_ERROR 0x8000000000000018 + +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 + +#define EFI_MEMORY_UC 0x0000000000000001U +#define EFI_MEMORY_WC 0x0000000000000002U +#define EFI_MEMORY_WT 0x0000000000000004U +#define EFI_MEMORY_WB 0x0000000000000008U +#define EFI_MEMORY_UCE 0x0000000000000010U +#define EFI_MEMORY_WP 0x0000000000001000U +#define EFI_MEMORY_RP 0x0000000000002000U +#define EFI_MEMORY_XP 0x0000000000004000U +#define EFI_MEMORY_RO 0x0000000000020000U +#define EFI_MEMORY_NV 0x0000000000008000U +#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000U +#define EFI_MEMORY_RUNTIME 0x8000000000000000U + +#define EFI_OPTIONAL_PTR 0x00000001 + +#define EFI_SCAN_NULL 0x0000 +#define EFI_SCAN_UP 0x0001 +#define EFI_SCAN_DOWN 0x0002 +#define EFI_SCAN_RIGHT 0x0003 +#define EFI_SCAN_LEFT 0x0004 +#define EFI_SCAN_HOME 0x0005 +#define EFI_SCAN_END 0x0006 +#define EFI_SCAN_INSERT 0x0007 +#define EFI_SCAN_DELETE 0x0008 +#define EFI_SCAN_PAGE_UP 0x0009 +#define EFI_SCAN_PAGE_DOWN 0x000A +#define EFI_SCAN_F1 0x000B +#define EFI_SCAN_F2 0x000C +#define EFI_SCAN_F3 0x000D +#define EFI_SCAN_F4 0x000E +#define EFI_SCAN_F5 0x000F +#define EFI_SCAN_F6 0x0010 +#define EFI_SCAN_F7 0x0011 +#define EFI_SCAN_F8 0x0012 +#define EFI_SCAN_F9 0x0013 +#define EFI_SCAN_F10 0x0014 +#define EFI_SCAN_ESC 0x0017 + +#define EFI_EVT_TIMER 0x80000000 +#define EFI_EVT_RUNTIME 0x40000000 +#define EFI_EVT_NOTIFY_WAIT 0x00000100 +#define EFI_EVT_NOTIFY_SIGNAL 0x00000200 +#define EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 +#define EFI_EVT_RUNTIME_CONTEXT 0x20000000 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define EFIAPI __attribute__((__ms_abi__)) +#define EFI_STATUS uint64_t +#define EFI_EVENT uintptr_t +#define EFI_HANDLE uintptr_t + +typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL; +typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiPersistentMemory, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +typedef enum { + EfiResetCold, + EfiResetWarm, + EfiResetShutdown, + EfiResetPlatformSpecific +} EFI_RESET_TYPE; + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} EFI_ALLOCATE_TYPE; + +typedef enum { + TimerCancel, + TimerPeriodic, + TimerRelative, +} EFI_TIMER_DELAY; + +typedef struct { + uint32_t Resolution; + uint32_t Accuracy; + bool SetsToZero; +} EFI_TIME_CAPABILITIES; + +typedef struct { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +} EFI_GUID; + +typedef struct { + uint16_t Year; + uint8_t Month; + uint8_t Day; + uint8_t Hour; + uint8_t Minute; + uint8_t Second; + uint8_t Pad1; + uint32_t Nanosecond; + int16_t TimeZone; + uint8_t Daylight; + uint8_t Pad2; +} EFI_TIME; + +typedef struct { + uint32_t Type; + uint64_t PhysicalStart; + uint64_t VirtualStart; + uint64_t NumberOfPages; + uint64_t Attribute; +} EFI_MEMORY_DESCRIPTOR; + +typedef struct { + EFI_GUID VendorGuid; + void *VendorTable; +} EFI_CONFIGURATION_TABLE; + +typedef struct { + EFI_GUID CapsuleGuid; + uint32_t HeaderSize; + uint32_t Flags; + uint32_t CapsuleImageSize; +} EFI_CAPSULE_HEADER; + +typedef struct { + uint16_t ScanCode; + char16_t UnicodeChar; +} EFI_INPUT_KEY; + +typedef struct { + int32_t MaxMode; + int32_t Mode; + int32_t Attribute; + int32_t CursorColumn; + int32_t CursorRow; + bool CursorVisible; +} EFI_SIMPLE_TEXT_OUTPUT_MODE; + +typedef struct { + uint64_t Signature; + uint32_t Revision; + uint32_t HeaderSize; + uint32_t CRC32; + uint32_t Reserved; +} EFI_TABLE_HEADER; + +typedef EFI_STATUS(EFIAPI *EFI_EXIT)(EFI_HANDLE ImageHandle, + EFI_STATUS ExitStatus, + uintptr_t ExitDataSize, + char16_t *opt_ExitData); + +typedef EFI_STATUS(EFIAPI *EFI_GET_VARIABLE)(char16_t *VariableName, + EFI_GUID *VendorGuid, + uint32_t *outopt_Attributes, + uintptr_t *inout_DataSize, + void *outopt_Data); +typedef EFI_STATUS(EFIAPI *EFI_SET_VARIABLE)(char16_t *VariableName, + EFI_GUID *VendorGuid, + uint32_t Attributes, + uintptr_t DataSize, void *Data); +typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)( + uintptr_t *inout_VariableNameSize, char16_t *inout_VariableName, + EFI_GUID *inout_VendorGuid); +typedef EFI_STATUS(EFIAPI *EFI_QUERY_VARIABLE_INFO)( + uint32_t Attributes, uint64_t *out_MaximumVariableStorageSize, + uint64_t *out_RemainingVariableStorageSize, + uint64_t *out_MaximumVariableSize); + +typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_PAGES)(EFI_ALLOCATE_TYPE Type, + EFI_MEMORY_TYPE MemoryType, + uintptr_t Pages, + uint64_t *inout_Memory); +typedef EFI_STATUS(EFIAPI *EFI_FREE_PAGES)(uint64_t Memory, uintptr_t Pages); +typedef EFI_STATUS(EFIAPI *EFI_GET_MEMORY_MAP)( + uintptr_t *inout_MemoryMapSize, EFI_MEMORY_DESCRIPTOR *inout_MemoryMap, + uintptr_t *out_MapKey, uintptr_t *out_DescriptorSize, + uint32_t *out_DescriptorVersion); + +typedef EFI_STATUS(EFIAPI *EFI_CHECK_EVENT)(EFI_EVENT Event); +typedef EFI_STATUS(EFIAPI *EFI_CLOSE_EVENT)(EFI_EVENT Event); +typedef EFI_STATUS(EFIAPI *EFI_SIGNAL_EVENT)(EFI_EVENT Event); +typedef EFI_STATUS(EFIAPI *EFI_WAIT_FOR_EVENT)(uintptr_t NumberOfEvents, + EFI_EVENT *Events, + uintptr_t *out_Index); +typedef EFI_STATUS(EFIAPI *EFI_SET_TIMER)(EFI_EVENT Event, EFI_TIMER_DELAY Type, + uint64_t TriggerTime); +typedef void(EFIAPI *EFI_EVENT_NOTIFY)(EFI_EVENT Event, void *Context); +typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT)(uint32_t Type, uintptr_t NotifyTpl, + EFI_EVENT_NOTIFY NotifyFunction, + void *NotifyContext, + EFI_EVENT *out_Event); +typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT_EX)( + uint32_t Type, uintptr_t NotifyTpl, EFI_EVENT_NOTIFY opt_NotifyFunction, + const void *opt_NotifyContext, const EFI_GUID *opt_EventGroup, + EFI_EVENT *out_Event); + +typedef EFI_STATUS(EFIAPI *EFI_UPDATE_CAPSULE)( + EFI_CAPSULE_HEADER **CapsuleHeaderArray, uintptr_t CapsuleCount, + uint64_t opt_ScatterGatherList); +typedef EFI_STATUS(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES)( + EFI_CAPSULE_HEADER **CapsuleHeaderArray, uintptr_t CapsuleCount, + uint64_t *out_MaximumCapsuleSize, EFI_RESET_TYPE *out_ResetType); +typedef EFI_STATUS(EFIAPI *EFI_GET_WAKEUP_TIME)(bool *out_Enabled, + bool *out_Pending, + EFI_TIME *out_Time); +typedef EFI_STATUS(EFIAPI *EFI_SET_WAKEUP_TIME)(bool Enable, + EFI_TIME *opt_Time); +typedef EFI_STATUS(EFIAPI *EFI_SET_WATCHDOG_TIMER)(uintptr_t Timeout, + uint64_t WatchdogCode, + uintptr_t DataSize, + char16_t *opt_WatchdogData); + +typedef EFI_STATUS(EFIAPI *EFI_SET_TIME)(EFI_TIME *Time); +typedef EFI_STATUS(EFIAPI *EFI_GET_TIME)( + EFI_TIME *out_Time, EFI_TIME_CAPABILITIES *outopt_Capabilities); +typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT)( + uint32_t *out_HighCount); +typedef EFI_STATUS(EFIAPI *EFI_STALL)(uintptr_t Microseconds); +typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)(uint64_t *out_Count); + +typedef EFI_STATUS(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)( + uintptr_t MemoryMapSize, uintptr_t DescriptorSize, + uint32_t DescriptorVersion, EFI_MEMORY_DESCRIPTOR *VirtualMap); +typedef void(EFIAPI *EFI_RESET_SYSTEM)(EFI_RESET_TYPE ResetType, + EFI_STATUS ResetStatus, + uintptr_t DataSize, void *opt_ResetData); +typedef EFI_STATUS(EFIAPI *EFI_CONVERT_POINTER)(uintptr_t DebugDisposition, + void **inout_Address); + +typedef EFI_STATUS(EFIAPI *EFI_INPUT_RESET)( + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, bool ExtendedVerification); +typedef EFI_STATUS(EFIAPI *EFI_INPUT_READ_KEY)( + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, EFI_INPUT_KEY *out_Key); + +typedef EFI_STATUS(EFIAPI *EFI_TEXT_RESET)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, bool ExtendedVerification); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_STRING)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, char16_t *String); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_TEST_STRING)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, char16_t *String); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_QUERY_MODE)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, uint64_t ModeNumber, + uint64_t *out_Columns, uint64_t *out_Rows); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_MODE)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, uint64_t ModeNumber); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_ATTRIBUTE)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, uint64_t Attribute); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_CLEAR_SCREEN)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, uint64_t Column, uint64_t Row); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_ENABLE_CURSOR)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, bool Visible); + +typedef struct { + EFI_TABLE_HEADER Hdr; + EFI_GET_TIME GetTime; + EFI_SET_TIME SetTime; + EFI_GET_WAKEUP_TIME GetWakeupTime; + EFI_SET_WAKEUP_TIME SetWakeupTime; + EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; + EFI_CONVERT_POINTER ConvertPointer; + EFI_GET_VARIABLE GetVariable; + EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; + EFI_SET_VARIABLE SetVariable; + EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount; + EFI_RESET_SYSTEM ResetSystem; + EFI_UPDATE_CAPSULE UpdateCapsule; + EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities; + EFI_QUERY_VARIABLE_INFO QueryVariableInfo; +} EFI_RUNTIME_SERVICES; + +typedef struct { + EFI_TABLE_HEADER Hdr; + void *RaiseTPL; + void *RestoreTPL; + EFI_ALLOCATE_PAGES AllocatePages; + EFI_FREE_PAGES FreePages; + EFI_GET_MEMORY_MAP GetMemoryMap; + void *AllocatePool; + void *FreePool; + EFI_CREATE_EVENT CreateEvent; + EFI_SET_TIMER SetTimer; + EFI_WAIT_FOR_EVENT WaitForEvent; + EFI_SIGNAL_EVENT SignalEvent; + EFI_CLOSE_EVENT CloseEvent; + EFI_CHECK_EVENT CheckEvent; + void *InstallProtocolInterface; + void *ReinstallProtocolInterface; + void *UninstallProtocolInterface; + void *HandleProtocol; + void *Reserved; + void *RegisterProtocolNotify; + void *LocateHandle; + void *LocateDevicePath; + void *InstallConfigurationTable; + void *LoadImage; + void *StartImage; + EFI_EXIT Exit; + void *UnloadImage; + void *ExitBootServices; + EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; + EFI_STALL Stall; + EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; + void *ConnectController; + void *DisconnectController; + void *OpenProtocol; + void *CloseProtocol; + void *OpenProtocolInformation; + void *ProtocolsPerHandle; + void *LocateHandleBuffer; + void *LocateProtocol; + void *InstallMultipleProtocolInterfaces; + void *UninstallMultipleProtocolInterfaces; + void *CalculateCrc32; + void *CopyMem; + void *SetMem; + EFI_CREATE_EVENT_EX CreateEventEx; +} EFI_BOOT_SERVICES; + +typedef struct { + EFI_TABLE_HEADER Hdr; + char16_t *FirmwareVendor; + uint32_t FirmwareRevision; + EFI_HANDLE ConsoleInHandle; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; + EFI_HANDLE ConsoleOutHandle; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; + EFI_HANDLE StandardErrorHandle; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr; + EFI_RUNTIME_SERVICES *RuntimeServices; + EFI_BOOT_SERVICES *BootServices; + uintptr_t NumberOfTableEntries; + EFI_CONFIGURATION_TABLE *ConfigurationTable; +} EFI_SYSTEM_TABLE; + +struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL { + EFI_INPUT_RESET Reset; + EFI_INPUT_READ_KEY ReadKeyStroke; + EFI_EVENT WaitForKey; +}; + +struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { + EFI_TEXT_RESET Reset; + EFI_TEXT_STRING OutputString; + EFI_TEXT_TEST_STRING TestString; + EFI_TEXT_QUERY_MODE QueryMode; + EFI_TEXT_SET_MODE SetMode; + EFI_TEXT_SET_ATTRIBUTE SetAttribute; + EFI_TEXT_CLEAR_SCREEN ClearScreen; + EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; + EFI_TEXT_ENABLE_CURSOR EnableCursor; + EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_EFI_H_ */ diff --git a/libc/nt/pedef.internal.h b/libc/nt/pedef.internal.h index 1df4209e3..152dc1c11 100644 --- a/libc/nt/pedef.internal.h +++ b/libc/nt/pedef.internal.h @@ -16,370 +16,370 @@ .tls: __declspec(thread) data (Fails with dynamically loaded DLLs -> hard to find bugs) */ -#define kNtImageDosSignature 0x5A4D -#define kNtImageOs2Signature 0x454E +#define kNtImageDosSignature 0x5A4D +#define kNtImageOs2Signature 0x454E #define kNtImageOs2SignatureLe 0x454C -#define kNtImageVxdSignature 0x454C -#define kNtImageNtSignature 0x00004550 +#define kNtImageVxdSignature 0x454C +#define kNtImageNtSignature 0x00004550 -#define kNtPeFileRelocsStripped 0x00001 -#define kNtPeFileExecutableImage 0x00002 -#define kNtPeFileLineNumsStripped 0x00004 +#define kNtPeFileRelocsStripped 0x00001 +#define kNtPeFileExecutableImage 0x00002 +#define kNtPeFileLineNumsStripped 0x00004 #define kNtPeFileLocalSymsStripped 0x00008 -#define kNtPeFile_32bitMachine 0x00100 -#define kNtPeFileDll 0x02000 +#define kNtPeFile_32bitMachine 0x00100 +#define kNtPeFileDll 0x02000 #define kNtPe32bit 0x010b #define kNtPe64bit 0x020b -#define kNtPeSectionCntCode 0x000000020 -#define kNtPeSectionCntInitializedData 0x000000040 +#define kNtPeSectionCntCode 0x000000020 +#define kNtPeSectionCntInitializedData 0x000000040 #define kNtPeSectionCntUninitializedData 0x000000080 -#define kNtPeSectionGprel 0x000008000 -#define kNtPeSectionMemDiscardable 0x02000000 -#define kNtPeSectionMemNotCached 0x04000000 -#define kNtPeSectionMemNotPaged 0x08000000 -#define kNtPeSectionMemShared 0x10000000 -#define kNtPeSectionMemExecute 0x20000000 -#define kNtPeSectionMemRead 0x40000000 -#define kNtPeSectionMemWrite 0x80000000 +#define kNtPeSectionGprel 0x000008000 +#define kNtPeSectionMemDiscardable 0x02000000 +#define kNtPeSectionMemNotCached 0x04000000 +#define kNtPeSectionMemNotPaged 0x08000000 +#define kNtPeSectionMemShared 0x10000000 +#define kNtPeSectionMemExecute 0x20000000 +#define kNtPeSectionMemRead 0x40000000 +#define kNtPeSectionMemWrite 0x80000000 -#define kNtPeGuardCfInstrumented 0x000000100 -#define kNtPeGuardCfwInstrumented 0x000000200 +#define kNtPeGuardCfInstrumented 0x000000100 +#define kNtPeGuardCfwInstrumented 0x000000200 #define kNtPeGuardCfFunctionTablePresent 0x000000400 -#define kNtPeGuardSecurityCookieUnused 0x000000800 +#define kNtPeGuardSecurityCookieUnused 0x000000800 -#define kNtPeRelBasedAbsolute 0 -#define kNtPeRelBasedHigh 1 -#define kNtPeRelBasedLow 2 -#define kNtPeRelBasedHighlow 3 -#define kNtPeRelBasedHighadj 4 -#define kNtPeRelBasedMipsJmpaddr 5 -#define kNtPeRelBasedSection 6 -#define kNtPeRelBasedRel32 7 +#define kNtPeRelBasedAbsolute 0 +#define kNtPeRelBasedHigh 1 +#define kNtPeRelBasedLow 2 +#define kNtPeRelBasedHighlow 3 +#define kNtPeRelBasedHighadj 4 +#define kNtPeRelBasedMipsJmpaddr 5 +#define kNtPeRelBasedSection 6 +#define kNtPeRelBasedRel32 7 #define kNtPeRelBasedMipsJmpaddr16 9 -#define kNtPeRelBasedIa64Imm64 9 -#define kNtPeRelBasedDir64 10 -#define kNtPeRelBasedHigh3adj 11 +#define kNtPeRelBasedIa64Imm64 9 +#define kNtPeRelBasedDir64 10 +#define kNtPeRelBasedHigh3adj 11 -#define kNtImageFileRelocsStripped 0x0001 -#define kNtImageFileExecutableImage 0x0002 -#define kNtImageFileLineNumsStripped 0x0004 -#define kNtImageFileLocalSymsStripped 0x0008 -#define kNtImageFileAggresiveWsTrim 0x0010 -#define kNtImageFileLargeAddressAware 0x0020 -#define kNtImageFileBytesReversedLo 0x0080 -#define kNtImageFile32bitMachine 0x0100 -#define kNtImageFileDebugStripped 0x0200 +#define kNtImageFileRelocsStripped 0x0001 +#define kNtImageFileExecutableImage 0x0002 +#define kNtImageFileLineNumsStripped 0x0004 +#define kNtImageFileLocalSymsStripped 0x0008 +#define kNtImageFileAggresiveWsTrim 0x0010 +#define kNtImageFileLargeAddressAware 0x0020 +#define kNtImageFileBytesReversedLo 0x0080 +#define kNtImageFile32bitMachine 0x0100 +#define kNtImageFileDebugStripped 0x0200 #define kNtImageFileRemovableRunFromSwap 0x0400 -#define kNtImageFileNetRunFromSwap 0x0800 -#define kNtImageFileSystem 0x1000 -#define kNtImageFileDll 0x2000 -#define kNtImageFileUpSystemOnly 0x4000 -#define kNtImageFileBytesReversedHi 0x8000 +#define kNtImageFileNetRunFromSwap 0x0800 +#define kNtImageFileSystem 0x1000 +#define kNtImageFileDll 0x2000 +#define kNtImageFileUpSystemOnly 0x4000 +#define kNtImageFileBytesReversedHi 0x8000 -#define kNtImageFileMachineUnknown 0 +#define kNtImageFileMachineUnknown 0 #define kNtImageFileMachineTargetHost 0x0001 -#define kNtImageFileMachineI386 0x014c -#define kNtImageFileMachineR3000 0x0162 -#define kNtImageFileMachineR4000 0x0166 -#define kNtImageFileMachineR10000 0x0168 -#define kNtImageFileMachineWcemipsv2 0x0169 -#define kNtImageFileMachineAlpha 0x0184 -#define kNtImageFileMachineSh3 0x01a2 -#define kNtImageFileMachineSh3dsp 0x01a3 -#define kNtImageFileMachineSh3e 0x01a4 -#define kNtImageFileMachineSh4 0x01a6 -#define kNtImageFileMachineSh5 0x01a8 -#define kNtImageFileMachineArm 0x01c0 -#define kNtImageFileMachineThumb 0x01c2 -#define kNtImageFileMachineArmnt 0x01c4 -#define kNtImageFileMachineAm33 0x01d3 -#define kNtImageFileMachinePowerpc 0x01F0 -#define kNtImageFileMachinePowerpcfp 0x01f1 -#define kNtImageFileMachineIa64 0x0200 -#define kNtImageFileMachineMips16 0x0266 -#define kNtImageFileMachineAlpha64 0x0284 -#define kNtImageFileMachineMipsfpu 0x0366 -#define kNtImageFileMachineMipsfpu16 0x0466 -#define kNtImageFileMachineAxp64 kNtImageFileMachineAlpha64 -#define kNtImageFileMachineTricore 0x0520 -#define kNtImageFileMachineCef 0x0CEF -#define kNtImageFileMachineEbc 0x0EBC -#define kNtImageFileMachineNexgen32e 0x8664 -#define kNtImageFileMachineM32r 0x9041 -#define kNtImageFileMachineArm64 0xAA64 -#define kNtImageFileMachineCee 0xC0EE +#define kNtImageFileMachineI386 0x014c +#define kNtImageFileMachineR3000 0x0162 +#define kNtImageFileMachineR4000 0x0166 +#define kNtImageFileMachineR10000 0x0168 +#define kNtImageFileMachineWcemipsv2 0x0169 +#define kNtImageFileMachineAlpha 0x0184 +#define kNtImageFileMachineSh3 0x01a2 +#define kNtImageFileMachineSh3dsp 0x01a3 +#define kNtImageFileMachineSh3e 0x01a4 +#define kNtImageFileMachineSh4 0x01a6 +#define kNtImageFileMachineSh5 0x01a8 +#define kNtImageFileMachineArm 0x01c0 +#define kNtImageFileMachineThumb 0x01c2 +#define kNtImageFileMachineArmnt 0x01c4 +#define kNtImageFileMachineAm33 0x01d3 +#define kNtImageFileMachinePowerpc 0x01F0 +#define kNtImageFileMachinePowerpcfp 0x01f1 +#define kNtImageFileMachineIa64 0x0200 +#define kNtImageFileMachineMips16 0x0266 +#define kNtImageFileMachineAlpha64 0x0284 +#define kNtImageFileMachineMipsfpu 0x0366 +#define kNtImageFileMachineMipsfpu16 0x0466 +#define kNtImageFileMachineAxp64 kNtImageFileMachineAlpha64 +#define kNtImageFileMachineTricore 0x0520 +#define kNtImageFileMachineCef 0x0CEF +#define kNtImageFileMachineEbc 0x0EBC +#define kNtImageFileMachineNexgen32e 0x8664 +#define kNtImageFileMachineM32r 0x9041 +#define kNtImageFileMachineArm64 0xAA64 +#define kNtImageFileMachineCee 0xC0EE -#define kNtImageSubsystemUnknown 0 -#define kNtImageSubsystemNative 1 -#define kNtImageSubsystemWindowsGui 2 -#define kNtImageSubsystemWindowsCui 3 -#define kNtImageSubsystemOs2Cui 5 -#define kNtImageSubsystemPosixCui 7 -#define kNtImageSubsystemNativeWindows 8 -#define kNtImageSubsystemWindowsCeGui 9 -#define kNtImageSubsystemEfiApplication 1 -#define kNtImageSubsystemEfiBootServiceDriver 11 -#define kNtImageSubsystemEfiRuntimeDriver 12 -#define kNtImageSubsystemEfiRom 13 -#define kNtImageSubsystemXbox 14 +#define kNtImageSubsystemUnknown 0 +#define kNtImageSubsystemNative 1 +#define kNtImageSubsystemWindowsGui 2 +#define kNtImageSubsystemWindowsCui 3 +#define kNtImageSubsystemOs2Cui 5 +#define kNtImageSubsystemPosixCui 7 +#define kNtImageSubsystemNativeWindows 8 +#define kNtImageSubsystemWindowsCeGui 9 +#define kNtImageSubsystemEfiApplication 10 +#define kNtImageSubsystemEfiBootServiceDriver 11 +#define kNtImageSubsystemEfiRuntimeDriver 12 +#define kNtImageSubsystemEfiRom 13 +#define kNtImageSubsystemXbox 14 #define kNtImageSubsystemWindowsBootApplication 16 -#define kNtImageSubsystemXboxCodeCatalog 17 +#define kNtImageSubsystemXboxCodeCatalog 17 -#define kNtImageDllcharacteristicsHighEntropyVa 0x0020 -#define kNtImageDllcharacteristicsDynamicBase 0x0040 -#define kNtImageDllcharacteristicsForceIntegrity 0x0080 -#define kNtImageDllcharacteristicsNxCompat 0x0100 -#define kNtImageDllcharacteristicsNoIsolation 0x0200 -#define kNtImageDllcharacteristicsNoSeh 0x0400 -#define kNtImageDllcharacteristicsNoBind 0x0800 -#define kNtImageDllcharacteristicsAppcontainer 0x1000 -#define kNtImageDllcharacteristicsWdmDriver 0x2000 -#define kNtImageDllcharacteristicsGuardCf 0x4000 +#define kNtImageDllcharacteristicsHighEntropyVa 0x0020 +#define kNtImageDllcharacteristicsDynamicBase 0x0040 +#define kNtImageDllcharacteristicsForceIntegrity 0x0080 +#define kNtImageDllcharacteristicsNxCompat 0x0100 +#define kNtImageDllcharacteristicsNoIsolation 0x0200 +#define kNtImageDllcharacteristicsNoSeh 0x0400 +#define kNtImageDllcharacteristicsNoBind 0x0800 +#define kNtImageDllcharacteristicsAppcontainer 0x1000 +#define kNtImageDllcharacteristicsWdmDriver 0x2000 +#define kNtImageDllcharacteristicsGuardCf 0x4000 #define kNtImageDllcharacteristicsTerminalServerAware 0x8000 -#define kNtImageDirectoryEntryExport 0 -#define kNtImageDirectoryEntryImport 1 -#define kNtImageDirectoryEntryResource 2 -#define kNtImageDirectoryEntryException 3 -#define kNtImageDirectoryEntrySecurity 4 -#define kNtImageDirectoryEntryBasereloc 5 -#define kNtImageDirectoryEntryDebug 6 -#define kNtImageDirectoryEntryArchitecture 7 -#define kNtImageDirectoryEntryGlobalptr 8 -#define kNtImageDirectoryEntryTls 9 -#define kNtImageDirectoryEntryLoadConfig 10 -#define kNtImageDirectoryEntryBoundImport 11 -#define kNtImageDirectoryEntryIat 12 -#define kNtImageDirectoryEntryDelayImport 13 +#define kNtImageDirectoryEntryExport 0 +#define kNtImageDirectoryEntryImport 1 +#define kNtImageDirectoryEntryResource 2 +#define kNtImageDirectoryEntryException 3 +#define kNtImageDirectoryEntrySecurity 4 +#define kNtImageDirectoryEntryBasereloc 5 +#define kNtImageDirectoryEntryDebug 6 +#define kNtImageDirectoryEntryArchitecture 7 +#define kNtImageDirectoryEntryGlobalptr 8 +#define kNtImageDirectoryEntryTls 9 +#define kNtImageDirectoryEntryLoadConfig 10 +#define kNtImageDirectoryEntryBoundImport 11 +#define kNtImageDirectoryEntryIat 12 +#define kNtImageDirectoryEntryDelayImport 13 #define kNtImageDirectoryEntryComDescriptor 14 -#define kNtImageScnTypeNoPad 0x00000008 -#define kNtImageScnCntCode 0x00000020 -#define kNtImageScnCntInitializedData 0x00000040 +#define kNtImageScnTypeNoPad 0x00000008 +#define kNtImageScnCntCode 0x00000020 +#define kNtImageScnCntInitializedData 0x00000040 #define kNtImageScnCntUninitializedData 0x00000080 -#define kNtImageScnLnkOther 0x00000100 -#define kNtImageScnLnkInfo 0x00000200 -#define kNtImageScnLnkRemove 0x00000800 -#define kNtImageScnLnkComdat 0x00001000 -#define kNtImageScnNoDeferSpecExc 0x00004000 -#define kNtImageScnGprel 0x00008000 -#define kNtImageScnMemFardata 0x00008000 -#define kNtImageScnMemPurgeable 0x00020000 -#define kNtImageScnMem16bit 0x00020000 -#define kNtImageScnMemLocked 0x00040000 -#define kNtImageScnMemPreload 0x00080000 +#define kNtImageScnLnkOther 0x00000100 +#define kNtImageScnLnkInfo 0x00000200 +#define kNtImageScnLnkRemove 0x00000800 +#define kNtImageScnLnkComdat 0x00001000 +#define kNtImageScnNoDeferSpecExc 0x00004000 +#define kNtImageScnGprel 0x00008000 +#define kNtImageScnMemFardata 0x00008000 +#define kNtImageScnMemPurgeable 0x00020000 +#define kNtImageScnMem16bit 0x00020000 +#define kNtImageScnMemLocked 0x00040000 +#define kNtImageScnMemPreload 0x00080000 -#define kNtImageScnAlign1bytes 0x00100000 -#define kNtImageScnAlign2bytes 0x00200000 -#define kNtImageScnAlign4bytes 0x00300000 -#define kNtImageScnAlign8bytes 0x00400000 -#define kNtImageScnAlign16bytes 0x00500000 -#define kNtImageScnAlign32bytes 0x00600000 -#define kNtImageScnAlign64bytes 0x00700000 -#define kNtImageScnAlign128bytes 0x00800000 -#define kNtImageScnAlign256bytes 0x00900000 -#define kNtImageScnAlign512bytes 0x00A00000 +#define kNtImageScnAlign1bytes 0x00100000 +#define kNtImageScnAlign2bytes 0x00200000 +#define kNtImageScnAlign4bytes 0x00300000 +#define kNtImageScnAlign8bytes 0x00400000 +#define kNtImageScnAlign16bytes 0x00500000 +#define kNtImageScnAlign32bytes 0x00600000 +#define kNtImageScnAlign64bytes 0x00700000 +#define kNtImageScnAlign128bytes 0x00800000 +#define kNtImageScnAlign256bytes 0x00900000 +#define kNtImageScnAlign512bytes 0x00A00000 #define kNtImageScnAlign1024bytes 0x00B00000 #define kNtImageScnAlign2048bytes 0x00C00000 #define kNtImageScnAlign4096bytes 0x00D00000 #define kNtImageScnAlign8192bytes 0x00E00000 -#define kNtImageScnAlignMask 0x00F00000 +#define kNtImageScnAlignMask 0x00F00000 -#define kNtImageScnLnkNrelocOvfl 0x01000000 +#define kNtImageScnLnkNrelocOvfl 0x01000000 #define kNtImageScnMemDiscardable 0x02000000 -#define kNtImageScnMemNotCached 0x04000000 -#define kNtImageScnMemNotPaged 0x08000000 -#define kNtImageScnMemShared 0x10000000 -#define kNtImageScnMemExecute 0x20000000 -#define kNtImageScnMemRead 0x40000000 -#define kNtImageScnMemWrite 0x80000000 -#define kNtImageScnScaleIndex 0x00000001 +#define kNtImageScnMemNotCached 0x04000000 +#define kNtImageScnMemNotPaged 0x08000000 +#define kNtImageScnMemShared 0x10000000 +#define kNtImageScnMemExecute 0x20000000 +#define kNtImageScnMemRead 0x40000000 +#define kNtImageScnMemWrite 0x80000000 +#define kNtImageScnScaleIndex 0x00000001 -#define kNtImageSymUndefined ((uint16_t)0) -#define kNtImageSymAbsolute ((uint16_t)-1) -#define kNtImageSymDebug ((uint16_t)-2) -#define kNtImageSymSectionMax 0xFEFF -#define kNtImageSymSectionMaxEx __LONG_MAX__ -#define kNtImageSymTypeNull 0x0000 -#define kNtImageSymTypeVoid 0x0001 -#define kNtImageSymTypeChar 0x0002 -#define kNtImageSymTypeShort 0x0003 -#define kNtImageSymTypeInt 0x0004 -#define kNtImageSymTypeLong 0x0005 -#define kNtImageSymTypeFloat 0x0006 -#define kNtImageSymTypeDouble 0x0007 -#define kNtImageSymTypeStruct 0x0008 -#define kNtImageSymTypeUnion 0x0009 -#define kNtImageSymTypeEnum 0x000A -#define kNtImageSymTypeMoe 0x000B -#define kNtImageSymTypeByte 0x000C -#define kNtImageSymTypeWord 0x000D -#define kNtImageSymTypeUint 0x000E -#define kNtImageSymTypeDword 0x000F -#define kNtImageSymTypePcode 0x8000 -#define kNtImageSymDtypeNull 0 -#define kNtImageSymDtypePointer 1 -#define kNtImageSymDtypeFunction 2 -#define kNtImageSymDtypeArray 3 -#define kNtImageSymClassEndOfFunction ((unsigned char)-1) -#define kNtImageSymClassNull 0x0000 -#define kNtImageSymClassAutomatic 0x0001 -#define kNtImageSymClassExternal 0x0002 -#define kNtImageSymClassStatic 0x0003 -#define kNtImageSymClassRegister 0x0004 -#define kNtImageSymClassExternalDef 0x0005 -#define kNtImageSymClassLabel 0x0006 -#define kNtImageSymClassUndefinedLabel 0x0007 -#define kNtImageSymClassMemberOfStruct 0x0008 -#define kNtImageSymClassArgument 0x0009 -#define kNtImageSymClassStructTag 0x000A -#define kNtImageSymClassMemberOfUnion 0x000B -#define kNtImageSymClassUnionTag 0x000C -#define kNtImageSymClassTypeDefinition 0x000D +#define kNtImageSymUndefined ((uint16_t)0) +#define kNtImageSymAbsolute ((uint16_t)-1) +#define kNtImageSymDebug ((uint16_t)-2) +#define kNtImageSymSectionMax 0xFEFF +#define kNtImageSymSectionMaxEx __LONG_MAX__ +#define kNtImageSymTypeNull 0x0000 +#define kNtImageSymTypeVoid 0x0001 +#define kNtImageSymTypeChar 0x0002 +#define kNtImageSymTypeShort 0x0003 +#define kNtImageSymTypeInt 0x0004 +#define kNtImageSymTypeLong 0x0005 +#define kNtImageSymTypeFloat 0x0006 +#define kNtImageSymTypeDouble 0x0007 +#define kNtImageSymTypeStruct 0x0008 +#define kNtImageSymTypeUnion 0x0009 +#define kNtImageSymTypeEnum 0x000A +#define kNtImageSymTypeMoe 0x000B +#define kNtImageSymTypeByte 0x000C +#define kNtImageSymTypeWord 0x000D +#define kNtImageSymTypeUint 0x000E +#define kNtImageSymTypeDword 0x000F +#define kNtImageSymTypePcode 0x8000 +#define kNtImageSymDtypeNull 0 +#define kNtImageSymDtypePointer 1 +#define kNtImageSymDtypeFunction 2 +#define kNtImageSymDtypeArray 3 +#define kNtImageSymClassEndOfFunction ((unsigned char)-1) +#define kNtImageSymClassNull 0x0000 +#define kNtImageSymClassAutomatic 0x0001 +#define kNtImageSymClassExternal 0x0002 +#define kNtImageSymClassStatic 0x0003 +#define kNtImageSymClassRegister 0x0004 +#define kNtImageSymClassExternalDef 0x0005 +#define kNtImageSymClassLabel 0x0006 +#define kNtImageSymClassUndefinedLabel 0x0007 +#define kNtImageSymClassMemberOfStruct 0x0008 +#define kNtImageSymClassArgument 0x0009 +#define kNtImageSymClassStructTag 0x000A +#define kNtImageSymClassMemberOfUnion 0x000B +#define kNtImageSymClassUnionTag 0x000C +#define kNtImageSymClassTypeDefinition 0x000D #define kNtImageSymClassUndefinedStatic 0x000E -#define kNtImageSymClassEnumTag 0x000F -#define kNtImageSymClassMemberOfEnum 0x0010 -#define kNtImageSymClassRegisterParam 0x0011 -#define kNtImageSymClassBitField 0x0012 -#define kNtImageSymClassFarExternal 0x0044 -#define kNtImageSymClassBlock 0x0064 -#define kNtImageSymClassFunction 0x0065 -#define kNtImageSymClassEndOfStruct 0x0066 -#define kNtImageSymClassFile 0x0067 -#define kNtImageSymClassSection 0x0068 -#define kNtImageSymClassWeakExternal 0x0069 -#define kNtImageSymClassClrToken 0x006B +#define kNtImageSymClassEnumTag 0x000F +#define kNtImageSymClassMemberOfEnum 0x0010 +#define kNtImageSymClassRegisterParam 0x0011 +#define kNtImageSymClassBitField 0x0012 +#define kNtImageSymClassFarExternal 0x0044 +#define kNtImageSymClassBlock 0x0064 +#define kNtImageSymClassFunction 0x0065 +#define kNtImageSymClassEndOfStruct 0x0066 +#define kNtImageSymClassFile 0x0067 +#define kNtImageSymClassSection 0x0068 +#define kNtImageSymClassWeakExternal 0x0069 +#define kNtImageSymClassClrToken 0x006B #define kNtImageComdatSelectNoduplicates 1 -#define kNtImageComdatSelectAny 2 -#define kNtImageComdatSelectSameSize 3 -#define kNtImageComdatSelectExactMatch 4 -#define kNtImageComdatSelectAssociative 5 -#define kNtImageComdatSelectLargest 6 -#define kNtImageComdatSelectNewest 7 +#define kNtImageComdatSelectAny 2 +#define kNtImageComdatSelectSameSize 3 +#define kNtImageComdatSelectExactMatch 4 +#define kNtImageComdatSelectAssociative 5 +#define kNtImageComdatSelectLargest 6 +#define kNtImageComdatSelectNewest 7 #define kNtImageWeakExternSearchNolibrary 1 -#define kNtImageWeakExternSearchLibrary 2 -#define kNtImageWeakExternSearchAlias 3 -#define kNtImageWeakExternAntiDependency 4 +#define kNtImageWeakExternSearchLibrary 2 +#define kNtImageWeakExternSearchAlias 3 +#define kNtImageWeakExternAntiDependency 4 #define kNtImageRelNexgen32eAbsolute 0x0000 -#define kNtImageRelNexgen32eAddr64 0x0001 -#define kNtImageRelNexgen32eAddr32 0x0002 +#define kNtImageRelNexgen32eAddr64 0x0001 +#define kNtImageRelNexgen32eAddr32 0x0002 #define kNtImageRelNexgen32eAddr32nb 0x0003 -#define kNtImageRelNexgen32eRel32 0x0004 -#define kNtImageRelNexgen32eRel32_1 0x0005 -#define kNtImageRelNexgen32eRel32_2 0x0006 -#define kNtImageRelNexgen32eRel32_3 0x0007 -#define kNtImageRelNexgen32eRel32_4 0x0008 -#define kNtImageRelNexgen32eRel32_5 0x0009 -#define kNtImageRelNexgen32eSection 0x000A -#define kNtImageRelNexgen32eSecrel 0x000B -#define kNtImageRelNexgen32eSecrel7 0x000C -#define kNtImageRelNexgen32eToken 0x000D -#define kNtImageRelNexgen32eSrel32 0x000E -#define kNtImageRelNexgen32ePair 0x000F -#define kNtImageRelNexgen32eSspan32 0x0010 +#define kNtImageRelNexgen32eRel32 0x0004 +#define kNtImageRelNexgen32eRel32_1 0x0005 +#define kNtImageRelNexgen32eRel32_2 0x0006 +#define kNtImageRelNexgen32eRel32_3 0x0007 +#define kNtImageRelNexgen32eRel32_4 0x0008 +#define kNtImageRelNexgen32eRel32_5 0x0009 +#define kNtImageRelNexgen32eSection 0x000A +#define kNtImageRelNexgen32eSecrel 0x000B +#define kNtImageRelNexgen32eSecrel7 0x000C +#define kNtImageRelNexgen32eToken 0x000D +#define kNtImageRelNexgen32eSrel32 0x000E +#define kNtImageRelNexgen32ePair 0x000F +#define kNtImageRelNexgen32eSspan32 0x0010 -#define kNtImageRelBasedAbsolute 0 -#define kNtImageRelBasedHigh 1 -#define kNtImageRelBasedLow 2 -#define kNtImageRelBasedHighlow 3 -#define kNtImageRelBasedHighadj 4 +#define kNtImageRelBasedAbsolute 0 +#define kNtImageRelBasedHigh 1 +#define kNtImageRelBasedLow 2 +#define kNtImageRelBasedHighlow 3 +#define kNtImageRelBasedHighadj 4 #define kNtImageRelBasedMachineSpecific_5 5 -#define kNtImageRelBasedReserved 6 +#define kNtImageRelBasedReserved 6 #define kNtImageRelBasedMachineSpecific_7 7 #define kNtImageRelBasedMachineSpecific_8 8 #define kNtImageRelBasedMachineSpecific_9 9 -#define kNtImageRelBasedDir64 10 +#define kNtImageRelBasedDir64 10 -#define kNtImageArchiveStartSize 8 -#define kNtImageArchiveStart "!\n" -#define kNtImageArchiveEnd "`\n" -#define kNtImageArchivePad "\n" -#define kNtImageArchiveLinkerMember "/ " +#define kNtImageArchiveStartSize 8 +#define kNtImageArchiveStart "!\n" +#define kNtImageArchiveEnd "`\n" +#define kNtImageArchivePad "\n" +#define kNtImageArchiveLinkerMember "/ " #define kNtImageArchiveLongnamesMember "// " #define kNtImageArchiveHybridmapMember "// " -#define kNtImageOrdinalFlag 0x8000000000000000 -#define NtImageOrdinal(Ordinal) (Ordinal & 0xffff) +#define kNtImageOrdinalFlag 0x8000000000000000 +#define NtImageOrdinal(Ordinal) (Ordinal & 0xffff) #define NtImageSnapByOrdinal(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0) -#define kNtImageResourceNameIsString 0x80000000 +#define kNtImageResourceNameIsString 0x80000000 #define kNtImageResourceDataIsDirectory 0x80000000 #define kNtImageDynamicRelocationGuardRfPrologue 0x00000001 #define kNtImageDynamicRelocationGuardRfEpilogue 0x00000002 -#define kNtImageHotPatchBaseObligatory 0x00000001 -#define kNtImageHotPatchChunkInverse 0x80000000 -#define kNtImageHotPatchChunkObligatory 0x40000000 -#define kNtImageHotPatchChunkReserved 0x3FF03000 -#define kNtImageHotPatchChunkType 0x000FC000 -#define kNtImageHotPatchChunkSourceRva 0x00008000 -#define kNtImageHotPatchChunkTargetRva 0x00004000 -#define kNtImageHotPatchChunkSize 0x00000FFF -#define kNtImageHotPatchNone 0x00000000 -#define kNtImageHotPatchFunction 0x0001C000 -#define kNtImageHotPatchAbsolute 0x0002C000 -#define kNtImageHotPatchRel32 0x0003C000 -#define kNtImageHotPatchCallTarget 0x00044000 -#define kNtImageHotPatchIndirect 0x0005C000 -#define kNtImageHotPatchNoCallTarget 0x00064000 -#define kNtImageHotPatchDynamicValue 0x00078000 -#define kNtImageGuardCfInstrumented 0x00000100 -#define kNtImageGuardCfwInstrumented 0x00000200 -#define kNtImageGuardCfFunctionTablePresent 0x00000400 -#define kNtImageGuardSecurityCookieUnused 0x00000800 -#define kNtImageGuardProtectDelayloadIat 0x00001000 -#define kNtImageGuardDelayloadIatInItsOwnSection 0x00002000 +#define kNtImageHotPatchBaseObligatory 0x00000001 +#define kNtImageHotPatchChunkInverse 0x80000000 +#define kNtImageHotPatchChunkObligatory 0x40000000 +#define kNtImageHotPatchChunkReserved 0x3FF03000 +#define kNtImageHotPatchChunkType 0x000FC000 +#define kNtImageHotPatchChunkSourceRva 0x00008000 +#define kNtImageHotPatchChunkTargetRva 0x00004000 +#define kNtImageHotPatchChunkSize 0x00000FFF +#define kNtImageHotPatchNone 0x00000000 +#define kNtImageHotPatchFunction 0x0001C000 +#define kNtImageHotPatchAbsolute 0x0002C000 +#define kNtImageHotPatchRel32 0x0003C000 +#define kNtImageHotPatchCallTarget 0x00044000 +#define kNtImageHotPatchIndirect 0x0005C000 +#define kNtImageHotPatchNoCallTarget 0x00064000 +#define kNtImageHotPatchDynamicValue 0x00078000 +#define kNtImageGuardCfInstrumented 0x00000100 +#define kNtImageGuardCfwInstrumented 0x00000200 +#define kNtImageGuardCfFunctionTablePresent 0x00000400 +#define kNtImageGuardSecurityCookieUnused 0x00000800 +#define kNtImageGuardProtectDelayloadIat 0x00001000 +#define kNtImageGuardDelayloadIatInItsOwnSection 0x00002000 #define kNtImageGuardCfExportSuppressionInfoPresent 0x00004000 -#define kNtImageGuardCfEnableExportSuppression 0x00008000 -#define kNtImageGuardCfLongjumpTablePresent 0x00010000 -#define kNtImageGuardRfInstrumented 0x00020000 -#define kNtImageGuardRfEnable 0x00040000 -#define kNtImageGuardRfStrict 0x00080000 -#define kNtImageGuardCfFunctionTableSizeMask 0xF0000000 -#define kNtImageGuardCfFunctionTableSizeShift 28 -#define kNtImageGuardFlagFidSuppressed 0x01 -#define kNtImageGuardFlagExportSuppressed 0x02 +#define kNtImageGuardCfEnableExportSuppression 0x00008000 +#define kNtImageGuardCfLongjumpTablePresent 0x00010000 +#define kNtImageGuardRfInstrumented 0x00020000 +#define kNtImageGuardRfEnable 0x00040000 +#define kNtImageGuardRfStrict 0x00080000 +#define kNtImageGuardCfFunctionTableSizeMask 0xF0000000 +#define kNtImageGuardCfFunctionTableSizeShift 28 +#define kNtImageGuardFlagFidSuppressed 0x01 +#define kNtImageGuardFlagExportSuppressed 0x02 -#define kNtImageEnclaveImportMatchNone 0x00000000 +#define kNtImageEnclaveImportMatchNone 0x00000000 #define kNtImageEnclaveImportMatchUniqueId 0x00000001 #define kNtImageEnclaveImportMatchAuthorId 0x00000002 #define kNtImageEnclaveImportMatchFamilyId 0x00000003 -#define kNtImageEnclaveImportMatchImageId 0x00000004 +#define kNtImageEnclaveImportMatchImageId 0x00000004 -#define kNtImageDebugTypeUnknown 0 -#define kNtImageDebugTypeCoff 1 -#define kNtImageDebugTypeCodeview 2 -#define kNtImageDebugTypeFpo 3 -#define kNtImageDebugTypeMisc 4 -#define kNtImageDebugTypeException 5 -#define kNtImageDebugTypeFixup 6 -#define kNtImageDebugTypeOmapToSrc 7 +#define kNtImageDebugTypeUnknown 0 +#define kNtImageDebugTypeCoff 1 +#define kNtImageDebugTypeCodeview 2 +#define kNtImageDebugTypeFpo 3 +#define kNtImageDebugTypeMisc 4 +#define kNtImageDebugTypeException 5 +#define kNtImageDebugTypeFixup 6 +#define kNtImageDebugTypeOmapToSrc 7 #define kNtImageDebugTypeOmapFromSrc 8 -#define kNtImageDebugTypeBorland 9 -#define kNtImageDebugTypeReserved10 10 -#define kNtImageDebugTypeClsid 11 -#define kNtImageDebugTypeVcFeature 12 -#define kNtImageDebugTypePogo 13 -#define kNtImageDebugTypeIltcg 14 -#define kNtImageDebugTypeMpx 15 -#define kNtImageDebugTypeRepro 16 +#define kNtImageDebugTypeBorland 9 +#define kNtImageDebugTypeReserved10 10 +#define kNtImageDebugTypeClsid 11 +#define kNtImageDebugTypeVcFeature 12 +#define kNtImageDebugTypePogo 13 +#define kNtImageDebugTypeIltcg 14 +#define kNtImageDebugTypeMpx 15 +#define kNtImageDebugTypeRepro 16 -#define kNtFrameFpo 0 -#define kNtFrameTrap 1 -#define kNtFrameTss 2 +#define kNtFrameFpo 0 +#define kNtFrameTrap 1 +#define kNtFrameTss 2 #define kNtFrameNonfpo 3 -#define kNtImageSizeofShortName 8 -#define kNtImageSizeofSectionHeader 40 -#define kNtImageSizeofSymbol 18 -#define kNtImageEnclaveLongIdLength 32 -#define kNtImageEnclaveShortIdLength 16 +#define kNtImageSizeofShortName 8 +#define kNtImageSizeofSectionHeader 40 +#define kNtImageSizeofSymbol 18 +#define kNtImageEnclaveLongIdLength 32 +#define kNtImageEnclaveShortIdLength 16 #define kNtImageNumberofDirectoryEntries 16 #endif /* COSMOPOLITAN_LIBC_NT_PEDEF_H_ */ diff --git a/libc/runtime/efimain.c b/libc/runtime/efimain.c new file mode 100644 index 000000000..a135312aa --- /dev/null +++ b/libc/runtime/efimain.c @@ -0,0 +1,72 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/efi.h" +#include "libc/dce.h" +#include "libc/nt/efi.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/runtime/runtime.h" + +/** + * EFI Application Entrypoint. + * + * This entrypoint is mutually exclusive from WinMain since + * Windows apps and EFI apps use the same PE binary format. + * By default, we build binaries to support Windows. If you + * want to your APE executable to boot on UEFI instead then + * you need to run the following build command: + * + * make -j8 CPPFLAGS=-DSUPPORT_VECTOR=251 + * + * That'll remove all the Windows code and turn EFI on. You + * can also remove by BIOS code too, by changing 251 to 249 + * but it shouldn't matter. Here's how to emulate EFI apps: + * + * qemu-system-x86_64 \ + * -bios OVMF.fd \ + * -serial stdio \ + * -net none \ + * -drive format=raw,file=fat:rw:o/tool/viz + * FS0: + * deathstar.com + * + * If you're using the amalgamated release binaries then it + * should be possible to enable UEFI mode by having this at + * the top of your main source file to hint the APE linker: + * + * STATIC_YOINK("EfiMain"); + * int main() { ... } + * + * @see libc/dce.h + */ +__msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, + EFI_SYSTEM_TABLE *SystemTable) { + extern char os asm("__hostos"); + os = UEFI; + __efi_image_handle = ImageHandle; + __efi_system_table = SystemTable; + asm("push\t$0\n\t" + "push\t$0\n\t" + "push\t$0\n\t" + "push\t$0\n\t" + "push\t$0\n\t" + "xor\t%edi,%edi\n\t" + ".weak\t_start\n\t" + "jmp\t_start"); + unreachable; +} diff --git a/libc/runtime/exit2.S b/libc/runtime/exit2.c similarity index 77% rename from libc/runtime/exit2.S rename to libc/runtime/exit2.c index 12c2958a4..fd5464756 100644 --- a/libc/runtime/exit2.S +++ b/libc/runtime/exit2.c @@ -1,7 +1,7 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ @@ -16,15 +16,16 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -.privileged -.source __FILE__ +#include "libc/runtime/runtime.h" -// Terminates process, ignoring destructors and atexit() handlers. -// -// @param edi is exit code ∈ [0,256) -// @asyncsignalsafe -// @vforksafe -// @noreturn -_exit: jmp _Exit - .endfn _exit,globl,protected +/** + * Terminates process, ignoring destructors and atexit() handlers. + * + * @param rc is exit code ∈ [0,256) + * @asyncsignalsafe + * @vforksafe + * @noreturn + */ +wontreturn void _exit(int rc) { + _Exit(rc); +} diff --git a/libc/runtime/exit3.c b/libc/runtime/exit3.c new file mode 100644 index 000000000..d950c8bf2 --- /dev/null +++ b/libc/runtime/exit3.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/efi.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nexgen32e/vendor.internal.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" + +/** + * Terminates process, ignoring destructors and atexit() handlers. + * + * @param rc is exit code ∈ [0,256) + * @asyncsignalsafe + * @vforksafe + * @noreturn + */ +wontreturn void _Exit(int rc) { + if ((!IsWindows() && !IsMetal() && !IsUefi()) || + (IsMetal() && IsGenuineCosmo())) { + sys_exit(rc); + } else if (IsUefi()) { + __efi_system_table->BootServices->Exit(__efi_image_handle, rc, 0, NULL); + } else if (IsWindows()) { + ExitProcess(rc & 0xff); + } + triplf(); +} diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 6c55eda12..f4b482f94 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -73,12 +73,6 @@ void *sbrk(intptr_t); int brk(void *); int NtGetVersion(void); -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § runtime » optimizations ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - -#define _exit(RC) _Exit(RC) - COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_ */ diff --git a/libc/sysv/systemfive.S b/libc/sysv/systemfive.S index c87ea5076..e3b1d6cd5 100644 --- a/libc/sysv/systemfive.S +++ b/libc/sysv/systemfive.S @@ -104,7 +104,7 @@ __systemfive: .privileged .Lanchorpoint: -#if SupportsLinux() || SupportsMetal() +#if SupportsLinux() || SupportsMetal() || SupportsUefi() systemfive_linux: and $0xfff,%eax cmp $0xfff,%eax @@ -194,14 +194,18 @@ systemfive_xnu: .init.start 300,_init_systemfive push %rbx push %rsi -#if SupportsMetal() - testb $METAL,(%rdi) # @see ape/ape.S - jnz _init_systemfive_metal -#endif #if SupportsXnu() testb $XNU,(%rdi) # @see libc/crt/crt.S jnz _init_systemfive_xnu #endif +#if SupportsUefi() + testb $UEFI,(%rdi) # @see ape/ape.S + jnz _init_systemfive_uefi +#endif +#if SupportsMetal() + testb $METAL,(%rdi) # @see ape/ape.S + jnz _init_systemfive_metal +#endif #if SupportsFreebsd() testb $FREEBSD,(%rdi) # @see libc/crt/crt.S jnz _init_systemfive_freebsd @@ -222,7 +226,7 @@ systemfive_xnu: lea 2(%eax),%eax jnz 0b #endif -#if SupportsLinux() || SupportsMetal() +#if SupportsLinux() _init_systemfive_linux: pushb systemfive_linux-.Lanchorpoint push $LINUX @@ -236,6 +240,13 @@ _init_systemfive_metal: ezlea syscon_linux,si jmp _init_systemfive_os #endif +#if SupportsUefi() +_init_systemfive_uefi: + pushb systemfive_linux-.Lanchorpoint + push $UEFI + ezlea syscon_linux,si + jmp _init_systemfive_os +#endif #if SupportsWindows() _init_systemfive_windows: pushb systemfive_enosys-.Lanchorpoint @@ -312,8 +323,8 @@ _init_systemfive_magnums: // 𝑠𝑙𝑖𝑑𝑒 #if SupportsSystemv() && !defined(TINY) _init_systemfive_stack: # determinism ftw! -#if SupportsWindows() - testb IsWindows() # already did this +#if SupportsWindows() || SupportsMetal() || SupportsUefi() + testb $WINDOWS|METAL|UEFI,__hostos(%rip) jnz _init_systemfive_done #endif push %rdi @@ -403,7 +414,7 @@ syscon_end: .type syscon_end,@object .globl syscon_start .globl syscon_end -#if SupportsLinux() || SupportsMetal() +#if SupportsLinux() || SupportsMetal() || SupportsUefi() .section .sort.rodata.syscon.linux.1,"a",@progbits .align 1 syscon_linux:/* diff --git a/tool/viz/printansi.c b/tool/viz/printansi.c new file mode 100644 index 000000000..1d5f38f27 --- /dev/null +++ b/tool/viz/printansi.c @@ -0,0 +1,385 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/half.h" +#include "dsp/core/twixt8.h" +#include "dsp/scale/scale.h" +#include "dsp/tty/quant.h" +#include "dsp/tty/tty.h" +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/ioctl.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/struct/winsize.h" +#include "libc/dce.h" +#include "libc/fmt/conv.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/mem/mem.h" +#include "libc/rand/rand.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/ex.h" +#include "libc/sysv/consts/exit.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/madv.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/termios.h" +#include "libc/x/x.h" +#include "third_party/getopt/getopt.h" +#include "third_party/stb/stb_image.h" +#include "tool/viz/lib/graphic.h" + +#define SQR(x) ((x) * (x)) + +static struct Flags { + const char *out; + bool invert; + bool subpixel; + bool unsharp; + bool dither; + bool ruler; + bool trailingnewline; + long half; + bool full; + long width; + long height; + enum TtyBlocksSelection blocks; + enum TtyQuantizationAlgorithm quant; +} g_flags; + +static wontreturn void PrintUsage(int rc, FILE *f) { + fprintf(f, "Usage: %s%s", program_invocation_name, "\ + [FLAGS] [PATH]\n\ +\n\ +FLAGS\n\ +\n\ + -w INT width\n\ + -h INT height\n\ + -i invert\n\ + -? shows this information\n\ +\n\ +EXAMPLES\n\ +\n\ + printansi.com -w80 -h40 logo.png\n\ +\n\ +\n"); + exit(rc); +} + +static int ParseNumberOption(const char *arg) { + long x; + x = strtol(arg, NULL, 0); + if (!(1 <= x && x <= INT_MAX)) { + fprintf(stderr, "invalid flexidecimal: %s\n\n", arg); + exit(EXIT_FAILURE); + } + return x; +} + +static void GetOpts(int *argc, char *argv[]) { + int opt; + struct winsize ws; + g_flags.quant = kTtyQuantTrue; + g_flags.blocks = IsWindows() ? kTtyBlocksCp437 : kTtyBlocksUnicode; + if (*argc == 2 && + (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-help") == 0)) { + PrintUsage(EXIT_SUCCESS, stdout); + } + while ((opt = getopt(*argc, argv, "?ivpfrtxads234o:w:h:")) != -1) { + switch (opt) { + case 'o': + g_flags.out = optarg; + break; + case 'd': + g_flags.dither = true; + break; + case 's': + g_flags.unsharp = true; + break; + case 'w': + g_flags.trailingnewline = true; + g_flags.width = ParseNumberOption(optarg); + break; + case 'h': + g_flags.trailingnewline = true; + g_flags.height = ParseNumberOption(optarg); + break; + case 'f': + g_flags.full = true; + break; + case 'i': + g_flags.invert = true; + break; + case '2': + g_flags.half = true; + break; + case 'r': + g_flags.ruler = true; + break; + case 'p': + g_flags.subpixel = true; + break; + case 'a': + g_flags.quant = kTtyQuantAnsi; + break; + case 'x': + g_flags.quant = kTtyQuantXterm256; + break; + case 't': + g_flags.quant = kTtyQuantTrue; + break; + case '3': + g_flags.blocks = kTtyBlocksCp437; + break; + case '4': + g_flags.blocks = kTtyBlocksUnicode; + break; + case 'v': + ++g_loglevel; + break; + case '?': + PrintUsage(EXIT_SUCCESS, stdout); + default: + PrintUsage(EX_USAGE, stderr); + } + } + if (optind == *argc) { + if (!g_flags.out) g_flags.out = "-"; + argv[(*argc)++] = "-"; + } + if (!g_flags.full && (!g_flags.width || !g_flags.width)) { + ws.ws_col = 80; + ws.ws_row = 24; + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) != -1 || + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) { + g_flags.width = ws.ws_col * (1 + !g_flags.half); + g_flags.height = ws.ws_row * 2; + } + } + ttyquantsetup(g_flags.quant, kTtyQuantRgb, g_flags.blocks); +} + +static unsigned char ChessBoard(unsigned y, unsigned x, unsigned char a, + unsigned char b) { + return !((y ^ x) & (1u << 2)) ? a : b; +} + +static unsigned char AlphaBackground(unsigned y, unsigned x) { + return ChessBoard(y, x, 255, 200); +} + +static void *Deblinterlace(long dyn, long dxn, unsigned char dst[3][dyn][dxn], + long syn, long sxn, long scn, + const unsigned char src[syn][sxn][scn], long y0, + long yn, long x0, long xn) { + long y, x; + unsigned char c; + for (y = y0; y < yn; ++y) { + for (x = x0; x < xn; ++x) { + switch (scn) { + case 1: + c = src[y][x][0]; + dst[0][y][x] = c; + dst[1][y][x] = c; + dst[2][y][x] = c; + break; + case 2: + c = twixt8(AlphaBackground(y, x), src[y][x][0], src[y][x][1]); + dst[0][y][x] = c; + dst[1][y][x] = c; + dst[2][y][x] = c; + break; + case 3: + dst[0][y][x] = src[y][x][0]; + dst[1][y][x] = src[y][x][1]; + dst[2][y][x] = src[y][x][2]; + break; + case 4: + c = AlphaBackground(y, x); + dst[0][y][x] = twixt8(c, src[y][x][0], src[y][x][3]); + dst[1][y][x] = twixt8(c, src[y][x][1], src[y][x][3]); + dst[2][y][x] = twixt8(c, src[y][x][2], src[y][x][3]); + break; + } + } + } + return dst; +} + +static void *DeblinterlaceSubpixelBgr(long dyn, long dxn, + unsigned char dst[3][dyn][dxn][3], + long syn, long sxn, + const unsigned char src[syn][sxn][4], + long y0, long yn, long x0, long xn) { + long y, x; + for (y = y0; y < yn; ++y) { + for (x = x0; x < xn; ++x) { + dst[0][y][x][0] = 0; + dst[1][y][x][0] = 0; + dst[2][y][x][0] = src[y][x][2]; + dst[0][y][x][1] = 0; + dst[1][y][x][1] = src[y][x][1]; + dst[2][y][x][1] = 0; + dst[0][y][x][2] = src[y][x][0]; + dst[1][y][x][2] = 0; + dst[2][y][x][2] = 0; + } + } + return dst; +} + +struct Block { + char16_t c; + unsigned char b[4][2]; +} kBlocks[] = { + {u' ', {{0000, 0000}, {0000, 0000}, {0000, 0000}, {0000, 0000}}}, // + {u'░', {{0060, 0060}, {0060, 0060}, {0060, 0060}, {0060, 0060}}}, // + {u'▒', {{0140, 0140}, {0140, 0140}, {0140, 0140}, {0140, 0140}}}, // + {u'▓', {{0300, 0300}, {0300, 0300}, {0300, 0300}, {0300, 0300}}}, // + {u'█', {{0377, 0377}, {0377, 0377}, {0377, 0377}, {0377, 0377}}}, // + {u'▄', {{0000, 0000}, {0000, 0000}, {0377, 0377}, {0377, 0377}}}, // + {u'▌', {{0377, 0000}, {0377, 0000}, {0377, 0000}, {0377, 0000}}}, // + {u'▐', {{0000, 0377}, {0000, 0377}, {0000, 0377}, {0000, 0377}}}, // + {u'▀', {{0377, 0377}, {0377, 0377}, {0000, 0000}, {0000, 0000}}}, // +}; + +static void *Raster(long yn, long xn, unsigned char Y[yn][xn]) { + long y, x, i, j, k, s, bi, bs; + for (y = 0; y + 4 <= yn; y += 4) { + if (y) fputc('\n', stdout); + for (x = 0; x + 2 <= xn; x += 2) { + bi = 0; + bs = LONG_MAX; + for (k = 0; k < ARRAYLEN(kBlocks); ++k) { + s = 0; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 2; ++j) { + s += SQR(Y[y + i][x + j] - kBlocks[k].b[i][j]); + } + } + if (s < bs) { + bi = k; + bs = s; + } + } + fputwc(kBlocks[bi].c, stdout); + } + } + fputc('\n', stdout); + return Y; +} + +static void *Invert(long yn, long xn, unsigned char Y[yn][xn]) { + long y, x; + if (!g_flags.invert) { + for (y = 0; y < yn; ++y) { + for (x = 0; x < xn; ++x) { + Y[y][x] = 255 - Y[y][x]; + } + } + } + return Y; +} + +static void *Grayify(long yn, long xn, unsigned char Y[yn][xn], + const unsigned char RGB[3][yn][xn]) { + long y, x; + for (y = 0; y < yn; ++y) { + for (x = 0; x < xn; ++x) { + Y[y][x] = RGB[0][y][x] * .299 + RGB[1][y][x] * .587 + RGB[2][y][x] * .114; + } + } + return Y; +} + +static void ProcessImage(long yn, long xn, unsigned char RGB[3][yn][xn]) { + Raster(yn, xn, + Invert(yn, xn, Grayify(yn, xn, gc(memalign(32, yn * xn)), RGB))); +} + +void WithImageFile(const char *path, + void fn(long yn, long xn, unsigned char RGB[3][yn][xn])) { + struct stat st; + void *map, *data, *data2; + int fd, yn, xn, cn, dyn, dxn, syn, sxn; + CHECK_NE(-1, (fd = open(path, O_RDONLY)), "%s", path); + CHECK_NE(-1, fstat(fd, &st)); + CHECK_GT(st.st_size, 0); + CHECK_LE(st.st_size, INT_MAX); + fadvise(fd, 0, 0, MADV_WILLNEED | MADV_SEQUENTIAL); + CHECK_NE(MAP_FAILED, + (map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0))); + CHECK_NOTNULL( + (data = gc(stbi_load_from_memory(map, st.st_size, &xn, &yn, &cn, 0))), + "%s", path); + CHECK_NE(-1, munmap(map, st.st_size)); + CHECK_NE(-1, close(fd)); + if (g_flags.subpixel) { + data = DeblinterlaceSubpixelBgr(yn, xn, gc(memalign(32, yn * xn * 4 * 3)), + yn, xn, data, 0, yn, 0, xn); + xn *= 3; + } else { + data = Deblinterlace(yn, xn, gc(memalign(32, yn * xn * 4)), yn, xn, cn, + data, 0, yn, 0, xn); + cn = 3; + } + if (g_flags.height && g_flags.width) { + syn = yn; + sxn = xn; + dyn = g_flags.height * 4; + dxn = g_flags.width * 2; + while (HALF(syn) > dyn || HALF(sxn) > dxn) { + if (HALF(sxn) > dxn) { + Magikarp2xX(yn, xn, data, syn, sxn); + Magikarp2xX(yn, xn, (char *)data + yn * xn, syn, sxn); + Magikarp2xX(yn, xn, (char *)data + yn * xn * 2, syn, sxn); + sxn = HALF(sxn); + } + if (HALF(syn) > dyn) { + Magikarp2xY(yn, xn, data, syn, sxn); + Magikarp2xY(yn, xn, (char *)data + yn * xn, syn, sxn); + Magikarp2xY(yn, xn, (char *)data + yn * xn * 2, syn, sxn); + syn = HALF(syn); + } + } + data = EzGyarados(3, dyn, dxn, gc(memalign(32, dyn * dxn * 3)), cn, yn, xn, + data, 0, cn, dyn, dxn, syn, sxn, 0, 0, 0, 0); + yn = dyn; + xn = dxn; + } + fn(yn, xn, data); +} + +int main(int argc, char *argv[]) { + int i; + GetOpts(&argc, argv); + stbi_set_unpremultiply_on_load(true); + for (i = optind; i < argc; ++i) { + WithImageFile(argv[i], ProcessImage); + } + return 0; +}