diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 19f213496..970f7da45 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -15,7 +15,7 @@ "alignas(x)", "alignof(x)", "artificial=", - "nodiscard=", + "dontdiscard=", "mayalias=", "forceinline=", "forcealign(x)=", @@ -48,7 +48,7 @@ "nosideeffect=", "unreachable=", "thatispacked=", - "nothrow=", + "dontthrow=", "nocallback=", "relegated=", "hidden=", diff --git a/Makefile b/Makefile index 1e9d4180c..2c29072ff 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ # # # basic debugging # make -j8 -O MODE=dbg o/dbg/examples/crashreport.com -# o/dbg/examples/crashreport.com +# o/examples/crashreport.com # less examples/crashreport.c # # # extremely tiny binaries @@ -60,7 +60,7 @@ # build/config.mk SHELL = /bin/sh -HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win7 win10 +HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 win7 win10 xnu SANITY := $(shell build/sanitycheck $$PPID) .SUFFIXES: @@ -69,7 +69,10 @@ SANITY := $(shell build/sanitycheck $$PPID) .PHONY: all o bins check test depend tags all: o -o: o/$(MODE)/ape \ +o: o/$(MODE) + +o/$(MODE): \ + o/$(MODE)/ape \ o/$(MODE)/dsp \ o/$(MODE)/net \ o/$(MODE)/libc \ @@ -108,13 +111,13 @@ include libc/rand/rand.mk # │ include libc/unicode/unicode.mk # │ include third_party/dlmalloc/dlmalloc.mk #─┘ include libc/mem/mem.mk #─┐ -include libc/ohmyplus/ohmyplus.mk # ├──DYNAMIC RUNTIME -include libc/zipos/zipos.mk # │ You can now use stdio -include third_party/gdtoa/gdtoa.mk # │ You can finally call malloc() -include libc/time/time.mk # │ +include libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME +include third_party/gdtoa/gdtoa.mk # │ You can now use stdio +include libc/time/time.mk # │ You can finally call malloc() +include libc/thread/thread.mk # │ include libc/alg/alg.mk # │ include libc/stdio/stdio.mk # │ -include libc/thread/thread.mk # │ +include third_party/libcxx/libcxx.mk # │ include net/net.mk # │ include libc/log/log.mk # │ include third_party/bzip2/bzip2.mk # │ @@ -138,14 +141,16 @@ include third_party/third_party.mk include libc/testlib/testlib.mk include tool/viz/lib/vizlib.mk include third_party/linenoise/linenoise.mk +include third_party/maxmind/maxmind.mk include third_party/lua/lua.mk include third_party/make/make.mk include third_party/argon2/argon2.mk +include third_party/smallz4/smallz4.mk include third_party/sqlite3/sqlite3.mk include third_party/mbedtls/test/test.mk include third_party/quickjs/quickjs.mk include third_party/lz4cli/lz4cli.mk -include third_party/infozip/infozip.mk +include third_party/zip/zip.mk include tool/build/lib/buildlib.mk include third_party/chibicc/chibicc.mk include third_party/chibicc/test/test.mk @@ -157,6 +162,11 @@ include examples/examples.mk include examples/pyapp/pyapp.mk include tool/decode/lib/decodelib.mk include tool/decode/decode.mk +include tool/lambda/lib/lib.mk +include tool/lambda/lambda.mk +include tool/plinko/lib/lib.mk +include tool/plinko/plinko.mk +include test/tool/plinko/test.mk include tool/hash/hash.mk include tool/net/net.mk include tool/viz/viz.mk @@ -167,6 +177,7 @@ include test/libc/intrin/test.mk include test/libc/mem/test.mk include test/libc/nexgen32e/test.mk include test/libc/runtime/test.mk +include test/libc/thread/test.mk include test/libc/sock/test.mk include test/libc/bits/test.mk include test/libc/str/test.mk @@ -210,7 +221,7 @@ CHECKS = $(foreach x,$(PKGS),$($(x)_CHECKS)) bins: $(BINS) check: $(CHECKS) -test: $(TESTS) all +test: $(TESTS) depend: o/$(MODE)/depend tags: TAGS HTAGS @@ -249,7 +260,6 @@ COSMOPOLITAN_OBJECTS = \ LIBC_NT_WS2_32 \ LIBC_NT_IPHLPAPI \ LIBC_NT_MSWSOCK \ - LIBC_OHMYPLUS \ LIBC_X \ THIRD_PARTY_GETOPT \ LIBC_LOG \ @@ -270,7 +280,9 @@ COSMOPOLITAN_OBJECTS = \ LIBC_CALLS \ LIBC_RAND \ LIBC_SYSV_CALLS \ - LIBC_NT_KERNELBASE \ + LIBC_NT_PSAPI \ + LIBC_NT_POWRPROF \ + LIBC_NT_PDH \ LIBC_NT_SHELL32 \ LIBC_NT_GDI32 \ LIBC_NT_COMDLG32 \ @@ -283,6 +295,7 @@ COSMOPOLITAN_OBJECTS = \ THIRD_PARTY_COMPILER_RT \ LIBC_THREAD \ LIBC_TINYMATH \ + THIRD_PARTY_XED \ LIBC_STR \ LIBC_SYSV \ LIBC_INTRIN \ @@ -302,11 +315,11 @@ COSMOPOLITAN_HEADERS = \ LIBC_MEM \ LIBC_NEXGEN32E \ LIBC_NT \ - LIBC_OHMYPLUS \ LIBC_RAND \ LIBC_RUNTIME \ LIBC_SOCK \ LIBC_STDIO \ + THIRD_PARTY_XED \ LIBC_STR \ LIBC_SYSV \ LIBC_THREAD \ diff --git a/README.md b/README.md index 9a3a231a2..2e8477863 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ If you're doing your development work on Linux or BSD then you need just five files to get started. Here's what you do on Linux: ```sh -wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-1.0.zip -unzip cosmopolitan-amalgamation-1.0.zip +wget https://justine.lol/cosmopolitan/cosmopolitan.zip +unzip cosmopolitan.zip printf 'main() { printf("hello world\\n"); }\n' >hello.c gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \ -fno-omit-frame-pointer -pg -mnop-mcount \ @@ -72,14 +72,45 @@ repository that bootstraps using a vendored static gcc9 executable. No further dependencies are required. ```sh -wget https://justine.lol/cosmopolitan/cosmopolitan-1.0.tar.gz -tar xf cosmopolitan-1.0.tar.gz # see releases page +wget https://justine.lol/cosmopolitan/cosmopolitan.tar.gz +tar xf cosmopolitan.tar.gz # see releases page cd cosmopolitan make -j16 o//examples/hello.com find o -name \*.com | xargs ls -rShal | less ``` +## GDB + +Here's the recommended `~/.gdbinit` config: + +``` +set host-charset UTF-8 +set target-charset UTF-8 +set target-wide-charset UTF-8 +set osabi none +set complaints 0 +set confirm off +set history save on +set history filename ~/.gdb_history +define asm + layout asm + layout reg +end +define src + layout src + layout reg +end +src +``` + +You normally run the `.com.dbg` file under gdb. If you need to debug the +`.com` file itself, then you can load the debug symbols independently as + +``` +gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000' +``` + ## Support Vector | Platform | Min Version | Circa | diff --git a/ape/ape.S b/ape/ape.S index f816582d0..48e25aaae 100644 --- a/ape/ape.S +++ b/ape/ape.S @@ -660,6 +660,7 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang #if SupportsSystemv() || SupportsMetal() .section .elf.phdrs,"a",@progbits + .long PT_LOAD .long PF_R|PF_X .stub ape_rom_offset,quad @@ -668,6 +669,7 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang .stub ape_rom_filesz,quad .stub ape_rom_memsz,quad .stub ape_rom_align,quad + .long PT_LOAD .long PF_R|PF_W .stub ape_ram_offset,quad @@ -676,14 +678,32 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang .stub ape_ram_filesz,quad .stub ape_ram_memsz,quad .stub ape_ram_align,quad + +// APE Stack Configuration +// +// We actually respect this when allocating a deterministically +// addressed stack on Windows and other operating systems. However +// there's a few caveats: +// +// - If ape_stack_pf has PF_X then OpenBSD probably won't work +// - We don't bother creating a deterministic stack in MODE=tiny +// +// With that said, here's some examples of configuration: +// +// STATIC_SYMBOL("ape_stack_pf", "7"); // RWX +// STATIC_STACK_ADDR(0x6fffffff0000); +// STATIC_STACK_SIZE(65536); +// +// @see ape.lds for defaults .long PT_GNU_STACK - .long PF_R|PF_W - .stub ape_stack_offset,quad - .stub ape_stack_vaddr,quad - .stub ape_stack_paddr,quad - .stub ape_stack_filesz,quad - .stub ape_stack_memsz,quad - .stub ape_stack_align,quad + .stub ape_stack_pf,long # override w/ PF_X for execstack + .stub ape_stack_offset,quad # ignored + .stub ape_stack_vaddr,quad # is mmap()'d with MAP_FIXED + .stub ape_stack_paddr,quad # ignored + .stub ape_stack_filesz,quad # ignored + .stub ape_stack_memsz,quad # is mmap(size) argument + .stub ape_stack_align,quad # must be 16+ + #if SupportsOpenbsd() || SupportsNetbsd() .long PT_NOTE .long PF_R @@ -1070,18 +1090,12 @@ str.error: str.crlf: .asciz "\r\n" .endobj str.crlf -str.cpuid: - .asciz "cpuid" - .endobj str.cpuid -str.oldskool: - .asciz "oldskool" - .endobj str.oldskool str.e820: .asciz "e820" .endobj str.e820 -str.long: - .asciz "nolong" - .endobj str.long +str.oldcpu: + .asciz "oldcpu" + .endobj str.oldcpu // Serial Line Configuration (8250 UART 16550) // If it's hacked, it'll at least get hacked very slowly. @@ -1264,7 +1278,7 @@ longmodeloader: lcheck: pushf # check for i8086 / i8088 / i80186 pop %ax test $0x80,%ah # see intel manual volume 1 20.1.2 - jnz 9f # we now assume 32bit is supported + jnz 10f # we now assume 32bit is supported pushfl # now check for i386 or early i486 pop %eax # test ability to change cpuid bit mov %eax,%ecx @@ -1275,7 +1289,7 @@ lcheck: pushf # check for i8086 / i8088 / i80186 pushfl pop %eax cmp %eax,%ecx - je 12f # we assume cpuid inst is available + je 10f # we assume cpuid inst is available or %ebx,%eax # puts cpuid bit in the on position push %eax popfl @@ -1293,11 +1307,7 @@ lcheck: pushf # check for i8086 / i8088 / i80186 jne 10f xor %ax,%ax 1: ret -9: mov $REAL(str.oldskool),%di - jmp 20f -10: mov $REAL(str.long),%di - jmp 20f -12: mov $REAL(str.cpuid),%di +10: mov $REAL(str.oldcpu),%di 20: call rldie .endfn lcheck @@ -1615,5 +1625,26 @@ ape_idata_ro: __data_start: .previous + .section .dataepilogue,"aw",@progbits + .type __data_end,@object + .globl __data_end + .hidden __data_end +__data_end: + .previous + + .section .bssprologue,"aw",@nobits + .type __bss_start,@object + .globl __bss_start + .hidden __bss_start +__bss_start: + .previous + + .section .bssepilogue,"aw",@nobits + .type __bss_end,@object + .globl __bss_end + .hidden __bss_end +__bss_end: + .previous + .end  \ No newline at end of file diff --git a/ape/ape.lds b/ape/ape.lds index ac41b1bc5..caac90617 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -177,6 +177,8 @@ #include "ape/macros.internal.h" #include "ape/relocations.h" #include "libc/dce.h" +#include "libc/elf/def.h" +#include "libc/elf/pf2prot.internal.h" #include "libc/nt/pedef.internal.h" #include "libc/zip.h" @@ -342,7 +344,7 @@ SECTIONS { /*END: Read Only Data (only needed for initialization) */ /*END: Read Only Data */ } :Rom - + .tdata . : { _tdata_start = .; *(SORT_BY_ALIGNMENT(.tdata)) @@ -358,6 +360,8 @@ SECTIONS { .data . : { /*BEGIN: Read/Write Data */ + KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*))) +/*BEGIN: NT FORK COPYING */ KEEP(*(.dataprologue)) *(.data .data.*) KEEP(*(SORT_BY_NAME(.sort.data.*))) @@ -378,6 +382,8 @@ SECTIONS { . = ALIGN(__SIZEOF_POINTER__); KEEP(*(SORT_BY_NAME(.piro.data.sort.*))) KEEP(*(.piro.pad.data)) + KEEP(*(.dataepilogue)) +/*END: NT FORK COPYING */ . = ALIGN(PAGESIZE); HIDDEN(_edata = .); PROVIDE_HIDDEN(edata = .); @@ -404,6 +410,8 @@ SECTIONS { /*BEGIN: bss memory that's addressable */ .bss ALIGN(64) : { +/*BEGIN: NT FORK COPYING */ + KEEP(*(.bssprologue)) KEEP(*(SORT_BY_NAME(.piro.bss.init.*))) *(.piro.bss) KEEP(*(SORT_BY_NAME(.piro.bss.sort.*))) @@ -418,6 +426,8 @@ SECTIONS { KEEP(*(SORT_BY_NAME(.sort.bss.*))) + KEEP(*(.bssepilogue)) +/*END: NT FORK COPYING */ . = ALIGN(FRAMESIZE); /* for brk()/sbrk() allocation */ HIDDEN(_end = .); PROVIDE_HIDDEN(end = .); @@ -477,9 +487,9 @@ PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56); PFSTUB4(ape_elf_shnum, 0); PFSTUB4(ape_elf_shstrndx, 0); -HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE)); +HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE)); HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) - - ROUNDDOWN(__privileged_start, PAGESIZE))); + ROUNDDOWN(__privileged_start, PAGESIZE))); HIDDEN(ape_rom_offset = 0); HIDDEN(ape_rom_vaddr = ADDR(.head)); @@ -497,6 +507,8 @@ HIDDEN(ape_ram_memsz = ADDR(.bss) + SIZEOF(.bss) - ape_ram_vaddr); HIDDEN(ape_ram_align = PAGESIZE); HIDDEN(ape_ram_rva = RVA(ape_ram_vaddr)); +HIDDEN(ape_stack_pf = DEFINED(ape_stack_pf) ? ape_stack_pf : PF_R | PF_W); +HIDDEN(ape_stack_prot = _PF2PROT(ape_stack_pf)); HIDDEN(ape_stack_offset = ape_ram_offset + ape_ram_filesz); HIDDEN(ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x700000000000 - STACKSIZE); HIDDEN(ape_stack_paddr = ape_ram_paddr + ape_ram_filesz); diff --git a/build/bootstrap/ar.com b/build/bootstrap/ar.com index 7e7731355..90bd84a8f 100755 Binary files a/build/bootstrap/ar.com and b/build/bootstrap/ar.com differ diff --git a/build/bootstrap/compile.com b/build/bootstrap/compile.com index 7e8a6e705..df9521d24 100755 Binary files a/build/bootstrap/compile.com and b/build/bootstrap/compile.com differ diff --git a/build/bootstrap/mkdeps.com b/build/bootstrap/mkdeps.com index 92a6b88a7..9b9e0cc16 100755 Binary files a/build/bootstrap/mkdeps.com and b/build/bootstrap/mkdeps.com differ diff --git a/build/bootstrap/package.com b/build/bootstrap/package.com index 4266ab544..285af9e64 100755 Binary files a/build/bootstrap/package.com and b/build/bootstrap/package.com differ diff --git a/build/bootstrap/zipobj.com b/build/bootstrap/zipobj.com index e0bb49481..1980a9018 100755 Binary files a/build/bootstrap/zipobj.com and b/build/bootstrap/zipobj.com differ diff --git a/build/config.mk b/build/config.mk index f2b48affa..5039164fb 100644 --- a/build/config.mk +++ b/build/config.mk @@ -5,6 +5,7 @@ # # - `make` # - Backtraces +# - Syscall tracing # - Function tracing # - Reasonably small # - Reasonably optimized @@ -13,6 +14,7 @@ ifeq ($(MODE),) CONFIG_CCFLAGS += \ $(BACKTRACES) \ $(FTRACE) \ + -DSYSDEBUG \ -Og TARGET_ARCH ?= \ -msse3 @@ -23,6 +25,8 @@ endif # - `make MODE=opt` # - Backtraces # - More optimized +# - Syscall tracing +# - Function tracing # - Reasonably small # - No memory corruption detection # - assert() / CHECK_xx() may leak code into binary for debuggability @@ -35,7 +39,9 @@ CONFIG_CPPFLAGS += \ CONFIG_CCFLAGS += \ $(BACKTRACES) \ $(FTRACE) \ - -O3 + -DSYSDEBUG \ + -O3 \ + -fmerge-all-constants TARGET_ARCH ?= \ -march=native endif @@ -55,7 +61,7 @@ CONFIG_CPPFLAGS += \ -Wa,-msse2avx \ -DSUPPORT_VECTOR=1 CONFIG_CCFLAGS += \ - -O3 + -O3 -fmerge-all-constants DEFAULT_COPTS += \ -mred-zone TARGET_ARCH ?= \ @@ -122,10 +128,12 @@ CONFIG_CPPFLAGS += \ CONFIG_CCFLAGS += \ $(BACKTRACES) \ $(FTRACE) \ + -DSYSDEBUG \ -O2 \ -fno-inline CONFIG_COPTS += \ - -fsanitize=address + -fsanitize=address \ + -fsanitize=undefined TARGET_ARCH ?= \ -msse3 OVERRIDE_CCFLAGS += \ @@ -287,7 +295,7 @@ endif # LLVM Mode ifeq ($(MODE), llvm) TARGET_ARCH ?= -msse3 -CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2 +CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -DSYSDEBUG -O2 AS = clang CC = clang CXX = clang++ diff --git a/build/definitions.mk b/build/definitions.mk index 005cf546f..cfb7eafe8 100644 --- a/build/definitions.mk +++ b/build/definitions.mk @@ -100,7 +100,8 @@ SANITIZER = \ NO_MAGIC = \ -mno-fentry \ -fno-stack-protector \ - -fwrapv + -fwrapv \ + -fno-sanitize=all OLD_CODE = \ -fno-strict-aliasing \ @@ -148,7 +149,6 @@ DEFAULT_CFLAGS = \ -std=gnu2x DEFAULT_CXXFLAGS = \ - -std=gnu++11 \ -fno-rtti \ -fno-exceptions \ -fuse-cxa-atexit \ @@ -169,7 +169,7 @@ DEFAULT_LDFLAGS = \ --gc-sections \ --build-id=none \ --no-dynamic-linker \ - -zmax-page-size=0x1000 + -zmax-page-size=0x1000 #--cref -Map=$@.map ZIPOBJ_FLAGS = \ -b$(IMAGE_BASE_VIRTUAL) @@ -301,6 +301,9 @@ OBJECTIFY.greg.c = \ -fno-instrument-functions \ -fno-optimize-sibling-calls \ -fno-sanitize=all \ + -ffreestanding \ + -mno-fentry \ + -fwrapv \ -c OBJECTIFY.ansi.c = $(CC) $(OBJECTIFY.c.flags) -ansi -Wextra -Werror -pedantic-errors -c diff --git a/build/htags b/build/htags index 401097cdc..b5957145f 100755 --- a/build/htags +++ b/build/htags @@ -48,7 +48,7 @@ set -- --regex-c='/^\(\(hidden\|extern\|const\) \)*[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)/\4/b' "$@" # ctags doesn't understand function prototypes, e.g. -# bool isheap(void *p) nothrow nocallback; +# bool isheap(void *p) dontthrow nocallback; set -- --regex-c='/^[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)(.*/\2/b' "$@" # ctags doesn't understand function pointers, e.g. diff --git a/build/rules.mk b/build/rules.mk index 554d958da..34c2359c8 100644 --- a/build/rules.mk +++ b/build/rules.mk @@ -31,7 +31,7 @@ o/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) o/%.inc: %.h ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $< o/%.pkg: ; @$(COMPILE) -APACKAGE -T$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^) o/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -xc -g0 -o $@ $< -o/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $< +o/%.okk: % ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $< o/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< o/%.zip.o: o/% ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $< @@ -60,7 +60,8 @@ o/$(MODE)/%.o: %.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx o/$(MODE)/%.o: o/$(MODE)/%.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< o/$(MODE)/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $< o/$(MODE)/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -xc -g0 -o $@ $< -o/$(MODE)/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $< +o/$(MODE)/%.hh.ok: %.hh ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $< +o/$(MODE)/%.okk: % ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $< o/$(MODE)/%.cxx.o: %.c ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) -xc++ $(OUTPUT_OPTION) $< o/$(MODE)/%.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< o/$(MODE)/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< @@ -77,7 +78,9 @@ o/$(MODE)/%.runs: o/$(MODE)/% ; @$(COMPILE) -ACHECK -tT$@ $< $(TESTARGS) o/$(MODE)/%.pkg: ; @$(COMPILE) -APACKAGE -T$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^) o/$(MODE)/%.zip.o: % ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $< o/$(MODE)/%-gcc.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< +o/$(MODE)/%-gcc.asm: %.cc ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $< o/$(MODE)/%-clang.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< +o/$(MODE)/%-clang.asm: %.cc ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $< o/$(MODE)/%-clang.asm: CC = $(CLANG) o/%.a: diff --git a/dsp/core/sad16x8n.S b/dsp/core/sad16x8n.S index 280ce3ccd..4eba76f63 100644 --- a/dsp/core/sad16x8n.S +++ b/dsp/core/sad16x8n.S @@ -37,4 +37,3 @@ sad16x8n: jnz 0b 1: .leafepilogue .endfn sad16x8n,globl,hidden - .source __FILE__ diff --git a/dsp/mpeg/clamp4int256-core.S b/dsp/mpeg/clamp4int256-core.S index 92e8fb6be..04dd3aba2 100644 --- a/dsp/mpeg/clamp4int256-core.S +++ b/dsp/mpeg/clamp4int256-core.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ clamp4int256$core: .leafprologue diff --git a/dsp/mpeg/mpeg1.c b/dsp/mpeg/mpeg1.c index 6a8471088..e3830207e 100644 --- a/dsp/mpeg/mpeg1.c +++ b/dsp/mpeg/mpeg1.c @@ -72,7 +72,8 @@ static const float PLM_VIDEO_PIXEL_ASPECT_RATIO[] = { 0.6735, /* 3:4? */ 0.7031, /* MPEG-1 / MPEG-2 video encoding divergence? */ 0.7615, 0.8055, 0.8437, 0.8935, 0.9157, 0.9815, - 1.0255, 1.0695, 1.0950, 1.1575, 1.2051}; + 1.0255, 1.0695, 1.0950, 1.1575, 1.2051, +}; static const float PLM_VIDEO_PICTURE_RATE[] = { 23.976, /* NTSC-Film */ diff --git a/dsp/scale/gyarados.c b/dsp/scale/gyarados.c index f996378ce..5367ce4e0 100644 --- a/dsp/scale/gyarados.c +++ b/dsp/scale/gyarados.c @@ -101,7 +101,7 @@ struct SamplingSolution *ComputeSamplingSolution(long dn, long sn, double dar, if (!off) off = (dar - 1) / 2; f = dar < 1 ? 1 / dar : dar; s = 3 * f + 4; - fweights = gc(xcalloc(s, sizeof(double))); + fweights = gc(xcalloc(s + /*xxx*/ 2, sizeof(double))); res = NewSamplingSolution(dn, s); weights = res->weights; indices = res->indices; diff --git a/dsp/tty/hidecursor.c b/dsp/tty/hidecursor.c index b5dfa8950..50f5addeb 100644 --- a/dsp/tty/hidecursor.c +++ b/dsp/tty/hidecursor.c @@ -19,6 +19,7 @@ #include "dsp/tty/tty.h" #include "libc/bits/pushpop.h" #include "libc/dce.h" +#include "libc/log/internal.h" #include "libc/log/log.h" #include "libc/nt/console.h" #include "libc/nt/runtime.h" @@ -30,7 +31,7 @@ static int ttysetcursor(int fd, bool visible) { struct NtConsoleCursorInfo ntcursor; char code[8] = "\e[?25l"; - if (IsTerminalInarticulate()) return 0; + if (__nocolor) return 0; if (visible) code[5] = 'h'; if (SupportsWindows()) { GetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor); diff --git a/dsp/tty/setraw.c b/dsp/tty/setraw.c index 72eb4a36b..6d2b8d273 100644 --- a/dsp/tty/setraw.c +++ b/dsp/tty/setraw.c @@ -31,13 +31,6 @@ int ttysetraw(struct termios *conf, int64_t flags) { conf->c_cflag &= ~(CSIZE | PARENB); conf->c_cflag |= CS8; conf->c_iflag |= IUTF8; - /* if (flags & kTtyLfToCrLf) { */ - /* /\* conf->c_oflag &= ~(OLCUC | OCRNL | ONLRET | OFILL | OFDEL); *\/ */ - /* /\* conf->c_oflag |= ONLCR | ONOCR; *\/ */ - /* conf->c_oflag |= ONLCR; */ - /* } else { */ - /* conf->c_oflag &= ~OPOST; */ - /* } */ if (!(flags & kTtySigs)) { conf->c_iflag &= ~(IGNBRK | BRKINT); conf->c_lflag &= ~(ISIG); diff --git a/dsp/tty/ttyraster.c b/dsp/tty/ttyraster.c index 51430b4eb..0e2f636dd 100644 --- a/dsp/tty/ttyraster.c +++ b/dsp/tty/ttyraster.c @@ -731,19 +731,19 @@ static bool ChunkEq(struct TtyRgb c[hasatleast 4], } static struct TtyRgb *CopyChunk(struct TtyRgb chunk[hasatleast 4], - const struct TtyRgb *c, size_t n) { - chunk[TL] = c[0 + 0]; - chunk[TR] = c[0 + 1]; - chunk[BL] = c[n + 0]; - chunk[BR] = c[n + 1]; + const struct TtyRgb *c, size_t xn) { + chunk[TL] = c[00 + 0]; + chunk[TR] = c[00 + 1]; + chunk[BL] = c[xn + 0]; + chunk[BR] = c[xn + 1]; return chunk; } static dontinline char *CopyRun(char *v, size_t n, - struct TtyRgb lastchunk[hasatleast 4], - const struct TtyRgb **c, size_t *x, - struct TtyRgb *bg, struct TtyRgb *fg, - struct Glyph *glyph) { + struct TtyRgb lastchunk[hasatleast 4], + const struct TtyRgb **c, size_t *x, + struct TtyRgb *bg, struct TtyRgb *fg, + struct Glyph *glyph) { struct TtyRgb chunk[4]; if (memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) { if (!ttyeq(*bg, *fg)) { @@ -766,17 +766,18 @@ static dontinline char *CopyRun(char *v, size_t n, /** * Maps 2×2 pixel chunks onto ANSI UNICODE cells. * @note h/t Nick Black for his quadrant blitting work on notcurses + * @note yn and xn need to be even */ -char *ttyraster(char *v, const struct TtyRgb *c, size_t yn, size_t n, +char *ttyraster(char *v, const struct TtyRgb *c, size_t yn, size_t xn, struct TtyRgb bg, struct TtyRgb fg) { unsigned y, x; struct Pick p; struct Glyph glyph; struct TtyRgb chun[4], lastchunk[4]; - for (y = 0; y < yn; y += 2, c += n) { + for (y = 0; y < yn; y += 2, c += xn) { if (y) *v++ = '\r', *v++ = '\n'; - for (x = 0; x < n; x += 2, c += 2) { - CopyChunk(chun, c, n); + for (x = 0; x < xn; x += 2, c += 2) { + CopyChunk(chun, c, xn); if (ttyquant()->alg == kTtyQuantTrue) { if (ttyquant()->blocks == kTtyBlocksCp437) { p = PickBlockCp437True(chun[TL], chun[TR], chun[BL], chun[BR]); diff --git a/dsp/tty/windex-avx2.S b/dsp/tty/windex-avx2.S index 77cbddf92..e9a14954c 100644 --- a/dsp/tty/windex-avx2.S +++ b/dsp/tty/windex-avx2.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns index of minimum uint16 in array. // diff --git a/dsp/tty/windex-sse4.S b/dsp/tty/windex-sse4.S index 93ff50ea4..f18a90c04 100644 --- a/dsp/tty/windex-sse4.S +++ b/dsp/tty/windex-sse4.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns index of minimum positive int16 in array. // diff --git a/dsp/tty/windex.S b/dsp/tty/windex.S index eeecba61a..df112ec85 100644 --- a/dsp/tty/windex.S +++ b/dsp/tty/windex.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/nexgen32e/x86feature.h" #include "libc/macros.internal.h" -.source __FILE__ // Dispatches to fastest windex() implementation. .initbss 300,_init_windex diff --git a/examples/auto-launch-gdb-on-crash.c b/examples/auto-launch-gdb-on-crash.c index 734b870ef..56c5d86c7 100644 --- a/examples/auto-launch-gdb-on-crash.c +++ b/examples/auto-launch-gdb-on-crash.c @@ -18,9 +18,12 @@ * make -j12 o//examples/auto-launch-gdb-on-crash.com * o//examples/auto-launch-gdb-on-crash.com * - * Backtrace is logged instead if run outside interactive terminal. - * Environmental factors such as GDB, MAKEFLAGS, ADDR2LINE, TERM, and - * isatty(STDERR_FILENO) should also be taken into consideration: + * Backtrace is logged instead if run outside interactive terminal. We + * also don't auto-launch GDB on non-Linux since the development tools + * on other platforms generally can't be relied upon to correctly debug + * binaries built with a Linux toolchain. Environmental factors such as + * GDB, MAKEFLAGS, ADDR2LINE, TERM, and isatty(STDERR_FILENO) should + * also be taken into consideration: * * $ export GDB=eoatuhshtuone * $ o//examples/auto-launch-gdb-on-crash.com @@ -37,7 +40,7 @@ */ int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); asm("int3"); /* cf. __die(), perror("msg"), abort(), exit(1), _Exit(1) */ return 0; } diff --git a/examples/auto-memory-safety-crash.c b/examples/auto-memory-safety-crash.c new file mode 100644 index 000000000..9d8253148 --- /dev/null +++ b/examples/auto-memory-safety-crash.c @@ -0,0 +1,62 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/log/log.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" + +/** + * ASAN static memory safety crash example. + * + * make -j8 MODE=dbg o/dbg/examples/auto-memory-safety-crash.com + * o/dbg/examples/auto-memory-safety-crash.com + * + * You should see: + * + * global redzone 1-byte store at 0x42700d shadow 0x8007ce01 + * ./o/dbg/examples/auto-memory-safety-crash.com + * x + * ........................................GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG + * |0 |0 |0 |0 |5 |-18 |-18 |-18 |-18 + *  f.☼▼ä     f.☼▼ä     f☼▼D  hello                                                 + * 000000400000-000000427000 .text + * 000000427000-000000429000 .data ←address + * 00007fff0000-00008000ffff + * 000080070000-00008008ffff ←shadow + * 0e007fff0000-0e008000ffff + * 100047d20000-100047d3ffff + * 6ffffffe0000-6fffffffffff + * the memory in question belongs to the symbols + * buffer [0x427000,0x42700c] size 13 + * the crash was caused by + * 0x00000000004046f3: __die at libc/log/die.c:40 + * 0x0000000000404aed: __asan_report_store at libc/intrin/asan.c:1183 + * 0x0000000000402552: main at examples/auto-memory-safety-crash.c:27 + * 0x000000000040268d: cosmo at libc/runtime/cosmo.S:64 + * 0x00000000004021ae: _start at libc/crt/crt.S:77 + * + * @see libc/intrin/asancodes.h for meaning of G, etc. and negative numbers + * @see libc/nexgen32e/kcp437.S for meaning of symbols + */ + +char buffer[13] = "hello"; + +int main(int argc, char *argv[]) { + if (!IsAsan()) { + printf("this example is intended for MODE=asan or MODE=dbg\n"); + exit(1); + } + ShowCrashReports(); /* not needed but yoinks appropriate symbols */ + int i = 13; + asm("" : "+r"(i)); /* prevent compiler being smart */ + buffer[i] = 1; + return 0; +} diff --git a/examples/auto-memory-safety-crash2.c b/examples/auto-memory-safety-crash2.c new file mode 100644 index 000000000..9525d52a9 --- /dev/null +++ b/examples/auto-memory-safety-crash2.c @@ -0,0 +1,74 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +/** + * ASAN heap memory safety crash example. + * + * make -j8 MODE=dbg o/dbg/examples/auto-memory-safety-crash2.com + * o/dbg/examples/auto-memory-safety-crash2.com + * + * You should see: + * + * heap overrun 1-byte store at 0x10008004002d shadow 0x20090000005 + * ./o/dbg/examples/auto-memory-safety-crash2.com + * x + * OOOOOOOOOOOUUUUUUUUUUUUUUUU.............OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO + * |-7 |-6 |-6 |0 |5 |-7 |-7 |-7 |-7 + *    »!@     ÿ▄:Y╩≥= S       hello ∙∙∙∙∙∙∙           ♪     GT◘&@     á+@     »!@   + * 000000400000-00000042b000 .text + * 00000042b000-00000042d000 .data + * 00007fff0000-00008000ffff + * 000080070000-00008008ffff + * 02008fff0000-02009000ffff ←shadow + * 0e007fff0000-0e008000ffff + * 10003ab90000-10003abaffff + * 100080000000-10008000ffff ←address + * 6ffffffe0000-6fffffffffff + * + * the memory was allocated by + * 0x100080040020 64 bytes [dlmalloc] + * 0x100080040030 13 bytes [actual] + * 402608 main + * 402ba0 cosmo + * 4021af _start + * + * the crash was caused by + * 0x0000000000404793: __die at libc/log/die.c:40 + * 0x0000000000404f56: __asan_report_store at libc/intrin/asan.c:1183 + * 0x0000000000402579: main at examples/auto-memory-safety-crash2.c:30 + * 0x000000000040270f: cosmo at libc/runtime/cosmo.S:64 + * 0x00000000004021ae: _start at libc/crt/crt.S:77 + * + * @see libc/intrin/asancodes.h for meaning of U, O, etc. and negative numbers + * @see libc/nexgen32e/kcp437.S for meaning of symbols + */ + +int main(int argc, char *argv[]) { + if (!IsAsan()) { + printf("this example is intended for MODE=asan or MODE=dbg\n"); + exit(1); + } + char *buffer; + ShowCrashReports(); /* not needed but yoinks appropriate symbols */ + buffer = malloc(13); + strcpy(buffer, "hello"); + int i = 13; + asm("" : "+r"(i)); /* prevent compiler being smart */ + buffer[i] = 1; + asm("" : "+r"(buffer)); /* prevent compiler being smart */ + return 0; +} diff --git a/examples/auto-memory-safety-crash3.c b/examples/auto-memory-safety-crash3.c new file mode 100644 index 000000000..b5730f976 --- /dev/null +++ b/examples/auto-memory-safety-crash3.c @@ -0,0 +1,39 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +/** + * ASAN use-after-free memory safety crash example. + * + * make -j8 MODE=dbg o/dbg/examples/auto-memory-safety-crash3.com + * o/dbg/examples/auto-memory-safety-crash3.com + * + */ + +int main(int argc, char *argv[]) { + if (!IsAsan()) { + printf("this example is intended for MODE=asan or MODE=dbg\n"); + exit(1); + } + char *buffer; + ShowCrashReports(); /* not needed but yoinks appropriate symbols */ + buffer = malloc(13); + strcpy(buffer, "hello"); + free(buffer); + asm("" : "+r"(buffer)); /* prevent compiler being smart */ + buffer[0] = 1; + return 0; +} diff --git a/examples/breakpoint.c b/examples/breakpoint.c index b3c639c11..c4de23644 100644 --- a/examples/breakpoint.c +++ b/examples/breakpoint.c @@ -7,19 +7,30 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif +#include "libc/intrin/kprintf.h" #include "libc/log/backtrace.internal.h" #include "libc/log/log.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" -#include "libc/stdio/stdio.h" int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); + if (IsDebuggerPresent(false)) { - printf("debugger found!\r\n"); - DebugBreak(); - return 0; + kprintf("debugger found!%n"); + } else { + kprintf("try running: gdb %s%n", argv[0]); + kprintf("try running: o//tool/build/strace.com %s%n", argv[0]); } - printf("try running: gdb %s\r\n", argv[0]); - return 1; + + asm volatile("mov\t%4,%%r10\n\t" + "mov\t%5,%%r8\n\t" + "mov\t%6,%%r9\n\t" + "int3" + : /* no outputs */ + : "a"(0), "D"(1), "S"(2), "d"(3), "g"(4), "g"(5), "g"(6) + : "r8", "r9", "r10"); + + printf("recovered from SIGTRAP without handler\r\n"); + return 0; } diff --git a/examples/cp.c b/examples/cp.c index 6a657545e..ddb4910c3 100644 --- a/examples/cp.c +++ b/examples/cp.c @@ -73,14 +73,14 @@ void GetOpts(int argc, char *argv[]) { int cp(const char *src, const char *dst) { if (endswith(dst, "/") || isdirectory(dst)) { - dst = _gc(xasprintf("%s/%s", dst, basename)); + dst = _gc(xasprintf("%s/%s", dst, basename(src))); } if (!force && access(dst, W_OK) == -1 && errno != ENOENT) goto OnFail; if (copyfile(src, dst, flags) == -1) goto OnFail; return 0; OnFail: fprintf(stderr, "%s %s %s: %s\n", "error: cp", src, dst, strerror(errno)); - return 1; + return -1; } int main(int argc, char *argv[]) { diff --git a/examples/cplusplus-stl.cc b/examples/cplusplus-stl.cc new file mode 100644 index 000000000..a3114b004 --- /dev/null +++ b/examples/cplusplus-stl.cc @@ -0,0 +1,38 @@ +/*-*-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 "libc/stdio/stdio.h" +#include "third_party/libcxx/map" +#include "third_party/libcxx/string" + +int main(int argc, char *argv[]) { + printf("std::map + std::string example\n"); + std::map m{ + {"CPU", 10}, + {"GPU", 15}, + {"RAM", 20}, + }; + printf("m[\"CPU\"] is %d\n", m["CPU"]); + printf("m[\"RAM\"] is %d\n", m["RAM"]); + printf("m[\"GPU\"] is %d\n", m["GPU"]); + printf("setting cpu to 25\n"); + m["CPU"] = 25; // update an existing value + printf("m[\"CPU\"] is %d\n", m["CPU"]); + printf("m[\"RAM\"] is %d\n", m["RAM"]); + printf("m[\"GPU\"] is %d\n", m["GPU"]); +} diff --git a/examples/crashreport.c b/examples/crashreport.c index 24c951083..bef370ac6 100644 --- a/examples/crashreport.c +++ b/examples/crashreport.c @@ -24,6 +24,6 @@ int main(int argc, char *argv[]) { volatile int64_t x; - showcrashreports(); + ShowCrashReports(); return 1 / (x = 0); } diff --git a/examples/crashreport2.c b/examples/crashreport2.c new file mode 100644 index 000000000..fab1424fd --- /dev/null +++ b/examples/crashreport2.c @@ -0,0 +1,52 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/log/log.h" +#include "libc/stdio/stdio.h" + +/** + * @fileoverview CTRL+\ debugging example + * + * make -j8 -O o//examples/crashreport2.com + * o//examples/crashreport2.com + * + * Assuming you call ShowCrashReports() from main(), you can press + * `CTRL+\` at anny time to generate a `SIGQUIT` message that lets you + * debug wrongness and freezups. + * + * On supported platforms, this will cause GDB to automatically attach. + * The nice thing about this, is you can start stepping through your + * code at the precice instruction where the interrupt happened. See + * `libc/log/attachdebugger.c` to see how it works. + * + * If you wish to suppress the auto-GDB behavior, then: + * + * export GDB= + * + * Or alternatively: + * + * extern int __isworker; + * __isworker = true; + * + * Will cause your `SIGQUIT` handler to just print a crash report + * instead. This is useful for production software that might be running + * in a terminal environment like GNU Screen, but it's not desirable to + * have ten worker processes trying to attach GDB at once. + */ + +int main(int argc, char *argv[]) { + volatile int64_t x; + ShowCrashReports(); + printf("please press ctrl+\\ and see what happens...\n"); + sigsuspend(0); + printf("\n\n"); + printf("congratulations! your program is now resuming\n"); + return 0; +} diff --git a/examples/ctrlc.c b/examples/ctrlc.c index d24fcc914..b8a1cb1d2 100644 --- a/examples/ctrlc.c +++ b/examples/ctrlc.c @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "This echos stdio until Ctrl+C is pressed.\n"); CHECK_NE(-1, sigaction(SIGINT, &saint, NULL)); for (;;) { - rc = read(0, buf, BUFSIZ); + rc = read(0, buf, 512); if (rc != -1) { got = rc; } else { diff --git a/examples/curl.c b/examples/curl.c index 1fb7e8e69..c1330bb2a 100644 --- a/examples/curl.c +++ b/examples/curl.c @@ -65,11 +65,26 @@ #define HeaderEqualCase(H, S) \ SlicesEqualCase(S, strlen(S), HeaderData(H), HeaderLength(H)) +int sock; + static bool TuneSocket(int fd, int a, int b, int x) { if (!b) return false; return setsockopt(fd, a, b, &x, sizeof(x)) != -1; } +static void Write(const void *p, size_t n) { + ssize_t rc; + rc = write(1, p, n); + if (rc == -1 && errno == EPIPE) { + close(sock); + exit(128 + SIGPIPE); + } + if (rc != n) { + fprintf(stderr, "write failed: %m\n"); + exit(1); + } +} + static int TlsSend(void *c, const unsigned char *p, size_t n) { int rc; NOISEF("begin send %zu", n); @@ -106,8 +121,7 @@ static wontreturn void PrintUsage(FILE *f, int rc) { } int main(int argc, char *argv[]) { - if (!NoDebug()) showcrashreports(); - xsigaction(SIGPIPE, SIG_IGN, 0, 0, 0); + if (!NoDebug()) ShowCrashReports(); /* * Read flags. @@ -226,19 +240,17 @@ int main(int argc, char *argv[]) { */ mbedtls_ssl_config conf; mbedtls_ssl_context ssl; - mbedtls_x509_crt *cachain = 0; mbedtls_ctr_drbg_context drbg; if (usessl) { mbedtls_ssl_init(&ssl); mbedtls_ctr_drbg_init(&drbg); mbedtls_ssl_config_init(&conf); - cachain = GetSslRoots(); CHECK_EQ(0, mbedtls_ctr_drbg_seed(&drbg, GetEntropy, 0, "justine", 7)); CHECK_EQ(0, mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)); mbedtls_ssl_conf_authmode(&conf, authmode); - mbedtls_ssl_conf_ca_chain(&conf, cachain, 0); + mbedtls_ssl_conf_ca_chain(&conf, GetSslRoots(), 0); mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &drbg); if (!IsTiny()) mbedtls_ssl_conf_dbg(&conf, TlsDebug, 0); CHECK_EQ(0, mbedtls_ssl_setup(&ssl, &conf)); @@ -258,7 +270,7 @@ int main(int argc, char *argv[]) { /* * Connect to server. */ - int ret, sock; + int ret; CHECK_NE(-1, (sock = GoodSocket(addr->ai_family, addr->ai_socktype, addr->ai_protocol, false, &(struct timeval){-60}))); @@ -283,6 +295,8 @@ int main(int argc, char *argv[]) { CHECK_EQ(n, write(sock, request, n)); } + xsigaction(SIGPIPE, SIG_IGN, 0, 0, 0); + /* * Handle response. */ @@ -330,7 +344,7 @@ int main(int argc, char *argv[]) { break; } if (method == kHttpHead) { - CHECK_EQ(hdrlen, write(1, p, hdrlen)); + Write(p, hdrlen); goto Finished; } else if (msg.status == 204 || msg.status == 304) { goto Finished; @@ -348,32 +362,32 @@ int main(int argc, char *argv[]) { t = kHttpClientStateBodyLengthed; paylen = rc; if (paylen > i - hdrlen) { - CHECK_EQ(i - hdrlen, write(1, p + hdrlen, i - hdrlen)); + Write(p + hdrlen, i - hdrlen); } else { - CHECK_EQ(paylen, write(1, p + hdrlen, paylen)); + Write(p + hdrlen, paylen); goto Finished; } } else { t = kHttpClientStateBody; - CHECK_EQ(i - hdrlen, write(1, p + hdrlen, i - hdrlen)); + Write(p + hdrlen, i - hdrlen); } } break; case kHttpClientStateBody: if (!g) goto Finished; - CHECK_EQ(g, write(1, p + i - g, g)); + Write(p + i - g, g); break; case kHttpClientStateBodyLengthed: CHECK(g); if (i - hdrlen > paylen) g = hdrlen + paylen - (i - g); - CHECK_EQ(g, write(1, p + i - g, g)); + Write(p + i - g, g); if (i - hdrlen >= paylen) goto Finished; break; case kHttpClientStateBodyChunked: Chunked: CHECK_NE(-1, (rc = Unchunk(&u, p + hdrlen, i - hdrlen, &paylen))); if (rc) { - CHECK_EQ(paylen, write(1, p + hdrlen, paylen)); + Write(p + hdrlen, paylen); goto Finished; } break; @@ -397,7 +411,6 @@ Finished: mbedtls_ssl_free(&ssl); mbedtls_ctr_drbg_free(&drbg); mbedtls_ssl_config_free(&conf); - mbedtls_x509_crt_free(cachain); mbedtls_ctr_drbg_free(&drbg); } diff --git a/examples/datauri.c b/examples/datauri.c new file mode 100644 index 000000000..c07f569ff --- /dev/null +++ b/examples/datauri.c @@ -0,0 +1,62 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/log/log.h" +#include "libc/runtime/gc.internal.h" +#include "libc/stdio/stdio.h" +#include "libc/x/x.h" +#include "net/http/escape.h" +#include "net/http/http.h" +#include "third_party/getopt/getopt.h" +#include "third_party/stb/stb_image.h" + +#define USAGE \ + " [FLAGS] FILE...\n\ +Utility for printing data:base64 URIs.\n\ +\n\ +FLAGS\n\ +\n\ + -h Help\n" + +void PrintUsage(int rc, FILE *f) { + fputs("Usage: ", f); + fputs(program_invocation_name, f); + fputs(USAGE, f); + exit(rc); +} + +void PrintUri(const char *path) { + size_t n; + void *img, *src, *mime; + int opt, i; + if (!(img = gc(xslurp(path, &n)))) exit(2); + fputs("data:", stdout); + fputs(FindContentType(path, -1), stdout); + fputs(";base64,", stdout); + fputs(gc(EncodeBase64(img, n, 0)), stdout); +} + +int main(int argc, char *argv[]) { + int i; + while ((i = getopt(argc, argv, "?h")) != -1) { + switch (i) { + case '?': + case 'h': + PrintUsage(0, stdout); + default: + PrintUsage(1, stderr); + } + } + if (optind == argc) { + PrintUsage(1, stderr); + } + for (i = optind; i < argc; ++i) { + PrintUri(argv[i]); + } +} diff --git a/examples/examples.mk b/examples/examples.mk index fedc2b780..a76e23ebd 100644 --- a/examples/examples.mk +++ b/examples/examples.mk @@ -8,135 +8,146 @@ EXAMPLES_MAINS_S = $(filter %.S,$(EXAMPLES_FILES)) EXAMPLES_MAINS_C = $(filter %.c,$(EXAMPLES_FILES)) EXAMPLES_MAINS_CC = $(filter %.cc,$(EXAMPLES_FILES)) -EXAMPLES_SRCS = \ - $(EXAMPLES_MAINS_S) \ - $(EXAMPLES_MAINS_C) \ +EXAMPLES_SRCS = \ + $(EXAMPLES_MAINS_S) \ + $(EXAMPLES_MAINS_C) \ $(EXAMPLES_MAINS_CC) -EXAMPLES_MAINS = \ - $(EXAMPLES_MAINS_S) \ - $(EXAMPLES_MAINS_C) \ +EXAMPLES_MAINS = \ + $(EXAMPLES_MAINS_S) \ + $(EXAMPLES_MAINS_C) \ $(EXAMPLES_MAINS_CC) -EXAMPLES_OBJS = \ - $(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.o) \ - $(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.o) \ +EXAMPLES_OBJS = \ + $(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.o) \ + $(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.o) \ $(EXAMPLES_MAINS_CC:%.cc=o/$(MODE)/%.o) -EXAMPLES_COMS = \ - $(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.com) \ - $(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.com) \ +EXAMPLES_COMS = \ + $(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.com) \ + $(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.com) \ $(EXAMPLES_MAINS_CC:%.cc=o/$(MODE)/%.com) -EXAMPLES_BINS = \ - $(EXAMPLES_COMS) \ +EXAMPLES_BINS = \ + $(EXAMPLES_COMS) \ $(EXAMPLES_COMS:%=%.dbg) -EXAMPLES_DIRECTDEPS = \ - DSP_CORE \ - DSP_SCALE \ - DSP_TTY \ - LIBC_ALG \ - LIBC_BITS \ - LIBC_CALLS \ - LIBC_DNS \ - LIBC_FMT \ - LIBC_INTRIN \ - LIBC_LOG \ - LIBC_MEM \ - LIBC_NEXGEN32E \ - LIBC_NT_IPHLPAPI \ - LIBC_NT_KERNEL32 \ - LIBC_NT_NTDLL \ - LIBC_NT_USER32 \ - LIBC_NT_WS2_32 \ - LIBC_NT_ADVAPI32 \ - LIBC_OHMYPLUS \ - LIBC_RAND \ - LIBC_RUNTIME \ - LIBC_SOCK \ - LIBC_STDIO \ - LIBC_STR \ - LIBC_STUBS \ - LIBC_SYSV \ - LIBC_SYSV_CALLS \ - LIBC_TESTLIB \ - LIBC_THREAD \ - LIBC_TIME \ - LIBC_TINYMATH \ - LIBC_UNICODE \ - LIBC_X \ - LIBC_ZIPOS \ - NET_HTTP \ - NET_HTTPS \ - THIRD_PARTY_COMPILER_RT \ - THIRD_PARTY_DLMALLOC \ - THIRD_PARTY_GDTOA \ - THIRD_PARTY_GETOPT \ - THIRD_PARTY_LINENOISE \ - THIRD_PARTY_LUA \ - THIRD_PARTY_MBEDTLS \ - THIRD_PARTY_MUSL \ - THIRD_PARTY_QUICKJS \ - THIRD_PARTY_STB \ - THIRD_PARTY_XED \ - THIRD_PARTY_ZLIB \ - TOOL_BUILD_LIB \ +EXAMPLES_DIRECTDEPS = \ + DSP_CORE \ + DSP_SCALE \ + DSP_TTY \ + LIBC_ALG \ + LIBC_BITS \ + LIBC_CALLS \ + LIBC_DNS \ + LIBC_FMT \ + LIBC_INTRIN \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_NT_IPHLPAPI \ + LIBC_NT_KERNEL32 \ + LIBC_NT_NTDLL \ + LIBC_NT_USER32 \ + LIBC_NT_WS2_32 \ + LIBC_NT_ADVAPI32 \ + LIBC_RAND \ + LIBC_RUNTIME \ + LIBC_SOCK \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_SYSV_CALLS \ + LIBC_TESTLIB \ + LIBC_THREAD \ + LIBC_TIME \ + LIBC_TINYMATH \ + LIBC_UNICODE \ + LIBC_X \ + LIBC_ZIPOS \ + NET_HTTP \ + NET_HTTPS \ + THIRD_PARTY_COMPILER_RT \ + THIRD_PARTY_DLMALLOC \ + THIRD_PARTY_GDTOA \ + THIRD_PARTY_GETOPT \ + THIRD_PARTY_LIBCXX \ + THIRD_PARTY_LINENOISE \ + THIRD_PARTY_LUA \ + THIRD_PARTY_MBEDTLS \ + THIRD_PARTY_MUSL \ + THIRD_PARTY_QUICKJS \ + THIRD_PARTY_STB \ + THIRD_PARTY_XED \ + THIRD_PARTY_ZLIB \ + TOOL_BUILD_LIB \ TOOL_VIZ_LIB -EXAMPLES_DEPS := \ +EXAMPLES_DEPS := \ $(call uniq,$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)))) -o/$(MODE)/examples/examples.pkg: \ - $(EXAMPLES_OBJS) \ +o/$(MODE)/examples/examples.pkg: \ + $(EXAMPLES_OBJS) \ $(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)_A).pkg) -o/$(MODE)/examples/unbourne.o: \ - OVERRIDE_CPPFLAGS += \ - -DSTACK_FRAME_UNLIMITED +o/$(MODE)/examples/unbourne.o: \ + OVERRIDE_CPPFLAGS += \ + -DSTACK_FRAME_UNLIMITED \ + -fpie -o/$(MODE)/examples/%.com.dbg: \ - $(EXAMPLES_DEPS) \ - o/$(MODE)/examples/%.o \ - o/$(MODE)/examples/examples.pkg \ - $(CRT) \ +o/$(MODE)/examples/%.com.dbg: \ + $(EXAMPLES_DEPS) \ + o/$(MODE)/examples/%.o \ + o/$(MODE)/examples/examples.pkg \ + $(CRT) \ $(APE) @$(APELINK) -o/$(MODE)/examples/hellolua.com.dbg: \ - $(EXAMPLES_DEPS) \ - o/$(MODE)/examples/hellolua.o \ - o/$(MODE)/examples/hellolua.lua.zip.o \ - o/$(MODE)/examples/examples.pkg \ - $(CRT) \ +o/$(MODE)/examples/hellolua.com.dbg: \ + $(EXAMPLES_DEPS) \ + o/$(MODE)/examples/hellolua.o \ + o/$(MODE)/examples/hellolua.lua.zip.o \ + o/$(MODE)/examples/examples.pkg \ + $(CRT) \ $(APE) @$(APELINK) -o/$(MODE)/examples/ispell.com.dbg: \ - $(EXAMPLES_DEPS) \ - o/$(MODE)/examples/ispell.o \ - o/$(MODE)/usr/share/dict/words.zip.o \ - o/$(MODE)/examples/examples.pkg \ - $(CRT) \ +o/$(MODE)/examples/ispell.com.dbg: \ + $(EXAMPLES_DEPS) \ + o/$(MODE)/examples/ispell.o \ + o/$(MODE)/usr/share/dict/words.zip.o \ + o/$(MODE)/examples/examples.pkg \ + $(CRT) \ $(APE) @$(APELINK) -o/$(MODE)/examples/nesemu1.com.dbg: \ - $(EXAMPLES_DEPS) \ - o/$(MODE)/examples/nesemu1.o \ - o/$(MODE)/usr/share/rom/mario.nes.zip.o \ - o/$(MODE)/usr/share/rom/zelda.nes.zip.o \ - o/$(MODE)/usr/share/rom/tetris.nes.zip.o \ - o/$(MODE)/examples/examples.pkg \ - $(CRT) \ +o/$(MODE)/examples/nesemu1.com.dbg: \ + $(EXAMPLES_DEPS) \ + o/$(MODE)/examples/nesemu1.o \ + o/$(MODE)/usr/share/rom/mario.nes.zip.o \ + o/$(MODE)/usr/share/rom/zelda.nes.zip.o \ + o/$(MODE)/usr/share/rom/tetris.nes.zip.o \ + o/$(MODE)/examples/examples.pkg \ + $(CRT) \ $(APE) @$(APELINK) -o/$(MODE)/examples/hello.com.dbg: \ - $(EXAMPLES_DEPS) \ - o/$(MODE)/examples/hello.o \ - o/$(MODE)/examples/examples.pkg \ - $(CRT) \ +o/$(MODE)/examples/nesemu1.com: \ + o/$(MODE)/examples/nesemu1.com.dbg \ + o/$(MODE)/third_party/zip/zip.com \ + o/$(MODE)/tool/build/symtab.com + @$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@ + @$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \ + -o o/$(MODE)/examples/.nesemu1/.symtab $< + @$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \ + o/$(MODE)/examples/.nesemu1/.symtab + +o/$(MODE)/examples/hello.com.dbg: \ + $(EXAMPLES_DEPS) \ + o/$(MODE)/examples/hello.o \ + o/$(MODE)/examples/examples.pkg \ + $(CRT) \ $(APE_NO_MODIFY_SELF) @$(APELINK) @@ -149,6 +160,6 @@ usr/share/dict/words: usr/share/dict/words.gz @$(GZ) $(ZFLAGS) -d <$< >$@ .PHONY: o/$(MODE)/examples -o/$(MODE)/examples: \ - o/$(MODE)/examples/package \ +o/$(MODE)/examples: \ + o/$(MODE)/examples/package \ $(EXAMPLES_BINS) diff --git a/examples/exec.c b/examples/exec.c index 5d51c4667..f844bf645 100644 --- a/examples/exec.c +++ b/examples/exec.c @@ -8,14 +8,26 @@ ╚─────────────────────────────────────────────────────────────────*/ #endif #include "libc/calls/calls.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/struct/sigset.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" +#include "libc/sysv/consts/sig.h" + +STATIC_YOINK("strerror"); int main(int argc, char *argv[]) { - if (argc < 3) { - fputs("USAGE: EXEC.COM PROG ARGV₀ [ARGV₁...]\n", stderr); + sigset_t ss; + if (argc < 2) { + fputs("USAGE: EXEC.COM PROG [ARGV₀...]\n", stderr); return 1; } + + // block arbitrary signal so __printargs() looks cooler + sigemptyset(&ss); + sigaddset(&ss, SIGPWR); + sigprocmask(SIG_BLOCK, &ss, 0); + execv(argv[1], argv + 2); return 127; } diff --git a/examples/forkexec.c b/examples/forkexec.c new file mode 100644 index 000000000..418e16485 --- /dev/null +++ b/examples/forkexec.c @@ -0,0 +1,23 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/stdio/stdio.h" + +int main(int argc, char *argv[]) { + int pid; + if (argc < 3) { + fputs("USAGE: FORKEXEC.COM PROG ARGV₀ [ARGV₁...]\n", stderr); + return 1; + } + if (!fork()) { + execv(argv[1], argv + 2); + return 127; + } +} diff --git a/examples/forkexecwait.c b/examples/forkexecwait.c new file mode 100644 index 000000000..eca2b20cd --- /dev/null +++ b/examples/forkexecwait.c @@ -0,0 +1,25 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/stdio/stdio.h" + +int main(int argc, char *argv[]) { + int pid; + volatile void *p; + if (argc < 3) { + fputs("USAGE: FORKEXECWAIT.COM PROG ARGV₀ [ARGV₁...]\n", stderr); + return 1; + } + if (!fork()) { + execv(argv[1], argv + 2); + return 127; + } + wait(0); +} diff --git a/examples/forkrand.c b/examples/forkrand.c index 971eff04b..ea6417d50 100644 --- a/examples/forkrand.c +++ b/examples/forkrand.c @@ -8,13 +8,17 @@ ╚─────────────────────────────────────────────────────────────────*/ #endif #include "libc/calls/calls.h" +#include "libc/intrin/kprintf.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/nt/nt/process.h" #include "libc/rand/rand.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" #include "libc/time/time.h" +#include "libc/x/x.h" dontinline void dostuff(const char *s) { int i, us; diff --git a/examples/getcpucount.c b/examples/getcpucount.c index 4ed429ad7..ec38eb478 100644 --- a/examples/getcpucount.c +++ b/examples/getcpucount.c @@ -14,11 +14,11 @@ int main(int argc, char *argv[]) { int c, n; - char a[22]; + char a[22], *p; if ((c = GetCpuCount())) { - n = int64toarray_radix10(c, a); - a[n++] = '\n'; - return write(1, a, n) == n ? 0 : 1; + p = FormatInt64(a, c); + *p++ = '\n'; + return write(1, a, p - a) == p - a ? 0 : 1; } else { return 1; } diff --git a/examples/getrandom.c b/examples/getrandom.c index 834fd39c7..a0143e3f9 100644 --- a/examples/getrandom.c +++ b/examples/getrandom.c @@ -209,6 +209,7 @@ const struct Function { {"getrandom", GetRandom}, // {"inc", inc}, // {"knuth", knuth}, // + {"lemur64", lemur64}, // {"libc", libc}, // {"moby", moby}, // {"mt19937", _mt19937}, // diff --git a/examples/hangman.c b/examples/hangman.c index f3b508dd6..f580aa476 100644 --- a/examples/hangman.c +++ b/examples/hangman.c @@ -44,8 +44,8 @@ #include "libc/str/str.h" #include "libc/time/time.h" #include "third_party/zlib/zlib.h" +// clang-format off -/* clang-format off */ #define DICT "usr/share/dict/hangman" #define MAXERR 7 #define MINSCORE 0 diff --git a/examples/hello.c b/examples/hello.c index 8486ab30a..a9c3249f3 100644 --- a/examples/hello.c +++ b/examples/hello.c @@ -9,6 +9,8 @@ #endif #include "libc/stdio/stdio.h" +STATIC_YOINK("mmap"); // TODO: fix bandaid for MODE=asan + int main() { printf("%s\n", "hello world"); return 0; diff --git a/examples/img.c b/examples/img.c index bfb21a4d7..37af07737 100644 --- a/examples/img.c +++ b/examples/img.c @@ -7,23 +7,98 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif +#include "libc/dce.h" +#include "libc/log/log.h" +#include "libc/runtime/gc.internal.h" #include "libc/stdio/stdio.h" #include "libc/x/x.h" +#include "net/http/escape.h" +#include "net/http/http.h" +#include "third_party/getopt/getopt.h" #include "third_party/stb/stb_image.h" -/** - * @fileoverview Utility for printing HTML tags. - */ +#define USAGE \ + " [FLAGS] IMG...\n\ +Utility for printing HTML tags.\n\ +\n\ +FLAGS\n\ +\n\ + -h Help\n\ + -a Wrap with tag\n\ + -u Embed data:base64 URI\n" + +int scale; +bool linktag; +bool datauri; +bool sizeonly; + +void PrintUsage(int rc, FILE *f) { + fputs("Usage: ", f); + fputs(program_invocation_name, f); + fputs(USAGE, f); + exit(rc); +} + +void PrintImg(const char *path) { + size_t n; + int opt, i, yn, xn, cn, w, h; + void *img, *pix, *src, *mime; + if (!(img = gc(xslurp(path, &n)))) exit(2); + if (!(pix = gc(stbi_load_from_memory(img, n, &xn, &yn, &cn, 0)))) exit(3); + if (linktag) { + printf("", path); + } + src = path; + if (datauri) { + src = xasprintf("data:%s;base64,%s", FindContentType(path, -1), + gc(EncodeBase64(img, n, &n))); + } + w = (xn + (1 << scale) / 2) >> scale; + h = (yn + (1 << scale) / 2) >> scale; + if (sizeonly) { + printf("width=\"%d\" height=\"%d\"", w, h); + } else { + printf("\"[%s]\"\n", w, + h, path, src); + } + if (linktag) { + printf(""); + } + printf("\n"); +} int main(int argc, char *argv[]) { - void *p; - size_t n; - int yn, xn, cn; - if (argc != 2) return 1; - if (!(p = xslurp(argv[1], &n))) return 2; - if (!(p = stbi_load_from_memory(p, n, &xn, &yn, &cn, 0))) return 3; - printf("\"[%s]\"\n", - argv[1], (xn + 1) >> 1, (yn + 1) >> 1, argv[1]); - return 0; + if (!NoDebug()) ShowCrashReports(); + int i; + while ((i = getopt(argc, argv, "?huas01234")) != -1) { + switch (i) { + case '0': + case '1': + case '2': + case '3': + case '4': + scale = i - '0'; + break; + case 's': + sizeonly = true; + break; + case 'a': + linktag = true; + break; + case 'u': + datauri = true; + break; + case '?': + case 'h': + PrintUsage(0, stdout); + default: + PrintUsage(1, stderr); + } + } + if (optind == argc) { + PrintUsage(1, stderr); + } + for (i = optind; i < argc; ++i) { + PrintImg(argv[i]); + } } diff --git a/examples/ispell.c b/examples/ispell.c index 4ddbe09a1..8ce96e96d 100644 --- a/examples/ispell.c +++ b/examples/ispell.c @@ -121,7 +121,7 @@ void SpellChecker(void) { printf("word: "); fflush(stdout); if (getline(&line, &linesize, stdin) > 0) { - query = strtolower(chomp(line)); + query = strtolower(_chomp(line)); if (critbit0_contains(&words, query)) { printf("ok\r\n"); } else { @@ -147,13 +147,13 @@ void SpellChecker(void) { void LoadWords(void) { CHECK_NOTNULL((f = fopen("/zip/usr/share/dict/words", "r"))); while (getline(&line, &linesize, f) > 0) { - critbit0_insert(&words, strtolower(chomp(line))); + critbit0_insert(&words, strtolower(_chomp(line))); } CHECK_NE(-1, fclose(f)); } int main(int argc, char *argv[]) { - showcrashreports(); + if (!NoDebug()) ShowCrashReports(); LoadWords(); SpellChecker(); return 0; diff --git a/examples/kilo.c b/examples/kilo.c index 5a01c4ba4..c6508e857 100644 --- a/examples/kilo.c +++ b/examples/kilo.c @@ -154,7 +154,7 @@ void editorSetStatusMessage(const char *fmt, ...); * matches and keywords. The file name matches are used in order to match * a given syntax with a given file name: if a match pattern starts with a * dot, it is matched as the last past of the filename, for example ".c". - * Otherwise the pattern is just searched inside the filenme, like "Makefile"). + * Otherwise the pattern is just searched inside the filename, like "Makefile"). * * The list of keywords to highlight is just a list of words, however if they * a trailing '|' character is added at the end, they are highlighted in @@ -249,7 +249,10 @@ fatal: int editorReadKey(int64_t fd) { int nread; char c, seq[3]; - if ((nread = read(fd, &c, 1)) == -1) exit(1); + do { + nread = read(fd, &c, 1); + if (nread == -1) exit(1); + } while (!nread); while (1) { switch (c) { @@ -390,7 +393,7 @@ int is_separator(int c) { /* Return true if the specified row last char is part of a multi line comment * that starts at this row or at one before, and does not end at the end - * of the row but spawns to the next row. */ + * of the row but spans to the next row. */ int editorRowHasOpenComment(erow *row) { if (row->hl && row->rsize && row->hl[row->rsize - 1] == HL_MLCOMMENT && (row->rsize < 2 || (row->render[row->rsize - 2] != '*' || @@ -651,7 +654,7 @@ void editorFreeRow(erow *row) { free(row->hl); } -/* Remove the row at the specified position, shifting the remainign on the +/* Remove the row at the specified position, shifting the remaining on the * top. */ void editorDelRow(int at) { erow *row; @@ -667,7 +670,7 @@ void editorDelRow(int at) { /* Turn the editor rows into a single heap-allocated string. * Returns the pointer to the heap-allocated string and populate the - * integer pointed by 'buflen' with the size of the string, escluding + * integer pointed by 'buflen' with the size of the string, excluding * the final nulterm. */ char *editorRowsToString(int *buflen) { char *buf = NULL, *p; diff --git a/examples/linenoise.c b/examples/linenoise.c new file mode 100644 index 000000000..b54e6f899 --- /dev/null +++ b/examples/linenoise.c @@ -0,0 +1,23 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "third_party/linenoise/linenoise.h" + +int main(int argc, char *argv[]) { + char *line; + while ((line = linenoiseWithHistory("IN> ", "foo"))) { + fputs("OUT> ", stdout); + fputs(line, stdout); + fputs("\n", stdout); + free(line); + } + return 0; +} diff --git a/examples/loadavg.c b/examples/loadavg.c new file mode 100644 index 000000000..c2550f066 --- /dev/null +++ b/examples/loadavg.c @@ -0,0 +1,20 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/log/check.h" +#include "libc/stdio/stdio.h" +#include "libc/time/time.h" + +int main(int argc, char *argv[]) { + double x[3]; + CHECK_NE(-1, getloadavg(x, 3)); + printf("%g %g %g\n", x[0], x[1], x[2]); + return 0; +} diff --git a/examples/nesemu1.cc b/examples/nesemu1.cc index 274973066..f195eb508 100644 --- a/examples/nesemu1.cc +++ b/examples/nesemu1.cc @@ -26,7 +26,6 @@ #include "libc/macros.internal.h" #include "libc/math.h" #include "libc/mem/mem.h" -#include "libc/ohmyplus/vector.h" #include "libc/runtime/runtime.h" #include "libc/sock/sock.h" #include "libc/stdio/stdio.h" @@ -43,6 +42,7 @@ #include "libc/zip.h" #include "libc/zipos/zipos.internal.h" #include "third_party/getopt/getopt.h" +#include "third_party/libcxx/vector" #include "tool/viz/lib/knobs.h" STATIC_YOINK("zip_uri_support"); @@ -1673,7 +1673,7 @@ char* GetLine(void) { static char* line; static size_t linesize; if (getline(&line, &linesize, stdin) > 0) { - return chomp(line); + return _chomp(line); } else { return NULL; } @@ -1703,7 +1703,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) { if ((ffplay = commandvenv("FFPLAY", "ffplay"))) { devnull = open("/dev/null", O_WRONLY | O_CLOEXEC); pipe2(pipefds, O_CLOEXEC); - if (!(playpid_ = vfork())) { + if (!(playpid_ = fork())) { const char* const args[] = { "ffplay", "-nodisp", "-loglevel", "quiet", "-fflags", "nobuffer", "-ac", "1", "-ar", "1789773", diff --git a/examples/panels.c b/examples/panels.c index 856aac2d4..4e3361126 100644 --- a/examples/panels.c +++ b/examples/panels.c @@ -12,6 +12,7 @@ #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/termios.h" #include "libc/calls/struct/winsize.h" +#include "libc/dce.h" #include "libc/log/check.h" #include "libc/log/gdb.h" #include "libc/log/log.h" @@ -152,7 +153,7 @@ void Draw(void) { int main(int argc, char *argv[]) { struct sigaction sa[2] = {{.sa_handler = OnShutdown}, {.sa_handler = OnInvalidate}}; - showcrashreports(); + if (!NoDebug()) ShowCrashReports(); Setup(); Enter(); GetTtySize(); diff --git a/examples/printargs.c b/examples/printargs.c index 7c9a13ffc..60ce148ed 100644 --- a/examples/printargs.c +++ b/examples/printargs.c @@ -7,94 +7,8 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/log/log.h" -#include "libc/macros.internal.h" -#include "libc/nt/process.h" #include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/auxv.h" -const struct AuxiliaryValue { - const char *fmt; - long *id; - const char *name; - const char *description; -} kAuxiliaryValues[] = { - {"%012lx", &AT_EXECFD, "AT_EXECFD", "file descriptor of program"}, - {"%012lx", &AT_PHDR, "AT_PHDR", "address of elf program headers"}, - {"%012lx", &AT_PHENT, "AT_PHENT", "size of program header entry"}, - {"%012lx", &AT_PHNUM, "AT_PHNUM", "number of program headers"}, - {"%012lx", &AT_PAGESZ, "AT_PAGESZ", "system page size"}, - {"%012lx", &AT_BASE, "AT_BASE", "base address of the program interpreter"}, - {"%012lx", &AT_ENTRY, "AT_ENTRY", "entry address of executable"}, - {"%012lx", &AT_NOTELF, "AT_NOTELF", "set if not an elf"}, - {"%-12d", &AT_UID, "AT_UID", "real user id of thread"}, - {"%-12d", &AT_EUID, "AT_EUID", "effective user id of thread"}, - {"%-12d", &AT_GID, "AT_GID", "real group id of thread"}, - {"%-12d", &AT_EGID, "AT_EGID", "effective group id of thread"}, - {"%-12d", &AT_CLKTCK, "AT_CLKTCK", "frequency of times() counts"}, - {"%012lx", &AT_OSRELDATE, "AT_OSRELDATE", - "freebsd release number, e.g. 1200086"}, - {"%012lx", &AT_PLATFORM, "AT_PLATFORM", - "string identifying hardware platform"}, - {"%012lx", &AT_DCACHEBSIZE, "AT_DCACHEBSIZE", "data cache block size"}, - {"%012lx", &AT_ICACHEBSIZE, "AT_ICACHEBSIZE", - "instruction cache block size"}, - {"%012lx", &AT_UCACHEBSIZE, "AT_UCACHEBSIZE", "unified cache block size"}, - {"%012lx", &AT_SECURE, "AT_SECURE", - "for set{u,g}id binz & security blankets"}, - {"%-12s", &AT_BASE_PLATFORM, "AT_BASE_PLATFORM", - "string identifying real platform"}, - {"%012lx", &AT_RANDOM, "AT_RANDOM", "address of sixteen random bytes"}, - {"%-12s", &AT_EXECFN, "AT_EXECFN", "pathname used to execute program"}, - {"%012lx", &AT_SYSINFO_EHDR, "AT_SYSINFO_EHDR", - "linux virtual dso page address"}, - {"%012lx", &AT_FLAGS, "AT_FLAGS", "unused?"}, - {"%012lx", &AT_HWCAP, "AT_HWCAP", "cpu stuff"}, - {"%012lx", &AT_HWCAP2, "AT_HWCAP2", "more cpu stuff"}, -}; - -const struct AuxiliaryValue *DescribeAuxv(unsigned long x) { - int i; - for (i = 0; i < ARRAYLEN(kAuxiliaryValues); ++i) { - if (x == *kAuxiliaryValues[i].id) { - return kAuxiliaryValues + i; - } - } - return NULL; -} - -int main(int argc, char *argv[], char **envp) { - long key; - unsigned i; - unsigned long *auxp; - char fmt[64], **env; - struct AuxiliaryValue *auxinfo; - uint32_t varlen; - char16_t var[PATH_MAX]; - printf("\nArguments:\n"); - for (i = 0; i < __argc; ++i) { - printf(" ☼ %s\n", argv[i]); - } - printf("\nEnvironment:\n"); - for (env = envp; *env; ++env) { - printf(" ☼ %s\n", *env); - } - printf("\nAuxiliary Values:\n"); - for (auxp = __auxv; *auxp; auxp += 2) { - if ((auxinfo = DescribeAuxv(auxp[0]))) { - stpcpy(stpcpy(stpcpy(fmt, "%16s[%4ld] = "), auxinfo->fmt), " # %s\n"); - printf(fmt, auxinfo->name, auxp[0], auxp[1], auxinfo->description); - } else { - printf("%16s[%4ld] = %012lx\n", "unknown", auxp[0], auxp[1]); - } - } - printf("\nSpecial Directories:\n"); - printf(" ☼ kTmpPath = %`'s\n", kTmpPath); - printf(" ☼ kNtSystemDirectory = %`'s\n", kNtSystemDirectory); - printf(" ☼ kNtWindowsDirectory = %`'s\n", kNtWindowsDirectory); - printf(" ☼ program_executable_name = %`'s\n", program_executable_name); - return 0; +int main() { + __printargs(""); } diff --git a/examples/printprimes.c b/examples/printprimes.c index 5624a98bf..73c7ff947 100644 --- a/examples/printprimes.c +++ b/examples/printprimes.c @@ -27,7 +27,7 @@ int main(int argc, char *argv[]) { } } if (isprime) { - int64toarray_radix10(i, buf); + FormatInt64(buf, i); fputs(buf, stdout); fputc('\n', stdout); if (k++ % 100 == 0) { diff --git a/examples/rlimit.c b/examples/rlimit.c new file mode 100644 index 000000000..47325062c --- /dev/null +++ b/examples/rlimit.c @@ -0,0 +1,72 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/rlimit.h" +#include "libc/errno.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/color.internal.h" +#include "libc/macros.internal.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/rlim.h" +#include "libc/sysv/consts/rlimit.h" + +/** + * @fileoverview tool for printing and changing system resource limits + * + * This is what you do if you want to not accidentally bomb your system + * with runaway code. If you haven't accidentally bombed your UNIX + * system before then you're not pushing it hard enough. + */ + +static void SetLimit(int resource, uint64_t soft, uint64_t hard) { + struct rlimit old; + struct rlimit lim = {soft, hard}; + if (resource == 127) return; + if (setrlimit(resource, &lim) == -1) { + if (!getrlimit(resource, &old)) { + lim.rlim_max = MIN(hard, old.rlim_max); + lim.rlim_cur = MIN(soft, lim.rlim_max); + if (!setrlimit(resource, &lim)) { + fprintf(stderr, "%sNOTE: SETRLIMIT(%s) DOWNGRADED TO {%,ld, %,ld}\n", + __strace_rlimit_name(resource), lim.rlim_cur, lim.rlim_max); + return; + } + } + fprintf(stderr, "ERROR: SETRLIMIT(%s, %,ld, %,ld) FAILED %m%n", + __strace_rlimit_name(resource), soft, hard); + exit(1); + } +} + +int main(int argc, char *argv[]) { + int i, rc; + struct rlimit rlim; + + // // example of how you might change the limits + // SetLimit(RLIMIT_CPU, 3, 33); + // SetLimit(RLIMIT_NPROC, 4, 128); + // SetLimit(RLIMIT_NOFILE, 32, 128); + // SetLimit(RLIMIT_SIGPENDING, 16, 1024); + // SetLimit(RLIMIT_AS, 8 * 1024 * 1024, 1l * 1024 * 1024 * 1024); + // SetLimit(RLIMIT_RSS, 8 * 1024 * 1024, 1l * 1024 * 1024 * 1024); + // SetLimit(RLIMIT_DATA, 8 * 1024 * 1024, 1l * 1024 * 1024 * 1024); + // SetLimit(RLIMIT_FSIZE, 8 * 1000 * 1000, 1l * 1000 * 1000 * 1000); + + for (i = 0; i < RLIM_NLIMITS; ++i) { + rc = getrlimit(i, &rlim); + printf("SETRLIMIT(%-20s, %,16ld, %,16ld) → %d %s\n", + __strace_rlimit_name(i), rlim.rlim_cur, rlim.rlim_max, rc, + !rc ? "" : strerror(errno)); + } + + return 0; +} diff --git a/examples/rusage.c b/examples/rusage.c index 2112c184a..969bba592 100644 --- a/examples/rusage.c +++ b/examples/rusage.c @@ -101,7 +101,7 @@ int main(int argc, char *argv[]) { sigaddset(&chldmask, SIGCHLD); sigprocmask(SIG_BLOCK, &chldmask, &savemask); ts1 = nowl(); - CHECK_NE(-1, (pid = vfork())); + CHECK_NE(-1, (pid = fork())); if (!pid) { sigaction(SIGINT, &dflt, 0); sigaction(SIGQUIT, &dflt, 0); diff --git a/examples/seq.c b/examples/seq.c index 7e2782cc1..dc7e2295a 100644 --- a/examples/seq.c +++ b/examples/seq.c @@ -7,8 +7,9 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif +#include "libc/calls/calls.h" #include "libc/fmt/conv.h" -#include "libc/stdio/stdio.h" +#include "libc/fmt/itoa.h" /** * @fileoverview Prints sequence of numbers. @@ -16,6 +17,7 @@ int main(int argc, char *argv[]) { long a, b, i; + char buf[21], *p; switch (argc) { case 2: a = 1; @@ -29,6 +31,9 @@ int main(int argc, char *argv[]) { return 1; } for (i = a; i <= b; ++i) { - printf("%ld\n", i); + p = buf; + p = FormatInt64(p, i); + *p++ = '\n'; + write(1, buf, p - buf); } } diff --git a/examples/setitimer.c b/examples/setitimer.c new file mode 100644 index 000000000..28d1d30e8 --- /dev/null +++ b/examples/setitimer.c @@ -0,0 +1,72 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/struct/itimerval.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/ucontext.h" +#include "libc/log/check.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/itimer.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sig.h" +#include "libc/time/time.h" + +volatile bool gotalrm; + +void OnSigAlrm(int sig, siginfo_t *si, ucontext_t *ctx) { + gotalrm = true; +} + +int main() { + + ////////////////////////////////////////////////////////////////////////////// + printf("first tutorial: set singleshot alarm for 1.5 seconds from now\n"); + + // setup alarm in 1.5 seconds + // this timer tears itself down once it's handled + struct itimerval shot = {{0, 0}, {1, 500000}}; + struct sigaction handler = {.sa_sigaction = OnSigAlrm, + .sa_flags = SA_RESETHAND | SA_SIGINFO}; + CHECK_EQ(0, sigaction(SIGALRM, &handler, 0)); + CHECK_EQ(0, setitimer(ITIMER_REAL, &shot, 0)); + + // wait for alarm + pause(); + printf("got singleshot alarm!\n\n"); + + ////////////////////////////////////////////////////////////////////////////// + printf("second tutorial: interval timer\n"); + + // setup timer every 1.5 seconds + struct sigaction oldalrm; + struct sigaction sigalrm = {.sa_sigaction = OnSigAlrm, + .sa_flags = SA_SIGINFO}; + CHECK_EQ(0, sigaction(SIGALRM, &sigalrm, &oldalrm)); + struct itimerval oldtimer; + struct itimerval timer = {{1, 500000}, {1, 500000}}; + CHECK_EQ(0, setitimer(ITIMER_REAL, &timer, &oldtimer)); + + // wait for three timeouts + int i = 0; + int n = 3; + while (i < n) { + pause(); + if (gotalrm) { + ++i; + printf("got timeout %d out of %d\n", i, n); + gotalrm = false; + } + } + + // teardown timer + CHECK_EQ(0, setitimer(ITIMER_REAL, &oldtimer, 0)); + CHECK_EQ(0, sigaction(SIGALRM, &oldalrm, 0)); +} diff --git a/examples/time.c b/examples/time.c index a224bd4ff..a09d0b0aa 100644 --- a/examples/time.c +++ b/examples/time.c @@ -47,8 +47,8 @@ void PrintMetric(const char *name, long double d) { mils = fmodl(d * 1000, 1000); mics = fmodl(d * 1000000, 1000); p = stpcpy(p, name), *p++ = '\t'; - p += int64toarray_radix10(mins, p), *p++ = 'm'; - p += int64toarray_radix10(secs, p), *p++ = '.'; + p = FormatInt64(p, mins), *p++ = 'm'; + p = FormatInt64(p, secs), *p++ = '.'; *p++ = '0' + mils / 100; *p++ = '0' + mils / 10 % 10; *p++ = '0' + mils % 10; @@ -69,7 +69,7 @@ int main(int argc, char *argv[]) { long double real; char exebuf[PATH_MAX]; if (argc >= 2) { - if ((exepath = commandv(argv[1], exebuf))) { + if ((exepath = commandv(argv[1], exebuf, sizeof(exebuf)))) { real = nowl(); argv[1] = exepath; if ((ws = xvspawn(OnChild, argv + 1, &r)) != -1) { diff --git a/examples/touch.c b/examples/touch.c index 0325bfc92..58e179f44 100644 --- a/examples/touch.c +++ b/examples/touch.c @@ -20,7 +20,7 @@ int main(int argc, char *argv[]) { int i; for (i = 1; i < argc; ++i) { - if (touch(argv[i], 0644) == -1) { + if (touch(argv[i], 0666) == -1) { fprintf(stderr, "ERROR: %s: %s\n", argv[i], strerror(errno)); exit(1); } diff --git a/examples/ttyinfo.c b/examples/ttyinfo.c index f6a2e3341..575e964dc 100644 --- a/examples/ttyinfo.c +++ b/examples/ttyinfo.c @@ -27,6 +27,7 @@ #include "libc/x/x.h" #define CTRL(C) ((C) ^ 0b01000000) +#define WRITE(FD, SLIT) write(FD, SLIT, strlen(SLIT)) #define ENABLE_SAFE_PASTE "\e[?2004h" #define ENABLE_MOUSE_TRACKING "\e[?1000;1002;1015;1006h" #define DISABLE_MOUSE_TRACKING "\e[?1000;1002;1015;1006l" @@ -46,7 +47,7 @@ void onkilled(int sig) { } void restoretty(void) { - write(1, DISABLE_MOUSE_TRACKING, strlen(DISABLE_MOUSE_TRACKING)); + WRITE(1, DISABLE_MOUSE_TRACKING); ioctl(1, TCSETS, &oldterm); } @@ -72,9 +73,9 @@ int rawmode(void) { t.c_cflag |= CS8; t.c_iflag |= IUTF8; ioctl(1, TCSETS, &t); - write(1, ENABLE_SAFE_PASTE, strlen(ENABLE_SAFE_PASTE)); - write(1, ENABLE_MOUSE_TRACKING, strlen(ENABLE_MOUSE_TRACKING)); - write(1, PROBE_DISPLAY_SIZE, strlen(PROBE_DISPLAY_SIZE)); + WRITE(1, ENABLE_SAFE_PASTE); + WRITE(1, ENABLE_MOUSE_TRACKING); + WRITE(1, PROBE_DISPLAY_SIZE); return 0; } diff --git a/examples/ucontext-sigfpe-recovery.c b/examples/ucontext-sigfpe-recovery.c index 0c7c6491d..30965799f 100644 --- a/examples/ucontext-sigfpe-recovery.c +++ b/examples/ucontext-sigfpe-recovery.c @@ -16,12 +16,22 @@ #include "libc/sysv/consts/sig.h" #include "third_party/xed/x86.h" +/** + * @fileoverview How to change CPU state on signal delivery + * + * This program redefines division by zero so that it has a definition. + * The definition is the meaning of life, the universe, and everything. + * Normally crash signals like `SIGSEGV`, `SIGILL`, and `SIGFPE` aren't + * recoverable. This example shows how it actually can be done with Xed + * and this example should work on all supported platforms even Windows + */ + void handler(int sig, siginfo_t *si, ucontext_t *ctx) { struct XedDecodedInst xedd; xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15); ctx->uc_mcontext.rip += xedd.length; - ctx->uc_mcontext.rax = 42; + ctx->uc_mcontext.rax = 42; // set the DIV result registers rdx:rax ctx->uc_mcontext.rdx = 0; } diff --git a/examples/uname.c b/examples/uname.c new file mode 100644 index 000000000..9cf0c5154 --- /dev/null +++ b/examples/uname.c @@ -0,0 +1,24 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/struct/utsname.h" +#include "libc/stdio/stdio.h" + +int main(int argc, char *argv[]) { + struct utsname names; + if (uname(&names)) return 1; + printf("%-10s %s\n", "sysname", names.sysname); + printf("%-10s %s\n", "nodename", names.nodename); + printf("%-10s %s\n", "release", names.release); + printf("%-10s %s\n", "version", names.version); + printf("%-10s %s\n", "machine", names.machine); + printf("%-10s %s\n", "domainname", names.domainname); + return 0; +} diff --git a/examples/unbourne.c b/examples/unbourne.c index 558297667..973d1a074 100644 --- a/examples/unbourne.c +++ b/examples/unbourne.c @@ -5731,7 +5731,7 @@ retry: linenoiseSetFreeHintsCallback(free); linenoiseSetHintsCallback(ShellHint); linenoiseSetCompletionCallback(ShellCompletion); - if ((p = linenoiseWithHistory("$ ", "unbourne"))) { + if ((p = linenoiseWithHistory(">: ", "unbourne"))) { nr = min(strlen(p), IBUFSIZ - 2); memcpy(buf, p, nr); buf[nr++] = '\n'; diff --git a/examples/x86split.c b/examples/x86split.c index 528efe32a..f61de6a06 100644 --- a/examples/x86split.c +++ b/examples/x86split.c @@ -55,8 +55,8 @@ int fgethex(FILE *f) { } int main(int argc, char *argv[argc]) { + int err; unsigned c, i, j, l; - enum XedError err; struct XedDecodedInst xedd; unsigned char buf[XED_MAX_INSTRUCTION_BYTES]; memset(buf, 0, sizeof(buf)); diff --git a/libc/alg/alg.h b/libc/alg/alg.h index 39fb1633a..2522ab53b 100644 --- a/libc/alg/alg.h +++ b/libc/alg/alg.h @@ -8,10 +8,10 @@ COSMOPOLITAN_C_START_ void *bsearch(const void *, const void *, size_t, size_t, int cmp(const void *, const void *)) - paramsnonnull() nothrow nosideeffect; + paramsnonnull() dontthrow nosideeffect; void *bsearch_r(const void *, const void *, size_t, size_t, int cmp(const void *, const void *, void *), void *) - paramsnonnull((1, 2, 5)) nothrow nosideeffect; + paramsnonnull((1, 2, 5)) dontthrow nosideeffect; void djbsort(int32_t *, size_t); void qsort(void *, size_t, size_t, int (*)(const void *, const void *)) paramsnonnull(); @@ -19,9 +19,9 @@ void qsort_r(void *, size_t, size_t, int cmp(const void *, const void *, void *), void *arg) paramsnonnull((1, 4)); int tarjan(int, const int (*)[2], int, int[], int[], int *) - paramsnonnull((2, 4)) nocallback nothrow; + paramsnonnull((2, 4)) nocallback dontthrow; -#define __algalloc returnspointerwithnoaliases nothrow nocallback nodiscard +#define __algalloc returnspointerwithnoaliases dontthrow nocallback dontdiscard char *replacestr(const char *, const char *, const char *) paramsnonnull() __algalloc; diff --git a/libc/alg/bisect.internal.h b/libc/alg/bisect.internal.h index 0616a859d..1d97a9a62 100644 --- a/libc/alg/bisect.internal.h +++ b/libc/alg/bisect.internal.h @@ -14,7 +14,7 @@ forceinline void *bisect(const void *k, const void *data, size_t n, size_t size, r = n - 1; p = data; while (l <= r) { - m = (l + r) >> 1; + m = (l & r) + ((l ^ r) >> 1); c = cmp(k, p + m * size, arg); if (c > 0) { l = m + 1; diff --git a/libc/alg/critbit0.h b/libc/alg/critbit0.h index ddacc991d..acf78f88e 100644 --- a/libc/alg/critbit0.h +++ b/libc/alg/critbit0.h @@ -11,15 +11,15 @@ struct critbit0 { size_t count; }; -bool critbit0_contains(struct critbit0 *, const char *) nothrow nosideeffect +bool critbit0_contains(struct critbit0 *, const char *) dontthrow nosideeffect paramsnonnull(); bool critbit0_insert(struct critbit0 *, const char *) paramsnonnull(); -bool critbit0_delete(struct critbit0 *, const char *) nothrow paramsnonnull(); -void critbit0_clear(struct critbit0 *) nothrow paramsnonnull(); +bool critbit0_delete(struct critbit0 *, const char *) dontthrow paramsnonnull(); +void critbit0_clear(struct critbit0 *) dontthrow paramsnonnull(); char *critbit0_get(struct critbit0 *, const char *); intptr_t critbit0_allprefixed(struct critbit0 *, const char *, intptr_t (*)(const char *, void *), void *) - paramsnonnull((1, 2, 3)) nothrow; + paramsnonnull((1, 2, 3)) dontthrow; bool critbit0_emplace(struct critbit0 *, char *, size_t) paramsnonnull(); COSMOPOLITAN_C_END_ diff --git a/libc/assert.h b/libc/assert.h index 8ab8e0cd1..6583800c8 100644 --- a/libc/assert.h +++ b/libc/assert.h @@ -12,7 +12,9 @@ void __assert_fail(const char *, const char *, int) hidden wontreturn relegated; ((void)((EXPR) || (__assert_fail(#EXPR, __FILE__, __LINE__), 0))) #endif +#ifndef __cplusplus #define static_assert _Static_assert +#endif COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/bits/asmflag.h b/libc/bits/asmflag.h new file mode 100644 index 000000000..64013b14b --- /dev/null +++ b/libc/bits/asmflag.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_ASMFLAG_H_ +#define COSMOPOLITAN_LIBC_BITS_ASMFLAG_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/* + * Constraints for virtual machine flags. + * @note we beseech clang devs for flag constraints + */ +#ifdef __GCC_ASM_FLAG_OUTPUTS__ /* GCC6+ CLANG10+ */ +#define CFLAG_CONSTRAINT "=@ccc" +#define CFLAG_ASM(OP) OP +#define ZFLAG_CONSTRAINT "=@ccz" +#define ZFLAG_ASM(OP) OP +#define OFLAG_CONSTRAINT "=@cco" +#define OFLAG_ASM(OP) OP +#define SFLAG_CONSTRAINT "=@ccs" +#define SFLAG_ASM(SP) SP +#define ABOVE_CONSTRAINT "=@cca" /* i.e. !ZF && !CF */ +#define ABOVEFLAG_ASM(OP) OP +#else +#define CFLAG_CONSTRAINT "=q" +#define CFLAG_ASM(OP) OP "\n\tsetc\t%b0" +#define ZFLAG_CONSTRAINT "=q" +#define ZFLAG_ASM(OP) OP "\n\tsetz\t%b0" +#define OFLAG_CONSTRAINT "=q" +#define OFLAG_ASM(OP) OP "\n\tseto\t%b0" +#define SFLAG_CONSTRAINT "=q" +#define SFLAG_ASM(SP) OP "\n\tsets\t%b0" +#define ABOVE_CONSTRAINT "=@cca" +#define ABOVEFLAG_ASM(OP) OP "\n\tseta\t%b0" +#endif + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_ASMFLAG_H_ */ diff --git a/libc/bits/atomic.h b/libc/bits/atomic.h index 9cb5d5571..e2d628adf 100644 --- a/libc/bits/atomic.h +++ b/libc/bits/atomic.h @@ -1,6 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_BITS_ATOMIC_H_ #define COSMOPOLITAN_LIBC_BITS_ATOMIC_H_ #include "libc/bits/bits.h" +#include "libc/intrin/lockcmpxchg.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -31,8 +32,8 @@ COSMOPOLITAN_C_START_ }) #define atomic_init(PTR, VAL) atomic_store(PTR, VAL) #define atomic_exchange(PTR, VAL) lockxchg(PTR, &(VAL)) -#define atomic_compare_exchange_strong(X, Y, Z) lockcmpxchg(X, Y, Z) -#define atomic_compare_exchange_weak(X, Y, Z) lockcmpxchg(X, Y, Z) +#define atomic_compare_exchange_strong(X, Y, Z) _lockcmpxchg(X, Y, Z) +#define atomic_compare_exchange_weak(X, Y, Z) _lockcmpxchg(X, Y, Z) #define atomic_load_explicit(PTR, ORDER) atomic_load(PTR) #define atomic_store_explicit(PTR, VAL, ORDER) atomic_store(PTR, VAL) #define atomic_flag_clear_explicit(PTR, ORDER) atomic_store(PTR, 0) diff --git a/libc/bits/bitop.h b/libc/bits/bitop.h new file mode 100644 index 000000000..934ca0160 --- /dev/null +++ b/libc/bits/bitop.h @@ -0,0 +1,45 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_BITOP_H_ +#define COSMOPOLITAN_LIBC_BITS_BITOP_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define bts(MEM, BIT) __BitOp("bts", BIT, MEM) /** bit test and set */ +#define btr(MEM, BIT) __BitOp("btr", BIT, MEM) /** bit test and reset */ +#define btc(MEM, BIT) __BitOp("btc", BIT, MEM) /** bit test and complement */ +#define lockbts(MEM, BIT) __BitOp("lock bts", BIT, MEM) +#define lockbtr(MEM, BIT) __BitOp("lock btr", BIT, MEM) +#define lockbtc(MEM, BIT) __BitOp("lock btc", BIT, MEM) + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define __BitOp(OP, BIT, MEM) \ + ({ \ + bool OldBit; \ + if (__builtin_constant_p(BIT)) { \ + asm(CFLAG_ASM(OP "%z1\t%2,%1") \ + : CFLAG_CONSTRAINT(OldBit), \ + "+m"((MEM)[(BIT) / (sizeof((MEM)[0]) * CHAR_BIT)]) \ + : "J"((BIT) % (sizeof((MEM)[0]) * CHAR_BIT)) \ + : "cc"); \ + } else if (sizeof((MEM)[0]) == 2) { \ + asm(CFLAG_ASM(OP "\t%w2,%1") \ + : CFLAG_CONSTRAINT(OldBit), "+m"((MEM)[0]) \ + : "r"(BIT) \ + : "cc"); \ + } else if (sizeof((MEM)[0]) == 4) { \ + asm(CFLAG_ASM(OP "\t%k2,%1") \ + : CFLAG_CONSTRAINT(OldBit), "+m"((MEM)[0]) \ + : "r"(BIT) \ + : "cc"); \ + } else if (sizeof((MEM)[0]) == 8) { \ + asm(CFLAG_ASM(OP "\t%q2,%1") \ + : CFLAG_CONSTRAINT(OldBit), "+m"((MEM)[0]) \ + : "r"(BIT) \ + : "cc"); \ + } \ + OldBit; \ + }) +#endif /* __GNUC__ && !__STRICT_ANSI__ */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_BITOP_H_ */ diff --git a/libc/bits/bits.h b/libc/bits/bits.h index 641e0c1f3..d283f9aa8 100644 --- a/libc/bits/bits.h +++ b/libc/bits/bits.h @@ -21,11 +21,6 @@ unsigned long roundup2pow(unsigned long) libcesque pureconst; unsigned long roundup2log(unsigned long) libcesque pureconst; unsigned long rounddown2pow(unsigned long) libcesque pureconst; unsigned long hamming(unsigned long, unsigned long) pureconst; -intptr_t lockxchg(void *, void *, size_t); -bool cmpxchg(void *, intptr_t, intptr_t, size_t); -bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); -intptr_t atomic_load(void *, size_t); -intptr_t atomic_store(void *, intptr_t, size_t); unsigned bextra(const unsigned *, size_t, char); /*───────────────────────────────────────────────────────────────────────────│─╗ @@ -136,84 +131,6 @@ unsigned bextra(const unsigned *, size_t, char); ╚────────────────────────────────────────────────────────────────────────────│*/ #if defined(__GNUC__) && !defined(__STRICT_ANSI__) -/* - * Constraints for virtual machine flags. - * @note we beseech clang devs for flag constraints - */ -#ifdef __GCC_ASM_FLAG_OUTPUTS__ /* GCC6+ CLANG10+ */ -#define CFLAG_CONSTRAINT "=@ccc" -#define CFLAG_ASM(OP) OP -#define ZFLAG_CONSTRAINT "=@ccz" -#define ZFLAG_ASM(OP) OP -#define OFLAG_CONSTRAINT "=@cco" -#define OFLAG_ASM(OP) OP -#define SFLAG_CONSTRAINT "=@ccs" -#define SFLAG_ASM(SP) SP -#define ABOVE_CONSTRAINT "=@cca" /* i.e. !ZF && !CF */ -#define ABOVEFLAG_ASM(OP) OP -#else -#define CFLAG_CONSTRAINT "=q" -#define CFLAG_ASM(OP) OP "\n\tsetc\t%b0" -#define ZFLAG_CONSTRAINT "=q" -#define ZFLAG_ASM(OP) OP "\n\tsetz\t%b0" -#define OFLAG_CONSTRAINT "=q" -#define OFLAG_ASM(OP) OP "\n\tseto\t%b0" -#define SFLAG_CONSTRAINT "=q" -#define SFLAG_ASM(SP) OP "\n\tsets\t%b0" -#define ABOVE_CONSTRAINT "=@cca" -#define ABOVEFLAG_ASM(OP) OP "\n\tseta\t%b0" -#endif - -/** - * Reads scalar from memory w/ one operation. - * - * @param MEM is alignas(𝑘) uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} - * @return *(MEM) - * @note defeats compiler load tearing optimizations - * @note alignas(𝑘) is implied if compiler knows type - * @note alignas(𝑘) only avoids multi-core / cross-page edge cases - * @see Intel's Six-Thousand Page Manual V.3A §8.2.3.1 - * @see atomic_store() - */ -#define atomic_load(MEM) \ - ({ \ - autotype(MEM) Mem = (MEM); \ - typeof(*Mem) Reg; \ - asm("mov\t%1,%0" : "=r"(Reg) : "m"(*Mem)); \ - Reg; \ - }) - -/** - * Saves scalar to memory w/ one operation. - * - * This is guaranteed to happen in either one or zero operations, - * depending on whether or not it's possible for *(MEM) to be read - * afterwards. This macro only forbids compiler from using >1 ops. - * - * @param MEM is alignas(𝑘) uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} - * @param VAL is uint𝑘_t w/ better encoding for immediates (constexpr) - * @return VAL - * @note alignas(𝑘) on nexgen32e only needed for end of page gotcha - * @note alignas(𝑘) is implied if compiler knows type - * @note needed to defeat store tearing optimizations - * @see Intel Six-Thousand Page Manual Manual V.3A §8.2.3.1 - * @see atomic_load() - */ -#define atomic_store(MEM, VAL) \ - ({ \ - autotype(VAL) Val = (VAL); \ - typeof(&Val) Mem = (MEM); \ - asm("mov%z1\t%1,%0" : "=m"(*Mem) : "r"(Val)); \ - Val; \ - }) - -#define bts(MEM, BIT) __BitOp("bts", BIT, MEM) /** bit test and set */ -#define btr(MEM, BIT) __BitOp("btr", BIT, MEM) /** bit test and reset */ -#define btc(MEM, BIT) __BitOp("btc", BIT, MEM) /** bit test and complement */ -#define lockbts(MEM, BIT) __BitOp("lock bts", BIT, MEM) -#define lockbtr(MEM, BIT) __BitOp("lock btr", BIT, MEM) -#define lockbtc(MEM, BIT) __BitOp("lock btc", BIT, MEM) - #define lockinc(MEM) __ArithmeticOp1("lock inc", MEM) #define lockdec(MEM) __ArithmeticOp1("lock dec", MEM) #define locknot(MEM) __ArithmeticOp1("lock not", MEM) @@ -225,66 +142,6 @@ unsigned bextra(const unsigned *, size_t, char); #define lockandeq(MEM, VAL) __ArithmeticOp2("lock and", VAL, MEM) #define lockoreq(MEM, VAL) __ArithmeticOp2("lock or", VAL, MEM) -/** - * Exchanges *MEMORY into *LOCALVAR w/ one operation. - * - * @param MEMORY is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} - * @param LOCALVAR is uint𝑘_t[hasatleast 1] - * @return LOCALVAR[0] - * @see xchg() - */ -#define lockxchg(MEMORY, LOCALVAR) \ - ({ \ - asm("xchg\t%0,%1" : "+%m"(*(MEMORY)), "+r"(*(LOCALVAR))); \ - *(LOCALVAR); \ - }) - -/** - * Compares and exchanges. - * - * @param IFTHING is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} - * @return true if value was exchanged, otherwise false - * @see lockcmpxchg() - */ -#define cmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ - ({ \ - bool DidIt; \ - autotype(IFTHING) IfThing = (IFTHING); \ - typeof(*IfThing) IsEqualToMe = (ISEQUALTOME); \ - typeof(*IfThing) ReplaceItWithMe = (REPLACEITWITHME); \ - asm volatile(ZFLAG_ASM("cmpxchg\t%3,%1") \ - : ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(IsEqualToMe) \ - : "r"(ReplaceItWithMe) \ - : "cc"); \ - DidIt; \ - }) - -/** - * Compares and exchanges w/ one operation. - * - * @param IFTHING is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} - * @return true if value was exchanged, otherwise false - * @see lockcmpxchg() - */ -#define lockcmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ - ({ \ - bool DidIt; \ - autotype(IFTHING) IfThing = (IFTHING); \ - typeof(*IfThing) IsEqualToMe = (ISEQUALTOME); \ - typeof(*IfThing) ReplaceItWithMe = (REPLACEITWITHME); \ - asm volatile(ZFLAG_ASM("lock cmpxchg\t%3,%1") \ - : ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(IsEqualToMe) \ - : "r"(ReplaceItWithMe) \ - : "cc"); \ - DidIt; \ - }) - -#define IsAddressCanonicalForm(P) \ - ({ \ - intptr_t p2 = (intptr_t)(P); \ - (0xffff800000000000l <= p2 && p2 <= 0x00007fffffffffffl); \ - }) - /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § bits » implementation details ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ @@ -301,44 +158,6 @@ unsigned bextra(const unsigned *, size_t, char); MEM; \ }) -#define __BitOp(OP, BIT, MEM) \ - ({ \ - bool OldBit; \ - if (__builtin_constant_p(BIT)) { \ - asm(CFLAG_ASM(OP "%z1\t%2,%1") \ - : CFLAG_CONSTRAINT(OldBit), \ - "+m"((MEM)[(BIT) / (sizeof((MEM)[0]) * CHAR_BIT)]) \ - : "J"((BIT) % (sizeof((MEM)[0]) * CHAR_BIT)) \ - : "cc"); \ - } else if (sizeof((MEM)[0]) == 2) { \ - asm(CFLAG_ASM(OP "\t%w2,%1") \ - : CFLAG_CONSTRAINT(OldBit), "+m"((MEM)[0]) \ - : "r"(BIT) \ - : "cc"); \ - } else if (sizeof((MEM)[0]) == 4) { \ - asm(CFLAG_ASM(OP "\t%k2,%1") \ - : CFLAG_CONSTRAINT(OldBit), "+m"((MEM)[0]) \ - : "r"(BIT) \ - : "cc"); \ - } else if (sizeof((MEM)[0]) == 8) { \ - asm(CFLAG_ASM(OP "\t%q2,%1") \ - : CFLAG_CONSTRAINT(OldBit), "+m"((MEM)[0]) \ - : "r"(BIT) \ - : "cc"); \ - } \ - OldBit; \ - }) - -#else -#define cmpxchg(MEM, CMP, VAL) \ - cmpxchg(MEM, (intptr_t)(CMP), (intptr_t)(VAL), sizeof(*(MEM))) -#define lockcmpxchg(MEM, CMP, VAL) \ - lockcmpxchg(MEM, (intptr_t)(CMP), (intptr_t)(VAL), sizeof(*(MEM))) -#define lockxchg(MEM, VAR) \ - lockxchg(MEM, VAR, sizeof(*(MEM)) / (sizeof(*(MEM)) == sizeof(*(VAR)))) -#define atomic_store(MEM, VAL) \ - atomic_store(MEM, VAL, sizeof(*(MEM)) / (sizeof(*(MEM)) == sizeof(*(VAL)))) -#define atomic_load(MEM) atomic_load(MEM, sizeof(*(MEM))) #endif /* __GNUC__ && !__STRICT_ANSI__ */ COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/bits/midpoint.h b/libc/bits/midpoint.h new file mode 100644 index 000000000..aa013453f --- /dev/null +++ b/libc/bits/midpoint.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_ +#define COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_ +#include "libc/assert.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86__) +/** + * Computes `(a + b) / 2` assuming unsigned. + * + * This implementation is the fastest on AMD Zen architecture. + */ +#define _midpoint(a, b) \ + ({ \ + typeof((a) + (b)) a_ = (a); \ + typeof(a_) b_ = (b); \ + assert(a_ >= 0); \ + assert(b_ >= 0); \ + asm("add\t%1,%0\n\t" \ + "rcr\t%0" \ + : "+r"(a_) \ + : "r"(b_)); \ + a_; \ + }) +#else +/** + * Computes `(a + b) / 2` assuming unsigned. + */ +#define _midpoint(a, b) (((a) & (b)) + ((a) ^ (b)) / 2) +#endif /* __GNUC__ && !__STRICT_ANSI__ && x86 */ + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_ */ diff --git a/libc/calls/addtimespec.c b/libc/calls/addtimespec.c index 94b8e1bfe..889a64484 100644 --- a/libc/calls/addtimespec.c +++ b/libc/calls/addtimespec.c @@ -19,7 +19,7 @@ #include "libc/calls/math.h" /** - * Adds two microsecond timestamps. + * Adds two nanosecond timestamps. */ struct timespec AddTimespec(struct timespec x, struct timespec y) { x.tv_sec += y.tv_sec; diff --git a/libc/calls/atfork.c b/libc/calls/atfork.c index 73ce94a0a..f7ff0b47b 100644 --- a/libc/calls/atfork.c +++ b/libc/calls/atfork.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/intrin/cmpxchg.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/sysv/errfuns.h" @@ -41,7 +41,7 @@ int atfork(void *fn, void *arg) { for (;;) { i = g_atfork.i; if (i == ARRAYLEN(g_atfork.p)) return enomem(); - if (cmpxchg(&g_atfork.i, i, i + 1)) { + if (_cmpxchg(&g_atfork.i, i, i + 1)) { g_atfork.p[i] = (struct AtForkCallback){.fn = fn, .arg = arg}; return 0; } diff --git a/libc/calls/calls.h b/libc/calls/calls.h index d4121ae94..ee64d4a59 100644 --- a/libc/calls/calls.h +++ b/libc/calls/calls.h @@ -17,6 +17,10 @@ #include "libc/sysv/consts/s.h" #include "libc/sysv/consts/sig.h" +#define _POSIX_VERSION 200809L +#define _POSIX2_VERSION _POSIX_VERSION +#define _XOPEN_VERSION 700 + #define EOF -1 /* end of file */ #define WEOF -1u /* end of file (multibyte) */ #define _IOFBF 0 /* fully buffered */ @@ -48,14 +52,14 @@ #define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK) #define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK) -#define WCOREDUMP(s) ((s)&0x80) -#define WEXITSTATUS(s) (((s)&0xff00) >> 8) +#define WCOREDUMP(s) (0x80 & (s)) +#define WEXITSTATUS(s) ((0xff00 & (s)) >> 8) #define WIFCONTINUED(s) ((s) == 0xffff) #define WIFEXITED(s) (!WTERMSIG(s)) -#define WIFSIGNALED(s) (((s)&0xffff) - 1u < 0xffu) -#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001) >> 8) > 0x7f00) +#define WIFSIGNALED(s) ((0xffff & (s)) - 1u < 0xffu) +#define WIFSTOPPED(s) ((short)(((0xffff & (s)) * 0x10001) >> 8) > 0x7f00) #define WSTOPSIG(s) WEXITSTATUS(s) -#define WTERMSIG(s) ((s)&0x7f) +#define WTERMSIG(s) (127 & (s)) #define W_STOPCODE(s) ((s) << 8 | 0177) #if !(__ASSEMBLER__ + __LINKER__ + 0) @@ -66,8 +70,8 @@ COSMOPOLITAN_C_START_ typedef int sig_atomic_t; -DIR *fdopendir(int) nodiscard; -DIR *opendir(const char *) nodiscard; +DIR *fdopendir(int) dontdiscard; +DIR *opendir(const char *) dontdiscard; bool fileexists(const char *); bool isdirectory(const char *); bool isexecutable(const char *); @@ -75,19 +79,18 @@ bool isregularfile(const char *); bool issymlink(const char *); bool32 isatty(int) nosideeffect; bool32 ischardev(int) nosideeffect; -char *commandv(const char *, char[hasatleast PATH_MAX]); -char *get_current_dir_name(void) nodiscard; +char *commandv(const char *, char *, size_t); +char *get_current_dir_name(void) dontdiscard; char *getcwd(char *, size_t); char *realpath(const char *, char *); -char *replaceuser(const char *) nodiscard; +char *replaceuser(const char *) dontdiscard; char *ttyname(int); -int access(const char *, int) nothrow; +int access(const char *, int) dontthrow; int arch_prctl(); int chdir(const char *); int chmod(const char *, uint32_t); int chown(const char *, uint32_t, uint32_t); int chroot(const char *); -int clone(int (*)(void *), void *, int, void *, ...); int close(int); int closedir(DIR *); int creat(const char *, uint32_t); @@ -105,7 +108,7 @@ int execvpe(const char *, char *const[], char *const[]); int faccessat(int, const char *, int, uint32_t); int fadvise(int, uint64_t, uint64_t, int); int fchdir(int); -int fchmod(int, uint32_t) nothrow; +int fchmod(int, uint32_t) dontthrow; int fchmodat(int, const char *, uint32_t, int); int fchown(int, uint32_t, uint32_t); int fchownat(int, const char *, uint32_t, uint32_t, int); @@ -120,16 +123,24 @@ int fsync(int); int ftruncate(int, int64_t); int getdents(unsigned, void *, unsigned, long *); int getdomainname(char *, size_t); +int getegid(void) nosideeffect; +int geteuid(void) nosideeffect; +int getgid(void) nosideeffect; int gethostname(char *, size_t); +int getloadavg(double *, int); int getpgid(int); +int getpgrp(void) nosideeffect; int getpid(void); int getppid(void); int getpriority(int, unsigned); int getrlimit(int, struct rlimit *); int getrusage(int, struct rusage *); +int getsid(int) nosideeffect; +int gettid(void); +int getuid(void) nosideeffect; int kill(int, int); int killpg(int, int); -int link(const char *, const char *) nothrow; +int link(const char *, const char *) dontthrow; int linkat(int, const char *, int, const char *, int); int lstat(const char *, struct stat *); int lutimes(const char *, const struct timeval[2]); @@ -147,7 +158,6 @@ int munlock(const void *, size_t); int munlockall(void); int nice(int); int open(const char *, int, ...); -int openanon(char *, unsigned); int openat(int, const char *, int, ...); int pause(void); int personality(uint64_t); @@ -155,7 +165,7 @@ int pipe(int[hasatleast 2]); int pipe2(int[hasatleast 2], int); int posix_fadvise(int, uint64_t, uint64_t, int); int posix_madvise(void *, uint64_t, int); -int prctl(); +int prctl(int, ...); int raise(int); int reboot(int); int remove(const char *); @@ -166,18 +176,22 @@ int rmdir(const char *); int sched_getaffinity(int, uint64_t, void *); int sched_setaffinity(int, uint64_t, const void *); int sched_yield(void); +int seccomp(unsigned, unsigned, void *); int setegid(uint32_t); int seteuid(uint32_t); -int setgid(uint32_t); +int setgid(int); int setpgid(int, int); +int setpgrp(void); int setpriority(int, unsigned, int); int setregid(uint32_t, uint32_t); int setresgid(uint32_t, uint32_t, uint32_t); int setresuid(uint32_t, uint32_t, uint32_t); +int getresgid(uint32_t *, uint32_t *, uint32_t *); +int getresuid(uint32_t *, uint32_t *, uint32_t *); int setreuid(uint32_t, uint32_t); int setrlimit(int, const struct rlimit *); int setsid(void); -int setuid(uint32_t); +int setuid(int); int sigignore(int); int siginterrupt(int, int); int sigprocmask(int, const struct sigset *, struct sigset *); @@ -192,6 +206,7 @@ int sysinfo(struct sysinfo *); int touch(const char *, uint32_t); int truncate(const char *, uint64_t); int ttyname_r(int, char *, size_t); +int umask(int); int uname(struct utsname *); int unlink(const char *); int unlink_s(const char **); @@ -202,13 +217,13 @@ int wait3(int *, int, struct rusage *); int wait4(int, int *, int, struct rusage *); int waitpid(int, int *, int); intptr_t syscall(int, ...); -long ptrace(int, int, void *, void *); +long ptrace(int, ...); long telldir(DIR *); long times(struct tms *); size_t GetFileSize(const char *); -size_t getfiledescriptorsize(int); ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t); ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t); +ssize_t getfiledescriptorsize(int); ssize_t lseek(int, int64_t, unsigned); ssize_t pread(int, void *, size_t, int64_t); ssize_t preadv(int, struct iovec *, int, int64_t); @@ -222,16 +237,12 @@ ssize_t splice(int, int64_t *, int, int64_t *, size_t, uint32_t); ssize_t vmsplice(int, const struct iovec *, int64_t, uint32_t); ssize_t write(int, const void *, size_t); struct dirent *readdir(DIR *); -uint32_t getegid(void) nosideeffect; -uint32_t geteuid(void) nosideeffect; -uint32_t getgid(void) nosideeffect; -uint32_t getpgrp(void) nosideeffect; -uint32_t getsid(int) nosideeffect; -uint32_t gettid(void) nosideeffect; -uint32_t getuid(void) nosideeffect; -uint32_t umask(int32_t); void rewinddir(DIR *); void sync(void); +int pledge(const char *, const char *); + +int clone(int (*)(void *), void *, size_t, int, void *, int *, void *, size_t, + int *); /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § system calls » formatting ─╬─│┼ diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index f95d5df86..c5469a5e5 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -44,7 +44,9 @@ LIBC_CALLS_A_DIRECTDEPS = \ LIBC_NT_IPHLPAPI \ LIBC_NT_KERNEL32 \ LIBC_NT_NTDLL \ - LIBC_NT_POWERPROF \ + LIBC_NT_PDH \ + LIBC_NT_PSAPI \ + LIBC_NT_POWRPROF \ LIBC_NT_WS2_32 \ LIBC_STR \ LIBC_STUBS \ @@ -63,8 +65,12 @@ $(LIBC_CALLS_A).pkg: \ $(LIBC_CALLS_A_OBJS) \ $(foreach x,$(LIBC_CALLS_A_DIRECTDEPS),$($(x)_A).pkg) +o/$(MODE)/libc/calls/vdsofunc.greg.o \ +o/$(MODE)/libc/calls/directmap.o \ +o/$(MODE)/libc/calls/directmap-nt.o \ o/$(MODE)/libc/calls/raise.o: \ OVERRIDE_COPTS += \ + -ffreestanding \ $(NO_MAGIC) o/$(MODE)/libc/calls/termios2linux.o \ @@ -78,6 +84,9 @@ o/$(MODE)/libc/calls/ntcontext2linux.o: \ -O3 # TODO(jart): make va_arg optimize well in default mode +o//libc/calls/open.o \ +o//libc/calls/openat.o \ +o//libc/calls/prctl.o \ o//libc/calls/ioctl.o \ o//libc/calls/ioctl_default.o \ o//libc/calls/ioctl_fioclex-nt.o \ @@ -96,11 +105,18 @@ o//libc/calls/fcntl.o: \ OVERRIDE_CFLAGS += \ -Os +# must use alloca() or path_max*2*2 o/$(MODE)/libc/calls/execl.o \ o/$(MODE)/libc/calls/execle.o \ o/$(MODE)/libc/calls/execlp.o \ +o/$(MODE)/libc/calls/copyfile.o \ o/$(MODE)/libc/calls/execve-nt.o \ +o/$(MODE)/libc/calls/linkat-nt.o \ +o/$(MODE)/libc/calls/renameat-nt.o \ o/$(MODE)/libc/calls/execve-sysv.o \ +o/$(MODE)/libc/calls/symlinkat-nt.o \ +o/$(MODE)/libc/calls/readlinkat-nt.o \ +o/$(MODE)/libc/calls/describeopenflags.greg.o \ o/$(MODE)/libc/calls/mkntenvblock.o: \ OVERRIDE_CPPFLAGS += \ -DSTACK_FRAME_UNLIMITED diff --git a/libc/calls/chdir-nt.c b/libc/calls/chdir-nt.c index 0fa936626..65c027ce5 100644 --- a/libc/calls/chdir-nt.c +++ b/libc/calls/chdir-nt.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/errno.h" #include "libc/macros.internal.h" #include "libc/nt/errors.h" #include "libc/nt/files.h" @@ -27,9 +28,10 @@ textwindows int sys_chdir_nt(const char *path) { uint32_t n; - int e, ms, len; + int e, ms, err, len; char16_t path16[PATH_MAX], var[4]; if ((len = __mkntpath(path, path16)) == -1) return -1; + if (!len) return enoent(); if (len && path16[len - 1] != u'\\') { if (len + 2 > PATH_MAX) return enametoolong(); path16[len + 0] = u'\\'; @@ -39,7 +41,7 @@ textwindows int sys_chdir_nt(const char *path) { * chdir() seems flaky on windows 7 * in a similar way to rmdir() sigh */ - for (ms = 1;; ms *= 2) { + for (err = errno, ms = 1;; ms *= 2) { if (SetCurrentDirectory(path16)) { /* * Now we need to set a magic environment variable. @@ -68,12 +70,12 @@ textwindows int sys_chdir_nt(const char *path) { if (ms <= 512 && (e == kNtErrorFileNotFound || e == kNtErrorAccessDenied)) { Sleep(ms); + errno = err; continue; } else { break; } } } - errno = e; - return -1; + return __fix_enotdir(-1, path16); } diff --git a/libc/calls/chdir.c b/libc/calls/chdir.c index 101f6dfb8..0b42d5a95 100644 --- a/libc/calls/chdir.c +++ b/libc/calls/chdir.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -30,10 +31,14 @@ * @see fchdir() */ int chdir(const char *path) { - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (!IsWindows()) { - return sys_chdir(path); + int rc; + if (!path || (IsAsan() && !__asan_is_valid(path, 1))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_chdir(path); } else { - return sys_chdir_nt(path); + rc = sys_chdir_nt(path); } + STRACE("%s(%#s) → %d% m", "chdir", path, rc); + return rc; } diff --git a/libc/calls/chroot.c b/libc/calls/chroot.c new file mode 100644 index 000000000..2f654f7a4 --- /dev/null +++ b/libc/calls/chroot.c @@ -0,0 +1,33 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" + +/** + * Changes root directory. + * + * @raise ENOSYS on Windows + */ +int chroot(const char *path) { + int rc; + rc = sys_chroot(path); + STRACE("chroot(%s) → %d% m", path, rc); + return rc; +} diff --git a/libc/calls/clock_gettime.c b/libc/calls/clock_gettime.c index 7b5ef8e39..f091d6719 100644 --- a/libc/calls/clock_gettime.c +++ b/libc/calls/clock_gettime.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/timeval.h" #include "libc/dce.h" #include "libc/fmt/conv.h" @@ -25,6 +26,8 @@ #include "libc/nt/synchronization.h" #include "libc/sysv/errfuns.h" +static typeof(sys_clock_gettime) *__clock_gettime = sys_clock_gettime; + /** * Returns nanosecond time. * @@ -39,14 +42,20 @@ * @see strftime(), gettimeofday() * @asyncsignalsafe */ -int clock_gettime(int clockid, struct timespec *ts) { - int rc; +noinstrument int clock_gettime(int clockid, struct timespec *ts) { + int rc, e; axdx_t ad; - if (!ts) return efault(); - if (IsAsan() && !__asan_is_valid(ts, sizeof(*ts))) return efault(); - if (clockid == -1) return einval(); - if (!IsWindows()) { - if ((rc = sys_clock_gettime(clockid, ts)) == -1 && errno == ENOSYS) { + char buf[45]; + if (!ts) { + rc = efault(); + } else if (IsAsan() && !__asan_is_valid(ts, sizeof(*ts))) { + rc = efault(); + } else if (clockid == -1) { + rc = einval(); + } else if (!IsWindows()) { + e = errno; + if ((rc = __clock_gettime(clockid, ts))) { + errno = e; ad = sys_gettimeofday((struct timeval *)ts, NULL, NULL); assert(ad.ax != -1); if (SupportsXnu() && ad.ax) { @@ -56,8 +65,32 @@ int clock_gettime(int clockid, struct timespec *ts) { ts->tv_nsec *= 1000; rc = 0; } - return rc; } else { - return sys_clock_gettime_nt(clockid, ts); + rc = sys_clock_gettime_nt(clockid, ts); } + if (!__time_critical) { + STRACE("clock_gettime(%d, [%s]) → %d% m", clockid, + __strace_timespec(buf, sizeof(buf), rc, ts), rc); + } + return rc; } + +/** + * Returns fast system clock_gettime() if it exists. + */ +void *__get_clock_gettime(void) { + void *vdso; + static bool once; + static void *result; + if (!once) { + if ((vdso = __vdsofunc("__vdso_clock_gettime"))) { + __clock_gettime = result = vdso; + } + once = true; + } + return result; +} + +const void *const __clock_gettime_ctor[] initarray = { + __get_clock_gettime, +}; diff --git a/libc/calls/close-nt.c b/libc/calls/close-nt.c index 1006ab75f..a6270628a 100644 --- a/libc/calls/close-nt.c +++ b/libc/calls/close-nt.c @@ -16,25 +16,41 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" #include "libc/calls/internal.h" #include "libc/nt/enum/filetype.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" +#include "libc/sock/ntstdin.internal.h" +#include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" textwindows int sys_close_nt(struct Fd *fd) { - bool32 ok; - if (fd->kind == kFdFile && GetFileType(fd->handle) == kNtFileTypeDisk) { - /* - * Like Linux, closing a file on Windows doesn't guarantee it's - * immediately synced to disk. But unlike Linux, this could cause - * subsequent operations, e.g. unlink() to break w/ access error. - */ + int e; + bool ok = true; + + if (fd->kind == kFdFile && ((fd->flags & O_ACCMODE) != O_RDONLY && + GetFileType(fd->handle) == kNtFileTypeDisk)) { + // Like Linux, closing a file on Windows doesn't guarantee it's + // immediately synced to disk. But unlike Linux, this could cause + // subsequent operations, e.g. unlink() to break w/ access error. + e = errno; FlushFileBuffers(fd->handle); + errno = e; + } + + // if this file descriptor is wrapped in a named pipe worker thread + // then we need to close our copy of the worker thread handle. it's + // also required that whatever install a worker use malloc, so free + if (fd->worker) { + if (!weaken(UnrefNtStdinWorker)(fd->worker)) ok = false; + fd->worker = 0; + } else { + if (!CloseHandle(fd->handle)) ok = false; } - ok = CloseHandle(fd->handle); if (fd->kind == kFdConsole && fd->extra && fd->extra != -1) { - ok &= CloseHandle(fd->extra); + if (!CloseHandle(fd->extra)) ok = false; } - return ok ? 0 : __winerr(); + + return ok ? 0 : -1; } diff --git a/libc/calls/close.c b/libc/calls/close.c index 680120710..13cfe7b21 100644 --- a/libc/calls/close.c +++ b/libc/calls/close.c @@ -19,7 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/macros.internal.h" #include "libc/sock/internal.h" #include "libc/sysv/errfuns.h" @@ -31,36 +31,52 @@ * This function may be used for file descriptors returned by socket, * accept, epoll_create, and zipos file descriptors too. * + * This function should never be called twice for the same file + * descriptor, regardless of whether or not an error happened. However + * that doesn't mean the error should be ignored. + * * @return 0 on success, or -1 w/ errno + * @error EINTR means a signal was received while closing (possibly + * because linger is enabled) in which case close() does not need to + * be called again, since the fd will close in the background, and + * chances are that on linux, the fd is already closed, even if the + * underlying resource isn't closed yet * @asyncsignalsafe * @vforksafe */ int close(int fd) { int rc; - if (fd == -1) return 0; - if (fd < 0) return einval(); - if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - rc = weaken(__zipos_close)(fd); + if (fd == -1) { + rc = 0; + } else if (fd < 0) { + rc = einval(); } else { - if (!IsWindows() && !IsMetal()) { - rc = sys_close(fd); - } else if (IsMetal()) { - rc = 0; + if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { + rc = weaken(__zipos_close)(fd); } else { - if (fd < g_fds.n && g_fds.p[fd].kind == kFdEpoll) { - rc = weaken(sys_close_epoll_nt)(fd); - } else if (fd < g_fds.n && g_fds.p[fd].kind == kFdSocket) { - rc = weaken(sys_closesocket_nt)(g_fds.p + fd); - } else if (fd < g_fds.n && (g_fds.p[fd].kind == kFdFile || - g_fds.p[fd].kind == kFdConsole || - g_fds.p[fd].kind == kFdProcess)) { - rc = sys_close_nt(g_fds.p + fd); + if (!IsWindows() && !IsMetal()) { + rc = sys_close(fd); + } else if (IsMetal()) { + rc = 0; } else { - rc = ebadf(); + if (fd < g_fds.n && g_fds.p[fd].kind == kFdEpoll) { + rc = weaken(sys_close_epoll_nt)(fd); + } else if (fd < g_fds.n && g_fds.p[fd].kind == kFdSocket) { + rc = weaken(sys_closesocket_nt)(g_fds.p + fd); + } else if (fd < g_fds.n && (g_fds.p[fd].kind == kFdFile || + g_fds.p[fd].kind == kFdConsole || + g_fds.p[fd].kind == kFdProcess)) { + rc = sys_close_nt(g_fds.p + fd); + } else { + STRACE("close(%d) unknown kind: %d", fd, g_fds.p[fd].kind); + rc = ebadf(); + } } } + if (!__vforked) { + __releasefd(fd); + } } - __releasefd(fd); - SYSDEBUG("close(%d) -> %d", fd, rc); + STRACE("%s(%d) → %d% m", "close", fd, rc); return rc; } diff --git a/libc/calls/commandv.c b/libc/calls/commandv.c index ced97a9b1..79ad7b629 100644 --- a/libc/calls/commandv.c +++ b/libc/calls/commandv.c @@ -16,60 +16,69 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" #include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/errno.h" #include "libc/log/libfatal.internal.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" +#include "libc/sysv/consts/ok.h" #include "libc/sysv/errfuns.h" -static noasan bool EndsWithIgnoreCase(const char *p, size_t n, const char *s) { - size_t i, m; - m = __strlen(s); - if (n >= m) { - for (i = n - m; i < n; ++i) { - if (kToLower[p[i] & 255] != (*s++ & 255)) { - return false; - } - } - return true; - } else { - return false; - } +static bool IsExePath(const char *s, size_t n) { + return n >= 4 && (READ32LE(s + n - 4) == READ32LE(".exe") || + READ32LE(s + n - 4) == READ32LE(".EXE")); } -static noasan bool AccessCommand(const char *name, - char path[hasatleast PATH_MAX], size_t namelen, - const char *suffix, size_t pathlen) { +static bool IsComPath(const char *s, size_t n) { + return n >= 4 && (READ32LE(s + n - 4) == READ32LE(".com") || + READ32LE(s + n - 4) == READ32LE(".COM")); +} + +static bool IsComDbgPath(const char *s, size_t n) { + return n >= 8 && (READ64LE(s + n - 8) == READ64LE(".com.dbg") || + READ64LE(s + n - 8) == READ64LE(".COM.DBG")); +} + +static bool AccessCommand(const char *name, char *path, size_t pathsz, + size_t namelen, int *err, const char *suffix, + size_t pathlen) { size_t suffixlen; - suffixlen = __strlen(suffix); - if (pathlen + 1 + namelen + suffixlen + 1 > PATH_MAX) return -1; + suffixlen = strlen(suffix); + if (pathlen + 1 + namelen + suffixlen + 1 > pathsz) return false; if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) { - path[pathlen] = !IsWindows() ? '/' - : __memchr(path, '\\', pathlen) ? '\\' - : '/'; + path[pathlen] = !IsWindows() ? '/' + : memchr(path, '\\', pathlen) ? '\\' + : '/'; pathlen++; } - __repmovsb(path + pathlen, name, namelen); - __repmovsb(path + pathlen + namelen, suffix, suffixlen + 1); - return isexecutable(path); + memcpy(path + pathlen, name, namelen); + memcpy(path + pathlen + namelen, suffix, suffixlen + 1); + if (!access(path, X_OK)) return true; + if (errno == EACCES || *err != EACCES) *err = errno; + return false; } -static noasan bool SearchPath(const char *name, char path[hasatleast PATH_MAX], - size_t namelen, const char *suffix) { +static bool SearchPath(const char *name, char *path, size_t pathsz, + size_t namelen, int *err, const char *suffix) { + char sep; size_t i; const char *p; - p = firstnonnull(emptytonull(getenv("PATH")), "/bin:/usr/local/bin:/usr/bin"); + if (!(p = getenv("PATH"))) p = "/bin:/usr/local/bin:/usr/bin"; + sep = IsWindows() && strchr(p, ';') ? ';' : ':'; for (;;) { - for (i = 0; p[i] && p[i] != ':' && p[i] != ';'; ++i) { - if (i < PATH_MAX) { + for (i = 0; p[i] && p[i] != sep; ++i) { + if (i < pathsz) { path[i] = p[i]; } } - if (AccessCommand(name, path, namelen, suffix, i)) { + if (AccessCommand(name, path, pathsz, namelen, err, suffix, i)) { return true; } - if (p[i] == ':' || p[i] == ';') { + if (p[i] == sep) { p += i + 1; } else { break; @@ -78,21 +87,36 @@ static noasan bool SearchPath(const char *name, char path[hasatleast PATH_MAX], return false; } -static noasan bool FindCommand(const char *name, - char pathbuf[hasatleast PATH_MAX], - size_t namelen, const char *suffix) { - if (memchr(name, '/', namelen) || memchr(name, '\\', namelen)) { - pathbuf[0] = 0; - return AccessCommand(name, pathbuf, namelen, suffix, 0); +static bool FindCommand(const char *name, char *pb, size_t pbsz, size_t namelen, + bool pri, const char *suffix, int *err) { + if (pri && (memchr(name, '/', namelen) || memchr(name, '\\', namelen))) { + pb[0] = 0; + return AccessCommand(name, pb, pbsz, namelen, err, suffix, 0); } - return ((IsWindows() && - (AccessCommand(name, pathbuf, namelen, suffix, - stpcpy(pathbuf, kNtSystemDirectory) - pathbuf) || - AccessCommand(name, pathbuf, namelen, suffix, - stpcpy(pathbuf, kNtWindowsDirectory) - pathbuf) || - AccessCommand(name, pathbuf, namelen, suffix, - stpcpy(pathbuf, ".") - pathbuf))) || - SearchPath(name, pathbuf, namelen, suffix)); + if (IsWindows() && pri && + pbsz > max(strlen(kNtSystemDirectory), strlen(kNtWindowsDirectory))) { + return AccessCommand(name, pb, pbsz, namelen, err, suffix, + stpcpy(pb, kNtSystemDirectory) - pb) || + AccessCommand(name, pb, pbsz, namelen, err, suffix, + stpcpy(pb, kNtWindowsDirectory) - pb); + } + return (IsWindows() && + (pbsz > 1 && AccessCommand(name, pb, pbsz, namelen, err, suffix, + stpcpy(pb, ".") - pb))) || + SearchPath(name, pb, pbsz, namelen, err, suffix); +} + +static bool FindVerbatim(const char *name, char *pb, size_t pbsz, + size_t namelen, bool pri, int *err) { + return FindCommand(name, pb, pbsz, namelen, pri, "", err); +} + +static bool FindSuffixed(const char *name, char *pb, size_t pbsz, + size_t namelen, bool pri, int *err) { + return !IsExePath(name, namelen) && !IsComPath(name, namelen) && + !IsComDbgPath(name, namelen) && + (FindCommand(name, pb, pbsz, namelen, pri, ".com", err) || + FindCommand(name, pb, pbsz, namelen, pri, ".exe", err)); } /** @@ -104,29 +128,36 @@ static noasan bool FindCommand(const char *name, * @asyncsignalsafe * @vforksafe */ -noasan char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) { - int olderr; +char *commandv(const char *name, char *pathbuf, size_t pathbufsz) { + int e, f; + char *res; size_t namelen; + res = 0; if (!name) { efault(); - return 0; - } - if (!(namelen = __strlen(name))) { + } else if (!(namelen = strlen(name))) { enoent(); - return 0; - } - if (namelen + 1 > PATH_MAX) { + } else if (namelen + 1 > pathbufsz) { enametoolong(); - return 0; - } - if (FindCommand(name, pathbuf, namelen, "") || - (!EndsWithIgnoreCase(name, namelen, ".exe") && - !EndsWithIgnoreCase(name, namelen, ".com") && - !EndsWithIgnoreCase(name, namelen, ".com.dbg") && - (FindCommand(name, pathbuf, namelen, ".com") || - FindCommand(name, pathbuf, namelen, ".exe")))) { - return pathbuf; } else { - return 0; + e = errno; + f = ENOENT; + if ((IsWindows() && + (FindSuffixed(name, pathbuf, pathbufsz, namelen, true, &f) || + FindVerbatim(name, pathbuf, pathbufsz, namelen, true, &f) || + FindSuffixed(name, pathbuf, pathbufsz, namelen, false, &f) || + FindVerbatim(name, pathbuf, pathbufsz, namelen, false, &f))) || + (!IsWindows() && + (FindVerbatim(name, pathbuf, pathbufsz, namelen, true, &f) || + FindSuffixed(name, pathbuf, pathbufsz, namelen, true, &f) || + FindVerbatim(name, pathbuf, pathbufsz, namelen, false, &f) || + FindSuffixed(name, pathbuf, pathbufsz, namelen, false, &f)))) { + errno = e; + res = pathbuf; + } else { + errno = f; + } } + STRACE("commandv(%#s, %p, %'zu) → %#s% m", name, pathbuf, pathbufsz, res); + return res; } diff --git a/libc/calls/copyfile.c b/libc/calls/copyfile.c index 5c4c91196..270532537 100644 --- a/libc/calls/copyfile.c +++ b/libc/calls/copyfile.c @@ -20,6 +20,7 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" +#include "libc/intrin/kprintf.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" @@ -27,6 +28,7 @@ #include "libc/nt/enum/filesharemode.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" +#include "libc/nt/struct/filetime.h" #include "libc/sysv/consts/at.h" #include "libc/sysv/consts/madv.h" #include "libc/sysv/consts/o.h" @@ -66,12 +68,12 @@ static int sys_copyfile(const char *src, const char *dst, int flags) { int64_t inoffset, outoffset; int rc, srcfd, dstfd, oflags, omode; rc = -1; - if ((srcfd = sys_openat(AT_FDCWD, src, O_RDONLY, 0)) != -1) { - if (sys_fstat(srcfd, &st) != -1) { + if ((srcfd = openat(AT_FDCWD, src, O_RDONLY, 0)) != -1) { + if (fstat(srcfd, &st) != -1) { omode = st.st_mode & 0777; oflags = O_WRONLY | O_CREAT; if (flags & COPYFILE_NOCLOBBER) oflags |= O_EXCL; - if ((dstfd = sys_openat(AT_FDCWD, dst, oflags, omode)) != -1) { + if ((dstfd = openat(AT_FDCWD, dst, oflags, omode)) != -1) { remaining = st.st_size; ftruncate(dstfd, remaining); inoffset = 0; @@ -86,13 +88,13 @@ static int sys_copyfile(const char *src, const char *dst, int flags) { if (flags & COPYFILE_PRESERVE_TIMESTAMPS) { amtime[0] = st.st_atim; amtime[1] = st.st_mtim; - sys_utimensat(dstfd, NULL, amtime, 0); + utimensat(dstfd, NULL, amtime, 0); } } - rc |= sys_close(dstfd); + rc |= close(dstfd); } } - rc |= sys_close(srcfd); + rc |= close(srcfd); } return rc; } @@ -108,7 +110,7 @@ static int sys_copyfile(const char *src, const char *dst, int flags) { * @return 0 on success, or -1 w/ errno */ int copyfile(const char *src, const char *dst, int flags) { - if (!IsWindows()) { + if (!IsWindows() || startswith(src, "/zip/") || startswith(dst, "/zip/")) { return sys_copyfile(src, dst, flags); } else { return sys_copyfile_nt(src, dst, flags); diff --git a/libc/calls/creat.c b/libc/calls/creat.c index a16f076bb..46a3d7442 100644 --- a/libc/calls/creat.c +++ b/libc/calls/creat.c @@ -35,6 +35,6 @@ * @see open(), touch() * @asyncsignalsafe */ -nodiscard int creat(const char *file, uint32_t mode) { +dontdiscard int creat(const char *file, uint32_t mode) { return openat(AT_FDCWD, file, O_CREAT | O_WRONLY | O_TRUNC, mode); } diff --git a/libc/calls/createfileflags.c b/libc/calls/createfileflags.c new file mode 100644 index 000000000..d90d3cc94 --- /dev/null +++ b/libc/calls/createfileflags.c @@ -0,0 +1,110 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/calls/calls.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/creationdisposition.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/enum/filesharemode.h" +#include "libc/sysv/consts/o.h" + +// code size optimization +// +#define _O_APPEND 0x00000400 // kNtFileAppendData +#define _O_CREAT 0x00000040 // kNtOpenAlways +#define _O_EXCL 0x00000080 // kNtCreateNew +#define _O_TRUNC 0x00000200 // kNtCreateAlways +#define _O_DIRECTORY 0x00010000 // kNtFileFlagBackupSemantics +#define _O_TMPFILE 0x00410000 // AttributeTemporary|FlagDeleteOnClose +#define _O_DIRECT 0x00004000 // kNtFileFlagNoBuffering +#define _O_NDELAY 0x00000800 // kNtFileFlagWriteThrough +#define _O_RANDOM 0x80000000 // kNtFileFlagRandomAccess +#define _O_SEQUENTIAL 0x40000000 // kNtFileFlagSequentialScan +#define _O_COMPRESSED 0x20000000 // kNtFileAttributeCompressed +#define _O_INDEXED 0x10000000 // !kNtFileAttributeNotContentIndexed +#define _O_NONBLOCK 0x00000800 +#define _O_CLOEXEC 0x00080000 +// + +textwindows int GetNtOpenFlags(int flags, int mode, uint32_t *out_perm, + uint32_t *out_share, uint32_t *out_disp, + uint32_t *out_attr) { + uint32_t perm, share, disp, attr; + + switch (flags & O_ACCMODE) { + case O_RDONLY: + perm = kNtFileGenericRead | kNtGenericExecute; + break; + case O_WRONLY: + perm = kNtFileGenericWrite | kNtGenericExecute; + break; + case O_RDWR: + perm = kNtFileGenericRead | kNtFileGenericWrite | kNtGenericExecute; + break; + default: + return -1; + } + if (flags & _O_APPEND) { + perm = kNtFileAppendData; + } + + if (flags & _O_EXCL) { + share = kNtFileShareExclusive; + } else { + share = kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete; + } + + if ((flags & _O_CREAT) && (flags & _O_EXCL)) { + disp = kNtCreateNew; + } else if ((flags & _O_CREAT) && (flags & _O_TRUNC)) { + disp = kNtCreateAlways; + } else if (flags & _O_CREAT) { + disp = kNtOpenAlways; + } else if (flags & _O_TRUNC) { + disp = kNtTruncateExisting; + } else { + disp = kNtOpenExisting; + } + + if ((flags & _O_TMPFILE) == _O_TMPFILE) { + attr = kNtFileAttributeTemporary | kNtFileFlagDeleteOnClose; + } else { + attr = kNtFileAttributeNormal; + if (flags & _O_DIRECTORY) { + attr |= kNtFileFlagBackupSemantics; + } + if (~mode & 0200) { + attr |= kNtFileAttributeReadonly; + } + } + + if (~flags & _O_INDEXED) attr |= kNtFileAttributeNotContentIndexed; + if (flags & _O_COMPRESSED) attr |= kNtFileAttributeCompressed; + if (flags & _O_SEQUENTIAL) attr |= kNtFileFlagSequentialScan; + if (flags & _O_RANDOM) attr |= kNtFileFlagRandomAccess; + if (flags & _O_DIRECT) attr |= kNtFileFlagNoBuffering; + if (flags & _O_NDELAY) attr |= kNtFileFlagWriteThrough; + + if (out_perm) *out_perm = perm; + if (out_share) *out_share = share; + if (out_disp) *out_disp = disp; + if (out_attr) *out_attr = attr; + return 0; +} diff --git a/libc/calls/createpipename.c b/libc/calls/createpipename.c index 8b81f5e25..5c3464e5d 100644 --- a/libc/calls/createpipename.c +++ b/libc/calls/createpipename.c @@ -16,32 +16,35 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/alg/reverse.internal.h" #include "libc/calls/calls.h" +#include "libc/intrin/lockxadd.h" #include "libc/nt/process.h" -static const char kPipeNamePrefix[] = "\\\\?\\pipe\\cosmo\\"; - -static textwindows size_t UintToChar16Array(char16_t *a, uint64_t i) { - size_t j = 0; +static textwindows char16_t *UintToChar16Array(char16_t p[21], uint64_t x) { + char t; + size_t a, b, i = 0; do { - a[j++] = i % 10 + '0'; - i /= 10; - } while (i > 0); - a[j] = 0; - reverse(a, j); - return j; + p[i++] = x % 10 + '0'; + x = x / 10; + } while (x > 0); + if (i) { + for (a = 0, b = i - 1; a < b; ++a, --b) { + t = p[a]; + p[a] = p[b]; + p[b] = t; + } + } + return p + i; } textwindows char16_t *CreatePipeName(char16_t *a) { static long x; - unsigned i; - for (i = 0; kPipeNamePrefix[i]; ++i) a[i] = kPipeNamePrefix[i]; - i += UintToChar16Array(a + i, GetCurrentProcessId()); - a[i++] = u'-'; - i += UintToChar16Array(a + i, GetCurrentProcessId()); - a[i++] = u'-'; - i += UintToChar16Array(a + i, x++); - a[i] = u'\0'; + char16_t *p = a; + const char *q = "\\\\?\\pipe\\cosmo\\"; + while (*q) *p++ = *q++; + p = UintToChar16Array(p, GetCurrentProcessId()); + *p++ = '-'; + p = UintToChar16Array(p, _lockxadd(&x, 1)); + *p = 0; return a; } diff --git a/libc/calls/describeclockname.c b/libc/calls/describeclockname.c new file mode 100644 index 000000000..5a32ff0cc --- /dev/null +++ b/libc/calls/describeclockname.c @@ -0,0 +1,38 @@ +/*-*- 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 2022 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/fmt/itoa.h" +#include "libc/fmt/magnumstrs.internal.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sol.h" + +/** + * Describes clock_gettime() clock argument. + */ +char *DescribeClockName(int x) { + int i; + char *s; + _Alignas(char) static char buf[32]; + if ((s = GetMagnumStr(kClockNames, x))) { + stpcpy(stpcpy(buf, "CLOCK_"), s); + return buf; + } else { + FormatInt32(buf, x); + return buf; + } +} diff --git a/libc/runtime/describeframe.c b/libc/calls/describeframe.c similarity index 89% rename from libc/runtime/describeframe.c rename to libc/calls/describeframe.c index 6d1f04e09..1dc78593f 100644 --- a/libc/runtime/describeframe.c +++ b/libc/calls/describeframe.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/log/libfatal.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" @@ -28,21 +28,19 @@ noasan const char *DescribeFrame(int x) { /* asan runtime depends on this function */ char *p; - static char buf[128]; + static char buf[32]; if (IsShadowFrame(x)) { - p = buf; - p = __stpcpy(p, " shadow of "); - p = __fixcpy(p, UNSHADOW(ADDR(x)), 48); + ksnprintf(buf, sizeof(buf), " /*shadow:%.12p*/", UNSHADOW(ADDR(x))); return buf; - return " shadow "; + return " /*shadow*/ "; } else if (IsAutoFrame(x)) { - return " automap"; + return " /*automap*/"; } else if (IsFixedFrame(x)) { - return " fixed "; + return " /*fixed*/ "; } else if (IsArenaFrame(x)) { - return " arena "; + return " /*arena*/ "; } else if (IsStaticStackFrame(x)) { - return " stack "; + return " /*stack*/ "; } else { return ""; } diff --git a/libc/runtime/describemapping.c b/libc/calls/describemapping.c similarity index 84% rename from libc/runtime/describemapping.c rename to libc/calls/describemapping.c index 3dffeab43..9d2aceaa2 100644 --- a/libc/runtime/describemapping.c +++ b/libc/calls/describemapping.c @@ -20,19 +20,32 @@ #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" -noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) { - /* asan runtime depends on this function */ +static noasan char DescribeMapType(int flags) { + switch (flags & MAP_TYPE) { + case MAP_FILE: + return 'f'; + case MAP_PRIVATE: + return 'p'; + case MAP_SHARED: + return 's'; + default: + return '?'; + } +} + +noasan char *DescribeProt(int prot, char p[hasatleast 4]) { p[0] = (prot & PROT_READ) ? 'r' : '-'; p[1] = (prot & PROT_WRITE) ? 'w' : '-'; p[2] = (prot & PROT_EXEC) ? 'x' : '-'; - if (flags & MAP_PRIVATE) { - p[3] = 'p'; - } else if (flags & MAP_SHARED) { - p[3] = 's'; - } else { - p[3] = '?'; - } - p[4] = (flags & MAP_ANONYMOUS) ? 'a' : 'f'; + p[3] = 0; + return p; +} + +noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) { + /* asan runtime depends on this function */ + DescribeProt(prot, p); + p[3] = DescribeMapType(flags); + p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-'; p[5] = (flags & MAP_GROWSDOWN) ? 'S' : '-'; p[6] = (flags & MAP_FIXED) ? 'F' : '-'; p[7] = 0; diff --git a/libc/calls/describeopenflags.greg.c b/libc/calls/describeopenflags.greg.c new file mode 100644 index 000000000..57ab7a46a --- /dev/null +++ b/libc/calls/describeopenflags.greg.c @@ -0,0 +1,41 @@ +/*-*- 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 2022 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/fmt/itoa.h" +#include "libc/fmt/magnumstrs.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/mem/alloca.h" +#include "libc/sysv/consts/sol.h" + +/** + * Describes clock_gettime() clock argument. + */ +char *DescribeOpenFlags(int x) { + char *s; + int i, n; + struct DescribeFlags *d; + _Alignas(char) static char openflags[128]; + // TODO(jart): unify DescribeFlags and MagnumStr data structures + for (n = 0; kOpenFlags[n].x != MAGNUM_TERMINATOR;) ++n; + d = alloca(n * sizeof(struct DescribeFlags)); + for (i = 0; i < n; ++i) { + d[i].flag = MAGNUM_NUMBER(kOpenFlags, i); + d[i].name = MAGNUM_STRING(kOpenFlags, i); + } + return DescribeFlags(openflags, sizeof(openflags), d, n, "O_", x); +} diff --git a/libc/runtime/directmap-metal.c b/libc/calls/directmap-metal.c similarity index 100% rename from libc/runtime/directmap-metal.c rename to libc/calls/directmap-metal.c diff --git a/libc/calls/directmap-nt.c b/libc/calls/directmap-nt.c new file mode 100644 index 000000000..78e1f58ee --- /dev/null +++ b/libc/calls/directmap-nt.c @@ -0,0 +1,102 @@ +/*-*- 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 "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/enum/pageflags.h" +#include "libc/nt/memory.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/processmemorycounters.h" +#include "libc/runtime/directmap.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" + +textwindows struct DirectMap sys_mmap_nt(void *addr, size_t size, int prot, + int flags, int fd, int64_t off) { + size_t i; + bool iscow; + int64_t handle; + uint32_t oldprot; + struct DirectMap dm; + struct ProtectNt fl; + const struct NtSecurityAttributes *sec; + struct NtProcessMemoryCountersEx memcount; + + if (fd != -1) { + handle = g_fds.p[fd].handle; + } else { + handle = kNtInvalidHandleValue; + } + + if (flags & MAP_PRIVATE) { + sec = 0; // MAP_PRIVATE isn't inherited across fork() + } else { + sec = &kNtIsInheritable; // MAP_SHARED gives us zero-copy fork() + } + + // nt will whine under many circumstances if we change the execute bit + // later using mprotect(). the workaround is to always request execute + // and then virtualprotect() it away until we actually need it. please + // note that open-nt.c always requests an kNtGenericExecute accessmask + iscow = false; + if (handle != -1) { + if (flags & MAP_PRIVATE) { + // windows has cow pages but they can't propagate across fork() + // that means we only get copy-on-write for the root process :( + fl = (struct ProtectNt){kNtPageExecuteWritecopy, + kNtFileMapCopy | kNtFileMapExecute}; + iscow = true; + } else { + assert(flags & MAP_SHARED); + if ((g_fds.p[fd].flags & O_ACCMODE) == O_RDONLY) { + fl = (struct ProtectNt){kNtPageExecuteRead, + kNtFileMapRead | kNtFileMapExecute}; + } else { + fl = (struct ProtectNt){kNtPageExecuteReadwrite, + kNtFileMapWrite | kNtFileMapExecute}; + } + } + } else { + assert(flags & MAP_ANONYMOUS); + fl = (struct ProtectNt){kNtPageExecuteReadwrite, + kNtFileMapWrite | kNtFileMapExecute}; + } + + if ((dm.maphandle = CreateFileMapping(handle, sec, fl.flags1, + (size + off) >> 32, (size + off), 0))) { + if ((dm.addr = MapViewOfFileEx(dm.maphandle, fl.flags2, off >> 32, off, + size, addr))) { + if (VirtualProtect(addr, size, __prot2nt(prot, iscow), &oldprot)) { + return dm; + } else { + return dm; + UnmapViewOfFile(dm.addr); + } + } + CloseHandle(dm.maphandle); + } + + dm.maphandle = kNtInvalidHandleValue; + dm.addr = (void *)(intptr_t)-1; + return dm; +} diff --git a/libc/runtime/directmap.c b/libc/calls/directmap.c similarity index 75% rename from libc/runtime/directmap.c rename to libc/calls/directmap.c index ab1a121b8..7c8a12d6d 100644 --- a/libc/runtime/directmap.c +++ b/libc/calls/directmap.c @@ -17,8 +17,9 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/errno.h" +#include "libc/intrin/describeflags.internal.h" #include "libc/nt/runtime.h" #include "libc/runtime/directmap.internal.h" #include "libc/runtime/memtrack.internal.h" @@ -31,25 +32,24 @@ * support Windows NT and Address Sanitizer. That memory tracking can be * bypassed by calling this function. However the caller is responsible * for passing the magic memory handle on Windows NT to CloseHandle(). + * + * @asyncsignalsafe + * @threadsafe */ -noasan struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, - int fd, int64_t off) { +struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd, + int64_t off) { /* asan runtime depends on this function */ - char mode[8]; - struct DirectMap dm; + struct DirectMap d; if (!IsWindows() && !IsMetal()) { - dm.addr = __sys_mmap(addr, size, prot, flags, fd, off, off); - SYSDEBUG("sys_mmap(0x%p%s, 0x%x, %s, %d, %d) -> 0x%p %s", addr, - DescribeFrame((intptr_t)addr >> 16), size, - DescribeMapping(prot, flags, mode), (long)fd, off, dm.addr, - dm.addr != MAP_FAILED ? "" : strerror(errno)); - dm.maphandle = kNtInvalidHandleValue; - return dm; + d.addr = __sys_mmap(addr, size, prot, flags, fd, off, off); + d.maphandle = kNtInvalidHandleValue; } else if (IsMetal()) { - return sys_mmap_metal(addr, size, prot, flags, fd, off); + d = sys_mmap_metal(addr, size, prot, flags, fd, off); } else { - return sys_mmap_nt(addr, size, prot, flags, - fd != -1 ? g_fds.p[fd].handle : kNtInvalidHandleValue, - off); + d = sys_mmap_nt(addr, size, prot, flags, fd, off); } + KERNTRACE("sys_mmap(%.12p%s, %'zu, %s, %s, %d, %'ld) → {%.12p, %p}% m", addr, + DescribeFrame((intptr_t)addr >> 16), size, DescribeProtFlags(prot), + DescribeMapFlags(flags), fd, off, d.addr, d.maphandle); + return d; } diff --git a/libc/calls/dup-nt.c b/libc/calls/dup-nt.c index 0e2727907..ba52b9e20 100644 --- a/libc/calls/dup-nt.c +++ b/libc/calls/dup-nt.c @@ -17,38 +17,69 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/mem/mem.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" +#include "libc/sock/internal.h" +#include "libc/sock/ntstdin.internal.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" /** - * Implements dup(), dup2(), and dup3() for Windows NT. + * Implements dup(), dup2(), dup3(), and F_DUPFD for Windows. */ -textwindows int sys_dup_nt(int oldfd, int newfd, int flags) { - int64_t proc; +textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) { + int64_t proc, handle; + + // validate the api usage if (oldfd < 0) return einval(); + if (flags & ~O_CLOEXEC) return einval(); if (oldfd >= g_fds.n || (g_fds.p[oldfd].kind != kFdFile && g_fds.p[oldfd].kind != kFdSocket && g_fds.p[oldfd].kind != kFdConsole)) { return ebadf(); } + + // allocate a new file descriptor if (newfd == -1) { - if ((newfd = __reservefd()) == -1) return -1; + if ((newfd = __reservefd(start)) == -1) { + return -1; + } } else { if (__ensurefds(newfd) == -1) return -1; if (g_fds.p[newfd].kind) close(newfd); g_fds.p[newfd].kind = kFdReserved; } + + // if this file descriptor is wrapped in a named pipe worker thread + // then we should clone the original authentic handle rather than the + // stdin worker's named pipe. we won't clone the worker, since that + // can always be recreated again on demand. + if (g_fds.p[oldfd].worker) { + handle = g_fds.p[oldfd].worker->reader; + } else { + handle = g_fds.p[oldfd].handle; + } + proc = GetCurrentProcess(); - if (DuplicateHandle(proc, g_fds.p[oldfd].handle, proc, &g_fds.p[newfd].handle, - 0, true, kNtDuplicateSameAccess)) { + if (DuplicateHandle(proc, handle, proc, &g_fds.p[newfd].handle, 0, true, + kNtDuplicateSameAccess)) { g_fds.p[newfd].kind = g_fds.p[oldfd].kind; - g_fds.p[newfd].extra = g_fds.p[oldfd].extra; - g_fds.p[newfd].flags = flags; + g_fds.p[newfd].mode = g_fds.p[oldfd].mode; + g_fds.p[newfd].flags = g_fds.p[oldfd].flags & ~O_CLOEXEC; + if (flags & O_CLOEXEC) g_fds.p[newfd].flags |= O_CLOEXEC; + if (g_fds.p[oldfd].kind == kFdSocket && weaken(_dupsockfd)) { + g_fds.p[newfd].extra = + (intptr_t)weaken(_dupsockfd)((struct SockFd *)g_fds.p[oldfd].extra); + } else { + g_fds.p[newfd].extra = g_fds.p[oldfd].extra; + } + if (g_fds.p[oldfd].worker) { + g_fds.p[newfd].worker = weaken(RefNtStdinWorker)(g_fds.p[oldfd].worker); + } return newfd; } else { __releasefd(newfd); diff --git a/libc/calls/dup.c b/libc/calls/dup.c index 13b9ee6e3..84ce876ee 100644 --- a/libc/calls/dup.c +++ b/libc/calls/dup.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" /** @@ -34,8 +34,8 @@ int dup(int fd) { if (!IsWindows()) { fd2 = sys_dup(fd); } else { - fd2 = sys_dup_nt(fd, -1, 0); + fd2 = sys_dup_nt(fd, -1, 0, -1); } - SYSDEBUG("dup(%d) -> %d", fd, fd2); + STRACE("%s(%d) → %d% m", "dup", fd, fd2); return fd2; } diff --git a/libc/calls/dup2.c b/libc/calls/dup2.c index 4ec133e97..ab8b79449 100644 --- a/libc/calls/dup2.c +++ b/libc/calls/dup2.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" /** @@ -32,11 +32,14 @@ * @vforksafe */ int dup2(int oldfd, int newfd) { - SYSDEBUG("dup2(%d, %d)", oldfd, newfd); - if (oldfd == newfd) return newfd; - if (!IsWindows()) { - return sys_dup3(oldfd, newfd, 0); + int rc; + if (oldfd == newfd) { + rc = newfd; + } else if (!IsWindows()) { + rc = sys_dup3(oldfd, newfd, 0); } else { - return sys_dup_nt(oldfd, newfd, 0); + rc = sys_dup_nt(oldfd, newfd, 0, -1); } + STRACE("dup2(%d, %d) → %d% m", oldfd, newfd, rc); + return rc; } diff --git a/libc/calls/dup3-sysv.c b/libc/calls/dup3-sysv.c index 400e7a638..ec9f64650 100644 --- a/libc/calls/dup3-sysv.c +++ b/libc/calls/dup3-sysv.c @@ -17,17 +17,17 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/errno.h" -#define __NR_dup3_linux 0x0124 /*RHEL5:CVE-2010-3301*/ - int32_t sys_dup3(int32_t oldfd, int32_t newfd, int flags) { static bool once, demodernize; int olderr, fd; if (!once) { olderr = errno; fd = __sys_dup3(oldfd, newfd, flags); - if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) { + if (fd == -1 && errno == ENOSYS) { + STRACE("demodernizing %s() due to %s", "dup3", "RHEL5:CVE-2010-3301"); demodernize = true; once = true; errno = olderr; diff --git a/libc/calls/dup3.c b/libc/calls/dup3.c index fc6e19858..f19dccab9 100644 --- a/libc/calls/dup3.c +++ b/libc/calls/dup3.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/sysv/errfuns.h" @@ -32,14 +32,16 @@ * @param oldfd isn't closed afterwards * @param newfd if already assigned, is silently closed beforehand; * unless it's equal to oldfd, in which case dup2() is a no-op - * @flags can have O_CLOEXEC + * @param flags can have O_CLOEXEC * @see dup(), dup2() */ int dup3(int oldfd, int newfd, int flags) { - SYSDEBUG("dup3(%d, %d, %d)", oldfd, newfd, flags); + int rc; if (!IsWindows()) { - return sys_dup3(oldfd, newfd, flags); + rc = sys_dup3(oldfd, newfd, flags); } else { - return sys_dup_nt(oldfd, newfd, flags); + rc = sys_dup_nt(oldfd, newfd, flags, -1); } + STRACE("dup3(%d, %d, %d) → %d% m", oldfd, newfd, flags, rc); + return rc; } diff --git a/libc/calls/ensurefds.c b/libc/calls/ensurefds.c deleted file mode 100644 index e036b8784..000000000 --- a/libc/calls/ensurefds.c +++ /dev/null @@ -1,63 +0,0 @@ -/*-*- 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 "libc/assert.h" -#include "libc/bits/bits.h" -#include "libc/bits/weaken.h" -#include "libc/calls/internal.h" -#include "libc/mem/mem.h" -#include "libc/str/str.h" -#include "libc/sysv/errfuns.h" - -static void __ensurefds_destroy(void) { - weaken(free)(g_fds.p); -} - -int __ensurefds(int fd) { - size_t n1, n2; - struct Fd *p1, *p2; - for (;;) { - p1 = g_fds.p; - n1 = g_fds.n; - if (fd < n1) return fd; - if (weaken(malloc)) { - n2 = MAX(fd + 1, n1 + (n1 << 1)); - if ((p2 = weaken(malloc)(n2 * sizeof(*p1)))) { - memcpy(p2, p1, n1 * sizeof(*p1)); - bzero(p2 + n1, (n2 - n1) * sizeof(*p1)); - if (cmpxchg(&g_fds.p, p1, p2)) { - g_fds.n = n2; - if (weaken(free)) { - if (p1 == g_fds.__init_p) { - atexit(__ensurefds_destroy); - } else { - weaken(free)(p1); - } - } - return fd; - } else if (weaken(free)) { - weaken(free)(p2); - } - } else { - return enomem(); - } - } else { - return emfile(); - } - } -} diff --git a/libc/calls/execlp.c b/libc/calls/execlp.c index 3444fe589..a2d97538d 100644 --- a/libc/calls/execlp.c +++ b/libc/calls/execlp.c @@ -40,7 +40,7 @@ int execlp(const char *prog, const char *arg, ... /*, NULL*/) { char **argv; va_list va, vb; char pathbuf[PATH_MAX]; - if (!(exe = commandv(prog, pathbuf))) return -1; + if (!(exe = commandv(prog, pathbuf, sizeof(pathbuf)))) return -1; va_copy(vb, va); va_start(va, arg); for (i = 0; va_arg(va, const char *); ++i) donothing; diff --git a/libc/calls/execve-nt.c b/libc/calls/execve-nt.c index 8a8887e0e..c45128e8c 100644 --- a/libc/calls/execve-nt.c +++ b/libc/calls/execve-nt.c @@ -27,6 +27,7 @@ #include "libc/nt/struct/processinformation.h" #include "libc/nt/struct/startupinfo.h" #include "libc/nt/synchronization.h" +#include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" @@ -40,9 +41,9 @@ textwindows int sys_execve_nt(const char *program, char *const argv[], bzero(&startinfo, sizeof(startinfo)); startinfo.cb = sizeof(struct NtStartupInfo); startinfo.dwFlags = kNtStartfUsestdhandles; - startinfo.hStdInput = g_fds.p[0].handle; - startinfo.hStdOutput = g_fds.p[1].handle; - startinfo.hStdError = g_fds.p[2].handle; + startinfo.hStdInput = __getfdhandleactual(0); + startinfo.hStdOutput = __getfdhandleactual(1); + startinfo.hStdError = __getfdhandleactual(2); rc = ntspawn(program, argv, envp, 0, 0, 0, 1, 0, 0, &startinfo, &procinfo); if (rc == -1) return -1; CloseHandle(g_fds.p[0].handle); @@ -54,5 +55,5 @@ textwindows int sys_execve_nt(const char *program, char *const argv[], GetExitCodeProcess(procinfo.hProcess, &dwExitCode); } while (dwExitCode == kNtStillActive); CloseHandle(procinfo.hProcess); - ExitProcess(dwExitCode); + _Exit(dwExitCode); } diff --git a/libc/calls/execve-sysv.c b/libc/calls/execve-sysv.c index 28b842734..60c4f5189 100644 --- a/libc/calls/execve-sysv.c +++ b/libc/calls/execve-sysv.c @@ -33,7 +33,8 @@ int sys_execve(const char *prog, char *const argv[], char *const envp[]) { shargs = alloca((i + 2) * sizeof(char *)); memcpy(shargs + 2, argv + 1, i * sizeof(char *)); if (IsFreebsd() || IsNetbsd()) { - shargs[0] = firstnonnull(commandv("bash", alloca(PATH_MAX)), _PATH_BSHELL); + shargs[0] = firstnonnull(commandv("bash", alloca(PATH_MAX), PATH_MAX), + _PATH_BSHELL); } else { shargs[0] = _PATH_BSHELL; } diff --git a/libc/calls/execve.c b/libc/calls/execve.c index a02843476..9df027a14 100644 --- a/libc/calls/execve.c +++ b/libc/calls/execve.c @@ -18,9 +18,10 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/log/libfatal.internal.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" @@ -38,35 +39,41 @@ * @asyncsignalsafe * @vforksafe */ -int execve(const char *program, char *const argv[], char *const envp[]) { +int execve(const char *prog, char *const argv[], char *const envp[]) { + int rc; size_t i; - if (!program || !argv || !envp) return efault(); - if (IsAsan() && - (!__asan_is_valid(program, 1) || !__asan_is_valid_strlist(argv) || - !__asan_is_valid_strlist(envp))) { - return efault(); - } - if (DEBUGSYS) { - __printf("SYS: execve(%s, {", program); - for (i = 0; argv[i]; ++i) { - if (i) __printf(", "); - __printf("%s", argv[i]); - } - __printf("}, {"); - for (i = 0; envp[i]; ++i) { - if (i) __printf(", "); - __printf("%s", envp[i]); - } - __printf("})\n"); - } - for (i = 3; i < g_fds.n; ++i) { - if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) { - close(i); - } - } - if (!IsWindows()) { - return sys_execve(program, argv, envp); + if (!prog || !argv || !envp || + (IsAsan() && + (!__asan_is_valid(prog, 1) || !__asan_is_valid_strlist(argv) || + !__asan_is_valid_strlist(envp)))) { + rc = efault(); } else { - return sys_execve_nt(program, argv, envp); +#ifdef SYSDEBUG + if (__strace > 0) { + kprintf(STRACE_PROLOGUE "execve(%#s, {", prog); + for (i = 0; argv[i]; ++i) { + if (i) kprintf(", "); + kprintf("%#s", argv[i]); + } + kprintf("}, {"); + for (i = 0; envp[i]; ++i) { + if (i) kprintf(", "); + kprintf("%#s", envp[i]); + } + kprintf("})\n"); + } +#endif + for (i = 3; i < g_fds.n; ++i) { + if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) { + close(i); + } + } + if (!IsWindows()) { + rc = sys_execve(prog, argv, envp); + } else { + rc = sys_execve_nt(prog, argv, envp); + } } + STRACE("execve(%#s) failed %d% m", prog, rc); + return rc; } diff --git a/libc/calls/execvpe.c b/libc/calls/execvpe.c index 8227f2eb1..40824c924 100644 --- a/libc/calls/execvpe.c +++ b/libc/calls/execvpe.c @@ -38,6 +38,6 @@ int execvpe(const char *prog, char *const argv[], char *const *envp) { char *exe; char pathbuf[PATH_MAX]; if (IsAsan() && !__asan_is_valid(prog, 1)) return efault(); - if (!(exe = commandv(prog, pathbuf))) return -1; + if (!(exe = commandv(prog, pathbuf, sizeof(pathbuf)))) return -1; return execve(exe, argv, envp); } diff --git a/libc/calls/faccessat-nt.c b/libc/calls/faccessat-nt.c index 1c8446184..2630da0fb 100644 --- a/libc/calls/faccessat-nt.c +++ b/libc/calls/faccessat-nt.c @@ -21,8 +21,9 @@ #include "libc/sysv/consts/at.h" #include "libc/sysv/errfuns.h" -int sys_faccessat_nt(int dirfd, const char *path, int mode, uint32_t flags) { +textwindows int sys_faccessat_nt(int dirfd, const char *path, int mode, + uint32_t flags) { char16_t path16[PATH_MAX]; if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; - return ntaccesscheck(path16, mode); + return __fix_enotdir(ntaccesscheck(path16, mode), path16); } diff --git a/libc/calls/faccessat.c b/libc/calls/faccessat.c index 62586f53a..cadba32f0 100644 --- a/libc/calls/faccessat.c +++ b/libc/calls/faccessat.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/consts/at.h" @@ -32,18 +33,24 @@ * file is a relative path, then file is opened relative to dirfd * @param path is a filename or directory * @param mode can be R_OK, W_OK, X_OK, F_OK - * @param flags should be 0 + * @param flags can have AT_EACCESS, AT_SYMLINK_NOFOLLOW * @return 0 if ok, or -1 and sets errno * @asyncsignalsafe */ int faccessat(int dirfd, const char *path, int mode, uint32_t flags) { - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) { - return -1; /* TODO(jart): implement me */ - } - if (!IsWindows()) { - return sys_faccessat(dirfd, path, mode, flags); + int rc; + char buf[12]; + if (IsAsan() && !__asan_is_valid(path, 1)) { + rc = efault(); + } else if (weaken(__zipos_notat) && + weaken(__zipos_notat)(dirfd, path) == -1) { + rc = -1; /* TODO(jart): implement me */ + } else if (!IsWindows()) { + rc = sys_faccessat(dirfd, path, mode, flags); } else { - return sys_faccessat_nt(dirfd, path, mode, flags); + rc = sys_faccessat_nt(dirfd, path, mode, flags); } + STRACE("faccessat(%s, %#s, %#o, %#x) → %d% m", __strace_dirfd(buf, dirfd), + path, mode, flags, rc); + return rc; } diff --git a/libc/calls/fadvise-nt.c b/libc/calls/fadvise-nt.c index 97aba7bda..82d818be8 100644 --- a/libc/calls/fadvise-nt.c +++ b/libc/calls/fadvise-nt.c @@ -17,49 +17,52 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/nt/createfile.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/enum/filesharemode.h" #include "libc/nt/enum/status.h" #include "libc/nt/files.h" #include "libc/nt/nt/file.h" -#include "libc/nt/ntdll.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/fileaccessinformation.h" #include "libc/nt/struct/filebasicinformation.h" #include "libc/nt/struct/iostatusblock.h" #include "libc/runtime/runtime.h" +#include "libc/sysv/consts/madv.h" +#include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" textwindows int sys_fadvise_nt(int fd, uint64_t offset, uint64_t len, int advice) { - int64_t h2; - NtStatus status; - uint32_t sharemode; - struct NtIoStatusBlock iostatus; - struct NtFileBasicInformation basicinfo; - struct NtFileAccessInformation accessinfo; + int64_t h1, h2; + int flags, mode; + uint32_t perm, share, attr; if (!__isfdkind(fd, kFdFile)) return ebadf(); - sharemode = /* xxx: no clue how to query this */ - kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete; - /* TODO(jart): can we do it in one call w/ NtQueryObject? */ - if (!NtError(status = NtQueryInformationFile(g_fds.p[fd].handle, &iostatus, - &basicinfo, sizeof(basicinfo), - kNtFileBasicInformation)) && - !NtError(status = NtQueryInformationFile(g_fds.p[fd].handle, &iostatus, - &accessinfo, sizeof(accessinfo), - kNtFileAccessInformation))) { - if ((h2 = ReOpenFile(g_fds.p[fd].handle, accessinfo.AccessFlags, sharemode, - advice | basicinfo.FileAttributes)) != -1) { - if (h2 != g_fds.p[fd].handle) { - CloseHandle(g_fds.p[fd].handle); - g_fds.p[fd].handle = h2; - } - return 0; + h1 = g_fds.p[fd].handle; + mode = g_fds.p[fd].mode; + flags = g_fds.p[fd].flags; + flags &= ~(O_SEQUENTIAL | O_RANDOM); + switch (advice) { + case MADV_NORMAL: + break; + case MADV_RANDOM: + flags |= O_RANDOM; + break; + case MADV_SEQUENTIAL: + flags |= O_SEQUENTIAL; + break; + default: + return einval(); + } + if (GetNtOpenFlags(flags, mode, &perm, &share, 0, &attr) == -1) return -1; + if ((h2 = ReOpenFile(h1, perm, share, attr)) != -1) { + if (h2 != h1) { + CloseHandle(h1); + g_fds.p[fd].handle = h2; } - return __winerr(); - } else if (status == kNtStatusDllNotFound) { - return enosys(); + g_fds.p[fd].flags = flags; + return 0; } else { - return ntreturn(status); + return __winerr(); } } diff --git a/libc/calls/fadvise.c b/libc/calls/fadvise.c index f464228be..31044b604 100644 --- a/libc/calls/fadvise.c +++ b/libc/calls/fadvise.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" /** @@ -31,9 +32,12 @@ * @return -1 on error */ int fadvise(int fd, uint64_t offset, uint64_t len, int advice) { + int rc; if (!IsWindows()) { - return sys_fadvise(fd, offset, len, advice); /* linux & freebsd */ + rc = sys_fadvise(fd, offset, len, advice); /* linux & freebsd */ } else { - return sys_fadvise_nt(fd, offset, len, advice); + rc = sys_fadvise_nt(fd, offset, len, advice); } + STRACE("fadvise(%d, %'lu, %'lu, %d) → %d% m", fd, offset, len, advice, rc); + return rc; } diff --git a/libc/calls/fchmodat-nt.c b/libc/calls/fchmodat-nt.c index fd8d0f190..7b0ba5f7c 100644 --- a/libc/calls/fchmodat-nt.c +++ b/libc/calls/fchmodat-nt.c @@ -25,7 +25,7 @@ textwindows int sys_fchmodat_nt(int dirfd, const char *path, uint32_t mode, uint32_t attr; uint16_t path16[PATH_MAX]; if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; - if ((attr = GetFileAttributes(path16)) != -1) { + if ((attr = GetFileAttributes(path16)) != -1u) { if (mode & 0200) { attr &= ~kNtFileAttributeReadonly; } else { diff --git a/libc/calls/fchmodat.c b/libc/calls/fchmodat.c index d33db04cf..26aa9305e 100644 --- a/libc/calls/fchmodat.c +++ b/libc/calls/fchmodat.c @@ -19,7 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -41,15 +41,17 @@ */ int fchmodat(int dirfd, const char *path, uint32_t mode, int flags) { int rc; - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) { - rc = -1; /* TODO(jart): implement me */ + char buf[12]; + if (IsAsan() && !__asan_is_valid(path, 1)) { + rc = efault(); + } else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) { + rc = eopnotsupp(); } else if (!IsWindows()) { rc = sys_fchmodat(dirfd, path, mode, flags); } else { rc = sys_fchmodat_nt(dirfd, path, mode, flags); } - SYSDEBUG("fchmodat(%d, %s, %o, %d) -> %d %s", (long)dirfd, path, mode, flags, - rc != -1 ? "" : strerror(errno)); + STRACE("fchmodat(%s, %#s, %#o, %d) → %d% m", __strace_dirfd(buf, dirfd), path, + mode, flags, rc); return rc; } diff --git a/libc/calls/fchownat.c b/libc/calls/fchownat.c index 4b408dcf6..fc1e5530c 100644 --- a/libc/calls/fchownat.c +++ b/libc/calls/fchownat.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -39,9 +40,16 @@ */ int fchownat(int dirfd, const char *path, uint32_t uid, uint32_t gid, int flags) { - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) { - return -1; /* TODO(jart): implement me */ + int rc; + char sb[12]; + if (IsAsan() && !__asan_is_valid(path, 1)) { + rc = efault(); + } else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) { + STRACE("zipos fchownat not supported yet"); + } else { + rc = sys_fchownat(dirfd, path, uid, gid, flags); } - return sys_fchownat(dirfd, path, uid, gid, flags); + STRACE("fchownat(%s, %#s, %d, %d, %#b) → %d% m", __strace_dirfd(sb, dirfd), + path, uid, gid, flags, rc); + return rc; } diff --git a/libc/calls/fcntl-nt.c b/libc/calls/fcntl-nt.c index 1d042fba2..d51cdc0a9 100644 --- a/libc/calls/fcntl-nt.c +++ b/libc/calls/fcntl-nt.c @@ -16,11 +16,13 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/flock.h" +#include "libc/intrin/cmpxchg.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" +#include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/enum/filelockflags.h" @@ -38,38 +40,8 @@ #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" -static textwindows int sys_fcntl_nt_reservefd(int start) { - int fd; - for (;;) { - fd = start; - if (fd >= g_fds.n) { - if (__ensurefds(fd) == -1) return -1; - } - cmpxchg(&g_fds.f, fd, fd + 1); - if (cmpxchg(&g_fds.p[fd].kind, kFdEmpty, kFdReserved)) { - return fd; - } - } -} - -static textwindows int sys_fcntl_nt_dupfd(int oldfd, int cmd, int start) { - int newfd; - int64_t proc; - if ((newfd = sys_fcntl_nt_reservefd(start)) != -1) { - proc = GetCurrentProcess(); - if (DuplicateHandle(proc, g_fds.p[oldfd].handle, proc, - &g_fds.p[newfd].handle, 0, true, - kNtDuplicateSameAccess)) { - g_fds.p[newfd].kind = g_fds.p[oldfd].kind; - g_fds.p[newfd].flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0; - return newfd; - } else { - __releasefd(newfd); - return __winerr(); - } - } else { - return -1; - } +static textwindows int sys_fcntl_nt_dupfd(int fd, int cmd, int start) { + return sys_dup_nt(fd, -1, (cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0), start); } static textwindows int sys_fcntl_nt_lock(struct Fd *f, int cmd, uintptr_t arg) { @@ -98,7 +70,7 @@ static textwindows int sys_fcntl_nt_lock(struct Fd *f, int cmd, uintptr_t arg) { } if (!len) len = size - off; if (off < 0 || len < 0) return einval(); - offset2overlap(off, &ov); + _offset2overlap(f->handle, off, &ov); if (l->l_type == F_RDLCK || l->l_type == F_WRLCK) { flags = 0; if (cmd == F_SETLK) flags |= kNtLockfileFailImmediately; @@ -136,11 +108,9 @@ textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) { return g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT | O_NOATIME | O_NONBLOCK); } else if (cmd == F_SETFL) { - /* - * - O_APPEND doesn't appear to be tunable at cursory glance - * - O_NONBLOCK might require we start doing all i/o in threads - * - O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything - */ + // O_APPEND doesn't appear to be tunable at cursory glance + // O_NONBLOCK might require we start doing all i/o in threads + // O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything return einval(); } else if (cmd == F_GETFD) { if (g_fds.p[fd].flags & O_CLOEXEC) { diff --git a/libc/calls/fcntl.c b/libc/calls/fcntl.c index 230fcb045..44d469619 100644 --- a/libc/calls/fcntl.c +++ b/libc/calls/fcntl.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" @@ -28,6 +29,12 @@ * * CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC)); * + * This function lets you duplicate file descriptors without running + * into an edge case where they take over stdio handles: + * + * CHECK_GE((newfd = fcntl(oldfd, F_DUPFD, 3)), 3); + * CHECK_GE((newfd = fcntl(oldfd, F_DUPFD_CLOEXEC, 3)), 3); + * * This function implements POSIX Advisory Locks, e.g. * * CHECK_NE(-1, fcntl(zfd, F_SETLKW, &(struct flock){F_WRLCK})); @@ -41,8 +48,10 @@ * @param arg can be FD_CLOEXEC, etc. depending * @return 0 on success, or -1 w/ errno * @asyncsignalsafe + * @restartable */ int fcntl(int fd, int cmd, ...) { + int rc; va_list va; uintptr_t arg; va_start(va, cmd); @@ -50,13 +59,15 @@ int fcntl(int fd, int cmd, ...) { va_end(va); if (fd >= 0) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return weaken(__zipos_fcntl)(fd, cmd, arg); + rc = weaken(__zipos_fcntl)(fd, cmd, arg); } else if (!IsWindows()) { - return sys_fcntl(fd, cmd, arg); + rc = sys_fcntl(fd, cmd, arg); } else { - return sys_fcntl_nt(fd, cmd, arg); + rc = sys_fcntl_nt(fd, cmd, arg); } } else { - return einval(); + rc = einval(); } + STRACE("fcntl(%d, %d, %p) → %#x% m", fd, cmd, arg, rc); + return rc; } diff --git a/libc/calls/fdatasync-nt.c b/libc/calls/fdatasync-nt.c index 43c5323ba..147d879fb 100644 --- a/libc/calls/fdatasync-nt.c +++ b/libc/calls/fdatasync-nt.c @@ -21,11 +21,7 @@ #include "libc/sysv/errfuns.h" textwindows int sys_fdatasync_nt(int fd) { + // TODO(jart): what should we do with worker pipes? if (!__isfdkind(fd, kFdFile)) return ebadf(); - /* - * XXX: On Windows NT this might be more analagous to fflush() and - * Microsoft docs say to do manual block i/o for database-ish - * guarantees on disk persistence. Consider: Really good UPS. - */ - return FlushFileBuffers(g_fds.p[fd].handle) ? 0 : __winerr(); + return FlushFileBuffers(g_fds.p[fd].handle) ? 0 : -1; } diff --git a/libc/calls/fdatasync.c b/libc/calls/fdatasync.c index 7da2a6f30..2f63c4281 100644 --- a/libc/calls/fdatasync.c +++ b/libc/calls/fdatasync.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" /** @@ -28,9 +29,12 @@ * @asyncsignalsafe */ int fdatasync(int fd) { + int rc; if (!IsWindows()) { - return sys_fdatasync(fd); + rc = sys_fdatasync(fd); } else { - return sys_fdatasync_nt(fd); + rc = sys_fdatasync_nt(fd); } + STRACE("%s(%d) → %d% m", "fdatasync", fd, rc); + return rc; } diff --git a/libc/calls/fileexists.c b/libc/calls/fileexists.c index ad6de423a..876a1cac9 100644 --- a/libc/calls/fileexists.c +++ b/libc/calls/fileexists.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/metastat.internal.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" @@ -49,8 +50,11 @@ bool fileexists(const char *path) { struct ZiposUri zipname; uint16_t path16[PATH_MAX]; e = errno; - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) { + if (IsAsan() && !__asan_is_valid(path, 1)) { + efault(); + res = false; + } else if (weaken(__zipos_open) && + weaken(__zipos_parseuri)(path, &zipname) != -1) { if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) { res = true; } else { @@ -69,8 +73,7 @@ bool fileexists(const char *path) { } else { res = false; } - SYSDEBUG("fileexists(%s) -> %s %s", path, res ? "true" : "false", - res ? "" : strerror(errno)); + STRACE("%s(%#s) → %hhhd% m", "fileexists", path, res); if (!res && (errno == ENOENT || errno == ENOTDIR)) { errno = e; } diff --git a/libc/calls/fixenotdir.c b/libc/calls/fixenotdir.c new file mode 100644 index 000000000..8b982fca4 --- /dev/null +++ b/libc/calls/fixenotdir.c @@ -0,0 +1,69 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/errno.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/errors.h" +#include "libc/nt/files.h" + +static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) { + int e; + char16_t *p; + uint32_t attrs; + e = errno; + while ((p = strrchr16(path, '\\'))) { + *p = u'\0'; + if ((attrs = GetFileAttributes(path)) != -1u) { + if (attrs & kNtFileAttributeDirectory) { + return false; + } else { + return true; + } + } else { + errno = e; + } + } + return false; +} + +textwindows dontinline int64_t __fix_enotdir3(int64_t rc, char16_t *path1, + char16_t *path2) { + if (rc == -1 && errno == kNtErrorPathNotFound) { + if ((!path1 || !SubpathExistsThatsNotDirectory(path1)) && + (!path2 || !SubpathExistsThatsNotDirectory(path2))) { + errno = kNtErrorFileNotFound; + } + } + return rc; +} + +// WIN32 doesn't distinguish between ENOTDIR and ENOENT. UNIX strictly +// requires that a directory component *exists* but is not a directory +// whereas WIN32 will return ENOTDIR if a dir label simply isn't found +// +// - ENOTDIR: A component used as a directory in pathname is not, in +// fact, a directory. -or- pathname is relative and dirfd is a file +// descriptor referring to a file other than a directory. +// +// - ENOENT: A directory component in pathname does not exist or is a +// dangling symbolic link. +// +textwindows int64_t __fix_enotdir(int64_t rc, char16_t *path) { + return __fix_enotdir3(rc, path, 0); +} diff --git a/libc/calls/flock.c b/libc/calls/flock.c index c8f7af7f9..b48232f7e 100644 --- a/libc/calls/flock.c +++ b/libc/calls/flock.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" /** @@ -28,11 +29,15 @@ * @param op can have LOCK_{SH,EX,NB,UN} for shared, exclusive, * non-blocking, and unlocking * @return 0 on success, or -1 w/ errno + * @restartable */ int flock(int fd, int op) { + int rc; if (!IsWindows()) { - return sys_flock(fd, op); + rc = sys_flock(fd, op); } else { - return sys_flock_nt(fd, op); + rc = sys_flock_nt(fd, op); } + STRACE("flock(%d, %d) → %d% m", fd, op, rc); + return rc; } diff --git a/libc/calls/fmodl.S b/libc/calls/fmodl.S new file mode 100644 index 000000000..b3d87215c --- /dev/null +++ b/libc/calls/fmodl.S @@ -0,0 +1,44 @@ +/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 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 "libc/runtime/pc.internal.h" +#include "libc/macros.internal.h" + +// fmod [sic] does (𝑥 rem 𝑦) w/ round()-style rounding. +// +// @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +// @param 𝑦 is the power, also pushed on stack, in reverse order +// @return remainder ∈ (-|𝑦|,|𝑦|) in %st +// @define 𝑥-truncl(𝑥/𝑦)*𝑦 +// @see emod() +fmodl: push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) +1: fprem + fnstsw + test $FPU_C2>>8,%ah + jnz 1b + fstp %st(1) + pop %rbp + ret +1: int3 + pop %rbp + ret + .endfn fmodl,globl diff --git a/libc/calls/fstat-nt.c b/libc/calls/fstat-nt.c index fd4bce286..125ef8e09 100644 --- a/libc/calls/fstat-nt.c +++ b/libc/calls/fstat-nt.c @@ -18,9 +18,10 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/stat.h" -#include "libc/calls/sysdebug.internal.h" #include "libc/fmt/conv.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/bsr.h" #include "libc/nt/enum/fileflagandattributes.h" @@ -64,7 +65,7 @@ static textwindows uint32_t GetSizeOfReparsePoint(int64_t fh) { z += x < 0200 ? 1 : bsrl(tpenc(x)) >> 3; } } else { - SYSDEBUG("GetSizeOfReparsePoint failed %d", GetLastError()); + STRACE("%s failed %m", "GetSizeOfReparsePoint"); } return z; } @@ -105,7 +106,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) { st->st_size = (uint64_t)wst.nFileSizeHigh << 32 | wst.nFileSizeLow; st->st_blksize = PAGESIZE; st->st_dev = wst.dwVolumeSerialNumber; - st->st_rdev = wst.dwVolumeSerialNumber; + st->st_rdev = 0; st->st_ino = (uint64_t)wst.nFileIndexHigh << 32 | wst.nFileIndexLow; st->st_nlink = wst.nNumberOfLinks; if (S_ISLNK(st->st_mode)) { @@ -122,7 +123,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) { st->st_blocks = ROUNDUP(actualsize, PAGESIZE) / 512; } } else { - SYSDEBUG("GetFileInformationByHandle failed %d", GetLastError()); + STRACE("%s failed %m", "GetFileInformationByHandle"); } break; default: @@ -130,7 +131,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) { } return 0; } else { - SYSDEBUG("GetFileType failed %d", GetLastError()); + STRACE("%s failed %m", "GetFileType"); return __winerr(); } } diff --git a/libc/calls/fstat-sysv.c b/libc/calls/fstat-sysv.c index f8ac0f054..e05714552 100644 --- a/libc/calls/fstat-sysv.c +++ b/libc/calls/fstat-sysv.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -42,7 +41,6 @@ int32_t sys_fstat(int32_t fd, struct stat *st) { __stat2cosmo(st, &ms); return 0; } else { - SYSDEBUG("sys_fstat(%d) failed w/ %m", fd); return -1; } } diff --git a/libc/calls/fstat.c b/libc/calls/fstat.c index e41f50834..b7d7d46a3 100644 --- a/libc/calls/fstat.c +++ b/libc/calls/fstat.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -26,18 +27,24 @@ /** * Returns information about file, via open()'d descriptor. + * + * @return 0 on success or -1 w/ errno * @asyncsignalsafe */ int fstat(int fd, struct stat *st) { + int rc; if (__isfdkind(fd, kFdZip)) { - return weaken(__zipos_fstat)( + rc = weaken(__zipos_fstat)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st); } else if (!IsWindows() && !IsMetal()) { - return sys_fstat(fd, st); + rc = sys_fstat(fd, st); } else if (IsMetal()) { - return sys_fstat_metal(fd, st); + rc = sys_fstat_metal(fd, st); + } else if (!__isfdkind(fd, kFdFile)) { + rc = ebadf(); } else { - if (!__isfdkind(fd, kFdFile)) return ebadf(); - return sys_fstat_nt(g_fds.p[fd].handle, st); + rc = sys_fstat_nt(__getfdhandleactual(fd), st); } + STRACE("fstat(%d, [%s]) → %d% m", fd, __strace_stat(rc, st), rc); + return rc; } diff --git a/libc/calls/fstatat-nt.c b/libc/calls/fstatat-nt.c index 5a77452ca..468752e70 100644 --- a/libc/calls/fstatat-nt.c +++ b/libc/calls/fstatat-nt.c @@ -39,8 +39,8 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st, 0)) != -1) { rc = st ? sys_fstat_nt(fh, st) : 0; CloseHandle(fh); - return rc; } else { - return __winerr(); + rc = __winerr(); } + return __fix_enotdir(rc, path16); } diff --git a/libc/calls/fstatat-sysv.c b/libc/calls/fstatat-sysv.c index 594ef7df5..4c64f3986 100644 --- a/libc/calls/fstatat-sysv.c +++ b/libc/calls/fstatat-sysv.c @@ -28,6 +28,7 @@ */ int32_t sys_fstatat(int32_t dirfd, const char *path, struct stat *st, int32_t flags) { + int rc; void *p; union metastat ms; if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); diff --git a/libc/calls/fstatat.c b/libc/calls/fstatat.c index db489f107..008c0908f 100644 --- a/libc/calls/fstatat.c +++ b/libc/calls/fstatat.c @@ -19,34 +19,58 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/fmt/itoa.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/log/log.h" #include "libc/str/str.h" #include "libc/sysv/consts/at.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" +static inline const char *__strace_fstatat_flags(int flags) { + static char buf[12]; + if (flags == AT_SYMLINK_NOFOLLOW) return "AT_SYMLINK_NOFOLLOW"; + FormatInt32(buf, flags); + return buf; +} + /** * Returns information about thing. * * @param dirfd is normally AT_FDCWD but if it's an open directory and * file is a relative path, then file becomes relative to dirfd * @param st is where result is stored - * @param flags can have AT_{EMPTY_PATH,NO_AUTOMOUNT,SYMLINK_NOFOLLOW} + * @param flags can have AT_SYMLINK_NOFOLLOW * @return 0 on success, or -1 w/ errno * @see S_ISDIR(st.st_mode), S_ISREG() * @asyncsignalsafe + * @vforksafe */ int fstatat(int dirfd, const char *path, struct stat *st, int flags) { + /* execve() depends on this */ + int rc; + char buf[12]; struct ZiposUri zipname; - if (__isfdkind(dirfd, kFdZip)) return einval(); /* TODO(jart): implement me */ - if (weaken(__zipos_stat) && weaken(__zipos_parseuri)(path, &zipname) != -1) { - return weaken(__zipos_stat)(&zipname, st); + if (__isfdkind(dirfd, kFdZip)) { + STRACE("zipos dirfd not supported yet"); + rc = einval(); + } else if (weaken(__zipos_stat) && + weaken(__zipos_parseuri)(path, &zipname) != -1) { + if (!__vforked) { + rc = weaken(__zipos_stat)(&zipname, st); + } else { + rc = enotsup(); + } } else if (!IsWindows()) { - return sys_fstatat(dirfd, path, st, flags); + rc = sys_fstatat(dirfd, path, st, flags); } else { - return sys_fstatat_nt(dirfd, path, st, flags); + rc = sys_fstatat_nt(dirfd, path, st, flags); } + STRACE("fstatat(%s, %#s, [%s], %s) → %d% m", __strace_dirfd(buf, dirfd), path, + __strace_stat(rc, st), __strace_fstatat_flags(flags), rc); + return rc; } diff --git a/libc/calls/fsync.c b/libc/calls/fsync.c index 39a8b4476..99b6286ec 100644 --- a/libc/calls/fsync.c +++ b/libc/calls/fsync.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" /** @@ -28,9 +29,12 @@ * @asyncsignalsafe */ int fsync(int fd) { + int rc; if (!IsWindows()) { - return sys_fsync(fd); + rc = sys_fsync(fd); } else { - return sys_fdatasync_nt(fd); + rc = sys_fdatasync_nt(fd); } + STRACE("%s(%d) → %d% m", "fsync", fd, rc); + return rc; } diff --git a/libc/calls/ftruncate-nt.c b/libc/calls/ftruncate-nt.c index e192c7e62..9c1e79288 100644 --- a/libc/calls/ftruncate-nt.c +++ b/libc/calls/ftruncate-nt.c @@ -25,12 +25,10 @@ textwindows int sys_ftruncate_nt(int64_t handle, uint64_t length) { bool32 ok; int64_t tell; tell = -1; - if (SetFilePointerEx(handle, 0, &tell, kNtFileCurrent)) { + if ((ok = SetFilePointerEx(handle, 0, &tell, kNtFileCurrent))) { ok = SetFilePointerEx(handle, length, NULL, kNtFileBegin) && SetEndOfFile(handle); SetFilePointerEx(handle, tell, NULL, kNtFileBegin); - return ok ? 0 : __winerr(); - } else { - return __winerr(); } + return ok ? 0 : __winerr(); } diff --git a/libc/calls/ftruncate.c b/libc/calls/ftruncate.c index a55b2fca4..5c17d5780 100644 --- a/libc/calls/ftruncate.c +++ b/libc/calls/ftruncate.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/sysv/errfuns.h" @@ -32,11 +33,15 @@ * @asyncsignalsafe */ int ftruncate(int fd, int64_t length) { - if (fd < 0) return einval(); - if (!IsWindows()) { - return sys_ftruncate(fd, length, length); + int rc; + if (fd < 0) { + rc = einval(); + } else if (!IsWindows()) { + rc = sys_ftruncate(fd, length, length); } else { - if (fd >= g_fds.n) return ebadf(); - return sys_ftruncate_nt(g_fds.p[fd].handle, length); + if (fd >= g_fds.n) rc = ebadf(); + rc = sys_ftruncate_nt(g_fds.p[fd].handle, length); } + STRACE("ftruncate(%d, %'ld) → %d% m", fd, length, rc); + return rc; } diff --git a/libc/calls/g_fds.c b/libc/calls/g_fds.c deleted file mode 100644 index ab33efb7f..000000000 --- a/libc/calls/g_fds.c +++ /dev/null @@ -1,53 +0,0 @@ -/*-*- 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 "libc/bits/pushpop.h" -#include "libc/calls/internal.h" -#include "libc/nt/runtime.h" -#include "libc/sysv/consts/fileno.h" - -STATIC_YOINK("_init_g_fds"); - -hidden struct Fds g_fds; - -hidden textstartup void InitializeFileDescriptors(void) { - struct Fds *fds; - fds = VEIL("r", &g_fds); - pushmov(&fds->n, ARRAYLEN(fds->__init_p)); - fds->p = fds->__init_p; - if (IsMetal()) { - pushmov(&fds->f, 3ull); - fds->__init_p[STDIN_FILENO].kind = pushpop(kFdSerial); - fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdSerial); - fds->__init_p[STDERR_FILENO].kind = pushpop(kFdSerial); - fds->__init_p[STDIN_FILENO].handle = VEIL("r", 0x3F8ull); - fds->__init_p[STDOUT_FILENO].handle = VEIL("r", 0x3F8ull); - fds->__init_p[STDERR_FILENO].handle = VEIL("r", 0x3F8ull); - } else if (IsWindows()) { - pushmov(&fds->f, 3ull); - fds->__init_p[STDIN_FILENO].kind = pushpop(kFdFile); - fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdFile); - fds->__init_p[STDERR_FILENO].kind = pushpop(kFdFile); - fds->__init_p[STDIN_FILENO].handle = - GetStdHandle(pushpop(kNtStdInputHandle)); - fds->__init_p[STDOUT_FILENO].handle = - GetStdHandle(pushpop(kNtStdOutputHandle)); - fds->__init_p[STDERR_FILENO].handle = - GetStdHandle(pushpop(kNtStdErrorHandle)); - } -} diff --git a/libc/calls/g_sighandrvas.c b/libc/calls/g_sighandrvas.c index ed01f3aa4..97964a95d 100644 --- a/libc/calls/g_sighandrvas.c +++ b/libc/calls/g_sighandrvas.c @@ -18,4 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +_Alignas(64) char __sig_lock; unsigned __sighandrvas[NSIG]; +unsigned __sighandflags[NSIG]; diff --git a/libc/calls/getauxval.c b/libc/calls/getauxval.c index 7368fa11c..7b43ffa50 100644 --- a/libc/calls/getauxval.c +++ b/libc/calls/getauxval.c @@ -27,6 +27,7 @@ * This function is typically regarded as a libc implementation detail; * thus, the source code is the documentation. * + * @return aux val or 0 if not available * @see libc/sysv/consts.sh * @see System Five Application Binary Interface § 3.4.3 * @asyncsignalsafe @@ -38,8 +39,5 @@ unsigned long getauxval(unsigned long at) { return ap[1]; } } - if (at == AT_EXECFN) { - return (intptr_t)__argv[0]; - } return 0; } diff --git a/libc/calls/getconsolectrlevent.h b/libc/calls/getconsolectrlevent.h deleted file mode 100644 index 0339af5ec..000000000 --- a/libc/calls/getconsolectrlevent.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ -#define COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ -#include "libc/nt/enum/ctrlevent.h" -#include "libc/sysv/consts/sig.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -static inline int GetConsoleCtrlEvent(int sig) { - switch (sig) { - case SIGINT: - return kNtCtrlCEvent; - case SIGHUP: - return kNtCtrlCloseEvent; - case SIGQUIT: - return kNtCtrlBreakEvent; - default: - return -1; - } -} - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ */ diff --git a/libc/calls/getconsolectrlevent.internal.h b/libc/calls/getconsolectrlevent.internal.h new file mode 100644 index 000000000..1606f73da --- /dev/null +++ b/libc/calls/getconsolectrlevent.internal.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ +#define COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ +#include "libc/nt/enum/ctrlevent.h" +#include "libc/sysv/consts/sig.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +static inline int GetConsoleCtrlEvent(int sig) { + switch (sig) { + case SIGINT: + return kNtCtrlCEvent; + case SIGQUIT: + return kNtCtrlBreakEvent; + default: + return -1; + } +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ */ diff --git a/libc/calls/getcwd-nt.c b/libc/calls/getcwd-nt.c index b2236e276..475824679 100644 --- a/libc/calls/getcwd-nt.c +++ b/libc/calls/getcwd-nt.c @@ -28,15 +28,22 @@ textwindows char *sys_getcwd_nt(char *buf, size_t size) { uint64_t w; wint_t x, y; uint32_t n, i, j; - char16_t name16[PATH_MAX + 1]; - if ((n = GetCurrentDirectory(ARRAYLEN(name16), name16))) { - if (n <= PATH_MAX) { - tprecode16to8(buf, size, name16); - for (j = i = 0; i < n;) { - x = name16[i++] & 0xffff; + char16_t p[PATH_MAX]; + if ((n = GetCurrentDirectory(ARRAYLEN(p), p))) { + if (4 + n + 1 <= size && 4 + n + 1 <= ARRAYLEN(p)) { + tprecode16to8(buf, size, p); + j = 0; + if (n >= 3 && isalpha(p[0]) && p[1] == ':' && p[2] == '\\') { + buf[j++] = '/'; + buf[j++] = '/'; + buf[j++] = '?'; + buf[j++] = '/'; + } + for (i = 0; i < n;) { + x = p[i++] & 0xffff; if (!IsUcs2(x)) { if (i < n) { - y = name16[i++] & 0xffff; + y = p[i++] & 0xffff; x = MergeUtf16(x, y); } else { x = 0xfffd; diff --git a/libc/calls/getcwd-xnu.c b/libc/calls/getcwd-xnu.c index 960d56918..63bfac438 100644 --- a/libc/calls/getcwd-xnu.c +++ b/libc/calls/getcwd-xnu.c @@ -29,14 +29,15 @@ char *sys_getcwd_xnu(char *res, size_t size) { int fd; - struct stat st[2]; + union metastat st[2]; char buf[XNU_MAXPATHLEN], *ret = NULL; if ((fd = sys_openat(AT_FDCWD, ".", O_RDONLY | O_DIRECTORY, 0)) != -1) { - if (sys_fstat(fd, &st[0]) != -1) { - if (st[0].st_dev && st[0].st_ino) { + if (__sys_fstat(fd, &st[0]) != -1) { + if (METASTAT(st[0], st_dev) && METASTAT(st[0], st_ino)) { if (__sys_fcntl(fd, XNU_F_GETPATH, (uintptr_t)buf) != -1) { - if (sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) { - if (st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino) { + if (__sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) { + if (METASTAT(st[0], st_dev) == METASTAT(st[1], st_dev) && + METASTAT(st[0], st_ino) == METASTAT(st[1], st_ino)) { if (memccpy(res, buf, '\0', size)) { ret = res; } else { diff --git a/libc/calls/getcwd.c b/libc/calls/getcwd.c index 536d8df79..158185a56 100644 --- a/libc/calls/getcwd.c +++ b/libc/calls/getcwd.c @@ -16,11 +16,13 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/log/backtrace.internal.h" #include "libc/mem/mem.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" @@ -43,19 +45,20 @@ char *getcwd(char *buf, size_t size) { if (buf) { p = buf; if (!size) { - SYSDEBUG("getcwd(%p, %x) EINVAL", buf, size); einval(); + STRACE("getcwd(%p, %'zu) %m", buf, size); return 0; } } else if (weaken(malloc)) { - if (!size) size = PATH_MAX + 1; + assert(!__vforked); + if (!size) size = PATH_MAX; if (!(p = weaken(malloc)(size))) { - SYSDEBUG("getcwd(%p, %x) ENOMEM", buf, size); + STRACE("getcwd(%p, %'zu) %m", buf, size); return 0; } } else { - SYSDEBUG("getcwd() EINVAL needs buf≠0 or STATIC_YOINK(\"malloc\")"); einval(); + STRACE("getcwd() needs buf≠0 or STATIC_YOINK(\"malloc\")"); return 0; } *p = '\0'; @@ -85,6 +88,6 @@ char *getcwd(char *buf, size_t size) { } } } - SYSDEBUG("getcwd(%p, %x) -> %s", buf, size, r); + STRACE("getcwd(%p, %'zu) → %#s", buf, size, r); return r; } diff --git a/libc/calls/getegid.c b/libc/calls/getegid.c new file mode 100644 index 000000000..e142d34f1 --- /dev/null +++ b/libc/calls/getegid.c @@ -0,0 +1,37 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" + +/** + * Returns effective group ID of calling process. + * @return group id + */ +int getegid(void) { + int rc; + if (!IsWindows()) { + rc = sys_getegid(); + } else { + rc = getgid(); + } + STRACE("%s() → %d% m", "getegid", rc); + return rc; +} diff --git a/libc/calls/geteuid.c b/libc/calls/geteuid.c new file mode 100644 index 000000000..ad16d7419 --- /dev/null +++ b/libc/calls/geteuid.c @@ -0,0 +1,36 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" + +/** + * Returns effective user ID of calling process. + * @return user id + */ +int geteuid(void) { + int rc; + if (!IsWindows()) { + rc = sys_geteuid(); + } else { + rc = getuid(); + } + STRACE("%s() → %d% m", "geteuid", rc); + return rc; +} diff --git a/libc/calls/getexecutablename.c b/libc/calls/getexecutablename.c new file mode 100644 index 000000000..455942bb7 --- /dev/null +++ b/libc/calls/getexecutablename.c @@ -0,0 +1,121 @@ +/*-*- 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/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/macros.internal.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/consts/ok.h" + +#define SIZE 1024 +#define CTL_KERN 1 +#define KERN_PROC 14 +#define KERN_PROC_PATHNAME_FREEBSD 12 +#define KERN_PROC_PATHNAME_NETBSD 5 + +char program_executable_name[PATH_MAX]; + +static inline void GetProgramExecutableNameImpl(char *p, char *e) { + char *q; + ssize_t rc; + size_t i, n; + union { + int cmd[4]; + char16_t path16[PATH_MAX]; + } u; + + if (IsWindows()) { + n = GetModuleFileName(0, u.path16, ARRAYLEN(u.path16)); + for (i = 0; i < n; ++i) { + if (u.path16[i] == '\\') { + u.path16[i] = '/'; + } + } + if (isalpha(u.path16[0]) && u.path16[1] == ':' && u.path16[2] == '/') { + p[0] = '/'; + p[1] = '/'; + p[2] = '?'; + p[3] = '/'; + p += 4; + } + tprecode16to8(p, e - p, u.path16); + return; + } + + if (__argc && (q = __argv[0]) && !sys_faccessat(AT_FDCWD, q, F_OK, 0)) { + if (*q != '/') { + if (q[0] == '.' && q[1] == '/') { + q += 2; + } + if (getcwd(p, e - p)) { + while (*p) ++p; + *p++ = '/'; + } + } + for (i = 0; *q && p + 1 < e; ++p, ++q) { + *p = *q; + } + *p = 0; + return; + } + + if ((rc = sys_readlinkat(AT_FDCWD, "/proc/self/exe", p, e - p - 1)) > 0 || + (rc = sys_readlinkat(AT_FDCWD, "/proc/curproc/file", p, e - p - 1)) > 0) { + p[rc] = 0; + return; + } + + if (IsFreebsd() || IsNetbsd()) { + u.cmd[0] = CTL_KERN; + u.cmd[1] = KERN_PROC; + if (IsFreebsd()) { + u.cmd[2] = KERN_PROC_PATHNAME_FREEBSD; + } else { + u.cmd[2] = KERN_PROC_PATHNAME_NETBSD; + } + u.cmd[3] = -1; // current process + n = e - p; + if (sysctl(u.cmd, ARRAYLEN(u.cmd), p, &n, 0, 0) != -1) { + return; + } + } +} + +/** + * Returns absolute path of executable. + */ +char *GetProgramExecutableName(void) { + int e; + static bool once; + if (!once) { + e = errno; + GetProgramExecutableNameImpl( + program_executable_name, + program_executable_name + sizeof(program_executable_name)); + errno = e; + } + return program_executable_name; +} + +const void *const GetProgramExecutableNameCtor[] initarray = { + GetProgramExecutableName, +}; diff --git a/libc/calls/getfdhandleactual.greg.c b/libc/calls/getfdhandleactual.greg.c new file mode 100644 index 000000000..b0f797b12 --- /dev/null +++ b/libc/calls/getfdhandleactual.greg.c @@ -0,0 +1,28 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/sock/ntstdin.internal.h" + +int64_t __getfdhandleactual(int fd) { + if (g_fds.p[fd].worker) { + return g_fds.p[fd].worker->reader; + } else { + return g_fds.p[fd].handle; + } +} diff --git a/libc/calls/getfiledescriptorsize.c b/libc/calls/getfiledescriptorsize.c index 5fa78a2a9..045e3ecd0 100644 --- a/libc/calls/getfiledescriptorsize.c +++ b/libc/calls/getfiledescriptorsize.c @@ -16,20 +16,65 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/metastat.internal.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" #include "libc/limits.h" +#include "libc/nt/enum/fileinfobyhandleclass.h" #include "libc/nt/files.h" +#include "libc/nt/struct/filestandardinformation.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.internal.h" /** * Determines size of open file. * - * @return file byte length, or -1ul w/ errno + * This function is equivalent to: + * + * struct stat st; + * !fstat(fd, &st) ? st.st_size : -1 + * + * Except faster on BSD/Windows and a much smaller link size. + * + * @return file byte length, or -1 w/ errno * @asyncsignalsafe */ -size_t getfiledescriptorsize(int fd) { - struct stat st; - if (fstat(fd, &st) == -1) return SIZE_MAX; - return st.st_size; +ssize_t getfiledescriptorsize(int fd) { + int e; + ssize_t rc; + union metastat st; + struct NtFileStandardInformation info; + e = errno; + if (__isfdkind(fd, kFdZip)) { + if (weaken(__zipos_fstat)( + (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, &st.cosmo) != + -1) { + rc = st.cosmo.st_size; + } else { + rc = -1; + } + } else if (IsMetal()) { + rc = -1; + } else if (!IsWindows()) { + if (!__sys_fstat(fd, &st)) { + rc = METASTAT(st, st_size); + } else { + rc = -1; + } + } else if (__isfdopen(fd)) { + if (GetFileInformationByHandleEx(g_fds.p[fd].handle, kNtFileStandardInfo, + &info, sizeof(info))) { + rc = info.EndOfFile; + } else { + rc = ebadf(); + } + } else { + rc = ebadf(); + } + STRACE("getfiledescriptorsize(%d) → %'zd% m", fd, rc); + return rc; } diff --git a/libc/calls/getfilesize.c b/libc/calls/getfilesize.c index cfd7c8f1c..8ef96630c 100644 --- a/libc/calls/getfilesize.c +++ b/libc/calls/getfilesize.c @@ -28,7 +28,7 @@ * Returns the byte length of file by path. * * @return number of bytes, or -1ul w/ errno - * @see getfiledescriptorsize + * @see getfiledescriptorsize() */ size_t GetFileSize(const char *pathname) { struct stat st; diff --git a/libc/calls/gethostname-nt.c b/libc/calls/gethostname-nt.c index 020147d6e..2cdf8c0f6 100644 --- a/libc/calls/gethostname-nt.c +++ b/libc/calls/gethostname-nt.c @@ -22,11 +22,11 @@ #include "libc/nt/systeminfo.h" #include "libc/str/str.h" -textwindows int gethostname_nt(char *name, size_t len) { +textwindows int gethostname_nt(char *name, size_t len, int kind) { uint32_t nSize; char16_t name16[256]; nSize = ARRAYLEN(name16); - if (GetComputerNameEx(kNtComputerNamePhysicalDnsHostname, name16, &nSize)) { + if (GetComputerNameEx(kind, name16, &nSize)) { tprecode16to8(name, len, name16); return 0; } else { diff --git a/libc/calls/gethostname.c b/libc/calls/gethostname.c index 5e4337331..eaafb2b43 100644 --- a/libc/calls/gethostname.c +++ b/libc/calls/gethostname.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/dce.h" +#include "libc/nt/enum/computernameformat.h" #include "libc/sysv/errfuns.h" /** @@ -26,6 +27,8 @@ * * pheidippides.domain.example * ^^^^^^^^^^^^ + * + * @return 0 on success or -1 w/ errno */ int gethostname(char *name, size_t len) { if (len < 1) return einval(); @@ -37,6 +40,6 @@ int gethostname(char *name, size_t len) { return gethostname_bsd(name, len); } } else { - return gethostname_nt(name, len); + return gethostname_nt(name, len, kNtComputerNamePhysicalDnsHostname); } } diff --git a/libc/calls/getitimer.c b/libc/calls/getitimer.c index 476df9bda..57b8937a9 100644 --- a/libc/calls/getitimer.c +++ b/libc/calls/getitimer.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -29,13 +30,22 @@ * @return 0 on success or -1 w/ errno */ int getitimer(int which, struct itimerval *curvalue) { + int rc; if (IsAsan() && !__asan_is_valid(curvalue, sizeof(*curvalue))) { - return efault(); - } - if (!IsWindows()) { - return sys_getitimer(which, curvalue); + rc = efault(); + } else if (!IsWindows()) { + rc = sys_getitimer(which, curvalue); + } else if (!curvalue) { + rc = efault(); } else { - if (!curvalue) return efault(); - return sys_setitimer_nt(which, 0, curvalue); + rc = sys_setitimer_nt(which, 0, curvalue); } + if (curvalue) { + STRACE("getitimer(%d, [{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m", which, + curvalue->it_interval.tv_sec, curvalue->it_interval.tv_usec, + curvalue->it_value.tv_sec, curvalue->it_value.tv_usec, rc); + } else { + STRACE("getitimer(%d, 0) → %d% m", which, rc); + } + return rc; } diff --git a/libc/calls/getloadavg.c b/libc/calls/getloadavg.c new file mode 100644 index 000000000..5a896926e --- /dev/null +++ b/libc/calls/getloadavg.c @@ -0,0 +1,40 @@ +/*-*- 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 2022 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/struct/sysinfo.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Returns system load average. + * @note work in progress + */ +int getloadavg(double *a, int n) { + /* cat /proc/loadavg */ + int i; + struct sysinfo si; + if (!n) return 0; + if (n < 0) return einval(); + if (sysinfo(&si) == -1) return -1; + if (n > 3) n = 3; + for (i = 0; i < n; i++) { + a[i] = 1. / 65536 * si.loads[i]; + } + return n; +} diff --git a/libc/calls/getntsyspath.S b/libc/calls/getntsyspath.S index 3e4725e83..f4969bcf4 100644 --- a/libc/calls/getntsyspath.S +++ b/libc/calls/getntsyspath.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Obtains WIN32 magic path, e.g. GetTempPathA. // diff --git a/libc/calls/getpgid.c b/libc/calls/getpgid.c index 8f8d0cac5..8ae485a7e 100644 --- a/libc/calls/getpgid.c +++ b/libc/calls/getpgid.c @@ -18,15 +18,19 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" /** * Returns process group id. */ int getpgid(int pid) { + int rc; if (!IsWindows()) { - return sys_getpgid(pid); + rc = sys_getpgid(pid); } else { - return getpid(); + rc = getpid(); } + STRACE("%s(%d) → %d% m", "getpgid", pid, rc); + return rc; } diff --git a/libc/calls/getpgrp.c b/libc/calls/getpgrp.c new file mode 100644 index 000000000..9a15d1c6e --- /dev/null +++ b/libc/calls/getpgrp.c @@ -0,0 +1,36 @@ +/*-*- 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" + +/** + * Returns process group id of calling process. + */ +int getpgrp(void) { + int rc; + if (!IsWindows()) { + rc = sys_getpgrp(); + } else { + rc = getpid(); + } + STRACE("%s() → %d% m", "getpgrp", rc); + return rc; +} diff --git a/libc/calls/getppid.c b/libc/calls/getppid.c index 7ab0b7c45..d997f6134 100644 --- a/libc/calls/getppid.c +++ b/libc/calls/getppid.c @@ -17,19 +17,23 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" /** * Returns parent process id. * @asyncsignalsafe */ int getppid(void) { + int rc; if (!IsWindows()) { if (!IsNetbsd()) { - return sys_getppid(); + rc = sys_getppid(); } else { - return sys_getpid().dx; + rc = sys_getpid().dx; } } else { - return sys_getppid_nt(); + rc = sys_getppid_nt(); } + STRACE("getppid() → %d% m", rc); + return rc; } diff --git a/libc/calls/getpriority.c b/libc/calls/getpriority.c index 31a8df634..6a65f48d1 100644 --- a/libc/calls/getpriority.c +++ b/libc/calls/getpriority.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" /** * Returns nice value of thing. @@ -28,9 +29,12 @@ * @see setpriority(), nice() */ int getpriority(int which, unsigned who) { + int rc; if (!IsWindows()) { - return sys_getpriority(which, who) - 20; + rc = sys_getpriority(which, who) - 20; } else { - return sys_getsetpriority_nt(which, who, 0, sys_getpriority_nt); + rc = sys_getsetpriority_nt(which, who, 0, sys_getpriority_nt); } + STRACE("getpriority(%d, %u) → %d% m", which, who, rc); + return rc; } diff --git a/libc/calls/getresgid.c b/libc/calls/getresgid.c new file mode 100644 index 000000000..1760de051 --- /dev/null +++ b/libc/calls/getresgid.c @@ -0,0 +1,51 @@ +/*-*- 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 "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" + +/** + * Gets real, effective, and "saved" group ids. + * + * @param real receives real user id, or null to do nothing + * @param effective receives effective user id, or null to do nothing + * @param saved receives saved user id, or null to do nothing + * @return 0 on success or -1 w/ errno + * @see setresuid() + */ +int getresgid(uint32_t *real, uint32_t *effective, uint32_t *saved) { + int rc, gid; + if (IsWindows()) { + gid = getgid(); + if (real) *real = gid; + if (effective) *effective = gid; + if (saved) *saved = gid; + rc = 0; + } else if (saved) { + rc = sys_getresgid(real, effective, saved); + } else { + if (real) *real = sys_getgid(); + if (effective) *effective = sys_getegid(); + rc = 0; + } + STRACE("getresgid([%d], [%d], [%d]) → %d% m", real ? *real : 0, + effective ? *effective : 0, saved ? *saved : 0, rc); + return rc; +} diff --git a/libc/calls/getresuid.c b/libc/calls/getresuid.c new file mode 100644 index 000000000..80a0f10a7 --- /dev/null +++ b/libc/calls/getresuid.c @@ -0,0 +1,51 @@ +/*-*- 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 "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" + +/** + * Gets real, effective, and "saved" user ids. + * + * @param real receives real user id, or null to do nothing + * @param effective receives effective user id, or null to do nothing + * @param saved receives saved user id, or null to do nothing + * @return 0 on success or -1 w/ errno + * @see setresuid() + */ +int getresuid(uint32_t *real, uint32_t *effective, uint32_t *saved) { + int rc, uid; + if (IsWindows()) { + uid = getuid(); + if (real) *real = uid; + if (effective) *effective = uid; + if (saved) *saved = uid; + rc = 0; + } else if (saved) { + rc = sys_getresuid(real, effective, saved); + } else { + if (real) *real = sys_getuid(); + if (effective) *effective = sys_geteuid(); + rc = 0; + } + STRACE("getresuid([%d], [%d], [%d]) → %d% m", real ? *real : 0, + effective ? *effective : 0, saved ? *saved : 0, rc); + return rc; +} diff --git a/libc/calls/getrlimit.c b/libc/calls/getrlimit.c index c651a3f70..25bacf842 100644 --- a/libc/calls/getrlimit.c +++ b/libc/calls/getrlimit.c @@ -18,8 +18,10 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/sysv/consts/rlimit.h" #include "libc/sysv/errfuns.h" /** @@ -31,7 +33,22 @@ * @see libc/sysv/consts.sh */ int getrlimit(int resource, struct rlimit *rlim) { - if (resource == 127) return einval(); - if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) return efault(); - return sys_getrlimit(resource, rlim); + int rc; + char buf[64]; + if (resource == 127) { + rc = einval(); + } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_getrlimit(resource, rlim); + } else if (resource == RLIMIT_AS) { + rlim->rlim_cur = __virtualmax; + rlim->rlim_max = __virtualmax; + rc = 0; + } else { + rc = einval(); + } + STRACE("getrlimit(%s, [%s]) → %d% m", __strace_rlimit_name(resource), + __strace_rlimit(buf, sizeof(buf), rc, rlim), rc); + return rc; } diff --git a/libc/calls/getrusage-nt.c b/libc/calls/getrusage-nt.c index 8d3fbe9e0..35bb44e50 100644 --- a/libc/calls/getrusage-nt.c +++ b/libc/calls/getrusage-nt.c @@ -18,30 +18,47 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" #include "libc/calls/struct/rusage.h" #include "libc/fmt/conv.h" +#include "libc/intrin/spinlock.h" #include "libc/nt/accounting.h" +#include "libc/nt/process.h" #include "libc/nt/runtime.h" +#include "libc/nt/struct/iocounters.h" +#include "libc/nt/struct/processmemorycounters.h" #include "libc/nt/thread.h" #include "libc/str/str.h" #include "libc/sysv/consts/rusage.h" #include "libc/sysv/errfuns.h" textwindows int sys_getrusage_nt(int who, struct rusage *usage) { - struct NtFileTime CreationFileTime; - struct NtFileTime ExitFileTime; - struct NtFileTime KernelFileTime; - struct NtFileTime UserFileTime; + int64_t me, nsignals; + struct NtIoCounters iocount; + struct NtProcessMemoryCountersEx memcount; + struct NtFileTime ftExit, ftUser, ftKernel, ftCreation; if (!usage) return efault(); - if (who == 99) return enosys(); /* @see libc/sysv/consts.sh */ - bzero(usage, sizeof(*usage)); - if ((who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)( + if (who == 99) return enosys(); // @see libc/sysv/consts.sh + if (!usage) return 0; + me = GetCurrentProcess(); + if (!(who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)( (who == RUSAGE_SELF ? GetCurrentProcess : GetCurrentThread)(), - &CreationFileTime, &ExitFileTime, &KernelFileTime, &UserFileTime)) { - usage->ru_utime = FileTimeToTimeVal(UserFileTime); - usage->ru_stime = FileTimeToTimeVal(KernelFileTime); - return 0; - } else { + &ftCreation, &ftExit, &ftKernel, &ftUser) || + !GetProcessMemoryInfo(me, &memcount, sizeof(memcount)) || + !GetProcessIoCounters(me, &iocount)) { return __winerr(); } + _spinlock(&__sig_lock); + nsignals = __sig_count; + _spunlock(&__sig_lock); + *usage = (struct rusage){ + .ru_utime = WindowsDurationToTimeVal(ReadFileTime(ftUser)), + .ru_stime = WindowsDurationToTimeVal(ReadFileTime(ftKernel)), + .ru_maxrss = memcount.PeakWorkingSetSize / 1024, + .ru_majflt = memcount.PageFaultCount, + .ru_inblock = iocount.ReadOperationCount, + .ru_oublock = iocount.WriteOperationCount, + .ru_nsignals = __sig_count, + }; + return 0; } diff --git a/libc/calls/getrusage.c b/libc/calls/getrusage.c index f4de92da0..68dc2151b 100644 --- a/libc/calls/getrusage.c +++ b/libc/calls/getrusage.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -29,11 +30,16 @@ * @return 0 on success, or -1 w/ errno */ int getrusage(int who, struct rusage *usage) { - if (who == 99) return einval(); - if (IsAsan() && !__asan_is_valid(usage, sizeof(*usage))) return efault(); - if (!IsWindows()) { - return sys_getrusage(who, usage); + int rc; + if (who == 99) { + rc = einval(); + } else if (IsAsan() && !__asan_is_valid(usage, sizeof(*usage))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_getrusage(who, usage); } else { - return sys_getrusage_nt(who, usage); + rc = sys_getrusage_nt(who, usage); } + STRACE("getrusage(%d, %p) → %d% m", who, usage, rc); + return rc; } diff --git a/libc/calls/getsid.c b/libc/calls/getsid.c index a2f057528..1d199e2b0 100644 --- a/libc/calls/getsid.c +++ b/libc/calls/getsid.c @@ -18,10 +18,14 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" /** * Creates session and sets the process group id. */ -uint32_t getsid(int pid) { - return sys_getsid(pid); +int getsid(int pid) { + int rc; + rc = sys_getsid(pid); + STRACE("%s(%d) → %d% m", "getsid", pid, rc); + return rc; } diff --git a/libc/calls/gettemppatha-flunk.S b/libc/calls/gettemppatha-flunk.S index dc1065213..d75ee846f 100644 --- a/libc/calls/gettemppatha-flunk.S +++ b/libc/calls/gettemppatha-flunk.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Calls GetTempPathA() w/ different API. // diff --git a/libc/calls/gettid.c b/libc/calls/gettid.c deleted file mode 100644 index 001718807..000000000 --- a/libc/calls/gettid.c +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- 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 "libc/calls/calls.h" -#include "libc/calls/internal.h" -#include "libc/dce.h" -#include "libc/nt/thread.h" - -/** - * Returns current thread id. - * @asyncsignalsafe - */ -uint32_t gettid(void) { - uint32_t res; - if (!IsWindows()) { - res = sys_gettid(); - if (res <= 0) { - res = getpid(); - } - return res; - } else { - return GetCurrentThreadId(); - } -} diff --git a/libc/calls/gettimeofday-nt.c b/libc/calls/gettimeofday-nt.c index becf42dd2..cf113f721 100644 --- a/libc/calls/gettimeofday-nt.c +++ b/libc/calls/gettimeofday-nt.c @@ -25,7 +25,7 @@ #include "libc/str/str.h" #include "libc/time/struct/timezone.h" -int sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz) { +textwindows int sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz) { struct NtFileTime ft; GetSystemTimeAsFileTime(&ft); if (tv) *tv = FileTimeToTimeVal(ft); diff --git a/libc/calls/gettimeofday.c b/libc/calls/gettimeofday.c index 425549707..927e785a4 100644 --- a/libc/calls/gettimeofday.c +++ b/libc/calls/gettimeofday.c @@ -25,6 +25,8 @@ #include "libc/time/struct/timezone.h" #include "libc/time/time.h" +static typeof(sys_gettimeofday) *__gettimeofday = sys_gettimeofday; + /** * Returns system wall time in microseconds. * @@ -40,7 +42,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) { return efault(); } if (!IsWindows() && !IsMetal()) { - ad = sys_gettimeofday(tv, tz, NULL); + ad = __gettimeofday(tv, tz, NULL); assert(ad.ax != -1); if (SupportsXnu() && ad.ax && tv) { tv->tv_sec = ad.ax; @@ -53,3 +55,14 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) { return sys_gettimeofday_nt(tv, tz); } } + +static textstartup void __gettimeofday_init(void) { + void *vdso; + if ((vdso = __vdsofunc("__vdso_gettimeofday"))) { + __gettimeofday = vdso; + } +} + +const void *const __gettimeofday_ctor[] initarray = { + __gettimeofday_init, +}; diff --git a/libc/calls/getuid.c b/libc/calls/getuid.c index f801a93f7..4c0d49be4 100644 --- a/libc/calls/getuid.c +++ b/libc/calls/getuid.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/nt/accounting.h" @@ -50,12 +51,15 @@ static textwindows dontinline uint32_t GetUserNameHash(void) { * @asyncsignalsafe * @vforksafe */ -uint32_t getuid(void) { +int getuid(void) { + int rc; if (!IsWindows()) { - return sys_getuid(); + rc = sys_getuid(); } else { - return GetUserNameHash(); + rc = GetUserNameHash(); } + STRACE("%s() → %d% m", "getuid", rc); + return rc; } /** @@ -67,10 +71,13 @@ uint32_t getuid(void) { * @asyncsignalsafe * @vforksafe */ -uint32_t getgid(void) { +int getgid(void) { + int rc; if (!IsWindows()) { - return sys_getgid(); + rc = sys_getgid(); } else { - return GetUserNameHash(); + rc = GetUserNameHash(); } + STRACE("%s() → %d% m", "getgid", rc); + return rc; } diff --git a/libc/calls/internal.h b/libc/calls/internal.h index c5de5d92d..50c0e3a85 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -5,19 +5,23 @@ #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/itimerval.h" #include "libc/calls/struct/metastat.internal.h" +#include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigaction-xnu.internal.h" +#include "libc/calls/struct/siginfo-xnu.internal.h" #include "libc/calls/struct/siginfo.h" #include "libc/calls/struct/sigval.h" #include "libc/calls/struct/stat.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" +#include "libc/calls/struct/winsize.h" #include "libc/calls/ucontext.h" #include "libc/dce.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/nt/struct/context.h" #include "libc/nt/struct/ntexceptionpointers.h" +#include "libc/nt/struct/overlapped.h" #include "libc/nt/struct/securityattributes.h" #include "libc/nt/struct/startupinfo.h" #include "libc/nt/struct/systeminfo.h" @@ -55,8 +59,11 @@ enum FdKind { struct Fd { enum FdKind kind; unsigned flags; + unsigned mode; int64_t handle; int64_t extra; + struct NtStdinWorker *worker; + bool zombie; }; struct Fds { @@ -68,15 +75,20 @@ struct Fds { extern const struct Fd kEmptyFd; -hidden extern volatile bool __interrupted; hidden extern int __vforked; +hidden extern char __fds_lock; +hidden extern char __sig_lock; +hidden extern bool __time_critical; hidden extern unsigned __sighandrvas[NSIG]; +hidden extern unsigned __sighandflags[NSIG]; hidden extern struct Fds g_fds; hidden extern const struct NtSecurityAttributes kNtIsInheritable; -int __reservefd(void) hidden; +int __reservefd(int) hidden; void __releasefd(int) hidden; int __ensurefds(int) hidden; +int64_t __getfdhandleactual(int) hidden; +void __printfds(void) hidden; forceinline bool __isfdopen(int fd) { return 0 <= fd && fd < g_fds.n && g_fds.p[fd].kind != kFdEmpty; @@ -86,7 +98,7 @@ forceinline bool __isfdkind(int fd, int kind) { return 0 <= fd && fd < g_fds.n && g_fds.p[fd].kind == kind; } -forceinline size_t clampio(size_t size) { +forceinline size_t _clampio(size_t size) { if (!IsTrustworthy()) { return MIN(size, 0x7ffff000); } else { @@ -119,9 +131,11 @@ i32 __sys_getrusage(i32, struct rusage *) hidden; i32 __sys_munmap(void *, u64) hidden; i32 __sys_openat(i32, const char *, i32, u32) hidden; i32 __sys_pipe2(i32[hasatleast 2], u32) hidden; +i32 __sys_sigprocmask(i32, const sigset *, sigset *, u64) hidden; i32 __sys_utimensat(i32, const char *, const struct timespec *, i32) hidden; i32 __sys_wait4(i32, i32 *, i32, struct rusage *) hidden; i32 sys_chdir(const char *) hidden; +i32 sys_chroot(const char *) hidden; i32 sys_clock_gettime(i32, struct timespec *) hidden; i32 sys_close(i32) hidden; i32 sys_dup(i32) hidden; @@ -146,10 +160,14 @@ i32 sys_futimes(i32, const struct timeval *) hidden; i32 sys_futimesat(i32, const char *, const struct timeval *) hidden; i32 sys_getitimer(i32, struct itimerval *) hidden; i32 sys_getpgid(i32) hidden; +i32 sys_getpgrp(void) hidden; i32 sys_getppid(void) hidden; i32 sys_getpriority(i32, u32) hidden; +i32 sys_getresgid(u32 *, u32 *, u32 *); +i32 sys_getresuid(u32 *, u32 *, u32 *); i32 sys_getrlimit(i32, struct rlimit *) hidden; i32 sys_getrusage(i32, struct rusage *) hidden; +i32 sys_getsid(int) hidden; i32 sys_ioctl(i32, u64, ...) hidden; i32 sys_kill(i32, i32, i32) hidden; i32 sys_linkat(i32, const char *, i32, const char *, i32) hidden; @@ -168,19 +186,25 @@ i32 sys_openat(i32, const char *, i32, u32) hidden; i32 sys_pause(void) hidden; i32 sys_pipe(i32[hasatleast 2]) hidden; i32 sys_pipe2(i32[hasatleast 2], u32) hidden; +i32 sys_pledge(const char *, const char *) hidden; i32 sys_posix_openpt(i32) hidden; i32 sys_renameat(i32, const char *, i32, const char *) hidden; i32 sys_sched_setaffinity(i32, u64, const void *) hidden; i32 sys_sched_yield(void) hidden; +i32 sys_setgid(i32) hidden; i32 sys_setitimer(i32, const struct itimerval *, struct itimerval *) hidden; +i32 sys_setpgid(i32, i32) hidden; i32 sys_setpriority(i32, u32, i32) hidden; -i32 sys_setresgid(uint32_t, uint32_t, uint32_t) hidden; -i32 sys_setresuid(uint32_t, uint32_t, uint32_t) hidden; +i32 sys_setregid(u32, u32) hidden; +i32 sys_setresgid(u32, u32, u32) hidden; +i32 sys_setresuid(u32, u32, u32) hidden; +i32 sys_setreuid(u32, u32) hidden; i32 sys_setrlimit(i32, const struct rlimit *) hidden; i32 sys_setsid(void) hidden; +i32 sys_setuid(i32) hidden; i32 sys_sigaction(i32, const void *, void *, i64, i64) hidden; i32 sys_sigaltstack(const void *, void *) hidden; -i32 sys_sigprocmask(i32, const sigset *, sigset *, u64) hidden; +i32 sys_sigprocmask(i32, const sigset *, sigset *) hidden; i32 sys_sigqueue(i32, i32, const union sigval) hidden; i32 sys_sigqueueinfo(i32, const siginfo_t *) hidden; i32 sys_sigsuspend(const sigset *, u64) hidden; @@ -209,10 +233,12 @@ i64 sys_sendfile(i32, i32, i64 *, u64) hidden; i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) hidden; i64 sys_vmsplice(i32, const struct iovec *, i64, u32) hidden; i64 sys_write(i32, const void *, u64) hidden; +u32 sys_getegid(void) hidden; +u32 sys_geteuid(void) hidden; u32 sys_getgid(void) hidden; -u32 sys_getsid(int) hidden; u32 sys_gettid(void) hidden; u32 sys_getuid(void) hidden; +u32 sys_umask(u32) 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; @@ -222,18 +248,19 @@ void sys_exit(int) hidden; ╚────────────────────────────────────────────────────────────────────────────│*/ void __onfork(void) hidden; +void *__vdsofunc(const char *) hidden; +void *__get_clock_gettime(void) hidden; i32 __fixupnewfd(i32, i32) hidden; -u32 __prot2nt(i32, i32) privileged; void __restore_rt() hidden; int sys_utimensat_xnu(int, const char *, const struct timespec *, int) hidden; int sys_nanosleep_xnu(const struct timespec *, struct timespec *) hidden; void __stat2cosmo(struct stat *restrict, const union metastat *) hidden; void __restore_rt_netbsd(void) hidden; -void __sigenter_xnu(void *, i32, i32, struct __darwin_siginfo *, +void __sigenter_xnu(void *, i32, i32, struct siginfo_xnu *, struct __darwin_ucontext *) hidden; int gethostname_linux(char *, size_t) hidden; int gethostname_bsd(char *, size_t) hidden; -int gethostname_nt(char *, size_t) hidden; +int gethostname_nt(char *, size_t, int) hidden; size_t __iovec_size(const struct iovec *, size_t) hidden; void __rusage2linux(struct rusage *) hidden; int __notziposat(int, const char *); @@ -259,7 +286,7 @@ i64 sys_lseek_nt(int, i64, int) hidden; int sys_chdir_nt(const char *) hidden; int sys_close_epoll_nt(int) hidden; int sys_close_nt(struct Fd *) hidden; -int sys_dup_nt(int, int, int) hidden; +int sys_dup_nt(int, int, int, int) hidden; int sys_execve_nt(const char *, char *const[], char *const[]) hidden; int sys_faccessat_nt(int, const char *, int, uint32_t) hidden; int sys_fadvise_nt(int, u64, u64, int) hidden; @@ -281,7 +308,7 @@ int sys_linkat_nt(int, const char *, int, const char *) hidden; int sys_lstat_nt(const char *, struct stat *) hidden; int sys_madvise_nt(void *, size_t, int) hidden; int sys_mkdirat_nt(int, const char *, uint32_t) hidden; -int sys_msync_nt(void *, size_t, int) hidden; +int sys_msync_nt(char *, size_t, int) hidden; int sys_nanosleep_nt(const struct timespec *, struct timespec *) hidden; int sys_pipe_nt(int[hasatleast 2], unsigned) hidden; int sys_renameat_nt(int, const char *, int, const char *) hidden; @@ -293,38 +320,48 @@ int sys_sync_nt(void) hidden; int sys_sysinfo_nt(struct sysinfo *) hidden; int sys_truncate_nt(const char *, u64) hidden; int sys_unlinkat_nt(int, const char *, int) hidden; +int sys_setrlimit_nt(int, const struct rlimit *) hidden; int sys_utimensat_nt(int, const char *, const struct timespec *, int) hidden; int sys_utimes_nt(const char *, const struct timeval[2]) hidden; -ssize_t sys_open_nt(int, const char *, u32, i32) nodiscard hidden; +ssize_t sys_open_nt(int, const char *, u32, i32) dontdiscard hidden; ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden; ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) hidden; -ssize_t sys_write_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden; +ssize_t sys_write_nt(int, const struct iovec *, size_t, ssize_t) hidden; +int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden; /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § syscalls » windows nt » support ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ +bool __is_linux_2_6_23(void) hidden; +int64_t __fix_enotdir(int64_t, char16_t *) hidden; +int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *) hidden; +bool _check_interrupts(bool, struct Fd *) hidden; +void _check_sigchld(void) hidden; +void _check_sigalrm(void) hidden; +int __sample_pids(int[hasatleast 64], int64_t[hasatleast 64], bool) hidden; bool isdirectory_nt(const char *) hidden; bool isregularfile_nt(const char *) hidden; bool issymlink_nt(const char *) hidden; bool32 ntsetprivilege(i64, const char16_t *, u32) hidden; char16_t *CreatePipeName(char16_t *) hidden; -int __mkntpath(const char *, char16_t[hasatleast PATH_MAX - 16]) hidden; -int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX - 16], int) hidden; -int __mkntpathat(int, const char *, int, char16_t[PATH_MAX]) hidden; +int __mkntpath(const char *, char16_t[hasatleast PATH_MAX]) hidden; +int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX], int) hidden; +int __mkntpathat(int, const char *, int, char16_t[hasatleast PATH_MAX]) hidden; int sys_clock_gettime_nt(int, struct timespec *) hidden; int ntaccesscheck(const char16_t *, u32) paramsnonnull() hidden; int sys_getsetpriority_nt(int, int, int, int (*)(int)); int64_t __winerr(void) nocallback privileged; int64_t ntreturn(uint32_t); ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) hidden; -ssize_t sys_writev_nt(struct Fd *, const struct iovec *, int) hidden; -struct NtOverlapped *offset2overlap(int64_t, struct NtOverlapped *) hidden; +ssize_t sys_writev_nt(int, const struct iovec *, int) hidden; unsigned __wincrash_nt(struct NtExceptionPointers *); void *GetProcAddressModule(const char *, const char *) hidden; void WinMainForked(void) hidden; -void __winalarm(void *, uint32_t, uint32_t) hidden; -void ntcontext2linux(struct ucontext *, const struct NtContext *) hidden; +void _ntcontext2linux(struct ucontext *, const struct NtContext *) hidden; +void _ntlinux2context(struct NtContext *, const ucontext_t *) hidden; +struct NtOverlapped *_offset2overlap(int64_t, int64_t, + struct NtOverlapped *) hidden; /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § syscalls » metal ─╬─│┼ diff --git a/libc/calls/interrupted.c b/libc/calls/interrupted.c deleted file mode 100644 index 3362c4e62..000000000 --- a/libc/calls/interrupted.c +++ /dev/null @@ -1,21 +0,0 @@ -/*-*- 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/internal.h" - -volatile bool __interrupted; diff --git a/libc/calls/interrupts-nt.c b/libc/calls/interrupts-nt.c new file mode 100644 index 000000000..a77b28bfd --- /dev/null +++ b/libc/calls/interrupts-nt.c @@ -0,0 +1,33 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/bits/weaken.h" +#include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/dce.h" + +textwindows bool _check_interrupts(bool restartable, struct Fd *fd) { + if (__time_critical) return false; + if (weaken(_check_sigalrm)) weaken(_check_sigalrm)(); + if (weaken(_check_sigchld)) weaken(_check_sigchld)(); + if (fd && weaken(_check_sigwinch)) weaken(_check_sigwinch)(fd); + return weaken(__sig_check) && weaken(__sig_check)(restartable); +} diff --git a/libc/calls/ioctl.c b/libc/calls/ioctl.c index d52cdaf0d..0f6e4685c 100644 --- a/libc/calls/ioctl.c +++ b/libc/calls/ioctl.c @@ -25,6 +25,7 @@ /** * Controls settings on device. + * @restartable * @vforksafe */ int(ioctl)(int fd, uint64_t request, ...) { diff --git a/libc/calls/ioctl_default.c b/libc/calls/ioctl_default.c index 8b58cb107..11886fb1a 100644 --- a/libc/calls/ioctl_default.c +++ b/libc/calls/ioctl_default.c @@ -35,7 +35,7 @@ int ioctl_default(int fd, uint64_t request, ...) { return sys_ioctl(fd, request, arg); } else if (__isfdopen(fd)) { if (g_fds.p[fd].kind == kFdSocket) { - handle = g_fds.p[fd].handle; + handle = __getfdhandleactual(fd); if ((rc = weaken(__sys_ioctlsocket_nt)(handle, request, arg)) != -1) { return rc; } else { diff --git a/libc/calls/ioctl_fioclex.c b/libc/calls/ioctl_fioclex.c index 4d8a0e303..8c0de779c 100644 --- a/libc/calls/ioctl_fioclex.c +++ b/libc/calls/ioctl_fioclex.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/calls/ioctl.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" @@ -28,6 +29,7 @@ * @see ioctl(fd, FIOCLEX, 0) dispatches here */ int ioctl_fioclex(int fd, int req) { + int rc; if (fd >= 0) { if (IsWindows() || (fd < g_fds.n && g_fds.p[fd].kind == kFdZip)) { if (__isfdopen(fd)) { @@ -36,14 +38,16 @@ int ioctl_fioclex(int fd, int req) { } else { g_fds.p[fd].flags &= ~O_CLOEXEC; } - return 0; + rc = 0; } else { - return ebadf(); + rc = ebadf(); } } else { - return sys_ioctl(fd, req); + rc = sys_ioctl(fd, req); } } else { - return einval(); + rc = einval(); } + STRACE("%s(%d, %d) → %d% m", "ioctl_fioclex", fd, req, rc); + return rc; } diff --git a/libc/calls/ioctl_siocgifconf-nt.c b/libc/calls/ioctl_siocgifconf-nt.c index 1c62ce33b..d693df24c 100644 --- a/libc/calls/ioctl_siocgifconf-nt.c +++ b/libc/calls/ioctl_siocgifconf-nt.c @@ -17,10 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" -#include "libc/bits/bits.h" #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/intrin/cmpxchg.h" #include "libc/nt/errors.h" #include "libc/nt/iphlpapi.h" #include "libc/nt/runtime.h" @@ -275,7 +275,7 @@ static int createHostInfo(struct NtIpAdapterAddresses *firstAdapter) { if (!node) goto err; if (!__hostInfo) { __hostInfo = node; - if (cmpxchg(&once, false, true)) { + if (_cmpxchg(&once, false, true)) { atexit(freeHostInfo); } } diff --git a/libc/calls/ioctl_siocgifconf.c b/libc/calls/ioctl_siocgifconf.c index debafc1b4..4f395736c 100644 --- a/libc/calls/ioctl_siocgifconf.c +++ b/libc/calls/ioctl_siocgifconf.c @@ -17,9 +17,11 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" +#include "libc/bits/bits.h" #include "libc/bits/weaken.h" #include "libc/calls/internal.h" #include "libc/calls/ioctl.h" +#include "libc/calls/strace.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/str/str.h" @@ -104,16 +106,19 @@ static int ioctl_siocgifaddr_sysv(int fd, uint64_t op, struct ifreq *ifr) { * @see ioctl(fd, SIOCGIFCONF, tio) dispatches here */ int ioctl_siocgifconf(int fd, ...) { + int rc; va_list va; struct ifconf *ifc; va_start(va, fd); ifc = va_arg(va, struct ifconf *); va_end(va); if (!IsWindows()) { - return ioctl_siocgifconf_sysv(fd, ifc); + rc = ioctl_siocgifconf_sysv(fd, ifc); } else { - return ioctl_siocgifconf_nt(fd, ifc); + rc = ioctl_siocgifconf_nt(fd, ifc); } + STRACE("%s(%d) → %d% m", "ioctl_siocgifconf", fd, rc); + return rc; } int ioctl_siocgifaddr(int fd, ...) { diff --git a/libc/calls/ioctl_tcgets-nt.c b/libc/calls/ioctl_tcgets-nt.c index 4dc69e732..ac04c84f5 100644 --- a/libc/calls/ioctl_tcgets-nt.c +++ b/libc/calls/ioctl_tcgets-nt.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/termios.h" +#include "libc/calls/ttydefaults.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/nt/struct/consolescreenbufferinfoex.h" @@ -31,19 +32,51 @@ textwindows int ioctl_tcgets_nt(int ignored, struct termios *tio) { int64_t in, out; bool32 inok, outok; uint32_t inmode, outmode; - inok = GetConsoleMode((in = g_fds.p[0].handle), &inmode); - outok = GetConsoleMode((out = g_fds.p[1].handle), &outmode); + inok = GetConsoleMode((in = __getfdhandleactual(0)), &inmode); + outok = GetConsoleMode((out = __getfdhandleactual(1)), &outmode); if (inok | outok) { bzero(tio, sizeof(*tio)); + + tio->c_cflag |= CS8; + + tio->c_cc[VINTR] = CTRL('C'); + tio->c_cc[VQUIT] = CTRL('\\'); + tio->c_cc[VERASE] = CTRL('?'); + tio->c_cc[VKILL] = CTRL('U'); + tio->c_cc[VEOF] = CTRL('D'); + tio->c_cc[VMIN] = CTRL('A'); + tio->c_cc[VSTART] = CTRL('Q'); + tio->c_cc[VSTOP] = CTRL('S'); + tio->c_cc[VSUSP] = CTRL('Z'); + tio->c_cc[VREPRINT] = CTRL('R'); + tio->c_cc[VDISCARD] = CTRL('O'); + tio->c_cc[VWERASE] = CTRL('W'); + tio->c_cc[VLNEXT] = CTRL('V'); + if (inok) { - if (inmode & kNtEnableLineInput) tio->c_lflag |= ICANON; - if (inmode & kNtEnableEchoInput) tio->c_lflag |= ECHO; - if (inmode & kNtEnableProcessedInput) tio->c_lflag |= IEXTEN | ISIG; + if (inmode & kNtEnableLineInput) { + tio->c_lflag |= ICANON; + } + if (inmode & kNtEnableEchoInput) { + tio->c_lflag |= ECHO; + } + if (inmode & kNtEnableProcessedInput) { + tio->c_lflag |= IEXTEN | ISIG; + if (tio->c_lflag | ECHO) { + tio->c_lflag |= ECHOE; + } + } } + if (outok) { - if (outmode & kNtEnableProcessedOutput) tio->c_oflag |= OPOST; - if (!(outmode & kNtDisableNewlineAutoReturn)) tio->c_oflag |= ONLCR; + if (outmode & kNtEnableProcessedOutput) { + tio->c_oflag |= OPOST; + } + if (!(outmode & kNtDisableNewlineAutoReturn)) { + tio->c_oflag |= OPOST | ONLCR; + } } + return 0; } else { return enotty(); diff --git a/libc/calls/ioctl_tcgets.c b/libc/calls/ioctl_tcgets.c index 564fcb772..14860ee24 100644 --- a/libc/calls/ioctl_tcgets.c +++ b/libc/calls/ioctl_tcgets.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/calls/ioctl.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/metatermios.internal.h" #include "libc/calls/termios.internal.h" #include "libc/calls/ttydefaults.h" @@ -65,23 +66,27 @@ static int ioctl_tcgets_sysv(int fd, struct termios *tio) { * @see ioctl(fd, TIOCGETA, tio) dispatches here */ int ioctl_tcgets(int fd, ...) { + int rc; va_list va; struct termios *tio; va_start(va, fd); tio = va_arg(va, struct termios *); va_end(va); if (fd >= 0) { - if (!tio) return efault(); - if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return enotty(); + if (!tio || (IsAsan() && !__asan_is_valid(tio, sizeof(*tio)))) { + rc = efault(); + } else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { + rc = enotty(); } else if (IsMetal()) { - return ioctl_tcgets_metal(fd, tio); + rc = ioctl_tcgets_metal(fd, tio); } else if (!IsWindows()) { - return ioctl_tcgets_sysv(fd, tio); + rc = ioctl_tcgets_sysv(fd, tio); } else { - return ioctl_tcgets_nt(fd, tio); + rc = ioctl_tcgets_nt(fd, tio); } } else { - return einval(); + rc = einval(); } + STRACE("ioctl_tcgets(%d, %p) → %d% m", fd, tio, rc); + return rc; } diff --git a/libc/calls/ioctl_tcsets-nt.c b/libc/calls/ioctl_tcsets-nt.c index ba52c2a80..9eb023cad 100644 --- a/libc/calls/ioctl_tcsets-nt.c +++ b/libc/calls/ioctl_tcsets-nt.c @@ -17,8 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/metatermios.internal.h" #include "libc/calls/termios.internal.h" +#include "libc/intrin/describeflags.internal.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/nt/enum/version.h" @@ -29,35 +31,54 @@ textwindows int ioctl_tcsets_nt(int ignored, uint64_t request, const struct termios *tio) { int64_t in, out; - bool32 inok, outok; + bool32 ok, inok, outok; uint32_t inmode, outmode; - inok = GetConsoleMode((in = g_fds.p[0].handle), &inmode); - outok = GetConsoleMode((out = g_fds.p[1].handle), &outmode); + inok = GetConsoleMode((in = __getfdhandleactual(0)), &inmode); + outok = GetConsoleMode((out = __getfdhandleactual(1)), &outmode); if (inok | outok) { + if (inok) { if (request == TCSETSF) { FlushConsoleInputBuffer(in); } inmode &= ~(kNtEnableLineInput | kNtEnableEchoInput | kNtEnableProcessedInput); - if (tio->c_lflag & ICANON) inmode |= kNtEnableLineInput; - if (tio->c_lflag & ECHO) inmode |= kNtEnableEchoInput; - if (tio->c_lflag & (IEXTEN | ISIG)) inmode |= kNtEnableProcessedInput; inmode |= kNtEnableWindowInput; + if (tio->c_lflag & ICANON) { + inmode |= kNtEnableLineInput; + } + if (tio->c_lflag & ECHO) { + /* + * kNtEnableEchoInput can be used only if the ENABLE_LINE_INPUT mode + * is also enabled. --Quoth MSDN + */ + inmode |= kNtEnableEchoInput | kNtEnableLineInput; + } + if (tio->c_lflag & (IEXTEN | ISIG)) { + inmode |= kNtEnableProcessedInput; + } if (NtGetVersion() >= kNtVersionWindows10) { inmode |= kNtEnableVirtualTerminalInput; } - SetConsoleMode(in, inmode); + ok = SetConsoleMode(in, inmode); + NTTRACE("SetConsoleMode(%p, %s) → %hhhd", in, + DescribeNtConsoleModeInputFlags(inmode), ok); } + if (outok) { - outmode |= kNtEnableWrapAtEolOutput; - if (tio->c_oflag & OPOST) outmode |= kNtEnableProcessedOutput; - if (!(tio->c_oflag & ONLCR)) outmode |= kNtDisableNewlineAutoReturn; + outmode &= ~(kNtDisableNewlineAutoReturn); + outmode |= kNtEnableProcessedOutput; + if (!(tio->c_oflag & ONLCR)) { + outmode |= kNtDisableNewlineAutoReturn; + } if (NtGetVersion() >= kNtVersionWindows10) { outmode |= kNtEnableVirtualTerminalProcessing; } - SetConsoleMode(out, outmode); + ok = SetConsoleMode(out, outmode); + NTTRACE("SetConsoleMode(%p, %s) → %hhhd", out, + DescribeNtConsoleModeOutputFlags(outmode), ok); } + return 0; } else { return enotty(); diff --git a/libc/calls/ioctl_tcsets.c b/libc/calls/ioctl_tcsets.c index 8986bfebd..34e2592fa 100644 --- a/libc/calls/ioctl_tcsets.c +++ b/libc/calls/ioctl_tcsets.c @@ -18,10 +18,12 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/calls/ioctl.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/metatermios.internal.h" #include "libc/calls/termios.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/nomultics.internal.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" @@ -35,7 +37,7 @@ static int ioctl_tcsets_metal(int fd, uint64_t request, static inline void *__termios2host(union metatermios *mt, const struct termios *lt) { if (!IsXnu() && !IsFreebsd() && !IsOpenbsd() && !IsNetbsd()) { - return lt; + return (/*unconst*/ void *)lt; } else if (IsXnu()) { COPY_TERMIOS(&mt->xnu, lt); return &mt->xnu; @@ -60,23 +62,27 @@ static int ioctl_tcsets_sysv(int fd, uint64_t request, * @see ioctl(fd, TIOCGETA{,W,F}, tio) dispatches here */ int ioctl_tcsets(int fd, uint64_t request, ...) { + int rc; va_list va; const struct termios *tio; va_start(va, request); tio = va_arg(va, const struct termios *); va_end(va); - if (!tio) return efault(); - if (fd >= 0) { + if (!tio || (IsAsan() && !__asan_is_valid(tio, sizeof(*tio)))) { + rc = efault(); + } else if (fd >= 0) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return enotty(); + rc = enotty(); } else if (IsMetal()) { - return ioctl_tcsets_metal(fd, request, tio); + rc = ioctl_tcsets_metal(fd, request, tio); } else if (!IsWindows()) { - return ioctl_tcsets_sysv(fd, request, tio); + rc = ioctl_tcsets_sysv(fd, request, tio); } else { - return ioctl_tcsets_nt(fd, request, tio); + rc = ioctl_tcsets_nt(fd, request, tio); } } else { - return einval(); + rc = einval(); } + STRACE("ioctl_tcsets(%d, %p, %p) → %d% m", fd, request, tio, rc); + return rc; } diff --git a/libc/calls/ioctl_tiocgwinsz-nt.c b/libc/calls/ioctl_tiocgwinsz-nt.c index 1a061683e..5080a3df5 100644 --- a/libc/calls/ioctl_tiocgwinsz-nt.c +++ b/libc/calls/ioctl_tiocgwinsz-nt.c @@ -16,10 +16,13 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/termios.h" #include "libc/calls/struct/winsize.h" +#include "libc/log/log.h" #include "libc/nt/console.h" #include "libc/nt/enum/startf.h" #include "libc/nt/startupinfo.h" @@ -27,40 +30,47 @@ #include "libc/str/str.h" #include "libc/sysv/errfuns.h" -textwindows int ioctl_tiocgwinsz_nt(int fd, struct winsize *ws) { - int i, fds[3]; +textwindows int ioctl_tiocgwinsz_nt(struct Fd *fd, struct winsize *ws) { + int i, e; uint32_t mode; + struct Fd *fds[3]; struct NtStartupInfo startinfo; struct NtConsoleScreenBufferInfoEx sbinfo; - if (!ws) return efault(); - fds[0] = fd, fds[1] = 1, fds[2] = 0; - GetStartupInfo(&startinfo); - for (i = 0; i < ARRAYLEN(fds); ++i) { - if (__isfdkind(fds[i], kFdFile) || __isfdkind(fds[i], kFdConsole)) { - if (GetConsoleMode(g_fds.p[fds[i]].handle, &mode)) { - bzero(&sbinfo, sizeof(sbinfo)); - sbinfo.cbSize = sizeof(sbinfo); - if (GetConsoleScreenBufferInfoEx(g_fds.p[fds[i]].handle, &sbinfo)) { - ws->ws_col = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1; - ws->ws_row = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1; - ws->ws_xpixel = 0; - ws->ws_ypixel = 0; - return 0; - } else if (startinfo.dwFlags & kNtStartfUsecountchars) { - ws->ws_col = startinfo.dwXCountChars; - ws->ws_row = startinfo.dwYCountChars; - ws->ws_xpixel = 0; - ws->ws_ypixel = 0; - return 0; + e = errno; + if (ws) { + fds[0] = fd, fds[1] = g_fds.p + 1, fds[2] = g_fds.p + 0; + GetStartupInfo(&startinfo); + for (i = 0; i < ARRAYLEN(fds); ++i) { + if (fds[i]->kind == kFdFile || fds[i]->kind == kFdConsole) { + if (GetConsoleMode(__getfdhandleactual(i), &mode)) { + bzero(&sbinfo, sizeof(sbinfo)); + sbinfo.cbSize = sizeof(sbinfo); + if (GetConsoleScreenBufferInfoEx(__getfdhandleactual(i), &sbinfo)) { + ws->ws_col = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1; + ws->ws_row = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1; + ws->ws_xpixel = 0; + ws->ws_ypixel = 0; + errno = e; + return 0; + } else if (startinfo.dwFlags & kNtStartfUsecountchars) { + ws->ws_col = startinfo.dwXCountChars; + ws->ws_row = startinfo.dwYCountChars; + ws->ws_xpixel = 0; + ws->ws_ypixel = 0; + errno = e; + return 0; + } else { + __winerr(); + } } else { - __winerr(); + enotty(); } } else { - enotty(); + ebadf(); } - } else { - ebadf(); } + } else { + efault(); } return -1; } diff --git a/libc/calls/ioctl_tiocgwinsz.c b/libc/calls/ioctl_tiocgwinsz.c index 7a2caa4f3..91abae9f8 100644 --- a/libc/calls/ioctl_tiocgwinsz.c +++ b/libc/calls/ioctl_tiocgwinsz.c @@ -18,35 +18,38 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/calls/ioctl.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/winsize.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" -int ioctl_tiocgwinsz_nt(int, struct winsize *); - /** * Returns width and height of terminal. * * @see ioctl(fd, TIOCGWINSZ, ws) dispatches here */ int ioctl_tiocgwinsz(int fd, ...) { + int rc; va_list va; struct winsize *ws; va_start(va, fd); ws = va_arg(va, struct winsize *); va_end(va); - if (IsAsan() && !__asan_is_valid(ws, sizeof(*ws))) return efault(); - if (fd >= 0) { + if (IsAsan() && !__asan_is_valid(ws, sizeof(*ws))) { + rc = efault(); + } else if (fd >= 0) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return enotty(); + rc = enotty(); } else if (!IsWindows()) { - return sys_ioctl(fd, TIOCGWINSZ, ws); + rc = sys_ioctl(fd, TIOCGWINSZ, ws); } else { - return ioctl_tiocgwinsz_nt(fd, ws); + rc = ioctl_tiocgwinsz_nt(g_fds.p + fd, ws); } } else { - return einval(); + rc = einval(); } + STRACE("%s(%d) → %d% m", "ioctl_tiocgwinsz", fd, rc); + return rc; } diff --git a/libc/calls/ioctl_tiocswinsz-nt.c b/libc/calls/ioctl_tiocswinsz-nt.c index bf87f4181..1b80cd24f 100644 --- a/libc/calls/ioctl_tiocswinsz-nt.c +++ b/libc/calls/ioctl_tiocswinsz-nt.c @@ -29,9 +29,10 @@ textwindows int ioctl_tiocswinsz_nt(int fd, const struct winsize *ws) { struct NtCoord coord; if (!ws) return efault(); if (!__isfdkind(fd, kFdFile)) return ebadf(); - if (!GetConsoleMode(g_fds.p[fd].handle, &mode)) return enotty(); + if (!GetConsoleMode(__getfdhandleactual(fd), &mode)) return enotty(); coord.X = ws->ws_col; coord.Y = ws->ws_row; - if (!SetConsoleScreenBufferSize(g_fds.p[fd].handle, coord)) return __winerr(); + if (!SetConsoleScreenBufferSize(__getfdhandleactual(fd), coord)) + return __winerr(); return 0; } diff --git a/libc/calls/isatty-nt.c b/libc/calls/isatty-nt.c index 014cd1990..f59eb9ba4 100644 --- a/libc/calls/isatty-nt.c +++ b/libc/calls/isatty-nt.c @@ -24,5 +24,5 @@ textwindows bool32 sys_isatty_nt(int fd) { return __isfdkind(fd, kFdConsole) || (__isfdkind(fd, kFdFile) && - GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar); + GetFileType(__getfdhandleactual(fd)) == kNtFileTypeChar); } diff --git a/libc/calls/isatty.c b/libc/calls/isatty.c index 788e8c66c..3498b7bc3 100644 --- a/libc/calls/isatty.c +++ b/libc/calls/isatty.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/winsize.h" #include "libc/dce.h" #include "libc/errno.h" @@ -27,23 +28,24 @@ * Returns true if file descriptor is backed by a terminal device. */ bool32 isatty(int fd) { - int err; + int e; bool32 res; struct winsize ws; + e = errno; if (fd >= 0) { if (__isfdkind(fd, kFdZip)) { - return false; + res = false; } else if (IsMetal()) { - return false; + res = false; } else if (!IsWindows()) { - err = errno; res = sys_ioctl(fd, TIOCGWINSZ, &ws) != -1; - errno = err; - return res; } else { - return sys_isatty_nt(fd); + res = sys_isatty_nt(fd); } } else { - return false; + res = false; } + STRACE("isatty(%d) → %hhhd% m", fd, res); + errno = e; + return res; } diff --git a/libc/calls/ischardev.c b/libc/calls/ischardev.c index 2777d0ad4..82fbe7d51 100644 --- a/libc/calls/ischardev.c +++ b/libc/calls/ischardev.c @@ -66,6 +66,6 @@ bool32 ischardev(int fd) { } else { return __isfdkind(fd, kFdConsole) || (__isfdkind(fd, kFdFile) && - GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar); + GetFileType(__getfdhandleactual(fd)) == kNtFileTypeChar); } } diff --git a/libc/calls/isdirectory-nt.c b/libc/calls/isdirectory-nt.c index 6cbac59e9..d0579a967 100644 --- a/libc/calls/isdirectory-nt.c +++ b/libc/calls/isdirectory-nt.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/errno.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/files.h" @@ -25,12 +26,15 @@ * Returns true if file exists and is a directory on Windows NT. */ bool isdirectory_nt(const char *path) { + int e; uint32_t x; char16_t path16[PATH_MAX]; + e = errno; if (__mkntpath(path, path16) == -1) return -1; if ((x = GetFileAttributes(path16)) != -1u) { return !!(x & kNtFileAttributeDirectory); } else { + errno = e; return false; } } diff --git a/libc/calls/isdirectory.c b/libc/calls/isdirectory.c index c1c927889..c68af54d4 100644 --- a/libc/calls/isdirectory.c +++ b/libc/calls/isdirectory.c @@ -19,9 +19,9 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/metastat.internal.h" #include "libc/calls/struct/stat.h" -#include "libc/calls/sysdebug.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/asan.internal.h" @@ -39,7 +39,7 @@ * return fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1 && * S_ISDIR(st.st_mode); * - * Except faster and with fewer dependencies. + * Except faster, with fewer dependencies, and less errno clobbering. * * @see isregularfile(), issymlink(), ischardev() */ @@ -49,8 +49,11 @@ bool isdirectory(const char *path) { union metastat st; struct ZiposUri zipname; e = errno; - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) { + if (IsAsan() && !__asan_is_valid(path, 1)) { + efault(); + res = false; + } else if (weaken(__zipos_open) && + weaken(__zipos_parseuri)(path, &zipname) != -1) { if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) { res = S_ISDIR(st.cosmo.st_mode); } else { @@ -59,7 +62,6 @@ bool isdirectory(const char *path) { } else if (IsMetal()) { res = false; } else if (!IsWindows()) { - e = errno; if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) { res = S_ISDIR(METASTAT(st, st_mode)); } else { @@ -68,8 +70,7 @@ bool isdirectory(const char *path) { } else { res = isdirectory_nt(path); } - SYSDEBUG("isdirectory(%s) -> %s %s", path, res ? "true" : "false", - res ? "" : strerror(errno)); + STRACE("%s(%#s) → %hhhd% m", "isdirectory", path, res); if (!res && (errno == ENOENT || errno == ENOTDIR)) { errno = e; } diff --git a/libc/calls/isexecutable.c b/libc/calls/isexecutable.c index f79f7ca6d..b1c3974d2 100644 --- a/libc/calls/isexecutable.c +++ b/libc/calls/isexecutable.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" +#include "libc/sysv/consts/at.h" #include "libc/sysv/consts/s.h" /** @@ -25,9 +26,10 @@ * * @see access(exe, X_OK) which is more accurate on NT * @asyncsignalsafe + * @vforksafe */ bool isexecutable(const char *path) { - struct stat st; - if (stat(path, &st)) return 0; - return st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH); + struct stat st; /* execve() depends on this */ + if (fstatat(AT_FDCWD, path, &st, 0)) return 0; + return !S_ISDIR(st.st_mode) && !!(st.st_mode & 0111); } diff --git a/libc/calls/islinux.c b/libc/calls/islinux.c new file mode 100644 index 000000000..1209f959e --- /dev/null +++ b/libc/calls/islinux.c @@ -0,0 +1,32 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/sysv/consts/pr.h" + +bool __is_linux_2_6_23(void) { + int rc; + if (!IsLinux()) return false; + asm volatile("syscall" + : "=a"(rc) + : "0"(157), "D"(PR_GET_SECCOMP) + : "rcx", "r11", "memory"); + return rc != -EINVAL; +} diff --git a/libc/calls/isregularfile-nt.c b/libc/calls/isregularfile-nt.c index cac70076b..45614ef64 100644 --- a/libc/calls/isregularfile-nt.c +++ b/libc/calls/isregularfile-nt.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/errno.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/files.h" @@ -25,12 +26,15 @@ * Returns true if file exists and is a regular file on Windows NT. */ bool isregularfile_nt(const char *path) { + int e; uint32_t x; char16_t path16[PATH_MAX]; + e = errno; if (__mkntpath(path, path16) == -1) return -1; if ((x = GetFileAttributes(path16)) != -1u) { return !(x & (kNtFileAttributeDirectory | kNtFileAttributeReparsePoint)); } else { + errno = e; return false; } } diff --git a/libc/calls/isregularfile.c b/libc/calls/isregularfile.c index 66d0022d4..35b145b9c 100644 --- a/libc/calls/isregularfile.c +++ b/libc/calls/isregularfile.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/metastat.internal.h" #include "libc/dce.h" #include "libc/errno.h" @@ -35,34 +36,40 @@ * return fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1 && * S_ISREG(st.st_mode); * - * Except faster and with fewer dependencies. + * Except faster, with fewer dependencies, and less errno clobbering. * * @see isdirectory(), ischardev(), issymlink() */ bool isregularfile(const char *path) { - int rc, e; + int e; + bool res; union metastat st; struct ZiposUri zipname; - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) { - e = errno; + e = errno; + if (IsAsan() && !__asan_is_valid(path, 1)) { + efault(); + res = false; + } else if (weaken(__zipos_open) && + weaken(__zipos_parseuri)(path, &zipname) != -1) { if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) { - return S_ISREG(st.cosmo.st_mode); + res = !!S_ISREG(st.cosmo.st_mode); } else { - errno = e; - return false; + res = false; } } else if (IsMetal()) { - return false; + res = false; } else if (!IsWindows()) { - e = errno; if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) { - return S_ISREG(METASTAT(st, st_mode)); + res = S_ISREG(METASTAT(st, st_mode)); } else { - errno = e; - return false; + res = false; } } else { - return isregularfile_nt(path); + res = isregularfile_nt(path); } + STRACE("%s(%#s) → %hhhd% m", "isregularfile", path, res); + if (!res && (errno == ENOENT || errno == ENOTDIR)) { + errno = e; + } + return res; } diff --git a/libc/calls/issymlink-nt.c b/libc/calls/issymlink-nt.c index 267f70cb8..4c074cadb 100644 --- a/libc/calls/issymlink-nt.c +++ b/libc/calls/issymlink-nt.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/errno.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/files.h" @@ -25,12 +26,15 @@ * Returns true if file exists and is a symbolic link on Windows NT. */ bool issymlink_nt(const char *path) { + int e; uint32_t x; char16_t path16[PATH_MAX]; + e = errno; if (__mkntpath(path, path16) == -1) return -1; if ((x = GetFileAttributes(path16)) != -1u) { return !!(x & kNtFileAttributeReparsePoint); } else { + errno = e; return false; } } diff --git a/libc/calls/issymlink.c b/libc/calls/issymlink.c index ecb907d22..2e2ddcfb5 100644 --- a/libc/calls/issymlink.c +++ b/libc/calls/issymlink.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/metastat.internal.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" @@ -44,22 +45,30 @@ */ bool issymlink(const char *path) { int e; + bool res; union metastat st; struct ZiposUri zipname; - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) { - return false; + e = errno; + if (IsAsan() && !__asan_is_valid(path, 1)) { + efault(); + res = false; + } else if (weaken(__zipos_open) && + weaken(__zipos_parseuri)(path, &zipname) != -1) { + res = false; } else if (IsMetal()) { - return false; + res = false; } else if (!IsWindows()) { - e = errno; if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) { - return S_ISLNK(METASTAT(st, st_mode)); + res = S_ISLNK(METASTAT(st, st_mode)); } else { - errno = e; - return false; + res = false; } } else { - return issymlink_nt(path); + res = issymlink_nt(path); } + STRACE("%s(%#s) → %hhhd% m", "issymlink", path, res); + if (!res && (errno == ENOENT || errno == ENOTDIR)) { + errno = e; + } + return res; } diff --git a/libc/calls/kclocknames.S b/libc/calls/kclocknames.S new file mode 100644 index 000000000..d302c87d3 --- /dev/null +++ b/libc/calls/kclocknames.S @@ -0,0 +1,47 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/fmt/magnumstrs.internal.h" +#include "libc/macros.internal.h" + + .macro .e e s + .long \e - kClockNames + .long 1f - kClockNames + .rodata.str1.1 +1: .string "\s" + .previous + .endm + + .section .rodata + .align 4 + .underrun +kClockNames: + .e CLOCK_REALTIME,"REALTIME" + .e CLOCK_MONOTONIC,"MONOTONIC" + .e CLOCK_MONOTONIC_RAW,"MONOTONIC_RAW" + .e CLOCK_REALTIME_COARSE,"REALTIME_COARSE" + .e CLOCK_MONOTONIC_COARSE,"MONOTONIC_COARSE" + .e CLOCK_PROCESS_CPUTIME_ID,"PROCESS_CPUTIME_ID" + .e CLOCK_TAI,"TAI" + .e CLOCK_PROF,"PROF" + .e CLOCK_BOOTTIME,"BOOTTIME" + .e CLOCK_REALTIME_ALARM,"REALTIME_ALARM" + .e CLOCK_BOOTTIME_ALARM,"BOOTTIME_ALARM" + .long MAGNUM_TERMINATOR + .endobj kClockNames,globl,hidden + .overrun diff --git a/libc/calls/kill-nt.c b/libc/calls/kill-nt.c index 9f5c5a759..9dc6d46a0 100644 --- a/libc/calls/kill-nt.c +++ b/libc/calls/kill-nt.c @@ -16,37 +16,74 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/getconsolectrlevent.h" +#include "libc/calls/calls.h" +#include "libc/calls/getconsolectrlevent.internal.h" #include "libc/calls/internal.h" #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/nt/console.h" #include "libc/nt/enum/ctrlevent.h" #include "libc/nt/enum/processaccess.h" +#include "libc/nt/errors.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/sysv/errfuns.h" textwindows int sys_kill_nt(int pid, int sig) { - bool ok; - int event; + bool32 ok; int64_t handle; - if (pid) { - pid = ABS(pid); - if ((event = GetConsoleCtrlEvent(sig)) != -1) { - ok = !!GenerateConsoleCtrlEvent( - event, __isfdkind(pid, kFdProcess) ? GetProcessId(g_fds.p[pid].handle) - : pid); - } else if (__isfdkind(pid, kFdProcess)) { - ok = !!TerminateProcess(g_fds.p[pid].handle, 128 + sig); - } else if ((handle = OpenProcess(kNtProcessAllAccess, false, pid))) { - ok = !!TerminateProcess(handle, 128 + sig); - CloseHandle(handle); - } else { - ok = false; - } - return ok ? 0 : __winerr(); - } else { + int event, ntpid; + + // is killing everything except init really worth supporting? + if (pid == -1) return einval(); + + // XXX: NT doesn't really have process groups. For instance the + // CreateProcess() flag for starting a process group actually + // just does an "ignore ctrl-c" internally. + pid = ABS(pid); + + // If we're targeting current process group then just call raise(). + if (!pid || pid == getpid()) { return raise(sig); } + + // GenerateConsoleCtrlEvent() will always signal groups and there's + // nothing we can do about it, unless we have a GUI GetMessage loop + // and alternatively create a centralized signal daemon like cygwin + if ((event = GetConsoleCtrlEvent(sig)) != -1) { + // we're killing with SIGINT or SIGQUIT which are the only two + // signals we can really use, since TerminateProcess() makes + // everything else effectively a SIGKILL ;_; + if (__isfdkind(pid, kFdProcess)) { + ntpid = GetProcessId(g_fds.p[pid].handle); + } else if (!__isfdopen(pid)) { + ntpid = pid; // XXX: suboptimal + } else { + return esrch(); + } + if (GenerateConsoleCtrlEvent(event, ntpid)) { + return 0; + } else { + return -1; + } + } + + // XXX: Is this a cosmo pid that was returned by fork_nt? + if (__isfdkind(pid, kFdProcess)) { + ok = TerminateProcess(g_fds.p[pid].handle, 128 + sig); + if (!ok && GetLastError() == kNtErrorAccessDenied) ok = true; + return 0; + } + + // XXX: Is this a raw new technology pid? Because that's messy. + if ((handle = OpenProcess(kNtProcessTerminate, false, pid))) { + ok = TerminateProcess(handle, 128 + sig); + if (!ok && GetLastError() == kNtErrorAccessDenied) { + ok = true; // cargo culting other codebases here + } + CloseHandle(handle); + return 0; + } else { + return -1; + } } diff --git a/libc/calls/kill.c b/libc/calls/kill.c index 26b9f0c84..a77ff7564 100644 --- a/libc/calls/kill.c +++ b/libc/calls/kill.c @@ -18,7 +18,9 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/str/str.h" /** * Sends signal to process. @@ -38,9 +40,12 @@ * @asyncsignalsafe */ int kill(int pid, int sig) { + int rc; if (!IsWindows()) { - return sys_kill(pid, sig, 1); + rc = sys_kill(pid, sig, 1); } else { - return sys_kill_nt(pid, sig); + rc = sys_kill_nt(pid, sig); } + STRACE("kill(%d, %G) → %d% m", pid, sig, rc); + return rc; } diff --git a/libc/calls/kntsystemdirectory.S b/libc/calls/kntsystemdirectory.S index 6c20bde2b..870b4faf9 100644 --- a/libc/calls/kntsystemdirectory.S +++ b/libc/calls/kntsystemdirectory.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" #include "libc/macros.internal.h" -.source __FILE__ #define BYTES 64 diff --git a/libc/calls/kntwindowsdirectory.S b/libc/calls/kntwindowsdirectory.S index 95ff82aa3..890cebfda 100644 --- a/libc/calls/kntwindowsdirectory.S +++ b/libc/calls/kntwindowsdirectory.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" #include "libc/macros.internal.h" -.source __FILE__ #define BYTES 64 diff --git a/libc/calls/kopenflags.S b/libc/calls/kopenflags.S new file mode 100644 index 000000000..a0749a5af --- /dev/null +++ b/libc/calls/kopenflags.S @@ -0,0 +1,65 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/fmt/magnumstrs.internal.h" +#include "libc/macros.internal.h" + + .macro .e e s + .long \e - kOpenFlags + .long 1f - kOpenFlags + .rodata.str1.1 +1: .string "\s" + .previous + .endm + + .section .rodata + .align 4 + .underrun +kOpenFlags: + .e O_RDWR,"RDWR" // order matters + .e O_RDONLY,"RDONLY" // + .e O_WRONLY,"WRONLY" // + .e O_ACCMODE,"ACCMODE" // mask of prev three + .e O_CREAT,"CREAT" // + .e O_EXCL,"EXCL" // + .e O_TRUNC,"TRUNC" // + .e O_CLOEXEC,"CLOEXEC" // + .e O_NONBLOCK,"NONBLOCK" // + .e O_DIRECT,"DIRECT" // no-op on xnu/openbsd + .e O_APPEND,"APPEND" // weird on nt + .e O_TMPFILE,"TMPFILE" // linux, windows + .e O_NOFOLLOW,"NOFOLLOW" // unix + .e O_SYNC,"SYNC" // unix + .e O_ASYNC,"ASYNC" // unix + .e O_NOCTTY,"NOCTTY" // unix + .e O_NOATIME,"NOATIME" // linux + .e O_EXEC,"EXEC" // free/openbsd + .e O_SEARCH,"SEARCH" // free/netbsd + .e O_DSYNC,"DSYNC" // linux/xnu/open/netbsd + .e O_RSYNC,"RSYNC" // linux/open/netbsd + .e O_PATH,"PATH" // linux + .e O_VERIFY,"VERIFY" // freebsd + .e O_SHLOCK,"SHLOCK" // bsd + .e O_EXLOCK,"EXLOCK" // bsd + .e O_RANDOM,"RANDOM" // windows + .e O_SEQUENTIAL,"SEQUENTIAL" // windows + .e O_COMPRESSED,"COMPRESSED" // windows + .e O_INDEXED,"INDEXED" // windows + .long MAGNUM_TERMINATOR + .endobj kOpenFlags,globl,hidden + .overrun diff --git a/libc/calls/ktmppath.S b/libc/calls/ktmppath.S index 7866690f5..3d1621c8f 100644 --- a/libc/calls/ktmppath.S +++ b/libc/calls/ktmppath.S @@ -43,4 +43,3 @@ kTmpPath: add $kTmpPathMax,%rdi #endif .init.end 300,_init_kTmpPath - .source __FILE__ diff --git a/libc/calls/linkat-nt.c b/libc/calls/linkat-nt.c index c1e4bfae4..072c203f6 100644 --- a/libc/calls/linkat-nt.c +++ b/libc/calls/linkat-nt.c @@ -30,7 +30,7 @@ textwindows int sys_linkat_nt(int olddirfd, const char *oldpath, int newdirfd, if (CreateHardLink(newpath16, oldpath16, NULL)) { return 0; } else { - return __winerr(); + return __fix_enotdir3(__winerr(), newpath16, oldpath16); } } else { return -1; diff --git a/libc/calls/linkat.c b/libc/calls/linkat.c index 2df6171c0..816b31a59 100644 --- a/libc/calls/linkat.c +++ b/libc/calls/linkat.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -36,18 +37,22 @@ */ int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags) { + int rc; + char buf[2][12]; if (IsAsan() && (!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) { - return efault(); - } - if (weaken(__zipos_notat) && - (weaken(__zipos_notat)(olddirfd, oldpath) == -1 || - weaken(__zipos_notat)(newdirfd, newpath) == -1)) { - return -1; /* TODO(jart): implement me */ - } - if (!IsWindows()) { - return sys_linkat(olddirfd, oldpath, newdirfd, newpath, flags); + rc = efault(); + } else if (weaken(__zipos_notat) && + ((rc = __zipos_notat(olddirfd, oldpath)) == -1 || + (rc = __zipos_notat(newdirfd, newpath)) == -1)) { + STRACE("zipos fchownat not supported yet"); + } else if (!IsWindows()) { + rc = sys_linkat(olddirfd, oldpath, newdirfd, newpath, flags); } else { - return sys_linkat_nt(olddirfd, oldpath, newdirfd, newpath); + rc = sys_linkat_nt(olddirfd, oldpath, newdirfd, newpath); } + STRACE("linkat(%s, %#s, %s, %#s, %#b) → %d% m", + __strace_dirfd(buf[0], olddirfd), oldpath, + __strace_dirfd(buf[1], newdirfd), newpath, flags, rc); + return rc; } diff --git a/libc/calls/loadavg-nt.c b/libc/calls/loadavg-nt.c new file mode 100644 index 000000000..28671071e --- /dev/null +++ b/libc/calls/loadavg-nt.c @@ -0,0 +1,97 @@ +/*-*- 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 2022 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/loadavg.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nexgen32e/nt2sysv.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/pdh.h" +#include "libc/nt/enum/securityimpersonationlevel.h" +#include "libc/nt/enum/wt.h" +#include "libc/nt/errors.h" +#include "libc/nt/events.h" +#include "libc/nt/files.h" +#include "libc/nt/pdh.h" +#include "libc/nt/privilege.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/luid.h" +#include "libc/nt/struct/pdhfmtcountervalue.h" +#include "libc/nt/struct/tokenprivileges.h" +#include "libc/nt/synchronization.h" +#include "libc/str/str.h" + +/** + * @fileoverview sysinfo() on the new technology + * @kudos Giampaolo Rodola for teaching how to do load average + */ + +#define LOAD_SAMPLING_INTERVAL 1 // in seconds + +// https://github.com/torvalds/linux/blob/345671ea0f9258f410eb057b9ced9cefbbe5dc78/include/linux/sched/loadavg.h#L20-L23 +#define LOAD1F .9200444146293232478931553241 +#define LOAD5F .9834714538216174894737477501 +#define LOAD15F .9944598480048967508795473394 + +double __ntloadavg[3]; + +static void LoadavgNtPoll(int64_t hCounter, bool32 timedOut) { + struct NtPdhFmtCountervalue c; + if (!PdhGetFormattedCounterValue(hCounter, kNtPdhFmtDouble, 0, &c)) { + __ntloadavg[0] = __ntloadavg[0] * LOAD1F + c.doubleValue * (1 - LOAD1F); + __ntloadavg[1] = __ntloadavg[1] * LOAD5F + c.doubleValue * (1 - LOAD5F); + __ntloadavg[2] = __ntloadavg[2] * LOAD15F + c.doubleValue * (1 - LOAD15F); + } else { + STRACE("PdhGetFormattedCounterValue(%ld) failed", hCounter); + } +} + +static textstartup void LoadavgNtInit(void) { + int64_t hQuery, hCounter, hEvent, hWaiter; + if (!IsWindows()) return; + STRACE("LoadavgNtInit()"); + if (PdhOpenQuery(0, 0, &hQuery)) { + STRACE("PdhOpenQuery failed"); + return; + } + if (PdhAddEnglishCounter(hQuery, u"\\System\\Processor Queue Length", 0, + &hCounter)) { + STRACE("PdhAddEnglishCounter() failed"); + return; + } + if (!(hEvent = CreateEvent(0, 0, 0, u"LoadUpdateEvent"))) { + STRACE("CreateEvent() failed"); + return; + } + if (PdhCollectQueryDataEx(hQuery, LOAD_SAMPLING_INTERVAL, hEvent)) { + STRACE("PdhCollectQueryDataEx() failed"); + return; + } + if (!RegisterWaitForSingleObject( + &hWaiter, hEvent, (void *)NT2SYSV(LoadavgNtPoll), + (void *)(intptr_t)hCounter, -1, kNtWtExecutedefault)) { + STRACE("RegisterWaitForSingleObject() failed"); + return; + } + LoadavgNtPoll(hCounter, 0); +} + +const void *const LoadavgNtCtor[] initarray = { + LoadavgNtInit, +}; diff --git a/libc/calls/loadavg.internal.h b/libc/calls/loadavg.internal.h new file mode 100644 index 000000000..dbae0f1a0 --- /dev/null +++ b/libc/calls/loadavg.internal.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_LOADAVG_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_LOADAVG_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern double __ntloadavg[3]; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_LOADAVG_INTERNAL_H_ */ diff --git a/libc/calls/lseek-nt.c b/libc/calls/lseek-nt.c index dc1954787..da27f64cf 100644 --- a/libc/calls/lseek-nt.c +++ b/libc/calls/lseek-nt.c @@ -17,15 +17,23 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/nt/enum/filetype.h" #include "libc/nt/files.h" #include "libc/sysv/errfuns.h" textwindows int64_t sys_lseek_nt(int fd, int64_t offset, int whence) { int64_t res; - if (!__isfdkind(fd, kFdFile)) return ebadf(); - if (SetFilePointerEx(g_fds.p[fd].handle, offset, &res, whence)) { - return res; + if (__isfdkind(fd, kFdFile)) { + if (GetFileType(g_fds.p[fd].handle) != kNtFileTypePipe) { + if (SetFilePointerEx(g_fds.p[fd].handle, offset, &res, whence)) { + return res; + } else { + return __winerr(); + } + } else { + return espipe(); + } } else { - return __winerr(); + return ebadf(); } } diff --git a/libc/calls/lseek.c b/libc/calls/lseek.c index e391f3bef..07961309f 100644 --- a/libc/calls/lseek.c +++ b/libc/calls/lseek.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/log/backtrace.internal.h" #include "libc/zipos/zipos.internal.h" @@ -33,14 +34,17 @@ * @asyncsignalsafe */ int64_t lseek(int fd, int64_t offset, unsigned whence) { + int64_t rc; if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return weaken(__zipos_lseek)( + rc = weaken(__zipos_lseek)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, offset, whence); } else if (!IsWindows() && !IsOpenbsd() && !IsNetbsd()) { - return sys_lseek(fd, offset, whence, 0); + rc = sys_lseek(fd, offset, whence, 0); } else if (IsOpenbsd() || IsNetbsd()) { - return sys_lseek(fd, offset, offset, whence); + rc = sys_lseek(fd, offset, offset, whence); } else { - return sys_lseek_nt(fd, offset, whence); + rc = sys_lseek_nt(fd, offset, whence); } + STRACE("lseek(%d, %'ld, %d) → %'ld% m", fd, offset, whence, rc); + return rc; } diff --git a/libc/calls/madvise-nt.c b/libc/calls/madvise-nt.c index 6592ff700..ce50c0002 100644 --- a/libc/calls/madvise-nt.c +++ b/libc/calls/madvise-nt.c @@ -50,8 +50,7 @@ forceinline typeof(OfferVirtualMemory) *GetOfferVirtualMemory(void) { textwindows int sys_madvise_nt(void *addr, size_t length, int advice) { uint32_t rangecount; struct NtMemoryRangeEntry ranges[1]; - if ((advice & (int)MADV_WILLNEED) == (int)MADV_WILLNEED || - (advice & (int)MADV_SEQUENTIAL) == (int)MADV_SEQUENTIAL) { + if (advice == MADV_WILLNEED || advice == MADV_SEQUENTIAL) { typeof(PrefetchVirtualMemory) *fn = GetPrefetchVirtualMemory(); if (fn) { ranges[0].VirtualAddress = addr; @@ -65,7 +64,7 @@ textwindows int sys_madvise_nt(void *addr, size_t length, int advice) { } else { return enosys(); } - } else if ((advice & (int)MADV_FREE) == (int)MADV_FREE) { + } else if (advice == MADV_FREE) { typeof(OfferVirtualMemory) *fn = GetOfferVirtualMemory(); if (fn) { if (fn(addr, length, kNtVmOfferPriorityNormal)) { diff --git a/libc/calls/madvise.c b/libc/calls/madvise.c index d73571ae3..d4f2c7b51 100644 --- a/libc/calls/madvise.c +++ b/libc/calls/madvise.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -31,10 +32,18 @@ * @see fadvise() */ int madvise(void *addr, size_t length, int advice) { - if (IsAsan() && !__asan_is_valid(addr, length)) return efault(); - if (!IsWindows()) { - return sys_madvise(addr, length, advice); + int rc; + if (advice != 127 /* see consts.sh */) { + if (IsAsan() && !__asan_is_valid(addr, length)) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_madvise(addr, length, advice); + } else { + rc = sys_madvise_nt(addr, length, advice); + } } else { - return sys_madvise_nt(addr, length, advice); + rc = einval(); } + STRACE("madvise(%p, %'zu, %d) → %d% m", addr, length, advice, rc); + return rc; } diff --git a/libc/calls/mkdir.c b/libc/calls/mkdir.c index cda89a91c..d41c67814 100644 --- a/libc/calls/mkdir.c +++ b/libc/calls/mkdir.c @@ -36,7 +36,7 @@ * @param path is a UTF-8 string, preferably relative w/ forward slashes * @param mode can be, for example, 0755 * @return 0 on success or -1 w/ errno - * @error EEXIST, ENOTDIR, ENAMETOOLONG, EACCES + * @error ENAMETOOLONG if >246 characters on NT * @asyncsignalsafe * @see makedirs() */ diff --git a/libc/calls/mkdirat-nt.c b/libc/calls/mkdirat-nt.c index c269daa4d..16133342a 100644 --- a/libc/calls/mkdirat-nt.c +++ b/libc/calls/mkdirat-nt.c @@ -17,33 +17,15 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" -#include "libc/errno.h" -#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/files.h" -#include "libc/nt/runtime.h" #include "libc/str/str.h" - -static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) { - char16_t *p; - uint32_t attrs; - while ((p = strrchr16(path, '\\'))) { - *p = u'\0'; - if ((attrs = GetFileAttributes(path)) != -1u) { - if (attrs & kNtFileAttributeDirectory) return false; - return true; - } - } - return false; -} +#include "libc/sysv/errfuns.h" textwindows int sys_mkdirat_nt(int dirfd, const char *path, uint32_t mode) { int e; char16_t *p, path16[PATH_MAX]; + /* if (strlen(path) > 248) return enametoolong(); */ if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; - if (CreateDirectory(path16, NULL)) return 0; - e = GetLastError(); - /* WIN32 doesn't distinguish between ENOTDIR and ENOENT */ - if (e == ENOTDIR && !SubpathExistsThatsNotDirectory(path16)) e = ENOENT; - errno = e; - return -1; + if (CreateDirectory(path16, 0)) return 0; + return __fix_enotdir(-1, path16); } diff --git a/libc/calls/mkdirat.c b/libc/calls/mkdirat.c index 29ccaedb4..bdb0b5a38 100644 --- a/libc/calls/mkdirat.c +++ b/libc/calls/mkdirat.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/consts/at.h" @@ -38,13 +39,18 @@ * @see makedirs() */ int mkdirat(int dirfd, const char *path, unsigned mode) { - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) { - return -1; /* TODO(jart): implement me */ - } - if (!IsWindows()) { - return sys_mkdirat(dirfd, path, mode); + int rc; + char buf[12]; + if (IsAsan() && !__asan_is_valid(path, 1)) { + rc = efault(); + } else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) { + STRACE("zipos mkdirat not supported yet"); + } else if (!IsWindows()) { + rc = sys_mkdirat(dirfd, path, mode); } else { - return sys_mkdirat_nt(dirfd, path, mode); + rc = sys_mkdirat_nt(dirfd, path, mode); } + STRACE("mkdirat(%s, %#s, %#o) → %d% m", __strace_dirfd(buf, dirfd), path, + mode, rc); + return rc; } diff --git a/libc/calls/mkfifo.c b/libc/calls/mkfifo.c index 82bc49cc7..2f85e7251 100644 --- a/libc/calls/mkfifo.c +++ b/libc/calls/mkfifo.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/nt/ipc.h" @@ -33,11 +34,15 @@ * @asyncsignalsafe */ int mkfifo(const char *pathname, unsigned mode) { - /* TODO(jart): Windows? */ - if (IsAsan() && !__asan_is_valid(pathname, 1)) return efault(); - if (IsLinux()) { - return sys_mknod(pathname, mode | S_IFIFO, 0); + // TODO(jart): Windows? + int rc; + if (IsAsan() && !__asan_is_valid(pathname, 1)) { + rc = efault(); + } else if (IsLinux()) { + rc = sys_mknod(pathname, mode | S_IFIFO, 0); } else { - return sys_mkfifo(pathname, mode); + rc = sys_mkfifo(pathname, mode); } + STRACE("mkfifo(%#s, %#o) → %d% m", pathname, mode, rc); + return rc; } diff --git a/libc/calls/mknod.c b/libc/calls/mknod.c index 33b13d598..63d2b9715 100644 --- a/libc/calls/mknod.c +++ b/libc/calls/mknod.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/consts/s.h" @@ -38,14 +39,17 @@ * @asyncsignalsafe */ int mknod(const char *path, uint32_t mode, uint64_t dev) { + int rc; if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); if (mode & S_IFREG) return creat(path, mode & ~S_IFREG); if (mode & S_IFDIR) return mkdir(path, mode & ~S_IFDIR); if (mode & S_IFIFO) return mkfifo(path, mode & ~S_IFIFO); if (!IsWindows()) { /* TODO(jart): Whys there code out there w/ S_xxx passed via dev? */ - return sys_mknod(path, mode, dev); + rc = sys_mknod(path, mode, dev); } else { - return enosys(); + rc = enosys(); } + STRACE("mknod(%#s, %#o, %#lx) → %d% m", path, mode, dev, rc); + return rc; } diff --git a/libc/calls/mkntcmdline.c b/libc/calls/mkntcmdline.c index e43573db8..29eacc9b1 100644 --- a/libc/calls/mkntcmdline.c +++ b/libc/calls/mkntcmdline.c @@ -23,10 +23,12 @@ #include "libc/str/utf16.h" #include "libc/sysv/errfuns.h" -#define APPEND(c) \ - do { \ - cmdline[k++] = c; \ - if (k == ARG_MAX) return e2big(); \ +#define APPEND(c) \ + do { \ + cmdline[k++] = c; \ + if (k == ARG_MAX / 2) { \ + return e2big(); \ + } \ } while (0) static noasan bool NeedsQuotes(const char *s) { @@ -52,15 +54,20 @@ static noasan bool NeedsQuotes(const char *s) { * @return freshly allocated lpCommandLine or NULL w/ errno * @see libc/runtime/dosargv.c */ -textwindows noasan int mkntcmdline(char16_t cmdline[ARG_MAX], const char *prog, - char *const argv[]) { +textwindows noasan int mkntcmdline(char16_t cmdline[ARG_MAX / 2], + const char *prog, char *const argv[]) { char *arg; uint64_t w; wint_t x, y; int slashes, n; bool needsquote; char16_t cbuf[2]; + char *ansiargv[2]; size_t i, j, k, s; + if (!argv[0]) { + bzero(ansiargv, sizeof(ansiargv)); + argv = ansiargv; + } for (arg = prog, k = i = 0; arg; arg = argv[++i]) { if (i) APPEND(u' '); if ((needsquote = NeedsQuotes(arg))) APPEND(u'"'); diff --git a/libc/calls/mkntenvblock.c b/libc/calls/mkntenvblock.c index 5c94eb3d0..95287bb6d 100644 --- a/libc/calls/mkntenvblock.c +++ b/libc/calls/mkntenvblock.c @@ -55,9 +55,9 @@ static noasan void InsertString(char **a, size_t i, char *s) { * @param envp is an a NULL-terminated array of UTF-8 strings * @param extravar is a VAR=val string we consider part of envp or NULL * @return 0 on success, or -1 w/ errno - * @error E2BIG if total number of shorts exceeded ARG_MAX (0x8000) + * @error E2BIG if total number of shorts exceeded ARG_MAX/2 (32767) */ -textwindows noasan int mkntenvblock(char16_t envvars[ARG_MAX], +textwindows noasan int mkntenvblock(char16_t envvars[ARG_MAX / 2], char *const envp[], const char *extravar) { bool v; char *t; @@ -98,7 +98,9 @@ textwindows noasan int mkntenvblock(char16_t envvars[ARG_MAX], w = EncodeUtf16(x); do { envvars[k++] = w & 0xffff; - if (k == ARG_MAX) return e2big(); + if (k == ARG_MAX / 2) { + return e2big(); + } } while ((w >>= 16)); } while (x); } diff --git a/libc/calls/mkntpath.c b/libc/calls/mkntpath.c index 0f60e65ff..a2a36a28a 100644 --- a/libc/calls/mkntpath.c +++ b/libc/calls/mkntpath.c @@ -18,7 +18,8 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/calls/ntmagicpaths.internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/macros.internal.h" #include "libc/nt/systeminfo.h" #include "libc/str/oldutf16.internal.h" #include "libc/str/str.h" @@ -49,7 +50,7 @@ textwindows static const char *FixNtMagicPath(const char *path, } textwindows int __mkntpath(const char *path, - char16_t path16[hasatleast PATH_MAX - 16]) { + char16_t path16[hasatleast PATH_MAX]) { return __mkntpath2(path, path16, -1); } @@ -67,23 +68,27 @@ textwindows int __mkntpath(const char *path, * @error ENAMETOOLONG */ textwindows int __mkntpath2(const char *path, - char16_t path16[hasatleast PATH_MAX - 16], - int flags) { + char16_t path16[hasatleast PATH_MAX], int flags) { /* - * 1. Reserve +1 for NUL-terminator - * 2. Reserve +1 for UTF-16 overflow - * 3. Reserve ≥2 for SetCurrentDirectory trailing slash requirement - * 4. Reserve ≥10 for CreateNamedPipe "\\.\pipe\" prefix requirement - * 5. Reserve ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0" + * 1. Need +1 for NUL-terminator + * 2. Need +1 for UTF-16 overflow + * 3. Need ≥2 for SetCurrentDirectory trailing slash requirement + * 5. Need ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0" + * which is an "8.3 filename" from the DOS days */ - char *q; char16_t *p; + const char *q; size_t i, n, m, z; if (!path) return efault(); path = FixNtMagicPath(path, flags); p = path16; q = path; - z = PATH_MAX - 16; + if (IsSlash(path[0]) && IsSlash(path[1]) && path[2] == '?' && + IsSlash(path[3])) { + z = MIN(32767, PATH_MAX); + } else { + z = MIN(260, PATH_MAX); + } if (IsSlash(q[0]) && q[1] == 't' && q[2] == 'm' && q[3] == 'p' && (IsSlash(q[4]) || !q[4])) { m = GetTempPath(z, p); @@ -95,8 +100,8 @@ textwindows int __mkntpath2(const char *path, m = 0; } n = tprecode8to16(p, z, q).ax; - if (n == z - 1) { - SYSDEBUG("path too long for windows: %s", path); + if (n >= z - 1) { + STRACE("path too long for windows: %#s", path); return enametoolong(); } for (i = 0; i < n; ++i) { diff --git a/libc/calls/mkntpathat.c b/libc/calls/mkntpathat.c index a2f4e2cef..f2258721b 100644 --- a/libc/calls/mkntpathat.c +++ b/libc/calls/mkntpathat.c @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/macros.internal.h" #include "libc/nt/files.h" #include "libc/str/str.h" @@ -25,17 +25,18 @@ #include "libc/sysv/errfuns.h" int __mkntpathat(int dirfd, const char *path, int flags, - char16_t file[PATH_MAX]) { + char16_t file[hasatleast PATH_MAX]) { char16_t dir[PATH_MAX]; uint32_t dirlen, filelen; if ((filelen = __mkntpath2(path, file, flags)) == -1) return -1; + if (!filelen) return enoent(); if (file[0] != u'\\' && dirfd != AT_FDCWD) { /* ProTip: \\?\C:\foo */ if (!__isfdkind(dirfd, kFdFile)) return ebadf(); dirlen = GetFinalPathNameByHandle(g_fds.p[dirfd].handle, dir, ARRAYLEN(dir), kNtFileNameNormalized | kNtVolumeNameDos); if (!dirlen) return __winerr(); if (dirlen + 1 + filelen + 1 > ARRAYLEN(dir)) { - SYSDEBUG("path too long: %.*hs\\%.*hs", dirlen, dir, filelen, file); + STRACE("path too long: %#.*hs\\%#.*hs", dirlen, dir, filelen, file); return enametoolong(); } dir[dirlen] = u'\\'; diff --git a/libc/runtime/mman.greg.c b/libc/calls/mman.greg.c similarity index 100% rename from libc/runtime/mman.greg.c rename to libc/calls/mman.greg.c diff --git a/libc/calls/mprotect.greg.c b/libc/calls/mprotect.greg.c deleted file mode 100644 index 00d7dfaa9..000000000 --- a/libc/calls/mprotect.greg.c +++ /dev/null @@ -1,61 +0,0 @@ -/*-*- 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. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#define ShouldUseMsabiAttribute() 1 -#include "libc/bits/bits.h" -#include "libc/calls/internal.h" -#include "libc/dce.h" -#include "libc/errno.h" -#include "libc/nt/memory.h" -#include "libc/nt/thunk/msabi.h" -#include "libc/sysv/consts/nr.h" - -extern __msabi typeof(VirtualProtect) *const __imp_VirtualProtect; - -/** - * Modifies restrictions on virtual memory address range. - * - * @param prot can have PROT_{NONE,READ,WRITE,EXEC,GROWSDOWN} - * @return 0 on success, or -1 w/ errno - * @see mmap() - */ -noasan noubsan privileged int mprotect(void *addr, uint64_t len, int prot) { - bool cf; - int64_t rc; - uint32_t oldprot; - if (!IsWindows()) { - asm volatile(CFLAG_ASM("clc\n\tsyscall") - : CFLAG_CONSTRAINT(cf), "=a"(rc) - : "1"(__NR_mprotect), "D"(addr), "S"(len), "d"(prot) - : "rcx", "r11", "memory", "cc"); - if (cf) { - errno = rc; - rc = -1; - } else if (rc > -4096ul) { - errno = -rc; - rc = -1; - } - return rc; - } else { - if (__imp_VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) { - return 0; - } else { - return __winerr(); - } - } -} diff --git a/libc/calls/mremap-sysv.greg.c b/libc/calls/mremap-sysv.greg.c new file mode 100644 index 000000000..c44cff2d1 --- /dev/null +++ b/libc/calls/mremap-sysv.greg.c @@ -0,0 +1,65 @@ +/*-*- 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/bits/asmflag.h" +#include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/mremap.h" +#include "libc/sysv/errfuns.h" + +/** + * Relocates memory. + * + * This function lets you move to to different addresses witohut copying + * it. This system call is currently supported on Linux and NetBSD. Your + * C library runtime won't have any awareness of this memory, so certain + * features like ASAN memory safety and kprintf() won't work as well. + */ +privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) { + bool cf; + uintptr_t rax, rdi, rsi, rdx; + register uintptr_t r8 asm("r8"); + register uintptr_t r10 asm("r10"); + if (IsLinux()) { + r10 = f; + r8 = (uintptr_t)q; + asm("syscall" + : "=a"(rax) + : "0"(0x019), "D"(p), "S"(n), "d"(m), "r"(r10), "r"(r8) + : "rcx", "r11", "memory", "cc"); + if (rax > -4096ul) errno = -rax, rax = -1; + } else if (IsNetbsd()) { + if (f & MREMAP_MAYMOVE) { + rax = 0x19B; + r10 = m; + r8 = (f & MREMAP_FIXED) ? MAP_FIXED : 0; + asm(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(cf), "+a"(rax) + : "D"(p), "S"(n), "d"(q), "r"(r10), "r"(r8) + : "rcx", "r9", "r11", "memory", "cc"); + if (cf) errno = rax, rax = -1; + } else { + rax = einval(); + } + } else { + rax = enosys(); + } + KERNTRACE("sys_mremap(%p, %'zu, %'zu, %#b, %p) → %p% m", p, n, m, f, q, rax); + return (void *)rax; +} diff --git a/libc/runtime/munmap-metal.c b/libc/calls/munmap-metal.c similarity index 100% rename from libc/runtime/munmap-metal.c rename to libc/calls/munmap-metal.c diff --git a/libc/runtime/munmap-sysv.c b/libc/calls/munmap-sysv.c similarity index 85% rename from libc/runtime/munmap-sysv.c rename to libc/calls/munmap-sysv.c index c4db57ac6..d2ea45e00 100644 --- a/libc/runtime/munmap-sysv.c +++ b/libc/calls/munmap-sysv.c @@ -17,10 +17,19 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/runtime/directmap.internal.h" #include "libc/runtime/memtrack.internal.h" +/** + * Unmaps memory directly with system. + * + * This function bypasses memtrack. Therefore it won't work on Windows, + * but it works on everything else including bare metal. + * + * @asyncsignalsafe + * @threadsafe + */ int sys_munmap(void *p, size_t n) { int rc; if (!IsMetal()) { @@ -28,7 +37,7 @@ int sys_munmap(void *p, size_t n) { } else { rc = sys_munmap_metal(p, n); } - SYSDEBUG("sys_munmap(0x%p%s, 0x%x) -> %d", p, - DescribeFrame((intptr_t)p >> 16), n, (long)rc); + KERNTRACE("sys_munmap(%p%s, %'zu) → %d", p, DescribeFrame((intptr_t)p >> 16), + n, rc); return rc; } diff --git a/libc/calls/nanosleep-nt.c b/libc/calls/nanosleep-nt.c index 9c8a6438a..275bf3086 100644 --- a/libc/calls/nanosleep-nt.c +++ b/libc/calls/nanosleep-nt.c @@ -1,7 +1,7 @@ /*-*- 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 │ @@ -17,28 +17,62 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" -#include "libc/nexgen32e/nexgen32e.h" -#include "libc/nt/enum/status.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/errno.h" +#include "libc/limits.h" +#include "libc/macros.internal.h" #include "libc/nt/errors.h" #include "libc/nt/nt/time.h" #include "libc/nt/synchronization.h" -#include "libc/str/str.h" #include "libc/sysv/errfuns.h" -textwindows int sys_nanosleep_nt(const struct timespec *req, - struct timespec *rem) { - int64_t millis, hectonanos, relasleep; - if (rem) memcpy(rem, req, sizeof(*rem)); - hectonanos = req->tv_sec * 10000000ull + div100int64(req->tv_nsec); - hectonanos = MAX(1, hectonanos); - relasleep = -hectonanos; - if (NtError(NtDelayExecution(true, &relasleep))) { - millis = div10000int64(hectonanos); - millis = MAX(1, millis); - if (SleepEx(millis, true) == kNtWaitIoCompletion) { - return eintr(); +textwindows noinstrument int sys_nanosleep_nt(const struct timespec *req, + struct timespec *rem) { + int rc; + bool alertable; + uint32_t slice; + int64_t ms, sec, nsec; + if (__builtin_mul_overflow(req->tv_sec, 1000, &ms) || + __builtin_add_overflow(ms, req->tv_nsec / 1000000, &ms)) { + ms = INT64_MAX; + } + if (!ms && (req->tv_sec || req->tv_nsec)) { + ms = 1; + } + rc = 0; + do { + if (!__time_critical && _check_interrupts(false, g_fds.p)) { + rc = eintr(); + break; + } + slice = MIN(__SIG_POLLING_INTERVAL_MS, ms); + if (__time_critical) { + alertable = false; + } else { + alertable = true; + POLLTRACE("sys_nanosleep_nt polling for %'ldms of %'ld"); + } + if (SleepEx(slice, alertable) == kNtWaitIoCompletion) { + POLLTRACE("IOCP EINTR"); + continue; + } + ms -= slice; + } while (ms > 0); + ms = MAX(ms, 0); + if (rem) { + sec = ms / 1000; + nsec = ms % 1000 * 1000000000; + rem->tv_nsec -= nsec; + if (rem->tv_nsec < 0) { + --rem->tv_sec; + rem->tv_nsec = 1000000000 - rem->tv_nsec; + } + rem->tv_sec -= sec; + if (rem->tv_sec < 0) { + rem->tv_sec = 0; + rem->tv_nsec = 0; } } - if (rem) bzero(rem, sizeof(*rem)); - return 0; + return rc; } diff --git a/libc/calls/nanosleep.c b/libc/calls/nanosleep.c index fda4656f2..3cde3bf05 100644 --- a/libc/calls/nanosleep.c +++ b/libc/calls/nanosleep.c @@ -18,24 +18,35 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/sysv/errfuns.h" /** * Sleeps for a particular amount of time. + * @norestart */ -int nanosleep(const struct timespec *req, struct timespec *rem) { - if (!req) return efault(); - if (req->tv_sec < 0 || !(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) { - return einval(); - } - if (!IsWindows() && !IsMetal() && !IsXnu()) { - return sys_nanosleep(req, rem); +noinstrument int nanosleep(const struct timespec *req, struct timespec *rem) { + int rc; + char buf[2][45]; + if (!req) { + rc = efault(); + } else if (req->tv_sec < 0 || + !(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) { + rc = einval(); + } else if (!IsWindows() && !IsMetal() && !IsXnu()) { + rc = sys_nanosleep(req, rem); } else if (IsXnu()) { - return sys_nanosleep_xnu(req, rem); + rc = sys_nanosleep_xnu(req, rem); } else if (IsMetal()) { - return enosys(); /* TODO: Sleep on Metal */ + rc = enosys(); /* TODO: Sleep on Metal */ } else { - return sys_nanosleep_nt(req, rem); + rc = sys_nanosleep_nt(req, rem); } + if (!__time_critical) { + STRACE("nanosleep(%s, [%s]) → %d% m", + __strace_timespec(buf[0], sizeof(buf[0]), rc, req), + __strace_timespec(buf[1], sizeof(buf[1]), rc, rem), rc); + } + return rc; } diff --git a/libc/calls/now.c b/libc/calls/now.c index c5458b7dd..a7ec88b88 100644 --- a/libc/calls/now.c +++ b/libc/calls/now.c @@ -20,6 +20,8 @@ #include "libc/bits/initializer.internal.h" #include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/rdtsc.h" @@ -29,9 +31,9 @@ #include "libc/time/time.h" static struct Now { - bool once; uint64_t k0; long double r0, cpn; + typeof(sys_clock_gettime) *clock_gettime; } g_now; static long double GetTimeSample(void) { @@ -40,17 +42,20 @@ static long double GetTimeSample(void) { sched_yield(); time1 = dtime(CLOCK_REALTIME); tick1 = rdtsc(); - nanosleep(&(struct timespec){0, 100000}, NULL); + nanosleep(&(struct timespec){0, 1000000}, NULL); time2 = dtime(CLOCK_REALTIME); tick2 = rdtsc(); return (time2 - time1) * 1e9 / MAX(1, tick2 - tick1); } static long double MeasureNanosPerCycle(void) { + bool tc; int i, n; long double avg, samp; + tc = __time_critical; + __time_critical = true; if (IsWindows()) { - n = 20; + n = 10; } else { n = 5; } @@ -58,6 +63,8 @@ static long double MeasureNanosPerCycle(void) { samp = GetTimeSample(); avg += (samp - avg) / i; } + __time_critical = tc; + STRACE("MeasureNanosPerCycle cpn*1000=%d", (long)(avg * 1000)); return avg; } @@ -66,22 +73,39 @@ void RefreshTime(void) { now.cpn = MeasureNanosPerCycle(); now.r0 = dtime(CLOCK_REALTIME); now.k0 = rdtsc(); - now.once = true; memcpy(&g_now, &now, sizeof(now)); } -long double ConvertTicksToNanos(uint64_t ticks) { - if (!g_now.once) RefreshTime(); - return ticks * g_now.cpn; /* pico scale */ -} - -long double nowl_sys(void) { +static long double nowl_sys(void) { return dtime(CLOCK_REALTIME); } -long double nowl_art(void) { - uint64_t ticks; - if (!g_now.once) RefreshTime(); - ticks = unsignedsubtract(rdtsc(), g_now.k0); +static long double nowl_art(void) { + uint64_t ticks = rdtsc() - g_now.k0; return g_now.r0 + (1 / 1e9L * (ticks * g_now.cpn)); } + +static long double nowl_vdso(void) { + long double secs; + struct timespec tv; + g_now.clock_gettime(CLOCK_REALTIME, &tv); + secs = tv.tv_nsec; + secs *= 1 / 1e9L; + secs += tv.tv_sec; + return secs; +} + +long double nowl_setup(void) { + uint64_t ticks; + if ((g_now.clock_gettime = __get_clock_gettime())) { + nowl = nowl_vdso; + } else if (X86_HAVE(INVTSC)) { + RefreshTime(); + nowl = nowl_art; + } else { + nowl = nowl_sys; + } + return nowl(); +} + +long double (*nowl)(void) = nowl_setup; diff --git a/libc/calls/nowl.S b/libc/calls/nowl.S deleted file mode 100644 index 09be0ff64..000000000 --- a/libc/calls/nowl.S +++ /dev/null @@ -1,38 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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 "libc/nexgen32e/x86feature.h" -#include "libc/macros.internal.h" - -// Returns timestamp without needing system calls. -// -// @return seconds since unix epoch in %st0 -// @note uses microsecond scale fallback on k8 or vm - .initbss 202,_init_nowl -nowl: .quad 0 - .endobj nowl,globl - .previous - - .init.start 202,_init_nowl - ezlea nowl_sys,ax - ezlea nowl_art,cx - testb X86_HAVE(INVTSC)+kCpuids(%rip) - cmovnz %rcx,%rax - stosq - .init.end 202,_init_nowl - .source __FILE__ diff --git a/libc/calls/ntaccesscheck.c b/libc/calls/ntaccesscheck.c index 79104c1c3..a06f7188b 100644 --- a/libc/calls/ntaccesscheck.c +++ b/libc/calls/ntaccesscheck.c @@ -19,7 +19,8 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/fmt/fmt.h" #include "libc/mem/mem.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/securityimpersonationlevel.h" @@ -31,6 +32,7 @@ #include "libc/nt/struct/privilegeset.h" #include "libc/nt/struct/securitydescriptor.h" #include "libc/runtime/runtime.h" +#include "libc/sock/internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/ok.h" #include "libc/sysv/errfuns.h" @@ -87,24 +89,23 @@ TryAgain: if (result || flags == F_OK) { rc = 0; } else { - SYSDEBUG("ntaccesscheck finale failed %d %d", result, flags); + STRACE("ntaccesscheck finale failed %d %d", result, flags); rc = eacces(); } } else { rc = __winerr(); - SYSDEBUG("AccessCheck failed: %m"); + STRACE("%s failed: %m", "AccessCheck"); } } else { rc = __winerr(); - SYSDEBUG("DuplicateToken failed: %m"); + STRACE("%s failed: %m", "DuplicateToken"); } } else { rc = __winerr(); - SYSDEBUG("OpenProcessToken failed: %m"); + STRACE("%s failed: %m", "OpenProcessToken"); } } else { e = GetLastError(); - SYSDEBUG("GetFileSecurity failed: %d %d", e, secsize); if (!IsTiny() && e == kNtErrorInsufficientBuffer) { if (!freeme && weaken(malloc) && (freeme = weaken(malloc)(secsize))) { s = freeme; diff --git a/libc/calls/ntcontext2linux.c b/libc/calls/ntcontext2linux.c index d9bdc1b12..c1a509b1e 100644 --- a/libc/calls/ntcontext2linux.c +++ b/libc/calls/ntcontext2linux.c @@ -21,9 +21,10 @@ #include "libc/nt/struct/context.h" #include "libc/str/str.h" -textwindows void ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) { +textwindows void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) { if (!cr) return; ctx->uc_flags = cr->EFlags; + ctx->uc_mcontext.eflags = cr->EFlags; ctx->uc_mcontext.rax = cr->Rax; ctx->uc_mcontext.rbx = cr->Rbx; ctx->uc_mcontext.rcx = cr->Rcx; @@ -47,3 +48,30 @@ textwindows void ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) { ctx->uc_mcontext.fpregs = &ctx->__fpustate; memcpy(&ctx->__fpustate, &cr->FltSave, sizeof(ctx->__fpustate)); } + +textwindows void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) { + if (!cr) return; + cr->EFlags = ctx->uc_flags; + cr->EFlags = ctx->uc_mcontext.eflags; + cr->Rax = ctx->uc_mcontext.rax; + cr->Rbx = ctx->uc_mcontext.rbx; + cr->Rcx = ctx->uc_mcontext.rcx; + cr->Rdx = ctx->uc_mcontext.rdx; + cr->Rdi = ctx->uc_mcontext.rdi; + cr->Rsi = ctx->uc_mcontext.rsi; + cr->Rbp = ctx->uc_mcontext.rbp; + cr->Rsp = ctx->uc_mcontext.rsp; + cr->Rip = ctx->uc_mcontext.rip; + cr->R8 = ctx->uc_mcontext.r8; + cr->R9 = ctx->uc_mcontext.r9; + cr->R10 = ctx->uc_mcontext.r10; + cr->R11 = ctx->uc_mcontext.r11; + cr->R12 = ctx->uc_mcontext.r12; + cr->R13 = ctx->uc_mcontext.r13; + cr->R14 = ctx->uc_mcontext.r14; + cr->R15 = ctx->uc_mcontext.r15; + cr->SegCs = ctx->uc_mcontext.cs; + cr->SegGs = ctx->uc_mcontext.gs; + cr->SegFs = ctx->uc_mcontext.fs; + memcpy(&cr->FltSave, &ctx->__fpustate, sizeof(ctx->__fpustate)); +} diff --git a/libc/calls/ntspawn.c b/libc/calls/ntspawn.c index b42505089..fe63fa82a 100644 --- a/libc/calls/ntspawn.c +++ b/libc/calls/ntspawn.c @@ -19,7 +19,7 @@ #include "libc/bits/pushpop.h" #include "libc/calls/internal.h" #include "libc/calls/ntspawn.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/macros.internal.h" #include "libc/nt/enum/filemapflags.h" #include "libc/nt/enum/pageflags.h" @@ -32,8 +32,13 @@ #include "libc/nt/struct/startupinfo.h" struct SpawnBlock { - char16_t cmdline[ARG_MAX]; - char16_t envvars[ARG_MAX]; + union { + struct { + char16_t cmdline[ARG_MAX / 2]; + char16_t envvars[ARG_MAX / 2]; + }; + char __pad[ROUNDUP(ARG_MAX / 2 * 2 * sizeof(char16_t), FRAMESIZE)]; + }; }; /** @@ -68,39 +73,25 @@ textwindows int ntspawn( struct NtProcessInformation *opt_out_lpProcessInformation) { int rc; int64_t handle; - size_t blocksize; struct SpawnBlock *block; char16_t prog16[PATH_MAX]; rc = -1; block = NULL; if (__mkntpath(prog, prog16) == -1) return -1; - blocksize = ROUNDUP(sizeof(*block), FRAMESIZE); - if ((handle = CreateFileMappingNuma( - -1, - &(struct NtSecurityAttributes){sizeof(struct NtSecurityAttributes), - NULL, false}, - pushpop(kNtPageReadwrite), 0, blocksize, NULL, - kNtNumaNoPreferredNode)) && - (block = - MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0, - blocksize, NULL, kNtNumaNoPreferredNode))) { - if (mkntcmdline(block->cmdline, prog, argv) != -1 && - mkntenvblock(block->envvars, envp, extravar) != -1) { - if (CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes, - opt_lpThreadAttributes, bInheritHandles, - dwCreationFlags | kNtCreateUnicodeEnvironment, - block->envvars, opt_lpCurrentDirectory, lpStartupInfo, - opt_out_lpProcessInformation)) { - rc = 0; - } else { - __winerr(); - } - SYSDEBUG("CreateProcess(`%hs`, `%hs`) -> %d", prog16, block->cmdline, rc); - } - } else { - __winerr(); + if ((handle = CreateFileMapping(-1, 0, pushpop(kNtPageReadwrite), 0, + sizeof(*block), 0)) && + (block = MapViewOfFileEx(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0, + sizeof(*block), 0)) && + mkntcmdline(block->cmdline, prog, argv) != -1 && + mkntenvblock(block->envvars, envp, extravar) != -1 && + CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes, + opt_lpThreadAttributes, bInheritHandles, + dwCreationFlags | kNtCreateUnicodeEnvironment, + block->envvars, opt_lpCurrentDirectory, lpStartupInfo, + opt_out_lpProcessInformation)) { + rc = 0; } if (block) UnmapViewOfFile(block); if (handle) CloseHandle(handle); - return rc; + return __fix_enotdir(rc, prog16); } diff --git a/libc/calls/ntspawn.h b/libc/calls/ntspawn.h index b794d5cce..df1955b43 100644 --- a/libc/calls/ntspawn.h +++ b/libc/calls/ntspawn.h @@ -6,8 +6,8 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -int mkntcmdline(char16_t[ARG_MAX], const char *, char *const[]) hidden; -int mkntenvblock(char16_t[ARG_MAX], char *const[], const char *) hidden; +int mkntcmdline(char16_t[ARG_MAX / 2], const char *, char *const[]) hidden; +int mkntenvblock(char16_t[ARG_MAX / 2], char *const[], const char *) hidden; int ntspawn(const char *, char *const[], char *const[], const char *, struct NtSecurityAttributes *, struct NtSecurityAttributes *, bool32, uint32_t, const char16_t *, const struct NtStartupInfo *, diff --git a/libc/calls/offset2overlap.c b/libc/calls/offset2overlap.c index 84d356868..e50d99811 100644 --- a/libc/calls/offset2overlap.c +++ b/libc/calls/offset2overlap.c @@ -18,10 +18,10 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/nt/struct/overlapped.h" -#include "libc/str/str.h" -textwindows struct NtOverlapped *offset2overlap(int64_t opt_offset, - struct NtOverlapped *mem) { +textwindows struct NtOverlapped *_offset2overlap(int64_t handle, + int64_t opt_offset, + struct NtOverlapped *mem) { if (opt_offset == -1) return NULL; bzero(mem, sizeof(struct NtOverlapped)); mem->Pointer = (void *)(uintptr_t)opt_offset; diff --git a/libc/calls/oldbench.c b/libc/calls/oldbench.c new file mode 100644 index 000000000..ee1ab4c41 --- /dev/null +++ b/libc/calls/oldbench.c @@ -0,0 +1,83 @@ +/*-*- 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 "libc/bits/bits.h" +#include "libc/bits/initializer.internal.h" +#include "libc/bits/safemacros.internal.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/macros.internal.h" +#include "libc/nexgen32e/rdtsc.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/clock.h" +#include "libc/time/time.h" + +static struct Now { + bool once; + uint64_t k0; + long double r0, cpn; +} g_now; + +static long double GetTimeSample(void) { + uint64_t tick1, tick2; + long double time1, time2; + sched_yield(); + time1 = dtime(CLOCK_REALTIME); + tick1 = rdtsc(); + nanosleep(&(struct timespec){0, 1000000}, NULL); + time2 = dtime(CLOCK_REALTIME); + tick2 = rdtsc(); + return (time2 - time1) * 1e9 / MAX(1, tick2 - tick1); +} + +static long double MeasureNanosPerCycle(void) { + bool tc; + int i, n; + long double avg, samp; + tc = __time_critical; + __time_critical = true; + if (IsWindows()) { + n = 30; + } else { + n = 20; + } + for (avg = 1.0L, i = 1; i < n; ++i) { + samp = GetTimeSample(); + avg += (samp - avg) / i; + } + __time_critical = tc; + STRACE("MeasureNanosPerCycle cpn*1000=%d", (long)(avg * 1000)); + return avg; +} + +static void Refresh(void) { + struct Now now; + now.cpn = MeasureNanosPerCycle(); + now.r0 = dtime(CLOCK_REALTIME); + now.k0 = rdtsc(); + now.once = true; + memcpy(&g_now, &now, sizeof(now)); +} + +long double ConvertTicksToNanos(uint64_t ticks) { + if (!g_now.once) Refresh(); + return ticks * g_now.cpn; /* pico scale */ +} diff --git a/libc/calls/onntconsoleevent.c b/libc/calls/onntconsoleevent.c index 7626b632d..bca10ac4a 100644 --- a/libc/calls/onntconsoleevent.c +++ b/libc/calls/onntconsoleevent.c @@ -16,46 +16,28 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/pushpop.h" -#include "libc/calls/internal.h" -#include "libc/calls/struct/siginfo.h" -#include "libc/calls/typedef/sigaction_f.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nexgen32e/nt2sysv.h" #include "libc/nt/enum/ctrlevent.h" -#include "libc/nt/runtime.h" -#include "libc/str/str.h" +#include "libc/sysv/consts/sicode.h" #include "libc/sysv/consts/sig.h" -textwindows bool32 __onntconsoleevent(uint32_t CtrlType) { - int sig; - unsigned rva; - siginfo_t info; - switch (CtrlType) { +textwindows bool32 __onntconsoleevent(uint32_t dwCtrlType) { + STRACE("__onntconsoleevent(%u)", dwCtrlType); + switch (dwCtrlType) { case kNtCtrlCEvent: - sig = pushpop(SIGINT); - break; + __sig_add(SIGINT, SI_KERNEL); + return true; case kNtCtrlBreakEvent: - sig = pushpop(SIGQUIT); - break; + __sig_add(SIGQUIT, SI_KERNEL); + return true; case kNtCtrlCloseEvent: - sig = pushpop(SIGHUP); - break; - case kNtCtrlLogoffEvent: // only received by services so hack hack hack - case kNtCtrlShutdownEvent: // only received by services so hack hack hack - sig = pushpop(SIGALRM); - break; + case kNtCtrlLogoffEvent: // only received by services + case kNtCtrlShutdownEvent: // only received by services + __sig_add(SIGHUP, SI_KERNEL); + return true; default: return false; } - switch ((rva = __sighandrvas[sig])) { - case (uintptr_t)SIG_DFL: - ExitProcess(128 + sig); - case (uintptr_t)SIG_IGN: - return true; - default: - bzero(&info, sizeof(info)); - info.si_signo = sig; - ((sigaction_f)(_base + rva))(sig, &info, NULL); - __interrupted = true; - return true; - } } diff --git a/libc/calls/onntconsoleevent_init.S b/libc/calls/onntconsoleevent_init.S index 754fac4b2..2e8862be9 100644 --- a/libc/calls/onntconsoleevent_init.S +++ b/libc/calls/onntconsoleevent_init.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .text.windows -.source __FILE__ __onntconsoleevent_nt: ezlea __onntconsoleevent,ax diff --git a/libc/calls/onwincrash.S b/libc/calls/onwincrash.S index ce4bfc96b..ad35d439c 100644 --- a/libc/calls/onwincrash.S +++ b/libc/calls/onwincrash.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .text.windows -.source __FILE__ __wincrash_nt: ezlea __wincrash,ax diff --git a/libc/calls/open-nt.c b/libc/calls/open-nt.c index 819256869..1955a5d18 100644 --- a/libc/calls/open-nt.c +++ b/libc/calls/open-nt.c @@ -19,6 +19,7 @@ #include "libc/assert.h" #include "libc/calls/internal.h" #include "libc/calls/ntmagicpaths.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" @@ -37,40 +38,13 @@ static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path, uint32_t flags, int32_t mode) { - uint32_t br; - int64_t handle; char16_t path16[PATH_MAX]; + uint32_t perm, share, disp, attr; if (__mkntpathat(dirfd, path, flags, path16) == -1) return -1; - if ((handle = CreateFile( - path16, flags & 0xf000000f, /* see consts.sh */ - (flags & O_EXCL) - ? kNtFileShareExclusive - : kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, - &kNtIsInheritable, - (flags & O_CREAT) && (flags & O_EXCL) ? kNtCreateNew - : (flags & O_CREAT) && (flags & O_TRUNC) ? kNtCreateAlways - : (flags & O_CREAT) ? kNtOpenAlways - : (flags & O_TRUNC) ? kNtTruncateExisting - : kNtOpenExisting, - /* TODO(jart): Should we just always set overlapped? */ - (/* note: content indexer demolishes unix-ey i/o performance */ - kNtFileAttributeNotContentIndexed | kNtFileAttributeNormal | - (((flags & ((kNtFileFlagWriteThrough | kNtFileFlagOverlapped | - kNtFileFlagNoBuffering | kNtFileFlagRandomAccess) >> - 8)) - << 8) | - (flags & (kNtFileFlagSequentialScan | kNtFileFlagDeleteOnClose | - kNtFileFlagBackupSemantics | kNtFileFlagPosixSemantics | - kNtFileAttributeTemporary)))), - 0)) != -1) { - return handle; - } else if (GetLastError() == kNtErrorFileExists && - ((flags & O_CREAT) && - (flags & O_TRUNC))) { /* TODO(jart): What was this? */ - return eisdir(); - } else { - return __winerr(); - } + if (GetNtOpenFlags(flags, mode, &perm, &share, &disp, &attr) == -1) return -1; + return __fix_enotdir( + CreateFile(path16, perm, share, &kNtIsInheritable, disp, attr, 0), + path16); } static textwindows ssize_t sys_open_nt_console(int dirfd, @@ -92,6 +66,7 @@ static textwindows ssize_t sys_open_nt_console(int dirfd, } g_fds.p[fd].kind = kFdConsole; g_fds.p[fd].flags = flags; + g_fds.p[fd].mode = mode; return fd; } @@ -101,6 +76,7 @@ static textwindows ssize_t sys_open_nt_file(int dirfd, const char *file, if ((g_fds.p[fd].handle = sys_open_nt_impl(dirfd, file, flags, mode)) != -1) { g_fds.p[fd].kind = kFdFile; g_fds.p[fd].flags = flags; + g_fds.p[fd].mode = mode; return fd; } else { return -1; @@ -111,7 +87,7 @@ textwindows ssize_t sys_open_nt(int dirfd, const char *file, uint32_t flags, int32_t mode) { int fd; ssize_t rc; - if ((fd = __reservefd()) == -1) return -1; + if ((fd = __reservefd(-1)) == -1) return -1; if ((flags & O_ACCMODE) == O_RDWR && !strcmp(file, kNtMagicPaths.devtty)) { rc = sys_open_nt_console(dirfd, &kNtMagicPaths, flags, mode, fd); } else { diff --git a/libc/calls/open.c b/libc/calls/open.c index 5f1e783ea..6bc9d90ba 100644 --- a/libc/calls/open.c +++ b/libc/calls/open.c @@ -29,6 +29,7 @@ * ignored if O_CREAT or O_TMPFILE weren't passed * @return number needing close(), or -1 w/ errno * @asyncsignalsafe + * @restartable * @vforksafe */ int open(const char *file, int flags, ...) { diff --git a/libc/calls/openanon.c b/libc/calls/openanon.c deleted file mode 100644 index 056f68653..000000000 --- a/libc/calls/openanon.c +++ /dev/null @@ -1,99 +0,0 @@ -/*-*- 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 "libc/assert.h" -#include "libc/calls/calls.h" -#include "libc/calls/internal.h" -#include "libc/dce.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/isslash.internal.h" -#include "libc/fmt/itoa.h" -#include "libc/nt/createfile.h" -#include "libc/nt/enum/accessmask.h" -#include "libc/nt/enum/creationdisposition.h" -#include "libc/nt/enum/fileflagandattributes.h" -#include "libc/nt/enum/filesharemode.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/at.h" -#include "libc/sysv/consts/o.h" - -static struct OpenAnon { int count; } g_openanon; - -static void openanon_genpath(const char *name, struct OpenAnon *state, - char pathbuf[hasatleast PATH_MAX]) { - char c; - size_t i; - char *p, *pe; - p = stpcpy(pathbuf, kTmpPath); - pe = pathbuf + PATH_MAX - 8 - 10 - 1 - 10 - 1; - if (!name) name = "openanon"; - for (i = 0; p < pe; ++i) { - if (!(c = name[i])) break; - if (isslash(c)) c = '_'; - *p++ = c; - } - *p++ = '.'; - p += uint64toarray_radix10(getpid(), p); - *p++ = '.'; - p += uint64toarray_radix10(++state->count, p); - *p = '\0'; - assert(p < pe); -} - -static int openanon_impl(const char *name, unsigned flags, - struct OpenAnon *state, - char pathbuf[hasatleast PATH_MAX]) { - int fd; - openanon_genpath(name, state, pathbuf); - flags |= O_RDWR | O_CREAT | O_EXCL | O_TRUNC; - if (!IsWindows()) { - if ((fd = sys_openat(AT_FDCWD, pathbuf, flags, 0600)) != -1) { - unlink(pathbuf); - } - return fd; - } else { - if ((fd = __reservefd()) == -1) return -1; - if ((g_fds.p[fd].handle = CreateFileA( - pathbuf, kNtGenericRead | kNtGenericWrite, kNtFileShareExclusive, - &kNtIsInheritable, kNtCreateAlways, - (kNtFileAttributeNotContentIndexed | kNtFileAttributeNormal | - kNtFileAttributeTemporary | kNtFileFlagDeleteOnClose), - 0)) != -1) { - g_fds.p[fd].kind = kFdFile; - g_fds.p[fd].flags = flags; - return fd; - } else { - __releasefd(fd); - return __winerr(); - } - } -} - -/** - * Creates anonymous file. - * - * @param name is purely informative - * @param flags can have O_CLOEXEC - * @return fd of file with no name, needing close(), or -1 w/ errno - * @see memfd_create() if disk-paranoid - * @see mkostempsm() for named files - */ -int openanon(char *name, unsigned flags) { - char pathbuf[PATH_MAX]; - return openanon_impl(name, flags, &g_openanon, pathbuf); -} diff --git a/libc/calls/openat-metal.c b/libc/calls/openat-metal.c index 2d83914ca..352301f0e 100644 --- a/libc/calls/openat-metal.c +++ b/libc/calls/openat-metal.c @@ -29,12 +29,13 @@ int sys_openat_metal(int dirfd, const char *file, int flags, unsigned mode) { struct MetalFile *state; if (strcmp(file, "ape.com")) return enoent(); if (!weaken(calloc)) return enomem(); - if ((fd = __reservefd()) == -1) return -1; + if ((fd = __reservefd(-1)) == -1) return -1; state = weaken(calloc)(1, sizeof(struct MetalFile)); state->base = (char *)_base; state->size = _end - _base; g_fds.p[fd].kind = kFdFile; g_fds.p[fd].flags = flags; + g_fds.p[fd].mode = mode; g_fds.p[fd].handle = (intptr_t)state; return fd; } diff --git a/libc/calls/openat.c b/libc/calls/openat.c index 501f54d0a..7f07dd379 100644 --- a/libc/calls/openat.c +++ b/libc/calls/openat.c @@ -19,8 +19,9 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/asan.internal.h" #include "libc/log/log.h" #include "libc/str/str.h" @@ -46,6 +47,7 @@ int openat(int dirfd, const char *file, int flags, ...) { int rc; va_list va; + char buf[12]; unsigned mode; struct ZiposUri zipname; va_start(va, flags); @@ -73,8 +75,8 @@ int openat(int dirfd, const char *file, int flags, ...) { } else { rc = efault(); } - SYSDEBUG("openat(%d, %s, %d, %d) -> %d %s", (long)dirfd, file, flags, - (flags & (O_CREAT | O_TMPFILE)) ? mode : 0, (long)rc, - rc == -1 ? strerror(errno) : ""); + STRACE("openat(%s, %#s, %s, %#o) → %d% m", __strace_dirfd(buf, dirfd), file, + DescribeOpenFlags(flags), (flags & (O_CREAT | O_TMPFILE)) ? mode : 0, + rc); return rc; } diff --git a/libc/calls/openbsd.internal.h b/libc/calls/openbsd.internal.h index 8a8b62bc7..b158ac9ff 100644 --- a/libc/calls/openbsd.internal.h +++ b/libc/calls/openbsd.internal.h @@ -8,8 +8,6 @@ COSMOPOLITAN_C_START_ typedef unsigned char u_char; -int pledge(const char *promises, const char *execpromises); - COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_COMPAT_OPENBSD_H_ */ diff --git a/libc/calls/pause.c b/libc/calls/pause.c index 1ce657307..b58303702 100644 --- a/libc/calls/pause.c +++ b/libc/calls/pause.c @@ -18,28 +18,34 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/sigset.h" +#include "libc/dce.h" #include "libc/errno.h" +#include "libc/nt/synchronization.h" #include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" /** * Waits for signal. * - * This suspends execution until an unmasked signal is delivered - * and its callback function has been called. It's a better idea - * to use sigsuspend() w/ sigprocmask() to avoid race conditions + * This suspends execution until an unmasked signal is delivered and its + * callback function has been called. The current signal mask is used. * * @return should always be -1 w/ EINTR * @see sigsuspend() + * @norestart */ int pause(void) { - int rc, olderr; - sigset_t oldmask; - olderr = errno; + int e, rc; + sigset_t mask; + e = errno; + STRACE("pause() → [...]"); if ((rc = sys_pause()) == -1 && errno == ENOSYS) { - errno = olderr; - if (sigprocmask(SIG_BLOCK, NULL, &oldmask) == -1) return -1; - rc = sigsuspend(&oldmask); + errno = e; + if (sigprocmask(SIG_BLOCK, 0, &mask) == -1) return -1; + rc = sigsuspend(&mask); } + STRACE("[...] pause → %d% m", rc); return rc; } diff --git a/libc/calls/pipe-nt.c b/libc/calls/pipe-nt.c index eb64f1b13..0c0db0823 100644 --- a/libc/calls/pipe-nt.c +++ b/libc/calls/pipe-nt.c @@ -20,41 +20,48 @@ #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" +#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/ipc.h" #include "libc/nt/runtime.h" +#include "libc/sysv/consts/limits.h" +#include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) { + uint32_t mode; int64_t hin, hout; int reader, writer; char16_t pipename[64]; - if (!pipefd) return efault(); CreatePipeName(pipename); - if ((reader = __reservefd()) == -1) return -1; - if ((writer = __reservefd()) == -1) { + if ((reader = __reservefd(-1)) == -1) return -1; + if ((writer = __reservefd(-1)) == -1) { __releasefd(reader); return -1; } - if ((hin = CreateNamedPipe(pipename, kNtPipeAccessInbound, - kNtPipeWait | kNtPipeReadmodeByte, 1, 65536, 65536, - 0, &kNtIsInheritable)) != -1) { + if (~flags & O_DIRECT) { + mode = kNtPipeTypeByte | kNtPipeReadmodeByte; + } else { + mode = kNtPipeTypeMessage | kNtPipeReadmodeMessage; + } + if ((hin = CreateNamedPipe( + pipename, kNtPipeAccessInbound | kNtFileFlagOverlapped, mode, 1, + PIPE_BUF, PIPE_BUF, 0, &kNtIsInheritable)) != -1) { if ((hout = CreateFile(pipename, kNtGenericWrite, 0, &kNtIsInheritable, - kNtOpenExisting, 0, 0)) != -1) { + kNtOpenExisting, kNtFileFlagOverlapped, 0)) != -1) { g_fds.p[reader].kind = kFdFile; g_fds.p[reader].flags = flags; + g_fds.p[reader].mode = 0010444; g_fds.p[reader].handle = hin; g_fds.p[writer].kind = kFdFile; g_fds.p[writer].flags = flags; + g_fds.p[writer].mode = 0010222; g_fds.p[writer].handle = hout; pipefd[0] = reader; pipefd[1] = writer; return 0; } else { - __winerr(); CloseHandle(hin); } - } else { - __winerr(); } __releasefd(writer); __releasefd(reader); diff --git a/libc/calls/pipe.c b/libc/calls/pipe.c index 03a97f54b..bbced47d4 100644 --- a/libc/calls/pipe.c +++ b/libc/calls/pipe.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -27,14 +28,26 @@ * * @param fd is (reader, writer) * @return 0 on success or -1 w/ errno + * @raise EFAULT if pipefd is NULL or an invalid address + * @raise EMFILE if RLIMIT_NOFILE is exceedde * @asyncsignalsafe * @see pipe2() */ int pipe(int pipefd[hasatleast 2]) { - if (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2)) return efault(); - if (!IsWindows()) { - return sys_pipe(pipefd); + int rc; + if (!pipefd || (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2))) { + // needed for windows which is polyfilled + // needed for xnu and netbsd which don't take an argument + rc = efault(); + } else if (!IsWindows()) { + rc = sys_pipe(pipefd); } else { - return sys_pipe_nt(pipefd, 0); + rc = sys_pipe_nt(pipefd, 0); } + if (!rc) { + STRACE("pipe([{%d, %d}]) → %d% m", pipefd[0], pipefd[1], rc); + } else { + STRACE("pipe(%p) → %d% m", pipefd, rc); + } + return rc; } diff --git a/libc/calls/pipe2-sysv.c b/libc/calls/pipe2-sysv.c index ab75113a1..34cb734ae 100644 --- a/libc/calls/pipe2-sysv.c +++ b/libc/calls/pipe2-sysv.c @@ -19,16 +19,15 @@ #include "libc/calls/internal.h" #include "libc/dce.h" #include "libc/errno.h" - -#define __NR_pipe2_linux 0x0125 /*RHEL5:CVE-2010-3301*/ +#include "libc/sysv/consts/o.h" +#include "libc/sysv/errfuns.h" int32_t sys_pipe2(int pipefd[hasatleast 2], unsigned flags) { int rc, olderr; if (!flags) goto OldSkool; olderr = errno; rc = __sys_pipe2(pipefd, flags); - if ((rc == -1 && errno == ENOSYS) || - (SupportsLinux() && rc == __NR_pipe2_linux)) { + if (rc == -1 && errno == ENOSYS) { errno = olderr; OldSkool: if ((rc = sys_pipe(pipefd)) != -1) { diff --git a/libc/calls/pipe2.c b/libc/calls/pipe2.c index f782dd018..2c916775a 100644 --- a/libc/calls/pipe2.c +++ b/libc/calls/pipe2.c @@ -17,23 +17,35 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" /** * Creates file-less file descriptors for interprocess communication. * * @param pipefd is used to return (reader, writer) file descriptors - * @param flags can have O_CLOEXEC, O_NONBLOCK, O_DIRECT + * @param flags can have O_CLOEXEC or O_DIRECT or O_NONBLOCK * @return 0 on success, or -1 w/ errno and pipefd isn't modified */ int pipe2(int pipefd[hasatleast 2], int flags) { - if (!pipefd) return efault(); - if (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2)) return efault(); - if (!IsWindows()) { - return sys_pipe2(pipefd, flags); + int rc; + if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT)) { + return einval(); + } else if (!pipefd || + (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_pipe2(pipefd, flags); } else { - return sys_pipe_nt(pipefd, flags); + rc = sys_pipe_nt(pipefd, flags); } + if (!rc) { + STRACE("pipe2([{%d, %d}], %#o) → %d% m", pipefd[0], pipefd[1], flags, rc); + } else { + STRACE("pipe2(%p, %#o) → %d% m", pipefd, flags, rc); + } + return rc; } diff --git a/libc/sock/poll-metal.c b/libc/calls/poll-metal.c similarity index 99% rename from libc/sock/poll-metal.c rename to libc/calls/poll-metal.c index 4eb946176..60c77a423 100644 --- a/libc/sock/poll-metal.c +++ b/libc/calls/poll-metal.c @@ -73,7 +73,7 @@ int sys_poll_metal(struct pollfd *fds, size_t nfds, unsigned timeout_ms) { if (rc || !blocking || unsignedsubtract(rdtsc(), start) >= timeout) { break; } else { - asm("pause"); + __builtin_ia32_pause(); } } return rc; diff --git a/libc/calls/poll-nt.c b/libc/calls/poll-nt.c new file mode 100644 index 000000000..b8664c48a --- /dev/null +++ b/libc/calls/poll-nt.c @@ -0,0 +1,213 @@ +/*-*- 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 "libc/bits/bits.h" +#include "libc/bits/weaken.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/errno.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/spinlock.h" +#include "libc/macros.internal.h" +#include "libc/mem/mem.h" +#include "libc/nt/enum/filetype.h" +#include "libc/nt/errors.h" +#include "libc/nt/files.h" +#include "libc/nt/ipc.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/pollfd.h" +#include "libc/nt/synchronization.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sock/ntstdin.internal.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/poll.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" + +_Alignas(64) static char poll_lock; + +/** + * Polls on the New Technology. + * + * This function is used to implement poll() and select(). You may poll + * on both sockets and files at the same time. We also poll for signals + * while poll is polling. + */ +textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms) { + bool ok; + uint32_t avail; + struct sys_pollfd_nt pipefds[8]; + struct sys_pollfd_nt sockfds[64]; + int pipeindices[ARRAYLEN(pipefds)]; + int sockindices[ARRAYLEN(sockfds)]; + int i, sn, pn, failed, gotinvals, gotpipes, gotsocks, waitfor; + + // check for interrupts early before doing work + if (_check_interrupts(false, g_fds.p)) return eintr(); + + // do the planning + // we need to read static variables + // we might need to spawn threads and open pipes + _spinlock(&poll_lock); + _spinlock(&__fds_lock); + for (gotinvals = failed = sn = pn = i = 0; i < nfds; ++i) { + if (fds[i].fd < 0) continue; + if (__isfdopen(fds[i].fd)) { + if (__isfdkind(fds[i].fd, kFdSocket)) { + if (sn < ARRAYLEN(sockfds)) { + // the magnums for POLLIN/OUT/PRI on NT include the other ones too + // we need to clear ones like POLLNVAL or else WSAPoll shall whine + sockindices[sn] = i; + sockfds[sn].handle = g_fds.p[fds[i].fd].handle; + sockfds[sn].events = fds[i].events & (POLLPRI | POLLIN | POLLOUT); + sockfds[sn].revents = 0; + ++sn; + } else { + // too many socket fds + failed = enomem(); + break; + } + } else if (pn < ARRAYLEN(pipefds)) { + pipeindices[pn] = i; + pipefds[pn].handle = g_fds.p[fds[i].fd].handle; + pipefds[pn].events = 0; + pipefds[pn].revents = 0; + switch (g_fds.p[fds[i].fd].flags & O_ACCMODE) { + case O_RDONLY: + pipefds[pn].events = fds[i].events & POLLIN; + break; + case O_WRONLY: + pipefds[pn].events = fds[i].events & POLLOUT; + break; + case O_RDWR: + pipefds[pn].events = fds[i].events & (POLLIN | POLLOUT); + break; + default: + unreachable; + } + ++pn; + } else { + // too many non-socket fds + failed = enomem(); + break; + } + } else { + ++gotinvals; + } + } + _spunlock(&__fds_lock); + _spunlock(&poll_lock); + if (failed) { + // failed to create a polling solution + return failed; + } + + // perform the i/o and sleeping and looping + for (;;) { + // see if input is available on non-sockets + for (gotpipes = i = 0; i < pn; ++i) { + if (pipefds[i].events & POLLOUT) { + // we have no way of polling if a non-socket is writeable yet + // therefore we assume that if it can happen, it shall happen + pipefds[i].revents = POLLOUT; + } + if (pipefds[i].events & POLLIN) { + if (GetFileType(pipefds[i].handle) == kNtFileTypePipe) { + ok = PeekNamedPipe(pipefds[i].handle, 0, 0, 0, &avail, 0); + POLLTRACE("PeekNamedPipe(%ld, 0, 0, 0, [%'u], 0) → %hhhd% m", + pipefds[i].handle, avail, ok); + if (ok) { + if (avail) { + pipefds[i].revents = POLLIN; + } + } else { + pipefds[i].revents = POLLERR; + } + } else { + // we have no way of polling if a non-socket is readable yet + // therefore we assume that if it can happen it shall happen + pipefds[i].revents = POLLIN; + } + } + if (pipefds[i].revents) { + ++gotpipes; + } + } + // if we haven't found any good results yet then here we + // compute a small time slice we don't mind sleeping for + waitfor = gotinvals || gotpipes ? 0 : MIN(__SIG_POLLING_INTERVAL_MS, *ms); + if (sn) { + // we need to poll the socket handles separately because + // microsoft certainly loves to challenge us with coding + // please note that winsock will fail if we pass zero fd +#if _NTTRACE + POLLTRACE("WSAPoll(%p, %u, %'d) out of %'lu", sockfds, sn, waitfor, *ms); +#endif + if ((gotsocks = WSAPoll(sockfds, sn, waitfor)) == -1) { + return __winsockerr(); + } + *ms -= waitfor; + } else { + gotsocks = 0; + if (!gotinvals && !gotpipes && waitfor) { + // if we've only got pipes and none of them are ready + // then we'll just explicitly sleep for the time left + POLLTRACE("SleepEx(%'d, false) out of %'lu", waitfor, *ms); + if (SleepEx(__SIG_POLLING_INTERVAL_MS, true) == kNtWaitIoCompletion) { + POLLTRACE("IOCP EINTR"); + } else { + *ms -= waitfor; + } + } + } + // we gave all the sockets and all the named pipes a shot + // if we found anything at all then it's time to end work + if (gotinvals || gotpipes || gotsocks || *ms <= 0) { + break; + } + // otherwise loop limitlessly for timeout to elapse while + // checking for signal delivery interrupts, along the way + if (_check_interrupts(false, g_fds.p)) { + return eintr(); + } + } + + // the system call is going to succeed + // it's now ok to start setting the output memory + for (i = 0; i < nfds; ++i) { + if (fds[i].fd < 0 || __isfdopen(fds[i].fd)) { + fds[i].revents = 0; + } else { + fds[i].revents = POLLNVAL; + } + } + for (i = 0; i < pn; ++i) { + fds[pipeindices[i]].revents = pipefds[i].revents; + } + for (i = 0; i < sn; ++i) { + fds[sockindices[i]].revents = sockfds[i].revents; + } + + // and finally return + return gotinvals + gotpipes + gotsocks; +} diff --git a/libc/calls/poll.c b/libc/calls/poll.c new file mode 100644 index 000000000..f58228e32 --- /dev/null +++ b/libc/calls/poll.c @@ -0,0 +1,105 @@ +/*-*- 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 "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/asan.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Waits for something to happen on multiple file descriptors at once. + * + * Warning: XNU has an inconsistency with other platforms. If you have + * pollfds with fd≥0 and none of the meaningful events flags are added + * e.g. POLLIN then XNU won't check for POLLNVAL. This matters because + * one of the use-cases for poll() is quickly checking for open files. + * + * Note: Polling works best on Windows for sockets. We're able to poll + * input on named pipes. But for anything that isn't a socket, or pipe + * with POLLIN, (e.g. regular file) then POLLIN/POLLOUT are always set + * into revents if they're requested, provided they were opened with a + * mode that permits reading and/or writing. + * + * Note: Windows has a limit of 64 file descriptors and ENOMEM with -1 + * is returned if that limit is exceeded. In practice the limit is not + * this low. For example, pollfds with fd<0 don't count. So the caller + * could flip the sign bit with a short timeout, to poll a larger set. + * + * @param fds[𝑖].fd should be a socket, input pipe, or conosle input + * and if it's a negative number then the entry is ignored + * @param fds[𝑖].events flags can have POLLIN, POLLOUT, POLLPRI, + * POLLRDNORM, POLLWRNORM, POLLRDBAND, POLLWRBAND as well as + * POLLERR, POLLHUP, and POLLNVAL although the latter are + * always implied (assuming fd≥0) so they're ignored here + * @param timeout_ms if 0 means don't wait and -1 means wait forever + * @return number of items fds whose revents field has been set to + * nonzero to describe its events, or 0 if the timeout elapsed, + * or -1 w/ errno + * @return fds[𝑖].revents is always zero initializaed and then will + * be populated with POLL{IN,OUT,PRI,HUP,ERR,NVAL} if something + * was determined about the file descriptor + * @asyncsignalsafe + * @threadsafe + * @norestart + */ +int poll(struct pollfd *fds, size_t nfds, int timeout_ms) { + int i, rc; + uint64_t millis; + + if (IsAsan() && !__asan_is_valid(fds, nfds * sizeof(struct pollfd))) { + rc = efault(); + } else if (!IsWindows()) { + if (!IsMetal()) { + rc = sys_poll(fds, nfds, timeout_ms); + } else { + rc = sys_poll_metal(fds, nfds, timeout_ms); + } + } else { + millis = timeout_ms; + rc = sys_poll_nt(fds, nfds, &millis); + } + +#if defined(SYSDEBUG) && _POLLTRACE + if (__strace > 0) { + if (rc == -1 && errno == EFAULT) { + STRACE("poll(%p, %'lu, %'d) → %d% lm", fds, nfds, timeout_ms, rc); + } else { + char flagbuf[2][64]; + kprintf(STRACE_PROLOGUE "poll({"); + for (i = 0; i < MIN(5, nfds); ++i) { + kprintf( + "%s{%d, %s, %s}", i ? ", " : "", fds[i].fd, + DescribePollFlags(flagbuf[0], sizeof(flagbuf[0]), fds[i].events), + DescribePollFlags(flagbuf[1], sizeof(flagbuf[1]), fds[i].revents)); + } + kprintf("%s}, %'zu, %'d) → %d% lm\n", i == 5 ? "..." : "", nfds, + timeout_ms, rc); + } + } +#endif + + return rc; +} diff --git a/libc/calls/prctl.c b/libc/calls/prctl.c new file mode 100644 index 000000000..71681273b --- /dev/null +++ b/libc/calls/prctl.c @@ -0,0 +1,67 @@ +/*-*- 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 2022 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/strace.internal.h" +#include "libc/errno.h" +#include "libc/sysv/consts/pr.h" +#include "libc/sysv/errfuns.h" + +static const char *DescribePrctlOperation(int x) { + switch (x) { + case PR_SET_NO_NEW_PRIVS: + return "PR_SET_NO_NEW_PRIVS"; + case PR_SET_SECCOMP: + return "PR_SET_SECCOMP"; + case PR_GET_SECCOMP: + return "PR_GET_SECCOMP"; + default: + return "PRCTL_???"; + } +} + +/** + * Tunes process on Linux. + * + * @raise ENOSYS on non-Linux. + */ +int prctl(int operation, ...) { + int rc; + va_list va; + intptr_t a, b; + register intptr_t c asm("r10"); + register intptr_t d asm("r8"); + va_start(va, operation); + a = va_arg(va, intptr_t); + b = va_arg(va, intptr_t); + c = va_arg(va, intptr_t); + d = va_arg(va, intptr_t); + va_end(va); + if (IsLinux()) { + asm volatile("syscall" + : "=a"(rc) + : "0"(157), "D"(operation), "S"(a), "d"(b), "r"(c), "r"(d) + : "rcx", "r11", "memory"); + if (rc > -4096u) errno = -rc, rc = -1; + } else { + rc = enosys(); + } + STRACE("prctl(%s, %p, %p, %p, %p) → %d% m", DescribePrctlOperation(operation), + a, b, c, d, rc); + return rc; +} diff --git a/libc/calls/pread.c b/libc/calls/pread.c index 5fd167800..1f4370e63 100644 --- a/libc/calls/pread.c +++ b/libc/calls/pread.c @@ -20,8 +20,10 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" +#include "libc/intrin/asan.internal.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/sysv/errfuns.h" @@ -43,7 +45,9 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) { ssize_t rc; if (fd == -1 || offset < 0) return einval(); - if (__isfdkind(fd, kFdZip)) { + if (IsAsan() && !__asan_is_valid(buf, size)) { + rc = efault(); + } else if (__isfdkind(fd, kFdZip)) { rc = weaken(__zipos_read)((struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, (struct iovec[]){{buf, size}}, 1, offset); @@ -54,8 +58,8 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) { } else { rc = ebadf(); } - if (!IsTrustworthy() && rc != -1) { - if ((size_t)rc > size) abort(); - } + assert(rc == -1 || (size_t)rc <= size); + DATATRACE("pread(%d, [%#.*hhs%s], %'zu, %'zd) → %'zd% m", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, offset, rc); return rc; } diff --git a/libc/calls/preadv.c b/libc/calls/preadv.c index 3ad2b28f2..94f83a1b8 100644 --- a/libc/calls/preadv.c +++ b/libc/calls/preadv.c @@ -20,25 +20,18 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/sysv/consts/iov.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" -#define __NR_preadv_linux 0x0127 - -/** - * Reads with maximum generality. - * - * @return number of bytes actually read, or -1 w/ errno - * @asyncsignalsafe - * @vforksafe - */ -ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) { +static ssize_t Preadv(int fd, struct iovec *iov, int iovlen, int64_t off) { static bool once, demodernize; int i, err; ssize_t rc; @@ -60,23 +53,21 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) { return enosys(); } + if (iovlen == 1) { + return sys_pread(fd, iov[0].iov_base, iov[0].iov_len, off, off); + } + /* - * NT, XNU, and 2007-era Linux don't support this system call. + * NT, 2018-era XNU, and 2007-era Linux don't support this system call */ - if (!once) { + if (!__vforked && !once) { err = errno; rc = sys_preadv(fd, iov, iovlen, off, off); if (rc == -1 && errno == ENOSYS) { errno = err; once = true; demodernize = true; - } else if (IsLinux() && rc == __NR_preadv_linux) { - if (__iovec_size(iov, iovlen) < __NR_preadv_linux) { - demodernize = true; /*RHEL5:CVE-2010-3301*/ - once = true; - } else { - return rc; - } + STRACE("demodernizing %s() due to %s", "preadv", "ENOSYS"); } else { once = true; return rc; @@ -109,3 +100,27 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) { return toto; } + +/** + * Reads with maximum generality. + * + * @return number of bytes actually read, or -1 w/ errno + * @asyncsignalsafe + * @vforksafe + */ +ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) { + ssize_t rc; + rc = Preadv(fd, iov, iovlen, off); +#if defined(SYSDEBUG) && _DATATRACE + if (__strace > 0) { + if (rc == -1 && errno == EFAULT) { + STRACE("preadv(%d, %p, %d, %'ld) → %'zd% m", fd, iov, iovlen, off, rc); + } else { + kprintf(STRACE_PROLOGUE "preadv(%d, [", fd); + __strace_iov(iov, iovlen, rc != -1 ? rc : 0); + kprintf("], %d, %'ld) → %'ld% m\n", iovlen, off, rc); + } + } +#endif + return rc; +} diff --git a/libc/calls/printfds.c b/libc/calls/printfds.c new file mode 100644 index 000000000..26ad273b2 --- /dev/null +++ b/libc/calls/printfds.c @@ -0,0 +1,61 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/spinlock.h" + +static const char *__fdkind2str(int x) { + switch (x) { + case kFdEmpty: + return "kFdEmpty"; + case kFdFile: + return "kFdFile"; + case kFdSocket: + return "kFdSocket"; + case kFdProcess: + return "kFdProcess"; + case kFdConsole: + return "kFdConsole"; + case kFdSerial: + return "kFdSerial"; + case kFdZip: + return "kFdZip"; + case kFdEpoll: + return "kFdEpoll"; + default: + return "kFdWut"; + } +} + +void __printfds(void) { + int i; + _spinlock(&__fds_lock); + for (i = 0; i < g_fds.n; ++i) { + if (!g_fds.p[i].kind) continue; + kprintf("%3d %s", i, __fdkind2str(g_fds.p[i].kind)); + if (g_fds.p[i].zombie) kprintf(" zombie"); + if (g_fds.p[i].flags) kprintf(" flags=%#x", g_fds.p[i].flags); + if (g_fds.p[i].mode) kprintf(" mode=%#o", g_fds.p[i].mode); + if (g_fds.p[i].handle) kprintf(" handle=%ld", g_fds.p[i].handle); + if (g_fds.p[i].extra) kprintf(" extra=%ld", g_fds.p[i].extra); + if (g_fds.p[i].worker) kprintf(" worker=%p", g_fds.p[i].worker); + kprintf("\n"); + } + _spunlock(&__fds_lock); +} diff --git a/libc/calls/prot2nt.greg.c b/libc/calls/prot2nt.greg.c deleted file mode 100644 index ab53d9663..000000000 --- a/libc/calls/prot2nt.greg.c +++ /dev/null @@ -1,49 +0,0 @@ -/*-*- 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 "libc/calls/internal.h" -#include "libc/nt/enum/pageflags.h" -#include "libc/nt/memory.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/prot.h" - -#define HAS(X, BITS) (((X) & (BITS)) == (BITS)) - -/** - * Converts System Five memory protection flags to Windows NT, Part 1. - * @see libc/sysv/consts.sh - */ -privileged uint32_t __prot2nt(int prot, int flags) { - return (HAS(prot, PROT_READ | PROT_WRITE | PROT_EXEC) - ? (HAS(flags, MAP_SHARED) || HAS(flags, MAP_ANONYMOUS)) - ? kNtPageExecuteReadwrite - : kNtPageExecuteWritecopy - : HAS(prot, PROT_READ | PROT_WRITE) - ? (HAS(flags, MAP_SHARED) || HAS(flags, MAP_ANONYMOUS)) - ? kNtPageReadwrite - : kNtPageReadwrite /* kNtPageWritecopy */ - : HAS(prot, PROT_READ | PROT_EXEC) - ? kNtPageExecuteRead - : HAS(prot, PROT_EXEC) - ? kNtPageExecute - : HAS(prot, PROT_READ) ? kNtPageReadonly - : kNtPageNoaccess) | - ((prot | flags) & - (kNtSecReserve | kNtSecCommit | kNtSecImage | kNtSecImageNoExecute | - kNtSecLargePages | kNtSecNocache | kNtSecWritecombine)); -} diff --git a/libc/calls/ptrace.c b/libc/calls/ptrace.c index 8866ca608..8eb15c3c9 100644 --- a/libc/calls/ptrace.c +++ b/libc/calls/ptrace.c @@ -17,16 +17,74 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/sysv/consts/ptrace.h" #include "libc/sysv/errfuns.h" +static const char *__ptrace_describe_request(int x) { + if (x == -1) return "-1"; + if (x == PTRACE_TRACEME) return "PTRACE_TRACEME"; + if (x == PTRACE_PEEKDATA) return "PTRACE_PEEKDATA"; + if (x == PTRACE_GETFPREGS) return "PTRACE_GETFPREGS"; + if (x == PTRACE_PEEKTEXT) return "PTRACE_PEEKTEXT"; + if (x == PTRACE_POKEDATA) return "PTRACE_POKEDATA"; + if (x == PTRACE_PEEKUSER) return "PTRACE_PEEKUSER"; + if (x == PTRACE_POKETEXT) return "PTRACE_POKETEXT"; + if (x == PTRACE_POKEUSER) return "PTRACE_POKEUSER"; + if (x == PTRACE_GETREGS) return "PTRACE_GETREGS"; + if (x == PTRACE_GETREGSET) return "PTRACE_GETREGSET"; + if (x == PTRACE_SETFPREGS) return "PTRACE_SETFPREGS"; + if (x == PTRACE_SETREGS) return "PTRACE_SETREGS"; + if (x == PTRACE_SETREGSET) return "PTRACE_SETREGSET"; + if (x == PTRACE_GETSIGINFO) return "PTRACE_GETSIGINFO"; + if (x == PTRACE_SETSIGINFO) return "PTRACE_SETSIGINFO"; + if (x == PTRACE_PEEKSIGINFO) return "PTRACE_PEEKSIGINFO"; + if (x == PTRACE_GETSIGMASK) return "PTRACE_GETSIGMASK"; + if (x == PTRACE_SETSIGMASK) return "PTRACE_SETSIGMASK"; + if (x == PTRACE_SETOPTIONS) return "PTRACE_SETOPTIONS"; + if (x == PTRACE_GETEVENTMSG) return "PTRACE_GETEVENTMSG"; + if (x == PTRACE_CONT) return "PTRACE_CONT"; + if (x == PTRACE_SINGLESTEP) return "PTRACE_SINGLESTEP"; + if (x == PTRACE_SYSCALL) return "PTRACE_SYSCALL"; + if (x == PTRACE_LISTEN) return "PTRACE_LISTEN"; + if (x == PTRACE_KILL) return "PTRACE_KILL"; + if (x == PTRACE_INTERRUPT) return "PTRACE_INTERRUPT"; + if (x == PTRACE_ATTACH) return "PTRACE_ATTACH"; + if (x == PTRACE_SEIZE) return "PTRACE_SEIZE"; + if (x == PTRACE_SECCOMP_GET_FILTER) return "PTRACE_SECCOMP_GET_FILTER"; + if (x == PTRACE_DETACH) return "PTRACE_DETACH"; + return "PTRACE_WUT"; +} + /** * Traces process. * * @param request can be PTRACE_xxx * @note de facto linux only atm + * @vforksafe */ -long ptrace(int request, int pid, void *addr, void *data) { - /* TODO(jart): FreeBSD addr and data args are different */ - if (request == -1) return einval(); /* see consts.sh */ - return sys_ptrace(request, pid, addr, data); +long ptrace(int request, ...) { + // TODO(jart): FreeBSD addr and data args are different + int pid; + va_list va; + bool ispeek; + long rc, peek; + void *addr, *data; + va_start(va, request); + pid = va_arg(va, int); + addr = va_arg(va, void *); + data = va_arg(va, void *); + va_end(va); + if (request == -1) { + rc = einval(); /* see consts.sh */ + } else { + ispeek = IsLinux() && request - 1u < 3; + if (ispeek) data = &peek; + rc = sys_ptrace(request, pid, addr, data); + if (rc != -1 && ispeek) rc = peek; + } + STRACE("ptrace(%s, %d, %p, %p) → %ld% m", __ptrace_describe_request(request), + pid, addr, data); + return rc; } diff --git a/libc/calls/ptsname_r.c b/libc/calls/ptsname_r.c index 3a85a84f1..49fefdb0a 100644 --- a/libc/calls/ptsname_r.c +++ b/libc/calls/ptsname_r.c @@ -29,7 +29,7 @@ errno_t ptsname_r(int fd, char *buf, size_t size) { if (size) { if (!buf) return einval(); if (ioctl(fd, TIOCGPTN, &pty) == -1) return errno; - int64toarray_radix10(pty, stpcpy(tb, "/dev/pts/")); + FormatInt32(stpcpy(tb, "/dev/pts/"), pty); if (strlen(tb) + 1 >= size) return (errno = ERANGE); stpcpy(buf, tb); /* TODO(jart): OpenBSD OMG */ diff --git a/libc/calls/pwrite.c b/libc/calls/pwrite.c index d8a061d3d..0335cbe28 100644 --- a/libc/calls/pwrite.c +++ b/libc/calls/pwrite.c @@ -19,8 +19,10 @@ #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" +#include "libc/intrin/asan.internal.h" #include "libc/macros.internal.h" #include "libc/sysv/errfuns.h" @@ -42,10 +44,12 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) { size_t wrote; if (fd == -1 || offset < 0) return einval(); size = MIN(size, 0x7ffff000); - if (!IsWindows()) { + if (IsAsan() && !__asan_is_valid(buf, size)) { + rc = efault(); + } else if (!IsWindows()) { rc = sys_pwrite(fd, buf, size, offset, offset); } else if (__isfdkind(fd, kFdFile)) { - rc = sys_write_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, offset); + rc = sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, offset); } else { return ebadf(); } @@ -57,5 +61,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) { assert(wrote <= size); } } + DATATRACE("pwrite(%d, %#.*hhs%s, %'zu, %'zd) → %'zd% m", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, offset, rc); return rc; } diff --git a/libc/calls/pwritev.c b/libc/calls/pwritev.c index 036ddfdb0..a480338bc 100644 --- a/libc/calls/pwritev.c +++ b/libc/calls/pwritev.c @@ -19,30 +19,19 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/sysv/consts/iov.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" -#define __NR_pwritev_linux 0x0128 - -/** - * Writes data from multiple buffers to offset. - * - * Please note that it's not an error for a short write to happen. This - * can happen in the kernel if EINTR happens after some of the write has - * been committed. It can also happen if we need to polyfill this system - * call using pwrite(). - * - * @return number of bytes actually sent, or -1 w/ errno - * @asyncsignalsafe - * @vforksafe - */ -ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) { +static ssize_t Pwritev(int fd, const struct iovec *iov, int iovlen, + int64_t off) { static bool once, demodernize; int i, err; ssize_t rc; @@ -56,7 +45,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) { (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off); } else if (IsWindows()) { if (fd < g_fds.n) { - return sys_write_nt(g_fds.p + fd, iov, iovlen, off); + return sys_write_nt(fd, iov, iovlen, off); } else { return ebadf(); } @@ -64,8 +53,12 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) { return enosys(); } + if (iovlen == 1) { + return sys_pwrite(fd, iov[0].iov_base, iov[0].iov_len, off, off); + } + /* - * NT, XNU, and 2007-era Linux don't support this system call. + * NT, 2018-era XNU, and 2007-era Linux don't support this system call */ if (!once) { err = errno; @@ -74,13 +67,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) { errno = err; once = true; demodernize = true; - } else if (IsLinux() && rc == __NR_pwritev_linux) { - if (__iovec_size(iov, iovlen) < __NR_pwritev_linux) { - demodernize = true; /*RHEL5:CVE-2010-3301*/ - once = true; - } else { - return rc; - } + STRACE("demodernizing %s() due to %s", "pwritev", "ENOSYS"); } else { once = true; return rc; @@ -113,3 +100,32 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) { return toto; } + +/** + * Writes data from multiple buffers to offset. + * + * Please note that it's not an error for a short write to happen. This + * can happen in the kernel if EINTR happens after some of the write has + * been committed. It can also happen if we need to polyfill this system + * call using pwrite(). + * + * @return number of bytes actually sent, or -1 w/ errno + * @asyncsignalsafe + * @vforksafe + */ +ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) { + ssize_t rc; + rc = Pwritev(fd, iov, iovlen, off); +#if defined(SYSDEBUG) && _DATATRACE + if (__strace > 0) { + if (rc == -1 && errno == EFAULT) { + STRACE("pwritev(%d, %p, %d, %'ld) → %'zd% m", fd, iov, iovlen, off, rc); + } else { + kprintf(STRACE_PROLOGUE "pwritev(%d, ", fd); + __strace_iov(iov, iovlen, rc != -1 ? rc : 0); + kprintf(", %d, %'ld) → %'ld% m\n", iovlen, off, rc); + } + } +#endif + return rc; +} diff --git a/libc/calls/raise.c b/libc/calls/raise.c index 70683b910..6b47956d6 100644 --- a/libc/calls/raise.c +++ b/libc/calls/raise.c @@ -17,12 +17,26 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" -#include "libc/calls/getconsolectrlevent.h" +#include "libc/calls/getconsolectrlevent.internal.h" #include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/nt/console.h" +#include "libc/nt/errors.h" +#include "libc/nt/process.h" #include "libc/nt/runtime.h" +#include "libc/nt/synchronization.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sicode.h" #include "libc/sysv/consts/sig.h" +static textwindows inline bool HasWorkingConsole(void) { + return !!(__ntconsolemode[0] | __ntconsolemode[1] | __ntconsolemode[2]); +} + /** * Sends signal to this process. * @@ -31,25 +45,36 @@ * @asyncsignalsafe */ int raise(int sig) { - int event; + int rc, event; + STRACE("raise(%G) → ...", sig); if (sig == SIGTRAP) { DebugBreak(); - return 0; - } - if (sig == SIGFPE) { + rc = 0; + } else if (sig == SIGFPE) { volatile int x = 0; x = 1 / x; - return 0; - } - if (!IsWindows()) { - return sys_kill(getpid(), sig, 1); - } else if ((event = GetConsoleCtrlEvent(sig))) { - if (GenerateConsoleCtrlEvent(event, 0)) { - return 0; - } else { - return __winerr(); - } + rc = 0; + } else if (!IsWindows()) { + // XXX: should be tkill() or tgkill() on linux + rc = sys_kill(getpid(), sig, 1); } else { - ExitProcess(128 + sig); + if (HasWorkingConsole() && (event = GetConsoleCtrlEvent(sig)) != -1) { + // XXX: MSDN says "If this parameter is zero, the signal is + // generated in all processes that share the console of the + // calling process." which seems to imply multiple process + // groups potentially. We just shouldn't use this because it + // doesn't make any sense and it's so evil. + if (GenerateConsoleCtrlEvent(event, 0)) { + SleepEx(100, true); + __sig_check(false); + rc = 0; + } else { + rc = __winerr(); + } + } else { + rc = __sig_raise(sig, SI_USER); + } } + STRACE("...raise(%G) → %d% m", sig, rc); + return rc; } diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 024acb67b..9c2d44692 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -16,27 +16,50 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/iovec.h" -#include "libc/errno.h" -#include "libc/limits.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/enum/filetype.h" #include "libc/nt/errors.h" +#include "libc/nt/files.h" +#include "libc/nt/ipc.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/overlapped.h" +#include "libc/nt/synchronization.h" #include "libc/sysv/errfuns.h" static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data, size_t size, ssize_t offset) { - uint32_t got; + uint32_t got, avail; struct NtOverlapped overlap; - if (ReadFile(fd->handle, data, clampio(size), &got, - offset2overlap(offset, &overlap))) { + if (GetFileType(fd->handle) == kNtFileTypePipe) { + for (;;) { + if (!PeekNamedPipe(fd->handle, 0, 0, 0, &avail, 0)) break; + if (avail) break; + POLLTRACE("sys_read_nt polling"); + if (SleepEx(__SIG_POLLING_INTERVAL_MS, true) == kNtWaitIoCompletion) { + POLLTRACE("IOCP EINTR"); + } + if (_check_interrupts(true, g_fds.p)) { + POLLTRACE("sys_read_nt interrupted"); + return eintr(); + } + } + POLLTRACE("sys_read_nt ready to read"); + } + if (ReadFile(fd->handle, data, _clampio(size), &got, + _offset2overlap(fd->handle, offset, &overlap))) { return got; - } else if (GetLastError() == kNtErrorBrokenPipe) { - return 0; - } else { - return __winerr(); + } + switch (GetLastError()) { + case kNtErrorBrokenPipe: // broken pipe + case kNtErrorNoData: // closing named pipe + case kNtErrorHandleEof: // pread read past EOF + return 0; // + case kNtErrorAccessDenied: // read doesn't return EACCESS + return ebadf(); // + default: + return __winerr(); } } @@ -45,6 +68,7 @@ textwindows ssize_t sys_read_nt(struct Fd *fd, const struct iovec *iov, ssize_t rc; uint32_t size; size_t i, total; + if (_check_interrupts(true, fd)) return eintr(); while (iovlen && !iov[0].iov_len) iov++, iovlen--; if (iovlen) { for (total = i = 0; i < iovlen; ++i) { diff --git a/libc/calls/read.c b/libc/calls/read.c index 1a33b0d4c..31ffff570 100644 --- a/libc/calls/read.c +++ b/libc/calls/read.c @@ -19,9 +19,11 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sysv/errfuns.h" @@ -37,24 +39,30 @@ * exception of size==0, in which case return zero means no error * @see write(), pread(), readv() * @asyncsignalsafe + * @restartable */ ssize_t read(int fd, void *buf, size_t size) { + ssize_t rc; if (fd >= 0) { - if (IsAsan() && !__asan_is_valid(buf, size)) return efault(); - if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return weaken(__zipos_read)( + if (IsAsan() && !__asan_is_valid(buf, size)) { + rc = efault(); + } else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { + rc = weaken(__zipos_read)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, &(struct iovec){buf, size}, 1, -1); } else if (!IsWindows() && !IsMetal()) { - return sys_read(fd, buf, size); + rc = sys_read(fd, buf, size); } else if (fd >= g_fds.n) { - return ebadf(); + rc = ebadf(); } else if (IsMetal()) { - return sys_readv_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1); + rc = sys_readv_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1); } else { - return sys_readv_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1); + rc = sys_readv_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1); } } else { - return einval(); + rc = einval(); } + DATATRACE("read(%d, [%#.*hhs%s], %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), + buf, rc > 40 ? "..." : "", size, rc); + return rc; } diff --git a/libc/calls/readlink.c b/libc/calls/readlink.c index 67d6adeab..d758647f5 100644 --- a/libc/calls/readlink.c +++ b/libc/calls/readlink.c @@ -22,16 +22,10 @@ /** * Reads symbolic link. * - * This does *not* nul-terminate the buffer. - * - * It is recommended that malloc() be linked into your program when - * using this function. Otherwise the buffer should be larger. It should - * also be noted that, without malloc, long names with many astral plane - * characters might not decode properly. - * * @param path must be a symbolic link pathname * @param buf will receive symbolic link contents, and won't be modified * unless the function succeeds (with the exception of no-malloc nt) + * and this buffer will *not* be nul-terminated * @return number of bytes written to buf, or -1 w/ errno; if the * return is equal to bufsiz then truncation may have occurred * @see readlinkat(AT_FDCWD, ...) for modern version of this diff --git a/libc/calls/readlinkat-nt.c b/libc/calls/readlinkat-nt.c index 13300daca..e55136d35 100644 --- a/libc/calls/readlinkat-nt.c +++ b/libc/calls/readlinkat-nt.c @@ -16,65 +16,37 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" -#include "libc/bits/weaken.h" -#include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" -#include "libc/mem/mem.h" -#include "libc/nexgen32e/bsr.h" +#include "libc/calls/strace.internal.h" +#include "libc/mem/alloca.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/creationdisposition.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/enum/fsctl.h" #include "libc/nt/enum/io.h" -#include "libc/nt/errors.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/reparsedatabuffer.h" +#include "libc/str/str.h" #include "libc/str/tpenc.h" #include "libc/str/utf16.h" #include "libc/sysv/errfuns.h" -static textwindows ssize_t sys_readlinkat_nt_error(void) { - uint32_t e; - e = GetLastError(); - SYSDEBUG("sys_readlinkat_nt() error %d", e); - switch (e) { - case kNtErrorNotAReparsePoint: - return einval(); - default: - errno = e; - return -1; - } -} - textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf, size_t bufsiz) { int64_t h; ssize_t rc; uint64_t w; wint_t x, y; - void *freeme; - uint32_t e, i, j, n, mem; + volatile char *memory; + uint32_t i, j, n, mem; char16_t path16[PATH_MAX], *p; struct NtReparseDataBuffer *rdb; - if (__mkntpathat(dirfd, path, 0, path16) == -1) { - SYSDEBUG("sys_readlinkat_nt() failed b/c __mkntpathat() failed"); - return -1; - } - if (weaken(malloc)) { - mem = 16384; - rdb = weaken(malloc)(mem); - freeme = rdb; - } else if (bufsiz >= sizeof(struct NtReparseDataBuffer) + 16) { - mem = bufsiz; - rdb = (struct NtReparseDataBuffer *)buf; - freeme = 0; - } else { - SYSDEBUG("sys_readlinkat_nt() needs bigger buffer malloc() to be yoinked"); - return enomem(); - } + if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; + mem = 16384; + memory = alloca(mem); + for (i = 0; i < mem; i += PAGESIZE) memory[i] = 0; + rdb = (struct NtReparseDataBuffer *)memory; if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting, kNtFileFlagOpenReparsePoint | kNtFileFlagBackupSemantics, 0)) != -1) { @@ -85,6 +57,12 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf, n = rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(char16_t); p = (char16_t *)((char *)rdb->SymbolicLinkReparseBuffer.PathBuffer + rdb->SymbolicLinkReparseBuffer.PrintNameOffset); + if (n >= 3 && isalpha(p[0]) && p[1] == ':' && p[2] == '\\') { + buf[j++] = '/'; + buf[j++] = '/'; + buf[j++] = '?'; + buf[j++] = '/'; + } while (i < n) { x = p[i++] & 0xffff; if (!IsUcs2(x)) { @@ -110,27 +88,17 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf, w >>= 8; } while (w); } - if (freeme || (intptr_t)(buf + j) <= (intptr_t)(p + i)) { - rc = j; - } else { - SYSDEBUG("sys_readlinkat_nt() too many astral codepoints"); - rc = enametoolong(); - } + rc = j; } else { - SYSDEBUG("sys_readlinkat_nt() should have kNtIoReparseTagSymlink"); + NTTRACE("sys_readlinkat_nt() should have kNtIoReparseTagSymlink"); rc = einval(); } } else { - SYSDEBUG("DeviceIoControl(kNtFsctlGetReparsePoint) failed"); - rc = sys_readlinkat_nt_error(); + rc = -1; } CloseHandle(h); } else { - SYSDEBUG("CreateFile(kNtFileFlagOpenReparsePoint) failed"); - rc = sys_readlinkat_nt_error(); - } - if (freeme && weaken(free)) { - weaken(free)(freeme); + rc = __fix_enotdir(-1, path16); } return rc; } diff --git a/libc/calls/readlinkat.c b/libc/calls/readlinkat.c index 93e4dcf81..58da8789e 100644 --- a/libc/calls/readlinkat.c +++ b/libc/calls/readlinkat.c @@ -17,14 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/weaken.h" -#include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" -#include "libc/errno.h" #include "libc/intrin/asan.internal.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/at.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" @@ -33,35 +29,31 @@ * * This does *not* nul-terminate the buffer. * - * It is recommended that malloc() be linked into your program when - * using this function. Otherwise the buffer should be larger. It should - * also be noted that, without malloc, long names with many astral plane - * characters might not decode properly. - * * @param dirfd is normally AT_FDCWD but if it's an open directory and * file is a relative path, then file is opened relative to dirfd * @param path must be a symbolic link pathname * @param buf will receive symbolic link contents, and won't be modified * unless the function succeeds (with the exception of no-malloc nt) + * and this buffer will *not* be nul-terminated * @return number of bytes written to buf, or -1 w/ errno; if the * return is equal to bufsiz then truncation may have occurred * @error EINVAL if path isn't a symbolic link * @asyncsignalsafe */ ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) { + char sb[12]; ssize_t bytes; - struct ZiposUri zipname; if ((IsAsan() && !__asan_is_valid(buf, bufsiz)) || (bufsiz && !buf)) { bytes = efault(); - } else if (weaken(__zipos_notat) && __zipos_notat(dirfd, path) == -1) { - SYSDEBUG("TOOD: zipos support for readlinkat"); - bytes = enosys(); /* TODO(jart): code me */ + } else if (weaken(__zipos_notat) && + (bytes = __zipos_notat(dirfd, path)) == -1) { + STRACE("TOOD: zipos support for readlinkat"); } else if (!IsWindows()) { bytes = sys_readlinkat(dirfd, path, buf, bufsiz); } else { bytes = sys_readlinkat_nt(dirfd, path, buf, bufsiz); } - SYSDEBUG("readlinkat(%d, %s, 0x%p, 0x%x) -> %d %s", (long)dirfd, path, buf, - bufsiz, bytes, bytes != -1 ? "" : strerror(errno)); + STRACE("readlinkat(%s, %#s, [%#.*s]) → %d% m", __strace_dirfd(sb, dirfd), + path, MAX(0, bytes), buf, bytes); return bytes; } diff --git a/libc/calls/readv-nt.c b/libc/calls/readv-nt.c index 1cc9d56c8..a9b55edd5 100644 --- a/libc/calls/readv-nt.c +++ b/libc/calls/readv-nt.c @@ -28,7 +28,7 @@ textwindows ssize_t sys_readv_nt(struct Fd *fd, const struct iovec *iov, case kFdConsole: return sys_read_nt(fd, iov, iovlen, -1); case kFdSocket: - return weaken(sys_recvfrom_nt)(fd, iov, iovlen, 0, NULL, 0); + return weaken(sys_recv_nt)(fd, iov, iovlen, 0); default: return ebadf(); } diff --git a/libc/calls/readv-serial.c b/libc/calls/readv-serial.c index f60993f18..15fde98be 100644 --- a/libc/calls/readv-serial.c +++ b/libc/calls/readv-serial.c @@ -35,21 +35,14 @@ static int GetFirstIov(struct iovec *iov, int iovlen) { } ssize_t sys_readv_serial(struct Fd *fd, const struct iovec *iov, int iovlen) { - size_t i, j, got = 0; + size_t i; if ((i = GetFirstIov(iov, iovlen)) != -1) { - while (!IsDataAvailable(fd)) asm("pause"); - i = 0; - j = 0; - do { - ++got; - ((char *)iov[i].iov_base)[j] = inb(fd->handle); - if (++j == iov[i].iov_len) { - j = 0; - if (++i == iovlen) { - break; - } - } - } while (IsDataAvailable(fd)); + while (!IsDataAvailable(fd)) { + __builtin_ia32_pause(); + } + ((char *)iov[i].iov_base)[0] = inb(fd->handle); + return 1; + } else { + return 0; } - return got; } diff --git a/libc/calls/readv.c b/libc/calls/readv.c index 0d2087aa5..490f02c1c 100644 --- a/libc/calls/readv.c +++ b/libc/calls/readv.c @@ -19,8 +19,10 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/sock/internal.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" @@ -28,25 +30,51 @@ /** * Reads data to multiple buffers. * + * This is the same thing as read() except it has multiple buffers. + * This yields a performance boost in situations where it'd be expensive + * to stitch data together using memcpy() or issuing multiple syscalls. + * This wrapper is implemented so that readv() calls where iovlen<2 may + * be passed to the kernel as read() instead. This yields a 100 cycle + * performance boost in the case of a single small iovec. + * * @return number of bytes actually read, or -1 w/ errno - * @asyncsignalsafe + * @restartable */ ssize_t readv(int fd, const struct iovec *iov, int iovlen) { + int i; + ssize_t rc; if (fd >= 0 && iovlen >= 0) { - if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault(); - if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return weaken(__zipos_read)( + if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) { + rc = efault(); + } else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { + rc = weaken(__zipos_read)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1); } else if (!IsWindows() && !IsMetal()) { - return sys_readv(fd, iov, iovlen); + if (iovlen == 1) { + rc = sys_read(fd, iov[0].iov_base, iov[0].iov_len); + } else { + rc = sys_readv(fd, iov, iovlen); + } } else if (fd >= g_fds.n) { - return ebadf(); + rc = ebadf(); } else if (IsMetal()) { - return sys_readv_metal(g_fds.p + fd, iov, iovlen); + rc = sys_readv_metal(g_fds.p + fd, iov, iovlen); } else { - return sys_readv_nt(g_fds.p + fd, iov, iovlen); + rc = sys_readv_nt(g_fds.p + fd, iov, iovlen); } } else { - return einval(); + rc = einval(); } +#if defined(SYSDEBUG) && _DATATRACE + if (__strace > 0) { + if (rc == -1 && errno == EFAULT) { + STRACE("readv(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc); + } else { + kprintf(STRACE_PROLOGUE "readv(%d, [", fd); + __strace_iov(iov, iovlen, rc != -1 ? rc : 0); + kprintf("], %d) → %'ld% m\n", iovlen, rc); + } + } +#endif + return rc; } diff --git a/libc/calls/realpath.c b/libc/calls/realpath.c index fafa4dcdf..cb79c7142 100644 --- a/libc/calls/realpath.c +++ b/libc/calls/realpath.c @@ -25,13 +25,14 @@ │ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ │ │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/bits/bits.h" #include "libc/bits/safemacros.internal.h" #include "libc/bits/weaken.h" #include "libc/calls/calls.h" -#include "libc/calls/sysdebug.internal.h" #include "libc/errno.h" #include "libc/limits.h" +#include "libc/log/backtrace.internal.h" #include "libc/mem/mem.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" @@ -73,13 +74,14 @@ static char *ResolvePath(char *d, const char *s, size_t n) * symbolic link then it's resolved. * * @param resolved needs PATH_MAX bytes or NULL to use malloc() + * @return resolved or NULL w/ errno */ char *realpath(const char *filename, char *resolved) { - ssize_t k; - int up, check_dir=0; - size_t p, q, l, l0, cnt=0, nup=0; - char output[PATH_MAX], stack[PATH_MAX+1], *z; + ssize_t rc; + int e, up, check_dir=0; + size_t k, p, q, l, l0, cnt=0, nup=0; + char output[PATH_MAX], stack[PATH_MAX], *z; if (!filename) { einval(); @@ -160,15 +162,10 @@ restart: * directories, processing .. can skip readlink. */ if (!check_dir) goto skip_readlink; } - k = readlink(output, stack, p); - if (k<0) SYSDEBUG("realpath readlink failed %d", (long)errno); - if (k==p) goto toolong; - if (!k) { - errno = ENOENT; - return 0; - } - if (k<0) { + e = errno; + if ((rc = readlink(output, stack, p)) == -1) { if (errno != EINVAL) return 0; + errno = e; /* [jart] undirty errno if not a symlink */ skip_readlink: check_dir = 0; if (up) { @@ -180,6 +177,14 @@ skip_readlink: check_dir = stack[p]; continue; } + k = rc; + assert(k <= p); + if (k==p) + goto toolong; + if (!k) { + errno = ENOENT; + return 0; + } if (++cnt == SYMLOOP_MAX) { errno = ELOOP; return 0; diff --git a/libc/calls/remove.c b/libc/calls/remove.c index 4c0dce691..256adff3a 100644 --- a/libc/calls/remove.c +++ b/libc/calls/remove.c @@ -16,8 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/errno.h" #include "libc/calls/calls.h" +#include "libc/errno.h" /** * Deletes "file" or empty directory associtaed with name. diff --git a/libc/calls/rename.c b/libc/calls/rename.c index f01f42ebc..8537d0502 100644 --- a/libc/calls/rename.c +++ b/libc/calls/rename.c @@ -22,6 +22,12 @@ /** * Moves file the Unix way. * + * This is generally an atomic operation with the file system, since all + * it's doing is changing a name associated with an inode. However, that + * means rename() doesn't permit your `oldpathname` and `newpathname` to + * be on separate file systems, in which case this returns EXDEV. That's + * also the case on Windows. + * * @return 0 on success or -1 w/ errno * @asyncsignalsafe */ diff --git a/libc/calls/renameat-nt.c b/libc/calls/renameat-nt.c index 5f0940d83..949d05d84 100644 --- a/libc/calls/renameat-nt.c +++ b/libc/calls/renameat-nt.c @@ -19,12 +19,9 @@ #include "libc/calls/internal.h" #include "libc/nt/enum/movefileexflags.h" #include "libc/nt/files.h" -#include "libc/nt/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/errfuns.h" textwindows int sys_renameat_nt(int olddirfd, const char *oldpath, int newdirfd, - const char *newpath) { + const char *newpath) { char16_t oldpath16[PATH_MAX]; char16_t newpath16[PATH_MAX]; if (__mkntpathat(olddirfd, oldpath, 0, oldpath16) == -1 || @@ -34,6 +31,6 @@ textwindows int sys_renameat_nt(int olddirfd, const char *oldpath, int newdirfd, if (MoveFileEx(oldpath16, newpath16, kNtMovefileReplaceExisting)) { return 0; } else { - return __winerr(); + return __fix_enotdir3(-1, oldpath16, newpath16); } } diff --git a/libc/calls/renameat.c b/libc/calls/renameat.c index f98061d88..71bde23d6 100644 --- a/libc/calls/renameat.c +++ b/libc/calls/renameat.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/consts/at.h" @@ -28,6 +29,12 @@ /** * Renames files relative to directories. * + * This is generally an atomic operation with the file system, since all + * it's doing is changing a name associated with an inode. However, that + * means rename() doesn't permit your `oldpathname` and `newpathname` to + * be on separate file systems, in which case this returns EXDEV. That's + * also the case on Windows. + * * @param olddirfd is normally AT_FDCWD but if it's an open directory * and oldpath is relative, then oldpath become relative to dirfd * @param newdirfd is normally AT_FDCWD but if it's an open directory @@ -36,18 +43,21 @@ */ int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { + int rc; + char buf[2][12]; if (IsAsan() && (!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) { - return efault(); - } - if (weaken(__zipos_notat) && - (weaken(__zipos_notat)(olddirfd, oldpath) == -1 || - weaken(__zipos_notat)(newdirfd, newpath) == -1)) { - return -1; /* TODO(jart): implement me */ - } - if (!IsWindows()) { - return sys_renameat(olddirfd, oldpath, newdirfd, newpath); + rc = efault(); + } else if (weaken(__zipos_notat) && + ((rc = __zipos_notat(olddirfd, oldpath)) == -1 || + (rc = __zipos_notat(newdirfd, newpath)) == -1)) { + STRACE("zipos renameat not supported yet"); + } else if (!IsWindows()) { + rc = sys_renameat(olddirfd, oldpath, newdirfd, newpath); } else { - return sys_renameat_nt(olddirfd, oldpath, newdirfd, newpath); + rc = sys_renameat_nt(olddirfd, oldpath, newdirfd, newpath); } + STRACE("renameat(%s, %#s, %s, %#s) → %d% m", __strace_dirfd(buf[0], olddirfd), + oldpath, __strace_dirfd(buf[1], newdirfd), newpath, rc); + return rc; } diff --git a/libc/calls/reservefd.c b/libc/calls/reservefd.c index d6b5ba473..a68a56e7c 100644 --- a/libc/calls/reservefd.c +++ b/libc/calls/reservefd.c @@ -16,24 +16,98 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/assert.h" +#include "libc/bits/weaken.h" +#include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/spinlock.h" +#include "libc/macros.internal.h" #include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" #include "libc/sysv/errfuns.h" +/** + * Grows file descriptor array memory if needed. + */ +int __ensurefds(int fd) { + size_t n1, n2; + struct Fd *p1, *p2; + _spinlock(&__fds_lock); + n1 = g_fds.n; + if (fd >= n1) { + STRACE("__ensurefds(%d) extending", fd); + if (weaken(malloc)) { + // TODO(jart): we need a semaphore for this + p1 = g_fds.p; + n2 = fd + (fd >> 1); + if ((p2 = weaken(malloc)(n2 * sizeof(*p1)))) { + memcpy(p2, p1, n1 * sizeof(*p1)); + g_fds.p = p2; + g_fds.n = n2; + if (p1 != g_fds.__init_p) { + weaken(free)(p1); + } + } else { + fd = enomem(); + } + } else { + fd = emfile(); + } + } + _spunlock(&__fds_lock); + return fd; +} + /** * Finds open file descriptor slot. */ -int __reservefd(void) { +int __reservefd(int start) { int fd; for (;;) { - fd = g_fds.f; - if (fd >= g_fds.n) { - if (__ensurefds(fd) == -1) return -1; - } - cmpxchg(&g_fds.f, fd, fd + 1); - if (cmpxchg(&g_fds.p[fd].kind, kFdEmpty, kFdReserved)) { + _spinlock(&__fds_lock); + fd = start < 0 ? g_fds.f : start; + while (fd < g_fds.n && g_fds.p[fd].kind) ++fd; + if (fd < g_fds.n) { + g_fds.f = fd + 1; + bzero(g_fds.p + fd, sizeof(*g_fds.p)); + g_fds.p[fd].kind = kFdReserved; + _spunlock(&__fds_lock); return fd; + } else { + _spunlock(&__fds_lock); + if (__ensurefds(fd) == -1) { + return -1; + } } } } + +/** + * Closes non-stdio file descriptors to free dynamic memory. + */ +static void FreeFds(void) { + int i; + NTTRACE("FreeFds()"); + for (i = 3; i < g_fds.n; ++i) { + if (g_fds.p[i].kind) { + close(i); + } + } + if (g_fds.p != g_fds.__init_p) { + memcpy(g_fds.__init_p, g_fds.p, sizeof(*g_fds.p) * 3); + weaken(free)(g_fds.p); + g_fds.p = g_fds.__init_p; + g_fds.n = ARRAYLEN(g_fds.__init_p); + } +} + +static textstartup void FreeFdsInit(void) { + atexit(FreeFds); +} + +const void *const FreeFdsCtor[] initarray = { + FreeFdsInit, +}; diff --git a/libc/calls/samplepids.c b/libc/calls/samplepids.c new file mode 100644 index 000000000..a14712ebb --- /dev/null +++ b/libc/calls/samplepids.c @@ -0,0 +1,50 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/rand/lcg.internal.h" + +/** + * Returns handles of windows pids being tracked. + * + * We return 64 at most because Windows can't await on a larger number + * of things at the same time. If we have a lot of subprocesses, then we + * choose a subgroup to monitor at random. + * + * @return number of items returned in pids and handles + */ +textwindows int __sample_pids(int pids[hasatleast 64], + int64_t handles[hasatleast 64], + bool exploratory) { + static uint64_t rando = 1; + uint32_t i, j, base, count; + base = KnuthLinearCongruentialGenerator(&rando) >> 32; + for (count = i = 0; i < g_fds.n; ++i) { + j = (base + i) % g_fds.n; + if (g_fds.p[j].kind == kFdProcess && (!exploratory || !g_fds.p[j].zombie)) { + pids[count] = j; + handles[count] = g_fds.p[j].handle; + if (++count == 64) { + break; + } + } + } + return count; +} diff --git a/libc/calls/sched_setaffinity.c b/libc/calls/sched_setaffinity.c index 508d61748..f1c8df0cd 100644 --- a/libc/calls/sched_setaffinity.c +++ b/libc/calls/sched_setaffinity.c @@ -29,8 +29,8 @@ #include "libc/str/str.h" static textwindows dontinline int sys_sched_setaffinity_nt(int pid, - uint64_t bitsetsize, - const void *bitset) { + uint64_t bitsetsize, + const void *bitset) { int rc; uintptr_t mask; int64_t handle; diff --git a/libc/calls/sched_yield-nt.c b/libc/calls/sched_yield-nt.c index 47a9fec3d..fc6fbb0fb 100644 --- a/libc/calls/sched_yield-nt.c +++ b/libc/calls/sched_yield-nt.c @@ -19,11 +19,16 @@ #include "libc/calls/internal.h" #include "libc/nt/enum/status.h" #include "libc/nt/ntdll.h" +#include "libc/nt/synchronization.h" textwindows int sys_sched_yield_nt(void) { - size_t i; - if (NtYieldExecution() == kNtStatusDllNotFound) { - for (i = 0; i < 16; ++i) asm("pause"); - } + // A value of zero, together with the bAlertable parameter set to + // FALSE, causes the thread to relinquish the remainder of its time + // slice to any other thread that is ready to run, if there are no + // pending user APCs on the calling thread. If there are no other + // threads ready to run and no user APCs are queued, the function + // returns immediately, and the thread continues execution. + // ──Quoth MSDN + SleepEx(0, false); return 0; } diff --git a/libc/calls/sched_yield.c b/libc/calls/sched_yield.c index c268fa279..04b744961 100644 --- a/libc/calls/sched_yield.c +++ b/libc/calls/sched_yield.c @@ -16,14 +16,15 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" -#include "libc/calls/internal.h" #include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" /** * Asks kernel to deschedule thread momentarily. */ int sched_yield(void) { + /* TODO(jart): Add get_sched_yield() so we can STRACE() */ if (!IsWindows()) { return sys_sched_yield(); } else { diff --git a/libc/calls/seccomp.c b/libc/calls/seccomp.c new file mode 100644 index 000000000..9f0e3c0a1 --- /dev/null +++ b/libc/calls/seccomp.c @@ -0,0 +1,83 @@ +/*-*- 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 2022 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/strace.internal.h" +#include "libc/calls/struct/seccomp.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/sysv/consts/pr.h" +#include "libc/sysv/errfuns.h" + +static const char *DescribeSeccompOperation(int x) { + switch (x) { + case SECCOMP_SET_MODE_STRICT: + return "SECCOMP_SET_MODE_STRICT"; + case SECCOMP_SET_MODE_FILTER: + return "SECCOMP_SET_MODE_FILTER"; + case SECCOMP_GET_ACTION_AVAIL: + return "SECCOMP_GET_ACTION_AVAIL"; + case SECCOMP_GET_NOTIF_SIZES: + return "SECCOMP_GET_NOTIF_SIZES"; + default: + return "SECCOMP_???"; + } +} + +/** + * Tunes Linux security policy. + * + * This system call was first introduced in Linux 3.17. We polyfill + * automatically features like SECCOMP_SET_MODE_STRICT, for kernels + * dating back to 2.6.23, whenever possible. + * + * @raise ENOSYS on non-Linux. + */ +int seccomp(unsigned operation, unsigned flags, void *args) { + int rc; + if (IsLinux()) { + asm volatile("syscall" + : "=a"(rc) + : "0"(317), "D"(operation), "S"(flags), "d"(args) + : "rcx", "r11", "memory"); + if (rc == -ENOSYS) { + if (operation == SECCOMP_SET_MODE_STRICT) { + asm volatile("syscall" + : "=a"(rc) + : "0"(157), "D"(PR_SET_SECCOMP), "S"(SECCOMP_MODE_STRICT) + : "rcx", "r11", "memory"); + } else if (operation == SECCOMP_SET_MODE_FILTER && !flags) { + asm volatile("syscall" + : "=a"(rc) + : "0"(157), "D"(PR_SET_SECCOMP), "S"(SECCOMP_MODE_FILTER), + "d"(args) + : "rcx", "r11", "memory"); + } + } + if (rc > -4096u) { + errno = -rc; + rc = -1; + } + } else { + rc = enosys(); + } + STRACE("seccomp(%s, %#x, %p) → %d% m", DescribeSeccompOperation(operation), + flags, args, rc); + return rc; +} diff --git a/libc/calls/sedebug.c b/libc/calls/sedebug.c new file mode 100644 index 000000000..c3988b70b --- /dev/null +++ b/libc/calls/sedebug.c @@ -0,0 +1,92 @@ +/*-*- 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 2022 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/strace.internal.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/securityimpersonationlevel.h" +#include "libc/nt/errors.h" +#include "libc/nt/files.h" +#include "libc/nt/privilege.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/luid.h" +#include "libc/nt/struct/tokenprivileges.h" + +static bool32 SetPrivilegeNt(int64_t hToken, const char16_t *lpwPrivilege, + bool32 bEnable) { + struct NtLuid luid; + uint32_t cbPrevious; + struct NtTokenPrivileges tp, tpPrevious; + cbPrevious = sizeof(struct NtTokenPrivileges); + if (!LookupPrivilegeValue(0, lpwPrivilege, &luid)) { + STRACE("LookupPrivilegeValue() failed"); + return false; + } + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = 0; + if (!AdjustTokenPrivileges(hToken, false, &tp, sizeof(tp), &tpPrevious, + &cbPrevious)) { + STRACE("AdjustTokenPrivileges() failed"); + return false; + } + tpPrevious.PrivilegeCount = 1; + tpPrevious.Privileges[0].Luid = luid; + if (bEnable) { + tpPrevious.Privileges[0].Attributes |= kNtSePrivilegeEnabled; + } else { + tpPrevious.Privileges[0].Attributes ^= + kNtSePrivilegeEnabled & tpPrevious.Privileges[0].Attributes; + } + if (!AdjustTokenPrivileges(hToken, false, &tpPrevious, cbPrevious, 0, 0)) { + STRACE("AdjustTokenPrivileges() failed"); + return false; + } + return true; +} + +static int64_t GetCurrentProcessSecurityToken(void) { + int64_t hToken; + if (OpenProcessToken(GetCurrentProcess(), + kNtTokenAdjustPrivileges | kNtTokenQuery, &hToken)) { + return hToken; + } else if (GetLastError() == kNtErrorNoToken) { + if (ImpersonateSelf(kNtSecurityImpersonation)) { + if (OpenProcessToken(GetCurrentProcess(), + kNtTokenAdjustPrivileges | kNtTokenQuery, &hToken)) { + return hToken; + } else { + STRACE("OpenProcessToken() failed"); + } + } else { + STRACE("ImpersonateSelf() failed"); + } + } else { + STRACE("OpenProcessToken() failed"); + } + return 0; +} + +bool32 ElevateSeDebugPrivilege(void) { + int64_t hToken; + if (!(hToken = GetCurrentProcessSecurityToken())) return false; + SetPrivilegeNt(hToken, u"SeDebugPrivilege", true); + RevertToSelf(); + CloseHandle(hToken); + return true; +} diff --git a/libc/calls/setegid.c b/libc/calls/setegid.c index 55113a93d..6a5c89087 100644 --- a/libc/calls/setegid.c +++ b/libc/calls/setegid.c @@ -17,10 +17,11 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" /** * Sets effective group ID. */ -int setegid(unsigned gid) { - return setregid(-1, gid); +int setegid(uint32_t egid) { + return setregid(-1, egid); } diff --git a/libc/calls/seteuid.c b/libc/calls/seteuid.c index b89b8f3c7..2361627e1 100644 --- a/libc/calls/seteuid.c +++ b/libc/calls/seteuid.c @@ -17,10 +17,11 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" /** * Sets effective user ID. */ -int seteuid(unsigned euid) { - return setreuid(-1, euid); +int seteuid(uint32_t euid) { + return setregid(euid, -1); } diff --git a/libc/calls/setgid.c b/libc/calls/setgid.c new file mode 100644 index 000000000..93431f3a4 --- /dev/null +++ b/libc/calls/setgid.c @@ -0,0 +1,36 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" + +/** + * Sets group id of current process. + * @return 0 on success or -1 w/ errno + */ +int setgid(int gid) { + int rc; + if (IsWindows() && gid == getgid()) { + rc = 0; + } else { + rc = sys_setgid(gid); + } + STRACE("setgid(%d) → %d% m", gid, rc); + return rc; +} diff --git a/libc/calls/setitimer-nt.c b/libc/calls/setitimer-nt.c index d6d296a70..52272b2e2 100644 --- a/libc/calls/setitimer-nt.c +++ b/libc/calls/setitimer-nt.c @@ -16,20 +16,31 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/itimerval.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/log/check.h" +#include "libc/math.h" #include "libc/nexgen32e/nexgen32e.h" +#include "libc/nexgen32e/nt2sysv.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" #include "libc/nt/synchronization.h" #include "libc/nt/thread.h" #include "libc/str/str.h" #include "libc/sysv/consts/itimer.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" +#include "libc/time/time.h" /** * @fileoverview Heartbreaking polyfill for SIGALRM on NT. @@ -45,59 +56,68 @@ * interrupting i/o operations on the standard input handle. */ -static struct ItimerNt { - int64_t ith; - uint32_t tid; - struct itimerval itv; -} g_itimernt; +static bool __hastimer; +static bool __singleshot; +static long double __lastalrm; +static long double __interval; -static uint32_t ItimerWorker(void *arg) { - do { - if (!WaitForSingleObject(g_itimernt.ith, -1)) { - __winalarm(NULL, 0, 0); +textwindows void _check_sigalrm(void) { + // TODO(jart): use a different timing source + // TODO(jart): synchronize across intervals? + long double now, elapsed; + if (!__hastimer) return; + now = nowl(); + elapsed = now - __lastalrm; + if (elapsed > __interval) { + __sig_add(SIGALRM, SI_TIMER); + if (__singleshot) { + __hastimer = false; + } else { + __lastalrm = now; } - } while (g_itimernt.ith && g_itimernt.tid == GetCurrentThreadId()); - return 0; + } } textwindows int sys_setitimer_nt(int which, const struct itimerval *newvalue, struct itimerval *out_opt_oldvalue) { - int32_t period; - int64_t ith, duetime; + long double elapsed, untilnext; if (which != ITIMER_REAL) return einval(); - if (newvalue) { - if (newvalue->it_value.tv_sec && newvalue->it_value.tv_usec) { - if (!(ith = CreateWaitableTimer(NULL, false, NULL))) { - return __winerr(); - } - duetime = -(newvalue->it_value.tv_sec * HECTONANOSECONDS + - newvalue->it_value.tv_usec * 10); - period = newvalue->it_value.tv_sec * 1000 + - div1000int64(newvalue->it_value.tv_usec); - if (!period && newvalue->it_value.tv_usec) period = 1; - if (!SetWaitableTimer(ith, &duetime, period, NULL, NULL, false)) { - errno = GetLastError(); - CloseHandle(ith); - return -1; - } - } else { - ith = 0; - } - if (g_itimernt.ith) { - CloseHandle(g_itimernt.ith); - g_itimernt.ith = 0; - } - } else { - ith = 0; - } if (out_opt_oldvalue) { - memcpy(out_opt_oldvalue, &g_itimernt.itv, sizeof(struct itimerval)); + if (__hastimer) { + elapsed = nowl() - __lastalrm; + if (elapsed > __interval) { + untilnext = 0; + } else { + untilnext = __interval - elapsed; + } + out_opt_oldvalue->it_interval.tv_sec = __interval; + out_opt_oldvalue->it_interval.tv_usec = 1 / 1e6 * fmodl(__interval, 1); + out_opt_oldvalue->it_value.tv_sec = untilnext; + out_opt_oldvalue->it_value.tv_usec = 1 / 1e6 * fmodl(untilnext, 1); + } else { + out_opt_oldvalue->it_interval.tv_sec = 0; + out_opt_oldvalue->it_interval.tv_usec = 0; + out_opt_oldvalue->it_value.tv_sec = 0; + out_opt_oldvalue->it_value.tv_usec = 0; + } } - if (ith) { - g_itimernt.ith = ith; - memcpy(&g_itimernt.itv, newvalue, sizeof(struct itimerval)); - CloseHandle( - CreateThread(NULL, STACKSIZE, ItimerWorker, NULL, 0, &g_itimernt.tid)); + if (newvalue) { + if (newvalue->it_interval.tv_sec || newvalue->it_interval.tv_usec || + newvalue->it_value.tv_sec || newvalue->it_value.tv_usec) { + __hastimer = true; + if (newvalue->it_interval.tv_sec || newvalue->it_interval.tv_usec) { + __singleshot = false; + __interval = newvalue->it_interval.tv_sec + + 1 / 1e6 * newvalue->it_interval.tv_usec; + } else { + __singleshot = true; + __interval = + newvalue->it_value.tv_sec + 1 / 1e6 * newvalue->it_value.tv_usec; + } + __lastalrm = nowl(); + } else { + __hastimer = false; + } } return 0; } diff --git a/libc/calls/setitimer.c b/libc/calls/setitimer.c index 479eed671..aa9f72aec 100644 --- a/libc/calls/setitimer.c +++ b/libc/calls/setitimer.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/itimerval.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" @@ -64,18 +65,41 @@ */ int setitimer(int which, const struct itimerval *newvalue, struct itimerval *oldvalue) { + int rc; + if (IsAsan() && ((newvalue && !__asan_is_valid(newvalue, sizeof(*newvalue))) || (oldvalue && !__asan_is_valid(oldvalue, sizeof(*oldvalue))))) { - return efault(); - } - if (!IsWindows()) { + rc = efault(); + } else if (!IsWindows()) { if (newvalue) { - return sys_setitimer(which, newvalue, oldvalue); + rc = sys_setitimer(which, newvalue, oldvalue); } else { - return sys_getitimer(which, oldvalue); + rc = sys_getitimer(which, oldvalue); } } else { - return sys_setitimer_nt(which, newvalue, oldvalue); + rc = sys_setitimer_nt(which, newvalue, oldvalue); } + + if (newvalue && oldvalue) { + STRACE("setitimer(%d, " + "{{%'ld, %'ld}, {%'ld, %'ld}}, " + "[{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m", + which, newvalue->it_interval.tv_sec, newvalue->it_interval.tv_usec, + newvalue->it_value.tv_sec, newvalue->it_value.tv_usec, + oldvalue->it_interval.tv_sec, oldvalue->it_interval.tv_usec, + oldvalue->it_value.tv_sec, oldvalue->it_value.tv_usec, rc); + } else if (newvalue) { + STRACE("setitimer(%d, {{%'ld, %'ld}, {%'ld, %'ld}}, NULL) → %d% m", which, + newvalue->it_interval.tv_sec, newvalue->it_interval.tv_usec, + newvalue->it_value.tv_sec, newvalue->it_value.tv_usec, rc); + } else if (oldvalue) { + STRACE("setitimer(%d, NULL, [{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m", which, + oldvalue->it_interval.tv_sec, oldvalue->it_interval.tv_usec, + oldvalue->it_value.tv_sec, oldvalue->it_value.tv_usec, rc); + } else { + STRACE("setitimer(%d, NULL, NULL) → %d% m", which, rc); + } + + return rc; } diff --git a/libc/calls/setpgid.c b/libc/calls/setpgid.c new file mode 100644 index 000000000..36a2aad4c --- /dev/null +++ b/libc/calls/setpgid.c @@ -0,0 +1,59 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/nt/console.h" +#include "libc/sysv/errfuns.h" + +/** + * Changes process group for process. + * @vforksafe + */ +int setpgid(int pid, int pgid) { + int rc, me; + if (!IsWindows()) { + rc = sys_setpgid(pid, pgid); + } else { + me = getpid(); + if (pid == me && pgid == me) { + /* + * "When a process is created with CREATE_NEW_PROCESS_GROUP + * specified, an implicit call to SetConsoleCtrlHandler(NULL,TRUE) + * is made on behalf of the new process; this means that the new + * process has CTRL+C disabled. This lets shells handle CTRL+C + * themselves, and selectively pass that signal on to + * sub-processes. CTRL+BREAK is not disabled, and may be used to + * interrupt the process/process group." + * ──Quoth MSDN § CreateProcessW() + */ + if (SetConsoleCtrlHandler(0, 1)) { + rc = 0; + } else { + rc = __winerr(); + } + } else { + // irregular use cases not supported on windows + rc = einval(); + } + } + STRACE("setpgid(%d, %d) → %d% m", pid, pgid, rc); + return rc; +} diff --git a/libc/calls/setpgrp.c b/libc/calls/setpgrp.c new file mode 100644 index 000000000..e7c549f27 --- /dev/null +++ b/libc/calls/setpgrp.c @@ -0,0 +1,26 @@ +/*-*- 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 2022 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" + +/** + * Sets the process group ID. + */ +int setpgrp(void) { + return setpgid(0, 0); +} diff --git a/libc/calls/setregid.c b/libc/calls/setregid.c new file mode 100644 index 000000000..e2ee4dc94 --- /dev/null +++ b/libc/calls/setregid.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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" + +/** + * Sets real and/or effective group ids. + * + * @param rgid is real group id or -1 to leave it unchanged + * @param egid is effective group id or -1 to leave it unchanged + * @return 0 on success or -1 w/ errno + */ +int setregid(uint32_t rgid, uint32_t egid) { + int rc; + rc = sys_setregid(rgid, egid); + STRACE("setregid(%d, %d) → %d% m", rgid, egid, rc); + return rc; +} diff --git a/libc/calls/setresgid.c b/libc/calls/setresgid.c index b1af4e79d..846df7a93 100644 --- a/libc/calls/setresgid.c +++ b/libc/calls/setresgid.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" /** * Sets real, effective, and "saved" group ids. @@ -25,9 +26,17 @@ * @param real sets real group id or -1 to do nothing * @param effective sets effective group id or -1 to do nothing * @param saved sets saved group id or -1 to do nothing - * @see setregid(), getauxval(AT_SECURE) + * @see setresuid(), getauxval(AT_SECURE) + * @raise ENOSYS on Windows NT */ int setresgid(uint32_t real, uint32_t effective, uint32_t saved) { - if (saved == -1) return setregid(real, effective); - return sys_setresgid(real, effective, saved); + int rc; + if (saved != -1) { + rc = sys_setresgid(real, effective, saved); + } else { + // polyfill xnu and netbsd + rc = sys_setregid(real, effective); + } + STRACE("setresgid(%d, %d, %d) → %d% m", real, effective, saved, rc); + return rc; } diff --git a/libc/calls/setresuid.c b/libc/calls/setresuid.c index c4bc134de..a585dc91c 100644 --- a/libc/calls/setresuid.c +++ b/libc/calls/setresuid.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" /** * Sets real, effective, and "saved" user ids. @@ -25,9 +26,17 @@ * @param real sets real user id or -1 to do nothing * @param effective sets effective user id or -1 to do nothing * @param saved sets saved user id or -1 to do nothing - * @see setreuid(), getauxval(AT_SECURE) + * @see setresgid(), getauxval(AT_SECURE) + * @raise ENOSYS on Windows NT */ int setresuid(uint32_t real, uint32_t effective, uint32_t saved) { - if (saved == -1) return setreuid(real, effective); - return sys_setresuid(real, effective, saved); + int rc; + if (saved != -1) { + rc = sys_setresuid(real, effective, saved); + } else { + // polyfill xnu and netbsd + rc = sys_setreuid(real, effective); + } + STRACE("setresuid(%d, %d, %d) → %d% m", real, effective, saved, rc); + return rc; } diff --git a/libc/calls/setreuid.c b/libc/calls/setreuid.c new file mode 100644 index 000000000..e3ff17143 --- /dev/null +++ b/libc/calls/setreuid.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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" + +/** + * Sets real and/or effective user ids. + * + * @param ruid is real user id or -1 to leave it unchanged + * @param euid is effective user id or -1 to leave it unchanged + * @return 0 on success or -1 w/ errno + */ +int setreuid(uint32_t ruid, uint32_t euid) { + int rc; + rc = sys_setreuid(ruid, euid); + STRACE("setreuid(%d, %d) → %d% m", ruid, euid, rc); + return rc; +} diff --git a/libc/calls/setrlimit.c b/libc/calls/setrlimit.c index 332efffcc..5ef298940 100644 --- a/libc/calls/setrlimit.c +++ b/libc/calls/setrlimit.c @@ -16,23 +16,73 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/sysv/consts/rlimit.h" #include "libc/sysv/errfuns.h" /** * Sets resource limit for current process. * - * @param resource can be RLIMIT_{CPU,FSIZE,DATA,STACK,CORE,RSS,etc.} + * The following resources are recommended: + * + * - `RLIMIT_AS` limits the size of the virtual address space. This will + * work on all platforms. It's emulated on XNU and Windows which means + * it won't propagate across execve() currently. + * + * - `RLIMIT_CPU` causes `SIGXCPU` to be sent to the process when the + * soft limit on CPU time is exceeded, and the process is destroyed + * when the hard limit is exceeded. It works everywhere but Windows + * where it should be possible to poll getrusage() with setitimer() + * + * - `RLIMIT_FSIZE` causes `SIGXFSZ` to sent to the process when the + * soft limit on file size is exceeded and the process is destroyed + * when the hard limit is exceeded. It works everywhere but Windows + * + * - `RLIMIT_NPROC` limits the number of simultaneous processes and it + * should work on all platforms except Windows. Please be advised it + * limits the process, with respect to the activities of the user id + * as a whole. + * + * - `RLIMIT_NOFILE` limits the number of open file descriptors and it + * should work on all platforms except Windows (TODO) + * + * The rlimit magnums differ for each platform but occupy the interval + * zero through `RLIM_NLIMITS`. Usually they're set to `RLIM_INFINITY` + * which is `-1` on Linux/Windows, and `LONG_MAX` on BSDs. In any case + * they're both very large numbers under the Cosmopolitan unsigned ABI + * because struct rlimit uses uint64_t. The special magnum 127 is used + * for constant values that aren't supported by the host platform. + * * @param rlim specifies new resource limit * @return 0 on success or -1 w/ errno * @see libc/sysv/consts.sh * @vforksafe */ int setrlimit(int resource, const struct rlimit *rlim) { - if (resource == 127) return einval(); - if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) return efault(); - return sys_setrlimit(resource, rlim); + int rc; + char buf[64]; + if (resource == 127) { + rc = einval(); + } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_setrlimit(resource, rlim); + if (IsXnu() && !rc && resource == RLIMIT_AS) { + // TODO(jart): What's up with XNU and NetBSD? + __virtualmax = rlim->rlim_cur; + } + } else if (resource == RLIMIT_AS) { + __virtualmax = rlim->rlim_cur; + rc = 0; + } else { + rc = einval(); + } + STRACE("setrlimit(%s, %s) → %d% m", __strace_rlimit_name(resource), + __strace_rlimit(buf, sizeof(buf), 0, rlim), rc); + return rc; } diff --git a/libc/calls/setsid.c b/libc/calls/setsid.c index e4cde3710..adcfff21b 100644 --- a/libc/calls/setsid.c +++ b/libc/calls/setsid.c @@ -18,10 +18,15 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" /** * Creates session and sets the process group id. + * @return new session id, or -1 w/ errno */ int setsid(void) { - return sys_setsid(); + int rc; + rc = sys_setsid(); + STRACE("setsid() → %d% m", rc); + return rc; } diff --git a/libc/calls/setuid.c b/libc/calls/setuid.c new file mode 100644 index 000000000..f46735559 --- /dev/null +++ b/libc/calls/setuid.c @@ -0,0 +1,36 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" + +/** + * Sets user id of current process. + * @return 0 on success or -1 w/ errno + */ +int setuid(int uid) { + int rc; + if (IsWindows() && uid == getuid()) { + rc = 0; + } else { + rc = sys_setuid(uid); + } + STRACE("setuid(%d) → %d% m", uid, rc); + return rc; +} diff --git a/libc/calls/sig.c b/libc/calls/sig.c new file mode 100644 index 000000000..5412f0bf5 --- /dev/null +++ b/libc/calls/sig.c @@ -0,0 +1,62 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/intrin/spinlock.h" +#include "libc/macros.internal.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" + +/** + * @fileoverview UNIX signals for the New Technology, Part 1. + * @threadsafe + */ + +struct Signals __sig; // TODO(jart): Need TLS + +/** + * Changes signal mask for main thread. + * @return 0 on success, or -1 w/ errno + */ +textwindows int __sig_mask(int how, const sigset_t *neu, sigset_t *old) { + int i; + uint64_t a, b; + if (how == SIG_BLOCK || how == SIG_UNBLOCK || how == SIG_SETMASK) { + _spinlock(&__sig_lock); + if (old) { + *old = __sig.mask; + } + if (neu) { + for (i = 0; i < ARRAYLEN(__sig.mask.__bits); ++i) { + if (how == SIG_BLOCK) { + __sig.mask.__bits[i] |= neu->__bits[i]; + } else if (how == SIG_UNBLOCK) { + __sig.mask.__bits[i] &= ~neu->__bits[i]; + } else { + __sig.mask.__bits[i] = neu->__bits[i]; + } + } + __sig.mask.__bits[0] &= ~(SIGKILL | SIGSTOP); + } + _spunlock(&__sig_lock); + return 0; + } else { + return einval(); + } +} diff --git a/libc/calls/sig.internal.h b/libc/calls/sig.internal.h new file mode 100644 index 000000000..2f58b1d6f --- /dev/null +++ b/libc/calls/sig.internal.h @@ -0,0 +1,37 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_ +#include "libc/calls/struct/sigset.h" +#include "libc/calls/ucontext.h" + +#define __SIG_QUEUE_LENGTH 8 +#define __SIG_POLLING_INTERVAL_MS 50 +#define __SIG_LOGGING_INTERVAL_MS 1700 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct Signal { + struct Signal *next; + bool used; + int sig; + int si_code; +}; + +struct Signals { + sigset_t mask; + struct Signal *queue; + struct Signal mem[__SIG_QUEUE_LENGTH]; +}; + +extern struct Signals __sig; // TODO(jart): Need TLS +extern long __sig_count; + +bool __sig_check(bool) hidden; +bool __sig_handle(bool, int, int, ucontext_t *) hidden; +int __sig_add(int, int) hidden; +int __sig_mask(int, const sigset_t *, sigset_t *) hidden; +int __sig_raise(int, int) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_ */ diff --git a/libc/calls/sig2.c b/libc/calls/sig2.c new file mode 100644 index 000000000..45626eff3 --- /dev/null +++ b/libc/calls/sig2.c @@ -0,0 +1,260 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/cmpxchg.h" +#include "libc/intrin/spinlock.h" +#include "libc/macros.internal.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/errfuns.h" + +/** + * @fileoverview UNIX signals for the New Technology, Part 2. + * @threadsafe + */ + +/** + * Allocates piece of memory for storing pending signal. + * @assume lock is held + */ +static textwindows struct Signal *__sig_alloc(void) { + int i; + struct Signal *res = 0; + for (i = 0; i < ARRAYLEN(__sig.mem); ++i) { + if (!__sig.mem[i].used) { + __sig.mem[i].used = true; + res = __sig.mem + i; + break; + } + } + return res; +} + +/** + * Returns signal memory to static pool. + */ +static textwindows void __sig_free(struct Signal *mem) { + mem->used = false; +} + +/** + * Dequeues signal that isn't masked. + * @return signal or null if empty or none unmasked + */ +static textwindows struct Signal *__sig_remove(void) { + struct Signal *prev, *res; + if (__sig.queue) { + _spinlock(&__sig_lock); + for (prev = 0, res = __sig.queue; res; prev = res, res = res->next) { + if (!sigismember(&__sig.mask, res->sig)) { + if (res == __sig.queue) { + __sig.queue = res->next; + } else if (prev) { + prev->next = res->next; + } + res->next = 0; + break; + } else { + STRACE("%G is masked", res->sig); + } + } + _spunlock(&__sig_lock); + } else { + res = 0; + } + return res; +} + +/** + * Delivers signal to callback. + * @note called from main thread + * @return true if EINTR should be returned by caller + */ +static textwindows bool __sig_deliver(bool restartable, int sig, int si_code, + ucontext_t *ctx) { + unsigned rva, flags; + siginfo_t info, *infop; + STRACE("delivering %G", sig); + + // enter the signal + _spinlock(&__sig_lock); + rva = __sighandrvas[sig]; + flags = __sighandflags[sig]; + if ((~flags & SA_NODEFER) || (flags & SA_RESETHAND)) { + // by default we try to avoid reentering a signal handler. for + // example, if a sigsegv handler segfaults, then we'd want the + // second signal to just kill the process. doing this means we + // track state. that's bad if you want to longjmp() out of the + // signal handler. in that case you must use SA_NODEFER. + __sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL; + } + _spunlock(&__sig_lock); + + // setup the somewhat expensive information args + // only if they're requested by the user in sigaction() + if (flags & SA_SIGINFO) { + bzero(&info, sizeof(info)); + info.si_signo = sig; + info.si_code = si_code; + infop = &info; + } else { + infop = 0; + ctx = 0; + } + + // handover control to user + ((sigaction_f)(_base + rva))(sig, infop, ctx); + + if ((~flags & SA_NODEFER) && (~flags & SA_RESETHAND)) { + // it's now safe to reenter the signal so we need to restore it. + // since sigaction() is @asyncsignalsafe we only restore it if the + // user didn't change it during the signal handler. we also don't + // need to do anything if this was a oneshot signal or nodefer. + _spinlock(&__sig_lock); + _cmpxchg(__sighandrvas + sig, (int32_t)(intptr_t)SIG_DFL, rva); + _spunlock(&__sig_lock); + } + + if (!restartable) { + return true; // always send EINTR for wait4(), poll(), etc. + } else if (flags & SA_RESTART) { + STRACE("restarting syscall on %G", sig); + return false; // resume syscall for read(), write(), etc. + } else { + return true; // default course is to raise EINTR + } +} + +/** + * Returns true if signal default action is to end process. + */ +static textwindows bool __sig_isfatal(int sig) { + if (sig == SIGCHLD || sig == SIGURG || sig == SIGWINCH) { + return false; + } else { + return true; + } +} + +/** + * Handles signal. + * + * @param restartable can be used to suppress true return if SA_RESTART + * @return true if signal was delivered + */ +textwindows bool __sig_handle(bool restartable, int sig, int si_code, + ucontext_t *ctx) { + bool delivered; + switch (__sighandrvas[sig]) { + case (intptr_t)SIG_DFL: + if (__sig_isfatal(sig)) { + STRACE("terminating on %G", sig); + __restorewintty(); + _Exit(128 + sig); + } + // fallthrough + case (intptr_t)SIG_IGN: + STRACE("ignoring %G", sig); + delivered = false; + break; + default: + delivered = __sig_deliver(restartable, sig, si_code, ctx); + break; + } + return delivered; +} + +/** + * Handles signal immediately if not blocked. + * + * @param restartable is for functions like read() but not poll() + * @return true if EINTR should be returned by caller + * @return 1 if delivered, 0 if enqueued, otherwise -1 w/ errno + * @note called from main thread + * @threadsafe + */ +textwindows int __sig_raise(int sig, int si_code) { + int rc; + int candeliver; + _spinlock(&__sig_lock); + candeliver = !sigismember(&__sig.mask, sig); + _spunlock(&__sig_lock); + switch (candeliver) { + case 1: + __sig_handle(false, sig, si_code, 0); + return 0; + case 0: + STRACE("%G is masked", sig); + return __sig_add(sig, si_code); + default: + return -1; // sigismember() validates `sig` + } +} + +/** + * Enqueues generic signal for delivery on New Technology. + * @return 0 if enqueued, otherwise -1 w/ errno + * @threadsafe + */ +textwindows int __sig_add(int sig, int si_code) { + int rc; + struct Signal *mem; + if (1 <= sig && sig <= NSIG) { + STRACE("enqueuing %G", sig); + _spinlock(&__sig_lock); + ++__sig_count; + if ((mem = __sig_alloc())) { + mem->sig = sig; + mem->si_code = si_code; + mem->next = __sig.queue; + __sig.queue = mem; + rc = 0; + } else { + rc = enomem(); + } + _spunlock(&__sig_lock); + } else { + rc = einval(); + } + return rc; +} + +/** + * Enqueues generic signal for delivery on New Technology. + * + * @param restartable is for functions like read() but not poll() + * @return true if EINTR should be returned by caller + * @note called from main thread + * @threadsafe + */ +textwindows bool __sig_check(bool restartable) { + unsigned rva; + bool delivered; + struct Signal *sig; + delivered = false; + while ((sig = __sig_remove())) { + delivered |= __sig_handle(restartable, sig->sig, sig->si_code, 0); + __sig_free(sig); + } + return delivered; +} diff --git a/libc/calls/sigaction.c b/libc/calls/sigaction.c index a8dd0cd49..17ac1962d 100644 --- a/libc/calls/sigaction.c +++ b/libc/calls/sigaction.c @@ -18,9 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/bits/bits.h" +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/sigaction-freebsd.internal.h" #include "libc/calls/struct/sigaction-linux.internal.h" #include "libc/calls/struct/sigaction-netbsd.h" @@ -31,7 +33,10 @@ #include "libc/calls/ucontext.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/spinlock.h" #include "libc/limits.h" +#include "libc/log/backtrace.internal.h" +#include "libc/log/log.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" @@ -40,6 +45,12 @@ #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" +#undef sigaction + +#ifdef SYSDEBUG +STATIC_YOINK("strsignal"); // for kprintf() +#endif + #define SA_RESTORER 0x04000000 #ifndef SWITCHEROO @@ -69,9 +80,9 @@ union metasigaction { struct sigaction_xnu_out xnu_out; }; -void __sigenter_netbsd(int, void *, void *); -void __sigenter_freebsd(int, void *, void *); -void __sigenter_openbsd(int, void *, void *); +void __sigenter_netbsd(int, void *, void *) hidden; +void __sigenter_freebsd(int, void *, void *) hidden; +void __sigenter_openbsd(int, void *, void *) hidden; static void sigaction_cosmo2native(union metasigaction *sa) { if (!sa) return; @@ -129,19 +140,8 @@ static void sigaction_native2cosmo(union metasigaction *sa) { } } -/** - * Installs handler for kernel interrupt, e.g.: - * - * void GotCtrlC(int sig, siginfo_t *si, ucontext_t *ctx); - * struct sigaction sa = {.sa_sigaction = GotCtrlC, - * .sa_flags = SA_RESETHAND|SA_RESTART|SA_SIGINFO}; - * CHECK_NE(-1, sigaction(SIGINT, &sa, NULL)); - * - * @see xsigaction() for a much better api - * @asyncsignalsafe - * @vforksafe - */ -int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { +static int __sigaction(int sig, const struct sigaction *act, + struct sigaction *oldact) { _Static_assert((sizeof(struct sigaction) > sizeof(struct sigaction_linux) && sizeof(struct sigaction) > sizeof(struct sigaction_xnu_in) && sizeof(struct sigaction) > sizeof(struct sigaction_xnu_out) && @@ -222,6 +222,7 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { rc = 0; } if (rc != -1 && !__vforked) { + _spinlock(&__sig_lock); if (oldact) { oldrva = __sighandrvas[sig]; oldact->sa_sigaction = (sigaction_f)( @@ -229,7 +230,226 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { } if (act) { __sighandrvas[sig] = rva; + __sighandflags[sig] = act->sa_flags; } + _spunlock(&__sig_lock); } return rc; } + +/** + * Installs handler for kernel interrupt, e.g.: + * + * void GotCtrlC(int sig, siginfo_t *si, ucontext_t *ctx); + * struct sigaction sa = {.sa_sigaction = GotCtrlC, + * .sa_flags = SA_RESETHAND|SA_RESTART|SA_SIGINFO}; + * CHECK_NE(-1, sigaction(SIGINT, &sa, NULL)); + * + * The following flags are supported across platforms: + * + * - `SA_SIGINFO`: Causes the `siginfo_t` and `ucontext_t` parameters to + * be passed. This not only gives you more information about the + * signal, but also allows your signal handler to change the CPU + * registers. That's useful for recovering from crashes. If you don't + * use this attribute, then signal delivery will go a little faster. + * + * - `SA_RESTART`: Enables BSD signal handling semantics. Normally i/o + * entrypoints check for pending signals to deliver. If one gets + * delivered during an i/o call, the normal behavior is to cancel the + * i/o operation and return -1 with EINTR in errno. If you use the + * `SA_RESTART` flag then that behavior changes, so that any function + * that's been annotated with @restartable will not return `EINTR` and + * will instead resume the i/o operation. This makes coding easier but + * it can be an anti-pattern if not used carefully, since poor usage + * can easily result in latency issues. It also requires one to do + * more work in signal handlers, so special care needs to be given to + * which C library functions are @asyncsignalsafe. + * + * - `SA_RESETHAND`: Causes signal handler to be single-shot. This means + * that, upon entry of delivery to a signal handler, it's reset to the + * `SIG_DFL` handler automatically. You may use the alias `SA_ONESHOT` + * for this flag, which means the same thing. + * + * - `SA_NODEFER`: Disables the reentrancy safety check on your signal + * handler. Normally that's a good thing, since for instance if your + * `SIGSEGV` signal handler happens to segfault, you're going to want + * your process to just crash rather than looping endlessly. But in + * some cases it's desirable to use `SA_NODEFER` instead, such as at + * times when you wish to `longjmp()` out of your signal handler and + * back into your program. This is only safe to do across platforms + * for non-crashing signals such as `SIGCHLD` and `SIGINT`. Crash + * handlers should use Xed instead to recover execution, because on + * Windows a `SIGSEGV` or `SIGTRAP` crash handler might happen on a + * separate stack and/or a separate thread. You may use the alias + * `SA_NOMASK` for this flag, which means the same thing. + * + * - `SA_NOCLDWAIT`: Changes `SIGCHLD` so the zombie is gone and you + * can't call `wait()` anymore; similar but may + * still deliver the SIGCHLD. + * + * - `SA_NOCLDSTOP`: Lets you set `SIGCHLD` handler that's only notified + * on exit/termination and not notified on `SIGSTOP`, `SIGTSTP`, + * `SIGTTIN`, `SIGTTOU`, or `SIGCONT`. + * + * Here's an example of the most professional way to handle signals in + * an i/o event loop. It's generally a best practice to have signal + * handlers do the fewest number of things possible. The trick is to + * have your signals work hand-in-glove with the EINTR errno. This + * obfuscates the need for having to worry about @asyncsignalsafe. + * + * static volatile bool gotctrlc; + * + * void OnCtrlC(int sig) { + * gotctrlc = true; + * } + * + * int main() { + * size_t got; + * ssize_t rc; + * char buf[1]; + * struct sigaction oldint; + * struct sigaction saint = {.sa_handler = GotCtrlC}; + * if (sigaction(SIGINT, &saint, &oldint) == -1) { + * perror("sigaction"); + * exit(1); + * } + * for (;;) { + * rc = read(0, buf, sizeof(buf)); + * if (rc == -1) { + * if (errno == EINTR) { + * if (gotctrlc) { + * break; + * } + * } else { + * perror("read"); + * exit(2); + * } + * } + * if (!(got = rc)) { + * break; + * } + * for (;;) { + * rc = write(1, buf, got); + * if (rc != -1) { + * assert(rc == 1); + * break; + * } else if (errno != EINTR) { + * perror("write"); + * exit(3); + * } + * } + * } + * sigaction(SIGINT, &oldint, 0); + * } + * + * Please note that you can't do the above if you use SA_RESTART. Since + * the purpose of SA_RESTART is to restart i/o operations whose docs say + * that they're @restartable and read() is one such function. Here's + * some even better news: if you don't install any signal handlers at + * all, then your i/o calls will never be interrupted! + * + * Here's an example of the most professional way to recover from + * `SIGSEGV`, `SIGFPE`, and `SIGILL`. + * + * void ContinueOnCrash(void); + * + * void SkipOverFaultingInstruction(struct ucontext *ctx) { + * struct XedDecodedInst xedd; + * xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); + * xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15); + * ctx->uc_mcontext.rip += xedd.length; + * } + * + * void OnCrash(int sig, struct siginfo *si, struct ucontext *ctx) { + * SkipOverFaultingInstruction(ctx); + * ContinueOnCrash(); // reinstall here in case *rip faults + * } + * + * void ContinueOnCrash(void) { + * struct sigaction sa = {.sa_handler = OnSigSegv, + * .sa_flags = SA_SIGINFO | SA_RESETHAND}; + * sigaction(SIGSEGV, &sa, 0); + * sigaction(SIGFPE, &sa, 0); + * sigaction(SIGILL, &sa, 0); + * } + * + * int main() { + * ContinueOnCrash(); + * // ... + * } + * + * You may also edit any other CPU registers during the handler. For + * example, you can use the above technique so that division by zero + * becomes defined to a specific value of your choosing! + * + * Please note that Xed isn't needed to recover from `SIGTRAP` which can + * be raised at any time by embedding `DebugBreak()` or `asm("int3")` in + * your program code. Your signal handler will automatically skip over + * the interrupt instruction, assuming your signal handler returns. + * + * The important signals supported across all platforms are: + * + * - `SIGINT`: When you press Ctrl-C this signal gets broadcasted to + * your process session group. This is the normal way to terminate + * console applications. + * + * - `SIGQUIT`: When you press CTRL-\ this signal gets broadcasted to + * your process session group. This is the irregular way to kill an + * application in cases where maybe your `SIGINT` handler is broken + * although, Cosmopolitan Libc ShowCrashReports() should program it + * such as to attach a debugger to the process if possible, or else + * show a crash report. Also note that in New Technology you should + * press CTRL+BREAK rather than CTRL+\ to get this signal. + * + * - `SIGHUP`: This gets sent to your non-daemon processes when you + * close your terminal session. + * + * - `SIGTERM` is what the `kill` command sends by default. It's the + * choice signal for terminating daemons. + * + * - `SIGUSR1` and `SIGUSR2` can be anything you want. Their default + * action is to kill the process. By convention `SIGUSR1` is usually + * used by daemons to reload the config file. + * + * - `SIGCHLD` is sent when a process terminates and it takes a certain + * degree of UNIX mastery to address sanely. + * + * - `SIGALRM` is invoked by `setitimer()` and `alarm()`. It can be + * useful for interrupting i/o operations like `connect()`. + * + * - `SIGTRAP`: This happens when an INT3 instruction is encountered. + * + * - `SIGILL` happens on illegal instructions, e.g. `UD2`. + * + * - `SIGABRT` happens when you call `abort()`. + * + * - `SIGFPE` happens when you divide ints by zero, among other things. + * + * - `SIGSEGV` and `SIGBUS` indicate memory access errors and they have + * inconsistent semantics across platforms like FreeBSD. + * + * - `SIGWINCH` is sent when your terminal window is resized. + * + * - `SIGXCPU` and `SIGXFSZ` may be raised if you run out of resources, + * which can happen if your process, or the parent process that + * spawned your process, happened to call `setrlimit()`. Doing this is + * a wonderful idea. + * + * @return 0 on success or -1 w/ errno + * @see xsigaction() for a much better api + * @asyncsignalsafe + * @vforksafe + */ +int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) { + int rc; + char buf[2][128]; + if (sig == SIGKILL || sig == SIGSTOP) { + rc = einval(); + } else { + rc = __sigaction(sig, act, oldact); + } + STRACE("sigaction(%G, %s, [%s]) → %d% m", sig, + __strace_sigaction(buf[0], sizeof(buf[0]), 0, act), + __strace_sigaction(buf[1], sizeof(buf[1]), rc, oldact), rc); + return rc; +} diff --git a/libc/calls/sigaddset.c b/libc/calls/sigaddset.c index e730d90b7..260b80304 100644 --- a/libc/calls/sigaddset.c +++ b/libc/calls/sigaddset.c @@ -22,13 +22,14 @@ /** * Adds signal to set. * - * @return true, false, or -1 w/ errno + * @return 0 on success, or -1 w/ errno + * @raises EINVAL if `1 ≤ sig ≤ NSIG` isn't the case * @asyncsignalsafe */ int sigaddset(sigset_t *set, int sig) { - unsigned i = sig - 1; - if (i < sizeof(set->__bits) * 8) { - set->__bits[i >> 6] |= 1ull << (i & 63); + _Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, ""); + if (1 <= sig && sig <= NSIG) { + set->__bits[(sig - 1) >> 6] |= 1ull << ((sig - 1) & 63); return 0; } else { return einval(); diff --git a/libc/calls/sigaltstack.c b/libc/calls/sigaltstack.c index 754fe4e95..3f2a74eb0 100644 --- a/libc/calls/sigaltstack.c +++ b/libc/calls/sigaltstack.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/metasigaltstack.h" #include "libc/calls/struct/sigaltstack.h" #include "libc/dce.h" @@ -70,37 +71,41 @@ static noasan void sigaltstack2linux(struct sigaltstack *linux, */ noasan int sigaltstack(const struct sigaltstack *neu, struct sigaltstack *old) { int rc; - void *a, *b; + void *b; + const void *a; struct sigaltstack_bsd bsd; if (IsAsan() && ((old && __asan_check(old, sizeof(*old)).kind) || (neu && (__asan_check(neu, sizeof(*neu)).kind || __asan_check(neu->ss_sp, neu->ss_size).kind)))) { - return efault(); - } - if (IsLinux()) { - a = neu; - b = old; - } else if (IsBsd()) { - if (neu) { - sigaltstack2bsd(&bsd, neu); - a = &bsd; + rc = efault(); + } else if (IsLinux() || IsBsd()) { + if (IsLinux()) { + a = neu; + b = old; } else { - a = 0; + if (neu) { + sigaltstack2bsd(&bsd, neu); + a = &bsd; + } else { + a = 0; + } + if (old) { + b = &bsd; + } else { + b = 0; + } } - if (old) { - b = &bsd; + if ((rc = sys_sigaltstack(a, b)) != -1) { + if (IsBsd() && old) { + sigaltstack2linux(old, &bsd); + } + rc = 0; } else { - b = 0; + rc = -1; } } else { - return enosys(); - } - if ((rc = sys_sigaltstack(a, b)) != -1) { - if (IsBsd() && old) { - sigaltstack2linux(old, &bsd); - } - return 0; - } else { - return -1; + rc = enosys(); } + STRACE("sigaltstack() → %d% m", rc); + return rc; } diff --git a/libc/calls/sigchld-nt.c b/libc/calls/sigchld-nt.c new file mode 100644 index 000000000..6d8b7a073 --- /dev/null +++ b/libc/calls/sigchld-nt.c @@ -0,0 +1,60 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/nt/enum/wait.h" +#include "libc/nt/runtime.h" +#include "libc/nt/synchronization.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" + +/** + * Checks to see if SIGCHLD should be raised on Windows. + * @return true if a signal was raised + * @note yoinked by fork-nt.c + */ +void _check_sigchld(void) { + siginfo_t si; + int pids[64]; + uint32_t i, n; + int64_t handles[64]; + if (!(n = __sample_pids(pids, handles, true))) return; + i = WaitForMultipleObjects(n, handles, false, 0); + if (i == kNtWaitTimeout) return; + if (i == kNtWaitFailed) { + STRACE("%s failed %u", "WaitForMultipleObjects", GetLastError()); + return; + } + if (__sighandrvas[SIGCHLD] == (intptr_t)SIG_IGN || + __sighandrvas[SIGCHLD] == (intptr_t)SIG_DFL) { + STRACE("new zombie fd=%d handle=%ld", pids[i], handles[i]); + return; + } + if (__sighandflags[SIGCHLD] & SA_NOCLDWAIT) { + STRACE("SIGCHILD SA_NOCLDWAIT fd=%d handle=%ld", pids[i], handles[i]); + CloseHandle(handles[i]); + __releasefd(pids[i]); + } + g_fds.p[pids[i]].zombie = true; + __sig_add(SIGCHLD, CLD_EXITED); +} diff --git a/libc/calls/sigcount.c b/libc/calls/sigcount.c new file mode 100644 index 000000000..74986db40 --- /dev/null +++ b/libc/calls/sigcount.c @@ -0,0 +1,21 @@ +/*-*- 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 2022 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/sig.internal.h" + +long __sig_count; diff --git a/libc/calls/sigdelset.c b/libc/calls/sigdelset.c index 856573808..84ca3129b 100644 --- a/libc/calls/sigdelset.c +++ b/libc/calls/sigdelset.c @@ -23,12 +23,13 @@ * Removes signal from set. * * @return 0 on success, or -1 w/ errno + * @raises EINVAL if `1 ≤ sig ≤ NSIG` isn't the case * @asyncsignalsafe */ int sigdelset(sigset_t *set, int sig) { - unsigned i = sig - 1; - if (i < sizeof(set->__bits) * 8) { - set->__bits[i >> 6] &= ~(1ull << (i & 63)); + _Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, ""); + if (1 <= sig && sig <= NSIG) { + set->__bits[(sig - 1) >> 6] &= ~(1ull << ((sig - 1) & 63)); return 0; } else { return einval(); diff --git a/libc/calls/sigenter-freebsd.c b/libc/calls/sigenter-freebsd.c index ae627734c..352d3f5d8 100644 --- a/libc/calls/sigenter-freebsd.c +++ b/libc/calls/sigenter-freebsd.c @@ -19,175 +19,101 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/sigaction-freebsd.internal.h" +#include "libc/calls/struct/siginfo-freebsd.internal.h" #include "libc/calls/struct/siginfo.h" +#include "libc/calls/struct/ucontext-freebsd.internal.h" #include "libc/calls/typedef/sigaction_f.h" #include "libc/calls/ucontext.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/repstosb.h" #include "libc/macros.internal.h" #include "libc/str/str.h" +#include "libc/sysv/consts/sa.h" -union sigval_freebsd { - int32_t sival_int; - void *sival_ptr; - int32_t sigval_int; - void *sigval_ptr; -}; - -struct siginfo_freebsd { - int32_t si_signo; - int32_t si_errno; - int32_t si_code; - int32_t si_pid; - uint32_t si_uid; - int32_t si_status; - void *si_addr; - union sigval_freebsd si_value; - union { - struct { - int32_t _trapno; - } _fault; - struct { - int32_t _timerid; - int32_t _overrun; - } _timer; - struct { - int32_t _mqd; - } _mesgq; - struct { - int64_t _band; - } _poll; - struct { - int64_t __spare1__; - int32_t __spare2__[7]; - } __spare__; - } _reason; -}; - -struct stack_freebsd { - void *ss_sp; - uint64_t ss_size; - int32_t ss_flags; -}; - -struct mcontext_freebsd { - int64_t mc_onstack; - int64_t mc_rdi; - int64_t mc_rsi; - int64_t mc_rdx; - int64_t mc_rcx; - int64_t mc_r8; - int64_t mc_r9; - int64_t mc_rax; - int64_t mc_rbx; - int64_t mc_rbp; - int64_t mc_r10; - int64_t mc_r11; - int64_t mc_r12; - int64_t mc_r13; - int64_t mc_r14; - int64_t mc_r15; - uint32_t mc_trapno; - uint16_t mc_fs; - uint16_t mc_gs; - int64_t mc_addr; - uint32_t mc_flags; - uint16_t mc_es; - uint16_t mc_ds; - int64_t mc_err; - int64_t mc_rip; - int64_t mc_cs; - int64_t mc_rflags; - int64_t mc_rsp; - int64_t mc_ss; - int64_t mc_len; - int64_t mc_fpformat; - int64_t mc_ownedfp; - int64_t mc_fpstate[64]; - int64_t mc_fsbase; - int64_t mc_gsbase; - int64_t mc_xfpustate; - int64_t mc_xfpustate_len; - int64_t mc_spare[4]; -}; - -struct ucontext_freebsd { - struct sigset_freebsd uc_sigmask; - struct mcontext_freebsd uc_mcontext; - struct ucontext_freebsd *uc_link; - struct stack_freebsd uc_stack; - int32_t uc_flags; - int32_t __spare__[4]; -}; - -void __sigenter_freebsd(int sig, struct siginfo_freebsd *si, +void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo, struct ucontext_freebsd *ctx) { - int rva; - ucontext_t uc; + int rva, flags; + struct Goodies { + ucontext_t uc; + siginfo_t si; + } g; rva = __sighandrvas[sig & (NSIG - 1)]; if (rva >= kSigactionMinRva) { - bzero(&uc, sizeof(uc)); - if (ctx) { - uc.uc_mcontext.fpregs = &uc.__fpustate; - uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp; - uc.uc_stack.ss_size = ctx->uc_stack.ss_size; - uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags; - uc.uc_flags = ctx->uc_flags; - memcpy(&uc.uc_sigmask, &ctx->uc_sigmask, - MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask))); - uc.uc_mcontext.r8 = ctx->uc_mcontext.mc_r8; - uc.uc_mcontext.r9 = ctx->uc_mcontext.mc_r9; - uc.uc_mcontext.r10 = ctx->uc_mcontext.mc_r10; - uc.uc_mcontext.r11 = ctx->uc_mcontext.mc_r11; - uc.uc_mcontext.r12 = ctx->uc_mcontext.mc_r12; - uc.uc_mcontext.r13 = ctx->uc_mcontext.mc_r13; - uc.uc_mcontext.r14 = ctx->uc_mcontext.mc_r14; - uc.uc_mcontext.r15 = ctx->uc_mcontext.mc_r15; - uc.uc_mcontext.rdi = ctx->uc_mcontext.mc_rdi; - uc.uc_mcontext.rsi = ctx->uc_mcontext.mc_rsi; - uc.uc_mcontext.rbp = ctx->uc_mcontext.mc_rbp; - uc.uc_mcontext.rbx = ctx->uc_mcontext.mc_rbx; - uc.uc_mcontext.rdx = ctx->uc_mcontext.mc_rdx; - uc.uc_mcontext.rax = ctx->uc_mcontext.mc_rax; - uc.uc_mcontext.rcx = ctx->uc_mcontext.mc_rcx; - uc.uc_mcontext.rsp = ctx->uc_mcontext.mc_rsp; - uc.uc_mcontext.rip = ctx->uc_mcontext.mc_rip; - uc.uc_mcontext.eflags = ctx->uc_mcontext.mc_flags; - uc.uc_mcontext.fs = ctx->uc_mcontext.mc_fs; - uc.uc_mcontext.gs = ctx->uc_mcontext.mc_gs; - uc.uc_mcontext.err = ctx->uc_mcontext.mc_err; - uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno; - memcpy(&uc.__fpustate, &ctx->uc_mcontext.mc_fpstate, 512); - } - ((sigaction_f)(_base + rva))(sig, (void *)si, &uc); - if (ctx) { - ctx->uc_stack.ss_sp = uc.uc_stack.ss_sp; - ctx->uc_stack.ss_size = uc.uc_stack.ss_size; - ctx->uc_stack.ss_flags = uc.uc_stack.ss_flags; - ctx->uc_flags = uc.uc_flags; - memcpy(&ctx->uc_sigmask, &uc.uc_sigmask, - MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask))); - ctx->uc_mcontext.mc_rdi = uc.uc_mcontext.rdi; - ctx->uc_mcontext.mc_rsi = uc.uc_mcontext.rsi; - ctx->uc_mcontext.mc_rdx = uc.uc_mcontext.rdx; - ctx->uc_mcontext.mc_rcx = uc.uc_mcontext.rcx; - ctx->uc_mcontext.mc_r8 = uc.uc_mcontext.r8; - ctx->uc_mcontext.mc_r9 = uc.uc_mcontext.r9; - ctx->uc_mcontext.mc_rax = uc.uc_mcontext.rax; - ctx->uc_mcontext.mc_rbx = uc.uc_mcontext.rbx; - ctx->uc_mcontext.mc_rbp = uc.uc_mcontext.rbp; - ctx->uc_mcontext.mc_r10 = uc.uc_mcontext.r10; - ctx->uc_mcontext.mc_r11 = uc.uc_mcontext.r11; - ctx->uc_mcontext.mc_r12 = uc.uc_mcontext.r12; - ctx->uc_mcontext.mc_r13 = uc.uc_mcontext.r13; - ctx->uc_mcontext.mc_r14 = uc.uc_mcontext.r14; - ctx->uc_mcontext.mc_r15 = uc.uc_mcontext.r15; - ctx->uc_mcontext.mc_trapno = uc.uc_mcontext.trapno; - ctx->uc_mcontext.mc_fs = uc.uc_mcontext.fs; - ctx->uc_mcontext.mc_gs = uc.uc_mcontext.gs; - ctx->uc_mcontext.mc_flags = uc.uc_mcontext.eflags; - ctx->uc_mcontext.mc_err = uc.uc_mcontext.err; - ctx->uc_mcontext.mc_rip = uc.uc_mcontext.rip; - ctx->uc_mcontext.mc_rsp = uc.uc_mcontext.rsp; - memcpy(&ctx->uc_mcontext.mc_fpstate, &uc.__fpustate, 512); + flags = __sighandflags[sig & (NSIG - 1)]; + if (~flags & SA_SIGINFO) { + ((sigaction_f)(_base + rva))(sig, 0, 0); + } else { + repstosb(&g, 0, sizeof(g)); + g.uc.uc_mcontext.fpregs = &g.uc.__fpustate; + g.uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp; + g.uc.uc_stack.ss_size = ctx->uc_stack.ss_size; + g.uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags; + g.uc.uc_flags = ctx->uc_flags; + memcpy(&g.uc.uc_sigmask, &ctx->uc_sigmask, + MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask))); + g.uc.uc_mcontext.r8 = ctx->uc_mcontext.mc_r8; + g.uc.uc_mcontext.r9 = ctx->uc_mcontext.mc_r9; + g.uc.uc_mcontext.r10 = ctx->uc_mcontext.mc_r10; + g.uc.uc_mcontext.r11 = ctx->uc_mcontext.mc_r11; + g.uc.uc_mcontext.r12 = ctx->uc_mcontext.mc_r12; + g.uc.uc_mcontext.r13 = ctx->uc_mcontext.mc_r13; + g.uc.uc_mcontext.r14 = ctx->uc_mcontext.mc_r14; + g.uc.uc_mcontext.r15 = ctx->uc_mcontext.mc_r15; + g.uc.uc_mcontext.rdi = ctx->uc_mcontext.mc_rdi; + g.uc.uc_mcontext.rsi = ctx->uc_mcontext.mc_rsi; + g.uc.uc_mcontext.rbp = ctx->uc_mcontext.mc_rbp; + g.uc.uc_mcontext.rbx = ctx->uc_mcontext.mc_rbx; + g.uc.uc_mcontext.rdx = ctx->uc_mcontext.mc_rdx; + g.uc.uc_mcontext.rax = ctx->uc_mcontext.mc_rax; + g.uc.uc_mcontext.rcx = ctx->uc_mcontext.mc_rcx; + g.uc.uc_mcontext.rsp = ctx->uc_mcontext.mc_rsp; + g.uc.uc_mcontext.rip = ctx->uc_mcontext.mc_rip; + g.uc.uc_mcontext.eflags = ctx->uc_mcontext.mc_flags; + g.uc.uc_mcontext.fs = ctx->uc_mcontext.mc_fs; + g.uc.uc_mcontext.gs = ctx->uc_mcontext.mc_gs; + g.uc.uc_mcontext.err = ctx->uc_mcontext.mc_err; + g.uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno; + memcpy(&g.uc.__fpustate, &ctx->uc_mcontext.mc_fpstate, 512); + g.si.si_signo = freebsdinfo->si_signo; + g.si.si_errno = freebsdinfo->si_errno; + g.si.si_code = freebsdinfo->si_code; + if (freebsdinfo->si_pid) { + g.si.si_pid = freebsdinfo->si_pid; + g.si.si_uid = freebsdinfo->si_uid; + } else { + g.si.si_addr = (void *)freebsdinfo->si_addr; + } + g.si.si_value = freebsdinfo->si_value; + ((sigaction_f)(_base + rva))(sig, &g.si, &g.uc); + ctx->uc_stack.ss_sp = g.uc.uc_stack.ss_sp; + ctx->uc_stack.ss_size = g.uc.uc_stack.ss_size; + ctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags; + ctx->uc_flags = g.uc.uc_flags; + memcpy(&ctx->uc_sigmask, &g.uc.uc_sigmask, + MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask))); + ctx->uc_mcontext.mc_rdi = g.uc.uc_mcontext.rdi; + ctx->uc_mcontext.mc_rsi = g.uc.uc_mcontext.rsi; + ctx->uc_mcontext.mc_rdx = g.uc.uc_mcontext.rdx; + ctx->uc_mcontext.mc_rcx = g.uc.uc_mcontext.rcx; + ctx->uc_mcontext.mc_r8 = g.uc.uc_mcontext.r8; + ctx->uc_mcontext.mc_r9 = g.uc.uc_mcontext.r9; + ctx->uc_mcontext.mc_rax = g.uc.uc_mcontext.rax; + ctx->uc_mcontext.mc_rbx = g.uc.uc_mcontext.rbx; + ctx->uc_mcontext.mc_rbp = g.uc.uc_mcontext.rbp; + ctx->uc_mcontext.mc_r10 = g.uc.uc_mcontext.r10; + ctx->uc_mcontext.mc_r11 = g.uc.uc_mcontext.r11; + ctx->uc_mcontext.mc_r12 = g.uc.uc_mcontext.r12; + ctx->uc_mcontext.mc_r13 = g.uc.uc_mcontext.r13; + ctx->uc_mcontext.mc_r14 = g.uc.uc_mcontext.r14; + ctx->uc_mcontext.mc_r15 = g.uc.uc_mcontext.r15; + ctx->uc_mcontext.mc_trapno = g.uc.uc_mcontext.trapno; + ctx->uc_mcontext.mc_fs = g.uc.uc_mcontext.fs; + ctx->uc_mcontext.mc_gs = g.uc.uc_mcontext.gs; + ctx->uc_mcontext.mc_flags = g.uc.uc_mcontext.eflags; + ctx->uc_mcontext.mc_err = g.uc.uc_mcontext.err; + ctx->uc_mcontext.mc_rip = g.uc.uc_mcontext.rip; + ctx->uc_mcontext.mc_rsp = g.uc.uc_mcontext.rsp; + memcpy(&ctx->uc_mcontext.mc_fpstate, &g.uc.__fpustate, 512); } } /* diff --git a/libc/calls/sigenter-netbsd.c b/libc/calls/sigenter-netbsd.c index 7022ad8cd..0d2595a96 100644 --- a/libc/calls/sigenter-netbsd.c +++ b/libc/calls/sigenter-netbsd.c @@ -19,127 +19,34 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/sigaction-freebsd.internal.h" +#include "libc/calls/struct/siginfo-netbsd.internal.h" #include "libc/calls/struct/siginfo.h" +#include "libc/calls/struct/ucontext-netbsd.internal.h" #include "libc/calls/typedef/sigaction_f.h" #include "libc/calls/ucontext.h" #include "libc/macros.internal.h" #include "libc/str/str.h" - -#define RDI 0 -#define RSI 1 -#define RDX 2 -#define R10 6 -#define R8 4 -#define R9 5 -#define RCX 3 -#define R11 7 -#define R12 8 -#define R13 9 -#define R14 10 -#define R15 11 -#define RBP 12 -#define RBX 13 -#define RAX 14 -#define GS 15 -#define FS 16 -#define ES 17 -#define DS 18 -#define TRAP 19 -#define ERR 20 -#define RIP 21 -#define CS 22 -#define RFLAGS 23 -#define RSP 24 -#define SS 25 - -union sigval_netbsd { - int32_t sival_int; - void *sival_ptr; -}; - -struct siginfo_netbsd { - int32_t _signo; - int32_t _code; - int32_t _errno; - int32_t _pad; - union { - struct { - int32_t _pid; - uint32_t _uid; - union sigval_netbsd _value; - } _rt; - struct { - int32_t _pid; - uint32_t _uid; - int32_t _status; - int64_t _utime; - int64_t _stime; - } _child; - struct { - void *_addr; - int32_t _trap; - int32_t _trap2; - int32_t _trap3; - } _fault; - struct { - int64_t _band; - int32_t _fd; - } _poll; - struct { - int32_t _sysnum; - int32_t _retval[2]; - int32_t _error; - uint64_t _args[8]; - } _syscall; - struct { - int32_t _pe_report_event; - union { - int32_t _pe_other_pid; - int32_t _pe_lwp; - } _option; - } _ptrace_state; - } _reason; -}; - -struct sigset_netbsd { - uint32_t __bits[4]; -}; - -struct stack_netbsd { - void *ss_sp; - size_t ss_size; - int32_t ss_flags; -}; - -struct mcontext_netbsd { - int64_t __gregs[26]; - int64_t _mc_tlsbase; - struct FpuState __fpregs; -}; - -struct ucontext_netbsd { - uint32_t uc_flags; - struct ucontext_netbsd *uc_link; - struct sigset_netbsd uc_sigmask; - struct stack_netbsd uc_stack; - struct mcontext_netbsd uc_mcontext; -}; +#include "libc/sysv/consts/sa.h" void __sigenter_netbsd(int sig, struct siginfo_netbsd *si, struct ucontext_netbsd *ctx) { - int rva; + int rva, flags; ucontext_t uc; struct siginfo si2; rva = __sighandrvas[sig & (NSIG - 1)]; if (rva >= kSigactionMinRva) { - bzero(&uc, sizeof(uc)); - bzero(&si2, sizeof(si2)); - if (si) { - si2.si_signo = si->_signo; - si2.si_code = si->_code; - si2.si_errno = si->_errno; - } - if (ctx) { + flags = __sighandflags[sig & (NSIG - 1)]; + if (~flags & SA_SIGINFO) { + ((sigaction_f)(_base + rva))(sig, 0, 0); + } else { + bzero(&uc, sizeof(uc)); + bzero(&si2, sizeof(si2)); + si2.si_signo = si->si_signo; + si2.si_code = si->si_code; + si2.si_errno = si->si_errno; + si2.si_pid = si->si_pid; + si2.si_uid = si->si_uid; + si2.si_value = si->si_value; uc.uc_mcontext.fpregs = &uc.__fpustate; uc.uc_flags = ctx->uc_flags; uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp; @@ -147,52 +54,50 @@ void __sigenter_netbsd(int sig, struct siginfo_netbsd *si, uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags; memcpy(&uc.uc_sigmask, &ctx->uc_sigmask, MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask))); - uc.uc_mcontext.rdi = ctx->uc_mcontext.__gregs[RDI]; - uc.uc_mcontext.rsi = ctx->uc_mcontext.__gregs[RSI]; - uc.uc_mcontext.rdx = ctx->uc_mcontext.__gregs[RDX]; - uc.uc_mcontext.rcx = ctx->uc_mcontext.__gregs[RCX]; - uc.uc_mcontext.r8 = ctx->uc_mcontext.__gregs[R8]; - uc.uc_mcontext.r9 = ctx->uc_mcontext.__gregs[R9]; - uc.uc_mcontext.rax = ctx->uc_mcontext.__gregs[RAX]; - uc.uc_mcontext.rbx = ctx->uc_mcontext.__gregs[RBX]; - uc.uc_mcontext.rbp = ctx->uc_mcontext.__gregs[RBP]; - uc.uc_mcontext.r10 = ctx->uc_mcontext.__gregs[R10]; - uc.uc_mcontext.r11 = ctx->uc_mcontext.__gregs[R11]; - uc.uc_mcontext.r12 = ctx->uc_mcontext.__gregs[R12]; - uc.uc_mcontext.r13 = ctx->uc_mcontext.__gregs[R13]; - uc.uc_mcontext.r14 = ctx->uc_mcontext.__gregs[R14]; - uc.uc_mcontext.r15 = ctx->uc_mcontext.__gregs[R15]; - uc.uc_mcontext.trapno = ctx->uc_mcontext.__gregs[TRAP]; - uc.uc_mcontext.fs = ctx->uc_mcontext.__gregs[FS]; - uc.uc_mcontext.gs = ctx->uc_mcontext.__gregs[GS]; - uc.uc_mcontext.err = ctx->uc_mcontext.__gregs[ERR]; - uc.uc_mcontext.rip = ctx->uc_mcontext.__gregs[RIP]; - uc.uc_mcontext.rsp = ctx->uc_mcontext.__gregs[RSP]; + uc.uc_mcontext.rdi = ctx->uc_mcontext.rdi; + uc.uc_mcontext.rsi = ctx->uc_mcontext.rsi; + uc.uc_mcontext.rdx = ctx->uc_mcontext.rdx; + uc.uc_mcontext.rcx = ctx->uc_mcontext.rcx; + uc.uc_mcontext.r8 = ctx->uc_mcontext.r8; + uc.uc_mcontext.r9 = ctx->uc_mcontext.r9; + uc.uc_mcontext.rax = ctx->uc_mcontext.rax; + uc.uc_mcontext.rbx = ctx->uc_mcontext.rbx; + uc.uc_mcontext.rbp = ctx->uc_mcontext.rbp; + uc.uc_mcontext.r10 = ctx->uc_mcontext.r10; + uc.uc_mcontext.r11 = ctx->uc_mcontext.r11; + uc.uc_mcontext.r12 = ctx->uc_mcontext.r12; + uc.uc_mcontext.r13 = ctx->uc_mcontext.r13; + uc.uc_mcontext.r14 = ctx->uc_mcontext.r14; + uc.uc_mcontext.r15 = ctx->uc_mcontext.r15; + uc.uc_mcontext.trapno = ctx->uc_mcontext.trapno; + uc.uc_mcontext.fs = ctx->uc_mcontext.fs; + uc.uc_mcontext.gs = ctx->uc_mcontext.gs; + uc.uc_mcontext.err = ctx->uc_mcontext.err; + uc.uc_mcontext.rip = ctx->uc_mcontext.rip; + uc.uc_mcontext.rsp = ctx->uc_mcontext.rsp; *uc.uc_mcontext.fpregs = ctx->uc_mcontext.__fpregs; - } - ((sigaction_f)(_base + rva))(sig, &si2, &uc); - if (ctx) { - ctx->uc_mcontext.__gregs[RDI] = uc.uc_mcontext.rdi; - ctx->uc_mcontext.__gregs[RSI] = uc.uc_mcontext.rsi; - ctx->uc_mcontext.__gregs[RDX] = uc.uc_mcontext.rdx; - ctx->uc_mcontext.__gregs[RCX] = uc.uc_mcontext.rcx; - ctx->uc_mcontext.__gregs[R8] = uc.uc_mcontext.r8; - ctx->uc_mcontext.__gregs[R9] = uc.uc_mcontext.r9; - ctx->uc_mcontext.__gregs[RAX] = uc.uc_mcontext.rax; - ctx->uc_mcontext.__gregs[RBX] = uc.uc_mcontext.rbx; - ctx->uc_mcontext.__gregs[RBP] = uc.uc_mcontext.rbp; - ctx->uc_mcontext.__gregs[R10] = uc.uc_mcontext.r10; - ctx->uc_mcontext.__gregs[R11] = uc.uc_mcontext.r11; - ctx->uc_mcontext.__gregs[R12] = uc.uc_mcontext.r12; - ctx->uc_mcontext.__gregs[R13] = uc.uc_mcontext.r13; - ctx->uc_mcontext.__gregs[R14] = uc.uc_mcontext.r14; - ctx->uc_mcontext.__gregs[R15] = uc.uc_mcontext.r15; - ctx->uc_mcontext.__gregs[TRAP] = uc.uc_mcontext.trapno; - ctx->uc_mcontext.__gregs[FS] = uc.uc_mcontext.fs; - ctx->uc_mcontext.__gregs[GS] = uc.uc_mcontext.gs; - ctx->uc_mcontext.__gregs[ERR] = uc.uc_mcontext.err; - ctx->uc_mcontext.__gregs[RIP] = uc.uc_mcontext.rip; - ctx->uc_mcontext.__gregs[RSP] = uc.uc_mcontext.rsp; + ((sigaction_f)(_base + rva))(sig, &si2, &uc); + ctx->uc_mcontext.rdi = uc.uc_mcontext.rdi; + ctx->uc_mcontext.rsi = uc.uc_mcontext.rsi; + ctx->uc_mcontext.rdx = uc.uc_mcontext.rdx; + ctx->uc_mcontext.rcx = uc.uc_mcontext.rcx; + ctx->uc_mcontext.r8 = uc.uc_mcontext.r8; + ctx->uc_mcontext.r9 = uc.uc_mcontext.r9; + ctx->uc_mcontext.rax = uc.uc_mcontext.rax; + ctx->uc_mcontext.rbx = uc.uc_mcontext.rbx; + ctx->uc_mcontext.rbp = uc.uc_mcontext.rbp; + ctx->uc_mcontext.r10 = uc.uc_mcontext.r10; + ctx->uc_mcontext.r11 = uc.uc_mcontext.r11; + ctx->uc_mcontext.r12 = uc.uc_mcontext.r12; + ctx->uc_mcontext.r13 = uc.uc_mcontext.r13; + ctx->uc_mcontext.r14 = uc.uc_mcontext.r14; + ctx->uc_mcontext.r15 = uc.uc_mcontext.r15; + ctx->uc_mcontext.trapno = uc.uc_mcontext.trapno; + ctx->uc_mcontext.fs = uc.uc_mcontext.fs; + ctx->uc_mcontext.gs = uc.uc_mcontext.gs; + ctx->uc_mcontext.err = uc.uc_mcontext.err; + ctx->uc_mcontext.rip = uc.uc_mcontext.rip; + ctx->uc_mcontext.rsp = uc.uc_mcontext.rsp; ctx->uc_mcontext.__fpregs = *uc.uc_mcontext.fpregs; } } diff --git a/libc/calls/sigenter-openbsd.c b/libc/calls/sigenter-openbsd.c index 5fff8b237..78a1dc0aa 100644 --- a/libc/calls/sigenter-openbsd.c +++ b/libc/calls/sigenter-openbsd.c @@ -19,145 +19,91 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/sigaction-freebsd.internal.h" +#include "libc/calls/struct/siginfo-openbsd.internal.h" #include "libc/calls/struct/siginfo.h" +#include "libc/calls/struct/ucontext-openbsd.internal.h" #include "libc/calls/typedef/sigaction_f.h" #include "libc/calls/ucontext.h" +#include "libc/intrin/repstosb.h" #include "libc/macros.internal.h" #include "libc/str/str.h" +#include "libc/sysv/consts/sa.h" -union sigval_openbsd { - int32_t sival_int; - void *sival_ptr; -}; - -struct siginfo_openbsd { - int32_t si_signo; - int32_t si_code; - int32_t si_errno; - union { - int _pad[29]; - struct { - int32_t _pid; - union { - struct { - uint32_t _uid; - union sigval_openbsd _value; - } _kill; - struct { - int64_t _utime; - int64_t _stime; - int32_t _status; - } _cld; - } _pdata; - } _proc; - struct { - void *_addr; - int32_t _trapno; - } _fault; - } _data; -}; - -struct ucontext_openbsd { - int64_t sc_rdi; - int64_t sc_rsi; - int64_t sc_rdx; - int64_t sc_rcx; - int64_t sc_r8; - int64_t sc_r9; - int64_t sc_r10; - int64_t sc_r11; - int64_t sc_r12; - int64_t sc_r13; - int64_t sc_r14; - int64_t sc_r15; - int64_t sc_rbp; - int64_t sc_rbx; - int64_t sc_rax; - int64_t sc_gs; - int64_t sc_fs; - int64_t sc_es; - int64_t sc_ds; - int64_t sc_trapno; - int64_t sc_err; - int64_t sc_rip; - int64_t sc_cs; - int64_t sc_rflags; - int64_t sc_rsp; - int64_t sc_ss; - struct FpuState *sc_fpstate; - int32_t __sc_unused; - int32_t sc_mask; - int64_t sc_cookie; -}; - -void __sigenter_openbsd(int sig, struct siginfo_openbsd *si, +void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo, struct ucontext_openbsd *ctx) { - int rva; - ucontext_t uc; - struct siginfo si2; + int rva, flags; + struct Goodies { + ucontext_t uc; + struct siginfo si; + } g; rva = __sighandrvas[sig & (NSIG - 1)]; if (rva >= kSigactionMinRva) { - bzero(&uc, sizeof(uc)); - bzero(&si2, sizeof(si2)); - if (si) { - si2.si_signo = si->si_signo; - si2.si_code = si->si_code; - si2.si_errno = si->si_errno; - } - if (ctx) { - uc.uc_mcontext.fpregs = &uc.__fpustate; - memcpy(&uc.uc_sigmask, &ctx->sc_mask, - MIN(sizeof(uc.uc_sigmask), sizeof(ctx->sc_mask))); - uc.uc_mcontext.rdi = ctx->sc_rdi; - uc.uc_mcontext.rsi = ctx->sc_rsi; - uc.uc_mcontext.rdx = ctx->sc_rdx; - uc.uc_mcontext.rcx = ctx->sc_rcx; - uc.uc_mcontext.r8 = ctx->sc_r8; - uc.uc_mcontext.r9 = ctx->sc_r9; - uc.uc_mcontext.rax = ctx->sc_rax; - uc.uc_mcontext.rbx = ctx->sc_rbx; - uc.uc_mcontext.rbp = ctx->sc_rbp; - uc.uc_mcontext.r10 = ctx->sc_r10; - uc.uc_mcontext.r11 = ctx->sc_r11; - uc.uc_mcontext.r12 = ctx->sc_r12; - uc.uc_mcontext.r13 = ctx->sc_r13; - uc.uc_mcontext.r14 = ctx->sc_r14; - uc.uc_mcontext.r15 = ctx->sc_r15; - uc.uc_mcontext.trapno = ctx->sc_trapno; - uc.uc_mcontext.fs = ctx->sc_fs; - uc.uc_mcontext.gs = ctx->sc_gs; - uc.uc_mcontext.err = ctx->sc_err; - uc.uc_mcontext.rip = ctx->sc_rip; - uc.uc_mcontext.rsp = ctx->sc_rsp; - if (ctx->sc_fpstate) { - *uc.uc_mcontext.fpregs = *ctx->sc_fpstate; + flags = __sighandflags[sig & (NSIG - 1)]; + if (~flags & SA_SIGINFO) { + ((sigaction_f)(_base + rva))(sig, 0, 0); + } else { + repstosb(&g, 0, sizeof(g)); + g.si.si_signo = openbsdinfo->si_signo; + g.si.si_code = openbsdinfo->si_code; + g.si.si_errno = openbsdinfo->si_errno; + if (openbsdinfo->si_pid) { + g.si.si_pid = openbsdinfo->si_pid; + g.si.si_uid = openbsdinfo->si_uid; + } else { + g.si.si_addr = (void *)openbsdinfo->si_addr; } - } - ((sigaction_f)(_base + rva))(sig, &si2, &uc); - if (ctx) { - ctx->sc_rdi = uc.uc_mcontext.rdi; - ctx->sc_rsi = uc.uc_mcontext.rsi; - ctx->sc_rdx = uc.uc_mcontext.rdx; - ctx->sc_rcx = uc.uc_mcontext.rcx; - ctx->sc_r8 = uc.uc_mcontext.r8; - ctx->sc_r9 = uc.uc_mcontext.r9; - ctx->sc_rax = uc.uc_mcontext.rax; - ctx->sc_rbx = uc.uc_mcontext.rbx; - ctx->sc_rbp = uc.uc_mcontext.rbp; - ctx->sc_r10 = uc.uc_mcontext.r10; - ctx->sc_r11 = uc.uc_mcontext.r11; - ctx->sc_r12 = uc.uc_mcontext.r12; - ctx->sc_r13 = uc.uc_mcontext.r13; - ctx->sc_r14 = uc.uc_mcontext.r14; - ctx->sc_r15 = uc.uc_mcontext.r15; - ctx->sc_trapno = uc.uc_mcontext.trapno; - ctx->sc_fs = uc.uc_mcontext.fs; - ctx->sc_gs = uc.uc_mcontext.gs; - ctx->sc_err = uc.uc_mcontext.err; - ctx->sc_rip = uc.uc_mcontext.rip; - ctx->sc_rsp = uc.uc_mcontext.rsp; + g.si.si_value = openbsdinfo->si_value; + g.uc.uc_mcontext.fpregs = &g.uc.__fpustate; + memcpy(&g.uc.uc_sigmask, &ctx->sc_mask, + MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->sc_mask))); + g.uc.uc_mcontext.rdi = ctx->sc_rdi; + g.uc.uc_mcontext.rsi = ctx->sc_rsi; + g.uc.uc_mcontext.rdx = ctx->sc_rdx; + g.uc.uc_mcontext.rcx = ctx->sc_rcx; + g.uc.uc_mcontext.r8 = ctx->sc_r8; + g.uc.uc_mcontext.r9 = ctx->sc_r9; + g.uc.uc_mcontext.rax = ctx->sc_rax; + g.uc.uc_mcontext.rbx = ctx->sc_rbx; + g.uc.uc_mcontext.rbp = ctx->sc_rbp; + g.uc.uc_mcontext.r10 = ctx->sc_r10; + g.uc.uc_mcontext.r11 = ctx->sc_r11; + g.uc.uc_mcontext.r12 = ctx->sc_r12; + g.uc.uc_mcontext.r13 = ctx->sc_r13; + g.uc.uc_mcontext.r14 = ctx->sc_r14; + g.uc.uc_mcontext.r15 = ctx->sc_r15; + g.uc.uc_mcontext.trapno = ctx->sc_trapno; + g.uc.uc_mcontext.fs = ctx->sc_fs; + g.uc.uc_mcontext.gs = ctx->sc_gs; + g.uc.uc_mcontext.err = ctx->sc_err; + g.uc.uc_mcontext.rip = ctx->sc_rip; + g.uc.uc_mcontext.rsp = ctx->sc_rsp; if (ctx->sc_fpstate) { - *ctx->sc_fpstate = *uc.uc_mcontext.fpregs; + *g.uc.uc_mcontext.fpregs = *ctx->sc_fpstate; + } + ((sigaction_f)(_base + rva))(sig, &g.si, &g.uc); + ctx->sc_rdi = g.uc.uc_mcontext.rdi; + ctx->sc_rsi = g.uc.uc_mcontext.rsi; + ctx->sc_rdx = g.uc.uc_mcontext.rdx; + ctx->sc_rcx = g.uc.uc_mcontext.rcx; + ctx->sc_r8 = g.uc.uc_mcontext.r8; + ctx->sc_r9 = g.uc.uc_mcontext.r9; + ctx->sc_rax = g.uc.uc_mcontext.rax; + ctx->sc_rbx = g.uc.uc_mcontext.rbx; + ctx->sc_rbp = g.uc.uc_mcontext.rbp; + ctx->sc_r10 = g.uc.uc_mcontext.r10; + ctx->sc_r11 = g.uc.uc_mcontext.r11; + ctx->sc_r12 = g.uc.uc_mcontext.r12; + ctx->sc_r13 = g.uc.uc_mcontext.r13; + ctx->sc_r14 = g.uc.uc_mcontext.r14; + ctx->sc_r15 = g.uc.uc_mcontext.r15; + ctx->sc_trapno = g.uc.uc_mcontext.trapno; + ctx->sc_fs = g.uc.uc_mcontext.fs; + ctx->sc_gs = g.uc.uc_mcontext.gs; + ctx->sc_err = g.uc.uc_mcontext.err; + ctx->sc_rip = g.uc.uc_mcontext.rip; + ctx->sc_rsp = g.uc.uc_mcontext.rsp; + if (ctx->sc_fpstate) { + *ctx->sc_fpstate = *g.uc.uc_mcontext.fpregs; } } } diff --git a/libc/calls/sigenter-xnu.c b/libc/calls/sigenter-xnu.c index 05ad60754..4065ab3ce 100644 --- a/libc/calls/sigenter-xnu.c +++ b/libc/calls/sigenter-xnu.c @@ -19,9 +19,11 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/metasigaltstack.h" +#include "libc/calls/struct/siginfo-xnu.internal.h" #include "libc/calls/struct/siginfo.h" #include "libc/calls/typedef/sigaction_f.h" #include "libc/calls/ucontext.h" +#include "libc/intrin/kprintf.h" #include "libc/intrin/repstosb.h" #include "libc/str/str.h" #include "libc/sysv/consts/sa.h" @@ -30,24 +32,6 @@ * @fileoverview XNU kernel callback normalization. */ -union __darwin_sigval { - int32_t sival_int; - void *sival_ptr; -}; - -struct __darwin_siginfo { - int32_t si_signo; - int32_t si_errno; - int32_t si_code; - int32_t si_pid; - uint32_t si_uid; - int32_t si_status; - void *si_addr; - union __darwin_sigval si_value; - int64_t si_band; - uint64_t __pad[7]; -}; - struct __darwin_mmst_reg { char __mmst_reg[10]; char __mmst_rsrv[6]; @@ -467,71 +451,76 @@ noasan static void linuxssefpustate2xnu( } noasan void __sigenter_xnu(void *fn, int infostyle, int sig, - struct __darwin_siginfo *xnuinfo, + struct siginfo_xnu *xnuinfo, struct __darwin_ucontext *xnuctx) { - int rva; intptr_t ax; + int rva, flags; struct Goodies { ucontext_t uc; siginfo_t si; } g; rva = __sighandrvas[sig & (NSIG - 1)]; if (rva >= kSigactionMinRva) { - repstosb(&g, 0, sizeof(g)); - if (xnuctx) { - g.uc.uc_flags = xnuctx->uc_onstack ? SA_ONSTACK : 0; - g.uc.uc_sigmask.__bits[0] = xnuctx->uc_sigmask; - g.uc.uc_stack.ss_sp = xnuctx->uc_stack.ss_sp; - g.uc.uc_stack.ss_flags = xnuctx->uc_stack.ss_flags; - g.uc.uc_stack.ss_size = xnuctx->uc_stack.ss_size; - g.uc.uc_mcontext.fpregs = &g.uc.__fpustate; - if (xnuctx->uc_mcontext) { - if (xnuctx->uc_mcsize >= - sizeof(struct __darwin_x86_exception_state64)) { - xnuexceptionstate2linux(&g.uc.uc_mcontext, - &xnuctx->uc_mcontext->__es); - } - if (xnuctx->uc_mcsize >= - (sizeof(struct __darwin_x86_exception_state64) + - sizeof(struct __darwin_x86_thread_state64))) { - xnuthreadstate2linux(&g.uc.uc_mcontext, &xnuctx->uc_mcontext->__ss); - } - if (xnuctx->uc_mcsize >= sizeof(struct __darwin_mcontext64)) { - xnussefpustate2linux(&g.uc.__fpustate, &xnuctx->uc_mcontext->__fs); + flags = __sighandflags[sig & (NSIG - 1)]; + if (~flags & SA_SIGINFO) { + ((sigaction_f)(_base + rva))(sig, 0, 0); + } else { + repstosb(&g, 0, sizeof(g)); + if (xnuctx) { + g.uc.uc_flags = xnuctx->uc_onstack ? SA_ONSTACK : 0; + g.uc.uc_sigmask.__bits[0] = xnuctx->uc_sigmask; + g.uc.uc_stack.ss_sp = xnuctx->uc_stack.ss_sp; + g.uc.uc_stack.ss_flags = xnuctx->uc_stack.ss_flags; + g.uc.uc_stack.ss_size = xnuctx->uc_stack.ss_size; + g.uc.uc_mcontext.fpregs = &g.uc.__fpustate; + if (xnuctx->uc_mcontext) { + if (xnuctx->uc_mcsize >= + sizeof(struct __darwin_x86_exception_state64)) { + xnuexceptionstate2linux(&g.uc.uc_mcontext, + &xnuctx->uc_mcontext->__es); + } + if (xnuctx->uc_mcsize >= + (sizeof(struct __darwin_x86_exception_state64) + + sizeof(struct __darwin_x86_thread_state64))) { + xnuthreadstate2linux(&g.uc.uc_mcontext, &xnuctx->uc_mcontext->__ss); + } + if (xnuctx->uc_mcsize >= sizeof(struct __darwin_mcontext64)) { + xnussefpustate2linux(&g.uc.__fpustate, &xnuctx->uc_mcontext->__fs); + } } } - } - if (xnuinfo) { - g.si.si_signo = xnuinfo->si_signo; - g.si.si_errno = xnuinfo->si_errno; - g.si.si_code = xnuinfo->si_code; - if (xnuinfo->si_pid) { - g.si.si_pid = xnuinfo->si_pid; - g.si.si_uid = xnuinfo->si_uid; - g.si.si_status = xnuinfo->si_status; - } else { - g.si.si_addr = (void *)xnuinfo->si_addr; + if (xnuinfo) { + g.si.si_signo = xnuinfo->si_signo; + g.si.si_errno = xnuinfo->si_errno; + g.si.si_code = xnuinfo->si_code; + if (xnuinfo->si_pid) { + g.si.si_pid = xnuinfo->si_pid; + g.si.si_uid = xnuinfo->si_uid; + } else { + g.si.si_addr = (void *)xnuinfo->si_addr; + } + g.si.si_value = xnuinfo->si_value; } - } - ((sigaction_f)(_base + rva))(sig, &g.si, &g.uc); - if (xnuctx) { - xnuctx->uc_stack.ss_sp = g.uc.uc_stack.ss_sp; - xnuctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags; - xnuctx->uc_stack.ss_size = g.uc.uc_stack.ss_size; - if (xnuctx->uc_mcontext) { - if (xnuctx->uc_mcsize >= - sizeof(struct __darwin_x86_exception_state64)) { - linuxexceptionstate2xnu(&xnuctx->uc_mcontext->__es, - &g.uc.uc_mcontext); - } - if (xnuctx->uc_mcsize >= - (sizeof(struct __darwin_x86_exception_state64) + - sizeof(struct __darwin_x86_thread_state64))) { - linuxthreadstate2xnu(&xnuctx->uc_mcontext->__ss, &g.uc, - &g.uc.uc_mcontext); - } - if (xnuctx->uc_mcsize >= sizeof(struct __darwin_mcontext64)) { - linuxssefpustate2xnu(&xnuctx->uc_mcontext->__fs, &g.uc.__fpustate); + ((sigaction_f)(_base + rva))(sig, &g.si, &g.uc); + if (xnuctx) { + xnuctx->uc_stack.ss_sp = g.uc.uc_stack.ss_sp; + xnuctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags; + xnuctx->uc_stack.ss_size = g.uc.uc_stack.ss_size; + if (xnuctx->uc_mcontext) { + if (xnuctx->uc_mcsize >= + sizeof(struct __darwin_x86_exception_state64)) { + linuxexceptionstate2xnu(&xnuctx->uc_mcontext->__es, + &g.uc.uc_mcontext); + } + if (xnuctx->uc_mcsize >= + (sizeof(struct __darwin_x86_exception_state64) + + sizeof(struct __darwin_x86_thread_state64))) { + linuxthreadstate2xnu(&xnuctx->uc_mcontext->__ss, &g.uc, + &g.uc.uc_mcontext); + } + if (xnuctx->uc_mcsize >= sizeof(struct __darwin_mcontext64)) { + linuxssefpustate2xnu(&xnuctx->uc_mcontext->__fs, &g.uc.__fpustate); + } } } } diff --git a/libc/calls/sigismember.c b/libc/calls/sigismember.c index bbb57fe73..246ac55db 100644 --- a/libc/calls/sigismember.c +++ b/libc/calls/sigismember.c @@ -22,14 +22,15 @@ /** * Returns true if signal is member of set. * - * @return true, false, or -1 w/ errno + * @return 1 if set, 0 if not set, or -1 w/ errno + * @raises EINVAL if `1 ≤ sig ≤ NSIG` isn't the case * @asyncsignalsafe * @vforksafe */ int sigismember(const sigset_t *set, int sig) { - unsigned i = sig - 1; - if (i < sizeof(set->__bits) * 8) { - return (set->__bits[i >> 6] >> (i & 63)) & 1; + _Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, ""); + if (1 <= sig && sig <= NSIG) { + return !!(set->__bits[(sig - 1) >> 6] & (1ull << ((sig - 1) & 63))); } else { return einval(); } diff --git a/libc/calls/signal.c b/libc/calls/signal.c index a90af2c7a..a006e109d 100644 --- a/libc/calls/signal.c +++ b/libc/calls/signal.c @@ -21,12 +21,20 @@ #include "libc/sysv/consts/sa.h" /** - * Installs kernel interrupt handler. + * Installs kernel interrupt handler, e.g. * - * @see sigaction() which has more features + * void GotCtrlC(int sig) { ... } + * CHECK_NE(SIG_ERR, signal(SIGINT, GotCtrlC)); + * + * @return old signal handler on success or SIG_ERR w/ errno + * @note this function has BSD semantics, i.e. SA_RESTART + * @see sigaction() which has more features and docs */ sighandler_t(signal)(int sig, sighandler_t func) { - struct sigaction sa_old, sa = {.sa_handler = func, .sa_flags = SA_RESTART}; - if ((sigaction)(sig, &sa, &sa_old) == -1) return SIG_ERR; - return sa_old.sa_handler; + struct sigaction old, sa = {.sa_handler = func, .sa_flags = SA_RESTART}; + if ((sigaction)(sig, &sa, &old) != -1) { + return old.sa_handler; + } else { + return SIG_ERR; + } } diff --git a/libc/calls/sigprocmask-sysv.c b/libc/calls/sigprocmask-sysv.c new file mode 100644 index 000000000..7f6ce2b41 --- /dev/null +++ b/libc/calls/sigprocmask-sysv.c @@ -0,0 +1,48 @@ +/*-*- 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 2022 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/internal.h" + +int sys_sigprocmask(int how, const sigset_t *opt_set, + sigset_t *opt_out_oldset) { + int res, rc, arg1; + sigset_t old = {0}; + const sigset_t *arg2; + if (!IsOpenbsd()) { + rc = __sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0, 8); + } else { + if (opt_set) { + // openbsd only supports 32 signals so it passses them in a reg + arg1 = how; + arg2 = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set); + } else { + arg1 = how; // SIG_BLOCK + arg2 = 0; // changes nothing + } + if ((res = __sys_sigprocmask(arg1, arg2, 0, 0)) != -1) { + memcpy(&old, &res, sizeof(res)); + rc = 0; + } else { + rc = -1; + } + } + if (rc != -1 && opt_out_oldset) { + *opt_out_oldset = old; + } + return rc; +} diff --git a/libc/calls/sigprocmask.c b/libc/calls/sigprocmask.c index e9dd0202c..f34fef059 100644 --- a/libc/calls/sigprocmask.c +++ b/libc/calls/sigprocmask.c @@ -16,16 +16,32 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/sigset.h" #include "libc/dce.h" +#include "libc/fmt/itoa.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/log.h" #include "libc/str/str.h" +#include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" +static const char *DescribeHow(char buf[12], int how) { + if (how == SIG_BLOCK) return "SIG_BLOCK"; + if (how == SIG_UNBLOCK) return "SIG_UNBLOCK"; + if (how == SIG_SETMASK) return "SIG_SETMASK"; + FormatInt32(buf, how); + return buf; +} + /** - * Changes program signal blocking state, e.g.: + * Changes signal blocking state of calling thread, e.g.: * * sigset_t neu,old; * sigfillset(&neu); @@ -37,28 +53,32 @@ * @param oldset will receive the old mask (optional) and can't overlap * @return 0 on success, or -1 w/ errno * @asyncsignalsafe + * @restartable * @vforksafe */ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) { - int32_t x; + sigset_t old; + char howbuf[12]; + char buf[2][41]; + int res, rc, arg1; + const sigset_t *arg2; + sigemptyset(&old); if (IsAsan() && ((opt_set && !__asan_is_valid(opt_set, sizeof(*opt_set))) || (opt_out_oldset && !__asan_is_valid(opt_out_oldset, sizeof(*opt_out_oldset))))) { - return efault(); - } - if (!IsWindows() && !IsOpenbsd()) { - return sys_sigprocmask(how, opt_set, opt_out_oldset, 8); - } else if (IsOpenbsd()) { - if (!opt_set) how = 1; - if (opt_set) opt_set = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set); - if ((x = sys_sigprocmask(how, opt_set, 0, 0)) != -1) { - if (opt_out_oldset) memcpy(opt_out_oldset, &x, sizeof(x)); - return 0; - } else { - return -1; - } + rc = efault(); + } else if (IsMetal() || IsWindows()) { + rc = __sig_mask(how, opt_set, &old); + _check_interrupts(false, 0); } else { - return 0; /* TODO(jart): Implement me! */ + rc = sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0); } + if (rc != -1 && opt_out_oldset) { + *opt_out_oldset = old; + } + STRACE("sigprocmask(%s, %s, [%s]) → %d% m", DescribeHow(howbuf, how), + __strace_sigset(buf[0], sizeof(buf[0]), 0, opt_set), + __strace_sigset(buf[1], sizeof(buf[1]), rc, opt_out_oldset), rc); + return rc; } diff --git a/libc/calls/sigsuspend.c b/libc/calls/sigsuspend.c index d699b173d..098327c28 100644 --- a/libc/calls/sigsuspend.c +++ b/libc/calls/sigsuspend.c @@ -16,27 +16,85 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/sigset.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/log/backtrace.internal.h" +#include "libc/nt/errors.h" +#include "libc/nt/synchronization.h" #include "libc/sysv/errfuns.h" /** * Blocks until SIG ∉ MASK is delivered to process. * - * @param ignore is a bitset of signals to block temporarily - * @return -1 w/ EINTR + * This temporarily replaces the signal mask until a signal that it + * doesn't contain is delivered. + * + * @param ignore is a bitset of signals to block temporarily, which if + * NULL is equivalent to passing an empty signal set + * @return -1 w/ EINTR (or possibly EFAULT) * @asyncsignalsafe + * @norestart */ int sigsuspend(const sigset_t *ignore) { - unsigned x; - if (IsAsan() && !__asan_is_valid(ignore, sizeof(*ignore))) return efault(); - if (!IsWindows()) { - if (IsOpenbsd()) ignore = (sigset_t *)(uintptr_t)(*(uint32_t *)ignore); - return sys_sigsuspend(ignore, 8); + int rc; + char buf[41]; + long ms, totoms; + sigset_t save, mask, *arg; + STRACE("sigsuspend(%s) → ...", __strace_sigset(buf, sizeof(buf), 0, ignore)); + if (IsAsan() && ignore && !__asan_is_valid(ignore, sizeof(*ignore))) { + rc = efault(); + } else if (IsXnu() || IsOpenbsd()) { + // openbsd and xnu only support 32 signals + // they use a register calling convention for sigsuspend + if (ignore) { + arg = (sigset_t *)(uintptr_t)(*(uint32_t *)ignore); + } else { + arg = 0; + } + rc = sys_sigsuspend(arg, 8); + } else if (IsLinux() || IsFreebsd() || IsNetbsd() || IsWindows()) { + if (ignore) { + arg = ignore; + } else { + sigemptyset(&mask); + arg = &mask; + } + if (!IsWindows()) { + rc = sys_sigsuspend(arg, 8); + } else { + __sig_mask(SIG_SETMASK, arg, &save); + ms = 0; + totoms = 0; + do { + if (_check_interrupts(false, g_fds.p)) { + rc = eintr(); + break; + } + if (SleepEx(__SIG_POLLING_INTERVAL_MS, true) == kNtWaitIoCompletion) { + POLLTRACE("IOCP EINTR"); + continue; + } +#if defined(SYSDEBUG) && defined(_POLLTRACE) + ms += __SIG_POLLING_INTERVAL_MS; + if (ms >= __SIG_LOGGING_INTERVAL_MS) { + totoms += ms, ms = 0; + POLLTRACE("... sigsuspending for %'lums...", totoms); + } +#endif + } while (1); + __sig_mask(SIG_SETMASK, &save, 0); + } } else { - return enosys(); /* TODO(jart): Implement me! */ + // TODO(jart): sigsuspend metal support + rc = enosys(); } + STRACE("...sigsuspend → %d% m", rc); + return rc; } diff --git a/libc/calls/sigwinch-nt.c b/libc/calls/sigwinch-nt.c new file mode 100644 index 000000000..c941b7524 --- /dev/null +++ b/libc/calls/sigwinch-nt.c @@ -0,0 +1,57 @@ +/*-*- 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/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/winsize.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nt/struct/consolescreenbufferinfoex.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" + +static struct winsize __ws; + +textwindows void _check_sigwinch(struct Fd *fd) { + int e; + siginfo_t si; + struct winsize ws, old; + struct NtConsoleScreenBufferInfoEx sbinfo; + old = __ws; + e = errno; + if (old.ws_row != 0xffff) { + if (ioctl_tiocgwinsz_nt(fd, &ws) != -1) { + if (old.ws_col != ws.ws_col || old.ws_row != ws.ws_row) { + __ws = ws; + if (old.ws_col | old.ws_row) { + __sig_add(SIGWINCH, SI_KERNEL); + } + } + } else { + if (!old.ws_row && !old.ws_col) { + __ws.ws_row = 0xffff; + } + } + } + errno = e; +} diff --git a/libc/calls/sleep.c b/libc/calls/sleep.c index b843b9183..19810c82f 100644 --- a/libc/calls/sleep.c +++ b/libc/calls/sleep.c @@ -16,12 +16,16 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/timespec.h" +#include "libc/sysv/errfuns.h" #include "libc/time/time.h" /** * Sleeps for a particular amount of time. * @asyncsignalsafe + * @norestart */ int sleep(uint32_t seconds) { return nanosleep(&(struct timespec){seconds, 0}, NULL); diff --git a/libc/calls/splice.c b/libc/calls/splice.c index bfe272af7..08cf2d8fc 100644 --- a/libc/calls/splice.c +++ b/libc/calls/splice.c @@ -32,9 +32,10 @@ static ssize_t splicer(int infd, int64_t *inoffset, int outfd, if (!uptobytes || flags == -1) return einval(); if (IsModeDbg() && uptobytes > 1) uptobytes >>= 1; olderr = errno; - if ((transferred = + if (__isfdkind(infd, kFdZip) || __isfdkind(outfd, kFdZip) || + (transferred = impl(infd, inoffset, outfd, outoffset, uptobytes, flags)) == -1 && - errno == ENOSYS) { + errno == ENOSYS) { errno = olderr; transferred = copyfd(infd, inoffset, outfd, outoffset, uptobytes, flags); } diff --git a/libc/calls/stat2cosmo.c b/libc/calls/stat2cosmo.c index b6c76763b..c4e28281e 100644 --- a/libc/calls/stat2cosmo.c +++ b/libc/calls/stat2cosmo.c @@ -24,6 +24,10 @@ void __stat2cosmo(struct stat *restrict st, const union metastat *ms) { if (st) { if (IsLinux()) { st->st_birthtim = st->st_ctim; + if (st->st_atim.tv_sec < st->st_ctim.tv_sec) + st->st_birthtim = st->st_atim; + if (st->st_mtim.tv_sec < st->st_ctim.tv_sec) + st->st_birthtim = st->st_mtim; } else if (IsXnu()) { st->st_dev = ms->xnu.st_dev; st->st_ino = ms->xnu.st_ino; diff --git a/libc/calls/strace.internal.h b/libc/calls/strace.internal.h new file mode 100644 index 000000000..509bfcd8f --- /dev/null +++ b/libc/calls/strace.internal.h @@ -0,0 +1,67 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_ +#include "libc/calls/struct/iovec.h" +#include "libc/calls/struct/rlimit.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/stat.h" + +#define _KERNTRACE 0 /* not configurable w/ flag yet */ +#define _POLLTRACE 0 /* not configurable w/ flag yet */ +#define _DATATRACE 1 /* not configurable w/ flag yet */ +#define _NTTRACE 0 /* not configurable w/ flag yet */ + +#define STRACE_PROLOGUE "%rSYS %5P %'18T " + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#ifdef SYSDEBUG +#define STRACE(FMT, ...) \ + do { \ + if (__strace > 0) { \ + __stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__); \ + } \ + } while (0) +#else +#define STRACE(FMT, ...) (void)0 +#endif + +#if defined(SYSDEBUG) && _DATATRACE +#define DATATRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) +#else +#define DATATRACE(FMT, ...) (void)0 +#endif + +#if defined(SYSDEBUG) && _POLLTRACE +#define POLLTRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) +#else +#define POLLTRACE(FMT, ...) (void)0 +#endif + +#if defined(SYSDEBUG) && _KERNTRACE +#define KERNTRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) +#else +#define KERNTRACE(FMT, ...) (void)0 +#endif + +#if defined(SYSDEBUG) && _NTTRACE +#define NTTRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) +#else +#define NTTRACE(FMT, ...) (void)0 +#endif + +extern int __strace; + +void __stracef(const char *, ...); +void __strace_iov(const struct iovec *, int, ssize_t); +const char *__strace_stat(int, const struct stat *); +const char *__strace_sigaction(char *, size_t, int, const struct sigaction *); +const char *__strace_sigset(char[41], size_t, int, const sigset_t *); +const char *__strace_rlimit_name(int); +const char *__strace_rlimit(char[41], size_t, int, const struct rlimit *); +const char *__strace_timespec(char[45], size_t, int, const struct timespec *); +const char *__strace_dirfd(char[12], int); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_ */ diff --git a/libc/calls/strace_dirfd.greg.c b/libc/calls/strace_dirfd.greg.c new file mode 100644 index 000000000..7b60493a5 --- /dev/null +++ b/libc/calls/strace_dirfd.greg.c @@ -0,0 +1,27 @@ +/*-*- 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/strace.internal.h" +#include "libc/fmt/itoa.h" +#include "libc/sysv/consts/at.h" + +privileged const char *__strace_dirfd(char buf[12], int dirfd) { + if (dirfd == AT_FDCWD) return "AT_FDCWD"; + FormatInt32(buf, dirfd); + return buf; +} diff --git a/libc/calls/strace_iov.greg.c b/libc/calls/strace_iov.greg.c new file mode 100644 index 000000000..7c37fe0f0 --- /dev/null +++ b/libc/calls/strace_iov.greg.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 2022 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/strace.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" + +void __strace_iov(const struct iovec *iov, int iovlen, ssize_t rem) { + int i; + kprintf("{"); + for (i = 0; rem && i < MIN(5, iovlen); ++i) { + kprintf( + "%s{%#.*hhs%s, %'zu}", i ? ", " : "", + MAX(0, MIN(40, MIN(rem, iov[i].iov_len))), iov[i].iov_base, + MAX(0, MIN(40, MIN(rem, iov[i].iov_len))) < iov[i].iov_len ? "..." : "", + iov[i].iov_len); + rem -= iov[i].iov_len; + } + kprintf("%s}", iovlen > 5 ? "..." : ""); +} diff --git a/libc/calls/strace_rlimit.c b/libc/calls/strace_rlimit.c new file mode 100644 index 000000000..b05f60f77 --- /dev/null +++ b/libc/calls/strace_rlimit.c @@ -0,0 +1,58 @@ +/*-*- 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/strace.internal.h" +#include "libc/calls/struct/rlimit.h" +#include "libc/fmt/itoa.h" +#include "libc/intrin/kprintf.h" +#include "libc/sysv/consts/rlimit.h" + +const char *__strace_rlimit_name(int resource) { + static char buf[12]; + if (resource != 127) { + if (resource == RLIMIT_AS) return "RLIMIT_AS"; + if (resource == RLIMIT_CPU) return "RLIMIT_CPU"; + if (resource == RLIMIT_FSIZE) return "RLIMIT_FSIZE"; + if (resource == RLIMIT_NPROC) return "RLIMIT_NPROC"; + if (resource == RLIMIT_NOFILE) return "RLIMIT_NOFILE"; + if (resource == RLIMIT_RSS) return "RLIMIT_RSS"; + if (resource == RLIMIT_DATA) return "RLIMIT_DATA"; + if (resource == RLIMIT_CORE) return "RLIMIT_CORE"; + if (resource == RLIMIT_STACK) return "RLIMIT_STACK"; + if (resource == RLIMIT_SIGPENDING) return "RLIMIT_SIGPENDING"; + if (resource == RLIMIT_MEMLOCK) return "RLIMIT_MEMLOCK"; + if (resource == RLIMIT_LOCKS) return "RLIMIT_LOCKS"; + if (resource == RLIMIT_MSGQUEUE) return "RLIMIT_MSGQUEUE"; + if (resource == RLIMIT_NICE) return "RLIMIT_NICE"; + if (resource == RLIMIT_RTPRIO) return "RLIMIT_RTPRIO"; + if (resource == RLIMIT_RTTIME) return "RLIMIT_RTTIME"; + if (resource == RLIMIT_SWAP) return "RLIMIT_SWAP"; + if (resource == RLIMIT_SBSIZE) return "RLIMIT_SBSIZE"; + if (resource == RLIMIT_NPTS) return "RLIMIT_NPTS"; + } + FormatInt32(buf, resource); + return buf; +} + +privileged const char *__strace_rlimit(char buf[64], size_t bufsize, int rc, + const struct rlimit *rlim) { + if (rc == -1) return "n/a"; + if (!rlim) return "NULL"; + ksnprintf(buf, bufsize, "{%'ld, %'ld}", rlim->rlim_cur, rlim->rlim_max); + return buf; +} diff --git a/libc/calls/strace_sigaction.greg.c b/libc/calls/strace_sigaction.greg.c new file mode 100644 index 000000000..e34df149b --- /dev/null +++ b/libc/calls/strace_sigaction.greg.c @@ -0,0 +1,31 @@ +/*-*- 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/strace.internal.h" +#include "libc/intrin/kprintf.h" + +privileged const char *__strace_sigaction(char *buf, size_t bufsize, int rc, + const struct sigaction *sa) { + char maskbuf[41]; + if (rc == -1) return "n/a"; + if (!sa) return "NULL"; + ksnprintf(buf, bufsize, "{.sa_handler=%p, .sa_flags=%#lx, .sa_mask=%s}", + sa->sa_handler, sa->sa_flags, + __strace_sigset(maskbuf, sizeof(maskbuf), rc, &sa->sa_mask)); + return buf; +} diff --git a/libc/calls/strace_sigset.greg.c b/libc/calls/strace_sigset.greg.c new file mode 100644 index 000000000..f083d75c6 --- /dev/null +++ b/libc/calls/strace_sigset.greg.c @@ -0,0 +1,28 @@ +/*-*- 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/strace.internal.h" +#include "libc/intrin/kprintf.h" + +privileged const char *__strace_sigset(char buf[41], size_t bufsize, int rc, + const sigset_t *ss) { + if (rc == -1) return "n/a"; + if (!ss) return "NULL"; + ksnprintf(buf, bufsize, "{%#lx, %#lx}", ss->__bits[0], ss->__bits[1]); + return buf; +} diff --git a/libc/calls/strace_stat.greg.c b/libc/calls/strace_stat.greg.c new file mode 100644 index 000000000..475e2c023 --- /dev/null +++ b/libc/calls/strace_stat.greg.c @@ -0,0 +1,29 @@ +/*-*- 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/strace.internal.h" +#include "libc/intrin/kprintf.h" + +privileged const char *__strace_stat(int rc, const struct stat *st) { + static char buf[256]; + if (rc == -1) return "n/a"; + if (!st) return "NULL"; + ksnprintf(buf, sizeof(buf), "{.st_size=%'ld, .st_mode=%#o, .st_ino=%'lu}", + st->st_size, st->st_mode, st->st_ino); + return buf; +} diff --git a/libc/calls/strace_timespec.greg.c b/libc/calls/strace_timespec.greg.c new file mode 100644 index 000000000..2e7f89475 --- /dev/null +++ b/libc/calls/strace_timespec.greg.c @@ -0,0 +1,29 @@ +/*-*- 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/strace.internal.h" +#include "libc/calls/struct/timespec.h" +#include "libc/intrin/kprintf.h" + +privileged const char *__strace_timespec(char buf[45], size_t bufsize, int rc, + const struct timespec *ts) { + if (rc == -1) return "n/a"; + if (!ts) return "NULL"; + ksnprintf(buf, bufsize, "{%ld, %ld}", ts->tv_sec, ts->tv_nsec); + return buf; +} diff --git a/libc/calls/struct/bpf.h b/libc/calls/struct/bpf.h new file mode 100644 index 000000000..1a1e896a8 --- /dev/null +++ b/libc/calls/struct/bpf.h @@ -0,0 +1,1332 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_BPF_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_BPF_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define BPF_MAXINSNS 4096 + +#define BPF_CLASS(code) ((code)&0x07) +#define BPF_LD 0x00 /* load ops */ +#define BPF_LDX 0x01 /* load into register */ +#define BPF_ST 0x02 /* store from immediate */ +#define BPF_STX 0x03 /* store from register */ +#define BPF_ALU 0x04 /* 32-bit arithmetic */ +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +#define BPF_SIZE(code) ((code)&0x18) +#define BPF_W 0x00 /* 32-bit */ +#define BPF_H 0x08 /* 16-bit */ +#define BPF_B 0x10 /* 8-bit */ + +#define BPF_MODE(code) ((code)&0xe0) +#define BPF_IMM 0x00 /* 64-bit immediate */ +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +#define BPF_OP(code) ((code)&0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_MOD 0x90 +#define BPF_XOR 0xa0 + +#define BPF_SRC(code) ((code)&0x08) +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_K 0x00 +#define BPF_X 0x08 + +#define BPF_JMP32 0x06 +#define BPF_ALU64 0x07 +#define BPF_DW 0x18 +#define BPF_ATOMIC 0xc0 +#define BPF_XADD 0xc0 +#define BPF_MOV 0xb0 +#define BPF_ARSH 0xc0 +#define BPF_END 0xd0 +#define BPF_TO_LE 0x00 +#define BPF_TO_BE 0x08 +#define BPF_FROM_LE BPF_TO_LE +#define BPF_FROM_BE BPF_TO_BE +#define BPF_JNE 0x50 +#define BPF_JLT 0xa0 +#define BPF_JLE 0xb0 +#define BPF_JSGT 0x60 +#define BPF_JSGE 0x70 +#define BPF_JSLT 0xc0 +#define BPF_JSLE 0xd0 +#define BPF_CALL 0x80 +#define BPF_EXIT 0x90 +#define BPF_FETCH 0x01 +#define BPF_XCHG (0xe0 | BPF_FETCH) +#define BPF_CMPXCHG (0xf0 | BPF_FETCH) +#define MAX_BPF_REG __MAX_BPF_REG + +#define BPF_REG_0 0 +#define BPF_REG_1 1 +#define BPF_REG_2 2 +#define BPF_REG_3 3 +#define BPF_REG_4 4 +#define BPF_REG_5 5 +#define BPF_REG_6 6 +#define BPF_REG_7 7 +#define BPF_REG_8 8 +#define BPF_REG_9 9 +#define BPF_REG_10 10 +#define __MAX_BPF_REG 11 + +#define BPF_MAP_CREATE 0 +#define BPF_MAP_LOOKUP_ELEM 1 +#define BPF_MAP_UPDATE_ELEM 2 +#define BPF_MAP_DELETE_ELEM 3 +#define BPF_MAP_GET_NEXT_KEY 4 +#define BPF_PROG_LOAD 5 +#define BPF_OBJ_PIN 6 +#define BPF_OBJ_GET 7 +#define BPF_PROG_ATTACH 8 +#define BPF_PROG_DETACH 9 +#define BPF_PROG_TEST_RUN 10 +#define BPF_PROG_GET_NEXT_ID 11 +#define BPF_MAP_GET_NEXT_ID 12 +#define BPF_PROG_GET_FD_BY_ID 13 +#define BPF_MAP_GET_FD_BY_ID 14 +#define BPF_OBJ_GET_INFO_BY_FD 15 +#define BPF_PROG_QUERY 16 +#define BPF_RAW_TRACEPOINT_OPEN 17 +#define BPF_BTF_LOAD 18 +#define BPF_BTF_GET_FD_BY_ID 19 +#define BPF_TASK_FD_QUERY 20 +#define BPF_MAP_LOOKUP_AND_DELETE_ELEM 21 +#define BPF_MAP_FREEZE 22 +#define BPF_BTF_GET_NEXT_ID 23 +#define BPF_MAP_LOOKUP_BATCH 24 +#define BPF_MAP_LOOKUP_AND_DELETE_BATCH 25 +#define BPF_MAP_UPDATE_BATCH 26 +#define BPF_MAP_DELETE_BATCH 27 +#define BPF_LINK_CREATE 28 +#define BPF_LINK_UPDATE 29 +#define BPF_LINK_GET_FD_BY_ID 30 +#define BPF_LINK_GET_NEXT_ID 31 +#define BPF_ENABLE_STATS 32 +#define BPF_ITER_CREATE 33 +#define BPF_LINK_DETACH 34 +#define BPF_PROG_BIND_MAP 35 +#define BPF_PROG_RUN BPF_PROG_TEST_RUN + +#define BPF_MAP_TYPE_UNSPEC 0 +#define BPF_MAP_TYPE_HASH 1 +#define BPF_MAP_TYPE_ARRAY 2 +#define BPF_MAP_TYPE_PROG_ARRAY 3 +#define BPF_MAP_TYPE_PERF_EVENT_ARRAY 4 +#define BPF_MAP_TYPE_PERCPU_HASH 5 +#define BPF_MAP_TYPE_PERCPU_ARRAY 6 +#define BPF_MAP_TYPE_STACK_TRACE 7 +#define BPF_MAP_TYPE_CGROUP_ARRAY 8 +#define BPF_MAP_TYPE_LRU_HASH 9 +#define BPF_MAP_TYPE_LRU_PERCPU_HASH 10 +#define BPF_MAP_TYPE_LPM_TRIE 11 +#define BPF_MAP_TYPE_ARRAY_OF_MAPS 12 +#define BPF_MAP_TYPE_HASH_OF_MAPS 13 +#define BPF_MAP_TYPE_DEVMAP 14 +#define BPF_MAP_TYPE_SOCKMAP 15 +#define BPF_MAP_TYPE_CPUMAP 16 +#define BPF_MAP_TYPE_XSKMAP 17 +#define BPF_MAP_TYPE_SOCKHASH 18 +#define BPF_MAP_TYPE_CGROUP_STORAGE 19 +#define BPF_MAP_TYPE_REUSEPORT_SOCKARRAY 20 +#define BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE 21 +#define BPF_MAP_TYPE_QUEUE 22 +#define BPF_MAP_TYPE_STACK 23 +#define BPF_MAP_TYPE_SK_STORAGE 24 +#define BPF_MAP_TYPE_DEVMAP_HASH 25 +#define BPF_MAP_TYPE_STRUCT_OPS 26 +#define BPF_MAP_TYPE_RINGBUF 27 +#define BPF_MAP_TYPE_INODE_STORAGE 28 +#define BPF_MAP_TYPE_TASK_STORAGE 29 + +#define BPF_PROG_TYPE_UNSPEC 0 +#define BPF_PROG_TYPE_SOCKET_FILTER 1 +#define BPF_PROG_TYPE_KPROBE 2 +#define BPF_PROG_TYPE_SCHED_CLS 3 +#define BPF_PROG_TYPE_SCHED_ACT 4 +#define BPF_PROG_TYPE_TRACEPOINT 5 +#define BPF_PROG_TYPE_XDP 6 +#define BPF_PROG_TYPE_PERF_EVENT 7 +#define BPF_PROG_TYPE_CGROUP_SKB 8 +#define BPF_PROG_TYPE_CGROUP_SOCK 9 +#define BPF_PROG_TYPE_LWT_IN 10 +#define BPF_PROG_TYPE_LWT_OUT 11 +#define BPF_PROG_TYPE_LWT_XMIT 12 +#define BPF_PROG_TYPE_SOCK_OPS 13 +#define BPF_PROG_TYPE_SK_SKB 14 +#define BPF_PROG_TYPE_CGROUP_DEVICE 15 +#define BPF_PROG_TYPE_SK_MSG 16 +#define BPF_PROG_TYPE_RAW_TRACEPOINT 17 +#define BPF_PROG_TYPE_CGROUP_SOCK_ADDR 18 +#define BPF_PROG_TYPE_LWT_SEG6LOCAL 19 +#define BPF_PROG_TYPE_LIRC_MODE2 20 +#define BPF_PROG_TYPE_SK_REUSEPORT 21 +#define BPF_PROG_TYPE_FLOW_DISSECTOR 22 +#define BPF_PROG_TYPE_CGROUP_SYSCTL 23 +#define BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE 24 +#define BPF_PROG_TYPE_CGROUP_SOCKOPT 25 +#define BPF_PROG_TYPE_TRACING 26 +#define BPF_PROG_TYPE_STRUCT_OPS 27 +#define BPF_PROG_TYPE_EXT 28 +#define BPF_PROG_TYPE_LSM 29 +#define BPF_PROG_TYPE_SK_LOOKUP 30 +#define BPF_PROG_TYPE_SYSCALL 31 + +#define BPF_CGROUP_INET_INGRESS 0 +#define BPF_CGROUP_INET_EGRESS 1 +#define BPF_CGROUP_INET_SOCK_CREATE 2 +#define BPF_CGROUP_SOCK_OPS 3 +#define BPF_SK_SKB_STREAM_PARSER 4 +#define BPF_SK_SKB_STREAM_VERDICT 5 +#define BPF_CGROUP_DEVICE 6 +#define BPF_SK_MSG_VERDICT 7 +#define BPF_CGROUP_INET4_BIND 8 +#define BPF_CGROUP_INET6_BIND 9 +#define BPF_CGROUP_INET4_CONNECT 10 +#define BPF_CGROUP_INET6_CONNECT 11 +#define BPF_CGROUP_INET4_POST_BIND 12 +#define BPF_CGROUP_INET6_POST_BIND 13 +#define BPF_CGROUP_UDP4_SENDMSG 14 +#define BPF_CGROUP_UDP6_SENDMSG 15 +#define BPF_LIRC_MODE2 16 +#define BPF_FLOW_DISSECTOR 17 +#define BPF_CGROUP_SYSCTL 18 +#define BPF_CGROUP_UDP4_RECVMSG 19 +#define BPF_CGROUP_UDP6_RECVMSG 20 +#define BPF_CGROUP_GETSOCKOPT 21 +#define BPF_CGROUP_SETSOCKOPT 22 +#define BPF_TRACE_RAW_TP 23 +#define BPF_TRACE_FENTRY 24 +#define BPF_TRACE_FEXIT 25 +#define BPF_MODIFY_RETURN 26 +#define BPF_LSM_MAC 27 +#define BPF_TRACE_ITER 28 +#define BPF_CGROUP_INET4_GETPEERNAME 29 +#define BPF_CGROUP_INET6_GETPEERNAME 30 +#define BPF_CGROUP_INET4_GETSOCKNAME 31 +#define BPF_CGROUP_INET6_GETSOCKNAME 32 +#define BPF_XDP_DEVMAP 33 +#define BPF_CGROUP_INET_SOCK_RELEASE 34 +#define BPF_XDP_CPUMAP 35 +#define BPF_SK_LOOKUP 36 +#define BPF_XDP 37 +#define BPF_SK_SKB_VERDICT 38 +#define BPF_SK_REUSEPORT_SELECT 39 +#define BPF_SK_REUSEPORT_SELECT_OR_MIGRATE 40 +#define __MAX_BPF_ATTACH_TYPE 41 + +#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE + +#define BPF_LINK_TYPE_UNSPEC 0 +#define BPF_LINK_TYPE_RAW_TRACEPOINT 1 +#define BPF_LINK_TYPE_TRACING 2 +#define BPF_LINK_TYPE_CGROUP 3 +#define BPF_LINK_TYPE_ITER 4 +#define BPF_LINK_TYPE_NETNS 5 +#define BPF_LINK_TYPE_XDP 6 +#define MAX_BPF_LINK_TYPE 7 + +#define BPF_F_ALLOW_OVERRIDE (1U << 0) +#define BPF_F_ALLOW_MULTI (1U << 1) +#define BPF_F_REPLACE (1U << 2) +#define BPF_F_STRICT_ALIGNMENT (1U << 0) +#define BPF_F_ANY_ALIGNMENT (1U << 1) +#define BPF_F_TEST_RND_HI32 (1U << 2) +#define BPF_F_TEST_STATE_FREQ (1U << 3) +#define BPF_F_SLEEPABLE (1U << 4) +#define BPF_PSEUDO_MAP_FD 1 +#define BPF_PSEUDO_MAP_IDX 5 +#define BPF_PSEUDO_MAP_VALUE 2 +#define BPF_PSEUDO_MAP_IDX_VALUE 6 +#define BPF_PSEUDO_BTF_ID 3 +#define BPF_PSEUDO_FUNC 4 +#define BPF_PSEUDO_CALL 1 +#define BPF_PSEUDO_KFUNC_CALL 2 + +#define BPF_ANY 0 +#define BPF_NOEXIST 1 +#define BPF_EXIST 2 +#define BPF_F_LOCK 4 +#define BPF_F_NO_PREALLOC (1U << 0) +#define BPF_F_NO_COMMON_LRU (1U << 1) +#define BPF_F_NUMA_NODE (1U << 2) +#define BPF_F_RDONLY (1U << 3) +#define BPF_F_WRONLY (1U << 4) +#define BPF_F_STACK_BUILD_ID (1U << 5) +#define BPF_F_ZERO_SEED (1U << 6) +#define BPF_F_RDONLY_PROG (1U << 7) +#define BPF_F_WRONLY_PROG (1U << 8) +#define BPF_F_CLONE (1U << 9) +#define BPF_F_MMAPABLE (1U << 10) +#define BPF_F_PRESERVE_ELEMS (1U << 11) +#define BPF_F_INNER_MAP (1U << 12) +#define BPF_F_QUERY_EFFECTIVE (1U << 0) +#define BPF_F_TEST_RUN_ON_CPU (1U << 0) + +#define BPF_STATS_RUN_TIME 0 +#define BPF_STACK_BUILD_ID_EMPTY 0 +#define BPF_STACK_BUILD_ID_VALID 1 +#define BPF_STACK_BUILD_ID_IP 2 +#define BPF_BUILD_ID_SIZE 20 +#define BPF_OBJ_NAME_LEN 16U + +#define BPF_F_RECOMPUTE_CSUM (1ULL << 0) +#define BPF_F_INVALIDATE_HASH (1ULL << 1) +#define BPF_F_HDR_FIELD_MASK 0xfULL +#define BPF_F_PSEUDO_HDR (1ULL << 4) +#define BPF_F_MARK_MANGLED_0 (1ULL << 5) +#define BPF_F_MARK_ENFORCE (1ULL << 6) +#define BPF_F_INGRESS (1ULL << 0) +#define BPF_F_TUNINFO_IPV6 (1ULL << 0) +#define BPF_F_SKIP_FIELD_MASK 0xffULL +#define BPF_F_USER_STACK (1ULL << 8) +#define BPF_F_FAST_STACK_CMP (1ULL << 9) +#define BPF_F_REUSE_STACKID (1ULL << 10) +#define BPF_F_USER_BUILD_ID (1ULL << 11) +#define BPF_F_ZERO_CSUM_TX (1ULL << 1) +#define BPF_F_DONT_FRAGMENT (1ULL << 2) +#define BPF_F_SEQ_NUMBER (1ULL << 3) +#define BPF_F_INDEX_MASK 0xffffffffULL +#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK +#define BPF_F_CTXLEN_MASK (0xfffffULL << 32) +#define BPF_F_CURRENT_NETNS (-1L) + +#define BPF_CSUM_LEVEL_QUERY 0 +#define BPF_CSUM_LEVEL_INC 1 +#define BPF_CSUM_LEVEL_DEC 2 +#define BPF_CSUM_LEVEL_RESET 3 + +#define BPF_F_ADJ_ROOM_FIXED_GSO (1ULL << 0) +#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 (1ULL << 1) +#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 (1ULL << 2) +#define BPF_F_ADJ_ROOM_ENCAP_L4_GRE (1ULL << 3) +#define BPF_F_ADJ_ROOM_ENCAP_L4_UDP (1ULL << 4) +#define BPF_F_ADJ_ROOM_NO_CSUM_RESET (1ULL << 5) +#define BPF_F_ADJ_ROOM_ENCAP_L2_ETH (1ULL << 6) +#define BPF_ADJ_ROOM_ENCAP_L2_MASK 0xff +#define BPF_ADJ_ROOM_ENCAP_L2_SHIFT 56 + +#define BPF_F_ADJ_ROOM_ENCAP_L2(len) \ + (((uint64_t)len & BPF_ADJ_ROOM_ENCAP_L2_MASK) << BPF_ADJ_ROOM_ENCAP_L2_SHIFT) + +#define BPF_F_SYSCTL_BASE_NAME (1ULL << 0) +#define BPF_LOCAL_STORAGE_GET_F_CREATE (1ULL << 0) +#define BPF_SK_STORAGE_GET_F_CREATE BPF_LOCAL_STORAGE_GET_F_CREATE +#define BPF_F_GET_BRANCH_RECORDS_SIZE (1ULL << 0) +#define BPF_RB_NO_WAKEUP (1ULL << 0) +#define BPF_RB_FORCE_WAKEUP (1ULL << 1) +#define BPF_RB_AVAIL_DATA 0 +#define BPF_RB_RING_SIZE 1 +#define BPF_RB_CONS_POS 2 +#define BPF_RB_PROD_POS 3 +#define BPF_RINGBUF_BUSY_BIT (1U << 31) +#define BPF_RINGBUF_DISCARD_BIT (1U << 30) +#define BPF_RINGBUF_HDR_SZ 8 +#define BPF_SK_LOOKUP_F_REPLACE (1ULL << 0) +#define BPF_SK_LOOKUP_F_NO_REUSEPORT (1ULL << 1) + +#define BPF_ADJ_ROOM_NET 0 +#define BPF_ADJ_ROOM_MAC 1 +#define BPF_HDR_START_MAC 0 +#define BPF_HDR_START_NET 1 +#define BPF_LWT_ENCAP_SEG6 0 +#define BPF_LWT_ENCAP_SEG6_INLINE 1 +#define BPF_LWT_ENCAP_IP 2 +#define BPF_F_BPRM_SECUREEXEC (1ULL << 0) +#define BPF_F_BROADCAST (1ULL << 3) +#define BPF_F_EXCLUDE_INGRESS (1ULL << 4) + +#define XDP_PACKET_HEADROOM 256 +#define BPF_TAG_SIZE 8 + +#define BPF_SOCK_OPS_RTO_CB_FLAG (1 << 0) +#define BPF_SOCK_OPS_RETRANS_CB_FLAG (1 << 1) +#define BPF_SOCK_OPS_STATE_CB_FLAG (1 << 2) +#define BPF_SOCK_OPS_RTT_CB_FLAG (1 << 3) +#define BPF_SOCK_OPS_PARSE_ALL_HDR_OPT_CB_FLAG (1 << 4) +#define BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG (1 << 5) +#define BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG (1 << 6) +#define BPF_SOCK_OPS_ALL_CB_FLAGS 0x7F + +#define BPF_SOCK_OPS_VOID 0 +#define BPF_SOCK_OPS_TIMEOUT_INIT 1 +#define BPF_SOCK_OPS_RWND_INIT 2 +#define BPF_SOCK_OPS_TCP_CONNECT_CB 3 +#define BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB 4 +#define BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB 5 +#define BPF_SOCK_OPS_NEEDS_ECN 6 +#define BPF_SOCK_OPS_BASE_RTT 7 +#define BPF_SOCK_OPS_RTO_CB 8 +#define BPF_SOCK_OPS_RETRANS_CB 9 +#define BPF_SOCK_OPS_STATE_CB 10 +#define BPF_SOCK_OPS_TCP_LISTEN_CB 11 +#define BPF_SOCK_OPS_RTT_CB 12 +#define BPF_SOCK_OPS_PARSE_HDR_OPT_CB 13 +#define BPF_SOCK_OPS_HDR_OPT_LEN_CB 14 +#define BPF_SOCK_OPS_WRITE_HDR_OPT_CB 15 + +#define BPF_TCP_ESTABLISHED 1 +#define BPF_TCP_SYN_SENT 2 +#define BPF_TCP_SYN_RECV 3 +#define BPF_TCP_FIN_WAIT1 4 +#define BPF_TCP_FIN_WAIT2 5 +#define BPF_TCP_TIME_WAIT 6 +#define BPF_TCP_CLOSE 7 +#define BPF_TCP_CLOSE_WAIT 8 +#define BPF_TCP_LAST_ACK 9 +#define BPF_TCP_LISTEN 10 +#define BPF_TCP_CLOSING 11 +#define BPF_TCP_NEW_SYN_RECV 12 +#define BPF_TCP_MAX_STATES 13 + +#define TCP_BPF_IW 1001 +#define TCP_BPF_SNDCWND_CLAMP 1002 +#define TCP_BPF_DELACK_MAX 1003 +#define TCP_BPF_RTO_MIN 1004 +#define TCP_BPF_SYN 1005 +#define TCP_BPF_SYN_IP 1006 +#define TCP_BPF_SYN_MAC 1007 +#define BPF_LOAD_HDR_OPT_TCP_SYN (1ULL << 0) +#define BPF_WRITE_HDR_TCP_CURRENT_MSS 1 +#define BPF_WRITE_HDR_TCP_SYNACK_COOKIE 2 + +#define BPF_DEVCG_ACC_MKNOD (1ULL << 0) +#define BPF_DEVCG_ACC_READ (1ULL << 1) +#define BPF_DEVCG_ACC_WRITE (1ULL << 2) +#define BPF_DEVCG_DEV_BLOCK (1ULL << 0) +#define BPF_DEVCG_DEV_CHAR (1ULL << 1) + +#define BPF_FIB_LOOKUP_DIRECT (1U << 0) +#define BPF_FIB_LOOKUP_OUTPUT (1U << 1) + +#define BPF_FIB_LKUP_RET_SUCCESS 0 +#define BPF_FIB_LKUP_RET_BLACKHOLE 1 +#define BPF_FIB_LKUP_RET_UNREACHABLE 2 +#define BPF_FIB_LKUP_RET_PROHIBIT 3 +#define BPF_FIB_LKUP_RET_NOT_FWDED 4 +#define BPF_FIB_LKUP_RET_FWD_DISABLED 5 +#define BPF_FIB_LKUP_RET_UNSUPP_LWT 6 +#define BPF_FIB_LKUP_RET_NO_NEIGH 7 +#define BPF_FIB_LKUP_RET_FRAG_NEEDED 8 + +#define BPF_MTU_CHK_SEGS (1U << 0) +#define BPF_MTU_CHK_RET_SUCCESS 0 +#define BPF_MTU_CHK_RET_FRAG_NEEDED 1 +#define BPF_MTU_CHK_RET_SEGS_TOOBIG 2 +#define BPF_FD_TYPE_RAW_TRACEPOINT 0 +#define BPF_FD_TYPE_TRACEPOINT 1 +#define BPF_FD_TYPE_KPROBE 2 +#define BPF_FD_TYPE_KRETPROBE 3 +#define BPF_FD_TYPE_UPROBE 4 +#define BPF_FD_TYPE_URETPROBE 5 +#define BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG (1U << 0) +#define BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL (1U << 1) +#define BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP (1U << 2) + +#define BPF_LINE_INFO_LINE_NUM(line_col) ((line_col) >> 10) +#define BPF_LINE_INFO_LINE_COL(line_col) ((line_col)&0x3ff) + +#define BTF_F_COMPACT (1ULL << 0) +#define BTF_F_NONAME (1ULL << 1) +#define BTF_F_PTR_RAW (1ULL << 2) +#define BTF_F_ZERO (1ULL << 3) + +#define BPF_OK 0 +#define BPF_DROP 2 +#define BPF_REDIRECT 7 +#define BPF_LWT_REROUTE 128 + +#define BPF_FUNC_unspec 0 +#define BPF_FUNC_map_lookup_elem 1 +#define BPF_FUNC_map_update_elem 2 +#define BPF_FUNC_map_delete_elem 3 +#define BPF_FUNC_probe_read 4 +#define BPF_FUNC_ktime_get_ns 5 +#define BPF_FUNC_trace_printk 6 +#define BPF_FUNC_get_prandom_u32 7 +#define BPF_FUNC_get_smp_processor_id 8 +#define BPF_FUNC_skb_store_bytes 9 +#define BPF_FUNC_l3_csum_replace 10 +#define BPF_FUNC_l4_csum_replace 11 +#define BPF_FUNC_tail_call 12 +#define BPF_FUNC_clone_redirect 13 +#define BPF_FUNC_get_current_pid_tgid 14 +#define BPF_FUNC_get_current_uid_gid 15 +#define BPF_FUNC_get_current_comm 16 +#define BPF_FUNC_get_cgroup_classid 17 +#define BPF_FUNC_skb_vlan_push 18 +#define BPF_FUNC_skb_vlan_pop 19 +#define BPF_FUNC_skb_get_tunnel_key 20 +#define BPF_FUNC_skb_set_tunnel_key 21 +#define BPF_FUNC_perf_event_read 22 +#define BPF_FUNC_redirect 23 +#define BPF_FUNC_get_route_realm 24 +#define BPF_FUNC_perf_event_output 25 +#define BPF_FUNC_skb_load_bytes 26 +#define BPF_FUNC_get_stackid 27 +#define BPF_FUNC_csum_diff 28 +#define BPF_FUNC_skb_get_tunnel_opt 29 +#define BPF_FUNC_skb_set_tunnel_opt 30 +#define BPF_FUNC_skb_change_proto 31 +#define BPF_FUNC_skb_change_type 32 +#define BPF_FUNC_skb_under_cgroup 33 +#define BPF_FUNC_get_hash_recalc 34 +#define BPF_FUNC_get_current_task 35 +#define BPF_FUNC_probe_write_user 36 +#define BPF_FUNC_current_task_under_cgroup 37 +#define BPF_FUNC_skb_change_tail 38 +#define BPF_FUNC_skb_pull_data 39 +#define BPF_FUNC_csum_update 40 +#define BPF_FUNC_set_hash_invalid 41 +#define BPF_FUNC_get_numa_node_id 42 +#define BPF_FUNC_skb_change_head 43 +#define BPF_FUNC_xdp_adjust_head 44 +#define BPF_FUNC_probe_read_str 45 +#define BPF_FUNC_get_socket_cookie 46 +#define BPF_FUNC_get_socket_uid 47 +#define BPF_FUNC_set_hash 48 +#define BPF_FUNC_setsockopt 49 +#define BPF_FUNC_skb_adjust_room 50 +#define BPF_FUNC_redirect_map 51 +#define BPF_FUNC_sk_redirect_map 52 +#define BPF_FUNC_sock_map_update 53 +#define BPF_FUNC_xdp_adjust_meta 54 +#define BPF_FUNC_perf_event_read_value 55 +#define BPF_FUNC_perf_prog_read_value 56 +#define BPF_FUNC_getsockopt 57 +#define BPF_FUNC_override_return 58 +#define BPF_FUNC_sock_ops_cb_flags_set 59 +#define BPF_FUNC_msg_redirect_map 60 +#define BPF_FUNC_msg_apply_bytes 61 +#define BPF_FUNC_msg_cork_bytes 62 +#define BPF_FUNC_msg_pull_data 63 +#define BPF_FUNC_bind 64 +#define BPF_FUNC_xdp_adjust_tail 65 +#define BPF_FUNC_skb_get_xfrm_state 66 +#define BPF_FUNC_get_stack 67 +#define BPF_FUNC_skb_load_bytes_relative 68 +#define BPF_FUNC_fib_lookup 69 +#define BPF_FUNC_sock_hash_update 70 +#define BPF_FUNC_msg_redirect_hash 71 +#define BPF_FUNC_sk_redirect_hash 72 +#define BPF_FUNC_lwt_push_encap 73 +#define BPF_FUNC_lwt_seg6_store_bytes 74 +#define BPF_FUNC_lwt_seg6_adjust_srh 75 +#define BPF_FUNC_lwt_seg6_action 76 +#define BPF_FUNC_rc_repeat 77 +#define BPF_FUNC_rc_keydown 78 +#define BPF_FUNC_skb_cgroup_id 79 +#define BPF_FUNC_get_current_cgroup_id 80 +#define BPF_FUNC_get_local_storage 81 +#define BPF_FUNC_sk_select_reuseport 82 +#define BPF_FUNC_skb_ancestor_cgroup_id 83 +#define BPF_FUNC_sk_lookup_tcp 84 +#define BPF_FUNC_sk_lookup_udp 85 +#define BPF_FUNC_sk_release 86 +#define BPF_FUNC_map_push_elem 87 +#define BPF_FUNC_map_pop_elem 88 +#define BPF_FUNC_map_peek_elem 89 +#define BPF_FUNC_msg_push_data 90 +#define BPF_FUNC_msg_pop_data 91 +#define BPF_FUNC_rc_pointer_rel 92 +#define BPF_FUNC_spin_lock 93 +#define BPF_FUNC_spin_unlock 94 +#define BPF_FUNC_sk_fullsock 95 +#define BPF_FUNC_tcp_sock 96 +#define BPF_FUNC_skb_ecn_set_ce 97 +#define BPF_FUNC_get_listener_sock 98 +#define BPF_FUNC_skc_lookup_tcp 99 +#define BPF_FUNC_tcp_check_syncookie 100 +#define BPF_FUNC_sysctl_get_name 101 +#define BPF_FUNC_sysctl_get_current_value 102 +#define BPF_FUNC_sysctl_get_new_value 103 +#define BPF_FUNC_sysctl_set_new_value 104 +#define BPF_FUNC_strtol 105 +#define BPF_FUNC_strtoul 106 +#define BPF_FUNC_sk_storage_get 107 +#define BPF_FUNC_sk_storage_delete 108 +#define BPF_FUNC_send_signal 109 +#define BPF_FUNC_tcp_gen_syncookie 110 +#define BPF_FUNC_skb_output 111 +#define BPF_FUNC_probe_read_user 112 +#define BPF_FUNC_probe_read_kernel 113 +#define BPF_FUNC_probe_read_user_str 114 +#define BPF_FUNC_probe_read_kernel_str 115 +#define BPF_FUNC_tcp_send_ack 116 +#define BPF_FUNC_send_signal_thread 117 +#define BPF_FUNC_jiffies64 118 +#define BPF_FUNC_read_branch_records 119 +#define BPF_FUNC_get_ns_current_pid_tgid 120 +#define BPF_FUNC_xdp_output 121 +#define BPF_FUNC_get_netns_cookie 122 +#define BPF_FUNC_get_current_ancestor_cgroup_id 123 +#define BPF_FUNC_sk_assign 124 +#define BPF_FUNC_ktime_get_boot_ns 125 +#define BPF_FUNC_seq_printf 126 +#define BPF_FUNC_seq_write 127 +#define BPF_FUNC_sk_cgroup_id 128 +#define BPF_FUNC_sk_ancestor_cgroup_id 129 +#define BPF_FUNC_ringbuf_output 130 +#define BPF_FUNC_ringbuf_reserve 131 +#define BPF_FUNC_ringbuf_submit 132 +#define BPF_FUNC_ringbuf_discard 133 +#define BPF_FUNC_ringbuf_query 134 +#define BPF_FUNC_csum_level 135 +#define BPF_FUNC_skc_to_tcp6_sock 136 +#define BPF_FUNC_skc_to_tcp_sock 137 +#define BPF_FUNC_skc_to_tcp_timewait_sock 138 +#define BPF_FUNC_skc_to_tcp_request_sock 139 +#define BPF_FUNC_skc_to_udp6_sock 140 +#define BPF_FUNC_get_task_stack 141 +#define BPF_FUNC_load_hdr_opt 142 +#define BPF_FUNC_store_hdr_opt 143 +#define BPF_FUNC_reserve_hdr_opt 144 +#define BPF_FUNC_inode_storage_get 145 +#define BPF_FUNC_inode_storage_delete 146 +#define BPF_FUNC_d_path 147 +#define BPF_FUNC_copy_from_user 148 +#define BPF_FUNC_snprintf_btf 149 +#define BPF_FUNC_seq_printf_btf 150 +#define BPF_FUNC_skb_cgroup_classid 151 +#define BPF_FUNC_redirect_neigh 152 +#define BPF_FUNC_per_cpu_ptr 153 +#define BPF_FUNC_this_cpu_ptr 154 +#define BPF_FUNC_redirect_peer 155 +#define BPF_FUNC_task_storage_get 156 +#define BPF_FUNC_task_storage_delete 157 +#define BPF_FUNC_get_current_task_btf 158 +#define BPF_FUNC_bprm_opts_set 159 +#define BPF_FUNC_ktime_get_coarse_ns 160 +#define BPF_FUNC_ima_inode_hash 161 +#define BPF_FUNC_sock_from_file 162 +#define BPF_FUNC_check_mtu 163 +#define BPF_FUNC_for_each_map_elem 164 +#define BPF_FUNC_snprintf 165 +#define BPF_FUNC_sys_bpf 166 +#define BPF_FUNC_btf_find_by_name_kind 167 +#define BPF_FUNC_sys_close 168 +#define __BPF_FUNC_MAX_ID 169 + +#define __bpf_md_ptr(type, name) \ + union { \ + type name; \ + uint64_t : 64; \ + } forcealign(8) + +struct bpf_insn { + uint8_t code; + uint8_t dst_reg : 4; + uint8_t src_reg : 4; + int16_t off; + int32_t imm; +}; + +struct bpf_lpm_trie_key { + uint32_t prefixlen; + uint8_t data[0]; +}; + +struct bpf_cgroup_storage_key { + uint64_t cgroup_inode_id; + uint32_t attach_type; +}; + +union bpf_iter_link_info { + struct { + uint32_t map_fd; + } map; +}; + +struct bpf_stack_build_id { + int32_t status; + unsigned char build_id[BPF_BUILD_ID_SIZE]; + union { + uint64_t offset; + uint64_t ip; + }; +}; + +union bpf_attr { + struct { + uint32_t map_type; + uint32_t key_size; + uint32_t value_size; + uint32_t max_entries; + uint32_t map_flags; + uint32_t inner_map_fd; + uint32_t numa_node; + char map_name[BPF_OBJ_NAME_LEN]; + uint32_t map_ifindex; + uint32_t btf_fd; + uint32_t btf_key_type_id; + uint32_t btf_value_type_id; + uint32_t btf_vmlinux_value_type_id; + }; + struct { + uint32_t map_fd; + uint64_t key; + union { + uint64_t value; + uint64_t next_key; + }; + uint64_t flags; + }; + struct { + uint64_t in_batch; + uint64_t out_batch; + uint64_t keys; + uint64_t values; + uint32_t count; + uint32_t map_fd; + uint64_t elem_flags; + uint64_t flags; + } batch; + struct { + uint32_t prog_type; + uint32_t insn_cnt; + uint64_t insns; + uint64_t license; + uint32_t log_level; + uint32_t log_size; + uint64_t log_buf; + uint32_t kern_version; + uint32_t prog_flags; + char prog_name[BPF_OBJ_NAME_LEN]; + uint32_t prog_ifindex; + uint32_t expected_attach_type; + uint32_t prog_btf_fd; + uint32_t func_info_rec_size; + uint64_t func_info; + uint32_t func_info_cnt; + uint32_t line_info_rec_size; + uint64_t line_info; + uint32_t line_info_cnt; + uint32_t attach_btf_id; + union { + uint32_t attach_prog_fd; + uint32_t attach_btf_obj_fd; + }; + uint32_t : 32; + uint64_t fd_array; + }; + struct { + uint64_t pathname; + uint32_t bpf_fd; + uint32_t file_flags; + }; + struct { + uint32_t target_fd; + uint32_t attach_bpf_fd; + uint32_t attach_type; + uint32_t attach_flags; + uint32_t replace_bpf_fd; + }; + struct { + uint32_t prog_fd; + uint32_t retval; + uint32_t data_size_in; + uint32_t data_size_out; + uint64_t data_in; + uint64_t data_out; + uint32_t repeat; + uint32_t duration; + uint32_t ctx_size_in; + uint32_t ctx_size_out; + uint64_t ctx_in; + uint64_t ctx_out; + uint32_t flags; + uint32_t cpu; + } test; + struct { + union { + uint32_t start_id; + uint32_t prog_id; + uint32_t map_id; + uint32_t btf_id; + uint32_t link_id; + }; + uint32_t next_id; + uint32_t open_flags; + }; + struct { + uint32_t bpf_fd; + uint32_t info_len; + uint64_t info; + } info; + struct { + uint32_t target_fd; + uint32_t attach_type; + uint32_t query_flags; + uint32_t attach_flags; + uint64_t prog_ids; + uint32_t prog_cnt; + } query; + struct { + uint64_t name; + uint32_t prog_fd; + } raw_tracepoint; + struct { + uint64_t btf; + uint64_t btf_log_buf; + uint32_t btf_size; + uint32_t btf_log_size; + uint32_t btf_log_level; + }; + struct { + uint32_t pid; + uint32_t fd; + uint32_t flags; + uint32_t buf_len; + uint64_t buf; + uint32_t prog_id; + uint32_t fd_type; + uint64_t probe_offset; + uint64_t probe_addr; + } task_fd_query; + struct { + uint32_t prog_fd; + union { + uint32_t target_fd; + uint32_t target_ifindex; + }; + uint32_t attach_type; + uint32_t flags; + union { + uint32_t target_btf_id; + struct { + uint64_t iter_info; + uint32_t iter_info_len; + }; + }; + } link_create; + struct { + uint32_t link_fd; + uint32_t new_prog_fd; + uint32_t flags; + uint32_t old_prog_fd; + } link_update; + struct { + uint32_t link_fd; + } link_detach; + struct { + uint32_t type; + } enable_stats; + struct { + uint32_t link_fd; + uint32_t flags; + } iter_create; + struct { + uint32_t prog_fd; + uint32_t map_fd; + uint32_t flags; + } prog_bind_map; +} forcealign(8); + +struct __sk_buff { + uint32_t len; + uint32_t pkt_type; + uint32_t mark; + uint32_t queue_mapping; + uint32_t protocol; + uint32_t vlan_present; + uint32_t vlan_tci; + uint32_t vlan_proto; + uint32_t priority; + uint32_t ingress_ifindex; + uint32_t ifindex; + uint32_t tc_index; + uint32_t cb[5]; + uint32_t hash; + uint32_t tc_classid; + uint32_t data; + uint32_t data_end; + uint32_t napi_id; + uint32_t family; + uint32_t remote_ip4; + uint32_t local_ip4; + uint32_t remote_ip6[4]; + uint32_t local_ip6[4]; + uint32_t remote_port; + uint32_t local_port; + uint32_t data_meta; + __bpf_md_ptr(struct bpf_flow_keys *, flow_keys); + uint64_t tstamp; + uint32_t wire_len; + uint32_t gso_segs; + __bpf_md_ptr(struct bpf_sock *, sk); + uint32_t gso_size; +}; + +struct bpf_tunnel_key { + uint32_t tunnel_id; + union { + uint32_t remote_ipv4; + uint32_t remote_ipv6[4]; + }; + uint8_t tunnel_tos; + uint8_t tunnel_ttl; + uint16_t tunnel_ext; + uint32_t tunnel_label; +}; + +struct bpf_xfrm_state { + uint32_t reqid; + uint32_t spi; + uint16_t family; + uint16_t ext; + union { + uint32_t remote_ipv4; + uint32_t remote_ipv6[4]; + }; +}; + +struct bpf_sock { + uint32_t bound_dev_if; + uint32_t family; + uint32_t type; + uint32_t protocol; + uint32_t mark; + uint32_t priority; + uint32_t src_ip4; + uint32_t src_ip6[4]; + uint32_t src_port; + uint32_t dst_port; + uint32_t dst_ip4; + uint32_t dst_ip6[4]; + uint32_t state; + int32_t rx_queue_mapping; +}; + +struct bpf_tcp_sock { + uint32_t snd_cwnd; + uint32_t srtt_us; + uint32_t rtt_min; + uint32_t snd_ssthresh; + uint32_t rcv_nxt; + uint32_t snd_nxt; + uint32_t snd_una; + uint32_t mss_cache; + uint32_t ecn_flags; + uint32_t rate_delivered; + uint32_t rate_interval_us; + uint32_t packets_out; + uint32_t retrans_out; + uint32_t total_retrans; + uint32_t segs_in; + uint32_t data_segs_in; + uint32_t segs_out; + uint32_t data_segs_out; + uint32_t lost_out; + uint32_t sacked_out; + uint64_t bytes_received; + uint64_t bytes_acked; + uint32_t dsack_dups; + uint32_t delivered; + uint32_t delivered_ce; + uint32_t icsk_retransmits; +}; + +struct bpf_sock_tuple { + union { + struct { + uint32_t saddr; /* big endian */ + uint32_t daddr; /* big endian */ + uint16_t sport; /* big endian */ + uint16_t dport; /* big endian */ + } ipv4; + struct { + uint32_t saddr[4]; /* big endian */ + uint32_t daddr[4]; /* big endian */ + uint16_t sport; /* big endian */ + uint16_t dport; /* big endian */ + } ipv6; + }; +}; + +struct bpf_xdp_sock { + uint32_t queue_id; +}; + +enum xdp_action { + XDP_ABORTED = 0, + XDP_DROP, + XDP_PASS, + XDP_TX, + XDP_REDIRECT, +}; + +struct xdp_md { + uint32_t data; + uint32_t data_end; + uint32_t data_meta; + uint32_t ingress_ifindex; + uint32_t rx_queue_index; + uint32_t egress_ifindex; +}; + +struct bpf_devmap_val { + uint32_t ifindex; + union { + int fd; + uint32_t id; + } bpf_prog; +}; + +struct bpf_cpumap_val { + uint32_t qsize; + union { + int fd; + uint32_t id; + } bpf_prog; +}; + +enum sk_action { + SK_DROP = 0, + SK_PASS, +}; + +struct sk_msg_md { + __bpf_md_ptr(void *, data); + __bpf_md_ptr(void *, data_end); + uint32_t family; + uint32_t remote_ip4; + uint32_t local_ip4; + uint32_t remote_ip6[4]; + uint32_t local_ip6[4]; + uint32_t remote_port; + uint32_t local_port; + uint32_t size; + __bpf_md_ptr(struct bpf_sock *, sk); +}; + +struct sk_reuseport_md { + __bpf_md_ptr(void *, data); + __bpf_md_ptr(void *, data_end); + uint32_t len; + uint32_t eth_protocol; + uint32_t ip_protocol; + uint32_t bind_inany; + uint32_t hash; + __bpf_md_ptr(struct bpf_sock *, sk); + __bpf_md_ptr(struct bpf_sock *, migrating_sk); +}; + +struct bpf_prog_info { + uint32_t type; + uint32_t id; + uint8_t tag[BPF_TAG_SIZE]; + uint32_t jited_prog_len; + uint32_t xlated_prog_len; + uint64_t jited_prog_insns; + uint64_t xlated_prog_insns; + uint64_t load_time; + uint32_t created_by_uid; + uint32_t nr_map_ids; + uint64_t map_ids; + char name[BPF_OBJ_NAME_LEN]; + uint32_t ifindex; + uint32_t gpl_compatible : 1; + uint32_t : 31; + uint64_t netns_dev; + uint64_t netns_ino; + uint32_t nr_jited_ksyms; + uint32_t nr_jited_func_lens; + uint64_t jited_ksyms; + uint64_t jited_func_lens; + uint32_t btf_id; + uint32_t func_info_rec_size; + uint64_t func_info; + uint32_t nr_func_info; + uint32_t nr_line_info; + uint64_t line_info; + uint64_t jited_line_info; + uint32_t nr_jited_line_info; + uint32_t line_info_rec_size; + uint32_t jited_line_info_rec_size; + uint32_t nr_prog_tags; + uint64_t prog_tags; + uint64_t run_time_ns; + uint64_t run_cnt; + uint64_t recursion_misses; +} forcealign(8); + +struct bpf_map_info { + uint32_t type; + uint32_t id; + uint32_t key_size; + uint32_t value_size; + uint32_t max_entries; + uint32_t map_flags; + char name[BPF_OBJ_NAME_LEN]; + uint32_t ifindex; + uint32_t btf_vmlinux_value_type_id; + uint64_t netns_dev; + uint64_t netns_ino; + uint32_t btf_id; + uint32_t btf_key_type_id; + uint32_t btf_value_type_id; +} forcealign(8); + +struct bpf_btf_info { + uint64_t btf; + uint32_t btf_size; + uint32_t id; + uint64_t name; + uint32_t name_len; + uint32_t kernel_btf; +} forcealign(8); + +struct bpf_link_info { + uint32_t type; + uint32_t id; + uint32_t prog_id; + union { + struct { + uint64_t tp_name; + uint32_t tp_name_len; + } raw_tracepoint; + struct { + uint32_t attach_type; + uint32_t target_obj_id; + uint32_t target_btf_id; + } tracing; + struct { + uint64_t cgroup_id; + uint32_t attach_type; + } cgroup; + struct { + uint64_t target_name; + uint32_t target_name_len; + union { + struct { + uint32_t map_id; + } map; + }; + } iter; + struct { + uint32_t netns_ino; + uint32_t attach_type; + } netns; + struct { + uint32_t ifindex; + } xdp; + }; +} forcealign(8); + +struct bpf_sock_addr { + uint32_t user_family; + uint32_t user_ip4; + uint32_t user_ip6[4]; + uint32_t user_port; + uint32_t family; + uint32_t type; + uint32_t protocol; + uint32_t msg_src_ip4; + uint32_t msg_src_ip6[4]; + __bpf_md_ptr(struct bpf_sock *, sk); +}; + +struct bpf_sock_ops { + uint32_t op; + union { + uint32_t args[4]; + uint32_t reply; + uint32_t replylong[4]; + }; + uint32_t family; + uint32_t remote_ip4; + uint32_t local_ip4; + uint32_t remote_ip6[4]; + uint32_t local_ip6[4]; + uint32_t remote_port; + uint32_t local_port; + uint32_t is_fullsock; + uint32_t snd_cwnd; + uint32_t srtt_us; + uint32_t bpf_sock_ops_cb_flags; + uint32_t state; + uint32_t rtt_min; + uint32_t snd_ssthresh; + uint32_t rcv_nxt; + uint32_t snd_nxt; + uint32_t snd_una; + uint32_t mss_cache; + uint32_t ecn_flags; + uint32_t rate_delivered; + uint32_t rate_interval_us; + uint32_t packets_out; + uint32_t retrans_out; + uint32_t total_retrans; + uint32_t segs_in; + uint32_t data_segs_in; + uint32_t segs_out; + uint32_t data_segs_out; + uint32_t lost_out; + uint32_t sacked_out; + uint32_t sk_txhash; + uint64_t bytes_received; + uint64_t bytes_acked; + __bpf_md_ptr(struct bpf_sock *, sk); + __bpf_md_ptr(void *, skb_data); + __bpf_md_ptr(void *, skb_data_end); + uint32_t skb_len; + uint32_t skb_tcp_flags; +}; + +struct bpf_perf_event_value { + uint64_t counter; + uint64_t enabled; + uint64_t running; +}; + +struct bpf_cgroup_dev_ctx { + uint32_t access_type; + uint32_t major; + uint32_t minor; +}; + +struct bpf_raw_tracepoint_args { + uint64_t args[0]; +}; + +struct bpf_fib_lookup { + uint8_t family; + uint8_t l4_protocol; + uint16_t sport; /* big endian */ + uint16_t dport; /* big endian */ + union { + uint16_t tot_len; + uint16_t mtu_result; + }; + uint32_t ifindex; + union { + uint8_t tos; + uint32_t flowinfo; /* big endian */ + uint32_t rt_metric; + }; + union { + uint32_t ipv4_src; /* big endian */ + uint32_t ipv6_src[4]; + }; + union { + uint32_t ipv4_dst; /* big endian */ + uint32_t ipv6_dst[4]; + }; + uint16_t h_vlan_proto; /* big endian */ + uint16_t h_vlan_TCI; /* big endian */ + uint8_t smac[6]; + uint8_t dmac[6]; +}; + +struct bpf_redir_neigh { + uint32_t nh_family; + union { + uint32_t ipv4_nh; /* big endian */ + uint32_t ipv6_nh[4]; + }; +}; + +struct bpf_flow_keys { + uint16_t nhoff; + uint16_t thoff; + uint16_t addr_proto; + uint8_t is_frag; + uint8_t is_first_frag; + uint8_t is_encap; + uint8_t ip_proto; + uint16_t n_proto; /* big endian */ + uint16_t sport; /* big endian */ + uint16_t dport; /* big endian */ + union { + struct { + uint32_t ipv4_src; /* big endian */ + uint32_t ipv4_dst; /* big endian */ + }; + struct { + uint32_t ipv6_src[4]; + uint32_t ipv6_dst[4]; + }; + }; + uint32_t flags; + uint32_t flow_label; +}; + +struct bpf_func_info { + uint32_t insn_off; + uint32_t type_id; +}; + +struct bpf_line_info { + uint32_t insn_off; + uint32_t file_name_off; + uint32_t line_off; + uint32_t line_col; +}; + +struct bpf_spin_lock { + uint32_t val; +}; + +struct bpf_sysctl { + uint32_t write_; + uint32_t file_pos; +}; + +struct bpf_sockopt { + __bpf_md_ptr(struct bpf_sock *, sk); + __bpf_md_ptr(void *, optval); + __bpf_md_ptr(void *, optval_end); + int32_t level; + int32_t optname; + int32_t optlen; + int32_t retval; +}; + +struct bpf_pidns_info { + uint32_t pid; + uint32_t tgid; +}; + +struct bpf_sk_lookup { + union { + __bpf_md_ptr(struct bpf_sock *, sk); + uint64_t cookie; + }; + uint32_t family; + uint32_t protocol; + uint32_t remote_ip4; + uint32_t remote_ip6[4]; + uint32_t remote_port; + uint32_t local_ip4; + uint32_t local_ip6[4]; + uint32_t local_port; +}; + +struct btf_ptr { + void *ptr; + uint32_t type_id; + uint32_t flags; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_BPF_H_ */ diff --git a/libc/calls/struct/filter.h b/libc/calls/struct/filter.h new file mode 100644 index 000000000..5814b4c1c --- /dev/null +++ b/libc/calls/struct/filter.h @@ -0,0 +1,59 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_FILTER_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FILTER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define BPF_MAJOR_VERSION 1 +#define BPF_MINOR_VERSION 1 + +struct sock_filter { + uint16_t code; + uint8_t jt; + uint8_t jf; + uint32_t k; +}; + +struct sock_fprog { + unsigned short len; + struct sock_filter *filter; +}; + +#define BPF_RVAL(code) ((code)&0x18) +#define BPF_A 0x10 +#define BPF_MISCOP(code) ((code)&0xf8) +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 + +#define BPF_STMT(code, k) \ + { (unsigned short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) \ + { (unsigned short)(code), jt, jf, k } + +#define BPF_MEMWORDS 16 + +#define SKF_AD_OFF (-0x1000) +#define SKF_AD_PROTOCOL 0 +#define SKF_AD_PKTTYPE 4 +#define SKF_AD_IFINDEX 8 +#define SKF_AD_NLATTR 12 +#define SKF_AD_NLATTR_NEST 16 +#define SKF_AD_MARK 20 +#define SKF_AD_QUEUE 24 +#define SKF_AD_HATYPE 28 +#define SKF_AD_RXHASH 32 +#define SKF_AD_CPU 36 +#define SKF_AD_ALU_XOR_X 40 +#define SKF_AD_VLAN_TAG 44 +#define SKF_AD_VLAN_TAG_PRESENT 48 +#define SKF_AD_PAY_OFFSET 52 +#define SKF_AD_RANDOM 56 +#define SKF_AD_VLAN_TPID 60 +#define SKF_AD_MAX 64 +#define SKF_NET_OFF (-0x100000) +#define SKF_LL_OFF (-0x200000) +#define BPF_NET_OFF SKF_NET_OFF +#define BPF_LL_OFF SKF_LL_OFF + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_FILTER_H_ */ diff --git a/libc/calls/struct/seccomp.h b/libc/calls/struct/seccomp.h new file mode 100644 index 000000000..0e5cc8f8c --- /dev/null +++ b/libc/calls/struct/seccomp.h @@ -0,0 +1,80 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_ + +#define SECCOMP_SET_MODE_STRICT 0 +#define SECCOMP_SET_MODE_FILTER 1 +#define SECCOMP_GET_ACTION_AVAIL 2 +#define SECCOMP_GET_NOTIF_SIZES 3 +#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) +#define SECCOMP_FILTER_FLAG_LOG (1UL << 1) +#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) +#define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3) +#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4) +#define SECCOMP_RET_KILL_PROCESS 0x80000000U +#define SECCOMP_RET_KILL_THREAD 0x00000000U +#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD +#define SECCOMP_RET_TRAP 0x00030000U +#define SECCOMP_RET_ERRNO 0x00050000U +#define SECCOMP_RET_USER_NOTIF 0x7fc00000U +#define SECCOMP_RET_TRACE 0x7ff00000U +#define SECCOMP_RET_LOG 0x7ffc0000U +#define SECCOMP_RET_ALLOW 0x7fff0000U +#define SECCOMP_RET_ACTION_FULL 0xffff0000U +#define SECCOMP_RET_ACTION 0x7fff0000U +#define SECCOMP_RET_DATA 0x0000ffffU +#define SECCOMP_USER_NOTIF_FLAG_CONTINUE (1UL << 0) +#define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0) +#define SECCOMP_ADDFD_FLAG_SEND (1UL << 1) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define SECCOMP_IOC_MAGIC '!' +#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) +#define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) +#define SECCOMP_IOW(nr, type) _IOW(SECCOMP_IOC_MAGIC, nr, type) +#define SECCOMP_IOWR(nr, type) _IOWR(SECCOMP_IOC_MAGIC, nr, type) + +#define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif) +#define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, struct seccomp_notif_resp) +#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64) +#define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, struct seccomp_notif_addfd) + +struct seccomp_data { + int32_t nr; + uint32_t arch; + uint64_t instruction_pointer; + uint64_t args[6]; +}; + +struct seccomp_notif_sizes { + uint16_t seccomp_notif; + uint16_t seccomp_notif_resp; + uint16_t seccomp_data; +}; + +struct seccomp_notif { + uint64_t id; + uint32_t pid; + uint32_t flags; + struct seccomp_data data; +}; + +struct seccomp_notif_resp { + uint64_t id; + int64_t val; + int32_t error; + uint32_t flags; +}; + +struct seccomp_notif_addfd { + uint64_t id; + uint32_t flags; + uint32_t srcfd; + uint32_t newfd; + uint32_t newfd_flags; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_ */ diff --git a/libc/calls/struct/sigaction.h b/libc/calls/struct/sigaction.h index 1fcfb06af..23bec2ee0 100644 --- a/libc/calls/struct/sigaction.h +++ b/libc/calls/struct/sigaction.h @@ -3,6 +3,7 @@ #include "libc/calls/struct/sigset.h" #include "libc/calls/typedef/sigaction_f.h" #include "libc/calls/typedef/sighandler_t.h" +#include "libc/dce.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) struct sigaction { /* cosmo abi */ @@ -24,6 +25,7 @@ COSMOPOLITAN_C_START_ void _init_onntconsoleevent(void); void _init_wincrash(void); +void _check_sigwinch(); #ifndef __SIGACTION_YOINK #define __SIGACTION_YOINK(SIG) \ @@ -44,12 +46,16 @@ void _init_wincrash(void); case SIGFPE: \ YOINK(_init_wincrash); \ break; \ + case SIGWINCH: \ + YOINK(_check_sigwinch); \ + break; \ default: \ break; \ } \ } else { \ YOINK(_init_onntconsoleevent); \ YOINK(_init_wincrash); \ + YOINK(_check_sigwinch); \ } \ } \ } while (0) diff --git a/libc/calls/struct/siginfo-freebsd.internal.h b/libc/calls/struct/siginfo-freebsd.internal.h new file mode 100644 index 000000000..71b1fa243 --- /dev/null +++ b/libc/calls/struct/siginfo-freebsd.internal.h @@ -0,0 +1,39 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_FREEBSD_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_FREEBSD_H_ +#include "libc/calls/struct/sigval.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct siginfo_freebsd { + int32_t si_signo; + int32_t si_errno; + int32_t si_code; + int32_t si_pid; + int32_t si_uid; + int32_t si_status; + void *si_addr; + union sigval si_value; + union { + struct { + int32_t si_trapno; + }; + struct { + int32_t si_timerid; + int32_t si_overrun; + }; + struct { + int32_t si_mqd; + }; + struct { + long si_band; + }; + struct { + int64_t __pad1; + int32_t __pad2[7]; + }; + }; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_FREEBSD_H_ */ diff --git a/libc/calls/struct/siginfo-netbsd.internal.h b/libc/calls/struct/siginfo-netbsd.internal.h new file mode 100644 index 000000000..e71e24f2b --- /dev/null +++ b/libc/calls/struct/siginfo-netbsd.internal.h @@ -0,0 +1,53 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_NETBSD_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_NETBSD_H_ +#include "libc/calls/struct/sigval.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct siginfo_netbsd { + int32_t si_signo; + int32_t si_code; + int32_t si_errno; + int32_t __pad; + union { + struct { /* RT */ + int32_t si_pid; + int32_t si_uid; + union sigval si_value; + }; + struct { /* chld */ + int32_t _pid; + int32_t _uid; + int32_t si_status; + int64_t si_utime; + int64_t si_stime; + }; + struct { /* fault */ + void *si_addr; + int32_t si_trap; + int32_t si_trap2; + int32_t si_trap3; + }; + struct { /* poll */ + int64_t si_band; + int32_t si_fd; + }; + struct { /* syscall */ + int32_t si_sysnum; + int32_t si_retval[2]; + int32_t si_error; + uint64_t si_args[8]; + }; + struct { /* ptrace */ + int32_t si_pe_report_event; + union { + int32_t si_pe_other_pid; + int32_t si_pe_lwp; + }; + }; + }; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_NETBSD_H_ */ diff --git a/libc/calls/struct/siginfo-openbsd.internal.h b/libc/calls/struct/siginfo-openbsd.internal.h new file mode 100644 index 000000000..f0a6322f8 --- /dev/null +++ b/libc/calls/struct/siginfo-openbsd.internal.h @@ -0,0 +1,36 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_OPENBSD_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_OPENBSD_H_ +#include "libc/calls/struct/sigval.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct siginfo_openbsd { + int32_t si_signo; + int32_t si_code; + int32_t si_errno; + union { + int32_t _pad[(128 / 4) - 3]; + struct { + int32_t si_pid; + union { + struct { + int32_t si_uid; + union sigval si_value; + }; + struct { + int64_t si_utime; + int64_t si_stime; + int32_t si_status; + }; + }; + }; + struct { + void *si_addr; + int32_t si_trapno; + }; + }; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_OPENBSD_H_ */ diff --git a/libc/calls/struct/siginfo-xnu.internal.h b/libc/calls/struct/siginfo-xnu.internal.h new file mode 100644 index 000000000..f6f4f8b53 --- /dev/null +++ b/libc/calls/struct/siginfo-xnu.internal.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_XNU_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_XNU_H_ +#include "libc/calls/struct/sigval.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct siginfo_xnu { + int32_t si_signo; + int32_t si_errno; + int32_t si_code; + int32_t si_pid; + int32_t si_uid; + int32_t si_status; + void *si_addr; + union sigval si_value; + int64_t si_band; + uint64_t __pad[7]; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_XNU_H_ */ diff --git a/libc/calls/struct/siginfo.h b/libc/calls/struct/siginfo.h index 105ad24c5..9c8cd81e7 100644 --- a/libc/calls/struct/siginfo.h +++ b/libc/calls/struct/siginfo.h @@ -15,7 +15,7 @@ struct siginfo { uint32_t si_uid; }; struct { - int32_t si_timerid; + int32_t si_timerid; /* SIGALRM */ int32_t si_overrun; }; }; @@ -23,7 +23,8 @@ struct siginfo { union sigval si_value; /* provided by third arg of sigqueue(2) */ struct { int32_t si_status; - int64_t si_utime, si_stime; + int64_t si_utime; + int64_t si_stime; }; }; }; @@ -39,7 +40,7 @@ struct siginfo { }; }; struct { - int64_t si_band; + int64_t si_band; /* SIGPOLL */ int32_t si_fd; }; struct { diff --git a/libc/calls/struct/stat.h b/libc/calls/struct/stat.h index fc39ec4a5..b744420cd 100644 --- a/libc/calls/struct/stat.h +++ b/libc/calls/struct/stat.h @@ -10,7 +10,7 @@ struct stat { /* cosmo abi */ uint32_t st_mode; /* 24: octal file mask thing */ uint32_t st_uid; /* 28: user id of owner */ uint32_t st_gid; /* group id of owning group */ - uint32_t st_flags; /* flags (bsd-only) */ + uint32_t st_flags; /* nt/xnu/bsd-only */ uint64_t st_rdev; /* id of device if a special file */ int64_t st_size; /* bytes in file */ int64_t st_blksize; /* preferred chunking for underlying filesystem */ @@ -19,7 +19,7 @@ struct stat { /* cosmo abi */ struct timespec st_mtim; /* modified time */ struct timespec st_ctim; /* complicated time */ struct timespec st_birthtim; - uint64_t st_gen; + uint64_t st_gen; /* xnu/bsd only */ }; #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/calls/struct/ucontext-freebsd.internal.h b/libc/calls/struct/ucontext-freebsd.internal.h new file mode 100644 index 000000000..f48bbafa2 --- /dev/null +++ b/libc/calls/struct/ucontext-freebsd.internal.h @@ -0,0 +1,65 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_FREEBSD_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_FREEBSD_INTERNAL_H_ +#include "libc/calls/struct/sigaction-freebsd.internal.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct stack_freebsd { + void *ss_sp; + uint64_t ss_size; + int32_t ss_flags; +}; + +struct mcontext_freebsd { + int64_t mc_onstack; + int64_t mc_rdi; + int64_t mc_rsi; + int64_t mc_rdx; + int64_t mc_rcx; + int64_t mc_r8; + int64_t mc_r9; + int64_t mc_rax; + int64_t mc_rbx; + int64_t mc_rbp; + int64_t mc_r10; + int64_t mc_r11; + int64_t mc_r12; + int64_t mc_r13; + int64_t mc_r14; + int64_t mc_r15; + uint32_t mc_trapno; + uint16_t mc_fs; + uint16_t mc_gs; + int64_t mc_addr; + uint32_t mc_flags; + uint16_t mc_es; + uint16_t mc_ds; + int64_t mc_err; + int64_t mc_rip; + int64_t mc_cs; + int64_t mc_rflags; + int64_t mc_rsp; + int64_t mc_ss; + int64_t mc_len; + int64_t mc_fpformat; + int64_t mc_ownedfp; + int64_t mc_fpstate[64]; + int64_t mc_fsbase; + int64_t mc_gsbase; + int64_t mc_xfpustate; + int64_t mc_xfpustate_len; + int64_t mc_spare[4]; +}; + +struct ucontext_freebsd { + struct sigset_freebsd uc_sigmask; + struct mcontext_freebsd uc_mcontext; + struct ucontext_freebsd *uc_link; + struct stack_freebsd uc_stack; + int32_t uc_flags; + int32_t __spare__[4]; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_FREEBSD_INTERNAL_H_ */ diff --git a/libc/calls/struct/ucontext-netbsd.internal.h b/libc/calls/struct/ucontext-netbsd.internal.h new file mode 100644 index 000000000..a0c60e247 --- /dev/null +++ b/libc/calls/struct/ucontext-netbsd.internal.h @@ -0,0 +1,84 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +// clang-format off +#include "libc/calls/ucontext.h" + +#define __UCONTEXT_SIZE 784 +#define _UC_SIGMASK 0x01 +#define _UC_STACK 0x02 +#define _UC_CPU 0x04 +#define _UC_FPU 0x08 +#define _UC_TLSBASE 0x00080000 +#define _UC_SETSTACK 0x00010000 +#define _UC_CLRSTACK 0x00020000 +#define _UC_CLRSTACK 0x00020000 + +union sigval_netbsd { + int32_t sival_int; + void *sival_ptr; +}; + +struct sigset_netbsd { + uint32_t __bits[4]; +}; + +struct stack_netbsd { + void *ss_sp; + size_t ss_size; + int32_t ss_flags; +}; + +struct mcontext_netbsd { + union { + struct { + uint64_t rdi; + uint64_t rsi; + uint64_t rdx; + uint64_t rcx; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t rbp; + uint64_t rbx; + uint64_t rax; + uint64_t gs; + uint64_t fs; + uint64_t es; + uint64_t ds; + uint64_t trapno; + uint64_t err; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; + }; + int64_t __gregs[26]; + }; + int64_t _mc_tlsbase; + struct FpuState __fpregs; +}; + +struct ucontext_netbsd { + union { + struct { + uint32_t uc_flags; /* see _UC_* above */ + struct ucontext_netbsd *uc_link; + struct sigset_netbsd uc_sigmask; + struct stack_netbsd uc_stack; + struct mcontext_netbsd uc_mcontext; + }; + char __pad[__UCONTEXT_SIZE]; + }; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_ */ diff --git a/libc/calls/struct/ucontext-openbsd.internal.h b/libc/calls/struct/ucontext-openbsd.internal.h new file mode 100644 index 000000000..e02871e6a --- /dev/null +++ b/libc/calls/struct/ucontext-openbsd.internal.h @@ -0,0 +1,42 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_OPENBSD_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_OPENBSD_INTERNAL_H_ +#include "libc/calls/ucontext.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct ucontext_openbsd { + int64_t sc_rdi; + int64_t sc_rsi; + int64_t sc_rdx; + int64_t sc_rcx; + int64_t sc_r8; + int64_t sc_r9; + int64_t sc_r10; + int64_t sc_r11; + int64_t sc_r12; + int64_t sc_r13; + int64_t sc_r14; + int64_t sc_r15; + int64_t sc_rbp; + int64_t sc_rbx; + int64_t sc_rax; + int64_t sc_gs; + int64_t sc_fs; + int64_t sc_es; + int64_t sc_ds; + int64_t sc_trapno; + int64_t sc_err; + int64_t sc_rip; + int64_t sc_cs; + int64_t sc_rflags; + int64_t sc_rsp; + int64_t sc_ss; + struct FpuState *sc_fpstate; + int32_t __sc_unused; + int32_t sc_mask; + int64_t sc_cookie; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_OPENBSD_INTERNAL_H_ */ diff --git a/libc/calls/symlinkat-nt.c b/libc/calls/symlinkat-nt.c index f55c7e226..1cbcc3907 100644 --- a/libc/calls/symlinkat-nt.c +++ b/libc/calls/symlinkat-nt.c @@ -19,7 +19,11 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/errno.h" +#include "libc/intrin/once.h" +#include "libc/intrin/spinlock.h" #include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/enum/symboliclink.h" #include "libc/nt/enum/tokeninformationclass.h" #include "libc/nt/errors.h" #include "libc/nt/files.h" @@ -27,27 +31,12 @@ #include "libc/nt/runtime.h" #include "libc/nt/struct/luid.h" #include "libc/nt/struct/tokenprivileges.h" +#include "libc/nt/thunk/msabi.h" #include "libc/sysv/errfuns.h" -static bool g_can_symlink; +__msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW; -textwindows int sys_symlinkat_nt(const char *target, int newdirfd, - const char *linkpath) { - uint32_t flags; - char16_t target16[PATH_MAX]; - char16_t linkpath16[PATH_MAX]; - if (!g_can_symlink) return eacces(); - flags = isdirectory(target) ? kNtSymbolicLinkFlagDirectory : 0; - if (__mkntpathat(newdirfd, linkpath, 0, linkpath16) == -1) return -1; - if (__mkntpath(target, target16) == -1) return -1; - if (CreateSymbolicLink(linkpath16, target16, flags)) { - return 0; - } else { - return __winerr(); - } -} - -static textstartup bool EnableSymlink(void) { +static bool AllowedToCreateSymlinks(void) { int64_t tok; struct NtLuid id; struct NtTokenPrivileges tp; @@ -60,10 +49,45 @@ static textstartup bool EnableSymlink(void) { return GetLastError() != kNtErrorNotAllAssigned; } -static textstartup void g_can_symlink_init() { - g_can_symlink = EnableSymlink(); -} +textwindows int sys_symlinkat_nt(const char *target, int newdirfd, + const char *linkpath) { + int targetlen; + uint32_t attrs, flags; + char16_t target16[PATH_MAX]; + char16_t linkpath16[PATH_MAX]; -const void *const g_can_symlink_ctor[] initarray = { - g_can_symlink_init, -}; + // convert the paths + if (__mkntpathat(newdirfd, linkpath, 0, linkpath16) == -1) return -1; + if ((targetlen = __mkntpath(target, target16)) == -1) return -1; + + // determine if we need directory flag + if ((attrs = __imp_GetFileAttributesW(target16)) != -1u) { + if (attrs & kNtFileAttributeDirectory) { + flags = kNtSymbolicLinkFlagDirectory; + } else { + flags = 0; + } + } else { + // win32 needs to know if it's a directory of a file symlink, but + // that's hard to determine if we're creating a broken symlink so + // we'll fall back to checking for trailing slash + if (targetlen && target16[targetlen - 1] == '\\') { + flags = kNtSymbolicLinkFlagDirectory; + } else { + flags = 0; + } + } + + // windows only lets administrators do this + // even then we're required to ask for permission + if (!_once(AllowedToCreateSymlinks())) { + return eperm(); + } + + // we can now proceed + if (CreateSymbolicLink(linkpath16, target16, flags)) { + return 0; + } else { + return __fix_enotdir(-1, linkpath16); + } +} diff --git a/libc/calls/symlinkat.c b/libc/calls/symlinkat.c index 889674236..26242b377 100644 --- a/libc/calls/symlinkat.c +++ b/libc/calls/symlinkat.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/consts/at.h" @@ -33,17 +34,22 @@ * @param target can be relative and needn't exist * @param linkpath is what gets created * @return 0 on success, or -1 w/ errno - * @note Windows NT only lets admins do this + * @raise EPERM if a non-admin on Windows NT tries to use this * @asyncsignalsafe */ int symlinkat(const char *target, int newdirfd, const char *linkpath) { + int rc; + char buf[12]; if (IsAsan() && (!__asan_is_valid(target, 1) || !__asan_is_valid(linkpath, 1))) { - return efault(); + rc = efault(); } if (!IsWindows()) { - return sys_symlinkat(target, newdirfd, linkpath); + rc = sys_symlinkat(target, newdirfd, linkpath); } else { - return sys_symlinkat_nt(target, newdirfd, linkpath); + rc = sys_symlinkat_nt(target, newdirfd, linkpath); } + STRACE("symlinkat(%#s, %s, %#s) → %d% m", target, + __strace_dirfd(buf, newdirfd), linkpath); + return rc; } diff --git a/libc/calls/sync-nt.c b/libc/calls/sync-nt.c index 5188199f0..31dbc395b 100644 --- a/libc/calls/sync-nt.c +++ b/libc/calls/sync-nt.c @@ -29,7 +29,7 @@ /** * Flushes all open file handles and, if possible, all disk drives. */ -int sys_sync_nt(void) { +textwindows int sys_sync_nt(void) { unsigned i; int64_t volume; uint32_t drives; diff --git a/libc/calls/sysdebug.internal.h b/libc/calls/sysdebug.internal.h deleted file mode 100644 index 614f66ec1..000000000 --- a/libc/calls/sysdebug.internal.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_CALLS_SYSDEBUG_INTERNAL_H_ -#define COSMOPOLITAN_LIBC_CALLS_SYSDEBUG_INTERNAL_H_ -#include "libc/log/libfatal.internal.h" - -#ifndef DEBUGSYS -#define DEBUGSYS 0 -#endif - -#if DEBUGSYS -#define SYSDEBUG(FMT, ...) __printf("SYS: " FMT "\n", ##__VA_ARGS__) -#else -#define SYSDEBUG(FMT, ...) (void)0 -#endif - -#endif /* COSMOPOLITAN_LIBC_CALLS_SYSDEBUG_INTERNAL_H_ */ diff --git a/libc/calls/sysinfo-nt.c b/libc/calls/sysinfo-nt.c index dc866fb8b..934d4fafc 100644 --- a/libc/calls/sysinfo-nt.c +++ b/libc/calls/sysinfo-nt.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/loadavg.internal.h" #include "libc/calls/struct/sysinfo.h" #include "libc/nt/accounting.h" #include "libc/nt/struct/memorystatusex.h" @@ -32,6 +33,9 @@ textwindows int sys_sysinfo_nt(struct sysinfo *info) { info->totalram = memstat.ullTotalPhys; info->freeram = memstat.ullAvailPhys; info->procs = sysinfo.dwNumberOfProcessors; + info->loads[0] = __ntloadavg[0] * 65536; + info->loads[1] = __ntloadavg[1] * 65536; + info->loads[2] = __ntloadavg[2] * 65536; info->mem_unit = 1; return 0; } else { diff --git a/libc/calls/sysinfo.c b/libc/calls/sysinfo.c index 11cafd245..18b33083a 100644 --- a/libc/calls/sysinfo.c +++ b/libc/calls/sysinfo.c @@ -47,8 +47,10 @@ int sysinfo(struct sysinfo *info) { } else { rc = sys_sysinfo_nt(info); } - info->procs = MAX(1, info->procs); - info->mem_unit = MAX(1, info->mem_unit); - info->totalram = MAX((8 * 1024 * 1024) / info->mem_unit, info->totalram); + if (rc != -1) { + info->procs = MAX(1, info->procs); + info->mem_unit = MAX(1, info->mem_unit); + info->totalram = MAX((8 * 1024 * 1024) / info->mem_unit, info->totalram); + } return rc; } diff --git a/libc/calls/tcgetattr.c b/libc/calls/tcgetattr.c index a520fe460..e83c2d6d5 100644 --- a/libc/calls/tcgetattr.c +++ b/libc/calls/tcgetattr.c @@ -23,6 +23,32 @@ /** * Obtains the termios struct. * + * Here are the general defaults you can expect across platforms: + * + * c_iflag = ICRNL IXON + * c_oflag = OPOST ONLCR NL0 CR0 TAB0 BS0 VT0 FF0 + * c_cflag = ISIG CREAD CS8 + * c_lflag = ISIG ICANON ECHO ECHOE ECHOK IEXTEN ECHOCTL ECHOKE + * c_ispeed = 38400 + * c_ospeed = 38400 + * c_cc[VINTR] = CTRL-C + * c_cc[VQUIT] = CTRL-\ # ignore this comment + * c_cc[VERASE] = CTRL-? + * c_cc[VKILL] = CTRL-U + * c_cc[VEOF] = CTRL-D + * c_cc[VTIME] = CTRL-@ + * c_cc[VMIN] = CTRL-A + * c_cc[VSTART] = CTRL-Q + * c_cc[VSTOP] = CTRL-S + * c_cc[VSUSP] = CTRL-Z + * c_cc[VEOL] = CTRL-@ + * c_cc[VSWTC] = CTRL-@ + * c_cc[VREPRINT] = CTRL-R + * c_cc[VDISCARD] = CTRL-O + * c_cc[VWERASE] = CTRL-W + * c_cc[VLNEXT] = CTRL-V + * c_cc[VEOL2] = CTRL-@ + * * @param fd open file descriptor that isatty() * @param tio is where result is stored * @return -1 w/ errno on error diff --git a/libc/calls/termios.h b/libc/calls/termios.h index 35ea0b223..9f88f7786 100644 --- a/libc/calls/termios.h +++ b/libc/calls/termios.h @@ -17,14 +17,14 @@ int tcsetpgrp(int, int32_t); int32_t tcgetpgrp(int); int openpty(int *, int *, char *, const struct termios *, - const struct winsize *) paramsnonnull((1, 2)) nodiscard; + const struct winsize *) paramsnonnull((1, 2)) dontdiscard; int forkpty(int *, char *, const struct termios *, const struct winsize *) - paramsnonnull((1, 2)) nodiscard; + paramsnonnull((1, 2)) dontdiscard; errno_t ptsname_r(int, char *, size_t); int grantpt(int); int unlockpt(int); -int posix_openpt(int) nodiscard; +int posix_openpt(int) dontdiscard; int tcdrain(int); int tcgetsid(int); diff --git a/libc/calls/timecritical.c b/libc/calls/timecritical.c new file mode 100644 index 000000000..7f32a4b50 --- /dev/null +++ b/libc/calls/timecritical.c @@ -0,0 +1,21 @@ +/*-*- 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 2022 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/internal.h" + +bool __time_critical; diff --git a/libc/calls/truncate-nt.c b/libc/calls/truncate-nt.c index 01d82ec37..29c0819b5 100644 --- a/libc/calls/truncate-nt.c +++ b/libc/calls/truncate-nt.c @@ -25,15 +25,17 @@ #include "libc/nt/runtime.h" textwindows int sys_truncate_nt(const char *path, uint64_t length) { + int rc; bool32 ok; int64_t fh; uint16_t path16[PATH_MAX]; if (__mkntpath(path, path16) == -1) return -1; if ((fh = CreateFile(path16, kNtGenericWrite, kNtFileShareRead, NULL, kNtOpenExisting, kNtFileAttributeNormal, 0)) != -1) { - ok = sys_ftruncate_nt(fh, length); + rc = sys_ftruncate_nt(fh, length); CloseHandle(fh); - if (ok) return 0; + } else { + rc = -1; } - return __winerr(); + return __fix_enotdir(rc, path16); } diff --git a/libc/calls/ttyname.c b/libc/calls/ttyname.c index f8181c183..94e064feb 100644 --- a/libc/calls/ttyname.c +++ b/libc/calls/ttyname.c @@ -21,6 +21,9 @@ static char ttyname_buf[PATH_MAX]; +/** + * Returns name of terminal. + */ char *ttyname(int fd) { int rc = ttyname_r(fd, ttyname_buf, sizeof(ttyname_buf)); if (rc != 0) return NULL; diff --git a/libc/calls/ttyname_r.c b/libc/calls/ttyname_r.c index 7f9ab945f..fcef19b89 100644 --- a/libc/calls/ttyname_r.c +++ b/libc/calls/ttyname_r.c @@ -16,19 +16,24 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" +#include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/fmt/itoa.h" +#include "libc/intrin/kprintf.h" #include "libc/log/log.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" -static textwindows dontinline int sys_ttyname_nt(int fd, char *buf, size_t size) { +static textwindows dontinline int sys_ttyname_nt(int fd, char *buf, + size_t size) { uint32_t mode; if (GetConsoleMode(g_fds.p[fd].handle, &mode)) { if (mode & kNtEnableVirtualTerminalInput) { @@ -59,7 +64,7 @@ static int ttyname_linux(int fd, char *buf, size_t size) { struct stat st1, st2; if (!isatty(fd)) return errno; char name[PATH_MAX]; - int64toarray_radix10(fd, stpcpy(name, "/proc/self/fd/")); + FormatInt32(stpcpy(name, "/proc/self/fd/"), fd); ssize_t got; got = readlink(name, buf, size); if (got == -1) return errno; @@ -70,18 +75,24 @@ static int ttyname_linux(int fd, char *buf, size_t size) { return 0; } +/** + * Returns name of terminal, reentrantly. + */ int ttyname_r(int fd, char *buf, size_t size) { + int rc; if (IsLinux()) { - return ttyname_linux(fd, buf, size); + rc = ttyname_linux(fd, buf, size); } else if (IsFreebsd()) { - return ttyname_freebsd(fd, buf, size); + rc = ttyname_freebsd(fd, buf, size); } else if (IsWindows()) { if (__isfdkind(fd, kFdFile)) { - return sys_ttyname_nt(fd, buf, size); + rc = sys_ttyname_nt(fd, buf, size); } else { - return ebadf(); + rc = ebadf(); } } else { - return enosys(); + rc = enosys(); } + STRACE("ttyname_r(%d, %s) → %d% m", fd, buf, rc); + return rc; } diff --git a/libc/calls/ucontext.h b/libc/calls/ucontext.h index df4e59af2..24450230b 100644 --- a/libc/calls/ucontext.h +++ b/libc/calls/ucontext.h @@ -5,56 +5,6 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#define REG_R8 REG_R8 -#define REG_R9 REG_R9 -#define REG_R10 REG_R10 -#define REG_R11 REG_R11 -#define REG_R12 REG_R12 -#define REG_R13 REG_R13 -#define REG_R14 REG_R14 -#define REG_R15 REG_R15 -#define REG_RDI REG_RDI -#define REG_RSI REG_RSI -#define REG_RBP REG_RBP -#define REG_RBX REG_RBX -#define REG_RDX REG_RDX -#define REG_RAX REG_RAX -#define REG_RCX REG_RCX -#define REG_RSP REG_RSP -#define REG_RIP REG_RIP -#define REG_EFL REG_EFL -#define REG_CSGSFS REG_CSGSFS -#define REG_ERR REG_ERR -#define REG_TRAPNO REG_TRAPNO -#define REG_OLDMASK REG_OLDMASK -#define REG_CR2 REG_CR2 - -enum GeneralRegister { - REG_R8, - REG_R9, - REG_R10, - REG_R11, - REG_R12, - REG_R13, - REG_R14, - REG_R15, - REG_RDI, - REG_RSI, - REG_RBP, - REG_RBX, - REG_RDX, - REG_RAX, - REG_RCX, - REG_RSP, - REG_RIP, - REG_EFL, - REG_CSGSFS, - REG_ERR, - REG_TRAPNO, - REG_OLDMASK, - REG_CR2 -}; - struct XmmRegister { uint64_t u64[2]; }; diff --git a/libc/calls/umask.c b/libc/calls/umask.c new file mode 100644 index 000000000..a6a439f8c --- /dev/null +++ b/libc/calls/umask.c @@ -0,0 +1,40 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" + +/** + * Sets file mode creation mask. + * + * @return previous mask + * @note always succeeds + */ +int umask(int newmask) { + int oldmask; + if (!IsWindows()) { + oldmask = sys_umask(newmask); + } else { + // TODO(jart): what should we do with this? + oldmask = newmask; + } + STRACE("umask(%#o) → %#o", oldmask); + return oldmask; +} diff --git a/libc/calls/uname.c b/libc/calls/uname.c index c080e0627..fa187db12 100644 --- a/libc/calls/uname.c +++ b/libc/calls/uname.c @@ -16,36 +16,92 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/utsname.h" +#include "libc/dce.h" +#include "libc/fmt/itoa.h" +#include "libc/intrin/asan.internal.h" +#include "libc/log/log.h" +#include "libc/nt/enum/computernameformat.h" +#include "libc/nt/struct/teb.h" +#include "libc/runtime/runtime.h" #include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +static inline textwindows noasan int NtGetMajorVersion(void) { + return NtGetPeb()->OSMajorVersion; +} + +static inline textwindows noasan int NtGetMinorVersion(void) { + return NtGetPeb()->OSMinorVersion; +} + +static inline textwindows noasan int NtGetBuildNumber(void) { + return NtGetPeb()->OSBuildNumber; +} /** * Asks kernel to give us the `uname -a` data. * @return 0 on success, or -1 w/ errno */ int uname(struct utsname *lool) { - char *out; + int rc, v; + char *out, *p; size_t i, j, len; char tmp[sizeof(struct utsname)]; - bzero(tmp, sizeof(tmp)); - if (sys_uname(tmp) != -1) { - out = (char *)lool; - i = 0; - j = 0; - for (;;) { - len = strlen(&tmp[j]); - if (len >= sizeof(struct utsname) - i) break; - memcpy(&out[i], &tmp[j], len + 1); - i += SYS_NMLN; - j += len; - while (j < sizeof(tmp) && tmp[j] == '\0') ++j; - if (j == sizeof(tmp)) break; - } - return 0; + if (!lool) return efault(); + if (!lool || (IsAsan() && !__asan_is_valid(lool, sizeof(*lool)))) { + rc = efault(); } else { - bzero(lool, sizeof(struct utsname)); - return -1; + bzero(tmp, sizeof(tmp)); + if (!IsWindows()) { + if (IsLinux() || IsFreebsd()) { + if ((rc = sys_uname(tmp)) != -1) { + out = (char *)lool; + for (i = j = 0;;) { + len = strlen(&tmp[j]); + if (len >= sizeof(struct utsname) - i) break; + memcpy(&out[i], &tmp[j], len + 1); + i += SYS_NMLN; + j += len; + while (j < sizeof(tmp) && tmp[j] == '\0') ++j; + if (j == sizeof(tmp)) break; + } + } + } else if (IsXnu()) { + strcpy(lool->sysname, "XNU's Not UNIX!"); + gethostname_bsd(lool->nodename, sizeof(lool->nodename)); + rc = 0; + } else if (IsOpenbsd()) { + strcpy(lool->sysname, "OpenBSD"); + gethostname_bsd(lool->nodename, sizeof(lool->nodename)); + rc = 0; + } else if (IsNetbsd()) { + strcpy(lool->sysname, "NetBSD"); + gethostname_bsd(lool->nodename, sizeof(lool->nodename)); + rc = 0; + } else { + rc = enosys(); + } + } else { + v = NtGetVersion(); + p = lool->release; + p = FormatUint32(p, NtGetMajorVersion()), *p++ = '.'; + p = FormatUint32(p, NtGetMinorVersion()), *p++ = '-'; + p = FormatUint32(p, NtGetBuildNumber()); + strcpy(lool->sysname, "The New Technology"); + strcpy(lool->machine, "x86_64"); + rc = gethostname_nt(lool->nodename, sizeof(lool->nodename), + kNtComputerNamePhysicalDnsHostname); + rc |= gethostname_nt(lool->domainname, sizeof(lool->domainname), + kNtComputerNamePhysicalDnsDomain); + } } + STRACE("uname([%s, %s, %s, %s, %s, %s]) → %d% m", lool->sysname, + lool->nodename, lool->release, lool->version, lool->machine, + lool->domainname, rc); + return rc; } diff --git a/libc/calls/unlink_s.c b/libc/calls/unlink_s.c index ec63d5758..562db3924 100644 --- a/libc/calls/unlink_s.c +++ b/libc/calls/unlink_s.c @@ -16,8 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" #include "libc/calls/calls.h" +#include "libc/intrin/lockxchg.h" /** * Deletes file. diff --git a/libc/calls/unlinkat-nt.c b/libc/calls/unlinkat-nt.c index 5666461b8..3b8555f03 100644 --- a/libc/calls/unlinkat-nt.c +++ b/libc/calls/unlinkat-nt.c @@ -18,7 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/errno.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/creationdisposition.h" #include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/enum/filesharemode.h" #include "libc/nt/enum/io.h" #include "libc/nt/errors.h" #include "libc/nt/files.h" @@ -28,10 +32,54 @@ #include "libc/nt/synchronization.h" #include "libc/sysv/consts/at.h" +/** + * Performs synchronization on directory of pathname. + * + * This code is intended to help prevent subsequent i/o operations + * from failing for no reason at all. For example a unit test that + * repeatedly opens and unlinks the same filename. + */ +static textwindows int SyncDirectory(int df, char16_t path[PATH_MAX], int n) { + int rc; + int64_t fh; + char16_t *p; + if ((p = memrchr16(path, '\\', n))) { + if (p - path == 2 && path[1] == ':') return 0; // XXX: avoid syncing volume + *p = 0; + } else { + if (df != AT_FDCWD) { + if (FlushFileBuffers(df)) { + return 0; + } else { + return -1; + } + } + path[0] = '.'; + path[1] = 0; + } + if ((fh = CreateFile( + path, kNtFileGenericWrite, + kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, 0, + kNtOpenExisting, kNtFileAttributeNormal | kNtFileFlagBackupSemantics, + 0)) != -1) { + if (FlushFileBuffers(fh)) { + rc = 0; + } else { + rc = -1; + } + CloseHandle(fh); + } else { + rc = -1; + } + return rc; +} + static textwindows bool IsDirectorySymlink(const char16_t *path) { + int e; int64_t h; struct NtWin32FindData data; struct NtWin32FileAttributeData info; + e = errno; if (GetFileAttributesEx(path, 0, &info) && ((info.dwFileAttributes & kNtFileAttributeDirectory) && (info.dwFileAttributes & kNtFileAttributeReparsePoint)) && @@ -40,6 +88,7 @@ static textwindows bool IsDirectorySymlink(const char16_t *path) { return data.dwReserved0 == kNtIoReparseTagSymlink || data.dwReserved0 == kNtIoReparseTagMountPoint; } else { + errno = e; return false; } } @@ -47,7 +96,9 @@ static textwindows bool IsDirectorySymlink(const char16_t *path) { static textwindows int sys_rmdir_nt(const char16_t *path) { int e, ms; for (ms = 1;; ms *= 2) { - if (RemoveDirectory(path)) return 0; + if (RemoveDirectory(path)) { + return 0; + } /* * Files can linger, for absolutely no reason. * Possibly some Windows Defender bug on Win7. @@ -55,28 +106,39 @@ static textwindows int sys_rmdir_nt(const char16_t *path) { * Alternative is use Microsoft internal APIs. * Never could have imagined it'd be this bad. */ - if ((e = GetLastError()) == kNtErrorDirNotEmpty && ms <= 512) { + if (GetLastError() == kNtErrorDirNotEmpty && ms <= 2048) { Sleep(ms); continue; } else { break; } } - errno = e; return -1; } static textwindows int sys_unlink_nt(const char16_t *path) { - if (IsDirectorySymlink(path)) return sys_rmdir_nt(path); - return DeleteFile(path) ? 0 : __winerr(); + if (IsDirectorySymlink(path)) { + return sys_rmdir_nt(path); + } else if (DeleteFile(path)) { + return 0; + } else { + return -1; + } } textwindows int sys_unlinkat_nt(int dirfd, const char *path, int flags) { - uint16_t path16[PATH_MAX]; - if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; - if (flags & AT_REMOVEDIR) { - return sys_rmdir_nt(path16); + int n, rc; + char16_t path16[PATH_MAX]; + if ((n = __mkntpathat(dirfd, path, 0, path16)) == -1) { + rc = -1; + } else if (flags & AT_REMOVEDIR) { + rc = sys_rmdir_nt(path16); } else { - return sys_unlink_nt(path16); + rc = sys_unlink_nt(path16); + if (rc != -1) { + // TODO(jart): prove that it helps first + // rc = SyncDirectory(dirfd, path16, n); + } } + return __fix_enotdir(rc, path16); } diff --git a/libc/calls/unlinkat.c b/libc/calls/unlinkat.c index ca2e06d46..5326350ce 100644 --- a/libc/calls/unlinkat.c +++ b/libc/calls/unlinkat.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/consts/at.h" @@ -28,6 +29,8 @@ /** * Deletes inode and maybe the file too. * + * This may be used to delete files and directories and symlinks. + * * @param dirfd is normally AT_FDCWD but if it's an open directory and * path is relative, then path becomes relative to dirfd * @param path is the thing to delete @@ -35,13 +38,18 @@ * @return 0 on success, or -1 w/ errno */ int unlinkat(int dirfd, const char *path, int flags) { - if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); - if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) { - return -1; /* TODO(jart): implement me */ - } - if (!IsWindows()) { - return sys_unlinkat(dirfd, path, flags); + int rc; + char buf[12]; + if (IsAsan() && !__asan_is_valid(path, 1)) { + rc = efault(); + } else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) { + STRACE("zipos unlinkat not supported yet"); + } else if (!IsWindows()) { + rc = sys_unlinkat(dirfd, path, flags); } else { - return sys_unlinkat_nt(dirfd, path, flags); + rc = sys_unlinkat_nt(dirfd, path, flags); } + STRACE("unlinkat(%s, %#s, %#b) → %d% m", __strace_dirfd(buf, dirfd), path, + flags, rc); + return rc; } diff --git a/libc/calls/usleep.c b/libc/calls/usleep.c index 9e7e2901d..c51e26fcb 100644 --- a/libc/calls/usleep.c +++ b/libc/calls/usleep.c @@ -16,14 +16,18 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/timespec.h" +#include "libc/sysv/errfuns.h" #include "libc/time/time.h" /** * Sleeps for particular amount of microseconds. + * @norestart */ int usleep(uint32_t microseconds) { - return nanosleep( - &(struct timespec){microseconds / 1000000, microseconds % 1000000 * 1000}, - NULL); + return nanosleep(&(struct timespec){(uint64_t)microseconds / 1000000, + (uint64_t)microseconds % 1000000 * 1000}, + NULL); } diff --git a/libc/calls/utimensat-sysv.c b/libc/calls/utimensat-sysv.c index 407f08ad0..5c4e87550 100644 --- a/libc/calls/utimensat-sysv.c +++ b/libc/calls/utimensat-sysv.c @@ -23,8 +23,6 @@ #include "libc/time/time.h" #include "libc/zipos/zipos.internal.h" -#define __NR_utimensat_linux 0x118 /*RHEL5:CVE-2010-3301*/ - int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2], int flags) { int rc, olderr; @@ -35,8 +33,7 @@ int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2], if (!IsXnu()) { olderr = errno; rc = __sys_utimensat(dirfd, path, ts, flags); - if (((rc == -1 && errno == ENOSYS) || rc == __NR_utimensat_linux) && - dirfd == AT_FDCWD && !flags) { + if ((rc == -1 && errno == ENOSYS) && dirfd == AT_FDCWD && !flags) { errno = olderr; if (ts) { tv[0].tv_sec = ts[0].tv_sec; diff --git a/libc/calls/utimensat.c b/libc/calls/utimensat.c index 53d07622a..8861f0420 100644 --- a/libc/calls/utimensat.c +++ b/libc/calls/utimensat.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/errfuns.h" @@ -34,16 +35,25 @@ */ int utimensat(int dirfd, const char *path, const struct timespec ts[2], int flags) { + int rc; + char buf[12]; if (IsAsan() && (!__asan_is_valid(path, 1) || (ts && !__asan_is_valid(ts, sizeof(struct timespec) * 2)))) { - return efault(); - } - if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) { - return -1; /* TODO(jart): implement me */ - } - if (!IsWindows()) { - return sys_utimensat(dirfd, path, ts, flags); + rc = efault(); + } else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) { + STRACE("zipos mkdirat not supported yet"); + } else if (!IsWindows()) { + rc = sys_utimensat(dirfd, path, ts, flags); } else { - return sys_utimensat_nt(dirfd, path, ts, flags); + rc = sys_utimensat_nt(dirfd, path, ts, flags); } + if (ts) { + STRACE("utimensat(%s, %#s, {{%,ld, %,ld}, {%,ld, %,ld}}, %#b) → %d% m", + __strace_dirfd(buf, dirfd), path, ts[0].tv_sec, ts[0].tv_nsec, + ts[1].tv_sec, ts[1].tv_nsec, flags, rc); + } else { + STRACE("utimensat(%s, %#s, 0, %#b) → %d% m", __strace_dirfd(buf, dirfd), + path, flags, rc); + } + return rc; } diff --git a/libc/calls/vdsofunc.greg.c b/libc/calls/vdsofunc.greg.c new file mode 100644 index 000000000..843b45822 --- /dev/null +++ b/libc/calls/vdsofunc.greg.c @@ -0,0 +1,94 @@ +/*-*- 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 2022 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/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/elf/scalar.h" +#include "libc/elf/struct/ehdr.h" +#include "libc/elf/struct/shdr.h" +#include "libc/elf/struct/sym.h" +#include "libc/log/libfatal.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/auxv.h" + +#define LAZY_RHEL7_RELOCATION 0xfffff + +#define GetStr(tab, rva) ((char *)(tab) + (rva)) +#define GetSection(e, s) ((void *)((intptr_t)(e) + (size_t)(s)->sh_offset)) +#define GetShstrtab(e) GetSection(e, GetShdr(e, (e)->e_shstrndx)) +#define GetSectionName(e, s) GetStr(GetShstrtab(e), (s)->sh_name) +#define GetPhdr(e, i) \ + ((Elf64_Phdr *)((intptr_t)(e) + (e)->e_phoff + \ + (size_t)(e)->e_phentsize * (i))) +#define GetShdr(e, i) \ + ((Elf64_Shdr *)((intptr_t)(e) + (e)->e_shoff + \ + (size_t)(e)->e_shentsize * (i))) + +static char *GetDynamicStringTable(Elf64_Ehdr *e, size_t *n) { + char *name; + Elf64_Half i; + Elf64_Shdr *shdr; + for (i = 0; i < e->e_shnum; ++i) { + shdr = GetShdr(e, i); + name = GetSectionName(e, GetShdr(e, i)); + if (shdr->sh_type == SHT_STRTAB) { + name = GetSectionName(e, GetShdr(e, i)); + if (name && READ64LE(name) == READ64LE(".dynstr")) { + if (n) *n = shdr->sh_size; + return GetSection(e, shdr); + } + } + } + return 0; +} + +static Elf64_Sym *GetDynamicSymbolTable(Elf64_Ehdr *e, Elf64_Xword *n) { + Elf64_Half i; + Elf64_Shdr *shdr; + for (i = e->e_shnum; i > 0; --i) { + shdr = GetShdr(e, i - 1); + if (shdr->sh_type == SHT_DYNSYM) { + if (shdr->sh_entsize != sizeof(Elf64_Sym)) continue; + if (n) *n = shdr->sh_size / shdr->sh_entsize; + return GetSection(e, shdr); + } + } + return 0; +} + +/** + * Returns Linux Kernel Virtual Dynamic Shared Object function address. + */ +void *__vdsofunc(const char *name) { + size_t m; + char *names; + Elf64_Ehdr *ehdr; + Elf64_Xword i, n; + Elf64_Sym *symtab, *sym; + if ((ehdr = (Elf64_Ehdr *)getauxval(AT_SYSINFO_EHDR)) && + (names = GetDynamicStringTable(ehdr, &m)) && + (symtab = GetDynamicSymbolTable(ehdr, &n))) { + for (i = 0; i < n; ++i) { + if (!__strcmp(names + symtab[i].st_name, name)) { + return (char *)ehdr + (symtab[i].st_value & LAZY_RHEL7_RELOCATION); + } + } + } + return 0; +} diff --git a/libc/calls/virtualmax.c b/libc/calls/virtualmax.c new file mode 100644 index 000000000..92df148c7 --- /dev/null +++ b/libc/calls/virtualmax.c @@ -0,0 +1,28 @@ +/*-*- 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 2022 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" + +/** + * Maximum amount of virtual memory in bytes. + * + * mmap() will return ENOMEM once this is reached. + * + * By default no limit is imposed. + */ +size_t __virtualmax = -1; diff --git a/libc/calls/wait.c b/libc/calls/wait.c index a0c4f85b6..a20a9b773 100644 --- a/libc/calls/wait.c +++ b/libc/calls/wait.c @@ -25,6 +25,7 @@ * may be inspected using WEEXITSTATUS(), etc. * @return process id of terminated child or -1 w/ errno * @asyncsignalsafe + * @restartable * @vforksafe */ int wait(int *opt_out_wstatus) { diff --git a/libc/calls/wait3.c b/libc/calls/wait3.c index 98d35128d..c236e77af 100644 --- a/libc/calls/wait3.c +++ b/libc/calls/wait3.c @@ -30,6 +30,7 @@ * @param opt_out_rusage optionally returns accounting data * @return process id of terminated child or -1 w/ errno * @asyncsignalsafe + * @restartable */ int wait3(int *opt_out_wstatus, int options, struct rusage *opt_out_rusage) { return wait4(-1, opt_out_wstatus, options, opt_out_rusage); diff --git a/libc/calls/wait4-nt.c b/libc/calls/wait4-nt.c index a5fa862c2..14e00a01b 100644 --- a/libc/calls/wait4-nt.c +++ b/libc/calls/wait4-nt.c @@ -19,48 +19,75 @@ #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysdebug.internal.h" #include "libc/fmt/conv.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/nt/accounting.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/processaccess.h" #include "libc/nt/enum/status.h" #include "libc/nt/enum/wait.h" +#include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/filetime.h" +#include "libc/nt/struct/processmemorycounters.h" #include "libc/nt/synchronization.h" +#include "libc/rand/lcg.internal.h" +#include "libc/runtime/ezmap.internal.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/w.h" #include "libc/sysv/errfuns.h" -textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options, - struct rusage *opt_out_rusage) { +static textwindows int sys_wait4_nt_impl(int pid, int *opt_out_wstatus, + int options, + struct rusage *opt_out_rusage) { int pids[64]; + int64_t handle; int64_t handles[64]; uint32_t dwExitCode; - uint32_t i, count, timeout; + bool shouldinterrupt; + uint32_t i, j, base, count, timeout; + struct NtProcessMemoryCountersEx memcount; struct NtFileTime createfiletime, exitfiletime, kernelfiletime, userfiletime; - if (pid != -1) { + if (_check_interrupts(true, g_fds.p)) return eintr(); + if (pid != -1 && pid != 0) { + if (pid < 0) { + /* XXX: this is sloppy */ + pid = -pid; + } if (!__isfdkind(pid, kFdProcess)) { - return echild(); + /* XXX: this is sloppy (see fork-nt.c) */ + if (!__isfdopen(pid) && + (handle = OpenProcess(kNtSynchronize | kNtProcessQueryInformation, + true, pid))) { + if ((pid = __reservefd(-1)) != -1) { + g_fds.p[pid].kind = kFdProcess; + g_fds.p[pid].handle = handle; + g_fds.p[pid].flags = O_CLOEXEC; + } else { + CloseHandle(handle); + return echild(); + } + } else { + return echild(); + } } handles[0] = g_fds.p[pid].handle; pids[0] = pid; count = 1; } else { - for (count = 0, i = g_fds.n; i--;) { - if (g_fds.p[i].kind == kFdProcess) { - pids[count] = i; - handles[count] = g_fds.p[i].handle; - if (++count == ARRAYLEN(handles)) break; - } - } - if (!count) { - return echild(); - } + count = __sample_pids(pids, handles, false); + if (!count) return echild(); } for (;;) { + if (_check_interrupts(true, 0)) return eintr(); dwExitCode = kNtStillActive; if (options & WNOHANG) { i = WaitForMultipleObjects(count, handles, false, 0); @@ -68,15 +95,18 @@ textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options, return 0; } } else { - i = WaitForMultipleObjects(count, handles, false, -1); + i = WaitForMultipleObjects(count, handles, false, + __SIG_POLLING_INTERVAL_MS); + if (i == kNtWaitTimeout) { + continue; + } } if (i == kNtWaitFailed) { - SYSDEBUG("WaitForMultipleObjects failed %d", GetLastError()); + STRACE("%s failed %u", "WaitForMultipleObjects", GetLastError()); return __winerr(); } - assert(__isfdkind(pids[i], kFdProcess)); if (!GetExitCodeProcess(handles[i], &dwExitCode)) { - SYSDEBUG("GetExitCodeProcess failed %d", GetLastError()); + STRACE("%s failed %u", "GetExitCodeProcess", GetLastError()); return __winerr(); } if (dwExitCode == kNtStillActive) continue; @@ -85,18 +115,38 @@ textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options, } if (opt_out_rusage) { bzero(opt_out_rusage, sizeof(*opt_out_rusage)); - if (GetProcessTimes(g_fds.p[pids[i]].handle, &createfiletime, - &exitfiletime, &kernelfiletime, &userfiletime)) { + bzero(&memcount, sizeof(memcount)); + memcount.cb = sizeof(struct NtProcessMemoryCountersEx); + if (GetProcessMemoryInfo(handles[i], &memcount, sizeof(memcount))) { + opt_out_rusage->ru_maxrss = memcount.PeakWorkingSetSize / 1024; + opt_out_rusage->ru_majflt = memcount.PageFaultCount; + } else { + STRACE("%s failed %u", "GetProcessMemoryInfo", GetLastError()); + } + if (GetProcessTimes(handles[i], &createfiletime, &exitfiletime, + &kernelfiletime, &userfiletime)) { opt_out_rusage->ru_utime = WindowsDurationToTimeVal(ReadFileTime(userfiletime)); opt_out_rusage->ru_stime = WindowsDurationToTimeVal(ReadFileTime(kernelfiletime)); } else { - SYSDEBUG("GetProcessTimes failed %d", GetLastError()); + STRACE("%s failed %u", "GetProcessTimes", GetLastError()); } } - CloseHandle(g_fds.p[pids[i]].handle); - g_fds.p[pids[i]].kind = kFdEmpty; + CloseHandle(handles[i]); + __releasefd(pids[i]); return pids[i]; } } + +textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options, + struct rusage *opt_out_rusage) { + int rc; + sigset_t mask, oldmask; + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + __sig_mask(SIG_BLOCK, &mask, &oldmask); + rc = sys_wait4_nt_impl(pid, opt_out_wstatus, options, opt_out_rusage); + __sig_mask(SIG_SETMASK, &oldmask, 0); + return rc; +} diff --git a/libc/calls/wait4.c b/libc/calls/wait4.c index f74f75c6b..a6b48e6f3 100644 --- a/libc/calls/wait4.c +++ b/libc/calls/wait4.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/wait4.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" @@ -35,24 +35,24 @@ * @param opt_out_rusage optionally returns accounting data * @return process id of terminated child or -1 w/ errno * @asyncsignalsafe + * @restartable */ int wait4(int pid, int *opt_out_wstatus, int options, struct rusage *opt_out_rusage) { - int rc, ws; + int rc, ws = 0; if (IsAsan() && ((opt_out_wstatus && !__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) || (opt_out_rusage && !__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))))) { - return efault(); - } - ws = 0; - if (!IsWindows()) { + rc = efault(); + } else if (!IsWindows()) { rc = sys_wait4(pid, &ws, options, opt_out_rusage); } else { rc = sys_wait4_nt(pid, &ws, options, opt_out_rusage); } - SYSDEBUG("waitpid(%d, [0x%x], %d) -> [%d]", pid, ws, options, rc); - if (opt_out_wstatus) *opt_out_wstatus = ws; + if (rc != -1 && opt_out_wstatus) *opt_out_wstatus = ws; + STRACE("wait4(%d, [%#x], %d, %p) → %d% m", pid, ws, options, opt_out_rusage, + rc); return rc; } diff --git a/libc/calls/waitpid.c b/libc/calls/waitpid.c index a5fb7d70e..a0d0ea510 100644 --- a/libc/calls/waitpid.c +++ b/libc/calls/waitpid.c @@ -28,6 +28,7 @@ * @param options can have WNOHANG, WUNTRACED, WCONTINUED, etc. * @return process id of terminated child or -1 w/ errno * @asyncsignalsafe + * @restartable */ int waitpid(int pid, int *opt_out_wstatus, int options) { return wait4(pid, opt_out_wstatus, options, NULL); diff --git a/libc/calls/weirdtypes.h b/libc/calls/weirdtypes.h index bd7c7fe70..de7973ae1 100644 --- a/libc/calls/weirdtypes.h +++ b/libc/calls/weirdtypes.h @@ -39,14 +39,34 @@ #define uid_t uint32_t #define rlim_t uint64_t /* int64_t on bsd */ -#define int_fast8_t __INT_FAST8_TYPE__ -#define uint_fast8_t __UINT_FAST8_TYPE__ -#define int_fast16_t __INT_FAST16_TYPE__ -#define uint_fast16_t __UINT_FAST16_TYPE__ -#define int_fast32_t __INT_FAST32_TYPE__ -#define uint_fast32_t __UINT_FAST32_TYPE__ -#define int_fast64_t __INT_FAST64_TYPE__ -#define uint_fast64_t __UINT_FAST64_TYPE__ +typedef __INT_FAST8_TYPE__ int_fast8_t; +typedef __UINT_FAST8_TYPE__ uint_fast8_t; +typedef __INT_FAST16_TYPE__ int_fast16_t; +typedef __UINT_FAST16_TYPE__ uint_fast16_t; +typedef __INT_FAST32_TYPE__ int_fast32_t; +typedef __UINT_FAST32_TYPE__ uint_fast32_t; +typedef __INT_FAST64_TYPE__ int_fast64_t; +typedef __UINT_FAST64_TYPE__ uint_fast64_t; + +#define TIME_T_MAX __INT64_MAX__ +#define UINT_FAST64_MAX __UINT_FAST64_MAX__ +#define UINT_FAST8_MAX __UINT_FAST8_MAX__ +#define INT_FAST32_MAX __INT_FAST32_MAX__ +#define INT_FAST16_MAX __INT_FAST16_MAX__ +#define UINT_FAST32_MAX __UINT_FAST32_MAX__ +#define INT_FAST8_MAX __INT_FAST8_MAX__ +#define INT_FAST64_MAX __INT_FAST64_MAX__ +#define UINT_FAST16_MAX __UINT_FAST16_MAX__ + +#define TIME_T_MIN (-TIME_T_MAX - 1) +#define UINT_FAST64_MIN (-UINT_FAST64_MAX - 1) +#define UINT_FAST8_MIN (-UINT_FAST8_MAX - 1) +#define INT_FAST32_MIN (-INT_FAST32_MAX - 1) +#define INT_FAST16_MIN (-INT_FAST16_MAX - 1) +#define UINT_FAST32_MIN (-UINT_FAST32_MAX - 1) +#define INT_FAST8_MIN (-INT_FAST8_MAX - 1) +#define INT_FAST64_MIN (-INT_FAST64_MAX - 1) +#define UINT_FAST16_MIN (-UINT_FAST16_MAX - 1) #define atomic_bool _Atomic(_Bool) #define atomic_bool32 atomic_int_fast32_t diff --git a/libc/calls/winalarm.S b/libc/calls/winalarm.S deleted file mode 100644 index 84055d2b5..000000000 --- a/libc/calls/winalarm.S +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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 "libc/macros.internal.h" -.text.windows -.source __FILE__ - -__winalarm_nt: - ezlea __winalarm,ax - jmp __nt2sysv - .endfn __winalarm_nt,globl,hidden diff --git a/libc/calls/winalarm.c b/libc/calls/winalarm.c deleted file mode 100644 index 50265aef5..000000000 --- a/libc/calls/winalarm.c +++ /dev/null @@ -1,35 +0,0 @@ -/*-*- 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 "libc/calls/internal.h" -#include "libc/calls/struct/siginfo.h" -#include "libc/calls/typedef/sigaction_f.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/sig.h" - -void __winalarm(void *lpArgToCompletionRoutine, uint32_t dwTimerLowValue, - uint32_t dwTimerHighValue) { - int rva; - siginfo_t info; - bzero(&info, sizeof(info)); - info.si_signo = SIGALRM; - rva = __sighandrvas[SIGALRM]; - if (rva >= kSigactionMinRva) { - ((sigaction_f)(_base + rva))(SIGALRM, &info, NULL); - } -} diff --git a/libc/calls/wincrash.c b/libc/calls/wincrash.c index 32259c4d1..bd2487faf 100644 --- a/libc/calls/wincrash.c +++ b/libc/calls/wincrash.c @@ -17,65 +17,103 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/typedef/sigaction_f.h" #include "libc/calls/ucontext.h" #include "libc/nt/enum/exceptionhandleractions.h" #include "libc/nt/enum/signal.h" #include "libc/nt/struct/ntexceptionpointers.h" #include "libc/str/str.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" textwindows unsigned __wincrash(struct NtExceptionPointers *ep) { - int sig, rva; - struct Goodies { - ucontext_t ctx; - struct siginfo si; - } g; - SYSDEBUG("__wincrash"); + int64_t rip; + int sig, code; + ucontext_t ctx; + STRACE("__wincrash"); switch (ep->ExceptionRecord->ExceptionCode) { case kNtSignalBreakpoint: + code = TRAP_BRKPT; sig = SIGTRAP; break; case kNtSignalIllegalInstruction: + code = ILL_ILLOPC; + sig = SIGILL; + break; case kNtSignalPrivInstruction: + code = ILL_PRVOPC; sig = SIGILL; break; case kNtSignalGuardPage: - case kNtSignalAccessViolation: case kNtSignalInPageError: + code = SEGV_MAPERR; + sig = SIGSEGV; + break; + case kNtSignalAccessViolation: + code = SEGV_ACCERR; sig = SIGSEGV; break; case kNtSignalInvalidHandle: case kNtSignalInvalidParameter: case kNtSignalAssertionFailure: + code = SI_USER; sig = SIGABRT; break; - case kNtSignalFltDenormalOperand: case kNtSignalFltDivideByZero: - case kNtSignalFltInexactResult: - case kNtSignalFltInvalidOperation: + code = FPE_FLTDIV; + sig = SIGFPE; + break; case kNtSignalFltOverflow: - case kNtSignalFltStackCheck: + code = FPE_FLTOVF; + sig = SIGFPE; + break; case kNtSignalFltUnderflow: + code = FPE_FLTUND; + sig = SIGFPE; + break; + case kNtSignalFltInexactResult: + code = FPE_FLTRES; + sig = SIGFPE; + break; + case kNtSignalFltDenormalOperand: + case kNtSignalFltInvalidOperation: + case kNtSignalFltStackCheck: case kNtSignalIntegerDivideByZero: case kNtSignalFloatMultipleFaults: case kNtSignalFloatMultipleTraps: + code = FPE_FLTINV; sig = SIGFPE; break; case kNtSignalDllNotFound: case kNtSignalOrdinalNotFound: case kNtSignalEntrypointNotFound: case kNtSignalDllInitFailed: + code = SI_KERNEL; sig = SIGSYS; break; default: return kNtExceptionContinueSearch; } - bzero(&g, sizeof(g)); - rva = __sighandrvas[sig]; - if (rva >= kSigactionMinRva) { - ntcontext2linux(&g.ctx, ep->ContextRecord); - ((sigaction_f)(_base + rva))(sig, &g.si, &g.ctx); + rip = ep->ContextRecord->Rip; + + if (__sighandflags[sig] & SA_SIGINFO) { + _ntcontext2linux(&ctx, ep->ContextRecord); + __sig_handle(false, sig, code, &ctx); + _ntlinux2context(ep->ContextRecord, &ctx); + } else { + __sig_handle(false, sig, code, 0); } + + // Windows seems to be the only operating system that traps INT3 at + // addressof(INT3) rather than addressof(INT3)+1. So we must adjust + // RIP to prevent the same INT3 from being trapped forevermore. + if (sig == SIGTRAP && rip == ep->ContextRecord->Rip) { + ep->ContextRecord->Rip++; + } + return kNtExceptionContinueExecution; } diff --git a/libc/calls/wincrash_init.S b/libc/calls/wincrash_init.S index 6bbe00f5d..68274ae48 100644 --- a/libc/calls/wincrash_init.S +++ b/libc/calls/wincrash_init.S @@ -17,9 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .init.start 300,_init_wincrash + mov __wincrashearly(%rip),%rcx + ntcall __imp_RemoveVectoredExceptionHandler pushpop 1,%rcx ezlea __wincrash_nt,dx ntcall __imp_AddVectoredExceptionHandler diff --git a/libc/calls/wincrashearly.c b/libc/calls/wincrashearly.c new file mode 100644 index 000000000..f2da22651 --- /dev/null +++ b/libc/calls/wincrashearly.c @@ -0,0 +1,20 @@ +/*-*- 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 2022 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. │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +int64_t __wincrashearly; diff --git a/libc/sock/winsockerr.c b/libc/calls/winsockerr.c similarity index 100% rename from libc/sock/winsockerr.c rename to libc/calls/winsockerr.c diff --git a/libc/calls/write-nt.c b/libc/calls/write-nt.c index 8c4cd0f8e..4999f6ce8 100644 --- a/libc/calls/write-nt.c +++ b/libc/calls/write-nt.c @@ -16,30 +16,40 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/iovec.h" -#include "libc/limits.h" -#include "libc/nt/files.h" +#include "libc/calls/sig.internal.h" +#include "libc/nt/errors.h" #include "libc/nt/runtime.h" -#include "libc/nt/struct/overlapped.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" -static textwindows ssize_t sys_write_nt_impl(struct Fd *fd, void *data, - size_t size, ssize_t offset) { - uint32_t sent; +static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size, + ssize_t offset) { + uint32_t err, sent; struct NtOverlapped overlap; - if (WriteFile(fd->handle, data, clampio(size), &sent, - offset2overlap(offset, &overlap))) { - /* TODO(jart): Trigger SIGPIPE on kNtErrorBrokenPipe */ + if (WriteFile(g_fds.p[fd].handle, data, _clampio(size), &sent, + _offset2overlap(g_fds.p[fd].handle, offset, &overlap))) { return sent; - } else { - return __winerr(); + } + switch (GetLastError()) { + // case kNtErrorInvalidHandle: + // return ebadf(); /* handled by consts.sh */ + // case kNtErrorNotEnoughQuota: + // return edquot(); /* handled by consts.sh */ + case kNtErrorBrokenPipe: // broken pipe + case kNtErrorNoData: // closing named pipe + __sig_raise(SIGPIPE, SI_KERNEL); // + return epipe(); // + case kNtErrorAccessDenied: // write doesn't return EACCESS + return ebadf(); // + default: + return __winerr(); } } -textwindows ssize_t sys_write_nt(struct Fd *fd, const struct iovec *iov, - size_t iovlen, ssize_t opt_offset) { +textwindows ssize_t sys_write_nt(int fd, const struct iovec *iov, size_t iovlen, + ssize_t opt_offset) { ssize_t rc; size_t i, total; uint32_t size, wrote; diff --git a/libc/calls/write.c b/libc/calls/write.c index 2b7866288..7bcc3a7d5 100644 --- a/libc/calls/write.c +++ b/libc/calls/write.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/weaken.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" @@ -35,24 +36,30 @@ * impossible unless size was passed as zero to do an error check * @see read(), pwrite(), writev(), SIGPIPE * @asyncsignalsafe + * @restartable */ ssize_t write(int fd, const void *buf, size_t size) { + ssize_t rc; if (fd >= 0) { - if (IsAsan() && !__asan_is_valid(buf, size)) return efault(); - if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return weaken(__zipos_write)( + if (IsAsan() && !__asan_is_valid(buf, size)) { + rc = efault(); + } else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { + rc = weaken(__zipos_write)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, &(struct iovec){buf, size}, 1, -1); } else if (!IsWindows() && !IsMetal()) { - return sys_write(fd, buf, size); + rc = sys_write(fd, buf, size); } else if (fd >= g_fds.n) { - return ebadf(); + rc = ebadf(); } else if (IsMetal()) { - return sys_writev_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1); + rc = sys_writev_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1); } else { - return sys_writev_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1); + rc = sys_writev_nt(fd, &(struct iovec){buf, size}, 1); } } else { - return einval(); + rc = einval(); } + DATATRACE("write(%d, %#.*hhs%s, %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), + buf, rc > 40 ? "..." : "", size, rc); + return rc; } diff --git a/libc/calls/writev-nt.c b/libc/calls/writev-nt.c index 3d07f04c7..fb6231aa1 100644 --- a/libc/calls/writev-nt.c +++ b/libc/calls/writev-nt.c @@ -21,14 +21,13 @@ #include "libc/sock/internal.h" #include "libc/sysv/errfuns.h" -textwindows ssize_t sys_writev_nt(struct Fd *fd, const struct iovec *iov, - int iovlen) { - switch (fd->kind) { +textwindows ssize_t sys_writev_nt(int fd, const struct iovec *iov, int iovlen) { + switch (g_fds.p[fd].kind) { case kFdFile: case kFdConsole: return sys_write_nt(fd, iov, iovlen, -1); case kFdSocket: - return weaken(sys_sendto_nt)(fd, iov, iovlen, 0, NULL, 0); + return weaken(sys_send_nt)(fd, iov, iovlen, 0); default: return ebadf(); } diff --git a/libc/calls/writev-serial.c b/libc/calls/writev-serial.c index b3fc44b4c..0fc1e5aaf 100644 --- a/libc/calls/writev-serial.c +++ b/libc/calls/writev-serial.c @@ -24,7 +24,9 @@ ssize_t sys_writev_serial(struct Fd *fd, const struct iovec *iov, int iovlen) { size_t i, j, wrote = 0; for (i = 0; i < iovlen; ++i) { for (j = 0; j < iov[i].iov_len; ++j) { - while (!(inb(fd->handle + UART_LSR) & UART_TTYTXR)) asm("pause"); + while (!(inb(fd->handle + UART_LSR) & UART_TTYTXR)) { + __builtin_ia32_pause(); + } outb(fd->handle, ((char *)iov[i].iov_base)[j]); ++wrote; } diff --git a/libc/calls/writev.c b/libc/calls/writev.c index e6d31258c..08bc6df0c 100644 --- a/libc/calls/writev.c +++ b/libc/calls/writev.c @@ -19,7 +19,10 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/errno.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/sock/internal.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" @@ -27,29 +30,59 @@ /** * Writes data from multiple buffers. * + * This is the same thing as write() except it has multiple buffers. + * This yields a performance boost in situations where it'd be expensive + * to stitch data together using memcpy() or issuing multiple syscalls. + * This wrapper is implemented so that writev() calls where iovlen<2 may + * be passed to the kernel as write() instead. This yields a 100 cycle + * performance boost in the case of a single small iovec. + * * Please note that it's not an error for a short write to happen. This * can happen in the kernel if EINTR happens after some of the write has * been committed. It can also happen if we need to polyfill this system * call using write(). * * @return number of bytes actually handed off, or -1 w/ errno + * @restartable */ ssize_t writev(int fd, const struct iovec *iov, int iovlen) { + int i; + ssize_t rc; + if (fd >= 0 && iovlen >= 0) { - if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault(); - if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { - return weaken(__zipos_write)( + if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) { + rc = efault(); + } else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { + rc = weaken(__zipos_write)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1); } else if (!IsWindows() && !IsMetal()) { - return sys_writev(fd, iov, iovlen); + if (iovlen == 1) { + rc = sys_write(fd, iov[0].iov_base, iov[0].iov_len); + } else { + rc = sys_writev(fd, iov, iovlen); + } } else if (fd >= g_fds.n) { - return ebadf(); + rc = ebadf(); } else if (IsMetal()) { - return sys_writev_metal(g_fds.p + fd, iov, iovlen); + rc = sys_writev_metal(g_fds.p + fd, iov, iovlen); } else { - return sys_writev_nt(g_fds.p + fd, iov, iovlen); + rc = sys_writev_nt(fd, iov, iovlen); } } else { - return einval(); + rc = einval(); } + +#if defined(SYSDEBUG) && _DATATRACE + if (__strace > 0) { + if (rc == -1 && errno == EFAULT) { + STRACE("writev(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc); + } else { + kprintf(STRACE_PROLOGUE "writev(%d, ", fd); + __strace_iov(iov, iovlen, rc != -1 ? rc : 0); + kprintf(", %d) → %'ld% m\n", iovlen, rc); + } + } +#endif + + return rc; } diff --git a/libc/calls/zygote.c b/libc/calls/zygote.c deleted file mode 100644 index 10c0a7872..000000000 --- a/libc/calls/zygote.c +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- 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 "libc/calls/internal.h" -#include "libc/nt/struct/securityattributes.h" - -hidden const struct NtSecurityAttributes kNtIsInheritable = { - sizeof(struct NtSecurityAttributes), - NULL, - true, -}; diff --git a/libc/complex.h b/libc/complex.h index 51f7dd322..ebde8e5b6 100644 --- a/libc/complex.h +++ b/libc/complex.h @@ -82,6 +82,39 @@ complex long double clogl(complex long double); complex long double conjl(complex long double); complex long double cpowl(complex long double, complex long double); +#ifndef __cplusplus +#define __CIMAG(x, t) \ + (+(union { \ + _Complex t __z; \ + t __xy[2]; \ + }){(_Complex t)(x)} \ + .__xy[1]) +#define creal(x) ((double)(x)) +#define crealf(x) ((float)(x)) +#define creall(x) ((long double)(x)) +#define cimag(x) __CIMAG(x, double) +#define cimagf(x) __CIMAG(x, float) +#define cimagl(x) __CIMAG(x, long double) +#endif + +#ifdef __GNUC__ +#define _Complex_I (__extension__(0.0f + 1.0fi)) +#else +#define _Complex_I (0.0f + 1.0fi) +#endif + +#ifdef _Imaginary_I +#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I * (t)(y)) +#elif defined(__clang__) +#define __CMPLX(x, y, t) (+(_Complex t){(t)(x), (t)(y)}) +#else +#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y))) +#endif + +#define CMPLX(x, y) __CMPLX(x, y, double) +#define CMPLXF(x, y) __CMPLX(x, y, float) +#define CMPLXL(x, y) __CMPLX(x, y, long double) + #endif /* C11 */ COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/crt/crt.S b/libc/crt/crt.S index 4d0f82a63..83a86ab20 100644 --- a/libc/crt/crt.S +++ b/libc/crt/crt.S @@ -28,45 +28,62 @@ // @note FreeBSD is special (see freebsd/lib/csu/amd64/...) // @noreturn _start: + #if SupportsFreebsd() +// detect free besiyata dishmaya test %rdi,%rdi cmovnz %rdi,%rsp jz 0f movb $FREEBSD,__hostos(%rip) #endif -0: mov (%rsp),%ebx # argc + +// get startup timestamp as early as possible +// its used by --strace flag and kprintf() %T +0: rdtsc + ezlea kStartTsc,bx + mov %eax,(%rbx) + mov %edx,4(%rbx) + +// translates arguments from old stack abi + mov (%rsp),%ebx # argc lea 8(%rsp),%rsi # argv lea 16(%rsp,%rbx,8),%rdx # envp mov %rsp,__oldstack(%rip) - .frame0 + and $-16,%rsp + xor %ebp,%ebp // bofram 9f + +// make win32 imps noop .weak ape_idata_iat .weak ape_idata_iatend - ezlea missingno,ax # make win32 imps noop + ezlea missingno,ax ezlea ape_idata_iat,di ezlea ape_idata_iatend,cx sub %rdi,%rcx shr $3,%ecx rep stosq - xor %eax,%eax # find end of environ + +// scan through environment varis +// find start of auxiliary values + xor %eax,%eax or $-1,%ecx mov %rdx,%rdi repnz scasq mov %rdi,%rcx # auxv + #if SupportsXnu() +// xnu doesn't have auxiliary values testb IsXnu() jz 1f # polyfill xnu auxv push $0 # auxv[1][1]=0 push $0 # auxv[1][0]=0 - mov (%rcx),%rax # executable_path=BIN - lea 16(%rax),%rax # BIN - push %rax # auxv[0][0]=BIN - push $31 # auxv[0][0]=AT_EXECFN mov %rsp,%rcx # auxv #endif + +// enter cosmopolitan runtime 1: mov %ebx,%edi call cosmo -9: ud2 +9: .unreachable .endfn _start,weak,hidden #if SupportsXnu() diff --git a/libc/dce.h b/libc/dce.h index 6b02b308b..9b80e4d06 100644 --- a/libc/dce.h +++ b/libc/dce.h @@ -57,7 +57,7 @@ #define IsOptimized() 0 #endif -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ #define IsAsan() 1 #else #define IsAsan() 0 diff --git a/libc/dns/gethoststxt.c b/libc/dns/gethoststxt.c index 9a8b8a012..16598bdde 100644 --- a/libc/dns/gethoststxt.c +++ b/libc/dns/gethoststxt.c @@ -37,7 +37,7 @@ static struct HostsTxtInitialStaticMemory { } g_hoststxt_init; static textwindows dontinline char *GetNtHostsTxtPath(char *pathbuf, - uint32_t size) { + uint32_t size) { const char *const kWinHostsPath = "\\drivers\\etc\\hosts"; uint32_t len = GetSystemDirectoryA(&pathbuf[0], size); if (len && len + strlen(kWinHostsPath) + 1 < size) { diff --git a/libc/dns/getnameinfo.c b/libc/dns/getnameinfo.c index 0966a676b..c0be7d773 100644 --- a/libc/dns/getnameinfo.c +++ b/libc/dns/getnameinfo.c @@ -73,10 +73,10 @@ int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *name, ip = (uint8_t *)&(((struct sockaddr_in *)addr)->sin_addr); p = rdomain; - p += int64toarray_radix10(ip[3], p), *p++ = '.'; - p += int64toarray_radix10(ip[2], p), *p++ = '.'; - p += int64toarray_radix10(ip[1], p), *p++ = '.'; - p += int64toarray_radix10(ip[0], p), stpcpy(p, ".in-addr.arpa"); + p = FormatUint32(p, ip[3]), *p++ = '.'; + p = FormatUint32(p, ip[2]), *p++ = '.'; + p = FormatUint32(p, ip[1]), *p++ = '.'; + p = FormatUint32(p, ip[0]), stpcpy(p, ".in-addr.arpa"); info[0] = '\0'; if (name != NULL && namelen != 0) { if ((flags & NI_NUMERICHOST) && (flags & NI_NAMEREQD)) return EAI_NONAME; diff --git a/libc/dns/lookupprotobyname.c b/libc/dns/lookupprotobyname.c index 921cf371d..f319d2ed6 100644 --- a/libc/dns/lookupprotobyname.c +++ b/libc/dns/lookupprotobyname.c @@ -48,10 +48,10 @@ int LookupProtoByName(const char *protoname, char *buf, size_t bufsize, const char *filepath) { FILE *f; char *line; - char pathbuf[PATH_MAX]; const char *path; size_t linesize; int found, result; + char pathbuf[PATH_MAX]; char *name, *number, *alias, *comment, *tok; if (!(path = filepath)) { path = "/etc/protocols"; diff --git a/libc/dns/lookupprotobynumber.c b/libc/dns/lookupprotobynumber.c index 6d455d4e8..e86e1c4da 100644 --- a/libc/dns/lookupprotobynumber.c +++ b/libc/dns/lookupprotobynumber.c @@ -52,10 +52,10 @@ int LookupProtoByNumber(const int protonum, char *buf, size_t bufsize, const char *filepath) { FILE *f; char *line; - char pathbuf[PATH_MAX]; - const char *path; - size_t linesize; int found; + size_t linesize; + const char *path; + char pathbuf[PATH_MAX]; char *name, *number, *comment, *tok; if (!(path = filepath)) { path = "/etc/protocols"; diff --git a/libc/dns/lookupservicesbyname.c b/libc/dns/lookupservicesbyname.c index ffefbf45c..14458531e 100644 --- a/libc/dns/lookupservicesbyname.c +++ b/libc/dns/lookupservicesbyname.c @@ -53,10 +53,10 @@ int LookupServicesByName(const char *servname, char *servproto, const char *filepath) { FILE *f; char *line; - char pathbuf[PATH_MAX]; const char *path; size_t linesize; int found, result; + char pathbuf[PATH_MAX]; char *name, *port, *proto, *alias, *comment, *tok; if (!(path = filepath)) { path = "/etc/services"; diff --git a/libc/elf/def.h b/libc/elf/def.h index b282babcb..0578d108b 100644 --- a/libc/elf/def.h +++ b/libc/elf/def.h @@ -5,6 +5,8 @@ * @fileoverview Executable and Linkable Format Definitions. */ +#define EI_NIDENT 16 + #define EI_MAG0 0 #define EI_MAG1 1 #define EI_MAG2 2 diff --git a/libc/elf/elf.h b/libc/elf/elf.h index ed9abee8f..9df8827ac 100644 --- a/libc/elf/elf.h +++ b/libc/elf/elf.h @@ -26,6 +26,8 @@ void GetElfVirtualAddressRange(const Elf64_Ehdr *, size_t, intptr_t *, intptr_t *); char *GetElfString(const Elf64_Ehdr *, size_t, const char *, Elf64_Word); const char *GetElfSectionName(const Elf64_Ehdr *, size_t, Elf64_Shdr *); +Elf64_Sym *GetElfDynSymbolTable(const Elf64_Ehdr *, size_t, Elf64_Xword *); +char *GetElfDynStringTable(const Elf64_Ehdr *, size_t); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/elf/getelfdynstringtable.c b/libc/elf/getelfdynstringtable.c new file mode 100644 index 000000000..6ed29f0a9 --- /dev/null +++ b/libc/elf/getelfdynstringtable.c @@ -0,0 +1,40 @@ +/*-*- 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 "libc/elf/def.h" +#include "libc/elf/elf.h" +#include "libc/str/str.h" + +char *GetElfDynStringTable(const Elf64_Ehdr *elf, size_t mapsize) { + char *name; + Elf64_Half i; + Elf64_Shdr *shdr; + if (elf->e_shentsize) { + for (i = 0; i < elf->e_shnum; ++i) { + shdr = GetElfSectionHeaderAddress(elf, mapsize, i); + if (shdr->sh_type == SHT_STRTAB) { + name = GetElfSectionName(elf, mapsize, + GetElfSectionHeaderAddress(elf, mapsize, i)); + if (name && !strcmp(name, ".dynstr")) { + return GetElfSectionAddress(elf, mapsize, shdr); + } + } + } + } + return NULL; +} diff --git a/libc/elf/getelfdynsymboltable.c b/libc/elf/getelfdynsymboltable.c new file mode 100644 index 000000000..09256fda6 --- /dev/null +++ b/libc/elf/getelfdynsymboltable.c @@ -0,0 +1,37 @@ +/*-*- 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 "libc/elf/def.h" +#include "libc/elf/elf.h" + +Elf64_Sym *GetElfDynSymbolTable(const Elf64_Ehdr *elf, size_t mapsize, + Elf64_Xword *out_count) { + Elf64_Half i; + Elf64_Shdr *shdr; + if (elf->e_shentsize) { + for (i = elf->e_shnum; i > 0; --i) { + shdr = GetElfSectionHeaderAddress(elf, mapsize, i - 1); + if (shdr->sh_type == SHT_DYNSYM) { + if (shdr->sh_entsize != sizeof(Elf64_Sym)) continue; + if (out_count) *out_count = shdr->sh_size / shdr->sh_entsize; + return GetElfSectionAddress(elf, mapsize, shdr); + } + } + } + return NULL; +} diff --git a/libc/elf/getelfstringtable.c b/libc/elf/getelfstringtable.c index e12f4da72..83106a156 100644 --- a/libc/elf/getelfstringtable.c +++ b/libc/elf/getelfstringtable.c @@ -24,13 +24,15 @@ char *GetElfStringTable(const Elf64_Ehdr *elf, size_t mapsize) { char *name; Elf64_Half i; Elf64_Shdr *shdr; - for (i = 0; i < elf->e_shnum; ++i) { - shdr = GetElfSectionHeaderAddress(elf, mapsize, i); - if (shdr->sh_type == SHT_STRTAB) { - name = GetElfSectionName(elf, mapsize, - GetElfSectionHeaderAddress(elf, mapsize, i)); - if (name && !strcmp(name, ".strtab")) { - return GetElfSectionAddress(elf, mapsize, shdr); + if (elf->e_shentsize) { + for (i = 0; i < elf->e_shnum; ++i) { + shdr = GetElfSectionHeaderAddress(elf, mapsize, i); + if (shdr->sh_type == SHT_STRTAB) { + name = GetElfSectionName(elf, mapsize, + GetElfSectionHeaderAddress(elf, mapsize, i)); + if (name && !strcmp(name, ".strtab")) { + return GetElfSectionAddress(elf, mapsize, shdr); + } } } } diff --git a/libc/elf/getelfsymboltable.c b/libc/elf/getelfsymboltable.c index 5e0244793..76384bf41 100644 --- a/libc/elf/getelfsymboltable.c +++ b/libc/elf/getelfsymboltable.c @@ -23,12 +23,14 @@ Elf64_Sym *GetElfSymbolTable(const Elf64_Ehdr *elf, size_t mapsize, Elf64_Xword *out_count) { Elf64_Half i; Elf64_Shdr *shdr; - for (i = elf->e_shnum; i > 0; --i) { - shdr = GetElfSectionHeaderAddress(elf, mapsize, i - 1); - if (shdr->sh_type == SHT_SYMTAB) { - if (shdr->sh_entsize != sizeof(Elf64_Sym)) continue; - if (out_count) *out_count = shdr->sh_size / shdr->sh_entsize; - return GetElfSectionAddress(elf, mapsize, shdr); + if (elf->e_shentsize) { + for (i = elf->e_shnum; i > 0; --i) { + shdr = GetElfSectionHeaderAddress(elf, mapsize, i - 1); + if (shdr->sh_type == SHT_SYMTAB) { + if (shdr->sh_entsize != sizeof(Elf64_Sym)) continue; + if (out_count) *out_count = shdr->sh_size / shdr->sh_entsize; + return GetElfSectionAddress(elf, mapsize, shdr); + } } } return NULL; diff --git a/libc/elf/pf2prot.internal.h b/libc/elf/pf2prot.internal.h new file mode 100644 index 000000000..591aed197 --- /dev/null +++ b/libc/elf/pf2prot.internal.h @@ -0,0 +1,7 @@ +#ifndef COSMOPOLITAN_LIBC_ELF_PF2PROT_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_ELF_PF2PROT_INTERNAL_H_ +#include "libc/elf/def.h" + +#define _PF2PROT(x) ((PF_R & (x)) >> 2 | (PF_W & (x)) | (PF_X & (x)) << 2) + +#endif /* COSMOPOLITAN_LIBC_ELF_PF2PROT_INTERNAL_H_ */ diff --git a/libc/fmt/abs.c b/libc/fmt/abs.c index ab4b6b6a8..1baff0057 100644 --- a/libc/fmt/abs.c +++ b/libc/fmt/abs.c @@ -18,6 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/conv.h" -int(abs)(int x) { +/** + * Returns absolute value of 32-bit integer. + * @note `labs(LONG_MIN)` returns `LONG_MIN` unless `-ftrapv` + * @note consider ABS() to avoid narrowing + */ +int abs(int x) { return 0 < x ? x : -x; } diff --git a/libc/fmt/basename.c b/libc/fmt/basename.c index d1191354c..4c9671490 100644 --- a/libc/fmt/basename.c +++ b/libc/fmt/basename.c @@ -17,19 +17,42 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/conv.h" -#include "libc/fmt/isslash.internal.h" +#include "libc/str/path.h" #include "libc/str/str.h" /** - * Returns pointer to last filename component in path. + * Returns pointer to last filename component in path, e.g. + * + * path │ dirname() │ basename() + * ───────────────────────────────── + * . │ . │ . + * .. │ . │ .. + * / │ / │ / + * usr │ . │ usr + * /usr/ │ / │ usr + * /usr/lib │ /usr │ lib * * Both / and \ are are considered valid component separators on all * platforms. Trailing slashes are ignored. We don't grant special * consideration to things like foo/., c:/, \\?\Volume, etc. * - * @param path is NUL-terminated UTF-8 path - * @return pointer inside path or path itself + * @param path is UTF-8 and may be mutated, but not expanded in length + * @return pointer to path, or inside path, or to a special r/o string + * @see dirname() + * @see SUSv2 */ -textstartup char *basename(const char *path) { - return basename_n(path, strlen(path)); +char *basename(char *path) { + size_t i; + if (path && *path) { + i = strlen(path) - 1; + for (; i && _isdirsep(path[i]); i--) { + path[i] = 0; + } + for (; i && !_isdirsep(path[i - 1]);) { + i--; + } + return path + i; + } else { + return "."; + } } diff --git a/libc/fmt/basename_n.c b/libc/fmt/basename_n.c deleted file mode 100644 index c7570e2d5..000000000 --- a/libc/fmt/basename_n.c +++ /dev/null @@ -1,49 +0,0 @@ -/*-*- 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 "libc/fmt/conv.h" -#include "libc/fmt/isslash.internal.h" - -/** - * Returns pointer to last filename component in path. - * - * Both / and \ are are considered valid component separators on all - * platforms. Trailing slashes are ignored. We don't grant special - * consideration to things like foo/., c:/, \\?\Volume, etc. - * - * @param path is UTF-8 path - * @param size is byte length of path - * @return pointer inside path or path itself - */ -textstartup char *basename_n(const char *path, size_t size) { - size_t i, l; - if (size) { - if (isslash(path[size - 1])) { - l = size - 1; - while (l && isslash(path[l - 1])) --l; - if (!l) return (/*unconst*/ char *)&path[size - 1]; - size = l; - } - for (i = size; i > 0; --i) { - if (isslash(path[i - 1])) { - return (/*unconst*/ char *)&path[i]; - } - } - } - return (/*unconst*/ char *)path; -} diff --git a/libc/fmt/conv.h b/libc/fmt/conv.h index 66c42bde6..c16567951 100644 --- a/libc/fmt/conv.h +++ b/libc/fmt/conv.h @@ -17,6 +17,7 @@ COSMOPOLITAN_C_START_ int abs(int) libcesque pureconst; long labs(long) libcesque pureconst; long long llabs(long long) libcesque pureconst; +intmax_t imaxabs(intmax_t) libcesque pureconst; int atoi(const char *) paramsnonnull() libcesque; long atol(const char *) paramsnonnull() libcesque; long long atoll(const char *) paramsnonnull() libcesque; @@ -24,7 +25,6 @@ unsigned long strtoul(const char *, char **, int) paramsnonnull((1)); long long strtoll(const char *, char **, int) paramsnonnull((1)); unsigned long long strtoull(const char *, char **, int) paramsnonnull((1)); long long strtonum(const char *, long long, long long, const char **); -intmax_t div10(intmax_t, unsigned *) hidden; intmax_t strtoimax(const char *, char **, int) paramsnonnull((1)); uintmax_t strtoumax(const char *, char **, int) paramsnonnull((1)); intmax_t wcstoimax(const wchar_t *, wchar_t **, int); @@ -33,18 +33,22 @@ long wcstol(const wchar_t *, wchar_t **, int); unsigned long wcstoul(const wchar_t *, wchar_t **, int); long strtol(const char *, char **, int) paramsnonnull((1)) libcesque; long sizetol(const char *, long) paramsnonnull() libcesque; +long long wcstoll(const wchar_t *, wchar_t **, int); +unsigned long long wcstoull(const wchar_t *, wchar_t **, int); +int wcscoll(const wchar_t *, const wchar_t *); +size_t wcsxfrm(wchar_t *, const wchar_t *, size_t); /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § conversion » time ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ -int64_t DosDateTimeToUnix(unsigned, unsigned) nothrow; -struct timeval WindowsTimeToTimeVal(int64_t) nothrow; -struct timespec WindowsTimeToTimeSpec(int64_t) nothrow; -int64_t TimeSpecToWindowsTime(struct timespec) nothrow; -int64_t TimeValToWindowsTime(struct timeval) nothrow; -struct timeval WindowsDurationToTimeVal(int64_t) nothrow; -struct timespec WindowsDurationToTimeSpec(int64_t) nothrow; +int64_t DosDateTimeToUnix(unsigned, unsigned) libcesque nosideeffect; +struct timeval WindowsTimeToTimeVal(int64_t) libcesque nosideeffect; +struct timespec WindowsTimeToTimeSpec(int64_t) libcesque nosideeffect; +int64_t TimeSpecToWindowsTime(struct timespec) libcesque nosideeffect; +int64_t TimeValToWindowsTime(struct timeval) libcesque nosideeffect; +struct timeval WindowsDurationToTimeVal(int64_t) libcesque nosideeffect; +struct timespec WindowsDurationToTimeSpec(int64_t) libcesque nosideeffect; static inline struct NtFileTime MakeFileTime(int64_t x) { return (struct NtFileTime){(uint32_t)x, (uint32_t)(x >> 32)}; @@ -65,9 +69,7 @@ static inline int64_t ReadFileTime(struct NtFileTime t) { ╚────────────────────────────────────────────────────────────────────────────│*/ char *dirname(char *); -char *basename(const char *) nosideeffect; -char *basename_n(const char *, size_t) nosideeffect; -bool isabspath(const char *) paramsnonnull() nosideeffect; +char *basename(char *); char *stripext(char *); char *stripexts(char *); @@ -110,10 +112,13 @@ imaxdiv_t imaxdiv(intmax_t, intmax_t) pureconst; #define lldiv(num, den) ((lldiv_t){(num) / (den), (num) % (den)}) #endif -#ifndef __STRICT_ANSI__ -intmax_t __imaxabs(intmax_t) libcesque pureconst; -#define imaxabs(x) __imaxabs(x) -#endif /* !ANSI */ +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 406 || defined(__llvm__) +int128_t i128abs(int128_t) libcesque pureconst; +int128_t strtoi128(const char *, char **, int) paramsnonnull((1)); +uint128_t strtou128(const char *, char **, int) paramsnonnull((1)); +int128_t wcstoi128(const wchar_t *, wchar_t **, int); +uint128_t wcstou128(const wchar_t *, wchar_t **, int); +#endif /* gcc 4.6+ */ COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/fmt/dirname.c b/libc/fmt/dirname.c index 4101daec8..234f7f111 100644 --- a/libc/fmt/dirname.c +++ b/libc/fmt/dirname.c @@ -17,30 +17,42 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/conv.h" +#include "libc/str/path.h" #include "libc/str/str.h" -#define ISSLASH(c) (c == '/' || c == '\\') -#define ISDELIM(c) (ISSLASH(c) || c == '.') - /** - * Returns directory portion of path. - * @param s is mutated + * Returns directory portion of path, e.g. + * + * path │ dirname() │ basename() + * ───────────────────────────────── + * . │ . │ . + * .. │ . │ .. + * / │ / │ / + * usr │ . │ usr + * /usr/ │ / │ usr + * /usr/lib │ /usr │ lib + * + * @param path is UTF-8 and may be mutated, but not expanded in length + * @return pointer to path, or inside path, or to a special r/o string + * @see basename() + * @see SUSv2 */ -char *dirname(char *s) { - size_t i, n; - if (!(n = strlen(s))) return s; - while (n && ISDELIM(s[n - 1])) --n; - if (n) { - while (n && !ISSLASH(s[n - 1])) --n; - if (n) { - while (n && ISDELIM(s[n - 1])) --n; - if (!n) ++n; - } else { - s[n++] = '.'; +char *dirname(char *path) { + size_t i; + if (path && *path) { + i = strlen(path) - 1; + for (; _isdirsep(path[i]); i--) { + if (!i) return "/"; } + for (; !_isdirsep(path[i]); i--) { + if (!i) return "."; + } + for (; _isdirsep(path[i]); i--) { + if (!i) return "/"; + } + path[i + 1] = 0; + return path; } else { - ++n; + return "."; } - s[n] = '\0'; - return s; } diff --git a/libc/fmt/divmod10.internal.h b/libc/fmt/divmod10.internal.h new file mode 100644 index 000000000..048cbdc60 --- /dev/null +++ b/libc/fmt/divmod10.internal.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_FMT_DIVMOD10_H_ +#define COSMOPOLITAN_LIBC_FMT_DIVMOD10_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +forceinline uint64_t DivMod10(uint64_t x, unsigned *r) { +#if defined(__STRICT_ANSI__) || !defined(__GNUC__) || \ + (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)) + *r = x % 10; + return x / 10; +#else + uint128_t dw; + unsigned long long hi, rm; + dw = x; + dw *= 0xcccccccccccccccdull; + hi = dw >> 64; + hi >>= 3; + rm = hi; + rm += rm << 2; + rm += rm; + *r = x - rm; + return hi; +#endif +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_FMT_DIVMOD10_H_ */ diff --git a/libc/fmt/fmt.c b/libc/fmt/fmt.c index 5fb417319..0166660d7 100644 --- a/libc/fmt/fmt.c +++ b/libc/fmt/fmt.c @@ -21,9 +21,10 @@ #include "libc/bits/weaken.h" #include "libc/fmt/conv.h" #include "libc/fmt/fmt.h" -#include "libc/fmt/fmts.h" +#include "libc/fmt/fmt.internal.h" #include "libc/fmt/internal.h" #include "libc/fmt/itoa.h" +#include "libc/intrin/nomultics.internal.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/bsr.h" @@ -32,25 +33,6 @@ #include "libc/sysv/errfuns.h" #include "third_party/gdtoa/gdtoa.h" -#define PUT(C) \ - do { \ - char Buf[1] = {C}; \ - if (out(Buf, arg, 1) == -1) { \ - return -1; \ - } \ - } while (0) - -static const char kSpecialFloats[2][2][4] = {{"INF", "inf"}, {"NAN", "nan"}}; - -static void __fmt_free_dtoa(char **mem) { - if (*mem) { - if (weaken(freedtoa)) { - weaken(freedtoa)(*mem); - } - *mem = 0; - } -} - static int __fmt_atoi(const char **str) { int i; for (i = 0; '0' <= **str && **str <= '9'; ++*str) { @@ -88,7 +70,8 @@ static int __fmt_atoi(const char **str) { * - `%ld` long (64-bit) * - `%lu` unsigned long (64-bit) * - `%lx` unsigned long (64-bit hexadecimal) - * - `%jd` intmax_t (128-bit) + * - `%jd` intmax_t (64-bit) + * - `%jjd` int128_t (128-bit) * * Width Modifiers * @@ -123,15 +106,10 @@ static int __fmt_atoi(const char **str) { * @note implementation detail of printf(), snprintf(), etc. * @see printf() for wordier documentation * @note netlib.org is so helpful - * @asyncsignalsafe - * @vforksafe + * @asyncsignalsafe if floating point isn't used + * @vforksafe if floating point isn't used */ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { - union { - double d; - uint32_t u[2]; - uint64_t q; - } pun; long ld; void *p; unsigned u; @@ -143,13 +121,12 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { const char *alphabet; int (*out)(const char *, void *, size_t); unsigned char signbit, log2base; - int c, d, k, w, n, i1, ui, bw, bex; - char *s, *q, *se, *mem, qchar, special[8]; - int sgn, alt, sign, prec, prec1, flags, width, decpt, lasterr; + char *s, *q, qchar; + int d, w, n; + int sign, prec, flags, width, lasterr; lasterr = errno; out = fn ? fn : (void *)missingno; - mem = 0; while (*format) { if (*format != '%') { @@ -170,12 +147,12 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { continue; } else if (format[1] == 'd') { /* FAST PATH: PLAIN INTEGER */ d = va_arg(va, int); - if (out(ibuf, arg, int64toarray_radix10(d, ibuf)) == -1) return -1; + if (out(ibuf, arg, FormatInt64(ibuf, d) - ibuf) == -1) return -1; format += 2; continue; } else if (format[1] == 'u') { /* FAST PATH: PLAIN UNSIGNED */ u = va_arg(va, unsigned); - if (out(ibuf, arg, uint64toarray_radix10(u, ibuf)) == -1) return -1; + if (out(ibuf, arg, FormatUint64(ibuf, u) - ibuf) == -1) return -1; format += 2; continue; } else if (format[1] == 'x') { /* FAST PATH: PLAIN HEX */ @@ -190,12 +167,12 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { continue; } else if (format[1] == 'l' && format[2] == 'd') { ld = va_arg(va, long); /* FAST PATH: PLAIN LONG */ - if (out(ibuf, arg, int64toarray_radix10(ld, ibuf)) == -1) return -1; + if (out(ibuf, arg, FormatInt64(ibuf, ld) - ibuf) == -1) return -1; format += 3; continue; } else if (format[1] == 'l' && format[2] == 'u') { lu = va_arg(va, unsigned long); /* FAST PATH: PLAIN UNSIGNED LONG */ - if (out(ibuf, arg, uint64toarray_radix10(lu, ibuf)) == -1) return -1; + if (out(ibuf, arg, FormatUint64(ibuf, lu) - ibuf) == -1) return -1; format += 3; continue; } else if (format[1] == '.' && format[2] == '*' && format[3] == 's') { @@ -289,6 +266,10 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { case 'j': /* intmax_t */ format++; signbit = sizeof(intmax_t) * 8 - 1; + if (*format == 'j') { + format++; + signbit = sizeof(int128_t) * 8 - 1; + } break; case 'l': if (format[1] == 'f' || format[1] == 'F') { @@ -355,7 +336,6 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } break; } - case 'c': prec = 1; flags |= FLAGS_PRECISION; @@ -363,20 +343,23 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { p = charbuf; charbuf[0] = va_arg(va, int); goto FormatString; - case 'm': p = weaken(strerror) ? weaken(strerror)(lasterr) : "?"; signbit = 0; goto FormatString; - case 'r': - flags |= FLAGS_REPR; - /* fallthrough */ - + // undocumented %r specifier + // used for good carriage return + // helps integrate loggers with repls + if (!__replstderr) { + break; + } else { + p = "\r\e[K"; + goto FormatString; + } case 'q': flags |= FLAGS_QUOTE; /* fallthrough */ - case 's': p = va_arg(va, void *); FormatString: @@ -384,362 +367,37 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { return -1; } break; - + case 'n': + __FMT_PUT('\n'); + break; case 'F': case 'f': - if (!(flags & FLAGS_PRECISION)) prec = 6; - if (longdouble) { - pun.d = va_arg(va, long double); - } else { - pun.d = va_arg(va, double); - } - FormatDtoa: + case 'G': + case 'g': + case 'e': + case 'E': + case 'a': + case 'A': if (!weaken(__fmt_dtoa)) { p = "?"; - goto FormatThatThing; - } - assert(!mem); - s = mem = weaken(__fmt_dtoa)(pun.d, 3, prec, &decpt, &sgn, &se); - if (decpt == 9999) { - Format9999: - bzero(special, sizeof(special)); - p = q = special; - if (sgn) { - *q++ = '-'; - } else if (flags & FLAGS_PLUS) { - *q++ = '+'; - } else if (flags & FLAGS_SPACE) { - *q++ = ' '; - } - memcpy(q, kSpecialFloats[*s == 'N'][d >= 'a'], 4); - FormatThatThing: - __fmt_free_dtoa(&mem); - mem = 0; - prec = alt = 0; + prec = 0; flags &= ~(FLAGS_PRECISION | FLAGS_PLUS | FLAGS_SPACE); goto FormatString; } - FormatReal: - if (sgn) sign = '-'; - if (prec > 0) width -= prec; - if (width > 0) { - if (sign) --width; - if (decpt <= 0) { - --width; - if (prec > 0) --width; - } else { - if (s == se) decpt = 1; - width -= decpt; - if (prec > 0 || alt) --width; - } - } - if (width > 0 && !(flags & FLAGS_LEFT)) { - if (flags & FLAGS_ZEROPAD) { - if (sign) PUT(sign); - sign = 0; - do PUT('0'); - while (--width > 0); - } else { - do PUT(' '); - while (--width > 0); - } - } - if (sign) PUT(sign); - if (decpt <= 0) { - PUT('0'); - if (prec > 0 || alt) PUT('.'); - while (decpt < 0) { - PUT('0'); - prec--; - decpt++; - } - } else { - do { - if ((c = *s)) { - s++; - } else { - c = '0'; - } - PUT(c); - } while (--decpt > 0); - if (prec > 0 || alt) PUT('.'); - } - while (--prec >= 0) { - if ((c = *s)) { - s++; - } else { - c = '0'; - } - PUT(c); - } - while (--width >= 0) { - PUT(' '); - } - __fmt_free_dtoa(&mem); - continue; - - case 'G': - case 'g': - if (!(flags & FLAGS_PRECISION)) prec = 6; - if (longdouble) { - pun.d = va_arg(va, long double); - } else { - pun.d = va_arg(va, double); - } - if (prec < 0) prec = 0; - if (!weaken(__fmt_dtoa)) { - p = "?"; - goto FormatThatThing; - } - assert(!mem); - s = mem = - weaken(__fmt_dtoa)(pun.d, prec ? 2 : 0, prec, &decpt, &sgn, &se); - if (decpt == 9999) goto Format9999; - c = se - s; - prec1 = prec; - if (!prec) { - prec = c; - prec1 = c + (s[1] || alt ? 5 : 4); - } - if (decpt > -4 && decpt <= prec1) { - if (alt) { - prec -= decpt; - } else { - prec = c - decpt; - } - if (prec < 0) prec = 0; - goto FormatReal; - } - d -= 2; - if (!alt && prec > c) prec = c; - --prec; - goto FormatExpo; - - case 'e': - case 'E': - if (!(flags & FLAGS_PRECISION)) prec = 6; - if (longdouble) { - pun.d = va_arg(va, long double); - } else { - pun.d = va_arg(va, double); - } - if (prec < 0) prec = 0; - if (!weaken(__fmt_dtoa)) { - p = "?"; - goto FormatThatThing; - } - assert(!mem); - s = mem = weaken(__fmt_dtoa)(pun.d, 2, prec + 1, &decpt, &sgn, &se); - if (decpt == 9999) goto Format9999; - FormatExpo: - if (sgn) sign = '-'; - if ((width -= prec + 5) > 0) { - if (sign) --width; - if (prec || alt) --width; - } - if ((c = --decpt) < 0) c = -c; - while (c >= 100) { - --width; - c /= 10; - } - if (width > 0 && !(flags & FLAGS_LEFT)) { - if (flags & FLAGS_ZEROPAD) { - if (sign) PUT(sign); - sign = 0; - do PUT('0'); - while (--width > 0); - } else { - do PUT(' '); - while (--width > 0); - } - } - if (sign) PUT(sign); - PUT(*s++); - if (prec || alt) PUT('.'); - while (--prec >= 0) { - if ((c = *s)) { - s++; - } else { - c = '0'; - } - PUT(c); - } - __fmt_free_dtoa(&mem); - PUT(d); - if (decpt < 0) { - PUT('-'); - decpt = -decpt; - } else { - PUT('+'); - } - for (c = 2, k = 10; 10 * k <= decpt; c++) k *= 10; - for (;;) { - i1 = decpt / k; - PUT(i1 + '0'); - if (--c <= 0) break; - decpt -= i1 * k; - decpt *= 10; - } - while (--width >= 0) { - PUT(' '); - } - continue; - - case 'a': - alphabet = "0123456789abcdefpx"; - goto FormatBinary; - case 'A': - alphabet = "0123456789ABCDEFPX"; - FormatBinary: - if (longdouble) { - pun.d = va_arg(va, long double); - } else { - pun.d = va_arg(va, double); - } - if ((pun.u[1] & 0x7ff00000) == 0x7ff00000) { - goto FormatDtoa; - } - if (pun.u[1] & 0x80000000) { - sign = '-'; - pun.u[1] &= 0x7fffffff; - } - if (pun.d) { - c = '1'; - bex = (pun.u[1] >> 20) - 1023; - pun.u[1] &= 0xfffff; - if (bex == -1023) { - ++bex; - if (pun.u[1]) { - do { - --bex; - pun.u[1] <<= 1; - if (pun.u[0] & 0x80000000) pun.u[1] |= 1; - pun.u[0] <<= 1; - } while (pun.u[1] < 0x100000); - } else { - while (!(pun.u[0] & 0x80000000)) { - --bex; - pun.u[0] <<= 1; - } - bex -= 21; - pun.u[1] = pun.u[0] >> 11; - pun.u[0] <<= 21; - } - } - } else { - c = '0'; - bex = 0; - } - if (flags & FLAGS_PRECISION) { - if (prec > 13) prec = 13; - if (pun.d && prec < 13) { - pun.u[1] |= 0x100000; - if (prec < 5) { - ui = 1u << ((5 - prec) * 4 - 1); - if (pun.u[1] & ui) { - if (pun.u[1] & ((ui - 1) | (ui << 1)) || pun.u[0]) { - pun.u[1] += ui; - BexCheck: - if (pun.u[1] & 0x200000) { - ++bex; - pun.u[1] >>= 1; - } - } - } - } else if (prec == 5) { - if (pun.u[0] & 0x80000000) { - BumpIt: - ++pun.u[1]; - goto BexCheck; - } - } else { - i1 = (13 - prec) * 4; - ui = 1u << (i1 - 1); - if (pun.u[0] & ui && pun.u[0] & ((ui - 1) | (ui << 1))) { - pun.u[0] += ui; - if (!(pun.u[0] >> i1)) goto BumpIt; - } - } - } - } else { - if ((ui = pun.u[0])) { - ui = __builtin_ctz(ui); - prec = 6 + ((32 - ROUNDDOWN(ui, 4)) >> 2) - 1; - } else if ((ui = pun.u[1] & 0xfffff)) { - ui = __builtin_ctz(ui); - prec = (20 - ROUNDDOWN(ui, 4)) >> 2; - } else { - prec = 0; - } - } - bw = 1; - if (bex) { - if ((i1 = bex) < 0) i1 = -i1; - while (i1 >= 10) { - ++bw; - i1 /= 10; - } - } - if (pun.u[1] & 0x80000000) { - pun.u[1] &= 0x7fffffff; - if (pun.d || sign) sign = '-'; - } - if ((width -= bw + 5) > 0) { - if (sign) --width; - if (prec || alt) --width; - } - if (pun.q && prec > 0) { - width -= ROUNDUP(bsrl(pun.q) + 1, 4) >> 2; - } - if (width > 0 && !(flags & FLAGS_LEFT)) { - if (flags & FLAGS_ZEROPAD) { - if (sign) { - PUT(sign); - sign = 0; - } - do PUT('0'); - while (--width > 0); - } else { - do PUT(' '); - while (--width > 0); - } - } - if (sign) PUT(sign); - PUT('0'); - PUT(alphabet[17]); - PUT(c); - if (prec > 0 || alt) PUT('.'); - while (prec-- > 0) { - PUT(alphabet[(pun.q >> 48) & 0xf]); - pun.q <<= 4; - } - PUT(alphabet[16]); - if (bex < 0) { - PUT('-'); - bex = -bex; - } else { - PUT('+'); - } - for (c = 1; 10 * c <= bex;) c *= 10; - for (;;) { - i1 = bex / c; - PUT('0' + i1); - if (!--bw) break; - bex -= i1 * c; - bex *= 10; + if (weaken(__fmt_dtoa)(out, arg, d, flags, prec, sign, width, + longdouble, qchar, signbit, alphabet, + va) == -1) { + return -1; } break; - case '%': - PUT('%'); + __FMT_PUT('%'); break; - default: - PUT(format[-1]); + __FMT_PUT(format[-1]); break; } } - assert(!mem); return 0; } diff --git a/libc/fmt/fmt.h b/libc/fmt/fmt.h index 6ecc118a2..199b004a6 100644 --- a/libc/fmt/fmt.h +++ b/libc/fmt/fmt.h @@ -15,18 +15,17 @@ COSMOPOLITAN_C_START_ int snprintf(char *, size_t, const char *, ...) printfesque(3) - paramsnonnull((3)) nothrow nocallback; + paramsnonnull((3)) dontthrow nocallback; int vsnprintf(char *, size_t, const char *, va_list) - paramsnonnull((3)) nothrow nocallback; + paramsnonnull((3)) dontthrow nocallback; int sprintf(char *, const char *, ...) printfesque(2) - paramsnonnull((2)) nothrow nocallback frownedupon(snprintf); + paramsnonnull((2)) dontthrow nocallback frownedupon(snprintf); int vsprintf(char *, const char *, va_list) - paramsnonnull((2)) nothrow nocallback frownedupon(vsnprintf); + paramsnonnull((2)) dontthrow nocallback frownedupon(vsnprintf); int sscanf(const char *, const char *, ...) scanfesque(2); int vsscanf(const char *, const char *, va_list); int vcscanf(int (*)(void *), int (*)(int, void *), void *, const char *, va_list); -int strerror_r(int, char *, size_t) nothrow nocallback; int __fmt(void *, void *, const char *, va_list) hidden; char *itoa(int, char *, int) compatfn; char *fcvt(double, int, int *, int *); diff --git a/libc/fmt/fmt.internal.h b/libc/fmt/fmt.internal.h new file mode 100644 index 000000000..48f4662a7 --- /dev/null +++ b/libc/fmt/fmt.internal.h @@ -0,0 +1,30 @@ +#ifndef COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_ + +#define PRINTF_NTOA_BUFFER_SIZE 144 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define __FMT_PUT(C) \ + do { \ + char Buf[1] = {C}; \ + if (out(Buf, arg, 1) == -1) { \ + return -1; \ + } \ + } while (0) + +int __fmt_pad(int (*)(const char *, void *, size_t), void *, + unsigned long) hidden; +int __fmt_stoa(int (*)(const char *, void *, size_t), void *, void *, + unsigned long, unsigned long, unsigned long, unsigned char, + unsigned char) hidden; +int __fmt_ntoa(int (*)(const char *, void *, size_t), void *, va_list, + unsigned char, unsigned long, unsigned long, unsigned long, + unsigned char, const char *) hidden; +int __fmt_dtoa(int (*)(const char *, void *, size_t), void *, int, int, int, + int, int, bool, char, unsigned char, const char *, va_list); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_ */ diff --git a/libc/fmt/fmts.h b/libc/fmt/fmts.h deleted file mode 100644 index c56f88650..000000000 --- a/libc/fmt/fmts.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_FMT_FMTS_H_ -#define COSMOPOLITAN_LIBC_FMT_FMTS_H_ - -#define PRINTF_NTOA_BUFFER_SIZE 144 - -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -int __fmt_pad(int (*)(const char *, void *, size_t), void *, - unsigned long) hidden; -int __fmt_stoa(int (*)(const char *, void *, size_t), void *, void *, - unsigned long, unsigned long, unsigned long, unsigned char, - unsigned char) hidden; -int __fmt_ntoa(int (*)(const char *, void *, size_t), void *, va_list, - unsigned char, unsigned long, unsigned long, unsigned long, - unsigned char, const char *) hidden; -char *__fmt_dtoa(double, int, int, int *, int *, char **) hidden; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_FMT_FMTS_H_ */ diff --git a/libc/fmt/formatbinary64.c b/libc/fmt/formatbinary64.c new file mode 100644 index 000000000..5e4e1b011 --- /dev/null +++ b/libc/fmt/formatbinary64.c @@ -0,0 +1,63 @@ +/*-*- 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/fmt/itoa.h" +#include "libc/nexgen32e/bsr.h" + +static inline int PickGoodWidth(unsigned x) { + if (x < 16) { + if (x < 2) return 0; + if (x < 8) return 7; + return 15; + } else { + if (x < 32) return 31; + return 63; + } +} + +/** + * Converts unsigned 64-bit integer to binary string. + * + * @param p needs at least 67 bytes + * @param z is 0 for DIGITS, 1 for 0bDIGITS, 2 for 0bDIGITS if ≠0 + * @return pointer to nul byte + */ +char *FormatBinary64(char p[hasatleast 67], uint64_t x, char z) { + int i; + uint64_t b; + if (x) { + if (z) { + *p++ = '0'; + *p++ = 'b'; + } + i = PickGoodWidth(bsrl(x)); + do { + b = 1; + b <<= i; + *p++ = '0' + !!(x & b); + } while (i--); + } else { + if (z == 1) { + *p++ = '0'; + *p++ = 'b'; + } + *p++ = '0'; + } + *p = 0; + return p; +} diff --git a/libc/fmt/formatflex64.c b/libc/fmt/formatflex64.c new file mode 100644 index 000000000..2c8b7f106 --- /dev/null +++ b/libc/fmt/formatflex64.c @@ -0,0 +1,63 @@ +/*-*- 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 2022 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/fmt/fmt.h" +#include "libc/fmt/itoa.h" +#include "libc/math.h" + +static inline int CountZeroesHex(uint64_t x) { + int n; + for (n = 0; x;) { + if (!(x & 15)) { + ++n; + } + x >>= 4; + } + return n; +} + +static inline int CountZeroesDec(int64_t s) { + int n, r; + uint64_t x; + x = s >= 0 ? s : -(uint64_t)s; + for (n = 0; x;) { + r = x % 10; + x = x / 10; + if (!r) ++n; + } + return n; +} + +/** + * Formats integer using decimal or hexadecimal. + * + * We choose hex vs. decimal based on whichever one has the most zeroes. + * We only bother counting zeroes for numbers outside -256 ≤ 𝑥 ≤ 256. + */ +char *FormatFlex64(char p[hasatleast 24], int64_t x, char z) { + int zhex, zdec; + if (-256 <= x && x <= 256) goto UseDecimal; + zhex = CountZeroesHex(x) * 16; + zdec = CountZeroesDec(x) * 10; + if (zdec >= zhex) { + UseDecimal: + return FormatInt64(p, x); + } else { + return FormatHex64(p, x, z); + } +} diff --git a/libc/fmt/formathex64.c b/libc/fmt/formathex64.c new file mode 100644 index 000000000..528150e4b --- /dev/null +++ b/libc/fmt/formathex64.c @@ -0,0 +1,64 @@ +/*-*- 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/fmt/itoa.h" +#include "libc/macros.internal.h" +#include "libc/nexgen32e/bsr.h" + +static inline int PickGoodWidth(unsigned x, char z) { + if (z) { + if (x < 16) { + if (x < 8) return 8; + return 16; + } else { + if (x < 32) return 32; + return 64; + } + } else { + return ROUNDUP(x + 1, 4); + } +} + +/** + * Converts unsigned 64-bit integer to hex string. + * + * @param p needs at least 19 bytes + * @param z is 0 for DIGITS, 1 for 0bDIGITS, 2 for 0bDIGITS if ≠0 + * @return pointer to nul byte + */ +char *FormatHex64(char p[hasatleast 19], uint64_t x, char z) { + int i; + if (x) { + if (z) { + *p++ = '0'; + *p++ = 'x'; + } + i = PickGoodWidth(bsrl(x), z); + do { + *p++ = "0123456789abcdef"[(x >> (i -= 4)) & 15]; + } while (i); + } else { + if (z == 1) { + *p++ = '0'; + *p++ = 'x'; + } + *p++ = '0'; + } + *p = 0; + return p; +} diff --git a/libc/fmt/formatint32.c b/libc/fmt/formatint32.c index 4637eb710..9afc72f50 100644 --- a/libc/fmt/formatint32.c +++ b/libc/fmt/formatint32.c @@ -24,7 +24,7 @@ * @param p needs at least 12 bytes * @return pointer to nul byte */ -dontinline char *FormatUint32(char p[static 12], uint32_t x) { +dontinline char *FormatUint32(char p[hasatleast 12], uint32_t x) { char t; size_t i, a, b; i = 0; @@ -49,7 +49,7 @@ dontinline char *FormatUint32(char p[static 12], uint32_t x) { * @param p needs at least 12 bytes * @return pointer to nul byte */ -char *FormatInt32(char p[static 12], int32_t x) { +char *FormatInt32(char p[hasatleast 12], int32_t x) { if (x < 0) *p++ = '-', x = -(uint32_t)x; return FormatUint32(p, x); } diff --git a/libc/fmt/formatoctal32.c b/libc/fmt/formatoctal32.c new file mode 100644 index 000000000..18f295e20 --- /dev/null +++ b/libc/fmt/formatoctal32.c @@ -0,0 +1,47 @@ +/*-*- 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/fmt/itoa.h" + +/** + * Converts unsigned 32-bit integer to octal string. + * + * @param p needs at least 12 bytes + * @param z ensures it starts with zero + * @return pointer to nul byte + */ +char *FormatOctal32(char p[hasatleast 13], uint32_t x, bool z) { + char t; + size_t i, a, b; + i = 0; + z = x && z; + do { + p[i++] = x % 8 + '0'; + x = x / 8; + } while (x > 0); + if (z) p[i++] = '0'; + p[i] = '\0'; + if (i) { + for (a = 0, b = i - 1; a < b; ++a, --b) { + t = p[a]; + p[a] = p[b]; + p[b] = t; + } + } + return p + i; +} diff --git a/libc/fmt/formatoctal64.c b/libc/fmt/formatoctal64.c new file mode 100644 index 000000000..c82171967 --- /dev/null +++ b/libc/fmt/formatoctal64.c @@ -0,0 +1,47 @@ +/*-*- 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/fmt/itoa.h" + +/** + * Converts unsigned 64-bit integer to octal string. + * + * @param p needs at least 24 bytes + * @param z ensures it starts with zero + * @return pointer to nul byte + */ +char *FormatOctal64(char p[hasatleast 24], uint64_t x, bool z) { + char t; + size_t i, a, b; + i = 0; + z = x && z; + do { + p[i++] = x % 8 + '0'; + x = x / 8; + } while (x > 0); + if (z) p[i++] = '0'; + p[i] = '\0'; + if (i) { + for (a = 0, b = i - 1; a < b; ++a, --b) { + t = p[a]; + p[a] = p[b]; + p[b] = t; + } + } + return p + i; +} diff --git a/libc/fmt/i128abs.c b/libc/fmt/i128abs.c new file mode 100644 index 000000000..c35be4f75 --- /dev/null +++ b/libc/fmt/i128abs.c @@ -0,0 +1,24 @@ +/*-*- 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 "libc/fmt/conv.h" +#include "libc/macros.internal.h" + +int128_t i128abs(int128_t x) { + return ABS(x); +} diff --git a/libc/fmt/imaxabs.c b/libc/fmt/imaxabs.c index 664d4d616..11a640d9f 100644 --- a/libc/fmt/imaxabs.c +++ b/libc/fmt/imaxabs.c @@ -19,6 +19,6 @@ #include "libc/fmt/conv.h" #include "libc/macros.internal.h" -intmax_t(imaxabs)(intmax_t x) { +intmax_t imaxabs(intmax_t x) { return ABS(x); } diff --git a/libc/fmt/imaxabs.thunk.S b/libc/fmt/imaxabs.thunk.S deleted file mode 100644 index 6f4025137..000000000 --- a/libc/fmt/imaxabs.thunk.S +++ /dev/null @@ -1,23 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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 "libc/macros.internal.h" - -__imaxabs: - jmp imaxabs - .endfn __imaxabs,globl diff --git a/libc/fmt/isabspath.c b/libc/fmt/isabspath.c deleted file mode 100644 index 877e22a5e..000000000 --- a/libc/fmt/isabspath.c +++ /dev/null @@ -1,38 +0,0 @@ -/*-*- 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 "libc/fmt/conv.h" -#include "libc/fmt/isslash.internal.h" - -/** - * Returns true if pathname could be absolute on any known platform. - * - * The ones we know about are System V (/foo/bar), DOS (C:\foo\bar), - * Windows NT (\\.\C:\foo\bar), Google Cloud (gs://bucket/foo/bar), etc. - */ -bool isabspath(const char *path) { - if (isslash(*path)) return true; - for (; *path; ++path) { - if (isslash(*path)) return false; - if (*path == ':') { - ++path; - if (isslash(*path)) return true; - } - } - return false; -} diff --git a/libc/fmt/isslash.internal.h b/libc/fmt/isslash.internal.h deleted file mode 100644 index 4ee549e46..000000000 --- a/libc/fmt/isslash.internal.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_FMT_ISSLASH_H_ -#define COSMOPOLITAN_LIBC_FMT_ISSLASH_H_ -#if !(__ASSEMBLER__ + __LINKER__ + 0) - -forceinline bool isslash(int c) { - return c == '/' || c == '\\'; -} - -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_FMT_ISSLASH_H_ */ diff --git a/libc/fmt/itoa.h b/libc/fmt/itoa.h index 5cfbc1466..a492328d1 100644 --- a/libc/fmt/itoa.h +++ b/libc/fmt/itoa.h @@ -2,19 +2,6 @@ #define COSMOPOLITAN_LIBC_FMT_ITOA_H_ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § integer conversion ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│─╝ - FASTEST + TINY - - - uint64toarray_radix10(0x31337, a) l: 68 (20ns) m: 112 (33ns) - - int64toarray_radix10(0x31337, a) l: 69 (20ns) m: 134 (39ns) - - FAST + AWESOME - - - snprintf(a, sizeof(a), "%d", 0x31337) l: 199 (58ns) m: 421 (123ns) - - uint128toarray_radix10(0x31337, a) l: 93 (27ns) m: 141 (41ns) - - int128toarray_radix10(0x31337, a) l: 96 (28ns) m: 173 (51ns) */ unsigned LengthInt64(int64_t) pureconst; unsigned LengthUint64(uint64_t) pureconst; @@ -26,8 +13,11 @@ char *FormatInt64(char[hasatleast 21], int64_t); char *FormatUint64(char[hasatleast 21], uint64_t); char *FormatInt64Thousands(char[hasatleast 27], int64_t); char *FormatUint64Thousands(char[hasatleast 27], uint64_t); -size_t int64toarray_radix10(int64_t, char[hasatleast 21]); -size_t uint64toarray_radix10(uint64_t, char[hasatleast 21]); +char *FormatOctal32(char[hasatleast 13], uint32_t, bool); +char *FormatOctal64(char[hasatleast 24], uint64_t, bool); +char *FormatBinary64(char[hasatleast 67], uint64_t, char); +char *FormatHex64(char[hasatleast 19], uint64_t, char); +char *FormatFlex64(char[hasatleast 24], int64_t, char); size_t uint64toarray_radix16(uint64_t, char[hasatleast 17]); size_t uint64toarray_fixed16(uint64_t, char[hasatleast 17], uint8_t); size_t uint64toarray_radix8(uint64_t, char[hasatleast 24]); diff --git a/libc/fmt/itoa64radix10.greg.c b/libc/fmt/itoa64radix10.greg.c deleted file mode 100644 index 25d403a8c..000000000 --- a/libc/fmt/itoa64radix10.greg.c +++ /dev/null @@ -1,49 +0,0 @@ -/*-*- 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 "libc/alg/reverse.internal.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/itoa.h" -#include "libc/limits.h" - -/** - * Converts unsigned 64-bit integer to string. - * @param a needs at least 21 bytes - * @return bytes written w/o nul - */ -dontinline size_t uint64toarray_radix10(uint64_t i, char a[hasatleast 21]) { - size_t j = 0; - do { - a[j++] = i % 10 + '0'; - i = i / 10; - } while (i > 0); - a[j] = '\0'; - reverse(a, j); - return j; -} - -/** - * Converts signed 64-bit integer to string. - * @param a needs at least 21 bytes - * @return bytes written w/o nul - */ -size_t int64toarray_radix10(int64_t i, char a[hasatleast 21]) { - if (i >= 0) return uint64toarray_radix10(i, a); - *a++ = '-'; - return 1 + uint64toarray_radix10(-(uint64_t)i, a); -} diff --git a/libc/fmt/kdos2errno.S b/libc/fmt/kdos2errno.S deleted file mode 100644 index 8c9789855..000000000 --- a/libc/fmt/kdos2errno.S +++ /dev/null @@ -1,102 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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/nt/errors.h" -#include "libc/macros.internal.h" - -// @fileoverview data structure for __dos2errno() - - .macro .e doscode systemv - .short \doscode - .long \systemv - kDos2Errno - .endm - - .section .rodata -kDos2Errno: - .e kNtErrorModNotFound,ENOSYS - .e kNtErrorBadCommand,EACCES - .e kNtErrorBadLength,EACCES - .e kNtErrorBadNetpath,ENOENT - .e kNtErrorBadNetName,ENOENT - .e kNtErrorBadNetResp,ENETDOWN - .e kNtErrorBadPathname,ENOENT - .e kNtErrorCannotMake,EACCES - .e kNtErrorCommitmentLimit,ENOMEM - .e kNtErrorConnectionAborted,ECONNABORTED - .e kNtErrorConnectionActive,EISCONN - .e kNtErrorConnectionRefused,ECONNREFUSED - .e kNtErrorCrc,EACCES - .e kNtErrorDirNotEmpty,ENOTEMPTY - .e kNtErrorDupName,EADDRINUSE - .e kNtErrorFilenameExcedRange,ENOENT - .e kNtErrorGenFailure,EACCES - .e kNtErrorGracefulDisconnect,EPIPE - .e kNtErrorHostDown,EHOSTUNREACH - .e kNtErrorHostUnreachable,EHOSTUNREACH - .e kNtErrorInsufficientBuffer,EFAULT - .e kNtErrorInvalidAddress,EADDRNOTAVAIL - .e kNtErrorInvalidFunction,EINVAL - .e kNtErrorInvalidNetname,EADDRNOTAVAIL - .e kNtErrorInvalidUserBuffer,EMSGSIZE - .e kNtErrorIoPending,EINPROGRESS - .e kNtErrorLockViolation,EACCES - .e kNtErrorMoreData,EMSGSIZE - .e kNtErrorNetnameDeleted,ECONNABORTED - .e kNtErrorNetworkAccessDenied,EACCES - .e kNtErrorNetworkBusy,ENETDOWN - .e kNtErrorNetworkUnreachable,ENETUNREACH - .e kNtErrorNoaccess,EFAULT - .e kNtErrorNonpagedSystemResources,ENOMEM - .e kNtErrorNotEnoughMemory,ENOMEM - .e kNtErrorNotEnoughQuota,ENOMEM - .e kNtErrorNotFound,ENOENT - .e kNtErrorNotLocked,EACCES - .e kNtErrorNotReady,EACCES - .e kNtErrorNotSupported,ENOTSUP - .e kNtErrorNoMoreFiles,ENOENT - .e kNtErrorNoSystemResources,ENOMEM - .e kNtErrorOperationAborted,EINTR - .e kNtErrorOutOfPaper,EACCES - .e kNtErrorPagedSystemResources,ENOMEM - .e kNtErrorPagefileQuota,ENOMEM - .e kNtErrorPipeNotConnected,EPIPE - .e kNtErrorPortUnreachable,ECONNRESET - .e kNtErrorProtocolUnreachable,ENETUNREACH - .e kNtErrorRemNotList,ECONNREFUSED - .e kNtErrorRequestAborted,EINTR - .e kNtErrorReqNotAccep,EWOULDBLOCK - .e kNtErrorSectorNotFound,EACCES - .e kNtErrorSemTimeout,ETIMEDOUT - .e kNtErrorSharingViolation,EACCES - .e kNtErrorTooManyNames,ENOMEM - .e kNtErrorUnexpNetErr,ECONNABORTED - .e kNtErrorWorkingSetQuota,ENOMEM - .e kNtErrorWriteProtect,EACCES - .e kNtErrorWrongDisk,EACCES - .e WSAEACCES,EACCES - .e WSAEDISCON,EPIPE - .e WSAEFAULT,EFAULT - .e WSAEINPROGRESS,EBUSY - .e WSAEINVAL,EINVAL - .e WSAEPROCLIM,ENOMEM - .e WSAESHUTDOWN,EPIPE - .e WSANOTINITIALISED,ENETDOWN - .e WSASYSNOTREADY,ENETDOWN - .e WSAVERNOTSUPPORTED,ENOSYS - .short 0 - .endobj kDos2Errno,globl,hidden diff --git a/libc/fmt/kerrnodocs.S b/libc/fmt/kerrnodocs.S new file mode 100644 index 000000000..d03750d07 --- /dev/null +++ b/libc/fmt/kerrnodocs.S @@ -0,0 +1,121 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/fmt/magnumstrs.internal.h" +#include "libc/macros.internal.h" + + .macro .e e s + .long \e - kErrnoDocs + .long 1f - kErrnoDocs + .rodata.str1.1 +1: .asciz "\s" + .previous + .endm + + .section .rodata + .align 4 + .underrun +kErrnoDocs: + .e EINVAL,"Invalid argument" + .e ENOSYS,"Function not implemented" + .e EPERM,"Operation not permitted" + .e ENOENT,"No such file or directory" + .e ESRCH,"No such process" + .e EINTR,"Interrupted system call" + .e EIO,"I/O error" + .e ENXIO,"No such device or address" + .e E2BIG,"Arg list too long" + .e ENOEXEC,"Exec format error" + .e EBADF,"Bad file number" + .e ECHILD,"No child processes" + .e EAGAIN,"Try again" + .e ENOMEM,"Out of memory" + .e EACCES,"Permission denied" + .e EFAULT,"Bad address" + .e ENOTBLK,"Block device required" + .e EBUSY,"Device or resource busy" + .e EEXIST,"File exists" + .e EXDEV,"Cross-device link" + .e ENODEV,"No such device" + .e ENOTDIR,"Not a directory" + .e EISDIR,"Is a directory" + .e ENFILE,"File table overflow" + .e EMFILE,"Too many open files" + .e ENOTTY,"Not a typewriter" + .e ETXTBSY,"Text file busy" + .e EFBIG,"File too large" + .e ENOSPC,"No space left on device" + .e EDQUOT,"Quota exceeded" + .e ESPIPE,"Illegal seek" + .e EROFS,"Read-only file system" + .e EMLINK,"Too many links" + .e EPIPE,"Broken pipe" + .e EDOM,"Math argument out of domain of func" + .e ERANGE,"Math result not representable" + .e EDEADLK,"Resource deadlock would occur" + .e ENAMETOOLONG,"File name too long" + .e ENOLCK,"No record locks available" + .e ENOTEMPTY,"Directory not empty" + .e ELOOP,"Too many symbolic links encountered" + .e ENOMSG,"No message of desired type" + .e EIDRM,"Identifier removed" + .e ETIME,"Timer expired" + .e EPROTO,"Protocol error" + .e EOVERFLOW,"Value too large for defined data type" + .e EILSEQ,"Illegal byte sequence" + .e EUSERS,"Too many users" + .e ENOTSOCK,"Socket operation on non-socket" + .e EDESTADDRREQ,"Destination address required" + .e EMSGSIZE,"Message too long" + .e EPROTOTYPE,"Protocol wrong type for socket" + .e ENOPROTOOPT,"Protocol not available" + .e EPROTONOSUPPORT,"Protocol not supported" + .e ESOCKTNOSUPPORT,"Socket type not supported" + .e ENOTSUP,"Operation not supported" + .e EOPNOTSUPP,"Operation not supported on transport endpoint" + .e EPFNOSUPPORT,"Protocol family not supported" + .e EAFNOSUPPORT,"Address family not supported by protocol" + .e EADDRINUSE,"Address already in use" + .e EADDRNOTAVAIL,"Cannot assign requested address" + .e ENETDOWN,"Network is down" + .e ENETUNREACH,"Network is unreachable" + .e ENETRESET,"Network dropped connection because of reset" + .e ECONNABORTED,"Software caused connection abort" + .e ECONNRESET,"Connection reset by peer" + .e ENOBUFS,"No buffer space available" + .e EISCONN,"Transport endpoint is already connected" + .e ENOTCONN,"Transport endpoint is not connected" + .e ESHUTDOWN,"Cannot send after transport endpoint shutdown" + .e ETOOMANYREFS,"Too many references: cannot splice" + .e ETIMEDOUT,"Connection timed out" + .e ECONNREFUSED,"Connection refused" + .e EHOSTDOWN,"Host is down" + .e EHOSTUNREACH,"No route to host" + .e EALREADY,"Operation already in progress" + .e EINPROGRESS,"Operation now in progress" + .e ESTALE,"Stale NFS file handle" + .e EREMOTE,"Object is remote" + .e EBADMSG,"Not a data message" + .e ECANCELED,"Operation Canceled" + .e EOWNERDEAD,"Owner died" + .e ENOTRECOVERABLE,"State not recoverable" + .e ENONET,"Machine is not on the network" + .e ERESTART,"Interrupted system call should be restarted" + .long MAGNUM_TERMINATOR + .endobj kErrnoDocs,globl,hidden + .overrun diff --git a/libc/fmt/kerrnonames.S b/libc/fmt/kerrnonames.S new file mode 100644 index 000000000..85394e0e2 --- /dev/null +++ b/libc/fmt/kerrnonames.S @@ -0,0 +1,122 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/fmt/magnumstrs.internal.h" +#include "libc/macros.internal.h" + + .macro .e e + .long \e - kErrnoNames + .long 1f - kErrnoNames + .rodata.str1.1 +1: .string "\e" + .previous + .endm + + .section .rodata + .align 4 + .underrun +kErrnoNames: + .e EINVAL + .e ENOSYS + .e EPERM + .e ENOENT + .e ESRCH + .e EINTR + .e EIO + .e ENXIO + .e E2BIG + .e ENOEXEC + .e EBADF + .e ECHILD + .e EAGAIN + .e ENOMEM + .e EACCES + .e EFAULT + .e ENOTBLK + .e EBUSY + .e EEXIST + .e EXDEV + .e ENODEV + .e ENOTDIR + .e EISDIR + .e ENFILE + .e EMFILE + .e ENOTTY + .e ETXTBSY + .e EFBIG + .e ENOSPC + .e EDQUOT + .e ESPIPE + .e EROFS + .e EMLINK + .e EPIPE + .e EDOM + .e ERANGE + .e EDEADLK + .e ENAMETOOLONG + .e ENOLCK + .e ENOTEMPTY + .e ELOOP + .e ENOMSG + .e EIDRM + .e ETIME + .e EPROTO + .e EOVERFLOW + .e EILSEQ + .e EUSERS + .e ENOTSOCK + .e EDESTADDRREQ + .e EMSGSIZE + .e EPROTOTYPE + .e ENOPROTOOPT + .e EPROTONOSUPPORT + .e ESOCKTNOSUPPORT + .e ENOTSUP + .e EOPNOTSUPP + .e EPFNOSUPPORT + .e EAFNOSUPPORT + .e EADDRINUSE + .e EADDRNOTAVAIL + .e ENETDOWN + .e ENETUNREACH + .e ENETRESET + .e ECONNABORTED + .e ECONNRESET + .e ENOBUFS + .e EISCONN + .e ENOTCONN + .e ESHUTDOWN + .e ETOOMANYREFS + .e ETIMEDOUT + .e ECONNREFUSED + .e EHOSTDOWN + .e EHOSTUNREACH + .e EALREADY + .e EINPROGRESS + .e ESTALE + .e EREMOTE + .e EBADMSG + .e ECANCELED + .e EOWNERDEAD + .e ENOTRECOVERABLE + .e ENONET + .e ERESTART + .e ENODATA + .long MAGNUM_TERMINATOR + .endobj kErrnoNames,globl,hidden + .overrun diff --git a/libc/fmt/kerrornames.S b/libc/fmt/kerrornames.S deleted file mode 100644 index fa3072923..000000000 --- a/libc/fmt/kerrornames.S +++ /dev/null @@ -1,118 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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/macros.internal.h" - - .macro .e e - .long \e - kErrorNames - .long 1f - kErrorNames - .rodata.str1.1 -1: .string "\e" - .previous - .endm - - .section .rodata - .align 4 -kErrorNames: - .e ENOSYS - .e EPERM - .e ENOENT - .e ESRCH - .e EINTR - .e EIO - .e ENXIO - .e E2BIG - .e ENOEXEC - .e EBADF - .e ECHILD - .e EAGAIN - .e ENOMEM - .e EACCES - .e EFAULT - .e ENOTBLK - .e EBUSY - .e EEXIST - .e EXDEV - .e ENODEV - .e ENOTDIR - .e EISDIR - .e EINVAL - .e ENFILE - .e EMFILE - .e ENOTTY - .e ETXTBSY - .e EFBIG - .e ENOSPC - .e EDQUOT - .e ESPIPE - .e EROFS - .e EMLINK - .e EPIPE - .e EDOM - .e ERANGE - .e EDEADLK - .e ENAMETOOLONG - .e ENOLCK - .e ENOTEMPTY - .e ELOOP - .e ENOMSG - .e EIDRM - .e ETIME - .e EPROTO - .e EOVERFLOW - .e EILSEQ - .e EUSERS - .e ENOTSOCK - .e EDESTADDRREQ - .e EMSGSIZE - .e EPROTOTYPE - .e ENOPROTOOPT - .e EPROTONOSUPPORT - .e ESOCKTNOSUPPORT - .e ENOTSUP - .e EOPNOTSUPP - .e EPFNOSUPPORT - .e EAFNOSUPPORT - .e EADDRINUSE - .e EADDRNOTAVAIL - .e ENETDOWN - .e ENETUNREACH - .e ENETRESET - .e ECONNABORTED - .e ECONNRESET - .e ENOBUFS - .e EISCONN - .e ENOTCONN - .e ESHUTDOWN - .e ETOOMANYREFS - .e ETIMEDOUT - .e ECONNREFUSED - .e EHOSTDOWN - .e EHOSTUNREACH - .e EALREADY - .e EINPROGRESS - .e ESTALE - .e EREMOTE - .e EBADMSG - .e ECANCELED - .e EOWNERDEAD - .e ENOTRECOVERABLE - .e ENONET - .e ERESTART - .long 0 - .endobj kErrorNames,globl,hidden diff --git a/libc/fmt/kerrornameslong.S b/libc/fmt/kerrornameslong.S deleted file mode 100644 index c5baeb694..000000000 --- a/libc/fmt/kerrornameslong.S +++ /dev/null @@ -1,183 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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/macros.internal.h" - - .macro .e e s - .long \e - kErrorNamesLong - .long 1f - kErrorNamesLong - .rodata.str1.1 -1: .asciz "\s" - .previous - .endm - - .section .rodata - .align 4 -kErrorNamesLong: - .e EPIPE,"EPIPE[Broken pipe]" - .e ENODEV,"ENODEV[No such device]" - .e EINVAL,"EINVAL[Invalid argument]" - .e EINTR,"EINTR[Interrupted system call]" - .e ENOTBLK,"ENOTBLK[Block device required]" - .e ENOSYS,"ENOSYS[Function not implemented]" - .e EHOSTUNREACH,"EHOSTUNREACH[No route to host]" - .e ESRCH,"ESRCH[No such process]" - .e EUSERS,"EUSERS[Too many users]" - .e EXDEV,"EXDEV[Cross-device link]" - .e E2BIG,"E2BIG[Arg list too long]" - .e EREMOTE,"EREMOTE[Object is remote]" - .e ECHILD,"ECHILD[No child processes]" - .e EMSGSIZE,"EMSGSIZE[Message too long]" - .e ENOTEMPTY,"ENOTEMPTY[Directory not empty]" - .e ENOBUFS,"ENOBUFS[No buffer space available]" - .e ELOOP,"ELOOP[Too many symbolic links encountered]" - .e EAFNOSUPPORT,"EAFNOSUPPORT[Address family not supported by protocol]" - .e EHOSTDOWN,"EHOSTDOWN[Host is down]" - .e EPFNOSUPPORT,"EPFNOSUPPORT[Protocol family not supported]" - .e ENOPROTOOPT,"ENOPROTOOPT[Protocol not available]" - .e EBUSY,"EBUSY[Device or resource busy]" - .e EWOULDBLOCK,"EWOULDBLOCK[Operation would block]" - .e EBADFD,"EBADFD[File descriptor in bad state]" - .e EISCONN,"EISCONN[Transport endpoint is already connected]" - .e ESHUTDOWN,"ESHUTDOWN[Cannot send after transport endpoint shutdown]" - .e ENONET,"ENONET[Machine is not on the network]" - .e EBADE,"EBADE[Invalid exchange]" - .e EBADF,"EBADF[Bad file number]" - .e EMULTIHOP,"EMULTIHOP[Multihop attempted]" - .e EIO,"EIO[I/O error]" - .e EUNATCH,"EUNATCH[Protocol driver not attached]" - .e EPROTOTYPE,"EPROTOTYPE[Protocol wrong type for socket]" - .e ENOSPC,"ENOSPC[No space left on device]" - .e ENOEXEC,"ENOEXEC[Exec format error]" - .e EALREADY,"EALREADY[Operation already in progress]" - .e ENETDOWN,"ENETDOWN[Network is down]" - .e ENOTNAM,"ENOTNAM[Not a XENIX named type file]" - .e EACCES,"EACCES[Permission denied]" - .e ELNRNG,"ELNRNG[Link number out of range]" - .e EILSEQ,"EILSEQ[Illegal byte sequence]" - .e ENOTDIR,"ENOTDIR[Not a directory]" - .e ENOTUNIQ,"ENOTUNIQ[Name not unique on network]" - .e EPERM,"EPERM[Operation not permitted]" - .e EDOM,"EDOM[Math argument out of domain of func]" - .e EXFULL,"EXFULL[Exchange full]" - .e ECONNREFUSED,"ECONNREFUSED[Connection refused]" - .e EISDIR,"EISDIR[Is a directory]" - .e EPROTONOSUPPORT,"EPROTONOSUPPORT[Protocol not supported]" - .e EROFS,"EROFS[Read-only file system]" - .e EADDRNOTAVAIL,"EADDRNOTAVAIL[Cannot assign requested address]" - .e EIDRM,"EIDRM[Identifier removed]" - .e ECOMM,"ECOMM[Communication error on send]" - .e ESRMNT,"ESRMNT[Srmount error]" - .e EREMOTEIO,"EREMOTEIO[Remote I/O error]" - .e EL3RST,"EL3RST[Level 3 reset]" - .e EBADMSG,"EBADMSG[Not a data message]" - .e ENFILE,"ENFILE[File table overflow]" - .e ELIBMAX,"ELIBMAX[Attempting to link in too many shared libraries]" - .e ESPIPE,"ESPIPE[Illegal seek]" - .e ENOLINK,"ENOLINK[Link has been severed]" - .e ENETRESET,"ENETRESET[Network dropped connection because of reset]" - .e ETIMEDOUT,"ETIMEDOUT[Connection timed out]" - .e ENOENT,"ENOENT[No such file or directory]" - .e EEXIST,"EEXIST[File exists]" - .e EDQUOT,"EDQUOT[Quota exceeded]" - .e ENOSTR,"ENOSTR[Device not a stream]" - .e EBADSLT,"EBADSLT[Invalid slot]" - .e EBADRQC,"EBADRQC[Invalid request code]" - .e ELIBACC,"ELIBACC[Can not access a needed shared library]" - .e EFAULT,"EFAULT[Bad address]" - .e EFBIG,"EFBIG[File too large]" - .e EDEADLK,"EDEADLK[Resource deadlock would occur]" - .e ENOTCONN,"ENOTCONN[Transport endpoint is not connected]" - .e EDESTADDRREQ,"EDESTADDRREQ[Destination address required]" - .e ELIBSCN,"ELIBSCN[.lib section in a.out corrupted]" - .e ENOLCK,"ENOLCK[No record locks available]" - .e EISNAM,"EISNAM[Is a named type file]" - .e ECONNABORTED,"ECONNABORTED[Software caused connection abort]" - .e ENETUNREACH,"ENETUNREACH[Network is unreachable]" - .e ESTALE,"ESTALE[Stale NFS file handle]" - .e ENOSR,"ENOSR[Out of streams resources]" - .e ENOMEM,"ENOMEM[Out of memory]" - .e ENOTSOCK,"ENOTSOCK[Socket operation on non-socket]" - .e ESTRPIPE,"ESTRPIPE[Streams pipe error]" - .e EMLINK,"EMLINK[Too many links]" - .e ERANGE,"ERANGE[Math result not representable]" - .e ELIBEXEC,"ELIBEXEC[Cannot exec a shared library directly]" - .e EL3HLT,"EL3HLT[Level 3 halted]" - .e ECONNRESET,"ECONNRESET[Connection reset by peer]" - .e EADDRINUSE,"EADDRINUSE[Address already in use]" - .e EOPNOTSUPP,"EOPNOTSUPP[Operation not supported on transport endpoint]" - .e EREMCHG,"EREMCHG[Remote address changed]" - .e EAGAIN,"EAGAIN[Try again]" - .e ENAMETOOLONG,"ENAMETOOLONG[File name too long]" - .e ENOTTY,"ENOTTY[Not a typewriter]" - .e ERESTART,"ERESTART[Interrupted system call should be restarted]" - .e ESOCKTNOSUPPORT,"ESOCKTNOSUPPORT[Socket type not supported]" - .e ETIME,"ETIME[Timer expired]" - .e ETOOMANYREFS,"ETOOMANYREFS[Too many references: cannot splice]" - .e EMFILE,"EMFILE[Too many open files]" - .e ETXTBSY,"ETXTBSY[Text file busy]" - .e EINPROGRESS,"EINPROGRESS[Operation now in progress]" - .e ENXIO,"ENXIO[No such device or address]" - .e ENOTSUP,"ENOTSUP[Operation not supported]" - .e EPROTO,"EPROTO[Protocol error]" - .e ENOMSG,"ENOMSG[No message of desired type]" - .e ENODATA,"ENODATA[No data available]" - .e EOVERFLOW,"EOVERFLOW[Value too large for defined data type]" - .e ENOMEDIUM,"ENOMEDIUM[No medium found]" - .e EMEDIUMTYPE,"EMEDIUMTYPE[Wrong medium type]" - .e ECANCELED,"ECANCELED[Operation Canceled]" - .e EOWNERDEAD,"EOWNERDEAD[Owner died]" - .e ENOTRECOVERABLE,"ENOTRECOVERABLE[State not recoverable]" - .e EOWNERDEAD,"EOWNERDEAD[Process died with the lock]" - .e ENOTRECOVERABLE,"ENOTRECOVERABLE[Lock is not recoverable]" - .e EFTYPE,"EFTYPE[Inappropriate file type or format]" - .e EAUTH,"EAUTH[Authentication error]" - .e EBADRPC,"EBADRPC[RPC struct is bad]" - .e ENEEDAUTH,"ENEEDAUTH[Need authenticator]" - .e ENOATTR,"ENOATTR[Attribute not found]" - .e EPROCUNAVAIL,"EPROCUNAVAIL[Bad procedure for program]" - .e EPROGMISMATCH,"EPROGMISMATCH[Program version wrong]" - .e EPROGUNAVAIL,"EPROGUNAVAIL[RPC prog. not avail]" - .e ERPCMISMATCH,"ERPCMISMATCH[RPC version wrong]" - .e EPROCLIM,"EPROCLIM[Too many processes]" - .e EBADARCH,"EBADARCH[Bad CPU type in executable]" - .e EBADEXEC,"EBADEXEC[Bad executable (or shared library)]" - .e EBADMACHO,"EBADMACHO[Malformed Mach-o file]" - .e EDEVERR,"EDEVERR[Device error]" - .e ENOPOLICY,"ENOPOLICY[Policy not found]" - .e EPWROFF,"EPWROFF[Device power is off]" - .e ESHLIBVERS,"ESHLIBVERS[Shared library version mismatch]" - .e ENOANO,"ENOANO[No anode]" - .e EADV,"EADV[Advertise error]" - .e EL2HLT,"EL2HLT[Level 2 halted]" - .e EDOTDOT,"EDOTDOT[RFS specific error]" - .e ENOPKG,"ENOPKG[Package not installed]" - .e EBADR,"EBADR[Invalid request descriptor]" - .e ENOCSI,"ENOCSI[No CSI structure available]" - .e ENOKEY,"ENOKEY[Required key not available]" - .e EUCLEAN,"EUCLEAN[Structure needs cleaning]" - .e ECHRNG,"ECHRNG[Channel number out of range]" - .e EL2NSYNC,"EL2NSYNC[Level 2 not synchronized]" - .e EKEYEXPIRED,"EKEYEXPIRED[Key has expired]" - .e ENAVAIL,"ENAVAIL[No XENIX semaphores available]" - .e EKEYREVOKED,"EKEYREVOKED[Key has been revoked]" - .e ELIBBAD,"ELIBBAD[Accessing a corrupted shared library]" - .e EKEYREJECTED,"EKEYREJECTED[Key was rejected by service]" - .e ERFKILL,"ERFKILL[Operation not possible due to RF-kill]" - .long 0 - .endobj kErrorNamesLong,globl,hidden diff --git a/libc/fmt/labs.c b/libc/fmt/labs.c index e3a1d3916..c47c0a361 100644 --- a/libc/fmt/labs.c +++ b/libc/fmt/labs.c @@ -17,8 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/conv.h" -#include "libc/macros.internal.h" -long(labs)(long x) { - return ABS(x); +/** + * Returns absolute value of long integer. + * @note `labs(LONG_MIN)` returns `LONG_MIN` unless `-ftrapv` + * @note consider ABS() to avoid narrowing + */ +long labs(long x) { + return 0 < x ? x : -x; } diff --git a/libc/fmt/llabs.c b/libc/fmt/llabs.c index 5ded9754c..fa1670b13 100644 --- a/libc/fmt/llabs.c +++ b/libc/fmt/llabs.c @@ -17,8 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/conv.h" -#include "libc/macros.internal.h" -long long(llabs)(long long x) { - return ABS(x); +/** + * Returns absolute value of long long integer. + * @note `llabs(LONG_LONG_MIN)` returns `LONG_LONG_MIN` unless `-ftrapv` + * @note consider ABS() to avoid narrowing + */ +long long llabs(long long x) { + return 0 < x ? x : -x; } diff --git a/libc/fmt/magnumstrs.internal.h b/libc/fmt/magnumstrs.internal.h new file mode 100644 index 000000000..af425fc93 --- /dev/null +++ b/libc/fmt/magnumstrs.internal.h @@ -0,0 +1,36 @@ +#ifndef COSMOPOLITAN_LIBC_FMT_MAGNUMSTRS_H_ +#define COSMOPOLITAN_LIBC_FMT_MAGNUMSTRS_H_ + +#define MAGNUM_TERMINATOR -123 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define MAGNUM_NUMBER(TABLE, INDEX) \ + *(const int *)((uintptr_t)TABLE + TABLE[INDEX].x) + +#define MAGNUM_STRING(TABLE, INDEX) \ + (const char *)((uintptr_t)TABLE + TABLE[INDEX].s) + +struct MagnumStr { + int x, s; +}; + +hidden extern const struct MagnumStr kClockNames[]; +hidden extern const struct MagnumStr kErrnoDocs[]; +hidden extern const struct MagnumStr kErrnoNames[]; +hidden extern const struct MagnumStr kIpOptnames[]; +hidden extern const struct MagnumStr kOpenFlags[]; +hidden extern const struct MagnumStr kSignalNames[]; +hidden extern const struct MagnumStr kSockOptnames[]; +hidden extern const struct MagnumStr kTcpOptnames[]; + +char *DescribeClockName(int) hidden; +char *DescribeOpenFlags(int) hidden; +char *DescribeSockLevel(int) hidden; +char *DescribeSockOptname(int, int) hidden; +char *GetMagnumStr(const struct MagnumStr *, int) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_FMT_MAGNUMSTRS_H_ */ diff --git a/libc/fmt/mapdoserrortoerrno.c b/libc/fmt/mapdoserrortoerrno.c deleted file mode 100644 index 989a5ef99..000000000 --- a/libc/fmt/mapdoserrortoerrno.c +++ /dev/null @@ -1,41 +0,0 @@ -/*-*- 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 "libc/errno.h" -#include "libc/nt/errors.h" -#include "libc/sock/sock.h" - -struct thatispacked Dos2Errno { - uint16_t doscode; - int32_t systemv; -}; - -extern const struct Dos2Errno kDos2Errno[]; - -/** - * Translates Windows error using superset of consts.sh. - */ -textwindows errno_t __dos2errno(uint32_t error) { - int i; - for (i = 0; kDos2Errno[i].doscode; ++i) { - if (error == kDos2Errno[i].doscode) { - return *(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv); - } - } - return error; -} diff --git a/libc/fmt/ntoa.c b/libc/fmt/ntoa.c index 488dffca6..c3d838e53 100644 --- a/libc/fmt/ntoa.c +++ b/libc/fmt/ntoa.c @@ -19,13 +19,14 @@ #include "libc/alg/reverse.internal.h" #include "libc/assert.h" #include "libc/fmt/conv.h" -#include "libc/fmt/fmts.h" +#include "libc/fmt/divmod10.internal.h" +#include "libc/fmt/fmt.internal.h" #include "libc/fmt/internal.h" #include "libc/limits.h" #define BUFFER_SIZE 144 -uintmax_t __udivmodti4(uintmax_t, uintmax_t, uintmax_t *); +uint128_t __udivmodti4(uint128_t, uint128_t, uint128_t *); static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg, char *buf, unsigned len, bool negative, @@ -90,10 +91,9 @@ static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg, } int __fmt_ntoa2(int out(const char *, void *, size_t), void *arg, - uintmax_t value, bool neg, unsigned log2base, unsigned prec, + uint128_t value, bool neg, unsigned log2base, unsigned prec, unsigned width, unsigned flags, const char *alphabet) { - uint64_t u64; - uintmax_t remainder; + uint128_t remainder; unsigned len, count, digit; char buf[BUFFER_SIZE]; len = 0; @@ -103,9 +103,7 @@ int __fmt_ntoa2(int out(const char *, void *, size_t), void *arg, do { if (!log2base) { if (value <= UINT64_MAX) { - u64 = value; - digit = u64 % 10; - value = u64 / 10; + value = DivMod10(value, &digit); } else { value = __udivmodti4(value, 10, &remainder); digit = remainder; @@ -134,7 +132,7 @@ int __fmt_ntoa(int out(const char *, void *, size_t), void *arg, va_list va, unsigned long prec, unsigned long width, unsigned char flags, const char *lang) { bool neg; - uintmax_t value, sign; + uint128_t value, sign; /* ignore '0' flag when prec is given */ if (flags & FLAGS_PRECISION) { diff --git a/libc/fmt/pad.c b/libc/fmt/pad.c index c489c745f..9a1eac704 100644 --- a/libc/fmt/pad.c +++ b/libc/fmt/pad.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/fmts.h" +#include "libc/fmt/fmt.internal.h" int __fmt_pad(int out(const char *, void *, size_t), void *arg, unsigned long n) { diff --git a/libc/fmt/pflink.h b/libc/fmt/pflink.h index e8c8be11f..4e7f2fb8b 100644 --- a/libc/fmt/pflink.h +++ b/libc/fmt/pflink.h @@ -1,7 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #define COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #include "libc/dce.h" -#include "libc/fmt/fmts.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" @@ -23,7 +22,6 @@ ({ \ if (___PFLINK(FMT, strpbrk, "faAeg")) STATIC_YOINK("__fmt_dtoa"); \ if (___PFLINK(FMT, strpbrk, "cmrqs")) { \ - if (___PFLINK(FMT, strchr, '#')) STATIC_YOINK("kCp437"); \ if (___PFLINK(FMT, strstr, "%m")) STATIC_YOINK("strerror"); \ if (!IsTiny() && (___PFLINK(FMT, strstr, "%*") || \ ___PFLINK(FMT, strpbrk, "0123456789"))) { \ diff --git a/libc/fmt/stoa.c b/libc/fmt/stoa.c index 239f49af7..f7efa15ac 100644 --- a/libc/fmt/stoa.c +++ b/libc/fmt/stoa.c @@ -20,7 +20,7 @@ #include "libc/bits/bits.h" #include "libc/bits/safemacros.internal.h" #include "libc/bits/weaken.h" -#include "libc/fmt/fmts.h" +#include "libc/fmt/fmt.internal.h" #include "libc/fmt/internal.h" #include "libc/nexgen32e/bsr.h" #include "libc/str/str.h" @@ -46,7 +46,7 @@ static int __fmt_stoa_wide(out_f out, void *a, uint64_t w) { static int __fmt_stoa_bing(out_f out, void *a, uint64_t w) { char buf[8]; - w = tpenc((*weaken(kCp437))[w & 0xFF]); + w = tpenc(kCp437[w & 0xFF]); WRITE64LE(buf, w); return out(buf, a, w ? (bsr(w) >> 3) + 1 : 1); } diff --git a/libc/fmt/strerdoc.greg.c b/libc/fmt/strerdoc.greg.c new file mode 100644 index 000000000..b8e89b384 --- /dev/null +++ b/libc/fmt/strerdoc.greg.c @@ -0,0 +1,32 @@ +/*-*- 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/fmt/fmt.h" +#include "libc/fmt/magnumstrs.internal.h" + +/** + * Converts errno value to descriptive sentence. + * @return non-null rodata string or null if not found + */ +char *strerdoc(int x) { + if (x) { + return GetMagnumStr(kErrnoDocs, x); + } else { + return 0; + } +} diff --git a/libc/fmt/strerrno.greg.c b/libc/fmt/strerrno.greg.c new file mode 100644 index 000000000..145727831 --- /dev/null +++ b/libc/fmt/strerrno.greg.c @@ -0,0 +1,32 @@ +/*-*- 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/fmt/magnumstrs.internal.h" +#include "libc/str/str.h" + +/** + * Converts errno value to symbolic name. + * @return non-null rodata string or null if not found + */ +char *strerrno(int x) { + if (x) { + return GetMagnumStr(kErrnoNames, x); + } else { + return 0; + } +} diff --git a/libc/fmt/strerror.c b/libc/fmt/strerror.c index d5d610a3a..8cfefe61b 100644 --- a/libc/fmt/strerror.c +++ b/libc/fmt/strerror.c @@ -16,14 +16,19 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.internal.h" #include "libc/fmt/fmt.h" /** * Converts errno value to string non-reentrantly. * @see strerror_r() */ -noasan char *strerror(int err) { - _Alignas(1) static char buf[512]; - strerror_r(err, buf, sizeof(buf)); - return buf; +char *strerror(int err) { + if (IsTiny()) { + return firstnonnull(strerrno(err), "EUNKNOWN"); + } else { + _Alignas(1) static char buf[512]; + strerror_r(err, buf, sizeof(buf)); + return buf; + } } diff --git a/libc/fmt/strerror_r.c b/libc/fmt/strerror_r.c deleted file mode 100644 index dc024cb6a..000000000 --- a/libc/fmt/strerror_r.c +++ /dev/null @@ -1,124 +0,0 @@ -/*-*- 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 "libc/bits/safemacros.internal.h" -#include "libc/dce.h" -#include "libc/errno.h" -#include "libc/fmt/fmt.h" -#include "libc/fmt/itoa.h" -#include "libc/log/libfatal.internal.h" -#include "libc/macros.internal.h" -#include "libc/nexgen32e/bsr.h" -#include "libc/nt/enum/formatmessageflags.h" -#include "libc/nt/enum/lang.h" -#include "libc/nt/memory.h" -#include "libc/nt/process.h" -#include "libc/nt/runtime.h" -#include "libc/str/str.h" -#include "libc/str/tpenc.h" - -#if !IsTiny() -STATIC_YOINK("__dos2errno"); -#endif - -struct Error { - int x; - int s; -}; - -extern const struct Error kErrorNames[]; -extern const struct Error kErrorNamesLong[]; - -noasan static inline const char *GetErrorName(long x) { - int i; - if (x) { - for (i = 0; kErrorNames[i].x; ++i) { - if (x == *(const long *)((uintptr_t)kErrorNames + kErrorNames[i].x)) { - return (const char *)((uintptr_t)kErrorNames + kErrorNames[i].s); - } - } - } - return "EUNKNOWN"; -} - -noasan static inline const char *GetErrorNameLong(long x) { - int i; - if (x) { - for (i = 0; kErrorNamesLong[i].x; ++i) { - if (x == - *(const long *)((uintptr_t)kErrorNamesLong + kErrorNamesLong[i].x)) { - return (const char *)((uintptr_t)kErrorNamesLong + - kErrorNamesLong[i].s); - } - } - } - return "EUNKNOWN[No error information]"; -} - -/** - * Converts errno value to string. - * @return 0 on success, or error code - */ -noasan int strerror_r(int err, char *buf, size_t size) { - uint64_t w; - int c, i, n; - char *p, *e; - const char *s; - char16_t *ws = 0; - p = buf; - e = p + size; - err &= 0xFFFF; - s = IsTiny() ? GetErrorName(err) : GetErrorNameLong(err); - while ((c = *s++)) { - if (p + 1 + 1 <= e) *p++ = c; - } - if (!IsTiny()) { - if (p + 1 + 5 + 1 + 1 <= e) { - *p++ = '['; - p = __intcpy(p, err); - *p++ = ']'; - } - if (IsWindows()) { - err = GetLastError() & 0xffff; - if ((n = FormatMessage( - kNtFormatMessageAllocateBuffer | kNtFormatMessageFromSystem | - kNtFormatMessageIgnoreInserts, - 0, err, MAKELANGID(kNtLangNeutral, kNtSublangDefault), - (char16_t *)&ws, 0, 0))) { - while (n && ws[n - 1] <= L' ' || ws[n - 1] == L'.') --n; - if (p + 1 + 1 <= e) *p++ = '['; - for (i = 0; i < n; ++i) { - w = tpenc(ws[i] & 0xffff); - if (p + (bsrll(w) >> 3) + 1 + 1 <= e) { - do *p++ = w; - while ((w >>= 8)); - } - } - if (p + 1 + 1 <= e) *p++ = ']'; - LocalFree(ws); - } - if (p + 1 + 5 + 1 + 1 <= e) { - *p++ = '['; - p = __intcpy(p, err); - *p++ = ']'; - } - } - } - if (p + 1 <= e) *p = 0; - return 0; -} diff --git a/libc/fmt/strerror_r.greg.c b/libc/fmt/strerror_r.greg.c new file mode 100644 index 000000000..bec848b21 --- /dev/null +++ b/libc/fmt/strerror_r.greg.c @@ -0,0 +1,30 @@ +/*-*- 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 "libc/fmt/fmt.h" +#include "libc/nt/runtime.h" + +/** + * Converts errno value to string. + * + * @param err is error number or zero if unknown + * @return 0 on success, or error code + */ +int strerror_r(int err, char *buf, size_t size) { + return strerror_wr(err, GetLastError(), buf, size); +} diff --git a/libc/fmt/strerror_wr.greg.c b/libc/fmt/strerror_wr.greg.c new file mode 100644 index 000000000..8fad73863 --- /dev/null +++ b/libc/fmt/strerror_wr.greg.c @@ -0,0 +1,61 @@ +/*-*- 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 2022 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/bits/safemacros.internal.h" +#include "libc/dce.h" +#include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/formatmessageflags.h" +#include "libc/nt/enum/lang.h" +#include "libc/nt/process.h" + +/** + * Converts errno value to string with explicit windows errno too. + * + * @param err is error number or zero if unknown + * @return 0 on success, or error code + */ +int strerror_wr(int err, uint32_t winerr, char *buf, size_t size) { + /* kprintf() weakly depends on this function */ + int c, n; + char16_t winmsg[256]; + const char *sym, *msg; + sym = firstnonnull(strerrno(err), "EUNKNOWN"); + msg = firstnonnull(strerdoc(err), "No error information"); + if (IsTiny()) { + if (!sym) sym = "EUNKNOWN"; + for (; (c = *sym++); --size) + if (size > 1) *buf++ = c; + if (size) *buf = 0; + } else if (!IsWindows() || err == winerr || !winerr) { + ksnprintf(buf, size, "%s/%d/%s", sym, err, msg); + } else { + if ((n = FormatMessage( + kNtFormatMessageFromSystem | kNtFormatMessageIgnoreInserts, 0, + winerr, MAKELANGID(kNtLangNeutral, kNtSublangDefault), winmsg, + ARRAYLEN(winmsg), 0))) { + while ((n && winmsg[n - 1] <= ' ') || winmsg[n - 1] == '.') --n; + ksnprintf(buf, size, "%s/%d/%s/%d/%.*hs", sym, err, msg, winerr, n, + winmsg); + } else { + ksnprintf(buf, size, "%s/%d/%s/%d", sym, err, msg, winerr); + } + } + return 0; +} diff --git a/libc/fmt/strtoi128.c b/libc/fmt/strtoi128.c new file mode 100644 index 000000000..ff9d6a317 --- /dev/null +++ b/libc/fmt/strtoi128.c @@ -0,0 +1,60 @@ +/*-*- 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 "libc/errno.h" +#include "libc/fmt/conv.h" +#include "libc/fmt/strtol.internal.h" +#include "libc/limits.h" +#include "libc/str/str.h" + +/** + * Decodes 128-bit signed integer from ASCII string. + * + * @param s is a non-null nul-terminated string + * @param endptr if non-null will always receive a pointer to the char + * following the last one this function processed, which is usually + * the NUL byte, or in the case of invalid strings, would point to + * the first invalid character + * @param base can be anywhere between [2,36] or 0 to auto-detect based + * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or + * decimal (base 10) by default + * @return decoded saturated integer + * @see strtou128() + */ +int128_t strtoi128(const char *s, char **endptr, int base) { + char t = 0; + int d, c = *s; + int128_t x = 0; + CONSUME_SPACES(s, c); + GET_SIGN(s, c, d); + GET_RADIX(s, c, base); + if ((c = kBase36[c & 255]) && --c < base) { + if (!((t |= 1) & 2)) { + do { + if (__builtin_mul_overflow(x, base, &x) || + __builtin_add_overflow(x, c * d, &x)) { + x = d > 0 ? INT128_MAX : INT128_MIN; + errno = ERANGE; + t |= 2; + } + } while ((c = kBase36[*++s & 255]) && --c < base); + } + } + if (t && endptr) *endptr = s; + return x; +} diff --git a/libc/fmt/strtoimax.c b/libc/fmt/strtoimax.c index fdcb05391..7eacb3322 100644 --- a/libc/fmt/strtoimax.c +++ b/libc/fmt/strtoimax.c @@ -23,7 +23,7 @@ #include "libc/str/str.h" /** - * Decodes 128-bit signed integer from ASCII string. + * Decodes intmax_t from ASCII string. * * @param s is a non-null nul-terminated string * @param endptr if non-null will always receive a pointer to the char diff --git a/libc/fmt/strtoll_l.c b/libc/fmt/strtoll_l.c new file mode 100644 index 000000000..0bbb5ea32 --- /dev/null +++ b/libc/fmt/strtoll_l.c @@ -0,0 +1,24 @@ +/*-*- 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 2022 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/fmt/conv.h" +#include "libc/unicode/locale.h" + +long long strtoll_l(const char *nptr, char **endptr, int base, locale_t l) { + return strtoll(nptr, endptr, base); +} diff --git a/libc/fmt/strtou128.c b/libc/fmt/strtou128.c new file mode 100644 index 000000000..b8005fd18 --- /dev/null +++ b/libc/fmt/strtou128.c @@ -0,0 +1,53 @@ +/*-*- 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 "libc/fmt/conv.h" +#include "libc/fmt/strtol.internal.h" +#include "libc/str/str.h" + +/** + * Decodes 128-bit unsigned integer from ASCII string. + * + * @param s is a non-null nul-terminated string + * @param endptr if non-null will always receive a pointer to the char + * following the last one this function processed, which is usually + * the NUL byte, or in the case of invalid strings, would point to + * the first invalid character + * @param base can be anywhere between [2,36] or 0 to auto-detect based + * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or + * decimal (base 10) by default + * @return decoded integer mod 2¹²⁸ negated if leading `-` + * @see strtoi128() + */ +uint128_t strtou128(const char *s, char **endptr, int base) { + char t = 0; + int d, c = *s; + uint128_t x = 0; + CONSUME_SPACES(s, c); + GET_SIGN(s, c, d); + GET_RADIX(s, c, base); + if ((c = kBase36[c & 255]) && --c < base) { + t |= 1; + do { + x *= base; + x += c; + } while ((c = kBase36[*++s & 255]) && --c < base); + } + if (t && endptr) *endptr = s; + return d > 0 ? x : -x; +} diff --git a/libc/fmt/strtoull_l.c b/libc/fmt/strtoull_l.c new file mode 100644 index 000000000..52cf9313b --- /dev/null +++ b/libc/fmt/strtoull_l.c @@ -0,0 +1,25 @@ +/*-*- 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 2022 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/fmt/conv.h" +#include "libc/unicode/locale.h" + +unsigned long long strtoull_l(const char *nptr, char **endptr, int base, + locale_t l) { + return strtoull(nptr, endptr, base); +} diff --git a/libc/fmt/strtoumax.c b/libc/fmt/strtoumax.c index dd4f5f654..eb4e5134e 100644 --- a/libc/fmt/strtoumax.c +++ b/libc/fmt/strtoumax.c @@ -21,7 +21,7 @@ #include "libc/str/str.h" /** - * Decodes 128-bit unsigned integer from ASCII string. + * Decodes uintmax_t from ASCII string. * * @param s is a non-null nul-terminated string * @param endptr if non-null will always receive a pointer to the char diff --git a/libc/fmt/swprintf.c b/libc/fmt/swprintf.c new file mode 100644 index 000000000..da14232d2 --- /dev/null +++ b/libc/fmt/swprintf.c @@ -0,0 +1,26 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/fmt/fmt.h" +#include "libc/runtime/runtime.h" + +int swprintf(wchar_t* ws, size_t n, const wchar_t* format, ...) { + assert(!"not implemented"); + abort(); +} diff --git a/libc/fmt/vcscanf.c b/libc/fmt/vcscanf.c index bc4b19572..4dda5b761 100644 --- a/libc/fmt/vcscanf.c +++ b/libc/fmt/vcscanf.c @@ -70,7 +70,7 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg, } break; case '%': { - uintmax_t number; + uint128_t number; void *buf; size_t bufsize; unsigned width = 0; @@ -117,8 +117,12 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg, case '\'': thousands = true; break; - case 'j': /* 128-bit */ - bits = sizeof(intmax_t) * 8; + case 'j': /* j=64-bit jj=128-bit */ + if (bits < 64) { + bits = 64; + } else { + bits = 128; + } break; case 'l': /* long */ case 'L': /* loooong */ @@ -185,7 +189,7 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg, } } while ((c = callback(arg)) != -1); if (!discard) { - uintmax_t bane = (uintmax_t)1 << (bits - 1); + uint128_t bane = (uint128_t)1 << (bits - 1); if (!(number & ~((bane - 1) | (issigned ? 0 : bane))) || (issigned && number == bane /* two's complement bane */)) { ++items; @@ -198,8 +202,8 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg, } void *out = va_arg(va, void *); switch (bits) { - case sizeof(uintmax_t) * CHAR_BIT: - *(uintmax_t *)out = number; + case sizeof(uint128_t) * CHAR_BIT: + *(uint128_t *)out = number; break; case 48: case 64: diff --git a/libc/fmt/wcstoi128.c b/libc/fmt/wcstoi128.c new file mode 100644 index 000000000..4bb79d338 --- /dev/null +++ b/libc/fmt/wcstoi128.c @@ -0,0 +1,60 @@ +/*-*- 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 "libc/errno.h" +#include "libc/fmt/conv.h" +#include "libc/fmt/strtol.internal.h" +#include "libc/limits.h" +#include "libc/str/str.h" + +/** + * Decodes 128-bit signed integer from wide string. + * + * @param s is a non-null nul-terminated string + * @param endptr if non-null will always receive a pointer to the char + * following the last one this function processed, which is usually + * the NUL byte, or in the case of invalid strings, would point to + * the first invalid character + * @param base can be anywhere between [2,36] or 0 to auto-detect based + * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or + * decimal (base 10) by default + * @return decoded saturated integer + * @see strtou128() + */ +int128_t wcstoi128(const wchar_t *s, wchar_t **endptr, int base) { + char t = 0; + int128_t x = 0; + int d, c = *s; + CONSUME_SPACES(s, c); + GET_SIGN(s, c, d); + GET_RADIX(s, c, base); + if ((c = kBase36[c & 255]) && --c < base) { + if (!((t |= 1) & 2)) { + do { + if (__builtin_mul_overflow(x, base, &x) || + __builtin_add_overflow(x, c * d, &x)) { + x = d > 0 ? INT128_MAX : INT128_MIN; + errno = ERANGE; + t |= 2; + } + } while ((c = kBase36[*++s & 255]) && --c < base); + } + } + if (t && endptr) *endptr = s; + return x; +} diff --git a/libc/fmt/wcstoimax.c b/libc/fmt/wcstoimax.c index dfae5cf9d..b6abb147d 100644 --- a/libc/fmt/wcstoimax.c +++ b/libc/fmt/wcstoimax.c @@ -23,7 +23,7 @@ #include "libc/str/str.h" /** - * Decodes 128-bit signed integer from wide string. + * Decodes intmax_t from wide string. * * @param s is a non-null nul-terminated string * @param endptr if non-null will always receive a pointer to the char diff --git a/libc/fmt/wcstol.c b/libc/fmt/wcstol.c index cdc00649c..e27dfd204 100644 --- a/libc/fmt/wcstol.c +++ b/libc/fmt/wcstol.c @@ -23,7 +23,7 @@ #include "libc/str/str.h" /** - * Decodes signed integer from wide string. + * Decodes signed long integer from wide string. * * @param s is a non-null nul-terminated string * @param endptr if non-null will always receive a pointer to the char diff --git a/libc/fmt/wcstoll.c b/libc/fmt/wcstoll.c new file mode 100644 index 000000000..4b63f8d55 --- /dev/null +++ b/libc/fmt/wcstoll.c @@ -0,0 +1,59 @@ +/*-*- 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 "libc/errno.h" +#include "libc/fmt/conv.h" +#include "libc/fmt/strtol.internal.h" +#include "libc/limits.h" +#include "libc/str/str.h" + +/** + * Decodes signed long long integer from wide string. + * + * @param s is a non-null nul-terminated string + * @param endptr if non-null will always receive a pointer to the char + * following the last one this function processed, which is usually + * the NUL byte, or in the case of invalid strings, would point to + * the first invalid character + * @param base can be anywhere between [2,36] or 0 to auto-detect based + * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or + * decimal (base 10) by default + * @return the decoded signed saturated number + */ +long long wcstoll(const wchar_t *s, wchar_t **endptr, int base) { + char t = 0; + int d, c = *s; + long long x = 0; + CONSUME_SPACES(s, c); + GET_SIGN(s, c, d); + GET_RADIX(s, c, base); + if ((c = kBase36[c & 255]) && --c < base) { + if (!((t |= 1) & 2)) { + do { + if (__builtin_mul_overflow(x, base, &x) || + __builtin_add_overflow(x, c * d, &x)) { + x = d > 0 ? LONG_LONG_MAX : LONG_LONG_MIN; + errno = ERANGE; + t |= 2; + } + } while ((c = kBase36[*++s & 255]) && --c < base); + } + } + if (t && endptr) *endptr = s; + return x; +} diff --git a/libc/fmt/wcstoll_l.c b/libc/fmt/wcstoll_l.c new file mode 100644 index 000000000..441ed661c --- /dev/null +++ b/libc/fmt/wcstoll_l.c @@ -0,0 +1,25 @@ +/*-*- 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 2022 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/fmt/conv.h" +#include "libc/unicode/locale.h" + +long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base, + locale_t l) { + return wcstoll(nptr, endptr, base); +} diff --git a/libc/fmt/wcstou128.c b/libc/fmt/wcstou128.c new file mode 100644 index 000000000..38c74f8b2 --- /dev/null +++ b/libc/fmt/wcstou128.c @@ -0,0 +1,53 @@ +/*-*- 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 "libc/fmt/conv.h" +#include "libc/fmt/strtol.internal.h" +#include "libc/str/str.h" + +/** + * Decodes 128-bit unsigned integer from wide string. + * + * @param s is a non-null nul-terminated string + * @param endptr if non-null will always receive a pointer to the char + * following the last one this function processed, which is usually + * the NUL byte, or in the case of invalid strings, would point to + * the first invalid character + * @param base can be anywhere between [2,36] or 0 to auto-detect based + * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or + * decimal (base 10) by default + * @return decoded integer mod 2¹²⁸ negated if leading `-` + * @see strtoi128() + */ +uint128_t wcstou128(const wchar_t *s, wchar_t **endptr, int base) { + char t = 0; + int d, c = *s; + uint128_t x = 0; + CONSUME_SPACES(s, c); + GET_SIGN(s, c, d); + GET_RADIX(s, c, base); + if ((c = kBase36[c & 255]) && --c < base) { + t |= 1; + do { + x *= base; + x += c; + } while ((c = kBase36[*++s & 255]) && --c < base); + } + if (t && endptr) *endptr = s; + return d > 0 ? x : -x; +} diff --git a/libc/fmt/wcstoull.c b/libc/fmt/wcstoull.c new file mode 100644 index 000000000..c17fe8605 --- /dev/null +++ b/libc/fmt/wcstoull.c @@ -0,0 +1,53 @@ +/*-*- 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 "libc/errno.h" +#include "libc/fmt/conv.h" +#include "libc/fmt/strtol.internal.h" +#include "libc/str/str.h" + +/** + * Decodes unsigned long long integer from wide string. + * + * @param s is a non-null nul-terminated string + * @param endptr if non-null will always receive a pointer to the char + * following the last one this function processed, which is usually + * the NUL byte, or in the case of invalid strings, would point to + * the first invalid character + * @param base can be anywhere between [2,36] or 0 to auto-detect based + * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or + * decimal (base 10) by default + * @return decoded integer mod 2⁶⁴ negated if leading `-` + */ +unsigned long long wcstoull(const wchar_t *s, wchar_t **endptr, int base) { + char t = 0; + int d, c = *s; + unsigned long long x = 0; + CONSUME_SPACES(s, c); + GET_SIGN(s, c, d); + GET_RADIX(s, c, base); + if ((c = kBase36[c & 255]) && --c < base) { + t |= 1; + do { + x *= base; + x += c; + } while ((c = kBase36[*++s & 255]) && --c < base); + } + if (t && endptr) *endptr = s; + return d > 0 ? x : -x; +} diff --git a/libc/fmt/wcstoull_l.c b/libc/fmt/wcstoull_l.c new file mode 100644 index 000000000..926035623 --- /dev/null +++ b/libc/fmt/wcstoull_l.c @@ -0,0 +1,25 @@ +/*-*- 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 2022 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/fmt/conv.h" +#include "libc/unicode/locale.h" + +unsigned long long wcstoull_l(const wchar_t *nptr, wchar_t **endptr, int base, + locale_t l) { + return wcstoull(nptr, endptr, base); +} diff --git a/libc/fmt/wcstoumax.c b/libc/fmt/wcstoumax.c index fbbf98464..80f720756 100644 --- a/libc/fmt/wcstoumax.c +++ b/libc/fmt/wcstoumax.c @@ -21,7 +21,7 @@ #include "libc/str/str.h" /** - * Decodes 128-bit unsigned integer from wide string. + * Decodes uintmax_t from wide string. * * @param s is a non-null nul-terminated string * @param endptr if non-null will always receive a pointer to the char diff --git a/libc/integral/c.inc b/libc/integral/c.inc index 1dfbc05bb..c2186bdf3 100644 --- a/libc/integral/c.inc +++ b/libc/integral/c.inc @@ -102,6 +102,8 @@ typedef __CHAR16_TYPE__ char16_t; typedef __CHAR32_TYPE__ char32_t; #endif +#define _LIBCPP_STDINT_H + typedef int errno_t; typedef __SIZE_TYPE__ size_t; typedef __PTRDIFF_TYPE__ ssize_t; @@ -118,30 +120,18 @@ typedef __INT32_TYPE__ int32_t; typedef __UINT32_TYPE__ uint32_t; typedef __INT64_TYPE__ int64_t; typedef __UINT64_TYPE__ uint64_t; +typedef __INTMAX_TYPE__ intmax_t; +typedef __UINTMAX_TYPE__ uintmax_t; + +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 406 || defined(__llvm__) +typedef signed __int128 int128_t; +typedef unsigned __int128 uint128_t; +#endif typedef struct { intptr_t ax, dx; } axdx_t; -#ifdef __SIZEOF_INTMAX__ -#undef __SIZEOF_INTMAX__ -#endif -#if !defined(__STRICT_ANSI__) && __SIZEOF_POINTER__ == 8 && \ - ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 406 || defined(__llvm__)) -#define __SIZEOF_INTMAX__ 16 -#else -#define __SIZEOF_INTMAX__ __SIZEOF_POINTER__ -#endif -#if __SIZEOF_INTMAX__ == 16 -typedef signed __int128 int128_t; -typedef unsigned __int128 uint128_t; -typedef int128_t intmax_t; -typedef uint128_t uintmax_t; -#elif __SIZEOF_INTMAX__ == 8 -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; -#endif - #ifndef __chibicc__ #define va_list __builtin_va_list #define va_arg(ap, type) __builtin_va_arg(ap, type) @@ -152,11 +142,11 @@ typedef uint64_t uintmax_t; #include "libc/integral/lp64arg.inc" #endif -#define libcesque nothrow nocallback +#define libcesque dontthrow nocallback #define memcpyesque libcesque #define strlenesque libcesque nosideeffect paramsnonnull() #define vallocesque \ - libcesque nodiscard returnsaligned((PAGESIZE)) returnspointerwithnoaliases + libcesque dontdiscard returnsaligned((PAGESIZE)) returnspointerwithnoaliases #define reallocesque libcesque returnsaligned((16)) #define mallocesque reallocesque returnspointerwithnoaliases #define interruptfn nocallersavedregisters forcealignargpointer @@ -299,13 +289,13 @@ typedef uint64_t uintmax_t; #endif #endif -#ifndef nodiscard +#ifndef dontdiscard #if !defined(__STRICT_ANSI__) && \ ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 304 || \ __has_attribute(__warn_unused_result__)) -#define nodiscard __attribute__((__warn_unused_result__)) +#define dontdiscard __attribute__((__warn_unused_result__)) #else -#define nodiscard +#define dontdiscard #endif #endif @@ -408,15 +398,15 @@ typedef uint64_t uintmax_t; #endif #endif -#ifndef nothrow +#ifndef dontthrow #if defined(__cplusplus) && !defined(__STRICT_ANSI__) && \ - (__has_attribute(nothrow) || \ + (__has_attribute(dontthrow) || \ (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 303) -#define nothrow __attribute__((__nothrow__)) +#define dontthrow __attribute__((__nothrow__)) #elif defined(_MSC_VER) -#define nothrow __declspec(nothrow) +#define dontthrow __declspec(nothrow) #else -#define nothrow +#define dontthrow #endif #endif @@ -677,6 +667,7 @@ typedef uint64_t uintmax_t; #pragma GCC diagnostic ignored "-Wdangling-else" /* come on tidy */ #pragma GCC diagnostic ignored "-Wformat-security" /* come on tidy */ #pragma GCC diagnostic ignored "-Wunused-value" /* breaks macros */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" /* libcxx */ #ifndef __cplusplus #pragma GCC diagnostic ignored "-Wimplicit-int" #endif /* C++ */ diff --git a/libc/integral/lp64.inc b/libc/integral/lp64.inc index 903b72c36..808a4caa8 100644 --- a/libc/integral/lp64.inc +++ b/libc/integral/lp64.inc @@ -12,6 +12,8 @@ #define __INTPTR_MAX__ 0x7fffffffffffffffl #define __UINTPTR_MAX__ 0xfffffffffffffffful #define __WINT_MAX__ 0xffffffffu +#define __UINTMAX_MAX__ 0xffffffffffffffffUL +#define __INTMAX_MAX__ 0x7fffffffffffffffL #define __SIZEOF_SHORT__ 2 #define __SIZEOF_INT__ 4 @@ -30,21 +32,23 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) -#define __INT8_TYPE__ signed char -#define __UINT8_TYPE__ unsigned char -#define __INT16_TYPE__ short int -#define __UINT16_TYPE__ short unsigned int -#define __INT32_TYPE__ int -#define __UINT32_TYPE__ unsigned int -#define __INT64_TYPE__ long int -#define __UINT64_TYPE__ long unsigned int -#define __INTPTR_TYPE__ long int -#define __UINTPTR_TYPE__ long unsigned int -#define __PTRDIFF_TYPE__ long int -#define __SIZE_TYPE__ long unsigned int -#define __WCHAR_TYPE__ int #define __CHAR16_TYPE__ short unsigned int #define __CHAR32_TYPE__ unsigned int +#define __INT16_TYPE__ short int +#define __INT32_TYPE__ int +#define __INT64_TYPE__ long int +#define __INT8_TYPE__ signed char +#define __INTMAX_TYPE__ long int +#define __INTPTR_TYPE__ long int +#define __PTRDIFF_TYPE__ long int +#define __SIZE_TYPE__ long unsigned int +#define __UINT16_TYPE__ short unsigned int +#define __UINT32_TYPE__ unsigned int +#define __UINT64_TYPE__ long unsigned int +#define __UINT8_TYPE__ unsigned char +#define __UINTMAX_TYPE__ long unsigned int +#define __UINTPTR_TYPE__ long unsigned int +#define __WCHAR_TYPE__ int #define __WINT_TYPE__ unsigned int #define __INT_LEAST8_TYPE__ __INT8_TYPE__ diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 489d5a7f4..4cf6d3d06 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -70,13 +70,13 @@ #define BUFSIZ 0x1000 /* best stdio default */ #define CACHELINE 0x40 /* nexgen32e */ #define CHAR_BIT 8 /* b/c von neumann */ -#define ARG_MAX 0x8000 /* b/c windows */ -#define PATH_MAX 248 /* b/c win32 apis limit ~248..260 */ +#define ARG_MAX 0xfffe /* for argv and envp; see CreateProcess (32767*2) */ +#define PATH_MAX 1024 /* b/c _XOPEN_PATH_MAX */ #define NAME_MAX 63 /* b/c dns */ -#define CHILD_MAX 25 /* only if malloc isn't linked */ +#define CHILD_MAX 16 /* only if malloc isn't linked */ #define OPEN_MAX 16 /* only if malloc isn't linked */ #define ATEXIT_MAX 32 /* only if malloc isn't linked */ -#define NSIG 128 /* it's complicated */ +#define NSIG 128 /* b/c freebsd */ #if defined(__LP64__) && !defined(__INT64_TYPE__) #include "libc/integral/lp64.inc" diff --git a/libc/intrin/addvdi3.S b/libc/intrin/addvdi3.S index cdebf6d30..0b7ed1414 100644 --- a/libc/intrin/addvdi3.S +++ b/libc/intrin/addvdi3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/addvsi3.S b/libc/intrin/addvsi3.S index 0d6294ba6..4828103f3 100644 --- a/libc/intrin/addvsi3.S +++ b/libc/intrin/addvsi3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/addvti3.S b/libc/intrin/addvti3.S index 675dcebac..76066563e 100644 --- a/libc/intrin/addvti3.S +++ b/libc/intrin/addvti3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/asan.c b/libc/intrin/asan.c index c5befbf12..582a59dee 100644 --- a/libc/intrin/asan.c +++ b/libc/intrin/asan.c @@ -18,14 +18,18 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/alg/reverse.internal.h" #include "libc/assert.h" -#include "libc/bits/bits.h" #include "libc/bits/likely.h" #include "libc/bits/weaken.h" #include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" -#include "libc/calls/sysdebug.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/asancodes.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/lockcmpxchg.h" +#include "libc/intrin/nomultics.internal.h" #include "libc/log/backtrace.internal.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" @@ -37,8 +41,10 @@ #include "libc/nt/enum/version.h" #include "libc/nt/runtime.h" #include "libc/runtime/directmap.internal.h" +#include "libc/runtime/internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" +#include "libc/runtime/stack.h" #include "libc/runtime/symbols.internal.h" #include "libc/str/str.h" #include "libc/str/tpenc.h" @@ -47,10 +53,14 @@ #include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" +#include "third_party/dlmalloc/dlmalloc.h" STATIC_YOINK("_init_asan"); +#define ASAN_MORGUE_ITEMS 512 +#define ASAN_MORGUE_THRESHOLD 65536 // morgue memory O(ITEMS*THRESHOLD) +#define ASAN_TRACE_ITEMS 16 // backtrace limit on malloc origin + /** * @fileoverview Cosmopolitan Address Sanitizer Runtime. * @@ -89,18 +99,19 @@ STATIC_YOINK("_init_asan"); } \ } while (0) -#define REQUIRE(FUNC) \ - do { \ - if (!weaken(FUNC)) { \ - __asan_die("error: asan needs " #FUNC "\n")(); \ - __asan_unreachable(); \ - } \ +#define REQUIRE(FUNC) \ + do { \ + if (!weaken(FUNC)) { \ + kprintf("error: asan needs %s\n", #FUNC); \ + __asan_die()(); \ + __asan_unreachable(); \ + } \ } while (0) typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1))); struct AsanTrace { - intptr_t p[4]; + uint32_t p[ASAN_TRACE_ITEMS]; // assumes linkage into 32-bit space }; struct AsanExtra { @@ -135,15 +146,21 @@ struct AsanGlobal { struct AsanMorgue { unsigned i; - void *p[32]; + void *p[ASAN_MORGUE_ITEMS]; +}; + +struct ReportOriginHeap { + const unsigned char *a; + int z; }; bool __asan_noreentry; static struct AsanMorgue __asan_morgue; -static wontreturn void __asan_unreachable(void) { - for (;;) __builtin_trap(); -} +#define __asan_unreachable() \ + do { \ + for (;;) __builtin_trap(); \ + } while (0) static int __asan_bsf(uint64_t x) { _Static_assert(sizeof(long long) == sizeof(uint64_t), ""); @@ -227,7 +244,8 @@ static void *__asan_memset(void *p, char c, size_t n) { static void *__asan_mempcpy(void *dst, const void *src, size_t n) { size_t i; - char *d, *s; + char *d; + const char *s; uint64_t a, b; d = dst; s = src; @@ -303,14 +321,14 @@ static char *__asan_hexcpy(char *p, uint64_t x, uint8_t k) { } static void __asan_exit(void) { - __printf("your asan runtime needs\n" - "\tSTATIC_YOINK(\"__die\");\n" - "in order to show you backtraces\n"); + kprintf("your asan runtime needs\n" + "\tSTATIC_YOINK(\"__die\");\n" + "in order to show you backtraces\n"); + __restorewintty(); _Exit(99); } -nodiscard static __asan_die_f *__asan_die(const char *msg) { - __printf("%s", msg); +dontdiscard static __asan_die_f *__asan_die(void) { if (weaken(__die)) { return weaken(__die); } else { @@ -354,11 +372,12 @@ void __asan_unpoison(long p, long n) { } static bool __asan_is_mapped(int x) { + // xxx: we can't lock because no reentrant locks yet int i; struct MemoryIntervals *m; m = weaken(_mmi); i = FindMemoryInterval(m, x); - return i < m->i && m->p[i].x <= x && x <= m->p[i].y; + return i < m->i && x >= m->p[i].x; } static bool __asan_is_image(const unsigned char *p) { @@ -366,7 +385,7 @@ static bool __asan_is_image(const unsigned char *p) { } static bool __asan_exists(const void *x) { - return __asan_is_image(x) || __asan_is_mapped((intptr_t)x >> 16); + return !kisdangerous(x); } static struct AsanFault __asan_fault(const signed char *s, signed char dflt) { @@ -385,13 +404,13 @@ static struct AsanFault __asan_fault(const signed char *s, signed char dflt) { static struct AsanFault __asan_checka(const signed char *s, long ndiv8) { intptr_t a; uint64_t w; - signed char c, *e = s + ndiv8; + const signed char *e = s + ndiv8; for (; ((intptr_t)s & 7) && s < e; ++s) { if (*s) return __asan_fault(s - 1, kAsanHeapOverrun); } for (; s + 8 <= e; s += 8) { if (UNLIKELY(!((a = (intptr_t)s) & 0xffff))) { - if (!__asan_is_mapped(a >> 16)) { + if (kisdangerous((void *)a)) { return (struct AsanFault){kAsanUnmapped, s}; } } @@ -422,7 +441,6 @@ static struct AsanFault __asan_checka(const signed char *s, long ndiv8) { */ struct AsanFault __asan_check(const void *p, long n) { intptr_t a; - uint64_t w; struct AsanFault f; signed char c, k, *s; if (n > 0) { @@ -431,7 +449,7 @@ struct AsanFault __asan_check(const void *p, long n) { s = (signed char *)a; if (OverlapsShadowSpace(p, n)) { return (struct AsanFault){kAsanProtected, s}; - } else if (IsLegalPointer(a) && !__asan_is_mapped(a >> 16)) { + } else if (kisdangerous((void *)a)) { return (struct AsanFault){kAsanUnmapped, s}; } if (UNLIKELY(k)) { @@ -491,19 +509,6 @@ bool __asan_is_valid_strlist(char *const *p) { } } -static const char *__asan_dscribe_heap_poison(signed char c) { - switch (c) { - case kAsanHeapFree: - return "heap double free"; - case kAsanStackFree: - return "free stack after return"; - case kAsanHeapRelocated: - return "free after relocate"; - default: - return "this corruption"; - } -} - wint_t __asan_symbolize_access_poison(signed char kind) { switch (kind) { case kAsanNullPage: @@ -544,6 +549,10 @@ wint_t __asan_symbolize_access_poison(signed char kind) { return L'G'; case kAsanGlobalGone: return L'𝐺'; + case kAsanGlobalUnderrun: + return L'μ'; + case kAsanGlobalOverrun: + return L'Ω'; default: return L'?'; } @@ -589,16 +598,20 @@ const char *__asan_describe_access_poison(signed char kind) { return "global redzone"; case kAsanGlobalGone: return "global gone"; + case kAsanGlobalUnderrun: + return "global underrun"; + case kAsanGlobalOverrun: + return "global overrun"; default: return "poisoned"; } } -nodiscard static __asan_die_f *__asan_report_invalid_pointer(void *addr) { - __printf("\r\n%sasan error%s: this corruption at 0x%p shadow 0x%p\r\n", - !g_isterminalinarticulate ? "\e[J\e[1;91m" : "", - !g_isterminalinarticulate ? "\e[0m" : "", addr, SHADOW(addr)); - return __asan_die(""); +dontdiscard static __asan_die_f *__asan_report_invalid_pointer( + const void *addr) { + kprintf("\n\e[J\e[1;31masan error\e[0m: this corruption at %p shadow %p\n", + addr, SHADOW(addr)); + return __asan_die(); } static char *__asan_format_interval(char *p, intptr_t a, intptr_t b) { @@ -607,8 +620,8 @@ static char *__asan_format_interval(char *p, intptr_t a, intptr_t b) { return p; } -static char *__asan_format_section(char *p, void *p1, void *p2, - const char *name, void *addr) { +static char *__asan_format_section(char *p, const void *p1, const void *p2, + const char *name, const void *addr) { intptr_t a, b; if ((a = (intptr_t)p1) < (b = (intptr_t)p2)) { p = __asan_format_interval(p, a, b), *p++ = ' '; @@ -616,26 +629,116 @@ static char *__asan_format_section(char *p, void *p1, void *p2, if (a <= (intptr_t)addr && (intptr_t)addr <= b) { p = __stpcpy(p, " ←address"); } - *p++ = '\r', *p++ = '\n'; + *p++ = '\n'; } return p; } -nodiscard static __asan_die_f *__asan_report(void *addr, int size, - const char *message, - signed char kind) { +static void __asan_report_memory_origin_image(intptr_t a, int z) { + unsigned l, m, r, n, k; + struct SymbolTable *st; + kprintf("\nthe memory belongs to image symbols\n"); + if (weaken(GetSymbolTable)) { + if ((st = weaken(GetSymbolTable)())) { + l = 0; + r = n = st->count; + k = a - st->addr_base; + while (l < r) { + m = (l + r) >> 1; + if (st->symbols[m].y < k) { + l = m + 1; + } else { + r = m; + } + } + for (; l < n; ++l) { + if ((st->symbols[l].x <= k && k <= st->symbols[l].y) || + (st->symbols[l].x <= k + z && k + z <= st->symbols[l].y) || + (k < st->symbols[l].x && st->symbols[l].y < k + z)) { + kprintf("\t%s [%#x,%#x] size %'d\n", st->name_base + st->names[l], + st->addr_base + st->symbols[l].x, + st->addr_base + st->symbols[l].y, + st->symbols[l].y - st->symbols[l].x + 1); + } else { + break; + } + } + } else { + kprintf("\tunknown please supply .com.dbg symbols or set COMDBG\n"); + } + } else { + kprintf("\tunknown please STATIC_YOINK(\"GetSymbolTable\");\n"); + } +} + +static noasan void OnMemory(void *x, void *y, size_t n, void *a) { + const unsigned char *p = x; + struct ReportOriginHeap *t = a; + if ((p <= t->a && t->a < p + n) || + (p <= t->a + t->z && t->a + t->z < p + n) || + (t->a < p && p + n <= t->a + t->z)) { + kprintf("%p %,lu bytes [dlmalloc]", x, n); + __asan_print_trace(x); + kprintf("\n"); + } +} + +static void __asan_report_memory_origin_heap(const unsigned char *a, int z) { + struct ReportOriginHeap t; + kprintf("\nthe memory was allocated by\n"); + if (weaken(malloc_inspect_all)) { + t.a = a; + t.z = z; + weaken(malloc_inspect_all)(OnMemory, &t); + } else { + kprintf("\tunknown please STATIC_YOINK(\"malloc_inspect_all\");\n"); + } +} + +static void __asan_report_memory_origin(const unsigned char *addr, int size, + signed char kind) { + switch (kind) { + case kAsanStackOverrun: + case kAsanGlobalOverrun: + case kAsanAllocaOverrun: + case kAsanHeapOverrun: + addr -= 1; + size += 1; + break; + case kAsanHeapUnderrun: + case kAsanStackUnderrun: + case kAsanAllocaUnderrun: + case kAsanGlobalUnderrun: + size += 1; + break; + case kAsanGlobalRedzone: + addr -= 1; + size += 2; + break; + default: + break; + } + if (_base <= addr && addr < _end) { + __asan_report_memory_origin_image((intptr_t)addr, size); + } else if (IsAutoFrame((intptr_t)addr >> 16)) { + /* __asan_report_memory_origin_heap(addr, size); */ + } +} + +dontdiscard static __asan_die_f *__asan_report(const void *addr, int size, + const char *message, + signed char kind) { + int i; wint_t c; - int i, cc; signed char t; uint64_t x, y, z; char *p, *q, *base; struct MemoryIntervals *m; + ++g_ftrace; p = __fatalbuf; - __printf("\r\n%sasan error%s: %s %d-byte %s at 0x%p shadow 0x%p\r\n", - !g_isterminalinarticulate ? "\e[J\e[1;91m" : "", - !g_isterminalinarticulate ? "\e[0m" : "", - __asan_describe_access_poison(kind), size, message, addr, - SHADOW(addr)); + kprintf("\n\e[J\e[1;31masan error\e[0m: %s %d-byte %s at %p shadow %p\n%s\n", + __asan_describe_access_poison(kind), size, message, addr, + SHADOW(addr), __argv[0]); if (0 < size && size < 80) { base = (char *)addr - ((80 >> 1) - (size >> 1)); for (i = 0; i < 80; ++i) { @@ -649,30 +752,30 @@ nodiscard static __asan_die_f *__asan_report(void *addr, int size, *p++ = ' '; } } - *p++ = '\r', *p++ = '\n'; + *p++ = '\n'; for (c = i = 0; i < 80; ++i) { if (!(t = __asan_check(base + i, 1).kind)) { - if (!g_isterminalinarticulate && c != 32) { + if (c != 32) { p = __stpcpy(p, "\e[32m"); c = 32; } *p++ = '.'; } else { - if (!g_isterminalinarticulate && c != 31) { + if (c != 31) { p = __stpcpy(p, "\e[31m"); c = 31; } p = __asan_utf8cpy(p, __asan_symbolize_access_poison(t)); } } - if (!g_isterminalinarticulate) p = __stpcpy(p, "\e[39m"); - *p++ = '\r', *p++ = '\n'; + p = __stpcpy(p, "\e[39m"); + *p++ = '\n'; for (i = 0; (intptr_t)(base + i) & 7; ++i) *p++ = ' '; for (; i + 8 <= 80; i += 8) { q = p + 8; *p++ = '|'; z = ((intptr_t)(base + i) >> 3) + 0x7fff8000; - if (__asan_is_mapped(z >> 16)) { + if (!kisdangerous((void *)z)) { p = __intcpy(p, *(signed char *)z); } else { *p++ = '!'; @@ -682,17 +785,18 @@ nodiscard static __asan_die_f *__asan_report(void *addr, int size, } } for (; i < 80; ++i) *p++ = ' '; - *p++ = '\r', *p++ = '\n'; + *p++ = '\n'; for (i = 0; i < 80; ++i) { p = __asan_utf8cpy(p, __asan_exists(base + i) ? kCp437[((unsigned char *)base)[i]] : L'⋅'); } - *p++ = '\r', *p++ = '\n'; + *p++ = '\n'; } p = __asan_format_section(p, _base, _etext, ".text", addr); p = __asan_format_section(p, _etext, _edata, ".data", addr); p = __asan_format_section(p, _end, _edata, ".bss", addr); + // xxx: we can't lock because no reentrant locks yet for (m = weaken(_mmi), i = 0; i < m->i; ++i) { x = m->p[i].x; y = m->p[i].y; @@ -701,10 +805,14 @@ nodiscard static __asan_die_f *__asan_report(void *addr, int size, if (x <= z && z <= y) p = __stpcpy(p, " ←address"); z = (((intptr_t)addr >> 3) + 0x7fff8000) >> 16; if (x <= z && z <= y) p = __stpcpy(p, " ←shadow"); - *p++ = '\r', *p++ = '\n'; + *p++ = '\n'; } *p = 0; - return __asan_die(__fatalbuf); + kprintf("%s", __fatalbuf); + __asan_report_memory_origin(addr, size, kind); + kprintf("\nthe crash was caused by\n"); + --g_ftrace; + return __asan_die(); } void __asan_verify(const void *p, size_t n) { @@ -720,19 +828,19 @@ void __asan_verify(const void *p, size_t n) { __asan_unreachable(); } -nodiscard __asan_die_f *__asan_report_memory_fault(void *addr, int size, - const char *message) { +dontdiscard __asan_die_f *__asan_report_memory_fault(void *addr, int size, + const char *message) { return __asan_report(addr, size, message, __asan_fault(SHADOW(addr), -128).kind); } -const void *__asan_morgue_add(void *p) { +void *__asan_morgue_add(void *p) { void *r; int i, j; for (;;) { i = __asan_morgue.i; j = (i + 1) & (ARRAYLEN(__asan_morgue.p) - 1); - if (cmpxchg(&__asan_morgue.i, i, j)) { + if (_lockcmpxchg(&__asan_morgue.i, i, j)) { r = __asan_morgue.p[i]; __asan_morgue.p[i] = p; return r; @@ -745,7 +853,7 @@ static void __asan_morgue_flush(void) { void *p; for (i = 0; i < ARRAYLEN(__asan_morgue.p); ++i) { p = __asan_morgue.p[i]; - if (cmpxchg(__asan_morgue.p + i, p, 0)) { + if (_lockcmpxchg(__asan_morgue.p + i, p, 0)) { if (weaken(dlfree)) { weaken(dlfree)(p); } @@ -785,6 +893,17 @@ static bool __asan_read48(uint64_t value, uint64_t *x) { return cookie == ('J' | 'T' << 8); } +static void __asan_rawtrace(struct AsanTrace *bt, const struct StackFrame *bp) { + size_t i; + for (i = 0; bp && i < ARRAYLEN(bt->p); ++i, bp = bp->next) { + if (kisdangerous(bp)) break; + bt->p[i] = bp->addr; + } + for (; i < ARRAYLEN(bt->p); ++i) { + bt->p[i] = 0; + } +} + static void __asan_trace(struct AsanTrace *bt, const struct StackFrame *bp) { int f1, f2; size_t i, gi; @@ -792,10 +911,9 @@ static void __asan_trace(struct AsanTrace *bt, const struct StackFrame *bp) { struct Garbages *garbage; garbage = weaken(__garbage); gi = garbage ? garbage->i : 0; - __asan_memset(bt, 0, sizeof(*bt)); for (f1 = -1, i = 0; bp && i < ARRAYLEN(bt->p); ++i, bp = bp->next) { if (f1 != (f2 = ((intptr_t)bp >> 16))) { - if (!__asan_is_mapped(f2)) break; + if (kisdangerous(bp)) break; f1 = f2; } if (!__asan_checka(SHADOW(bp), sizeof(*bp) >> 3).kind) { @@ -809,8 +927,13 @@ static void __asan_trace(struct AsanTrace *bt, const struct StackFrame *bp) { break; } } + for (; i < ARRAYLEN(bt->p); ++i) { + bt->p[i] = 0; + } } +#define __asan_trace __asan_rawtrace + static void *__asan_allocate(size_t a, size_t n, int underrun, int overrun, struct AsanTrace *bt) { char *p; @@ -830,17 +953,14 @@ static void *__asan_allocate(size_t a, size_t n, int underrun, int overrun, return p; } -static struct AsanExtra *__asan_get_extra(void *p, size_t *c) { +static struct AsanExtra *__asan_get_extra(const void *p, size_t *c) { int f; long x, n; struct AsanExtra *e; - if ((0 < (intptr_t)p && (intptr_t)p < 0x800000000000) && - __asan_is_mapped((f = (intptr_t)p >> 16)) && - (LIKELY(f == (int)(((intptr_t)p - 16) >> 16)) || - __asan_is_mapped(((intptr_t)p - 16) >> 16)) && - (n = weaken(dlmalloc_usable_size)(p)) > sizeof(*e) && + f = (intptr_t)p >> 16; + if (!kisdangerous(p) && (n = weaken(dlmalloc_usable_size)(p)) > sizeof(*e) && !__builtin_add_overflow((intptr_t)p, n, &x) && x <= 0x800000000000 && - (LIKELY(f == (int)((x - 1) >> 16)) || __asan_is_mapped((x - 1) >> 16)) && + (LIKELY(f == (int)((x - 1) >> 16)) || !kisdangerous((void *)(x - 1))) && (LIKELY(f == (int)((x = x - sizeof(*e)) >> 16)) || __asan_is_mapped(x >> 16)) && !(x & (alignof(struct AsanExtra) - 1))) { @@ -882,27 +1002,25 @@ static size_t __asan_malloc_usable_size(const void *p) { } int __asan_print_trace(void *p) { - intptr_t x; size_t c, i, n; - const char *name; struct AsanExtra *e; if (!(e = __asan_get_extra(p, &c))) { - __printf(" bad pointer"); + kprintf(" bad pointer"); return einval(); } if (!__asan_read48(e->size, &n)) { - __printf(" bad cookie"); + kprintf(" bad cookie"); return -1; } - __printf(" %,d used", n); + kprintf("\n%p %,lu bytes [asan]", (char *)p, n); if (!__asan_is_mapped((((intptr_t)p >> 3) + 0x7fff8000) >> 16)) { - __printf(" (shadow not mapped?!)"); + kprintf(" (shadow not mapped?!)"); } for (i = 0; i < ARRAYLEN(e->bt.p) && e->bt.p[i]; ++i) { - __printf("\n%*x %s", 12, e->bt.p[i], - weaken(__get_symbol_by_addr) - ? weaken(__get_symbol_by_addr)(e->bt.p[i]) - : "please STATIC_YOINK(\"__get_symbol_by_addr\")"); + kprintf("\n%*lx %s", 12, e->bt.p[i], + weaken(__get_symbol_by_addr) + ? weaken(__get_symbol_by_addr)(e->bt.p[i]) + : "please STATIC_YOINK(\"__get_symbol_by_addr\")"); } return 0; } @@ -913,7 +1031,7 @@ static void __asan_deallocate(char *p, long kind) { if ((e = __asan_get_extra(p, &c))) { if (__asan_read48(e->size, &n)) { __asan_poison((uintptr_t)p, c, kind); - if (c <= FRAMESIZE) { + if (c <= ASAN_MORGUE_THRESHOLD) { p = __asan_morgue_add(p); } weaken(dlfree)(p); @@ -1052,10 +1170,7 @@ void __asan_stack_free(char *p, size_t size, int classid) { } void __asan_handle_no_return(void) { - uintptr_t stk, ssz; - stk = (uintptr_t)__builtin_frame_address(0); - ssz = GetStackSize(); - __asan_unpoison(stk, ROUNDUP(stk, ssz) - stk); + __asan_unpoison(GetStackAddr(0), GetStackSize()); } void __asan_register_globals(struct AsanGlobal g[], int n) { @@ -1078,21 +1193,37 @@ void __asan_unregister_globals(struct AsanGlobal g[], int n) { } } +void __asan_evil(uint8_t *addr, int size, const char *s1, const char *s2) { + struct AsanTrace tr; + __asan_rawtrace(&tr, __builtin_frame_address(0)); + kprintf( + "WARNING: ASAN error during %s bad %d byte %s at %x bt %x %x %x %x %x\n", + s1, size, s2, addr, tr.p[0], tr.p[1], tr.p[2], tr.p[3], tr.p[4], tr.p[5]); +} + void __asan_report_load(uint8_t *addr, int size) { - if (cmpxchg(&__asan_noreentry, false, true)) { - __asan_report_memory_fault(addr, size, "load")(); - __asan_unreachable(); + if (_lockcmpxchg(&__asan_noreentry, false, true)) { + if (!__vforked) { + __asan_report_memory_fault(addr, size, "load")(); + __asan_unreachable(); + } else { + __asan_evil(addr, size, "vfork()", "load"); + } } else { - __printf("WARNING: ASAN error reporting had an ASAN error\r\n"); + __asan_evil(addr, size, "ASAN Reporting", "load"); } } void __asan_report_store(uint8_t *addr, int size) { - if (cmpxchg(&__asan_noreentry, false, true)) { - __asan_report_memory_fault(addr, size, "store")(); - __asan_unreachable(); + if (_lockcmpxchg(&__asan_noreentry, false, true)) { + if (!__vforked) { + __asan_report_memory_fault(addr, size, "store")(); + __asan_unreachable(); + } else { + __asan_evil(addr, size, "vfork()", "store"); + } } else { - __printf("WARNING: ASAN error reporting had an ASAN error\r\n"); + __asan_evil(addr, size, "ASAN reporting", "store"); } } @@ -1104,15 +1235,14 @@ void __asan_unpoison_stack_memory(uintptr_t addr, size_t size) { __asan_unpoison(addr, size); } -void __asan_alloca_poison(uintptr_t addr, size_t size) { - /* TODO(jart): Make sense of this function. */ - /* __asan_poison(addr - 32, 32, kAsanAllocaUnderrun); */ - __asan_poison(ROUNDUP(addr + size, 32), 32, kAsanAllocaOverrun); - __asan_unpoison(addr, ROUNDUP(addr + size, 32) - (addr + size) + 32 + size); +void __asan_alloca_poison(uintptr_t addr, uintptr_t size) { + __asan_poison(addr - 32, 32, kAsanAllocaUnderrun); + __asan_poison(addr + size, 32, kAsanAllocaOverrun); } void __asan_allocas_unpoison(uintptr_t x, uintptr_t y) { - if (x && x > y) __asan_unpoison(x, y - x); + if (!x || x > y) return; + __asan_memset((void *)((x >> 3) + 0x7fff8000), 0, (y - x) / 8); } void *__asan_addr_is_in_fake_stack(void *fakestack, void *addr, void **beg, @@ -1124,6 +1254,14 @@ void *__asan_get_current_fake_stack(void) { return 0; } +void __sanitizer_annotate_contiguous_container(long beg, long end, long old_mid, + long new_mid) { + // the c++ stl uses this + // TODO(jart): make me faster + __asan_unpoison(beg, new_mid - beg); + __asan_poison(new_mid, end - new_mid, kAsanHeapOverrun); +} + void __asan_install_malloc_hooks(void) { HOOK(hook_free, __asan_free); HOOK(hook_malloc, __asan_malloc); @@ -1137,13 +1275,13 @@ void __asan_install_malloc_hooks(void) { } void __asan_map_shadow(uintptr_t p, size_t n) { + // assume _mmi.lock is held void *addr; + int i, a, b; size_t size; int prot, flag; - int i, x, a, b; struct DirectMap sm; struct MemoryIntervals *m; - SYSDEBUG("__asan_map_shadow(0x%p, 0x%x)", p, n); assert(!OverlapsShadowSpace((void *)p, n)); m = weaken(_mmi); a = (0x7fff8000 + (p >> 3)) >> 16; @@ -1166,8 +1304,10 @@ void __asan_map_shadow(uintptr_t p, size_t n) { if (sm.addr == MAP_FAILED || weaken(TrackMemoryInterval)( m, a, a + i - 1, sm.maphandle, PROT_READ | PROT_WRITE, - MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED) == -1) { - __asan_die("error: could not map asan shadow memory\n")(); + MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED, false, false, 0, + size) == -1) { + kprintf("error: could not map asan shadow memory\n"); + __asan_die()(); __asan_unreachable(); } __repstosb((void *)(intptr_t)((int64_t)((uint64_t)a << 32) >> 16), @@ -1202,28 +1342,30 @@ static textstartup void __asan_shadow_string_list(char **list) { __asan_map_shadow((uintptr_t)list, (i + 1) * sizeof(char *)); } -static textstartup void __asan_shadow_existing_mappings(void) { - size_t i; - struct MemoryIntervals m; - __asan_memcpy(&m, weaken(_mmi), sizeof(m)); - for (i = 0; i < m.i; ++i) { - __asan_map_shadow((uintptr_t)m.p[i].x << 16, - (uintptr_t)(m.p[i].y - m.p[i].x + 1) << 16); +static textstartup void __asan_shadow_mapping(struct MemoryIntervals *m, + size_t i) { + uintptr_t x, y; + if (i < m->i) { + x = m->p[i].x; + y = m->p[i].y; + __asan_shadow_mapping(m, i + 1); + __asan_map_shadow(x << 16, (y - x + 1) << 16); } - __asan_poison(GetStackAddr(0), PAGESIZE, kAsanStackOverflow); } -static textstartup bool IsMemoryManagementRuntimeLinked(void) { - return weaken(_mmi) && weaken(sys_mmap) && weaken(MAP_ANONYMOUS) && - weaken(TrackMemoryInterval); +static textstartup void __asan_shadow_existing_mappings(void) { + __asan_shadow_mapping(&_mmi, 0); + __asan_map_shadow(GetStackAddr(0), GetStackSize()); + __asan_poison(GetStackAddr(0), PAGESIZE, kAsanStackOverflow); } textstartup void __asan_init(int argc, char **argv, char **envp, intptr_t *auxv) { static bool once; - if (!cmpxchg(&once, false, true)) return; + if (!_lockcmpxchg(&once, false, true)) return; if (IsWindows() && NtGetVersion() < kNtVersionWindows10) { - __write_str("error: asan binaries require windows10\n"); + __write_str("error: asan binaries require windows10\r\n"); + __restorewintty(); _Exit(0); /* So `make MODE=dbg test` passes w/ Windows7 */ } REQUIRE(_mmi); @@ -1241,12 +1383,18 @@ textstartup void __asan_init(int argc, char **argv, char **envp, __asan_map_shadow(0, 4096); __asan_poison(0, PAGESIZE, kAsanNullPage); if (!IsWindows()) { - __sysv_mprotect((void *)0x00007fff8000, 0x10000, PROT_READ); + __sysv_mprotect((void *)0x7fff8000, 0x10000, PROT_READ); } __asan_shadow_string_list(argv); __asan_shadow_string_list(envp); __asan_shadow_auxv(auxv); __asan_install_malloc_hooks(); + STRACE(" _ ____ _ _ _ "); + STRACE(" / \\ / ___| / \\ | \\ | |"); + STRACE(" / _ \\ \\___ \\ / _ \\ | \\| |"); + STRACE(" / ___ \\ ___) / ___ \\| |\\ |"); + STRACE("/_/ \\_\\____/_/ \\_\\_| \\_|"); + STRACE("cosmopolitan memory safety module initialized"); } static textstartup void __asan_ctor(void) { diff --git a/libc/intrin/asan.internal.h b/libc/intrin/asan.internal.h index 393c7205a..6bcbb2700 100644 --- a/libc/intrin/asan.internal.h +++ b/libc/intrin/asan.internal.h @@ -1,29 +1,10 @@ #ifndef COSMOPOLITAN_LIBC_INTRIN_ASAN_H_ #define COSMOPOLITAN_LIBC_INTRIN_ASAN_H_ #include "libc/calls/struct/iovec.h" +#include "libc/intrin/asancodes.h" #include "libc/macros.internal.h" - -#define kAsanScale 3 -#define kAsanMagic 0x7fff8000 -#define kAsanNullPage -1 /* ∅ 0xff */ -#define kAsanProtected -2 /* P 0xfe */ -#define kAsanHeapFree -3 /* F 0xfd */ -#define kAsanHeapRelocated -4 /* R 0xfc */ -#define kAsanAllocaOverrun -5 /* 𝑂 0xfb */ -#define kAsanHeapUnderrun -6 /* U 0xfa */ -#define kAsanHeapOverrun -7 /* O 0xf9 */ -#define kAsanStackUnscoped -8 /* s 0xf8 */ -#define kAsanStackOverflow -9 /* ! 0xf7 */ -#define kAsanGlobalOrder -10 /* I 0xf6 */ -#define kAsanStackFree -11 /* r 0xf5 */ -#define kAsanStackPartial -12 /* p 0xf4 */ -#define kAsanStackOverrun -13 /* o 0xf3 */ -#define kAsanStackMiddle -14 /* m 0xf2 */ -#define kAsanStackUnderrun -15 /* u 0xf1 */ -#define kAsanAllocaUnderrun -16 /* 𝑈 0xf0 */ -#define kAsanUnmapped -17 /* M 0xef */ -#define kAsanGlobalRedzone -18 /* G 0xee */ -#define kAsanGlobalGone -19 /* 𝐺 0xed */ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ #define SHADOW(x) ((signed char *)(((intptr_t)(x) >> kAsanScale) + kAsanMagic)) #define UNSHADOW(x) ((void *)(MAX(0, (intptr_t)(x)-kAsanMagic) << kAsanScale)) @@ -32,7 +13,7 @@ typedef void __asan_die_f(void); struct AsanFault { signed char kind; - signed char *shadow; + const signed char *shadow; }; extern bool __asan_noreentry; @@ -58,4 +39,6 @@ void *__asan_memalign(size_t, size_t); size_t __asan_get_heap_size(const void *); void *__asan_realloc_in_place(void *, size_t); +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_INTRIN_ASAN_H_ */ diff --git a/libc/intrin/asancodes.h b/libc/intrin/asancodes.h new file mode 100644 index 000000000..d2320950c --- /dev/null +++ b/libc/intrin/asancodes.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_ +#define COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_ + +#define kAsanScale 3 +#define kAsanMagic 0x7fff8000 +#define kAsanNullPage -1 /* ∅ 0xff */ +#define kAsanProtected -2 /* P 0xfe */ +#define kAsanHeapFree -3 /* F 0xfd */ +#define kAsanHeapRelocated -4 /* R 0xfc */ +#define kAsanAllocaOverrun -5 /* 𝑂 0xfb */ +#define kAsanHeapUnderrun -6 /* U 0xfa */ +#define kAsanHeapOverrun -7 /* O 0xf9 */ +#define kAsanStackUnscoped -8 /* s 0xf8 */ +#define kAsanStackOverflow -9 /* ! 0xf7 */ +#define kAsanGlobalOrder -10 /* I 0xf6 */ +#define kAsanStackFree -11 /* r 0xf5 */ +#define kAsanStackPartial -12 /* p 0xf4 */ +#define kAsanStackOverrun -13 /* o 0xf3 */ +#define kAsanStackMiddle -14 /* m 0xf2 */ +#define kAsanStackUnderrun -15 /* u 0xf1 */ +#define kAsanAllocaUnderrun -16 /* 𝑈 0xf0 */ +#define kAsanUnmapped -17 /* M 0xef */ +#define kAsanGlobalRedzone -18 /* G 0xee */ +#define kAsanGlobalGone -19 /* 𝐺 0xed */ +#define kAsanGlobalUnderrun -20 /* μ 0xec */ +#define kAsanGlobalOverrun -21 /* Ω 0xeb */ + +#endif /* COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_ */ diff --git a/libc/runtime/assertfail.c b/libc/intrin/assertfail.c similarity index 82% rename from libc/runtime/assertfail.c rename to libc/intrin/assertfail.c index ab06ff276..1be6fe260 100644 --- a/libc/runtime/assertfail.c +++ b/libc/intrin/assertfail.c @@ -17,10 +17,13 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" -#include "libc/bits/bits.h" #include "libc/bits/weaken.h" -#include "libc/log/libfatal.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/cmpxchg.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/lockcmpxchg.h" #include "libc/log/log.h" +#include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" /** @@ -28,15 +31,21 @@ */ relegated wontreturn void __assert_fail(const char *expr, const char *file, int line) { + int rc; static bool noreentry; - __printf("%s:%d: assert(%s) failed\r\n", file, line, expr); - if (cmpxchg(&noreentry, false, true)) { + __strace = 0; + g_ftrace = 0; + kprintf("%s:%d: assert(%s) failed\n", file, line, expr); + if (_lockcmpxchg(&noreentry, false, true)) { if (weaken(__die)) { weaken(__die)(); } else { - __printf("can't backtrace b/c `__die` not linked\r\n"); + kprintf("can't backtrace b/c `__die` not linked\n"); } - quick_exit(23); + rc = 23; + } else { + rc = 24; } - _Exit(24); + __restorewintty(); + _Exit(rc); } diff --git a/libc/bits/atomic_load.c b/libc/intrin/atomic_load.c similarity index 83% rename from libc/bits/atomic_load.c rename to libc/intrin/atomic_load.c index 9f2ef57a7..a384ce053 100644 --- a/libc/bits/atomic_load.c +++ b/libc/intrin/atomic_load.c @@ -16,15 +16,21 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" -#include "libc/macros.internal.h" -#include "libc/str/str.h" +#include "libc/intrin/atomic_load.h" /** - * Atomically loads value. + * Reads scalar from memory w/ one operation. * * This macro is intended to prevent things like compiler load tearing * optimizations. + * + * @param MEM is alignas(𝑘) uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @return *(MEM) + * @note defeats compiler load tearing optimizations + * @note alignas(𝑘) is implied if compiler knows type + * @note alignas(𝑘) only avoids multi-core / cross-page edge cases + * @see Intel's Six-Thousand Page Manual V.3A §8.2.3.1 + * @see atomic_store() */ intptr_t(atomic_load)(void *p, size_t n) { intptr_t x = 0; diff --git a/libc/intrin/atomic_load.h b/libc/intrin/atomic_load.h new file mode 100644 index 000000000..d5a292de9 --- /dev/null +++ b/libc/intrin/atomic_load.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_ATOMIC_LOAD_H_ +#define COSMOPOLITAN_LIBC_INTRIN_ATOMIC_LOAD_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +intptr_t atomic_load(void *, size_t); + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define atomic_load(MEM) \ + ({ \ + autotype(MEM) Mem = (MEM); \ + typeof(*Mem) Reg; \ + asm("mov\t%1,%0" : "=r"(Reg) : "m"(*Mem)); \ + Reg; \ + }) +#else +#define atomic_load(MEM) atomic_load(MEM, sizeof(*(MEM))) +#endif /* GNUC && !ANSI && x86 */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_ATOMIC_LOAD_H_ */ diff --git a/libc/bits/atomic_store.c b/libc/intrin/atomic_store.c similarity index 75% rename from libc/bits/atomic_store.c rename to libc/intrin/atomic_store.c index 74ddf68dd..c4c32e6b7 100644 --- a/libc/bits/atomic_store.c +++ b/libc/intrin/atomic_store.c @@ -16,15 +16,23 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" -#include "libc/macros.internal.h" -#include "libc/str/str.h" +#include "libc/intrin/atomic_store.h" /** - * Atomically stores value. + * Saves scalar to memory w/ one operation. * - * This macro is intended to prevent things like compiler store tearing - * optimizations. + * This is guaranteed to happen in either one or zero operations, + * depending on whether or not it's possible for *(MEM) to be read + * afterwards. This macro only forbids compiler from using >1 ops. + * + * @param MEM is alignas(𝑘) uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @param VAL is uint𝑘_t w/ better encoding for immediates (constexpr) + * @return VAL + * @note alignas(𝑘) on nexgen32e only needed for end of page gotcha + * @note alignas(𝑘) is implied if compiler knows type + * @note needed to defeat store tearing optimizations + * @see Intel Six-Thousand Page Manual Manual V.3A §8.2.3.1 + * @see atomic_load() */ intptr_t(atomic_store)(void *p, intptr_t x, size_t n) { switch (n) { diff --git a/libc/intrin/atomic_store.h b/libc/intrin/atomic_store.h new file mode 100644 index 000000000..9a83c407c --- /dev/null +++ b/libc/intrin/atomic_store.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_ATOMIC_STORE_H_ +#define COSMOPOLITAN_LIBC_INTRIN_ATOMIC_STORE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +intptr_t atomic_store(void *, intptr_t, size_t); + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define atomic_store(MEM, VAL) \ + ({ \ + autotype(VAL) Val = (VAL); \ + typeof(&Val) Mem = (MEM); \ + asm("mov%z1\t%1,%0" : "=m"(*Mem) : "r"(Val)); \ + Val; \ + }) +#else +#define atomic_store(MEM, VAL) \ + atomic_store(MEM, VAL, sizeof(*(MEM)) / (sizeof(*(MEM)) == sizeof(*(VAL)))) +#endif /* __GNUC__ && !__STRICT_ANSI__ */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_ATOMIC_STORE_H_ */ diff --git a/libc/intrin/bzero.c b/libc/intrin/bzero.c index cb5e0c48d..40becb89b 100644 --- a/libc/intrin/bzero.c +++ b/libc/intrin/bzero.c @@ -26,7 +26,7 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1))); typedef long long xmm_a __attribute__((__vector_size__(16), __aligned__(16))); -noasan static dontinline antiquity void bzero_sse(char *p, size_t n) { +static dontinline antiquity void bzero_sse(char *p, size_t n) { xmm_t v = {0}; if (IsAsan()) __asan_verify(p, n); if (n <= 32) { @@ -43,7 +43,7 @@ noasan static dontinline antiquity void bzero_sse(char *p, size_t n) { } } -noasan microarchitecture("avx") static void bzero_avx(char *p, size_t n) { +microarchitecture("avx") static void bzero_avx(char *p, size_t n) { xmm_t v = {0}; if (IsAsan()) __asan_verify(p, n); if (n <= 32) { @@ -149,7 +149,7 @@ void(bzero)(void *p, size_t n) { } while (n); } } else if (IsTiny()) { - asm("rep stosb" : "+D"(b), "+c"(n), "=m"(*(char(*)[n])b) : "0"(p), "a"(0)); + asm("rep stosb" : "+D"(b), "+c"(n), "=m"(*(char(*)[n])b) : "a"(0)); return; } else if (X86_HAVE(AVX)) { bzero_avx(b, n); diff --git a/libc/intrin/closehandle.greg.c b/libc/intrin/closehandle.greg.c new file mode 100644 index 000000000..dfd278caf --- /dev/null +++ b/libc/intrin/closehandle.greg.c @@ -0,0 +1,38 @@ +/*-*- 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 2022 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/bits/weaken.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/log/log.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(CloseHandle) *const __imp_CloseHandle; + +/** + * Closes an open object handle. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 CloseHandle(int64_t hObject) { + bool32 ok; + ok = __imp_CloseHandle(hObject); + if (!ok) __winerr(); + NTTRACE("CloseHandle(%ld) → %hhhd% m", hObject, ok); + return ok; +} diff --git a/libc/bits/cmpxchg.c b/libc/intrin/cmpxchg.c similarity index 77% rename from libc/bits/cmpxchg.c rename to libc/intrin/cmpxchg.c index 8800d7c5d..f8e363138 100644 --- a/libc/bits/cmpxchg.c +++ b/libc/intrin/cmpxchg.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/intrin/cmpxchg.h" /** * Compares and exchanges. @@ -24,23 +24,23 @@ * @param ifthing is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} * @param size is automatically supplied by macro wrapper * @return true if value was exchanged, otherwise false - * @see lockcmpxchg() + * @see _lockcmpxchg() */ -bool(cmpxchg)(void *ifthing, intptr_t isequaltome, intptr_t replaceitwithme, - size_t size) { +bool(_cmpxchg)(void *ifthing, intptr_t isequaltome, intptr_t replaceitwithme, + size_t size) { switch (size) { case 1: - return cmpxchg((int8_t *)ifthing, (int8_t)isequaltome, - (int8_t)replaceitwithme); + return _cmpxchg((int8_t *)ifthing, (int8_t)isequaltome, + (int8_t)replaceitwithme); case 2: - return cmpxchg((int16_t *)ifthing, (int16_t)isequaltome, - (int16_t)replaceitwithme); + return _cmpxchg((int16_t *)ifthing, (int16_t)isequaltome, + (int16_t)replaceitwithme); case 4: - return cmpxchg((int32_t *)ifthing, (int32_t)isequaltome, - (int32_t)replaceitwithme); + return _cmpxchg((int32_t *)ifthing, (int32_t)isequaltome, + (int32_t)replaceitwithme); case 8: - return cmpxchg((int64_t *)ifthing, (int64_t)isequaltome, - (int64_t)replaceitwithme); + return _cmpxchg((int64_t *)ifthing, (int64_t)isequaltome, + (int64_t)replaceitwithme); default: return false; } diff --git a/libc/intrin/cmpxchg.h b/libc/intrin/cmpxchg.h new file mode 100644 index 000000000..2f560c813 --- /dev/null +++ b/libc/intrin/cmpxchg.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_CMPXCHG_H_ +#define COSMOPOLITAN_LIBC_INTRIN_CMPXCHG_H_ +#include "libc/bits/asmflag.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +bool _cmpxchg(void *, intptr_t, intptr_t, size_t); + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86__) +#define _cmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ + ({ \ + bool DidIt; \ + autotype(IFTHING) IfThing = (IFTHING); \ + typeof(*IfThing) IsEqualToMe = (ISEQUALTOME); \ + typeof(*IfThing) ReplaceItWithMe = (REPLACEITWITHME); \ + asm volatile(ZFLAG_ASM("cmpxchg\t%3,%1") \ + : ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(IsEqualToMe) \ + : "r"(ReplaceItWithMe) \ + : "cc"); \ + DidIt; \ + }) +#else +#define _cmpxchg(MEM, CMP, VAL) \ + _cmpxchg(MEM, (intptr_t)(CMP), (intptr_t)(VAL), sizeof(*(MEM))) +#endif /* GNUC && !ANSI && x86 */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_CMPXCHG_H_ */ diff --git a/libc/intrin/cmpxchg16b.internal.h b/libc/intrin/cmpxchg16b.internal.h new file mode 100644 index 000000000..a254d9fba --- /dev/null +++ b/libc/intrin/cmpxchg16b.internal.h @@ -0,0 +1,46 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_CMPXCHG16B_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_BITS_CMPXCHG16B_INTERNAL_H_ +#include "libc/bits/asmflag.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * Compares and exchanges 128-bit value, i.e. + * + * if (*IfThing == *IsEqualToMe) { + * *IfThing = ReplaceItWithMe; + * return true; + * } else { + * *IsEqualToMe = *IfThing; + * return false; + * } + * + * Please note that Intel Architecture doesn't guarantee 16-byte memory + * accesses to be atomic on their own. Therefore _lockcmpxchg16b should + * be considered instead for both thread and asynchronous signal safety + * + * @param IfThing should point to aligned memory + * @param IsEqualToMe should point to in/out local variable + * @param ReplaceItWithMe might become the new memory value + * @return true if *IfThing was changed + */ +static inline bool _cmpxchg16b(uint128_t *IfThing, uint128_t *IsEqualToMe, + uint128_t ReplaceItWithMe) { + bool DidIt; + uint64_t ax, bx, cx, dx; + ax = *IsEqualToMe; + dx = *IsEqualToMe >> 64; + bx = ReplaceItWithMe; + cx = ReplaceItWithMe >> 64; + asm volatile(ZFLAG_ASM("cmpxchg16b\t%1") + : ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(ax), "+d"(dx) + : "b"(bx), "c"(cx)); + if (!DidIt) { + *IsEqualToMe = ax | (uint128_t)dx << 64; + } + return DidIt; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_CMPXCHG16B_INTERNAL_H_ */ diff --git a/libc/intrin/createdirectory.greg.c b/libc/intrin/createdirectory.greg.c new file mode 100644 index 000000000..f0a8efd10 --- /dev/null +++ b/libc/intrin/createdirectory.greg.c @@ -0,0 +1,42 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(CreateDirectory) *const __imp_CreateDirectoryW; + +/** + * Creates directory on the New Technology. + * + * @return handle, or -1 on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 +CreateDirectory(const char16_t *lpPathName, + struct NtSecurityAttributes *lpSecurityAttributes) { + bool32 ok; + ok = __imp_CreateDirectoryW(lpPathName, lpSecurityAttributes); + if (!ok) __winerr(); + NTTRACE("CreateDirectory(%#hs, %s) → %hhhd% m", lpPathName, + DescribeNtSecurityAttributes(lpSecurityAttributes), ok); + return ok; +} diff --git a/libc/intrin/createfile.greg.c b/libc/intrin/createfile.greg.c new file mode 100644 index 000000000..6290f7381 --- /dev/null +++ b/libc/intrin/createfile.greg.c @@ -0,0 +1,51 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/createfile.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(CreateFile) *const __imp_CreateFileW; + +/** + * Opens file on the New Technology. + * + * @return handle, or -1 on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows int64_t CreateFile( + const char16_t *lpFileName, uint32_t dwDesiredAccess, uint32_t dwShareMode, + struct NtSecurityAttributes *opt_lpSecurityAttributes, + int dwCreationDisposition, uint32_t dwFlagsAndAttributes, + int64_t opt_hTemplateFile) { + int64_t hHandle; + hHandle = __imp_CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, + opt_lpSecurityAttributes, dwCreationDisposition, + dwFlagsAndAttributes, opt_hTemplateFile); + if (hHandle == -1) __winerr(); + NTTRACE("CreateFile(%#hs, %s, %s, %s, %s, %s, %ld) → %ld% m", lpFileName, + DescribeNtFileAccessFlags(dwDesiredAccess), + DescribeNtFileShareFlags(dwShareMode), + DescribeNtSecurityAttributes(opt_lpSecurityAttributes), + DescribeNtCreationDisposition(dwCreationDisposition), + DescribeNtFileFlagsAndAttributes(dwFlagsAndAttributes), + opt_hTemplateFile, hHandle); + return hHandle; +} diff --git a/libc/intrin/createfilemapping.greg.c b/libc/intrin/createfilemapping.greg.c new file mode 100644 index 000000000..a8a5ea4aa --- /dev/null +++ b/libc/intrin/createfilemapping.greg.c @@ -0,0 +1,52 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/memory.h" +#include "libc/nt/struct/securityattributes.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(CreateFileMapping) *const __imp_CreateFileMappingW; + +/** + * Creates file mapping object on the New Technology. + * + * @param opt_hFile may be -1 for MAP_ANONYMOUS behavior + * @return handle, or 0 on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + * @see MapViewOfFileEx() + */ +textwindows int64_t CreateFileMapping( + int64_t opt_hFile, + const struct NtSecurityAttributes *opt_lpFileMappingAttributes, + uint32_t flProtect, uint32_t dwMaximumSizeHigh, uint32_t dwMaximumSizeLow, + const char16_t *opt_lpName) { + int64_t hHandle; + hHandle = __imp_CreateFileMappingW(opt_hFile, opt_lpFileMappingAttributes, + flProtect, dwMaximumSizeHigh, + dwMaximumSizeLow, opt_lpName); + if (!hHandle) __winerr(); + NTTRACE("CreateFileMapping(%ld, %s, %s, %'zu, %#hs) → %ld% m", opt_hFile, + DescribeNtSecurityAttributes(opt_lpFileMappingAttributes), + DescribeNtPageFlags(flProtect), + (uint64_t)dwMaximumSizeHigh << 32 | dwMaximumSizeLow, opt_lpName, + hHandle); + return hHandle; +} diff --git a/libc/intrin/createfilemappingnuma.greg.c b/libc/intrin/createfilemappingnuma.greg.c new file mode 100644 index 000000000..7da20c4fc --- /dev/null +++ b/libc/intrin/createfilemappingnuma.greg.c @@ -0,0 +1,53 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/memory.h" +#include "libc/nt/struct/securityattributes.h" + +__msabi extern typeof(CreateFileMappingNuma) *const + __imp_CreateFileMappingNumaW; + +/** + * Creates file mapping object on the New Technology. + * + * @param opt_hFile may be -1 for MAP_ANONYMOUS behavior + * @return handle, or 0 on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + * @see MapViewOfFileExNuma() + */ +textwindows int64_t CreateFileMappingNuma( + int64_t opt_hFile, + const struct NtSecurityAttributes *opt_lpFileMappingAttributes, + uint32_t flProtect, uint32_t dwMaximumSizeHigh, uint32_t dwMaximumSizeLow, + const char16_t *opt_lpName, uint32_t nndDesiredNumaNode) { + int64_t hHandle; + hHandle = __imp_CreateFileMappingNumaW( + opt_hFile, opt_lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, + dwMaximumSizeLow, opt_lpName, nndDesiredNumaNode); + if (!hHandle) __winerr(); + NTTRACE("CreateFileMappingNuma(%ld, %s, %s, %'zu, %#hs) → %ld% m", opt_hFile, + DescribeNtSecurityAttributes(opt_lpFileMappingAttributes), + DescribeNtPageFlags(flProtect), + (uint64_t)dwMaximumSizeHigh << 32 | dwMaximumSizeLow, opt_lpName, + hHandle); + return hHandle; +} diff --git a/libc/intrin/createnamedpipe.greg.c b/libc/intrin/createnamedpipe.greg.c new file mode 100644 index 000000000..7e70683e1 --- /dev/null +++ b/libc/intrin/createnamedpipe.greg.c @@ -0,0 +1,50 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/ipc.h" +#include "libc/nt/struct/securityattributes.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(CreateNamedPipe) *const __imp_CreateNamedPipeW; + +/** + * Creates pipe. + * + * @return handle to server end + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows int64_t CreateNamedPipe( + const char16_t *lpName, uint32_t dwOpenMode, uint32_t dwPipeMode, + uint32_t nMaxInstances, uint32_t nOutBufferSize, uint32_t nInBufferSize, + uint32_t nDefaultTimeOutMs, + const struct NtSecurityAttributes *opt_lpSecurityAttributes) { + int64_t hServer; + hServer = __imp_CreateNamedPipeW(lpName, dwOpenMode, dwPipeMode, + nMaxInstances, nOutBufferSize, nInBufferSize, + nDefaultTimeOutMs, opt_lpSecurityAttributes); + if (hServer == -1) __winerr(); + NTTRACE("CreateNamedPipe(%#hs, %s, %s, %u, %'u, %'u, %'u, %s) → %ld% m", + lpName, DescribeNtPipeOpenFlags(dwOpenMode), + DescribeNtPipeModeFlags(dwPipeMode), nMaxInstances, nOutBufferSize, + nInBufferSize, nDefaultTimeOutMs, + DescribeNtSecurityAttributes(opt_lpSecurityAttributes), hServer); + return hServer; +} diff --git a/libc/intrin/createpipe.greg.c b/libc/intrin/createpipe.greg.c new file mode 100644 index 000000000..4e295530a --- /dev/null +++ b/libc/intrin/createpipe.greg.c @@ -0,0 +1,43 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/ipc.h" +#include "libc/nt/struct/securityattributes.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(CreatePipe) *const __imp_CreatePipe; + +/** + * Creates anonymous pipe. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 CreatePipe( + int64_t *out_hReadPipe, int64_t *out_hWritePipe, + const struct NtSecurityAttributes *opt_lpPipeAttributes, uint32_t nSize) { + bool32 ok; + ok = __imp_CreatePipe(out_hReadPipe, out_hWritePipe, opt_lpPipeAttributes, + nSize); + if (!ok) __winerr(); + NTTRACE("CreatePipe([%ld], [%ld], %s, %'zu) → %hhhd% m", *out_hReadPipe, + *out_hWritePipe, DescribeNtSecurityAttributes(opt_lpPipeAttributes), + nSize, ok); + return ok; +} diff --git a/libc/intrin/createprocess.greg.c b/libc/intrin/createprocess.greg.c new file mode 100644 index 000000000..e18232d85 --- /dev/null +++ b/libc/intrin/createprocess.greg.c @@ -0,0 +1,55 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/process.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(CreateProcess) *const __imp_CreateProcessW; + +/** + * Creates process on the New Technology. + * + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 +CreateProcess(const char16_t *opt_lpApplicationName, char16_t *lpCommandLine, + struct NtSecurityAttributes *opt_lpProcessAttributes, + struct NtSecurityAttributes *opt_lpThreadAttributes, + bool32 bInheritHandles, uint32_t dwCreationFlags, + void *opt_lpEnvironment, const char16_t *opt_lpCurrentDirectory, + const struct NtStartupInfo *lpStartupInfo, + struct NtProcessInformation *opt_out_lpProcessInformation) { + bool32 ok; + ok = __imp_CreateProcessW(opt_lpApplicationName, lpCommandLine, + opt_lpProcessAttributes, opt_lpThreadAttributes, + bInheritHandles, dwCreationFlags, opt_lpEnvironment, + opt_lpCurrentDirectory, lpStartupInfo, + opt_out_lpProcessInformation); + if (!ok) __winerr(); + NTTRACE("CreateProcess(%#hs, %#!hs, %s, %s, %hhhd, %u, %p, %#hs, %p, %p) → " + "%hhhd% m", + opt_lpApplicationName, lpCommandLine, + DescribeNtSecurityAttributes(opt_lpProcessAttributes), + DescribeNtSecurityAttributes(opt_lpThreadAttributes), bInheritHandles, + dwCreationFlags, opt_lpEnvironment, opt_lpCurrentDirectory, + lpStartupInfo, opt_out_lpProcessInformation, ok); + return ok; +} diff --git a/libc/intrin/createsymboliclink.greg.c b/libc/intrin/createsymboliclink.greg.c new file mode 100644 index 000000000..ddbe879a0 --- /dev/null +++ b/libc/intrin/createsymboliclink.greg.c @@ -0,0 +1,39 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/files.h" + +__msabi extern typeof(CreateSymbolicLink) *const __imp_CreateSymbolicLinkW; + +/** + * Creates symbolic link on the New Technology. + * @note you need to elevate process privileges before calling this + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +bool32 CreateSymbolicLink(const char16_t *lpSymlinkFileName, + const char16_t *lpTargetPathName, uint32_t dwFlags) { + bool32 ok; + ok = __imp_CreateSymbolicLinkW(lpSymlinkFileName, lpTargetPathName, dwFlags); + if (!ok) __winerr(); + NTTRACE("CreateSymbolicLink(%#hs, %#hs, %s) → %hhhd% m", lpSymlinkFileName, + lpTargetPathName, DescribeNtSymbolicLinkFlags(dwFlags), ok); + return ok; +} diff --git a/libc/intrin/createthread.greg.c b/libc/intrin/createthread.greg.c new file mode 100644 index 000000000..77992f157 --- /dev/null +++ b/libc/intrin/createthread.greg.c @@ -0,0 +1,47 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/struct/securityattributes.h" +#include "libc/nt/thread.h" + +__msabi extern typeof(CreateThread) *const __imp_CreateThread; + +/** + * Opens file on the New Technology. + * + * @param dwStackSize may be 0 for default per executable + * @return thread handle, or 0 on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows int64_t CreateThread( + struct NtSecurityAttributes *lpThreadAttributes, size_t dwStackSize, + NtThreadStartRoutine lpStartAddress, void *lpParameter, + uint32_t dwCreationFlags, uint32_t *opt_lpThreadId) { + int64_t hHandle; + hHandle = __imp_CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, + lpParameter, dwCreationFlags, opt_lpThreadId); + if (hHandle == -1) __winerr(); + NTTRACE("CreateThread(%s, %'zu, %p, %p, %s, %p) → %ld% m", + DescribeNtSecurityAttributes(lpThreadAttributes), dwStackSize, + lpStartAddress, lpParameter, dwCreationFlags, opt_lpThreadId, + hHandle); + return hHandle; +} diff --git a/libc/intrin/cxaatexit.c b/libc/intrin/cxaatexit.c index 4a5918625..a71602958 100644 --- a/libc/intrin/cxaatexit.c +++ b/libc/intrin/cxaatexit.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/bits/weaken.h" +#include "libc/calls/strace.internal.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/bsr.h" diff --git a/libc/intrin/cxafinalize.c b/libc/intrin/cxafinalize.c index 741fee0dc..ca9796b05 100644 --- a/libc/intrin/cxafinalize.c +++ b/libc/intrin/cxafinalize.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/bits/weaken.h" +#include "libc/calls/strace.internal.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/bsf.h" #include "libc/runtime/cxaatexit.internal.h" @@ -45,6 +46,7 @@ StartOver: if (!pred || pred == b->p[i].pred) { b->mask &= ~(1u << i); if (b->p[i].fp) { + STRACE("__cxa_finalize(%t, %p)", b->p[i].fp, b->p[i].arg); ((void (*)(void *))b->p[i].fp)(b->p[i].arg); goto StartOver; } diff --git a/libc/intrin/deletefile.greg.c b/libc/intrin/deletefile.greg.c new file mode 100644 index 000000000..bf30eb534 --- /dev/null +++ b/libc/intrin/deletefile.greg.c @@ -0,0 +1,36 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(DeleteFile) *const __imp_DeleteFileW; + +/** + * Deletes existing file. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 DeleteFile(const char16_t *lpPathName) { + bool32 ok; + ok = __imp_DeleteFileW(lpPathName); + if (!ok) __winerr(); + NTTRACE("DeleteFile(%#hs) → %hhhd% m", lpPathName, ok); + return ok; +} diff --git a/libc/intrin/describeflags.greg.c b/libc/intrin/describeflags.greg.c new file mode 100644 index 000000000..b7166d269 --- /dev/null +++ b/libc/intrin/describeflags.greg.c @@ -0,0 +1,59 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/intrin/kprintf.h" + +const char *DescribeFlags(char *p, size_t n, struct DescribeFlags *d, size_t m, + const char *prefix, unsigned x) { + bool t; + char b[21]; + size_t i, j, k; + for (t = i = j = 0; j < m; ++j) { + if (d[j].flag && d[j].flag != -1 && (x & d[j].flag) == d[j].flag) { + x &= ~d[j].flag; + if (t) { + if (i + 1 < n) p[i++] = '|'; + } else { + t = true; + } + for (k = 0; prefix && prefix[k]; ++k) { + if (i + 1 < n) p[i++] = prefix[k]; + } + for (k = 0; d[j].name[k]; ++k) { + if (i + 1 < n) p[i++] = d[j].name[k]; + } + } + } + if (x || !t) { + if (t && i + 1 < n) p[i++] = '|'; + if (i + 1 < n) p[i++] = '0'; + if (x) { + if (i + 1 < n) p[i++] = 'x'; + k = 0; + do { + if (i + 1 < n) b[k++] = "0123456789abcdef"[x % 16]; + } while ((x /= 16)); + while (k--) { + if (i + 1 < n) p[i++] = b[k]; + } + } + } + if (i < n) p[i] = 0; + return p; +} diff --git a/libc/intrin/describeflags.internal.h b/libc/intrin/describeflags.internal.h new file mode 100644 index 000000000..521319d8a --- /dev/null +++ b/libc/intrin/describeflags.internal.h @@ -0,0 +1,40 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_ +#include "libc/nt/struct/securityattributes.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct thatispacked DescribeFlags { + unsigned flag; + const char *name; +}; + +const char *DescribeFlags(char *, size_t, struct DescribeFlags *, size_t, + const char *, unsigned); + +const char *DescribeMapFlags(int); +const char *DescribeProtFlags(int); +const char *DescribeRemapFlags(int); +const char *DescribeSeccompOperationFlags(int); +const char *DescribePollFlags(char *, size_t, int); + +const char *DescribeNtPageFlags(uint32_t); +const char *DescribeNtStartFlags(uint32_t); +const char *DescribeNtFileMapFlags(uint32_t); +const char *DescribeNtFiletypeFlags(uint32_t); +const char *DescribeNtPipeOpenFlags(uint32_t); +const char *DescribeNtPipeModeFlags(uint32_t); +const char *DescribeNtFileShareFlags(uint32_t); +const char *DescribeNtFileAccessFlags(uint32_t); +const char *DescribeNtSymbolicLinkFlags(uint32_t); +const char *DescribeNtProcessAccessFlags(uint32_t); +const char *DescribeNtMoveFileInputFlags(uint32_t); +const char *DescribeNtCreationDisposition(uint32_t); +const char *DescribeNtConsoleModeInputFlags(uint32_t); +const char *DescribeNtConsoleModeOutputFlags(uint32_t); +const char *DescribeNtFileFlagsAndAttributes(uint32_t); +const char *DescribeNtSecurityAttributes(struct NtSecurityAttributes *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_ */ diff --git a/libc/intrin/describemapflags.greg.c b/libc/intrin/describemapflags.greg.c new file mode 100644 index 000000000..8b361b72a --- /dev/null +++ b/libc/intrin/describemapflags.greg.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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/consolemodeflags.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +const char *DescribeMapFlags(int x) { + _Alignas(char) static char mapflags[256]; + const struct DescribeFlags kMapFlags[] = { + {MAP_ANONYMOUS, "ANONYMOUS"}, // + {MAP_PRIVATE, "PRIVATE"}, // + {MAP_SHARED, "SHARED"}, // + {MAP_FIXED, "FIXED"}, // + {MAP_FIXED_NOREPLACE, "FIXED_NOREPLACE"}, // + {MAP_GROWSDOWN, "GROWSDOWN"}, // + {MAP_CONCEAL, "CONCEAL"}, // + {MAP_HUGETLB, "HUGETLB"}, // + {MAP_LOCKED, "LOCKED"}, // + {MAP_NORESERVE, "NORESERVE"}, // + {MAP_NONBLOCK, "NONBLOCK"}, // + {MAP_POPULATE, "POPULATE"}, // + {MAP_STACK, "STACK"}, // order matters + }; + return DescribeFlags(mapflags, sizeof(mapflags), kMapFlags, + ARRAYLEN(kMapFlags), "MAP_", x); +} diff --git a/libc/intrin/describentconsolemodeinputflags.greg.c b/libc/intrin/describentconsolemodeinputflags.greg.c new file mode 100644 index 000000000..1b3fb94eb --- /dev/null +++ b/libc/intrin/describentconsolemodeinputflags.greg.c @@ -0,0 +1,41 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/consolemodeflags.h" + +static const struct DescribeFlags kConsoleModeInputFlags[] = { + {kNtEnableProcessedInput, "ProcessedInput"}, // + {kNtEnableLineInput, "LineInput"}, // + {kNtEnableEchoInput, "EchoInput"}, // + {kNtEnableWindowInput, "WindowInput"}, // + {kNtEnableMouseInput, "MouseInput"}, // + {kNtEnableInsertMode, "InsertMode"}, // + {kNtEnableQuickEditMode, "QuickEditMode"}, // + {kNtEnableExtendedFlags, "ExtendedFlags"}, // + {kNtEnableAutoPosition, "AutoPosition"}, // + {kNtEnableVirtualTerminalInput, "VirtualTerminalInput"}, // +}; + +const char *DescribeNtConsoleModeInputFlags(uint32_t x) { + _Alignas(char) static char consolemodeinputflags[256]; + return DescribeFlags(consolemodeinputflags, sizeof(consolemodeinputflags), + kConsoleModeInputFlags, ARRAYLEN(kConsoleModeInputFlags), + "kNtEnable", x); +} diff --git a/libc/intrin/describentconsolemodeoutputflags.greg.c b/libc/intrin/describentconsolemodeoutputflags.greg.c new file mode 100644 index 000000000..139b6e9ed --- /dev/null +++ b/libc/intrin/describentconsolemodeoutputflags.greg.c @@ -0,0 +1,36 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/consolemodeflags.h" + +static const struct DescribeFlags kConsoleModeOutputFlags[] = { + {kNtEnableProcessedOutput, "EnableProcessedOutput"}, // + {kNtEnableWrapAtEolOutput, "EnableWrapAtEolOutput"}, // + {kNtEnableVirtualTerminalProcessing, "EnableVirtualTerminalProcessing"}, // + {kNtDisableNewlineAutoReturn, "DisableNewlineAutoReturn"}, // + {kNtEnableLvbGridWorldwide, "EnableLvbGridWorldwide"}, // +}; + +const char *DescribeNtConsoleModeOutputFlags(uint32_t x) { + _Alignas(char) static char consolemodeoutputflags[128]; + return DescribeFlags(consolemodeoutputflags, sizeof(consolemodeoutputflags), + kConsoleModeOutputFlags, + ARRAYLEN(kConsoleModeOutputFlags), "kNt", x); +} diff --git a/libc/intrin/describentcreationdisposition.greg.c b/libc/intrin/describentcreationdisposition.greg.c new file mode 100644 index 000000000..3285578d0 --- /dev/null +++ b/libc/intrin/describentcreationdisposition.greg.c @@ -0,0 +1,37 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/nt/enum/creationdisposition.h" + +const char *DescribeNtCreationDisposition(uint32_t x) { + switch (x) { + case kNtCreateNew: + return "kNtCreateNew"; + case kNtCreateAlways: + return "kNtCreateAlways"; + case kNtOpenExisting: + return "kNtOpenExisting"; + case kNtOpenAlways: + return "kNtOpenAlways"; + case kNtTruncateExisting: + return "kNtTruncateExisting"; + default: + return "wut"; + } +} diff --git a/libc/intrin/describentfileaccessflags.greg.c b/libc/intrin/describentfileaccessflags.greg.c new file mode 100644 index 000000000..79924afb7 --- /dev/null +++ b/libc/intrin/describentfileaccessflags.greg.c @@ -0,0 +1,70 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/filesharemode.h" + +static const struct DescribeFlags kFileAccessflags[] = { + {kNtFileAllAccess, "FileAllAccess"}, // order matters + {kNtFileGenericRead, "FileGenericRead"}, // order matters + {kNtFileGenericWrite, "FileGenericWrite"}, // order matters + {kNtFileGenericExecute, "FileGenericExecute"}, // order matters + {kNtGenericRead, "GenericRead"}, // + {kNtGenericWrite, "GenericWrite"}, // + {kNtGenericExecute, "GenericExecute"}, // + {kNtGenericAll, "GenericAll"}, // + {kNtDelete, "Delete"}, // + {kNtReadControl, "ReadControl"}, // + {kNtWriteDac, "WriteDac"}, // + {kNtWriteOwner, "WriteOwner"}, // + {kNtSynchronize, "Synchronize"}, // + {kNtStandardRightsRequired, "StandardRightsRequired"}, // + {kNtAccessSystemSecurity, "AccessSystemSecurity"}, // + {kNtMaximumAllowed, "MaximumAllowed"}, // + {kNtFileReadData, "FileReadData"}, // + {kNtFileListDirectory, "FileListDirectory"}, // + {kNtFileWriteData, "FileWriteData"}, // + {kNtFileAddFile, "FileAddFile"}, // + {kNtFileAppendData, "FileAppendData"}, // + {kNtFileAddSubdirectory, "FileAddSubdirectory"}, // + {kNtFileCreatePipeInstance, "FileCreatePipeInstance"}, // + {kNtFileReadEa, "FileReadEa"}, // + {kNtFileWriteEa, "FileWriteEa"}, // + {kNtFileExecute, "FileExecute"}, // + {kNtFileTraverse, "FileTraverse"}, // + {kNtFileDeleteChild, "FileDeleteChild"}, // + {kNtFileReadAttributes, "FileReadAttributes"}, // + {kNtFileWriteAttributes, "FileWriteAttributes"}, // + {kNtTokenAssignPrimary, "TokenAssignPrimary"}, // + {kNtTokenDuplicate, "TokenDuplicate"}, // + {kNtTokenImpersonate, "TokenImpersonate"}, // + {kNtTokenQuery, "TokenQuery"}, // + {kNtTokenQuerySource, "TokenQuerySource"}, // + {kNtTokenAdjustPrivileges, "TokenAdjustPrivileges"}, // + {kNtTokenAdjustGroups, "TokenAdjustGroups"}, // + {kNtTokenAdjustDefault, "TokenAdjustDefault"}, // + {kNtTokenAdjustSessionid, "TokenAdjustSessionid"}, // +}; + +const char *DescribeNtFileAccessFlags(uint32_t x) { + _Alignas(char) static char ntfileaccessflags[512]; + return DescribeFlags(ntfileaccessflags, sizeof(ntfileaccessflags), + kFileAccessflags, ARRAYLEN(kFileAccessflags), "kNt", x); +} diff --git a/libc/intrin/describentfileflagsandattributes.greg.c b/libc/intrin/describentfileflagsandattributes.greg.c new file mode 100644 index 000000000..53a5a47d7 --- /dev/null +++ b/libc/intrin/describentfileflagsandattributes.greg.c @@ -0,0 +1,59 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/runtime/runtime.h" + +static const struct DescribeFlags kFileFlags[] = { + {kNtFileAttributeReadonly, "AttributeReadonly"}, // + {kNtFileAttributeHidden, "AttributeHidden"}, // + {kNtFileAttributeSystem, "AttributeSystem"}, // + {kNtFileAttributeVolumelabel, "AttributeVolumelabel"}, // + {kNtFileAttributeDirectory, "AttributeDirectory"}, // + {kNtFileAttributeArchive, "AttributeArchive"}, // + {kNtFileAttributeDevice, "AttributeDevice"}, // + {kNtFileAttributeNormal, "AttributeNormal"}, // + {kNtFileAttributeTemporary, "AttributeTemporary"}, // + {kNtFileAttributeSparseFile, "AttributeSparseFile"}, // + {kNtFileAttributeReparsePoint, "AttributeReparsePoint"}, // + {kNtFileAttributeCompressed, "AttributeCompressed"}, // + {kNtFileAttributeOffline, "AttributeOffline"}, // + {kNtFileAttributeNotContentIndexed, "AttributeNotContentIndexed"}, // + {kNtFileAttributeEncrypted, "AttributeEncrypted"}, // + {kNtFileFlagWriteThrough, "FlagWriteThrough"}, // + {kNtFileFlagOverlapped, "FlagOverlapped"}, // + {kNtFileFlagNoBuffering, "FlagNoBuffering"}, // + {kNtFileFlagRandomAccess, "FlagRandomAccess"}, // + {kNtFileFlagSequentialScan, "FlagSequentialScan"}, // + {kNtFileFlagDeleteOnClose, "FlagDeleteOnClose"}, // + {kNtFileFlagBackupSemantics, "FlagBackupSemantics"}, // + {kNtFileFlagPosixSemantics, "FlagPosixSemantics"}, // + {kNtFileFlagOpenReparsePoint, "FlagOpenReparsePoint"}, // + {kNtFileFlagOpenNoRecall, "FlagOpenNoRecall"}, // + {kNtFileFlagFirstPipeInstance, "FlagFirstPipeInstance"}, // +}; + +const char *DescribeNtFileFlagsAndAttributes(uint32_t x) { + _Alignas(char) static char ntfileflags[256]; + if (x == -1u) return "-1u"; + return DescribeFlags(ntfileflags, sizeof(ntfileflags), kFileFlags, + ARRAYLEN(kFileFlags), "kNtFile", x); +} diff --git a/libc/intrin/describentfilemapflags.greg.c b/libc/intrin/describentfilemapflags.greg.c new file mode 100644 index 000000000..f5cdabaf5 --- /dev/null +++ b/libc/intrin/describentfilemapflags.greg.c @@ -0,0 +1,37 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/filemapflags.h" + +static const struct DescribeFlags kFileMapFlags[] = { + {kNtFileMapCopy, "Copy"}, // + {kNtFileMapWrite, "Write"}, // + {kNtFileMapRead, "Read"}, // + {kNtFileMapExecute, "Execute"}, // + {kNtFileMapReserve, "Reserve"}, // + {kNtFileMapTargetsInvalid, "TargetsInvalid"}, // + {kNtFileMapLargePages, "LargePages"}, // +}; + +const char *DescribeNtFileMapFlags(uint32_t x) { + _Alignas(char) static char filemapflags[64]; + return DescribeFlags(filemapflags, sizeof(filemapflags), kFileMapFlags, + ARRAYLEN(kFileMapFlags), "kNtFileMap", x); +} diff --git a/libc/intrin/describentfileshareflags.greg.c b/libc/intrin/describentfileshareflags.greg.c new file mode 100644 index 000000000..c322e3b86 --- /dev/null +++ b/libc/intrin/describentfileshareflags.greg.c @@ -0,0 +1,34 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/filesharemode.h" + +static const struct DescribeFlags kFileShareflags[] = { + {kNtFileShareRead, "Read"}, // + {kNtFileShareWrite, "Write"}, // + {kNtFileShareDelete, "Delete"}, // +}; + +const char *DescribeNtFileShareFlags(uint32_t x) { + _Alignas(char) static char ntfileshareflags[64]; + return DescribeFlags(ntfileshareflags, sizeof(ntfileshareflags), + kFileShareflags, ARRAYLEN(kFileShareflags), + "kNtFileShare", x); +} diff --git a/libc/intrin/describentfiletypeflags.greg.c b/libc/intrin/describentfiletypeflags.greg.c new file mode 100644 index 000000000..70b48ea1b --- /dev/null +++ b/libc/intrin/describentfiletypeflags.greg.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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/filetype.h" +#include "libc/sysv/consts/mremap.h" + +static const struct DescribeFlags kFiletypeFlags[] = { + {kNtFileTypeRemote, "Remote"}, // + {kNtFileTypePipe, "Pipe"}, // order matters + {kNtFileTypeDisk, "Disk"}, // + {kNtFileTypeChar, "Char"}, // +}; + +const char *DescribeNtFiletypeFlags(uint32_t x) { + _Alignas(char) static char filetypeflags[64]; + return DescribeFlags(filetypeflags, sizeof(filetypeflags), kFiletypeFlags, + ARRAYLEN(kFiletypeFlags), "kNtFileType", x); +} diff --git a/libc/intrin/describentmovefileflags.greg.c b/libc/intrin/describentmovefileflags.greg.c new file mode 100644 index 000000000..c2f29b869 --- /dev/null +++ b/libc/intrin/describentmovefileflags.greg.c @@ -0,0 +1,37 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/movefileexflags.h" + +static const struct DescribeFlags kMoveFileInputFlags[] = { + {kNtMovefileReplaceExisting, "ReplaceExisting"}, // + {kNtMovefileCopyAllowed, "CopyAllowed"}, // + {kNtMovefileDelayUntilReboot, "DelayUntilReboot"}, // + {kNtMovefileWriteThrough, "WriteThrough"}, // + {kNtMovefileCreateHardlink, "CreateHardlink"}, // + {kNtMovefileFailIfNotTrackable, "FailIfNotTrackable"}, // +}; + +const char *DescribeNtMoveFileInputFlags(uint32_t x) { + _Alignas(char) static char movefileflags[256]; + return DescribeFlags(movefileflags, sizeof(movefileflags), + kMoveFileInputFlags, ARRAYLEN(kMoveFileInputFlags), + "kNtMovefile", x); +} diff --git a/libc/intrin/describentpageflags.greg.c b/libc/intrin/describentpageflags.greg.c new file mode 100644 index 000000000..02a7451c8 --- /dev/null +++ b/libc/intrin/describentpageflags.greg.c @@ -0,0 +1,48 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/pageflags.h" + +static const struct DescribeFlags kPageFlags[] = { + {kNtPageNoaccess, "PageNoaccess"}, // + {kNtPageReadonly, "PageReadonly"}, // + {kNtPageReadwrite, "PageReadwrite"}, // + {kNtPageWritecopy, "PageWritecopy"}, // + {kNtPageExecute, "PageExecute"}, // + {kNtPageExecuteRead, "PageExecuteRead"}, // + {kNtPageExecuteReadwrite, "PageExecuteReadwrite"}, // + {kNtPageExecuteWritecopy, "PageExecuteWritecopy"}, // + {kNtPageGuard, "PageGuard"}, // + {kNtPageNocache, "PageNocache"}, // + {kNtPageWritecombine, "PageWritecombine"}, // + {kNtSecReserve, "SecReserve"}, // + {kNtSecCommit, "SecCommit"}, // + {kNtSecImageNoExecute, "SecImageNoExecute"}, // order matters + {kNtSecImage, "SecImage"}, // + {kNtSecLargePages, "SecLargePages"}, // + {kNtSecNocache, "SecNocache"}, // + {kNtSecWritecombine, "SecWritecombine"}, // +}; + +const char *DescribeNtPageFlags(uint32_t x) { + _Alignas(char) static char pageflags[64]; + return DescribeFlags(pageflags, sizeof(pageflags), kPageFlags, + ARRAYLEN(kPageFlags), "kNt", x); +} diff --git a/libc/intrin/describentpipemodeflags.greg.c b/libc/intrin/describentpipemodeflags.greg.c new file mode 100644 index 000000000..f8f1f89ee --- /dev/null +++ b/libc/intrin/describentpipemodeflags.greg.c @@ -0,0 +1,39 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/ipc.h" + +static const struct DescribeFlags kPipeModeFlags[] = { + {kNtPipeNowait, "Nowait"}, // 0x0000000001 + {kNtPipeReadmodeMessage, "ReadmodeMessage"}, // 0x0000000002 + {kNtPipeTypeMessage, "TypeMessage"}, // 0x0000000004 + {kNtPipeRejectRemoteClients, "RejectRemoteClients"}, // 0x0000000008 + //{kNtPipeAcceptRemoteClients, "AcceptRemoteClients"}, // 0x00000000 + //{kNtPipeReadmodeByte, "ReadmodeByte"}, // 0x00000000 + //{kNtPipeWait, "Wait"}, // 0x00000000 + //{kNtPipeTypeByte, "TypeByte"}, // 0x00000000 +}; + +const char *DescribeNtPipeModeFlags(uint32_t x) { + _Alignas(char) static char pipemodeflags[64]; + return DescribeFlags(pipemodeflags, sizeof(pipemodeflags), kPipeModeFlags, + ARRAYLEN(kPipeModeFlags), "kNtPipe", x); +} diff --git a/libc/intrin/describentpipeopenflags.greg.c b/libc/intrin/describentpipeopenflags.greg.c new file mode 100644 index 000000000..10ab98a81 --- /dev/null +++ b/libc/intrin/describentpipeopenflags.greg.c @@ -0,0 +1,34 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/ipc.h" + +static const struct DescribeFlags kPipeOpenFlags[] = { + {kNtPipeAccessDuplex, "Duplex"}, // 0x00000003 + {kNtPipeAccessOutbound, "Outbound"}, // 0x00000002 + {kNtPipeAccessInbound, "Inbound"}, // 0x00000001 +}; + +const char *DescribeNtPipeOpenFlags(uint32_t x) { + _Alignas(char) static char pipeopenflags[64]; + return DescribeFlags(pipeopenflags, sizeof(pipeopenflags), kPipeOpenFlags, + ARRAYLEN(kPipeOpenFlags), "kNtPipeAccess", x); +} diff --git a/libc/intrin/describentprocessaccessflags.greg.c b/libc/intrin/describentprocessaccessflags.greg.c new file mode 100644 index 000000000..5f3d7fcdd --- /dev/null +++ b/libc/intrin/describentprocessaccessflags.greg.c @@ -0,0 +1,45 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/processaccess.h" + +static const struct DescribeFlags kProcessAccessflags[] = { + {kNtProcessAllAccess, "AllAccess"}, // + {kNtProcessCreateProcess, "CreateProcess"}, // + {kNtProcessCreateThread, "CreateThread"}, // + {kNtProcessDupHandle, "DupHandle"}, // + {kNtProcessQueryInformation, "QueryInformation"}, // + {kNtProcessQueryLimitedInformation, "QueryLimitedInformation"}, // + {kNtProcessSetInformation, "SetInformation"}, // + {kNtProcessSetQuota, "SetQuota"}, // + {kNtProcessSuspendResume, "SuspendResume"}, // + {kNtProcessTerminate, "Terminate"}, // + {kNtProcessVmOperation, "VmOperation"}, // + {kNtProcessVmRead, "VmRead"}, // + {kNtProcessVmWrite, "VmWrite"}, // + {kNtProcessSynchronize, "Synchronize"}, // +}; + +const char *DescribeNtProcessAccessFlags(uint32_t x) { + _Alignas(char) static char ntprocessaccessflags[256]; + return DescribeFlags(ntprocessaccessflags, sizeof(ntprocessaccessflags), + kProcessAccessflags, ARRAYLEN(kProcessAccessflags), + "kNtProcess", x); +} diff --git a/libc/intrin/describentsecurityattributes.greg.c b/libc/intrin/describentsecurityattributes.greg.c new file mode 100644 index 000000000..192fb72f0 --- /dev/null +++ b/libc/intrin/describentsecurityattributes.greg.c @@ -0,0 +1,26 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/struct/securityattributes.h" + +const char *DescribeNtSecurityAttributes(struct NtSecurityAttributes *p) { + if (p == &kNtIsInheritable) return "&kNtIsInheritable"; + return "0"; +} diff --git a/libc/intrin/describentstartflags.greg.c b/libc/intrin/describentstartflags.greg.c new file mode 100644 index 000000000..d80e2778b --- /dev/null +++ b/libc/intrin/describentstartflags.greg.c @@ -0,0 +1,45 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/startf.h" +#include "libc/sysv/consts/prot.h" + +static const struct DescribeFlags kNtStartFlags[] = { + {kNtStartfUseshowwindow, "Useshowwindow"}, // + {kNtStartfUsesize, "Usesize"}, // + {kNtStartfUseposition, "Useposition"}, // + {kNtStartfUsecountchars, "Usecountchars"}, // + {kNtStartfUsefillattribute, "Usefillattribute"}, // + {kNtStartfRunfullscreen, "Runfullscreen"}, // + {kNtStartfForceonfeedback, "Forceonfeedback"}, // + {kNtStartfForceofffeedback, "Forceofffeedback"}, // + {kNtStartfUsestdhandles, "Usestdhandles"}, // + {kNtStartfUsehotkey, "Usehotkey"}, // + {kNtStartfTitleislinkname, "Titleislinkname"}, // + {kNtStartfTitleisappid, "Titleisappid"}, // + {kNtStartfPreventpinning, "Preventpinning"}, // + {kNtStartfUntrustedsource, "Untrustedsource"}, // +}; + +const char *DescribeNtStartFlags(uint32_t x) { + _Alignas(char) static char startflags[128]; + return DescribeFlags(startflags, sizeof(startflags), kNtStartFlags, + ARRAYLEN(kNtStartFlags), "kNtStartf", x); +} diff --git a/libc/intrin/describentsymboliclinkflags.greg.c b/libc/intrin/describentsymboliclinkflags.greg.c new file mode 100644 index 000000000..233945f94 --- /dev/null +++ b/libc/intrin/describentsymboliclinkflags.greg.c @@ -0,0 +1,33 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/symboliclink.h" + +static const struct DescribeFlags kSymbolicLinkflags[] = { + {kNtSymbolicLinkFlagDirectory, "Directory"}, // + {kNtSymbolicLinkFlagAllowUnprivilegedCreate, "AllowUnprivilegedCreate"}, // +}; + +const char *DescribeNtSymbolicLinkFlags(uint32_t x) { + _Alignas(char) static char ntsymboliclinkflags[64]; + return DescribeFlags(ntsymboliclinkflags, sizeof(ntsymboliclinkflags), + kSymbolicLinkflags, ARRAYLEN(kSymbolicLinkflags), + "kNtSymbolicLinkFlag", x); +} diff --git a/libc/intrin/describepollflags.greg.c b/libc/intrin/describepollflags.greg.c new file mode 100644 index 000000000..c1c868e51 --- /dev/null +++ b/libc/intrin/describepollflags.greg.c @@ -0,0 +1,39 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/sysv/consts/poll.h" + +const char *DescribePollFlags(char *buf, size_t size, int x) { + const struct DescribeFlags kPollFlags[] = { + {POLLIN, "IN"}, // order matters + {POLLOUT, "OUT"}, // order matters + {POLLPRI, "PRI"}, // + {POLLHUP, "HUP"}, // + {POLLERR, "ERR"}, // + {POLLNVAL, "NVAL"}, // + {POLLRDBAND, "RDBAND"}, // + {POLLRDHUP, "RDHUP"}, // + {POLLRDNORM, "RDNORM"}, // + {POLLWRBAND, "WRBAND"}, // + {POLLWRNORM, "WRNORM"}, // + }; + return DescribeFlags(buf, size, kPollFlags, ARRAYLEN(kPollFlags), "POLL", x); +} diff --git a/libc/intrin/describeprotflags.greg.c b/libc/intrin/describeprotflags.greg.c new file mode 100644 index 000000000..ac30ab5fc --- /dev/null +++ b/libc/intrin/describeprotflags.greg.c @@ -0,0 +1,33 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/sysv/consts/prot.h" + +static const struct DescribeFlags kProtFlags[] = { + {PROT_READ, "READ"}, // + {PROT_WRITE, "WRITE"}, // + {PROT_EXEC, "EXEC"}, // +}; + +const char *DescribeProtFlags(int x) { + _Alignas(char) static char protflags[64]; + return DescribeFlags(protflags, sizeof(protflags), kProtFlags, + ARRAYLEN(kProtFlags), "PROT_", x); +} diff --git a/libc/intrin/describeremapflags.greg.c b/libc/intrin/describeremapflags.greg.c new file mode 100644 index 000000000..40ce7219e --- /dev/null +++ b/libc/intrin/describeremapflags.greg.c @@ -0,0 +1,32 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/macros.internal.h" +#include "libc/sysv/consts/mremap.h" + +static const struct DescribeFlags kRemapFlags[] = { + {MREMAP_MAYMOVE, "MAYMOVE"}, // + {MREMAP_FIXED, "FIXED"}, // +}; + +const char *DescribeRemapFlags(int x) { + _Alignas(char) static char remapflags[64]; + return DescribeFlags(remapflags, sizeof(remapflags), kRemapFlags, + ARRAYLEN(kRemapFlags), "MREMAP_", x); +} diff --git a/libc/intrin/deviceiocontrol.greg.c b/libc/intrin/deviceiocontrol.greg.c new file mode 100644 index 000000000..903137913 --- /dev/null +++ b/libc/intrin/deviceiocontrol.greg.c @@ -0,0 +1,47 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/struct/overlapped.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(DeviceIoControl) *const __imp_DeviceIoControl; + +/** + * Does device file stuff on the New Technology. + * + * @return handle, or -1 on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 DeviceIoControl(int64_t hDevice, uint32_t dwIoControlCode, + void *lpInBuffer, uint32_t nInBufferSize, + void *lpOutBuffer, uint32_t nOutBufferSize, + uint32_t *lpBytesReturned, + struct NtOverlapped *lpOverlapped) { + bool32 ok; + ok = __imp_DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, + nInBufferSize, lpOutBuffer, nOutBufferSize, + lpBytesReturned, lpOverlapped); + if (!ok) __winerr(); + NTTRACE("DeviceIoControl(%ld, %#x, %p, %'zu, %p, %'zu, %p, %p) → %hhhd% m", + hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, + nOutBufferSize, lpBytesReturned, lpOverlapped, ok); + return ok; +} diff --git a/libc/intrin/dos2errno.greg.c b/libc/intrin/dos2errno.greg.c new file mode 100644 index 000000000..73c90b8a8 --- /dev/null +++ b/libc/intrin/dos2errno.greg.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 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 "libc/errno.h" +#include "libc/intrin/dos2errno.internal.h" +#include "libc/nt/errors.h" +#include "libc/sock/sock.h" + +/** + * Translates Windows error using superset of consts.sh. + * + * This function is called by __winerr(). It can only be used on + * Windows, because it returns an errno. Normally, errnos will be + * programmed to be the same as DOS errnos, per consts.sh. But since + * there's so many more errors in DOS, this function provides an added + * optional benefit mapping additional constants onto the errnos in + * consts.sh. + */ +privileged errno_t __dos2errno(uint32_t error) { + int i; + if (error) { + for (i = 0; kDos2Errno[i].doscode; ++i) { + if (error == kDos2Errno[i].doscode) { + return *(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv); + } + } + } + return error; +} diff --git a/libc/intrin/dos2errno.internal.h b/libc/intrin/dos2errno.internal.h new file mode 100644 index 000000000..bc02eb705 --- /dev/null +++ b/libc/intrin/dos2errno.internal.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_DOS2ERRNO_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_INTRIN_DOS2ERRNO_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct thatispacked Dos2Errno { + uint16_t doscode; + int32_t systemv; +}; + +extern const struct Dos2Errno kDos2Errno[]; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_DOS2ERRNO_INTERNAL_H_ */ diff --git a/libc/intrin/exit.c b/libc/intrin/exit.c deleted file mode 100644 index 9183d7487..000000000 --- a/libc/intrin/exit.c +++ /dev/null @@ -1,53 +0,0 @@ -/*-*- 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/internal.h" -#include "libc/dce.h" -#include "libc/nexgen32e/vendor.internal.h" -#include "libc/nt/runtime.h" -#include "libc/nt/thunk/msabi.h" -#include "libc/sysv/consts/nr.h" - -extern void(__msabi* __imp_ExitProcess)(uint32_t); - -/** - * Terminates process, ignoring destructors and atexit() handlers. - * - * When running on bare metal, this function will reboot your computer - * by hosing the interrupt descriptors and triple faulting the system. - * - * @param exitcode is masked with 255 - * @asyncsignalsafe - * @vforksafe - * @noreturn - */ -privileged noinstrument noasan noubsan wontreturn void _Exit(int exitcode) { - if ((!IsWindows() && !IsMetal()) || (IsMetal() && IsGenuineCosmo())) { - asm volatile("syscall" - : /* no outputs */ - : "a"(__NR_exit_group), "D"(exitcode) - : "memory"); - } else if (IsWindows()) { - __imp_ExitProcess(exitcode & 0xff); - } - asm("push\t$0\n\t" - "push\t$0\n\t" - "cli\n\t" - "lidt\t(%rsp)"); - for (;;) asm("ud2"); -} diff --git a/libc/intrin/exit.greg.c b/libc/intrin/exit.greg.c new file mode 100644 index 000000000..72d7a637d --- /dev/null +++ b/libc/intrin/exit.greg.c @@ -0,0 +1,55 @@ +/*-*- 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. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#define ShouldUseMsabiAttribute() 1 +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/nexgen32e/vendor.internal.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/nr.h" + +/** + * Terminates process, ignoring destructors and atexit() handlers. + * + * When running on bare metal, this function will reboot your computer + * by hosing the interrupt descriptors and triple faulting the system. + * + * @param exitcode is masked with 255 + * @asyncsignalsafe + * @threadsafe + * @vforksafe + * @noreturn + */ +privileged wontreturn void _Exit(int exitcode) { + int i; + STRACE("_Exit(%d)", exitcode); + if (!IsWindows() && !IsMetal()) { + asm volatile("syscall" + : /* no outputs */ + : "a"(__NR_exit_group), "D"(exitcode) + : "rcx", "r11", "memory"); + } else if (IsWindows()) { + __imp_ExitProcess(exitcode & 0xff); + } + asm("push\t$0\n\t" + "push\t$0\n\t" + "cli\n\t" + "lidt\t(%rsp)"); + for (;;) asm("ud2"); +} diff --git a/libc/intrin/exit1.greg.c b/libc/intrin/exit1.greg.c new file mode 100644 index 000000000..2b20fec0e --- /dev/null +++ b/libc/intrin/exit1.greg.c @@ -0,0 +1,56 @@ +/*-*- 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/bits/weaken.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/intrin/winthread.internal.h" +#include "libc/mem/mem.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thread.h" +#include "libc/sysv/consts/nr.h" + +/** + * Terminates thread with raw system call. + * + * @param rc only works on Linux and Windows + * @see cthread_exit() + * @threadsafe + * @noreturn + */ +privileged wontreturn void _Exit1(int rc) { + struct WinThread *wt; + STRACE("_Exit1(%d)", rc); + if (!IsWindows() && !IsMetal()) { + asm volatile("syscall" + : /* no outputs */ + : "a"(__NR_exit), "D"(IsLinux() ? rc : 0) + : "rcx", "r11", "memory"); + __builtin_unreachable(); + } else if (IsWindows()) { + if ((wt = GetWinThread())) { + __releasefd(wt->pid); + weaken(free)(wt); + } + ExitThread(rc); + } + for (;;) { + asm("ud2"); + } +} diff --git a/libc/intrin/findclose.greg.c b/libc/intrin/findclose.greg.c new file mode 100644 index 000000000..17fe27fe7 --- /dev/null +++ b/libc/intrin/findclose.greg.c @@ -0,0 +1,36 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(FindClose) *const __imp_FindClose; + +/** + * Finds more files in directory. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 FindClose(int64_t hFindFile) { + bool32 ok; + ok = __imp_FindClose(hFindFile); + if (!ok) __winerr(); + NTTRACE("FindClose(%ld) → %hhhd% m", hFindFile, ok); + return ok; +} diff --git a/libc/intrin/findfirstfile.greg.c b/libc/intrin/findfirstfile.greg.c new file mode 100644 index 000000000..76936932d --- /dev/null +++ b/libc/intrin/findfirstfile.greg.c @@ -0,0 +1,52 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/memory.h" +#include "libc/nt/struct/win32finddata.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(FindFirstFile) *const __imp_FindFirstFileW; + +/** + * Finds first file in directory. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows int64_t FindFirstFile(const char16_t *lpFileName, + struct NtWin32FindData *out_lpFindFileData) { + int64_t hFindFile; + hFindFile = __imp_FindFirstFileW(lpFileName, out_lpFindFileData); + if (hFindFile != -1) { + NTTRACE( + "FindFirstFile(%#hs, [{" + ".cFileName=%#hs, " + ".dwFileAttributes=%s, " + ".dwFileType=%s" + "}]) → %ld% m", + lpFileName, out_lpFindFileData->cFileName, + DescribeNtFileFlagsAndAttributes(out_lpFindFileData->dwFileAttributes), + DescribeNtFiletypeFlags(out_lpFindFileData->dwFileType), hFindFile); + } else { + __winerr(); + NTTRACE("FindFirstFile(%#hs, [n/a]) → %ld% m", lpFileName, hFindFile); + } + return hFindFile; +} diff --git a/libc/intrin/findnextfile.greg.c b/libc/intrin/findnextfile.greg.c new file mode 100644 index 000000000..750ea2138 --- /dev/null +++ b/libc/intrin/findnextfile.greg.c @@ -0,0 +1,54 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/errors.h" +#include "libc/nt/files.h" +#include "libc/nt/memory.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/win32finddata.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(FindNextFile) *const __imp_FindNextFileW; + +/** + * Finds more files in directory. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 FindNextFile(int64_t hFindFile, + struct NtWin32FindData *out_lpFindFileData) { + bool32 ok; + ok = __imp_FindNextFileW(hFindFile, out_lpFindFileData); + if (ok) { + NTTRACE( + "FindNextFile(%ld, [{" + ".cFileName=%#hs, " + ".dwFileAttributes=%s, " + ".dwFileType=%s" + "}]) → %hhhd% m", + hFindFile, out_lpFindFileData->cFileName, + DescribeNtFileFlagsAndAttributes(out_lpFindFileData->dwFileAttributes), + DescribeNtFiletypeFlags(out_lpFindFileData->dwFileType), ok); + } else { + if (GetLastError() != kNtErrorNoMoreFiles) __winerr(); + NTTRACE("FindNextFile(%ld) → %hhhd% m", hFindFile, ok); + } + return ok; +} diff --git a/libc/intrin/flushfilebuffers.greg.c b/libc/intrin/flushfilebuffers.greg.c new file mode 100644 index 000000000..e6b4c90e4 --- /dev/null +++ b/libc/intrin/flushfilebuffers.greg.c @@ -0,0 +1,43 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/files.h" + +__msabi extern typeof(FlushFileBuffers) *const __imp_FlushFileBuffers; + +/** + * Flushes buffers of specified file to disk. + * + * This provides a stronger degree of assurance and blocking for things + * to be sent to a physical medium, but it's not guaranteed unless your + * file is opened in a direct non-caching mode. One main advantage here + * seems to be coherency. + * + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + * @note consider buying a ups + * @see FlushViewOfFile() + */ +textwindows bool32 FlushFileBuffers(int64_t hFile) { + bool32 ok; + ok = __imp_FlushFileBuffers(hFile); + if (!ok) __winerr(); + NTTRACE("FlushFileBuffers(%ld) → %hhhd% m", hFile, ok); + return ok; +} diff --git a/libc/intrin/flushviewoffile.greg.c b/libc/intrin/flushviewoffile.greg.c new file mode 100644 index 000000000..e8ad6082c --- /dev/null +++ b/libc/intrin/flushviewoffile.greg.c @@ -0,0 +1,43 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/memory.h" + +__msabi extern typeof(FlushViewOfFile) *const __imp_FlushViewOfFile; + +/** + * Syncs memory created by MapViewOfFileEx(). + * + * This doesn't wait until the pages are written out to the physical + * medium. This doesn't update timestamps or file/dir metadata. + * + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + * @note consider buying a ups + * @see FlushFileBuffers() + */ +textwindows bool32 FlushViewOfFile(const void *lpBaseAddress, + size_t dwNumberOfBytesToFlush) { + bool32 ok; + ok = __imp_FlushViewOfFile(lpBaseAddress, dwNumberOfBytesToFlush); + if (!ok) __winerr(); + NTTRACE("FlushViewOfFile(%p, %'zu) → %hhhd% m", lpBaseAddress, + dwNumberOfBytesToFlush, ok); + return ok; +} diff --git a/libc/runtime/ftrace.c b/libc/intrin/ftrace.c similarity index 100% rename from libc/runtime/ftrace.c rename to libc/intrin/ftrace.c diff --git a/libc/intrin/g_fds.c b/libc/intrin/g_fds.c new file mode 100644 index 000000000..d071e00b0 --- /dev/null +++ b/libc/intrin/g_fds.c @@ -0,0 +1,55 @@ +/*-*- 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 "libc/bits/pushpop.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/runtime.h" +#include "libc/sysv/consts/o.h" + +STATIC_YOINK("_init_g_fds"); + +struct Fds g_fds; +_Alignas(64) char __fds_lock; + +textstartup void InitializeFileDescriptors(void) { + struct Fds *fds; + fds = VEIL("r", &g_fds); + pushmov(&fds->n, ARRAYLEN(fds->__init_p)); + fds->p = fds->__init_p; + if (IsMetal()) { + pushmov(&fds->f, 3ull); + fds->__init_p[0].kind = pushpop(kFdSerial); + fds->__init_p[1].kind = pushpop(kFdSerial); + fds->__init_p[2].kind = pushpop(kFdSerial); + fds->__init_p[0].handle = VEIL("r", 0x3F8ull); + fds->__init_p[1].handle = VEIL("r", 0x3F8ull); + fds->__init_p[2].handle = VEIL("r", 0x3F8ull); + } else if (IsWindows()) { + pushmov(&fds->f, 3ull); + fds->__init_p[0].kind = pushpop(kFdFile); + fds->__init_p[1].kind = pushpop(kFdFile); + fds->__init_p[2].kind = pushpop(kFdFile); + fds->__init_p[0].handle = GetStdHandle(pushpop(kNtStdInputHandle)); + fds->__init_p[1].handle = GetStdHandle(pushpop(kNtStdOutputHandle)); + fds->__init_p[2].handle = GetStdHandle(pushpop(kNtStdErrorHandle)); + } + fds->__init_p[0].flags = O_RDONLY; + fds->__init_p[1].flags = O_WRONLY | O_APPEND; + fds->__init_p[2].flags = O_WRONLY | O_APPEND; +} diff --git a/libc/calls/g_fds_init.S b/libc/intrin/g_fds_init.S similarity index 96% rename from libc/calls/g_fds_init.S rename to libc/intrin/g_fds_init.S index c08c217fc..b444acd84 100644 --- a/libc/calls/g_fds_init.S +++ b/libc/intrin/g_fds_init.S @@ -18,11 +18,10 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" - .init.start 302,_init_g_fds + .init.start 305,_init_g_fds push %rdi push %rsi call InitializeFileDescriptors pop %rsi pop %rdi - .init.end 302,_init_g_fds - .source __FILE__ + .init.end 305,_init_g_fds diff --git a/libc/intrin/generateconsolectrlevent.greg.c b/libc/intrin/generateconsolectrlevent.greg.c new file mode 100644 index 000000000..4617973d2 --- /dev/null +++ b/libc/intrin/generateconsolectrlevent.greg.c @@ -0,0 +1,41 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/console.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(GenerateConsoleCtrlEvent) *const + __imp_GenerateConsoleCtrlEvent; + +/** + * Sends signal to process group that shares console w/ calling process. + * + * @param dwCtrlEvent can be kNtCtrlCEvent or kNtCtrlBreakEvent + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 GenerateConsoleCtrlEvent(uint32_t dwCtrlEvent, + uint32_t dwProcessGroupId) { + bool32 ok; + ok = __imp_GenerateConsoleCtrlEvent(dwCtrlEvent, dwProcessGroupId); + if (!ok) __winerr(); + NTTRACE("GenerateConsoleCtrlEvent(%x, %d) → %hhhd% m", dwCtrlEvent, + dwProcessGroupId, ok); + return ok; +} diff --git a/libc/calls/getenv.c b/libc/intrin/getenv.c similarity index 76% rename from libc/calls/getenv.c rename to libc/intrin/getenv.c index 6d0025cef..107cfb4db 100644 --- a/libc/calls/getenv.c +++ b/libc/intrin/getenv.c @@ -16,18 +16,23 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/libfatal.internal.h" #include "libc/runtime/runtime.h" -#define ToUpper(c) \ - (IsWindows() && (c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c)) +forceinline int Identity(int c) { + return c; +} -/** - * Returns value of environment variable, or NULL if not found. - * - * Environment variables can store empty string on Unix but not Windows. - */ -char *getenv(const char *s) { +forceinline int ToUpper(int c) { + return 'a' <= c && c <= 'z' ? c - ('a' - 'A') : c; +} + +forceinline char *GetEnv(const char *s, int xlat(int)) { char **p; size_t i, j; if ((p = environ)) { @@ -39,7 +44,7 @@ char *getenv(const char *s) { } break; } - if (ToUpper(s[j]) != ToUpper(p[i][j])) { + if (xlat(s[j]) != xlat(p[i][j])) { break; } } @@ -47,3 +52,26 @@ char *getenv(const char *s) { } return 0; } + +/** + * Returns value of environment variable, or NULL if not found. + * + * Environment variables can store empty string on Unix but not Windows. + * + * @note should not be used after __cxa_finalize() is called + */ +char *getenv(const char *s) { + char *r; + if (!IsWindows()) { + r = GetEnv(s, Identity); + } else { + r = GetEnv(s, ToUpper); + } +#if SYSDEBUG + if (!(s[0] == 'T' && s[1] == 'Z' && !s[2])) { + // TODO(jart): memoize TZ or something + STRACE("getenv(%#s) → %#s", s, r); + } +#endif + return r; +} diff --git a/libc/intrin/getexitcodeprocess.greg.c b/libc/intrin/getexitcodeprocess.greg.c new file mode 100644 index 000000000..9fd02ea1e --- /dev/null +++ b/libc/intrin/getexitcodeprocess.greg.c @@ -0,0 +1,36 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/accounting.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(GetExitCodeProcess) *const __imp_GetExitCodeProcess; + +/** + * Obtains exit code for process. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows int32_t GetExitCodeProcess(int64_t hProcess, uint32_t *lpExitCode) { + int32_t rc; + rc = __imp_GetExitCodeProcess(hProcess, lpExitCode); + if (!rc) __winerr(); + NTTRACE("GetExitCodeProcess(%ld, [%u]) → %u% m", hProcess, *lpExitCode, rc); + return rc; +} diff --git a/libc/intrin/getfileattributes.greg.c b/libc/intrin/getfileattributes.greg.c new file mode 100644 index 000000000..c7dcc4c00 --- /dev/null +++ b/libc/intrin/getfileattributes.greg.c @@ -0,0 +1,41 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/files.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW; + +/** + * Gets file info on the New Technology. + * + * @return handle, or -1u on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows uint32_t GetFileAttributes(const char16_t *lpPathName) { + uint32_t flags; + flags = __imp_GetFileAttributesW(lpPathName); + if (flags == -1u) __winerr(); + NTTRACE("GetFileAttributes(%#hs) → %s% m", lpPathName, + DescribeNtFileFlagsAndAttributes(flags)); + return flags; +} diff --git a/libc/intrin/getmagnumstr.greg.c b/libc/intrin/getmagnumstr.greg.c new file mode 100644 index 000000000..20834e936 --- /dev/null +++ b/libc/intrin/getmagnumstr.greg.c @@ -0,0 +1,29 @@ +/*-*- 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 2022 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/fmt/magnumstrs.internal.h" + +char *GetMagnumStr(const struct MagnumStr *ms, int x) { + int i; + for (i = 0; ms[i].x != MAGNUM_TERMINATOR; ++i) { + if (x == MAGNUM_NUMBER(ms, i)) { + return MAGNUM_STRING(ms, i); + } + } + return 0; +} diff --git a/libc/calls/getpid.c b/libc/intrin/getpid.c similarity index 78% rename from libc/calls/getpid.c rename to libc/intrin/getpid.c index 5db92d62d..0d8113aed 100644 --- a/libc/calls/getpid.c +++ b/libc/intrin/getpid.c @@ -16,27 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/dce.h" -#include "libc/nt/process.h" -#include "libc/runtime/runtime.h" - -static int __pid; - -static int __getpid(void) { - if (!IsWindows()) { - return sys_getpid().ax; - } else { - return GetCurrentProcessId(); - } -} - -static void __updatepid(void) { - __pid = __getpid(); -} +#include "libc/runtime/internal.h" /** * Returns process id. @@ -44,15 +26,11 @@ static void __updatepid(void) { * @vforksafe */ int getpid(void) { - static bool once; - if (__vforked) { - return sys_getpid().ax; + int rc; + if (!__vforked) { + rc = __pid; + } else { + rc = sys_getpid().ax; } - if (!once) { - __updatepid(); - if (cmpxchg(&once, false, true)) { - atfork(__updatepid, NULL); - } - } - return __pid; + return rc; } diff --git a/libc/intrin/gettid.greg.c b/libc/intrin/gettid.greg.c new file mode 100644 index 000000000..4a8f92703 --- /dev/null +++ b/libc/intrin/gettid.greg.c @@ -0,0 +1,85 @@ +/*-*- 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 "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/intrin/tls.h" +#include "libc/intrin/winthread.internal.h" +#include "libc/nt/thread.h" + +/** + * Returns current thread id. + * @asyncsignalsafe + */ +int gettid(void) { + int rc; + int64_t wut; + struct WinThread *wt; + + if (IsLinux()) { + asm("syscall" + : "=a"(rc) // man says always succeeds + : "0"(186) // __NR_gettid + : "rcx", "r11", "memory"); + return rc; + } + + if (IsXnu()) { + asm("syscall" // xnu/osfmk/kern/ipc_tt.c + : "=a"(rc) // assume success + : "0"(0x1000000 | 27) // Mach thread_self_trap() + : "rcx", "r11", "memory", "cc"); + return rc; + } + + if (IsOpenbsd()) { + asm("syscall" + : "=a"(rc) // man says always succeeds + : "0"(299) // getthrid() + : "rcx", "r11", "memory", "cc"); + return rc; + } + + if (IsNetbsd()) { + asm("syscall" + : "=a"(rc) // man says always succeeds + : "0"(311) // _lwp_self() + : "rcx", "r11", "memory", "cc"); + return rc; + } + + if (IsFreebsd()) { + asm("syscall" + : "=a"(rc), // only fails w/ EFAULT, which isn't possible + "=m"(wut) // must be 64-bit + : "0"(432), // thr_self() + "D"(&wut) // but not actually 64-bit + : "rcx", "r11", "memory", "cc"); + return wut; // narrowing intentional + } + + if (IsWindows()) { + if ((wt = GetWinThread())) { + return wt->pid; + } else { + return GetCurrentThreadId(); + } + } + + return getpid(); +} diff --git a/libc/intrin/intrin.mk b/libc/intrin/intrin.mk index 2686b4db4..02b18b99b 100644 --- a/libc/intrin/intrin.mk +++ b/libc/intrin/intrin.mk @@ -26,6 +26,7 @@ LIBC_INTRIN_A_CHECKS = \ LIBC_INTRIN_A_DIRECTDEPS = \ LIBC_STUBS \ LIBC_SYSV \ + LIBC_SYSV_CALLS \ LIBC_NEXGEN32E \ LIBC_NT_KERNEL32 @@ -57,16 +58,58 @@ o/$(MODE)/libc/intrin/asan.o: \ -finline \ -finline-functions +o/$(MODE)/libc/intrin/kprintf.greg.o: \ + OVERRIDE_CFLAGS += \ + -fpie \ + -ffreestanding \ + $(NO_MAGIC) + +o/$(MODE)/libc/intrin/tls.greg.o \ +o/$(MODE)/libc/intrin/exit.greg.o \ +o/$(MODE)/libc/intrin/exit1.greg.o \ +o/$(MODE)/libc/intrin/gettid.greg.o \ +o/$(MODE)/libc/intrin/createfile.greg.o \ +o/$(MODE)/libc/intrin/reopenfile.greg.o \ +o/$(MODE)/libc/intrin/deletefile.greg.o \ +o/$(MODE)/libc/intrin/createpipe.greg.o \ +o/$(MODE)/libc/intrin/closehandle.greg.o \ +o/$(MODE)/libc/intrin/openprocess.greg.o \ +o/$(MODE)/libc/intrin/createthread.greg.o \ +o/$(MODE)/libc/intrin/findnextfile.greg.o \ +o/$(MODE)/libc/intrin/createprocess.greg.o \ +o/$(MODE)/libc/intrin/findfirstfile.greg.o \ +o/$(MODE)/libc/intrin/describeflags.greg.o \ +o/$(MODE)/libc/intrin/removedirectory.greg.o \ +o/$(MODE)/libc/intrin/createnamedpipe.greg.o \ +o/$(MODE)/libc/intrin/unmapviewoffile.greg.o \ +o/$(MODE)/libc/intrin/flushviewoffile.greg.o \ +o/$(MODE)/libc/intrin/deviceiocontrol.greg.o \ +o/$(MODE)/libc/intrin/createdirectory.greg.o \ +o/$(MODE)/libc/intrin/flushfilebuffers.greg.o \ +o/$(MODE)/libc/intrin/terminateprocess.greg.o \ +o/$(MODE)/libc/intrin/describemapflags.greg.o \ +o/$(MODE)/libc/intrin/getfileattributes.greg.o \ +o/$(MODE)/libc/intrin/getexitcodeprocess.greg.o \ +o/$(MODE)/libc/intrin/waitforsingleobject.greg.o \ +o/$(MODE)/libc/intrin/setcurrentdirectory.greg.o \ +o/$(MODE)/libc/intrin/mapviewoffileexnuma.greg.o \ +o/$(MODE)/libc/intrin/createfilemappingnuma.greg.o \ +o/$(MODE)/libc/intrin/waitformultipleobjects.greg.o \ +o/$(MODE)/libc/intrin/generateconsolectrlevent.greg.o \ +o/$(MODE)/libc/intrin/kstarttsc.o \ +o/$(MODE)/libc/intrin/nomultics.o \ +o/$(MODE)/libc/intrin/ntconsolemode.o: \ + OVERRIDE_CFLAGS += \ + -Os \ + -ffreestanding \ + $(NO_MAGIC) + o/$(MODE)/libc/intrin/asan.o \ o/$(MODE)/libc/intrin/ubsan.o: \ OVERRIDE_CFLAGS += \ -fno-sanitize=all \ -fno-stack-protector -o/$(MODE)/libc/intrin/memcmp.o: \ - OVERRIDE_CFLAGS += \ - -Os - o//libc/intrin/memmove.o: \ OVERRIDE_CFLAGS += \ -fno-toplevel-reorder @@ -76,7 +119,7 @@ o//libc/intrin/memcmp.o \ o//libc/intrin/memset.o \ o//libc/intrin/memmove.o: \ OVERRIDE_CFLAGS += \ - -O3 + -O2 -finline o/$(MODE)/libc/intrin/bzero.o \ o/$(MODE)/libc/intrin/memcmp.o \ @@ -84,18 +127,11 @@ o/$(MODE)/libc/intrin/memmove.o: \ OVERRIDE_CFLAGS += \ -fpie -o/$(MODE)/libc/intrin/printf.o: \ - OVERRIDE_CFLAGS += \ - -Os \ - -fpie \ - -mgeneral-regs-only - LIBC_INTRIN_LIBS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x))) LIBC_INTRIN_HDRS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_HDRS)) LIBC_INTRIN_SRCS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_SRCS)) LIBC_INTRIN_CHECKS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_CHECKS)) LIBC_INTRIN_OBJS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_OBJS)) -LIBC_INTRIN_CHECKS = $(LIBC_INTRIN_HDRS:%=o/$(MODE)/%.ok) $(LIBC_INTRIN_OBJS): $(BUILD_FILES) libc/intrin/intrin.mk .PHONY: o/$(MODE)/libc/intrin diff --git a/libc/intrin/isatleastwindows10.greg.c b/libc/intrin/isatleastwindows10.greg.c new file mode 100644 index 000000000..100098058 --- /dev/null +++ b/libc/intrin/isatleastwindows10.greg.c @@ -0,0 +1,32 @@ +/*-*- 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/assert.h" +#include "libc/dce.h" +#include "libc/nt/enum/version.h" +#include "libc/nt/version.h" + +/** + * Returns true if we're running at least Windows 10. + * + * This function may only be called if IsWindows() is true. + */ +privileged bool(IsAtLeastWindows10)(void) { + assert(IsWindows()); + return IsAtLeastWindows10(); +} diff --git a/libc/intrin/isdebuggerpresent.c b/libc/intrin/isdebuggerpresent.c deleted file mode 100644 index 772236469..000000000 --- a/libc/intrin/isdebuggerpresent.c +++ /dev/null @@ -1,58 +0,0 @@ -/*-*- 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 "libc/dce.h" -#include "libc/log/libfatal.internal.h" -#include "libc/log/log.h" -#include "libc/nexgen32e/vendor.internal.h" -#include "libc/nt/struct/teb.h" -#include "libc/sysv/consts/o.h" - -#define kBufSize 1024 -#define kPid "TracerPid:\t" - -/** - * Determines if gdb, strace, windbg, etc. is controlling process. - * @return non-zero if attached, otherwise 0 - */ -noasan noubsan int IsDebuggerPresent(bool force) { - /* asan runtime depends on this function */ - int fd, res; - ssize_t got; - char *p, buf[1024]; - if (!force) { - if (IsGenuineCosmo()) return 0; - if (__getenv(__envp, "HEISENDEBUG")) return 0; - } - if (IsWindows()) { - return NtGetPeb()->BeingDebugged; /* needs noasan */ - } else { - res = 0; - if ((fd = __sysv_open("/proc/self/status", O_RDONLY, 0)) >= 0) { - if ((got = __sysv_read(fd, buf, sizeof(buf) - 1)) > 0) { - buf[got] = '\0'; - if ((p = __strstr(buf, kPid))) { - p += sizeof(kPid) - 1; - res = __atoul(p); - } - } - __sysv_close(fd); - } - return res; - } -} diff --git a/libc/intrin/isdebuggerpresent.greg.c b/libc/intrin/isdebuggerpresent.greg.c new file mode 100644 index 000000000..4332ae24c --- /dev/null +++ b/libc/intrin/isdebuggerpresent.greg.c @@ -0,0 +1,54 @@ +/*-*- 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 "libc/dce.h" +#include "libc/log/libfatal.internal.h" +#include "libc/log/log.h" +#include "libc/nexgen32e/vendor.internal.h" +#include "libc/nt/struct/teb.h" +#include "libc/sysv/consts/o.h" + +#define kBufSize 1024 +#define kPid "TracerPid:\t" + +/** + * Determines if gdb, strace, windbg, etc. is controlling process. + * @return non-zero if attached, otherwise 0 + */ +noasan noubsan int IsDebuggerPresent(bool force) { + /* asan runtime depends on this function */ + int fd, res; + ssize_t got; + char *p, buf[1024]; + if (!force && IsGenuineCosmo()) return 0; + if (!force && getenv("HEISENDEBUG")) return 0; + if (IsWindows()) return NtGetPeb()->BeingDebugged; /* needs noasan */ + if (__isworker) return false; + res = 0; + if ((fd = __sysv_open("/proc/self/status", O_RDONLY, 0)) >= 0) { + if ((got = __sysv_read(fd, buf, sizeof(buf) - 1)) > 0) { + buf[got] = '\0'; + if ((p = __strstr(buf, kPid))) { + p += sizeof(kPid) - 1; + res = __atoul(p); + } + } + __sysv_close(fd); + } + return res; +} diff --git a/libc/intrin/isrunningundermake.c b/libc/intrin/isrunningundermake.c index 9d94b59a2..b6744cf11 100644 --- a/libc/intrin/isrunningundermake.c +++ b/libc/intrin/isrunningundermake.c @@ -30,9 +30,8 @@ bool IsRunningUnderMake(void) { return g_isrunningundermake; } -textstartup void g_isrunningundermake_init(int argc, char **argv, char **envp, - intptr_t *auxv) { - g_isrunningundermake = !!__getenv(envp, "MAKEFLAGS"); +textstartup void g_isrunningundermake_init(void) { + g_isrunningundermake = !!getenv("MAKEFLAGS"); } const void *const g_isrunningundermake_ctor[] initarray = { diff --git a/libc/intrin/isterminalinarticulate.c b/libc/intrin/isterminalinarticulate.c deleted file mode 100644 index 9ee478299..000000000 --- a/libc/intrin/isterminalinarticulate.c +++ /dev/null @@ -1,46 +0,0 @@ -/*-*- 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 "libc/bits/safemacros.internal.h" -#include "libc/log/internal.h" -#include "libc/log/libfatal.internal.h" -#include "libc/log/log.h" -#include "libc/nt/enum/version.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" - -bool g_isterminalinarticulate; - -bool IsTerminalInarticulate(void) { - return g_isterminalinarticulate; -} - -textstartup noasan void g_isterminalinarticulate_init(int argc, char **argv, - char **envp, - intptr_t *auxv) { - char *s; - if (IsWindows() && NtGetVersion() < kNtVersionWindows10) { - g_isterminalinarticulate = true; - } else if ((s = __getenv(envp, "TERM"))) { - g_isterminalinarticulate = !__strcmp(s, "dumb"); - } -} - -const void *const g_isterminalinarticulate_ctor[] initarray = { - g_isterminalinarticulate_init, -}; diff --git a/libc/intrin/isworker.c b/libc/intrin/isworker.c new file mode 100644 index 000000000..a2913c1e6 --- /dev/null +++ b/libc/intrin/isworker.c @@ -0,0 +1,28 @@ +/*-*- 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 2022 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" + +/** + * Indicates if current execution context is a worker task. + * + * Setting this to true on things like the forked process of a web + * server is a good idea since it'll ask the C runtime to not pull + * magical stunts like attaching GDB to the process on crash. + */ +bool __isworker; diff --git a/libc/intrin/kdos2errno.S b/libc/intrin/kdos2errno.S new file mode 100644 index 000000000..f09390e7f --- /dev/null +++ b/libc/intrin/kdos2errno.S @@ -0,0 +1,174 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/nt/errors.h" +#include "libc/nt/errors.h" +#include "libc/macros.internal.h" + +// @fileoverview data structure for __dos2errno() + + .macro .e doscode systemv + .short \doscode + .long \systemv - kDos2Errno + .endm + + .section .rodata + .underrun +kDos2Errno: +// .e kNtErrorInvalidFunction,ENOSYS # in consts.sh +// .e kNtErrorFileNotFound,ENOENT # in consts.sh +// .e kNtErrorPathNotFound,ENOTDIR # in consts.sh +// .e kNtErrorTooManyOpenFiles,EMFILE # in consts.sh +// .e kNtErrorTooManyDescriptors,ENFILE # in consts.sh +// .e kNtErrorTooManyLinks,EMLINK # in consts.sh +// .e kNtErrorAccessDenied,EACCES # in consts.sh +// .e kNtErrorInvalidHandle,EBADF # in consts.sh +// .e kNtErrorInvalidAccess,EPERM # in consts.sh +// .e kNtErrorNotEnoughQuota,EDQUOT # in consts.sh +// .e kNtErrorSeek,ESPIPE # in consts.sh +// .e kNtErrorNotDosDisk,ENOTBLK # in consts.sh +// .e kNtErrorFileExists,EEXIST # in consts.sh +// .e kNtErrorInvalidParameter,EINVAL # in consts.sh +// .e kNtErrorOutofmemory,ENOMEM # in consts.sh +// .e kNtErrorBrokenPipe,EPIPE # in consts.sh +// .e kNtErrorWaitNoChildren,ECHILD # in consts.sh +// .e kNtErrorPathBusy,ETXTBSY # in consts.sh +// .e kNtErrorBusy,EBUSY # in consts.sh +// .e kNtErrorAlreadyExists,EEXIST # in consts.sh +// .e kNtErrorBadExeFormat,ENOEXEC # in consts.sh +// .e kNtErrorFileTooLarge,EFBIG # in consts.sh +// .e kNtErrorDirectoryNotSupported,EISDIR # in consts.sh +// .e kNtErrorInvalidAddress,EFAULT # in consts.sh +// .e kNtErrorThreadNotInProcess,ESRCH # in consts.sh +// .e kNtErrorNoMediaInDrive,ENXIO # in consts.sh +// .e kNtErrorIoDevice,EIO # in consts.sh +// .e kNtErrorSerialNoDevice,ENOTTY # in consts.sh +// .e kNtErrorPossibleDeadlock,EDEADLK # in consts.sh +// .e kNtErrorBadDevice,ENODEV # in consts.sh +// .e kNtErrorInvalidCommandLine,E2BIG # in consts.sh +// .e kNtErrorFileReadOnly,EROFS # in consts.sh +// .e kNtErrorNoData,ENODATA # in consts.sh +// .e WSAEPROCLIM,EPROCLIM # in consts.sh +// .e WSAESHUTDOWN,ESHUTDOWN # in consts.sh +// .e WSAEINPROGRESS,EINPROGRESS # in consts.sh +// .e WSAENETDOWN,ENETDOWN # in consts.sh +// .e WSAENETUNREACH,ENETUNREACH # in consts.sh +// .e WSAENETRESET,ENETRESET # in consts.sh +// .e WSAEUSERS,EUSERS # in consts.sh +// .e WSAENOTSOCK,ENOTSOCK # in consts.sh +// .e WSAEDESTADDRREQ,EDESTADDRREQ # in consts.sh +// .e WSAEMSGSIZE,EMSGSIZE # in consts.sh +// .e WSAEPROTOTYPE,EPROTOTYPE # in consts.sh +// .e WSAENOPROTOOPT,ENOPROTOOPT # in consts.sh +// .e WSAEPROTONOSUPPORT,EPROTONOSUPPORT # in consts.sh +// .e WSAESOCKTNOSUPPORT,ESOCKTNOSUPPORT # in consts.sh +// .e WSAEOPNOTSUPP,ENOTSUP # in consts.sh +// .e WSAEOPNOTSUPP,EOPNOTSUPP # in consts.sh +// .e WSAEPFNOSUPPORT,EPFNOSUPPORT # in consts.sh +// .e WSAEAFNOSUPPORT,EAFNOSUPPORT # in consts.sh +// .e WSAEADDRINUSE,EADDRINUSE # in consts.sh +// .e WSAEADDRNOTAVAIL,EADDRNOTAVAIL # in consts.sh +// .e WSAECONNABORTED,ECONNABORTED # in consts.sh +// .e WSAECONNRESET,ECONNRESET # in consts.sh +// .e WSAENOBUFS,ENOBUFS # in consts.sh +// .e WSAEISCONN,EISCONN # in consts.sh +// .e WSAENOTCONN,ENOTCONN # in consts.sh +// .e WSAESHUTDOWN,ESHUTDOWN # in consts.sh +// .e WSAETOOMANYREFS,ETOOMANYREFS # in consts.sh +// .e WSAETIMEDOUT,ETIMEDOUT # in consts.sh +// .e WSAECONNREFUSED,ECONNREFUSED # in consts.sh +// .e WSAEHOSTDOWN,EHOSTDOWN # in consts.sh +// .e WSAEHOSTUNREACH,EHOSTUNREACH # in consts.sh +// .e WSAEALREADY,EALREADY # in consts.sh +// .e WSAESTALE,ESTALE # in consts.sh +// .e WSAEREMOTE,EREMOTE # in consts.sh +// .e WSAEINTR,EINTR # in consts.sh + .e kNtErrorModNotFound,ENOSYS + .e kNtErrorBadCommand,EACCES + .e kNtErrorBadLength,EACCES + .e kNtErrorBadNetpath,ENOENT + .e kNtErrorBadNetName,ENOENT + .e kNtErrorBadPathname,ENOENT + .e kNtErrorBadNetResp,ENETDOWN + .e kNtErrorFileExists,EEXIST + .e kNtErrorCannotMake,EACCES + .e kNtErrorCommitmentLimit,ENOMEM + .e kNtErrorConnectionAborted,ECONNABORTED + .e kNtErrorConnectionActive,EISCONN + .e kNtErrorConnectionRefused,ECONNREFUSED + .e kNtErrorCrc,EACCES + .e kNtErrorDirNotEmpty,ENOTEMPTY + .e kNtErrorDupName,EADDRINUSE + .e kNtErrorFilenameExcedRange,ENAMETOOLONG + .e kNtErrorGenFailure,EACCES + .e kNtErrorGracefulDisconnect,EPIPE + .e kNtErrorHostDown,EHOSTUNREACH + .e kNtErrorHostUnreachable,EHOSTUNREACH + .e kNtErrorInsufficientBuffer,EFAULT + .e kNtErrorNoaccess,EFAULT + .e kNtErrorInvalidAddress,EADDRNOTAVAIL + .e kNtErrorNotAReparsePoint,EINVAL + .e kNtErrorInvalidFunction,EINVAL + .e kNtErrorInvalidNetname,EADDRNOTAVAIL + .e kNtErrorInvalidUserBuffer,EMSGSIZE + .e kNtErrorIoPending,EINPROGRESS + .e kNtErrorLockViolation,EACCES + .e kNtErrorMoreData,EMSGSIZE + .e kNtErrorNetnameDeleted,ECONNABORTED + .e kNtErrorNetworkAccessDenied,EACCES + .e kNtErrorNetworkBusy,ENETDOWN + .e kNtErrorNetworkUnreachable,ENETUNREACH + .e kNtErrorNonpagedSystemResources,ENOMEM + .e kNtErrorNotEnoughMemory,ENOMEM + .e kNtErrorNotEnoughQuota,ENOMEM + .e kNtErrorNotFound,ENOENT + .e kNtErrorNotLocked,EACCES + .e kNtErrorNotReady,EACCES + .e kNtErrorNotSupported,ENOTSUP + .e kNtErrorNoMoreFiles,ENOENT + .e kNtErrorNoSystemResources,ENOMEM + .e kNtErrorOperationAborted,EINTR + .e kNtErrorOutOfPaper,EACCES + .e kNtErrorPagedSystemResources,ENOMEM + .e kNtErrorPagefileQuota,ENOMEM + .e kNtErrorPipeNotConnected,EPIPE + .e kNtErrorPortUnreachable,ECONNRESET + .e kNtErrorProtocolUnreachable,ENETUNREACH + .e kNtErrorRemNotList,ECONNREFUSED + .e kNtErrorRequestAborted,EINTR + .e kNtErrorReqNotAccep,EWOULDBLOCK + .e kNtErrorSectorNotFound,EACCES + .e kNtErrorSemTimeout,ETIMEDOUT + .e kNtErrorSharingViolation,EACCES + .e kNtErrorTooManyNames,ENOMEM + .e kNtErrorUnexpNetErr,ECONNABORTED + .e kNtErrorWorkingSetQuota,ENOMEM + .e kNtErrorWriteProtect,EACCES + .e kNtErrorWrongDisk,EACCES + .e WSAEACCES,EACCES + .e WSAEDISCON,EPIPE + .e WSAEFAULT,EFAULT + .e WSAEINVAL,EINVAL + .e WSAEDQUOT,EDQUOT + .e WSAEPROCLIM,ENOMEM + .e WSANOTINITIALISED,ENETDOWN + .e WSASYSNOTREADY,ENETDOWN + .e WSAVERNOTSUPPORTED,ENOSYS + .short 0 + .endobj kDos2Errno,globl,hidden + .overrun diff --git a/libc/intrin/kntisinheritable.greg.c b/libc/intrin/kntisinheritable.greg.c new file mode 100644 index 000000000..e4c19ceb6 --- /dev/null +++ b/libc/intrin/kntisinheritable.greg.c @@ -0,0 +1,25 @@ +/*-*- 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 2022 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/nt/struct/securityattributes.h" + +hidden const struct NtSecurityAttributes kNtIsInheritable = { + sizeof(struct NtSecurityAttributes), + NULL, + true, +}; diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c new file mode 100644 index 000000000..9595606ae --- /dev/null +++ b/libc/intrin/kprintf.greg.c @@ -0,0 +1,932 @@ +/*-*- 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. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#define ShouldUseMsabiAttribute() 1 +#include "libc/bits/likely.h" +#include "libc/bits/safemacros.internal.h" +#include "libc/bits/weaken.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/fmt/divmod10.internal.h" +#include "libc/fmt/fmt.h" +#include "libc/intrin/cmpxchg.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/lockcmpxchg.h" +#include "libc/intrin/nomultics.internal.h" +#include "libc/intrin/spinlock.h" +#include "libc/limits.h" +#include "libc/log/internal.h" +#include "libc/macros.internal.h" +#include "libc/nexgen32e/rdtsc.h" +#include "libc/nexgen32e/uart.internal.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/nt/winsock.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.internal.h" +#include "libc/str/str.h" +#include "libc/str/tpenc.h" +#include "libc/str/utf16.h" +#include "libc/sysv/consts/nr.h" +#include "libc/sysv/consts/prot.h" +#include "libc/time/clockstonanos.internal.h" + +struct Timestamps { + unsigned long long birth; + unsigned long long start; +}; + +extern bool __threaded; +unsigned long long __kbirth; // see fork-nt.c + +privileged static struct Timestamps kenter(void) { + struct Timestamps ts; + ts.start = rdtsc(); + ts.birth = __kbirth; + if (!ts.birth) { + ts.birth = kStartTsc; + if (!ts.birth) ts.birth = 1; + _lockcmpxchg(&__kbirth, 0, ts.birth); + } + return ts; +} + +privileged static void kleave(struct Timestamps ts) { + uint64_t finish, elapse, adjust; + finish = rdtsc(); + elapse = unsignedsubtract(finish, ts.start); + adjust = ts.birth + elapse; + if (!adjust) adjust = 1; + if (__kbirth == ts.birth) { + _lockcmpxchg(&__kbirth, ts.birth, adjust); // ignore overlapping intervals + } +} + +privileged static inline char *kadvance(char *p, char *e, long n) { + intptr_t t = (intptr_t)p; + if (__builtin_add_overflow(t, n, &t)) t = (intptr_t)e; + return (char *)t; +} + +privileged static char *kemitquote(char *p, char *e, signed char t, + unsigned c) { + if (t) { + if (p < e) { + *p = t < 0 ? 'u' : 'L'; + } + ++p; + } + if (p < e) { + *p = c; + } + ++p; + return p; +} + +privileged static unsigned long long kgetint(va_list va, signed char t, + bool s) { +#ifdef __LP64__ + int bits; + unsigned long long x; + x = va_arg(va, unsigned long); + if (t <= 0) { + bits = 64 - (32 >> MIN(5, -t)); + x <<= bits; + if (s) { + x = (signed long)x >> bits; + } else { + x >>= bits; + } + } + return x; +#else + if (s) { + switch (t) { + case -2: + return (signed char)va_arg(va, int); + case -1: + return (signed short)va_arg(va, int); + default: + return va_arg(va, signed int); + case 1: + return va_arg(va, signed long); + case 2: + return va_arg(va, signed long long); + } + } else { + switch (t) { + case -2: + return (unsigned char)va_arg(va, int); + case -1: + return (unsigned short)va_arg(va, int); + default: + return va_arg(va, unsigned int); + case 1: + return va_arg(va, unsigned long); + case 2: + return va_arg(va, unsigned long long); + } + } +#endif +} + +privileged static inline bool kiskernelpointer(const void *p) { + return 0x7f0000000000 <= (intptr_t)p && (intptr_t)p < 0x800000000000; +} + +privileged static inline bool kistextpointer(const void *p) { + return _base <= (const unsigned char *)p && (const unsigned char *)p < _etext; +} + +privileged static inline bool kisimagepointer(const void *p) { + return _base <= (const unsigned char *)p && (const unsigned char *)p < _end; +} + +privileged static inline bool kischarmisaligned(const char *p, signed char t) { + if (t == -1) return (intptr_t)p & 1; + if (t >= 1) return !!((intptr_t)p & 3); + return false; +} + +privileged static inline bool kismemtrackhosed(void) { + return !((weaken(_mmi)->i <= weaken(_mmi)->n) && + (weaken(_mmi)->p == weaken(_mmi)->s || + weaken(_mmi)->p == (struct MemoryInterval *)kMemtrackStart)); +} + +privileged static bool kismapped(int x) { + // xxx: we can't lock because no reentrant locks yet + size_t m, r, l = 0; + if (!weaken(_mmi)) return true; + if (kismemtrackhosed()) return false; + r = weaken(_mmi)->i; + while (l < r) { + m = (l + r) >> 1; + if (weaken(_mmi)->p[m].y < x) { + l = m + 1; + } else { + r = m; + } + } + if (l < weaken(_mmi)->i && x >= weaken(_mmi)->p[l].x) { + return !!(weaken(_mmi)->p[l].prot & PROT_READ); + } else { + return false; + } +} + +privileged bool kisdangerous(const void *p) { + int frame; + if (kisimagepointer(p)) return false; + if (kiskernelpointer(p)) return false; + if (IsLegalPointer(p)) { + frame = (intptr_t)p >> 16; + if (IsStackFrame(frame)) return false; + if (IsOldStackFrame(frame)) return false; + if (kismapped(frame)) return false; + } + return true; +} + +privileged static void klog(const char *b, size_t n) { + int e; + size_t i; + uint16_t dx; + uint32_t wrote; + unsigned char al; + long rax, rdi, rsi, rdx; + if (IsWindows()) { + e = __imp_GetLastError(); + __imp_WriteFile(__imp_GetStdHandle(kNtStdErrorHandle), b, n, &wrote, 0); + __imp_SetLastError(e); + } else if (IsMetal()) { + for (i = 0; i < n; ++i) { + for (;;) { + dx = 0x3F8 + UART_LSR; + asm("inb\t%1,%0" : "=a"(al) : "dN"(dx)); + if (al & UART_TTYTXR) break; + asm("pause"); + } + dx = 0x3F8; + asm volatile("outb\t%0,%1" + : /* no inputs */ + : "a"(b[i]), "dN"(dx)); + } + } else { + asm volatile("syscall" + : "=a"(rax), "=D"(rdi), "=S"(rsi), "=d"(rdx) + : "0"(__NR_write), "1"(2), "2"(b), "3"(n) + : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"); + } +} + +privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va, + struct Timestamps ts) { + int si; + wint_t t, u; + const char *abet; + signed char type; + const char *s, *f; + unsigned long long x; + unsigned i, j, m, rem, sign, hash, cols, prec; + char c, *p, *e, pdot, zero, flip, dang, base, quot, uppr, z[128]; + if (kistextpointer(b) || kisdangerous(b)) n = 0; + if (!kistextpointer(fmt)) fmt = "!!WONTFMT"; + p = b; + f = fmt; + e = p + n; + for (;;) { + for (;;) { + if (!(c = *f++) || c == '%') break; + EmitFormatByte: + if (p < e) *p = c; + ++p; + } + if (!c) break; + pdot = 0; + flip = 0; + dang = 0; + hash = 0; + sign = 0; + prec = 0; + quot = 0; + type = 0; + cols = 0; + zero = 0; + uppr = 0; + abet = "0123456789abcdef"; + for (;;) { + switch ((c = *f++)) { + default: + goto EmitFormatByte; + + case '\0': + break; + + case '.': + pdot = 1; + continue; + + case '-': + flip = 1; + continue; + + case '#': + hash = '0'; + continue; + + case '_': + case ',': + case '\'': + quot = c; + continue; + + case ' ': + case '+': + sign = c; + continue; + + case '^': + uppr = c; + continue; + + case 'h': + --type; + continue; + + case 'j': + case 'l': + case 'z': + ++type; + continue; + + case '!': + dang = 1; + continue; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + si = pdot ? prec : cols; + si *= 10; + si += c - '0'; + goto UpdateCols; + + case '*': + si = va_arg(va, int); + UpdateCols: + if (pdot) { + if (si >= 0) { + prec = si; + } + } else { + if (si < 0) { + flip = 1; + si = -si; + } + cols = si; + if (!cols) { + zero = 1; + } + } + continue; + + case 'T': + x = ClocksToNanos(ts.start, ts.birth) % 86400000000000; + goto FormatUnsigned; + + case 'P': + if (!__vforked) { + if (!__threaded) { + x = __pid; + } else { + // clone() is linked and it yoinks gettid() + x = weaken(gettid)(); + } + } else { + asm volatile("syscall" + : "=a"(x) + : "0"(__NR_getpid) + : "rcx", "rdx", "r11", "memory", "cc"); + } + goto FormatUnsigned; + + case 'u': + case 'd': + if (UNLIKELY(type <= -3)) { + s = va_arg(va, int) ? "true" : "false"; + goto FormatString; + } + x = kgetint(va, type, c == 'd'); + FormatDecimal: + if ((long long)x < 0 && c != 'u') { + x = -x; + sign = '-'; + } + FormatUnsigned: + if (x && hash) sign = hash; + for (i = j = 0;;) { + x = DivMod10(x, &rem); + z[i++ & 127] = '0' + rem; + if (pdot ? i >= prec : !x) break; + if (quot && ++j == 3) { + z[i++ & 127] = quot; + j = 0; + } + } + EmitNumber: + if (flip || pdot) zero = 0; + while (zero && sign) { + if (p < e) *p = sign; + if (cols) --cols; + sign >>= 8; + ++p; + } + t = !!sign + !!(sign >> 8); + if (!flip && cols >= t) { + for (j = i; j < cols - t; ++j) { + if (p < e) { + *p++ = zero ? '0' : ' '; + } else { + p = kadvance(p, e, cols - t - j); + break; + } + } + } + while (sign) { + if (p < e) *p = sign; + sign >>= 8; + ++p; + } + for (j = i; j; ++p) { + --j; + if (p < e) { + *p = z[j & 127]; + } + } + if (flip && cols >= t) { + for (j = i; j < cols - t; ++j) { + if (p < e) { + *p++ = ' '; + } else { + p = kadvance(p, e, cols - t - j); + break; + } + } + } + break; + + case 'b': + base = 1; + if (hash) hash = '0' | 'b' << 8; + BinaryNumber: + x = kgetint(va, type, false); + FormatNumber: + i = 0; + m = (1 << base) - 1; + if (hash && x) sign = hash; + do z[i++ & 127] = abet[x & m]; + while ((x >>= base) || (pdot && i < prec)); + goto EmitNumber; + + case 'X': + abet = "0123456789ABCDEF"; + /* fallthrough */ + case 'x': + base = 4; + if (hash) hash = '0' | 'x' << 8; + goto BinaryNumber; + + case 'o': + base = 3; + goto BinaryNumber; + + case 'p': + x = va_arg(va, intptr_t); + if (!x && pdot) pdot = 0; + if ((long)x == -1) { + pdot = 0; + goto FormatDecimal; + } + hash = '0' | 'x' << 8; + base = 4; + goto FormatNumber; + + case 'C': + c = 'c'; + type = 1; + // fallthrough + case 'c': + i = 1; + j = 0; + x = 0; + s = (const char *)&x; + t = va_arg(va, int); + if (!type) t &= 255; + if (hash) { + quot = 1; + hash = '\''; + p = kemitquote(p, e, type, hash); + if (cols && type) --cols; // u/L + if (cols) --cols; // start quote + if (cols) --cols; // end quote + } + goto EmitChar; + + case 'm': { + int unixerr; + uint32_t winerr; + unixerr = errno; + winerr = 0; + if (IsWindows()) { + if (type == 1 && weaken(WSAGetLastError)) { + winerr = weaken(WSAGetLastError)(); + } else if (weaken(GetLastError)) { + winerr = weaken(GetLastError)(); + } + } + if (!unixerr && sign == ' ') { + break; + } else if (weaken(strerror_wr) && + !weaken(strerror_wr)(unixerr, winerr, z, sizeof(z))) { + s = z; + type = 0; + goto FormatString; + } else { + if (p + 4 <= e) { + *p++ = 'e'; + *p++ = 'r'; + *p++ = 'r'; + *p++ = '='; + } + type = 0; + x = unixerr; + goto FormatDecimal; + } + } + + case 'G': + x = va_arg(va, int); + if (weaken(strsignal) && (s = weaken(strsignal)(x))) { + goto FormatString; + } else { + goto FormatDecimal; + } + + case 't': { + int idx; + x = va_arg(va, intptr_t); + if (weaken(__get_symbol) && + (idx = weaken(__get_symbol)(0, x)) != -1) { + if (p + 1 <= e) *p++ = '&'; + s = weaken(GetSymbolTable)()->name_base + + weaken(GetSymbolTable)()->names[idx]; + goto FormatString; + } + base = 4; + hash = '&'; + goto FormatNumber; + } + + case 'n': + // nonstandard %n specifier + if (p < e) *p = '\n'; + ++p; + break; + + case 'r': + // undocumented %r specifier + // used for good carriage return + // helps integrate loggers with repls + if (!__replstderr || __nocolor) { + break; + } else { + s = "\r\033[K"; + goto FormatString; + } + + case 's': + if (!(s = va_arg(va, const void *))) { + s = sign != ' ' ? "NULL" : ""; + FormatString: + hash = 0; + type = 0; + } else if (!dang && (kisdangerous(s) || kischarmisaligned(s, type))) { + if (sign == ' ') { + if (p < e) *p = ' '; + ++p; + } + x = (intptr_t)s; + base = 4; + hash = '!' | '!' << 8; + goto FormatNumber; + } else if (hash) { + quot = 1; + hash = '"'; + if (cols && type) --cols; // u/L + if (cols) --cols; // start quote + if (cols) --cols; // end quote + p = kemitquote(p, e, type, hash); + } + if (sign == ' ' && (!pdot || prec) && *s) { + if (p < e) *p = ' '; + ++p; + } + for (i = j = 0; !pdot || j < prec; ++j) { + if (UNLIKELY(!((intptr_t)s & (PAGESIZE - 1)))) { + if (!dang && kisdangerous(s)) break; + } + if (!type) { + if (!(t = *s++ & 255)) break; + if ((t & 0300) == 0200) goto ActuallyEmitByte; + ++i; + EmitByte: + if (uppr && 'a' <= t && t <= 'z') { + t -= 'a' - 'A'; + } + if (UNLIKELY(quot) && (t == '\\' || ((t == '"' && c == 's') || + (t == '\'' && c == 'c')))) { + if (p + 2 <= e) { + p[0] = '\\'; + p[1] = t; + } + p += 2; + i += 1; + continue; + } + if (pdot || + (t != 0x7F && (t >= 0x20 || (t == '\n' || t == '\t' || + t == '\r' || t == '\e')))) { + ActuallyEmitByte: + if (p < e) *p = t; + p += 1; + continue; + } else if (quot) { + if (p + 4 <= e) { + p[0] = '\\'; + p[1] = '0' + ((t & 0300) >> 6); + p[2] = '0' + ((t & 0070) >> 3); + p[3] = '0' + ((t & 0007) >> 0); + } + p += 4; + i += 3; + continue; + } else { + /* Control Pictures + ═══════════════════════════════════════════════════════ + 2400 │ 0 1 2 3 4 5 6 7 8 9 a b c d e f + ─────────────────────────────────────────────────────── + 2400 │ ␀ ␁ ␂ ␃ ␄ ␅ ␆ ␇ ␈ ␉ ␊ ␋ ␌ ␍ ␎ ␏ + 2410 │ ␐ ␑ ␒ ␓ ␔ ␕ ␖ ␗ ␘ ␙ ␚ ␛ ␜ ␝ ␞ ␟ + 2420 │ ␠ ␡ ␢ ␣ ␤ ␥ ␦ */ + if (t != 0x7F) { + t += 0x2400; + } else { + t = 0x2421; + } + goto EmitChar; + } + } else if (type < -1) { + if ((t = *s++ & 255) || prec) { + t = kCp437[t]; + } + } else if (type < 0) { + t = *(const char16_t *)s; + s += sizeof(char16_t); + if (IsHighSurrogate(t)) { + if (!pdot || j + 1 < prec) { + if (UNLIKELY(!((intptr_t)s & (PAGESIZE - 1)))) { + if (!dang && kisdangerous(s)) break; + } + u = *(const char16_t *)s; + if (IsLowSurrogate(u)) { + t = MergeUtf16(t, u); + s += sizeof(char16_t); + j += 1; + } + } else { + break; + } + } else if (!t) { + break; + } + } else { + t = *(const wchar_t *)s; + s += sizeof(wchar_t); + } + if (!t) break; + ++i; + EmitChar: + if (t <= 0x7f) goto EmitByte; + if (uppr) { + if (weaken(towupper)) { + t = weaken(towupper)(t); + } else if (uppr && 'a' <= t && t <= 'z') { + t -= 'a' - 'A'; + } + } + if (t <= 0x7ff) { + if (p + 2 <= e) { + p[0] = 0300 | (t >> 6); + p[1] = 0200 | (t & 077); + } + p += 2; + } else if (t <= 0xffff) { + if (UNLIKELY(IsSurrogate(t))) { + EncodeReplacementCharacter: + t = 0xfffd; + } + if (p + 3 <= e) { + p[0] = 0340 | (t >> 12); + p[1] = 0200 | ((t >> 6) & 077); + p[2] = 0200 | (t & 077); + } + p += 3; + } else if (~(t >> 18) & 007) { + if (p + 4 <= e) { + p[0] = 0360 | (t >> 18); + p[1] = 0200 | ((t >> 12) & 077); + p[2] = 0200 | ((t >> 6) & 077); + p[3] = 0200 | (t & 077); + } + p += 4; + } else { + goto EncodeReplacementCharacter; + } + } + if (hash) { + if (p < e) *p = hash; + ++p; + } + for (; cols > i; --cols) { + if (p < e) { + *p++ = ' '; + } else { + p = kadvance(p, e, cols - i); + break; + } + } + break; + } + break; + } + } + if (p < e) { + *p = 0; + } else if (e > b) { + u = 0; + *--e = 0; + s = "\n..."; + if (!(((f - fmt) >= 2 && f[-2] == '\n') || + ((f - fmt) >= 3 && f[-3] == '%' && f[-2] == 'n'))) { + ++s; + } + while ((t = *s++) && e > b) { + u = *--e; + *e = t; + } + if ((u & 0300) == 0200) { + while (e > b) { + u = *--e; + *e = '.'; + if ((u & 0300) != 0200) { + break; + } + } + } + } + return p - b; +} + +/** + * Privileged snprintf(). + * + * @param b is buffer, and guaranteed a NUL-terminator if `n>0` + * @param n is number of bytes available in buffer + * @return length of output excluding NUL, which may exceed `n` + * @see kprintf() for documentation + * @asyncsignalsafe + * @vforksafe + */ +privileged size_t ksnprintf(char *b, size_t n, const char *fmt, ...) { + size_t m; + va_list v; + struct Timestamps t; + t = kenter(); + va_start(v, fmt); + m = kformat(b, n, fmt, v, t); + va_end(v); + kleave(t); + return m; +} + +/** + * Privileged snprintf() w/o timestamp feature. + * + * This provides a marginal performance boost, but it means %T can no + * longer be used. + * + * snprintf(".") l: 25𝑐 8𝑛𝑠 + * kusnprintf(".") l: 22𝑐 7𝑛𝑠 + * ksnprintf(".") l: 54𝑐 17𝑛𝑠 + * + * @param b is buffer, and guaranteed a NUL-terminator if `n>0` + * @param n is number of bytes available in buffer + * @return length of output excluding NUL, which may exceed `n` + * @see kprintf() for documentation + * @asyncsignalsafe + * @vforksafe + */ +privileged size_t kusnprintf(char *b, size_t n, const char *fmt, ...) { + size_t m; + va_list v; + va_start(v, fmt); + m = kformat(b, n, fmt, v, (struct Timestamps){0}); + va_end(v); + return m; +} + +/** + * Privileged vsnprintf(). + * + * @param b is buffer, and guaranteed a NUL-terminator if `n>0` + * @param n is number of bytes available in buffer + * @return length of output excluding NUL, which may exceed `n` + * @see kprintf() for documentation + * @asyncsignalsafe + * @vforksafe + */ +privileged size_t kvsnprintf(char *b, size_t n, const char *fmt, va_list v) { + size_t m; + struct Timestamps t; + t = kenter(); + m = kformat(b, n, fmt, v, t); + kleave(t); + return m; +} + +/** + * Privileged vprintf. + * + * @see kprintf() for documentation + * @asyncsignalsafe + * @vforksafe + */ +privileged void kvprintf(const char *fmt, va_list v) { + size_t n; + char b[4000]; + struct Timestamps t; + if (!v) return; + t = kenter(); + n = kformat(b, sizeof(b), fmt, v, t); + klog(b, MIN(n, sizeof(b) - 1)); + kleave(t); +} + +/** + * Privileged printf(). + * + * This function is intended for crash reporting. It's designed to be as + * unbreakable as possible, so that error messages can always be printed + * even when the rest of the runtime is broken. As such, it has continue + * on error semantics, doesn't support buffering between invocations and + * floating point is not supported. Output is also truncated if the line + * gets too long, but care is taken to preserve your newline characters. + * Your errno and GetLastError() state will not be clobbered, and ftrace + * and other runtime magic won't be invoked, since all the runtime magic + * depends on this function. + * + * Directives: + * + * %[FLAGS][WIDTH|*][.[PRECISION|*]][TYPE]SPECIFIER + * + * Specifiers: + * + * - `P` pid + * - `c` char + * - `o` octal + * - `b` binary + * - `s` string + * - `t` symbol + * - `p` pointer + * - `d` decimal + * - `n` newline + * - `u` unsigned + * - `r` carriage + * - `m` strerror + * - `G` strsignal + * - `X` uppercase + * - `T` timestamp + * - `x` hexadecimal + * + * Types: + * + * - `hhh` bool + * - `hh` char or cp437 + * - `h` short or char16_t + * - `l` long or wchar_t + * - `ll` long long + * + * Flags: + * + * - `0` zero padding + * - `-` flip alignment + * - `!` bypass memory safety + * - `,` thousands grouping w/ comma + * - `'` thousands grouping w/ apostrophe + * - `_` thousands grouping w/ underscore + * - `+` plus leftpad if positive (aligns w/ negatives) + * - ` ` space leftpad if positive (aligns w/ negatives) + * - `#` represent value with literal syntax, e.g. 0x, 0b, quotes + * - `^` uppercasing w/ towupper() if linked, otherwise toupper() + * + * Error numbers: + * + * - `%m` formats error (if strerror_wr if is linked) + * - `%m` formats errno number (if strerror_wr isn't linked) + * - `% m` formats error with leading space if errno isn't zero + * - `%lm` means favor WSAGetLastError() over GetLastError() if linked + * + * You need to link and load the symbol table before `%t` will work. You + * can do that by calling `GetSymbolTable()`. If that hasn't happened it + * will print `&hexnumber` instead. + * + * @asyncsignalsafe + * @vforksafe + */ +privileged void kprintf(const char *fmt, ...) { + /* system call support runtime depends on this function */ + /* function tracing runtime depends on this function */ + /* asan runtime depends on this function */ + va_list v; + va_start(v, fmt); + kvprintf(fmt, v); + va_end(v); +} diff --git a/libc/intrin/kprintf.h b/libc/intrin/kprintf.h new file mode 100644 index 000000000..7fb1450db --- /dev/null +++ b/libc/intrin/kprintf.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_KPRINTF_H_ +#define COSMOPOLITAN_LIBC_INTRIN_KPRINTF_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void kprintf(const char *, ...); +size_t ksnprintf(char *, size_t, const char *, ...); +size_t kusnprintf(char *, size_t, const char *, ...); +void kvprintf(const char *, va_list); +size_t kvsnprintf(char *, size_t, const char *, va_list); +bool kisdangerous(const void *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_KPRINTF_H_ */ diff --git a/libc/intrin/kstarttsc.c b/libc/intrin/kstarttsc.c new file mode 100644 index 000000000..598fd54db --- /dev/null +++ b/libc/intrin/kstarttsc.c @@ -0,0 +1,26 @@ +/*-*- 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. │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/** + * Timestamp of process start. + * + * @see libc/runtime/winmain.greg.h + * @see libc/crt/crt.S + */ +uint64_t kStartTsc; diff --git a/libc/bits/lockcmpxchg.c b/libc/intrin/lockcmpxchg.c similarity index 76% rename from libc/bits/lockcmpxchg.c rename to libc/intrin/lockcmpxchg.c index 59121e835..126659419 100644 --- a/libc/bits/lockcmpxchg.c +++ b/libc/intrin/lockcmpxchg.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/intrin/lockcmpxchg.h" /** * Compares and exchanges w/ lock prefix. @@ -24,23 +24,23 @@ * @param ifthing is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} * @param size is automatically supplied by macro wrapper * @return true if value was exchanged, otherwise false - * @see cmpxchg() + * @see cmpxchg() if only written by one thread */ -bool(lockcmpxchg)(void *ifthing, intptr_t isequaltome, intptr_t replaceitwithme, - size_t size) { +bool(_lockcmpxchg)(void *ifthing, intptr_t isequaltome, + intptr_t replaceitwithme, size_t size) { switch (size) { case 1: - return lockcmpxchg((int8_t *)ifthing, (int8_t)isequaltome, - (int8_t)replaceitwithme); + return _lockcmpxchg((int8_t *)ifthing, (int8_t)isequaltome, + (int8_t)replaceitwithme); case 2: - return lockcmpxchg((int16_t *)ifthing, (int16_t)isequaltome, - (int16_t)replaceitwithme); + return _lockcmpxchg((int16_t *)ifthing, (int16_t)isequaltome, + (int16_t)replaceitwithme); case 4: - return lockcmpxchg((int32_t *)ifthing, (int32_t)isequaltome, - (int32_t)replaceitwithme); + return _lockcmpxchg((int32_t *)ifthing, (int32_t)isequaltome, + (int32_t)replaceitwithme); case 8: - return lockcmpxchg((int64_t *)ifthing, (int64_t)isequaltome, - (int64_t)replaceitwithme); + return _lockcmpxchg((int64_t *)ifthing, (int64_t)isequaltome, + (int64_t)replaceitwithme); default: return false; } diff --git a/libc/intrin/lockcmpxchg.h b/libc/intrin/lockcmpxchg.h new file mode 100644 index 000000000..8079c6309 --- /dev/null +++ b/libc/intrin/lockcmpxchg.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_LOCKCMPXCHG_H_ +#define COSMOPOLITAN_LIBC_INTRIN_LOCKCMPXCHG_H_ +#include "libc/bits/asmflag.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +bool _lockcmpxchg(void *, intptr_t, intptr_t, size_t); + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86__) +#define _lockcmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ + ({ \ + bool DidIt; \ + autotype(IFTHING) IfThing = (IFTHING); \ + typeof(*IfThing) IsEqualToMe = (ISEQUALTOME); \ + typeof(*IfThing) ReplaceItWithMe = (REPLACEITWITHME); \ + asm volatile(ZFLAG_ASM("lock cmpxchg\t%3,%1") \ + : ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(IsEqualToMe) \ + : "r"(ReplaceItWithMe) \ + : "cc"); \ + DidIt; \ + }) +#else +#define _lockcmpxchg(MEM, CMP, VAL) \ + _lockcmpxchg(MEM, (intptr_t)(CMP), (intptr_t)(VAL), sizeof(*(MEM))) +#endif /* GNUC && !ANSI && x86 */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_LOCKCMPXCHG_H_ */ diff --git a/libc/intrin/lockcmpxchg16b.h b/libc/intrin/lockcmpxchg16b.h new file mode 100644 index 000000000..3a6196099 --- /dev/null +++ b/libc/intrin/lockcmpxchg16b.h @@ -0,0 +1,46 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_LOCKCMPXCHG16B_H_ +#define COSMOPOLITAN_LIBC_BITS_LOCKCMPXCHG16B_H_ +#include "libc/bits/asmflag.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86__) +/** + * Compares and exchanges 128-bit value, i.e. + * + * if (*IfThing == *IsEqualToMe) { + * *IfThing = ReplaceItWithMe; + * return true; + * } else { + * *IsEqualToMe = *IfThing; + * return false; + * } + * + * @param IfThing should point to aligned memory + * @param IsEqualToMe should point to in/out local variable + * @param ReplaceItWithMe might become the new memory value + * @return true if *IfThing was changed + * @asyncsignalsafe + * @threadsafe + */ +static inline bool _lockcmpxchg16b(uint128_t *IfThing, uint128_t *IsEqualToMe, + uint128_t ReplaceItWithMe) { + bool DidIt; + uint64_t ax, bx, cx, dx; + ax = *IsEqualToMe; + dx = *IsEqualToMe >> 64; + bx = ReplaceItWithMe; + cx = ReplaceItWithMe >> 64; + asm volatile(ZFLAG_ASM("lock cmpxchg16b\t%1") + : ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(ax), "+d"(dx) + : "b"(bx), "c"(cx)); + if (!DidIt) { + *IsEqualToMe = ax | (uint128_t)dx << 64; + } + return DidIt; +} +#endif /* __GNUC__ && !__STRICT_ANSI__ */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_LOCKCMPXCHG16B_H_ */ diff --git a/libc/intrin/lockxadd.c b/libc/intrin/lockxadd.c new file mode 100644 index 000000000..653a6377d --- /dev/null +++ b/libc/intrin/lockxadd.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/intrin/lockxadd.h" +#include "libc/runtime/runtime.h" + +/** + * Compares and exchanges w/ lock prefix. + * + * @param ifthing is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @param size is automatically supplied by macro wrapper + * @return value at location `*ifthing` *before* addition + * @see InterlockedAdd() for a very similar API + * @see xadd() if only written by one thread + */ +intptr_t(_lockxadd)(void *ifthing, intptr_t replaceitwithme, size_t size) { + switch (size) { + case 1: + return _lockxadd((int8_t *)ifthing, (int8_t)replaceitwithme); + case 2: + return _lockxadd((int16_t *)ifthing, (int16_t)replaceitwithme); + case 4: + return _lockxadd((int32_t *)ifthing, (int32_t)replaceitwithme); + case 8: + return _lockxadd((int64_t *)ifthing, (int64_t)replaceitwithme); + default: + abort(); + } +} diff --git a/libc/intrin/lockxadd.h b/libc/intrin/lockxadd.h new file mode 100644 index 000000000..b47c53f39 --- /dev/null +++ b/libc/intrin/lockxadd.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_LOCKXADD_H_ +#define COSMOPOLITAN_LIBC_BITS_LOCKXADD_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +intptr_t _lockxadd(void *, intptr_t, size_t); + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86__) +#define _lockxadd(PTR, VAL) \ + ({ \ + typeof(*(PTR)) Res; \ + typeof(Res) Val = (VAL); \ + asm volatile("lock xadd\t%0,%1" : "=r"(Res), "+m"(*(PTR)) : "0"(Val)); \ + Res; /* contains *PTR before addition cf. InterlockedAdd() */ \ + }) +#else +#define _lockxadd(MEM, VAL) _lockxadd(MEM, (intptr_t)(VAL), sizeof(*(MEM))) +#endif /* GNUC && !ANSI && x86 */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_LOCKXADD_H_ */ diff --git a/libc/bits/lockxchg.c b/libc/intrin/lockxchg.c similarity index 98% rename from libc/bits/lockxchg.c rename to libc/intrin/lockxchg.c index 651e23052..a372ff997 100644 --- a/libc/bits/lockxchg.c +++ b/libc/intrin/lockxchg.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/intrin/lockxchg.h" /** * Compares and exchanges w/ lock prefix. diff --git a/libc/intrin/lockxchg.h b/libc/intrin/lockxchg.h new file mode 100644 index 000000000..72733a645 --- /dev/null +++ b/libc/intrin/lockxchg.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_LOCKXCHG_H_ +#define COSMOPOLITAN_LIBC_INTRIN_LOCKXCHG_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +intptr_t lockxchg(void *, void *, size_t); + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +/** + * Exchanges *MEMORY into *LOCALVAR w/ one operation. + * + * @param MEMORY is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @param LOCALVAR is uint𝑘_t[hasatleast 1] + * @return LOCALVAR[0] + * @see xchg() + */ +#define lockxchg(MEMORY, LOCALVAR) \ + ({ \ + asm("xchg\t%0,%1" : "+%m"(*(MEMORY)), "+r"(*(LOCALVAR))); \ + *(LOCALVAR); \ + }) +#else +#define lockxchg(MEM, VAR) \ + lockxchg(MEM, VAR, sizeof(*(MEM)) / (sizeof(*(MEM)) == sizeof(*(VAR)))) +#endif /* __GNUC__ && !__STRICT_ANSI__ */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_LOCKXCHG_H_ */ diff --git a/libc/intrin/mapviewoffileex.greg.c b/libc/intrin/mapviewoffileex.greg.c new file mode 100644 index 000000000..778e56497 --- /dev/null +++ b/libc/intrin/mapviewoffileex.greg.c @@ -0,0 +1,53 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/memory.h" + +__msabi extern typeof(MapViewOfFileEx) *const __imp_MapViewOfFileEx; + +/** + * Maps view of file mapping into memory on the New Technology. + * + * @param hFileMappingObject was returned by CreateFileMapping() + * @param dwDesiredAccess has kNtFileMap... flags + * @param opt_lpDesiredBaseAddress may be NULL to let o/s choose + * @return base address, or NULL on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows void *MapViewOfFileEx(int64_t hFileMappingObject, + uint32_t dwDesiredAccess, + uint32_t dwFileOffsetHigh, + uint32_t dwFileOffsetLow, + size_t dwNumberOfBytesToMap, + void *opt_lpDesiredBaseAddress) { + void *pStartingAddress; + pStartingAddress = __imp_MapViewOfFileEx( + hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, + dwNumberOfBytesToMap, opt_lpDesiredBaseAddress); + if (!pStartingAddress) __winerr(); + NTTRACE("MapViewOfFileEx(%ld, %s, %'ld, %'zu, %p) → %p% m", + hFileMappingObject, DescribeNtFileMapFlags(dwDesiredAccess), + (uint64_t)dwFileOffsetHigh << 32 | dwFileOffsetLow, + dwNumberOfBytesToMap, opt_lpDesiredBaseAddress, pStartingAddress); + return pStartingAddress; +} diff --git a/libc/intrin/mapviewoffileexnuma.greg.c b/libc/intrin/mapviewoffileexnuma.greg.c new file mode 100644 index 000000000..dbbe9e3e5 --- /dev/null +++ b/libc/intrin/mapviewoffileexnuma.greg.c @@ -0,0 +1,55 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/memory.h" + +__msabi extern typeof(MapViewOfFileExNuma) *const __imp_MapViewOfFileExNuma; + +/** + * Maps view of file mapping into memory on the New Technology. + * + * @param hFileMappingObject was returned by CreateFileMapping() + * @param dwDesiredAccess has kNtFileMap... flags + * @param opt_lpDesiredBaseAddress may be NULL to let o/s choose + * @return base address, or NULL on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows void *MapViewOfFileExNuma(int64_t hFileMappingObject, + uint32_t dwDesiredAccess, + uint32_t dwFileOffsetHigh, + uint32_t dwFileOffsetLow, + size_t dwNumberOfBytesToMap, + void *opt_lpDesiredBaseAddress, + uint32_t nndDesiredNumaNode) { + void *pStartingAddress; + pStartingAddress = __imp_MapViewOfFileExNuma( + hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, + dwNumberOfBytesToMap, opt_lpDesiredBaseAddress, nndDesiredNumaNode); + if (!pStartingAddress) __winerr(); + NTTRACE("MapViewOfFileExNuma(%ld, %s, %'ld, %'zu, %p) → %p% m", + hFileMappingObject, DescribeNtFileMapFlags(dwDesiredAccess), + (uint64_t)dwFileOffsetHigh << 32 | dwFileOffsetLow, + dwNumberOfBytesToMap, opt_lpDesiredBaseAddress, pStartingAddress); + return pStartingAddress; +} diff --git a/libc/intrin/memcmp.c b/libc/intrin/memcmp.c index d46eeb261..3793577ef 100644 --- a/libc/intrin/memcmp.c +++ b/libc/intrin/memcmp.c @@ -26,9 +26,8 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1))); static dontinline antiquity int memcmp_sse(const unsigned char *p, - const unsigned char *q, size_t n) { - uint64_t w; - unsigned u, u0, u1, u2, u3; + const unsigned char *q, size_t n) { + unsigned u; if (n > 32) { while (n > 16 + 16) { if (!(u = PMOVMSKB(*(xmm_t *)p == *(xmm_t *)q) ^ 0xffff)) { diff --git a/libc/intrin/memset.c b/libc/intrin/memset.c index 30d8e8f72..b13c61325 100644 --- a/libc/intrin/memset.c +++ b/libc/intrin/memset.c @@ -26,7 +26,7 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1))); typedef long long xmm_a __attribute__((__vector_size__(16), __aligned__(16))); -noasan static dontinline antiquity void *memset_sse(char *p, char c, size_t n) { +static dontinline antiquity void *memset_sse(char *p, char c, size_t n) { xmm_t v = {c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c}; if (IsAsan()) __asan_verify(p, n); if (n <= 32) { @@ -44,8 +44,7 @@ noasan static dontinline antiquity void *memset_sse(char *p, char c, size_t n) { return p; } -noasan microarchitecture("avx") static void *memset_avx(char *p, char c, - size_t n) { +microarchitecture("avx") static void *memset_avx(char *p, char c, size_t n) { char *t; xmm_t v = {c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c}; if (IsAsan()) __asan_verify(p, n); diff --git a/libc/intrin/movefileex.greg.c b/libc/intrin/movefileex.greg.c new file mode 100644 index 000000000..8f497ab8c --- /dev/null +++ b/libc/intrin/movefileex.greg.c @@ -0,0 +1,40 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/memory.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(MoveFileEx) *const __imp_MoveFileExW; + +/** + * Deletes existing empty directory. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 MoveFileEx(const char16_t *lpExistingFileName, + const char16_t *lpNewFileName, int dwFlags) { + bool32 ok; + ok = __imp_MoveFileExW(lpExistingFileName, lpNewFileName, dwFlags); + if (!ok) __winerr(); + NTTRACE("MoveFileEx(%#hs, %#hs, %s) → %hhhd% m", lpExistingFileName, + lpNewFileName, DescribeNtMoveFileInputFlags(dwFlags), ok); + return ok; +} diff --git a/libc/intrin/mulvdi3.S b/libc/intrin/mulvdi3.S index fbf5752e5..7ef4b6512 100644 --- a/libc/intrin/mulvdi3.S +++ b/libc/intrin/mulvdi3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/mulvsi3.S b/libc/intrin/mulvsi3.S index a55c96513..51a8e6e3d 100644 --- a/libc/intrin/mulvsi3.S +++ b/libc/intrin/mulvsi3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/mulvti3.S b/libc/intrin/mulvti3.S index d6f163314..93b25b911 100644 --- a/libc/intrin/mulvti3.S +++ b/libc/intrin/mulvti3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/negvdi2.S b/libc/intrin/negvdi2.S index b05f7bbde..5cb827852 100644 --- a/libc/intrin/negvdi2.S +++ b/libc/intrin/negvdi2.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/negvsi2.S b/libc/intrin/negvsi2.S index 57390047e..38f564690 100644 --- a/libc/intrin/negvsi2.S +++ b/libc/intrin/negvsi2.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/negvti2.S b/libc/intrin/negvti2.S index 39d3af164..add96c0b1 100644 --- a/libc/intrin/negvti2.S +++ b/libc/intrin/negvti2.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/nocolor.c b/libc/intrin/nocolor.c new file mode 100644 index 000000000..316f3eda6 --- /dev/null +++ b/libc/intrin/nocolor.c @@ -0,0 +1,61 @@ +/*-*- 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 "libc/dce.h" +#include "libc/log/internal.h" +#include "libc/nt/version.h" +#include "libc/runtime/runtime.h" + +#define IsDumb(s) \ + (s[0] == 'd' && s[1] == 'u' && s[2] == 'm' && s[3] == 'b' && !s[4]) + +/** + * Indicates if ANSI terminal colors are inappropriate. + * + * Normally this variable should be false. We only set it to true if + * we're running on an old version of Windows or the environment + * variable `TERM` is set to `dumb`. + * + * We think colors should be the norm, since most software is usually + * too conservative about removing them. Rather than using `isatty` + * consider using sed for instances where color must be removed: + * + * sed 's/\x1b\[[;[:digit:]]*m//g' uncolor.txt + * + * For some reason, important software is configured by default in many + * operating systems, to not only disable colors, but utf-8 too! Here's + * an example of how a wrapper script can fix that for `less`. + * + * #!/bin/sh + * LESSCHARSET=UTF-8 exec /usr/bin/less -RS "$@" + * + * Thank you for using colors! + */ +bool __nocolor; + +optimizesize textstartup noasan void __nocolor_init(int argc, char **argv, + char **envp, + intptr_t *auxv) { + char *s; + __nocolor = (IsWindows() && !IsAtLeastWindows10()) || + ((s = getenv("TERM")) && IsDumb(s)); +} + +const void *const __nocolor_ctor[] initarray = { + __nocolor_init, +}; diff --git a/libc/intrin/nomultics.c b/libc/intrin/nomultics.c new file mode 100644 index 000000000..e0003b831 --- /dev/null +++ b/libc/intrin/nomultics.c @@ -0,0 +1,28 @@ +/*-*- 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. │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/** + * Controls ANSI prefix for log emissions. + * + * This should be true in raw tty mode repls. + * + * @see kprintf(), vflogf(), linenoise() + */ +char __replmode; +char __replstderr; diff --git a/libc/intrin/nomultics.internal.h b/libc/intrin/nomultics.internal.h new file mode 100644 index 000000000..ffc15900c --- /dev/null +++ b/libc/intrin/nomultics.internal.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_NOMULTICS_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_INTRIN_NOMULTICS_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern char __replmode; +extern char __replstderr; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_NOMULTICS_INTERNAL_H_ */ diff --git a/libc/intrin/ntconsolemode.c b/libc/intrin/ntconsolemode.c new file mode 100644 index 000000000..8c72a48ed --- /dev/null +++ b/libc/intrin/ntconsolemode.c @@ -0,0 +1,21 @@ +/*-*- 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/runtime/internal.h" + +uint32_t __ntconsolemode[3]; diff --git a/libc/intrin/onarithmeticoverflow.S b/libc/intrin/onarithmeticoverflow.S index b1a09b546..4e3d1efc2 100644 --- a/libc/intrin/onarithmeticoverflow.S +++ b/libc/intrin/onarithmeticoverflow.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .privileged -.source __FILE__ // Arithmetic overflow handler. // @see -ftrapv @@ -26,5 +25,6 @@ __on_arithmetic_overflow: push %rbp mov %rsp,%rbp int3 - call abort +0: ud2 + jmp 0b .endfn __on_arithmetic_overflow,weak diff --git a/libc/intrin/once.h b/libc/intrin/once.h new file mode 100644 index 000000000..52eb74f2d --- /dev/null +++ b/libc/intrin/once.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_ONCE_H_ +#define COSMOPOLITAN_LIBC_INTRIN_ONCE_H_ +#include "libc/intrin/spinlock.h" + +#define _once(x) \ + ({ \ + typeof(x) oncerc; \ + static bool once; \ + static typeof(oncerc) onceresult; \ + _Alignas(64) static char oncelock; \ + _spinlock(&oncelock); \ + if (once) { \ + oncerc = onceresult; \ + } else { \ + oncerc = onceresult = x; \ + } \ + _spunlock(&oncelock); \ + oncerc; \ + }) + +#endif /* COSMOPOLITAN_LIBC_INTRIN_ONCE_H_ */ diff --git a/libc/intrin/openprocess.greg.c b/libc/intrin/openprocess.greg.c new file mode 100644 index 000000000..897d4f7c9 --- /dev/null +++ b/libc/intrin/openprocess.greg.c @@ -0,0 +1,46 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/memory.h" +#include "libc/nt/process.h" +#include "libc/nt/struct/securityattributes.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(OpenProcess) *const __imp_OpenProcess; + +/** + * Creates file mapping object on the New Technology. + * + * @param dwDesiredAccess should be kNtProcess... combination + * @return ehandle, or 0 on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + * @see MapViewOfFileEx() + */ +textwindows int64_t OpenProcess(uint32_t dwDesiredAccess, bool32 bInheritHandle, + uint32_t dwProcessId) { + int64_t hHandle; + hHandle = __imp_OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId); + if (!hHandle) __winerr(); + NTTRACE("OpenProcess(%s, %hhhd, %u) → %ld% m", + DescribeNtProcessAccessFlags(dwDesiredAccess), bInheritHandle, + dwProcessId, hHandle); + return hHandle; +} diff --git a/libc/intrin/printf.c b/libc/intrin/printf.c deleted file mode 100644 index 1ad0b9a2b..000000000 --- a/libc/intrin/printf.c +++ /dev/null @@ -1,242 +0,0 @@ -/*-*- 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/limits.h" -#include "libc/log/libfatal.internal.h" -#include "libc/nexgen32e/uart.internal.h" -#include "libc/nt/runtime.h" -#include "libc/runtime/runtime.h" -#include "libc/str/tpenc.h" -#include "libc/sysv/consts/nr.h" - -/** - * Privileged vprintf. - * - * This will work without any cosmopolitan runtime support once the - * executable has been loaded into memory. - */ -privileged noasan noubsan noinstrument void __vprintf(const char *fmt, - va_list va) { - short w[2]; - uint16_t dx; - const void *s; - uint32_t wrote; - unsigned long x; - unsigned char al; - int i, j, t, cstr; - long d, rax, rdi, rsi, rdx, dot; - char c, *p, *e, pad, bits, base, sign, thou, z[28], b[2048]; - p = b; - e = p + sizeof(b); - do { - switch ((c = *fmt++)) { - default: - if (p < e) { - *p++ = c; - } - break; - case '\0': - break; - case '%': - dot = 0; - pad = ' '; - sign = 0; - bits = 0; - thou = 0; - w[0] = 0; - w[1] = SHRT_MAX; - NeedMoar: - switch ((c = *fmt++)) { - case '\0': - break; - case 'l': - case 'z': - goto NeedMoar; - case ' ': - case '+': - sign = c; - goto NeedMoar; - case 'e': - dot = 1; - goto NeedMoar; - case ',': - thou = c; - goto NeedMoar; - case 'h': - bits = 16; - goto NeedMoar; - case '0': - pad = c; - /* fallthrough */ - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - w[dot] *= 10; - w[dot] += c - '0'; - goto NeedMoar; - case '*': - w[dot] = va_arg(va, int); - goto NeedMoar; - case 'd': - d = va_arg(va, long); - ApiAbuse: - x = d; - if (d < 0) { - x = -x; - sign = '-'; - } - for (i = j = 0;;) { - z[i++] = x % 10 + '0'; - if (!(x /= 10)) break; - if (thou && !(++j % 3)) { - z[i++] = thou; - } - } - if (sign) { - z[i++] = sign; - } - EmitNumber: - while (w[0]-- > i) { - if (p < e) *p++ = pad; - } - do { - if (p < e) *p++ = z[--i]; - } while (i); - break; - case 'b': - base = 1; - BinaryNumber: - i = 0; - x = va_arg(va, unsigned long); - do z[i++] = "0123456789abcdef"[x & ((1 << base) - 1)]; - while ((x >>= base) && i < w[1]); - goto EmitNumber; - case 'p': - pad = '0'; - w[0] = 12; - w[1] = 12; - /* fallthrough */ - case 'x': - base = 4; - goto BinaryNumber; - case 'o': - base = 3; - goto BinaryNumber; - case 'c': - cstr = va_arg(va, int); - s = &cstr; - goto EmitString; - case 's': - s = va_arg(va, const void *); - EmitString: - if (!s) { - s = "NULL"; - bits = 0; - } else if ((uintptr_t)s < PAGESIZE) { - d = (intptr_t)s; - goto ApiAbuse; - } - for (i = 0; i < w[1]; ++i) { - if (!bits) { - t = ((const char *)s)[i]; - EmitByte: - if (t) { - if (p < e) { - *p++ = t; - } - } else { - break; - } - } else { - t = ((const char16_t *)s)[i]; - if (t <= 0x7f) { - goto EmitByte; - } else if (t <= 0x7ff) { - if (p + 1 < e) { - p[0] = 0300 | t >> 6; - p[1] = 0200 | x << 8 | t & 077; - p += 2; - } - } else if (p + 2 < e) { - p[0] = 0340 | t >> 12; - p[1] = 0200 | x << 8 | (t >> 6) & 077; - p[2] = 0200 | x << 8 | t & 077; - p += 3; - } - } - } - while (w[0]-- > i) { - if (p < e) *p++ = pad; - } - break; - default: - break; - } - break; - } - } while (c); - if (p == e) { - e[-4] = '.'; - e[-3] = '.'; - e[-2] = '.'; - e[-1] = '\n'; - } - if (IsWindows()) { - WriteFile(GetStdHandle(kNtStdErrorHandle), b, p - b, &wrote, 0); - } else if (IsMetal()) { - for (e = p, p = b; p < e; ++p) { - for (;;) { - dx = 0x3F8 + UART_LSR; - asm("inb\t%1,%0" : "=a"(al) : "dN"(dx)); - if (al & UART_TTYTXR) break; - asm("pause"); - } - dx = 0x3F8; - asm volatile("outb\t%0,%1" - : /* no inputs */ - : "a"(*p), "dN"(dx)); - } - } else { - asm volatile("syscall" - : "=a"(rax), "=D"(rdi), "=S"(rsi), "=d"(rdx) - : "0"(__NR_write), "1"(2L), "2"(b), "3"(p - b) - : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"); - } -} - -/** - * Privileged printf. - * - * This will work without any cosmopolitan runtime support once the - * executable has been loaded into memory. - */ -privileged noasan noubsan noinstrument void __printf(const char *fmt, ...) { - /* system call support runtime depends on this function */ - /* function tracing runtime depends on this function */ - /* asan runtime depends on this function */ - va_list va; - va_start(va, fmt); - __vprintf(fmt, va); - va_end(va); -} diff --git a/libc/intrin/printsystemmappings.c b/libc/intrin/printsystemmappings.greg.c similarity index 100% rename from libc/intrin/printsystemmappings.c rename to libc/intrin/printsystemmappings.greg.c diff --git a/libc/intrin/prot2nt.greg.c b/libc/intrin/prot2nt.greg.c new file mode 100644 index 000000000..4547a57ee --- /dev/null +++ b/libc/intrin/prot2nt.greg.c @@ -0,0 +1,48 @@ +/*-*- 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 "libc/calls/internal.h" +#include "libc/nt/enum/pageflags.h" +#include "libc/runtime/directmap.internal.h" +#include "libc/sysv/consts/prot.h" + +privileged uint32_t __prot2nt(int prot, bool iscow) { + switch (prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) { + case PROT_READ: + return kNtPageReadonly; + case PROT_EXEC: + case PROT_EXEC | PROT_READ: + return kNtPageExecuteRead; + case PROT_WRITE: + case PROT_READ | PROT_WRITE: + if (iscow) { + return kNtPageWritecopy; + } else { + return kNtPageReadwrite; + } + case PROT_WRITE | PROT_EXEC: + case PROT_READ | PROT_WRITE | PROT_EXEC: + if (iscow) { + return kNtPageExecuteWritecopy; + } else { + return kNtPageExecuteReadwrite; + } + default: + return kNtPageNoaccess; + } +} diff --git a/libc/intrin/psrldq.c b/libc/intrin/psrldq.c index 505d870e1..eb69a2fab 100644 --- a/libc/intrin/psrldq.c +++ b/libc/intrin/psrldq.c @@ -27,8 +27,10 @@ * @mayalias */ void(psrldq)(uint8_t b[16], const uint8_t a[16], unsigned long n) { - unsigned i; - if (n > 16) n = 16; - __builtin_memcpy(b, a + n, 16 - n); + if (n > 16) { + n = 16; + } else { + __builtin_memcpy(b, a + n, 16 - n); + } __builtin_memset(b + (16 - n), 0, n); } diff --git a/libc/runtime/quick_exit.c b/libc/intrin/quick_exit.c similarity index 85% rename from libc/runtime/quick_exit.c rename to libc/intrin/quick_exit.c index aea08672c..ec9c3be73 100644 --- a/libc/runtime/quick_exit.c +++ b/libc/intrin/quick_exit.c @@ -16,10 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/pushpop.h" #include "libc/bits/weaken.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" #include "libc/nt/console.h" -#include "libc/nt/enum/consolemodeflags.h" +#include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" @@ -33,17 +34,13 @@ */ wontreturn void quick_exit(int exitcode) { const uintptr_t *p; + STRACE("quick_exit(%d)", exitcode); + __restorewintty(); if (weaken(fflush)) { weaken(fflush)(0); } for (p = __fini_array_end; p > __fini_array_start;) { ((void (*)(void))(*--p))(); } - if (SupportsWindows() && __ntconsolemode) { - SetConsoleMode(GetStdHandle(pushpop(kNtStdInputHandle)), __ntconsolemode); - SetConsoleMode(GetStdHandle(pushpop(kNtStdOutputHandle)), - kNtEnableProcessedOutput | kNtEnableWrapAtEolOutput | - kNtEnableVirtualTerminalProcessing); - } _Exit(exitcode); } diff --git a/libc/intrin/refcount.h b/libc/intrin/refcount.h new file mode 100644 index 000000000..076de6a03 --- /dev/null +++ b/libc/intrin/refcount.h @@ -0,0 +1,7 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_REFCOUNT_H_ +#define COSMOPOLITAN_LIBC_INTRIN_REFCOUNT_H_ + +#define _incref(x) __atomic_fetch_add(x, 1, __ATOMIC_RELAXED) +#define _decref(x) __atomic_sub_fetch(x, 1, __ATOMIC_SEQ_CST) + +#endif /* COSMOPOLITAN_LIBC_INTRIN_REFCOUNT_H_ */ diff --git a/libc/calls/releasefd.c b/libc/intrin/releasefd.c similarity index 89% rename from libc/calls/releasefd.c rename to libc/intrin/releasefd.c index 2708f6968..3b9410d36 100644 --- a/libc/calls/releasefd.c +++ b/libc/intrin/releasefd.c @@ -16,16 +16,15 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" #include "libc/calls/internal.h" +#include "libc/intrin/spinlock.h" +#include "libc/macros.internal.h" void __releasefd(int fd) { - int x; - if (!__vforked && 0 <= fd && fd < g_fds.n) { - g_fds.p[fd].kind = kFdEmpty; - do { - x = g_fds.f; - if (fd >= x) break; - } while (!cmpxchg(&g_fds.f, x, fd)); + _spinlock(&__fds_lock); + if (0 <= fd && fd < g_fds.n) { + g_fds.p[fd].kind = 0; + g_fds.f = MIN(fd, g_fds.f); } + _spunlock(&__fds_lock); } diff --git a/libc/intrin/removedirectory.greg.c b/libc/intrin/removedirectory.greg.c new file mode 100644 index 000000000..6f6035c54 --- /dev/null +++ b/libc/intrin/removedirectory.greg.c @@ -0,0 +1,36 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(RemoveDirectory) *const __imp_RemoveDirectoryW; + +/** + * Deletes existing empty directory on the New Technology. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 RemoveDirectory(const char16_t *lpPathName) { + bool32 ok; + ok = __imp_RemoveDirectoryW(lpPathName); + if (!ok) __winerr(); + NTTRACE("RemoveDirectory(%#hs) → %hhhd% m", lpPathName, ok); + return ok; +} diff --git a/libc/intrin/reopenfile.greg.c b/libc/intrin/reopenfile.greg.c new file mode 100644 index 000000000..b20292ae6 --- /dev/null +++ b/libc/intrin/reopenfile.greg.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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(ReOpenFile) *const __imp_ReOpenFile; + +/** + * Reopens file on the New Technology. + * + * @return handle, or -1 on failure + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +int64_t ReOpenFile(int64_t hOriginalFile, uint32_t dwDesiredAccess, + uint32_t dwShareMode, uint32_t dwFlagsAndAttributes) { + int64_t hHandle; + hHandle = __imp_ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, + dwFlagsAndAttributes); + if (hHandle == -1) __winerr(); + NTTRACE("ReOpenFile(%ld, %s, %s, %s) → %ld% m", hOriginalFile, + DescribeNtFileAccessFlags(dwDesiredAccess), + DescribeNtFileShareFlags(dwShareMode), + DescribeNtFileFlagsAndAttributes(dwFlagsAndAttributes), hHandle); + return hHandle; +} diff --git a/libc/intrin/restorewintty.greg.c b/libc/intrin/restorewintty.greg.c new file mode 100644 index 000000000..808d81986 --- /dev/null +++ b/libc/intrin/restorewintty.greg.c @@ -0,0 +1,47 @@ +/*-*- 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 2022 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/strace.internal.h" +#include "libc/dce.h" +#include "libc/nt/console.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/internal.h" + +uint32_t __winmainpid; + +const char kConsoleHandles[3] = { + kNtStdInputHandle, + kNtStdOutputHandle, + kNtStdErrorHandle, +}; + +/** + * Puts cmd.exe gui back the way it was. + */ +noasan void __restorewintty(void) { + int i; + if (!IsWindows()) return; + NTTRACE("__restorewintty()"); + if (GetCurrentProcessId() == __winmainpid) { + for (i = 0; i < 3; ++i) { + SetConsoleMode(GetStdHandle(kConsoleHandles[i]), __ntconsolemode[i]); + } + __winmainpid = 0; + } +} diff --git a/libc/intrin/setcurrentdirectory.greg.c b/libc/intrin/setcurrentdirectory.greg.c new file mode 100644 index 000000000..28f0f9516 --- /dev/null +++ b/libc/intrin/setcurrentdirectory.greg.c @@ -0,0 +1,37 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/files.h" +#include "libc/nt/memory.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(SetCurrentDirectory) *const __imp_SetCurrentDirectoryW; + +/** + * Sets current directory. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 SetCurrentDirectory(const char16_t *lpPathName) { + bool32 ok; + ok = __imp_SetCurrentDirectoryW(lpPathName); + if (!ok) __winerr(); + NTTRACE("SetCurrentDirectory(%#hs) → %hhhd% m", lpPathName, ok); + return ok; +} diff --git a/libc/intrin/somanyasan.S b/libc/intrin/somanyasan.S index 807d176cc..a473f4a8b 100644 --- a/libc/intrin/somanyasan.S +++ b/libc/intrin/somanyasan.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .rodata.cst4 __asan_option_detect_stack_use_after_return: @@ -185,7 +184,7 @@ __asan_version_mismatch_check_v8: .endfn __asan_version_mismatch_check_v8,globl // Initializes Address Sanitizer runtime earlier if linked. - .init.start 301,_init_asan + .init.start 303,_init_asan push %rdi push %rsi mov %r12,%rdi @@ -195,7 +194,7 @@ __asan_version_mismatch_check_v8: call __asan_init pop %rsi pop %rdi - .init.end 301,_init_asan + .init.end 303,_init_asan __asan_before_dynamic_init: push %rbp diff --git a/libc/intrin/spinlock.h b/libc/intrin/spinlock.h new file mode 100644 index 000000000..e8cdffaa2 --- /dev/null +++ b/libc/intrin/spinlock.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_ +#define COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_ + +#ifdef TINY +#define _spinlock(lock) \ + do { \ + while (__sync_lock_test_and_set(lock, 1)) { \ + __builtin_ia32_pause(); \ + } \ + } while (0) +#else +#define _spinlock(lock) \ + do { \ + for (;;) { \ + typeof(*(lock)) x; \ + __atomic_load(lock, &x, __ATOMIC_RELAXED); \ + if (!x && !__sync_lock_test_and_set(lock, 1)) { \ + break; \ + } else { \ + __builtin_ia32_pause(); \ + } \ + } \ + } while (0) +#endif + +#define _spunlock(lock) __sync_lock_release(lock) + +#endif /* COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_ */ diff --git a/libc/intrin/stracef.greg.c b/libc/intrin/stracef.greg.c new file mode 100644 index 000000000..ab5fbc4fe --- /dev/null +++ b/libc/intrin/stracef.greg.c @@ -0,0 +1,28 @@ +/*-*- 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/strace.internal.h" +#include "libc/intrin/kprintf.h" + +privileged void __stracef(const char *fmt, ...) { + va_list v; + if (__strace <= 0) return; + va_start(v, fmt); + kvprintf(fmt, v); + va_end(v); +} diff --git a/libc/intrin/subvdi3.S b/libc/intrin/subvdi3.S index a6f826590..ac2ac9f0d 100644 --- a/libc/intrin/subvdi3.S +++ b/libc/intrin/subvdi3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/subvsi3.S b/libc/intrin/subvsi3.S index 99a4af1f9..13d9d4b12 100644 --- a/libc/intrin/subvsi3.S +++ b/libc/intrin/subvsi3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/subvti3.S b/libc/intrin/subvti3.S index 29ed27fb3..5e8a568ea 100644 --- a/libc/intrin/subvti3.S +++ b/libc/intrin/subvti3.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .privileged .alignfunc diff --git a/libc/intrin/terminateprocess.greg.c b/libc/intrin/terminateprocess.greg.c new file mode 100644 index 000000000..5f308f7cf --- /dev/null +++ b/libc/intrin/terminateprocess.greg.c @@ -0,0 +1,37 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/console.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(TerminateProcess) *const __imp_TerminateProcess; + +/** + * Terminates the specified process and all of its threads. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 TerminateProcess(int64_t hProcess, uint32_t uExitCode) { + bool32 ok; + ok = __imp_TerminateProcess(hProcess, uExitCode); + if (!ok) __winerr(); + NTTRACE("TerminateProcess(%ld, %u) → %hhhd% m", hProcess, uExitCode, ok); + return ok; +} diff --git a/libc/intrin/threaded.c b/libc/intrin/threaded.c new file mode 100644 index 000000000..0971a44a6 --- /dev/null +++ b/libc/intrin/threaded.c @@ -0,0 +1,20 @@ +/*-*- 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 2022 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. │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +bool __threaded; diff --git a/libc/intrin/tls.greg.c b/libc/intrin/tls.greg.c new file mode 100644 index 000000000..2dec7159a --- /dev/null +++ b/libc/intrin/tls.greg.c @@ -0,0 +1,89 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/dce.h" +#include "libc/intrin/tls.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(TlsFree) *const __imp_TlsFree; +__msabi extern typeof(TlsAlloc) *const __imp_TlsAlloc; +__msabi extern typeof(TlsGetValue) *const __imp_TlsGetValue; +__msabi extern typeof(TlsSetValue) *const __imp_TlsSetValue; + +/** + * Assigns thread-local storage slot. + * + * This function may for instance be called at startup and the result + * can be assigned to a global static variable; from then on, all the + * threads in your application may pass that value to TlsGetValue, to + * retrieve their thread-local values. + * + * @return index on success, or -1u w/ errno + * @threadsafe + */ +uint32_t TlsAlloc(void) { + return __imp_TlsAlloc(); +} + +/** + * Releases thread-local storage slot. + * @threadsafe + */ +bool32 TlsFree(uint32_t dwTlsIndex) { + return __imp_TlsFree(dwTlsIndex); +} + +/** + * Sets value to thread-local storage slot. + * + * @param dwTlsIndex is something returned by TlsAlloc() + * @return true if successful, otherwise false + * @threadsafe + */ +bool32 TlsSetValue(uint32_t dwTlsIndex, void *lpTlsValue) { + assert(IsWindows()); + if (dwTlsIndex < 64) { + asm("mov\t%1,%%gs:%0" + : "=m"(*((long *)0x1480 + dwTlsIndex)) + : "r"(lpTlsValue)); + return true; + } else { + return __imp_TlsSetValue(dwTlsIndex, lpTlsValue); + } +} + +/** + * Retrieves value from thread-local storage slot. + * + * @param dwTlsIndex is something returned by TlsAlloc() + * @return true if successful, otherwise false + * @threadsafe + */ +void *TlsGetValue(uint32_t dwTlsIndex) { + void *lpTlsValue; + assert(IsWindows()); + if (dwTlsIndex < 64) { + asm("mov\t%%gs:%1,%0" + : "=r"(lpTlsValue) + : "m"(*((long *)0x1480 + dwTlsIndex))); + return lpTlsValue; + } else { + return __imp_TlsGetValue(dwTlsIndex); + } +} diff --git a/libc/intrin/tls.h b/libc/intrin/tls.h new file mode 100644 index 000000000..8f539900d --- /dev/null +++ b/libc/intrin/tls.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_INTRIN_TLS_H_ +#define COSMOPOLITAN_LIBC_INTRIN_TLS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +uint32_t TlsAlloc(void); +bool32 TlsFree(uint32_t); +bool32 TlsSetValue(uint32_t, void *); +void *TlsGetValue(uint32_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_TLS_H_ */ diff --git a/libc/intrin/tpenc.S b/libc/intrin/tpenc.S index 542d3dc81..aace173e1 100644 --- a/libc/intrin/tpenc.S +++ b/libc/intrin/tpenc.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Encodes Thompson-Pike varint. // @@ -47,6 +46,7 @@ tpenc: .leafprologue .rodata .align 4 + .underrun kTpenc: .rept 4 # MSB≤10 (0x7FF) .byte 1,0b11000000 # len,mark .endr @@ -64,3 +64,4 @@ kTpenc: .rept 4 # MSB≤10 (0x7FF) .endr .zero 2 .endobj kTpenc + .overrun diff --git a/libc/intrin/ubsan.c b/libc/intrin/ubsan.c index ae95fede5..ec357de0f 100644 --- a/libc/intrin/ubsan.c +++ b/libc/intrin/ubsan.c @@ -20,7 +20,10 @@ #include "libc/bits/pushpop.h" #include "libc/bits/weaken.h" #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" #include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/color.internal.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" @@ -36,6 +39,8 @@ #define kUbsanKindFloat 1 #define kUbsanKindUnknown 0xffff +typedef void __ubsan_die_f(void); + struct UbsanSourceLocation { const char *file; uint32_t line; @@ -187,17 +192,43 @@ static uintptr_t __ubsan_extend(struct UbsanTypeDescriptor *t, uintptr_t x) { return x; } -void __ubsan_abort(const struct UbsanSourceLocation *loc, - const char *description) { - __printf("\r\n%s:%d: ubsan error: %s\r\n", loc->file, loc->line, description); - if (weaken(__die)) weaken(__die)(); - _Exit(134); +static wontreturn void __ubsan_unreachable(void) { + for (;;) __builtin_trap(); +} + +static void __ubsan_exit(void) { + kprintf("your ubsan runtime needs\n" + "\tSTATIC_YOINK(\"__die\");\n" + "in order to show you backtraces\n"); + __restorewintty(); + _Exit(99); +} + +dontdiscard static __ubsan_die_f *__ubsan_die(void) { + if (weaken(__die)) { + return weaken(__die); + } else { + return __ubsan_exit; + } +} + +static void __ubsan_warning(const struct UbsanSourceLocation *loc, + const char *description) { + kprintf("%s:%d: %subsan warning: %s is undefined behavior%s\n", loc->file, + loc->line, SUBTLE, description, RESET); +} + +dontdiscard __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc, + const char *description) { + kprintf("\n%s:%d: %subsan error%s: %s\n", loc->file, loc->line, RED2, RESET, + description); + return __ubsan_die(); } static const char *__ubsan_describe_shift( struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, uintptr_t rhs) { if (__ubsan_negative(info->rhs_type, rhs)) { - return "shift exponent is negative"; + return "negative shift exponent"; } else if (rhs >= __ubsan_bits(info->lhs_type)) { return "shift exponent too large for type"; } else if (__ubsan_negative(info->lhs_type, lhs)) { @@ -209,9 +240,10 @@ static const char *__ubsan_describe_shift( } } -void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info, - uintptr_t lhs, uintptr_t rhs) { - char buf[512], *p = buf; +static char *__ubsan_describe_shift_out_of_bounds( + char buf[512], struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, + uintptr_t rhs) { + char *p = buf; lhs = __ubsan_extend(info->lhs_type, lhs); rhs = __ubsan_extend(info->rhs_type, rhs); p = __stpcpy(p, __ubsan_describe_shift(info, lhs, rhs)), *p++ = ' '; @@ -219,12 +251,22 @@ void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info, p = __stpcpy(p, info->lhs_type->name), *p++ = ' '; p = __ubsan_itpcpy(p, info->rhs_type, rhs), *p++ = ' '; p = __stpcpy(p, info->rhs_type->name); - __ubsan_abort(&info->location, buf); + return buf; +} + +void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info, + uintptr_t lhs, uintptr_t rhs) { + char buf[512]; + __ubsan_warning(&info->location, + __ubsan_describe_shift_out_of_bounds(buf, info, lhs, rhs)); } void __ubsan_handle_shift_out_of_bounds_abort( struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, uintptr_t rhs) { - __ubsan_handle_shift_out_of_bounds(info, lhs, rhs); + char buf[512]; + __ubsan_abort(&info->location, + __ubsan_describe_shift_out_of_bounds(buf, info, lhs, rhs))(); + __ubsan_unreachable(); } void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info, @@ -236,7 +278,8 @@ void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info, p = __stpcpy(p, " into "); p = __stpcpy(p, info->array_type->name); p = __stpcpy(p, " out of bounds"); - __ubsan_abort(&info->location, buf); + __ubsan_abort(&info->location, buf)(); + __ubsan_unreachable(); } void __ubsan_handle_out_of_bounds_abort(struct UbsanOutOfBoundsInfo *info, @@ -244,11 +287,11 @@ void __ubsan_handle_out_of_bounds_abort(struct UbsanOutOfBoundsInfo *info, __ubsan_handle_out_of_bounds(info, index); } -void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info, - uintptr_t pointer) { +static __ubsan_die_f *__ubsan_type_mismatch_handler( + struct UbsanTypeMismatchInfo *info, uintptr_t pointer) { const char *kind; char buf[512], *p = buf; - if (!pointer) __ubsan_abort(&info->location, "null pointer access"); + if (!pointer) return __ubsan_abort(&info->location, "null pointer access"); kind = __ubsan_dubnul(kUbsanTypeCheckKinds, info->type_check_kind); if (info->alignment && (pointer & (info->alignment - 1))) { p = __stpcpy(p, "unaligned "); @@ -258,48 +301,64 @@ void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info, p = __stpcpy(p, " align "); p = __intcpy(p, info->alignment); } else { - p = __stpcpy(p, "insufficient size\r\n\t"); + p = __stpcpy(p, "insufficient size "); p = __stpcpy(p, kind); p = __stpcpy(p, " address 0x"); p = __fixcpy(p, pointer, sizeof(pointer) * CHAR_BIT); p = __stpcpy(p, " with insufficient space for object of type "); p = __stpcpy(p, info->type->name); } - __ubsan_abort(&info->location, buf); + return __ubsan_abort(&info->location, buf); +} + +void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info, + uintptr_t pointer) { + __ubsan_type_mismatch_handler(info, pointer)(); + __ubsan_unreachable(); } void __ubsan_handle_type_mismatch_abort(struct UbsanTypeMismatchInfo *info, uintptr_t pointer) { - __ubsan_handle_type_mismatch(info, pointer); + __ubsan_type_mismatch_handler(info, pointer)(); + __ubsan_unreachable(); } -void __ubsan_handle_type_mismatch_v1( +static __ubsan_die_f *__ubsan_type_mismatch_v1_handler( struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) { struct UbsanTypeMismatchInfo mm; mm.location = type_mismatch->location; mm.type = type_mismatch->type; mm.alignment = 1u << type_mismatch->log_alignment; mm.type_check_kind = type_mismatch->type_check_kind; - __ubsan_handle_type_mismatch(&mm, pointer); + return __ubsan_type_mismatch_handler(&mm, pointer); +} + +void __ubsan_handle_type_mismatch_v1( + struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) { + __ubsan_type_mismatch_v1_handler(type_mismatch, pointer)(); + __ubsan_unreachable(); } void __ubsan_handle_type_mismatch_v1_abort( struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) { - __ubsan_handle_type_mismatch_v1(type_mismatch, pointer); + __ubsan_type_mismatch_v1_handler(type_mismatch, pointer)(); + __ubsan_unreachable(); } void __ubsan_handle_float_cast_overflow(void *data_raw, void *from_raw) { struct UbsanFloatCastOverflowData *data = (struct UbsanFloatCastOverflowData *)data_raw; #if __GNUC__ + 0 >= 6 - __ubsan_abort(&data->location, "float cast overflow"); + __ubsan_abort(&data->location, "float cast overflow")(); + __ubsan_unreachable(); #else const struct UbsanSourceLocation kUnknownLocation = { "", pushpop(0), pushpop(0), }; - __ubsan_abort(((void)data, &kUnknownLocation), "float cast overflow"); + __ubsan_abort(((void)data, &kUnknownLocation), "float cast overflow")(); + __ubsan_unreachable(); #endif } @@ -308,7 +367,8 @@ void __ubsan_handle_float_cast_overflow_abort(void *data_raw, void *from_raw) { } void __ubsan_handle_add_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "add overflow"); + __ubsan_abort(loc, "add overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_add_overflow_abort(const struct UbsanSourceLocation *loc) { @@ -317,7 +377,8 @@ void __ubsan_handle_add_overflow_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_alignment_assumption( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "alignment assumption"); + __ubsan_abort(loc, "alignment assumption")(); + __ubsan_unreachable(); } void __ubsan_handle_alignment_assumption_abort( @@ -326,7 +387,8 @@ void __ubsan_handle_alignment_assumption_abort( } void __ubsan_handle_builtin_unreachable(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "builtin unreachable"); + __ubsan_abort(loc, "builtin unreachable")(); + __ubsan_unreachable(); } void __ubsan_handle_builtin_unreachable_abort( @@ -335,7 +397,8 @@ void __ubsan_handle_builtin_unreachable_abort( } void __ubsan_handle_cfi_bad_type(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "cfi bad type"); + __ubsan_abort(loc, "cfi bad type")(); + __ubsan_unreachable(); } void __ubsan_handle_cfi_bad_type_abort(const struct UbsanSourceLocation *loc) { @@ -343,7 +406,8 @@ void __ubsan_handle_cfi_bad_type_abort(const struct UbsanSourceLocation *loc) { } void __ubsan_handle_cfi_check_fail(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "cfi check fail"); + __ubsan_abort(loc, "cfi check fail")(); + __ubsan_unreachable(); } void __ubsan_handle_cfi_check_fail_abort( @@ -352,7 +416,8 @@ void __ubsan_handle_cfi_check_fail_abort( } void __ubsan_handle_divrem_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "divrem overflow"); + __ubsan_abort(loc, "divrem overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_divrem_overflow_abort( @@ -362,7 +427,8 @@ void __ubsan_handle_divrem_overflow_abort( void __ubsan_handle_dynamic_type_cache_miss( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "dynamic type cache miss"); + __ubsan_abort(loc, "dynamic type cache miss")(); + __ubsan_unreachable(); } void __ubsan_handle_dynamic_type_cache_miss_abort( @@ -372,7 +438,8 @@ void __ubsan_handle_dynamic_type_cache_miss_abort( void __ubsan_handle_function_type_mismatch( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "function type mismatch"); + __ubsan_abort(loc, "function type mismatch")(); + __ubsan_unreachable(); } void __ubsan_handle_function_type_mismatch_abort( @@ -381,7 +448,8 @@ void __ubsan_handle_function_type_mismatch_abort( } void __ubsan_handle_implicit_conversion(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "implicit conversion"); + __ubsan_abort(loc, "implicit conversion")(); + __ubsan_unreachable(); } void __ubsan_handle_implicit_conversion_abort( @@ -390,7 +458,8 @@ void __ubsan_handle_implicit_conversion_abort( } void __ubsan_handle_invalid_builtin(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "invalid builtin"); + __ubsan_abort(loc, "invalid builtin")(); + __ubsan_unreachable(); } void __ubsan_handle_invalid_builtin_abort( @@ -399,7 +468,8 @@ void __ubsan_handle_invalid_builtin_abort( } void __ubsan_handle_load_invalid_value(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "load invalid value (uninitialized? bool∌[01]?)"); + __ubsan_abort(loc, "load invalid value (uninitialized? bool∌[01]?)")(); + __ubsan_unreachable(); } void __ubsan_handle_load_invalid_value_abort( @@ -408,7 +478,8 @@ void __ubsan_handle_load_invalid_value_abort( } void __ubsan_handle_missing_return(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "missing return"); + __ubsan_abort(loc, "missing return")(); + __ubsan_unreachable(); } void __ubsan_handle_missing_return_abort( @@ -417,7 +488,8 @@ void __ubsan_handle_missing_return_abort( } void __ubsan_handle_mul_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "multiply overflow"); + __ubsan_abort(loc, "multiply overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_mul_overflow_abort(const struct UbsanSourceLocation *loc) { @@ -425,7 +497,8 @@ void __ubsan_handle_mul_overflow_abort(const struct UbsanSourceLocation *loc) { } void __ubsan_handle_negate_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "negate overflow"); + __ubsan_abort(loc, "negate overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_negate_overflow_abort( @@ -434,24 +507,28 @@ void __ubsan_handle_negate_overflow_abort( } void __ubsan_handle_nonnull_arg(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "nonnull argument"); + __ubsan_warning(loc, "null argument here"); } void __ubsan_handle_nonnull_arg_abort(const struct UbsanSourceLocation *loc) { - __ubsan_handle_nonnull_arg(loc); + __ubsan_abort(loc, "nonnull argument")(); + __ubsan_unreachable(); } void __ubsan_handle_nonnull_return_v1(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "non-null return (v1)"); + __ubsan_abort(loc, "non-null return (v1)")(); + __ubsan_unreachable(); } void __ubsan_handle_nonnull_return_v1_abort( const struct UbsanSourceLocation *loc) { - __ubsan_handle_nonnull_return_v1(loc); + __ubsan_abort(loc, "non-null return (v1)")(); + __ubsan_unreachable(); } void __ubsan_handle_nullability_arg(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "nullability arg"); + __ubsan_abort(loc, "nullability arg")(); + __ubsan_unreachable(); } void __ubsan_handle_nullability_arg_abort( @@ -461,7 +538,8 @@ void __ubsan_handle_nullability_arg_abort( void __ubsan_handle_nullability_return_v1( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "nullability return (v1)"); + __ubsan_abort(loc, "nullability return (v1)")(); + __ubsan_unreachable(); } void __ubsan_handle_nullability_return_v1_abort( @@ -470,7 +548,8 @@ void __ubsan_handle_nullability_return_v1_abort( } void __ubsan_handle_pointer_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "pointer overflow"); + __ubsan_abort(loc, "pointer overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_pointer_overflow_abort( @@ -479,7 +558,8 @@ void __ubsan_handle_pointer_overflow_abort( } void __ubsan_handle_sub_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "subtract overflow"); + __ubsan_abort(loc, "subtract overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_sub_overflow_abort(const struct UbsanSourceLocation *loc) { @@ -488,7 +568,8 @@ void __ubsan_handle_sub_overflow_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_vla_bound_not_positive( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "vla bound not positive"); + __ubsan_abort(loc, "vla bound not positive")(); + __ubsan_unreachable(); } void __ubsan_handle_vla_bound_not_positive_abort( @@ -497,7 +578,8 @@ void __ubsan_handle_vla_bound_not_positive_abort( } void __ubsan_handle_nonnull_return(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "nonnull return"); + __ubsan_abort(loc, "nonnull return")(); + __ubsan_unreachable(); } void __ubsan_handle_nonnull_return_abort( @@ -514,3 +596,16 @@ void __ubsan_on_report(void) { void *__ubsan_get_current_report_data(void) { return 0; } + +static textstartup void ubsan_init() { + STRACE(" _ _ ____ ____ _ _ _"); + STRACE("| | | | __ ) ___| / \\ | \\ | |"); + STRACE("| | | | _ \\___ \\ / _ \\ | \\| |"); + STRACE("| |_| | |_) |__) / ___ \\| |\\ |"); + STRACE(" \\___/|____/____/_/ \\_\\_| \\_|"); + STRACE("cosmopolitan behavior module initialized"); +} + +const void *const ubsan_ctor[] initarray = { + ubsan_init, +}; diff --git a/libc/intrin/unmapviewoffile.greg.c b/libc/intrin/unmapviewoffile.greg.c new file mode 100644 index 000000000..aa7684fa0 --- /dev/null +++ b/libc/intrin/unmapviewoffile.greg.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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/memory.h" + +__msabi extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile; + +/** + * Unmaps memory created by MapViewOfFileEx(). + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 UnmapViewOfFile(const void *lpBaseAddress) { + bool32 ok; + ok = __imp_UnmapViewOfFile(lpBaseAddress); + if (!ok) __winerr(); + NTTRACE("UnmapViewOfFile(%p) → %hhhd% m", lpBaseAddress, ok); + return ok; +} diff --git a/libc/calls/vforked.c b/libc/intrin/vforked.c similarity index 100% rename from libc/calls/vforked.c rename to libc/intrin/vforked.c diff --git a/libc/intrin/virtualprotect.greg.c b/libc/intrin/virtualprotect.greg.c new file mode 100644 index 000000000..07fb6f747 --- /dev/null +++ b/libc/intrin/virtualprotect.greg.c @@ -0,0 +1,46 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/log/libfatal.internal.h" +#include "libc/nt/memory.h" + +__msabi extern typeof(VirtualProtect) *const __imp_VirtualProtect; + +/** + * Protects memory on the New Technology. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +textwindows bool32 VirtualProtect(void *lpAddress, uint64_t dwSize, + uint32_t flNewProtect, + uint32_t *lpflOldProtect) { + bool32 bOk; + char oldbuf[64]; + bOk = __imp_VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect); + if (bOk) { + __stpcpy(oldbuf, DescribeNtPageFlags(*lpflOldProtect)); + } else { + __winerr(); + __stpcpy(oldbuf, "n/a"); + } + NTTRACE("VirtualProtect(%p, %'zu, %s, [%s]) → %hhhd% m", lpAddress, dwSize, + DescribeNtPageFlags(flNewProtect), oldbuf, bOk); + return bOk; +} diff --git a/libc/intrin/waitformultipleobjects.greg.c b/libc/intrin/waitformultipleobjects.greg.c new file mode 100644 index 000000000..2b6aa0be0 --- /dev/null +++ b/libc/intrin/waitformultipleobjects.greg.c @@ -0,0 +1,39 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/synchronization.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(WaitForMultipleObjects) *const + __imp_WaitForMultipleObjects; + +/** + * Waits for handles to change status. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +uint32_t WaitForMultipleObjects(uint32_t nCount, const int64_t *lpHandles, + bool32 bWaitAll, uint32_t dwMilliseconds) { + uint32_t x; + x = __imp_WaitForMultipleObjects(nCount, lpHandles, bWaitAll, dwMilliseconds); + if (x == -1u) __winerr(); + POLLTRACE("WaitForMultipleObjects(%ld, %p, %hhhd, %'d) → %d% m", nCount, + lpHandles, bWaitAll, dwMilliseconds, x); + return x; +} diff --git a/libc/intrin/waitforsingleobject.greg.c b/libc/intrin/waitforsingleobject.greg.c new file mode 100644 index 000000000..d345ef17b --- /dev/null +++ b/libc/intrin/waitforsingleobject.greg.c @@ -0,0 +1,37 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/synchronization.h" +#include "libc/nt/thunk/msabi.h" + +__msabi extern typeof(WaitForSingleObject) *const __imp_WaitForSingleObject; + +/** + * Waits for handle to change status. + * @note this wrapper takes care of ABI, STRACE(), and __winerr() + */ +uint32_t WaitForSingleObject(int64_t hHandle, uint32_t dwMilliseconds) { + uint32_t rc; + rc = __imp_WaitForSingleObject(hHandle, dwMilliseconds); + if (rc == -1u) __winerr(); + POLLTRACE("WaitForSingleObject(%ld, %'d) → %d% m", hHandle, dwMilliseconds, + rc); + return rc; +} diff --git a/libc/calls/winerr.greg.c b/libc/intrin/winerr.greg.c similarity index 92% rename from libc/calls/winerr.greg.c rename to libc/intrin/winerr.greg.c index 45c8d37c4..80360fa62 100644 --- a/libc/calls/winerr.greg.c +++ b/libc/intrin/winerr.greg.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#define ShouldUseMsabiAttribute() 1 #include "libc/bits/weaken.h" #include "libc/dce.h" #include "libc/errno.h" @@ -30,16 +31,13 @@ * @return -1 w/ few exceptions * @note this is a code-size saving device */ -privileged noasan int64_t __winerr(void) { +privileged int64_t __winerr(void) { errno_t e; if (IsWindows()) { - e = GetLastError(); - if (weaken(__dos2errno)) { - e = weaken(__dos2errno)(e); - } - errno = e; - return -1; + e = __dos2errno(__imp_GetLastError()); } else { - return enosys(); + e = ENOSYS; } + errno = e; + return -1; } diff --git a/libc/intrin/winthread.c b/libc/intrin/winthread.c new file mode 100644 index 000000000..89c193fbe --- /dev/null +++ b/libc/intrin/winthread.c @@ -0,0 +1,38 @@ +/*-*- 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 2022 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/dce.h" +#include "libc/intrin/tls.h" +#include "libc/intrin/winthread.internal.h" + +/** + * @fileoverview TLS slot for clone() win32 polyfill. + */ + +int __winthread; + +static textstartup void __winthread_init(void) { + if (IsWindows()) { + __winthread = TlsAlloc(); + TlsSetValue(__winthread, 0); + } +} + +const void *const __winthread_ctor[] initarray = { + __winthread_init, +}; diff --git a/libc/intrin/winthread.internal.h b/libc/intrin/winthread.internal.h new file mode 100644 index 000000000..2464dbd58 --- /dev/null +++ b/libc/intrin/winthread.internal.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_WINTHREAD_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_WINTHREAD_INTERNAL_H_ +#include "libc/intrin/tls.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct WinThread { + int pid; +}; + +extern int __winthread; + +static inline struct WinThread *GetWinThread(void) { + return TlsGetValue(__winthread); +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_WINTHREAD_INTERNAL_H_ */ diff --git a/tool/decode/lib/x86gradenames.c b/libc/intrin/x86gradenames.c similarity index 100% rename from tool/decode/lib/x86gradenames.c rename to libc/intrin/x86gradenames.c diff --git a/tool/decode/lib/x86marchnames.c b/libc/intrin/x86marchnames.c similarity index 100% rename from tool/decode/lib/x86marchnames.c rename to libc/intrin/x86marchnames.c diff --git a/libc/inttypes.h b/libc/inttypes.h index 9d131be68..e996192bc 100644 --- a/libc/inttypes.h +++ b/libc/inttypes.h @@ -48,6 +48,8 @@ typedef __UINT_LEAST64_TYPE__ uint_least64_t; #define __PRI128 "ll" #elif __SIZEOF_INTMAX__ == 16 #define __PRI128 "j" +#else +#define __PRI128 "jj" #endif #if __SIZEOF_POINTER__ == __SIZEOF_INT__ diff --git a/libc/isystem/complex.h b/libc/isystem/complex.h index 8267a4409..1da2fa62f 100644 --- a/libc/isystem/complex.h +++ b/libc/isystem/complex.h @@ -1,4 +1,6 @@ #ifndef LIBC_ISYSTEM_COMPLEX_H_ #define LIBC_ISYSTEM_COMPLEX_H_ +#include "libc/complex.h" #include "libc/math.h" +#define I _Complex_I #endif diff --git a/libc/isystem/endian.h b/libc/isystem/endian.h index 60a154711..1104d2854 100644 --- a/libc/isystem/endian.h +++ b/libc/isystem/endian.h @@ -1,4 +1,10 @@ #ifndef LIBC_ISYSTEM_ENDIAN_H_ #define LIBC_ISYSTEM_ENDIAN_H_ + +#define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#define __BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#define __PDP_ENDIAN __ORDER_PDP_ENDIAN__ +#define __BYTE_ORDER __BYTE_ORDER__ + #include "libc/bits/newbie.h" -#endif +#endif /* LIBC_ISYSTEM_ENDIAN_H_ */ diff --git a/libc/isystem/features.h b/libc/isystem/features.h new file mode 100644 index 000000000..eb3f84a50 --- /dev/null +++ b/libc/isystem/features.h @@ -0,0 +1,38 @@ +#ifndef COSMOPOLITAN_LIBC_ISYSTEM_FEATURES_H_ +#define COSMOPOLITAN_LIBC_ISYSTEM_FEATURES_H_ + +#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE 1 +#endif + +#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE) +#define _BSD_SOURCE 1 +#endif + +#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) && \ + !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) && \ + !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__) +#define _BSD_SOURCE 1 +#define _XOPEN_SOURCE 700 +#endif + +#if __STDC_VERSION__ >= 199901L +#define __restrict restrict +#elif !defined(__GNUC__) +#define __restrict +#endif + +#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) +#define __inline inline +#elif !defined(__GNUC__) +#define __inline +#endif + +#if __STDC_VERSION__ >= 201112L +#elif defined(__GNUC__) +#define _Noreturn __attribute__((__noreturn__)) +#else +#define _Noreturn +#endif + +#endif /* COSMOPOLITAN_LIBC_ISYSTEM_FEATURES_H_ */ diff --git a/libc/isystem/stdint.h b/libc/isystem/stdint.h index 145c8eb9b..5a3dc2798 100644 --- a/libc/isystem/stdint.h +++ b/libc/isystem/stdint.h @@ -1,4 +1,5 @@ #ifndef LIBC_ISYSTEM_STDINT_H_ #define LIBC_ISYSTEM_STDINT_H_ +#include "libc/limits.h" #include "libc/literal.h" #endif diff --git a/libc/isystem/stdio.h b/libc/isystem/stdio.h index 8ef49a187..e227eda4d 100644 --- a/libc/isystem/stdio.h +++ b/libc/isystem/stdio.h @@ -1,6 +1,8 @@ #ifndef LIBC_ISYSTEM_STDIO_H_ #define LIBC_ISYSTEM_STDIO_H_ +#include "libc/calls/calls.h" #include "libc/fmt/fmt.h" #include "libc/log/log.h" #include "libc/stdio/stdio.h" +#include "libc/stdio/temp.h" #endif diff --git a/libc/isystem/stdlib.h b/libc/isystem/stdlib.h index b887d8453..96aa83a43 100644 --- a/libc/isystem/stdlib.h +++ b/libc/isystem/stdlib.h @@ -1,9 +1,11 @@ #ifndef LIBC_ISYSTEM_STDLIB_H_ #define LIBC_ISYSTEM_STDLIB_H_ +#include "libc/alg/alg.h" #include "libc/fmt/conv.h" #include "libc/mem/mem.h" #include "libc/rand/rand.h" #include "libc/runtime/runtime.h" #include "libc/stdio/temp.h" #include "libc/sysv/consts/exit.h" +#include "third_party/gdtoa/gdtoa.h" #endif diff --git a/libc/isystem/time.h b/libc/isystem/time.h index aabd49d7b..22484f93d 100644 --- a/libc/isystem/time.h +++ b/libc/isystem/time.h @@ -1,5 +1,6 @@ #ifndef LIBC_ISYSTEM_TIME_H_ #define LIBC_ISYSTEM_TIME_H_ #include "libc/sysv/consts/sched.h" +#include "libc/time/struct/tm.h" #include "libc/time/time.h" #endif diff --git a/libc/isystem/wchar.h b/libc/isystem/wchar.h index 2d3ecb03b..fd707abc8 100644 --- a/libc/isystem/wchar.h +++ b/libc/isystem/wchar.h @@ -1,4 +1,5 @@ #ifndef LIBC_ISYSTEM_WCHAR_H_ #define LIBC_ISYSTEM_WCHAR_H_ #include "libc/str/str.h" +#include "libc/time/time.h" #endif diff --git a/libc/isystem/windows.h b/libc/isystem/windows.h index c2571efea..ee92e29f4 100644 --- a/libc/isystem/windows.h +++ b/libc/isystem/windows.h @@ -250,6 +250,12 @@ #define HUMPD int64_t #define HWND int64_t +#define PDH_FUNCTION LONG + +#define PDH_HCOUNTER HANDLE +#define PDH_HQUERY HANDLE +#define PDH_HLOG HANDLE + #define ADDRESS_FAMILY uint16_t #define TUNNEL_TYPE uint32_t #define NET_IF_CONNECTION_TYPE uint32_t @@ -440,6 +446,9 @@ #define _FILE_FULL_EA_INFORMATION NtFileFullEaInformation #define FILE_FULL_EA_INFORMATION struct NtFileFullEaInformation #define PFILE_FULL_EA_INFORMATION struct NtFileFullEaInformation* +#define _PDH_FMT_COUNTERVALUE NtPdhFmtCountervalue +#define PDH_FMT_COUNTERVALUE struct NtPdhFmtCountervalue +#define PPDH_FMT_COUNTERVALUE struct NtPdhFmtCountervalue* #define _LUID NtLuid #define LUID struct NtLuid diff --git a/libc/libc.mk b/libc/libc.mk index 854099606..143b7aa7b 100644 --- a/libc/libc.mk +++ b/libc/libc.mk @@ -22,7 +22,6 @@ o/$(MODE)/libc: o/$(MODE)/libc/alg \ o/$(MODE)/libc/mem \ o/$(MODE)/libc/nexgen32e \ o/$(MODE)/libc/nt \ - o/$(MODE)/libc/ohmyplus \ o/$(MODE)/libc/rand \ o/$(MODE)/libc/runtime \ o/$(MODE)/libc/sock \ diff --git a/libc/limits.h b/libc/limits.h index cc2226918..65ff9286a 100644 --- a/libc/limits.h +++ b/libc/limits.h @@ -1,5 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_LIMITS_H_ #define COSMOPOLITAN_LIBC_LIMITS_H_ +#define __STDC_LIMIT_MACROS #define UCHAR_MIN 0 #define UCHAR_MAX 255 @@ -32,6 +33,8 @@ #define UINT16_MAX __UINT16_MAX__ #define UINT32_MAX __UINT32_MAX__ #define UINT64_MAX __UINT64_MAX__ +#define INTMAX_MAX __INTMAX_MAX__ +#define UINTMAX_MAX __UINTMAX_MAX__ #define SCHAR_MIN (-SCHAR_MAX - 1) #define SHRT_MIN (-SHRT_MAX - 1) @@ -70,27 +73,18 @@ #define UINT32_MIN 0u #define UINT64_MIN 0ull #define UINTPTR_MIN 0ull +#define UINTMAX_MIN ((uintmax_t)0) #define MB_CUR_MAX 4 #define MB_LEN_MAX 4 -#if !(__ASSEMBLER__ + __LINKER__ + 0) - #if __GNUC__ * 100 + __GNUC_MINOR__ >= 406 || defined(__llvm__) -#define INTMAX_MAX \ - (((intmax_t)0x7fffffffffffffff) << 64 | (intmax_t)0xffffffffffffffff) -#define UINTMAX_MAX \ - (((uintmax_t)0xffffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff) -#define INT128_MIN INTMAX_MIN -#define INT128_MAX INTMAX_MAX -#define UINTMAX_MIN ((uintmax_t)0) -#define UINT128_MIN ((uintmax_t)0) -#define UINT128_MAX UINTMAX_MAX -#else -#define INTMAX_MAX __INT64_MAX__ -#define UINTMAX_MAX __UINT64_MAX__ -#define UINTMAX_MIN UINT64_MIN +#define INT128_MIN (-INT128_MAX - 1) +#define UINT128_MIN ((uint128_t)0) +#define INT128_MAX \ + ((int128_t)0x7fffffffffffffff << 64 | (int128_t)0xffffffffffffffff) +#define UINT128_MAX \ + ((uint128_t)0xffffffffffffffff << 64 | (uint128_t)0xffffffffffffffff) #endif /* GCC 4.6+ */ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_LIMITS_H_ */ diff --git a/libc/literal.h b/libc/literal.h index d2f6ac077..d9ae4456a 100644 --- a/libc/literal.h +++ b/libc/literal.h @@ -1,5 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_LITERAL_H_ #define COSMOPOLITAN_LIBC_LITERAL_H_ +#define __STDC_CONSTANT_MACROS #ifdef __INT8_C #define INT8_C(c) __INT8_C(c) diff --git a/libc/log/addr2linepath.c b/libc/log/addr2linepath.c index b2af0c798..44b51de5a 100644 --- a/libc/log/addr2linepath.c +++ b/libc/log/addr2linepath.c @@ -18,6 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/log/log.h" -noasan const char *GetAddr2linePath(void) { +const char *GetAddr2linePath(void) { return commandvenv("ADDR2LINE", "addr2line"); } diff --git a/libc/log/appendresourcereport.c b/libc/log/appendresourcereport.c index b2d34f840..b48d1a315 100644 --- a/libc/log/appendresourcereport.c +++ b/libc/log/appendresourcereport.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" #include "libc/calls/struct/rusage.h" #include "libc/fmt/itoa.h" #include "libc/log/log.h" @@ -23,26 +24,35 @@ #include "libc/runtime/clktck.h" #include "libc/stdio/append.internal.h" -static void AppendInt(char **b, int64_t x) { - char buf[27], *e; - e = FormatInt64Thousands(buf, x); - appendd(b, buf, e - buf); +struct State { + char **b; + const char *nl; + char ibuf[27]; +}; + +static void AppendNl(struct State *s) { + appends(s->b, s->nl); } -static void AppendMetric(char **b, const char *s1, int64_t x, const char *s2, - const char *nl) { - appends(b, s1); - AppendInt(b, x); - appends(b, s2); - appends(b, nl); +static void AppendInt(struct State *s, int64_t x) { + char *e = FormatInt64Thousands(s->ibuf, x); + appendd(s->b, s->ibuf, e - s->ibuf); } -static void AppendUnit(char **b, int64_t x, const char *s) { - AppendInt(b, x); - appendw(b, ' '); - appends(b, s); +static void AppendMetric(struct State *s, const char *s1, int64_t x, + const char *s2) { + appends(s->b, s1); + AppendInt(s, x); + appends(s->b, s2); + AppendNl(s); +} + +static void AppendUnit(struct State *s, int64_t x, const char *t) { + AppendInt(s, x); + appendw(s->b, ' '); + appends(s->b, t); if (x == 1) { - appendw(b, 's'); + appendw(s->b, 's'); } } @@ -50,74 +60,82 @@ static void AppendUnit(char **b, int64_t x, const char *s) { * Generates process resource usage report. */ void AppendResourceReport(char **b, struct rusage *ru, const char *nl) { - char ibuf[27]; + struct State s; long utime, stime; long double ticks; + struct State *st = &s; + s.b = b; + s.nl = nl; + asm("" : "+r"(st)); if (ru->ru_maxrss) { - AppendMetric(b, "ballooned to ", ru->ru_maxrss, "kb in size", nl); + AppendMetric(st, "ballooned to ", ru->ru_maxrss, "kb in size"); } if ((utime = ru->ru_utime.tv_sec * 1000000 + ru->ru_utime.tv_usec) | (stime = ru->ru_stime.tv_sec * 1000000 + ru->ru_stime.tv_usec)) { appends(b, "needed "); - AppendInt(b, utime + stime); + AppendInt(st, utime + stime); appends(b, "us cpu ("); - AppendInt(b, (long double)stime / (utime + stime) * 100); + AppendInt(st, (long double)stime / (utime + stime) * 100); appends(b, "% kernel)"); - appends(b, nl); + AppendNl(st); ticks = ceill((long double)(utime + stime) / (1000000.L / CLK_TCK)); if (ru->ru_idrss) { - AppendMetric(b, "needed ", lroundl(ru->ru_idrss / ticks), - " memory on average", nl); + AppendMetric(st, "needed ", lroundl(ru->ru_idrss / ticks), + " memory on average"); } if (ru->ru_isrss) { - AppendMetric(b, "needed ", lroundl(ru->ru_isrss / ticks), - " stack on average", nl); + AppendMetric(st, "needed ", lroundl(ru->ru_isrss / ticks), + " stack on average"); } if (ru->ru_ixrss) { - AppendMetric(b, "needed ", lroundl(ru->ru_ixrss / ticks), - " shared on average", nl); + AppendMetric(st, "needed ", lroundl(ru->ru_ixrss / ticks), + " shared on average"); } } if (ru->ru_minflt || ru->ru_majflt) { appends(b, "caused "); - AppendInt(b, ru->ru_minflt + ru->ru_majflt); + AppendInt(st, ru->ru_minflt + ru->ru_majflt); appends(b, " page faults ("); AppendInt( - b, (long double)ru->ru_minflt / (ru->ru_minflt + ru->ru_majflt) * 100); + st, (long double)ru->ru_minflt / (ru->ru_minflt + ru->ru_majflt) * 100); appends(b, "% memcpy)"); - appends(b, nl); + AppendNl(st); } if (ru->ru_nvcsw + ru->ru_nivcsw > 1) { - AppendInt(b, ru->ru_nvcsw + ru->ru_nivcsw); - appends(b, " context switch ("); - AppendInt(b, + AppendInt(st, ru->ru_nvcsw + ru->ru_nivcsw); + appends(b, " context switch"); + if ((ru->ru_nvcsw + ru->ru_nivcsw) > 1) { + appendw(b, READ16LE("es")); + } + appendw(b, READ16LE(" (")); + AppendInt(st, (long double)ru->ru_nvcsw / (ru->ru_nvcsw + ru->ru_nivcsw) * 100); appends(b, "% consensual)"); - appends(b, nl); + AppendNl(st); } if (ru->ru_msgrcv || ru->ru_msgsnd) { appends(b, "received "); - AppendUnit(b, ru->ru_msgrcv, "message"); + AppendUnit(st, ru->ru_msgrcv, "message"); appends(b, " and sent "); - AppendInt(b, ru->ru_msgsnd); - appends(b, nl); + AppendInt(st, ru->ru_msgsnd); + AppendNl(st); } if (ru->ru_inblock || ru->ru_oublock) { appends(b, "performed "); - AppendUnit(b, ru->ru_inblock, "read"); + AppendUnit(st, ru->ru_inblock, "read"); appends(b, " and "); - AppendInt(b, ru->ru_oublock); + AppendInt(st, ru->ru_oublock); appends(b, " write i/o operations"); - appends(b, nl); + AppendNl(st); } if (ru->ru_nsignals) { appends(b, "received "); - AppendUnit(b, ru->ru_nsignals, "signal"); - appends(b, nl); + AppendUnit(st, ru->ru_nsignals, "signal"); + AppendNl(st); } if (ru->ru_nswap) { appends(b, "got swapped "); - AppendUnit(b, ru->ru_nswap, "time"); - appends(b, nl); + AppendUnit(st, ru->ru_nswap, "time"); + AppendNl(st); } } diff --git a/libc/log/attachdebugger.c b/libc/log/attachdebugger.c index 7dacf176a..7d5208182 100644 --- a/libc/log/attachdebugger.c +++ b/libc/log/attachdebugger.c @@ -19,6 +19,7 @@ #include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" #include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" #include "libc/log/color.internal.h" #include "libc/log/gdb.h" #include "libc/log/internal.h" @@ -41,7 +42,7 @@ * possible UX for debugging your app, for varying levels of available * information, on most of the various platforms. * - * Before calling this function, consider placing showcrashreports() in + * Before calling this function, consider placing ShowCrashReports() in * your main function and calling DebugBreak() wherever you want; it's * safer. Also note the "GDB" environment variable can be set to empty * string, as a fail-safe for disabling this behavior. @@ -50,17 +51,17 @@ * @return gdb pid if continuing, 0 if detached, or -1 w/ errno * @note this is called via eponymous spinlock macro wrapper */ -relegated int(attachdebugger)(intptr_t continuetoaddr) { +relegated int(AttachDebugger)(intptr_t continuetoaddr) { int pid, ttyfd; struct StackFrame *bp; char pidstr[11], breakcmd[40]; const char *se, *elf, *gdb, *rewind, *layout; - if (IsGenuineCosmo() || !(gdb = GetGdbPath()) || + __restore_tty(); + if (IsGenuineCosmo() || !(gdb = GetGdbPath()) || !isatty(0) || !isatty(1) || (ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC)) == -1) { return -1; } - __restore_tty(ttyfd); - snprintf(pidstr, sizeof(pidstr), "%u", getpid()); + ksnprintf(pidstr, sizeof(pidstr), "%u", getpid()); layout = "layout asm"; if ((elf = FindDebugBinary())) { se = "-se"; @@ -75,12 +76,12 @@ relegated int(attachdebugger)(intptr_t continuetoaddr) { continuetoaddr = bp->addr; } rewind = "-ex"; - snprintf(breakcmd, sizeof(breakcmd), "%s *%#p", "break", continuetoaddr); + ksnprintf(breakcmd, sizeof(breakcmd), "%s *%#p", "break", continuetoaddr); } else { rewind = NULL; breakcmd[0] = '\0'; } - if (!(pid = vfork())) { + if (!(pid = fork())) { dup2(ttyfd, 0); dup2(ttyfd, 1); execv(gdb, (char *const[]){ diff --git a/libc/log/backtrace2.c b/libc/log/backtrace2.c deleted file mode 100644 index e5bb6b764..000000000 --- a/libc/log/backtrace2.c +++ /dev/null @@ -1,194 +0,0 @@ -/*-*- 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 "libc/alg/alg.h" -#include "libc/alg/bisectcarleft.internal.h" -#include "libc/bits/safemacros.internal.h" -#include "libc/bits/weaken.h" -#include "libc/calls/calls.h" -#include "libc/calls/sigbits.h" -#include "libc/dce.h" -#include "libc/errno.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/fmt.h" -#include "libc/fmt/itoa.h" -#include "libc/log/backtrace.internal.h" -#include "libc/log/libfatal.internal.h" -#include "libc/log/log.h" -#include "libc/nexgen32e/gc.internal.h" -#include "libc/runtime/gc.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/stack.h" -#include "libc/runtime/symbols.internal.h" -#include "libc/stdio/append.internal.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/fileno.h" -#include "libc/sysv/consts/o.h" -#include "libc/sysv/consts/sig.h" -#include "libc/x/x.h" - -#define kBacktraceMaxFrames 128 -#define kBacktraceBufSize ((kBacktraceMaxFrames - 1) * (18 + 1)) - -static noasan int PrintBacktraceUsingAddr2line(int fd, - const struct StackFrame *bp) { - ssize_t got; - intptr_t addr; - size_t i, j, gi; - int ws, pid, pipefds[2]; - struct Garbages *garbage; - sigset_t chldmask, savemask; - const struct StackFrame *frame; - char *debugbin, *p1, *p2, *p3, *addr2line; - char buf[kBacktraceBufSize], *argv[kBacktraceMaxFrames]; - if (IsOpenbsd()) return -1; - if (IsWindows()) return -1; - if (!(debugbin = FindDebugBinary())) return -1; - if (!(addr2line = GetAddr2linePath())) return -1; - i = 0; - j = 0; - argv[i++] = "addr2line"; - argv[i++] = "-a"; /* filter out w/ shell script wrapper for old versions */ - argv[i++] = "-pCife"; - argv[i++] = debugbin; - garbage = weaken(__garbage); - gi = garbage ? garbage->i : 0; - for (frame = bp; frame && i < kBacktraceMaxFrames - 1; frame = frame->next) { - if (!IsValidStackFramePointer(frame)) { - return -1; - } - addr = frame->addr; - if (addr == weakaddr("__gc")) { - do { - --gi; - } while ((addr = garbage->p[gi].ret) == weakaddr("__gc")); - } - argv[i++] = buf + j; - buf[j++] = '0'; - buf[j++] = 'x'; - j += uint64toarray_radix16(addr - 1, buf + j) + 1; - } - argv[i++] = NULL; - sigemptyset(&chldmask); - sigaddset(&chldmask, SIGCHLD); - sigprocmask(SIG_BLOCK, &chldmask, &savemask); - pipe(pipefds); - if (!(pid = vfork())) { - sigprocmask(SIG_SETMASK, &savemask, NULL); - dup2(pipefds[1], 1); - close(pipefds[0]); - close(pipefds[1]); - execvp(addr2line, argv); - _exit(127); - } - close(pipefds[1]); - while ((got = read(pipefds[0], buf, kBacktraceBufSize)) > 0) { - p1 = buf; - p3 = p1 + got; - - /* - * Remove deep libc error reporting facilities from backtraces. - * - * For example, if the following shows up in Emacs: - * - * 40d097: __die at libc/log/die.c:33 - * 434daa: __asan_die at libc/intrin/asan.c:483 - * 435146: __asan_report_memory_fault at libc/intrin/asan.c:524 - * 435b32: __asan_report_store at libc/intrin/asan.c:719 - * 43472e: __asan_report_store1 at libc/intrin/somanyasan.S:118 - * 40c3a9: GetCipherSuite at net/https/getciphersuite.c:80 - * 4383a5: GetCipherSuite_test at test/net/https/getciphersuite.c:23 - * ... - * - * Then it's unpleasant to need to press C-x C-n six times. - */ -#if 0 - while ((p2 = memchr(p1, '\n', p3 - p1))) { - if (memmem(p1, p2 - p1, ": __asan_", 9) || - memmem(p1, p2 - p1, ": __die", 7)) { - memmove(p1, p2 + 1, p3 - (p2 + 1)); - p3 -= p2 + 1 - p1; - } else { - p1 = p2 + 1; - break; - } - } -#endif - - /* - * remove racist output from gnu tooling, that can't be disabled - * otherwise, since it breaks other tools like emacs that aren't - * equipped to ignore it, and what's most problematic is that - * addr2line somehow manages to put the racism onto the one line - * in the backtrace we actually care about. - */ - for (got = p3 - buf, p1 = buf; got;) { - if ((p2 = memmem(p1, got, " (discriminator ", - strlen(" (discriminator ") - 1)) && - (p3 = memchr(p2, '\n', got - (p2 - p1)))) { - if (p3 > p2 && p3[-1] == '\r') --p3; - __write(p1, p2 - p1); - got -= p3 - p1; - p1 += p3 - p1; - } else { - __write(p1, got); - break; - } - } - } - close(pipefds[0]); - while (waitpid(pid, &ws, 0) == -1) { - if (errno == EINTR) continue; - return -1; - } - sigprocmask(SIG_SETMASK, &savemask, NULL); - if (WIFEXITED(ws) && !WEXITSTATUS(ws)) { - return 0; - } else { - return -1; - } -} - -static noasan int PrintBacktrace(int fd, const struct StackFrame *bp) { - if (!IsTiny()) { - if (PrintBacktraceUsingAddr2line(fd, bp) != -1) { - return 0; - } - } - return PrintBacktraceUsingSymbols(fd, bp, GetSymbolTable()); -} - -noasan void ShowBacktrace(int fd, const struct StackFrame *bp) { -#ifdef __FNO_OMIT_FRAME_POINTER__ - /* asan runtime depends on this function */ - static bool noreentry; - ++g_ftrace; - if (!bp) bp = __builtin_frame_address(0); - if (!noreentry) { - noreentry = true; - PrintBacktrace(fd, bp); - noreentry = false; - } - --g_ftrace; -#else - __printf("ShowBacktrace() needs these flags to show C backtrace:\n" - "\t-D__FNO_OMIT_FRAME_POINTER__\n" - "\t-fno-omit-frame-pointer\n"); -#endif -} diff --git a/libc/log/backtrace2.greg.c b/libc/log/backtrace2.greg.c new file mode 100644 index 000000000..376a2a580 --- /dev/null +++ b/libc/log/backtrace2.greg.c @@ -0,0 +1,191 @@ +/*-*- 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 "libc/alg/alg.h" +#include "libc/alg/bisectcarleft.internal.h" +#include "libc/bits/safemacros.internal.h" +#include "libc/bits/weaken.h" +#include "libc/calls/calls.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/fmt/conv.h" +#include "libc/fmt/fmt.h" +#include "libc/fmt/itoa.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/backtrace.internal.h" +#include "libc/log/color.internal.h" +#include "libc/log/libfatal.internal.h" +#include "libc/log/log.h" +#include "libc/nexgen32e/gc.internal.h" +#include "libc/runtime/gc.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/stack.h" +#include "libc/runtime/symbols.internal.h" +#include "libc/stdio/append.internal.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/sig.h" +#include "libc/x/x.h" + +#define kBacktraceMaxFrames 128 +#define kBacktraceBufSize ((kBacktraceMaxFrames - 1) * (18 + 1)) + +static void ShowHint(const char *s) { + kprintf("%snote: %s%s\n", SUBTLE, s, RESET); +} + +static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { + ssize_t got; + intptr_t addr; + size_t i, j, gi; + int ws, pid, pipefds[2]; + struct Garbages *garbage; + const struct StackFrame *frame; + char *debugbin, *p1, *p2, *p3, *addr2line; + char buf[kBacktraceBufSize], *argv[kBacktraceMaxFrames]; + + if (!(debugbin = FindDebugBinary())) { + return -1; + } + + if (!(addr2line = GetAddr2linePath())) { + if (IsLinux()) { + ShowHint("can't find addr2line on path or in ADDR2LINE"); + } + return -1; + } + + /* + * DWARF is a weak standard. Platforms that use LLVM or old GNU + * usually can't be counted upon to print backtraces correctly. + */ + if (!IsLinux() && !IsWindows()) { + ShowHint("won't print addr2line backtrace because probably llvm"); + return -1; + } + + i = 0; + j = 0; + argv[i++] = "addr2line"; + argv[i++] = "-a"; /* filter out w/ shell script wrapper for old versions */ + argv[i++] = "-pCife"; + argv[i++] = debugbin; + garbage = weaken(__garbage); + gi = garbage ? garbage->i : 0; + for (frame = bp; frame && i < kBacktraceMaxFrames - 1; frame = frame->next) { + if (!IsValidStackFramePointer(frame)) { + return -1; + } + addr = frame->addr; + if (addr == weakaddr("__gc")) { + do { + --gi; + } while ((addr = garbage->p[gi].ret) == weakaddr("__gc")); + } + argv[i++] = buf + j; + buf[j++] = '0'; + buf[j++] = 'x'; + j += uint64toarray_radix16(addr - 1, buf + j) + 1; + } + argv[i++] = NULL; + pipe(pipefds); + if (!(pid = vfork())) { + dup2(pipefds[1], 1); + if (pipefds[0] != 1) close(pipefds[0]); + if (pipefds[1] != 1) close(pipefds[1]); + execve(addr2line, argv, environ); + _exit(127); + } + close(pipefds[1]); + for (;;) { + got = read(pipefds[0], buf, kBacktraceBufSize); + if (!got) break; + if (got == -1 && errno == EINTR) { + errno = 0; + continue; + } + if (got == -1) { + kprintf("error reading backtrace %m\n"); + break; + } + p1 = buf; + p3 = p1 + got; + /* + * remove racist output from gnu tooling, that can't be disabled + * otherwise, since it breaks other tools like emacs that aren't + * equipped to ignore it, and what's most problematic is that + * addr2line somehow manages to put the racism onto the one line + * in the backtrace we actually care about. + */ + for (got = p3 - buf, p1 = buf; got;) { + if ((p2 = memmem(p1, got, " (discriminator ", + strlen(" (discriminator ") - 1)) && + (p3 = memchr(p2, '\n', got - (p2 - p1)))) { + if (p3 > p2 && p3[-1] == '\r') --p3; + __write(p1, p2 - p1); + got -= p3 - p1; + p1 += p3 - p1; + } else { + __write(p1, got); + break; + } + } + } + close(pipefds[0]); + while (waitpid(pid, &ws, 0) == -1) { + if (errno == EINTR) continue; + return -1; + } + if (WIFEXITED(ws) && !WEXITSTATUS(ws)) { + return 0; + } else { + return -1; + } +} + +static int PrintBacktrace(int fd, const struct StackFrame *bp) { + if (!IsTiny() && !__isworker) { + if (PrintBacktraceUsingAddr2line(fd, bp) != -1) { + return 0; + } + } + return PrintBacktraceUsingSymbols(fd, bp, GetSymbolTable()); +} + +void ShowBacktrace(int fd, const struct StackFrame *bp) { +#ifdef __FNO_OMIT_FRAME_POINTER__ + /* asan runtime depends on this function */ + int st, ft; + st = __strace, __strace = 0; + ft = g_ftrace, g_ftrace = 0; + if (!bp) bp = __builtin_frame_address(0); + + PrintBacktrace(fd, bp); + + __strace = st; + g_ftrace = ft; +#else + (fprintf)(stderr, "ShowBacktrace() needs these flags to show C backtrace:\n" + "\t-D__FNO_OMIT_FRAME_POINTER__\n" + "\t-fno-omit-frame-pointer\n"); +#endif +} diff --git a/libc/log/backtrace3.c b/libc/log/backtrace3.c deleted file mode 100644 index ed2fc87d4..000000000 --- a/libc/log/backtrace3.c +++ /dev/null @@ -1,93 +0,0 @@ -/*-*- 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 "libc/alg/bisectcarleft.internal.h" -#include "libc/assert.h" -#include "libc/bits/weaken.h" -#include "libc/calls/calls.h" -#include "libc/fmt/fmt.h" -#include "libc/fmt/itoa.h" -#include "libc/log/backtrace.internal.h" -#include "libc/log/libfatal.internal.h" -#include "libc/macros.internal.h" -#include "libc/nexgen32e/gc.internal.h" -#include "libc/nexgen32e/stackframe.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/symbols.internal.h" -#include "libc/str/str.h" - -#define LIMIT 100 - -/** - * Prints stack frames with symbols. - * - * PrintBacktraceUsingSymbols(STDOUT_FILENO, NULL, GetSymbolTable()); - * - * @param f is output stream - * @param bp is rbp which can be NULL to detect automatically - * @param st is open symbol table for current executable - * @return -1 w/ errno if error happened - */ -noinstrument noasan int PrintBacktraceUsingSymbols(int fd, - const struct StackFrame *bp, - struct SymbolTable *st) { - size_t gi; - intptr_t addr; - int i, symbol, addend; - struct Garbages *garbage; - const struct StackFrame *frame; - ++g_ftrace; - if (!bp) bp = __builtin_frame_address(0); - garbage = weaken(__garbage); - gi = garbage ? garbage->i : 0; - for (i = 0, frame = bp; frame; frame = frame->next) { - if (!IsValidStackFramePointer(frame)) { - __printf("%p corrupt frame pointer\n", frame); - break; - } - if (++i == LIMIT) { - __printf("\n"); - break; - } - addr = frame->addr; - if (addr == weakaddr("__gc")) { - do { - --gi; - } while ((addr = garbage->p[gi].ret) == weakaddr("__gc")); - } - /* - * we subtract one to handle the case of noreturn functions with a - * call instruction at the end, since %rip in such cases will point - * to the start of the next function. generally %rip always points - * to the byte after the instruction. one exception is in case like - * __restore_rt where the kernel creates a stack frame that points - * to the beginning of the function. - */ - if ((symbol = __get_symbol(st, addr - 1)) != -1 || - (symbol = __get_symbol(st, addr - 0)) != -1) { - addend = addr - st->addr_base; - addend -= st->symbols[symbol].x; - } else { - addend = 0; - } - __printf("%p %p %s%+d\r\n", frame, addr, __get_symbol_name(st, symbol), - addend); - } - --g_ftrace; - return 0; -} diff --git a/libc/log/backtrace3.greg.c b/libc/log/backtrace3.greg.c new file mode 100644 index 000000000..e1857751e --- /dev/null +++ b/libc/log/backtrace3.greg.c @@ -0,0 +1,91 @@ +/*-*- 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 "libc/alg/bisectcarleft.internal.h" +#include "libc/assert.h" +#include "libc/bits/weaken.h" +#include "libc/calls/calls.h" +#include "libc/fmt/fmt.h" +#include "libc/fmt/itoa.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/backtrace.internal.h" +#include "libc/macros.internal.h" +#include "libc/nexgen32e/gc.internal.h" +#include "libc/nexgen32e/stackframe.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.internal.h" +#include "libc/str/str.h" + +#define LIMIT 100 + +/** + * Prints stack frames with symbols. + * + * PrintBacktraceUsingSymbols(STDOUT_FILENO, NULL, GetSymbolTable()); + * + * @param f is output stream + * @param bp is rbp which can be NULL to detect automatically + * @param st is open symbol table for current executable + * @return -1 w/ errno if error happened + */ +noinstrument noasan int PrintBacktraceUsingSymbols(int fd, + const struct StackFrame *bp, + struct SymbolTable *st) { + size_t gi; + intptr_t addr; + int i, symbol, addend; + struct Garbages *garbage; + const struct StackFrame *frame; + if (!bp) bp = __builtin_frame_address(0); + garbage = weaken(__garbage); + gi = garbage ? garbage->i : 0; + for (i = 0, frame = bp; frame; frame = frame->next) { + if (!IsValidStackFramePointer(frame)) { + kprintf("%p corrupt frame pointer\n", frame); + break; + } + if (++i == LIMIT) { + kprintf("\n"); + break; + } + addr = frame->addr; + if (addr == weakaddr("__gc")) { + do { + --gi; + } while ((addr = garbage->p[gi].ret) == weakaddr("__gc")); + } + /* + * we subtract one to handle the case of noreturn functions with a + * call instruction at the end, since %rip in such cases will point + * to the start of the next function. generally %rip always points + * to the byte after the instruction. one exception is in case like + * __restore_rt where the kernel creates a stack frame that points + * to the beginning of the function. + */ + if ((symbol = __get_symbol(st, addr - 1)) != -1 || + (symbol = __get_symbol(st, addr - 0)) != -1) { + addend = addr - st->addr_base; + addend -= st->symbols[symbol].x; + } else { + addend = 0; + } + kprintf("%012lx %012lx %s%+d\n", frame, addr, __get_symbol_name(st, symbol), + addend); + } + return 0; +} diff --git a/libc/log/cancolor.c b/libc/log/cancolor.c deleted file mode 100644 index b4f144afe..000000000 --- a/libc/log/cancolor.c +++ /dev/null @@ -1,60 +0,0 @@ -/*-*- 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 "libc/bits/safemacros.internal.h" -#include "libc/calls/calls.h" -#include "libc/dce.h" -#include "libc/log/color.internal.h" -#include "libc/log/log.h" -#include "libc/nt/enum/version.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" - -/** - * Returns true if ANSI terminal colors are appropriate. - * - * We take an optimistic approach here. We use colors, unless we see the - * environment variable TERM=dumb, which is set by software like Emacs. - * It's a common antipattern to check isatty(STDERR_FILENO), since that - * usually makes colors harder to get than they are to remove: - * - * sed 's/\x1b\[[;[:digit:]]*m//g' uncolor.txt - * - * Ideally, all software should be updated to understand color, since - * it's been formally standardized nearly as long as ASCII. Even old - * MS-DOS supports it (but Windows didn't until Windows 10) yet even - * tools like less may need wrapper scripts, e.g.: - * - * #!/bin/sh - * LESSCHARSET=UTF-8 exec /usr/bin/less -RS "$@" - * - * It's that easy fam. - */ -bool cancolor(void) { - static bool once; - static bool result; - return 1; - if (!once) { - result = (!IsWindows() || NtGetVersion() >= kNtVersionWindows10 || - !ischardev(1)) && - !!strcmp(nulltoempty(getenv("DONTANSIMEBRO")), "1") && - !!strcmp(nulltoempty(getenv("TERM")), "dumb"); - once = true; - } - return result; -} diff --git a/libc/log/checkfail.c b/libc/log/checkfail.c index 7d5d38f04..d98055e7e 100644 --- a/libc/log/checkfail.c +++ b/libc/log/checkfail.c @@ -18,14 +18,20 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" #include "libc/errno.h" #include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" #include "libc/log/check.h" #include "libc/log/color.internal.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" #include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" + +STATIC_YOINK("strerror_wr"); /** * Handles failure of CHECK_xx() macros. @@ -39,60 +45,29 @@ relegated void __check_fail(const char *suffix, const char *opstr, size_t i; va_list va; char hostname[32]; + __strace = 0; + g_ftrace = 0; e = errno; - p = __fatalbuf; __start_fatal(file, line); __stpcpy(hostname, "unknown"); gethostname(hostname, sizeof(hostname)); - p = __stpcpy(p, "check failed on "); - p = __stpcpy(p, hostname); - p = __stpcpy(p, " pid "); - p = __intcpy(p, __getpid()); - p = __stpcpy(p, "\n"); - p = __stpcpy(p, "\tCHECK_"); - for (; *suffix; ++suffix) { - *p++ = *suffix - ('a' <= *suffix && *suffix <= 'z') * 32; - } - p = __stpcpy(p, "("); - p = __stpcpy(p, wantstr); - p = __stpcpy(p, ", "); - p = __stpcpy(p, gotstr); - p = __stpcpy(p, ");\n\t\t → 0x"); - p = __hexcpy(p, want); - p = __stpcpy(p, " ("); - p = __stpcpy(p, wantstr); - p = __stpcpy(p, ")\n\t\t"); - p = __stpcpy(p, opstr); - p = __stpcpy(p, " 0x"); - p = __hexcpy(p, got); - p = __stpcpy(p, " ("); - p = __stpcpy(p, gotstr); - p = __stpcpy(p, ")\n"); + kprintf("check failed on %s pid %d\n", hostname, getpid()); + kprintf("\tCHECK_%^s(%s, %s);\n", suffix, wantstr, gotstr); + kprintf("\t\t → %p (%s)\n", want, wantstr); + kprintf("\t\t%s %p (%s)\n", opstr, got, gotstr); if (!isempty(fmt)) { - *p++ = '\t'; + kprintf("\t"); va_start(va, fmt); - p += (vsprintf)(p, fmt, va); + kvprintf(fmt, va); va_end(va); - *p++ = '\n'; + kprintf("\n"); } - p = __stpcpy(p, "\t"); - p = __stpcpy(p, strerror(e)); - p = __stpcpy(p, "\n\t"); - p = __stpcpy(p, SUBTLE); - p = __stpcpy(p, program_invocation_name); - if (__argc > 1) p = __stpcpy(p, " \\"); - p = __stpcpy(p, RESET); - p = __stpcpy(p, "\n"); - __write(__fatalbuf, p - __fatalbuf); + kprintf("\t%m\n\t%s%s", SUBTLE, program_invocation_name); for (i = 1; i < __argc; ++i) { - p = __fatalbuf; - p = __stpcpy(p, "\t\t"); - p = __stpcpy(p, __argv[i]); - if (i < __argc - 1) p = __stpcpy(p, " \\"); - p = __stpcpy(p, "\n"); + kprintf(" %s", __argv[i]); } + kprintf("%s\n", RESET); if (!IsTiny() && e == ENOMEM) { - __write("\n", 1); PrintMemoryIntervals(2, &_mmi); } __die(); diff --git a/libc/log/checkfail_ndebug.c b/libc/log/checkfail_ndebug.c index 7217e487d..410364304 100644 --- a/libc/log/checkfail_ndebug.c +++ b/libc/log/checkfail_ndebug.c @@ -18,8 +18,9 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/errno.h" #include "libc/log/internal.h" -#include "libc/log/libfatal.internal.h" +#include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" #include "libc/str/str.h" /** @@ -34,9 +35,10 @@ */ relegated void ___check_fail_ndebug(uint64_t want, uint64_t got, const char *opchar) { - __restore_tty(1); - __printf("\n%serror: %s: check failed: 0x%x %s 0x%x (%s)\n", - !g_isterminalinarticulate ? "\e[J" : "", program_invocation_name, - want, opchar, got, strerror(errno)); - exit(1); + __restore_tty(); + (fprintf)(stderr, "\n%serror: %s: check failed: 0x%x %s 0x%x (%s)\n", + !__nocolor ? "\e[J" : "", program_invocation_name, want, opchar, + got, strerror(errno)); + __restorewintty(); + _Exit(68); } diff --git a/libc/log/color.internal.h b/libc/log/color.internal.h index 05c7cb564..663e554b9 100644 --- a/libc/log/color.internal.h +++ b/libc/log/color.internal.h @@ -1,20 +1,17 @@ #ifndef COSMOPOLITAN_LIBC_LOG_COLOR_H_ #define COSMOPOLITAN_LIBC_LOG_COLOR_H_ +#include "libc/log/internal.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -#define CLS (cancolor() ? "\r\e[J" : "") -#define RED (cancolor() ? "\e[30;101m" : "") -#define GREEN (cancolor() ? "\e[32m" : "") -#define UNBOLD (cancolor() ? "\e[22m" : "") -#define RED2 (cancolor() ? "\e[91;1m" : "") -#define BLUE1 (cancolor() ? "\e[94;49m" : "") -#define BLUE2 (cancolor() ? "\e[34m" : "") -#define RESET (cancolor() ? "\e[0m" : "") -#define SUBTLE (cancolor() ? "\e[35m" : "") +#define CLS (!__nocolor ? "\r\e[J" : "") +#define RED (!__nocolor ? "\e[30;101m" : "") +#define GREEN (!__nocolor ? "\e[32m" : "") +#define UNBOLD (!__nocolor ? "\e[22m" : "") +#define RED2 (!__nocolor ? "\e[91;1m" : "") +#define BLUE1 (!__nocolor ? "\e[94;49m" : "") +#define BLUE2 (!__nocolor ? "\e[34m" : "") +#define RESET (!__nocolor ? "\e[0m" : "") +#define SUBTLE (!__nocolor ? "\e[35m" : "") -bool cancolor(void) nothrow nocallback nosideeffect; - -COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_LOG_COLOR_H_ */ diff --git a/libc/log/commandvenv.c b/libc/log/commandvenv.c index 4b1712a38..5586e8cfc 100644 --- a/libc/log/commandvenv.c +++ b/libc/log/commandvenv.c @@ -45,7 +45,7 @@ * or the environment variable was empty; noting that the caller * should copy this string before saving it */ -noasan const char *commandvenv(const char *var, const char *cmd) { +const char *commandvenv(const char *var, const char *cmd) { const char *exepath; static char pathbuf[PATH_MAX]; if (*cmd == '/' || *cmd == '\\') return cmd; @@ -57,5 +57,5 @@ noasan const char *commandvenv(const char *var, const char *cmd) { return NULL; } } - return commandv(cmd, pathbuf); + return commandv(cmd, pathbuf, sizeof(pathbuf)); } diff --git a/libc/log/countbranch.h b/libc/log/countbranch.h index b8d79e6a6..f396bf30a 100644 --- a/libc/log/countbranch.h +++ b/libc/log/countbranch.h @@ -1,12 +1,12 @@ #ifndef COSMOPOLITAN_LIBC_LOG_COUNTBRANCH_H_ #define COSMOPOLITAN_LIBC_LOG_COUNTBRANCH_H_ +#include "libc/macros.internal.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#include "libc/macros.internal.h" #define COUNTBRANCH(x) COUNTBRANCH_(x, #x, STRINGIFY(__FILE__), __LINE__) #define COUNTBRANCH_(x, xs, file, line) \ - COUNTBRANCH__(x, STRINGIFY(xs), STRINGIFY(#x), file, line) + COUNTBRANCH__(x, STRINGIFY(xs), STRINGIFY(xs), file, line) #define COUNTBRANCH__(x, xs, xss, file, line) \ ({ \ bool Cond; \ @@ -46,7 +46,7 @@ struct countbranch { const char *code; const char *xcode; const char *file; - int line; + long line; }; extern struct countbranch countbranch_data[]; diff --git a/libc/log/countbranch_data.S b/libc/log/countbranch_data.S index 31d781b21..0d6aa76d9 100644 --- a/libc/log/countbranch_data.S +++ b/libc/log/countbranch_data.S @@ -22,6 +22,7 @@ .section .sort.data.countbranch.1,"a",@progbits .align 8 + .underrun .globl countbranch_data countbranch_data: .previous @@ -31,4 +32,5 @@ countbranch_data: .rept 5 .quad -1 .endr + .overrun .previous diff --git a/libc/log/countbranch_report.c b/libc/log/countbranch_report.c index 5a6b70985..b3a1864ee 100644 --- a/libc/log/countbranch_report.c +++ b/libc/log/countbranch_report.c @@ -18,8 +18,10 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/alg/alg.h" #include "libc/calls/calls.h" +#include "libc/intrin/kprintf.h" #include "libc/log/countbranch.h" #include "libc/macros.internal.h" +#include "libc/math.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" @@ -35,7 +37,7 @@ static double GetPercent(const struct countbranch *p) { } } -static double RankCounter(const struct countbranch *p) { +static int RankCounter(const struct countbranch *p) { double x; x = GetPercent(p); x = MIN(x, 100 - x); @@ -65,18 +67,28 @@ static void SortCounters(size_t n) { } void countbranch_report(void) { + double r; size_t i, n; + int pct, nines; struct countbranch *p; n = CountCounters(); SortCounters(n); for (i = n; i--;) { p = countbranch_data + i; - if (strcmp(p->code, p->xcode)) { - dprintf(2, "%s:%d: %g%% taken (%,ld/%,ld) %s [%s]\n", p->file, p->line, - GetPercent(p), p->taken, p->total, p->code, p->xcode); + if (p->total) { + r = (double)p->taken / p->total; + pct = floor(r * 100); + nines = floor(fmod(r * 100, 1) * 100000); } else { - dprintf(2, "%s:%d: %g%% taken (%,ld/%,ld) %s\n", p->file, p->line, - GetPercent(p), p->taken, p->total, p->code); + pct = 0; + nines = 0; + } + if (strcmp(p->code, p->xcode)) { + kprintf("%s:%-4d: %3d.%05d%% taken (%'ld/%'ld) %s [%s]\n", p->file, + p->line, pct, nines, p->taken, p->total, p->code, p->xcode); + } else { + kprintf("%s:%-4d: %3d.%05d%% taken (%'ld/%'ld) %s\n", p->file, p->line, + pct, nines, p->taken, p->total, p->code); } } } diff --git a/libc/log/countexpr.h b/libc/log/countexpr.h new file mode 100644 index 000000000..967c329ef --- /dev/null +++ b/libc/log/countexpr.h @@ -0,0 +1,85 @@ +#ifndef COSMOPOLITAN_LIBC_LOG_COUNTEXPR_H_ +#define COSMOPOLITAN_LIBC_LOG_COUNTEXPR_H_ +#include "libc/macros.internal.h" +#include "libc/nexgen32e/bench.h" +#include "libc/nexgen32e/bsr.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * Shows nanosecond timings histogram for expr at exit(). + */ +#define COUNTEXPR(expr) \ + COUNTEXPR_(expr, #expr, STRINGIFY(__FILE__), __LINE__, rdtsc, rdtsc, \ + "COUNTEXPR") + +/** + * Like COUNTEXPR() but can be used on function calls that return void. + */ +#define COUNTSTMT(stmt) \ + (void)COUNTEXPR_((stmt, 0), #stmt, STRINGIFY(__FILE__), __LINE__, rdtsc, \ + rdtsc, "COUNTSTMT") + +/** + * Same as COUNTEXPR() but uses Intel's expensive measurement technique. + */ +#define BENCHEXPR(expr) \ + COUNTEXPR_(expr, #expr, STRINGIFY(__FILE__), __LINE__, __startbench, \ + __endbench, "BENCHEXPR") + +#define COUNTEXPR_(expr, code, file, line, start, stop, macro) \ + COUNTEXPR__(expr, STRINGIFY(code), file, line, start, stop, STRINGIFY(macro)) + +#define COUNTEXPR__(expr, code, file, line, start, stop, macro) \ + ({ \ + struct countexpr *InfO; \ + uint64_t t1_, t2_, TiCkS, NaNoS; \ + t1_ = start(); \ + asm volatile("" ::: "memory"); \ + autotype(expr) ReS = (expr); \ + asm volatile("" ::: "memory"); \ + t2_ = stop(); \ + TiCkS = t2_ >= t1_ ? t2_ - t1_ : ~t1_ + t2_ + 1; \ + asm(".section .rodata.str1.1,\"aMS\",@progbits,1\n\t" \ + ".align\t1\n" \ + "31340:\t.asciz\t" file "\n\t" \ + "31338:\t.asciz\t" code "\n" \ + "31332:\t.asciz\t" macro "\n" \ + ".previous\n\t" \ + ".section .yoink\n\t" \ + "nopl\tcountexpr_data(%%rip)\n\t" \ + ".previous\n\t" \ + ".section .sort.data.countexpr.2,\"a\",@progbits\n\t" \ + ".align\t8\n31337:\t" \ + ".quad\t" #line "\n\t" \ + ".quad\t31340b\n\t" \ + ".quad\t31338b\n\t" \ + ".quad\t31332b\n\t" \ + ".rept\t65\n\t" \ + ".quad\t0\n\t" \ + ".endr\n\t" \ + ".previous\n\t" \ + "lea\t31337b(%%rip),%0" \ + : "=r"(InfO)); \ + /* approximation of round(x*.323018) which is usually */ \ + /* the ratio, between x86 rdtsc ticks and nanoseconds */ \ + NaNoS = (TiCkS * 338709) >> 20; \ + ++InfO->logos[NaNoS ? bsrl(NaNoS) + 1 : 0]; \ + ReS; \ + }) + +struct countexpr { + long line; /* zero for last entry */ + const char *file; + const char *code; + const char *macro; + long logos[65]; +}; + +extern struct countexpr countexpr_data[]; + +void countexpr_report(void); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_LOG_COUNTEXPR_H_ */ diff --git a/libc/log/countexpr_data.S b/libc/log/countexpr_data.S new file mode 100644 index 000000000..2a80d41de --- /dev/null +++ b/libc/log/countexpr_data.S @@ -0,0 +1,35 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/macros.internal.h" +#include "libc/notice.inc" + + .yoink countexpr_report + + .section .sort.data.countexpr.1,"a",@progbits + .align 8 + .globl countexpr_data + .underrun +countexpr_data: + .previous + + .section .sort.data.countexpr.3,"a",@progbits + .align 8 + .quad 0 + .overrun + .previous diff --git a/libc/log/countexpr_report.c b/libc/log/countexpr_report.c new file mode 100644 index 000000000..f3ffbec0b --- /dev/null +++ b/libc/log/countexpr_report.c @@ -0,0 +1,82 @@ +/*-*- 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/alg/alg.h" +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/intrin/kprintf.h" +#include "libc/limits.h" +#include "libc/log/countexpr.h" +#include "libc/macros.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" + +static long GetLongSum(const long *h, size_t n) { + long t; + size_t i; + for (t = i = 0; i < n; ++i) { + if (__builtin_add_overflow(t, h[i], &t)) { + t = LONG_MAX; + break; + } + } + return t; +} + +static size_t GetRowCount(const long *h, size_t n) { + while (n && !h[n - 1]) --n; + return n; +} + +static void PrintHistogram(const long *h, size_t n, long t) { + size_t i; + long j, p; + char s[101]; + unsigned long logos; + for (i = 0; i < n; ++i) { + p = (h[i] * 10000 + (t >> 1)) / t; + assert(0 <= p && p <= 10000); + if (p) { + for (j = 0; j < p / 100; ++j) s[j] = '#'; + s[j] = 0; + logos = i ? 1ul << (i - 1) : 0; + kprintf("%'12lu %'16ld %3d.%02d%% %s\n", logos, h[i], p / 100, p % 100, + s); + } + } +} + +void countexpr_report(void) { + long hits; + struct countexpr *p; + for (p = countexpr_data; p->line; ++p) { + if ((hits = GetLongSum(p->logos, 64))) { + kprintf("%s:%d: %s(%s) %'ld hits\n", p->file, p->line, p->macro, p->code, + hits); + PrintHistogram(p->logos, 64, hits); + } + } +} + +static textstartup void countexpr_init() { + atexit(countexpr_report); +} + +const void *const countexpr_ctor[] initarray = { + countexpr_init, +}; diff --git a/libc/log/die.c b/libc/log/die.c index 8893584a6..ac36f77ad 100644 --- a/libc/log/die.c +++ b/libc/log/die.c @@ -16,12 +16,13 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" #include "libc/dce.h" +#include "libc/intrin/lockcmpxchg.h" #include "libc/log/backtrace.internal.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" +#include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" /** @@ -31,15 +32,18 @@ */ relegated wontreturn void __die(void) { /* asan runtime depends on this function */ + int rc; static bool once; - if (cmpxchg(&once, false, true)) { - __restore_tty(1); + if (_lockcmpxchg(&once, false, true)) { + __restore_tty(); if (IsDebuggerPresent(false)) { DebugBreak(); } ShowBacktrace(2, NULL); - quick_exit(77); + rc = 77; + } else { + rc = 78; } - __write_str("PANIC: __DIE() DIED\r\n"); - _Exit(78); + __restorewintty(); + _Exit(rc); } diff --git a/libc/log/gdb.h b/libc/log/gdb.h index 0eccb440e..0444a8f45 100644 --- a/libc/log/gdb.h +++ b/libc/log/gdb.h @@ -18,10 +18,10 @@ COSMOPOLITAN_C_START_ extern volatile int g_gdbsync; int gdbexec(const char *); -int attachdebugger(intptr_t); +int AttachDebugger(intptr_t); -#define attachdebugger(CONTINUE_TO_ADDR) /* shorten backtraces */ \ - SYNCHRONIZE_DEBUGGER((attachdebugger)(CONTINUE_TO_ADDR)) +#define AttachDebugger(CONTINUE_TO_ADDR) /* shorten backtraces */ \ + SYNCHRONIZE_DEBUGGER((AttachDebugger)(CONTINUE_TO_ADDR)) #define SYNCHRONIZE_DEBUGGER(PID) \ ({ \ @@ -40,20 +40,20 @@ int attachdebugger(intptr_t); Pid; \ }) -#define __inline_wait4(PID, OPT_OUT_WSTATUS, OPTIONS, OPT_OUT_RUSAGE) \ - ({ \ - int64_t WaAx; \ - if (!IsWindows()) { \ - asm volatile("mov\t%5,%%r10\n\t" \ - "syscall" \ - : "=a"(WaAx) \ - : "0"(__NR_wait4), "D"(PID), "S"(OPT_OUT_WSTATUS), \ - "d"(OPTIONS), "g"(OPT_OUT_RUSAGE) \ - : "rcx", "r10", "r11", "cc", "memory"); \ - } else { \ +#define __inline_wait4(PID, OPT_OUT_WSTATUS, OPTIONS, OPT_OUT_RUSAGE) \ + ({ \ + int64_t WaAx; \ + if (!IsWindows()) { \ + asm volatile("mov\t%5,%%r10\n\t" \ + "syscall" \ + : "=a"(WaAx) \ + : "0"(__NR_wait4), "D"(PID), "S"(OPT_OUT_WSTATUS), \ + "d"(OPTIONS), "g"(OPT_OUT_RUSAGE) \ + : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"); \ + } else { \ WaAx = sys_wait4_nt(PID, OPT_OUT_WSTATUS, OPTIONS, OPT_OUT_RUSAGE); \ - } \ - WaAx; \ + } \ + WaAx; \ }) COSMOPOLITAN_C_END_ diff --git a/libc/log/getsicodename.c b/libc/log/getsicodename.c index e7427681e..9b07cd8f1 100644 --- a/libc/log/getsicodename.c +++ b/libc/log/getsicodename.c @@ -82,6 +82,8 @@ const char *GetSiCodeName(int sig, int si_code) { strcpy(b + 5, "MAPERR"); /* address not mapped to object */ } else if (si_code == SEGV_ACCERR) { strcpy(b + 5, "ACCERR"); /* invalid permissions for mapped object */ + } else if (si_code == SEGV_PKUERR) { + strcpy(b + 5, "PKUERR"); /* FreeBSD: x86: PKU violation */ } } else if (sig == SIGFPE) { strcpy(b, "FPE_???"); @@ -129,10 +131,12 @@ const char *GetSiCodeName(int sig, int si_code) { strcpy(b + 4, "ADRERR"); /* non-existent physical address */ } else if (si_code == BUS_OBJERR) { strcpy(b + 4, "OBJERR"); /* object specific hardware error */ + } else if (si_code == BUS_OOMERR) { + strcpy(b + 4, "OOMERR"); /* FreeBSD */ } else if (si_code == BUS_MCEERR_AR) { - strcpy(b + 4, "BUS_AR"); /* Linux 2.6.32+ */ + strcpy(b + 4, "MCEERR_AR"); /* Linux 2.6.32+ */ } else if (si_code == BUS_MCEERR_AO) { - strcpy(b + 4, "BUS_AO"); /* Linux 2.6.32+ */ + strcpy(b + 4, "MCEERR_AO"); /* Linux 2.6.32+ */ } } else if (sig == SIGIO) { strcpy(b, "POLL_???"); diff --git a/libc/log/getsymboltable.c b/libc/log/getsymboltable.c deleted file mode 100644 index c8388f2df..000000000 --- a/libc/log/getsymboltable.c +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- 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 "libc/calls/calls.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/symbols.internal.h" - -/** - * Returns debug binary symbol table, as global singleton. - * @return symbol table, or NULL w/ errno on first call - */ -noasan struct SymbolTable *GetSymbolTable(void) { - /* asan runtime depends on this function */ - static bool once; - static struct SymbolTable *singleton; - const char *debugbin; - if (!once) { - once = true; - ++g_ftrace; - singleton = OpenSymbolTable(FindDebugBinary()); - --g_ftrace; - } - return singleton; -} diff --git a/libc/log/getttysize.c b/libc/log/getttysize.c index b9ef3c65a..a50731924 100644 --- a/libc/log/getttysize.c +++ b/libc/log/getttysize.c @@ -20,6 +20,7 @@ #include "libc/calls/calls.h" #include "libc/calls/termios.h" #include "libc/fmt/conv.h" +#include "libc/log/internal.h" #include "libc/log/log.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/termios.h" @@ -34,7 +35,7 @@ * @returns -1 on error or something else on success */ int getttysize(int fd, struct winsize *out) { - if (IsTerminalInarticulate()) { + if (__nocolor) { out->ws_col = strtoimax(firstnonnull(getenv("COLUMNS"), "80"), NULL, 0); out->ws_row = strtoimax(firstnonnull(getenv("ROWS"), "40"), NULL, 0); out->ws_xpixel = 0; diff --git a/libc/log/internal.h b/libc/log/internal.h index 298911be3..14a644ca8 100644 --- a/libc/log/internal.h +++ b/libc/log/internal.h @@ -7,15 +7,14 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern hidden int kCrashSigs[8]; +extern hidden bool __nocolor; +extern hidden int kCrashSigs[7]; extern hidden bool g_isrunningundermake; -extern hidden bool g_isterminalinarticulate; -extern hidden struct termios g_oldtermios; -extern hidden struct sigaction g_oldcrashacts[8]; +extern hidden struct sigaction g_oldcrashacts[7]; void __start_fatal(const char *, int) hidden; void __oncrash(int, struct siginfo *, struct ucontext *) relegated; -void __restore_tty(int); +void __restore_tty(void); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/log/leaks.c b/libc/log/leaks.c new file mode 100644 index 000000000..0f61dda6a --- /dev/null +++ b/libc/log/leaks.c @@ -0,0 +1,117 @@ +/*-*- 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/bits/bits.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/lockcmpxchg.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/testlib/testlib.h" + +STATIC_YOINK("__get_symbol_by_addr"); + +#define MAXLEAKS 1000 + +static bool once; +static bool hasleaks; + +static noasan void CheckLeak(void *x, void *y, size_t n, void *a) { + if (n) { + if (IsAsan()) { + if (__asan_get_heap_size(x)) { + hasleaks = true; + } + } else { + hasleaks = true; + } + } +} + +static noasan void OnMemory(void *x, void *y, size_t n, void *a) { + static int i; + if (n) { + if (MAXLEAKS) { + if (i < MAXLEAKS) { + ++i; + kprintf("%p %,lu bytes [dlmalloc]", x, n); + if (IsAsan()) { + __asan_print_trace(x); + } + kprintf("\n"); + } else if (i == MAXLEAKS) { + ++i; + kprintf("etc. etc.\n"); + } + } + } +} + +static noasan bool HasLeaks(void) { + malloc_inspect_all(CheckLeak, 0); + return hasleaks; +} + +/** + * Tests for memory leaks. + * + * This function needs to call __cxa_finalize(). Therefore any runtime + * services that depend on malloc() cannot be used, after calling this + * function. + */ +noasan void CheckForMemoryLeaks(void) { + struct mallinfo mi; + if (!_lockcmpxchg(&once, false, true)) { + kprintf("CheckForMemoryLeaks() may only be called once\n"); + exit(1); + } + __cxa_finalize(0); + STRACE("checking for memory leaks% m"); + if (!IsAsan()) { + /* TODO(jart): How can we make this work without ASAN? */ + return; + } + malloc_trim(0); + if (HasLeaks()) { + mi = mallinfo(); + kprintf("\n" + "UNFREED MEMORY\n" + "%s\n" + "max allocated space %,*d\n" + "total allocated space %,*d\n" + "total free space %,*d\n" + "releasable space %,*d\n" + "mmaped space %,*d\n" + "non-mmapped space %,*d\n" + "\n", + __argv[0], 16l, mi.usmblks, 16l, mi.uordblks, 16l, mi.fordblks, 16l, + mi.hblkhd, 16l, mi.keepcost, 16l, mi.arena); + if (!IsAsan()) { + kprintf("# NOTE: Use `make -j8 MODE=dbg` for malloc() backtraces\n"); + } + malloc_inspect_all(OnMemory, 0); + kprintf("\n"); + PrintMemoryIntervals(2, &_mmi); + /* PrintSystemMappings(2); */ + /* PrintGarbage(); */ + __restorewintty(); + _Exit(78); + } +} diff --git a/libc/log/libfatal.internal.h b/libc/log/libfatal.internal.h index 264c43a8f..eb723f5e6 100644 --- a/libc/log/libfatal.internal.h +++ b/libc/log/libfatal.internal.h @@ -11,10 +11,9 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern char __fatalbuf[]; +#define __ToUpper(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c)) -void __printf(const char *, ...); -void __vprintf(const char *, va_list); +extern char __fatalbuf[]; forceinline long __sysv_exit(long rc) { long ax; @@ -116,8 +115,6 @@ forceinline int __getpid(void) { } forceinline ssize_t __write(const void *p, size_t n) { - char cf; - ssize_t rc; uint32_t wrote; if (!IsWindows()) { return __sysv_write(2, p, n); @@ -160,25 +157,23 @@ forceinline void *__repstosb(void *di, char al, size_t cx) { : "0"(di), "1"(cx), "a"(al)); return di; #else - size_t i; volatile char *volatile d = di; while (cx--) *d++ = al; - return d; + return (void *)d; #endif } -forceinline void *__repmovsb(void *di, void *si, size_t cx) { +forceinline void *__repmovsb(void *di, const void *si, size_t cx) { #if defined(__x86__) && defined(__GNUC__) && !defined(__STRICT_ANSI__) asm("rep movsb" : "=D"(di), "=S"(si), "=c"(cx), "=m"(*(char(*)[cx])di) : "0"(di), "1"(si), "2"(cx), "m"(*(char(*)[cx])si)); return di; #else - size_t i; volatile char *volatile d = di; volatile char *volatile s = si; while (cx--) *d++ = *s++; - return d; + return (void *)d; #endif } @@ -247,6 +242,20 @@ forceinline char *__strstr(const char *haystack, const char *needle) { return 0; } +forceinline char16_t *__strstr16(const char16_t *haystack, + const char16_t *needle) { + size_t i; + for (;;) { + for (i = 0;; ++i) { + if (!needle[i]) return (/*unconst*/ char16_t *)haystack; + if (!haystack[i]) break; + if (needle[i] != haystack[i]) break; + } + if (!*haystack++) break; + } + return 0; +} + forceinline char *__getenv(char **p, const char *s) { size_t i, j; if (p) { @@ -258,7 +267,7 @@ forceinline char *__getenv(char **p, const char *s) { } break; } - if (s[j] != p[i][j]) { + if ((s[j] & 255) != __ToUpper(p[i][j] & 255)) { break; } } @@ -267,6 +276,14 @@ forceinline char *__getenv(char **p, const char *s) { return 0; } +forceinline const char *__strchr(const char *s, unsigned char c) { + char *r; + for (;; ++s) { + if ((*s & 255) == c) return s; + if (!*s) return 0; + } +} + forceinline unsigned long __atoul(const char *p) { int c; unsigned long x = 0; diff --git a/libc/log/log.h b/libc/log/log.h index dac2adc47..3c804d0a1 100644 --- a/libc/log/log.h +++ b/libc/log/log.h @@ -4,6 +4,7 @@ #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/winsize.h" +#include "libc/errno.h" #include "libc/nexgen32e/stackframe.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" @@ -58,6 +59,7 @@ void AppendResourceReport(char **, struct rusage *, const char *); char *__get_symbol_by_addr(int64_t); void PrintGarbage(void); void PrintGarbageNumeric(FILE *); +void CheckForMemoryLeaks(void); #define showcrashreports() ShowCrashReports() @@ -75,15 +77,15 @@ extern unsigned __log_level; /* log level for runtime check */ // log a message with the specified log level (not checking if LOGGABLE) #define LOGF(LEVEL, FMT, ...) \ do { \ - ++g_ftrace; \ - flogf(LEVEL, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + flogf(LEVEL, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } while (0) // die with an error message without backtrace and debugger invocation #define DIEF(FMT, ...) \ do { \ - ++g_ftrace; \ + --g_ftrace; \ flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ exit(1); \ unreachable; \ @@ -91,7 +93,7 @@ extern unsigned __log_level; /* log level for runtime check */ #define FATALF(FMT, ...) \ do { \ - ++g_ftrace; \ + --g_ftrace; \ ffatalf(kLogFatal, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ unreachable; \ } while (0) @@ -99,78 +101,78 @@ extern unsigned __log_level; /* log level for runtime check */ #define ERRORF(FMT, ...) \ do { \ if (LOGGABLE(kLogError)) { \ - ++g_ftrace; \ - flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define WARNF(FMT, ...) \ do { \ if (LOGGABLE(kLogWarn)) { \ - ++g_ftrace; \ - flogf(kLogWarn, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + flogf(kLogWarn, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define INFOF(FMT, ...) \ do { \ if (LOGGABLE(kLogInfo)) { \ - ++g_ftrace; \ - flogf(kLogInfo, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + flogf(kLogInfo, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define VERBOSEF(FMT, ...) \ do { \ if (LOGGABLE(kLogVerbose)) { \ - ++g_ftrace; \ - fverbosef(kLogVerbose, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + fverbosef(kLogVerbose, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define DEBUGF(FMT, ...) \ do { \ if (UNLIKELY(LOGGABLE(kLogDebug))) { \ - ++g_ftrace; \ - fdebugf(kLogDebug, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + fdebugf(kLogDebug, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define NOISEF(FMT, ...) \ do { \ if (UNLIKELY(LOGGABLE(kLogNoise))) { \ - ++g_ftrace; \ - fnoisef(kLogNoise, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + fnoisef(kLogNoise, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define FLOGF(F, FMT, ...) \ do { \ if (LOGGABLE(kLogInfo)) { \ - ++g_ftrace; \ - flogf(kLogInfo, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + flogf(kLogInfo, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define FWARNF(F, FMT, ...) \ do { \ if (LOGGABLE(kLogWarn)) { \ - ++g_ftrace; \ - flogf(kLogWarn, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + flogf(kLogWarn, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define FFATALF(F, FMT, ...) \ do { \ - ++g_ftrace; \ + --g_ftrace; \ ffatalf(kLogFatal, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ unreachable; \ } while (0) @@ -178,18 +180,18 @@ extern unsigned __log_level; /* log level for runtime check */ #define FDEBUGF(F, FMT, ...) \ do { \ if (UNLIKELY(LOGGABLE(kLogDebug))) { \ - ++g_ftrace; \ - fdebugf(kLogDebug, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + fdebugf(kLogDebug, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) #define FNOISEF(F, FMT, ...) \ do { \ if (UNLIKELY(LOGGABLE(kLogNoise))) { \ - ++g_ftrace; \ - fnoisef(kLogNoise, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ --g_ftrace; \ + fnoisef(kLogNoise, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \ + ++g_ftrace; \ } \ } while (0) @@ -199,22 +201,26 @@ extern unsigned __log_level; /* log level for runtime check */ #define LOGIFNEG1(FORM) \ ({ \ + int e = errno; \ autotype(FORM) Ax = (FORM); \ if (UNLIKELY(Ax == (typeof(Ax))(-1)) && LOGGABLE(kLogWarn)) { \ - ++g_ftrace; \ - __logerrno(__FILE__, __LINE__, #FORM); \ --g_ftrace; \ + __logerrno(__FILE__, __LINE__, #FORM); \ + ++g_ftrace; \ + errno = e; \ } \ Ax; \ }) #define LOGIFNULL(FORM) \ ({ \ + int e = errno; \ autotype(FORM) Ax = (FORM); \ if (Ax == NULL && LOGGABLE(kLogWarn)) { \ - ++g_ftrace; \ - __logerrno(__FILE__, __LINE__, #FORM); \ --g_ftrace; \ + __logerrno(__FILE__, __LINE__, #FORM); \ + ++g_ftrace; \ + errno = e; \ } \ Ax; \ }) diff --git a/libc/log/log.mk b/libc/log/log.mk index 9f3494c5c..593dd3982 100644 --- a/libc/log/log.mk +++ b/libc/log/log.mk @@ -41,6 +41,7 @@ LIBC_LOG_A_DIRECTDEPS = \ LIBC_STR \ LIBC_STUBS \ LIBC_SYSV \ + LIBC_SYSV_CALLS \ LIBC_TIME \ LIBC_TINYMATH \ LIBC_UNICODE \ @@ -58,11 +59,16 @@ $(LIBC_LOG_A).pkg: \ $(LIBC_LOG_A_OBJS) \ $(foreach x,$(LIBC_LOG_A_DIRECTDEPS),$($(x)_A).pkg) -o/$(MODE)/libc/log/backtrace2.o \ -o/$(MODE)/libc/log/backtrace3.o: \ +o/$(MODE)/libc/log/backtrace2.greg.o \ +o/$(MODE)/libc/log/backtrace3.greg.o: \ OVERRIDE_CFLAGS += \ -fno-sanitize=all +o/$(MODE)/libc/log/checkfail.o: \ + OVERRIDE_CFLAGS += \ + -mgeneral-regs-only + +o/$(MODE)/libc/log/restoretty.greg.o \ o/$(MODE)/libc/log/attachdebugger.o \ o/$(MODE)/libc/log/backtrace2.o \ o/$(MODE)/libc/log/backtrace3.o \ @@ -70,7 +76,6 @@ o/$(MODE)/libc/log/checkaligned.o \ o/$(MODE)/libc/log/checkfail.o \ o/$(MODE)/libc/log/checkfail_ndebug.o \ o/$(MODE)/libc/log/getsymboltable.o \ -o/$(MODE)/libc/log/cancolor.o \ o/$(MODE)/libc/log/restoretty.o \ o/$(MODE)/libc/log/oncrash.o \ o/$(MODE)/libc/log/onkill.o \ diff --git a/libc/log/loglevel.S b/libc/log/loglevel.S index a823b7e50..b2f70029a 100644 --- a/libc/log/loglevel.S +++ b/libc/log/loglevel.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/log/log.h" #include "libc/macros.internal.h" -.source __FILE__ .bss .align 4 diff --git a/libc/log/malloc_stats.c b/libc/log/malloc_stats.c index f57f049df..4a5612e99 100644 --- a/libc/log/malloc_stats.c +++ b/libc/log/malloc_stats.c @@ -17,12 +17,8 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/mem/mem.h" -#include "libc/stdio/stdio.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" +#include "third_party/dlmalloc/dlmalloc.h" void malloc_stats(void) { - struct MallocStats res = dlmalloc_stats(g_dlmalloc); - (fprintf)(stderr, "max system bytes = %'10zu\n", res.maxfp); - (fprintf)(stderr, "system bytes = %'10zu\n", res.fp); - (fprintf)(stderr, "in use bytes = %'10zu\n", res.used); + dlmalloc_stats(); } diff --git a/libc/log/oncrash.c b/libc/log/oncrash.c index 81b32fec7..b46452bd5 100644 --- a/libc/log/oncrash.c +++ b/libc/log/oncrash.c @@ -16,49 +16,34 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" #include "libc/bits/weaken.h" #include "libc/calls/calls.h" +#include "libc/calls/internal.h" #include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/sigaction.h" -#include "libc/calls/struct/siginfo.h" -#include "libc/calls/struct/termios.h" -#include "libc/calls/struct/utsname.h" -#include "libc/calls/termios.h" -#include "libc/calls/ucontext.h" -#include "libc/dce.h" #include "libc/errno.h" -#include "libc/fmt/fmt.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/lockcmpxchg.h" #include "libc/log/backtrace.internal.h" -#include "libc/log/color.internal.h" #include "libc/log/gdb.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" #include "libc/macros.internal.h" -#include "libc/nexgen32e/bsr.h" #include "libc/nexgen32e/stackframe.h" -#include "libc/nt/process.h" -#include "libc/nt/runtime.h" #include "libc/runtime/internal.h" -#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/pc.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/stack.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/auxv.h" -#include "libc/sysv/consts/fileno.h" -#include "libc/sysv/consts/nr.h" -#include "libc/sysv/consts/o.h" -#include "libc/sysv/consts/sig.h" -#include "libc/sysv/consts/termios.h" /** * @fileoverview Abnormal termination handling & GUI debugging. * @see libc/onkill.c */ +STATIC_YOINK("strerror_wr"); /* for kprintf %m */ +STATIC_YOINK("strsignal"); /* for kprintf %G */ + static const char kGregOrder[17] forcealign(1) = { 13, 11, 8, 14, 12, 9, 10, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, }; @@ -71,38 +56,14 @@ static const char kGregNames[17][4] forcealign(1) = { static const char kCpuFlags[12] forcealign(1) = "CVPRAKZSTIDO"; static const char kFpuExceptions[6] forcealign(1) = "IDZOUP"; -/* : showcrashreports.c, oncrashthunks.S, oncrash.c */ -int kCrashSigs[8]; -struct sigaction g_oldcrashacts[8]; -static const char kCrashSigNames[8][5] forcealign(1) = { - "QUIT", // - "FPE", // - "ILL", // - "SEGV", // - "TRAP", // - "ABRT", // - "BUS", // - "PIPE", // -}; -/* : showcrashreports.c, oncrashthunks.S, oncrash.c */ - -relegated static const char *TinyStrSignal(int sig) { - size_t i; - for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) { - if (kCrashSigs[i] && sig == kCrashSigs[i]) { - return kCrashSigNames[i]; - } - } - return "???"; -} +int kCrashSigs[7]; +struct sigaction g_oldcrashacts[7]; relegated static void ShowFunctionCalls(ucontext_t *ctx) { struct StackFrame *bp; struct StackFrame goodframe; if (!ctx->uc_mcontext.rip) { - __printf("%s is NULL can't show backtrace\n", "RIP"); - } else if (!ctx->uc_mcontext.rbp) { - __printf("%s is NULL can't show backtrace\n", "RBP"); + kprintf("%s is NULL can't show backtrace\n", "RIP"); } else { goodframe.next = (struct StackFrame *)ctx->uc_mcontext.rbp; goodframe.addr = ctx->uc_mcontext.rip; @@ -153,7 +114,7 @@ relegated static void ShowGeneralRegisters(ucontext_t *ctx) { long double st; char *p, buf[128]; p = buf; - *p++ = '\n'; + kprintf("\n"); for (i = 0, j = 0, k = 0; i < ARRAYLEN(kGregNames); ++i) { if (j > 0) *p++ = ' '; if (!(s = kGregNames[(unsigned)kGregOrder[i]])[2]) *p++ = ' '; @@ -172,24 +133,24 @@ relegated static void ShowGeneralRegisters(ucontext_t *ctx) { x = st * 1000; if (x < 0) x = -x, *p++ = '-'; p = __uintcpy(p, x / 1000), *p++ = '.'; - p = __uintcpy(p, x % 1000), *p++ = '\n'; + p = __uintcpy(p, x % 1000); *p = 0; - __printf("%s", buf); + kprintf("%s\n", buf); p = buf; } } DescribeCpuFlags( - p, ctx->uc_mcontext.gregs[REG_EFL], + p, ctx->uc_mcontext.eflags, ctx->uc_mcontext.fpregs ? ctx->uc_mcontext.fpregs->swd : 0, ctx->uc_mcontext.fpregs ? ctx->uc_mcontext.fpregs->mxcsr : 0); - __printf("%s\n", buf); + kprintf("%s\n", buf); } relegated static void ShowSseRegisters(ucontext_t *ctx) { size_t i; char *p, buf[128]; if (ctx->uc_mcontext.fpregs) { - __printf("\n"); + kprintf("\n"); for (i = 0; i < 8; ++i) { p = buf; if (i >= 10) { @@ -214,7 +175,7 @@ relegated static void ShowSseRegisters(ucontext_t *ctx) { p = __fixcpy(p, ctx->uc_mcontext.fpregs->xmm[i + 8].u64[1], 64); p = __fixcpy(p, ctx->uc_mcontext.fpregs->xmm[i + 8].u64[0], 64); *p = 0; - __printf("XMM%s\n", buf); + kprintf("XMM%s\n", buf); } } } @@ -226,48 +187,48 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si, int i; char *p; char host[64]; - intptr_t stackaddr; struct utsname names; static char buf[4096]; if (weaken(ShowCrashReportHook)) { ShowCrashReportHook(2, err, sig, si, ctx); } + names.sysname[0] = 0; + names.release[0] = 0; + names.version[0] = 0; + names.nodename[0] = 0; __stpcpy(host, "unknown"); gethostname(host, sizeof(host)); + uname(&names); p = buf; - __printf("\n%serror%s: Uncaught SIG%s", - !g_isterminalinarticulate ? "\e[30;101m" : "", - !g_isterminalinarticulate ? "\e[0m" : "", TinyStrSignal(sig)); - stackaddr = GetStackAddr(0); - if (ctx && (ctx->uc_mcontext.rsp >= GetStaticStackAddr(0) && - ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + PAGESIZE)) { - __printf(" (Stack Overflow)"); - } else if (si) { - __printf(" (%s)", GetSiCodeName(sig, si->si_code)); - } - __printf(" on %s pid %d\n %s\n %s\n", host, __getpid(), - program_invocation_name, strerror(err)); - if (uname(&names) != -1) { - __printf(" %s %s %s %s\n", names.sysname, names.nodename, names.release, - names.version); - } + errno = err; + kprintf("\n%serror%s: Uncaught %G (%s) on %s pid %d\n" + " %s\n" + " %m\n" + " %s %s %s %s\n", + !__nocolor ? "\e[30;101m" : "", !__nocolor ? "\e[0m" : "", sig, + (ctx && (ctx->uc_mcontext.rsp >= GetStaticStackAddr(0) && + ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + PAGESIZE)) + ? "Stack Overflow" + : GetSiCodeName(sig, si->si_code), + host, getpid(), program_invocation_name, names.sysname, names.version, + names.nodename, names.release); if (ctx) { - __printf("\n"); + kprintf("\n"); ShowFunctionCalls(ctx); ShowGeneralRegisters(ctx); ShowSseRegisters(ctx); } - __printf("\n"); + kprintf("\n"); PrintMemoryIntervals(2, &_mmi); /* PrintSystemMappings(2); */ if (__argv) { for (i = 0; i < __argc; ++i) { if (!__argv[i]) continue; if (IsAsan() && !__asan_is_valid(__argv[i], 1)) continue; - __printf("%s ", __argv[i]); + kprintf("%s ", __argv[i]); } } - __printf("\n"); + kprintf("\n"); } relegated static void RestoreDefaultCrashSignalHandlers(void) { @@ -280,6 +241,24 @@ relegated static void RestoreDefaultCrashSignalHandlers(void) { } } +static wontreturn relegated noinstrument void __minicrash(int sig, + struct siginfo *si, + ucontext_t *ctx, + const char *kind) { + kprintf("\n" + "\n" + "CRASHED %s WITH %G\n" + "%s\n" + "RIP %x\n" + "RSP %x\n" + "RBP %x\n" + "\n", + kind, sig, __argv[0], ctx ? ctx->uc_mcontext.rip : 0, + ctx ? ctx->uc_mcontext.rsp : 0, ctx ? ctx->uc_mcontext.rbp : 0); + __restorewintty(); + _Exit(119); +} + /** * Crashes in a developer-friendly human-centric way. * @@ -293,48 +272,50 @@ relegated static void RestoreDefaultCrashSignalHandlers(void) { * * This function never returns, except for traps w/ human supervision. */ -noasan relegated void __oncrash(int sig, struct siginfo *si, ucontext_t *ctx) { +relegated noinstrument void __oncrash(int sig, struct siginfo *si, + ucontext_t *ctx) { intptr_t rip; - int gdbpid, err; + int gdbpid, err, st, ft; static bool noreentry, notpossible; - ++g_ftrace; - rip = ctx ? ctx->uc_mcontext.rip : 0; - if (cmpxchg(&noreentry, false, true)) { - err = errno; - if ((gdbpid = IsDebuggerPresent(true))) { - DebugBreak(); - } else if (g_isterminalinarticulate || g_isrunningundermake) { - gdbpid = -1; - } else if (FindDebugBinary()) { - RestoreDefaultCrashSignalHandlers(); - gdbpid = - attachdebugger(((sig == SIGTRAP || sig == SIGQUIT) && - (rip >= (intptr_t)&_base && rip < (intptr_t)&_etext)) - ? rip - : 0); + st = __strace, __strace = 0; + ft = g_ftrace, g_ftrace = 0; + if (_lockcmpxchg(&noreentry, false, true)) { + if (!__vforked) { + rip = ctx ? ctx->uc_mcontext.rip : 0; + err = errno; + if ((gdbpid = IsDebuggerPresent(true))) { + DebugBreak(); + } else if (__nocolor || g_isrunningundermake) { + gdbpid = -1; + } else if (!IsTiny() && IsLinux() && FindDebugBinary() && !__isworker) { + RestoreDefaultCrashSignalHandlers(); + gdbpid = AttachDebugger( + ((sig == SIGTRAP || sig == SIGQUIT) && + (rip >= (intptr_t)&_base && rip < (intptr_t)&_etext)) + ? rip + : 0); + } + if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) { + __restore_tty(); + ShowCrashReport(err, sig, si, ctx); + __restorewintty(); + _Exit(128 + sig); + } + } else { + __minicrash(sig, si, ctx, "WHILE VFORKED"); } - if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) { - __restore_tty(1); - ShowCrashReport(err, sig, si, ctx); - _Exit(128 + sig); - } - } else if (cmpxchg(¬possible, false, true)) { - __printf("\n" - "\n" - "CRASHED WHILE CRASHING WITH SIG%s\n" - "%s\n" - "RIP %x\n" - "RSP %x\n" - "RBP %x\n" - "\n", - TinyStrSignal(sig), __argv[0], rip, ctx ? ctx->uc_mcontext.rsp : 0, - ctx ? ctx->uc_mcontext.rbp : 0); - _Exit(119); + } else if (sig == SIGTRAP) { + /* chances are IsDebuggerPresent() confused strace w/ gdb */ + g_ftrace = ft; + __strace = st; + return; + } else if (_lockcmpxchg(¬possible, false, true)) { + __minicrash(sig, si, ctx, "WHILE CRASHING"); } else { for (;;) { asm("ud2"); } } noreentry = false; - --g_ftrace; + ++g_ftrace; } diff --git a/libc/log/oncrashthunks.S b/libc/log/oncrashthunks.S index ef70cb9e8..13b9a85c0 100644 --- a/libc/log/oncrashthunks.S +++ b/libc/log/oncrashthunks.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // These function names make it a bit more obvious which signal // caused the crash, particularly in the GDB GUI. They're coded @@ -90,15 +89,6 @@ __oncrash_sigbus: ret .endfn __oncrash_sigbus,globl - .org 11*7 -__oncrash_sigpipe: - push %rbp - mov %rsp,%rbp - call __oncrash - pop %rbp - ret - .endfn __oncrash_sigpipe,globl - // : showcrashreports.c, oncrashthunks.S, oncrash.c .endobj __oncrash_thunks,globl diff --git a/libc/log/onkill.c b/libc/log/onkill.c index 1c37c0d61..971a0c94d 100644 --- a/libc/log/onkill.c +++ b/libc/log/onkill.c @@ -51,7 +51,7 @@ textexit static void __onkill(int sig, struct siginfo *si, /** * Installs default handlers for friendly kill signals. - * @see showcrashreports() + * @see ShowCrashReports() */ void callexitontermination(sigset_t *opt_out_exitsigs) { struct sigaction sa; diff --git a/libc/log/printgarbage.c b/libc/log/printgarbage.c index 7c8d8bd49..69f0bc574 100644 --- a/libc/log/printgarbage.c +++ b/libc/log/printgarbage.c @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/fmt.h" -#include "libc/log/libfatal.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/log/log.h" #include "libc/nexgen32e/gc.internal.h" #include "libc/stdio/stdio.h" @@ -30,27 +30,27 @@ void PrintGarbage(void) { size_t i; char name[19]; const char *symbol; - __printf("\n"); - __printf(" SHADOW STACK @ 0x%p\n", __builtin_frame_address(0)); - __printf("garbage entry parent frame original ret callback arg \n"); - __printf("-------------- -------------- ------------------ ------------------ ------------------\n"); + kprintf("\n"); + kprintf(" SHADOW STACK @ %p\n", __builtin_frame_address(0)); + kprintf("garbage ent. parent frame original ret callback arg \n"); + kprintf("------------ ------------ ------------------ ------------------ ------------------\n"); if (__garbage.i) { for (i = __garbage.i; i--;) { symbol = __get_symbol_by_addr(__garbage.p[i].ret); if (symbol) { - snprintf(name, sizeof(name), "%s", symbol); + ksnprintf(name, sizeof(name), "%s", symbol); } else { - snprintf(name, sizeof(name), "0x%012lx", __garbage.p[i].ret); + ksnprintf(name, sizeof(name), "%#014lx", __garbage.p[i].ret); } - __printf("0x%p 0x%p %18s %18s 0x%016lx\n", - __garbage.p + i, - __garbage.p[i].frame, - name, - __get_symbol_by_addr(__garbage.p[i].fn), - __garbage.p[i].arg); + kprintf("%12lx %12lx %18s %18s %#18lx\n", + __garbage.p + i, + __garbage.p[i].frame, + name, + __get_symbol_by_addr(__garbage.p[i].fn), + __garbage.p[i].arg); } } else { - __printf("%14s %14s %18s %18s %18s\n","empty","-","-","-","-"); + kprintf("%12s %12s %18s %18s %18s\n","empty","-","-","-","-"); } - __printf("\n"); + kprintf("\n"); } diff --git a/libc/log/restoretty.c b/libc/log/restoretty.c deleted file mode 100644 index b5e50c4bd..000000000 --- a/libc/log/restoretty.c +++ /dev/null @@ -1,53 +0,0 @@ -/*-*- 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/termios.h" -#include "libc/dce.h" -#include "libc/log/color.internal.h" -#include "libc/log/internal.h" -#include "libc/nt/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/nr.h" - -#define RESET_COLOR "\e[0m" -#define SHOW_CURSOR "\e[?25h" -#define DISABLE_MOUSE "\e[?1000;1002;1015;1006l" -#define ANSI_RESTORE RESET_COLOR SHOW_CURSOR DISABLE_MOUSE - -struct termios g_oldtermios; - -asm(".section .privileged,\"ax\",@progbits\n__syscall:\n\t" - "syscall\n\t" - "ret\n\t" - ".previous"); - -static textstartup void g_oldtermios_init() { - tcgetattr(1, &g_oldtermios); -} - -const void *const g_oldtermios_ctor[] initarray = { - g_oldtermios_init, -}; - -void __restore_tty(int fd) { - if (g_oldtermios.c_lflag && isatty(fd) && cancolor()) { - write(fd, ANSI_RESTORE, strlen(ANSI_RESTORE)); - tcsetattr(fd, TCSAFLUSH, &g_oldtermios); - } -} diff --git a/libc/log/restoretty.greg.c b/libc/log/restoretty.greg.c new file mode 100644 index 000000000..3175a7b3c --- /dev/null +++ b/libc/log/restoretty.greg.c @@ -0,0 +1,67 @@ +/*-*- 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/internal.h" +#include "libc/calls/struct/metatermios.internal.h" +#include "libc/calls/struct/termios.h" +#include "libc/calls/termios.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/log/color.internal.h" +#include "libc/log/internal.h" +#include "libc/runtime/internal.h" +#include "libc/sysv/consts/termios.h" + +/** + * @fileoverview Terminal Restoration Helper for System Five. + * + * This is used by the crash reporting functions, e.g. __die(), to help + * ensure the terminal is in an unborked state after a crash happens. + */ + +#define RESET_COLOR "\e[0m" +#define SHOW_CURSOR "\e[?25h" +#define DISABLE_MOUSE "\e[?1000;1002;1015;1006l" +#define ANSI_RESTORE RESET_COLOR SHOW_CURSOR DISABLE_MOUSE + +static bool __isrestorable; +static union metatermios __oldtermios; + +static textstartup void __oldtermios_init() { + int e; + e = errno; + if (sys_ioctl(0, TCGETS, &__oldtermios) != -1) { + __isrestorable = true; + } + errno = e; +} + +const void *const __oldtermios_ctor[] initarray = { + __oldtermios_init, +}; + +void __restore_tty(void) { + int e; + if (__isrestorable && !__isworker && !__nocolor) { + e = errno; + sys_write(0, ANSI_RESTORE, strlen(ANSI_RESTORE)); + sys_ioctl(0, TCSETSF, &__oldtermios); + errno = e; + } +} diff --git a/libc/log/showcrashreports.c b/libc/log/showcrashreports.c index cfca95610..66edf6490 100644 --- a/libc/log/showcrashreports.c +++ b/libc/log/showcrashreports.c @@ -22,11 +22,14 @@ #include "libc/log/internal.h" #include "libc/log/log.h" #include "libc/macros.internal.h" +#include "libc/runtime/symbols.internal.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/ss.h" -STATIC_YOINK("__die"); +STATIC_YOINK("__die"); /* for backtracing */ +STATIC_YOINK("malloc_inspect_all"); /* for asan memory origin */ +STATIC_YOINK("__get_symbol_by_addr"); /* for asan memory origin */ extern const unsigned char __oncrash_thunks[8][11]; @@ -59,7 +62,6 @@ void ShowCrashReports(void) { kCrashSigs[4] = SIGTRAP; /* bad system call */ kCrashSigs[5] = SIGABRT; /* abort() called */ kCrashSigs[6] = SIGBUS; /* misaligned, noncanonical ptr, etc. */ - kCrashSigs[7] = SIGPIPE; /* write to closed thing */ /* : showcrashreports.c, oncrashthunks.S, oncrash.c */ bzero(&sa, sizeof(sa)); ss.ss_flags = 0; @@ -71,11 +73,12 @@ void ShowCrashReports(void) { for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) { sigdelset(&sa.sa_mask, kCrashSigs[i]); } - sigaltstack(&ss, 0); + if (!IsWindows()) sigaltstack(&ss, 0); for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) { if (kCrashSigs[i]) { sa.sa_sigaction = (sigaction_f)__oncrash_thunks[i]; sigaction(kCrashSigs[i], &sa, &g_oldcrashacts[i]); } } + GetSymbolTable(); } diff --git a/libc/log/startfatal.c b/libc/log/startfatal.c index ac3b65096..599b1bd22 100644 --- a/libc/log/startfatal.c +++ b/libc/log/startfatal.c @@ -16,9 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/kprintf.h" #include "libc/log/color.internal.h" #include "libc/log/internal.h" -#include "libc/log/libfatal.internal.h" #include "libc/runtime/runtime.h" /** @@ -27,19 +27,8 @@ * @note this is support code for __check_fail(), __assert_fail(), etc. */ relegated void __start_fatal(const char *file, int line) { - bool colorful; - char s[16 + 16 + 16 + 16 + PATH_MAX + 16 + NAME_MAX + 16], *p = s; - __restore_tty(1); - colorful = cancolor(); - *p++ = '\r'; - if (colorful) p = __stpcpy(p, "\e[J\e[30;101m"); - p = __stpcpy(p, "error"); - if (colorful) p = __stpcpy(p, "\e[94;49m"), *p++ = ':'; - p = __stpcpy(p, file), *p++ = ':'; - p = __intcpy(p, line), *p++ = ':'; - p = __stpcpy(p, program_invocation_short_name); - if (colorful) p = __stpcpy(p, "\e[0m"); - *p++ = ':'; - *p++ = ' '; - __write(s, p - s); + __restore_tty(); + kprintf("%r%serror%s:%s:%d:%s%s: ", !__nocolor ? "\e[J\e[30;101m" : "", + !__nocolor ? "\e[94;49m" : "", file, line, + program_invocation_short_name, !__nocolor ? "\e[0m" : ""); } diff --git a/libc/log/thunks/__check_fail_eq.S b/libc/log/thunks/__check_fail_eq.S index d79ab39d3..a3acefd72 100644 --- a/libc/log/thunks/__check_fail_eq.S +++ b/libc/log/thunks/__check_fail_eq.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .text.unlikely -.source __FILE__ // Code-size saving thunk for CHECK_EQ() in NDEBUG mode. __check_fail_eq: diff --git a/libc/log/thunks/__check_fail_ge.S b/libc/log/thunks/__check_fail_ge.S index ed3f9d8d3..2c5daac54 100644 --- a/libc/log/thunks/__check_fail_ge.S +++ b/libc/log/thunks/__check_fail_ge.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .text.unlikely -.source __FILE__ // Code-size saving thunk for CHECK_GE() in NDEBUG mode. __check_fail_ge: diff --git a/libc/log/thunks/__check_fail_gt.S b/libc/log/thunks/__check_fail_gt.S index b86c96a4d..5b0e6ec9c 100644 --- a/libc/log/thunks/__check_fail_gt.S +++ b/libc/log/thunks/__check_fail_gt.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .text.unlikely -.source __FILE__ // Code-size saving thunk for CHECK_GT() in NDEBUG mode. __check_fail_gt: diff --git a/libc/log/thunks/__check_fail_le.S b/libc/log/thunks/__check_fail_le.S index e21fabf2e..ed9c7b754 100644 --- a/libc/log/thunks/__check_fail_le.S +++ b/libc/log/thunks/__check_fail_le.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .text.unlikely -.source __FILE__ // Code-size saving thunk for CHECK_LE() in NDEBUG mode. __check_fail_le: diff --git a/libc/log/thunks/__check_fail_lt.S b/libc/log/thunks/__check_fail_lt.S index ea2161ed1..20d62aedb 100644 --- a/libc/log/thunks/__check_fail_lt.S +++ b/libc/log/thunks/__check_fail_lt.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .text.unlikely -.source __FILE__ // Code-size saving thunk for CHECK_LT() in NDEBUG mode. __check_fail_lt: diff --git a/libc/log/thunks/__check_fail_ndebug.S b/libc/log/thunks/__check_fail_ndebug.S index 65a16c051..8ff4b7e23 100644 --- a/libc/log/thunks/__check_fail_ndebug.S +++ b/libc/log/thunks/__check_fail_ndebug.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ __check_fail_ndebug: push %rbp diff --git a/libc/log/thunks/__check_fail_ne.S b/libc/log/thunks/__check_fail_ne.S index a0a8afbc0..aa9023b07 100644 --- a/libc/log/thunks/__check_fail_ne.S +++ b/libc/log/thunks/__check_fail_ne.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .text.unlikely -.source __FILE__ // Code-size saving thunk for CHECK_NE() in NDEBUG mode. __check_fail_ne: diff --git a/libc/log/vflogf.c b/libc/log/vflogf.c index 5e3d6685c..ffedd9fac 100644 --- a/libc/log/vflogf.c +++ b/libc/log/vflogf.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/stat.h" #include "libc/calls/struct/timeval.h" #include "libc/dce.h" @@ -44,11 +45,12 @@ static struct timespec vflogf_ts; */ void vflogf_onfail(FILE *f) { errno_t err; - struct stat st; + int64_t size; if (IsTiny()) return; err = ferror(f); if (fileno(f) != -1 && (err == ENOSPC || err == EDQUOT || err == EFBIG) && - (fstat(fileno(f), &st) == -1 || st.st_size > kNontrivialSize)) { + ((size = getfiledescriptorsize(fileno(f))) == -1 || + size > kNontrivialSize)) { ftruncate(fileno(f), 0); fseek(f, SEEK_SET, 0); f->beg = f->end = 0; @@ -74,15 +76,17 @@ void vflogf_onfail(FILE *f) { */ void(vflogf)(unsigned level, const char *file, int line, FILE *f, const char *fmt, va_list va) { - int bufmode; struct tm tm; long double t2; + int st, bufmode; const char *prog; bool issamesecond; char buf32[32]; int64_t secs, nsec, dots; if (!f) f = __log_file; if (!f) return; + st = __strace; + __strace = 0; t2 = nowl(); secs = t2; nsec = (t2 - secs) * 1e9L; @@ -95,13 +99,13 @@ void(vflogf)(unsigned level, const char *file, int line, FILE *f, prog = basename(program_invocation_name); bufmode = f->bufmode; if (bufmode == _IOLBF) f->bufmode = _IOFBF; - if ((fprintf)(f, "%c%s%06ld:%s:%d:%.*s:%d] ", "FEWIVDNT"[level & 7], buf32, + if ((fprintf)(f, "%r%c%s%06ld:%s:%d:%.*s:%d] ", "FEWIVDNT"[level & 7], buf32, rem1000000int64(div1000int64(dots)), file, line, strchrnul(prog, '.') - prog, prog, getpid()) <= 0) { vflogf_onfail(f); } (vfprintf)(f, fmt, va); - fputs("\n", f); + fprintf(f, "\n"); if (bufmode == _IOLBF) { f->bufmode = _IOLBF; fflush(f); @@ -114,4 +118,5 @@ void(vflogf)(unsigned level, const char *file, int line, FILE *f, __die(); unreachable; } + __strace = st; } diff --git a/libc/macros-cpp.internal.inc b/libc/macros-cpp.internal.inc index 2593c40fa..21f91ecbe 100644 --- a/libc/macros-cpp.internal.inc +++ b/libc/macros-cpp.internal.inc @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/asancodes.h" #include "ape/relocations.h" /* clang-format off */ @@ -97,13 +98,13 @@ #endif .endm -// Creates first stack frame. -.macro .frame0 - and $-16,%rsp - xor %ebp,%ebp -.endm - -.macro .source symbol:req +// Documents unreachable assembly code. +.macro .unreachable +#ifndef NDEBUG + ud2 # crash if contract is broken +#elif defined(__FNO_OMIT_FRAME_POINTER__) + nop # avoid noreturn tail call backtrace ambiguity +#endif .endm // Inserts profiling hook in prologue if cc wants it. @@ -148,29 +149,6 @@ pop \dest .endm -// Loads address of linktime mergeable string literal into register. -.macro getstr text:req reg64:req reg32 regsz64 regsz32 bias=0 - .section .rodata.str1.1,"aSM",@progbits,1 - .type .Lstr\@,@object -.Lstr\@: .asciz "\text" -.Lstr\@.size = .-.Lstr\@ - 1 - .size .Lstr\@,.-.Lstr\@ - .previous - plea .Lstr\@,\reg64,\reg32 - .ifnb \regsz64 -#ifdef __OPTIMIZE_SIZE__ - .if .Lstr\@.size + \bias < 128 - pushpop .Lstr\@.size,\regsz64 - .else - mov $.Lstr\@.size,\regsz32 - .endif -#else - mov $.Lstr\@.size,\regsz32 -#endif - .endif -.endm - -// TODO(jart): delete // Loads address of linktime mergeable string literal into register. .macro loadstr text:req reg:req regsz bias=0 .section .rodata.str1.1,"aSM",@progbits,1 @@ -192,3 +170,31 @@ #endif .endif .endm + +.macro .poison name:req kind:req +#ifdef __SANITIZE_ADDRESS__ +2323: .quad 0 + .init.start 304,"_init_\name\()_poison_\@" + push %rdi + push %rsi + ezlea 2323b,di + mov $8,%esi + mov $\kind,%edx + call __asan_poison + pop %rsi + pop %rdi + .init.end 304,"_init_\name\()_poison_\@" +#endif +.endm + +.macro .underrun +#ifdef __SANITIZE_ADDRESS__ + .poison __BASE_FILE__, kAsanGlobalUnderrun +#endif +.endm + +.macro .overrun +#ifdef __SANITIZE_ADDRESS__ + .poison __BASE_FILE__, kAsanGlobalUnderrun +#endif +.endm diff --git a/libc/macros.internal.inc b/libc/macros.internal.inc index e7f5201cb..f4e0de543 100644 --- a/libc/macros.internal.inc +++ b/libc/macros.internal.inc @@ -138,19 +138,19 @@ // @param name should be consistent across macros for a module // @see libc/runtime/_init.S .macro .initro number:req name:req - .section .initro.\number\().\name,"a",@progbits + .section ".initro.\number\().\name","a",@progbits .align 8 .endm .macro .initbss number:req name:req - .section .piro.bss.init.2.\number\().\name,"aw",@nobits + .section ".piro.bss.init.2.\number\().\name","aw",@nobits .align 8 .endm .macro .init.start number:req name:req - .section .init.\number\().\name,"ax",@progbits -\name: + .section ".init.\number\().\name","ax",@progbits +"\name": .endm .macro .init.end number:req name:req bnd=globl vis - .endfn \name,\bnd,\vis + .endfn "\name",\bnd,\vis .previous .endm @@ -165,34 +165,32 @@ // Ends function definition. // @cost saves 1-3 lines of code .macro .endfn name:req bnd vis - .size \name,.-\name - .type \name,@function + .size "\name",.-"\name" + .type "\name",@function .ifnb \bnd - .\bnd \name + .\bnd "\name" .endif .ifnb \vis - .\vis \name + .\vis "\name" .endif .endm // Ends variable definition. // @cost saves 1-3 lines of code .macro .endobj name:req bnd vis - .size \name,.-\name - .type \name,@object + .size "\name",.-"\name" + .type "\name",@object .ifnb \bnd - .\bnd \name + .\bnd "\name" .endif .ifnb \vis - .\vis \name + .\vis "\name" .endif .endm // LOOP Instruction Replacement. -// With its mop-Fusion Mexican equivalent. -// Thus avoiding 3x legacy pipeline slowdown. .macro .loop label:req - .byte 0x83,0xe9,0x01 # sub $1,%ecx + .byte 0x83,0xe9,0x01 # sub §1,%ecx jnz \label .endm @@ -218,10 +216,10 @@ // Declares optional function. .macro .optfn fn:req - .globl \fn - .weak \fn - .equ \fn,missingno - .type \fn,@function + .globl "\fn" + .weak "\fn" + .equ "\fn",missingno + .type "\fn",@function .endm // Embeds fixed-width zero-filled string table. @@ -259,17 +257,18 @@ // Puts initialized data in uninitialized data section. .macro .bsdata name:req expr:req bnd vis - .section .initbss.300._init_\name,"aw",@nobits -\name: .quad 0 - .endobj \name,\bnd,\vis + .section ".initbss.300._init_\name","aw",@nobits +"\name": + .quad 0 + .endobj "\name",\bnd,\vis .previous - .section .initro.300._init_\name,"a",@progbits + .section ".initro.300._init_\name","a",@progbits .quad \expr .previous - .section .init.300._init_\name,"ax",@progbits -_init_\name: + .section ".init.300._init_\name","ax",@progbits +"_init_\name": movsq - .endfn _init_\name + .endfn "_init_\name" .previous .endm diff --git a/libc/math.h b/libc/math.h index 4bf59a90a..0087f694c 100644 --- a/libc/math.h +++ b/libc/math.h @@ -182,6 +182,8 @@ float fminf(float, float); float fmodf(float, float); float hypotf(float, float); float ldexpf(float, int); +float lgammaf(float); +float lgammaf_r(float, int *); float log10f(float); float log1pf(float); float log2f(float); @@ -205,10 +207,11 @@ float sinhf(float); float sqrtf(float); float tanf(float); float tanhf(float); -float truncf(float); float tgammaf(float); +float truncf(float); int finitef(float); +int finitel(long double); long double acoshl(long double); long double acosl(long double); long double asinhl(long double); @@ -237,6 +240,8 @@ long double fminl(long double, long double); long double fmodl(long double, long double); long double hypotl(long double, long double); long double ldexpl(long double, int); +long double lgammal(long double); +long double lgammal_r(long double, int *); long double log10l(long double); long double log1pl(long double); long double log2l(long double); @@ -260,8 +265,8 @@ long double sinl(long double); long double sqrtl(long double); long double tanhl(long double); long double tanl(long double); +long double tgammal(long double); long double truncl(long double); -int finitel(long double); long lrint(double); long lrintf(float); @@ -283,12 +288,15 @@ long long llroundl(long double); double frexp(double, int *); double modf(double, double *); +double nan(const char *); double remquo(double, double, int *); float frexpf(float, int *); float modff(float, float *); +float nanf(const char *); float remquof(float, float, int *); long double frexpl(long double, int *); long double modfl(long double, long double *); +long double nanl(const char *); long double remquol(long double, long double, int *); void sincos(double, double *, double *); void sincosf(float, float *, float *); diff --git a/libc/mem/calloc.S b/libc/mem/calloc.S index ded1a095f..8f89690ef 100644 --- a/libc/mem/calloc.S +++ b/libc/mem/calloc.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" #include "libc/notice.inc" -.source __FILE__ // Allocates n * itemsize bytes, initialized to zero. // diff --git a/libc/mem/copyfd.c b/libc/mem/copyfd.c new file mode 100644 index 000000000..c058505e5 --- /dev/null +++ b/libc/mem/copyfd.c @@ -0,0 +1,86 @@ +/*-*- 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 2022 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/errno.h" +#include "libc/mem/mem.h" + +#define CHUNK 32768 + +/** + * Copies data between fds the old fashioned way. + * + * Even though Cosmopolitan polyfills copy_file_range() to fallback to + * doing this, it's useful to call this function in cases where you know + * it'd be more helpful to get the larger buffer size with read/write. + * + * Reads are allowed to be interrupted. Writes are uninterruptible. If + * we get an interrupt when partial data was written, we return the + * partial amount. Therefore the file descriptors are guaranteed to + * remain in a consistent state, provided EINTR is the only error. + * + * If n is 0 then 0 is returned and no i/o operations are performed. + * + * @return bytes successfully exchanged + */ +ssize_t _copyfd(int infd, int outfd, size_t n) { + int e; + char *buf; + ssize_t rc; + size_t i, j, got, sent; + rc = 0; + if (n) { + if ((buf = malloc(CHUNK))) { + for (e = errno, i = 0; i < n; i += j) { + rc = read(infd, buf, CHUNK); + if (rc == -1) { + // eintr may interrupt the read operation + if (i && errno == EINTR) { + // suppress error if partially completed + errno = e; + rc = i; + } + break; + } + got = rc; + if (!got) { + rc = i; + break; + } + // write operation must complete + for (j = 0; j < got; j += sent) { + rc = write(outfd, buf + j, got - j); + if (rc != -1) { + sent = rc; + } else if (errno == EINTR) { + // write operation must be uninterruptible + errno = e; + sent = 0; + } else { + break; + } + } + if (rc == -1) break; + } + free(buf); + } else { + rc = -1; + } + } + return rc; +} diff --git a/libc/mem/cxx/free.S b/libc/mem/cxx/free.S index 72a92b52b..9d3264658 100644 --- a/libc/mem/cxx/free.S +++ b/libc/mem/cxx/free.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Frees memory the C++ way. // diff --git a/libc/mem/cxx/malloc.S b/libc/mem/cxx/malloc.S index a5e98e8cc..20870572c 100644 --- a/libc/mem/cxx/malloc.S +++ b/libc/mem/cxx/malloc.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Allocates memory the C++ way. // diff --git a/libc/mem/cxx/memalign.S b/libc/mem/cxx/memalign.S index dded5b421..8a67e5558 100644 --- a/libc/mem/cxx/memalign.S +++ b/libc/mem/cxx/memalign.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Allocates aligned memory the C++ way. // diff --git a/libc/mem/free.S b/libc/mem/free.S index 44af4076e..0190fe07c 100644 --- a/libc/mem/free.S +++ b/libc/mem/free.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Free memory returned by malloc() & co. // diff --git a/libc/mem/get_current_dir_name.c b/libc/mem/get_current_dir_name.c index 4a5668cfe..403bffb0c 100644 --- a/libc/mem/get_current_dir_name.c +++ b/libc/mem/get_current_dir_name.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" +#include "libc/str/path.h" /** * Returns current working directory. @@ -28,7 +29,7 @@ * * @return pointer that must be free()'d, or NULL w/ errno */ -nodiscard char *get_current_dir_name(void) { +dontdiscard char *get_current_dir_name(void) { const char *p; if ((p = getenv("PWD")) && _isabspath(p)) { return strdup(p); diff --git a/libc/mem/hook/calloc.S b/libc/mem/hook/calloc.S index b2c537347..b05631677 100644 --- a/libc/mem/hook/calloc.S +++ b/libc/mem/hook/calloc.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .initbss 202,_init_calloc hook_calloc: diff --git a/libc/mem/hook/free.S b/libc/mem/hook/free.S index e130ec1de..9d3019859 100644 --- a/libc/mem/hook/free.S +++ b/libc/mem/hook/free.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .initbss 202,_init_free hook_free: diff --git a/libc/mem/hook/malloc.S b/libc/mem/hook/malloc.S index b6df454a1..8b715f326 100644 --- a/libc/mem/hook/malloc.S +++ b/libc/mem/hook/malloc.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .initbss 202,_init_malloc hook_malloc: diff --git a/libc/mem/hook/malloc_trim.S b/libc/mem/hook/malloc_trim.S index b98b2a647..bc0799b1b 100644 --- a/libc/mem/hook/malloc_trim.S +++ b/libc/mem/hook/malloc_trim.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .initbss 202,_init_malloc_trim hook_malloc_trim: diff --git a/libc/mem/hook/malloc_usable_size.S b/libc/mem/hook/malloc_usable_size.S index ed8dffaff..1dabdbdc8 100644 --- a/libc/mem/hook/malloc_usable_size.S +++ b/libc/mem/hook/malloc_usable_size.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .initbss 202,_init_malloc_usable_size hook_malloc_usable_size: diff --git a/libc/mem/hook/memalign.S b/libc/mem/hook/memalign.S index 70ad1bfa8..6cdc719b6 100644 --- a/libc/mem/hook/memalign.S +++ b/libc/mem/hook/memalign.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .initbss 202,_init_memalign hook_memalign: diff --git a/libc/mem/hook/realloc.S b/libc/mem/hook/realloc.S index 18d0beba5..98879f5ea 100644 --- a/libc/mem/hook/realloc.S +++ b/libc/mem/hook/realloc.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .initbss 202,_init_realloc hook_realloc: diff --git a/libc/mem/hook/realloc_in_place.S b/libc/mem/hook/realloc_in_place.S index 374c6b46c..fec93817d 100644 --- a/libc/mem/hook/realloc_in_place.S +++ b/libc/mem/hook/realloc_in_place.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .initbss 202,_init_realloc_in_place hook_realloc_in_place: diff --git a/libc/mem/io.h b/libc/mem/io.h new file mode 100644 index 000000000..22f365c15 --- /dev/null +++ b/libc/mem/io.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_MEM_IO_H_ +#define COSMOPOLITAN_LIBC_MEM_IO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +ssize_t _copyfd(int, int, size_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_MEM_IO_H_ */ diff --git a/libc/mem/mallinfo.c b/libc/mem/mallinfo.c new file mode 100644 index 000000000..9259f8ff6 --- /dev/null +++ b/libc/mem/mallinfo.c @@ -0,0 +1,24 @@ +/*-*- 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 2022 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/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +struct mallinfo mallinfo(void) { + return dlmallinfo(); +} diff --git a/libc/mem/malloc_inspect_all.c b/libc/mem/malloc_inspect_all.c new file mode 100644 index 000000000..b7620023a --- /dev/null +++ b/libc/mem/malloc_inspect_all.c @@ -0,0 +1,26 @@ +/*-*- 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 2022 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/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +void malloc_inspect_all(void (*handler)(void* start, void* end, + size_t used_bytes, void* callback_arg), + void* arg) { + dlmalloc_inspect_all(handler, arg); +} diff --git a/libc/mem/malloc_usable_size.S b/libc/mem/malloc_usable_size.S index c534fef64..0242a7708 100644 --- a/libc/mem/malloc_usable_size.S +++ b/libc/mem/malloc_usable_size.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" #include "libc/notice.inc" -.source __FILE__ // Returns the number of bytes you can actually use in // an allocated chunk, which may be more than you requested diff --git a/libc/mem/mem.h b/libc/mem/mem.h index 4d772fd7e..4535f6eb9 100644 --- a/libc/mem/mem.h +++ b/libc/mem/mem.h @@ -15,16 +15,16 @@ void free(void *) libcesque; void *malloc(size_t) attributeallocsize((1)) mallocesque; void *calloc(size_t, size_t) attributeallocsize((1, 2)) mallocesque; void *memalign(size_t, size_t) attributeallocalign((1)) - attributeallocsize((2)) returnspointerwithnoaliases libcesque nodiscard; + attributeallocsize((2)) returnspointerwithnoaliases libcesque dontdiscard; void *realloc(void *, size_t) reallocesque; void *realloc_in_place(void *, size_t) reallocesque; -void *reallocarray(void *, size_t, size_t) nodiscard; +void *reallocarray(void *, size_t, size_t) dontdiscard; void *valloc(size_t) attributeallocsize((1)) vallocesque; void *pvalloc(size_t) vallocesque; char *strdup(const char *) paramsnonnull() mallocesque; char *strndup(const char *, size_t) paramsnonnull() mallocesque; void *aligned_alloc(size_t, size_t) attributeallocsize((1)) - attributeallocsize((2)) returnspointerwithnoaliases libcesque nodiscard; + attributeallocsize((2)) returnspointerwithnoaliases libcesque dontdiscard; int posix_memalign(void **, size_t, size_t); bool __grow(void *, size_t *, size_t, size_t) paramsnonnull((1, 2)) libcesque; @@ -34,7 +34,7 @@ size_t malloc_usable_size(const void *); void **independent_calloc(size_t, size_t, void **); void **independent_comalloc(size_t, size_t *, void **); -wchar_t *wcsdup(const wchar_t *) strlenesque nodiscard; +wchar_t *wcsdup(const wchar_t *) strlenesque dontdiscard; struct mallinfo { size_t arena; /* non-mmapped space allocated from system */ @@ -48,6 +48,7 @@ struct mallinfo { size_t fordblks; /* total free space */ size_t keepcost; /* releasable (via malloc_trim) space */ }; + struct mallinfo mallinfo(void); void malloc_stats(void); diff --git a/libc/mem/mem.mk b/libc/mem/mem.mk index 052fba956..86a2ef8a9 100644 --- a/libc/mem/mem.mk +++ b/libc/mem/mem.mk @@ -29,6 +29,7 @@ LIBC_MEM_A_CHECKS = \ LIBC_MEM_A_DIRECTDEPS = \ LIBC_CALLS \ + LIBC_SYSV_CALLS \ LIBC_FMT \ LIBC_INTRIN \ LIBC_NEXGEN32E \ diff --git a/libc/mem/pledge.c b/libc/mem/pledge.c new file mode 100644 index 000000000..929519fd7 --- /dev/null +++ b/libc/mem/pledge.c @@ -0,0 +1,402 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/filter.h" +#include "libc/dce.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/nrlinux.h" +#include "libc/sysv/consts/pr.h" +#include "libc/sysv/errfuns.h" +#include "tool/net/sandbox.h" + +static const uint16_t kPledgeLinuxDefault[] = { + __NR_linux_exit, // + __NR_linux_exit_group, // +}; + +static const uint16_t kPledgeLinuxStdio[] = { + __NR_linux_clock_getres, // + __NR_linux_clock_gettime, // + __NR_linux_close, // + __NR_linux_dup, // + __NR_linux_dup2, // + __NR_linux_dup3, // + __NR_linux_fchdir, // + /* __NR_linux_fcntl, // */ + __NR_linux_fstat, // + __NR_linux_fsync, // + __NR_linux_ftruncate, // + __NR_linux_getdents, // + __NR_linux_getegid, // + __NR_linux_getrandom, // + __NR_linux_geteuid, // + __NR_linux_getgid, // + __NR_linux_getgroups, // + __NR_linux_getitimer, // + __NR_linux_getpgid, // + __NR_linux_getpgrp, // + __NR_linux_getpid, // + __NR_linux_getppid, // + __NR_linux_getresgid, // + __NR_linux_getresuid, // + __NR_linux_getrlimit, // + __NR_linux_getsid, // + __NR_linux_gettimeofday, // + __NR_linux_getuid, // + __NR_linux_lseek, // + __NR_linux_madvise, // + __NR_linux_brk, // + __NR_linux_mmap, // + __NR_linux_mprotect, // + __NR_linux_munmap, // + __NR_linux_nanosleep, // + __NR_linux_pipe, // + __NR_linux_pipe2, // + __NR_linux_poll, // + __NR_linux_pread, // + __NR_linux_preadv, // + __NR_linux_pwrite, // + __NR_linux_pwritev, // + __NR_linux_read, // + __NR_linux_readv, // + __NR_linux_recvfrom, // + __NR_linux_recvmsg, // + __NR_linux_select, // + __NR_linux_sendmsg, // + __NR_linux_sendto, // + __NR_linux_setitimer, // + __NR_linux_shutdown, // + __NR_linux_sigaction, // + __NR_linux_sigprocmask, // + __NR_linux_sigreturn, // + __NR_linux_socketpair, // + __NR_linux_umask, // + __NR_linux_wait4, // + __NR_linux_write, // + __NR_linux_writev, // +}; + +static const uint16_t kPledgeLinuxRpath[] = { + __NR_linux_chdir, // + __NR_linux_getcwd, // + __NR_linux_openat, // + __NR_linux_fstatat, // + __NR_linux_faccessat, // + __NR_linux_readlinkat, // + __NR_linux_lstat, // + __NR_linux_chmod, // + __NR_linux_fchmod, // + __NR_linux_fchmodat, // + __NR_linux_chown, // + __NR_linux_fchown, // + __NR_linux_fchownat, // + __NR_linux_fstat, // +}; + +static const uint16_t kPledgeLinuxWpath[] = { + __NR_linux_getcwd, // + __NR_linux_openat, // + __NR_linux_fstatat, // + __NR_linux_faccessat, // + __NR_linux_readlinkat, // + __NR_linux_lstat, // + __NR_linux_chmod, // + __NR_linux_fchmod, // + __NR_linux_fchmodat, // + __NR_linux_chown, // + __NR_linux_fchown, // + __NR_linux_fchownat, // + __NR_linux_fstat, // +}; + +static const uint16_t kPledgeLinuxCpath[] = { + __NR_linux_rename, // + __NR_linux_renameat, // + __NR_linux_link, // + __NR_linux_linkat, // + __NR_linux_symlink, // + __NR_linux_symlinkat, // + __NR_linux_unlink, // + __NR_linux_unlinkat, // + __NR_linux_mkdir, // + __NR_linux_mkdirat, // + __NR_linux_rmdir, // +}; + +static const uint16_t kPledgeLinuxDpath[] = { + __NR_linux_mknod, // +}; + +static const uint16_t kPledgeLinuxTmppath[] = { + __NR_linux_lstat, // + __NR_linux_chmod, // + __NR_linux_chown, // + __NR_linux_unlink, // + __NR_linux_fstat, // +}; + +static const uint16_t kPledgeLinuxInet[] = { + __NR_linux_socket, // + __NR_linux_listen, // + __NR_linux_bind, // + __NR_linux_connect, // + __NR_linux_accept4, // + __NR_linux_accept, // + __NR_linux_getpeername, // + __NR_linux_getsockname, // + __NR_linux_setsockopt, // + __NR_linux_getsockopt, // +}; + +static const uint16_t kPledgeLinuxFattr[] = { + __NR_linux_utimes, // + __NR_linux_utimensat, // + __NR_linux_chmod, // + __NR_linux_fchmod, // + __NR_linux_fchmodat, // + __NR_linux_chown, // + __NR_linux_fchownat, // + __NR_linux_lchown, // + __NR_linux_fchown, // + __NR_linux_utimes, // +}; + +static const uint16_t kPledgeLinuxUnix[] = { + __NR_linux_socket, // + __NR_linux_listen, // + __NR_linux_bind, // + __NR_linux_connect, // + __NR_linux_accept4, // + __NR_linux_accept, // + __NR_linux_getpeername, // + __NR_linux_getsockname, // + __NR_linux_setsockopt, // + __NR_linux_getsockopt, // +}; + +static const uint16_t kPledgeLinuxDns[] = { + __NR_linux_sendto, // + __NR_linux_recvfrom, // + __NR_linux_socket, // + __NR_linux_connect, // +}; + +static const uint16_t kPledgeLinuxProc[] = { + __NR_linux_fork, // + __NR_linux_vfork, // + __NR_linux_kill, // + __NR_linux_getpriority, // + __NR_linux_setpriority, // + __NR_linux_setrlimit, // + __NR_linux_setpgid, // + __NR_linux_setsid, // +}; + +static const uint16_t kPledgeLinuxExec[] = { + __NR_linux_execve, // +}; + +static const uint16_t kPledgeLinuxId[] = { + __NR_linux_setuid, // + __NR_linux_setreuid, // + __NR_linux_setresuid, // + __NR_linux_setgid, // + __NR_linux_setregid, // + __NR_linux_setresgid, // + __NR_linux_setgroups, // + __NR_linux_setrlimit, // + __NR_linux_getpriority, // + __NR_linux_setpriority, // +}; + +#define PLEDGELEN(pledge) pledge, ARRAYLEN(pledge) + +static const struct Pledges { + const char *name; + const uint16_t *syscalls; + const size_t len; +} kPledgeLinux[] = { + {"default", PLEDGELEN(kPledgeLinuxDefault)}, // + {"stdio", PLEDGELEN(kPledgeLinuxStdio)}, // + {"rpath", PLEDGELEN(kPledgeLinuxRpath)}, // + {"wpath", PLEDGELEN(kPledgeLinuxWpath)}, // + {"cpath", PLEDGELEN(kPledgeLinuxCpath)}, // + {"dpath", PLEDGELEN(kPledgeLinuxDpath)}, // + {"tmppath", PLEDGELEN(kPledgeLinuxTmppath)}, // + {"inet", PLEDGELEN(kPledgeLinuxInet)}, // + {"fattr", PLEDGELEN(kPledgeLinuxFattr)}, // + {"unix", PLEDGELEN(kPledgeLinuxUnix)}, // + {"dns", PLEDGELEN(kPledgeLinuxDns)}, // + {"proc", PLEDGELEN(kPledgeLinuxProc)}, // + {"exec", PLEDGELEN(kPledgeLinuxExec)}, // + {"id", PLEDGELEN(kPledgeLinuxId)}, // + {0}, // +}; + +static const struct sock_filter kFilterStart[] = { + _SECCOMP_MACHINE(AUDIT_ARCH_X86_64), // + _SECCOMP_LOAD_SYSCALL_NR(), // +}; + +static const struct sock_filter kFilterEnd[] = { + _SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM +}; + +struct Filter { + size_t n; + struct sock_filter *p; +}; + +static bool AppendFilter(struct Filter *f, struct sock_filter *p, size_t n) { + size_t m; + struct sock_filter *q; + m = f->n + n; + if (!(q = realloc(f->p, m * sizeof(*f->p)))) return false; + memcpy(q + f->n, p, n * sizeof(*q)); + f->p = q; + f->n = m; + return true; +} + +static bool AppendPledge(struct Filter *f, const uint16_t *p, size_t len) { + int i; + for (i = 0; i < len; ++i) { + struct sock_filter fragment[] = {_SECCOMP_ALLOW_SYSCALL(p[i])}; + if (!AppendFilter(f, fragment, ARRAYLEN(fragment))) { + return false; + } + } + return true; +} + +static const uint16_t *FindPledge(const struct Pledges *p, const char *name, size_t *len) { + int i; + for (i = 0; p[i].name; ++i) { + if (!strcasecmp(name, p[i].name)) { + *len = p[i].len; + return p[i].syscalls; + } + } + return 0; +} + +static int sys_pledge_linux(const char *promises, const char *execpromises) { + bool ok; + int rc = -1; + size_t plen; + struct Filter f = {0}; + const uint16_t *pledge; + char *s, *tok, *state, *start; + if (execpromises) return einval(); + if ((start = s = strdup(promises)) && + AppendFilter(&f, kFilterStart, ARRAYLEN(kFilterStart)) && + AppendPledge(&f, kPledgeLinuxDefault, ARRAYLEN(kPledgeLinuxDefault))) { + for (ok = true; (tok = strtok_r(start, " \t\r\n", &state)); start = 0) { + if (!(pledge = FindPledge(kPledgeLinux, tok, &plen))) { + ok = false; + rc = einval(); + break; + } + if (!AppendPledge(&f, pledge, plen)) { + ok = false; + break; + } + } + if (ok && AppendFilter(&f, kFilterEnd, ARRAYLEN(kFilterEnd)) && + (rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) != -1) { + struct sock_fprog sandbox = {.len = f.n, .filter = f.p}; + rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &sandbox); + } + } + free(f.p); + free(s); + return rc; +} + +/** + * Restricts system operations. + * + * Only available on OpenBSD and Linux. + * + * By default exit and exit_group are always allowed. This is useful + * for processes that perform pure computation and interface with the + * parent via shared memory. + * + * `promises` is a string that may include any of the following groups + * delimited by spaces. + * + * - "stdio" allows clock_getres, clock_gettime, close, dup, dup2, dup3, + * fchdir, fstat, fsync, ftruncate, getdents, getegid, getrandom, + * geteuid, getgid, getgroups, getitimer, getpgid, getpgrp, getpid, + * getppid, getresgid, getresuid, getrlimit, getsid, gettimeofday, + * getuid, lseek, madvise, brk, mmap, mprotect, munmap, nanosleep, + * pipe, pipe2, poll, pread, preadv, pwrite, pwritev, read, readv, + * recvfrom, recvmsg, select, sendmsg, sendto, setitimer, shutdown, + * sigaction, sigprocmask, sigreturn, socketpair, umask, wait4, write, + * writev. + * + * - "rpath" allows chdir, getcwd, openat, fstatat, faccessat, + * readlinkat, lstat, chmod, fchmod, fchmodat, chown, fchown, + * fchownat, fstat. + * + * - "wpath" allows getcwd, openat, fstatat, faccessat, readlinkat, + * lstat, chmod, fchmod, fchmodat, chown, fchown, fchownat, fstat. + * + * - "cpath" allows rename, renameat, link, linkat, symlink, symlinkat, + * unlink, unlinkat, mkdir, mkdirat, rmdir. + * + * - "dpath" allows mknod + * + * - "tmppath" allows lstat, chmod, chown, unlink, fstat. + * + * - "inet" allows socket, listen, bind, connect, accept4, accept, + * getpeername, getsockname, setsockopt, getsockopt. + * + * - "fattr" allows utimes, utimensat, chmod, fchmod, fchmodat, chown, + * fchownat, lchown, fchown, utimes. + * + * - "unix" allows socket, listen, bind, connect, accept4, accept, + * getpeername, getsockname, setsockopt, getsockopt. + * + * - "dns" allows sendto, recvfrom, socket, connect. + * + * - "proc" allows fork, vfork, kill, getpriority, setpriority, + * setrlimit, setpgid, setsid. + * + * - "exec" allows execve. + * + * - "id" allows setuid, setreuid, setresuid, setgid, setregid, + * setresgid, setgroups, setrlimit, getpriority, setpriority. + * + */ +int pledge(const char *promises, const char *execpromises) { + int rc; + if (IsLinux()) { + rc = sys_pledge_linux(promises, execpromises); + } else { + rc = sys_pledge(promises, execpromises); + } + STRACE("pledge(%#s, %#s) → %d% m", promises, execpromises, rc); + return rc; +} diff --git a/libc/mem/putenv.c b/libc/mem/putenv.c index 56011f090..27ff77240 100644 --- a/libc/mem/putenv.c +++ b/libc/mem/putenv.c @@ -17,46 +17,63 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/alg/alg.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/macros.internal.h" #include "libc/mem/internal.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" -#define MAX_VARS 512 - #define ToUpper(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c)) static bool once; +static size_t capacity; -static void PutEnvDestroy(void) { +static size_t GetEnvironLen(char **env) { + char **p = env; + while (*p) ++p; + return p - env; +} + +static void RestoreOriginalEnvironment(char **envp) { + environ = envp; +} + +static void PutEnvImplAtExit(void *p) { + free(p); +} + +static void FreeEnviron(char **env) { char **a; - for (a = environ; *a; ++a) free(*a); - free(environ); -} - -static void PutEnvInit(void) { - char **pin, **pout; - pin = environ; - pout = malloc(sizeof(char *) * MAX_VARS); - environ = pout; - while (*pin) *pout++ = strdup(*pin++); - *pout = NULL; - atexit(PutEnvDestroy); -} - -void __freeenv(void *p) { - if (once) { - free(p); + for (a = env; *a; ++a) { + free(*a); } + free(env); +} + +static void GrowEnviron(void) { + size_t n, c; + char **a, **b, **p; + a = environ; + n = GetEnvironLen(a); + c = MAX(16ul, n) << 1; + b = calloc(c, sizeof(char *)); + for (p = b; *a;) { + *p++ = strdup(*a++); + } + __cxa_atexit(FreeEnviron, b, 0); + environ = b; + capacity = c; } int PutEnvImpl(char *s, bool overwrite) { char *p; unsigned i, namelen; if (!once) { - PutEnvInit(); + __cxa_atexit(RestoreOriginalEnvironment, environ, 0); + GrowEnviron(); once = true; } for (p = s; *p && *p != '='; ++p) { @@ -64,7 +81,7 @@ int PutEnvImpl(char *s, bool overwrite) { *p = ToUpper(*p); } } - if (*p != '=') goto fail; + if (*p != '=') goto Fail; namelen = p + 1 - s; for (i = 0; environ[i]; ++i) { if (!strncmp(environ[i], s, namelen)) { @@ -72,27 +89,38 @@ int PutEnvImpl(char *s, bool overwrite) { free(s); return 0; } - goto replace; + goto Replace; } } - if (i + 1 >= MAX_VARS) { - free(s); - return enomem(); + if (i + 1 >= capacity) { + GrowEnviron(); } - environ[i + 1] = NULL; -replace: - free(environ[i]); + environ[i + 1] = 0; +Replace: + __cxa_atexit(PutEnvImplAtExit, environ[i], 0); environ[i] = s; return 0; -fail: +Fail: free(s); return einval(); } +/* weakly called by unsetenv() when removing a pointer */ +void __freeenv(void *p) { + if (once) { + __cxa_atexit(free, p, 0); + } +} + /** * Emplaces environment key=value. + * + * @return 0 on success or non-zero on error * @see setenv(), getenv() */ -int putenv(char *string) { - return PutEnvImpl(strdup(string), true); +int putenv(char *s) { + int rc; + rc = PutEnvImpl(strdup(s), true); + STRACE("putenv(%#s) → %d", s, rc); + return rc; } diff --git a/libc/mem/realloc.S b/libc/mem/realloc.S index d0c53c378..01f398c1e 100644 --- a/libc/mem/realloc.S +++ b/libc/mem/realloc.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" #include "libc/notice.inc" -.source __FILE__ // Allocates / resizes / frees memory, e.g. // diff --git a/libc/mem/realloc_in_place.S b/libc/mem/realloc_in_place.S index ac7e5b975..5ad041b76 100644 --- a/libc/mem/realloc_in_place.S +++ b/libc/mem/realloc_in_place.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" #include "libc/notice.inc" -.source __FILE__ // Resizes the space allocated for p to size n, only if this can be // done without moving p (i.e., only if there is adjacent space diff --git a/libc/mem/setenv.c b/libc/mem/setenv.c index cb0b72262..bb9c33cdc 100644 --- a/libc/mem/setenv.c +++ b/libc/mem/setenv.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/strace.internal.h" #include "libc/mem/internal.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" @@ -28,9 +29,14 @@ * @see putenv(), getenv() */ int setenv(const char *name, const char *value, int overwrite) { - size_t namelen = strlen(name); - size_t valuelen = strlen(value); - char *s = malloc(namelen + valuelen + 2); + int rc; + char *s; + size_t namelen, valuelen; + namelen = strlen(name); + valuelen = strlen(value); + s = malloc(namelen + valuelen + 2); memcpy(mempcpy(mempcpy(s, name, namelen), "=", 1), value, valuelen + 1); - return PutEnvImpl(s, overwrite); + rc = PutEnvImpl(s, overwrite); + STRACE("setenv(%#s, %#s, %d) → %d", name, value, overwrite, rc); + return rc; } diff --git a/libc/mem/unhexstr.c b/libc/mem/unhexstr.c index f949a36fc..82499ddef 100644 --- a/libc/mem/unhexstr.c +++ b/libc/mem/unhexstr.c @@ -21,7 +21,7 @@ #include "libc/mem/mem.h" #include "libc/str/str.h" -nodiscard void *unhexstr(const char *hexdigs) { +dontdiscard void *unhexstr(const char *hexdigs) { assert(strlen(hexdigs) % 2 == 0); return unhexbuf(malloc(strlen(hexdigs) / 2), strlen(hexdigs) / 2, hexdigs); } diff --git a/libc/mem/vasprintf.c b/libc/mem/vasprintf.c index f74ca4251..26ad2fe6c 100644 --- a/libc/mem/vasprintf.c +++ b/libc/mem/vasprintf.c @@ -22,33 +22,36 @@ /** * Formats string w/ dynamic memory allocation. - * - * @param *strp is output-only and must be free'd, even on error; since - * that's the behavior that'll make your code most portable - * @return complete bytes written (excluding NUL) or -1 w/ errno * @see xasprintf() for a better API */ int(vasprintf)(char **strp, const char *fmt, va_list va) { - char *p; - size_t size; va_list vb; + size_t size; + char *p, *p2; int wrote, rc = -1; - if ((*strp = malloc((size = 512)))) { + if ((p = malloc((size = 512)))) { va_copy(vb, va); - wrote = (vsnprintf)(*strp, size, fmt, va); + wrote = (vsnprintf)(p, size, fmt, va); if (wrote < size) { - if ((p = realloc(*strp, wrote + 1))) *strp = p; - rc = wrote; + if ((p2 = realloc(p, wrote + 1))) { + p = p2; + rc = wrote; + } } else { size = wrote + 1; - if ((p = realloc(*strp, size))) { - *strp = p; - wrote = (vsnprintf)(*strp, size, fmt, vb); + if ((p2 = realloc(p, size))) { + p = p2; + wrote = (vsnprintf)(p, size, fmt, vb); assert(wrote == size - 1); rc = wrote; } } va_end(vb); } - return rc; + if (rc != -1) { + *strp = p; + return rc; + } else { + return -1; + } } diff --git a/libc/nexgen32e/bsf.h b/libc/nexgen32e/bsf.h index 5869080d0..8464e0959 100644 --- a/libc/nexgen32e/bsf.h +++ b/libc/nexgen32e/bsf.h @@ -20,7 +20,7 @@ COSMOPOLITAN_C_START_ int bsf(int) pureconst; int bsfl(long) pureconst; int bsfll(long long) pureconst; -int bsfmax(uintmax_t) pureconst; +int bsf128(uintmax_t) pureconst; #if defined(__GNUC__) && !defined(__STRICT_ANSI__) #define bsf(u) \ diff --git a/libc/nexgen32e/bsr.h b/libc/nexgen32e/bsr.h index b694a5b63..46c479c84 100644 --- a/libc/nexgen32e/bsr.h +++ b/libc/nexgen32e/bsr.h @@ -20,7 +20,7 @@ COSMOPOLITAN_C_START_ int bsr(int) pureconst; int bsrl(long) pureconst; int bsrll(long long) pureconst; -int bsrmax(uintmax_t) pureconst; +int bsr128(uint128_t) pureconst; #if defined(__GNUC__) && defined(__x86_64__) && !defined(__STRICT_ANSI__) #define bsr(u) \ diff --git a/libc/nexgen32e/bsr128.S b/libc/nexgen32e/bsr128.S new file mode 100644 index 000000000..9a0f1d6b6 --- /dev/null +++ b/libc/nexgen32e/bsr128.S @@ -0,0 +1,44 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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 "libc/macros.internal.h" + +// Returns binary logarithm of integer 𝑥. +// +// uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥) +// 0x00000000 wut 32 0 wut 32 +// 0x00000001 0 0 1 0 31 +// 0x80000001 0 0 1 31 0 +// 0x80000000 31 31 32 31 0 +// 0x00000010 4 4 5 4 27 +// 0x08000010 4 4 5 27 4 +// 0x08000000 27 27 28 27 4 +// 0xffffffff 0 0 1 31 0 +// +// @param rsi:rdi is 128-bit unsigned 𝑥 value +// @return eax number in range [0,128) or undef if 𝑥 is 0 +// @see also treasure trove of nearly identical functions +bsr128: .leafprologue + .profilable + bsr %rsi,%rax + jnz 2f + bsr %rdi,%rax +1: .leafepilogue +2: add $64,%eax + jmp 1b + .endfn bsr128,globl diff --git a/libc/nexgen32e/bsrmax.S b/libc/nexgen32e/bsrmax.S deleted file mode 100644 index 122133dc9..000000000 --- a/libc/nexgen32e/bsrmax.S +++ /dev/null @@ -1,45 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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 "libc/macros.internal.h" - -// Returns binary logarithm of integer 𝑥. -// -// uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥) -// 0x00000000 wut 32 0 wut 32 -// 0x00000001 0 0 1 0 31 -// 0x80000001 0 0 1 31 0 -// 0x80000000 31 31 32 31 0 -// 0x00000010 4 4 5 4 27 -// 0x08000010 4 4 5 27 4 -// 0x08000000 27 27 28 27 4 -// 0xffffffff 0 0 1 31 0 -// -// @param rsi:rdi is 128-bit unsigned 𝑥 value -// @return eax number in range [0,128) or undef if 𝑥 is 0 -// @see also treasure trove of nearly identical functions -bsrmax: .leafprologue - .profilable - bsr %rsi,%rax - jnz 2f - bsr %rdi,%rax -1: .leafepilogue -2: add $64,%eax - jmp 1b - .endfn bsrmax,globl - .source __FILE__ diff --git a/libc/nexgen32e/cescapec.S b/libc/nexgen32e/cescapec.S index b7623117f..83eea6c53 100644 --- a/libc/nexgen32e/cescapec.S +++ b/libc/nexgen32e/cescapec.S @@ -127,4 +127,3 @@ cescapectab: add $(8-.Lcescapectab.ro.size%8),%rsi .endif .init.end 300,_init_cescapec - .source __FILE__ diff --git a/libc/nexgen32e/cmpsb.S b/libc/nexgen32e/cmpsb.S index 025389384..48f649197 100644 --- a/libc/nexgen32e/cmpsb.S +++ b/libc/nexgen32e/cmpsb.S @@ -39,4 +39,3 @@ cmpsb: .leafprologue .Lneg1: .long -1 .endobj .Lneg1 .previous - .source __FILE__ diff --git a/libc/nexgen32e/cmpsl.S b/libc/nexgen32e/cmpsl.S index d0aa19924..400160c21 100644 --- a/libc/nexgen32e/cmpsl.S +++ b/libc/nexgen32e/cmpsl.S @@ -42,4 +42,3 @@ cmpsl: .leafprologue .Lneg1: .long -1 .endobj .Lneg1 .previous - .source __FILE__ diff --git a/libc/nexgen32e/cmpsq.S b/libc/nexgen32e/cmpsq.S index bcb9f4048..535a3fd75 100644 --- a/libc/nexgen32e/cmpsq.S +++ b/libc/nexgen32e/cmpsq.S @@ -39,4 +39,3 @@ cmpsq: .leafprologue .Lneg1: .long -1 .endobj .Lneg1 .previous - .source __FILE__ diff --git a/libc/nexgen32e/cmpsw.S b/libc/nexgen32e/cmpsw.S index ff4a78e9f..59930f6dd 100644 --- a/libc/nexgen32e/cmpsw.S +++ b/libc/nexgen32e/cmpsw.S @@ -39,4 +39,3 @@ cmpsw: .leafprologue .Lneg1: .long -1 .endobj .Lneg1 .previous - .source __FILE__ diff --git a/libc/nexgen32e/cmpub.S b/libc/nexgen32e/cmpub.S index ca848a23e..e3b1a5aab 100644 --- a/libc/nexgen32e/cmpub.S +++ b/libc/nexgen32e/cmpub.S @@ -39,4 +39,3 @@ cmpub: .leafprologue .Lneg1: .long -1 .endobj .Lneg1 .previous - .source __FILE__ diff --git a/libc/nexgen32e/cmpul.S b/libc/nexgen32e/cmpul.S index fc4739b6c..83a142fc3 100644 --- a/libc/nexgen32e/cmpul.S +++ b/libc/nexgen32e/cmpul.S @@ -39,4 +39,3 @@ cmpul: .leafprologue .Lneg1: .long -1 .endobj .Lneg1 .previous - .source __FILE__ diff --git a/libc/nexgen32e/cmpuq.S b/libc/nexgen32e/cmpuq.S index 9c8e30144..297330e37 100644 --- a/libc/nexgen32e/cmpuq.S +++ b/libc/nexgen32e/cmpuq.S @@ -39,4 +39,3 @@ cmpuq: .leafprologue .Lneg1: .long -1 .endobj .Lneg1 .previous - .source __FILE__ diff --git a/libc/nexgen32e/cmpuw.S b/libc/nexgen32e/cmpuw.S index 33f59a871..80e529ae2 100644 --- a/libc/nexgen32e/cmpuw.S +++ b/libc/nexgen32e/cmpuw.S @@ -39,4 +39,3 @@ cmpuw: .leafprologue .Lneg1: .long -1 .endobj .Lneg1 .previous - .source __FILE__ diff --git a/libc/nexgen32e/crc32-pclmul.S b/libc/nexgen32e/crc32-pclmul.S index 92b30ed70..28be50e9b 100644 --- a/libc/nexgen32e/crc32-pclmul.S +++ b/libc/nexgen32e/crc32-pclmul.S @@ -138,7 +138,6 @@ crc32_pclmul: shr $32,%rax .leafepilogue .endfn crc32_pclmul,globl,hidden - .source __FILE__ // Definitions of the bit-reflected domain constants k1,k2,k3, etc. // and the CRC32+Barrett polynomials given at the end of the paper. diff --git a/libc/nexgen32e/crc32init.S b/libc/nexgen32e/crc32init.S index 30205e4c1..6f2284107 100644 --- a/libc/nexgen32e/crc32init.S +++ b/libc/nexgen32e/crc32init.S @@ -67,4 +67,3 @@ crc32init: leave ret .endfn crc32init,globl - .source __FILE__ diff --git a/libc/nexgen32e/div1000000000int64.S b/libc/nexgen32e/div1000000000int64.S index 682764355..b8eb3fced 100644 --- a/libc/nexgen32e/div1000000000int64.S +++ b/libc/nexgen32e/div1000000000int64.S @@ -28,4 +28,3 @@ div1000000000int64: jmp tinydivsi .globl tinydivsi .endfn div1000000000int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/div1000000int64.S b/libc/nexgen32e/div1000000int64.S index 599414c20..d3cf80e10 100644 --- a/libc/nexgen32e/div1000000int64.S +++ b/libc/nexgen32e/div1000000int64.S @@ -27,4 +27,3 @@ div1000000int64: movabs $0x431bde82d7b634db,%rdx jmp tinydivsi .endfn div1000000int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/div10000int64.S b/libc/nexgen32e/div10000int64.S index ca4dadde1..d737a1fac 100644 --- a/libc/nexgen32e/div10000int64.S +++ b/libc/nexgen32e/div10000int64.S @@ -27,4 +27,3 @@ div10000int64: movabs $0x346dc5d63886594b,%rdx jmp tinydivsi .endfn div10000int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/div1000int64.S b/libc/nexgen32e/div1000int64.S index d74e59792..6d31784d2 100644 --- a/libc/nexgen32e/div1000int64.S +++ b/libc/nexgen32e/div1000int64.S @@ -27,4 +27,3 @@ div1000int64: movabs $0x20c49ba5e353f7cf,%rdx jmp tinydivsi .endfn div1000int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/div100int64.S b/libc/nexgen32e/div100int64.S index f9525016b..7251d963d 100644 --- a/libc/nexgen32e/div100int64.S +++ b/libc/nexgen32e/div100int64.S @@ -32,4 +32,3 @@ div100int64: sub %rdi,%rax ret .endfn div100int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/div10int64.S b/libc/nexgen32e/div10int64.S index 95eb4f8a3..eb72913ab 100644 --- a/libc/nexgen32e/div10int64.S +++ b/libc/nexgen32e/div10int64.S @@ -27,4 +27,3 @@ div10int64: movabs $0x6666666666666667,%rdx jmp tinydivsi .endfn div10int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/djbsort-avx2.S b/libc/nexgen32e/djbsort-avx2.S index 1cd7dec27..70e24cbdd 100644 --- a/libc/nexgen32e/djbsort-avx2.S +++ b/libc/nexgen32e/djbsort-avx2.S @@ -1,5 +1,4 @@ #include "libc/macros.internal.h" -.source __FILE__ // D.J. Bernstein's outrageously fast integer sorting algorithm. // diff --git a/libc/nexgen32e/environ.S b/libc/nexgen32e/environ.S index c8b23baea..d35260000 100644 --- a/libc/nexgen32e/environ.S +++ b/libc/nexgen32e/environ.S @@ -30,4 +30,3 @@ environ: .init.start 300,_init_environ mov %r14,environ(%rip) .init.end 300,_init_environ - .source __FILE__ diff --git a/libc/nexgen32e/fentry.S b/libc/nexgen32e/fentry.S index 297da31f3..33f833e39 100644 --- a/libc/nexgen32e/fentry.S +++ b/libc/nexgen32e/fentry.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .real -.source __FILE__ .code16 # ∩ .code32 ∩ .code64 // Function entry hook stub. diff --git a/libc/nexgen32e/ffs.S b/libc/nexgen32e/ffs.S index 5231f070a..8468e684b 100644 --- a/libc/nexgen32e/ffs.S +++ b/libc/nexgen32e/ffs.S @@ -42,4 +42,3 @@ ffs: .leafprologue inc %eax .leafepilogue .endfn ffs,globl - .source __FILE__ diff --git a/libc/nexgen32e/ffsl.S b/libc/nexgen32e/ffsl.S index f6138045d..14fd39ba4 100644 --- a/libc/nexgen32e/ffsl.S +++ b/libc/nexgen32e/ffsl.S @@ -43,4 +43,3 @@ ffsl: .leafprologue .leafepilogue .endfn ffsl,globl .alias ffsl,ffsll - .source __FILE__ diff --git a/libc/nexgen32e/gc.S b/libc/nexgen32e/gc.S index c098f646b..08c03c60b 100644 --- a/libc/nexgen32e/gc.S +++ b/libc/nexgen32e/gc.S @@ -58,7 +58,6 @@ __gc: decq __garbage(%rip) ret 9: hlt .endfn __gc,globl,hidden - .source __FILE__ .bss .align 8 diff --git a/libc/nexgen32e/identity.S b/libc/nexgen32e/identity.S index 0708c5533..c5f997de0 100644 --- a/libc/nexgen32e/identity.S +++ b/libc/nexgen32e/identity.S @@ -25,4 +25,3 @@ identity: mov %rdi,%rax ret .endfn identity,globl - .source __FILE__ diff --git a/libc/nexgen32e/imapxlatab.S b/libc/nexgen32e/imapxlatab.S index 7a9282a15..ae603c3a3 100644 --- a/libc/nexgen32e/imapxlatab.S +++ b/libc/nexgen32e/imapxlatab.S @@ -36,4 +36,3 @@ imapxlatab: .loop 1b .leafepilogue .endfn imapxlatab,globl,hidden - .source __FILE__ diff --git a/libc/nexgen32e/kbase36.S b/libc/nexgen32e/kbase36.S index 4b6486adc..1f31b32b3 100644 --- a/libc/nexgen32e/kbase36.S +++ b/libc/nexgen32e/kbase36.S @@ -43,4 +43,3 @@ kBase36:.zero 256 .loop 0b add $255-'Z',%rdi .init.end 300,_init_kBase36 - .source __FILE__ diff --git a/libc/nexgen32e/kcp437.S b/libc/nexgen32e/kcp437.S index 4dbd6aca4..5ea7666b6 100644 --- a/libc/nexgen32e/kcp437.S +++ b/libc/nexgen32e/kcp437.S @@ -19,7 +19,6 @@ #include "libc/macros.internal.h" .rodata .align 16 -.source __FILE__ // ibm cp437 unicode table w/ string literal safety // diff --git a/libc/nexgen32e/kcpuids.S b/libc/nexgen32e/kcpuids.S index ddaee90eb..3f6191e31 100644 --- a/libc/nexgen32e/kcpuids.S +++ b/libc/nexgen32e/kcpuids.S @@ -84,4 +84,3 @@ kCpuids:.long 0,0,0,0 # EAX=0 (Basic Processor Info) #endif 5: pop %rbx .init.end 201,_init_kCpuids - .source __FILE__ diff --git a/libc/nexgen32e/kcrc32ctab.S b/libc/nexgen32e/kcrc32ctab.S index 7ec41907e..f621f94f0 100644 --- a/libc/nexgen32e/kcrc32ctab.S +++ b/libc/nexgen32e/kcrc32ctab.S @@ -38,4 +38,3 @@ kCrc32cTab: call crc32init pop %rsi .init.end 300,_init_kCrc32cTab - .source __FILE__ diff --git a/libc/nexgen32e/khalfcache3.S b/libc/nexgen32e/khalfcache3.S index df3ec8a93..41e0b09d7 100644 --- a/libc/nexgen32e/khalfcache3.S +++ b/libc/nexgen32e/khalfcache3.S @@ -60,4 +60,3 @@ kHalfCache3: 4: shr %eax stosq .init.end 202,_init_kHalfCache3 - .source __FILE__ diff --git a/libc/nexgen32e/kreversebits.S b/libc/nexgen32e/kreversebits.S index 293f4142c..41e85fc3e 100644 --- a/libc/nexgen32e/kreversebits.S +++ b/libc/nexgen32e/kreversebits.S @@ -86,4 +86,3 @@ kReverseBits: .byte 0b00111111,0b10111111,0b01111111,0b11111111 .endobj kReverseBits,globl .previous - .source __FILE__ diff --git a/libc/nexgen32e/kstarttsc.S b/libc/nexgen32e/kstarttsc.S deleted file mode 100644 index 8822ae9cb..000000000 --- a/libc/nexgen32e/kstarttsc.S +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 sw=8 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 "libc/macros.internal.h" - -// Stores CPU Timestamp Counter at startup. -// -// It can be useful as an added source of seeding information. -// -// @note rdtsc is a 25 cycle instruction - .initbss 200,_init_kStartTsc -kStartTsc: - .quad 0 - .endobj kStartTsc,globl - .previous - - .init.start 200,_init_kStartTsc - rdtsc - stosl - xchg %edx,%eax - stosl - .init.end 200,_init_kStartTsc - - .source __FILE__ diff --git a/libc/nexgen32e/lolendian.S b/libc/nexgen32e/lolendian.S index 3b7b71686..b1c9b9b34 100644 --- a/libc/nexgen32e/lolendian.S +++ b/libc/nexgen32e/lolendian.S @@ -75,4 +75,3 @@ htons: movzwl %di,%eax .endfn htole16,globl .endfn ntohs,globl .endfn bswap_16,globl - .source __FILE__ diff --git a/libc/nexgen32e/mcount.S b/libc/nexgen32e/mcount.S index 3f5872622..3e1da9003 100644 --- a/libc/nexgen32e/mcount.S +++ b/libc/nexgen32e/mcount.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .real -.source __FILE__ .code16 # ∩ .code32 ∩ .code64 // Function Profiling Hook. diff --git a/libc/nexgen32e/memeqmask.S b/libc/nexgen32e/memeqmask.S index 6276bdc97..426934662 100644 --- a/libc/nexgen32e/memeqmask.S +++ b/libc/nexgen32e/memeqmask.S @@ -46,4 +46,3 @@ memeqmask: 1: mov %rdi,%rax .leafepilogue .endfn memeqmask,globl - .source __FILE__ diff --git a/libc/nexgen32e/memjmpinit.S b/libc/nexgen32e/memjmpinit.S index 2b5ebb1e5..715d95a82 100644 --- a/libc/nexgen32e/memjmpinit.S +++ b/libc/nexgen32e/memjmpinit.S @@ -46,4 +46,3 @@ memjmpinit: lodsq .leafepilogue .endfn memjmpinit,globl,hidden - .source __FILE__ diff --git a/libc/nexgen32e/memrchr.S b/libc/nexgen32e/memrchr.S index 942b01c10..e0b368352 100644 --- a/libc/nexgen32e/memrchr.S +++ b/libc/nexgen32e/memrchr.S @@ -60,4 +60,3 @@ memrchr: lea (%rdi,%rcx),%rax 9: .leafepilogue .endfn memrchr,globl - .source __FILE__ diff --git a/libc/nexgen32e/memrchr16.S b/libc/nexgen32e/memrchr16.S index 57dbd6a03..c54e81894 100644 --- a/libc/nexgen32e/memrchr16.S +++ b/libc/nexgen32e/memrchr16.S @@ -60,4 +60,3 @@ memrchr16: lea (%rdi,%rcx,2),%rax 9: .leafepilogue .endfn memrchr16,globl - .source __FILE__ diff --git a/libc/nexgen32e/memrchr32.S b/libc/nexgen32e/memrchr32.S index 8bef92107..cd95050a4 100644 --- a/libc/nexgen32e/memrchr32.S +++ b/libc/nexgen32e/memrchr32.S @@ -60,4 +60,3 @@ wmemrchr: lea (%rdi,%rcx,4),%rax 9: .leafepilogue .endfn wmemrchr,globl - .source __FILE__ diff --git a/libc/nexgen32e/missingno.S b/libc/nexgen32e/missingno.S index 1bffd54b9..03c196edb 100644 --- a/libc/nexgen32e/missingno.S +++ b/libc/nexgen32e/missingno.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .real -.source __FILE__ .code16 # ∩ .code32 ∩ .code64 // Optional function stub. diff --git a/libc/nexgen32e/nt2sysv.S b/libc/nexgen32e/nt2sysv.S index cc14d9263..472e5f568 100644 --- a/libc/nexgen32e/nt2sysv.S +++ b/libc/nexgen32e/nt2sysv.S @@ -55,4 +55,3 @@ __nt2sysv: leave ret .endfn __nt2sysv,globl,hidden - .source __FILE__ diff --git a/libc/nexgen32e/program_invocation_name.S b/libc/nexgen32e/program_invocation_name.S index 454fb4127..f1910d4d9 100644 --- a/libc/nexgen32e/program_invocation_name.S +++ b/libc/nexgen32e/program_invocation_name.S @@ -29,4 +29,3 @@ program_invocation_name: mov (%r13),%rax stosq .init.end 300,_init_program_invocation_name - .source __FILE__ diff --git a/libc/nexgen32e/rdtscp.h b/libc/nexgen32e/rdtscp.h index 92b1a2ad8..4c5ecbbd2 100644 --- a/libc/nexgen32e/rdtscp.h +++ b/libc/nexgen32e/rdtscp.h @@ -1,6 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_NEXGEN32E_RDTSCP_H_ #define COSMOPOLITAN_LIBC_NEXGEN32E_RDTSCP_H_ -#include "libc/bits/bits.h" +#include "libc/bits/asmflag.h" #include "libc/nexgen32e/x86feature.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ diff --git a/libc/nexgen32e/rem1000000000int64.S b/libc/nexgen32e/rem1000000000int64.S index 4a8ab74d1..0b48e6634 100644 --- a/libc/nexgen32e/rem1000000000int64.S +++ b/libc/nexgen32e/rem1000000000int64.S @@ -36,4 +36,3 @@ rem1000000000int64: mov %rdi,%rax ret .endfn rem1000000000int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/rem1000000int64.S b/libc/nexgen32e/rem1000000int64.S index 37fbbd573..3d80a80b4 100644 --- a/libc/nexgen32e/rem1000000int64.S +++ b/libc/nexgen32e/rem1000000int64.S @@ -36,4 +36,3 @@ rem1000000int64: mov %rdi,%rax ret .endfn rem1000000int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/rem10000int64.S b/libc/nexgen32e/rem10000int64.S index cd34b88b9..3cc71b870 100644 --- a/libc/nexgen32e/rem10000int64.S +++ b/libc/nexgen32e/rem10000int64.S @@ -36,4 +36,3 @@ rem10000int64: mov %rdi,%rax ret .endfn rem10000int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/rem1000int64.S b/libc/nexgen32e/rem1000int64.S index 825c1e643..3b94342da 100644 --- a/libc/nexgen32e/rem1000int64.S +++ b/libc/nexgen32e/rem1000int64.S @@ -36,4 +36,3 @@ rem1000int64: mov %rdi,%rax ret .endfn rem1000int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/rem100int64.S b/libc/nexgen32e/rem100int64.S index e5566e658..d8bc78f09 100644 --- a/libc/nexgen32e/rem100int64.S +++ b/libc/nexgen32e/rem100int64.S @@ -36,4 +36,3 @@ rem100int64: mov %rdi,%rax ret .endfn rem100int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/rem10int64.S b/libc/nexgen32e/rem10int64.S index 8ae95ca79..d980611cd 100644 --- a/libc/nexgen32e/rem10int64.S +++ b/libc/nexgen32e/rem10int64.S @@ -37,4 +37,3 @@ rem10int64: mov %rdi,%rax ret .endfn rem10int64,globl - .source __FILE__ diff --git a/libc/nexgen32e/rldecode.S b/libc/nexgen32e/rldecode.S index b44fb8dae..51cfaf804 100644 --- a/libc/nexgen32e/rldecode.S +++ b/libc/nexgen32e/rldecode.S @@ -37,4 +37,3 @@ rldecode: jmp 0b 2: .leafepilogue .endfn rldecode,globl - .source __FILE__ diff --git a/libc/nexgen32e/slowcall.S b/libc/nexgen32e/slowcall.S index 755e98c17..68e37c4f0 100644 --- a/libc/nexgen32e/slowcall.S +++ b/libc/nexgen32e/slowcall.S @@ -81,4 +81,3 @@ slowcall: pop %rbp ret .endfn slowcall,globl - .source __FILE__ diff --git a/libc/nexgen32e/strcpyzbw.S b/libc/nexgen32e/strcpyzbw.S index 641ca6a94..61d01e6dd 100644 --- a/libc/nexgen32e/strcpyzbw.S +++ b/libc/nexgen32e/strcpyzbw.S @@ -31,4 +31,3 @@ strcpyzbw: pop %rax .leafepilogue .endfn strcpyzbw,globl - .source __FILE__ diff --git a/libc/nexgen32e/strsak.S b/libc/nexgen32e/strsak.S index 7789ecb51..503fb6ac9 100644 --- a/libc/nexgen32e/strsak.S +++ b/libc/nexgen32e/strsak.S @@ -19,7 +19,6 @@ #include "libc/nexgen32e/x86feature.h" #include "libc/nexgen32e/macros.h" #include "libc/macros.internal.h" -.source __FILE__ // Returns length of NUL-terminated string w/ security blankets. // diff --git a/libc/nexgen32e/strsak16.S b/libc/nexgen32e/strsak16.S index c56674c32..5631e4e8e 100644 --- a/libc/nexgen32e/strsak16.S +++ b/libc/nexgen32e/strsak16.S @@ -156,4 +156,3 @@ strsak16: add %rcx,%rax jmp .Lword .endfn strsak16 - .source __FILE__ diff --git a/libc/nexgen32e/strsak32.S b/libc/nexgen32e/strsak32.S index 84708e6ef..b5b835ca9 100644 --- a/libc/nexgen32e/strsak32.S +++ b/libc/nexgen32e/strsak32.S @@ -179,4 +179,3 @@ wcssak: lea -4(%rdi),%rax .endfn wcslen,globl .endfn wcschr,globl .endfn wcschrnul,globl - .source __FILE__ diff --git a/libc/nexgen32e/strstr-sse42.S b/libc/nexgen32e/strstr-sse42.S index 1bb75db77..8449d5f37 100644 --- a/libc/nexgen32e/strstr-sse42.S +++ b/libc/nexgen32e/strstr-sse42.S @@ -39,4 +39,3 @@ strstr_sse42: 4: xor %eax,%eax 5: .leafepilogue .endfn strstr_sse42,globl,hidden - .source __FILE__ diff --git a/libc/nexgen32e/strstr16-sse42.S b/libc/nexgen32e/strstr16-sse42.S index c72d78f27..8e3a4e66a 100644 --- a/libc/nexgen32e/strstr16-sse42.S +++ b/libc/nexgen32e/strstr16-sse42.S @@ -24,4 +24,3 @@ strstr16$sse42: .strstr .Lequalorder16 .endfn strstr16$sse42,globl,hidden - .source __FILE__ diff --git a/libc/nexgen32e/tinydivsi.greg.S b/libc/nexgen32e/tinydivsi.greg.S index c1d536575..41f8fe19b 100644 --- a/libc/nexgen32e/tinydivsi.greg.S +++ b/libc/nexgen32e/tinydivsi.greg.S @@ -39,4 +39,3 @@ tinydivsi: sub %rdi,%rax .leafepilogue .endfn tinydivsi,globl - .source __FILE__ diff --git a/libc/nexgen32e/tinywcslen.greg.S b/libc/nexgen32e/tinywcslen.greg.S index 018590c80..dcbcea9ab 100644 --- a/libc/nexgen32e/tinywcslen.greg.S +++ b/libc/nexgen32e/tinywcslen.greg.S @@ -33,4 +33,3 @@ tinywcslen: jmp 1b 2: .leafepilogue .endfn tinywcslen,globl - .source __FILE__ diff --git a/libc/nexgen32e/tinywcsnlen.greg.S b/libc/nexgen32e/tinywcsnlen.greg.S index cfa7c7e71..e24c35336 100644 --- a/libc/nexgen32e/tinywcsnlen.greg.S +++ b/libc/nexgen32e/tinywcsnlen.greg.S @@ -36,4 +36,3 @@ tinywcsnlen: jmp 1b 2: .leafepilogue .endfn tinywcsnlen,globl - .source __FILE__ diff --git a/libc/nt/KernelBase/AcquireStateLock.s b/libc/nt/KernelBase/AcquireStateLock.s deleted file mode 100644 index 1a5ed3b0d..000000000 --- a/libc/nt/KernelBase/AcquireStateLock.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AcquireStateLock,AcquireStateLock,11 diff --git a/libc/nt/KernelBase/AddExtensionProgId.s b/libc/nt/KernelBase/AddExtensionProgId.s deleted file mode 100644 index a02c36007..000000000 --- a/libc/nt/KernelBase/AddExtensionProgId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AddExtensionProgId,AddExtensionProgId,26 diff --git a/libc/nt/KernelBase/AddPackageToFamilyXref.s b/libc/nt/KernelBase/AddPackageToFamilyXref.s deleted file mode 100644 index 1b8e26e47..000000000 --- a/libc/nt/KernelBase/AddPackageToFamilyXref.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AddPackageToFamilyXref,AddPackageToFamilyXref,28 diff --git a/libc/nt/KernelBase/AppContainerDeriveSidFromMoniker.s b/libc/nt/KernelBase/AppContainerDeriveSidFromMoniker.s deleted file mode 100644 index 74029dadb..000000000 --- a/libc/nt/KernelBase/AppContainerDeriveSidFromMoniker.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppContainerDeriveSidFromMoniker,AppContainerDeriveSidFromMoniker,42 diff --git a/libc/nt/KernelBase/AppContainerFreeMemory.s b/libc/nt/KernelBase/AppContainerFreeMemory.s deleted file mode 100644 index 60f330303..000000000 --- a/libc/nt/KernelBase/AppContainerFreeMemory.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppContainerFreeMemory,AppContainerFreeMemory,43 diff --git a/libc/nt/KernelBase/AppContainerLookupDisplayNameMrtReference.s b/libc/nt/KernelBase/AppContainerLookupDisplayNameMrtReference.s deleted file mode 100644 index 563dc600d..000000000 --- a/libc/nt/KernelBase/AppContainerLookupDisplayNameMrtReference.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppContainerLookupDisplayNameMrtReference,AppContainerLookupDisplayNameMrtReference,44 diff --git a/libc/nt/KernelBase/AppContainerLookupMoniker.s b/libc/nt/KernelBase/AppContainerLookupMoniker.s deleted file mode 100644 index 18818ee4e..000000000 --- a/libc/nt/KernelBase/AppContainerLookupMoniker.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppContainerLookupMoniker,AppContainerLookupMoniker,45 diff --git a/libc/nt/KernelBase/AppContainerRegisterSid.s b/libc/nt/KernelBase/AppContainerRegisterSid.s deleted file mode 100644 index d5355496e..000000000 --- a/libc/nt/KernelBase/AppContainerRegisterSid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppContainerRegisterSid,AppContainerRegisterSid,46 diff --git a/libc/nt/KernelBase/AppContainerUnregisterSid.s b/libc/nt/KernelBase/AppContainerUnregisterSid.s deleted file mode 100644 index 308820315..000000000 --- a/libc/nt/KernelBase/AppContainerUnregisterSid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppContainerUnregisterSid,AppContainerUnregisterSid,47 diff --git a/libc/nt/KernelBase/AppPolicyGetClrCompat.s b/libc/nt/KernelBase/AppPolicyGetClrCompat.s deleted file mode 100644 index 5df4fb1c8..000000000 --- a/libc/nt/KernelBase/AppPolicyGetClrCompat.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppPolicyGetClrCompat,AppPolicyGetClrCompat,48 diff --git a/libc/nt/KernelBase/AppPolicyGetCreateFileAccess.s b/libc/nt/KernelBase/AppPolicyGetCreateFileAccess.s deleted file mode 100644 index 64523c3f6..000000000 --- a/libc/nt/KernelBase/AppPolicyGetCreateFileAccess.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppPolicyGetCreateFileAccess,AppPolicyGetCreateFileAccess,49 diff --git a/libc/nt/KernelBase/AppPolicyGetLifecycleManagement.s b/libc/nt/KernelBase/AppPolicyGetLifecycleManagement.s deleted file mode 100644 index f8748f833..000000000 --- a/libc/nt/KernelBase/AppPolicyGetLifecycleManagement.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppPolicyGetLifecycleManagement,AppPolicyGetLifecycleManagement,50 diff --git a/libc/nt/KernelBase/AppPolicyGetMediaFoundationCodecLoading.s b/libc/nt/KernelBase/AppPolicyGetMediaFoundationCodecLoading.s deleted file mode 100644 index 5c91e73f8..000000000 --- a/libc/nt/KernelBase/AppPolicyGetMediaFoundationCodecLoading.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppPolicyGetMediaFoundationCodecLoading,AppPolicyGetMediaFoundationCodecLoading,51 diff --git a/libc/nt/KernelBase/AppPolicyGetProcessTerminationMethod.s b/libc/nt/KernelBase/AppPolicyGetProcessTerminationMethod.s deleted file mode 100644 index 8e719afb2..000000000 --- a/libc/nt/KernelBase/AppPolicyGetProcessTerminationMethod.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppPolicyGetProcessTerminationMethod,AppPolicyGetProcessTerminationMethod,52 diff --git a/libc/nt/KernelBase/AppPolicyGetShowDeveloperDiagnostic.s b/libc/nt/KernelBase/AppPolicyGetShowDeveloperDiagnostic.s deleted file mode 100644 index fc79f3362..000000000 --- a/libc/nt/KernelBase/AppPolicyGetShowDeveloperDiagnostic.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppPolicyGetShowDeveloperDiagnostic,AppPolicyGetShowDeveloperDiagnostic,53 diff --git a/libc/nt/KernelBase/AppPolicyGetThreadInitializationType.s b/libc/nt/KernelBase/AppPolicyGetThreadInitializationType.s deleted file mode 100644 index 18212f7da..000000000 --- a/libc/nt/KernelBase/AppPolicyGetThreadInitializationType.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppPolicyGetThreadInitializationType,AppPolicyGetThreadInitializationType,54 diff --git a/libc/nt/KernelBase/AppPolicyGetWindowingModel.s b/libc/nt/KernelBase/AppPolicyGetWindowingModel.s deleted file mode 100644 index b8500da86..000000000 --- a/libc/nt/KernelBase/AppPolicyGetWindowingModel.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppPolicyGetWindowingModel,AppPolicyGetWindowingModel,55 diff --git a/libc/nt/KernelBase/AppXFreeMemory.s b/libc/nt/KernelBase/AppXFreeMemory.s deleted file mode 100644 index 04e6acd84..000000000 --- a/libc/nt/KernelBase/AppXFreeMemory.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXFreeMemory,AppXFreeMemory,56 diff --git a/libc/nt/KernelBase/AppXGetApplicationData.s b/libc/nt/KernelBase/AppXGetApplicationData.s deleted file mode 100644 index f2b855252..000000000 --- a/libc/nt/KernelBase/AppXGetApplicationData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXGetApplicationData,AppXGetApplicationData,57 diff --git a/libc/nt/KernelBase/AppXGetDevelopmentMode.s b/libc/nt/KernelBase/AppXGetDevelopmentMode.s deleted file mode 100644 index 9edf379e9..000000000 --- a/libc/nt/KernelBase/AppXGetDevelopmentMode.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXGetDevelopmentMode,AppXGetDevelopmentMode,58 diff --git a/libc/nt/KernelBase/AppXGetOSMaxVersionTested.s b/libc/nt/KernelBase/AppXGetOSMaxVersionTested.s deleted file mode 100644 index c626a6afe..000000000 --- a/libc/nt/KernelBase/AppXGetOSMaxVersionTested.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXGetOSMaxVersionTested,AppXGetOSMaxVersionTested,59 diff --git a/libc/nt/KernelBase/AppXGetOSMinVersion.s b/libc/nt/KernelBase/AppXGetOSMinVersion.s deleted file mode 100644 index d75fa5d5f..000000000 --- a/libc/nt/KernelBase/AppXGetOSMinVersion.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXGetOSMinVersion,AppXGetOSMinVersion,60 diff --git a/libc/nt/KernelBase/AppXGetPackageCapabilities.s b/libc/nt/KernelBase/AppXGetPackageCapabilities.s deleted file mode 100644 index e74137ecb..000000000 --- a/libc/nt/KernelBase/AppXGetPackageCapabilities.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXGetPackageCapabilities,AppXGetPackageCapabilities,61 diff --git a/libc/nt/KernelBase/AppXGetPackageSid.s b/libc/nt/KernelBase/AppXGetPackageSid.s deleted file mode 100644 index 649797055..000000000 --- a/libc/nt/KernelBase/AppXGetPackageSid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXGetPackageSid,AppXGetPackageSid,62 diff --git a/libc/nt/KernelBase/AppXLookupDisplayName.s b/libc/nt/KernelBase/AppXLookupDisplayName.s deleted file mode 100644 index 7f1d7a02b..000000000 --- a/libc/nt/KernelBase/AppXLookupDisplayName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXLookupDisplayName,AppXLookupDisplayName,63 diff --git a/libc/nt/KernelBase/AppXLookupMoniker.s b/libc/nt/KernelBase/AppXLookupMoniker.s deleted file mode 100644 index bacce2836..000000000 --- a/libc/nt/KernelBase/AppXLookupMoniker.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXLookupMoniker,AppXLookupMoniker,64 diff --git a/libc/nt/KernelBase/AppXPostSuccessExtension.s b/libc/nt/KernelBase/AppXPostSuccessExtension.s deleted file mode 100644 index a20ed499b..000000000 --- a/libc/nt/KernelBase/AppXPostSuccessExtension.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXPostSuccessExtension,AppXPostSuccessExtension,65 diff --git a/libc/nt/KernelBase/AppXPreCreationExtension.s b/libc/nt/KernelBase/AppXPreCreationExtension.s deleted file mode 100644 index 0234ef7a3..000000000 --- a/libc/nt/KernelBase/AppXPreCreationExtension.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXPreCreationExtension,AppXPreCreationExtension,66 diff --git a/libc/nt/KernelBase/AppXReleaseAppXContext.s b/libc/nt/KernelBase/AppXReleaseAppXContext.s deleted file mode 100644 index a9084deca..000000000 --- a/libc/nt/KernelBase/AppXReleaseAppXContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXReleaseAppXContext,AppXReleaseAppXContext,67 diff --git a/libc/nt/KernelBase/AppXUpdatePackageCapabilities.s b/libc/nt/KernelBase/AppXUpdatePackageCapabilities.s deleted file mode 100644 index ef1206e64..000000000 --- a/libc/nt/KernelBase/AppXUpdatePackageCapabilities.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AppXUpdatePackageCapabilities,AppXUpdatePackageCapabilities,68 diff --git a/libc/nt/KernelBase/ApplicationUserModelIdFromProductId.s b/libc/nt/KernelBase/ApplicationUserModelIdFromProductId.s deleted file mode 100644 index 19094e8fe..000000000 --- a/libc/nt/KernelBase/ApplicationUserModelIdFromProductId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ApplicationUserModelIdFromProductId,ApplicationUserModelIdFromProductId,69 diff --git a/libc/nt/KernelBase/AreThereVisibleLogoffScriptsInternal.s b/libc/nt/KernelBase/AreThereVisibleLogoffScriptsInternal.s deleted file mode 100644 index 761150a79..000000000 --- a/libc/nt/KernelBase/AreThereVisibleLogoffScriptsInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AreThereVisibleLogoffScriptsInternal,AreThereVisibleLogoffScriptsInternal,73 diff --git a/libc/nt/KernelBase/AreThereVisibleShutdownScriptsInternal.s b/libc/nt/KernelBase/AreThereVisibleShutdownScriptsInternal.s deleted file mode 100644 index ae99f8081..000000000 --- a/libc/nt/KernelBase/AreThereVisibleShutdownScriptsInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_AreThereVisibleShutdownScriptsInternal,AreThereVisibleShutdownScriptsInternal,74 diff --git a/libc/nt/KernelBase/BaseCheckAppcompatCache.s b/libc/nt/KernelBase/BaseCheckAppcompatCache.s deleted file mode 100644 index f702f7628..000000000 --- a/libc/nt/KernelBase/BaseCheckAppcompatCache.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseCheckAppcompatCache,BaseCheckAppcompatCache,76 diff --git a/libc/nt/KernelBase/BaseCheckAppcompatCacheEx.s b/libc/nt/KernelBase/BaseCheckAppcompatCacheEx.s deleted file mode 100644 index b6ca33d06..000000000 --- a/libc/nt/KernelBase/BaseCheckAppcompatCacheEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseCheckAppcompatCacheEx,BaseCheckAppcompatCacheEx,77 diff --git a/libc/nt/KernelBase/BaseCleanupAppcompatCacheSupport.s b/libc/nt/KernelBase/BaseCleanupAppcompatCacheSupport.s deleted file mode 100644 index 62fdc5c53..000000000 --- a/libc/nt/KernelBase/BaseCleanupAppcompatCacheSupport.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseCleanupAppcompatCacheSupport,BaseCleanupAppcompatCacheSupport,78 diff --git a/libc/nt/KernelBase/BaseDllFreeResourceId.s b/libc/nt/KernelBase/BaseDllFreeResourceId.s deleted file mode 100644 index f281a5932..000000000 --- a/libc/nt/KernelBase/BaseDllFreeResourceId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseDllFreeResourceId,BaseDllFreeResourceId,79 diff --git a/libc/nt/KernelBase/BaseDllMapResourceIdW.s b/libc/nt/KernelBase/BaseDllMapResourceIdW.s deleted file mode 100644 index 4dadea52a..000000000 --- a/libc/nt/KernelBase/BaseDllMapResourceIdW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseDllMapResourceIdW,BaseDllMapResourceIdW,80 diff --git a/libc/nt/KernelBase/BaseDumpAppcompatCache.s b/libc/nt/KernelBase/BaseDumpAppcompatCache.s deleted file mode 100644 index 9a0c1c2de..000000000 --- a/libc/nt/KernelBase/BaseDumpAppcompatCache.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseDumpAppcompatCache,BaseDumpAppcompatCache,81 diff --git a/libc/nt/KernelBase/BaseFlushAppcompatCache.s b/libc/nt/KernelBase/BaseFlushAppcompatCache.s deleted file mode 100644 index 373eea117..000000000 --- a/libc/nt/KernelBase/BaseFlushAppcompatCache.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseFlushAppcompatCache,BaseFlushAppcompatCache,82 diff --git a/libc/nt/KernelBase/BaseFormatObjectAttributes.s b/libc/nt/KernelBase/BaseFormatObjectAttributes.s deleted file mode 100644 index 2715592cc..000000000 --- a/libc/nt/KernelBase/BaseFormatObjectAttributes.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseFormatObjectAttributes,BaseFormatObjectAttributes,83 diff --git a/libc/nt/KernelBase/BaseFreeAppCompatDataForProcess.s b/libc/nt/KernelBase/BaseFreeAppCompatDataForProcess.s deleted file mode 100644 index 23d59f8cc..000000000 --- a/libc/nt/KernelBase/BaseFreeAppCompatDataForProcess.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseFreeAppCompatDataForProcess,BaseFreeAppCompatDataForProcess,84 diff --git a/libc/nt/KernelBase/BaseGetConsoleReference.s b/libc/nt/KernelBase/BaseGetConsoleReference.s deleted file mode 100644 index 41c4118a8..000000000 --- a/libc/nt/KernelBase/BaseGetConsoleReference.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseGetConsoleReference,BaseGetConsoleReference,85 diff --git a/libc/nt/KernelBase/BaseGetNamedObjectDirectory.s b/libc/nt/KernelBase/BaseGetNamedObjectDirectory.s deleted file mode 100644 index 7dca1d15e..000000000 --- a/libc/nt/KernelBase/BaseGetNamedObjectDirectory.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseGetNamedObjectDirectory,BaseGetNamedObjectDirectory,86 diff --git a/libc/nt/KernelBase/BaseInitAppcompatCacheSupport.s b/libc/nt/KernelBase/BaseInitAppcompatCacheSupport.s deleted file mode 100644 index 9d31dcd37..000000000 --- a/libc/nt/KernelBase/BaseInitAppcompatCacheSupport.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseInitAppcompatCacheSupport,BaseInitAppcompatCacheSupport,87 diff --git a/libc/nt/KernelBase/BaseIsAppcompatInfrastructureDisabled.s b/libc/nt/KernelBase/BaseIsAppcompatInfrastructureDisabled.s deleted file mode 100644 index d04d571ea..000000000 --- a/libc/nt/KernelBase/BaseIsAppcompatInfrastructureDisabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseIsAppcompatInfrastructureDisabled,BaseIsAppcompatInfrastructureDisabled,88 diff --git a/libc/nt/KernelBase/BaseMarkFileForDelete.s b/libc/nt/KernelBase/BaseMarkFileForDelete.s deleted file mode 100644 index 522afbaf7..000000000 --- a/libc/nt/KernelBase/BaseMarkFileForDelete.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseMarkFileForDelete,BaseMarkFileForDelete,89 diff --git a/libc/nt/KernelBase/BaseReadAppCompatDataForProcess.s b/libc/nt/KernelBase/BaseReadAppCompatDataForProcess.s deleted file mode 100644 index 76deb4820..000000000 --- a/libc/nt/KernelBase/BaseReadAppCompatDataForProcess.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseReadAppCompatDataForProcess,BaseReadAppCompatDataForProcess,90 diff --git a/libc/nt/KernelBase/BaseUpdateAppcompatCache.s b/libc/nt/KernelBase/BaseUpdateAppcompatCache.s deleted file mode 100644 index be104534e..000000000 --- a/libc/nt/KernelBase/BaseUpdateAppcompatCache.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BaseUpdateAppcompatCache,BaseUpdateAppcompatCache,91 diff --git a/libc/nt/KernelBase/BasepAdjustObjectAttributesForPrivateNamespace.s b/libc/nt/KernelBase/BasepAdjustObjectAttributesForPrivateNamespace.s deleted file mode 100644 index 22c4ad021..000000000 --- a/libc/nt/KernelBase/BasepAdjustObjectAttributesForPrivateNamespace.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BasepAdjustObjectAttributesForPrivateNamespace,BasepAdjustObjectAttributesForPrivateNamespace,92 diff --git a/libc/nt/KernelBase/BasepCopyFileCallback.s b/libc/nt/KernelBase/BasepCopyFileCallback.s deleted file mode 100644 index c8aa7a9c8..000000000 --- a/libc/nt/KernelBase/BasepCopyFileCallback.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BasepCopyFileCallback,BasepCopyFileCallback,93 diff --git a/libc/nt/KernelBase/BasepCopyFileExW.s b/libc/nt/KernelBase/BasepCopyFileExW.s deleted file mode 100644 index 459cd096b..000000000 --- a/libc/nt/KernelBase/BasepCopyFileExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BasepCopyFileExW,BasepCopyFileExW,94 diff --git a/libc/nt/KernelBase/BasepNotifyTrackingService.s b/libc/nt/KernelBase/BasepNotifyTrackingService.s deleted file mode 100644 index 9743b6456..000000000 --- a/libc/nt/KernelBase/BasepNotifyTrackingService.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_BasepNotifyTrackingService,BasepNotifyTrackingService,95 diff --git a/libc/nt/KernelBase/CLOSE_LOCAL_HANDLE_INTERNAL.s b/libc/nt/KernelBase/CLOSE_LOCAL_HANDLE_INTERNAL.s deleted file mode 100644 index 45a28e5c5..000000000 --- a/libc/nt/KernelBase/CLOSE_LOCAL_HANDLE_INTERNAL.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CLOSE_LOCAL_HANDLE_INTERNAL,CLOSE_LOCAL_HANDLE_INTERNAL,97 diff --git a/libc/nt/KernelBase/CallEnclave.s b/libc/nt/KernelBase/CallEnclave.s deleted file mode 100644 index 7d89d40fb..000000000 --- a/libc/nt/KernelBase/CallEnclave.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CallEnclave,CallEnclave,98 diff --git a/libc/nt/KernelBase/CharLowerA.s b/libc/nt/KernelBase/CharLowerA.s deleted file mode 100644 index 68c9e1f77..000000000 --- a/libc/nt/KernelBase/CharLowerA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharLowerA,CharLowerA,108 diff --git a/libc/nt/KernelBase/CharLowerBuffA.s b/libc/nt/KernelBase/CharLowerBuffA.s deleted file mode 100644 index 280e5fb77..000000000 --- a/libc/nt/KernelBase/CharLowerBuffA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharLowerBuffA,CharLowerBuffA,109 diff --git a/libc/nt/KernelBase/CharLowerBuffW.s b/libc/nt/KernelBase/CharLowerBuffW.s deleted file mode 100644 index a6c01fb5f..000000000 --- a/libc/nt/KernelBase/CharLowerBuffW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharLowerBuffW,CharLowerBuffW,110 diff --git a/libc/nt/KernelBase/CharLowerW.s b/libc/nt/KernelBase/CharLowerW.s deleted file mode 100644 index 5e899a482..000000000 --- a/libc/nt/KernelBase/CharLowerW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharLowerW,CharLowerW,111 diff --git a/libc/nt/KernelBase/CharNextA.s b/libc/nt/KernelBase/CharNextA.s deleted file mode 100644 index 66fa9250b..000000000 --- a/libc/nt/KernelBase/CharNextA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharNextA,CharNextA,112 diff --git a/libc/nt/KernelBase/CharNextExA.s b/libc/nt/KernelBase/CharNextExA.s deleted file mode 100644 index c9ac7872a..000000000 --- a/libc/nt/KernelBase/CharNextExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharNextExA,CharNextExA,113 diff --git a/libc/nt/KernelBase/CharNextW.s b/libc/nt/KernelBase/CharNextW.s deleted file mode 100644 index 2cc3e4cd7..000000000 --- a/libc/nt/KernelBase/CharNextW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharNextW,CharNextW,114 diff --git a/libc/nt/KernelBase/CharPrevA.s b/libc/nt/KernelBase/CharPrevA.s deleted file mode 100644 index d7b654c2e..000000000 --- a/libc/nt/KernelBase/CharPrevA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharPrevA,CharPrevA,115 diff --git a/libc/nt/KernelBase/CharPrevExA.s b/libc/nt/KernelBase/CharPrevExA.s deleted file mode 100644 index 898633c9c..000000000 --- a/libc/nt/KernelBase/CharPrevExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharPrevExA,CharPrevExA,116 diff --git a/libc/nt/KernelBase/CharPrevW.s b/libc/nt/KernelBase/CharPrevW.s deleted file mode 100644 index b15ef71b9..000000000 --- a/libc/nt/KernelBase/CharPrevW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharPrevW,CharPrevW,117 diff --git a/libc/nt/KernelBase/CharUpperA.s b/libc/nt/KernelBase/CharUpperA.s deleted file mode 100644 index 4e4afedbd..000000000 --- a/libc/nt/KernelBase/CharUpperA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharUpperA,CharUpperA,118 diff --git a/libc/nt/KernelBase/CharUpperBuffA.s b/libc/nt/KernelBase/CharUpperBuffA.s deleted file mode 100644 index 3b412802c..000000000 --- a/libc/nt/KernelBase/CharUpperBuffA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharUpperBuffA,CharUpperBuffA,119 diff --git a/libc/nt/KernelBase/CharUpperBuffW.s b/libc/nt/KernelBase/CharUpperBuffW.s deleted file mode 100644 index aa649e6c3..000000000 --- a/libc/nt/KernelBase/CharUpperBuffW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharUpperBuffW,CharUpperBuffW,120 diff --git a/libc/nt/KernelBase/CharUpperW.s b/libc/nt/KernelBase/CharUpperW.s deleted file mode 100644 index ecf2234be..000000000 --- a/libc/nt/KernelBase/CharUpperW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CharUpperW,CharUpperW,121 diff --git a/libc/nt/KernelBase/CheckAllowDecryptedRemoteDestinationPolicy.s b/libc/nt/KernelBase/CheckAllowDecryptedRemoteDestinationPolicy.s deleted file mode 100644 index 449d79e90..000000000 --- a/libc/nt/KernelBase/CheckAllowDecryptedRemoteDestinationPolicy.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CheckAllowDecryptedRemoteDestinationPolicy,CheckAllowDecryptedRemoteDestinationPolicy,122 diff --git a/libc/nt/KernelBase/CheckGroupPolicyEnabled.s b/libc/nt/KernelBase/CheckGroupPolicyEnabled.s deleted file mode 100644 index 7785e885d..000000000 --- a/libc/nt/KernelBase/CheckGroupPolicyEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CheckGroupPolicyEnabled,CheckGroupPolicyEnabled,123 diff --git a/libc/nt/KernelBase/CheckIfStateChangeNotificationExists.s b/libc/nt/KernelBase/CheckIfStateChangeNotificationExists.s deleted file mode 100644 index 970937855..000000000 --- a/libc/nt/KernelBase/CheckIfStateChangeNotificationExists.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CheckIfStateChangeNotificationExists,CheckIfStateChangeNotificationExists,124 diff --git a/libc/nt/KernelBase/ChrCmpIA.s b/libc/nt/KernelBase/ChrCmpIA.s deleted file mode 100644 index 1ecdd3307..000000000 --- a/libc/nt/KernelBase/ChrCmpIA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ChrCmpIA,ChrCmpIA,129 diff --git a/libc/nt/KernelBase/ChrCmpIW.s b/libc/nt/KernelBase/ChrCmpIW.s deleted file mode 100644 index 2c9674184..000000000 --- a/libc/nt/KernelBase/ChrCmpIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ChrCmpIW,ChrCmpIW,130 diff --git a/libc/nt/KernelBase/CloseGlobalizationUserSettingsKey.s b/libc/nt/KernelBase/CloseGlobalizationUserSettingsKey.s deleted file mode 100644 index 4d987ca48..000000000 --- a/libc/nt/KernelBase/CloseGlobalizationUserSettingsKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CloseGlobalizationUserSettingsKey,CloseGlobalizationUserSettingsKey,133 diff --git a/libc/nt/KernelBase/CloseState.s b/libc/nt/KernelBase/CloseState.s deleted file mode 100644 index 540b9c6fb..000000000 --- a/libc/nt/KernelBase/CloseState.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CloseState,CloseState,137 diff --git a/libc/nt/KernelBase/CloseStateAtom.s b/libc/nt/KernelBase/CloseStateAtom.s deleted file mode 100644 index 17fb216e3..000000000 --- a/libc/nt/KernelBase/CloseStateAtom.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CloseStateAtom,CloseStateAtom,138 diff --git a/libc/nt/KernelBase/CloseStateChangeNotification.s b/libc/nt/KernelBase/CloseStateChangeNotification.s deleted file mode 100644 index 59cf4c8dd..000000000 --- a/libc/nt/KernelBase/CloseStateChangeNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CloseStateChangeNotification,CloseStateChangeNotification,139 diff --git a/libc/nt/KernelBase/CloseStateContainer.s b/libc/nt/KernelBase/CloseStateContainer.s deleted file mode 100644 index db48fffe2..000000000 --- a/libc/nt/KernelBase/CloseStateContainer.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CloseStateContainer,CloseStateContainer,140 diff --git a/libc/nt/KernelBase/CloseStateLock.s b/libc/nt/KernelBase/CloseStateLock.s deleted file mode 100644 index ff9e3e5b5..000000000 --- a/libc/nt/KernelBase/CloseStateLock.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CloseStateLock,CloseStateLock,141 diff --git a/libc/nt/KernelBase/CommitStateAtom.s b/libc/nt/KernelBase/CommitStateAtom.s deleted file mode 100644 index 595bcbc88..000000000 --- a/libc/nt/KernelBase/CommitStateAtom.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CommitStateAtom,CommitStateAtom,149 diff --git a/libc/nt/KernelBase/CompareObjectHandles.s b/libc/nt/KernelBase/CompareObjectHandles.s deleted file mode 100644 index 228c883c2..000000000 --- a/libc/nt/KernelBase/CompareObjectHandles.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CompareObjectHandles,CompareObjectHandles,151 diff --git a/libc/nt/KernelBase/ConvertAuxiliaryCounterToPerformanceCounter.s b/libc/nt/KernelBase/ConvertAuxiliaryCounterToPerformanceCounter.s deleted file mode 100644 index 73ca792f7..000000000 --- a/libc/nt/KernelBase/ConvertAuxiliaryCounterToPerformanceCounter.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ConvertAuxiliaryCounterToPerformanceCounter,ConvertAuxiliaryCounterToPerformanceCounter,158 diff --git a/libc/nt/KernelBase/ConvertPerformanceCounterToAuxiliaryCounter.s b/libc/nt/KernelBase/ConvertPerformanceCounterToAuxiliaryCounter.s deleted file mode 100644 index d3bae779b..000000000 --- a/libc/nt/KernelBase/ConvertPerformanceCounterToAuxiliaryCounter.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ConvertPerformanceCounterToAuxiliaryCounter,ConvertPerformanceCounterToAuxiliaryCounter,161 diff --git a/libc/nt/KernelBase/CouldMultiUserAppsBehaviorBePossibleForPackage.s b/libc/nt/KernelBase/CouldMultiUserAppsBehaviorBePossibleForPackage.s deleted file mode 100644 index 95bea41d4..000000000 --- a/libc/nt/KernelBase/CouldMultiUserAppsBehaviorBePossibleForPackage.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CouldMultiUserAppsBehaviorBePossibleForPackage,CouldMultiUserAppsBehaviorBePossibleForPackage,171 diff --git a/libc/nt/KernelBase/CreateAppContainerToken.s b/libc/nt/KernelBase/CreateAppContainerToken.s deleted file mode 100644 index d6ea75389..000000000 --- a/libc/nt/KernelBase/CreateAppContainerToken.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateAppContainerToken,CreateAppContainerToken,173 diff --git a/libc/nt/KernelBase/CreateAppContainerTokenForUser.s b/libc/nt/KernelBase/CreateAppContainerTokenForUser.s deleted file mode 100644 index 2d8ef8f08..000000000 --- a/libc/nt/KernelBase/CreateAppContainerTokenForUser.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateAppContainerTokenForUser,CreateAppContainerTokenForUser,174 diff --git a/libc/nt/KernelBase/CreateEnclave.s b/libc/nt/KernelBase/CreateEnclave.s deleted file mode 100644 index 6e9c52638..000000000 --- a/libc/nt/KernelBase/CreateEnclave.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateEnclave,CreateEnclave,180 diff --git a/libc/nt/KernelBase/CreateProcessInternalA.s b/libc/nt/KernelBase/CreateProcessInternalA.s deleted file mode 100644 index 17866d6b5..000000000 --- a/libc/nt/KernelBase/CreateProcessInternalA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateProcessInternalA,CreateProcessInternalA,210 diff --git a/libc/nt/KernelBase/CreateProcessInternalW.s b/libc/nt/KernelBase/CreateProcessInternalW.s deleted file mode 100644 index a2f0281d8..000000000 --- a/libc/nt/KernelBase/CreateProcessInternalW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateProcessInternalW,CreateProcessInternalW,211 diff --git a/libc/nt/KernelBase/CreateStateAtom.s b/libc/nt/KernelBase/CreateStateAtom.s deleted file mode 100644 index dd932fe7d..000000000 --- a/libc/nt/KernelBase/CreateStateAtom.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateStateAtom,CreateStateAtom,218 diff --git a/libc/nt/KernelBase/CreateStateChangeNotification.s b/libc/nt/KernelBase/CreateStateChangeNotification.s deleted file mode 100644 index d6aa69784..000000000 --- a/libc/nt/KernelBase/CreateStateChangeNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateStateChangeNotification,CreateStateChangeNotification,219 diff --git a/libc/nt/KernelBase/CreateStateContainer.s b/libc/nt/KernelBase/CreateStateContainer.s deleted file mode 100644 index 2920265ef..000000000 --- a/libc/nt/KernelBase/CreateStateContainer.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateStateContainer,CreateStateContainer,220 diff --git a/libc/nt/KernelBase/CreateStateLock.s b/libc/nt/KernelBase/CreateStateLock.s deleted file mode 100644 index 89bae352e..000000000 --- a/libc/nt/KernelBase/CreateStateLock.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateStateLock,CreateStateLock,221 diff --git a/libc/nt/KernelBase/CreateStateSubcontainer.s b/libc/nt/KernelBase/CreateStateSubcontainer.s deleted file mode 100644 index aaab2d3fb..000000000 --- a/libc/nt/KernelBase/CreateStateSubcontainer.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CreateStateSubcontainer,CreateStateSubcontainer,222 diff --git a/libc/nt/KernelBase/CtrlRoutine.s b/libc/nt/KernelBase/CtrlRoutine.s deleted file mode 100644 index cbf47575a..000000000 --- a/libc/nt/KernelBase/CtrlRoutine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CtrlRoutine,CtrlRoutine,236 diff --git a/libc/nt/KernelBase/CveEventWrite.s b/libc/nt/KernelBase/CveEventWrite.s deleted file mode 100644 index 2e6ed1a8a..000000000 --- a/libc/nt/KernelBase/CveEventWrite.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_CveEventWrite,CveEventWrite,237 diff --git a/libc/nt/KernelBase/DelayLoadFailureHook.s b/libc/nt/KernelBase/DelayLoadFailureHook.s deleted file mode 100644 index 841e5d0c4..000000000 --- a/libc/nt/KernelBase/DelayLoadFailureHook.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DelayLoadFailureHook,DelayLoadFailureHook,246 diff --git a/libc/nt/KernelBase/DelayLoadFailureHookLookup.s b/libc/nt/KernelBase/DelayLoadFailureHookLookup.s deleted file mode 100644 index 1acc7db77..000000000 --- a/libc/nt/KernelBase/DelayLoadFailureHookLookup.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DelayLoadFailureHookLookup,DelayLoadFailureHookLookup,247 diff --git a/libc/nt/KernelBase/DeleteEnclave.s b/libc/nt/KernelBase/DeleteEnclave.s deleted file mode 100644 index ee23e2a3d..000000000 --- a/libc/nt/KernelBase/DeleteEnclave.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DeleteEnclave,DeleteEnclave,251 diff --git a/libc/nt/KernelBase/DeleteStateAtomValue.s b/libc/nt/KernelBase/DeleteStateAtomValue.s deleted file mode 100644 index e3639361e..000000000 --- a/libc/nt/KernelBase/DeleteStateAtomValue.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DeleteStateAtomValue,DeleteStateAtomValue,256 diff --git a/libc/nt/KernelBase/DeleteStateContainer.s b/libc/nt/KernelBase/DeleteStateContainer.s deleted file mode 100644 index ae5de771a..000000000 --- a/libc/nt/KernelBase/DeleteStateContainer.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DeleteStateContainer,DeleteStateContainer,257 diff --git a/libc/nt/KernelBase/DeleteStateContainerValue.s b/libc/nt/KernelBase/DeleteStateContainerValue.s deleted file mode 100644 index 829fbc330..000000000 --- a/libc/nt/KernelBase/DeleteStateContainerValue.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DeleteStateContainerValue,DeleteStateContainerValue,258 diff --git a/libc/nt/KernelBase/DeriveCapabilitySidsFromName.s b/libc/nt/KernelBase/DeriveCapabilitySidsFromName.s deleted file mode 100644 index 004984e7f..000000000 --- a/libc/nt/KernelBase/DeriveCapabilitySidsFromName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DeriveCapabilitySidsFromName,DeriveCapabilitySidsFromName,263 diff --git a/libc/nt/KernelBase/DisablePredefinedHandleTableInternal.s b/libc/nt/KernelBase/DisablePredefinedHandleTableInternal.s deleted file mode 100644 index 4882a11a0..000000000 --- a/libc/nt/KernelBase/DisablePredefinedHandleTableInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DisablePredefinedHandleTableInternal,DisablePredefinedHandleTableInternal,266 diff --git a/libc/nt/KernelBase/DnsHostnameToComputerNameExW.s b/libc/nt/KernelBase/DnsHostnameToComputerNameExW.s deleted file mode 100644 index b9d32760d..000000000 --- a/libc/nt/KernelBase/DnsHostnameToComputerNameExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DnsHostnameToComputerNameExW,DnsHostnameToComputerNameExW,271 diff --git a/libc/nt/KernelBase/DsBindWithSpnExW.s b/libc/nt/KernelBase/DsBindWithSpnExW.s deleted file mode 100644 index 5b7a0094f..000000000 --- a/libc/nt/KernelBase/DsBindWithSpnExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsBindWithSpnExW,DsBindWithSpnExW,272 diff --git a/libc/nt/KernelBase/DsCrackNamesW.s b/libc/nt/KernelBase/DsCrackNamesW.s deleted file mode 100644 index 0c4486719..000000000 --- a/libc/nt/KernelBase/DsCrackNamesW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsCrackNamesW,DsCrackNamesW,273 diff --git a/libc/nt/KernelBase/DsFreeDomainControllerInfoW.s b/libc/nt/KernelBase/DsFreeDomainControllerInfoW.s deleted file mode 100644 index 5d13d070e..000000000 --- a/libc/nt/KernelBase/DsFreeDomainControllerInfoW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsFreeDomainControllerInfoW,DsFreeDomainControllerInfoW,274 diff --git a/libc/nt/KernelBase/DsFreeNameResultW.s b/libc/nt/KernelBase/DsFreeNameResultW.s deleted file mode 100644 index ab0d6029b..000000000 --- a/libc/nt/KernelBase/DsFreeNameResultW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsFreeNameResultW,DsFreeNameResultW,275 diff --git a/libc/nt/KernelBase/DsFreeNgcKey.s b/libc/nt/KernelBase/DsFreeNgcKey.s deleted file mode 100644 index 91d3487a9..000000000 --- a/libc/nt/KernelBase/DsFreeNgcKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsFreeNgcKey,DsFreeNgcKey,276 diff --git a/libc/nt/KernelBase/DsFreePasswordCredentials.s b/libc/nt/KernelBase/DsFreePasswordCredentials.s deleted file mode 100644 index 5b06e173f..000000000 --- a/libc/nt/KernelBase/DsFreePasswordCredentials.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsFreePasswordCredentials,DsFreePasswordCredentials,277 diff --git a/libc/nt/KernelBase/DsGetDomainControllerInfoW.s b/libc/nt/KernelBase/DsGetDomainControllerInfoW.s deleted file mode 100644 index 45793664b..000000000 --- a/libc/nt/KernelBase/DsGetDomainControllerInfoW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsGetDomainControllerInfoW,DsGetDomainControllerInfoW,278 diff --git a/libc/nt/KernelBase/DsMakePasswordCredentialsW.s b/libc/nt/KernelBase/DsMakePasswordCredentialsW.s deleted file mode 100644 index 66bc309d9..000000000 --- a/libc/nt/KernelBase/DsMakePasswordCredentialsW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsMakePasswordCredentialsW,DsMakePasswordCredentialsW,279 diff --git a/libc/nt/KernelBase/DsReadNgcKeyW.s b/libc/nt/KernelBase/DsReadNgcKeyW.s deleted file mode 100644 index be2cdc66d..000000000 --- a/libc/nt/KernelBase/DsReadNgcKeyW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsReadNgcKeyW,DsReadNgcKeyW,280 diff --git a/libc/nt/KernelBase/DsUnBindW.s b/libc/nt/KernelBase/DsUnBindW.s deleted file mode 100644 index 1dbfcc379..000000000 --- a/libc/nt/KernelBase/DsUnBindW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsUnBindW,DsUnBindW,281 diff --git a/libc/nt/KernelBase/DsWriteNgcKeyW.s b/libc/nt/KernelBase/DsWriteNgcKeyW.s deleted file mode 100644 index 4872c023f..000000000 --- a/libc/nt/KernelBase/DsWriteNgcKeyW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DsWriteNgcKeyW,DsWriteNgcKeyW,282 diff --git a/libc/nt/KernelBase/DuplicateStateContainerHandle.s b/libc/nt/KernelBase/DuplicateStateContainerHandle.s deleted file mode 100644 index 45ba50e16..000000000 --- a/libc/nt/KernelBase/DuplicateStateContainerHandle.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_DuplicateStateContainerHandle,DuplicateStateContainerHandle,284 diff --git a/libc/nt/KernelBase/EmptyWorkingSet.s b/libc/nt/KernelBase/EmptyWorkingSet.s deleted file mode 100644 index 911ef1ca2..000000000 --- a/libc/nt/KernelBase/EmptyWorkingSet.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EmptyWorkingSet,EmptyWorkingSet,287 diff --git a/libc/nt/KernelBase/EnterCriticalPolicySectionInternal.s b/libc/nt/KernelBase/EnterCriticalPolicySectionInternal.s deleted file mode 100644 index 051a18846..000000000 --- a/libc/nt/KernelBase/EnterCriticalPolicySectionInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnterCriticalPolicySectionInternal,EnterCriticalPolicySectionInternal,291 diff --git a/libc/nt/KernelBase/EnumDeviceDrivers.s b/libc/nt/KernelBase/EnumDeviceDrivers.s deleted file mode 100644 index 9e8f6850e..000000000 --- a/libc/nt/KernelBase/EnumDeviceDrivers.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumDeviceDrivers,EnumDeviceDrivers,300 diff --git a/libc/nt/KernelBase/EnumDynamicTimeZoneInformation.s b/libc/nt/KernelBase/EnumDynamicTimeZoneInformation.s deleted file mode 100644 index c8326ee73..000000000 --- a/libc/nt/KernelBase/EnumDynamicTimeZoneInformation.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumDynamicTimeZoneInformation,EnumDynamicTimeZoneInformation,301 diff --git a/libc/nt/KernelBase/EnumPageFilesA.s b/libc/nt/KernelBase/EnumPageFilesA.s deleted file mode 100644 index 8ceb2d182..000000000 --- a/libc/nt/KernelBase/EnumPageFilesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumPageFilesA,EnumPageFilesA,303 diff --git a/libc/nt/KernelBase/EnumPageFilesW.s b/libc/nt/KernelBase/EnumPageFilesW.s deleted file mode 100644 index 66a4b9f37..000000000 --- a/libc/nt/KernelBase/EnumPageFilesW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumPageFilesW,EnumPageFilesW,304 diff --git a/libc/nt/KernelBase/EnumProcessModules.s b/libc/nt/KernelBase/EnumProcessModules.s deleted file mode 100644 index 0b9b116eb..000000000 --- a/libc/nt/KernelBase/EnumProcessModules.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumProcessModules,EnumProcessModules,305 diff --git a/libc/nt/KernelBase/EnumProcessModulesEx.s b/libc/nt/KernelBase/EnumProcessModulesEx.s deleted file mode 100644 index 5e4366cdb..000000000 --- a/libc/nt/KernelBase/EnumProcessModulesEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumProcessModulesEx,EnumProcessModulesEx,306 diff --git a/libc/nt/KernelBase/EnumProcesses.s b/libc/nt/KernelBase/EnumProcesses.s deleted file mode 100644 index cb704c5cb..000000000 --- a/libc/nt/KernelBase/EnumProcesses.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumProcesses,EnumProcesses,307 diff --git a/libc/nt/KernelBase/EnumSystemGeoNames.s b/libc/nt/KernelBase/EnumSystemGeoNames.s deleted file mode 100644 index 060c8e908..000000000 --- a/libc/nt/KernelBase/EnumSystemGeoNames.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumSystemGeoNames,EnumSystemGeoNames,318 diff --git a/libc/nt/KernelBase/EnumerateExtensionNames.s b/libc/nt/KernelBase/EnumerateExtensionNames.s deleted file mode 100644 index e1f16c60f..000000000 --- a/libc/nt/KernelBase/EnumerateExtensionNames.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumerateExtensionNames,EnumerateExtensionNames,326 diff --git a/libc/nt/KernelBase/EnumerateStateAtomValues.s b/libc/nt/KernelBase/EnumerateStateAtomValues.s deleted file mode 100644 index e633a3e00..000000000 --- a/libc/nt/KernelBase/EnumerateStateAtomValues.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumerateStateAtomValues,EnumerateStateAtomValues,327 diff --git a/libc/nt/KernelBase/EnumerateStateContainerItems.s b/libc/nt/KernelBase/EnumerateStateContainerItems.s deleted file mode 100644 index c5e9628e5..000000000 --- a/libc/nt/KernelBase/EnumerateStateContainerItems.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_EnumerateStateContainerItems,EnumerateStateContainerItems,328 diff --git a/libc/nt/KernelBase/ExpungeConsoleCommandHistoryA.s b/libc/nt/KernelBase/ExpungeConsoleCommandHistoryA.s deleted file mode 100644 index 7a72c2fa9..000000000 --- a/libc/nt/KernelBase/ExpungeConsoleCommandHistoryA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ExpungeConsoleCommandHistoryA,ExpungeConsoleCommandHistoryA,347 diff --git a/libc/nt/KernelBase/ExpungeConsoleCommandHistoryW.s b/libc/nt/KernelBase/ExpungeConsoleCommandHistoryW.s deleted file mode 100644 index 001a51468..000000000 --- a/libc/nt/KernelBase/ExpungeConsoleCommandHistoryW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ExpungeConsoleCommandHistoryW,ExpungeConsoleCommandHistoryW,348 diff --git a/libc/nt/KernelBase/ExtensionProgIdExists.s b/libc/nt/KernelBase/ExtensionProgIdExists.s deleted file mode 100644 index a4a6c31f0..000000000 --- a/libc/nt/KernelBase/ExtensionProgIdExists.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ExtensionProgIdExists,ExtensionProgIdExists,349 diff --git a/libc/nt/KernelBase/ForceSyncFgPolicyInternal.s b/libc/nt/KernelBase/ForceSyncFgPolicyInternal.s deleted file mode 100644 index e52eebd8a..000000000 --- a/libc/nt/KernelBase/ForceSyncFgPolicyInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ForceSyncFgPolicyInternal,ForceSyncFgPolicyInternal,394 diff --git a/libc/nt/KernelBase/FormatApplicationUserModelIdA.s b/libc/nt/KernelBase/FormatApplicationUserModelIdA.s deleted file mode 100644 index 8afa40597..000000000 --- a/libc/nt/KernelBase/FormatApplicationUserModelIdA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_FormatApplicationUserModelIdA,FormatApplicationUserModelIdA,396 diff --git a/libc/nt/KernelBase/FreeGPOListInternalA.s b/libc/nt/KernelBase/FreeGPOListInternalA.s deleted file mode 100644 index 996ead4ff..000000000 --- a/libc/nt/KernelBase/FreeGPOListInternalA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_FreeGPOListInternalA,FreeGPOListInternalA,402 diff --git a/libc/nt/KernelBase/FreeGPOListInternalW.s b/libc/nt/KernelBase/FreeGPOListInternalW.s deleted file mode 100644 index 4ff9cbe44..000000000 --- a/libc/nt/KernelBase/FreeGPOListInternalW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_FreeGPOListInternalW,FreeGPOListInternalW,403 diff --git a/libc/nt/KernelBase/GenerateGPNotificationInternal.s b/libc/nt/KernelBase/GenerateGPNotificationInternal.s deleted file mode 100644 index 18896e783..000000000 --- a/libc/nt/KernelBase/GenerateGPNotificationInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GenerateGPNotificationInternal,GenerateGPNotificationInternal,411 diff --git a/libc/nt/KernelBase/GetAcceptLanguagesA.s b/libc/nt/KernelBase/GetAcceptLanguagesA.s deleted file mode 100644 index 910640352..000000000 --- a/libc/nt/KernelBase/GetAcceptLanguagesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAcceptLanguagesA,GetAcceptLanguagesA,413 diff --git a/libc/nt/KernelBase/GetAcceptLanguagesW.s b/libc/nt/KernelBase/GetAcceptLanguagesW.s deleted file mode 100644 index 7ac2a93db..000000000 --- a/libc/nt/KernelBase/GetAcceptLanguagesW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAcceptLanguagesW,GetAcceptLanguagesW,414 diff --git a/libc/nt/KernelBase/GetAdjustObjectAttributesForPrivateNamespaceRoutine.s b/libc/nt/KernelBase/GetAdjustObjectAttributesForPrivateNamespaceRoutine.s deleted file mode 100644 index 3ed90b0df..000000000 --- a/libc/nt/KernelBase/GetAdjustObjectAttributesForPrivateNamespaceRoutine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAdjustObjectAttributesForPrivateNamespaceRoutine,GetAdjustObjectAttributesForPrivateNamespaceRoutine,417 diff --git a/libc/nt/KernelBase/GetAlternatePackageRoots.s b/libc/nt/KernelBase/GetAlternatePackageRoots.s deleted file mode 100644 index b13e06fd6..000000000 --- a/libc/nt/KernelBase/GetAlternatePackageRoots.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAlternatePackageRoots,GetAlternatePackageRoots,418 diff --git a/libc/nt/KernelBase/GetAppContainerAce.s b/libc/nt/KernelBase/GetAppContainerAce.s deleted file mode 100644 index f2a12af96..000000000 --- a/libc/nt/KernelBase/GetAppContainerAce.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAppContainerAce,GetAppContainerAce,419 diff --git a/libc/nt/KernelBase/GetAppDataFolder.s b/libc/nt/KernelBase/GetAppDataFolder.s deleted file mode 100644 index 45cfef212..000000000 --- a/libc/nt/KernelBase/GetAppDataFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAppDataFolder,GetAppDataFolder,421 diff --git a/libc/nt/KernelBase/GetAppModelVersion.s b/libc/nt/KernelBase/GetAppModelVersion.s deleted file mode 100644 index f4967a520..000000000 --- a/libc/nt/KernelBase/GetAppModelVersion.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAppModelVersion,GetAppModelVersion,422 diff --git a/libc/nt/KernelBase/GetApplicationUserModelIdFromToken.s b/libc/nt/KernelBase/GetApplicationUserModelIdFromToken.s deleted file mode 100644 index 1a65f8d80..000000000 --- a/libc/nt/KernelBase/GetApplicationUserModelIdFromToken.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetApplicationUserModelIdFromToken,GetApplicationUserModelIdFromToken,426 diff --git a/libc/nt/KernelBase/GetAppliedGPOListInternalA.s b/libc/nt/KernelBase/GetAppliedGPOListInternalA.s deleted file mode 100644 index 51eccbbff..000000000 --- a/libc/nt/KernelBase/GetAppliedGPOListInternalA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAppliedGPOListInternalA,GetAppliedGPOListInternalA,427 diff --git a/libc/nt/KernelBase/GetAppliedGPOListInternalW.s b/libc/nt/KernelBase/GetAppliedGPOListInternalW.s deleted file mode 100644 index e1fe077c8..000000000 --- a/libc/nt/KernelBase/GetAppliedGPOListInternalW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetAppliedGPOListInternalW,GetAppliedGPOListInternalW,428 diff --git a/libc/nt/KernelBase/GetCPFileNameFromRegistry.s b/libc/nt/KernelBase/GetCPFileNameFromRegistry.s deleted file mode 100644 index a26b217f1..000000000 --- a/libc/nt/KernelBase/GetCPFileNameFromRegistry.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCPFileNameFromRegistry,GetCPFileNameFromRegistry,429 diff --git a/libc/nt/KernelBase/GetCPHashNode.s b/libc/nt/KernelBase/GetCPHashNode.s deleted file mode 100644 index 32f01e19e..000000000 --- a/libc/nt/KernelBase/GetCPHashNode.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCPHashNode,GetCPHashNode,430 diff --git a/libc/nt/KernelBase/GetCachedSigningLevel.s b/libc/nt/KernelBase/GetCachedSigningLevel.s deleted file mode 100644 index 30a7ca5ea..000000000 --- a/libc/nt/KernelBase/GetCachedSigningLevel.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCachedSigningLevel,GetCachedSigningLevel,433 diff --git a/libc/nt/KernelBase/GetCalendar.s b/libc/nt/KernelBase/GetCalendar.s deleted file mode 100644 index 2876137e3..000000000 --- a/libc/nt/KernelBase/GetCalendar.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCalendar,GetCalendar,434 diff --git a/libc/nt/KernelBase/GetCommPorts.s b/libc/nt/KernelBase/GetCommPorts.s deleted file mode 100644 index d31f65051..000000000 --- a/libc/nt/KernelBase/GetCommPorts.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCommPorts,GetCommPorts,440 diff --git a/libc/nt/KernelBase/GetConsoleCommandHistoryA.s b/libc/nt/KernelBase/GetConsoleCommandHistoryA.s deleted file mode 100644 index 9bafb968a..000000000 --- a/libc/nt/KernelBase/GetConsoleCommandHistoryA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetConsoleCommandHistoryA,GetConsoleCommandHistoryA,461 diff --git a/libc/nt/KernelBase/GetConsoleCommandHistoryLengthA.s b/libc/nt/KernelBase/GetConsoleCommandHistoryLengthA.s deleted file mode 100644 index 591d20405..000000000 --- a/libc/nt/KernelBase/GetConsoleCommandHistoryLengthA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetConsoleCommandHistoryLengthA,GetConsoleCommandHistoryLengthA,462 diff --git a/libc/nt/KernelBase/GetConsoleCommandHistoryLengthW.s b/libc/nt/KernelBase/GetConsoleCommandHistoryLengthW.s deleted file mode 100644 index 4c35dbc3e..000000000 --- a/libc/nt/KernelBase/GetConsoleCommandHistoryLengthW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetConsoleCommandHistoryLengthW,GetConsoleCommandHistoryLengthW,463 diff --git a/libc/nt/KernelBase/GetConsoleCommandHistoryW.s b/libc/nt/KernelBase/GetConsoleCommandHistoryW.s deleted file mode 100644 index e8f470779..000000000 --- a/libc/nt/KernelBase/GetConsoleCommandHistoryW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetConsoleCommandHistoryW,GetConsoleCommandHistoryW,464 diff --git a/libc/nt/KernelBase/GetConsoleInputExeNameA.s b/libc/nt/KernelBase/GetConsoleInputExeNameA.s deleted file mode 100644 index ac1f67686..000000000 --- a/libc/nt/KernelBase/GetConsoleInputExeNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetConsoleInputExeNameA,GetConsoleInputExeNameA,469 diff --git a/libc/nt/KernelBase/GetConsoleInputExeNameW.s b/libc/nt/KernelBase/GetConsoleInputExeNameW.s deleted file mode 100644 index b317041c1..000000000 --- a/libc/nt/KernelBase/GetConsoleInputExeNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetConsoleInputExeNameW,GetConsoleInputExeNameW,470 diff --git a/libc/nt/KernelBase/GetCurrentPackageApplicationContext.s b/libc/nt/KernelBase/GetCurrentPackageApplicationContext.s deleted file mode 100644 index 00f0659eb..000000000 --- a/libc/nt/KernelBase/GetCurrentPackageApplicationContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCurrentPackageApplicationContext,GetCurrentPackageApplicationContext,490 diff --git a/libc/nt/KernelBase/GetCurrentPackageApplicationResourcesContext.s b/libc/nt/KernelBase/GetCurrentPackageApplicationResourcesContext.s deleted file mode 100644 index 2f5d6be76..000000000 --- a/libc/nt/KernelBase/GetCurrentPackageApplicationResourcesContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCurrentPackageApplicationResourcesContext,GetCurrentPackageApplicationResourcesContext,491 diff --git a/libc/nt/KernelBase/GetCurrentPackageContext.s b/libc/nt/KernelBase/GetCurrentPackageContext.s deleted file mode 100644 index 2ad2740d1..000000000 --- a/libc/nt/KernelBase/GetCurrentPackageContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCurrentPackageContext,GetCurrentPackageContext,492 diff --git a/libc/nt/KernelBase/GetCurrentPackageResourcesContext.s b/libc/nt/KernelBase/GetCurrentPackageResourcesContext.s deleted file mode 100644 index 5e3dbc74b..000000000 --- a/libc/nt/KernelBase/GetCurrentPackageResourcesContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCurrentPackageResourcesContext,GetCurrentPackageResourcesContext,498 diff --git a/libc/nt/KernelBase/GetCurrentPackageSecurityContext.s b/libc/nt/KernelBase/GetCurrentPackageSecurityContext.s deleted file mode 100644 index 0b109d6ff..000000000 --- a/libc/nt/KernelBase/GetCurrentPackageSecurityContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCurrentPackageSecurityContext,GetCurrentPackageSecurityContext,499 diff --git a/libc/nt/KernelBase/GetCurrentTargetPlatformContext.s b/libc/nt/KernelBase/GetCurrentTargetPlatformContext.s deleted file mode 100644 index ccaf68584..000000000 --- a/libc/nt/KernelBase/GetCurrentTargetPlatformContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetCurrentTargetPlatformContext,GetCurrentTargetPlatformContext,504 diff --git a/libc/nt/KernelBase/GetDeviceDriverBaseNameA.s b/libc/nt/KernelBase/GetDeviceDriverBaseNameA.s deleted file mode 100644 index df0486063..000000000 --- a/libc/nt/KernelBase/GetDeviceDriverBaseNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetDeviceDriverBaseNameA,GetDeviceDriverBaseNameA,511 diff --git a/libc/nt/KernelBase/GetDeviceDriverBaseNameW.s b/libc/nt/KernelBase/GetDeviceDriverBaseNameW.s deleted file mode 100644 index 1908f1887..000000000 --- a/libc/nt/KernelBase/GetDeviceDriverBaseNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetDeviceDriverBaseNameW,GetDeviceDriverBaseNameW,512 diff --git a/libc/nt/KernelBase/GetDeviceDriverFileNameA.s b/libc/nt/KernelBase/GetDeviceDriverFileNameA.s deleted file mode 100644 index 7c6baa79b..000000000 --- a/libc/nt/KernelBase/GetDeviceDriverFileNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetDeviceDriverFileNameA,GetDeviceDriverFileNameA,513 diff --git a/libc/nt/KernelBase/GetDeviceDriverFileNameW.s b/libc/nt/KernelBase/GetDeviceDriverFileNameW.s deleted file mode 100644 index 801b800a6..000000000 --- a/libc/nt/KernelBase/GetDeviceDriverFileNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetDeviceDriverFileNameW,GetDeviceDriverFileNameW,514 diff --git a/libc/nt/KernelBase/GetDynamicTimeZoneInformationEffectiveYears.s b/libc/nt/KernelBase/GetDynamicTimeZoneInformationEffectiveYears.s deleted file mode 100644 index 72f021fa9..000000000 --- a/libc/nt/KernelBase/GetDynamicTimeZoneInformationEffectiveYears.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetDynamicTimeZoneInformationEffectiveYears,GetDynamicTimeZoneInformationEffectiveYears,523 diff --git a/libc/nt/KernelBase/GetEffectivePackageStatusForUser.s b/libc/nt/KernelBase/GetEffectivePackageStatusForUser.s deleted file mode 100644 index 5d37a3d8c..000000000 --- a/libc/nt/KernelBase/GetEffectivePackageStatusForUser.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetEffectivePackageStatusForUser,GetEffectivePackageStatusForUser,524 diff --git a/libc/nt/KernelBase/GetEffectivePackageStatusForUserSid.s b/libc/nt/KernelBase/GetEffectivePackageStatusForUserSid.s deleted file mode 100644 index ba384e30c..000000000 --- a/libc/nt/KernelBase/GetEffectivePackageStatusForUserSid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetEffectivePackageStatusForUserSid,GetEffectivePackageStatusForUserSid,525 diff --git a/libc/nt/KernelBase/GetEightBitStringToUnicodeSizeRoutine.s b/libc/nt/KernelBase/GetEightBitStringToUnicodeSizeRoutine.s deleted file mode 100644 index 07fddb968..000000000 --- a/libc/nt/KernelBase/GetEightBitStringToUnicodeSizeRoutine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetEightBitStringToUnicodeSizeRoutine,GetEightBitStringToUnicodeSizeRoutine,526 diff --git a/libc/nt/KernelBase/GetEightBitStringToUnicodeStringRoutine.s b/libc/nt/KernelBase/GetEightBitStringToUnicodeStringRoutine.s deleted file mode 100644 index f86e9e10a..000000000 --- a/libc/nt/KernelBase/GetEightBitStringToUnicodeStringRoutine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetEightBitStringToUnicodeStringRoutine,GetEightBitStringToUnicodeStringRoutine,527 diff --git a/libc/nt/KernelBase/GetEraNameCountedString.s b/libc/nt/KernelBase/GetEraNameCountedString.s deleted file mode 100644 index bffabfbff..000000000 --- a/libc/nt/KernelBase/GetEraNameCountedString.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetEraNameCountedString,GetEraNameCountedString,534 diff --git a/libc/nt/KernelBase/GetExtensionApplicationUserModelId.s b/libc/nt/KernelBase/GetExtensionApplicationUserModelId.s deleted file mode 100644 index 465482c0e..000000000 --- a/libc/nt/KernelBase/GetExtensionApplicationUserModelId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetExtensionApplicationUserModelId,GetExtensionApplicationUserModelId,538 diff --git a/libc/nt/KernelBase/GetExtensionProgIds.s b/libc/nt/KernelBase/GetExtensionProgIds.s deleted file mode 100644 index 051762dab..000000000 --- a/libc/nt/KernelBase/GetExtensionProgIds.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetExtensionProgIds,GetExtensionProgIds,539 diff --git a/libc/nt/KernelBase/GetExtensionProperty.s b/libc/nt/KernelBase/GetExtensionProperty.s deleted file mode 100644 index 6c3f1aafa..000000000 --- a/libc/nt/KernelBase/GetExtensionProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetExtensionProperty,GetExtensionProperty,540 diff --git a/libc/nt/KernelBase/GetExtensionProperty2.s b/libc/nt/KernelBase/GetExtensionProperty2.s deleted file mode 100644 index 7a41df7aa..000000000 --- a/libc/nt/KernelBase/GetExtensionProperty2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetExtensionProperty2,GetExtensionProperty2,541 diff --git a/libc/nt/KernelBase/GetFallbackDisplayName.s b/libc/nt/KernelBase/GetFallbackDisplayName.s deleted file mode 100644 index fe7c44c2c..000000000 --- a/libc/nt/KernelBase/GetFallbackDisplayName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFallbackDisplayName,GetFallbackDisplayName,542 diff --git a/libc/nt/KernelBase/GetFileVersionInfoA.s b/libc/nt/KernelBase/GetFileVersionInfoA.s deleted file mode 100644 index d4af0a1da..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoA,GetFileVersionInfoA,556 diff --git a/libc/nt/KernelBase/GetFileVersionInfoByHandle.s b/libc/nt/KernelBase/GetFileVersionInfoByHandle.s deleted file mode 100644 index 24fad9789..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoByHandle.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoByHandle,GetFileVersionInfoByHandle,557 diff --git a/libc/nt/KernelBase/GetFileVersionInfoExA.s b/libc/nt/KernelBase/GetFileVersionInfoExA.s deleted file mode 100644 index 7f9358e38..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoExA,GetFileVersionInfoExA,558 diff --git a/libc/nt/KernelBase/GetFileVersionInfoExW.s b/libc/nt/KernelBase/GetFileVersionInfoExW.s deleted file mode 100644 index 740867b2f..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoExW,GetFileVersionInfoExW,559 diff --git a/libc/nt/KernelBase/GetFileVersionInfoSizeA.s b/libc/nt/KernelBase/GetFileVersionInfoSizeA.s deleted file mode 100644 index a2ebb2344..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoSizeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoSizeA,GetFileVersionInfoSizeA,560 diff --git a/libc/nt/KernelBase/GetFileVersionInfoSizeExA.s b/libc/nt/KernelBase/GetFileVersionInfoSizeExA.s deleted file mode 100644 index 7ff028881..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoSizeExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoSizeExA,GetFileVersionInfoSizeExA,561 diff --git a/libc/nt/KernelBase/GetFileVersionInfoSizeExW.s b/libc/nt/KernelBase/GetFileVersionInfoSizeExW.s deleted file mode 100644 index f69d1d02c..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoSizeExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoSizeExW,GetFileVersionInfoSizeExW,562 diff --git a/libc/nt/KernelBase/GetFileVersionInfoSizeW.s b/libc/nt/KernelBase/GetFileVersionInfoSizeW.s deleted file mode 100644 index 4c0298a38..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoSizeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoSizeW,GetFileVersionInfoSizeW,563 diff --git a/libc/nt/KernelBase/GetFileVersionInfoW.s b/libc/nt/KernelBase/GetFileVersionInfoW.s deleted file mode 100644 index d078c97b5..000000000 --- a/libc/nt/KernelBase/GetFileVersionInfoW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetFileVersionInfoW,GetFileVersionInfoW,564 diff --git a/libc/nt/KernelBase/GetGPOListInternalA.s b/libc/nt/KernelBase/GetGPOListInternalA.s deleted file mode 100644 index 21b98be3e..000000000 --- a/libc/nt/KernelBase/GetGPOListInternalA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetGPOListInternalA,GetGPOListInternalA,569 diff --git a/libc/nt/KernelBase/GetGPOListInternalW.s b/libc/nt/KernelBase/GetGPOListInternalW.s deleted file mode 100644 index 10e20cc19..000000000 --- a/libc/nt/KernelBase/GetGPOListInternalW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetGPOListInternalW,GetGPOListInternalW,570 diff --git a/libc/nt/KernelBase/GetGamingDeviceModelInformation.s b/libc/nt/KernelBase/GetGamingDeviceModelInformation.s deleted file mode 100644 index a344ad1fc..000000000 --- a/libc/nt/KernelBase/GetGamingDeviceModelInformation.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetGamingDeviceModelInformation,GetGamingDeviceModelInformation,571 diff --git a/libc/nt/KernelBase/GetGeoInfoEx.s b/libc/nt/KernelBase/GetGeoInfoEx.s deleted file mode 100644 index f0b5a13fc..000000000 --- a/libc/nt/KernelBase/GetGeoInfoEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetGeoInfoEx,GetGeoInfoEx,572 diff --git a/libc/nt/KernelBase/GetHivePath.s b/libc/nt/KernelBase/GetHivePath.s deleted file mode 100644 index 860fb6b8c..000000000 --- a/libc/nt/KernelBase/GetHivePath.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetHivePath,GetHivePath,575 diff --git a/libc/nt/KernelBase/GetIntegratedDisplaySize.s b/libc/nt/KernelBase/GetIntegratedDisplaySize.s deleted file mode 100644 index ca1f9e835..000000000 --- a/libc/nt/KernelBase/GetIntegratedDisplaySize.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetIntegratedDisplaySize,GetIntegratedDisplaySize,576 diff --git a/libc/nt/KernelBase/GetIsEdpEnabled.s b/libc/nt/KernelBase/GetIsEdpEnabled.s deleted file mode 100644 index 9bd6c8997..000000000 --- a/libc/nt/KernelBase/GetIsEdpEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetIsEdpEnabled,GetIsEdpEnabled,577 diff --git a/libc/nt/KernelBase/GetLocaleInfoHelper.s b/libc/nt/KernelBase/GetLocaleInfoHelper.s deleted file mode 100644 index 1d5e67408..000000000 --- a/libc/nt/KernelBase/GetLocaleInfoHelper.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetLocaleInfoHelper,GetLocaleInfoHelper,586 diff --git a/libc/nt/KernelBase/GetMappedFileNameA.s b/libc/nt/KernelBase/GetMappedFileNameA.s deleted file mode 100644 index 1968033c9..000000000 --- a/libc/nt/KernelBase/GetMappedFileNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetMappedFileNameA,GetMappedFileNameA,594 diff --git a/libc/nt/KernelBase/GetMappedFileNameW.s b/libc/nt/KernelBase/GetMappedFileNameW.s deleted file mode 100644 index 118bab1ac..000000000 --- a/libc/nt/KernelBase/GetMappedFileNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetMappedFileNameW,GetMappedFileNameW,595 diff --git a/libc/nt/KernelBase/GetModuleBaseNameA.s b/libc/nt/KernelBase/GetModuleBaseNameA.s deleted file mode 100644 index 0130241e2..000000000 --- a/libc/nt/KernelBase/GetModuleBaseNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetModuleBaseNameA,GetModuleBaseNameA,597 diff --git a/libc/nt/KernelBase/GetModuleBaseNameW.s b/libc/nt/KernelBase/GetModuleBaseNameW.s deleted file mode 100644 index f3c1df4f9..000000000 --- a/libc/nt/KernelBase/GetModuleBaseNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetModuleBaseNameW,GetModuleBaseNameW,598 diff --git a/libc/nt/KernelBase/GetModuleFileNameExA.s b/libc/nt/KernelBase/GetModuleFileNameExA.s deleted file mode 100644 index e04572ea3..000000000 --- a/libc/nt/KernelBase/GetModuleFileNameExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetModuleFileNameExA,GetModuleFileNameExA,600 diff --git a/libc/nt/KernelBase/GetModuleFileNameExW.s b/libc/nt/KernelBase/GetModuleFileNameExW.s deleted file mode 100644 index 61be98603..000000000 --- a/libc/nt/KernelBase/GetModuleFileNameExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetModuleFileNameExW,GetModuleFileNameExW,601 diff --git a/libc/nt/KernelBase/GetModuleInformation.s b/libc/nt/KernelBase/GetModuleInformation.s deleted file mode 100644 index c845db472..000000000 --- a/libc/nt/KernelBase/GetModuleInformation.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetModuleInformation,GetModuleInformation,607 diff --git a/libc/nt/KernelBase/GetNamedLocaleHashNode.s b/libc/nt/KernelBase/GetNamedLocaleHashNode.s deleted file mode 100644 index 0c8fc35b9..000000000 --- a/libc/nt/KernelBase/GetNamedLocaleHashNode.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetNamedLocaleHashNode,GetNamedLocaleHashNode,610 diff --git a/libc/nt/KernelBase/GetNamedPipeAttribute.s b/libc/nt/KernelBase/GetNamedPipeAttribute.s deleted file mode 100644 index 36af81e84..000000000 --- a/libc/nt/KernelBase/GetNamedPipeAttribute.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetNamedPipeAttribute,GetNamedPipeAttribute,611 diff --git a/libc/nt/KernelBase/GetNextFgPolicyRefreshInfoInternal.s b/libc/nt/KernelBase/GetNextFgPolicyRefreshInfoInternal.s deleted file mode 100644 index b39b28d5d..000000000 --- a/libc/nt/KernelBase/GetNextFgPolicyRefreshInfoInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetNextFgPolicyRefreshInfoInternal,GetNextFgPolicyRefreshInfoInternal,616 diff --git a/libc/nt/KernelBase/GetOsManufacturingMode.s b/libc/nt/KernelBase/GetOsManufacturingMode.s deleted file mode 100644 index 69ba15f0c..000000000 --- a/libc/nt/KernelBase/GetOsManufacturingMode.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetOsManufacturingMode,GetOsManufacturingMode,625 diff --git a/libc/nt/KernelBase/GetOsSafeBootMode.s b/libc/nt/KernelBase/GetOsSafeBootMode.s deleted file mode 100644 index 442883888..000000000 --- a/libc/nt/KernelBase/GetOsSafeBootMode.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetOsSafeBootMode,GetOsSafeBootMode,626 diff --git a/libc/nt/KernelBase/GetPackageApplicationContext.s b/libc/nt/KernelBase/GetPackageApplicationContext.s deleted file mode 100644 index fecdcadc8..000000000 --- a/libc/nt/KernelBase/GetPackageApplicationContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageApplicationContext,GetPackageApplicationContext,629 diff --git a/libc/nt/KernelBase/GetPackageApplicationProperty.s b/libc/nt/KernelBase/GetPackageApplicationProperty.s deleted file mode 100644 index 868279cce..000000000 --- a/libc/nt/KernelBase/GetPackageApplicationProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageApplicationProperty,GetPackageApplicationProperty,631 diff --git a/libc/nt/KernelBase/GetPackageApplicationPropertyString.s b/libc/nt/KernelBase/GetPackageApplicationPropertyString.s deleted file mode 100644 index edc0fb890..000000000 --- a/libc/nt/KernelBase/GetPackageApplicationPropertyString.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageApplicationPropertyString,GetPackageApplicationPropertyString,632 diff --git a/libc/nt/KernelBase/GetPackageApplicationResourcesContext.s b/libc/nt/KernelBase/GetPackageApplicationResourcesContext.s deleted file mode 100644 index f37571da1..000000000 --- a/libc/nt/KernelBase/GetPackageApplicationResourcesContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageApplicationResourcesContext,GetPackageApplicationResourcesContext,633 diff --git a/libc/nt/KernelBase/GetPackageContext.s b/libc/nt/KernelBase/GetPackageContext.s deleted file mode 100644 index 4f493a319..000000000 --- a/libc/nt/KernelBase/GetPackageContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageContext,GetPackageContext,634 diff --git a/libc/nt/KernelBase/GetPackageFamilyNameFromProgId.s b/libc/nt/KernelBase/GetPackageFamilyNameFromProgId.s deleted file mode 100644 index 0af866581..000000000 --- a/libc/nt/KernelBase/GetPackageFamilyNameFromProgId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageFamilyNameFromProgId,GetPackageFamilyNameFromProgId,636 diff --git a/libc/nt/KernelBase/GetPackageFamilyNameFromToken.s b/libc/nt/KernelBase/GetPackageFamilyNameFromToken.s deleted file mode 100644 index d1e0a20de..000000000 --- a/libc/nt/KernelBase/GetPackageFamilyNameFromToken.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageFamilyNameFromToken,GetPackageFamilyNameFromToken,637 diff --git a/libc/nt/KernelBase/GetPackageFullNameFromToken.s b/libc/nt/KernelBase/GetPackageFullNameFromToken.s deleted file mode 100644 index 8e95137e5..000000000 --- a/libc/nt/KernelBase/GetPackageFullNameFromToken.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageFullNameFromToken,GetPackageFullNameFromToken,639 diff --git a/libc/nt/KernelBase/GetPackageInstallTime.s b/libc/nt/KernelBase/GetPackageInstallTime.s deleted file mode 100644 index b15edf4e6..000000000 --- a/libc/nt/KernelBase/GetPackageInstallTime.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageInstallTime,GetPackageInstallTime,642 diff --git a/libc/nt/KernelBase/GetPackageOSMaxVersionTested.s b/libc/nt/KernelBase/GetPackageOSMaxVersionTested.s deleted file mode 100644 index 564e7803c..000000000 --- a/libc/nt/KernelBase/GetPackageOSMaxVersionTested.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageOSMaxVersionTested,GetPackageOSMaxVersionTested,643 diff --git a/libc/nt/KernelBase/GetPackagePathOnVolume.s b/libc/nt/KernelBase/GetPackagePathOnVolume.s deleted file mode 100644 index b56b7722f..000000000 --- a/libc/nt/KernelBase/GetPackagePathOnVolume.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackagePathOnVolume,GetPackagePathOnVolume,646 diff --git a/libc/nt/KernelBase/GetPackageProperty.s b/libc/nt/KernelBase/GetPackageProperty.s deleted file mode 100644 index 2b2164d36..000000000 --- a/libc/nt/KernelBase/GetPackageProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageProperty,GetPackageProperty,647 diff --git a/libc/nt/KernelBase/GetPackagePropertyString.s b/libc/nt/KernelBase/GetPackagePropertyString.s deleted file mode 100644 index 807f025ed..000000000 --- a/libc/nt/KernelBase/GetPackagePropertyString.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackagePropertyString,GetPackagePropertyString,648 diff --git a/libc/nt/KernelBase/GetPackageResourcesContext.s b/libc/nt/KernelBase/GetPackageResourcesContext.s deleted file mode 100644 index 81643887d..000000000 --- a/libc/nt/KernelBase/GetPackageResourcesContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageResourcesContext,GetPackageResourcesContext,649 diff --git a/libc/nt/KernelBase/GetPackageResourcesProperty.s b/libc/nt/KernelBase/GetPackageResourcesProperty.s deleted file mode 100644 index b1422948a..000000000 --- a/libc/nt/KernelBase/GetPackageResourcesProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageResourcesProperty,GetPackageResourcesProperty,650 diff --git a/libc/nt/KernelBase/GetPackageSecurityContext.s b/libc/nt/KernelBase/GetPackageSecurityContext.s deleted file mode 100644 index 5924a03d6..000000000 --- a/libc/nt/KernelBase/GetPackageSecurityContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageSecurityContext,GetPackageSecurityContext,651 diff --git a/libc/nt/KernelBase/GetPackageSecurityProperty.s b/libc/nt/KernelBase/GetPackageSecurityProperty.s deleted file mode 100644 index 48ff81bc3..000000000 --- a/libc/nt/KernelBase/GetPackageSecurityProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageSecurityProperty,GetPackageSecurityProperty,652 diff --git a/libc/nt/KernelBase/GetPackageStatus.s b/libc/nt/KernelBase/GetPackageStatus.s deleted file mode 100644 index 87e0639ed..000000000 --- a/libc/nt/KernelBase/GetPackageStatus.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageStatus,GetPackageStatus,653 diff --git a/libc/nt/KernelBase/GetPackageStatusForUser.s b/libc/nt/KernelBase/GetPackageStatusForUser.s deleted file mode 100644 index 1159e2f1c..000000000 --- a/libc/nt/KernelBase/GetPackageStatusForUser.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageStatusForUser,GetPackageStatusForUser,654 diff --git a/libc/nt/KernelBase/GetPackageStatusForUserSid.s b/libc/nt/KernelBase/GetPackageStatusForUserSid.s deleted file mode 100644 index fbfecca08..000000000 --- a/libc/nt/KernelBase/GetPackageStatusForUserSid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageStatusForUserSid,GetPackageStatusForUserSid,655 diff --git a/libc/nt/KernelBase/GetPackageTargetPlatformProperty.s b/libc/nt/KernelBase/GetPackageTargetPlatformProperty.s deleted file mode 100644 index 7b0e6ab4c..000000000 --- a/libc/nt/KernelBase/GetPackageTargetPlatformProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageTargetPlatformProperty,GetPackageTargetPlatformProperty,656 diff --git a/libc/nt/KernelBase/GetPackageVolumeSisPath.s b/libc/nt/KernelBase/GetPackageVolumeSisPath.s deleted file mode 100644 index 55ed62716..000000000 --- a/libc/nt/KernelBase/GetPackageVolumeSisPath.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPackageVolumeSisPath,GetPackageVolumeSisPath,657 diff --git a/libc/nt/KernelBase/GetPerformanceInfo.s b/libc/nt/KernelBase/GetPerformanceInfo.s deleted file mode 100644 index 33d9bae17..000000000 --- a/libc/nt/KernelBase/GetPerformanceInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPerformanceInfo,GetPerformanceInfo,659 diff --git a/libc/nt/KernelBase/GetPersistedFileLocationW.s b/libc/nt/KernelBase/GetPersistedFileLocationW.s deleted file mode 100644 index 27a01a8f7..000000000 --- a/libc/nt/KernelBase/GetPersistedFileLocationW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPersistedFileLocationW,GetPersistedFileLocationW,660 diff --git a/libc/nt/KernelBase/GetPersistedRegistryLocationW.s b/libc/nt/KernelBase/GetPersistedRegistryLocationW.s deleted file mode 100644 index 8d8a8ce52..000000000 --- a/libc/nt/KernelBase/GetPersistedRegistryLocationW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPersistedRegistryLocationW,GetPersistedRegistryLocationW,661 diff --git a/libc/nt/KernelBase/GetPersistedRegistryValueW.s b/libc/nt/KernelBase/GetPersistedRegistryValueW.s deleted file mode 100644 index d96703fb8..000000000 --- a/libc/nt/KernelBase/GetPersistedRegistryValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPersistedRegistryValueW,GetPersistedRegistryValueW,662 diff --git a/libc/nt/KernelBase/GetPreviousFgPolicyRefreshInfoInternal.s b/libc/nt/KernelBase/GetPreviousFgPolicyRefreshInfoInternal.s deleted file mode 100644 index 2cee86cef..000000000 --- a/libc/nt/KernelBase/GetPreviousFgPolicyRefreshInfoInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPreviousFgPolicyRefreshInfoInternal,GetPreviousFgPolicyRefreshInfoInternal,664 diff --git a/libc/nt/KernelBase/GetProcAddressForCaller.s b/libc/nt/KernelBase/GetProcAddressForCaller.s deleted file mode 100644 index 0c1459e01..000000000 --- a/libc/nt/KernelBase/GetProcAddressForCaller.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetProcAddressForCaller,GetProcAddressForCaller,668 diff --git a/libc/nt/KernelBase/GetProcessMemoryInfo.s b/libc/nt/KernelBase/GetProcessMemoryInfo.s deleted file mode 100644 index ae3f6cd60..000000000 --- a/libc/nt/KernelBase/GetProcessMemoryInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetProcessMemoryInfo,GetProcessMemoryInfo,679 diff --git a/libc/nt/KernelBase/GetProtocolAumid.s b/libc/nt/KernelBase/GetProtocolAumid.s deleted file mode 100644 index 5aebc4633..000000000 --- a/libc/nt/KernelBase/GetProtocolAumid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetProtocolAumid,GetProtocolAumid,689 diff --git a/libc/nt/KernelBase/GetProtocolProperty.s b/libc/nt/KernelBase/GetProtocolProperty.s deleted file mode 100644 index 07a4a401e..000000000 --- a/libc/nt/KernelBase/GetProtocolProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetProtocolProperty,GetProtocolProperty,690 diff --git a/libc/nt/KernelBase/GetPtrCalData.s b/libc/nt/KernelBase/GetPtrCalData.s deleted file mode 100644 index dbf516221..000000000 --- a/libc/nt/KernelBase/GetPtrCalData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPtrCalData,GetPtrCalData,691 diff --git a/libc/nt/KernelBase/GetPtrCalDataArray.s b/libc/nt/KernelBase/GetPtrCalDataArray.s deleted file mode 100644 index 657fec321..000000000 --- a/libc/nt/KernelBase/GetPtrCalDataArray.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPtrCalDataArray,GetPtrCalDataArray,692 diff --git a/libc/nt/KernelBase/GetPublisherCacheFolder.s b/libc/nt/KernelBase/GetPublisherCacheFolder.s deleted file mode 100644 index 848d01308..000000000 --- a/libc/nt/KernelBase/GetPublisherCacheFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPublisherCacheFolder,GetPublisherCacheFolder,693 diff --git a/libc/nt/KernelBase/GetPublisherRootFolder.s b/libc/nt/KernelBase/GetPublisherRootFolder.s deleted file mode 100644 index 0fd11290d..000000000 --- a/libc/nt/KernelBase/GetPublisherRootFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetPublisherRootFolder,GetPublisherRootFolder,694 diff --git a/libc/nt/KernelBase/GetRegistryExtensionFlags.s b/libc/nt/KernelBase/GetRegistryExtensionFlags.s deleted file mode 100644 index 20e0e6754..000000000 --- a/libc/nt/KernelBase/GetRegistryExtensionFlags.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetRegistryExtensionFlags,GetRegistryExtensionFlags,697 diff --git a/libc/nt/KernelBase/GetRegistryValueWithFallbackW.s b/libc/nt/KernelBase/GetRegistryValueWithFallbackW.s deleted file mode 100644 index 6fbadf9a8..000000000 --- a/libc/nt/KernelBase/GetRegistryValueWithFallbackW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetRegistryValueWithFallbackW,GetRegistryValueWithFallbackW,698 diff --git a/libc/nt/KernelBase/GetRoamingLastObservedChangeTime.s b/libc/nt/KernelBase/GetRoamingLastObservedChangeTime.s deleted file mode 100644 index e02726d70..000000000 --- a/libc/nt/KernelBase/GetRoamingLastObservedChangeTime.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetRoamingLastObservedChangeTime,GetRoamingLastObservedChangeTime,699 diff --git a/libc/nt/KernelBase/GetSecureSystemAppDataFolder.s b/libc/nt/KernelBase/GetSecureSystemAppDataFolder.s deleted file mode 100644 index 8fb31bbd4..000000000 --- a/libc/nt/KernelBase/GetSecureSystemAppDataFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSecureSystemAppDataFolder,GetSecureSystemAppDataFolder,700 diff --git a/libc/nt/KernelBase/GetSerializedAtomBytes.s b/libc/nt/KernelBase/GetSerializedAtomBytes.s deleted file mode 100644 index a8331eb7b..000000000 --- a/libc/nt/KernelBase/GetSerializedAtomBytes.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSerializedAtomBytes,GetSerializedAtomBytes,708 diff --git a/libc/nt/KernelBase/GetSharedLocalFolder.s b/libc/nt/KernelBase/GetSharedLocalFolder.s deleted file mode 100644 index 9feb93031..000000000 --- a/libc/nt/KernelBase/GetSharedLocalFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSharedLocalFolder,GetSharedLocalFolder,709 diff --git a/libc/nt/KernelBase/GetStagedPackageOrigin.s b/libc/nt/KernelBase/GetStagedPackageOrigin.s deleted file mode 100644 index 361b67b75..000000000 --- a/libc/nt/KernelBase/GetStagedPackageOrigin.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetStagedPackageOrigin,GetStagedPackageOrigin,715 diff --git a/libc/nt/KernelBase/GetStateContainerDepth.s b/libc/nt/KernelBase/GetStateContainerDepth.s deleted file mode 100644 index 78f7244b1..000000000 --- a/libc/nt/KernelBase/GetStateContainerDepth.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetStateContainerDepth,GetStateContainerDepth,718 diff --git a/libc/nt/KernelBase/GetStateFolder.s b/libc/nt/KernelBase/GetStateFolder.s deleted file mode 100644 index 2388a9072..000000000 --- a/libc/nt/KernelBase/GetStateFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetStateFolder,GetStateFolder,719 diff --git a/libc/nt/KernelBase/GetStateRootFolder.s b/libc/nt/KernelBase/GetStateRootFolder.s deleted file mode 100644 index 620994776..000000000 --- a/libc/nt/KernelBase/GetStateRootFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetStateRootFolder,GetStateRootFolder,720 diff --git a/libc/nt/KernelBase/GetStateRootFolderBase.s b/libc/nt/KernelBase/GetStateRootFolderBase.s deleted file mode 100644 index beecf5181..000000000 --- a/libc/nt/KernelBase/GetStateRootFolderBase.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetStateRootFolderBase,GetStateRootFolderBase,721 diff --git a/libc/nt/KernelBase/GetStateSettingsFolder.s b/libc/nt/KernelBase/GetStateSettingsFolder.s deleted file mode 100644 index 5dad55cfa..000000000 --- a/libc/nt/KernelBase/GetStateSettingsFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetStateSettingsFolder,GetStateSettingsFolder,722 diff --git a/libc/nt/KernelBase/GetStateVersion.s b/libc/nt/KernelBase/GetStateVersion.s deleted file mode 100644 index 511b7f7d2..000000000 --- a/libc/nt/KernelBase/GetStateVersion.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetStateVersion,GetStateVersion,723 diff --git a/libc/nt/KernelBase/GetStringTableEntry.s b/libc/nt/KernelBase/GetStringTableEntry.s deleted file mode 100644 index 73a3fdc62..000000000 --- a/libc/nt/KernelBase/GetStringTableEntry.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetStringTableEntry,GetStringTableEntry,726 diff --git a/libc/nt/KernelBase/GetSystemAppDataFolder.s b/libc/nt/KernelBase/GetSystemAppDataFolder.s deleted file mode 100644 index f74ac6040..000000000 --- a/libc/nt/KernelBase/GetSystemAppDataFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemAppDataFolder,GetSystemAppDataFolder,730 diff --git a/libc/nt/KernelBase/GetSystemAppDataKey.s b/libc/nt/KernelBase/GetSystemAppDataKey.s deleted file mode 100644 index 569d488c9..000000000 --- a/libc/nt/KernelBase/GetSystemAppDataKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemAppDataKey,GetSystemAppDataKey,731 diff --git a/libc/nt/KernelBase/GetSystemMetadataPath.s b/libc/nt/KernelBase/GetSystemMetadataPath.s deleted file mode 100644 index b28fdb4ea..000000000 --- a/libc/nt/KernelBase/GetSystemMetadataPath.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemMetadataPath,GetSystemMetadataPath,742 diff --git a/libc/nt/KernelBase/GetSystemMetadataPathForPackage.s b/libc/nt/KernelBase/GetSystemMetadataPathForPackage.s deleted file mode 100644 index 542f1da41..000000000 --- a/libc/nt/KernelBase/GetSystemMetadataPathForPackage.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemMetadataPathForPackage,GetSystemMetadataPathForPackage,743 diff --git a/libc/nt/KernelBase/GetSystemMetadataPathForPackageFamily.s b/libc/nt/KernelBase/GetSystemMetadataPathForPackageFamily.s deleted file mode 100644 index 011c50ef1..000000000 --- a/libc/nt/KernelBase/GetSystemMetadataPathForPackageFamily.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemMetadataPathForPackageFamily,GetSystemMetadataPathForPackageFamily,744 diff --git a/libc/nt/KernelBase/GetSystemStateRootFolder.s b/libc/nt/KernelBase/GetSystemStateRootFolder.s deleted file mode 100644 index d6405f235..000000000 --- a/libc/nt/KernelBase/GetSystemStateRootFolder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemStateRootFolder,GetSystemStateRootFolder,746 diff --git a/libc/nt/KernelBase/GetSystemTimeAdjustmentPrecise.s b/libc/nt/KernelBase/GetSystemTimeAdjustmentPrecise.s deleted file mode 100644 index b5088b484..000000000 --- a/libc/nt/KernelBase/GetSystemTimeAdjustmentPrecise.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemTimeAdjustmentPrecise,GetSystemTimeAdjustmentPrecise,749 diff --git a/libc/nt/KernelBase/GetSystemWow64Directory2A.s b/libc/nt/KernelBase/GetSystemWow64Directory2A.s deleted file mode 100644 index 7cb6c4b22..000000000 --- a/libc/nt/KernelBase/GetSystemWow64Directory2A.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemWow64Directory2A,GetSystemWow64Directory2A,755 diff --git a/libc/nt/KernelBase/GetSystemWow64Directory2W.s b/libc/nt/KernelBase/GetSystemWow64Directory2W.s deleted file mode 100644 index 4fd0b2a16..000000000 --- a/libc/nt/KernelBase/GetSystemWow64Directory2W.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetSystemWow64Directory2W,GetSystemWow64Directory2W,756 diff --git a/libc/nt/KernelBase/GetTargetPlatformContext.s b/libc/nt/KernelBase/GetTargetPlatformContext.s deleted file mode 100644 index 85440595e..000000000 --- a/libc/nt/KernelBase/GetTargetPlatformContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetTargetPlatformContext,GetTargetPlatformContext,759 diff --git a/libc/nt/KernelBase/GetThreadDescription.s b/libc/nt/KernelBase/GetThreadDescription.s deleted file mode 100644 index 3fccdd4dd..000000000 --- a/libc/nt/KernelBase/GetThreadDescription.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetThreadDescription,GetThreadDescription,765 diff --git a/libc/nt/KernelBase/GetUnicodeStringToEightBitSizeRoutine.s b/libc/nt/KernelBase/GetUnicodeStringToEightBitSizeRoutine.s deleted file mode 100644 index 2bfda358f..000000000 --- a/libc/nt/KernelBase/GetUnicodeStringToEightBitSizeRoutine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetUnicodeStringToEightBitSizeRoutine,GetUnicodeStringToEightBitSizeRoutine,791 diff --git a/libc/nt/KernelBase/GetUnicodeStringToEightBitStringRoutine.s b/libc/nt/KernelBase/GetUnicodeStringToEightBitStringRoutine.s deleted file mode 100644 index 8e16a60b7..000000000 --- a/libc/nt/KernelBase/GetUnicodeStringToEightBitStringRoutine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetUnicodeStringToEightBitStringRoutine,GetUnicodeStringToEightBitStringRoutine,792 diff --git a/libc/nt/KernelBase/GetUserDefaultGeoName.s b/libc/nt/KernelBase/GetUserDefaultGeoName.s deleted file mode 100644 index a97a275d0..000000000 --- a/libc/nt/KernelBase/GetUserDefaultGeoName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetUserDefaultGeoName,GetUserDefaultGeoName,793 diff --git a/libc/nt/KernelBase/GetUserInfo.s b/libc/nt/KernelBase/GetUserInfo.s deleted file mode 100644 index 98deb7e22..000000000 --- a/libc/nt/KernelBase/GetUserInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetUserInfo,GetUserInfo,799 diff --git a/libc/nt/KernelBase/GetUserInfoWord.s b/libc/nt/KernelBase/GetUserInfoWord.s deleted file mode 100644 index 4875087fa..000000000 --- a/libc/nt/KernelBase/GetUserInfoWord.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetUserInfoWord,GetUserInfoWord,800 diff --git a/libc/nt/KernelBase/GetUserOverrideString.s b/libc/nt/KernelBase/GetUserOverrideString.s deleted file mode 100644 index 306c36595..000000000 --- a/libc/nt/KernelBase/GetUserOverrideString.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetUserOverrideString,GetUserOverrideString,801 diff --git a/libc/nt/KernelBase/GetUserOverrideWord.s b/libc/nt/KernelBase/GetUserOverrideWord.s deleted file mode 100644 index 308ffabd5..000000000 --- a/libc/nt/KernelBase/GetUserOverrideWord.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetUserOverrideWord,GetUserOverrideWord,802 diff --git a/libc/nt/KernelBase/GetWsChanges.s b/libc/nt/KernelBase/GetWsChanges.s deleted file mode 100644 index 24cd8dadb..000000000 --- a/libc/nt/KernelBase/GetWsChanges.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetWsChanges,GetWsChanges,817 diff --git a/libc/nt/KernelBase/GetWsChangesEx.s b/libc/nt/KernelBase/GetWsChangesEx.s deleted file mode 100644 index 80b7db59a..000000000 --- a/libc/nt/KernelBase/GetWsChangesEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GetWsChangesEx,GetWsChangesEx,818 diff --git a/libc/nt/KernelBase/GuardCheckLongJumpTarget.s b/libc/nt/KernelBase/GuardCheckLongJumpTarget.s deleted file mode 100644 index e4196c483..000000000 --- a/libc/nt/KernelBase/GuardCheckLongJumpTarget.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_GuardCheckLongJumpTarget,GuardCheckLongJumpTarget,823 diff --git a/libc/nt/KernelBase/HasPolicyForegroundProcessingCompletedInternal.s b/libc/nt/KernelBase/HasPolicyForegroundProcessingCompletedInternal.s deleted file mode 100644 index dd8b9aa77..000000000 --- a/libc/nt/KernelBase/HasPolicyForegroundProcessingCompletedInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_HasPolicyForegroundProcessingCompletedInternal,HasPolicyForegroundProcessingCompletedInternal,824 diff --git a/libc/nt/KernelBase/HashData.s b/libc/nt/KernelBase/HashData.s deleted file mode 100644 index 4de4e4109..000000000 --- a/libc/nt/KernelBase/HashData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_HashData,HashData,825 diff --git a/libc/nt/KernelBase/HeapSummary.s b/libc/nt/KernelBase/HeapSummary.s deleted file mode 100644 index 12ca25bc6..000000000 --- a/libc/nt/KernelBase/HeapSummary.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_HeapSummary,HeapSummary,836 diff --git a/libc/nt/KernelBase/IncrementPackageStatusVersion.s b/libc/nt/KernelBase/IncrementPackageStatusVersion.s deleted file mode 100644 index b0ed1bc9f..000000000 --- a/libc/nt/KernelBase/IncrementPackageStatusVersion.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IncrementPackageStatusVersion,IncrementPackageStatusVersion,847 diff --git a/libc/nt/KernelBase/InitializeEnclave.s b/libc/nt/KernelBase/InitializeEnclave.s deleted file mode 100644 index 7ef996ad0..000000000 --- a/libc/nt/KernelBase/InitializeEnclave.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_InitializeEnclave,InitializeEnclave,858 diff --git a/libc/nt/KernelBase/InitializeProcessForWsWatch.s b/libc/nt/KernelBase/InitializeProcessForWsWatch.s deleted file mode 100644 index 6b62b5f8d..000000000 --- a/libc/nt/KernelBase/InitializeProcessForWsWatch.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_InitializeProcessForWsWatch,InitializeProcessForWsWatch,860 diff --git a/libc/nt/KernelBase/InternalLcidToName.s b/libc/nt/KernelBase/InternalLcidToName.s deleted file mode 100644 index 6731a0803..000000000 --- a/libc/nt/KernelBase/InternalLcidToName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_InternalLcidToName,InternalLcidToName,872 diff --git a/libc/nt/KernelBase/Internal_EnumCalendarInfo.s b/libc/nt/KernelBase/Internal_EnumCalendarInfo.s deleted file mode 100644 index 9e2c7c0db..000000000 --- a/libc/nt/KernelBase/Internal_EnumCalendarInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Internal_EnumCalendarInfo,Internal_EnumCalendarInfo,873 diff --git a/libc/nt/KernelBase/Internal_EnumDateFormats.s b/libc/nt/KernelBase/Internal_EnumDateFormats.s deleted file mode 100644 index 414a88413..000000000 --- a/libc/nt/KernelBase/Internal_EnumDateFormats.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Internal_EnumDateFormats,Internal_EnumDateFormats,874 diff --git a/libc/nt/KernelBase/Internal_EnumLanguageGroupLocales.s b/libc/nt/KernelBase/Internal_EnumLanguageGroupLocales.s deleted file mode 100644 index 622f1f68b..000000000 --- a/libc/nt/KernelBase/Internal_EnumLanguageGroupLocales.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Internal_EnumLanguageGroupLocales,Internal_EnumLanguageGroupLocales,875 diff --git a/libc/nt/KernelBase/Internal_EnumSystemCodePages.s b/libc/nt/KernelBase/Internal_EnumSystemCodePages.s deleted file mode 100644 index d2441eaa1..000000000 --- a/libc/nt/KernelBase/Internal_EnumSystemCodePages.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Internal_EnumSystemCodePages,Internal_EnumSystemCodePages,876 diff --git a/libc/nt/KernelBase/Internal_EnumSystemLanguageGroups.s b/libc/nt/KernelBase/Internal_EnumSystemLanguageGroups.s deleted file mode 100644 index 2e533c1fa..000000000 --- a/libc/nt/KernelBase/Internal_EnumSystemLanguageGroups.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Internal_EnumSystemLanguageGroups,Internal_EnumSystemLanguageGroups,877 diff --git a/libc/nt/KernelBase/Internal_EnumSystemLocales.s b/libc/nt/KernelBase/Internal_EnumSystemLocales.s deleted file mode 100644 index 73ba09251..000000000 --- a/libc/nt/KernelBase/Internal_EnumSystemLocales.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Internal_EnumSystemLocales,Internal_EnumSystemLocales,878 diff --git a/libc/nt/KernelBase/Internal_EnumTimeFormats.s b/libc/nt/KernelBase/Internal_EnumTimeFormats.s deleted file mode 100644 index 14a7bc7b1..000000000 --- a/libc/nt/KernelBase/Internal_EnumTimeFormats.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Internal_EnumTimeFormats,Internal_EnumTimeFormats,879 diff --git a/libc/nt/KernelBase/Internal_EnumUILanguages.s b/libc/nt/KernelBase/Internal_EnumUILanguages.s deleted file mode 100644 index f8c1649b3..000000000 --- a/libc/nt/KernelBase/Internal_EnumUILanguages.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Internal_EnumUILanguages,Internal_EnumUILanguages,880 diff --git a/libc/nt/KernelBase/InternetTimeFromSystemTimeA.s b/libc/nt/KernelBase/InternetTimeFromSystemTimeA.s deleted file mode 100644 index 30ffcf92d..000000000 --- a/libc/nt/KernelBase/InternetTimeFromSystemTimeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_InternetTimeFromSystemTimeA,InternetTimeFromSystemTimeA,881 diff --git a/libc/nt/KernelBase/InternetTimeFromSystemTimeW.s b/libc/nt/KernelBase/InternetTimeFromSystemTimeW.s deleted file mode 100644 index 26a7e0b32..000000000 --- a/libc/nt/KernelBase/InternetTimeFromSystemTimeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_InternetTimeFromSystemTimeW,InternetTimeFromSystemTimeW,882 diff --git a/libc/nt/KernelBase/InternetTimeToSystemTimeA.s b/libc/nt/KernelBase/InternetTimeToSystemTimeA.s deleted file mode 100644 index 02752dec3..000000000 --- a/libc/nt/KernelBase/InternetTimeToSystemTimeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_InternetTimeToSystemTimeA,InternetTimeToSystemTimeA,883 diff --git a/libc/nt/KernelBase/InternetTimeToSystemTimeW.s b/libc/nt/KernelBase/InternetTimeToSystemTimeW.s deleted file mode 100644 index bd8454701..000000000 --- a/libc/nt/KernelBase/InternetTimeToSystemTimeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_InternetTimeToSystemTimeW,InternetTimeToSystemTimeW,884 diff --git a/libc/nt/KernelBase/InvalidateAppModelVersionCache.s b/libc/nt/KernelBase/InvalidateAppModelVersionCache.s deleted file mode 100644 index 957842c54..000000000 --- a/libc/nt/KernelBase/InvalidateAppModelVersionCache.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_InvalidateAppModelVersionCache,InvalidateAppModelVersionCache,885 diff --git a/libc/nt/KernelBase/IsCharAlphaA.s b/libc/nt/KernelBase/IsCharAlphaA.s deleted file mode 100644 index 19d1fbbda..000000000 --- a/libc/nt/KernelBase/IsCharAlphaA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharAlphaA,IsCharAlphaA,886 diff --git a/libc/nt/KernelBase/IsCharAlphaNumericA.s b/libc/nt/KernelBase/IsCharAlphaNumericA.s deleted file mode 100644 index 00434f233..000000000 --- a/libc/nt/KernelBase/IsCharAlphaNumericA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharAlphaNumericA,IsCharAlphaNumericA,887 diff --git a/libc/nt/KernelBase/IsCharAlphaNumericW.s b/libc/nt/KernelBase/IsCharAlphaNumericW.s deleted file mode 100644 index b2f40934c..000000000 --- a/libc/nt/KernelBase/IsCharAlphaNumericW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharAlphaNumericW,IsCharAlphaNumericW,888 diff --git a/libc/nt/KernelBase/IsCharAlphaW.s b/libc/nt/KernelBase/IsCharAlphaW.s deleted file mode 100644 index b644f5dd9..000000000 --- a/libc/nt/KernelBase/IsCharAlphaW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharAlphaW,IsCharAlphaW,889 diff --git a/libc/nt/KernelBase/IsCharBlankW.s b/libc/nt/KernelBase/IsCharBlankW.s deleted file mode 100644 index c652cb578..000000000 --- a/libc/nt/KernelBase/IsCharBlankW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharBlankW,IsCharBlankW,890 diff --git a/libc/nt/KernelBase/IsCharCntrlW.s b/libc/nt/KernelBase/IsCharCntrlW.s deleted file mode 100644 index b70a51882..000000000 --- a/libc/nt/KernelBase/IsCharCntrlW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharCntrlW,IsCharCntrlW,891 diff --git a/libc/nt/KernelBase/IsCharDigitW.s b/libc/nt/KernelBase/IsCharDigitW.s deleted file mode 100644 index 5dd94418f..000000000 --- a/libc/nt/KernelBase/IsCharDigitW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharDigitW,IsCharDigitW,892 diff --git a/libc/nt/KernelBase/IsCharLowerA.s b/libc/nt/KernelBase/IsCharLowerA.s deleted file mode 100644 index cd21d8d5a..000000000 --- a/libc/nt/KernelBase/IsCharLowerA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharLowerA,IsCharLowerA,893 diff --git a/libc/nt/KernelBase/IsCharLowerW.s b/libc/nt/KernelBase/IsCharLowerW.s deleted file mode 100644 index c8da6c49f..000000000 --- a/libc/nt/KernelBase/IsCharLowerW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharLowerW,IsCharLowerW,894 diff --git a/libc/nt/KernelBase/IsCharPunctW.s b/libc/nt/KernelBase/IsCharPunctW.s deleted file mode 100644 index 58841d3e3..000000000 --- a/libc/nt/KernelBase/IsCharPunctW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharPunctW,IsCharPunctW,895 diff --git a/libc/nt/KernelBase/IsCharSpaceA.s b/libc/nt/KernelBase/IsCharSpaceA.s deleted file mode 100644 index 66c5d4cda..000000000 --- a/libc/nt/KernelBase/IsCharSpaceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharSpaceA,IsCharSpaceA,896 diff --git a/libc/nt/KernelBase/IsCharSpaceW.s b/libc/nt/KernelBase/IsCharSpaceW.s deleted file mode 100644 index 7e2c77324..000000000 --- a/libc/nt/KernelBase/IsCharSpaceW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharSpaceW,IsCharSpaceW,897 diff --git a/libc/nt/KernelBase/IsCharUpperA.s b/libc/nt/KernelBase/IsCharUpperA.s deleted file mode 100644 index 4f907565e..000000000 --- a/libc/nt/KernelBase/IsCharUpperA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharUpperA,IsCharUpperA,898 diff --git a/libc/nt/KernelBase/IsCharUpperW.s b/libc/nt/KernelBase/IsCharUpperW.s deleted file mode 100644 index 237b2c5b0..000000000 --- a/libc/nt/KernelBase/IsCharUpperW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharUpperW,IsCharUpperW,899 diff --git a/libc/nt/KernelBase/IsCharXDigitW.s b/libc/nt/KernelBase/IsCharXDigitW.s deleted file mode 100644 index bce4c780b..000000000 --- a/libc/nt/KernelBase/IsCharXDigitW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsCharXDigitW,IsCharXDigitW,900 diff --git a/libc/nt/KernelBase/IsDebuggerPresent.s b/libc/nt/KernelBase/IsDebuggerPresent.s deleted file mode 100644 index 4c7c5b96c..000000000 --- a/libc/nt/KernelBase/IsDebuggerPresent.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsDebuggerPresent,IsDebuggerPresent,903 diff --git a/libc/nt/KernelBase/IsDeveloperModeEnabled.s b/libc/nt/KernelBase/IsDeveloperModeEnabled.s deleted file mode 100644 index 6c90b8caf..000000000 --- a/libc/nt/KernelBase/IsDeveloperModeEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsDeveloperModeEnabled,IsDeveloperModeEnabled,904 diff --git a/libc/nt/KernelBase/IsDeveloperModePolicyApplied.s b/libc/nt/KernelBase/IsDeveloperModePolicyApplied.s deleted file mode 100644 index b7256acb4..000000000 --- a/libc/nt/KernelBase/IsDeveloperModePolicyApplied.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsDeveloperModePolicyApplied,IsDeveloperModePolicyApplied,905 diff --git a/libc/nt/KernelBase/IsEnclaveTypeSupported.s b/libc/nt/KernelBase/IsEnclaveTypeSupported.s deleted file mode 100644 index b526fe0c8..000000000 --- a/libc/nt/KernelBase/IsEnclaveTypeSupported.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsEnclaveTypeSupported,IsEnclaveTypeSupported,906 diff --git a/libc/nt/KernelBase/IsGlobalizationUserSettingsKeyRedirected.s b/libc/nt/KernelBase/IsGlobalizationUserSettingsKeyRedirected.s deleted file mode 100644 index 625b816b5..000000000 --- a/libc/nt/KernelBase/IsGlobalizationUserSettingsKeyRedirected.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsGlobalizationUserSettingsKeyRedirected,IsGlobalizationUserSettingsKeyRedirected,907 diff --git a/libc/nt/KernelBase/IsInternetESCEnabled.s b/libc/nt/KernelBase/IsInternetESCEnabled.s deleted file mode 100644 index f19567154..000000000 --- a/libc/nt/KernelBase/IsInternetESCEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsInternetESCEnabled,IsInternetESCEnabled,908 diff --git a/libc/nt/KernelBase/IsOnDemandRegistrationSupportedForExtensionCategory.s b/libc/nt/KernelBase/IsOnDemandRegistrationSupportedForExtensionCategory.s deleted file mode 100644 index 609b55614..000000000 --- a/libc/nt/KernelBase/IsOnDemandRegistrationSupportedForExtensionCategory.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsOnDemandRegistrationSupportedForExtensionCategory,IsOnDemandRegistrationSupportedForExtensionCategory,911 diff --git a/libc/nt/KernelBase/IsSideloadingEnabled.s b/libc/nt/KernelBase/IsSideloadingEnabled.s deleted file mode 100644 index b17e53be5..000000000 --- a/libc/nt/KernelBase/IsSideloadingEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsSideloadingEnabled,IsSideloadingEnabled,915 diff --git a/libc/nt/KernelBase/IsSideloadingPolicyApplied.s b/libc/nt/KernelBase/IsSideloadingPolicyApplied.s deleted file mode 100644 index 734c62124..000000000 --- a/libc/nt/KernelBase/IsSideloadingPolicyApplied.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsSideloadingPolicyApplied,IsSideloadingPolicyApplied,916 diff --git a/libc/nt/KernelBase/IsSyncForegroundPolicyRefresh.s b/libc/nt/KernelBase/IsSyncForegroundPolicyRefresh.s deleted file mode 100644 index e67ed0c14..000000000 --- a/libc/nt/KernelBase/IsSyncForegroundPolicyRefresh.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsSyncForegroundPolicyRefresh,IsSyncForegroundPolicyRefresh,917 diff --git a/libc/nt/KernelBase/IsTimeZoneRedirectionEnabled.s b/libc/nt/KernelBase/IsTimeZoneRedirectionEnabled.s deleted file mode 100644 index 7891f498c..000000000 --- a/libc/nt/KernelBase/IsTimeZoneRedirectionEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsTimeZoneRedirectionEnabled,IsTimeZoneRedirectionEnabled,920 diff --git a/libc/nt/KernelBase/IsValidRelativeSecurityDescriptor.s b/libc/nt/KernelBase/IsValidRelativeSecurityDescriptor.s deleted file mode 100644 index 210d6f071..000000000 --- a/libc/nt/KernelBase/IsValidRelativeSecurityDescriptor.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsValidRelativeSecurityDescriptor,IsValidRelativeSecurityDescriptor,928 diff --git a/libc/nt/KernelBase/IsWow64GuestMachineSupported.s b/libc/nt/KernelBase/IsWow64GuestMachineSupported.s deleted file mode 100644 index 22b7ea495..000000000 --- a/libc/nt/KernelBase/IsWow64GuestMachineSupported.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsWow64GuestMachineSupported,IsWow64GuestMachineSupported,932 diff --git a/libc/nt/KernelBase/IsWow64Process2.s b/libc/nt/KernelBase/IsWow64Process2.s deleted file mode 100644 index 333f92363..000000000 --- a/libc/nt/KernelBase/IsWow64Process2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_IsWow64Process2,IsWow64Process2,934 diff --git a/libc/nt/KernelBase/KernelBaseGetGlobalData.s b/libc/nt/KernelBase/KernelBaseGetGlobalData.s deleted file mode 100644 index 4bf704a73..000000000 --- a/libc/nt/KernelBase/KernelBaseGetGlobalData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_KernelBaseGetGlobalData,KernelBaseGetGlobalData,962 diff --git a/libc/nt/KernelBase/KernelbasePostInit.s b/libc/nt/KernelBase/KernelbasePostInit.s deleted file mode 100644 index fbd9bb13c..000000000 --- a/libc/nt/KernelBase/KernelbasePostInit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_KernelbasePostInit,KernelbasePostInit,963 diff --git a/libc/nt/KernelBase/LeaveCriticalPolicySectionInternal.s b/libc/nt/KernelBase/LeaveCriticalPolicySectionInternal.s deleted file mode 100644 index b258da341..000000000 --- a/libc/nt/KernelBase/LeaveCriticalPolicySectionInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LeaveCriticalPolicySectionInternal,LeaveCriticalPolicySectionInternal,968 diff --git a/libc/nt/KernelBase/LoadAppInitDlls.s b/libc/nt/KernelBase/LoadAppInitDlls.s deleted file mode 100644 index 0f740e506..000000000 --- a/libc/nt/KernelBase/LoadAppInitDlls.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LoadAppInitDlls,LoadAppInitDlls,971 diff --git a/libc/nt/KernelBase/LoadEnclaveData.s b/libc/nt/KernelBase/LoadEnclaveData.s deleted file mode 100644 index 032f67624..000000000 --- a/libc/nt/KernelBase/LoadEnclaveData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LoadEnclaveData,LoadEnclaveData,972 diff --git a/libc/nt/KernelBase/LoadEnclaveImageA.s b/libc/nt/KernelBase/LoadEnclaveImageA.s deleted file mode 100644 index 37a3e50a3..000000000 --- a/libc/nt/KernelBase/LoadEnclaveImageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LoadEnclaveImageA,LoadEnclaveImageA,973 diff --git a/libc/nt/KernelBase/LoadEnclaveImageW.s b/libc/nt/KernelBase/LoadEnclaveImageW.s deleted file mode 100644 index 980988a47..000000000 --- a/libc/nt/KernelBase/LoadEnclaveImageW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LoadEnclaveImageW,LoadEnclaveImageW,974 diff --git a/libc/nt/KernelBase/LoadStringA.s b/libc/nt/KernelBase/LoadStringA.s deleted file mode 100644 index 38c078166..000000000 --- a/libc/nt/KernelBase/LoadStringA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LoadStringA,LoadStringA,981 diff --git a/libc/nt/KernelBase/LoadStringBaseExW.s b/libc/nt/KernelBase/LoadStringBaseExW.s deleted file mode 100644 index de0069812..000000000 --- a/libc/nt/KernelBase/LoadStringBaseExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LoadStringBaseExW,LoadStringBaseExW,982 diff --git a/libc/nt/KernelBase/LoadStringByReference.s b/libc/nt/KernelBase/LoadStringByReference.s deleted file mode 100644 index 944edf84f..000000000 --- a/libc/nt/KernelBase/LoadStringByReference.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LoadStringByReference,LoadStringByReference,983 diff --git a/libc/nt/KernelBase/LoadStringW.s b/libc/nt/KernelBase/LoadStringW.s deleted file mode 100644 index 5ecb3ee22..000000000 --- a/libc/nt/KernelBase/LoadStringW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_LoadStringW,LoadStringW,984 diff --git a/libc/nt/KernelBase/MakeAbsoluteSD2.s b/libc/nt/KernelBase/MakeAbsoluteSD2.s deleted file mode 100644 index 4b96d701f..000000000 --- a/libc/nt/KernelBase/MakeAbsoluteSD2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_MakeAbsoluteSD2,MakeAbsoluteSD2,997 diff --git a/libc/nt/KernelBase/MapPredefinedHandleInternal.s b/libc/nt/KernelBase/MapPredefinedHandleInternal.s deleted file mode 100644 index 59ec3f165..000000000 --- a/libc/nt/KernelBase/MapPredefinedHandleInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_MapPredefinedHandleInternal,MapPredefinedHandleInternal,1000 diff --git a/libc/nt/KernelBase/MapViewOfFile3.s b/libc/nt/KernelBase/MapViewOfFile3.s deleted file mode 100644 index e60655afb..000000000 --- a/libc/nt/KernelBase/MapViewOfFile3.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_MapViewOfFile3,MapViewOfFile3,1003 diff --git a/libc/nt/KernelBase/MapViewOfFile3FromApp.s b/libc/nt/KernelBase/MapViewOfFile3FromApp.s deleted file mode 100644 index b4fc87f6c..000000000 --- a/libc/nt/KernelBase/MapViewOfFile3FromApp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_MapViewOfFile3FromApp,MapViewOfFile3FromApp,1004 diff --git a/libc/nt/KernelBase/MapViewOfFileNuma2.s b/libc/nt/KernelBase/MapViewOfFileNuma2.s deleted file mode 100644 index 8499a33c2..000000000 --- a/libc/nt/KernelBase/MapViewOfFileNuma2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_MapViewOfFileNuma2,MapViewOfFileNuma2,1008 diff --git a/libc/nt/KernelBase/MoveFileWithProgressTransactedW.s b/libc/nt/KernelBase/MoveFileWithProgressTransactedW.s deleted file mode 100644 index c3d5ed322..000000000 --- a/libc/nt/KernelBase/MoveFileWithProgressTransactedW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_MoveFileWithProgressTransactedW,MoveFileWithProgressTransactedW,1010 diff --git a/libc/nt/KernelBase/NamedPipeEventEnum.s b/libc/nt/KernelBase/NamedPipeEventEnum.s deleted file mode 100644 index c1662089c..000000000 --- a/libc/nt/KernelBase/NamedPipeEventEnum.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NamedPipeEventEnum,NamedPipeEventEnum,1014 diff --git a/libc/nt/KernelBase/NamedPipeEventSelect.s b/libc/nt/KernelBase/NamedPipeEventSelect.s deleted file mode 100644 index 4a900c44d..000000000 --- a/libc/nt/KernelBase/NamedPipeEventSelect.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NamedPipeEventSelect,NamedPipeEventSelect,1015 diff --git a/libc/nt/KernelBase/NlsCheckPolicy.s b/libc/nt/KernelBase/NlsCheckPolicy.s deleted file mode 100644 index 690de7957..000000000 --- a/libc/nt/KernelBase/NlsCheckPolicy.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsCheckPolicy,NlsCheckPolicy,1018 diff --git a/libc/nt/KernelBase/NlsDispatchAnsiEnumProc.s b/libc/nt/KernelBase/NlsDispatchAnsiEnumProc.s deleted file mode 100644 index 759dda402..000000000 --- a/libc/nt/KernelBase/NlsDispatchAnsiEnumProc.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsDispatchAnsiEnumProc,NlsDispatchAnsiEnumProc,1019 diff --git a/libc/nt/KernelBase/NlsEventDataDescCreate.s b/libc/nt/KernelBase/NlsEventDataDescCreate.s deleted file mode 100644 index 0e2ceca2d..000000000 --- a/libc/nt/KernelBase/NlsEventDataDescCreate.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsEventDataDescCreate,NlsEventDataDescCreate,1020 diff --git a/libc/nt/KernelBase/NlsGetACPFromLocale.s b/libc/nt/KernelBase/NlsGetACPFromLocale.s deleted file mode 100644 index 010de0adb..000000000 --- a/libc/nt/KernelBase/NlsGetACPFromLocale.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsGetACPFromLocale,NlsGetACPFromLocale,1021 diff --git a/libc/nt/KernelBase/NlsGetCacheUpdateCount.s b/libc/nt/KernelBase/NlsGetCacheUpdateCount.s deleted file mode 100644 index 4d9d8b9c2..000000000 --- a/libc/nt/KernelBase/NlsGetCacheUpdateCount.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsGetCacheUpdateCount,NlsGetCacheUpdateCount,1022 diff --git a/libc/nt/KernelBase/NlsIsUserDefaultLocale.s b/libc/nt/KernelBase/NlsIsUserDefaultLocale.s deleted file mode 100644 index f039da842..000000000 --- a/libc/nt/KernelBase/NlsIsUserDefaultLocale.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsIsUserDefaultLocale,NlsIsUserDefaultLocale,1023 diff --git a/libc/nt/KernelBase/NlsUpdateLocale.s b/libc/nt/KernelBase/NlsUpdateLocale.s deleted file mode 100644 index 3a69d0f42..000000000 --- a/libc/nt/KernelBase/NlsUpdateLocale.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsUpdateLocale,NlsUpdateLocale,1024 diff --git a/libc/nt/KernelBase/NlsUpdateSystemLocale.s b/libc/nt/KernelBase/NlsUpdateSystemLocale.s deleted file mode 100644 index 86e7895a2..000000000 --- a/libc/nt/KernelBase/NlsUpdateSystemLocale.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsUpdateSystemLocale,NlsUpdateSystemLocale,1025 diff --git a/libc/nt/KernelBase/NlsValidateLocale.s b/libc/nt/KernelBase/NlsValidateLocale.s deleted file mode 100644 index c43b8b95d..000000000 --- a/libc/nt/KernelBase/NlsValidateLocale.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsValidateLocale,NlsValidateLocale,1026 diff --git a/libc/nt/KernelBase/NlsWriteEtwEvent.s b/libc/nt/KernelBase/NlsWriteEtwEvent.s deleted file mode 100644 index 0a0e79edc..000000000 --- a/libc/nt/KernelBase/NlsWriteEtwEvent.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NlsWriteEtwEvent,NlsWriteEtwEvent,1027 diff --git a/libc/nt/KernelBase/NotifyMountMgr.s b/libc/nt/KernelBase/NotifyMountMgr.s deleted file mode 100644 index 2bce67eb6..000000000 --- a/libc/nt/KernelBase/NotifyMountMgr.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NotifyMountMgr,NotifyMountMgr,1029 diff --git a/libc/nt/KernelBase/NotifyRedirectedStringChange.s b/libc/nt/KernelBase/NotifyRedirectedStringChange.s deleted file mode 100644 index 0dd8641b9..000000000 --- a/libc/nt/KernelBase/NotifyRedirectedStringChange.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_NotifyRedirectedStringChange,NotifyRedirectedStringChange,1030 diff --git a/libc/nt/KernelBase/OpenCommPort.s b/libc/nt/KernelBase/OpenCommPort.s deleted file mode 100644 index 9532fcc9b..000000000 --- a/libc/nt/KernelBase/OpenCommPort.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenCommPort,OpenCommPort,1036 diff --git a/libc/nt/KernelBase/OpenFileMappingFromApp.s b/libc/nt/KernelBase/OpenFileMappingFromApp.s deleted file mode 100644 index ae087af7e..000000000 --- a/libc/nt/KernelBase/OpenFileMappingFromApp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenFileMappingFromApp,OpenFileMappingFromApp,1040 diff --git a/libc/nt/KernelBase/OpenGlobalizationUserSettingsKey.s b/libc/nt/KernelBase/OpenGlobalizationUserSettingsKey.s deleted file mode 100644 index 3d033529c..000000000 --- a/libc/nt/KernelBase/OpenGlobalizationUserSettingsKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenGlobalizationUserSettingsKey,OpenGlobalizationUserSettingsKey,1042 diff --git a/libc/nt/KernelBase/OpenPackageInfoByFullNameForUser.s b/libc/nt/KernelBase/OpenPackageInfoByFullNameForUser.s deleted file mode 100644 index c1563d43b..000000000 --- a/libc/nt/KernelBase/OpenPackageInfoByFullNameForUser.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenPackageInfoByFullNameForUser,OpenPackageInfoByFullNameForUser,1045 diff --git a/libc/nt/KernelBase/OpenRegKey.s b/libc/nt/KernelBase/OpenRegKey.s deleted file mode 100644 index 88f11f8d3..000000000 --- a/libc/nt/KernelBase/OpenRegKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenRegKey,OpenRegKey,1049 diff --git a/libc/nt/KernelBase/OpenState.s b/libc/nt/KernelBase/OpenState.s deleted file mode 100644 index 1bab8ea26..000000000 --- a/libc/nt/KernelBase/OpenState.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenState,OpenState,1051 diff --git a/libc/nt/KernelBase/OpenStateAtom.s b/libc/nt/KernelBase/OpenStateAtom.s deleted file mode 100644 index 97b54d544..000000000 --- a/libc/nt/KernelBase/OpenStateAtom.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenStateAtom,OpenStateAtom,1052 diff --git a/libc/nt/KernelBase/OpenStateExplicit.s b/libc/nt/KernelBase/OpenStateExplicit.s deleted file mode 100644 index a038a9301..000000000 --- a/libc/nt/KernelBase/OpenStateExplicit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenStateExplicit,OpenStateExplicit,1053 diff --git a/libc/nt/KernelBase/OpenStateExplicitForUserSid.s b/libc/nt/KernelBase/OpenStateExplicitForUserSid.s deleted file mode 100644 index 348b6e0b7..000000000 --- a/libc/nt/KernelBase/OpenStateExplicitForUserSid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenStateExplicitForUserSid,OpenStateExplicitForUserSid,1054 diff --git a/libc/nt/KernelBase/OpenStateExplicitForUserSidString.s b/libc/nt/KernelBase/OpenStateExplicitForUserSidString.s deleted file mode 100644 index 3a479f819..000000000 --- a/libc/nt/KernelBase/OpenStateExplicitForUserSidString.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OpenStateExplicitForUserSidString,OpenStateExplicitForUserSidString,1055 diff --git a/libc/nt/KernelBase/OverrideRoamingDataModificationTimesInRange.s b/libc/nt/KernelBase/OverrideRoamingDataModificationTimesInRange.s deleted file mode 100644 index 2199682f2..000000000 --- a/libc/nt/KernelBase/OverrideRoamingDataModificationTimesInRange.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_OverrideRoamingDataModificationTimesInRange,OverrideRoamingDataModificationTimesInRange,1061 diff --git a/libc/nt/KernelBase/PackageFamilyNameFromFullNameA.s b/libc/nt/KernelBase/PackageFamilyNameFromFullNameA.s deleted file mode 100644 index 537cb7e6d..000000000 --- a/libc/nt/KernelBase/PackageFamilyNameFromFullNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageFamilyNameFromFullNameA,PackageFamilyNameFromFullNameA,1063 diff --git a/libc/nt/KernelBase/PackageFamilyNameFromIdA.s b/libc/nt/KernelBase/PackageFamilyNameFromIdA.s deleted file mode 100644 index 54f4b60f6..000000000 --- a/libc/nt/KernelBase/PackageFamilyNameFromIdA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageFamilyNameFromIdA,PackageFamilyNameFromIdA,1065 diff --git a/libc/nt/KernelBase/PackageFamilyNameFromProductId.s b/libc/nt/KernelBase/PackageFamilyNameFromProductId.s deleted file mode 100644 index ead4e67f2..000000000 --- a/libc/nt/KernelBase/PackageFamilyNameFromProductId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageFamilyNameFromProductId,PackageFamilyNameFromProductId,1066 diff --git a/libc/nt/KernelBase/PackageFullNameFromIdA.s b/libc/nt/KernelBase/PackageFullNameFromIdA.s deleted file mode 100644 index 70691f834..000000000 --- a/libc/nt/KernelBase/PackageFullNameFromIdA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageFullNameFromIdA,PackageFullNameFromIdA,1068 diff --git a/libc/nt/KernelBase/PackageFullNameFromProductId.s b/libc/nt/KernelBase/PackageFullNameFromProductId.s deleted file mode 100644 index 3879c5ad0..000000000 --- a/libc/nt/KernelBase/PackageFullNameFromProductId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageFullNameFromProductId,PackageFullNameFromProductId,1069 diff --git a/libc/nt/KernelBase/PackageIdFromFullNameA.s b/libc/nt/KernelBase/PackageIdFromFullNameA.s deleted file mode 100644 index 9baad1665..000000000 --- a/libc/nt/KernelBase/PackageIdFromFullNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageIdFromFullNameA,PackageIdFromFullNameA,1071 diff --git a/libc/nt/KernelBase/PackageIdFromProductId.s b/libc/nt/KernelBase/PackageIdFromProductId.s deleted file mode 100644 index cd4291470..000000000 --- a/libc/nt/KernelBase/PackageIdFromProductId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageIdFromProductId,PackageIdFromProductId,1072 diff --git a/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyNameA.s b/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyNameA.s deleted file mode 100644 index 6f9e3e411..000000000 --- a/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageNameAndPublisherIdFromFamilyNameA,PackageNameAndPublisherIdFromFamilyNameA,1074 diff --git a/libc/nt/KernelBase/PackageRelativeApplicationIdFromProductId.s b/libc/nt/KernelBase/PackageRelativeApplicationIdFromProductId.s deleted file mode 100644 index d033e4232..000000000 --- a/libc/nt/KernelBase/PackageRelativeApplicationIdFromProductId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageRelativeApplicationIdFromProductId,PackageRelativeApplicationIdFromProductId,1075 diff --git a/libc/nt/KernelBase/PackageSidFromFamilyName.s b/libc/nt/KernelBase/PackageSidFromFamilyName.s deleted file mode 100644 index 8a0f48148..000000000 --- a/libc/nt/KernelBase/PackageSidFromFamilyName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageSidFromFamilyName,PackageSidFromFamilyName,1076 diff --git a/libc/nt/KernelBase/PackageSidFromProductId.s b/libc/nt/KernelBase/PackageSidFromProductId.s deleted file mode 100644 index 119437ec0..000000000 --- a/libc/nt/KernelBase/PackageSidFromProductId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PackageSidFromProductId,PackageSidFromProductId,1 diff --git a/libc/nt/KernelBase/ParseApplicationUserModelIdA.s b/libc/nt/KernelBase/ParseApplicationUserModelIdA.s deleted file mode 100644 index 3b6f02c65..000000000 --- a/libc/nt/KernelBase/ParseApplicationUserModelIdA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ParseApplicationUserModelIdA,ParseApplicationUserModelIdA,1078 diff --git a/libc/nt/KernelBase/ParseURLA.s b/libc/nt/KernelBase/ParseURLA.s deleted file mode 100644 index 21cdb6ba1..000000000 --- a/libc/nt/KernelBase/ParseURLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ParseURLA,ParseURLA,1079 diff --git a/libc/nt/KernelBase/ParseURLW.s b/libc/nt/KernelBase/ParseURLW.s deleted file mode 100644 index de395aba2..000000000 --- a/libc/nt/KernelBase/ParseURLW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ParseURLW,ParseURLW,1080 diff --git a/libc/nt/KernelBase/PathAddBackslashA.s b/libc/nt/KernelBase/PathAddBackslashA.s deleted file mode 100644 index fa66931c4..000000000 --- a/libc/nt/KernelBase/PathAddBackslashA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathAddBackslashA,PathAddBackslashA,1081 diff --git a/libc/nt/KernelBase/PathAddBackslashW.s b/libc/nt/KernelBase/PathAddBackslashW.s deleted file mode 100644 index de10501c3..000000000 --- a/libc/nt/KernelBase/PathAddBackslashW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathAddBackslashW,PathAddBackslashW,1082 diff --git a/libc/nt/KernelBase/PathAddExtensionA.s b/libc/nt/KernelBase/PathAddExtensionA.s deleted file mode 100644 index 082124e0e..000000000 --- a/libc/nt/KernelBase/PathAddExtensionA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathAddExtensionA,PathAddExtensionA,1083 diff --git a/libc/nt/KernelBase/PathAddExtensionW.s b/libc/nt/KernelBase/PathAddExtensionW.s deleted file mode 100644 index 7b15da9e1..000000000 --- a/libc/nt/KernelBase/PathAddExtensionW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathAddExtensionW,PathAddExtensionW,1084 diff --git a/libc/nt/KernelBase/PathAllocCanonicalize.s b/libc/nt/KernelBase/PathAllocCanonicalize.s deleted file mode 100644 index aac7e540b..000000000 --- a/libc/nt/KernelBase/PathAllocCanonicalize.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathAllocCanonicalize,PathAllocCanonicalize,1085 diff --git a/libc/nt/KernelBase/PathAllocCombine.s b/libc/nt/KernelBase/PathAllocCombine.s deleted file mode 100644 index 6c316c616..000000000 --- a/libc/nt/KernelBase/PathAllocCombine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathAllocCombine,PathAllocCombine,1086 diff --git a/libc/nt/KernelBase/PathAppendA.s b/libc/nt/KernelBase/PathAppendA.s deleted file mode 100644 index 5f87fe414..000000000 --- a/libc/nt/KernelBase/PathAppendA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathAppendA,PathAppendA,1087 diff --git a/libc/nt/KernelBase/PathAppendW.s b/libc/nt/KernelBase/PathAppendW.s deleted file mode 100644 index 8fbb2f7e9..000000000 --- a/libc/nt/KernelBase/PathAppendW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathAppendW,PathAppendW,1088 diff --git a/libc/nt/KernelBase/PathCanonicalizeA.s b/libc/nt/KernelBase/PathCanonicalizeA.s deleted file mode 100644 index f25949065..000000000 --- a/libc/nt/KernelBase/PathCanonicalizeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCanonicalizeA,PathCanonicalizeA,1089 diff --git a/libc/nt/KernelBase/PathCanonicalizeW.s b/libc/nt/KernelBase/PathCanonicalizeW.s deleted file mode 100644 index 071254172..000000000 --- a/libc/nt/KernelBase/PathCanonicalizeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCanonicalizeW,PathCanonicalizeW,1090 diff --git a/libc/nt/KernelBase/PathCchAddBackslash.s b/libc/nt/KernelBase/PathCchAddBackslash.s deleted file mode 100644 index 343836135..000000000 --- a/libc/nt/KernelBase/PathCchAddBackslash.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchAddBackslash,PathCchAddBackslash,1091 diff --git a/libc/nt/KernelBase/PathCchAddBackslashEx.s b/libc/nt/KernelBase/PathCchAddBackslashEx.s deleted file mode 100644 index 200ede37e..000000000 --- a/libc/nt/KernelBase/PathCchAddBackslashEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchAddBackslashEx,PathCchAddBackslashEx,1092 diff --git a/libc/nt/KernelBase/PathCchAddExtension.s b/libc/nt/KernelBase/PathCchAddExtension.s deleted file mode 100644 index 7e0fb43b1..000000000 --- a/libc/nt/KernelBase/PathCchAddExtension.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchAddExtension,PathCchAddExtension,1093 diff --git a/libc/nt/KernelBase/PathCchAppend.s b/libc/nt/KernelBase/PathCchAppend.s deleted file mode 100644 index ba191167a..000000000 --- a/libc/nt/KernelBase/PathCchAppend.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchAppend,PathCchAppend,1094 diff --git a/libc/nt/KernelBase/PathCchAppendEx.s b/libc/nt/KernelBase/PathCchAppendEx.s deleted file mode 100644 index 38276ffbc..000000000 --- a/libc/nt/KernelBase/PathCchAppendEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchAppendEx,PathCchAppendEx,1095 diff --git a/libc/nt/KernelBase/PathCchCanonicalize.s b/libc/nt/KernelBase/PathCchCanonicalize.s deleted file mode 100644 index cf768ea15..000000000 --- a/libc/nt/KernelBase/PathCchCanonicalize.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchCanonicalize,PathCchCanonicalize,1096 diff --git a/libc/nt/KernelBase/PathCchCanonicalizeEx.s b/libc/nt/KernelBase/PathCchCanonicalizeEx.s deleted file mode 100644 index 0db98df2f..000000000 --- a/libc/nt/KernelBase/PathCchCanonicalizeEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchCanonicalizeEx,PathCchCanonicalizeEx,1097 diff --git a/libc/nt/KernelBase/PathCchCombine.s b/libc/nt/KernelBase/PathCchCombine.s deleted file mode 100644 index 809c7089e..000000000 --- a/libc/nt/KernelBase/PathCchCombine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchCombine,PathCchCombine,1098 diff --git a/libc/nt/KernelBase/PathCchCombineEx.s b/libc/nt/KernelBase/PathCchCombineEx.s deleted file mode 100644 index d998e71b4..000000000 --- a/libc/nt/KernelBase/PathCchCombineEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchCombineEx,PathCchCombineEx,1099 diff --git a/libc/nt/KernelBase/PathCchFindExtension.s b/libc/nt/KernelBase/PathCchFindExtension.s deleted file mode 100644 index c35243313..000000000 --- a/libc/nt/KernelBase/PathCchFindExtension.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchFindExtension,PathCchFindExtension,1100 diff --git a/libc/nt/KernelBase/PathCchIsRoot.s b/libc/nt/KernelBase/PathCchIsRoot.s deleted file mode 100644 index 218176c50..000000000 --- a/libc/nt/KernelBase/PathCchIsRoot.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchIsRoot,PathCchIsRoot,1101 diff --git a/libc/nt/KernelBase/PathCchRemoveBackslash.s b/libc/nt/KernelBase/PathCchRemoveBackslash.s deleted file mode 100644 index 4792a10a4..000000000 --- a/libc/nt/KernelBase/PathCchRemoveBackslash.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchRemoveBackslash,PathCchRemoveBackslash,1102 diff --git a/libc/nt/KernelBase/PathCchRemoveBackslashEx.s b/libc/nt/KernelBase/PathCchRemoveBackslashEx.s deleted file mode 100644 index d153f047e..000000000 --- a/libc/nt/KernelBase/PathCchRemoveBackslashEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchRemoveBackslashEx,PathCchRemoveBackslashEx,1103 diff --git a/libc/nt/KernelBase/PathCchRemoveExtension.s b/libc/nt/KernelBase/PathCchRemoveExtension.s deleted file mode 100644 index ca5b471d2..000000000 --- a/libc/nt/KernelBase/PathCchRemoveExtension.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchRemoveExtension,PathCchRemoveExtension,1104 diff --git a/libc/nt/KernelBase/PathCchRemoveFileSpec.s b/libc/nt/KernelBase/PathCchRemoveFileSpec.s deleted file mode 100644 index edcfae82b..000000000 --- a/libc/nt/KernelBase/PathCchRemoveFileSpec.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchRemoveFileSpec,PathCchRemoveFileSpec,1105 diff --git a/libc/nt/KernelBase/PathCchRenameExtension.s b/libc/nt/KernelBase/PathCchRenameExtension.s deleted file mode 100644 index c01680cd8..000000000 --- a/libc/nt/KernelBase/PathCchRenameExtension.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchRenameExtension,PathCchRenameExtension,1106 diff --git a/libc/nt/KernelBase/PathCchSkipRoot.s b/libc/nt/KernelBase/PathCchSkipRoot.s deleted file mode 100644 index 016cc8444..000000000 --- a/libc/nt/KernelBase/PathCchSkipRoot.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchSkipRoot,PathCchSkipRoot,1107 diff --git a/libc/nt/KernelBase/PathCchStripPrefix.s b/libc/nt/KernelBase/PathCchStripPrefix.s deleted file mode 100644 index 7b7991533..000000000 --- a/libc/nt/KernelBase/PathCchStripPrefix.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchStripPrefix,PathCchStripPrefix,1108 diff --git a/libc/nt/KernelBase/PathCchStripToRoot.s b/libc/nt/KernelBase/PathCchStripToRoot.s deleted file mode 100644 index 679cf6e33..000000000 --- a/libc/nt/KernelBase/PathCchStripToRoot.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCchStripToRoot,PathCchStripToRoot,1109 diff --git a/libc/nt/KernelBase/PathCombineA.s b/libc/nt/KernelBase/PathCombineA.s deleted file mode 100644 index dd5272072..000000000 --- a/libc/nt/KernelBase/PathCombineA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCombineA,PathCombineA,1110 diff --git a/libc/nt/KernelBase/PathCombineW.s b/libc/nt/KernelBase/PathCombineW.s deleted file mode 100644 index 3be21d965..000000000 --- a/libc/nt/KernelBase/PathCombineW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCombineW,PathCombineW,1111 diff --git a/libc/nt/KernelBase/PathCommonPrefixA.s b/libc/nt/KernelBase/PathCommonPrefixA.s deleted file mode 100644 index 0850b8d2f..000000000 --- a/libc/nt/KernelBase/PathCommonPrefixA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCommonPrefixA,PathCommonPrefixA,1112 diff --git a/libc/nt/KernelBase/PathCommonPrefixW.s b/libc/nt/KernelBase/PathCommonPrefixW.s deleted file mode 100644 index 1504201ef..000000000 --- a/libc/nt/KernelBase/PathCommonPrefixW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCommonPrefixW,PathCommonPrefixW,1113 diff --git a/libc/nt/KernelBase/PathCreateFromUrlA.s b/libc/nt/KernelBase/PathCreateFromUrlA.s deleted file mode 100644 index 9cb36fc30..000000000 --- a/libc/nt/KernelBase/PathCreateFromUrlA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCreateFromUrlA,PathCreateFromUrlA,1114 diff --git a/libc/nt/KernelBase/PathCreateFromUrlAlloc.s b/libc/nt/KernelBase/PathCreateFromUrlAlloc.s deleted file mode 100644 index 972ff08df..000000000 --- a/libc/nt/KernelBase/PathCreateFromUrlAlloc.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCreateFromUrlAlloc,PathCreateFromUrlAlloc,1115 diff --git a/libc/nt/KernelBase/PathCreateFromUrlW.s b/libc/nt/KernelBase/PathCreateFromUrlW.s deleted file mode 100644 index 03de14eef..000000000 --- a/libc/nt/KernelBase/PathCreateFromUrlW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathCreateFromUrlW,PathCreateFromUrlW,1116 diff --git a/libc/nt/KernelBase/PathFileExistsA.s b/libc/nt/KernelBase/PathFileExistsA.s deleted file mode 100644 index 8e2476198..000000000 --- a/libc/nt/KernelBase/PathFileExistsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathFileExistsA,PathFileExistsA,1117 diff --git a/libc/nt/KernelBase/PathFileExistsW.s b/libc/nt/KernelBase/PathFileExistsW.s deleted file mode 100644 index 501197c91..000000000 --- a/libc/nt/KernelBase/PathFileExistsW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathFileExistsW,PathFileExistsW,1118 diff --git a/libc/nt/KernelBase/PathFindExtensionA.s b/libc/nt/KernelBase/PathFindExtensionA.s deleted file mode 100644 index 096fdf2c8..000000000 --- a/libc/nt/KernelBase/PathFindExtensionA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathFindExtensionA,PathFindExtensionA,1119 diff --git a/libc/nt/KernelBase/PathFindExtensionW.s b/libc/nt/KernelBase/PathFindExtensionW.s deleted file mode 100644 index 7d7564eab..000000000 --- a/libc/nt/KernelBase/PathFindExtensionW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathFindExtensionW,PathFindExtensionW,1120 diff --git a/libc/nt/KernelBase/PathFindFileNameA.s b/libc/nt/KernelBase/PathFindFileNameA.s deleted file mode 100644 index 1218e9db1..000000000 --- a/libc/nt/KernelBase/PathFindFileNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathFindFileNameA,PathFindFileNameA,1121 diff --git a/libc/nt/KernelBase/PathFindFileNameW.s b/libc/nt/KernelBase/PathFindFileNameW.s deleted file mode 100644 index 0f67bca56..000000000 --- a/libc/nt/KernelBase/PathFindFileNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathFindFileNameW,PathFindFileNameW,1122 diff --git a/libc/nt/KernelBase/PathFindNextComponentA.s b/libc/nt/KernelBase/PathFindNextComponentA.s deleted file mode 100644 index 786882d2e..000000000 --- a/libc/nt/KernelBase/PathFindNextComponentA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathFindNextComponentA,PathFindNextComponentA,1123 diff --git a/libc/nt/KernelBase/PathFindNextComponentW.s b/libc/nt/KernelBase/PathFindNextComponentW.s deleted file mode 100644 index 6ed6f3e4c..000000000 --- a/libc/nt/KernelBase/PathFindNextComponentW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathFindNextComponentW,PathFindNextComponentW,1124 diff --git a/libc/nt/KernelBase/PathGetArgsA.s b/libc/nt/KernelBase/PathGetArgsA.s deleted file mode 100644 index aa9cc4540..000000000 --- a/libc/nt/KernelBase/PathGetArgsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathGetArgsA,PathGetArgsA,1125 diff --git a/libc/nt/KernelBase/PathGetArgsW.s b/libc/nt/KernelBase/PathGetArgsW.s deleted file mode 100644 index a0e997252..000000000 --- a/libc/nt/KernelBase/PathGetArgsW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathGetArgsW,PathGetArgsW,1126 diff --git a/libc/nt/KernelBase/PathGetCharTypeA.s b/libc/nt/KernelBase/PathGetCharTypeA.s deleted file mode 100644 index 0b02382d7..000000000 --- a/libc/nt/KernelBase/PathGetCharTypeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathGetCharTypeA,PathGetCharTypeA,1127 diff --git a/libc/nt/KernelBase/PathGetCharTypeW.s b/libc/nt/KernelBase/PathGetCharTypeW.s deleted file mode 100644 index 249a2b9fb..000000000 --- a/libc/nt/KernelBase/PathGetCharTypeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathGetCharTypeW,PathGetCharTypeW,1128 diff --git a/libc/nt/KernelBase/PathGetDriveNumberA.s b/libc/nt/KernelBase/PathGetDriveNumberA.s deleted file mode 100644 index 9f6b5e054..000000000 --- a/libc/nt/KernelBase/PathGetDriveNumberA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathGetDriveNumberA,PathGetDriveNumberA,1129 diff --git a/libc/nt/KernelBase/PathGetDriveNumberW.s b/libc/nt/KernelBase/PathGetDriveNumberW.s deleted file mode 100644 index 122677cc9..000000000 --- a/libc/nt/KernelBase/PathGetDriveNumberW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathGetDriveNumberW,PathGetDriveNumberW,1130 diff --git a/libc/nt/KernelBase/PathIsFileSpecA.s b/libc/nt/KernelBase/PathIsFileSpecA.s deleted file mode 100644 index 43ee464d7..000000000 --- a/libc/nt/KernelBase/PathIsFileSpecA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsFileSpecA,PathIsFileSpecA,1131 diff --git a/libc/nt/KernelBase/PathIsFileSpecW.s b/libc/nt/KernelBase/PathIsFileSpecW.s deleted file mode 100644 index eb8c0c9b0..000000000 --- a/libc/nt/KernelBase/PathIsFileSpecW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsFileSpecW,PathIsFileSpecW,1132 diff --git a/libc/nt/KernelBase/PathIsLFNFileSpecA.s b/libc/nt/KernelBase/PathIsLFNFileSpecA.s deleted file mode 100644 index a08f4358d..000000000 --- a/libc/nt/KernelBase/PathIsLFNFileSpecA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsLFNFileSpecA,PathIsLFNFileSpecA,1133 diff --git a/libc/nt/KernelBase/PathIsLFNFileSpecW.s b/libc/nt/KernelBase/PathIsLFNFileSpecW.s deleted file mode 100644 index 90d328fa8..000000000 --- a/libc/nt/KernelBase/PathIsLFNFileSpecW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsLFNFileSpecW,PathIsLFNFileSpecW,1134 diff --git a/libc/nt/KernelBase/PathIsPrefixA.s b/libc/nt/KernelBase/PathIsPrefixA.s deleted file mode 100644 index 5a0ae0f0e..000000000 --- a/libc/nt/KernelBase/PathIsPrefixA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsPrefixA,PathIsPrefixA,1135 diff --git a/libc/nt/KernelBase/PathIsPrefixW.s b/libc/nt/KernelBase/PathIsPrefixW.s deleted file mode 100644 index 3b15d64b6..000000000 --- a/libc/nt/KernelBase/PathIsPrefixW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsPrefixW,PathIsPrefixW,1136 diff --git a/libc/nt/KernelBase/PathIsRelativeA.s b/libc/nt/KernelBase/PathIsRelativeA.s deleted file mode 100644 index 9c1311929..000000000 --- a/libc/nt/KernelBase/PathIsRelativeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsRelativeA,PathIsRelativeA,1137 diff --git a/libc/nt/KernelBase/PathIsRelativeW.s b/libc/nt/KernelBase/PathIsRelativeW.s deleted file mode 100644 index 3ae43b1e5..000000000 --- a/libc/nt/KernelBase/PathIsRelativeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsRelativeW,PathIsRelativeW,1138 diff --git a/libc/nt/KernelBase/PathIsRootA.s b/libc/nt/KernelBase/PathIsRootA.s deleted file mode 100644 index 20b19c7ef..000000000 --- a/libc/nt/KernelBase/PathIsRootA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsRootA,PathIsRootA,1139 diff --git a/libc/nt/KernelBase/PathIsRootW.s b/libc/nt/KernelBase/PathIsRootW.s deleted file mode 100644 index d5f629dff..000000000 --- a/libc/nt/KernelBase/PathIsRootW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsRootW,PathIsRootW,1140 diff --git a/libc/nt/KernelBase/PathIsSameRootA.s b/libc/nt/KernelBase/PathIsSameRootA.s deleted file mode 100644 index 3b99850c4..000000000 --- a/libc/nt/KernelBase/PathIsSameRootA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsSameRootA,PathIsSameRootA,1141 diff --git a/libc/nt/KernelBase/PathIsSameRootW.s b/libc/nt/KernelBase/PathIsSameRootW.s deleted file mode 100644 index 6a02074ff..000000000 --- a/libc/nt/KernelBase/PathIsSameRootW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsSameRootW,PathIsSameRootW,1142 diff --git a/libc/nt/KernelBase/PathIsUNCA.s b/libc/nt/KernelBase/PathIsUNCA.s deleted file mode 100644 index 6f268aa48..000000000 --- a/libc/nt/KernelBase/PathIsUNCA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsUNCA,PathIsUNCA,1143 diff --git a/libc/nt/KernelBase/PathIsUNCEx.s b/libc/nt/KernelBase/PathIsUNCEx.s deleted file mode 100644 index 4286c0746..000000000 --- a/libc/nt/KernelBase/PathIsUNCEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsUNCEx,PathIsUNCEx,1144 diff --git a/libc/nt/KernelBase/PathIsUNCServerA.s b/libc/nt/KernelBase/PathIsUNCServerA.s deleted file mode 100644 index bc65b54b6..000000000 --- a/libc/nt/KernelBase/PathIsUNCServerA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsUNCServerA,PathIsUNCServerA,1145 diff --git a/libc/nt/KernelBase/PathIsUNCServerShareA.s b/libc/nt/KernelBase/PathIsUNCServerShareA.s deleted file mode 100644 index 647be4754..000000000 --- a/libc/nt/KernelBase/PathIsUNCServerShareA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsUNCServerShareA,PathIsUNCServerShareA,1146 diff --git a/libc/nt/KernelBase/PathIsUNCServerShareW.s b/libc/nt/KernelBase/PathIsUNCServerShareW.s deleted file mode 100644 index c5079c878..000000000 --- a/libc/nt/KernelBase/PathIsUNCServerShareW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsUNCServerShareW,PathIsUNCServerShareW,1147 diff --git a/libc/nt/KernelBase/PathIsUNCServerW.s b/libc/nt/KernelBase/PathIsUNCServerW.s deleted file mode 100644 index f63a6f2bd..000000000 --- a/libc/nt/KernelBase/PathIsUNCServerW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsUNCServerW,PathIsUNCServerW,1148 diff --git a/libc/nt/KernelBase/PathIsUNCW.s b/libc/nt/KernelBase/PathIsUNCW.s deleted file mode 100644 index 8aaeb964e..000000000 --- a/libc/nt/KernelBase/PathIsUNCW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsUNCW,PathIsUNCW,1149 diff --git a/libc/nt/KernelBase/PathIsURLA.s b/libc/nt/KernelBase/PathIsURLA.s deleted file mode 100644 index 796cc1c20..000000000 --- a/libc/nt/KernelBase/PathIsURLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsURLA,PathIsURLA,1150 diff --git a/libc/nt/KernelBase/PathIsURLW.s b/libc/nt/KernelBase/PathIsURLW.s deleted file mode 100644 index f6ed4ae2e..000000000 --- a/libc/nt/KernelBase/PathIsURLW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsURLW,PathIsURLW,1151 diff --git a/libc/nt/KernelBase/PathIsValidCharA.s b/libc/nt/KernelBase/PathIsValidCharA.s deleted file mode 100644 index 4af677dd7..000000000 --- a/libc/nt/KernelBase/PathIsValidCharA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsValidCharA,PathIsValidCharA,1152 diff --git a/libc/nt/KernelBase/PathIsValidCharW.s b/libc/nt/KernelBase/PathIsValidCharW.s deleted file mode 100644 index 7a77e958a..000000000 --- a/libc/nt/KernelBase/PathIsValidCharW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathIsValidCharW,PathIsValidCharW,1153 diff --git a/libc/nt/KernelBase/PathMatchSpecA.s b/libc/nt/KernelBase/PathMatchSpecA.s deleted file mode 100644 index 0e70b5aca..000000000 --- a/libc/nt/KernelBase/PathMatchSpecA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathMatchSpecA,PathMatchSpecA,1154 diff --git a/libc/nt/KernelBase/PathMatchSpecExA.s b/libc/nt/KernelBase/PathMatchSpecExA.s deleted file mode 100644 index 0d0318d81..000000000 --- a/libc/nt/KernelBase/PathMatchSpecExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathMatchSpecExA,PathMatchSpecExA,1155 diff --git a/libc/nt/KernelBase/PathMatchSpecExW.s b/libc/nt/KernelBase/PathMatchSpecExW.s deleted file mode 100644 index aa2d37d2d..000000000 --- a/libc/nt/KernelBase/PathMatchSpecExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathMatchSpecExW,PathMatchSpecExW,1156 diff --git a/libc/nt/KernelBase/PathMatchSpecW.s b/libc/nt/KernelBase/PathMatchSpecW.s deleted file mode 100644 index b02775582..000000000 --- a/libc/nt/KernelBase/PathMatchSpecW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathMatchSpecW,PathMatchSpecW,1157 diff --git a/libc/nt/KernelBase/PathParseIconLocationA.s b/libc/nt/KernelBase/PathParseIconLocationA.s deleted file mode 100644 index a68b2abe5..000000000 --- a/libc/nt/KernelBase/PathParseIconLocationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathParseIconLocationA,PathParseIconLocationA,1158 diff --git a/libc/nt/KernelBase/PathParseIconLocationW.s b/libc/nt/KernelBase/PathParseIconLocationW.s deleted file mode 100644 index cad201b54..000000000 --- a/libc/nt/KernelBase/PathParseIconLocationW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathParseIconLocationW,PathParseIconLocationW,1159 diff --git a/libc/nt/KernelBase/PathQuoteSpacesA.s b/libc/nt/KernelBase/PathQuoteSpacesA.s deleted file mode 100644 index a61a5cad5..000000000 --- a/libc/nt/KernelBase/PathQuoteSpacesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathQuoteSpacesA,PathQuoteSpacesA,1160 diff --git a/libc/nt/KernelBase/PathQuoteSpacesW.s b/libc/nt/KernelBase/PathQuoteSpacesW.s deleted file mode 100644 index 2be89495a..000000000 --- a/libc/nt/KernelBase/PathQuoteSpacesW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathQuoteSpacesW,PathQuoteSpacesW,1161 diff --git a/libc/nt/KernelBase/PathRelativePathToA.s b/libc/nt/KernelBase/PathRelativePathToA.s deleted file mode 100644 index 07eefc9ea..000000000 --- a/libc/nt/KernelBase/PathRelativePathToA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRelativePathToA,PathRelativePathToA,1162 diff --git a/libc/nt/KernelBase/PathRelativePathToW.s b/libc/nt/KernelBase/PathRelativePathToW.s deleted file mode 100644 index 21c58a53e..000000000 --- a/libc/nt/KernelBase/PathRelativePathToW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRelativePathToW,PathRelativePathToW,1163 diff --git a/libc/nt/KernelBase/PathRemoveBackslashA.s b/libc/nt/KernelBase/PathRemoveBackslashA.s deleted file mode 100644 index 7b368169c..000000000 --- a/libc/nt/KernelBase/PathRemoveBackslashA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRemoveBackslashA,PathRemoveBackslashA,1164 diff --git a/libc/nt/KernelBase/PathRemoveBackslashW.s b/libc/nt/KernelBase/PathRemoveBackslashW.s deleted file mode 100644 index 25a626fd3..000000000 --- a/libc/nt/KernelBase/PathRemoveBackslashW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRemoveBackslashW,PathRemoveBackslashW,1165 diff --git a/libc/nt/KernelBase/PathRemoveBlanksA.s b/libc/nt/KernelBase/PathRemoveBlanksA.s deleted file mode 100644 index ed8b2e68f..000000000 --- a/libc/nt/KernelBase/PathRemoveBlanksA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRemoveBlanksA,PathRemoveBlanksA,1166 diff --git a/libc/nt/KernelBase/PathRemoveBlanksW.s b/libc/nt/KernelBase/PathRemoveBlanksW.s deleted file mode 100644 index 2e96ec699..000000000 --- a/libc/nt/KernelBase/PathRemoveBlanksW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRemoveBlanksW,PathRemoveBlanksW,1167 diff --git a/libc/nt/KernelBase/PathRemoveExtensionA.s b/libc/nt/KernelBase/PathRemoveExtensionA.s deleted file mode 100644 index d1991783e..000000000 --- a/libc/nt/KernelBase/PathRemoveExtensionA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRemoveExtensionA,PathRemoveExtensionA,1168 diff --git a/libc/nt/KernelBase/PathRemoveExtensionW.s b/libc/nt/KernelBase/PathRemoveExtensionW.s deleted file mode 100644 index 4ab59ed0e..000000000 --- a/libc/nt/KernelBase/PathRemoveExtensionW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRemoveExtensionW,PathRemoveExtensionW,1169 diff --git a/libc/nt/KernelBase/PathRemoveFileSpecA.s b/libc/nt/KernelBase/PathRemoveFileSpecA.s deleted file mode 100644 index e967db1f3..000000000 --- a/libc/nt/KernelBase/PathRemoveFileSpecA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRemoveFileSpecA,PathRemoveFileSpecA,1170 diff --git a/libc/nt/KernelBase/PathRemoveFileSpecW.s b/libc/nt/KernelBase/PathRemoveFileSpecW.s deleted file mode 100644 index 1d159123a..000000000 --- a/libc/nt/KernelBase/PathRemoveFileSpecW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRemoveFileSpecW,PathRemoveFileSpecW,1171 diff --git a/libc/nt/KernelBase/PathRenameExtensionA.s b/libc/nt/KernelBase/PathRenameExtensionA.s deleted file mode 100644 index 388887d6a..000000000 --- a/libc/nt/KernelBase/PathRenameExtensionA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRenameExtensionA,PathRenameExtensionA,1172 diff --git a/libc/nt/KernelBase/PathRenameExtensionW.s b/libc/nt/KernelBase/PathRenameExtensionW.s deleted file mode 100644 index d4cd80e7f..000000000 --- a/libc/nt/KernelBase/PathRenameExtensionW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathRenameExtensionW,PathRenameExtensionW,1173 diff --git a/libc/nt/KernelBase/PathSearchAndQualifyA.s b/libc/nt/KernelBase/PathSearchAndQualifyA.s deleted file mode 100644 index 91b441645..000000000 --- a/libc/nt/KernelBase/PathSearchAndQualifyA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathSearchAndQualifyA,PathSearchAndQualifyA,1174 diff --git a/libc/nt/KernelBase/PathSearchAndQualifyW.s b/libc/nt/KernelBase/PathSearchAndQualifyW.s deleted file mode 100644 index dd7ba88af..000000000 --- a/libc/nt/KernelBase/PathSearchAndQualifyW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathSearchAndQualifyW,PathSearchAndQualifyW,1175 diff --git a/libc/nt/KernelBase/PathSkipRootA.s b/libc/nt/KernelBase/PathSkipRootA.s deleted file mode 100644 index 6ef50ea43..000000000 --- a/libc/nt/KernelBase/PathSkipRootA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathSkipRootA,PathSkipRootA,1176 diff --git a/libc/nt/KernelBase/PathSkipRootW.s b/libc/nt/KernelBase/PathSkipRootW.s deleted file mode 100644 index 69425790d..000000000 --- a/libc/nt/KernelBase/PathSkipRootW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathSkipRootW,PathSkipRootW,1177 diff --git a/libc/nt/KernelBase/PathStripPathA.s b/libc/nt/KernelBase/PathStripPathA.s deleted file mode 100644 index fba21964d..000000000 --- a/libc/nt/KernelBase/PathStripPathA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathStripPathA,PathStripPathA,1178 diff --git a/libc/nt/KernelBase/PathStripPathW.s b/libc/nt/KernelBase/PathStripPathW.s deleted file mode 100644 index d86d16f43..000000000 --- a/libc/nt/KernelBase/PathStripPathW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathStripPathW,PathStripPathW,1179 diff --git a/libc/nt/KernelBase/PathStripToRootA.s b/libc/nt/KernelBase/PathStripToRootA.s deleted file mode 100644 index 247351330..000000000 --- a/libc/nt/KernelBase/PathStripToRootA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathStripToRootA,PathStripToRootA,1180 diff --git a/libc/nt/KernelBase/PathStripToRootW.s b/libc/nt/KernelBase/PathStripToRootW.s deleted file mode 100644 index daa050b8f..000000000 --- a/libc/nt/KernelBase/PathStripToRootW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathStripToRootW,PathStripToRootW,1181 diff --git a/libc/nt/KernelBase/PathUnExpandEnvStringsA.s b/libc/nt/KernelBase/PathUnExpandEnvStringsA.s deleted file mode 100644 index 7b8a6ce3e..000000000 --- a/libc/nt/KernelBase/PathUnExpandEnvStringsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathUnExpandEnvStringsA,PathUnExpandEnvStringsA,1182 diff --git a/libc/nt/KernelBase/PathUnExpandEnvStringsW.s b/libc/nt/KernelBase/PathUnExpandEnvStringsW.s deleted file mode 100644 index 926710217..000000000 --- a/libc/nt/KernelBase/PathUnExpandEnvStringsW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathUnExpandEnvStringsW,PathUnExpandEnvStringsW,1183 diff --git a/libc/nt/KernelBase/PathUnquoteSpacesA.s b/libc/nt/KernelBase/PathUnquoteSpacesA.s deleted file mode 100644 index 8739bba95..000000000 --- a/libc/nt/KernelBase/PathUnquoteSpacesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathUnquoteSpacesA,PathUnquoteSpacesA,1184 diff --git a/libc/nt/KernelBase/PathUnquoteSpacesW.s b/libc/nt/KernelBase/PathUnquoteSpacesW.s deleted file mode 100644 index ff74d4b67..000000000 --- a/libc/nt/KernelBase/PathUnquoteSpacesW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PathUnquoteSpacesW,PathUnquoteSpacesW,1185 diff --git a/libc/nt/KernelBase/PcwAddQueryItem.s b/libc/nt/KernelBase/PcwAddQueryItem.s deleted file mode 100644 index c04ada904..000000000 --- a/libc/nt/KernelBase/PcwAddQueryItem.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwAddQueryItem,PcwAddQueryItem,1186 diff --git a/libc/nt/KernelBase/PcwClearCounterSetSecurity.s b/libc/nt/KernelBase/PcwClearCounterSetSecurity.s deleted file mode 100644 index d25c6f176..000000000 --- a/libc/nt/KernelBase/PcwClearCounterSetSecurity.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwClearCounterSetSecurity,PcwClearCounterSetSecurity,1187 diff --git a/libc/nt/KernelBase/PcwCollectData.s b/libc/nt/KernelBase/PcwCollectData.s deleted file mode 100644 index 0e8e98205..000000000 --- a/libc/nt/KernelBase/PcwCollectData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwCollectData,PcwCollectData,1188 diff --git a/libc/nt/KernelBase/PcwCompleteNotification.s b/libc/nt/KernelBase/PcwCompleteNotification.s deleted file mode 100644 index 7f81cd020..000000000 --- a/libc/nt/KernelBase/PcwCompleteNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwCompleteNotification,PcwCompleteNotification,1189 diff --git a/libc/nt/KernelBase/PcwCreateNotifier.s b/libc/nt/KernelBase/PcwCreateNotifier.s deleted file mode 100644 index 0ea46e4f0..000000000 --- a/libc/nt/KernelBase/PcwCreateNotifier.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwCreateNotifier,PcwCreateNotifier,1190 diff --git a/libc/nt/KernelBase/PcwCreateQuery.s b/libc/nt/KernelBase/PcwCreateQuery.s deleted file mode 100644 index e4ac67a1d..000000000 --- a/libc/nt/KernelBase/PcwCreateQuery.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwCreateQuery,PcwCreateQuery,1191 diff --git a/libc/nt/KernelBase/PcwDisconnectCounterSet.s b/libc/nt/KernelBase/PcwDisconnectCounterSet.s deleted file mode 100644 index d6bca143d..000000000 --- a/libc/nt/KernelBase/PcwDisconnectCounterSet.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwDisconnectCounterSet,PcwDisconnectCounterSet,1192 diff --git a/libc/nt/KernelBase/PcwEnumerateInstances.s b/libc/nt/KernelBase/PcwEnumerateInstances.s deleted file mode 100644 index 0e591f4ad..000000000 --- a/libc/nt/KernelBase/PcwEnumerateInstances.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwEnumerateInstances,PcwEnumerateInstances,1193 diff --git a/libc/nt/KernelBase/PcwIsNotifierAlive.s b/libc/nt/KernelBase/PcwIsNotifierAlive.s deleted file mode 100644 index 178b74442..000000000 --- a/libc/nt/KernelBase/PcwIsNotifierAlive.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwIsNotifierAlive,PcwIsNotifierAlive,1194 diff --git a/libc/nt/KernelBase/PcwQueryCounterSetSecurity.s b/libc/nt/KernelBase/PcwQueryCounterSetSecurity.s deleted file mode 100644 index 916545d49..000000000 --- a/libc/nt/KernelBase/PcwQueryCounterSetSecurity.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwQueryCounterSetSecurity,PcwQueryCounterSetSecurity,1195 diff --git a/libc/nt/KernelBase/PcwReadNotificationData.s b/libc/nt/KernelBase/PcwReadNotificationData.s deleted file mode 100644 index 761c59448..000000000 --- a/libc/nt/KernelBase/PcwReadNotificationData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwReadNotificationData,PcwReadNotificationData,1196 diff --git a/libc/nt/KernelBase/PcwRegisterCounterSet.s b/libc/nt/KernelBase/PcwRegisterCounterSet.s deleted file mode 100644 index 7b602ce66..000000000 --- a/libc/nt/KernelBase/PcwRegisterCounterSet.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwRegisterCounterSet,PcwRegisterCounterSet,1197 diff --git a/libc/nt/KernelBase/PcwRemoveQueryItem.s b/libc/nt/KernelBase/PcwRemoveQueryItem.s deleted file mode 100644 index e51462c75..000000000 --- a/libc/nt/KernelBase/PcwRemoveQueryItem.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwRemoveQueryItem,PcwRemoveQueryItem,1198 diff --git a/libc/nt/KernelBase/PcwSendNotification.s b/libc/nt/KernelBase/PcwSendNotification.s deleted file mode 100644 index d560fa2bd..000000000 --- a/libc/nt/KernelBase/PcwSendNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwSendNotification,PcwSendNotification,1199 diff --git a/libc/nt/KernelBase/PcwSendStatelessNotification.s b/libc/nt/KernelBase/PcwSendStatelessNotification.s deleted file mode 100644 index b4ad274bf..000000000 --- a/libc/nt/KernelBase/PcwSendStatelessNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwSendStatelessNotification,PcwSendStatelessNotification,1200 diff --git a/libc/nt/KernelBase/PcwSetCounterSetSecurity.s b/libc/nt/KernelBase/PcwSetCounterSetSecurity.s deleted file mode 100644 index 815d7913f..000000000 --- a/libc/nt/KernelBase/PcwSetCounterSetSecurity.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwSetCounterSetSecurity,PcwSetCounterSetSecurity,1201 diff --git a/libc/nt/KernelBase/PcwSetQueryItemUserData.s b/libc/nt/KernelBase/PcwSetQueryItemUserData.s deleted file mode 100644 index 361715308..000000000 --- a/libc/nt/KernelBase/PcwSetQueryItemUserData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PcwSetQueryItemUserData,PcwSetQueryItemUserData,1202 diff --git a/libc/nt/KernelBase/PoolPerAppKeyStateInternal.s b/libc/nt/KernelBase/PoolPerAppKeyStateInternal.s deleted file mode 100644 index ccf4ce65d..000000000 --- a/libc/nt/KernelBase/PoolPerAppKeyStateInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PoolPerAppKeyStateInternal,PoolPerAppKeyStateInternal,1220 diff --git a/libc/nt/KernelBase/PrivCopyFileExW.s b/libc/nt/KernelBase/PrivCopyFileExW.s deleted file mode 100644 index e2336dcaf..000000000 --- a/libc/nt/KernelBase/PrivCopyFileExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PrivCopyFileExW,PrivCopyFileExW,1223 diff --git a/libc/nt/KernelBase/ProductIdFromPackageFamilyName.s b/libc/nt/KernelBase/ProductIdFromPackageFamilyName.s deleted file mode 100644 index b230f29f3..000000000 --- a/libc/nt/KernelBase/ProductIdFromPackageFamilyName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ProductIdFromPackageFamilyName,ProductIdFromPackageFamilyName,1227 diff --git a/libc/nt/KernelBase/PsmCreateKey.s b/libc/nt/KernelBase/PsmCreateKey.s deleted file mode 100644 index 7c668abf1..000000000 --- a/libc/nt/KernelBase/PsmCreateKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmCreateKey,PsmCreateKey,1228 diff --git a/libc/nt/KernelBase/PsmCreateKeyWithDynamicId.s b/libc/nt/KernelBase/PsmCreateKeyWithDynamicId.s deleted file mode 100644 index f095da7b2..000000000 --- a/libc/nt/KernelBase/PsmCreateKeyWithDynamicId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmCreateKeyWithDynamicId,PsmCreateKeyWithDynamicId,1229 diff --git a/libc/nt/KernelBase/PsmEqualApplication.s b/libc/nt/KernelBase/PsmEqualApplication.s deleted file mode 100644 index 771488026..000000000 --- a/libc/nt/KernelBase/PsmEqualApplication.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmEqualApplication,PsmEqualApplication,1230 diff --git a/libc/nt/KernelBase/PsmEqualPackage.s b/libc/nt/KernelBase/PsmEqualPackage.s deleted file mode 100644 index 4932841c2..000000000 --- a/libc/nt/KernelBase/PsmEqualPackage.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmEqualPackage,PsmEqualPackage,1231 diff --git a/libc/nt/KernelBase/PsmGetApplicationNameFromKey.s b/libc/nt/KernelBase/PsmGetApplicationNameFromKey.s deleted file mode 100644 index c0267689e..000000000 --- a/libc/nt/KernelBase/PsmGetApplicationNameFromKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmGetApplicationNameFromKey,PsmGetApplicationNameFromKey,1232 diff --git a/libc/nt/KernelBase/PsmGetKeyFromProcess.s b/libc/nt/KernelBase/PsmGetKeyFromProcess.s deleted file mode 100644 index 9640380fc..000000000 --- a/libc/nt/KernelBase/PsmGetKeyFromProcess.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmGetKeyFromProcess,PsmGetKeyFromProcess,1233 diff --git a/libc/nt/KernelBase/PsmGetKeyFromToken.s b/libc/nt/KernelBase/PsmGetKeyFromToken.s deleted file mode 100644 index 4b2b68651..000000000 --- a/libc/nt/KernelBase/PsmGetKeyFromToken.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmGetKeyFromToken,PsmGetKeyFromToken,1234 diff --git a/libc/nt/KernelBase/PsmGetPackageFullNameFromKey.s b/libc/nt/KernelBase/PsmGetPackageFullNameFromKey.s deleted file mode 100644 index b5501481c..000000000 --- a/libc/nt/KernelBase/PsmGetPackageFullNameFromKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmGetPackageFullNameFromKey,PsmGetPackageFullNameFromKey,1235 diff --git a/libc/nt/KernelBase/PsmIsChildKey.s b/libc/nt/KernelBase/PsmIsChildKey.s deleted file mode 100644 index 6ceb58050..000000000 --- a/libc/nt/KernelBase/PsmIsChildKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmIsChildKey,PsmIsChildKey,1236 diff --git a/libc/nt/KernelBase/PsmIsDynamicKey.s b/libc/nt/KernelBase/PsmIsDynamicKey.s deleted file mode 100644 index a8eb81d41..000000000 --- a/libc/nt/KernelBase/PsmIsDynamicKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmIsDynamicKey,PsmIsDynamicKey,1237 diff --git a/libc/nt/KernelBase/PsmIsValidKey.s b/libc/nt/KernelBase/PsmIsValidKey.s deleted file mode 100644 index 4b52df272..000000000 --- a/libc/nt/KernelBase/PsmIsValidKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PsmIsValidKey,PsmIsValidKey,1238 diff --git a/libc/nt/KernelBase/PublishStateChangeNotification.s b/libc/nt/KernelBase/PublishStateChangeNotification.s deleted file mode 100644 index 4a1333082..000000000 --- a/libc/nt/KernelBase/PublishStateChangeNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_PublishStateChangeNotification,PublishStateChangeNotification,1249 diff --git a/libc/nt/KernelBase/QISearch.s b/libc/nt/KernelBase/QISearch.s deleted file mode 100644 index 4d6f5043d..000000000 --- a/libc/nt/KernelBase/QISearch.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QISearch,QISearch,1252 diff --git a/libc/nt/KernelBase/QueryAuxiliaryCounterFrequency.s b/libc/nt/KernelBase/QueryAuxiliaryCounterFrequency.s deleted file mode 100644 index 3b0fc9125..000000000 --- a/libc/nt/KernelBase/QueryAuxiliaryCounterFrequency.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryAuxiliaryCounterFrequency,QueryAuxiliaryCounterFrequency,1255 diff --git a/libc/nt/KernelBase/QueryInterruptTime.s b/libc/nt/KernelBase/QueryInterruptTime.s deleted file mode 100644 index f0ca82fa0..000000000 --- a/libc/nt/KernelBase/QueryInterruptTime.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryInterruptTime,QueryInterruptTime,1262 diff --git a/libc/nt/KernelBase/QueryInterruptTimePrecise.s b/libc/nt/KernelBase/QueryInterruptTimePrecise.s deleted file mode 100644 index a6435a9f0..000000000 --- a/libc/nt/KernelBase/QueryInterruptTimePrecise.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryInterruptTimePrecise,QueryInterruptTimePrecise,1263 diff --git a/libc/nt/KernelBase/QueryOptionalDelayLoadedAPI.s b/libc/nt/KernelBase/QueryOptionalDelayLoadedAPI.s deleted file mode 100644 index 014872469..000000000 --- a/libc/nt/KernelBase/QueryOptionalDelayLoadedAPI.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryOptionalDelayLoadedAPI,QueryOptionalDelayLoadedAPI,1265 diff --git a/libc/nt/KernelBase/QueryStateAtomValueInfo.s b/libc/nt/KernelBase/QueryStateAtomValueInfo.s deleted file mode 100644 index f180978b4..000000000 --- a/libc/nt/KernelBase/QueryStateAtomValueInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryStateAtomValueInfo,QueryStateAtomValueInfo,1272 diff --git a/libc/nt/KernelBase/QueryStateContainerCreatedNew.s b/libc/nt/KernelBase/QueryStateContainerCreatedNew.s deleted file mode 100644 index 9640f64c2..000000000 --- a/libc/nt/KernelBase/QueryStateContainerCreatedNew.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryStateContainerCreatedNew,QueryStateContainerCreatedNew,1273 diff --git a/libc/nt/KernelBase/QueryStateContainerItemInfo.s b/libc/nt/KernelBase/QueryStateContainerItemInfo.s deleted file mode 100644 index a4e3c8a67..000000000 --- a/libc/nt/KernelBase/QueryStateContainerItemInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryStateContainerItemInfo,QueryStateContainerItemInfo,1274 diff --git a/libc/nt/KernelBase/QueryUnbiasedInterruptTimePrecise.s b/libc/nt/KernelBase/QueryUnbiasedInterruptTimePrecise.s deleted file mode 100644 index 7e0ae29f2..000000000 --- a/libc/nt/KernelBase/QueryUnbiasedInterruptTimePrecise.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryUnbiasedInterruptTimePrecise,QueryUnbiasedInterruptTimePrecise,1278 diff --git a/libc/nt/KernelBase/QueryVirtualMemoryInformation.s b/libc/nt/KernelBase/QueryVirtualMemoryInformation.s deleted file mode 100644 index 60e2cfe9c..000000000 --- a/libc/nt/KernelBase/QueryVirtualMemoryInformation.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryVirtualMemoryInformation,QueryVirtualMemoryInformation,1279 diff --git a/libc/nt/KernelBase/QueryWorkingSet.s b/libc/nt/KernelBase/QueryWorkingSet.s deleted file mode 100644 index 33c81e0e8..000000000 --- a/libc/nt/KernelBase/QueryWorkingSet.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryWorkingSet,QueryWorkingSet,1280 diff --git a/libc/nt/KernelBase/QueryWorkingSetEx.s b/libc/nt/KernelBase/QueryWorkingSetEx.s deleted file mode 100644 index 8d4a394b0..000000000 --- a/libc/nt/KernelBase/QueryWorkingSetEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QueryWorkingSetEx,QueryWorkingSetEx,1281 diff --git a/libc/nt/KernelBase/QuirkGetData.s b/libc/nt/KernelBase/QuirkGetData.s deleted file mode 100644 index 915f8a77e..000000000 --- a/libc/nt/KernelBase/QuirkGetData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkGetData,QuirkGetData,1284 diff --git a/libc/nt/KernelBase/QuirkGetData2.s b/libc/nt/KernelBase/QuirkGetData2.s deleted file mode 100644 index fc9ea2464..000000000 --- a/libc/nt/KernelBase/QuirkGetData2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkGetData2,QuirkGetData2,1285 diff --git a/libc/nt/KernelBase/QuirkIsEnabled.s b/libc/nt/KernelBase/QuirkIsEnabled.s deleted file mode 100644 index 9a1775fd2..000000000 --- a/libc/nt/KernelBase/QuirkIsEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkIsEnabled,QuirkIsEnabled,1286 diff --git a/libc/nt/KernelBase/QuirkIsEnabled2.s b/libc/nt/KernelBase/QuirkIsEnabled2.s deleted file mode 100644 index 5dbcf1dee..000000000 --- a/libc/nt/KernelBase/QuirkIsEnabled2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkIsEnabled2,QuirkIsEnabled2,1287 diff --git a/libc/nt/KernelBase/QuirkIsEnabled3.s b/libc/nt/KernelBase/QuirkIsEnabled3.s deleted file mode 100644 index d4bcc3f16..000000000 --- a/libc/nt/KernelBase/QuirkIsEnabled3.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkIsEnabled3,QuirkIsEnabled3,1288 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForPackage.s b/libc/nt/KernelBase/QuirkIsEnabledForPackage.s deleted file mode 100644 index 8497faff2..000000000 --- a/libc/nt/KernelBase/QuirkIsEnabledForPackage.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkIsEnabledForPackage,QuirkIsEnabledForPackage,1289 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForPackage2.s b/libc/nt/KernelBase/QuirkIsEnabledForPackage2.s deleted file mode 100644 index 503be5734..000000000 --- a/libc/nt/KernelBase/QuirkIsEnabledForPackage2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkIsEnabledForPackage2,QuirkIsEnabledForPackage2,1290 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForPackage3.s b/libc/nt/KernelBase/QuirkIsEnabledForPackage3.s deleted file mode 100644 index d0bc9b1c3..000000000 --- a/libc/nt/KernelBase/QuirkIsEnabledForPackage3.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkIsEnabledForPackage3,QuirkIsEnabledForPackage3,1291 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForPackage4.s b/libc/nt/KernelBase/QuirkIsEnabledForPackage4.s deleted file mode 100644 index 49bbd9d3a..000000000 --- a/libc/nt/KernelBase/QuirkIsEnabledForPackage4.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkIsEnabledForPackage4,QuirkIsEnabledForPackage4,1292 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForProcess.s b/libc/nt/KernelBase/QuirkIsEnabledForProcess.s deleted file mode 100644 index 084ee5748..000000000 --- a/libc/nt/KernelBase/QuirkIsEnabledForProcess.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_QuirkIsEnabledForProcess,QuirkIsEnabledForProcess,1293 diff --git a/libc/nt/KernelBase/RaiseCustomSystemEventTrigger.s b/libc/nt/KernelBase/RaiseCustomSystemEventTrigger.s deleted file mode 100644 index 3b98ce6cf..000000000 --- a/libc/nt/KernelBase/RaiseCustomSystemEventTrigger.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RaiseCustomSystemEventTrigger,RaiseCustomSystemEventTrigger,1294 diff --git a/libc/nt/KernelBase/ReadConsoleInputExA.s b/libc/nt/KernelBase/ReadConsoleInputExA.s deleted file mode 100644 index 68e41d030..000000000 --- a/libc/nt/KernelBase/ReadConsoleInputExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ReadConsoleInputExA,ReadConsoleInputExA,1300 diff --git a/libc/nt/KernelBase/ReadConsoleInputExW.s b/libc/nt/KernelBase/ReadConsoleInputExW.s deleted file mode 100644 index 69b2f5e7d..000000000 --- a/libc/nt/KernelBase/ReadConsoleInputExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ReadConsoleInputExW,ReadConsoleInputExW,1301 diff --git a/libc/nt/KernelBase/ReadDirectoryChangesExW.s b/libc/nt/KernelBase/ReadDirectoryChangesExW.s deleted file mode 100644 index e5dbc71ae..000000000 --- a/libc/nt/KernelBase/ReadDirectoryChangesExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ReadDirectoryChangesExW,ReadDirectoryChangesExW,1309 diff --git a/libc/nt/KernelBase/ReadStateAtomValue.s b/libc/nt/KernelBase/ReadStateAtomValue.s deleted file mode 100644 index fe00d978e..000000000 --- a/libc/nt/KernelBase/ReadStateAtomValue.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ReadStateAtomValue,ReadStateAtomValue,1315 diff --git a/libc/nt/KernelBase/ReadStateContainerValue.s b/libc/nt/KernelBase/ReadStateContainerValue.s deleted file mode 100644 index 73cd0c989..000000000 --- a/libc/nt/KernelBase/ReadStateContainerValue.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ReadStateContainerValue,ReadStateContainerValue,1316 diff --git a/libc/nt/KernelBase/RefreshPackageInfo.s b/libc/nt/KernelBase/RefreshPackageInfo.s deleted file mode 100644 index aa7fbb238..000000000 --- a/libc/nt/KernelBase/RefreshPackageInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RefreshPackageInfo,RefreshPackageInfo,1318 diff --git a/libc/nt/KernelBase/RefreshPolicyExInternal.s b/libc/nt/KernelBase/RefreshPolicyExInternal.s deleted file mode 100644 index e970e5902..000000000 --- a/libc/nt/KernelBase/RefreshPolicyExInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RefreshPolicyExInternal,RefreshPolicyExInternal,1319 diff --git a/libc/nt/KernelBase/RefreshPolicyInternal.s b/libc/nt/KernelBase/RefreshPolicyInternal.s deleted file mode 100644 index b0c417162..000000000 --- a/libc/nt/KernelBase/RefreshPolicyInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RefreshPolicyInternal,RefreshPolicyInternal,1320 diff --git a/libc/nt/KernelBase/RegCreateKeyExInternalA.s b/libc/nt/KernelBase/RegCreateKeyExInternalA.s deleted file mode 100644 index 3c194df39..000000000 --- a/libc/nt/KernelBase/RegCreateKeyExInternalA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegCreateKeyExInternalA,RegCreateKeyExInternalA,1324 diff --git a/libc/nt/KernelBase/RegCreateKeyExInternalW.s b/libc/nt/KernelBase/RegCreateKeyExInternalW.s deleted file mode 100644 index 2d3add29c..000000000 --- a/libc/nt/KernelBase/RegCreateKeyExInternalW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegCreateKeyExInternalW,RegCreateKeyExInternalW,1325 diff --git a/libc/nt/KernelBase/RegDeleteKeyExInternalA.s b/libc/nt/KernelBase/RegDeleteKeyExInternalA.s deleted file mode 100644 index 4bfefb2f9..000000000 --- a/libc/nt/KernelBase/RegDeleteKeyExInternalA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegDeleteKeyExInternalA,RegDeleteKeyExInternalA,1328 diff --git a/libc/nt/KernelBase/RegDeleteKeyExInternalW.s b/libc/nt/KernelBase/RegDeleteKeyExInternalW.s deleted file mode 100644 index b7d6b63df..000000000 --- a/libc/nt/KernelBase/RegDeleteKeyExInternalW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegDeleteKeyExInternalW,RegDeleteKeyExInternalW,1329 diff --git a/libc/nt/KernelBase/RegKrnGetAppKeyEventAddressInternal.s b/libc/nt/KernelBase/RegKrnGetAppKeyEventAddressInternal.s deleted file mode 100644 index 2e5d58ca7..000000000 --- a/libc/nt/KernelBase/RegKrnGetAppKeyEventAddressInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegKrnGetAppKeyEventAddressInternal,RegKrnGetAppKeyEventAddressInternal,1346 diff --git a/libc/nt/KernelBase/RegKrnGetAppKeyLoaded.s b/libc/nt/KernelBase/RegKrnGetAppKeyLoaded.s deleted file mode 100644 index 08b8666ee..000000000 --- a/libc/nt/KernelBase/RegKrnGetAppKeyLoaded.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegKrnGetAppKeyLoaded,RegKrnGetAppKeyLoaded,1347 diff --git a/libc/nt/KernelBase/RegKrnGetClassesEnumTableAddressInternal.s b/libc/nt/KernelBase/RegKrnGetClassesEnumTableAddressInternal.s deleted file mode 100644 index bc82c45de..000000000 --- a/libc/nt/KernelBase/RegKrnGetClassesEnumTableAddressInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegKrnGetClassesEnumTableAddressInternal,RegKrnGetClassesEnumTableAddressInternal,1348 diff --git a/libc/nt/KernelBase/RegKrnGetHKEY_ClassesRootAddress.s b/libc/nt/KernelBase/RegKrnGetHKEY_ClassesRootAddress.s deleted file mode 100644 index 6fb7e89a0..000000000 --- a/libc/nt/KernelBase/RegKrnGetHKEY_ClassesRootAddress.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegKrnGetHKEY_ClassesRootAddress,RegKrnGetHKEY_ClassesRootAddress,1349 diff --git a/libc/nt/KernelBase/RegKrnGetTermsrvRegistryExtensionFlags.s b/libc/nt/KernelBase/RegKrnGetTermsrvRegistryExtensionFlags.s deleted file mode 100644 index 270e0d5b3..000000000 --- a/libc/nt/KernelBase/RegKrnGetTermsrvRegistryExtensionFlags.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegKrnGetTermsrvRegistryExtensionFlags,RegKrnGetTermsrvRegistryExtensionFlags,1350 diff --git a/libc/nt/KernelBase/RegKrnResetAppKeyLoaded.s b/libc/nt/KernelBase/RegKrnResetAppKeyLoaded.s deleted file mode 100644 index 935a53ecd..000000000 --- a/libc/nt/KernelBase/RegKrnResetAppKeyLoaded.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegKrnResetAppKeyLoaded,RegKrnResetAppKeyLoaded,1351 diff --git a/libc/nt/KernelBase/RegKrnSetDllHasThreadStateGlobal.s b/libc/nt/KernelBase/RegKrnSetDllHasThreadStateGlobal.s deleted file mode 100644 index e88232920..000000000 --- a/libc/nt/KernelBase/RegKrnSetDllHasThreadStateGlobal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegKrnSetDllHasThreadStateGlobal,RegKrnSetDllHasThreadStateGlobal,1352 diff --git a/libc/nt/KernelBase/RegKrnSetTermsrvRegistryExtensionFlags.s b/libc/nt/KernelBase/RegKrnSetTermsrvRegistryExtensionFlags.s deleted file mode 100644 index 9dd7ec5f6..000000000 --- a/libc/nt/KernelBase/RegKrnSetTermsrvRegistryExtensionFlags.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegKrnSetTermsrvRegistryExtensionFlags,RegKrnSetTermsrvRegistryExtensionFlags,1353 diff --git a/libc/nt/KernelBase/RegOpenKeyExInternalA.s b/libc/nt/KernelBase/RegOpenKeyExInternalA.s deleted file mode 100644 index 6b7fdbba1..000000000 --- a/libc/nt/KernelBase/RegOpenKeyExInternalA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegOpenKeyExInternalA,RegOpenKeyExInternalA,1363 diff --git a/libc/nt/KernelBase/RegOpenKeyExInternalW.s b/libc/nt/KernelBase/RegOpenKeyExInternalW.s deleted file mode 100644 index a4dd41390..000000000 --- a/libc/nt/KernelBase/RegOpenKeyExInternalW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegOpenKeyExInternalW,RegOpenKeyExInternalW,1364 diff --git a/libc/nt/KernelBase/RegisterGPNotificationInternal.s b/libc/nt/KernelBase/RegisterGPNotificationInternal.s deleted file mode 100644 index e4db4c267..000000000 --- a/libc/nt/KernelBase/RegisterGPNotificationInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegisterGPNotificationInternal,RegisterGPNotificationInternal,1385 diff --git a/libc/nt/KernelBase/RegisterStateChangeNotification.s b/libc/nt/KernelBase/RegisterStateChangeNotification.s deleted file mode 100644 index 5ffec23b7..000000000 --- a/libc/nt/KernelBase/RegisterStateChangeNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegisterStateChangeNotification,RegisterStateChangeNotification,1386 diff --git a/libc/nt/KernelBase/RegisterStateLock.s b/libc/nt/KernelBase/RegisterStateLock.s deleted file mode 100644 index 51e96a35d..000000000 --- a/libc/nt/KernelBase/RegisterStateLock.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegisterStateLock,RegisterStateLock,1387 diff --git a/libc/nt/KernelBase/RegisterWaitForSingleObjectEx.s b/libc/nt/KernelBase/RegisterWaitForSingleObjectEx.s deleted file mode 100644 index 474364ba2..000000000 --- a/libc/nt/KernelBase/RegisterWaitForSingleObjectEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RegisterWaitForSingleObjectEx,RegisterWaitForSingleObjectEx,1389 diff --git a/libc/nt/KernelBase/ReleaseStateLock.s b/libc/nt/KernelBase/ReleaseStateLock.s deleted file mode 100644 index 1cffda1a2..000000000 --- a/libc/nt/KernelBase/ReleaseStateLock.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ReleaseStateLock,ReleaseStateLock,1397 diff --git a/libc/nt/KernelBase/RemapPredefinedHandleInternal.s b/libc/nt/KernelBase/RemapPredefinedHandleInternal.s deleted file mode 100644 index fe8929b6d..000000000 --- a/libc/nt/KernelBase/RemapPredefinedHandleInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RemapPredefinedHandleInternal,RemapPredefinedHandleInternal,1398 diff --git a/libc/nt/KernelBase/RemoveExtensionProgIds.s b/libc/nt/KernelBase/RemoveExtensionProgIds.s deleted file mode 100644 index 2bfba73c9..000000000 --- a/libc/nt/KernelBase/RemoveExtensionProgIds.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RemoveExtensionProgIds,RemoveExtensionProgIds,1402 diff --git a/libc/nt/KernelBase/RemovePackageFromFamilyXref.s b/libc/nt/KernelBase/RemovePackageFromFamilyXref.s deleted file mode 100644 index 2ea0d0a66..000000000 --- a/libc/nt/KernelBase/RemovePackageFromFamilyXref.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RemovePackageFromFamilyXref,RemovePackageFromFamilyXref,1403 diff --git a/libc/nt/KernelBase/RemovePackageStatus.s b/libc/nt/KernelBase/RemovePackageStatus.s deleted file mode 100644 index 12191c1c4..000000000 --- a/libc/nt/KernelBase/RemovePackageStatus.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RemovePackageStatus,RemovePackageStatus,1404 diff --git a/libc/nt/KernelBase/RemovePackageStatusForUser.s b/libc/nt/KernelBase/RemovePackageStatusForUser.s deleted file mode 100644 index f2ab94efb..000000000 --- a/libc/nt/KernelBase/RemovePackageStatusForUser.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RemovePackageStatusForUser,RemovePackageStatusForUser,1405 diff --git a/libc/nt/KernelBase/ReplaceFileExInternal.s b/libc/nt/KernelBase/ReplaceFileExInternal.s deleted file mode 100644 index f5dcbd369..000000000 --- a/libc/nt/KernelBase/ReplaceFileExInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ReplaceFileExInternal,ReplaceFileExInternal,1408 diff --git a/libc/nt/KernelBase/ResetState.s b/libc/nt/KernelBase/ResetState.s deleted file mode 100644 index 45805d4bb..000000000 --- a/libc/nt/KernelBase/ResetState.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_ResetState,ResetState,1411 diff --git a/libc/nt/KernelBase/RsopLoggingEnabledInternal.s b/libc/nt/KernelBase/RsopLoggingEnabledInternal.s deleted file mode 100644 index ae0378b71..000000000 --- a/libc/nt/KernelBase/RsopLoggingEnabledInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_RsopLoggingEnabledInternal,RsopLoggingEnabledInternal,1419 diff --git a/libc/nt/KernelBase/SHCoCreateInstance.s b/libc/nt/KernelBase/SHCoCreateInstance.s deleted file mode 100644 index 05f20004e..000000000 --- a/libc/nt/KernelBase/SHCoCreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHCoCreateInstance,SHCoCreateInstance,1420 diff --git a/libc/nt/KernelBase/SHExpandEnvironmentStringsA.s b/libc/nt/KernelBase/SHExpandEnvironmentStringsA.s deleted file mode 100644 index e9c4f6604..000000000 --- a/libc/nt/KernelBase/SHExpandEnvironmentStringsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHExpandEnvironmentStringsA,SHExpandEnvironmentStringsA,1421 diff --git a/libc/nt/KernelBase/SHExpandEnvironmentStringsW.s b/libc/nt/KernelBase/SHExpandEnvironmentStringsW.s deleted file mode 100644 index 991fec28a..000000000 --- a/libc/nt/KernelBase/SHExpandEnvironmentStringsW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHExpandEnvironmentStringsW,SHExpandEnvironmentStringsW,1422 diff --git a/libc/nt/KernelBase/SHLoadIndirectString.s b/libc/nt/KernelBase/SHLoadIndirectString.s deleted file mode 100644 index 665c3e010..000000000 --- a/libc/nt/KernelBase/SHLoadIndirectString.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHLoadIndirectString,SHLoadIndirectString,1423 diff --git a/libc/nt/KernelBase/SHLoadIndirectStringInternal.s b/libc/nt/KernelBase/SHLoadIndirectStringInternal.s deleted file mode 100644 index b04937d8d..000000000 --- a/libc/nt/KernelBase/SHLoadIndirectStringInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHLoadIndirectStringInternal,SHLoadIndirectStringInternal,1424 diff --git a/libc/nt/KernelBase/SHRegCloseUSKey.s b/libc/nt/KernelBase/SHRegCloseUSKey.s deleted file mode 100644 index 75baaa606..000000000 --- a/libc/nt/KernelBase/SHRegCloseUSKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegCloseUSKey,SHRegCloseUSKey,1425 diff --git a/libc/nt/KernelBase/SHRegCreateUSKeyA.s b/libc/nt/KernelBase/SHRegCreateUSKeyA.s deleted file mode 100644 index 32f4fb738..000000000 --- a/libc/nt/KernelBase/SHRegCreateUSKeyA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegCreateUSKeyA,SHRegCreateUSKeyA,1426 diff --git a/libc/nt/KernelBase/SHRegCreateUSKeyW.s b/libc/nt/KernelBase/SHRegCreateUSKeyW.s deleted file mode 100644 index b3a7015f2..000000000 --- a/libc/nt/KernelBase/SHRegCreateUSKeyW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegCreateUSKeyW,SHRegCreateUSKeyW,1427 diff --git a/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyA.s b/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyA.s deleted file mode 100644 index 9cbf12e0f..000000000 --- a/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegDeleteEmptyUSKeyA,SHRegDeleteEmptyUSKeyA,1428 diff --git a/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyW.s b/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyW.s deleted file mode 100644 index c5eff69b5..000000000 --- a/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegDeleteEmptyUSKeyW,SHRegDeleteEmptyUSKeyW,1429 diff --git a/libc/nt/KernelBase/SHRegDeleteUSValueA.s b/libc/nt/KernelBase/SHRegDeleteUSValueA.s deleted file mode 100644 index 9e9b8c933..000000000 --- a/libc/nt/KernelBase/SHRegDeleteUSValueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegDeleteUSValueA,SHRegDeleteUSValueA,1430 diff --git a/libc/nt/KernelBase/SHRegDeleteUSValueW.s b/libc/nt/KernelBase/SHRegDeleteUSValueW.s deleted file mode 100644 index 015c4db79..000000000 --- a/libc/nt/KernelBase/SHRegDeleteUSValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegDeleteUSValueW,SHRegDeleteUSValueW,1431 diff --git a/libc/nt/KernelBase/SHRegEnumUSKeyA.s b/libc/nt/KernelBase/SHRegEnumUSKeyA.s deleted file mode 100644 index 932be409b..000000000 --- a/libc/nt/KernelBase/SHRegEnumUSKeyA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegEnumUSKeyA,SHRegEnumUSKeyA,1432 diff --git a/libc/nt/KernelBase/SHRegEnumUSKeyW.s b/libc/nt/KernelBase/SHRegEnumUSKeyW.s deleted file mode 100644 index 3ea659a7a..000000000 --- a/libc/nt/KernelBase/SHRegEnumUSKeyW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegEnumUSKeyW,SHRegEnumUSKeyW,1433 diff --git a/libc/nt/KernelBase/SHRegEnumUSValueA.s b/libc/nt/KernelBase/SHRegEnumUSValueA.s deleted file mode 100644 index 28da79b3e..000000000 --- a/libc/nt/KernelBase/SHRegEnumUSValueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegEnumUSValueA,SHRegEnumUSValueA,1434 diff --git a/libc/nt/KernelBase/SHRegEnumUSValueW.s b/libc/nt/KernelBase/SHRegEnumUSValueW.s deleted file mode 100644 index a64d3dbfc..000000000 --- a/libc/nt/KernelBase/SHRegEnumUSValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegEnumUSValueW,SHRegEnumUSValueW,1435 diff --git a/libc/nt/KernelBase/SHRegGetBoolUSValueA.s b/libc/nt/KernelBase/SHRegGetBoolUSValueA.s deleted file mode 100644 index 41bbc03c0..000000000 --- a/libc/nt/KernelBase/SHRegGetBoolUSValueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegGetBoolUSValueA,SHRegGetBoolUSValueA,1436 diff --git a/libc/nt/KernelBase/SHRegGetBoolUSValueW.s b/libc/nt/KernelBase/SHRegGetBoolUSValueW.s deleted file mode 100644 index c2f54755b..000000000 --- a/libc/nt/KernelBase/SHRegGetBoolUSValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegGetBoolUSValueW,SHRegGetBoolUSValueW,1437 diff --git a/libc/nt/KernelBase/SHRegGetUSValueA.s b/libc/nt/KernelBase/SHRegGetUSValueA.s deleted file mode 100644 index 59eef14ae..000000000 --- a/libc/nt/KernelBase/SHRegGetUSValueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegGetUSValueA,SHRegGetUSValueA,1438 diff --git a/libc/nt/KernelBase/SHRegGetUSValueW.s b/libc/nt/KernelBase/SHRegGetUSValueW.s deleted file mode 100644 index 1d3c280db..000000000 --- a/libc/nt/KernelBase/SHRegGetUSValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegGetUSValueW,SHRegGetUSValueW,1439 diff --git a/libc/nt/KernelBase/SHRegOpenUSKeyA.s b/libc/nt/KernelBase/SHRegOpenUSKeyA.s deleted file mode 100644 index 55437e355..000000000 --- a/libc/nt/KernelBase/SHRegOpenUSKeyA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegOpenUSKeyA,SHRegOpenUSKeyA,1440 diff --git a/libc/nt/KernelBase/SHRegOpenUSKeyW.s b/libc/nt/KernelBase/SHRegOpenUSKeyW.s deleted file mode 100644 index 1bd8c6ee7..000000000 --- a/libc/nt/KernelBase/SHRegOpenUSKeyW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegOpenUSKeyW,SHRegOpenUSKeyW,1441 diff --git a/libc/nt/KernelBase/SHRegQueryInfoUSKeyA.s b/libc/nt/KernelBase/SHRegQueryInfoUSKeyA.s deleted file mode 100644 index 88608e81b..000000000 --- a/libc/nt/KernelBase/SHRegQueryInfoUSKeyA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegQueryInfoUSKeyA,SHRegQueryInfoUSKeyA,1442 diff --git a/libc/nt/KernelBase/SHRegQueryInfoUSKeyW.s b/libc/nt/KernelBase/SHRegQueryInfoUSKeyW.s deleted file mode 100644 index b798d5916..000000000 --- a/libc/nt/KernelBase/SHRegQueryInfoUSKeyW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegQueryInfoUSKeyW,SHRegQueryInfoUSKeyW,1443 diff --git a/libc/nt/KernelBase/SHRegQueryUSValueA.s b/libc/nt/KernelBase/SHRegQueryUSValueA.s deleted file mode 100644 index 159fcb383..000000000 --- a/libc/nt/KernelBase/SHRegQueryUSValueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegQueryUSValueA,SHRegQueryUSValueA,1444 diff --git a/libc/nt/KernelBase/SHRegQueryUSValueW.s b/libc/nt/KernelBase/SHRegQueryUSValueW.s deleted file mode 100644 index e3e420850..000000000 --- a/libc/nt/KernelBase/SHRegQueryUSValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegQueryUSValueW,SHRegQueryUSValueW,1445 diff --git a/libc/nt/KernelBase/SHRegSetUSValueA.s b/libc/nt/KernelBase/SHRegSetUSValueA.s deleted file mode 100644 index ed18e7f61..000000000 --- a/libc/nt/KernelBase/SHRegSetUSValueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegSetUSValueA,SHRegSetUSValueA,1446 diff --git a/libc/nt/KernelBase/SHRegSetUSValueW.s b/libc/nt/KernelBase/SHRegSetUSValueW.s deleted file mode 100644 index e77831fda..000000000 --- a/libc/nt/KernelBase/SHRegSetUSValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegSetUSValueW,SHRegSetUSValueW,1447 diff --git a/libc/nt/KernelBase/SHRegWriteUSValueA.s b/libc/nt/KernelBase/SHRegWriteUSValueA.s deleted file mode 100644 index d35efa234..000000000 --- a/libc/nt/KernelBase/SHRegWriteUSValueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegWriteUSValueA,SHRegWriteUSValueA,1448 diff --git a/libc/nt/KernelBase/SHRegWriteUSValueW.s b/libc/nt/KernelBase/SHRegWriteUSValueW.s deleted file mode 100644 index f9b3763e6..000000000 --- a/libc/nt/KernelBase/SHRegWriteUSValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHRegWriteUSValueW,SHRegWriteUSValueW,1449 diff --git a/libc/nt/KernelBase/SHTruncateString.s b/libc/nt/KernelBase/SHTruncateString.s deleted file mode 100644 index c671a573d..000000000 --- a/libc/nt/KernelBase/SHTruncateString.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SHTruncateString,SHTruncateString,1450 diff --git a/libc/nt/KernelBase/SaveAlternatePackageRootPath.s b/libc/nt/KernelBase/SaveAlternatePackageRootPath.s deleted file mode 100644 index d86459a9d..000000000 --- a/libc/nt/KernelBase/SaveAlternatePackageRootPath.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SaveAlternatePackageRootPath,SaveAlternatePackageRootPath,1451 diff --git a/libc/nt/KernelBase/SaveStateRootFolderPath.s b/libc/nt/KernelBase/SaveStateRootFolderPath.s deleted file mode 100644 index bed7d45a8..000000000 --- a/libc/nt/KernelBase/SaveStateRootFolderPath.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SaveStateRootFolderPath,SaveStateRootFolderPath,1452 diff --git a/libc/nt/KernelBase/SetCachedSigningLevel.s b/libc/nt/KernelBase/SetCachedSigningLevel.s deleted file mode 100644 index 9835881a4..000000000 --- a/libc/nt/KernelBase/SetCachedSigningLevel.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetCachedSigningLevel,SetCachedSigningLevel,1458 diff --git a/libc/nt/KernelBase/SetClientDynamicTimeZoneInformation.s b/libc/nt/KernelBase/SetClientDynamicTimeZoneInformation.s deleted file mode 100644 index fd64e510b..000000000 --- a/libc/nt/KernelBase/SetClientDynamicTimeZoneInformation.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetClientDynamicTimeZoneInformation,SetClientDynamicTimeZoneInformation,1460 diff --git a/libc/nt/KernelBase/SetClientTimeZoneInformation.s b/libc/nt/KernelBase/SetClientTimeZoneInformation.s deleted file mode 100644 index 724d1e468..000000000 --- a/libc/nt/KernelBase/SetClientTimeZoneInformation.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetClientTimeZoneInformation,SetClientTimeZoneInformation,1461 diff --git a/libc/nt/KernelBase/SetComputerNameEx2W.s b/libc/nt/KernelBase/SetComputerNameEx2W.s deleted file mode 100644 index f96bfc2da..000000000 --- a/libc/nt/KernelBase/SetComputerNameEx2W.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetComputerNameEx2W,SetComputerNameEx2W,1468 diff --git a/libc/nt/KernelBase/SetConsoleInputExeNameA.s b/libc/nt/KernelBase/SetConsoleInputExeNameA.s deleted file mode 100644 index 4bbaa575c..000000000 --- a/libc/nt/KernelBase/SetConsoleInputExeNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetConsoleInputExeNameA,SetConsoleInputExeNameA,1479 diff --git a/libc/nt/KernelBase/SetConsoleInputExeNameW.s b/libc/nt/KernelBase/SetConsoleInputExeNameW.s deleted file mode 100644 index 0713e9342..000000000 --- a/libc/nt/KernelBase/SetConsoleInputExeNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetConsoleInputExeNameW,SetConsoleInputExeNameW,1480 diff --git a/libc/nt/KernelBase/SetConsoleNumberOfCommandsA.s b/libc/nt/KernelBase/SetConsoleNumberOfCommandsA.s deleted file mode 100644 index bd4a5b9c2..000000000 --- a/libc/nt/KernelBase/SetConsoleNumberOfCommandsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetConsoleNumberOfCommandsA,SetConsoleNumberOfCommandsA,1482 diff --git a/libc/nt/KernelBase/SetConsoleNumberOfCommandsW.s b/libc/nt/KernelBase/SetConsoleNumberOfCommandsW.s deleted file mode 100644 index 68c0eb596..000000000 --- a/libc/nt/KernelBase/SetConsoleNumberOfCommandsW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetConsoleNumberOfCommandsW,SetConsoleNumberOfCommandsW,1483 diff --git a/libc/nt/KernelBase/SetEnvironmentStringsW.s b/libc/nt/KernelBase/SetEnvironmentStringsW.s deleted file mode 100644 index 93ca27dbc..000000000 --- a/libc/nt/KernelBase/SetEnvironmentStringsW.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetEnvironmentStringsW,SetEnvironmentStringsW,1498 - - .text.windows -SetEnvironmentStrings: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_SetEnvironmentStringsW(%rip) - leave - ret - .endfn SetEnvironmentStrings,globl - .previous diff --git a/libc/nt/KernelBase/SetExtensionProperty.s b/libc/nt/KernelBase/SetExtensionProperty.s deleted file mode 100644 index e0dcf432a..000000000 --- a/libc/nt/KernelBase/SetExtensionProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetExtensionProperty,SetExtensionProperty,1504 diff --git a/libc/nt/KernelBase/SetIsDeveloperModeEnabled.s b/libc/nt/KernelBase/SetIsDeveloperModeEnabled.s deleted file mode 100644 index cfe006c94..000000000 --- a/libc/nt/KernelBase/SetIsDeveloperModeEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetIsDeveloperModeEnabled,SetIsDeveloperModeEnabled,1518 diff --git a/libc/nt/KernelBase/SetIsSideloadingEnabled.s b/libc/nt/KernelBase/SetIsSideloadingEnabled.s deleted file mode 100644 index 3fe81c1fb..000000000 --- a/libc/nt/KernelBase/SetIsSideloadingEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetIsSideloadingEnabled,SetIsSideloadingEnabled,1519 diff --git a/libc/nt/KernelBase/SetLastConsoleEventActive.s b/libc/nt/KernelBase/SetLastConsoleEventActive.s deleted file mode 100644 index 9f7c6ff99..000000000 --- a/libc/nt/KernelBase/SetLastConsoleEventActive.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetLastConsoleEventActive,SetLastConsoleEventActive,1521 diff --git a/libc/nt/KernelBase/SetProcessGroupAffinity.s b/libc/nt/KernelBase/SetProcessGroupAffinity.s deleted file mode 100644 index e183e31ea..000000000 --- a/libc/nt/KernelBase/SetProcessGroupAffinity.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetProcessGroupAffinity,SetProcessGroupAffinity,1531 diff --git a/libc/nt/KernelBase/SetProcessValidCallTargets.s b/libc/nt/KernelBase/SetProcessValidCallTargets.s deleted file mode 100644 index 7824b56ae..000000000 --- a/libc/nt/KernelBase/SetProcessValidCallTargets.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetProcessValidCallTargets,SetProcessValidCallTargets,1537 diff --git a/libc/nt/KernelBase/SetProtocolProperty.s b/libc/nt/KernelBase/SetProtocolProperty.s deleted file mode 100644 index 3cd9e7dbb..000000000 --- a/libc/nt/KernelBase/SetProtocolProperty.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetProtocolProperty,SetProtocolProperty,1540 diff --git a/libc/nt/KernelBase/SetRoamingLastObservedChangeTime.s b/libc/nt/KernelBase/SetRoamingLastObservedChangeTime.s deleted file mode 100644 index df0f447bf..000000000 --- a/libc/nt/KernelBase/SetRoamingLastObservedChangeTime.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetRoamingLastObservedChangeTime,SetRoamingLastObservedChangeTime,1541 diff --git a/libc/nt/KernelBase/SetStateVersion.s b/libc/nt/KernelBase/SetStateVersion.s deleted file mode 100644 index 0503c5c9b..000000000 --- a/libc/nt/KernelBase/SetStateVersion.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetStateVersion,SetStateVersion,1549 diff --git a/libc/nt/KernelBase/SetStdHandleEx.s b/libc/nt/KernelBase/SetStdHandleEx.s deleted file mode 100644 index b9c36779a..000000000 --- a/libc/nt/KernelBase/SetStdHandleEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetStdHandleEx,SetStdHandleEx,1551 diff --git a/libc/nt/KernelBase/SetSystemTimeAdjustmentPrecise.s b/libc/nt/KernelBase/SetSystemTimeAdjustmentPrecise.s deleted file mode 100644 index ca9ba59fd..000000000 --- a/libc/nt/KernelBase/SetSystemTimeAdjustmentPrecise.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetSystemTimeAdjustmentPrecise,SetSystemTimeAdjustmentPrecise,1555 diff --git a/libc/nt/KernelBase/SetThreadDescription.s b/libc/nt/KernelBase/SetThreadDescription.s deleted file mode 100644 index 655519ed9..000000000 --- a/libc/nt/KernelBase/SetThreadDescription.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetThreadDescription,SetThreadDescription,1557 diff --git a/libc/nt/KernelBase/SetUserGeoName.s b/libc/nt/KernelBase/SetUserGeoName.s deleted file mode 100644 index 893ceae82..000000000 --- a/libc/nt/KernelBase/SetUserGeoName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SetUserGeoName,SetUserGeoName,1582 diff --git a/libc/nt/KernelBase/SharedLocalIsEnabled.s b/libc/nt/KernelBase/SharedLocalIsEnabled.s deleted file mode 100644 index 786cf9dcd..000000000 --- a/libc/nt/KernelBase/SharedLocalIsEnabled.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SharedLocalIsEnabled,SharedLocalIsEnabled,1587 diff --git a/libc/nt/KernelBase/SpecialMBToWC.s b/libc/nt/KernelBase/SpecialMBToWC.s deleted file mode 100644 index 58f1931ea..000000000 --- a/libc/nt/KernelBase/SpecialMBToWC.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SpecialMBToWC,SpecialMBToWC,1594 diff --git a/libc/nt/KernelBase/StmAlignSize.s b/libc/nt/KernelBase/StmAlignSize.s deleted file mode 100644 index d467ca5ea..000000000 --- a/libc/nt/KernelBase/StmAlignSize.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StmAlignSize,StmAlignSize,1596 diff --git a/libc/nt/KernelBase/StmAllocateFlat.s b/libc/nt/KernelBase/StmAllocateFlat.s deleted file mode 100644 index 01adc5cd9..000000000 --- a/libc/nt/KernelBase/StmAllocateFlat.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StmAllocateFlat,StmAllocateFlat,1597 diff --git a/libc/nt/KernelBase/StmCoalesceChunks.s b/libc/nt/KernelBase/StmCoalesceChunks.s deleted file mode 100644 index ea4547bad..000000000 --- a/libc/nt/KernelBase/StmCoalesceChunks.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StmCoalesceChunks,StmCoalesceChunks,1598 diff --git a/libc/nt/KernelBase/StmDeinitialize.s b/libc/nt/KernelBase/StmDeinitialize.s deleted file mode 100644 index 28e2003e4..000000000 --- a/libc/nt/KernelBase/StmDeinitialize.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StmDeinitialize,StmDeinitialize,1599 diff --git a/libc/nt/KernelBase/StmInitialize.s b/libc/nt/KernelBase/StmInitialize.s deleted file mode 100644 index fc55d824e..000000000 --- a/libc/nt/KernelBase/StmInitialize.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StmInitialize,StmInitialize,1600 diff --git a/libc/nt/KernelBase/StmReduceSize.s b/libc/nt/KernelBase/StmReduceSize.s deleted file mode 100644 index 176b58d7e..000000000 --- a/libc/nt/KernelBase/StmReduceSize.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StmReduceSize,StmReduceSize,1601 diff --git a/libc/nt/KernelBase/StmReserve.s b/libc/nt/KernelBase/StmReserve.s deleted file mode 100644 index 8e158baf9..000000000 --- a/libc/nt/KernelBase/StmReserve.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StmReserve,StmReserve,1602 diff --git a/libc/nt/KernelBase/StmWrite.s b/libc/nt/KernelBase/StmWrite.s deleted file mode 100644 index b1d66863c..000000000 --- a/libc/nt/KernelBase/StmWrite.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StmWrite,StmWrite,1603 diff --git a/libc/nt/KernelBase/StrCSpnA.s b/libc/nt/KernelBase/StrCSpnA.s deleted file mode 100644 index e746c3367..000000000 --- a/libc/nt/KernelBase/StrCSpnA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCSpnA,StrCSpnA,1604 diff --git a/libc/nt/KernelBase/StrCSpnIA.s b/libc/nt/KernelBase/StrCSpnIA.s deleted file mode 100644 index ddea4c3b6..000000000 --- a/libc/nt/KernelBase/StrCSpnIA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCSpnIA,StrCSpnIA,1605 diff --git a/libc/nt/KernelBase/StrCSpnIW.s b/libc/nt/KernelBase/StrCSpnIW.s deleted file mode 100644 index 07d7e2ac4..000000000 --- a/libc/nt/KernelBase/StrCSpnIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCSpnIW,StrCSpnIW,1606 diff --git a/libc/nt/KernelBase/StrCSpnW.s b/libc/nt/KernelBase/StrCSpnW.s deleted file mode 100644 index ffc748b02..000000000 --- a/libc/nt/KernelBase/StrCSpnW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCSpnW,StrCSpnW,1607 diff --git a/libc/nt/KernelBase/StrCatBuffA.s b/libc/nt/KernelBase/StrCatBuffA.s deleted file mode 100644 index c220acd50..000000000 --- a/libc/nt/KernelBase/StrCatBuffA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCatBuffA,StrCatBuffA,1608 diff --git a/libc/nt/KernelBase/StrCatBuffW.s b/libc/nt/KernelBase/StrCatBuffW.s deleted file mode 100644 index ac3e8a31d..000000000 --- a/libc/nt/KernelBase/StrCatBuffW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCatBuffW,StrCatBuffW,1609 diff --git a/libc/nt/KernelBase/StrCatChainW.s b/libc/nt/KernelBase/StrCatChainW.s deleted file mode 100644 index cd8a0789d..000000000 --- a/libc/nt/KernelBase/StrCatChainW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCatChainW,StrCatChainW,1610 diff --git a/libc/nt/KernelBase/StrChrA.s b/libc/nt/KernelBase/StrChrA.s deleted file mode 100644 index 13ce8f170..000000000 --- a/libc/nt/KernelBase/StrChrA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrChrA,StrChrA,1611 diff --git a/libc/nt/KernelBase/StrChrA_MB.s b/libc/nt/KernelBase/StrChrA_MB.s deleted file mode 100644 index 5b624bf0a..000000000 --- a/libc/nt/KernelBase/StrChrA_MB.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrChrA_MB,StrChrA_MB,1612 diff --git a/libc/nt/KernelBase/StrChrIA.s b/libc/nt/KernelBase/StrChrIA.s deleted file mode 100644 index da4a1b08e..000000000 --- a/libc/nt/KernelBase/StrChrIA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrChrIA,StrChrIA,1613 diff --git a/libc/nt/KernelBase/StrChrIW.s b/libc/nt/KernelBase/StrChrIW.s deleted file mode 100644 index 0253494f9..000000000 --- a/libc/nt/KernelBase/StrChrIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrChrIW,StrChrIW,1614 diff --git a/libc/nt/KernelBase/StrChrNIW.s b/libc/nt/KernelBase/StrChrNIW.s deleted file mode 100644 index 09231351b..000000000 --- a/libc/nt/KernelBase/StrChrNIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrChrNIW,StrChrNIW,1615 diff --git a/libc/nt/KernelBase/StrChrNW.s b/libc/nt/KernelBase/StrChrNW.s deleted file mode 100644 index 61ede218e..000000000 --- a/libc/nt/KernelBase/StrChrNW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrChrNW,StrChrNW,1616 diff --git a/libc/nt/KernelBase/StrChrW.s b/libc/nt/KernelBase/StrChrW.s deleted file mode 100644 index 678b3603f..000000000 --- a/libc/nt/KernelBase/StrChrW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrChrW,StrChrW,1617 diff --git a/libc/nt/KernelBase/StrCmpCA.s b/libc/nt/KernelBase/StrCmpCA.s deleted file mode 100644 index 5d67018ab..000000000 --- a/libc/nt/KernelBase/StrCmpCA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpCA,StrCmpCA,1618 diff --git a/libc/nt/KernelBase/StrCmpCW.s b/libc/nt/KernelBase/StrCmpCW.s deleted file mode 100644 index f1f1cef34..000000000 --- a/libc/nt/KernelBase/StrCmpCW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpCW,StrCmpCW,1619 diff --git a/libc/nt/KernelBase/StrCmpICA.s b/libc/nt/KernelBase/StrCmpICA.s deleted file mode 100644 index 016345f62..000000000 --- a/libc/nt/KernelBase/StrCmpICA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpICA,StrCmpICA,1620 diff --git a/libc/nt/KernelBase/StrCmpICW.s b/libc/nt/KernelBase/StrCmpICW.s deleted file mode 100644 index 6543b6958..000000000 --- a/libc/nt/KernelBase/StrCmpICW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpICW,StrCmpICW,1621 diff --git a/libc/nt/KernelBase/StrCmpIW.s b/libc/nt/KernelBase/StrCmpIW.s deleted file mode 100644 index 691e51520..000000000 --- a/libc/nt/KernelBase/StrCmpIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpIW,StrCmpIW,1622 diff --git a/libc/nt/KernelBase/StrCmpLogicalW.s b/libc/nt/KernelBase/StrCmpLogicalW.s deleted file mode 100644 index 30dd631e1..000000000 --- a/libc/nt/KernelBase/StrCmpLogicalW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpLogicalW,StrCmpLogicalW,1623 diff --git a/libc/nt/KernelBase/StrCmpNA.s b/libc/nt/KernelBase/StrCmpNA.s deleted file mode 100644 index 088b8bba9..000000000 --- a/libc/nt/KernelBase/StrCmpNA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpNA,StrCmpNA,1624 diff --git a/libc/nt/KernelBase/StrCmpNCA.s b/libc/nt/KernelBase/StrCmpNCA.s deleted file mode 100644 index 39028a6f6..000000000 --- a/libc/nt/KernelBase/StrCmpNCA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpNCA,StrCmpNCA,1625 diff --git a/libc/nt/KernelBase/StrCmpNCW.s b/libc/nt/KernelBase/StrCmpNCW.s deleted file mode 100644 index 15f28edf7..000000000 --- a/libc/nt/KernelBase/StrCmpNCW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpNCW,StrCmpNCW,1626 diff --git a/libc/nt/KernelBase/StrCmpNIA.s b/libc/nt/KernelBase/StrCmpNIA.s deleted file mode 100644 index 545099387..000000000 --- a/libc/nt/KernelBase/StrCmpNIA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpNIA,StrCmpNIA,1627 diff --git a/libc/nt/KernelBase/StrCmpNICA.s b/libc/nt/KernelBase/StrCmpNICA.s deleted file mode 100644 index a8447add6..000000000 --- a/libc/nt/KernelBase/StrCmpNICA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpNICA,StrCmpNICA,1628 diff --git a/libc/nt/KernelBase/StrCmpNICW.s b/libc/nt/KernelBase/StrCmpNICW.s deleted file mode 100644 index 0a083d8cd..000000000 --- a/libc/nt/KernelBase/StrCmpNICW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpNICW,StrCmpNICW,1629 diff --git a/libc/nt/KernelBase/StrCmpNIW.s b/libc/nt/KernelBase/StrCmpNIW.s deleted file mode 100644 index 3b60da802..000000000 --- a/libc/nt/KernelBase/StrCmpNIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpNIW,StrCmpNIW,1630 diff --git a/libc/nt/KernelBase/StrCmpNW.s b/libc/nt/KernelBase/StrCmpNW.s deleted file mode 100644 index bbae7c17d..000000000 --- a/libc/nt/KernelBase/StrCmpNW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpNW,StrCmpNW,1631 diff --git a/libc/nt/KernelBase/StrCmpW.s b/libc/nt/KernelBase/StrCmpW.s deleted file mode 100644 index 3586aeb07..000000000 --- a/libc/nt/KernelBase/StrCmpW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCmpW,StrCmpW,1632 diff --git a/libc/nt/KernelBase/StrCpyNW.s b/libc/nt/KernelBase/StrCpyNW.s deleted file mode 100644 index acd7aad6b..000000000 --- a/libc/nt/KernelBase/StrCpyNW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCpyNW,StrCpyNW,1633 diff --git a/libc/nt/KernelBase/StrCpyNXA.s b/libc/nt/KernelBase/StrCpyNXA.s deleted file mode 100644 index a65815187..000000000 --- a/libc/nt/KernelBase/StrCpyNXA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCpyNXA,StrCpyNXA,1634 diff --git a/libc/nt/KernelBase/StrCpyNXW.s b/libc/nt/KernelBase/StrCpyNXW.s deleted file mode 100644 index 38eea9860..000000000 --- a/libc/nt/KernelBase/StrCpyNXW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrCpyNXW,StrCpyNXW,1635 diff --git a/libc/nt/KernelBase/StrDupA.s b/libc/nt/KernelBase/StrDupA.s deleted file mode 100644 index c86c498a7..000000000 --- a/libc/nt/KernelBase/StrDupA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrDupA,StrDupA,1636 diff --git a/libc/nt/KernelBase/StrDupW.s b/libc/nt/KernelBase/StrDupW.s deleted file mode 100644 index 0715942d3..000000000 --- a/libc/nt/KernelBase/StrDupW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrDupW,StrDupW,1637 diff --git a/libc/nt/KernelBase/StrIsIntlEqualA.s b/libc/nt/KernelBase/StrIsIntlEqualA.s deleted file mode 100644 index e591a29d3..000000000 --- a/libc/nt/KernelBase/StrIsIntlEqualA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrIsIntlEqualA,StrIsIntlEqualA,1638 diff --git a/libc/nt/KernelBase/StrIsIntlEqualW.s b/libc/nt/KernelBase/StrIsIntlEqualW.s deleted file mode 100644 index 77a99d5d6..000000000 --- a/libc/nt/KernelBase/StrIsIntlEqualW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrIsIntlEqualW,StrIsIntlEqualW,1639 diff --git a/libc/nt/KernelBase/StrPBrkA.s b/libc/nt/KernelBase/StrPBrkA.s deleted file mode 100644 index e70fdef88..000000000 --- a/libc/nt/KernelBase/StrPBrkA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrPBrkA,StrPBrkA,1640 diff --git a/libc/nt/KernelBase/StrPBrkW.s b/libc/nt/KernelBase/StrPBrkW.s deleted file mode 100644 index 90733d6de..000000000 --- a/libc/nt/KernelBase/StrPBrkW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrPBrkW,StrPBrkW,1641 diff --git a/libc/nt/KernelBase/StrRChrA.s b/libc/nt/KernelBase/StrRChrA.s deleted file mode 100644 index 77bb1365e..000000000 --- a/libc/nt/KernelBase/StrRChrA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrRChrA,StrRChrA,1642 diff --git a/libc/nt/KernelBase/StrRChrIA.s b/libc/nt/KernelBase/StrRChrIA.s deleted file mode 100644 index 1515df47b..000000000 --- a/libc/nt/KernelBase/StrRChrIA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrRChrIA,StrRChrIA,1643 diff --git a/libc/nt/KernelBase/StrRChrIW.s b/libc/nt/KernelBase/StrRChrIW.s deleted file mode 100644 index 434246b45..000000000 --- a/libc/nt/KernelBase/StrRChrIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrRChrIW,StrRChrIW,1644 diff --git a/libc/nt/KernelBase/StrRChrW.s b/libc/nt/KernelBase/StrRChrW.s deleted file mode 100644 index 5340cb611..000000000 --- a/libc/nt/KernelBase/StrRChrW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrRChrW,StrRChrW,1645 diff --git a/libc/nt/KernelBase/StrRStrIA.s b/libc/nt/KernelBase/StrRStrIA.s deleted file mode 100644 index e1685ca16..000000000 --- a/libc/nt/KernelBase/StrRStrIA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrRStrIA,StrRStrIA,1646 diff --git a/libc/nt/KernelBase/StrRStrIW.s b/libc/nt/KernelBase/StrRStrIW.s deleted file mode 100644 index 1ca7ac57b..000000000 --- a/libc/nt/KernelBase/StrRStrIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrRStrIW,StrRStrIW,1647 diff --git a/libc/nt/KernelBase/StrSpnA.s b/libc/nt/KernelBase/StrSpnA.s deleted file mode 100644 index acbf7bba9..000000000 --- a/libc/nt/KernelBase/StrSpnA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrSpnA,StrSpnA,1648 diff --git a/libc/nt/KernelBase/StrSpnW.s b/libc/nt/KernelBase/StrSpnW.s deleted file mode 100644 index dfd9522f4..000000000 --- a/libc/nt/KernelBase/StrSpnW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrSpnW,StrSpnW,1649 diff --git a/libc/nt/KernelBase/StrStrA.s b/libc/nt/KernelBase/StrStrA.s deleted file mode 100644 index da6149973..000000000 --- a/libc/nt/KernelBase/StrStrA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrStrA,StrStrA,1650 diff --git a/libc/nt/KernelBase/StrStrIA.s b/libc/nt/KernelBase/StrStrIA.s deleted file mode 100644 index 43a03254c..000000000 --- a/libc/nt/KernelBase/StrStrIA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrStrIA,StrStrIA,1651 diff --git a/libc/nt/KernelBase/StrStrIW.s b/libc/nt/KernelBase/StrStrIW.s deleted file mode 100644 index ce18ee83c..000000000 --- a/libc/nt/KernelBase/StrStrIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrStrIW,StrStrIW,1652 diff --git a/libc/nt/KernelBase/StrStrNIW.s b/libc/nt/KernelBase/StrStrNIW.s deleted file mode 100644 index 137f29221..000000000 --- a/libc/nt/KernelBase/StrStrNIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrStrNIW,StrStrNIW,1653 diff --git a/libc/nt/KernelBase/StrStrNW.s b/libc/nt/KernelBase/StrStrNW.s deleted file mode 100644 index 0a7632b05..000000000 --- a/libc/nt/KernelBase/StrStrNW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrStrNW,StrStrNW,1654 diff --git a/libc/nt/KernelBase/StrStrW.s b/libc/nt/KernelBase/StrStrW.s deleted file mode 100644 index 6185a2a03..000000000 --- a/libc/nt/KernelBase/StrStrW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrStrW,StrStrW,1655 diff --git a/libc/nt/KernelBase/StrToInt64ExA.s b/libc/nt/KernelBase/StrToInt64ExA.s deleted file mode 100644 index 3e684b0f8..000000000 --- a/libc/nt/KernelBase/StrToInt64ExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrToInt64ExA,StrToInt64ExA,1656 diff --git a/libc/nt/KernelBase/StrToInt64ExW.s b/libc/nt/KernelBase/StrToInt64ExW.s deleted file mode 100644 index 3ff471f08..000000000 --- a/libc/nt/KernelBase/StrToInt64ExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrToInt64ExW,StrToInt64ExW,1657 diff --git a/libc/nt/KernelBase/StrToIntA.s b/libc/nt/KernelBase/StrToIntA.s deleted file mode 100644 index 2ffc605fe..000000000 --- a/libc/nt/KernelBase/StrToIntA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrToIntA,StrToIntA,1658 diff --git a/libc/nt/KernelBase/StrToIntExA.s b/libc/nt/KernelBase/StrToIntExA.s deleted file mode 100644 index c79a72ae6..000000000 --- a/libc/nt/KernelBase/StrToIntExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrToIntExA,StrToIntExA,1659 diff --git a/libc/nt/KernelBase/StrToIntExW.s b/libc/nt/KernelBase/StrToIntExW.s deleted file mode 100644 index 6ec3c6b3b..000000000 --- a/libc/nt/KernelBase/StrToIntExW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrToIntExW,StrToIntExW,1660 diff --git a/libc/nt/KernelBase/StrToIntW.s b/libc/nt/KernelBase/StrToIntW.s deleted file mode 100644 index 83dac3409..000000000 --- a/libc/nt/KernelBase/StrToIntW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrToIntW,StrToIntW,1661 diff --git a/libc/nt/KernelBase/StrTrimA.s b/libc/nt/KernelBase/StrTrimA.s deleted file mode 100644 index 17b048467..000000000 --- a/libc/nt/KernelBase/StrTrimA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrTrimA,StrTrimA,1662 diff --git a/libc/nt/KernelBase/StrTrimW.s b/libc/nt/KernelBase/StrTrimW.s deleted file mode 100644 index 1c06a96ed..000000000 --- a/libc/nt/KernelBase/StrTrimW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_StrTrimW,StrTrimW,1663 diff --git a/libc/nt/KernelBase/SubscribeEdpEnabledStateChange.s b/libc/nt/KernelBase/SubscribeEdpEnabledStateChange.s deleted file mode 100644 index b5844fead..000000000 --- a/libc/nt/KernelBase/SubscribeEdpEnabledStateChange.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SubscribeEdpEnabledStateChange,SubscribeEdpEnabledStateChange,1665 diff --git a/libc/nt/KernelBase/SubscribeStateChangeNotification.s b/libc/nt/KernelBase/SubscribeStateChangeNotification.s deleted file mode 100644 index 707533867..000000000 --- a/libc/nt/KernelBase/SubscribeStateChangeNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_SubscribeStateChangeNotification,SubscribeStateChangeNotification,1666 diff --git a/libc/nt/KernelBase/TerminateEnclave.s b/libc/nt/KernelBase/TerminateEnclave.s deleted file mode 100644 index bdc575c54..000000000 --- a/libc/nt/KernelBase/TerminateEnclave.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_TerminateEnclave,TerminateEnclave,1673 diff --git a/libc/nt/KernelBase/TerminateProcessOnMemoryExhaustion.s b/libc/nt/KernelBase/TerminateProcessOnMemoryExhaustion.s deleted file mode 100644 index da1acfd6c..000000000 --- a/libc/nt/KernelBase/TerminateProcessOnMemoryExhaustion.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_TerminateProcessOnMemoryExhaustion,TerminateProcessOnMemoryExhaustion,1675 diff --git a/libc/nt/KernelBase/UnmapViewOfFile2.s b/libc/nt/KernelBase/UnmapViewOfFile2.s deleted file mode 100644 index 7b8dfd0ec..000000000 --- a/libc/nt/KernelBase/UnmapViewOfFile2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UnmapViewOfFile2,UnmapViewOfFile2,1696 diff --git a/libc/nt/KernelBase/UnmapViewOfFileEx.s b/libc/nt/KernelBase/UnmapViewOfFileEx.s deleted file mode 100644 index 04ff7e505..000000000 --- a/libc/nt/KernelBase/UnmapViewOfFileEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UnmapViewOfFileEx,UnmapViewOfFileEx,1697 diff --git a/libc/nt/KernelBase/UnregisterGPNotificationInternal.s b/libc/nt/KernelBase/UnregisterGPNotificationInternal.s deleted file mode 100644 index fb194724d..000000000 --- a/libc/nt/KernelBase/UnregisterGPNotificationInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UnregisterGPNotificationInternal,UnregisterGPNotificationInternal,1699 diff --git a/libc/nt/KernelBase/UnregisterStateChangeNotification.s b/libc/nt/KernelBase/UnregisterStateChangeNotification.s deleted file mode 100644 index 9d96bc7d1..000000000 --- a/libc/nt/KernelBase/UnregisterStateChangeNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UnregisterStateChangeNotification,UnregisterStateChangeNotification,1700 diff --git a/libc/nt/KernelBase/UnregisterStateLock.s b/libc/nt/KernelBase/UnregisterStateLock.s deleted file mode 100644 index 85d97ab00..000000000 --- a/libc/nt/KernelBase/UnregisterStateLock.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UnregisterStateLock,UnregisterStateLock,1701 diff --git a/libc/nt/KernelBase/UnsubscribeEdpEnabledStateChange.s b/libc/nt/KernelBase/UnsubscribeEdpEnabledStateChange.s deleted file mode 100644 index 5e79469ce..000000000 --- a/libc/nt/KernelBase/UnsubscribeEdpEnabledStateChange.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UnsubscribeEdpEnabledStateChange,UnsubscribeEdpEnabledStateChange,1704 diff --git a/libc/nt/KernelBase/UnsubscribeStateChangeNotification.s b/libc/nt/KernelBase/UnsubscribeStateChangeNotification.s deleted file mode 100644 index 84f1b5e11..000000000 --- a/libc/nt/KernelBase/UnsubscribeStateChangeNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UnsubscribeStateChangeNotification,UnsubscribeStateChangeNotification,1705 diff --git a/libc/nt/KernelBase/UpdatePackageStatus.s b/libc/nt/KernelBase/UpdatePackageStatus.s deleted file mode 100644 index b18a67196..000000000 --- a/libc/nt/KernelBase/UpdatePackageStatus.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UpdatePackageStatus,UpdatePackageStatus,1706 diff --git a/libc/nt/KernelBase/UpdatePackageStatusForUser.s b/libc/nt/KernelBase/UpdatePackageStatusForUser.s deleted file mode 100644 index 92ed9820b..000000000 --- a/libc/nt/KernelBase/UpdatePackageStatusForUser.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UpdatePackageStatusForUser,UpdatePackageStatusForUser,1707 diff --git a/libc/nt/KernelBase/UpdatePackageStatusForUserSid.s b/libc/nt/KernelBase/UpdatePackageStatusForUserSid.s deleted file mode 100644 index 108479afc..000000000 --- a/libc/nt/KernelBase/UpdatePackageStatusForUserSid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UpdatePackageStatusForUserSid,UpdatePackageStatusForUserSid,1708 diff --git a/libc/nt/KernelBase/UrlApplySchemeA.s b/libc/nt/KernelBase/UrlApplySchemeA.s deleted file mode 100644 index d8d6729df..000000000 --- a/libc/nt/KernelBase/UrlApplySchemeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlApplySchemeA,UrlApplySchemeA,1710 diff --git a/libc/nt/KernelBase/UrlApplySchemeW.s b/libc/nt/KernelBase/UrlApplySchemeW.s deleted file mode 100644 index f238b5998..000000000 --- a/libc/nt/KernelBase/UrlApplySchemeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlApplySchemeW,UrlApplySchemeW,1711 diff --git a/libc/nt/KernelBase/UrlCanonicalizeA.s b/libc/nt/KernelBase/UrlCanonicalizeA.s deleted file mode 100644 index f51ceb9e5..000000000 --- a/libc/nt/KernelBase/UrlCanonicalizeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlCanonicalizeA,UrlCanonicalizeA,1712 diff --git a/libc/nt/KernelBase/UrlCanonicalizeW.s b/libc/nt/KernelBase/UrlCanonicalizeW.s deleted file mode 100644 index 41ded1873..000000000 --- a/libc/nt/KernelBase/UrlCanonicalizeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlCanonicalizeW,UrlCanonicalizeW,1713 diff --git a/libc/nt/KernelBase/UrlCombineA.s b/libc/nt/KernelBase/UrlCombineA.s deleted file mode 100644 index 6720f4359..000000000 --- a/libc/nt/KernelBase/UrlCombineA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlCombineA,UrlCombineA,1714 diff --git a/libc/nt/KernelBase/UrlCombineW.s b/libc/nt/KernelBase/UrlCombineW.s deleted file mode 100644 index 78a8b8284..000000000 --- a/libc/nt/KernelBase/UrlCombineW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlCombineW,UrlCombineW,1715 diff --git a/libc/nt/KernelBase/UrlCompareA.s b/libc/nt/KernelBase/UrlCompareA.s deleted file mode 100644 index 7f5071519..000000000 --- a/libc/nt/KernelBase/UrlCompareA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlCompareA,UrlCompareA,1716 diff --git a/libc/nt/KernelBase/UrlCompareW.s b/libc/nt/KernelBase/UrlCompareW.s deleted file mode 100644 index ae7ac1c3c..000000000 --- a/libc/nt/KernelBase/UrlCompareW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlCompareW,UrlCompareW,1717 diff --git a/libc/nt/KernelBase/UrlCreateFromPathA.s b/libc/nt/KernelBase/UrlCreateFromPathA.s deleted file mode 100644 index a83536e64..000000000 --- a/libc/nt/KernelBase/UrlCreateFromPathA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlCreateFromPathA,UrlCreateFromPathA,1718 diff --git a/libc/nt/KernelBase/UrlCreateFromPathW.s b/libc/nt/KernelBase/UrlCreateFromPathW.s deleted file mode 100644 index fda675ef7..000000000 --- a/libc/nt/KernelBase/UrlCreateFromPathW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlCreateFromPathW,UrlCreateFromPathW,1719 diff --git a/libc/nt/KernelBase/UrlEscapeA.s b/libc/nt/KernelBase/UrlEscapeA.s deleted file mode 100644 index 244199c9c..000000000 --- a/libc/nt/KernelBase/UrlEscapeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlEscapeA,UrlEscapeA,1720 diff --git a/libc/nt/KernelBase/UrlEscapeW.s b/libc/nt/KernelBase/UrlEscapeW.s deleted file mode 100644 index 50d7bad7f..000000000 --- a/libc/nt/KernelBase/UrlEscapeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlEscapeW,UrlEscapeW,1721 diff --git a/libc/nt/KernelBase/UrlFixupW.s b/libc/nt/KernelBase/UrlFixupW.s deleted file mode 100644 index 542c2e57a..000000000 --- a/libc/nt/KernelBase/UrlFixupW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlFixupW,UrlFixupW,1722 diff --git a/libc/nt/KernelBase/UrlGetLocationA.s b/libc/nt/KernelBase/UrlGetLocationA.s deleted file mode 100644 index 0f7858c33..000000000 --- a/libc/nt/KernelBase/UrlGetLocationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlGetLocationA,UrlGetLocationA,1723 diff --git a/libc/nt/KernelBase/UrlGetLocationW.s b/libc/nt/KernelBase/UrlGetLocationW.s deleted file mode 100644 index 99e6f9f22..000000000 --- a/libc/nt/KernelBase/UrlGetLocationW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlGetLocationW,UrlGetLocationW,1724 diff --git a/libc/nt/KernelBase/UrlGetPartA.s b/libc/nt/KernelBase/UrlGetPartA.s deleted file mode 100644 index 36828f58f..000000000 --- a/libc/nt/KernelBase/UrlGetPartA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlGetPartA,UrlGetPartA,1725 diff --git a/libc/nt/KernelBase/UrlGetPartW.s b/libc/nt/KernelBase/UrlGetPartW.s deleted file mode 100644 index ceacf87ba..000000000 --- a/libc/nt/KernelBase/UrlGetPartW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlGetPartW,UrlGetPartW,1726 diff --git a/libc/nt/KernelBase/UrlHashA.s b/libc/nt/KernelBase/UrlHashA.s deleted file mode 100644 index bc115b9a1..000000000 --- a/libc/nt/KernelBase/UrlHashA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlHashA,UrlHashA,1727 diff --git a/libc/nt/KernelBase/UrlHashW.s b/libc/nt/KernelBase/UrlHashW.s deleted file mode 100644 index 3c9ce753b..000000000 --- a/libc/nt/KernelBase/UrlHashW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlHashW,UrlHashW,1728 diff --git a/libc/nt/KernelBase/UrlIsA.s b/libc/nt/KernelBase/UrlIsA.s deleted file mode 100644 index 637013230..000000000 --- a/libc/nt/KernelBase/UrlIsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlIsA,UrlIsA,1729 diff --git a/libc/nt/KernelBase/UrlIsNoHistoryA.s b/libc/nt/KernelBase/UrlIsNoHistoryA.s deleted file mode 100644 index 967140d48..000000000 --- a/libc/nt/KernelBase/UrlIsNoHistoryA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlIsNoHistoryA,UrlIsNoHistoryA,1730 diff --git a/libc/nt/KernelBase/UrlIsNoHistoryW.s b/libc/nt/KernelBase/UrlIsNoHistoryW.s deleted file mode 100644 index c1c5fd3e9..000000000 --- a/libc/nt/KernelBase/UrlIsNoHistoryW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlIsNoHistoryW,UrlIsNoHistoryW,1731 diff --git a/libc/nt/KernelBase/UrlIsOpaqueA.s b/libc/nt/KernelBase/UrlIsOpaqueA.s deleted file mode 100644 index f01b54978..000000000 --- a/libc/nt/KernelBase/UrlIsOpaqueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlIsOpaqueA,UrlIsOpaqueA,1732 diff --git a/libc/nt/KernelBase/UrlIsOpaqueW.s b/libc/nt/KernelBase/UrlIsOpaqueW.s deleted file mode 100644 index 56c3ec3f8..000000000 --- a/libc/nt/KernelBase/UrlIsOpaqueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlIsOpaqueW,UrlIsOpaqueW,1733 diff --git a/libc/nt/KernelBase/UrlIsW.s b/libc/nt/KernelBase/UrlIsW.s deleted file mode 100644 index ac18c022a..000000000 --- a/libc/nt/KernelBase/UrlIsW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlIsW,UrlIsW,1734 diff --git a/libc/nt/KernelBase/UrlUnescapeA.s b/libc/nt/KernelBase/UrlUnescapeA.s deleted file mode 100644 index 643129ccb..000000000 --- a/libc/nt/KernelBase/UrlUnescapeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlUnescapeA,UrlUnescapeA,1735 diff --git a/libc/nt/KernelBase/UrlUnescapeW.s b/libc/nt/KernelBase/UrlUnescapeW.s deleted file mode 100644 index 6cdc64f73..000000000 --- a/libc/nt/KernelBase/UrlUnescapeW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_UrlUnescapeW,UrlUnescapeW,1736 diff --git a/libc/nt/KernelBase/VerFindFileA.s b/libc/nt/KernelBase/VerFindFileA.s deleted file mode 100644 index 02733d6e1..000000000 --- a/libc/nt/KernelBase/VerFindFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerFindFileA,VerFindFileA,1737 diff --git a/libc/nt/KernelBase/VerFindFileW.s b/libc/nt/KernelBase/VerFindFileW.s deleted file mode 100644 index 0f6b7251d..000000000 --- a/libc/nt/KernelBase/VerFindFileW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerFindFileW,VerFindFileW,1738 diff --git a/libc/nt/KernelBase/VerQueryValueA.s b/libc/nt/KernelBase/VerQueryValueA.s deleted file mode 100644 index eb3c7ab6b..000000000 --- a/libc/nt/KernelBase/VerQueryValueA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerQueryValueA,VerQueryValueA,1741 diff --git a/libc/nt/KernelBase/VerQueryValueW.s b/libc/nt/KernelBase/VerQueryValueW.s deleted file mode 100644 index bf101dbdc..000000000 --- a/libc/nt/KernelBase/VerQueryValueW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerQueryValueW,VerQueryValueW,1742 diff --git a/libc/nt/KernelBase/VerifyApplicationUserModelId.s b/libc/nt/KernelBase/VerifyApplicationUserModelId.s deleted file mode 100644 index 0f3c3265c..000000000 --- a/libc/nt/KernelBase/VerifyApplicationUserModelId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyApplicationUserModelId,VerifyApplicationUserModelId,1744 diff --git a/libc/nt/KernelBase/VerifyApplicationUserModelIdA.s b/libc/nt/KernelBase/VerifyApplicationUserModelIdA.s deleted file mode 100644 index b76ee2ca6..000000000 --- a/libc/nt/KernelBase/VerifyApplicationUserModelIdA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyApplicationUserModelIdA,VerifyApplicationUserModelIdA,1745 diff --git a/libc/nt/KernelBase/VerifyPackageFamilyName.s b/libc/nt/KernelBase/VerifyPackageFamilyName.s deleted file mode 100644 index a8540b2e6..000000000 --- a/libc/nt/KernelBase/VerifyPackageFamilyName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyPackageFamilyName,VerifyPackageFamilyName,1746 diff --git a/libc/nt/KernelBase/VerifyPackageFamilyNameA.s b/libc/nt/KernelBase/VerifyPackageFamilyNameA.s deleted file mode 100644 index cd750cc0f..000000000 --- a/libc/nt/KernelBase/VerifyPackageFamilyNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyPackageFamilyNameA,VerifyPackageFamilyNameA,1747 diff --git a/libc/nt/KernelBase/VerifyPackageFullName.s b/libc/nt/KernelBase/VerifyPackageFullName.s deleted file mode 100644 index f71c36ba3..000000000 --- a/libc/nt/KernelBase/VerifyPackageFullName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyPackageFullName,VerifyPackageFullName,1748 diff --git a/libc/nt/KernelBase/VerifyPackageFullNameA.s b/libc/nt/KernelBase/VerifyPackageFullNameA.s deleted file mode 100644 index 1cc746cf6..000000000 --- a/libc/nt/KernelBase/VerifyPackageFullNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyPackageFullNameA,VerifyPackageFullNameA,1749 diff --git a/libc/nt/KernelBase/VerifyPackageId.s b/libc/nt/KernelBase/VerifyPackageId.s deleted file mode 100644 index 7c7f175b6..000000000 --- a/libc/nt/KernelBase/VerifyPackageId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyPackageId,VerifyPackageId,1750 diff --git a/libc/nt/KernelBase/VerifyPackageIdA.s b/libc/nt/KernelBase/VerifyPackageIdA.s deleted file mode 100644 index fb6107243..000000000 --- a/libc/nt/KernelBase/VerifyPackageIdA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyPackageIdA,VerifyPackageIdA,1751 diff --git a/libc/nt/KernelBase/VerifyPackageRelativeApplicationId.s b/libc/nt/KernelBase/VerifyPackageRelativeApplicationId.s deleted file mode 100644 index 01904db89..000000000 --- a/libc/nt/KernelBase/VerifyPackageRelativeApplicationId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyPackageRelativeApplicationId,VerifyPackageRelativeApplicationId,1752 diff --git a/libc/nt/KernelBase/VerifyPackageRelativeApplicationIdA.s b/libc/nt/KernelBase/VerifyPackageRelativeApplicationIdA.s deleted file mode 100644 index b5bd50ad2..000000000 --- a/libc/nt/KernelBase/VerifyPackageRelativeApplicationIdA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VerifyPackageRelativeApplicationIdA,VerifyPackageRelativeApplicationIdA,1753 diff --git a/libc/nt/KernelBase/VirtualAlloc2.s b/libc/nt/KernelBase/VirtualAlloc2.s deleted file mode 100644 index beec22fa1..000000000 --- a/libc/nt/KernelBase/VirtualAlloc2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VirtualAlloc2,VirtualAlloc2,1756 diff --git a/libc/nt/KernelBase/VirtualAlloc2FromApp.s b/libc/nt/KernelBase/VirtualAlloc2FromApp.s deleted file mode 100644 index 0d8e14fb0..000000000 --- a/libc/nt/KernelBase/VirtualAlloc2FromApp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VirtualAlloc2FromApp,VirtualAlloc2FromApp,1757 diff --git a/libc/nt/KernelBase/VirtualAllocFromApp.s b/libc/nt/KernelBase/VirtualAllocFromApp.s deleted file mode 100644 index 0f3b23ad8..000000000 --- a/libc/nt/KernelBase/VirtualAllocFromApp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VirtualAllocFromApp,VirtualAllocFromApp,1760 diff --git a/libc/nt/KernelBase/VirtualProtectFromApp.s b/libc/nt/KernelBase/VirtualProtectFromApp.s deleted file mode 100644 index b08f07da7..000000000 --- a/libc/nt/KernelBase/VirtualProtectFromApp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VirtualProtectFromApp,VirtualProtectFromApp,1766 diff --git a/libc/nt/KernelBase/VirtualUnlockEx.s b/libc/nt/KernelBase/VirtualUnlockEx.s deleted file mode 100644 index 7cbfe4922..000000000 --- a/libc/nt/KernelBase/VirtualUnlockEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_VirtualUnlockEx,VirtualUnlockEx,1770 diff --git a/libc/nt/KernelBase/WTSGetServiceSessionId.s b/libc/nt/KernelBase/WTSGetServiceSessionId.s deleted file mode 100644 index 653082f22..000000000 --- a/libc/nt/KernelBase/WTSGetServiceSessionId.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WTSGetServiceSessionId,WTSGetServiceSessionId,1771 diff --git a/libc/nt/KernelBase/WTSIsServerContainer.s b/libc/nt/KernelBase/WTSIsServerContainer.s deleted file mode 100644 index 2f245de68..000000000 --- a/libc/nt/KernelBase/WTSIsServerContainer.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WTSIsServerContainer,WTSIsServerContainer,1772 diff --git a/libc/nt/KernelBase/WaitForDebugEventEx.s b/libc/nt/KernelBase/WaitForDebugEventEx.s deleted file mode 100644 index 17986b81d..000000000 --- a/libc/nt/KernelBase/WaitForDebugEventEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WaitForDebugEventEx,WaitForDebugEventEx,1775 diff --git a/libc/nt/KernelBase/WaitForMachinePolicyForegroundProcessingInternal.s b/libc/nt/KernelBase/WaitForMachinePolicyForegroundProcessingInternal.s deleted file mode 100644 index 6c2a41c1c..000000000 --- a/libc/nt/KernelBase/WaitForMachinePolicyForegroundProcessingInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WaitForMachinePolicyForegroundProcessingInternal,WaitForMachinePolicyForegroundProcessingInternal,1776 diff --git a/libc/nt/KernelBase/WaitForUserPolicyForegroundProcessingInternal.s b/libc/nt/KernelBase/WaitForUserPolicyForegroundProcessingInternal.s deleted file mode 100644 index d247ebc5f..000000000 --- a/libc/nt/KernelBase/WaitForUserPolicyForegroundProcessingInternal.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WaitForUserPolicyForegroundProcessingInternal,WaitForUserPolicyForegroundProcessingInternal,1785 diff --git a/libc/nt/KernelBase/WaitOnAddress.s b/libc/nt/KernelBase/WaitOnAddress.s deleted file mode 100644 index e1f80653c..000000000 --- a/libc/nt/KernelBase/WaitOnAddress.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WaitOnAddress,WaitOnAddress,1787 diff --git a/libc/nt/KernelBase/WerRegisterAdditionalProcess.s b/libc/nt/KernelBase/WerRegisterAdditionalProcess.s deleted file mode 100644 index 338eed709..000000000 --- a/libc/nt/KernelBase/WerRegisterAdditionalProcess.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerRegisterAdditionalProcess,WerRegisterAdditionalProcess,1793 diff --git a/libc/nt/KernelBase/WerRegisterAppLocalDump.s b/libc/nt/KernelBase/WerRegisterAppLocalDump.s deleted file mode 100644 index a8b6a63ff..000000000 --- a/libc/nt/KernelBase/WerRegisterAppLocalDump.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerRegisterAppLocalDump,WerRegisterAppLocalDump,1794 diff --git a/libc/nt/KernelBase/WerRegisterCustomMetadata.s b/libc/nt/KernelBase/WerRegisterCustomMetadata.s deleted file mode 100644 index 10ace560d..000000000 --- a/libc/nt/KernelBase/WerRegisterCustomMetadata.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerRegisterCustomMetadata,WerRegisterCustomMetadata,1795 diff --git a/libc/nt/KernelBase/WerRegisterExcludedMemoryBlock.s b/libc/nt/KernelBase/WerRegisterExcludedMemoryBlock.s deleted file mode 100644 index 348cfddde..000000000 --- a/libc/nt/KernelBase/WerRegisterExcludedMemoryBlock.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerRegisterExcludedMemoryBlock,WerRegisterExcludedMemoryBlock,1796 diff --git a/libc/nt/KernelBase/WerUnregisterAdditionalProcess.s b/libc/nt/KernelBase/WerUnregisterAdditionalProcess.s deleted file mode 100644 index dec0f8f8c..000000000 --- a/libc/nt/KernelBase/WerUnregisterAdditionalProcess.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerUnregisterAdditionalProcess,WerUnregisterAdditionalProcess,1801 diff --git a/libc/nt/KernelBase/WerUnregisterAppLocalDump.s b/libc/nt/KernelBase/WerUnregisterAppLocalDump.s deleted file mode 100644 index c9f262cd2..000000000 --- a/libc/nt/KernelBase/WerUnregisterAppLocalDump.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerUnregisterAppLocalDump,WerUnregisterAppLocalDump,1802 diff --git a/libc/nt/KernelBase/WerUnregisterCustomMetadata.s b/libc/nt/KernelBase/WerUnregisterCustomMetadata.s deleted file mode 100644 index 5cc11451a..000000000 --- a/libc/nt/KernelBase/WerUnregisterCustomMetadata.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerUnregisterCustomMetadata,WerUnregisterCustomMetadata,1803 diff --git a/libc/nt/KernelBase/WerUnregisterExcludedMemoryBlock.s b/libc/nt/KernelBase/WerUnregisterExcludedMemoryBlock.s deleted file mode 100644 index cd82ff0ce..000000000 --- a/libc/nt/KernelBase/WerUnregisterExcludedMemoryBlock.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerUnregisterExcludedMemoryBlock,WerUnregisterExcludedMemoryBlock,1804 diff --git a/libc/nt/KernelBase/WerpNotifyLoadStringResource.s b/libc/nt/KernelBase/WerpNotifyLoadStringResource.s deleted file mode 100644 index 07edd933a..000000000 --- a/libc/nt/KernelBase/WerpNotifyLoadStringResource.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerpNotifyLoadStringResource,WerpNotifyLoadStringResource,1808 diff --git a/libc/nt/KernelBase/WerpNotifyUseStringResource.s b/libc/nt/KernelBase/WerpNotifyUseStringResource.s deleted file mode 100644 index 9556ded06..000000000 --- a/libc/nt/KernelBase/WerpNotifyUseStringResource.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WerpNotifyUseStringResource,WerpNotifyUseStringResource,1809 diff --git a/libc/nt/KernelBase/Wow64SetThreadDefaultGuestMachine.s b/libc/nt/KernelBase/Wow64SetThreadDefaultGuestMachine.s deleted file mode 100644 index f68ffb1ad..000000000 --- a/libc/nt/KernelBase/Wow64SetThreadDefaultGuestMachine.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_Wow64SetThreadDefaultGuestMachine,Wow64SetThreadDefaultGuestMachine,1813 diff --git a/libc/nt/KernelBase/WriteStateAtomValue.s b/libc/nt/KernelBase/WriteStateAtomValue.s deleted file mode 100644 index e6d971f90..000000000 --- a/libc/nt/KernelBase/WriteStateAtomValue.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WriteStateAtomValue,WriteStateAtomValue,1827 diff --git a/libc/nt/KernelBase/WriteStateContainerValue.s b/libc/nt/KernelBase/WriteStateContainerValue.s deleted file mode 100644 index 473414d8e..000000000 --- a/libc/nt/KernelBase/WriteStateContainerValue.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_WriteStateContainerValue,WriteStateContainerValue,1828 diff --git a/libc/nt/KernelBase/_AddMUIStringToCache.s b/libc/nt/KernelBase/_AddMUIStringToCache.s deleted file mode 100644 index d841e13e4..000000000 --- a/libc/nt/KernelBase/_AddMUIStringToCache.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__AddMUIStringToCache,_AddMUIStringToCache,1830 diff --git a/libc/nt/KernelBase/_GetMUIStringFromCache.s b/libc/nt/KernelBase/_GetMUIStringFromCache.s deleted file mode 100644 index 479b928c5..000000000 --- a/libc/nt/KernelBase/_GetMUIStringFromCache.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__GetMUIStringFromCache,_GetMUIStringFromCache,1831 diff --git a/libc/nt/KernelBase/_OpenMuiStringCache.s b/libc/nt/KernelBase/_OpenMuiStringCache.s deleted file mode 100644 index 71be50cc7..000000000 --- a/libc/nt/KernelBase/_OpenMuiStringCache.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__OpenMuiStringCache,_OpenMuiStringCache,1832 diff --git a/libc/nt/KernelBase/_amsg_exit.s b/libc/nt/KernelBase/_amsg_exit.s deleted file mode 100644 index 56b547b95..000000000 --- a/libc/nt/KernelBase/_amsg_exit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__amsg_exit,_amsg_exit,1838 diff --git a/libc/nt/KernelBase/_c_exit.s b/libc/nt/KernelBase/_c_exit.s deleted file mode 100644 index 942e9432c..000000000 --- a/libc/nt/KernelBase/_c_exit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__c_exit,_c_exit,1839 diff --git a/libc/nt/KernelBase/_cexit.s b/libc/nt/KernelBase/_cexit.s deleted file mode 100644 index 4e6d4822c..000000000 --- a/libc/nt/KernelBase/_cexit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__cexit,_cexit,1840 diff --git a/libc/nt/KernelBase/_exit.s b/libc/nt/KernelBase/_exit.s deleted file mode 100644 index 14099d428..000000000 --- a/libc/nt/KernelBase/_exit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__exit,_exit,1841 diff --git a/libc/nt/KernelBase/_initterm.s b/libc/nt/KernelBase/_initterm.s deleted file mode 100644 index 411f29502..000000000 --- a/libc/nt/KernelBase/_initterm.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__initterm,_initterm,1842 diff --git a/libc/nt/KernelBase/_initterm_e.s b/libc/nt/KernelBase/_initterm_e.s deleted file mode 100644 index 7e810ad14..000000000 --- a/libc/nt/KernelBase/_initterm_e.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__initterm_e,_initterm_e,1843 diff --git a/libc/nt/KernelBase/_invalid_parameter.s b/libc/nt/KernelBase/_invalid_parameter.s deleted file mode 100644 index b434c20d3..000000000 --- a/libc/nt/KernelBase/_invalid_parameter.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__invalid_parameter,_invalid_parameter,1844 diff --git a/libc/nt/KernelBase/_onexit.s b/libc/nt/KernelBase/_onexit.s deleted file mode 100644 index 4c98622e0..000000000 --- a/libc/nt/KernelBase/_onexit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__onexit,_onexit,1846 diff --git a/libc/nt/KernelBase/_purecall.s b/libc/nt/KernelBase/_purecall.s deleted file mode 100644 index d936fb19b..000000000 --- a/libc/nt/KernelBase/_purecall.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__purecall,_purecall,1847 diff --git a/libc/nt/KernelBase/_time64.s b/libc/nt/KernelBase/_time64.s deleted file mode 100644 index 92b461fc3..000000000 --- a/libc/nt/KernelBase/_time64.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp__time64,_time64,1848 diff --git a/libc/nt/KernelBase/atexit.s b/libc/nt/KernelBase/atexit.s deleted file mode 100644 index c7e24b536..000000000 --- a/libc/nt/KernelBase/atexit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_atexit,atexit,1849 diff --git a/libc/nt/KernelBase/exit.s b/libc/nt/KernelBase/exit.s deleted file mode 100644 index 74b618985..000000000 --- a/libc/nt/KernelBase/exit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_exit,exit,1850 diff --git a/libc/nt/KernelBase/hgets.s b/libc/nt/KernelBase/hgets.s deleted file mode 100644 index 819fbd41a..000000000 --- a/libc/nt/KernelBase/hgets.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_hgets,hgets,1851 diff --git a/libc/nt/KernelBase/hwprintf.s b/libc/nt/KernelBase/hwprintf.s deleted file mode 100644 index e9a5edd22..000000000 --- a/libc/nt/KernelBase/hwprintf.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp KernelBase,__imp_hwprintf,hwprintf,1852 diff --git a/libc/nt/MsWSock/AcceptEx.s b/libc/nt/MsWSock/AcceptEx.s index 430f96840..e70b16a7d 100644 --- a/libc/nt/MsWSock/AcceptEx.s +++ b/libc/nt/MsWSock/AcceptEx.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp MsWSock,__imp_AcceptEx,AcceptEx,1 +.imp MsWSock,__imp_AcceptEx,AcceptEx,0 .text.windows AcceptEx: diff --git a/libc/nt/MsWSock/DisconnectEx.s b/libc/nt/MsWSock/DisconnectEx.s new file mode 100644 index 000000000..18b9b8605 --- /dev/null +++ b/libc/nt/MsWSock/DisconnectEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp MsWSock,__imp_DisconnectEx,DisconnectEx,0 + + .text.windows +DisconnectEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DisconnectEx(%rip),%rax + jmp __sysv2nt + .endfn DisconnectEx,globl + .previous diff --git a/libc/nt/MsWSock/GetAcceptExSockaddrs.s b/libc/nt/MsWSock/GetAcceptExSockaddrs.s index 0aad36d0a..d46558a6c 100644 --- a/libc/nt/MsWSock/GetAcceptExSockaddrs.s +++ b/libc/nt/MsWSock/GetAcceptExSockaddrs.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp MsWSock,__imp_GetAcceptExSockaddrs,GetAcceptExSockaddrs,4 +.imp MsWSock,__imp_GetAcceptExSockaddrs,GetAcceptExSockaddrs,0 .text.windows GetAcceptExSockaddrs: diff --git a/libc/nt/MsWSock/TransmitFile.s b/libc/nt/MsWSock/TransmitFile.s index f4c666852..a6c40bbe5 100644 --- a/libc/nt/MsWSock/TransmitFile.s +++ b/libc/nt/MsWSock/TransmitFile.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp MsWSock,__imp_TransmitFile,TransmitFile,53 +.imp MsWSock,__imp_TransmitFile,TransmitFile,0 .text.windows TransmitFile: diff --git a/libc/nt/MsWSock/WSARecvEx.s b/libc/nt/MsWSock/WSARecvEx.s index 1b4604946..25ad67732 100644 --- a/libc/nt/MsWSock/WSARecvEx.s +++ b/libc/nt/MsWSock/WSARecvEx.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" -.imp MsWSock,__imp_WSARecvEx,WSARecvEx,54 +.imp MsWSock,__imp_WSARecvEx,WSARecvEx,0 + + .text.windows +WSARecvEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSARecvEx(%rip),%rax + jmp __sysv2nt + .endfn WSARecvEx,globl + .previous diff --git a/libc/nt/PowerProf/SetSuspendState.s b/libc/nt/PowrProf/SetSuspendState.s similarity index 78% rename from libc/nt/PowerProf/SetSuspendState.s rename to libc/nt/PowrProf/SetSuspendState.s index 1cc2efb42..51b532fa1 100644 --- a/libc/nt/PowerProf/SetSuspendState.s +++ b/libc/nt/PowrProf/SetSuspendState.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp PowerProf,__imp_SetSuspendState,SetSuspendState,0 +.imp PowrProf,__imp_SetSuspendState,SetSuspendState,0 .text.windows SetSuspendState: diff --git a/libc/nt/advapi32/ImpersonateSelf.s b/libc/nt/advapi32/ImpersonateSelf.s index 1410e1d9c..454bd1f2a 100644 --- a/libc/nt/advapi32/ImpersonateSelf.s +++ b/libc/nt/advapi32/ImpersonateSelf.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp advapi32,__imp_ImpersonateSelf,ImpersonateSelf,0 + + .text.windows +ImpersonateSelf: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_ImpersonateSelf(%rip) + leave + ret + .endfn ImpersonateSelf,globl + .previous diff --git a/libc/nt/advapi32/RegisterEventSourceA.s b/libc/nt/advapi32/RegisterEventSourceA.s deleted file mode 100644 index e742c3632..000000000 --- a/libc/nt/advapi32/RegisterEventSourceA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_RegisterEventSourceA,RegisterEventSourceA,1686 - - .text.windows -RegisterEventSourceA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_RegisterEventSourceA(%rip),%rax - jmp __sysv2nt - .endfn RegisterEventSourceA,globl - .previous diff --git a/libc/nt/advapi32/RegisterServiceCtrlHandlerA.s b/libc/nt/advapi32/RegisterServiceCtrlHandlerA.s deleted file mode 100644 index 4b29b24d7..000000000 --- a/libc/nt/advapi32/RegisterServiceCtrlHandlerA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_RegisterServiceCtrlHandlerA,RegisterServiceCtrlHandlerA,1689 diff --git a/libc/nt/advapi32/RegisterServiceCtrlHandlerExA.s b/libc/nt/advapi32/RegisterServiceCtrlHandlerExA.s deleted file mode 100644 index 7242f2568..000000000 --- a/libc/nt/advapi32/RegisterServiceCtrlHandlerExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_RegisterServiceCtrlHandlerExA,RegisterServiceCtrlHandlerExA,1690 diff --git a/libc/nt/advapi32/ReportEventA.s b/libc/nt/advapi32/ReportEventA.s index fb61edaef..2f2133b73 100644 --- a/libc/nt/advapi32/ReportEventA.s +++ b/libc/nt/advapi32/ReportEventA.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_ReportEventA,ReportEventA,1704 +.imp advapi32,__imp_ReportEventA,ReportEventA,0 .text.windows ReportEventA: diff --git a/libc/nt/advapi32/ReportEventW.s b/libc/nt/advapi32/ReportEventW.s index 683e07733..e96ea8e7a 100644 --- a/libc/nt/advapi32/ReportEventW.s +++ b/libc/nt/advapi32/ReportEventW.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_ReportEventW,ReportEventW,1705 +.imp advapi32,__imp_ReportEventW,ReportEventW,0 .text.windows ReportEvent: diff --git a/libc/nt/advapi32/RevertToSelf.s b/libc/nt/advapi32/RevertToSelf.s index 9b19851fa..982195652 100644 --- a/libc/nt/advapi32/RevertToSelf.s +++ b/libc/nt/advapi32/RevertToSelf.s @@ -1,2 +1,14 @@ .include "o/libc/nt/codegen.inc" .imp advapi32,__imp_RevertToSelf,RevertToSelf,0 + + .text.windows +RevertToSelf: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_RevertToSelf(%rip) + leave + ret + .endfn RevertToSelf,globl + .previous diff --git a/libc/nt/advapi32/SetEntriesInAccessListA.s b/libc/nt/advapi32/SetEntriesInAccessListA.s deleted file mode 100644 index 34b06c94f..000000000 --- a/libc/nt/advapi32/SetEntriesInAccessListA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_SetEntriesInAccessListA,SetEntriesInAccessListA,1726 diff --git a/libc/nt/advapi32/SetEntriesInAclA.s b/libc/nt/advapi32/SetEntriesInAclA.s deleted file mode 100644 index 72c39dd4d..000000000 --- a/libc/nt/advapi32/SetEntriesInAclA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_SetEntriesInAclA,SetEntriesInAclA,1728 diff --git a/libc/nt/advapi32/SetEntriesInAuditListA.s b/libc/nt/advapi32/SetEntriesInAuditListA.s deleted file mode 100644 index 90ce4fcb2..000000000 --- a/libc/nt/advapi32/SetEntriesInAuditListA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_SetEntriesInAuditListA,SetEntriesInAuditListA,1730 diff --git a/libc/nt/advapi32/SetFileSecurityA.s b/libc/nt/advapi32/SetFileSecurityA.s deleted file mode 100644 index 192a2f425..000000000 --- a/libc/nt/advapi32/SetFileSecurityA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_SetFileSecurityA,SetFileSecurityA,1732 diff --git a/libc/nt/advapi32/SetNamedSecurityInfoA.s b/libc/nt/advapi32/SetNamedSecurityInfoA.s deleted file mode 100644 index 21387c686..000000000 --- a/libc/nt/advapi32/SetNamedSecurityInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_SetNamedSecurityInfoA,SetNamedSecurityInfoA,1737 diff --git a/libc/nt/advapi32/SetNamedSecurityInfoExA.s b/libc/nt/advapi32/SetNamedSecurityInfoExA.s deleted file mode 100644 index 07513a914..000000000 --- a/libc/nt/advapi32/SetNamedSecurityInfoExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_SetNamedSecurityInfoExA,SetNamedSecurityInfoExA,1738 diff --git a/libc/nt/advapi32/SetSecurityInfoExA.s b/libc/nt/advapi32/SetSecurityInfoExA.s deleted file mode 100644 index a4e0c9e1c..000000000 --- a/libc/nt/advapi32/SetSecurityInfoExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_SetSecurityInfoExA,SetSecurityInfoExA,1751 diff --git a/libc/nt/advapi32/StartServiceA.s b/libc/nt/advapi32/StartServiceA.s deleted file mode 100644 index d9a3aa33c..000000000 --- a/libc/nt/advapi32/StartServiceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_StartServiceA,StartServiceA,1761 diff --git a/libc/nt/advapi32/StartServiceCtrlDispatcherA.s b/libc/nt/advapi32/StartServiceCtrlDispatcherA.s deleted file mode 100644 index db1b7f87e..000000000 --- a/libc/nt/advapi32/StartServiceCtrlDispatcherA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_StartServiceCtrlDispatcherA,StartServiceCtrlDispatcherA,1762 diff --git a/libc/nt/advapi32/StartTraceA.s b/libc/nt/advapi32/StartTraceA.s deleted file mode 100644 index 5f0650d2b..000000000 --- a/libc/nt/advapi32/StartTraceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_StartTraceA,StartTraceA,1765 diff --git a/libc/nt/advapi32/StopTraceA.s b/libc/nt/advapi32/StopTraceA.s deleted file mode 100644 index 4e193a658..000000000 --- a/libc/nt/advapi32/StopTraceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_StopTraceA,StopTraceA,1767 diff --git a/libc/nt/advapi32/TreeResetNamedSecurityInfoA.s b/libc/nt/advapi32/TreeResetNamedSecurityInfoA.s deleted file mode 100644 index 261cf0aca..000000000 --- a/libc/nt/advapi32/TreeResetNamedSecurityInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_TreeResetNamedSecurityInfoA,TreeResetNamedSecurityInfoA,1813 diff --git a/libc/nt/advapi32/TreeSetNamedSecurityInfoA.s b/libc/nt/advapi32/TreeSetNamedSecurityInfoA.s deleted file mode 100644 index 04277e6be..000000000 --- a/libc/nt/advapi32/TreeSetNamedSecurityInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_TreeSetNamedSecurityInfoA,TreeSetNamedSecurityInfoA,1815 diff --git a/libc/nt/advapi32/TrusteeAccessToObjectA.s b/libc/nt/advapi32/TrusteeAccessToObjectA.s deleted file mode 100644 index 94539a77d..000000000 --- a/libc/nt/advapi32/TrusteeAccessToObjectA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_TrusteeAccessToObjectA,TrusteeAccessToObjectA,1817 diff --git a/libc/nt/advapi32/UpdateTraceA.s b/libc/nt/advapi32/UpdateTraceA.s deleted file mode 100644 index f67a6581c..000000000 --- a/libc/nt/advapi32/UpdateTraceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_UpdateTraceA,UpdateTraceA,1823 diff --git a/libc/nt/advapi32/UsePinForEncryptedFilesA.s b/libc/nt/advapi32/UsePinForEncryptedFilesA.s deleted file mode 100644 index 649519de6..000000000 --- a/libc/nt/advapi32/UsePinForEncryptedFilesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_UsePinForEncryptedFilesA,UsePinForEncryptedFilesA,1825 diff --git a/libc/nt/advapi32/WmiDevInstToInstanceNameA.s b/libc/nt/advapi32/WmiDevInstToInstanceNameA.s deleted file mode 100644 index 5a659bc55..000000000 --- a/libc/nt/advapi32/WmiDevInstToInstanceNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiDevInstToInstanceNameA,WmiDevInstToInstanceNameA,1829 diff --git a/libc/nt/advapi32/WmiExecuteMethodA.s b/libc/nt/advapi32/WmiExecuteMethodA.s deleted file mode 100644 index 8401c52f0..000000000 --- a/libc/nt/advapi32/WmiExecuteMethodA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiExecuteMethodA,WmiExecuteMethodA,1832 diff --git a/libc/nt/advapi32/WmiFileHandleToInstanceNameA.s b/libc/nt/advapi32/WmiFileHandleToInstanceNameA.s deleted file mode 100644 index aeff46af1..000000000 --- a/libc/nt/advapi32/WmiFileHandleToInstanceNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiFileHandleToInstanceNameA,WmiFileHandleToInstanceNameA,1834 diff --git a/libc/nt/advapi32/WmiMofEnumerateResourcesA.s b/libc/nt/advapi32/WmiMofEnumerateResourcesA.s deleted file mode 100644 index 7a92984b0..000000000 --- a/libc/nt/advapi32/WmiMofEnumerateResourcesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiMofEnumerateResourcesA,WmiMofEnumerateResourcesA,1837 diff --git a/libc/nt/advapi32/WmiNotificationRegistrationA.s b/libc/nt/advapi32/WmiNotificationRegistrationA.s deleted file mode 100644 index 0aabe8bb1..000000000 --- a/libc/nt/advapi32/WmiNotificationRegistrationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiNotificationRegistrationA,WmiNotificationRegistrationA,1839 diff --git a/libc/nt/advapi32/WmiQueryAllDataA.s b/libc/nt/advapi32/WmiQueryAllDataA.s deleted file mode 100644 index 5bb41324c..000000000 --- a/libc/nt/advapi32/WmiQueryAllDataA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiQueryAllDataA,WmiQueryAllDataA,1842 diff --git a/libc/nt/advapi32/WmiQueryAllDataMultipleA.s b/libc/nt/advapi32/WmiQueryAllDataMultipleA.s deleted file mode 100644 index 1a19806a9..000000000 --- a/libc/nt/advapi32/WmiQueryAllDataMultipleA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiQueryAllDataMultipleA,WmiQueryAllDataMultipleA,1843 diff --git a/libc/nt/advapi32/WmiQuerySingleInstanceA.s b/libc/nt/advapi32/WmiQuerySingleInstanceA.s deleted file mode 100644 index e0dcfb34e..000000000 --- a/libc/nt/advapi32/WmiQuerySingleInstanceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiQuerySingleInstanceA,WmiQuerySingleInstanceA,1847 diff --git a/libc/nt/advapi32/WmiQuerySingleInstanceMultipleA.s b/libc/nt/advapi32/WmiQuerySingleInstanceMultipleA.s deleted file mode 100644 index 90a9ce263..000000000 --- a/libc/nt/advapi32/WmiQuerySingleInstanceMultipleA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiQuerySingleInstanceMultipleA,WmiQuerySingleInstanceMultipleA,1848 diff --git a/libc/nt/advapi32/WmiReceiveNotificationsA.s b/libc/nt/advapi32/WmiReceiveNotificationsA.s deleted file mode 100644 index de7870f3a..000000000 --- a/libc/nt/advapi32/WmiReceiveNotificationsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiReceiveNotificationsA,WmiReceiveNotificationsA,1851 diff --git a/libc/nt/advapi32/WmiSetSingleInstanceA.s b/libc/nt/advapi32/WmiSetSingleInstanceA.s deleted file mode 100644 index 62ad82eb8..000000000 --- a/libc/nt/advapi32/WmiSetSingleInstanceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiSetSingleInstanceA,WmiSetSingleInstanceA,1853 diff --git a/libc/nt/advapi32/WmiSetSingleItemA.s b/libc/nt/advapi32/WmiSetSingleItemA.s deleted file mode 100644 index d13509e22..000000000 --- a/libc/nt/advapi32/WmiSetSingleItemA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp advapi32,__imp_WmiSetSingleItemA,WmiSetSingleItemA,1855 diff --git a/libc/nt/comdlg32/ChooseColorA.s b/libc/nt/comdlg32/ChooseColorA.s deleted file mode 100644 index 0e02c3539..000000000 --- a/libc/nt/comdlg32/ChooseColorA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_ChooseColorA,ChooseColorA,102 - - .text.windows -ChooseColorA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_ChooseColorA(%rip) - leave - ret - .endfn ChooseColorA,globl - .previous diff --git a/libc/nt/comdlg32/ChooseFontA.s b/libc/nt/comdlg32/ChooseFontA.s deleted file mode 100644 index 91a441c21..000000000 --- a/libc/nt/comdlg32/ChooseFontA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_ChooseFontA,ChooseFontA,104 - - .text.windows -ChooseFontA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_ChooseFontA(%rip) - leave - ret - .endfn ChooseFontA,globl - .previous diff --git a/libc/nt/comdlg32/FindTextA.s b/libc/nt/comdlg32/FindTextA.s deleted file mode 100644 index 29ac262ce..000000000 --- a/libc/nt/comdlg32/FindTextA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_FindTextA,FindTextA,109 diff --git a/libc/nt/comdlg32/GetFileTitleA.s b/libc/nt/comdlg32/GetFileTitleA.s deleted file mode 100644 index 88a1fcc09..000000000 --- a/libc/nt/comdlg32/GetFileTitleA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_GetFileTitleA,GetFileTitleA,111 - - .text.windows -GetFileTitleA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_GetFileTitleA(%rip),%rax - jmp __sysv2nt - .endfn GetFileTitleA,globl - .previous diff --git a/libc/nt/comdlg32/GetOpenFileNameA.s b/libc/nt/comdlg32/GetOpenFileNameA.s deleted file mode 100644 index 5b628459b..000000000 --- a/libc/nt/comdlg32/GetOpenFileNameA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_GetOpenFileNameA,GetOpenFileNameA,113 - - .text.windows -GetOpenFileNameA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_GetOpenFileNameA(%rip) - leave - ret - .endfn GetOpenFileNameA,globl - .previous diff --git a/libc/nt/comdlg32/GetSaveFileNameA.s b/libc/nt/comdlg32/GetSaveFileNameA.s deleted file mode 100644 index b390319d8..000000000 --- a/libc/nt/comdlg32/GetSaveFileNameA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_GetSaveFileNameA,GetSaveFileNameA,115 - - .text.windows -GetSaveFileNameA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_GetSaveFileNameA(%rip) - leave - ret - .endfn GetSaveFileNameA,globl - .previous diff --git a/libc/nt/comdlg32/PageSetupDlgA.s b/libc/nt/comdlg32/PageSetupDlgA.s deleted file mode 100644 index 0e12a033b..000000000 --- a/libc/nt/comdlg32/PageSetupDlgA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_PageSetupDlgA,PageSetupDlgA,118 diff --git a/libc/nt/comdlg32/PrintDlgA.s b/libc/nt/comdlg32/PrintDlgA.s deleted file mode 100644 index b70082525..000000000 --- a/libc/nt/comdlg32/PrintDlgA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_PrintDlgA,PrintDlgA,120 - - .text.windows -PrintDlgA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_PrintDlgA(%rip) - leave - ret - .endfn PrintDlgA,globl - .previous diff --git a/libc/nt/comdlg32/PrintDlgExA.s b/libc/nt/comdlg32/PrintDlgExA.s deleted file mode 100644 index 37b1ae864..000000000 --- a/libc/nt/comdlg32/PrintDlgExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_PrintDlgExA,PrintDlgExA,121 diff --git a/libc/nt/comdlg32/ReplaceTextA.s b/libc/nt/comdlg32/ReplaceTextA.s deleted file mode 100644 index 1451440c6..000000000 --- a/libc/nt/comdlg32/ReplaceTextA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_ReplaceTextA,ReplaceTextA,124 - - .text.windows -ReplaceTextA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_ReplaceTextA(%rip) - leave - ret - .endfn ReplaceTextA,globl - .previous diff --git a/libc/nt/comdlg32/dwLBSubclass.s b/libc/nt/comdlg32/dwLBSubclass.s deleted file mode 100644 index 9abed9421..000000000 --- a/libc/nt/comdlg32/dwLBSubclass.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_dwLBSubclass,dwLBSubclass,128 diff --git a/libc/nt/comdlg32/dwOKSubclass.s b/libc/nt/comdlg32/dwOKSubclass.s deleted file mode 100644 index b760c18e6..000000000 --- a/libc/nt/comdlg32/dwOKSubclass.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp comdlg32,__imp_dwOKSubclass,dwOKSubclass,129 diff --git a/libc/nt/createfile.h b/libc/nt/createfile.h index 98b7d11e1..9030fb3c4 100644 --- a/libc/nt/createfile.h +++ b/libc/nt/createfile.h @@ -18,6 +18,9 @@ int64_t CreateFileA( uint32_t dwFlagsAndAttributes, /* libc/nt/enum/fileflagandattributes.h */ int64_t opt_hTemplateFile) paramsnonnull((1)); +int GetNtOpenFlags(int flags, int mode, uint32_t *out_perm, uint32_t *out_share, + uint32_t *out_disp, uint32_t *out_attr); + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_NT_CREATEFILE_H_ */ diff --git a/libc/nt/enum/accessmask.h b/libc/nt/enum/accessmask.h index 44cfeb019..da67f0682 100644 --- a/libc/nt/enum/accessmask.h +++ b/libc/nt/enum/accessmask.h @@ -20,38 +20,38 @@ * }; * }; */ -#define kNtGenericRead 0x80000000u -#define kNtGenericWrite 0x40000000u -#define kNtGenericExecute 0x20000000u -#define kNtGenericAll 0x10000000u -#define kNtDelete 0x00010000u -#define kNtReadControl 0x00020000u -#define kNtWriteDac 0x00040000u -#define kNtWriteOwner 0x00080000u -#define kNtSynchronize 0x00100000u +#define kNtGenericRead 0x80000000u +#define kNtGenericWrite 0x40000000u +#define kNtGenericExecute 0x20000000u +#define kNtGenericAll 0x10000000u +#define kNtDelete 0x00010000u +#define kNtReadControl 0x00020000u +#define kNtWriteDac 0x00040000u +#define kNtWriteOwner 0x00080000u +#define kNtSynchronize 0x00100000u #define kNtStandardRightsRequired 0x000F0000u -#define kNtStandardRightsRead kNtReadControl -#define kNtStandardRightsWrite kNtReadControl -#define kNtStandardRightsExecute kNtReadControl -#define kNtStandardRightsAll 0x001F0000u -#define kNtSpecificRightsAll 0x0000FFFFu -#define kNtAccessSystemSecurity 0x01000000u -#define kNtMaximumAllowed 0x02000000u -#define kNtFileReadData 0x0001u -#define kNtFileListDirectory 0x0001u -#define kNtFileWriteData 0x0002u -#define kNtFileAddFile 0x0002u -#define kNtFileAppendData 0x0004u -#define kNtFileAddSubdirectory 0x0004u +#define kNtStandardRightsRead kNtReadControl +#define kNtStandardRightsWrite kNtReadControl +#define kNtStandardRightsExecute kNtReadControl +#define kNtStandardRightsAll 0x001F0000u +#define kNtSpecificRightsAll 0x0000FFFFu +#define kNtAccessSystemSecurity 0x01000000u +#define kNtMaximumAllowed 0x02000000u +#define kNtFileReadData 0x0001u +#define kNtFileListDirectory 0x0001u +#define kNtFileWriteData 0x0002u +#define kNtFileAddFile 0x0002u +#define kNtFileAppendData 0x0004u +#define kNtFileAddSubdirectory 0x0004u #define kNtFileCreatePipeInstance 0x0004u -#define kNtFileReadEa 0x0008u -#define kNtFileWriteEa 0x0010u -#define kNtFileExecute 0x0020u -#define kNtFileTraverse 0x0020u -#define kNtFileDeleteChild 0x0040u -#define kNtFileReadAttributes 0x0080u -#define kNtFileWriteAttributes 0x0100u -#define kNtFileAllAccess (kNtStandardRightsRequired | kNtSynchronize | 0x1FFu) +#define kNtFileReadEa 0x0008u +#define kNtFileWriteEa 0x0010u +#define kNtFileExecute 0x0020u +#define kNtFileTraverse 0x0020u +#define kNtFileDeleteChild 0x0040u +#define kNtFileReadAttributes 0x0080u +#define kNtFileWriteAttributes 0x0100u +#define kNtFileAllAccess (kNtStandardRightsRequired | kNtSynchronize | 0x1FFu) #define kNtFileGenericRead \ (kNtStandardRightsRead | kNtFileReadData | kNtFileReadAttributes | \ kNtFileReadEa | kNtSynchronize) @@ -61,21 +61,21 @@ #define kNtFileGenericExecute \ (kNtStandardRightsExecute | kNtFileReadAttributes | kNtFileExecute | \ kNtSynchronize) -#define kNtTokenAssignPrimary 0x0001u -#define kNtTokenDuplicate 0x0002u -#define kNtTokenImpersonate 0x0004u -#define kNtTokenQuery 0x0008u -#define kNtTokenQuerySource 0x0010u +#define kNtTokenAssignPrimary 0x0001u +#define kNtTokenDuplicate 0x0002u +#define kNtTokenImpersonate 0x0004u +#define kNtTokenQuery 0x0008u +#define kNtTokenQuerySource 0x0010u #define kNtTokenAdjustPrivileges 0x0020u -#define kNtTokenAdjustGroups 0x0040u -#define kNtTokenAdjustDefault 0x0080u -#define kNtTokenAdjustSessionid 0x0100u +#define kNtTokenAdjustGroups 0x0040u +#define kNtTokenAdjustDefault 0x0080u +#define kNtTokenAdjustSessionid 0x0100u #define kNtTokenAllAccessP \ (kNtStandardRightsRequired | kNtTokenAssignPrimary | kNtTokenDuplicate | \ kNtTokenImpersonate | kNtTokenQuery | kNtTokenQuerySource | \ kNtTokenAdjustPrivileges | kNtTokenAdjustGroups | kNtTokenAdjustDefault) #define kNtTokenAllAccess kNtTokenAllAccessP | kNtTokenAdjustSessionid -#define kNtTokenRead kNtStandardRightsRead | kNtTokenQuery +#define kNtTokenRead kNtStandardRightsRead | kNtTokenQuery #define kNtTokenWrite \ (kNtStandardRightsWrite | kNtTokenAdjustPrivileges | kNtTokenAdjustGroups | \ kNtTokenAdjustDefault) @@ -83,6 +83,6 @@ #define kNtTokenTrustConstraintMask \ (kNtStandardRightsRead | kNtTokenQuery | kNtTokenQuerySource) #define kNtTokenAccessPseudoHandleWin8 kNtTokenQuery | kNtTokenQuerySource -#define kNtTokenAccessPseudoHandle kNtTokenAccessPseudoHandleWin8 +#define kNtTokenAccessPseudoHandle kNtTokenAccessPseudoHandleWin8 #endif /* COSMOPOLITAN_LIBC_NT_ENUM_ACCESSMASK_H_ */ diff --git a/libc/nt/enum/heap.h b/libc/nt/enum/heap.h new file mode 100644 index 000000000..f7ccc0915 --- /dev/null +++ b/libc/nt/enum/heap.h @@ -0,0 +1,9 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_HEAP_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_HEAP_H_ + +#define kNtHeapNoSerialize 1 +#define kNtHeapGenerateExceptions 4 +#define kNtHeapZeroMemory 8 +#define kNtHeapReallocInPlaceOnly 16 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_HEAP_H_ */ diff --git a/libc/nt/enum/movefileexflags.h b/libc/nt/enum/movefileexflags.h index 190207162..cf2976f0d 100644 --- a/libc/nt/enum/movefileexflags.h +++ b/libc/nt/enum/movefileexflags.h @@ -4,8 +4,8 @@ #define kNtMovefileReplaceExisting 1 #define kNtMovefileCopyAllowed 2 #define kNtMovefileDelayUntilReboot 4 +#define kNtMovefileWriteThrough 8 #define kNtMovefileCreateHardlink 16 #define kNtMovefileFailIfNotTrackable 32 -#define kNtMovefileWriteThrough 8 #endif /* COSMOPOLITAN_LIBC_NT_ENUM_MOVEFILEEXFLAGS_H_ */ diff --git a/libc/nt/enum/pageflags.h b/libc/nt/enum/pageflags.h index ba76a0db4..5cef3a2fa 100644 --- a/libc/nt/enum/pageflags.h +++ b/libc/nt/enum/pageflags.h @@ -2,25 +2,25 @@ #define COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_ /* Pick One */ -#define kNtPageNoaccess 0x01 -#define kNtPageReadonly 0x02 -#define kNtPageReadwrite 0x04 -#define kNtPageWritecopy 0x08 -#define kNtPageExecute 0x10 -#define kNtPageExecuteRead 0x20 -#define kNtPageExecuteReadwrite 0x40 -#define kNtPageExecuteWritecopy 0x80 -#define kNtPageGuard 0x100 -#define kNtPageNocache 0x200 -#define kNtPageWritecombine 0x400 +#define kNtPageNoaccess 0x001 +#define kNtPageReadonly 0x002 +#define kNtPageReadwrite 0x004 +#define kNtPageWritecopy 0x008 +#define kNtPageExecute 0x010 +#define kNtPageExecuteRead 0x020 +#define kNtPageExecuteReadwrite 0x040 +#define kNtPageExecuteWritecopy 0x080 +#define kNtPageGuard 0x100 +#define kNtPageNocache 0x200 +#define kNtPageWritecombine 0x400 /* These may be OR'd */ -#define kNtSecReserve 0x4000000 -#define kNtSecCommit 0x8000000 /* ←default */ -#define kNtSecImage 0x1000000 +#define kNtSecReserve 0x04000000 +#define kNtSecCommit 0x08000000 /* default */ #define kNtSecImageNoExecute 0x11000000 -#define kNtSecLargePages 0x80000000 -#define kNtSecNocache 0x10000000 -#define kNtSecWritecombine 0x40000000 +#define kNtSecImage 0x01000000 +#define kNtSecNocache 0x10000000 +#define kNtSecLargePages 0x80000000 +#define kNtSecWritecombine 0x40000000 #endif /* COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_ */ diff --git a/libc/nt/enum/pdh.h b/libc/nt/enum/pdh.h new file mode 100644 index 000000000..b4e2f50e8 --- /dev/null +++ b/libc/nt/enum/pdh.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_PDH_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_PDH_H_ + +#define kNtPdhFmtRaw 0x00000010u +#define kNtPdhFmtAnsi 0x00000020u +#define kNtPdhFmtUnicode 0x00000040u +#define kNtPdhFmtLong 0x00000100u +#define kNtPdhFmtDouble 0x00000200u +#define kNtPdhFmtLarge 0x00000400u +#define kNtPdhFmtNoscale 0x00001000u +#define kNtPdhFmt1000 0x00002000u +#define kNtPdhFmtNodata 0x00004000u +#define kNtPdhFmtNocap100 0x00008000u +#define kNtPerfDetailCostly 0x00010000u +#define kNtPerfDetailStandard 0x0000FFFFu + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PDH_H_ */ diff --git a/libc/nt/enum/sio.h b/libc/nt/enum/sio.h index 9993718ba..b8984aeeb 100644 --- a/libc/nt/enum/sio.h +++ b/libc/nt/enum/sio.h @@ -1,7 +1,68 @@ #ifndef COSMOPOLITAN_LIBC_NT_ENUM_SIO_H_ #define COSMOPOLITAN_LIBC_NT_ENUM_SIO_H_ -#define kNtSioBspHandlePoll 0x4800001D -#define kNtSioBaseHandle 0x48000022 +#define kNtSioAbsorbRtralert 0x98000005u +#define kNtSioAcquirePortReservation 0x98000064u +#define kNtSioAddressListChange 0x28000017u +#define kNtSioAddressListQuery 0x48000016u +#define kNtSioAddressListSort 0xc8000019u +#define kNtSioApplyTransportSetting 0x98000013u +#define kNtSioAssociateHandle 0x88000001u +#define kNtSioAssociatePortReservation 0x98000066u +#define kNtSioBaseHandle 0x48000022u +#define kNtSioBspHandlePoll 0x4800001Du +#define kNtSioDeletePeerTargetName 0x980000cbu +#define kNtSioEnableCircularQueueing 0x28000002u +#define kNtSioFindRoute 0x48000003u +#define kNtSioFlush 0x28000004u +#define kNtSioGetBroadcastAddress 0x48000005u +#define kNtSioGetExtensionFunctionPointer 0xc8000006u +#define kNtSioGetGroupQos 0xc8000008u +#define kNtSioGetInterfaceList 0x4008747fu +#define kNtSioGetMultipleExtensionFunctionPointer 0xc8000024u +#define kNtSioGetQos 0xc8000007u +#define kNtSioIndexAddMcast 0x9800000au +#define kNtSioIndexBind 0x98000008u +#define kNtSioIndexDelMcast 0x9800000bu +#define kNtSioIndexMcastif 0x98000009u +#define kNtSioKeepaliveVals 0x98000004u +#define kNtSioLimitBroadcasts 0x98000007u +#define kNtSioLoopbackFastPath 0x98000010u +#define kNtSioMulticastScope 0x8800000au +#define kNtSioMultipointLoopback 0x88000009u +#define kNtSioQueryRssProcessorInfo 0x48000025u +#define kNtSioQueryRssScalabilityInfo 0x580000d2u +#define kNtSioQuerySecurity 0xd80000c9u +#define kNtSioQueryTargetPnpHandle 0x48000018u +#define kNtSioQueryTransportSetting 0x98000014u +#define kNtSioQueryWfpAleEndpointHandle 0x580000cdu +#define kNtSioQueryWfpConnectionRedirectContext 0x980000ddu +#define kNtSioQueryWfpConnectionRedirectRecords 0x980000dcu +#define kNtSioRcvall 0x98000001u +#define kNtSioRcvallIf 0x9800000eu +#define kNtSioRcvallIgmpmcast 0x98000003u +#define kNtSioRcvallMcast 0x98000002u +#define kNtSioRcvallMcastIf 0x9800000du +#define kNtSioReleasePortReservation 0x98000065u +#define kNtSioReserved1 0x8800001au +#define kNtSioReserved2 0x88000021u +#define kNtSioRoutingInterfaceChange 0x88000015u +#define kNtSioRoutingInterfaceQuery 0xc8000014u +#define kNtSioSetGroupQos 0x8800000cu +#define kNtSioSetPeerTargetName 0x980000cau +#define kNtSioSetPriorityHint 0x98000018u +#define kNtSioSetQos 0x8800000bu +#define kNtSioSetSecurity 0x980000c8u +#define kNtSioSetWfpConnectionRedirectRecords 0x980000deu +#define kNtSioSocketCloseNotify 0x9800000du +#define kNtSioSocketUsageNotification 0x980000ccu +#define kNtSioTcpInfo 0xd8000027u +#define kNtSioTcpInitialRto 0x98000011u +#define kNtSioTcpSetAckFrequency 0x98000017u +#define kNtSioTcpSetIcw 0x98000016u +#define kNtSioTranslateHandle 0xc800000du +#define kNtSioUcastIf 0x98000006u +#define kNtSioUdpConnreset 0x9800000cu +#define kNtSioUdpNetreset 0x9800000fu #endif /* COSMOPOLITAN_LIBC_NT_ENUM_SIO_H_ */ diff --git a/libc/nt/enum/symboliclink.h b/libc/nt/enum/symboliclink.h new file mode 100644 index 000000000..d19da7e04 --- /dev/null +++ b/libc/nt/enum/symboliclink.h @@ -0,0 +1,7 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SYMBOLICLINK_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SYMBOLICLINK_H_ + +#define kNtSymbolicLinkFlagDirectory 1 +#define kNtSymbolicLinkFlagAllowUnprivilegedCreate 2 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SYMBOLICLINK_H_ */ diff --git a/libc/nt/enum/wsa.h b/libc/nt/enum/wsa.h new file mode 100644 index 000000000..869cbc966 --- /dev/null +++ b/libc/nt/enum/wsa.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_WSA_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_WSA_H_ +#include "libc/nt/errors.h" + +#define kNtWsaInvalidHandle kNtErrorInvalidHandle +#define kNtWsaNotEnoughMemory kNtErrorNotEnoughMemory +#define kNtWsaInvalidParameter kNtErrorInvalidParameter +#define kNtWsaIoPending kNtErrorIoPending +#define kNtWsaIoIncomplete kNtErrorIoIncomplete +#define kNtWsaOperationAborted kNtErrorOperationAborted + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_WSA_H_ */ diff --git a/libc/nt/enum/wsaid.h b/libc/nt/enum/wsaid.h new file mode 100644 index 000000000..4fda23aa2 --- /dev/null +++ b/libc/nt/enum/wsaid.h @@ -0,0 +1,71 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_WSAID_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_WSAID_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define WSAID_WSAPOLL \ + { \ + 0x18C76F85, 0xDC66, 0x4964, { \ + 0x97, 0x2E, 0x23, 0xC2, 0x72, 0x38, 0x31, 0x2B \ + } \ + } + +#define WSAID_WSARECVMSG \ + { \ + 0xf689d7c8, 0x6f1f, 0x436b, { \ + 0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22 \ + } \ + } + +#define WSAID_WSASENDMSG \ + { \ + 0xa441e712, 0x754f, 0x43ca, { \ + 0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d \ + } \ + } + +#define WSAID_CONNECTEX \ + { \ + 0x25a207b9, 0xddf3, 0x4660, { \ + 0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e \ + } \ + } + +#define WSAID_ACCEPTEX \ + { \ + 0xb5367df1, 0xcbac, 0x11cf, { \ + 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 \ + } \ + } + +#define WSAID_GETACCEPTEXSOCKADDRS \ + { \ + 0xb5367df2, 0xcbac, 0x11cf, { \ + 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 \ + } \ + } + +#define WSAID_TRANSMITFILE \ + { \ + 0xb5367df0, 0xcbac, 0x11cf, { \ + 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 \ + } \ + } + +#define WSAID_TRANSMITPACKETS \ + { \ + 0xd9689da0, 0x1f90, 0x11d3, { \ + 0x99, 0x71, 0x00, 0xc0, 0x4f, 0x68, 0xc8, 0x76 \ + } \ + } + +#define WSAID_DISCONNECTEX \ + { \ + 0x7fda2e11, 0x8630, 0x436f, { \ + 0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57 \ + } \ + } + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_WSAID_H_ */ diff --git a/libc/nt/enum/wt.h b/libc/nt/enum/wt.h index 0430e5da3..a79955ea8 100644 --- a/libc/nt/enum/wt.h +++ b/libc/nt/enum/wt.h @@ -1,10 +1,11 @@ #ifndef COSMOPOLITAN_LIBC_NT_ENUM_WT_H_ #define COSMOPOLITAN_LIBC_NT_ENUM_WT_H_ -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -#define kNtWtExecuteonlyonce 8 +#define kNtWtExecutedefault 0x00000000u +#define kNtWtExecuteonlyonce 0x00000008u +#define kNtWtExecuteintimerthread 0x00000020u +#define kNtWtExecuteinpersistentthread 0x00000080u +#define kNtWtExecutelongfunction 0x00000010u +#define kNtWtTransferImpersonation 0𝔵00000100𝔲 -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_NT_ENUM_WT_H_ */ diff --git a/libc/nt/errors.h b/libc/nt/errors.h index d4edd0882..da05e1af2 100644 --- a/libc/nt/errors.h +++ b/libc/nt/errors.h @@ -164,7 +164,7 @@ #define kNtErrorInfloopInRelocChain 202 #define kNtErrorEnvvarNotFound 203 #define kNtErrorNoSignalSent 205 -#define kNtErrorFilenameExcedRange 206 +#define kNtErrorFilenameExcedRange 206 /* ENAMETOOLONG */ #define kNtErrorRing2StackInUse 207 #define kNtErrorMetaExpansionTooLong 208 #define kNtErrorInvalidSignalNumber 209 @@ -194,7 +194,7 @@ #define kNtErrorEaListInconsistent 255 #define kNtErrorNoMoreItems 259 #define kNtErrorCannotCopy 266 -#define kNtErrorDirectory 267 +#define kNtErrorDirectory 267 /* EISDIR */ #define kNtErrorEasDidntFit 275 #define kNtErrorEaFileCorrupt 276 #define kNtErrorEaTableFull 277 @@ -238,7 +238,7 @@ #define kNtErrorNotRedundantStorage 333 #define kNtErrorResidentFileNotSupported 334 #define kNtErrorCompressedFileNotSupported 335 -#define kNtErrorDirectoryNotSupported 336 /* EISDIR */ +#define kNtErrorDirectoryNotSupported 336 #define kNtErrorNotReadFromCopy 337 #define kNtErrorFtWriteFailure 338 #define kNtErrorFtDiScanRequired 339 @@ -1102,7 +1102,7 @@ #define kNtErrorResourceTypeNotFound 1813 #define kNtErrorResourceNameNotFound 1814 #define kNtErrorResourceLangNotFound 1815 -#define kNtErrorNotEnoughQuota 1816 +#define kNtErrorNotEnoughQuota 1816 /* EDQUOT */ #define kNtErrorInvalidTime 1901 #define kNtErrorInvalidFormName 1902 #define kNtErrorInvalidFormSize 1903 diff --git a/libc/nt/events.h b/libc/nt/events.h index d8a60fedf..d9bcce6cf 100644 --- a/libc/nt/events.h +++ b/libc/nt/events.h @@ -51,8 +51,8 @@ int32_t ReportEventA(int64_t handle, uint16_t wType, uint16_t wCategory, uint32_t dwEventID, const char *lpUserId, uint16_t wNumStrings, uint32_t dwDataSize, const char **lpStrings, void **lpRawData); -int64_t RegisterEventSourceA(const char *lpUNCServerName, - const char *lpSourceName); +int64_t RegisterEventSource(const char16_t *lpUNCServerName, + const char16_t *lpSourceName); int32_t DeregisterEventSource(uint64_t handle); int64_t CreateEvent(struct NtSecurityAttributes *lpEventAttributes, diff --git a/libc/nt/files.h b/libc/nt/files.h index 5a8fc1aaa..97c95a83f 100644 --- a/libc/nt/files.h +++ b/libc/nt/files.h @@ -44,8 +44,6 @@ #define kNtDuplicateCloseSource 1 #define kNtDuplicateSameAccess 2 -#define kNtSymbolicLinkFlagDirectory 1 - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -179,7 +177,7 @@ int64_t FindFirstFileEx(const char16_t *lpFileName, int fInfoLevelId, uint32_t dwAdditionalFlags); bool32 FindNextFile(int64_t hFindFile, struct NtWin32FindData *out_lpFindFileData); -bool32 FindClose(int64_t inout_hFindFile); +bool32 FindClose(int64_t hFindFile); int64_t FindFirstVolume(char16_t *out_lpszVolumeName, uint32_t cchBufferLength); bool32 FindNextVolume(int64_t inout_hFindVolume, char16_t *out_lpszVolumeName, diff --git a/libc/nt/gdi32/AddFontResourceA.s b/libc/nt/gdi32/AddFontResourceA.s deleted file mode 100644 index 048bfb16e..000000000 --- a/libc/nt/gdi32/AddFontResourceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_AddFontResourceA,AddFontResourceA,1018 diff --git a/libc/nt/gdi32/AddFontResourceExA.s b/libc/nt/gdi32/AddFontResourceExA.s deleted file mode 100644 index aba91b911..000000000 --- a/libc/nt/gdi32/AddFontResourceExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_AddFontResourceExA,AddFontResourceExA,1019 diff --git a/libc/nt/gdi32/CopyEnhMetaFileA.s b/libc/nt/gdi32/CopyEnhMetaFileA.s deleted file mode 100644 index be38e90bd..000000000 --- a/libc/nt/gdi32/CopyEnhMetaFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CopyEnhMetaFileA,CopyEnhMetaFileA,1052 diff --git a/libc/nt/gdi32/CopyMetaFileA.s b/libc/nt/gdi32/CopyMetaFileA.s deleted file mode 100644 index 6de5a2b64..000000000 --- a/libc/nt/gdi32/CopyMetaFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CopyMetaFileA,CopyMetaFileA,1054 diff --git a/libc/nt/gdi32/CreateColorSpaceA.s b/libc/nt/gdi32/CreateColorSpaceA.s deleted file mode 100644 index f2ad94869..000000000 --- a/libc/nt/gdi32/CreateColorSpaceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateColorSpaceA,CreateColorSpaceA,1061 diff --git a/libc/nt/gdi32/CreateDCA.s b/libc/nt/gdi32/CreateDCA.s deleted file mode 100644 index 0f9f172c4..000000000 --- a/libc/nt/gdi32/CreateDCA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateDCA,CreateDCA,1065 diff --git a/libc/nt/gdi32/CreateEnhMetaFileA.s b/libc/nt/gdi32/CreateEnhMetaFileA.s deleted file mode 100644 index f92acfe0c..000000000 --- a/libc/nt/gdi32/CreateEnhMetaFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateEnhMetaFileA,CreateEnhMetaFileA,1075 diff --git a/libc/nt/gdi32/CreateFontA.s b/libc/nt/gdi32/CreateFontA.s deleted file mode 100644 index b230b8209..000000000 --- a/libc/nt/gdi32/CreateFontA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateFontA,CreateFontA,1077 diff --git a/libc/nt/gdi32/CreateFontIndirectA.s b/libc/nt/gdi32/CreateFontIndirectA.s deleted file mode 100644 index 6d14ad2db..000000000 --- a/libc/nt/gdi32/CreateFontIndirectA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateFontIndirectA,CreateFontIndirectA,1078 diff --git a/libc/nt/gdi32/CreateFontIndirectExA.s b/libc/nt/gdi32/CreateFontIndirectExA.s deleted file mode 100644 index f533f11a2..000000000 --- a/libc/nt/gdi32/CreateFontIndirectExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateFontIndirectExA,CreateFontIndirectExA,1079 diff --git a/libc/nt/gdi32/CreateICA.s b/libc/nt/gdi32/CreateICA.s deleted file mode 100644 index 511789c5d..000000000 --- a/libc/nt/gdi32/CreateICA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateICA,CreateICA,1085 diff --git a/libc/nt/gdi32/CreateMetaFileA.s b/libc/nt/gdi32/CreateMetaFileA.s deleted file mode 100644 index d80413b5e..000000000 --- a/libc/nt/gdi32/CreateMetaFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateMetaFileA,CreateMetaFileA,1087 diff --git a/libc/nt/gdi32/CreateScalableFontResourceA.s b/libc/nt/gdi32/CreateScalableFontResourceA.s deleted file mode 100644 index db4ec0bca..000000000 --- a/libc/nt/gdi32/CreateScalableFontResourceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_CreateScalableFontResourceA,CreateScalableFontResourceA,1100 diff --git a/libc/nt/gdi32/DeviceCapabilitiesExA.s b/libc/nt/gdi32/DeviceCapabilitiesExA.s deleted file mode 100644 index 878487c4e..000000000 --- a/libc/nt/gdi32/DeviceCapabilitiesExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_DeviceCapabilitiesExA,DeviceCapabilitiesExA,1391 diff --git a/libc/nt/gdi32/EnumFontFamiliesA.s b/libc/nt/gdi32/EnumFontFamiliesA.s deleted file mode 100644 index 0ecbeb727..000000000 --- a/libc/nt/gdi32/EnumFontFamiliesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_EnumFontFamiliesA,EnumFontFamiliesA,1449 diff --git a/libc/nt/gdi32/EnumFontFamiliesExA.s b/libc/nt/gdi32/EnumFontFamiliesExA.s deleted file mode 100644 index 22d1c5bd4..000000000 --- a/libc/nt/gdi32/EnumFontFamiliesExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_EnumFontFamiliesExA,EnumFontFamiliesExA,1450 diff --git a/libc/nt/gdi32/EnumFontsA.s b/libc/nt/gdi32/EnumFontsA.s deleted file mode 100644 index 1cae60dde..000000000 --- a/libc/nt/gdi32/EnumFontsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_EnumFontsA,EnumFontsA,1453 diff --git a/libc/nt/gdi32/EnumICMProfilesA.s b/libc/nt/gdi32/EnumICMProfilesA.s deleted file mode 100644 index b05eb6284..000000000 --- a/libc/nt/gdi32/EnumICMProfilesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_EnumICMProfilesA,EnumICMProfilesA,1455 diff --git a/libc/nt/gdi32/ExtTextOutA.s b/libc/nt/gdi32/ExtTextOutA.s deleted file mode 100644 index a52441f07..000000000 --- a/libc/nt/gdi32/ExtTextOutA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_ExtTextOutA,ExtTextOutA,1469 diff --git a/libc/nt/gdi32/GetCharABCWidthsA.s b/libc/nt/gdi32/GetCharABCWidthsA.s deleted file mode 100644 index b4fe16f1c..000000000 --- a/libc/nt/gdi32/GetCharABCWidthsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetCharABCWidthsA,GetCharABCWidthsA,1605 diff --git a/libc/nt/gdi32/GetCharABCWidthsFloatA.s b/libc/nt/gdi32/GetCharABCWidthsFloatA.s deleted file mode 100644 index 868619f1f..000000000 --- a/libc/nt/gdi32/GetCharABCWidthsFloatA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetCharABCWidthsFloatA,GetCharABCWidthsFloatA,1606 diff --git a/libc/nt/gdi32/GetCharWidth32A.s b/libc/nt/gdi32/GetCharWidth32A.s deleted file mode 100644 index d1efa1b73..000000000 --- a/libc/nt/gdi32/GetCharWidth32A.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetCharWidth32A,GetCharWidth32A,1611 diff --git a/libc/nt/gdi32/GetCharWidthA.s b/libc/nt/gdi32/GetCharWidthA.s deleted file mode 100644 index 3d3f05bb2..000000000 --- a/libc/nt/gdi32/GetCharWidthA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetCharWidthA,GetCharWidthA,1613 diff --git a/libc/nt/gdi32/GetCharWidthFloatA.s b/libc/nt/gdi32/GetCharWidthFloatA.s deleted file mode 100644 index e813b9541..000000000 --- a/libc/nt/gdi32/GetCharWidthFloatA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetCharWidthFloatA,GetCharWidthFloatA,1614 diff --git a/libc/nt/gdi32/GetCharacterPlacementA.s b/libc/nt/gdi32/GetCharacterPlacementA.s deleted file mode 100644 index eb6fba7a3..000000000 --- a/libc/nt/gdi32/GetCharacterPlacementA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetCharacterPlacementA,GetCharacterPlacementA,1619 diff --git a/libc/nt/gdi32/GetEnhMetaFileA.s b/libc/nt/gdi32/GetEnhMetaFileA.s deleted file mode 100644 index 080e13f7b..000000000 --- a/libc/nt/gdi32/GetEnhMetaFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetEnhMetaFileA,GetEnhMetaFileA,1639 diff --git a/libc/nt/gdi32/GetEnhMetaFileDescriptionA.s b/libc/nt/gdi32/GetEnhMetaFileDescriptionA.s deleted file mode 100644 index 4fcf0a192..000000000 --- a/libc/nt/gdi32/GetEnhMetaFileDescriptionA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetEnhMetaFileDescriptionA,GetEnhMetaFileDescriptionA,1641 diff --git a/libc/nt/gdi32/GetGlyphIndicesA.s b/libc/nt/gdi32/GetGlyphIndicesA.s deleted file mode 100644 index ae8c59475..000000000 --- a/libc/nt/gdi32/GetGlyphIndicesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetGlyphIndicesA,GetGlyphIndicesA,1655 diff --git a/libc/nt/gdi32/GetGlyphOutlineA.s b/libc/nt/gdi32/GetGlyphOutlineA.s deleted file mode 100644 index bc507d401..000000000 --- a/libc/nt/gdi32/GetGlyphOutlineA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetGlyphOutlineA,GetGlyphOutlineA,1658 diff --git a/libc/nt/gdi32/GetICMProfileA.s b/libc/nt/gdi32/GetICMProfileA.s deleted file mode 100644 index 0957a063f..000000000 --- a/libc/nt/gdi32/GetICMProfileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetICMProfileA,GetICMProfileA,1663 diff --git a/libc/nt/gdi32/GetKerningPairsA.s b/libc/nt/gdi32/GetKerningPairsA.s deleted file mode 100644 index a29f534f9..000000000 --- a/libc/nt/gdi32/GetKerningPairsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetKerningPairsA,GetKerningPairsA,1666 diff --git a/libc/nt/gdi32/GetLogColorSpaceA.s b/libc/nt/gdi32/GetLogColorSpaceA.s deleted file mode 100644 index 90357f026..000000000 --- a/libc/nt/gdi32/GetLogColorSpaceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetLogColorSpaceA,GetLogColorSpaceA,1669 diff --git a/libc/nt/gdi32/GetMetaFileA.s b/libc/nt/gdi32/GetMetaFileA.s deleted file mode 100644 index 55d9bc839..000000000 --- a/libc/nt/gdi32/GetMetaFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetMetaFileA,GetMetaFileA,1672 diff --git a/libc/nt/gdi32/GetObjectA.s b/libc/nt/gdi32/GetObjectA.s deleted file mode 100644 index 97b25f985..000000000 --- a/libc/nt/gdi32/GetObjectA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetObjectA,GetObjectA,1682 diff --git a/libc/nt/gdi32/GetOutlineTextMetricsA.s b/libc/nt/gdi32/GetOutlineTextMetricsA.s deleted file mode 100644 index b77041fe8..000000000 --- a/libc/nt/gdi32/GetOutlineTextMetricsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetOutlineTextMetricsA,GetOutlineTextMetricsA,1685 diff --git a/libc/nt/gdi32/GetStringBitmapA.s b/libc/nt/gdi32/GetStringBitmapA.s deleted file mode 100644 index 78f4c429b..000000000 --- a/libc/nt/gdi32/GetStringBitmapA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetStringBitmapA,GetStringBitmapA,1703 diff --git a/libc/nt/gdi32/GetTextExtentExPointA.s b/libc/nt/gdi32/GetTextExtentExPointA.s deleted file mode 100644 index 163225478..000000000 --- a/libc/nt/gdi32/GetTextExtentExPointA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetTextExtentExPointA,GetTextExtentExPointA,1713 diff --git a/libc/nt/gdi32/GetTextExtentPoint32A.s b/libc/nt/gdi32/GetTextExtentPoint32A.s deleted file mode 100644 index 4bfcfb9c4..000000000 --- a/libc/nt/gdi32/GetTextExtentPoint32A.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetTextExtentPoint32A,GetTextExtentPoint32A,1717 diff --git a/libc/nt/gdi32/GetTextExtentPointA.s b/libc/nt/gdi32/GetTextExtentPointA.s deleted file mode 100644 index cf536c78e..000000000 --- a/libc/nt/gdi32/GetTextExtentPointA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetTextExtentPointA,GetTextExtentPointA,1719 diff --git a/libc/nt/gdi32/GetTextFaceA.s b/libc/nt/gdi32/GetTextFaceA.s deleted file mode 100644 index 844036899..000000000 --- a/libc/nt/gdi32/GetTextFaceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetTextFaceA,GetTextFaceA,1722 diff --git a/libc/nt/gdi32/GetTextMetricsA.s b/libc/nt/gdi32/GetTextMetricsA.s deleted file mode 100644 index 2b0fcca1c..000000000 --- a/libc/nt/gdi32/GetTextMetricsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_GetTextMetricsA,GetTextMetricsA,1725 diff --git a/libc/nt/gdi32/LineDDA.s b/libc/nt/gdi32/LineDDA.s deleted file mode 100644 index e598289c0..000000000 --- a/libc/nt/gdi32/LineDDA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_LineDDA,LineDDA,1742 diff --git a/libc/nt/gdi32/PolyTextOutA.s b/libc/nt/gdi32/PolyTextOutA.s deleted file mode 100644 index 65a98f524..000000000 --- a/libc/nt/gdi32/PolyTextOutA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_PolyTextOutA,PolyTextOutA,1787 diff --git a/libc/nt/gdi32/RemoveFontResourceA.s b/libc/nt/gdi32/RemoveFontResourceA.s deleted file mode 100644 index 48f46bb58..000000000 --- a/libc/nt/gdi32/RemoveFontResourceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_RemoveFontResourceA,RemoveFontResourceA,1800 diff --git a/libc/nt/gdi32/RemoveFontResourceExA.s b/libc/nt/gdi32/RemoveFontResourceExA.s deleted file mode 100644 index 4773bcb32..000000000 --- a/libc/nt/gdi32/RemoveFontResourceExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_RemoveFontResourceExA,RemoveFontResourceExA,1801 diff --git a/libc/nt/gdi32/ResetDCA.s b/libc/nt/gdi32/ResetDCA.s deleted file mode 100644 index 09a5ec7d3..000000000 --- a/libc/nt/gdi32/ResetDCA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_ResetDCA,ResetDCA,1805 diff --git a/libc/nt/gdi32/SetICMProfileA.s b/libc/nt/gdi32/SetICMProfileA.s deleted file mode 100644 index ddf3c9e5f..000000000 --- a/libc/nt/gdi32/SetICMProfileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_SetICMProfileA,SetICMProfileA,1889 diff --git a/libc/nt/gdi32/StartDocA.s b/libc/nt/gdi32/StartDocA.s deleted file mode 100644 index 84a38ce5c..000000000 --- a/libc/nt/gdi32/StartDocA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_StartDocA,StartDocA,1921 diff --git a/libc/nt/gdi32/TextOutA.s b/libc/nt/gdi32/TextOutA.s deleted file mode 100644 index 9bf4a7bd4..000000000 --- a/libc/nt/gdi32/TextOutA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_TextOutA,TextOutA,1930 diff --git a/libc/nt/gdi32/UpdateICMRegKeyA.s b/libc/nt/gdi32/UpdateICMRegKeyA.s deleted file mode 100644 index 04c16c42d..000000000 --- a/libc/nt/gdi32/UpdateICMRegKeyA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_UpdateICMRegKeyA,UpdateICMRegKeyA,1936 diff --git a/libc/nt/gdi32/bCreateDCW.s b/libc/nt/gdi32/bCreateDCW.s deleted file mode 100644 index 8f2b60ee9..000000000 --- a/libc/nt/gdi32/bCreateDCW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_bCreateDCW,bCreateDCW,1948 diff --git a/libc/nt/gdi32/bDeleteLDC.s b/libc/nt/gdi32/bDeleteLDC.s deleted file mode 100644 index 177273b2b..000000000 --- a/libc/nt/gdi32/bDeleteLDC.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_bDeleteLDC,bDeleteLDC,1949 diff --git a/libc/nt/gdi32/bInitSystemAndFontsDirectoriesW.s b/libc/nt/gdi32/bInitSystemAndFontsDirectoriesW.s deleted file mode 100644 index 87e2d5627..000000000 --- a/libc/nt/gdi32/bInitSystemAndFontsDirectoriesW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_bInitSystemAndFontsDirectoriesW,bInitSystemAndFontsDirectoriesW,1950 diff --git a/libc/nt/gdi32/bMakePathNameW.s b/libc/nt/gdi32/bMakePathNameW.s deleted file mode 100644 index 183a6c3ca..000000000 --- a/libc/nt/gdi32/bMakePathNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_bMakePathNameW,bMakePathNameW,1951 diff --git a/libc/nt/gdi32/ghICM.s b/libc/nt/gdi32/ghICM.s deleted file mode 100644 index 14ee71a02..000000000 --- a/libc/nt/gdi32/ghICM.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_ghICM,ghICM,1959 diff --git a/libc/nt/gdi32/hGetPEBHandle.s b/libc/nt/gdi32/hGetPEBHandle.s deleted file mode 100644 index cdca9508b..000000000 --- a/libc/nt/gdi32/hGetPEBHandle.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_hGetPEBHandle,hGetPEBHandle,1960 diff --git a/libc/nt/gdi32/pGdiDevCaps.s b/libc/nt/gdi32/pGdiDevCaps.s deleted file mode 100644 index 46c58ec30..000000000 --- a/libc/nt/gdi32/pGdiDevCaps.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_pGdiDevCaps,pGdiDevCaps,1961 diff --git a/libc/nt/gdi32/pGdiSharedHandleTable.s b/libc/nt/gdi32/pGdiSharedHandleTable.s deleted file mode 100644 index b85c9b52c..000000000 --- a/libc/nt/gdi32/pGdiSharedHandleTable.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_pGdiSharedHandleTable,pGdiSharedHandleTable,1962 diff --git a/libc/nt/gdi32/pGdiSharedMemory.s b/libc/nt/gdi32/pGdiSharedMemory.s deleted file mode 100644 index b71d94cd7..000000000 --- a/libc/nt/gdi32/pGdiSharedMemory.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_pGdiSharedMemory,pGdiSharedMemory,1963 diff --git a/libc/nt/gdi32/pldcGet.s b/libc/nt/gdi32/pldcGet.s deleted file mode 100644 index 13baabd55..000000000 --- a/libc/nt/gdi32/pldcGet.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_pldcGet,pldcGet,1964 diff --git a/libc/nt/gdi32/semDxTrimNotification.s b/libc/nt/gdi32/semDxTrimNotification.s deleted file mode 100644 index c17cc710c..000000000 --- a/libc/nt/gdi32/semDxTrimNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp gdi32,__imp_semDxTrimNotification,semDxTrimNotification,1965 diff --git a/libc/nt/ipc.h b/libc/nt/ipc.h index 2c79321c9..3fce3fd1e 100644 --- a/libc/nt/ipc.h +++ b/libc/nt/ipc.h @@ -43,11 +43,11 @@ #define kNtPipeRejectRemoteClients 0x00000008 /* CreateNamedPipe::nMaxInstances */ -#define NT_PIPE_UNLIMITED_INSTANCES 255 +#define kNtPipeUnlimitedInstances 255 -/* CreateNamedPipeInfo */ -#define PIPE_CLIENT_END 0x00000000 -#define PIPE_SERVER_END 0x00000001 +/* GetNamedPipeInfo */ +#define kNtPipeClientEnd 0x00000000 +#define kNtPipeServerEnd 0x00000001 #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ diff --git a/libc/nt/kernel32/AddAtomA.s b/libc/nt/kernel32/AddAtomA.s deleted file mode 100644 index 72895fbef..000000000 --- a/libc/nt/kernel32/AddAtomA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_AddAtomA,AddAtomA,5 diff --git a/libc/nt/kernel32/AddLocalAlternateComputerNameA.s b/libc/nt/kernel32/AddLocalAlternateComputerNameA.s deleted file mode 100644 index 5296277f1..000000000 --- a/libc/nt/kernel32/AddLocalAlternateComputerNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_AddLocalAlternateComputerNameA,AddLocalAlternateComputerNameA,11 diff --git a/libc/nt/kernel32/BeginUpdateResourceA.s b/libc/nt/kernel32/BeginUpdateResourceA.s deleted file mode 100644 index 662f88dbc..000000000 --- a/libc/nt/kernel32/BeginUpdateResourceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_BeginUpdateResourceA,BeginUpdateResourceA,103 diff --git a/libc/nt/kernel32/CheckNameLegalDOS8Dot3A.s b/libc/nt/kernel32/CheckNameLegalDOS8Dot3A.s deleted file mode 100644 index b89a81c4b..000000000 --- a/libc/nt/kernel32/CheckNameLegalDOS8Dot3A.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_CheckNameLegalDOS8Dot3A,CheckNameLegalDOS8Dot3A,127 diff --git a/libc/nt/kernel32/CloseHandle.s b/libc/nt/kernel32/CloseHandle.s index 71f601a43..254df6b9a 100644 --- a/libc/nt/kernel32/CloseHandle.s +++ b/libc/nt/kernel32/CloseHandle.s @@ -2,7 +2,7 @@ .imp kernel32,__imp_CloseHandle,CloseHandle,0 .text.windows -CloseHandle: +__CloseHandle: push %rbp mov %rsp,%rbp .profilable @@ -11,5 +11,5 @@ CloseHandle: call *__imp_CloseHandle(%rip) leave ret - .endfn CloseHandle,globl + .endfn __CloseHandle,globl .previous diff --git a/libc/nt/kernel32/CommConfigDialogA.s b/libc/nt/kernel32/CommConfigDialogA.s deleted file mode 100644 index 50d7b1fbd..000000000 --- a/libc/nt/kernel32/CommConfigDialogA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_CommConfigDialogA,CommConfigDialogA,148 diff --git a/libc/nt/kernel32/CompareStringA.s b/libc/nt/kernel32/CompareStringA.s deleted file mode 100644 index b357a8d3d..000000000 --- a/libc/nt/kernel32/CompareStringA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_CompareStringA,CompareStringA,0 diff --git a/libc/nt/kernel32/CreateDirectoryW.s b/libc/nt/kernel32/CreateDirectoryW.s index e8e6c595e..543ba1726 100644 --- a/libc/nt/kernel32/CreateDirectoryW.s +++ b/libc/nt/kernel32/CreateDirectoryW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreateDirectoryW,CreateDirectoryW,0 .text.windows -CreateDirectory: +__CreateDirectory: push %rbp mov %rsp,%rbp .profilable mov __imp_CreateDirectoryW(%rip),%rax jmp __sysv2nt - .endfn CreateDirectory,globl + .endfn __CreateDirectory,globl .previous diff --git a/libc/nt/kernel32/CreateFileMappingNumaW.s b/libc/nt/kernel32/CreateFileMappingNumaW.s index 19f542339..3ce9ae334 100644 --- a/libc/nt/kernel32/CreateFileMappingNumaW.s +++ b/libc/nt/kernel32/CreateFileMappingNumaW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreateFileMappingNumaW,CreateFileMappingNumaW,0 .text.windows -CreateFileMappingNuma: +__CreateFileMappingNuma: push %rbp mov %rsp,%rbp .profilable mov __imp_CreateFileMappingNumaW(%rip),%rax jmp __sysv2nt8 - .endfn CreateFileMappingNuma,globl + .endfn __CreateFileMappingNuma,globl .previous diff --git a/libc/nt/kernel32/CreateFileMappingW.s b/libc/nt/kernel32/CreateFileMappingW.s index 6fa9275fd..6d4330c59 100644 --- a/libc/nt/kernel32/CreateFileMappingW.s +++ b/libc/nt/kernel32/CreateFileMappingW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreateFileMappingW,CreateFileMappingW,0 .text.windows -CreateFileMapping: +__CreateFileMapping: push %rbp mov %rsp,%rbp .profilable mov __imp_CreateFileMappingW(%rip),%rax - jmp __sysv2nt8 - .endfn CreateFileMapping,globl + jmp __sysv2nt6 + .endfn __CreateFileMapping,globl .previous diff --git a/libc/nt/kernel32/CreateFileW.s b/libc/nt/kernel32/CreateFileW.s index 078ba1aff..ce8e9938d 100644 --- a/libc/nt/kernel32/CreateFileW.s +++ b/libc/nt/kernel32/CreateFileW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreateFileW,CreateFileW,0 .text.windows -CreateFile: +__CreateFile: push %rbp mov %rsp,%rbp .profilable mov __imp_CreateFileW(%rip),%rax jmp __sysv2nt8 - .endfn CreateFile,globl + .endfn __CreateFile,globl .previous diff --git a/libc/nt/kernel32/CreateNamedPipeW.s b/libc/nt/kernel32/CreateNamedPipeW.s index 203cf9ce0..455358c5c 100644 --- a/libc/nt/kernel32/CreateNamedPipeW.s +++ b/libc/nt/kernel32/CreateNamedPipeW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreateNamedPipeW,CreateNamedPipeW,0 .text.windows -CreateNamedPipe: +__CreateNamedPipe: push %rbp mov %rsp,%rbp .profilable mov __imp_CreateNamedPipeW(%rip),%rax jmp __sysv2nt8 - .endfn CreateNamedPipe,globl + .endfn __CreateNamedPipe,globl .previous diff --git a/libc/nt/kernel32/CreatePipe.s b/libc/nt/kernel32/CreatePipe.s index 04d998982..217301928 100644 --- a/libc/nt/kernel32/CreatePipe.s +++ b/libc/nt/kernel32/CreatePipe.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreatePipe,CreatePipe,0 .text.windows -CreatePipe: +__CreatePipe: push %rbp mov %rsp,%rbp .profilable mov __imp_CreatePipe(%rip),%rax jmp __sysv2nt - .endfn CreatePipe,globl + .endfn __CreatePipe,globl .previous diff --git a/libc/nt/kernel32/CreateProcessW.s b/libc/nt/kernel32/CreateProcessW.s index 5f7eb201e..50fe02ff4 100644 --- a/libc/nt/kernel32/CreateProcessW.s +++ b/libc/nt/kernel32/CreateProcessW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreateProcessW,CreateProcessW,0 .text.windows -CreateProcess: +__CreateProcess: push %rbp mov %rsp,%rbp .profilable mov __imp_CreateProcessW(%rip),%rax jmp __sysv2nt10 - .endfn CreateProcess,globl + .endfn __CreateProcess,globl .previous diff --git a/libc/nt/kernel32/CreateSymbolicLinkW.s b/libc/nt/kernel32/CreateSymbolicLinkW.s index 7dd4dcb60..4fa19cf9a 100644 --- a/libc/nt/kernel32/CreateSymbolicLinkW.s +++ b/libc/nt/kernel32/CreateSymbolicLinkW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreateSymbolicLinkW,CreateSymbolicLinkW,0 .text.windows -CreateSymbolicLink: +__CreateSymbolicLink: push %rbp mov %rsp,%rbp .profilable mov __imp_CreateSymbolicLinkW(%rip),%rax jmp __sysv2nt - .endfn CreateSymbolicLink,globl + .endfn __CreateSymbolicLink,globl .previous diff --git a/libc/nt/kernel32/CreateThread.s b/libc/nt/kernel32/CreateThread.s index d2e48111d..67e4a644b 100644 --- a/libc/nt/kernel32/CreateThread.s +++ b/libc/nt/kernel32/CreateThread.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_CreateThread,CreateThread,0 .text.windows -CreateThread: +__CreateThread: push %rbp mov %rsp,%rbp .profilable mov __imp_CreateThread(%rip),%rax jmp __sysv2nt6 - .endfn CreateThread,globl + .endfn __CreateThread,globl .previous diff --git a/libc/nt/kernel32/DeleteFileW.s b/libc/nt/kernel32/DeleteFileW.s index 02b456052..492a94116 100644 --- a/libc/nt/kernel32/DeleteFileW.s +++ b/libc/nt/kernel32/DeleteFileW.s @@ -2,7 +2,7 @@ .imp kernel32,__imp_DeleteFileW,DeleteFileW,0 .text.windows -DeleteFile: +__DeleteFile: push %rbp mov %rsp,%rbp .profilable @@ -11,5 +11,5 @@ DeleteFile: call *__imp_DeleteFileW(%rip) leave ret - .endfn DeleteFile,globl + .endfn __DeleteFile,globl .previous diff --git a/libc/nt/kernel32/DeviceIoControl.s b/libc/nt/kernel32/DeviceIoControl.s index 166497c20..f250662fb 100644 --- a/libc/nt/kernel32/DeviceIoControl.s +++ b/libc/nt/kernel32/DeviceIoControl.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_DeviceIoControl,DeviceIoControl,0 .text.windows -DeviceIoControl: +__DeviceIoControl: push %rbp mov %rsp,%rbp .profilable mov __imp_DeviceIoControl(%rip),%rax jmp __sysv2nt8 - .endfn DeviceIoControl,globl + .endfn __DeviceIoControl,globl .previous diff --git a/libc/nt/kernel32/EnumSystemGeoNames.s b/libc/nt/kernel32/EnumSystemGeoNames.s new file mode 100644 index 000000000..7143a52e7 --- /dev/null +++ b/libc/nt/kernel32/EnumSystemGeoNames.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumSystemGeoNames,EnumSystemGeoNames,318 diff --git a/libc/nt/kernel32/ExitThread.s b/libc/nt/kernel32/ExitThread.s new file mode 100644 index 000000000..575958455 --- /dev/null +++ b/libc/nt/kernel32/ExitThread.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ExitThread,ExitThread,0 + + .text.windows +ExitThread: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_ExitThread(%rip) + leave + ret + .endfn ExitThread,globl + .previous diff --git a/libc/nt/kernel32/FindClose.s b/libc/nt/kernel32/FindClose.s index e6dcc3acd..2a151dc83 100644 --- a/libc/nt/kernel32/FindClose.s +++ b/libc/nt/kernel32/FindClose.s @@ -2,7 +2,7 @@ .imp kernel32,__imp_FindClose,FindClose,0 .text.windows -FindClose: +__FindClose: push %rbp mov %rsp,%rbp .profilable @@ -11,5 +11,5 @@ FindClose: call *__imp_FindClose(%rip) leave ret - .endfn FindClose,globl + .endfn __FindClose,globl .previous diff --git a/libc/nt/kernel32/FindFirstFileW.s b/libc/nt/kernel32/FindFirstFileW.s index 80b3d9f59..30c263fe3 100644 --- a/libc/nt/kernel32/FindFirstFileW.s +++ b/libc/nt/kernel32/FindFirstFileW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_FindFirstFileW,FindFirstFileW,0 .text.windows -FindFirstFile: +__FindFirstFile: push %rbp mov %rsp,%rbp .profilable mov __imp_FindFirstFileW(%rip),%rax jmp __sysv2nt - .endfn FindFirstFile,globl + .endfn __FindFirstFile,globl .previous diff --git a/libc/nt/kernel32/FindNextFileW.s b/libc/nt/kernel32/FindNextFileW.s index a00fc206a..0a7bac505 100644 --- a/libc/nt/kernel32/FindNextFileW.s +++ b/libc/nt/kernel32/FindNextFileW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_FindNextFileW,FindNextFileW,0 .text.windows -FindNextFile: +__FindNextFile: push %rbp mov %rsp,%rbp .profilable mov __imp_FindNextFileW(%rip),%rax jmp __sysv2nt - .endfn FindNextFile,globl + .endfn __FindNextFile,globl .previous diff --git a/libc/nt/kernel32/FlushFileBuffers.s b/libc/nt/kernel32/FlushFileBuffers.s index 1022a3add..96a26512b 100644 --- a/libc/nt/kernel32/FlushFileBuffers.s +++ b/libc/nt/kernel32/FlushFileBuffers.s @@ -2,7 +2,7 @@ .imp kernel32,__imp_FlushFileBuffers,FlushFileBuffers,0 .text.windows -FlushFileBuffers: +__FlushFileBuffers: push %rbp mov %rsp,%rbp .profilable @@ -11,5 +11,5 @@ FlushFileBuffers: call *__imp_FlushFileBuffers(%rip) leave ret - .endfn FlushFileBuffers,globl + .endfn __FlushFileBuffers,globl .previous diff --git a/libc/nt/kernel32/FlushViewOfFile.s b/libc/nt/kernel32/FlushViewOfFile.s index 229635ad7..638ba1966 100644 --- a/libc/nt/kernel32/FlushViewOfFile.s +++ b/libc/nt/kernel32/FlushViewOfFile.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_FlushViewOfFile,FlushViewOfFile,0 .text.windows -FlushViewOfFile: +__FlushViewOfFile: push %rbp mov %rsp,%rbp .profilable mov __imp_FlushViewOfFile(%rip),%rax jmp __sysv2nt - .endfn FlushViewOfFile,globl + .endfn __FlushViewOfFile,globl .previous diff --git a/libc/nt/kernel32/GenerateConsoleCtrlEvent.s b/libc/nt/kernel32/GenerateConsoleCtrlEvent.s index 1cabe43fa..33d423456 100644 --- a/libc/nt/kernel32/GenerateConsoleCtrlEvent.s +++ b/libc/nt/kernel32/GenerateConsoleCtrlEvent.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_GenerateConsoleCtrlEvent,GenerateConsoleCtrlEvent,0 .text.windows -GenerateConsoleCtrlEvent: +__GenerateConsoleCtrlEvent: push %rbp mov %rsp,%rbp .profilable mov __imp_GenerateConsoleCtrlEvent(%rip),%rax jmp __sysv2nt - .endfn GenerateConsoleCtrlEvent,globl + .endfn __GenerateConsoleCtrlEvent,globl .previous diff --git a/libc/nt/kernel32/GetExitCodeProcess.s b/libc/nt/kernel32/GetExitCodeProcess.s index 78b43b59a..bd7cdc55f 100644 --- a/libc/nt/kernel32/GetExitCodeProcess.s +++ b/libc/nt/kernel32/GetExitCodeProcess.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_GetExitCodeProcess,GetExitCodeProcess,0 .text.windows -GetExitCodeProcess: +__GetExitCodeProcess: push %rbp mov %rsp,%rbp .profilable mov __imp_GetExitCodeProcess(%rip),%rax jmp __sysv2nt - .endfn GetExitCodeProcess,globl + .endfn __GetExitCodeProcess,globl .previous diff --git a/libc/nt/kernel32/GetFileAttributesW.s b/libc/nt/kernel32/GetFileAttributesW.s index 0295417db..581fde16b 100644 --- a/libc/nt/kernel32/GetFileAttributesW.s +++ b/libc/nt/kernel32/GetFileAttributesW.s @@ -2,7 +2,7 @@ .imp kernel32,__imp_GetFileAttributesW,GetFileAttributesW,0 .text.windows -GetFileAttributes: +__GetFileAttributes: push %rbp mov %rsp,%rbp .profilable @@ -11,5 +11,5 @@ GetFileAttributes: call *__imp_GetFileAttributesW(%rip) leave ret - .endfn GetFileAttributes,globl + .endfn __GetFileAttributes,globl .previous diff --git a/libc/nt/kernel32/GetFirmwareEnvironmentVariableA.s b/libc/nt/kernel32/GetFirmwareEnvironmentVariableA.s deleted file mode 100644 index b3bbb3e2b..000000000 --- a/libc/nt/kernel32/GetFirmwareEnvironmentVariableA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_GetFirmwareEnvironmentVariableA,GetFirmwareEnvironmentVariableA,597 diff --git a/libc/nt/kernel32/GetFirmwareEnvironmentVariableExA.s b/libc/nt/kernel32/GetFirmwareEnvironmentVariableExA.s deleted file mode 100644 index 441396030..000000000 --- a/libc/nt/kernel32/GetFirmwareEnvironmentVariableExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_GetFirmwareEnvironmentVariableExA,GetFirmwareEnvironmentVariableExA,598 diff --git a/libc/nt/kernel32/GetFullPathNameA.s b/libc/nt/kernel32/GetFullPathNameA.s deleted file mode 100644 index 3b41722b6..000000000 --- a/libc/nt/kernel32/GetFullPathNameA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_GetFullPathNameA,GetFullPathNameA,0 - - .text.windows -GetFullPathNameA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_GetFullPathNameA(%rip),%rax - jmp __sysv2nt - .endfn GetFullPathNameA,globl - .previous diff --git a/libc/nt/kernel32/GetFullPathNameTransactedA.s b/libc/nt/kernel32/GetFullPathNameTransactedA.s deleted file mode 100644 index c0c17c5d7..000000000 --- a/libc/nt/kernel32/GetFullPathNameTransactedA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_GetFullPathNameTransactedA,GetFullPathNameTransactedA,603 diff --git a/libc/nt/kernel32/GetGeoInfoA.s b/libc/nt/kernel32/GetGeoInfoA.s deleted file mode 100644 index 239808af8..000000000 --- a/libc/nt/kernel32/GetGeoInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_GetGeoInfoA,GetGeoInfoA,606 diff --git a/libc/nt/kernel32/GetProcessHeap.s b/libc/nt/kernel32/GetProcessHeap.s index 4aa7b0b00..582ffd2ee 100644 --- a/libc/nt/kernel32/GetProcessHeap.s +++ b/libc/nt/kernel32/GetProcessHeap.s @@ -1,2 +1,14 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_GetProcessHeap,GetProcessHeap,0 + + .text.windows +GetProcessHeap: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetProcessHeap(%rip) + leave + ret + .endfn GetProcessHeap,globl + .previous diff --git a/libc/nt/kernel32/GetProcessHeaps.s b/libc/nt/kernel32/GetProcessHeaps.s index ce5308cfa..7c5bd6ab6 100644 --- a/libc/nt/kernel32/GetProcessHeaps.s +++ b/libc/nt/kernel32/GetProcessHeaps.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_GetProcessHeaps,GetProcessHeaps,0 + + .text.windows +GetProcessHeaps: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessHeaps(%rip),%rax + jmp __sysv2nt + .endfn GetProcessHeaps,globl + .previous diff --git a/libc/nt/kernel32/GetProcessImageFileNameA.s b/libc/nt/kernel32/GetProcessImageFileNameA.s deleted file mode 100644 index 359e4ff60..000000000 --- a/libc/nt/kernel32/GetProcessImageFileNameA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_GetProcessImageFileNameA,GetProcessImageFileNameA,676 - - .text.windows -GetProcessImageFileNameA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_GetProcessImageFileNameA(%rip),%rax - jmp __sysv2nt - .endfn GetProcessImageFileNameA,globl - .previous diff --git a/libc/nt/kernel32/HeapAlloc.s b/libc/nt/kernel32/HeapAlloc.s new file mode 100644 index 000000000..5d71b53ba --- /dev/null +++ b/libc/nt/kernel32/HeapAlloc.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_HeapAlloc,HeapAlloc,0 + + .text.windows +HeapAlloc: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_HeapAlloc(%rip),%rax + jmp __sysv2nt + .endfn HeapAlloc,globl + .previous diff --git a/libc/nt/kernel32/HeapCompact.s b/libc/nt/kernel32/HeapCompact.s index 6322c22c0..b557f6886 100644 --- a/libc/nt/kernel32/HeapCompact.s +++ b/libc/nt/kernel32/HeapCompact.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_HeapCompact,HeapCompact,0 + + .text.windows +HeapCompact: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_HeapCompact(%rip),%rax + jmp __sysv2nt + .endfn HeapCompact,globl + .previous diff --git a/libc/nt/kernel32/HeapCreate.s b/libc/nt/kernel32/HeapCreate.s index bf8db4cdf..cbdfff932 100644 --- a/libc/nt/kernel32/HeapCreate.s +++ b/libc/nt/kernel32/HeapCreate.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_HeapCreate,HeapCreate,0 + + .text.windows +HeapCreate: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_HeapCreate(%rip),%rax + jmp __sysv2nt + .endfn HeapCreate,globl + .previous diff --git a/libc/nt/kernel32/HeapDestroy.s b/libc/nt/kernel32/HeapDestroy.s index 02d78182f..9cf8b76f4 100644 --- a/libc/nt/kernel32/HeapDestroy.s +++ b/libc/nt/kernel32/HeapDestroy.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_HeapDestroy,HeapDestroy,0 + + .text.windows +HeapDestroy: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_HeapDestroy(%rip) + leave + ret + .endfn HeapDestroy,globl + .previous diff --git a/libc/nt/kernel32/HeapFree.s b/libc/nt/kernel32/HeapFree.s index 138e1927c..e7bf59084 100644 --- a/libc/nt/kernel32/HeapFree.s +++ b/libc/nt/kernel32/HeapFree.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_HeapFree,HeapFree,847 + + .text.windows +HeapFree: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_HeapFree(%rip),%rax + jmp __sysv2nt + .endfn HeapFree,globl + .previous diff --git a/libc/nt/kernel32/HeapReAlloc.s b/libc/nt/kernel32/HeapReAlloc.s new file mode 100644 index 000000000..f775d27b0 --- /dev/null +++ b/libc/nt/kernel32/HeapReAlloc.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_HeapReAlloc,HeapReAlloc,0 + + .text.windows +HeapReAlloc: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_HeapReAlloc(%rip),%rax + jmp __sysv2nt + .endfn HeapReAlloc,globl + .previous diff --git a/libc/nt/kernel32/K32GetModuleBaseNameA.s b/libc/nt/kernel32/K32GetModuleBaseNameA.s deleted file mode 100644 index 38c0d1d20..000000000 --- a/libc/nt/kernel32/K32GetModuleBaseNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_K32GetModuleBaseNameA,K32GetModuleBaseNameA,0 diff --git a/libc/nt/kernel32/K32GetModuleFileNameExA.s b/libc/nt/kernel32/K32GetModuleFileNameExA.s deleted file mode 100644 index 217375ed0..000000000 --- a/libc/nt/kernel32/K32GetModuleFileNameExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_K32GetModuleFileNameExA,K32GetModuleFileNameExA,0 diff --git a/libc/nt/kernel32/K32GetProcessImageFileNameA.s b/libc/nt/kernel32/K32GetProcessImageFileNameA.s deleted file mode 100644 index b28e59ea8..000000000 --- a/libc/nt/kernel32/K32GetProcessImageFileNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_K32GetProcessImageFileNameA,K32GetProcessImageFileNameA,0 diff --git a/libc/nt/kernel32/MapViewOfFileEx.s b/libc/nt/kernel32/MapViewOfFileEx.s index 0c0b1c667..a4036ecba 100644 --- a/libc/nt/kernel32/MapViewOfFileEx.s +++ b/libc/nt/kernel32/MapViewOfFileEx.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_MapViewOfFileEx,MapViewOfFileEx,0 + + .text.windows +__MapViewOfFileEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MapViewOfFileEx(%rip),%rax + jmp __sysv2nt6 + .endfn __MapViewOfFileEx,globl + .previous diff --git a/libc/nt/kernel32/MapViewOfFileExNuma.s b/libc/nt/kernel32/MapViewOfFileExNuma.s index b28d08586..b74a7b956 100644 --- a/libc/nt/kernel32/MapViewOfFileExNuma.s +++ b/libc/nt/kernel32/MapViewOfFileExNuma.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_MapViewOfFileExNuma,MapViewOfFileExNuma,0 .text.windows -MapViewOfFileExNuma: +__MapViewOfFileExNuma: push %rbp mov %rsp,%rbp .profilable mov __imp_MapViewOfFileExNuma(%rip),%rax jmp __sysv2nt8 - .endfn MapViewOfFileExNuma,globl + .endfn __MapViewOfFileExNuma,globl .previous diff --git a/libc/nt/kernel32/MoveFileExW.s b/libc/nt/kernel32/MoveFileExW.s index c05159558..4ca9cb47a 100644 --- a/libc/nt/kernel32/MoveFileExW.s +++ b/libc/nt/kernel32/MoveFileExW.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_MoveFileExW,MoveFileExW,0 .text.windows -MoveFileEx: +__MoveFileEx: push %rbp mov %rsp,%rbp .profilable mov __imp_MoveFileExW(%rip),%rax jmp __sysv2nt - .endfn MoveFileEx,globl + .endfn __MoveFileEx,globl .previous diff --git a/libc/nt/kernel32/OpenProcess.s b/libc/nt/kernel32/OpenProcess.s index b5eb77b22..e7b47f3c0 100644 --- a/libc/nt/kernel32/OpenProcess.s +++ b/libc/nt/kernel32/OpenProcess.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_OpenProcess,OpenProcess,0 .text.windows -OpenProcess: +__OpenProcess: push %rbp mov %rsp,%rbp .profilable mov __imp_OpenProcess(%rip),%rax jmp __sysv2nt - .endfn OpenProcess,globl + .endfn __OpenProcess,globl .previous diff --git a/libc/nt/kernel32/ReOpenFile.s b/libc/nt/kernel32/ReOpenFile.s index 1d315dfe2..57e2e32df 100644 --- a/libc/nt/kernel32/ReOpenFile.s +++ b/libc/nt/kernel32/ReOpenFile.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_ReOpenFile,ReOpenFile,0 .text.windows -ReOpenFile: +__ReOpenFile: push %rbp mov %rsp,%rbp .profilable mov __imp_ReOpenFile(%rip),%rax jmp __sysv2nt - .endfn ReOpenFile,globl + .endfn __ReOpenFile,globl .previous diff --git a/libc/nt/kernel32/RemoveDirectoryW.s b/libc/nt/kernel32/RemoveDirectoryW.s index 831c4aea2..b19f45f2a 100644 --- a/libc/nt/kernel32/RemoveDirectoryW.s +++ b/libc/nt/kernel32/RemoveDirectoryW.s @@ -2,7 +2,7 @@ .imp kernel32,__imp_RemoveDirectoryW,RemoveDirectoryW,0 .text.windows -RemoveDirectory: +__RemoveDirectory: push %rbp mov %rsp,%rbp .profilable @@ -11,5 +11,5 @@ RemoveDirectory: call *__imp_RemoveDirectoryW(%rip) leave ret - .endfn RemoveDirectory,globl + .endfn __RemoveDirectory,globl .previous diff --git a/libc/nt/kernel32/SetCurrentDirectoryW.s b/libc/nt/kernel32/SetCurrentDirectoryW.s index f922e710d..9459e34b0 100644 --- a/libc/nt/kernel32/SetCurrentDirectoryW.s +++ b/libc/nt/kernel32/SetCurrentDirectoryW.s @@ -2,7 +2,7 @@ .imp kernel32,__imp_SetCurrentDirectoryW,SetCurrentDirectoryW,0 .text.windows -SetCurrentDirectory: +__SetCurrentDirectory: push %rbp mov %rsp,%rbp .profilable @@ -11,5 +11,5 @@ SetCurrentDirectory: call *__imp_SetCurrentDirectoryW(%rip) leave ret - .endfn SetCurrentDirectory,globl + .endfn __SetCurrentDirectory,globl .previous diff --git a/libc/nt/kernel32/SetLastError.s b/libc/nt/kernel32/SetLastError.s index 03a1f7d39..779f9bee4 100644 --- a/libc/nt/kernel32/SetLastError.s +++ b/libc/nt/kernel32/SetLastError.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_SetLastError,SetLastError,1336 +.imp kernel32,__imp_SetLastError,SetLastError,0 .text.windows SetLastError: diff --git a/libc/nt/kernel32/TerminateProcess.s b/libc/nt/kernel32/TerminateProcess.s index 75979e8d1..2fd282be4 100644 --- a/libc/nt/kernel32/TerminateProcess.s +++ b/libc/nt/kernel32/TerminateProcess.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_TerminateProcess,TerminateProcess,0 .text.windows -TerminateProcess: +__TerminateProcess: push %rbp mov %rsp,%rbp .profilable mov __imp_TerminateProcess(%rip),%rax jmp __sysv2nt - .endfn TerminateProcess,globl + .endfn __TerminateProcess,globl .previous diff --git a/libc/nt/kernel32/TlsAlloc.s b/libc/nt/kernel32/TlsAlloc.s index 40d390207..e39628b00 100644 --- a/libc/nt/kernel32/TlsAlloc.s +++ b/libc/nt/kernel32/TlsAlloc.s @@ -1,2 +1,14 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_TlsAlloc,TlsAlloc,0 + + .text.windows +__TlsAlloc: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_TlsAlloc(%rip) + leave + ret + .endfn __TlsAlloc,globl + .previous diff --git a/libc/nt/kernel32/TlsFree.s b/libc/nt/kernel32/TlsFree.s index 1c09fd7d0..8a66707ad 100644 --- a/libc/nt/kernel32/TlsFree.s +++ b/libc/nt/kernel32/TlsFree.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_TlsFree,TlsFree,0 + + .text.windows +__TlsFree: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_TlsFree(%rip) + leave + ret + .endfn __TlsFree,globl + .previous diff --git a/libc/nt/kernel32/TlsGetValue.s b/libc/nt/kernel32/TlsGetValue.s index 491efefae..371ed9084 100644 --- a/libc/nt/kernel32/TlsGetValue.s +++ b/libc/nt/kernel32/TlsGetValue.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_TlsGetValue,TlsGetValue,0 + + .text.windows +__TlsGetValue: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_TlsGetValue(%rip) + leave + ret + .endfn __TlsGetValue,globl + .previous diff --git a/libc/nt/kernel32/TlsSetValue.s b/libc/nt/kernel32/TlsSetValue.s index 7cdb3d286..77d63bf4b 100644 --- a/libc/nt/kernel32/TlsSetValue.s +++ b/libc/nt/kernel32/TlsSetValue.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_TlsSetValue,TlsSetValue,0 + + .text.windows +__TlsSetValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_TlsSetValue(%rip),%rax + jmp __sysv2nt + .endfn __TlsSetValue,globl + .previous diff --git a/libc/nt/kernel32/UnmapViewOfFile.s b/libc/nt/kernel32/UnmapViewOfFile.s index 1f6764c55..301ce163f 100644 --- a/libc/nt/kernel32/UnmapViewOfFile.s +++ b/libc/nt/kernel32/UnmapViewOfFile.s @@ -2,7 +2,7 @@ .imp kernel32,__imp_UnmapViewOfFile,UnmapViewOfFile,0 .text.windows -UnmapViewOfFile: +__UnmapViewOfFile: push %rbp mov %rsp,%rbp .profilable @@ -11,5 +11,5 @@ UnmapViewOfFile: call *__imp_UnmapViewOfFile(%rip) leave ret - .endfn UnmapViewOfFile,globl + .endfn __UnmapViewOfFile,globl .previous diff --git a/libc/nt/kernel32/UnmapViewOfFile2.s b/libc/nt/kernel32/UnmapViewOfFile2.s new file mode 100644 index 000000000..7e00613c1 --- /dev/null +++ b/libc/nt/kernel32/UnmapViewOfFile2.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UnmapViewOfFile2,UnmapViewOfFile2,0 + + .text.windows +UnmapViewOfFile2: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_UnmapViewOfFile2(%rip),%rax + jmp __sysv2nt + .endfn UnmapViewOfFile2,globl + .previous diff --git a/libc/nt/kernel32/UnmapViewOfFileEx.s b/libc/nt/kernel32/UnmapViewOfFileEx.s new file mode 100644 index 000000000..2700038f2 --- /dev/null +++ b/libc/nt/kernel32/UnmapViewOfFileEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UnmapViewOfFileEx,UnmapViewOfFileEx,0 + + .text.windows +UnmapViewOfFileEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_UnmapViewOfFileEx(%rip),%rax + jmp __sysv2nt + .endfn UnmapViewOfFileEx,globl + .previous diff --git a/libc/nt/kernel32/VirtualProtect.s b/libc/nt/kernel32/VirtualProtect.s index 706c74aa3..0acf070a5 100644 --- a/libc/nt/kernel32/VirtualProtect.s +++ b/libc/nt/kernel32/VirtualProtect.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_VirtualProtect,VirtualProtect,0 .text.windows -VirtualProtect: +__VirtualProtect: push %rbp mov %rsp,%rbp .profilable mov __imp_VirtualProtect(%rip),%rax jmp __sysv2nt - .endfn VirtualProtect,globl + .endfn __VirtualProtect,globl .previous diff --git a/libc/nt/kernel32/WaitForMultipleObjects.s b/libc/nt/kernel32/WaitForMultipleObjects.s index d5bd67864..ec06eccd6 100644 --- a/libc/nt/kernel32/WaitForMultipleObjects.s +++ b/libc/nt/kernel32/WaitForMultipleObjects.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_WaitForMultipleObjects,WaitForMultipleObjects,0 .text.windows -WaitForMultipleObjects: +__WaitForMultipleObjects: push %rbp mov %rsp,%rbp .profilable mov __imp_WaitForMultipleObjects(%rip),%rax jmp __sysv2nt - .endfn WaitForMultipleObjects,globl + .endfn __WaitForMultipleObjects,globl .previous diff --git a/libc/nt/kernel32/WaitForSingleObject.s b/libc/nt/kernel32/WaitForSingleObject.s index 90adca673..61363d463 100644 --- a/libc/nt/kernel32/WaitForSingleObject.s +++ b/libc/nt/kernel32/WaitForSingleObject.s @@ -2,11 +2,11 @@ .imp kernel32,__imp_WaitForSingleObject,WaitForSingleObject,0 .text.windows -WaitForSingleObject: +__WaitForSingleObject: push %rbp mov %rsp,%rbp .profilable mov __imp_WaitForSingleObject(%rip),%rax jmp __sysv2nt - .endfn WaitForSingleObject,globl + .endfn __WaitForSingleObject,globl .previous diff --git a/libc/nt/kernel32/_hread.s b/libc/nt/kernel32/_hread.s deleted file mode 100644 index 0444e40ed..000000000 --- a/libc/nt/kernel32/_hread.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp__hread,_hread,1582 diff --git a/libc/nt/kernel32/_hwrite.s b/libc/nt/kernel32/_hwrite.s deleted file mode 100644 index 24d364da6..000000000 --- a/libc/nt/kernel32/_hwrite.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp__hwrite,_hwrite,1583 diff --git a/libc/nt/kernel32/_lclose.s b/libc/nt/kernel32/_lclose.s deleted file mode 100644 index 1ff92fdd5..000000000 --- a/libc/nt/kernel32/_lclose.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp__lclose,_lclose,1584 diff --git a/libc/nt/kernel32/_lcreat.s b/libc/nt/kernel32/_lcreat.s deleted file mode 100644 index bf03eaeb6..000000000 --- a/libc/nt/kernel32/_lcreat.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp__lcreat,_lcreat,1585 diff --git a/libc/nt/kernel32/_llseek.s b/libc/nt/kernel32/_llseek.s deleted file mode 100644 index da8081d1a..000000000 --- a/libc/nt/kernel32/_llseek.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp__llseek,_llseek,1586 diff --git a/libc/nt/kernel32/_lopen.s b/libc/nt/kernel32/_lopen.s deleted file mode 100644 index 778ad9478..000000000 --- a/libc/nt/kernel32/_lopen.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp__lopen,_lopen,1588 diff --git a/libc/nt/kernel32/_lread.s b/libc/nt/kernel32/_lread.s deleted file mode 100644 index 7acd0848c..000000000 --- a/libc/nt/kernel32/_lread.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp__lread,_lread,1589 diff --git a/libc/nt/kernel32/_lwrite.s b/libc/nt/kernel32/_lwrite.s deleted file mode 100644 index fb8cc513c..000000000 --- a/libc/nt/kernel32/_lwrite.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp__lwrite,_lwrite,1590 diff --git a/libc/nt/kernel32/timeBeginPeriod.s b/libc/nt/kernel32/timeBeginPeriod.s deleted file mode 100644 index 890c9a150..000000000 --- a/libc/nt/kernel32/timeBeginPeriod.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_timeBeginPeriod,timeBeginPeriod,1609 diff --git a/libc/nt/kernel32/timeEndPeriod.s b/libc/nt/kernel32/timeEndPeriod.s deleted file mode 100644 index 8fa1e3f37..000000000 --- a/libc/nt/kernel32/timeEndPeriod.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_timeEndPeriod,timeEndPeriod,1610 diff --git a/libc/nt/kernel32/timeGetDevCaps.s b/libc/nt/kernel32/timeGetDevCaps.s deleted file mode 100644 index 28c17c219..000000000 --- a/libc/nt/kernel32/timeGetDevCaps.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_timeGetDevCaps,timeGetDevCaps,1611 diff --git a/libc/nt/kernel32/timeGetSystemTime.s b/libc/nt/kernel32/timeGetSystemTime.s deleted file mode 100644 index d5ff24c81..000000000 --- a/libc/nt/kernel32/timeGetSystemTime.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_timeGetSystemTime,timeGetSystemTime,1612 diff --git a/libc/nt/kernel32/timeGetTime.s b/libc/nt/kernel32/timeGetTime.s deleted file mode 100644 index 9f36a66d6..000000000 --- a/libc/nt/kernel32/timeGetTime.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_timeGetTime,timeGetTime,1613 diff --git a/libc/nt/master.sh b/libc/nt/master.sh index 1f0a9593e..50db7cd24 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -1,171 +1,1414 @@ -/usr/bin/env echo ' -*- mode:sh; indent-tabs-mode:nil; tab-width:8; coding:utf-8 -*-│ +/usr/bin/env echo ' -*-mode:sh;indent-tabs-mode:nil;tab-width:8;coding:utf-8-*-│ │vi: set net ft=sh 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. │ ╚────────────────────────────────────────────────────────────────'>/dev/null #*/ . libc/nt/codegen.sh # The New Technology API # » so many sections + +# KERNEL32.DLL # # Name Actual DLL Hint Arity -imp 'AbortDoc' AbortDoc gdi32 1011 -imp 'AbortPath' AbortPath gdi32 1012 -imp 'AbortSystemShutdownA' AbortSystemShutdownA advapi32 1005 -imp 'AbortSystemShutdown' AbortSystemShutdownW advapi32 1006 -imp 'AcceptEx' AcceptEx MsWSock 1 8 -imp 'AccessCheck' AccessCheck advapi32 0 8 # KernelBase -imp 'AccessCheckAndAuditAlarm' AccessCheckAndAuditAlarmW advapi32 0 # KernelBase -imp 'AccessCheckAndAuditAlarmA' AccessCheckAndAuditAlarmA advapi32 1008 -imp 'AccessCheckByType' AccessCheckByType advapi32 0 # KernelBase -imp 'AccessCheckByTypeAndAuditAlarm' AccessCheckByTypeAndAuditAlarmW advapi32 0 # KernelBase -imp 'AccessCheckByTypeAndAuditAlarmA' AccessCheckByTypeAndAuditAlarmA advapi32 1011 -imp 'AccessCheckByTypeResultList' AccessCheckByTypeResultList advapi32 0 # KernelBase -imp 'AccessCheckByTypeResultListAndAuditAlarm' AccessCheckByTypeResultListAndAuditAlarmW advapi32 0 # KernelBase -imp 'AccessCheckByTypeResultListAndAuditAlarmA' AccessCheckByTypeResultListAndAuditAlarmA advapi32 1014 -imp 'AccessCheckByTypeResultListAndAuditAlarmByHandle' AccessCheckByTypeResultListAndAuditAlarmByHandleW advapi32 0 # KernelBase -imp 'AccessCheckByTypeResultListAndAuditAlarmByHandleA' AccessCheckByTypeResultListAndAuditAlarmByHandleA advapi32 1015 -imp 'AcquireStateLock' AcquireStateLock KernelBase 11 -imp 'ActivateActCtx' ActivateActCtx kernel32 0 # KernelBase +imp 'AcquireSRWLockExclusive' AcquireSRWLockExclusive kernel32 0 1 +imp 'AcquireSRWLockShared' AcquireSRWLockShared kernel32 0 1 +imp 'ActivateActCtx' ActivateActCtx kernel32 0 imp 'ActivateActCtxWorker' ActivateActCtxWorker kernel32 4 -imp 'ActivateKeyboardLayout' ActivateKeyboardLayout user32 1505 -imp 'AddAccessAllowedAce' AddAccessAllowedAce advapi32 0 # KernelBase -imp 'AddAccessAllowedAceEx' AddAccessAllowedAceEx advapi32 0 # KernelBase -imp 'AddAccessAllowedObjectAce' AddAccessAllowedObjectAce advapi32 0 # KernelBase -imp 'AddAccessDeniedAce' AddAccessDeniedAce advapi32 0 # KernelBase -imp 'AddAccessDeniedAceEx' AddAccessDeniedAceEx advapi32 0 # KernelBase -imp 'AddAccessDeniedObjectAce' AddAccessDeniedObjectAce advapi32 0 # KernelBase -imp 'AddAce' AddAce advapi32 0 # KernelBase -imp 'AddAtomA' AddAtomA kernel32 5 imp 'AddAtom' AddAtomW kernel32 6 -imp 'AddAuditAccessAce' AddAuditAccessAce advapi32 0 # KernelBase -imp 'AddAuditAccessAceEx' AddAuditAccessAceEx advapi32 0 # KernelBase -imp 'AddAuditAccessObjectAce' AddAuditAccessObjectAce advapi32 0 # KernelBase -imp 'AddClipboardFormatListener' AddClipboardFormatListener user32 1506 -imp 'AddConditionalAce' AddConditionalAce advapi32 1028 -imp 'AddConsoleAliasA' AddConsoleAliasA kernel32 0 # KernelBase -imp 'AddConsoleAlias' AddConsoleAliasW kernel32 0 # KernelBase -imp 'AddDllDirectory' AddDllDirectory kernel32 0 # KernelBase -imp 'AddExtensionProgId' AddExtensionProgId KernelBase 26 -imp 'AddFontMemResourceEx' AddFontMemResourceEx gdi32 1017 -imp 'AddFontResourceA' AddFontResourceA gdi32 1018 -imp 'AddFontResourceExA' AddFontResourceExA gdi32 1019 -imp 'AddFontResourceEx' AddFontResourceExW gdi32 1020 -imp 'AddFontResourceTracking' AddFontResourceTracking gdi32 1021 -imp 'AddFontResource' AddFontResourceW gdi32 1022 +imp 'AddConsoleAlias' AddConsoleAliasW kernel32 0 +imp 'AddConsoleAliasA' AddConsoleAliasA kernel32 0 +imp 'AddDllDirectory' AddDllDirectory kernel32 0 imp 'AddIntegrityLabelToBoundaryDescriptor' AddIntegrityLabelToBoundaryDescriptor kernel32 10 -imp 'AddLocalAlternateComputerNameA' AddLocalAlternateComputerNameA kernel32 11 imp 'AddLocalAlternateComputerName' AddLocalAlternateComputerNameW kernel32 12 -imp 'AddMIMEFileTypesPS' AddMIMEFileTypesPS url 102 -imp 'AddMandatoryAce' AddMandatoryAce advapi32 0 # KernelBase -imp 'AddPackageToFamilyXref' AddPackageToFamilyXref KernelBase 28 -imp 'AddRefActCtx' AddRefActCtx kernel32 0 # KernelBase +imp 'AddRefActCtx' AddRefActCtx kernel32 0 imp 'AddRefActCtxWorker' AddRefActCtxWorker kernel32 14 -imp 'AddResourceAttributeAce' AddResourceAttributeAce kernel32 0 # KernelBase -imp 'AddSIDToBoundaryDescriptor' AddSIDToBoundaryDescriptor kernel32 0 # KernelBase -imp 'AddScopedPolicyIDAce' AddScopedPolicyIDAce kernel32 0 # KernelBase +imp 'AddResourceAttributeAce' AddResourceAttributeAce kernel32 0 +imp 'AddSIDToBoundaryDescriptor' AddSIDToBoundaryDescriptor kernel32 0 +imp 'AddScopedPolicyIDAce' AddScopedPolicyIDAce kernel32 0 imp 'AddSecureMemoryCacheCallback' AddSecureMemoryCacheCallback kernel32 18 -imp 'AddUsersToEncryptedFile' AddUsersToEncryptedFile advapi32 1030 -imp 'AddUsersToEncryptedFileEx' AddUsersToEncryptedFileEx advapi32 1031 -imp 'AddVectoredExceptionHandler' AddVectoredExceptionHandler kernel32 0 2 # KernelBase -imp 'AddVectoredContinueHandler' AddVectoredContinueHandler kernel32 0 2 # KernelBase -imp 'RemoveVectoredExceptionHandler' RemoveVectoredExceptionHandler kernel32 0 1 # KernelBase -imp 'RemoveVectoredContinueHandler' RemoveVectoredContinueHandler kernel32 0 1 # KernelBase +imp 'AddVectoredContinueHandler' AddVectoredContinueHandler kernel32 0 2 +imp 'AddVectoredExceptionHandler' AddVectoredExceptionHandler kernel32 0 2 imp 'AdjustCalendarDate' AdjustCalendarDate kernel32 21 -imp 'AdjustTokenGroups' AdjustTokenGroups advapi32 0 # KernelBase -imp 'AdjustTokenPrivileges' AdjustTokenPrivileges advapi32 0 6 # KernelBase -imp 'AdjustWindowRect' AdjustWindowRect user32 1507 3 -imp 'AdjustWindowRectEx' AdjustWindowRectEx user32 1508 -imp 'AdjustWindowRectExForDpi' AdjustWindowRectExForDpi user32 1509 -imp 'AlignRects' AlignRects user32 1510 -imp 'AllocConsole' AllocConsole kernel32 0 0 # KernelBase -imp 'AllocateAndInitializeSid' AllocateAndInitializeSid advapi32 0 # KernelBase -imp 'AllocateLocallyUniqueId' AllocateLocallyUniqueId advapi32 0 # KernelBase -imp 'AllocateUserPhysicalPages' AllocateUserPhysicalPages kernel32 0 # KernelBase -imp 'AllocateUserPhysicalPagesNuma' AllocateUserPhysicalPagesNuma kernel32 0 # KernelBase -imp 'AllowForegroundActivation' AllowForegroundActivation user32 1511 -imp 'AllowSetForegroundWindow' AllowSetForegroundWindow user32 1512 -imp 'AlpcAdjustCompletionListConcurrencyCount' AlpcAdjustCompletionListConcurrencyCount ntdll 12 -imp 'AlpcFreeCompletionListMessage' AlpcFreeCompletionListMessage ntdll 13 -imp 'AlpcGetCompletionListLastMessageInformation' AlpcGetCompletionListLastMessageInformation ntdll 14 -imp 'AlpcGetCompletionListMessageAttributes' AlpcGetCompletionListMessageAttributes ntdll 15 -imp 'AlpcGetHeaderSize' AlpcGetHeaderSize ntdll 16 -imp 'AlpcGetMessageAttribute' AlpcGetMessageAttribute ntdll 17 -imp 'AlpcGetMessageFromCompletionList' AlpcGetMessageFromCompletionList ntdll 18 -imp 'AlpcGetOutstandingCompletionListMessageCount' AlpcGetOutstandingCompletionListMessageCount ntdll 19 -imp 'AlpcInitializeMessageAttribute' AlpcInitializeMessageAttribute ntdll 20 -imp 'AlpcMaxAllowedMessageLength' AlpcMaxAllowedMessageLength ntdll 21 -imp 'AlpcRegisterCompletionList' AlpcRegisterCompletionList ntdll 22 -imp 'AlpcRegisterCompletionListWorkerThread' AlpcRegisterCompletionListWorkerThread ntdll 23 -imp 'AlpcRundownCompletionList' AlpcRundownCompletionList ntdll 24 -imp 'AlpcUnregisterCompletionList' AlpcUnregisterCompletionList ntdll 25 -imp 'AlpcUnregisterCompletionListWorkerThread' AlpcUnregisterCompletionListWorkerThread ntdll 26 -imp 'AngleArc' AngleArc gdi32 1023 -imp 'AnimatePalette' AnimatePalette gdi32 1024 -imp 'AnimateWindow' AnimateWindow user32 1513 3 -imp 'AnyLinkedFonts' AnyLinkedFonts gdi32 1025 -imp 'AnyPopup' AnyPopup user32 1514 -imp 'ApiSetQueryApiSetPresence' ApiSetQueryApiSetPresence ntdll 27 -imp 'AppCompat_RunDLLW' AppCompat_RunDLLW shell32 255 -imp 'AppContainerDeriveSidFromMoniker' AppContainerDeriveSidFromMoniker KernelBase 42 -imp 'AppContainerFreeMemory' AppContainerFreeMemory KernelBase 43 -imp 'AppContainerLookupDisplayNameMrtReference' AppContainerLookupDisplayNameMrtReference KernelBase 44 -imp 'AppContainerLookupMoniker' AppContainerLookupMoniker KernelBase 45 -imp 'AppContainerRegisterSid' AppContainerRegisterSid KernelBase 46 -imp 'AppContainerUnregisterSid' AppContainerUnregisterSid KernelBase 47 -imp 'AppPolicyGetClrCompat' AppPolicyGetClrCompat KernelBase 48 -imp 'AppPolicyGetCreateFileAccess' AppPolicyGetCreateFileAccess KernelBase 49 -imp 'AppPolicyGetLifecycleManagement' AppPolicyGetLifecycleManagement KernelBase 50 -imp 'AppPolicyGetMediaFoundationCodecLoading' AppPolicyGetMediaFoundationCodecLoading KernelBase 51 -imp 'AppPolicyGetProcessTerminationMethod' AppPolicyGetProcessTerminationMethod KernelBase 52 -imp 'AppPolicyGetShowDeveloperDiagnostic' AppPolicyGetShowDeveloperDiagnostic KernelBase 53 -imp 'AppPolicyGetThreadInitializationType' AppPolicyGetThreadInitializationType KernelBase 54 -imp 'AppPolicyGetWindowingModel' AppPolicyGetWindowingModel KernelBase 55 -imp 'AppXFreeMemory' AppXFreeMemory KernelBase 56 -imp 'AppXGetApplicationData' AppXGetApplicationData KernelBase 57 -imp 'AppXGetDevelopmentMode' AppXGetDevelopmentMode KernelBase 58 -imp 'AppXGetOSMaxVersionTested' AppXGetOSMaxVersionTested KernelBase 59 -imp 'AppXGetOSMinVersion' AppXGetOSMinVersion KernelBase 60 -imp 'AppXGetPackageCapabilities' AppXGetPackageCapabilities KernelBase 61 -imp 'AppXGetPackageSid' AppXGetPackageSid KernelBase 62 -imp 'AppXLookupDisplayName' AppXLookupDisplayName KernelBase 63 -imp 'AppXLookupMoniker' AppXLookupMoniker KernelBase 64 -imp 'AppXPostSuccessExtension' AppXPostSuccessExtension KernelBase 65 -imp 'AppXPreCreationExtension' AppXPreCreationExtension KernelBase 66 -imp 'AppXReleaseAppXContext' AppXReleaseAppXContext KernelBase 67 -imp 'AppXUpdatePackageCapabilities' AppXUpdatePackageCapabilities KernelBase 68 -imp 'AppendMenuA' AppendMenuA user32 1515 4 -imp 'AppendMenu' AppendMenuW user32 1516 4 +imp 'AllocConsole' AllocConsole kernel32 0 0 +imp 'AllocateUserPhysicalPages' AllocateUserPhysicalPages kernel32 0 +imp 'AllocateUserPhysicalPagesNuma' AllocateUserPhysicalPagesNuma kernel32 0 imp 'ApplicationRecoveryFinished' ApplicationRecoveryFinished kernel32 34 imp 'ApplicationRecoveryInProgress' ApplicationRecoveryInProgress kernel32 35 -imp 'ApplicationUserModelIdFromProductId' ApplicationUserModelIdFromProductId KernelBase 69 -imp 'Arc' Arc gdi32 1026 -imp 'ArcTo' ArcTo gdi32 1027 -imp 'AreAllAccessesGranted' AreAllAccessesGranted advapi32 0 # KernelBase -imp 'AreAnyAccessesGranted' AreAnyAccessesGranted advapi32 0 # KernelBase -imp 'AreDpiAwarenessContextsEqual' AreDpiAwarenessContextsEqual user32 1517 -imp 'AreFileApisANSI' AreFileApisANSI kernel32 0 # KernelBase -imp 'AreThereVisibleLogoffScriptsInternal' AreThereVisibleLogoffScriptsInternal KernelBase 73 -imp 'AreThereVisibleShutdownScriptsInternal' AreThereVisibleShutdownScriptsInternal KernelBase 74 -imp 'ArrangeIconicWindows' ArrangeIconicWindows user32 1518 +imp 'AreFileApisANSI' AreFileApisANSI kernel32 0 imp 'AssignProcessToJobObject' AssignProcessToJobObject kernel32 37 -imp 'AssocCreateForClasses' AssocCreateForClasses shell32 263 -imp 'AssocGetDetailsOfPropKey' AssocGetDetailsOfPropKey shell32 267 -imp 'AttachConsole' AttachConsole kernel32 0 1 # KernelBase -imp 'AttachThreadInput' AttachThreadInput user32 1519 +imp 'AttachConsole' AttachConsole kernel32 0 1 +imp 'BackupRead' BackupRead kernel32 39 +imp 'BackupSeek' BackupSeek kernel32 40 +imp 'BackupWrite' BackupWrite kernel32 41 +imp 'BaseCheckAppcompatCacheExWorker' BaseCheckAppcompatCacheExWorker kernel32 44 +imp 'BaseCheckAppcompatCacheWorker' BaseCheckAppcompatCacheWorker kernel32 45 +imp 'BaseCheckElevation' BaseCheckElevation kernel32 46 +imp 'BaseCleanupAppcompatCacheSupportWorker' BaseCleanupAppcompatCacheSupportWorker kernel32 48 +imp 'BaseDestroyVDMEnvironment' BaseDestroyVDMEnvironment kernel32 49 +imp 'BaseDllReadWriteIniFile' BaseDllReadWriteIniFile kernel32 50 +imp 'BaseDumpAppcompatCacheWorker' BaseDumpAppcompatCacheWorker kernel32 52 +imp 'BaseElevationPostProcessing' BaseElevationPostProcessing kernel32 53 +imp 'BaseFlushAppcompatCacheWorker' BaseFlushAppcompatCacheWorker kernel32 55 +imp 'BaseFormatTimeOut' BaseFormatTimeOut kernel32 57 +imp 'BaseFreeAppCompatDataForProcessWorker' BaseFreeAppCompatDataForProcessWorker kernel32 58 +imp 'BaseGenerateAppCompatData' BaseGenerateAppCompatData kernel32 59 +imp 'BaseInitAppcompatCacheSupportWorker' BaseInitAppcompatCacheSupportWorker kernel32 62 +imp 'BaseIsAppcompatInfrastructureDisabledWorker' BaseIsAppcompatInfrastructureDisabledWorker kernel32 64 +imp 'BaseIsDosApplication' BaseIsDosApplication kernel32 65 +imp 'BaseQueryModuleData' BaseQueryModuleData kernel32 66 +imp 'BaseReadAppCompatDataForProcessWorker' BaseReadAppCompatDataForProcessWorker kernel32 67 +imp 'BaseSetLastNTError' BaseSetLastNTError kernel32 68 +imp 'BaseThreadInitThunk' BaseThreadInitThunk kernel32 69 +imp 'BaseUpdateAppcompatCacheWorker' BaseUpdateAppcompatCacheWorker kernel32 71 +imp 'BaseUpdateVDMEntry' BaseUpdateVDMEntry kernel32 72 +imp 'BaseVerifyUnicodeString' BaseVerifyUnicodeString kernel32 73 +imp 'BaseWriteErrorElevationRequiredEvent' BaseWriteErrorElevationRequiredEvent kernel32 74 +imp 'Basep8BitStringToDynamicUnicodeString' Basep8BitStringToDynamicUnicodeString kernel32 75 +imp 'BasepAllocateActivationContextActivationBlock' BasepAllocateActivationContextActivationBlock kernel32 76 +imp 'BasepAnsiStringToDynamicUnicodeString' BasepAnsiStringToDynamicUnicodeString kernel32 77 +imp 'BasepAppContainerEnvironmentExtension' BasepAppContainerEnvironmentExtension kernel32 78 +imp 'BasepAppXExtension' BasepAppXExtension kernel32 79 +imp 'BasepCheckAppCompat' BasepCheckAppCompat kernel32 80 +imp 'BasepCheckWebBladeHashes' BasepCheckWebBladeHashes kernel32 81 +imp 'BasepCheckWinSaferRestrictions' BasepCheckWinSaferRestrictions kernel32 82 +imp 'BasepConstructSxsCreateProcessMessage' BasepConstructSxsCreateProcessMessage kernel32 83 +imp 'BasepCopyEncryption' BasepCopyEncryption kernel32 84 +imp 'BasepFreeActivationContextActivationBlock' BasepFreeActivationContextActivationBlock kernel32 85 +imp 'BasepFreeAppCompatData' BasepFreeAppCompatData kernel32 86 +imp 'BasepGetAppCompatData' BasepGetAppCompatData kernel32 87 +imp 'BasepGetComputerNameFromNtPath' BasepGetComputerNameFromNtPath kernel32 88 +imp 'BasepGetExeArchType' BasepGetExeArchType kernel32 89 +imp 'BasepInitAppCompatData' BasepInitAppCompatData kernel32 90 +imp 'BasepIsProcessAllowed' BasepIsProcessAllowed kernel32 91 +imp 'BasepMapModuleHandle' BasepMapModuleHandle kernel32 92 +imp 'BasepNotifyLoadStringResource' BasepNotifyLoadStringResource kernel32 93 +imp 'BasepPostSuccessAppXExtension' BasepPostSuccessAppXExtension kernel32 94 +imp 'BasepProcessInvalidImage' BasepProcessInvalidImage kernel32 95 +imp 'BasepQueryAppCompat' BasepQueryAppCompat kernel32 96 +imp 'BasepQueryModuleChpeSettings' BasepQueryModuleChpeSettings kernel32 97 +imp 'BasepReleaseAppXContext' BasepReleaseAppXContext kernel32 98 +imp 'BasepReleaseSxsCreateProcessUtilityStruct' BasepReleaseSxsCreateProcessUtilityStruct kernel32 99 +imp 'BasepReportFault' BasepReportFault kernel32 100 +imp 'BasepSetFileEncryptionCompression' BasepSetFileEncryptionCompression kernel32 101 +imp 'Beep' Beep kernel32 0 +imp 'BeginUpdateResource' BeginUpdateResourceW kernel32 104 +imp 'BindIoCompletionCallback' BindIoCompletionCallback kernel32 105 +imp 'BuildCommDCBA' BuildCommDCBA kernel32 106 +imp 'BuildCommDCBAndTimeouts' BuildCommDCBAndTimeoutsW kernel32 108 +imp 'BuildCommDCBAndTimeoutsA' BuildCommDCBAndTimeoutsA kernel32 107 +imp 'BuildCommDCBW' BuildCommDCBW kernel32 109 +imp 'CallNamedPipe' CallNamedPipeW kernel32 0 7 +imp 'CallNamedPipeA' CallNamedPipeA kernel32 110 7 +imp 'CallbackMayRunLong' CallbackMayRunLong kernel32 0 +imp 'CancelDeviceWakeupRequest' CancelDeviceWakeupRequest kernel32 113 +imp 'CancelIo' CancelIo kernel32 0 1 +imp 'CancelIoEx' CancelIoEx kernel32 0 2 +imp 'CancelSynchronousIo' CancelSynchronousIo kernel32 0 1 +imp 'CancelTimerQueueTimer' CancelTimerQueueTimer kernel32 118 +imp 'CancelWaitableTimer' CancelWaitableTimer kernel32 0 +imp 'CeipIsOptedIn' CeipIsOptedIn kernel32 0 +imp 'ChangeTimerQueueTimer' ChangeTimerQueueTimer kernel32 0 +imp 'CheckElevation' CheckElevation kernel32 123 +imp 'CheckElevationEnabled' CheckElevationEnabled kernel32 124 +imp 'CheckForReadOnlyResource' CheckForReadOnlyResource kernel32 125 +imp 'CheckForReadOnlyResourceFilter' CheckForReadOnlyResourceFilter kernel32 126 +imp 'CheckNameLegalDOS8Dot3' CheckNameLegalDOS8Dot3W kernel32 128 +imp 'CheckRemoteDebuggerPresent' CheckRemoteDebuggerPresent kernel32 0 2 +imp 'CheckTokenCapability' CheckTokenCapability kernel32 0 +imp 'CheckTokenMembershipEx' CheckTokenMembershipEx kernel32 0 +imp 'ClearCommBreak' ClearCommBreak kernel32 0 +imp 'ClearCommError' ClearCommError kernel32 0 +imp 'CloseConsoleHandle' CloseConsoleHandle kernel32 134 +imp 'ClosePackageInfo' ClosePackageInfo kernel32 0 +imp 'ClosePrivateNamespace' ClosePrivateNamespace kernel32 0 +imp 'CloseProfileUserMapping' CloseProfileUserMapping kernel32 138 +imp 'CmdBatNotification' CmdBatNotification kernel32 147 +imp 'CommConfigDialog' CommConfigDialogW kernel32 149 +imp 'CompareCalendarDates' CompareCalendarDates kernel32 150 +imp 'CompareFileTime' CompareFileTime kernel32 0 +imp 'CompareString' CompareStringW kernel32 0 +imp 'CompareStringEx' CompareStringEx kernel32 0 +imp 'CompareStringOrdinal' CompareStringOrdinal kernel32 0 +imp 'ConnectNamedPipe' ConnectNamedPipe kernel32 0 2 +imp 'ConsoleMenuControl' ConsoleMenuControl kernel32 157 +imp 'ContinueDebugEvent' ContinueDebugEvent kernel32 0 3 +imp 'ConvertCalDateTimeToSystemTime' ConvertCalDateTimeToSystemTime kernel32 159 +imp 'ConvertDefaultLocale' ConvertDefaultLocale kernel32 0 +imp 'ConvertFiberToThread' ConvertFiberToThread kernel32 0 +imp 'ConvertNLSDayOfWeekToWin32DayOfWeek' ConvertNLSDayOfWeekToWin32DayOfWeek kernel32 162 +imp 'ConvertSystemTimeToCalDateTime' ConvertSystemTimeToCalDateTime kernel32 163 +imp 'ConvertThreadToFiber' ConvertThreadToFiber kernel32 0 +imp 'ConvertThreadToFiberEx' ConvertThreadToFiberEx kernel32 0 +imp 'CopyContext' CopyContext kernel32 0 +imp 'CopyFile' CopyFileW kernel32 0 3 +imp 'CopyFile2' CopyFile2 kernel32 0 +imp 'CopyFileA' CopyFileA kernel32 168 3 +imp 'CopyFileEx' CopyFileExW kernel32 0 +imp 'CopyFileExA' CopyFileExA kernel32 169 +imp 'CopyFileTransacted' CopyFileTransactedW kernel32 172 +imp 'CopyFileTransactedA' CopyFileTransactedA kernel32 171 +imp 'CopyLZFile' CopyLZFile kernel32 174 +imp 'CreateActCtx' CreateActCtxW kernel32 0 +imp 'CreateActCtxA' CreateActCtxA kernel32 175 +imp 'CreateActCtxWWorker' CreateActCtxWWorker kernel32 177 +imp 'CreateBoundaryDescriptor' CreateBoundaryDescriptorW kernel32 0 +imp 'CreateBoundaryDescriptorA' CreateBoundaryDescriptorA kernel32 178 +imp 'CreateConsoleScreenBuffer' CreateConsoleScreenBuffer kernel32 0 +imp 'CreateDirectoryA' CreateDirectoryA kernel32 0 2 +imp 'CreateDirectoryEx' CreateDirectoryExW kernel32 0 +imp 'CreateDirectoryExA' CreateDirectoryExA kernel32 182 +imp 'CreateDirectoryTransacted' CreateDirectoryTransactedW kernel32 185 +imp 'CreateDirectoryTransactedA' CreateDirectoryTransactedA kernel32 184 +imp 'CreateEvent' CreateEventW kernel32 0 4 +imp 'CreateEventA' CreateEventA kernel32 0 4 +imp 'CreateEventEx' CreateEventExW kernel32 0 4 +imp 'CreateEventExA' CreateEventExA kernel32 0 4 +imp 'CreateFiber' CreateFiber kernel32 0 +imp 'CreateFiberEx' CreateFiberEx kernel32 0 +imp 'CreateFile2' CreateFile2 kernel32 0 +imp 'CreateFileA' CreateFileA kernel32 0 7 +imp 'CreateFileMappingA' CreateFileMappingA kernel32 196 7 +imp 'CreateFileMappingFromApp' CreateFileMappingFromApp kernel32 0 +imp 'CreateFileMappingNumaA' CreateFileMappingNumaA kernel32 198 7 +imp 'CreateFileTransacted' CreateFileTransactedW kernel32 202 +imp 'CreateFileTransactedA' CreateFileTransactedA kernel32 201 +imp 'CreateHardLink' CreateHardLinkW kernel32 0 3 +imp 'CreateHardLinkA' CreateHardLinkA kernel32 0 3 +imp 'CreateHardLinkTransacted' CreateHardLinkTransactedW kernel32 206 +imp 'CreateHardLinkTransactedA' CreateHardLinkTransactedA kernel32 205 +imp 'CreateIoCompletionPort' CreateIoCompletionPort kernel32 0 4 +imp 'CreateJobObject' CreateJobObjectW kernel32 210 +imp 'CreateJobObjectA' CreateJobObjectA kernel32 209 +imp 'CreateJobSet' CreateJobSet kernel32 211 +imp 'CreateMailslot' CreateMailslotW kernel32 213 +imp 'CreateMailslotA' CreateMailslotA kernel32 212 +imp 'CreateMemoryResourceNotification' CreateMemoryResourceNotification kernel32 0 +imp 'CreateMutex' CreateMutexW kernel32 0 +imp 'CreateMutexA' CreateMutexA kernel32 0 +imp 'CreateMutexEx' CreateMutexExW kernel32 0 +imp 'CreateMutexExA' CreateMutexExA kernel32 0 +imp 'CreateNamedPipeA' CreateNamedPipeA kernel32 219 8 +imp 'CreatePrivateNamespace' CreatePrivateNamespaceW kernel32 0 +imp 'CreatePrivateNamespaceA' CreatePrivateNamespaceA kernel32 222 +imp 'CreateProcessA' CreateProcessA kernel32 0 10 +imp 'CreateRemoteThread' CreateRemoteThread kernel32 0 +imp 'CreateRemoteThreadEx' CreateRemoteThreadEx kernel32 0 +imp 'CreateSemaphore' CreateSemaphoreW kernel32 0 +imp 'CreateSemaphoreA' CreateSemaphoreA kernel32 232 +imp 'CreateSemaphoreEx' CreateSemaphoreExW kernel32 0 +imp 'CreateSemaphoreExA' CreateSemaphoreExA kernel32 233 +imp 'CreateSymbolicLinkA' CreateSymbolicLinkA kernel32 0 3 +imp 'CreateSymbolicLinkTransacted' CreateSymbolicLinkTransactedW kernel32 238 +imp 'CreateSymbolicLinkTransactedA' CreateSymbolicLinkTransactedA kernel32 237 +imp 'CreateTapePartition' CreateTapePartition kernel32 240 +imp 'CreateThreadpool' CreateThreadpool kernel32 0 +imp 'CreateThreadpoolCleanupGroup' CreateThreadpoolCleanupGroup kernel32 0 +imp 'CreateThreadpoolIo' CreateThreadpoolIo kernel32 0 +imp 'CreateThreadpoolTimer' CreateThreadpoolTimer kernel32 0 +imp 'CreateThreadpoolWait' CreateThreadpoolWait kernel32 0 +imp 'CreateThreadpoolWork' CreateThreadpoolWork kernel32 0 +imp 'CreateTimerQueue' CreateTimerQueue kernel32 0 +imp 'CreateTimerQueueTimer' CreateTimerQueueTimer kernel32 0 +imp 'CreateToolhelp32Snapshot' CreateToolhelp32Snapshot kernel32 250 +imp 'CreateUmsCompletionList' CreateUmsCompletionList kernel32 251 +imp 'CreateUmsThreadContext' CreateUmsThreadContext kernel32 252 +imp 'CreateWaitableTimer' CreateWaitableTimerW kernel32 0 3 +imp 'CreateWaitableTimerA' CreateWaitableTimerA kernel32 253 3 +imp 'CreateWaitableTimerEx' CreateWaitableTimerExW kernel32 0 4 +imp 'CreateWaitableTimerExA' CreateWaitableTimerExA kernel32 254 4 +imp 'DeactivateActCtx' DeactivateActCtx kernel32 0 +imp 'DeactivateActCtxWorker' DeactivateActCtxWorker kernel32 259 +imp 'DebugActiveProcess' DebugActiveProcess kernel32 0 1 +imp 'DebugActiveProcessStop' DebugActiveProcessStop kernel32 0 1 +imp 'DebugBreakProcess' DebugBreakProcess kernel32 263 1 +imp 'DebugSetProcessKillOnExit' DebugSetProcessKillOnExit kernel32 264 +imp 'DefineDosDevice' DefineDosDeviceW kernel32 0 +imp 'DefineDosDeviceA' DefineDosDeviceA kernel32 267 +imp 'DeleteAtom' DeleteAtom kernel32 270 +imp 'DeleteBoundaryDescriptor' DeleteBoundaryDescriptor kernel32 0 +imp 'DeleteCriticalSection' DeleteCriticalSection kernel32 0 1 +imp 'DeleteFiber' DeleteFiber kernel32 0 +imp 'DeleteFileA' DeleteFileA kernel32 0 1 +imp 'DeleteFileTransacted' DeleteFileTransactedW kernel32 276 +imp 'DeleteFileTransactedA' DeleteFileTransactedA kernel32 275 +imp 'DeleteProcThreadAttributeList' DeleteProcThreadAttributeList kernel32 0 1 +imp 'DeleteSynchronizationBarrier' DeleteSynchronizationBarrier kernel32 279 +imp 'DeleteTimerQueue' DeleteTimerQueue kernel32 280 +imp 'DeleteTimerQueueEx' DeleteTimerQueueEx kernel32 0 +imp 'DeleteTimerQueueTimer' DeleteTimerQueueTimer kernel32 0 +imp 'DeleteUmsCompletionList' DeleteUmsCompletionList kernel32 283 +imp 'DeleteUmsThreadContext' DeleteUmsThreadContext kernel32 284 +imp 'DeleteVolumeMountPoint' DeleteVolumeMountPointW kernel32 0 +imp 'DeleteVolumeMountPointA' DeleteVolumeMountPointA kernel32 285 +imp 'DequeueUmsCompletionListItems' DequeueUmsCompletionListItems kernel32 287 +imp 'DisableThreadLibraryCalls' DisableThreadLibraryCalls kernel32 0 +imp 'DisableThreadProfiling' DisableThreadProfiling kernel32 290 +imp 'DiscardVirtualMemory' DiscardVirtualMemory kernel32 0 +imp 'DisconnectNamedPipe' DisconnectNamedPipe kernel32 0 1 +imp 'DnsHostnameToComputerName' DnsHostnameToComputerNameW kernel32 296 +imp 'DnsHostnameToComputerNameA' DnsHostnameToComputerNameA kernel32 294 +imp 'DosDateTimeToFileTime' DosDateTimeToFileTime kernel32 297 +imp 'DosPathToSessionPath' DosPathToSessionPathW kernel32 299 +imp 'DosPathToSessionPathA' DosPathToSessionPathA kernel32 298 +imp 'DuplicateConsoleHandle' DuplicateConsoleHandle kernel32 300 +imp 'DuplicateEncryptionInfoFileExt' DuplicateEncryptionInfoFileExt kernel32 301 +imp 'DuplicateHandle' DuplicateHandle kernel32 0 7 +imp 'EnableThreadProfiling' EnableThreadProfiling kernel32 303 +imp 'EndUpdateResource' EndUpdateResourceW kernel32 307 +imp 'EndUpdateResourceA' EndUpdateResourceA kernel32 306 +imp 'EnterCriticalSection' EnterCriticalSection kernel32 0 1 +imp 'EnterSynchronizationBarrier' EnterSynchronizationBarrier kernel32 0 +imp 'EnterUmsSchedulingMode' EnterUmsSchedulingMode kernel32 310 +imp 'EnumCalendarInfo' EnumCalendarInfoW kernel32 0 +imp 'EnumCalendarInfoA' EnumCalendarInfoA kernel32 311 +imp 'EnumCalendarInfoEx' EnumCalendarInfoExW kernel32 0 +imp 'EnumCalendarInfoExA' EnumCalendarInfoExA kernel32 312 +imp 'EnumCalendarInfoExEx' EnumCalendarInfoExEx kernel32 0 +imp 'EnumDateFormats' EnumDateFormatsW kernel32 0 +imp 'EnumDateFormatsA' EnumDateFormatsA kernel32 316 +imp 'EnumDateFormatsEx' EnumDateFormatsExW kernel32 0 +imp 'EnumDateFormatsExA' EnumDateFormatsExA kernel32 317 +imp 'EnumDateFormatsExEx' EnumDateFormatsExEx kernel32 0 +imp 'EnumLanguageGroupLocales' EnumLanguageGroupLocalesW kernel32 0 +imp 'EnumLanguageGroupLocalesA' EnumLanguageGroupLocalesA kernel32 321 +imp 'EnumResourceLanguages' EnumResourceLanguagesW kernel32 326 +imp 'EnumResourceLanguagesA' EnumResourceLanguagesA kernel32 323 +imp 'EnumResourceLanguagesEx' EnumResourceLanguagesExW kernel32 0 +imp 'EnumResourceLanguagesExA' EnumResourceLanguagesExA kernel32 0 +imp 'EnumResourceNames' EnumResourceNamesW kernel32 0 +imp 'EnumResourceNamesA' EnumResourceNamesA kernel32 327 +imp 'EnumResourceNamesEx' EnumResourceNamesExW kernel32 0 +imp 'EnumResourceNamesExA' EnumResourceNamesExA kernel32 0 +imp 'EnumResourceTypes' EnumResourceTypesW kernel32 334 +imp 'EnumResourceTypesA' EnumResourceTypesA kernel32 331 +imp 'EnumResourceTypesEx' EnumResourceTypesExW kernel32 0 +imp 'EnumResourceTypesExA' EnumResourceTypesExA kernel32 0 +imp 'EnumSystemCodePages' EnumSystemCodePagesW kernel32 0 +imp 'EnumSystemCodePagesA' EnumSystemCodePagesA kernel32 335 +imp 'EnumSystemFirmwareTables' EnumSystemFirmwareTables kernel32 0 +imp 'EnumSystemGeoID' EnumSystemGeoID kernel32 0 +imp 'EnumSystemGeoNames' EnumSystemGeoNames kernel32 318 +imp 'EnumSystemLanguageGroups' EnumSystemLanguageGroupsW kernel32 0 +imp 'EnumSystemLanguageGroupsA' EnumSystemLanguageGroupsA kernel32 340 +imp 'EnumSystemLocales' EnumSystemLocalesW kernel32 0 +imp 'EnumSystemLocalesA' EnumSystemLocalesA kernel32 0 +imp 'EnumSystemLocalesEx' EnumSystemLocalesEx kernel32 0 +imp 'EnumTimeFormats' EnumTimeFormatsW kernel32 0 +imp 'EnumTimeFormatsA' EnumTimeFormatsA kernel32 345 +imp 'EnumTimeFormatsEx' EnumTimeFormatsEx kernel32 0 +imp 'EnumUILanguages' EnumUILanguagesW kernel32 0 +imp 'EnumUILanguagesA' EnumUILanguagesA kernel32 348 +imp 'EnumerateLocalComputerNames' EnumerateLocalComputerNamesW kernel32 351 +imp 'EnumerateLocalComputerNamesA' EnumerateLocalComputerNamesA kernel32 350 +imp 'EraseTape' EraseTape kernel32 352 +imp 'EscapeCommFunction' EscapeCommFunction kernel32 0 +imp 'ExecuteUmsThread' ExecuteUmsThread kernel32 354 +imp 'ExitThread' ExitThread kernel32 0 1 +imp 'ExitProcess' ExitProcess kernel32 0 1 # a.k.a. RtlExitUserProcess +imp 'ExitVDM' ExitVDM kernel32 357 +imp 'ExpandEnvironmentStrings' ExpandEnvironmentStringsW kernel32 0 +imp 'ExpandEnvironmentStringsA' ExpandEnvironmentStringsA kernel32 0 +imp 'FatalAppExit' FatalAppExitW kernel32 0 +imp 'FatalAppExitA' FatalAppExitA kernel32 0 +imp 'FatalExit' FatalExit kernel32 364 1 +imp 'FileTimeToDosDateTime' FileTimeToDosDateTime kernel32 365 +imp 'FileTimeToLocalFileTime' FileTimeToLocalFileTime kernel32 0 +imp 'FileTimeToSystemTime' FileTimeToSystemTime kernel32 0 +imp 'FillConsoleOutputAttribute' FillConsoleOutputAttribute kernel32 0 5 +imp 'FillConsoleOutputCharacter' FillConsoleOutputCharacterW kernel32 0 5 +imp 'FillConsoleOutputCharacterA' FillConsoleOutputCharacterA kernel32 0 5 +imp 'FindActCtxSectionGuid' FindActCtxSectionGuid kernel32 0 +imp 'FindActCtxSectionGuidWorker' FindActCtxSectionGuidWorker kernel32 372 +imp 'FindActCtxSectionString' FindActCtxSectionStringW kernel32 0 +imp 'FindActCtxSectionStringA' FindActCtxSectionStringA kernel32 373 +imp 'FindActCtxSectionStringWWorker' FindActCtxSectionStringWWorker kernel32 375 +imp 'FindAtom' FindAtomW kernel32 377 +imp 'FindAtomA' FindAtomA kernel32 376 +imp 'FindCloseChangeNotification' FindCloseChangeNotification kernel32 0 +imp 'FindFirstChangeNotification' FindFirstChangeNotificationW kernel32 0 +imp 'FindFirstChangeNotificationA' FindFirstChangeNotificationA kernel32 0 +imp 'FindFirstFileA' FindFirstFileA kernel32 0 2 +imp 'FindFirstFileEx' FindFirstFileExW kernel32 0 6 +imp 'FindFirstFileExA' FindFirstFileExA kernel32 0 6 +imp 'FindFirstFileName' FindFirstFileNameW kernel32 0 +imp 'FindFirstFileNameTransacted' FindFirstFileNameTransactedW kernel32 385 +imp 'FindFirstFileTransacted' FindFirstFileTransactedW kernel32 388 +imp 'FindFirstFileTransactedA' FindFirstFileTransactedA kernel32 387 +imp 'FindFirstStream' FindFirstStreamW kernel32 0 +imp 'FindFirstStreamTransacted' FindFirstStreamTransactedW kernel32 390 +imp 'FindFirstVolume' FindFirstVolumeW kernel32 0 2 +imp 'FindFirstVolumeA' FindFirstVolumeA kernel32 392 2 +imp 'FindFirstVolumeMountPoint' FindFirstVolumeMountPointW kernel32 394 +imp 'FindFirstVolumeMountPointA' FindFirstVolumeMountPointA kernel32 393 +imp 'FindNLSString' FindNLSString kernel32 0 +imp 'FindNLSStringEx' FindNLSStringEx kernel32 0 +imp 'FindNextChangeNotification' FindNextChangeNotification kernel32 0 +imp 'FindNextFileA' FindNextFileA kernel32 0 2 +imp 'FindNextFileName' FindNextFileNameW kernel32 0 +imp 'FindNextStream' FindNextStreamW kernel32 0 +imp 'FindNextVolume' FindNextVolumeW kernel32 0 3 +imp 'FindNextVolumeA' FindNextVolumeA kernel32 403 3 +imp 'FindNextVolumeMountPoint' FindNextVolumeMountPointW kernel32 405 +imp 'FindNextVolumeMountPointA' FindNextVolumeMountPointA kernel32 404 +imp 'FindPackagesByPackageFamily' FindPackagesByPackageFamily kernel32 0 +imp 'FindResource' FindResourceW kernel32 0 +imp 'FindResourceA' FindResourceA kernel32 408 +imp 'FindResourceEx' FindResourceExW kernel32 0 +imp 'FindResourceExA' FindResourceExA kernel32 409 +imp 'FindStringOrdinal' FindStringOrdinal kernel32 0 +imp 'FindVolumeClose' FindVolumeClose kernel32 0 1 +imp 'FindVolumeMountPointClose' FindVolumeMountPointClose kernel32 414 +imp 'FlsAlloc' FlsAlloc kernel32 0 +imp 'FlsFree' FlsFree kernel32 0 +imp 'FlsGetValue' FlsGetValue kernel32 0 +imp 'FlsSetValue' FlsSetValue kernel32 0 +imp 'FlushConsoleInputBuffer' FlushConsoleInputBuffer kernel32 0 1 +imp 'FlushInstructionCache' FlushInstructionCache kernel32 0 +imp 'FoldString' FoldStringW kernel32 0 +imp 'FoldStringA' FoldStringA kernel32 424 +imp 'FormatApplicationUserModelId' FormatApplicationUserModelId kernel32 0 +imp 'FormatMessage' FormatMessageW kernel32 0 7 +imp 'FormatMessageA' FormatMessageA kernel32 0 7 +imp 'FreeConsole' FreeConsole kernel32 0 0 +imp 'FreeEnvironmentStrings' FreeEnvironmentStringsW kernel32 0 1 +imp 'FreeEnvironmentStringsA' FreeEnvironmentStringsA kernel32 0 1 +imp 'FreeLibrary' FreeLibrary kernel32 0 1 +imp 'FreeLibraryAndExitThread' FreeLibraryAndExitThread kernel32 0 +imp 'FreeMemoryJobObject' FreeMemoryJobObject kernel32 435 +imp 'FreeResource' FreeResource kernel32 0 1 +imp 'FreeUserPhysicalPages' FreeUserPhysicalPages kernel32 0 +imp 'GetACP' GetACP kernel32 0 +imp 'GetActiveProcessorCount' GetActiveProcessorCount kernel32 440 +imp 'GetActiveProcessorGroupCount' GetActiveProcessorGroupCount kernel32 441 +imp 'GetAppContainerNamedObjectPath' GetAppContainerNamedObjectPath kernel32 0 +imp 'GetApplicationRecoveryCallback' GetApplicationRecoveryCallback kernel32 0 +imp 'GetApplicationRecoveryCallbackWorker' GetApplicationRecoveryCallbackWorker kernel32 445 +imp 'GetApplicationRestartSettings' GetApplicationRestartSettings kernel32 0 +imp 'GetApplicationRestartSettingsWorker' GetApplicationRestartSettingsWorker kernel32 447 +imp 'GetApplicationUserModelId' GetApplicationUserModelId kernel32 0 +imp 'GetAtomName' GetAtomNameW kernel32 450 +imp 'GetAtomNameA' GetAtomNameA kernel32 449 +imp 'GetBinaryType' GetBinaryTypeW kernel32 453 +imp 'GetBinaryTypeA' GetBinaryTypeA kernel32 452 +imp 'GetCPInfo' GetCPInfo kernel32 0 +imp 'GetCPInfoEx' GetCPInfoExW kernel32 0 +imp 'GetCPInfoExA' GetCPInfoExA kernel32 455 +imp 'GetCalendarDateFormat' GetCalendarDateFormat kernel32 458 +imp 'GetCalendarDateFormatEx' GetCalendarDateFormatEx kernel32 459 +imp 'GetCalendarDaysInMonth' GetCalendarDaysInMonth kernel32 460 +imp 'GetCalendarDifferenceInDays' GetCalendarDifferenceInDays kernel32 461 +imp 'GetCalendarInfo' GetCalendarInfoW kernel32 0 +imp 'GetCalendarInfoA' GetCalendarInfoA kernel32 462 +imp 'GetCalendarInfoEx' GetCalendarInfoEx kernel32 0 +imp 'GetCalendarMonthsInYear' GetCalendarMonthsInYear kernel32 465 +imp 'GetCalendarSupportedDateRange' GetCalendarSupportedDateRange kernel32 466 +imp 'GetCalendarWeekNumber' GetCalendarWeekNumber kernel32 467 +imp 'GetComPlusPackageInstallStatus' GetComPlusPackageInstallStatus kernel32 468 +imp 'GetCommConfig' GetCommConfig kernel32 0 +imp 'GetCommMask' GetCommMask kernel32 0 +imp 'GetCommModemStatus' GetCommModemStatus kernel32 0 +imp 'GetCommProperties' GetCommProperties kernel32 0 +imp 'GetCommState' GetCommState kernel32 0 +imp 'GetCommTimeouts' GetCommTimeouts kernel32 0 +imp 'GetCommandLine' GetCommandLineW kernel32 0 0 +imp 'GetCommandLineA' GetCommandLineA kernel32 0 0 +imp 'GetCompressedFileSize' GetCompressedFileSizeW kernel32 0 2 +imp 'GetCompressedFileSizeA' GetCompressedFileSizeA kernel32 0 2 +imp 'GetCompressedFileSizeTransacted' GetCompressedFileSizeTransactedW kernel32 479 +imp 'GetCompressedFileSizeTransactedA' GetCompressedFileSizeTransactedA kernel32 478 +imp 'GetComputerName' GetComputerNameW kernel32 484 +imp 'GetComputerNameA' GetComputerNameA kernel32 481 +imp 'GetComputerNameEx' GetComputerNameExW kernel32 0 3 +imp 'GetComputerNameExA' GetComputerNameExA kernel32 0 3 +imp 'GetConsoleAlias' GetConsoleAliasW kernel32 0 +imp 'GetConsoleAliasA' GetConsoleAliasA kernel32 0 +imp 'GetConsoleAliasExes' GetConsoleAliasExesW kernel32 0 +imp 'GetConsoleAliasExesA' GetConsoleAliasExesA kernel32 0 +imp 'GetConsoleAliasExesLength' GetConsoleAliasExesLengthW kernel32 0 +imp 'GetConsoleAliasExesLengthA' GetConsoleAliasExesLengthA kernel32 0 +imp 'GetConsoleAliases' GetConsoleAliasesW kernel32 0 +imp 'GetConsoleAliasesA' GetConsoleAliasesA kernel32 0 +imp 'GetConsoleAliasesLength' GetConsoleAliasesLengthW kernel32 0 +imp 'GetConsoleAliasesLengthA' GetConsoleAliasesLengthA kernel32 0 +imp 'GetConsoleCP' GetConsoleCP kernel32 0 0 +imp 'GetConsoleCharType' GetConsoleCharType kernel32 496 +imp 'GetConsoleCursorInfo' GetConsoleCursorInfo kernel32 0 2 +imp 'GetConsoleCursorMode' GetConsoleCursorMode kernel32 502 +imp 'GetConsoleDisplayMode' GetConsoleDisplayMode kernel32 0 +imp 'GetConsoleFontInfo' GetConsoleFontInfo kernel32 504 +imp 'GetConsoleFontSize' GetConsoleFontSize kernel32 0 +imp 'GetConsoleHardwareState' GetConsoleHardwareState kernel32 506 +imp 'GetConsoleHistoryInfo' GetConsoleHistoryInfo kernel32 0 +imp 'GetConsoleInputWaitHandle' GetConsoleInputWaitHandle kernel32 510 +imp 'GetConsoleKeyboardLayoutName' GetConsoleKeyboardLayoutNameW kernel32 512 +imp 'GetConsoleKeyboardLayoutNameA' GetConsoleKeyboardLayoutNameA kernel32 511 +imp 'GetConsoleMode' GetConsoleMode kernel32 0 2 +imp 'GetConsoleNlsMode' GetConsoleNlsMode kernel32 514 +imp 'GetConsoleOriginalTitle' GetConsoleOriginalTitleW kernel32 0 +imp 'GetConsoleOriginalTitleA' GetConsoleOriginalTitleA kernel32 0 +imp 'GetConsoleOutputCP' GetConsoleOutputCP kernel32 0 0 +imp 'GetConsoleProcessList' GetConsoleProcessList kernel32 0 +imp 'GetConsoleScreenBufferInfo' GetConsoleScreenBufferInfo kernel32 0 2 +imp 'GetConsoleScreenBufferInfoEx' GetConsoleScreenBufferInfoEx kernel32 0 2 +imp 'GetConsoleSelectionInfo' GetConsoleSelectionInfo kernel32 0 1 +imp 'GetConsoleTitle' GetConsoleTitleW kernel32 0 2 +imp 'GetConsoleTitleA' GetConsoleTitleA kernel32 0 2 +imp 'GetConsoleWindow' GetConsoleWindow kernel32 0 0 +imp 'GetCurrencyFormat' GetCurrencyFormatW kernel32 0 +imp 'GetCurrencyFormatA' GetCurrencyFormatA kernel32 525 +imp 'GetCurrencyFormatEx' GetCurrencyFormatEx kernel32 0 +imp 'GetCurrentActCtx' GetCurrentActCtx kernel32 0 +imp 'GetCurrentActCtxWorker' GetCurrentActCtxWorker kernel32 529 +imp 'GetCurrentApplicationUserModelId' GetCurrentApplicationUserModelId kernel32 0 +imp 'GetCurrentConsoleFont' GetCurrentConsoleFont kernel32 0 +imp 'GetCurrentConsoleFontEx' GetCurrentConsoleFontEx kernel32 0 +imp 'GetCurrentDirectory' GetCurrentDirectoryW kernel32 0 2 +imp 'GetCurrentDirectoryA' GetCurrentDirectoryA kernel32 0 2 +imp 'GetCurrentPackageFamilyName' GetCurrentPackageFamilyName kernel32 0 +imp 'GetCurrentPackageFullName' GetCurrentPackageFullName kernel32 0 +imp 'GetCurrentPackageId' GetCurrentPackageId kernel32 0 +imp 'GetCurrentPackageInfo' GetCurrentPackageInfo kernel32 0 +imp 'GetCurrentPackagePath' GetCurrentPackagePath kernel32 0 +imp 'GetCurrentProcess' GetCurrentProcess kernel32 0 0 +imp 'GetCurrentProcessId' GetCurrentProcessId kernel32 0 0 +imp 'GetCurrentThread' GetCurrentThread kernel32 0 0 +imp 'GetCurrentThreadId' GetCurrentThreadId kernel32 0 0 +imp 'GetCurrentThreadStackLimits' GetCurrentThreadStackLimits kernel32 0 +imp 'GetCurrentUmsThread' GetCurrentUmsThread kernel32 547 +imp 'GetDateFormat' GetDateFormatW kernel32 0 +imp 'GetDateFormatA' GetDateFormatA kernel32 0 +imp 'GetDateFormatAWorker' GetDateFormatAWorker kernel32 549 +imp 'GetDateFormatEx' GetDateFormatEx kernel32 0 +imp 'GetDateFormatWWorker' GetDateFormatWWorker kernel32 552 +imp 'GetDefaultCommConfig' GetDefaultCommConfigW kernel32 554 +imp 'GetDefaultCommConfigA' GetDefaultCommConfigA kernel32 553 +imp 'GetDevicePowerState' GetDevicePowerState kernel32 555 +imp 'GetDiskFreeSpace' GetDiskFreeSpaceW kernel32 0 +imp 'GetDiskFreeSpaceA' GetDiskFreeSpaceA kernel32 0 +imp 'GetDiskFreeSpaceEx' GetDiskFreeSpaceExW kernel32 0 +imp 'GetDiskFreeSpaceExA' GetDiskFreeSpaceExA kernel32 0 +imp 'GetDllDirectory' GetDllDirectoryW kernel32 561 +imp 'GetDllDirectoryA' GetDllDirectoryA kernel32 560 +imp 'GetDriveType' GetDriveTypeW kernel32 0 +imp 'GetDriveTypeA' GetDriveTypeA kernel32 0 +imp 'GetDurationFormat' GetDurationFormat kernel32 564 +imp 'GetDurationFormatEx' GetDurationFormatEx kernel32 0 +imp 'GetDynamicTimeZoneInformation' GetDynamicTimeZoneInformation kernel32 0 +imp 'GetEnabledXStateFeatures' GetEnabledXStateFeatures kernel32 0 +imp 'GetEncryptedFileVersionExt' GetEncryptedFileVersionExt kernel32 568 +imp 'GetEnvironmentStrings' GetEnvironmentStringsW kernel32 0 1 +imp 'GetEnvironmentStringsA' GetEnvironmentStringsA kernel32 0 1 +imp 'GetEnvironmentVariable' GetEnvironmentVariableW kernel32 0 3 +imp 'GetEnvironmentVariableA' GetEnvironmentVariableA kernel32 0 3 +imp 'GetErrorMode' GetErrorMode kernel32 0 +imp 'GetExitCodeThread' GetExitCodeThread kernel32 0 2 +imp 'GetExpandedName' GetExpandedNameW kernel32 579 +imp 'GetExpandedNameA' GetExpandedNameA kernel32 578 +imp 'GetFileAttributesA' GetFileAttributesA kernel32 0 1 +imp 'GetFileAttributesEx' GetFileAttributesExW kernel32 0 3 +imp 'GetFileAttributesExA' GetFileAttributesExA kernel32 0 3 +imp 'GetFileAttributesTransacted' GetFileAttributesTransactedW kernel32 584 +imp 'GetFileAttributesTransactedA' GetFileAttributesTransactedA kernel32 583 +imp 'GetFileBandwidthReservation' GetFileBandwidthReservation kernel32 586 +imp 'GetFileInformationByHandle' GetFileInformationByHandle kernel32 0 2 +imp 'GetFileInformationByHandleEx' GetFileInformationByHandleEx kernel32 0 4 +imp 'GetFileMUIInfo' GetFileMUIInfo kernel32 0 +imp 'GetFileMUIPath' GetFileMUIPath kernel32 0 +imp 'GetFileSize' GetFileSize kernel32 0 2 +imp 'GetFileSizeEx' GetFileSizeEx kernel32 0 2 +imp 'GetFileTime' GetFileTime kernel32 0 4 +imp 'GetFileType' GetFileType kernel32 0 1 +imp 'GetFinalPathNameByHandle' GetFinalPathNameByHandleW kernel32 0 4 +imp 'GetFinalPathNameByHandleA' GetFinalPathNameByHandleA kernel32 0 4 +imp 'GetFirmwareEnvironmentVariable' GetFirmwareEnvironmentVariableW kernel32 600 +imp 'GetFirmwareEnvironmentVariableEx' GetFirmwareEnvironmentVariableExW kernel32 599 +imp 'GetFirmwareType' GetFirmwareType kernel32 601 +imp 'GetFullPathName' GetFullPathNameW kernel32 0 4 +imp 'GetFullPathNameTransacted' GetFullPathNameTransactedW kernel32 604 +imp 'GetGeoInfo' GetGeoInfoW kernel32 0 +imp 'GetHandleInformation' GetHandleInformation kernel32 0 2 +imp 'GetLargePageMinimum' GetLargePageMinimum kernel32 0 +imp 'GetLargestConsoleWindowSize' GetLargestConsoleWindowSize kernel32 0 1 +imp 'GetLastError' GetLastError kernel32 0 0 +imp 'GetLocalTime' GetLocalTime kernel32 0 +imp 'GetLocaleInfo' GetLocaleInfoW kernel32 0 +imp 'GetLocaleInfoA' GetLocaleInfoA kernel32 0 +imp 'GetLocaleInfoEx' GetLocaleInfoEx kernel32 0 +imp 'GetLogicalDriveStrings' GetLogicalDriveStringsW kernel32 0 +imp 'GetLogicalDriveStringsA' GetLogicalDriveStringsA kernel32 617 +imp 'GetLogicalDrives' GetLogicalDrives kernel32 0 0 +imp 'GetLogicalProcessorInformation' GetLogicalProcessorInformation kernel32 0 +imp 'GetLogicalProcessorInformationEx' GetLogicalProcessorInformationEx kernel32 0 +imp 'GetLongPathName' GetLongPathNameW kernel32 0 +imp 'GetLongPathNameA' GetLongPathNameA kernel32 0 +imp 'GetLongPathNameTransacted' GetLongPathNameTransactedW kernel32 624 +imp 'GetLongPathNameTransactedA' GetLongPathNameTransactedA kernel32 623 +imp 'GetMailslotInfo' GetMailslotInfo kernel32 626 +imp 'GetMaximumProcessorCount' GetMaximumProcessorCount kernel32 627 1 # Windows 7+ +imp 'GetMaximumProcessorGroupCount' GetMaximumProcessorGroupCount kernel32 628 +imp 'GetMemoryErrorHandlingCapabilities' GetMemoryErrorHandlingCapabilities kernel32 0 +imp 'GetModuleFileName' GetModuleFileNameW kernel32 0 3 +imp 'GetModuleFileNameA' GetModuleFileNameA kernel32 0 3 +imp 'GetModuleHandle' GetModuleHandleA kernel32 0 1 +imp 'GetModuleHandleEx' GetModuleHandleExW kernel32 0 3 +imp 'GetModuleHandleExA' GetModuleHandleExA kernel32 0 3 +imp 'GetModuleHandleW' GetModuleHandleW kernel32 0 1 +imp 'GetNLSVersion' GetNLSVersion kernel32 0 +imp 'GetNLSVersionEx' GetNLSVersionEx kernel32 0 +imp 'GetNamedPipeClientComputerName' GetNamedPipeClientComputerNameW kernel32 0 +imp 'GetNamedPipeClientComputerNameA' GetNamedPipeClientComputerNameA kernel32 639 +imp 'GetNamedPipeClientProcessId' GetNamedPipeClientProcessId kernel32 641 +imp 'GetNamedPipeClientSessionId' GetNamedPipeClientSessionId kernel32 642 +imp 'GetNamedPipeHandleState' GetNamedPipeHandleStateW kernel32 0 +imp 'GetNamedPipeHandleStateA' GetNamedPipeHandleStateA kernel32 643 +imp 'GetNamedPipeInfo' GetNamedPipeInfo kernel32 0 +imp 'GetNamedPipeServerProcessId' GetNamedPipeServerProcessId kernel32 646 +imp 'GetNamedPipeServerSessionId' GetNamedPipeServerSessionId kernel32 647 +imp 'GetNativeSystemInfo' GetNativeSystemInfo kernel32 0 +imp 'GetNextUmsListItem' GetNextUmsListItem kernel32 649 +imp 'GetNextVDMCommand' GetNextVDMCommand kernel32 650 +imp 'GetNumaAvailableMemoryNode' GetNumaAvailableMemoryNode kernel32 651 +imp 'GetNumaAvailableMemoryNodeEx' GetNumaAvailableMemoryNodeEx kernel32 652 +imp 'GetNumaHighestNodeNumber' GetNumaHighestNodeNumber kernel32 0 +imp 'GetNumaNodeNumberFromHandle' GetNumaNodeNumberFromHandle kernel32 654 +imp 'GetNumaNodeProcessorMask' GetNumaNodeProcessorMask kernel32 655 +imp 'GetNumaNodeProcessorMaskEx' GetNumaNodeProcessorMaskEx kernel32 0 +imp 'GetNumaProcessorNode' GetNumaProcessorNode kernel32 657 +imp 'GetNumaProcessorNodeEx' GetNumaProcessorNodeEx kernel32 658 +imp 'GetNumaProximityNode' GetNumaProximityNode kernel32 659 +imp 'GetNumaProximityNodeEx' GetNumaProximityNodeEx kernel32 0 +imp 'GetNumberFormat' GetNumberFormatW kernel32 0 +imp 'GetNumberFormatA' GetNumberFormatA kernel32 661 +imp 'GetNumberFormatEx' GetNumberFormatEx kernel32 0 +imp 'GetNumberOfConsoleFonts' GetNumberOfConsoleFonts kernel32 664 +imp 'GetNumberOfConsoleInputEvents' GetNumberOfConsoleInputEvents kernel32 0 2 +imp 'GetNumberOfConsoleMouseButtons' GetNumberOfConsoleMouseButtons kernel32 0 1 +imp 'GetOEMCP' GetOEMCP kernel32 0 +imp 'GetOverlappedResult' GetOverlappedResult kernel32 0 4 +imp 'GetOverlappedResultEx' GetOverlappedResultEx kernel32 0 5 +imp 'GetPackageApplicationIds' GetPackageApplicationIds kernel32 0 +imp 'GetPackageFamilyName' GetPackageFamilyName kernel32 0 +imp 'GetPackageFullName' GetPackageFullName kernel32 0 +imp 'GetPackageId' GetPackageId kernel32 0 +imp 'GetPackageInfo' GetPackageInfo kernel32 0 +imp 'GetPackagePath' GetPackagePath kernel32 0 +imp 'GetPackagePathByFullName' GetPackagePathByFullName kernel32 0 +imp 'GetPackagesByPackageFamily' GetPackagesByPackageFamily kernel32 0 +imp 'GetPhysicallyInstalledSystemMemory' GetPhysicallyInstalledSystemMemory kernel32 0 +imp 'GetPriorityClass' GetPriorityClass kernel32 0 1 +imp 'GetPrivateProfileInt' GetPrivateProfileIntW kernel32 681 +imp 'GetPrivateProfileIntA' GetPrivateProfileIntA kernel32 680 +imp 'GetPrivateProfileSection' GetPrivateProfileSectionW kernel32 685 +imp 'GetPrivateProfileSectionA' GetPrivateProfileSectionA kernel32 682 +imp 'GetPrivateProfileSectionNames' GetPrivateProfileSectionNamesW kernel32 684 +imp 'GetPrivateProfileSectionNamesA' GetPrivateProfileSectionNamesA kernel32 683 +imp 'GetPrivateProfileString' GetPrivateProfileStringW kernel32 687 +imp 'GetPrivateProfileStringA' GetPrivateProfileStringA kernel32 686 +imp 'GetPrivateProfileStruct' GetPrivateProfileStructW kernel32 689 +imp 'GetPrivateProfileStructA' GetPrivateProfileStructA kernel32 688 +imp 'GetProcAddress' GetProcAddress kernel32 0 2 +imp 'GetProcessAffinityMask' GetProcessAffinityMask kernel32 0 3 +imp 'GetProcessDEPPolicy' GetProcessDEPPolicy kernel32 692 +imp 'GetProcessDefaultCpuSets' GetProcessDefaultCpuSets kernel32 0 +imp 'GetProcessGroupAffinity' GetProcessGroupAffinity kernel32 0 +imp 'GetProcessHandleCount' GetProcessHandleCount kernel32 0 2 +imp 'GetProcessHeap' GetProcessHeap kernel32 0 0 +imp 'GetProcessHeaps' GetProcessHeaps kernel32 0 2 +imp 'GetProcessId' GetProcessId kernel32 0 1 +imp 'GetProcessIdOfThread' GetProcessIdOfThread kernel32 0 1 +imp 'GetProcessInformation' GetProcessInformation kernel32 0 4 +imp 'GetProcessIoCounters' GetProcessIoCounters kernel32 701 2 +imp 'GetProcessMitigationPolicy' GetProcessMitigationPolicy kernel32 0 +imp 'GetProcessPreferredUILanguages' GetProcessPreferredUILanguages kernel32 0 +imp 'GetProcessPriorityBoost' GetProcessPriorityBoost kernel32 0 2 +imp 'GetProcessShutdownParameters' GetProcessShutdownParameters kernel32 0 +imp 'GetProcessTimes' GetProcessTimes kernel32 0 5 +imp 'GetProcessVersion' GetProcessVersion kernel32 0 +imp 'GetProcessWorkingSetSize' GetProcessWorkingSetSize kernel32 708 3 +imp 'GetProcessWorkingSetSizeEx' GetProcessWorkingSetSizeEx kernel32 0 4 +imp 'GetProcessorSystemCycleTime' GetProcessorSystemCycleTime kernel32 0 +imp 'GetProductInfo' GetProductInfo kernel32 0 +imp 'GetProfileInt' GetProfileIntW kernel32 713 +imp 'GetProfileIntA' GetProfileIntA kernel32 712 +imp 'GetProfileSection' GetProfileSectionW kernel32 715 +imp 'GetProfileSectionA' GetProfileSectionA kernel32 714 +imp 'GetProfileString' GetProfileStringW kernel32 717 +imp 'GetProfileStringA' GetProfileStringA kernel32 716 +imp 'GetQueuedCompletionStatus' GetQueuedCompletionStatus kernel32 0 5 +imp 'GetQueuedCompletionStatusEx' GetQueuedCompletionStatusEx kernel32 0 6 +imp 'GetShortPathName' GetShortPathNameW kernel32 0 +imp 'GetShortPathNameA' GetShortPathNameA kernel32 720 +imp 'GetStagedPackagePathByFullName' GetStagedPackagePathByFullName kernel32 0 +imp 'GetStartupInfo' GetStartupInfoW kernel32 0 1 +imp 'GetStartupInfoA' GetStartupInfoA kernel32 723 1 +imp 'GetStdHandle' GetStdHandle kernel32 0 1 +imp 'GetStringScripts' GetStringScripts kernel32 0 +imp 'GetStringType' GetStringTypeW kernel32 0 +imp 'GetStringTypeA' GetStringTypeA kernel32 0 +imp 'GetStringTypeEx' GetStringTypeExW kernel32 0 +imp 'GetStringTypeExA' GetStringTypeExA kernel32 729 +imp 'GetSystemCpuSetInformation' GetSystemCpuSetInformation kernel32 0 +imp 'GetSystemDEPPolicy' GetSystemDEPPolicy kernel32 734 +imp 'GetSystemDefaultLCID' GetSystemDefaultLCID kernel32 0 +imp 'GetSystemDefaultLangID' GetSystemDefaultLangID kernel32 0 +imp 'GetSystemDefaultLocaleName' GetSystemDefaultLocaleName kernel32 0 +imp 'GetSystemDefaultUILanguage' GetSystemDefaultUILanguage kernel32 0 +imp 'GetSystemDirectory' GetSystemDirectoryW kernel32 0 2 +imp 'GetSystemDirectoryA' GetSystemDirectoryA kernel32 0 2 +imp 'GetSystemFileCacheSize' GetSystemFileCacheSize kernel32 0 +imp 'GetSystemFirmwareTable' GetSystemFirmwareTable kernel32 0 +imp 'GetSystemInfo' GetSystemInfo kernel32 0 1 +imp 'GetSystemPowerStatus' GetSystemPowerStatus kernel32 744 +imp 'GetSystemPreferredUILanguages' GetSystemPreferredUILanguages kernel32 0 +imp 'GetSystemRegistryQuota' GetSystemRegistryQuota kernel32 746 +imp 'GetSystemTime' GetSystemTime kernel32 0 1 +imp 'GetSystemTimeAdjustment' GetSystemTimeAdjustment kernel32 0 3 +imp 'GetSystemTimeAsFileTime' GetSystemTimeAsFileTime kernel32 0 1 +imp 'GetSystemTimePreciseAsFileTime' GetSystemTimePreciseAsFileTime kernel32 0 1 +imp 'GetSystemTimes' GetSystemTimes kernel32 0 +imp 'GetSystemWindowsDirectory' GetSystemWindowsDirectoryW kernel32 0 +imp 'GetSystemWindowsDirectoryA' GetSystemWindowsDirectoryA kernel32 0 +imp 'GetSystemWow64Directory' GetSystemWow64DirectoryW kernel32 0 +imp 'GetSystemWow64DirectoryA' GetSystemWow64DirectoryA kernel32 0 +imp 'GetTapeParameters' GetTapeParameters kernel32 756 +imp 'GetTapePosition' GetTapePosition kernel32 757 +imp 'GetTapeStatus' GetTapeStatus kernel32 758 +imp 'GetTempFileName' GetTempFileNameW kernel32 0 +imp 'GetTempFileNameA' GetTempFileNameA kernel32 0 +imp 'GetTempPath' GetTempPathW kernel32 0 2 +imp 'GetTempPathA' GetTempPathA kernel32 0 2 +imp 'GetThreadContext' GetThreadContext kernel32 0 +imp 'GetThreadErrorMode' GetThreadErrorMode kernel32 0 +imp 'GetThreadGroupAffinity' GetThreadGroupAffinity kernel32 0 +imp 'GetThreadIOPendingFlag' GetThreadIOPendingFlag kernel32 0 2 +imp 'GetThreadId' GetThreadId kernel32 0 1 +imp 'GetThreadIdealProcessorEx' GetThreadIdealProcessorEx kernel32 0 +imp 'GetThreadInformation' GetThreadInformation kernel32 0 +imp 'GetThreadLocale' GetThreadLocale kernel32 0 +imp 'GetThreadPreferredUILanguages' GetThreadPreferredUILanguages kernel32 0 +imp 'GetThreadPriority' GetThreadPriority kernel32 0 1 +imp 'GetThreadPriorityBoost' GetThreadPriorityBoost kernel32 0 2 +imp 'GetThreadSelectedCpuSets' GetThreadSelectedCpuSets kernel32 0 +imp 'GetThreadSelectorEntry' GetThreadSelectorEntry kernel32 776 +imp 'GetThreadTimes' GetThreadTimes kernel32 0 5 +imp 'GetThreadUILanguage' GetThreadUILanguage kernel32 0 +imp 'GetTickCount' GetTickCount kernel32 0 +imp 'GetTickCount64' GetTickCount64 kernel32 0 0 +imp 'GetTimeFormat' GetTimeFormatW kernel32 0 +imp 'GetTimeFormatA' GetTimeFormatA kernel32 0 +imp 'GetTimeFormatAWorker' GetTimeFormatAWorker kernel32 782 +imp 'GetTimeFormatEx' GetTimeFormatEx kernel32 0 +imp 'GetTimeFormatWWorker' GetTimeFormatWWorker kernel32 785 +imp 'GetTimeZoneInformation' GetTimeZoneInformation kernel32 0 +imp 'GetTimeZoneInformationForYear' GetTimeZoneInformationForYear kernel32 0 +imp 'GetUILanguageInfo' GetUILanguageInfo kernel32 0 +imp 'GetUmsCompletionListEvent' GetUmsCompletionListEvent kernel32 789 +imp 'GetUmsSystemThreadInformation' GetUmsSystemThreadInformation kernel32 790 +imp 'GetUserDefaultLCID' GetUserDefaultLCID kernel32 0 +imp 'GetUserDefaultLangID' GetUserDefaultLangID kernel32 0 +imp 'GetUserDefaultLocaleName' GetUserDefaultLocaleName kernel32 0 +imp 'GetUserDefaultUILanguage' GetUserDefaultUILanguage kernel32 0 +imp 'GetUserGeoID' GetUserGeoID kernel32 0 +imp 'GetUserPreferredUILanguages' GetUserPreferredUILanguages kernel32 0 +imp 'GetVDMCurrentDirectories' GetVDMCurrentDirectories kernel32 798 +imp 'GetVersion' GetVersion kernel32 0 +imp 'GetVersionEx' GetVersionExW kernel32 0 1 +imp 'GetVersionExA' GetVersionExA kernel32 0 1 +imp 'GetVolumeInformation' GetVolumeInformationW kernel32 0 +imp 'GetVolumeInformationA' GetVolumeInformationA kernel32 0 +imp 'GetVolumeInformationByHandle' GetVolumeInformationByHandleW kernel32 0 +imp 'GetVolumeNameForVolumeMountPoint' GetVolumeNameForVolumeMountPointW kernel32 0 +imp 'GetVolumeNameForVolumeMountPointA' GetVolumeNameForVolumeMountPointA kernel32 805 +imp 'GetVolumePathName' GetVolumePathNameW kernel32 0 3 +imp 'GetVolumePathNameA' GetVolumePathNameA kernel32 807 3 +imp 'GetVolumePathNamesForVolumeName' GetVolumePathNamesForVolumeNameW kernel32 0 +imp 'GetVolumePathNamesForVolumeNameA' GetVolumePathNamesForVolumeNameA kernel32 809 +imp 'GetWindowsDirectory' GetWindowsDirectoryW kernel32 0 2 +imp 'GetWindowsDirectoryA' GetWindowsDirectoryA kernel32 0 2 +imp 'GetWriteWatch' GetWriteWatch kernel32 0 +imp 'GetXStateFeaturesMask' GetXStateFeaturesMask kernel32 0 +imp 'GlobalAddAtom' GlobalAddAtomW kernel32 818 +imp 'GlobalAddAtomA' GlobalAddAtomA kernel32 815 +imp 'GlobalAddAtomEx' GlobalAddAtomExW kernel32 817 +imp 'GlobalAddAtomExA' GlobalAddAtomExA kernel32 816 +imp 'GlobalAlloc' GlobalAlloc kernel32 0 2 +imp 'GlobalCompact' GlobalCompact kernel32 820 +imp 'GlobalDeleteAtom' GlobalDeleteAtom kernel32 821 +imp 'GlobalFindAtom' GlobalFindAtomW kernel32 823 +imp 'GlobalFindAtomA' GlobalFindAtomA kernel32 822 +imp 'GlobalFix' GlobalFix kernel32 824 +imp 'GlobalFlags' GlobalFlags kernel32 825 +imp 'GlobalFree' GlobalFree kernel32 0 1 +imp 'GlobalGetAtomName' GlobalGetAtomNameW kernel32 828 +imp 'GlobalGetAtomNameA' GlobalGetAtomNameA kernel32 827 +imp 'GlobalHandle' GlobalHandle kernel32 829 +imp 'GlobalLock' GlobalLock kernel32 830 +imp 'GlobalMemoryStatus' GlobalMemoryStatus kernel32 831 +imp 'GlobalMemoryStatusEx' GlobalMemoryStatusEx kernel32 0 1 +imp 'GlobalReAlloc' GlobalReAlloc kernel32 833 +imp 'GlobalSize' GlobalSize kernel32 834 +imp 'GlobalUnWire' GlobalUnWire kernel32 835 +imp 'GlobalUnfix' GlobalUnfix kernel32 836 +imp 'GlobalUnlock' GlobalUnlock kernel32 837 +imp 'GlobalWire' GlobalWire kernel32 838 +imp 'Heap32First' Heap32First kernel32 839 +imp 'Heap32ListFirst' Heap32ListFirst kernel32 840 +imp 'Heap32ListNext' Heap32ListNext kernel32 841 +imp 'Heap32Next' Heap32Next kernel32 842 +imp 'HeapAlloc' HeapAlloc kernel32 0 3 +imp 'HeapCompact' HeapCompact kernel32 0 2 +imp 'HeapCreate' HeapCreate kernel32 0 3 +imp 'HeapDestroy' HeapDestroy kernel32 0 1 +imp 'HeapFree' HeapFree kernel32 847 3 +imp 'HeapLock' HeapLock kernel32 0 +imp 'HeapQueryInformation' HeapQueryInformation kernel32 0 +imp 'HeapReAlloc' HeapReAlloc kernel32 0 4 +imp 'HeapSetInformation' HeapSetInformation kernel32 0 +imp 'HeapUnlock' HeapUnlock kernel32 0 +imp 'HeapValidate' HeapValidate kernel32 0 +imp 'HeapWalk' HeapWalk kernel32 0 +imp 'IdnToAscii' IdnToAscii kernel32 0 +imp 'IdnToNameprepUnicode' IdnToNameprepUnicode kernel32 0 +imp 'IdnToUnicode' IdnToUnicode kernel32 0 +imp 'InitAtomTable' InitAtomTable kernel32 860 +imp 'InitOnceBeginInitialize' InitOnceBeginInitialize kernel32 0 +imp 'InitOnceComplete' InitOnceComplete kernel32 0 +imp 'InitOnceExecuteOnce' InitOnceExecuteOnce kernel32 0 +imp 'InitializeContext' InitializeContext kernel32 0 +imp 'InitializeCriticalSection' InitializeCriticalSection kernel32 0 1 +imp 'InitializeCriticalSectionAndSpinCount' InitializeCriticalSectionAndSpinCount kernel32 0 2 +imp 'InitializeCriticalSectionAndSpinCount' InitializeCriticalSectionAndSpinCount kernel32 0 2 +imp 'InitializeCriticalSectionEx' InitializeCriticalSectionEx kernel32 0 +imp 'InitializeProcThreadAttributeList' InitializeProcThreadAttributeList kernel32 0 4 +imp 'InitializeSRWLock' InitializeSRWLock kernel32 0 1 +imp 'InitializeSynchronizationBarrier' InitializeSynchronizationBarrier kernel32 0 +imp 'InstallELAMCertificateInfo' InstallELAMCertificateInfo kernel32 0 +imp 'InvalidateConsoleDIBits' InvalidateConsoleDIBits kernel32 881 +imp 'IsBadCodePtr' IsBadCodePtr kernel32 882 +imp 'IsBadHugeReadPtr' IsBadHugeReadPtr kernel32 883 +imp 'IsBadHugeWritePtr' IsBadHugeWritePtr kernel32 884 +imp 'IsBadReadPtr' IsBadReadPtr kernel32 885 +imp 'IsBadStringPtr' IsBadStringPtrW kernel32 887 +imp 'IsBadStringPtrA' IsBadStringPtrA kernel32 886 +imp 'IsBadWritePtr' IsBadWritePtr kernel32 888 +imp 'IsCalendarLeapDay' IsCalendarLeapDay kernel32 889 +imp 'IsCalendarLeapMonth' IsCalendarLeapMonth kernel32 890 +imp 'IsCalendarLeapYear' IsCalendarLeapYear kernel32 891 +imp 'IsDBCSLeadByte' IsDBCSLeadByte kernel32 0 +imp 'IsDBCSLeadByteEx' IsDBCSLeadByteEx kernel32 0 +imp 'IsNLSDefinedString' IsNLSDefinedString kernel32 0 +imp 'IsNativeVhdBoot' IsNativeVhdBoot kernel32 897 +imp 'IsNormalizedString' IsNormalizedString kernel32 0 +imp 'IsProcessCritical' IsProcessCritical kernel32 0 +imp 'IsProcessInJob' IsProcessInJob kernel32 0 +imp 'IsProcessorFeaturePresent' IsProcessorFeaturePresent kernel32 0 +imp 'IsSystemResumeAutomatic' IsSystemResumeAutomatic kernel32 902 +imp 'IsThreadAFiber' IsThreadAFiber kernel32 0 +imp 'IsValidCalDateTime' IsValidCalDateTime kernel32 905 +imp 'IsValidCodePage' IsValidCodePage kernel32 0 +imp 'IsValidLanguageGroup' IsValidLanguageGroup kernel32 0 +imp 'IsValidLocale' IsValidLocale kernel32 0 +imp 'IsValidLocaleName' IsValidLocaleName kernel32 0 +imp 'IsValidNLSVersion' IsValidNLSVersion kernel32 0 +imp 'IsWow64Process' IsWow64Process kernel32 0 +imp 'K32EmptyWorkingSet' K32EmptyWorkingSet kernel32 0 +imp 'K32EnumDeviceDrivers' K32EnumDeviceDrivers kernel32 0 +imp 'K32EnumPageFiles' K32EnumPageFilesW kernel32 0 +imp 'K32EnumPageFilesA' K32EnumPageFilesA kernel32 0 +imp 'K32EnumProcessModules' K32EnumProcessModules kernel32 0 +imp 'K32EnumProcessModulesEx' K32EnumProcessModulesEx kernel32 0 +imp 'K32EnumProcesses' K32EnumProcesses kernel32 0 +imp 'K32GetDeviceDriverBaseName' K32GetDeviceDriverBaseNameW kernel32 0 +imp 'K32GetDeviceDriverBaseNameA' K32GetDeviceDriverBaseNameA kernel32 0 +imp 'K32GetDeviceDriverFileName' K32GetDeviceDriverFileNameW kernel32 0 +imp 'K32GetDeviceDriverFileNameA' K32GetDeviceDriverFileNameA kernel32 0 +imp 'K32GetMappedFileName' K32GetMappedFileNameW kernel32 0 +imp 'K32GetMappedFileNameA' K32GetMappedFileNameA kernel32 0 +imp 'K32GetModuleBaseName' K32GetModuleBaseNameW kernel32 0 +imp 'K32GetModuleFileNameEx' K32GetModuleFileNameExW kernel32 0 +imp 'K32GetModuleInformation' K32GetModuleInformation kernel32 0 +imp 'K32GetPerformanceInfo' K32GetPerformanceInfo kernel32 0 +imp 'K32GetProcessImageFileName' K32GetProcessImageFileNameW kernel32 0 +imp 'K32GetProcessMemoryInfo' K32GetProcessMemoryInfo kernel32 0 +imp 'K32GetWsChanges' K32GetWsChanges kernel32 0 +imp 'K32GetWsChangesEx' K32GetWsChangesEx kernel32 0 +imp 'K32InitializeProcessForWsWatch' K32InitializeProcessForWsWatch kernel32 0 +imp 'K32QueryWorkingSet' K32QueryWorkingSet kernel32 0 +imp 'K32QueryWorkingSetEx' K32QueryWorkingSetEx kernel32 0 +imp 'LCIDToLocaleName' LCIDToLocaleName kernel32 0 +imp 'LCMapString' LCMapStringW kernel32 0 +imp 'LCMapStringA' LCMapStringA kernel32 0 +imp 'LCMapStringEx' LCMapStringEx kernel32 0 +imp 'LZClose' LZClose kernel32 945 +imp 'LZCloseFile' LZCloseFile kernel32 946 +imp 'LZCopy' LZCopy kernel32 947 +imp 'LZCreateFile' LZCreateFileW kernel32 948 +imp 'LZDone' LZDone kernel32 949 +imp 'LZInit' LZInit kernel32 950 +imp 'LZOpenFile' LZOpenFileW kernel32 952 +imp 'LZOpenFileA' LZOpenFileA kernel32 951 +imp 'LZRead' LZRead kernel32 953 +imp 'LZSeek' LZSeek kernel32 954 +imp 'LZStart' LZStart kernel32 955 +imp 'LeaveCriticalSection' LeaveCriticalSection kernel32 0 1 +imp 'LoadLibrary' LoadLibraryW kernel32 0 1 +imp 'LoadLibraryA' LoadLibraryA kernel32 0 1 +imp 'LoadLibraryEx' LoadLibraryExW kernel32 0 3 +imp 'LoadLibraryExA' LoadLibraryExA kernel32 0 3 +imp 'LoadModule' LoadModule kernel32 964 +imp 'LoadPackagedLibrary' LoadPackagedLibrary kernel32 0 +imp 'LoadResource' LoadResource kernel32 0 2 +imp 'LoadStringBase' LoadStringBaseW kernel32 968 +imp 'LocalAlloc' LocalAlloc kernel32 0 +imp 'LocalCompact' LocalCompact kernel32 970 +imp 'LocalFileTimeToFileTime' LocalFileTimeToFileTime kernel32 0 +imp 'LocalFlags' LocalFlags kernel32 972 +imp 'LocalFree' LocalFree kernel32 0 1 +imp 'LocalHandle' LocalHandle kernel32 974 +imp 'LocalLock' LocalLock kernel32 0 +imp 'LocalReAlloc' LocalReAlloc kernel32 0 +imp 'LocalShrink' LocalShrink kernel32 977 +imp 'LocalSize' LocalSize kernel32 978 +imp 'LocalUnlock' LocalUnlock kernel32 0 +imp 'LocaleNameToLCID' LocaleNameToLCID kernel32 0 +imp 'LocateXStateFeature' LocateXStateFeature kernel32 0 +imp 'LockFile' LockFile kernel32 0 5 +imp 'LockFileEx' LockFileEx kernel32 0 6 +imp 'LockResource' LockResource kernel32 0 1 +imp 'MapUserPhysicalPages' MapUserPhysicalPages kernel32 0 +imp 'MapUserPhysicalPagesScatter' MapUserPhysicalPagesScatter kernel32 986 +imp 'MapViewOfFile' MapViewOfFile kernel32 0 +imp 'MapViewOfFileFromApp' MapViewOfFileFromApp kernel32 0 +imp 'Module32First' Module32FirstW kernel32 992 +imp 'Module32Next' Module32NextW kernel32 994 +imp 'MoveFile' MoveFileW kernel32 1000 2 +imp 'MoveFileA' MoveFileA kernel32 995 2 +imp 'MoveFileExA' MoveFileExA kernel32 996 3 +imp 'MoveFileTransacted' MoveFileTransactedW kernel32 999 +imp 'MoveFileTransactedA' MoveFileTransactedA kernel32 998 +imp 'MoveFileWithProgress' MoveFileWithProgressW kernel32 0 +imp 'MoveFileWithProgressA' MoveFileWithProgressA kernel32 1001 +imp 'MulDiv' MulDiv kernel32 0 +imp 'MultiByteToWideChar' MultiByteToWideChar kernel32 0 6 +imp 'NeedCurrentDirectoryForExePath' NeedCurrentDirectoryForExePathW kernel32 0 +imp 'NeedCurrentDirectoryForExePathA' NeedCurrentDirectoryForExePathA kernel32 0 +imp 'NormalizeString' NormalizeString kernel32 0 +imp 'NotifyUILanguageChange' NotifyUILanguageChange kernel32 1015 +imp 'OOBEComplete' OOBEComplete kernel32 1017 +imp 'OfferVirtualMemory' OfferVirtualMemory kernel32 0 3 +imp 'OpenConsole' OpenConsoleW kernel32 1019 +imp 'OpenConsoleWStub' OpenConsoleWStub kernel32 1020 +imp 'OpenEvent' OpenEventW kernel32 0 +imp 'OpenEventA' OpenEventA kernel32 0 +imp 'OpenFile' OpenFile kernel32 1023 +imp 'OpenFileById' OpenFileById kernel32 0 +imp 'OpenFileMapping' OpenFileMappingW kernel32 0 +imp 'OpenFileMappingA' OpenFileMappingA kernel32 1025 +imp 'OpenJobObject' OpenJobObjectW kernel32 1028 +imp 'OpenJobObjectA' OpenJobObjectA kernel32 1027 +imp 'OpenMutex' OpenMutexW kernel32 0 +imp 'OpenMutexA' OpenMutexA kernel32 1029 +imp 'OpenPackageInfoByFullName' OpenPackageInfoByFullName kernel32 0 +imp 'OpenPrivateNamespace' OpenPrivateNamespaceW kernel32 0 +imp 'OpenPrivateNamespaceA' OpenPrivateNamespaceA kernel32 1032 +imp 'OpenProfileUserMapping' OpenProfileUserMapping kernel32 1036 +imp 'OpenSemaphore' OpenSemaphoreW kernel32 0 +imp 'OpenSemaphoreA' OpenSemaphoreA kernel32 1037 +imp 'OpenThread' OpenThread kernel32 0 3 +imp 'OpenWaitableTimer' OpenWaitableTimerW kernel32 0 +imp 'OpenWaitableTimerA' OpenWaitableTimerA kernel32 1043 +imp 'OutputDebugString' OutputDebugStringW kernel32 0 +imp 'OutputDebugStringA' OutputDebugStringA kernel32 0 +imp 'PackageFamilyNameFromFullName' PackageFamilyNameFromFullName kernel32 0 +imp 'PackageFamilyNameFromId' PackageFamilyNameFromId kernel32 0 +imp 'PackageFullNameFromId' PackageFullNameFromId kernel32 0 +imp 'PackageIdFromFullName' PackageIdFromFullName kernel32 0 +imp 'PackageNameAndPublisherIdFromFamilyName' PackageNameAndPublisherIdFromFamilyName kernel32 0 +imp 'ParseApplicationUserModelId' ParseApplicationUserModelId kernel32 0 +imp 'PeekConsoleInput' PeekConsoleInputW kernel32 0 4 +imp 'PeekConsoleInputA' PeekConsoleInputA kernel32 0 4 +imp 'PeekNamedPipe' PeekNamedPipe kernel32 0 6 +imp 'PostQueuedCompletionStatus' PostQueuedCompletionStatus kernel32 0 4 +imp 'PowerClearRequest' PowerClearRequest kernel32 1057 +imp 'PowerCreateRequest' PowerCreateRequest kernel32 1058 +imp 'PowerSetRequest' PowerSetRequest kernel32 1059 +imp 'PrefetchVirtualMemory' PrefetchVirtualMemory kernel32 0 4 +imp 'PrepareTape' PrepareTape kernel32 1061 +imp 'PrivMoveFileIdentity' PrivMoveFileIdentityW kernel32 1063 +imp 'Process32First' Process32FirstW kernel32 1065 +imp 'Process32Next' Process32NextW kernel32 1067 +imp 'ProcessIdToSessionId' ProcessIdToSessionId kernel32 0 +imp 'PssCaptureSnapshot' PssCaptureSnapshot kernel32 0 +imp 'PssDuplicateSnapshot' PssDuplicateSnapshot kernel32 0 +imp 'PssFreeSnapshot' PssFreeSnapshot kernel32 0 +imp 'PssQuerySnapshot' PssQuerySnapshot kernel32 0 +imp 'PssWalkMarkerCreate' PssWalkMarkerCreate kernel32 0 +imp 'PssWalkMarkerFree' PssWalkMarkerFree kernel32 0 +imp 'PssWalkMarkerGetPosition' PssWalkMarkerGetPosition kernel32 0 +imp 'PssWalkMarkerRewind' PssWalkMarkerRewind kernel32 1076 +imp 'PssWalkMarkerSeek' PssWalkMarkerSeek kernel32 1077 +imp 'PssWalkMarkerSeekToBeginning' PssWalkMarkerSeekToBeginning kernel32 0 +imp 'PssWalkMarkerSetPosition' PssWalkMarkerSetPosition kernel32 0 +imp 'PssWalkMarkerTell' PssWalkMarkerTell kernel32 1080 +imp 'PssWalkSnapshot' PssWalkSnapshot kernel32 0 +imp 'PulseEvent' PulseEvent kernel32 0 1 +imp 'PurgeComm' PurgeComm kernel32 0 +imp 'QueryActCtx' QueryActCtxW kernel32 0 +imp 'QueryActCtxSettings' QueryActCtxSettingsW kernel32 0 +imp 'QueryActCtxSettingsWWorker' QueryActCtxSettingsWWorker kernel32 1085 +imp 'QueryActCtxWWorker' QueryActCtxWWorker kernel32 1087 +imp 'QueryDosDevice' QueryDosDeviceW kernel32 0 +imp 'QueryDosDeviceA' QueryDosDeviceA kernel32 1089 +imp 'QueryFullProcessImageName' QueryFullProcessImageNameW kernel32 0 +imp 'QueryFullProcessImageNameA' QueryFullProcessImageNameA kernel32 0 +imp 'QueryIdleProcessorCycleTime' QueryIdleProcessorCycleTime kernel32 0 +imp 'QueryIdleProcessorCycleTimeEx' QueryIdleProcessorCycleTimeEx kernel32 0 +imp 'QueryInformationJobObject' QueryInformationJobObject kernel32 1095 +imp 'QueryIoRateControlInformationJobObject' QueryIoRateControlInformationJobObject kernel32 1096 +imp 'QueryMemoryResourceNotification' QueryMemoryResourceNotification kernel32 0 +imp 'QueryPerformanceCounter' QueryPerformanceCounter kernel32 1098 1 +imp 'QueryPerformanceFrequency' QueryPerformanceFrequency kernel32 1099 1 +imp 'QueryProcessAffinityUpdateMode' QueryProcessAffinityUpdateMode kernel32 0 +imp 'QueryProcessCycleTime' QueryProcessCycleTime kernel32 0 +imp 'QueryProtectedPolicy' QueryProtectedPolicy kernel32 0 +imp 'QueryThreadCycleTime' QueryThreadCycleTime kernel32 0 +imp 'QueryThreadProfiling' QueryThreadProfiling kernel32 1104 +imp 'QueryThreadpoolStackInformation' QueryThreadpoolStackInformation kernel32 0 +imp 'QueryUmsThreadInformation' QueryUmsThreadInformation kernel32 1106 +imp 'QueryUnbiasedInterruptTime' QueryUnbiasedInterruptTime kernel32 1107 +imp 'QueueUserAPC' QueueUserAPC kernel32 0 +imp 'QueueUserWorkItem' QueueUserWorkItem kernel32 0 +imp 'QuirkGetData2Worker' QuirkGetData2Worker kernel32 1110 +imp 'QuirkGetDataWorker' QuirkGetDataWorker kernel32 1111 +imp 'QuirkIsEnabled2Worker' QuirkIsEnabled2Worker kernel32 1112 +imp 'QuirkIsEnabled3Worker' QuirkIsEnabled3Worker kernel32 1113 +imp 'QuirkIsEnabledForPackage2Worker' QuirkIsEnabledForPackage2Worker kernel32 1114 +imp 'QuirkIsEnabledForPackage3Worker' QuirkIsEnabledForPackage3Worker kernel32 1115 +imp 'QuirkIsEnabledForPackage4Worker' QuirkIsEnabledForPackage4Worker kernel32 1116 +imp 'QuirkIsEnabledForPackageWorker' QuirkIsEnabledForPackageWorker kernel32 1117 +imp 'QuirkIsEnabledForProcessWorker' QuirkIsEnabledForProcessWorker kernel32 1118 +imp 'QuirkIsEnabledWorker' QuirkIsEnabledWorker kernel32 1119 +imp 'RaiseException' RaiseException kernel32 0 +imp 'RaiseFailFastException' RaiseFailFastException kernel32 0 +imp 'RaiseInvalid16BitExeError' RaiseInvalid16BitExeError kernel32 1122 +imp 'ReadConsole' ReadConsoleW kernel32 0 5 +imp 'ReadConsoleA' ReadConsoleA kernel32 0 5 +imp 'ReadConsoleInput' ReadConsoleInputW kernel32 0 4 +imp 'ReadConsoleInputA' ReadConsoleInputA kernel32 0 4 +imp 'ReadConsoleOutput' ReadConsoleOutputW kernel32 0 5 +imp 'ReadConsoleOutputA' ReadConsoleOutputA kernel32 0 5 +imp 'ReadConsoleOutputAttribute' ReadConsoleOutputAttribute kernel32 0 5 +imp 'ReadConsoleOutputCharacter' ReadConsoleOutputCharacterW kernel32 0 5 +imp 'ReadConsoleOutputCharacterA' ReadConsoleOutputCharacterA kernel32 0 5 +imp 'ReadDirectoryChanges' ReadDirectoryChangesW kernel32 0 +imp 'ReadFile' ReadFile kernel32 0 5 +imp 'ReadFileEx' ReadFileEx kernel32 0 5 +imp 'ReadFileScatter' ReadFileScatter kernel32 0 5 +imp 'ReadProcessMemory' ReadProcessMemory kernel32 0 +imp 'ReadThreadProfilingData' ReadThreadProfilingData kernel32 1141 +imp 'ReclaimVirtualMemory' ReclaimVirtualMemory kernel32 0 +imp 'RegDisablePredefinedCacheEx' RegDisablePredefinedCacheEx kernel32 0 +imp 'RegLoadMUIStringA' RegLoadMUIStringA kernel32 0 +imp 'RegSaveKeyExA' RegSaveKeyExA kernel32 0 +imp 'RegisterApplicationRecoveryCallback' RegisterApplicationRecoveryCallback kernel32 1184 +imp 'RegisterApplicationRestart' RegisterApplicationRestart kernel32 1185 +imp 'RegisterBadMemoryNotification' RegisterBadMemoryNotification kernel32 0 +imp 'RegisterConsoleIME' RegisterConsoleIME kernel32 1187 +imp 'RegisterConsoleOS2' RegisterConsoleOS2 kernel32 1188 +imp 'RegisterConsoleVDM' RegisterConsoleVDM kernel32 1189 +imp 'RegisterWaitForInputIdle' RegisterWaitForInputIdle kernel32 1190 +imp 'RegisterWaitForSingleObject' RegisterWaitForSingleObject kernel32 1191 6 +imp 'RegisterWaitUntilOOBECompleted' RegisterWaitUntilOOBECompleted kernel32 1193 +imp 'RegisterWowBaseHandlers' RegisterWowBaseHandlers kernel32 1194 +imp 'RegisterWowExec' RegisterWowExec kernel32 1195 +imp 'ReleaseActCtx' ReleaseActCtx kernel32 0 +imp 'ReleaseActCtxWorker' ReleaseActCtxWorker kernel32 1197 +imp 'ReleaseMutex' ReleaseMutex kernel32 0 1 +imp 'ReleaseSRWLockExclusive' ReleaseSRWLockExclusive kernel32 0 1 +imp 'ReleaseSRWLockShared' ReleaseSRWLockShared kernel32 0 1 +imp 'ReleaseSemaphore' ReleaseSemaphore kernel32 0 3 +imp 'RemoveDirectoryA' RemoveDirectoryA kernel32 0 1 +imp 'RemoveDirectoryTransacted' RemoveDirectoryTransactedW kernel32 1206 +imp 'RemoveDirectoryTransactedA' RemoveDirectoryTransactedA kernel32 1205 +imp 'RemoveDllDirectory' RemoveDllDirectory kernel32 0 +imp 'RemoveLocalAlternateComputerName' RemoveLocalAlternateComputerNameW kernel32 1210 +imp 'RemoveLocalAlternateComputerNameA' RemoveLocalAlternateComputerNameA kernel32 1209 +imp 'RemoveSecureMemoryCacheCallback' RemoveSecureMemoryCacheCallback kernel32 1211 +imp 'RemoveVectoredContinueHandler' RemoveVectoredContinueHandler kernel32 0 1 +imp 'RemoveVectoredExceptionHandler' RemoveVectoredExceptionHandler kernel32 0 1 +imp 'ReplaceFile' ReplaceFileW kernel32 0 +imp 'ReplaceFileA' ReplaceFileA kernel32 1215 +imp 'ReplacePartitionUnit' ReplacePartitionUnit kernel32 1217 +imp 'RequestDeviceWakeup' RequestDeviceWakeup kernel32 1218 +imp 'RequestWakeupLatency' RequestWakeupLatency kernel32 1219 +imp 'ResetEvent' ResetEvent kernel32 0 1 +imp 'ResetWriteWatch' ResetWriteWatch kernel32 0 +imp 'ResolveDelayLoadedAPI' ResolveDelayLoadedAPI kernel32 0 +imp 'ResolveDelayLoadsFromDll' ResolveDelayLoadsFromDll kernel32 0 +imp 'ResolveLocaleName' ResolveLocaleName kernel32 0 +imp 'ResumeThread' ResumeThread kernel32 0 +imp 'ScrollConsoleScreenBuffer' ScrollConsoleScreenBufferW kernel32 0 +imp 'ScrollConsoleScreenBufferA' ScrollConsoleScreenBufferA kernel32 0 +imp 'SearchPath' SearchPathW kernel32 0 +imp 'SearchPathA' SearchPathA kernel32 0 +imp 'SetCalendarInfo' SetCalendarInfoW kernel32 0 +imp 'SetCalendarInfoA' SetCalendarInfoA kernel32 1249 +imp 'SetComPlusPackageInstallStatus' SetComPlusPackageInstallStatus kernel32 1251 +imp 'SetCommBreak' SetCommBreak kernel32 0 +imp 'SetCommConfig' SetCommConfig kernel32 0 +imp 'SetCommMask' SetCommMask kernel32 0 +imp 'SetCommState' SetCommState kernel32 0 +imp 'SetCommTimeouts' SetCommTimeouts kernel32 0 +imp 'SetComputerName' SetComputerNameW kernel32 0 +imp 'SetComputerNameA' SetComputerNameA kernel32 0 +imp 'SetComputerNameEx' SetComputerNameExW kernel32 0 +imp 'SetComputerNameExA' SetComputerNameExA kernel32 0 +imp 'SetConsoleActiveScreenBuffer' SetConsoleActiveScreenBuffer kernel32 0 1 # TODO(jart): 6.2 and higher +imp 'SetConsoleCP' SetConsoleCP kernel32 0 1 # TODO(jart): 6.2 and higher +imp 'SetConsoleCtrlHandler' SetConsoleCtrlHandler kernel32 0 2 +imp 'SetConsoleCursor' SetConsoleCursor kernel32 1265 +imp 'SetConsoleCursorInfo' SetConsoleCursorInfo kernel32 0 2 +imp 'SetConsoleCursorMode' SetConsoleCursorMode kernel32 1267 +imp 'SetConsoleCursorPosition' SetConsoleCursorPosition kernel32 0 2 +imp 'SetConsoleDisplayMode' SetConsoleDisplayMode kernel32 0 +imp 'SetConsoleFont' SetConsoleFont kernel32 1270 +imp 'SetConsoleHardwareState' SetConsoleHardwareState kernel32 1271 +imp 'SetConsoleHistoryInfo' SetConsoleHistoryInfo kernel32 0 +imp 'SetConsoleIcon' SetConsoleIcon kernel32 1273 +imp 'SetConsoleKeyShortcuts' SetConsoleKeyShortcuts kernel32 1276 +imp 'SetConsoleLocalEUDC' SetConsoleLocalEUDC kernel32 1277 +imp 'SetConsoleMaximumWindowSize' SetConsoleMaximumWindowSize kernel32 1278 +imp 'SetConsoleMenuClose' SetConsoleMenuClose kernel32 1279 +imp 'SetConsoleMode' SetConsoleMode kernel32 0 2 +imp 'SetConsoleNlsMode' SetConsoleNlsMode kernel32 1281 +imp 'SetConsoleOS2OemFormat' SetConsoleOS2OemFormat kernel32 1284 +imp 'SetConsoleOutputCP' SetConsoleOutputCP kernel32 0 1 +imp 'SetConsolePalette' SetConsolePalette kernel32 1286 +imp 'SetConsoleScreenBufferInfoEx' SetConsoleScreenBufferInfoEx kernel32 0 2 +imp 'SetConsoleScreenBufferSize' SetConsoleScreenBufferSize kernel32 0 2 +imp 'SetConsoleTextAttribute' SetConsoleTextAttribute kernel32 0 +imp 'SetConsoleTitle' SetConsoleTitleW kernel32 0 1 +imp 'SetConsoleTitleA' SetConsoleTitleA kernel32 0 1 +imp 'SetConsoleWindowInfo' SetConsoleWindowInfo kernel32 0 3 +imp 'SetCriticalSectionSpinCount' SetCriticalSectionSpinCount kernel32 0 2 +imp 'SetCurrentConsoleFontEx' SetCurrentConsoleFontEx kernel32 0 +imp 'SetCurrentDirectoryA' SetCurrentDirectoryA kernel32 0 1 +imp 'SetDefaultCommConfig' SetDefaultCommConfigW kernel32 1298 +imp 'SetDefaultCommConfigA' SetDefaultCommConfigA kernel32 1297 +imp 'SetDefaultDllDirectories' SetDefaultDllDirectories kernel32 0 1 # Windows 8+, KB2533623 on Windows 7 +imp 'SetDllDirectory' SetDllDirectoryW kernel32 1301 +imp 'SetDllDirectoryA' SetDllDirectoryA kernel32 1300 +imp 'SetDynamicTimeZoneInformation' SetDynamicTimeZoneInformation kernel32 0 +imp 'SetEndOfFile' SetEndOfFile kernel32 0 1 +imp 'SetEnvironmentStringsA' SetEnvironmentStringsA kernel32 1304 1 +imp 'SetEnvironmentVariable' SetEnvironmentVariableW kernel32 0 2 +imp 'SetEnvironmentVariableA' SetEnvironmentVariableA kernel32 0 2 +imp 'SetErrorMode' SetErrorMode kernel32 0 1 +imp 'SetEvent' SetEvent kernel32 0 1 +imp 'SetFileApisToANSI' SetFileApisToANSI kernel32 0 +imp 'SetFileApisToOEM' SetFileApisToOEM kernel32 0 +imp 'SetFileAttributes' SetFileAttributesW kernel32 0 2 +imp 'SetFileAttributesA' SetFileAttributesA kernel32 0 2 +imp 'SetFileAttributesTransacted' SetFileAttributesTransactedW kernel32 1315 +imp 'SetFileAttributesTransactedA' SetFileAttributesTransactedA kernel32 1314 +imp 'SetFileBandwidthReservation' SetFileBandwidthReservation kernel32 1317 +imp 'SetFileCompletionNotificationModes' SetFileCompletionNotificationModes kernel32 1318 2 +imp 'SetFileInformationByHandle' SetFileInformationByHandle kernel32 0 +imp 'SetFileIoOverlappedRange' SetFileIoOverlappedRange kernel32 0 +imp 'SetFilePointer' SetFilePointer kernel32 0 4 +imp 'SetFilePointerEx' SetFilePointerEx kernel32 0 4 +imp 'SetFileShortName' SetFileShortNameW kernel32 1324 +imp 'SetFileShortNameA' SetFileShortNameA kernel32 1323 +imp 'SetFileTime' SetFileTime kernel32 0 4 +imp 'SetFileValidData' SetFileValidData kernel32 0 2 +imp 'SetFirmwareEnvironmentVariable' SetFirmwareEnvironmentVariableW kernel32 1330 +imp 'SetFirmwareEnvironmentVariableA' SetFirmwareEnvironmentVariableA kernel32 1327 +imp 'SetFirmwareEnvironmentVariableEx' SetFirmwareEnvironmentVariableExW kernel32 1329 +imp 'SetFirmwareEnvironmentVariableExA' SetFirmwareEnvironmentVariableExA kernel32 1328 +imp 'SetHandleCount' SetHandleCount kernel32 0 1 +imp 'SetHandleInformation' SetHandleInformation kernel32 0 3 +imp 'SetInformationJobObject' SetInformationJobObject kernel32 1333 +imp 'SetIoRateControlInformationJobObject' SetIoRateControlInformationJobObject kernel32 1334 +imp 'SetLastError' SetLastError kernel32 0 1 +imp 'SetLocalPrimaryComputerName' SetLocalPrimaryComputerNameW kernel32 1338 +imp 'SetLocalPrimaryComputerNameA' SetLocalPrimaryComputerNameA kernel32 1337 +imp 'SetLocalTime' SetLocalTime kernel32 0 +imp 'SetLocaleInfo' SetLocaleInfoW kernel32 0 +imp 'SetLocaleInfoA' SetLocaleInfoA kernel32 1340 +imp 'SetMailslotInfo' SetMailslotInfo kernel32 1342 +imp 'SetMessageWaitingIndicator' SetMessageWaitingIndicator kernel32 1343 +imp 'SetNamedPipeAttribute' SetNamedPipeAttribute kernel32 1344 +imp 'SetNamedPipeHandleState' SetNamedPipeHandleState kernel32 0 4 +imp 'SetPriorityClass' SetPriorityClass kernel32 0 2 +imp 'SetProcessAffinityMask' SetProcessAffinityMask kernel32 1347 2 +imp 'SetProcessAffinityUpdateMode' SetProcessAffinityUpdateMode kernel32 0 +imp 'SetProcessDEPPolicy' SetProcessDEPPolicy kernel32 1349 +imp 'SetProcessDefaultCpuSets' SetProcessDefaultCpuSets kernel32 0 +imp 'SetProcessInformation' SetProcessInformation kernel32 0 +imp 'SetProcessMitigationPolicy' SetProcessMitigationPolicy kernel32 0 +imp 'SetProcessPreferredUILanguages' SetProcessPreferredUILanguages kernel32 0 +imp 'SetProcessPriorityBoost' SetProcessPriorityBoost kernel32 0 2 +imp 'SetProcessShutdownParameters' SetProcessShutdownParameters kernel32 0 +imp 'SetProcessWorkingSetSize' SetProcessWorkingSetSize kernel32 1356 3 +imp 'SetProcessWorkingSetSizeEx' SetProcessWorkingSetSizeEx kernel32 0 4 +imp 'SetProtectedPolicy' SetProtectedPolicy kernel32 0 +imp 'SetSearchPathMode' SetSearchPathMode kernel32 1359 +imp 'SetStdHandle' SetStdHandle kernel32 0 2 +imp 'SetSystemFileCacheSize' SetSystemFileCacheSize kernel32 0 +imp 'SetSystemPowerState' SetSystemPowerState kernel32 1363 +imp 'SetSystemTime' SetSystemTime kernel32 0 +imp 'SetSystemTimeAdjustment' SetSystemTimeAdjustment kernel32 0 +imp 'SetTapeParameters' SetTapeParameters kernel32 1366 +imp 'SetTapePosition' SetTapePosition kernel32 1367 +imp 'SetTermsrvAppInstallMode' SetTermsrvAppInstallMode kernel32 1368 +imp 'SetThreadAffinityMask' SetThreadAffinityMask kernel32 1369 2 +imp 'SetThreadContext' SetThreadContext kernel32 0 +imp 'SetThreadErrorMode' SetThreadErrorMode kernel32 0 +imp 'SetThreadExecutionState' SetThreadExecutionState kernel32 1373 +imp 'SetThreadGroupAffinity' SetThreadGroupAffinity kernel32 0 +imp 'SetThreadIdealProcessor' SetThreadIdealProcessor kernel32 0 +imp 'SetThreadIdealProcessorEx' SetThreadIdealProcessorEx kernel32 0 +imp 'SetThreadInformation' SetThreadInformation kernel32 0 +imp 'SetThreadLocale' SetThreadLocale kernel32 0 +imp 'SetThreadPreferredUILanguages' SetThreadPreferredUILanguages kernel32 0 +imp 'SetThreadPriority' SetThreadPriority kernel32 0 2 +imp 'SetThreadPriorityBoost' SetThreadPriorityBoost kernel32 0 2 +imp 'SetThreadSelectedCpuSets' SetThreadSelectedCpuSets kernel32 0 +imp 'SetThreadStackGuarantee' SetThreadStackGuarantee kernel32 0 +imp 'SetThreadUILanguage' SetThreadUILanguage kernel32 0 +imp 'SetThreadpoolStackInformation' SetThreadpoolStackInformation kernel32 0 +imp 'SetThreadpoolThreadMinimum' SetThreadpoolThreadMinimum kernel32 0 +imp 'SetTimeZoneInformation' SetTimeZoneInformation kernel32 0 +imp 'SetTimerQueueTimer' SetTimerQueueTimer kernel32 1394 +imp 'SetUmsThreadInformation' SetUmsThreadInformation kernel32 1395 +imp 'SetUnhandledExceptionFilter' SetUnhandledExceptionFilter kernel32 0 1 +imp 'SetUserGeoID' SetUserGeoID kernel32 0 +imp 'SetVDMCurrentDirectories' SetVDMCurrentDirectories kernel32 1399 +imp 'SetVolumeLabel' SetVolumeLabelW kernel32 1401 +imp 'SetVolumeLabelA' SetVolumeLabelA kernel32 1400 +imp 'SetVolumeMountPoint' SetVolumeMountPointW kernel32 1403 +imp 'SetVolumeMountPointA' SetVolumeMountPointA kernel32 1402 +imp 'SetVolumeMountPointWStub' SetVolumeMountPointWStub kernel32 1404 +imp 'SetWaitableTimer' SetWaitableTimer kernel32 0 6 +imp 'SetWaitableTimerEx' SetWaitableTimerEx kernel32 0 +imp 'SetXStateFeaturesMask' SetXStateFeaturesMask kernel32 0 +imp 'SetupComm' SetupComm kernel32 0 +imp 'ShowConsoleCursor' ShowConsoleCursor kernel32 1409 +imp 'SignalObjectAndWait' SignalObjectAndWait kernel32 0 +imp 'SizeofResource' SizeofResource kernel32 0 +imp 'Sleep' Sleep kernel32 0 1 +imp 'SleepConditionVariableCS' SleepConditionVariableCS kernel32 0 +imp 'SleepConditionVariableSRW' SleepConditionVariableSRW kernel32 0 +imp 'SleepEx' SleepEx kernel32 0 2 +imp 'SortCloseHandle' SortCloseHandle kernel32 1416 +imp 'SortGetHandle' SortGetHandle kernel32 1417 +imp 'SuspendThread' SuspendThread kernel32 0 +imp 'SwitchToFiber' SwitchToFiber kernel32 0 +imp 'SwitchToThread' SwitchToThread kernel32 0 +imp 'SystemTimeToFileTime' SystemTimeToFileTime kernel32 0 2 +imp 'SystemTimeToTzSpecificLocalTime' SystemTimeToTzSpecificLocalTime kernel32 0 +imp 'SystemTimeToTzSpecificLocalTimeEx' SystemTimeToTzSpecificLocalTimeEx kernel32 0 +imp 'TerminateJobObject' TerminateJobObject kernel32 1426 +imp 'TerminateThread' TerminateThread kernel32 0 +imp 'TermsrvAppInstallMode' TermsrvAppInstallMode kernel32 1429 +imp 'TermsrvConvertSysRootToUserDir' TermsrvConvertSysRootToUserDir kernel32 1430 +imp 'TermsrvCreateRegEntry' TermsrvCreateRegEntry kernel32 1431 +imp 'TermsrvDeleteKey' TermsrvDeleteKey kernel32 1432 +imp 'TermsrvDeleteValue' TermsrvDeleteValue kernel32 1433 +imp 'TermsrvGetPreSetValue' TermsrvGetPreSetValue kernel32 1434 +imp 'TermsrvGetWindowsDirectory' TermsrvGetWindowsDirectoryW kernel32 1436 +imp 'TermsrvGetWindowsDirectoryA' TermsrvGetWindowsDirectoryA kernel32 1435 +imp 'TermsrvOpenRegEntry' TermsrvOpenRegEntry kernel32 1437 +imp 'TermsrvOpenUserClasses' TermsrvOpenUserClasses kernel32 1438 +imp 'TermsrvRestoreKey' TermsrvRestoreKey kernel32 1439 +imp 'TermsrvSetKeySecurity' TermsrvSetKeySecurity kernel32 1440 +imp 'TermsrvSetValueKey' TermsrvSetValueKey kernel32 1441 +imp 'TermsrvSyncUserIniFileExt' TermsrvSyncUserIniFileExt kernel32 1442 +imp 'Thread32First' Thread32First kernel32 1443 +imp 'Thread32Next' Thread32Next kernel32 1444 +imp 'Toolhelp32ReadProcessMemory' Toolhelp32ReadProcessMemory kernel32 1449 +imp 'TransactNamedPipe' TransactNamedPipe kernel32 0 7 +imp 'TransmitCommChar' TransmitCommChar kernel32 0 +imp 'TryAcquireSRWLockExclusive' TryAcquireSRWLockExclusive kernel32 0 1 +imp 'TryAcquireSRWLockShared' TryAcquireSRWLockShared kernel32 0 1 +imp 'TryEnterCriticalSection' TryEnterCriticalSection kernel32 0 1 +imp 'TrySubmitThreadpoolCallback' TrySubmitThreadpoolCallback kernel32 0 +imp 'TzSpecificLocalTimeToSystemTime' TzSpecificLocalTimeToSystemTime kernel32 0 +imp 'TzSpecificLocalTimeToSystemTimeEx' TzSpecificLocalTimeToSystemTimeEx kernel32 0 +imp 'UTRegister' UTRegister kernel32 1458 +imp 'UTUnRegister' UTUnRegister kernel32 1459 +imp 'UmsThreadYield' UmsThreadYield kernel32 1460 +imp 'UnhandledExceptionFilter' UnhandledExceptionFilter kernel32 0 +imp 'UnlockFile' UnlockFile kernel32 0 5 +imp 'UnlockFileEx' UnlockFileEx kernel32 0 5 +imp 'UnmapViewOfFile2' UnmapViewOfFile2 kernel32 0 2 +imp 'UnmapViewOfFileEx' UnmapViewOfFileEx kernel32 0 3 +imp 'UnregisterApplicationRecoveryCallback' UnregisterApplicationRecoveryCallback kernel32 1466 +imp 'UnregisterApplicationRestart' UnregisterApplicationRestart kernel32 1467 +imp 'UnregisterBadMemoryNotification' UnregisterBadMemoryNotification kernel32 0 +imp 'UnregisterConsoleIME' UnregisterConsoleIME kernel32 1469 +imp 'UnregisterWait' UnregisterWait kernel32 1470 +imp 'UnregisterWaitEx' UnregisterWaitEx kernel32 0 +imp 'UnregisterWaitUntilOOBECompleted' UnregisterWaitUntilOOBECompleted kernel32 1472 +imp 'UpdateCalendarDayOfWeek' UpdateCalendarDayOfWeek kernel32 1473 +imp 'UpdateProcThreadAttribute' UpdateProcThreadAttribute kernel32 0 7 +imp 'UpdateResource' UpdateResourceW kernel32 1476 +imp 'UpdateResourceA' UpdateResourceA kernel32 1475 +imp 'VDMConsoleOperation' VDMConsoleOperation kernel32 1477 +imp 'VDMOperationStarted' VDMOperationStarted kernel32 1478 +imp 'VerLanguageName' VerLanguageNameW kernel32 0 +imp 'VerLanguageNameA' VerLanguageNameA kernel32 0 +imp 'VerifyConsoleIoHandle' VerifyConsoleIoHandle kernel32 1482 +imp 'VerifyScripts' VerifyScripts kernel32 0 +imp 'VerifyVersionInfo' VerifyVersionInfoW kernel32 1485 +imp 'VerifyVersionInfoA' VerifyVersionInfoA kernel32 1484 +imp 'VirtualAlloc' VirtualAlloc kernel32 0 4 +imp 'VirtualAllocEx' VirtualAllocEx kernel32 0 5 +imp 'VirtualAllocExNuma' VirtualAllocExNuma kernel32 0 +imp 'VirtualFree' VirtualFree kernel32 0 3 +imp 'VirtualFreeEx' VirtualFreeEx kernel32 0 +imp 'VirtualLock' VirtualLock kernel32 0 +imp 'VirtualProtectEx' VirtualProtectEx kernel32 0 +imp 'VirtualQuery' VirtualQuery kernel32 0 3 +imp 'VirtualQueryEx' VirtualQueryEx kernel32 0 +imp 'VirtualUnlock' VirtualUnlock kernel32 0 +imp 'WTSGetActiveConsoleSessionId' WTSGetActiveConsoleSessionId kernel32 1497 +imp 'WaitCommEvent' WaitCommEvent kernel32 0 +imp 'WaitForDebugEvent' WaitForDebugEvent kernel32 0 +imp 'WaitForMultipleObjectsEx' WaitForMultipleObjectsEx kernel32 0 5 +imp 'WaitForSingleObjectEx' WaitForSingleObjectEx kernel32 0 3 +imp 'WaitNamedPipe' WaitNamedPipeW kernel32 0 +imp 'WaitNamedPipeA' WaitNamedPipeA kernel32 1509 2 +imp 'WerGetFlags' WerGetFlags kernel32 0 +imp 'WerGetFlagsWorker' WerGetFlagsWorker kernel32 1514 +imp 'WerRegisterFile' WerRegisterFile kernel32 0 +imp 'WerRegisterFileWorker' WerRegisterFileWorker kernel32 1520 +imp 'WerRegisterMemoryBlock' WerRegisterMemoryBlock kernel32 0 +imp 'WerRegisterMemoryBlockWorker' WerRegisterMemoryBlockWorker kernel32 1522 +imp 'WerRegisterRuntimeExceptionModule' WerRegisterRuntimeExceptionModule kernel32 0 +imp 'WerRegisterRuntimeExceptionModuleWorker' WerRegisterRuntimeExceptionModuleWorker kernel32 1524 +imp 'WerSetFlags' WerSetFlags kernel32 0 +imp 'WerSetFlagsWorker' WerSetFlagsWorker kernel32 1526 +imp 'WerUnregisterFile' WerUnregisterFile kernel32 0 +imp 'WerUnregisterFileWorker' WerUnregisterFileWorker kernel32 1532 +imp 'WerUnregisterMemoryBlock' WerUnregisterMemoryBlock kernel32 0 +imp 'WerUnregisterMemoryBlockWorker' WerUnregisterMemoryBlockWorker kernel32 1534 +imp 'WerUnregisterRuntimeExceptionModule' WerUnregisterRuntimeExceptionModule kernel32 0 +imp 'WerUnregisterRuntimeExceptionModuleWorker' WerUnregisterRuntimeExceptionModuleWorker kernel32 1536 +imp 'WerpGetDebugger' WerpGetDebugger kernel32 1537 +imp 'WerpInitiateRemoteRecovery' WerpInitiateRemoteRecovery kernel32 1538 +imp 'WerpLaunchAeDebug' WerpLaunchAeDebug kernel32 1539 +imp 'WerpNotifyLoadStringResourceWorker' WerpNotifyLoadStringResourceWorker kernel32 1540 +imp 'WerpNotifyUseStringResourceWorker' WerpNotifyUseStringResourceWorker kernel32 1541 +imp 'WideCharToMultiByte' WideCharToMultiByte kernel32 1553 8 +imp 'WinExec' WinExec kernel32 1543 +imp 'Wow64DisableWow64FsRedirection' Wow64DisableWow64FsRedirection kernel32 0 +imp 'Wow64EnableWow64FsRedirection' Wow64EnableWow64FsRedirection kernel32 1545 +imp 'Wow64GetThreadContext' Wow64GetThreadContext kernel32 1546 +imp 'Wow64GetThreadSelectorEntry' Wow64GetThreadSelectorEntry kernel32 1547 +imp 'Wow64RevertWow64FsRedirection' Wow64RevertWow64FsRedirection kernel32 0 +imp 'Wow64SetThreadContext' Wow64SetThreadContext kernel32 1549 +imp 'Wow64SuspendThread' Wow64SuspendThread kernel32 1550 +imp 'WriteConsole' WriteConsoleW kernel32 0 5 +imp 'WriteConsoleA' WriteConsoleA kernel32 0 5 +imp 'WriteConsoleInput' WriteConsoleInputW kernel32 0 4 +imp 'WriteConsoleInputA' WriteConsoleInputA kernel32 0 4 +imp 'WriteConsoleInputVDMA' WriteConsoleInputVDMA kernel32 1553 +imp 'WriteConsoleInputVDMW' WriteConsoleInputVDMW kernel32 1554 +imp 'WriteConsoleOutput' WriteConsoleOutputW kernel32 0 +imp 'WriteConsoleOutputA' WriteConsoleOutputA kernel32 0 +imp 'WriteConsoleOutputAttribute' WriteConsoleOutputAttribute kernel32 0 5 +imp 'WriteConsoleOutputCharacter' WriteConsoleOutputCharacterW kernel32 0 5 +imp 'WriteConsoleOutputCharacterA' WriteConsoleOutputCharacterA kernel32 0 5 +imp 'WriteFile' WriteFile kernel32 0 5 +imp 'WriteFileEx' WriteFileEx kernel32 0 5 +imp 'WriteFileGather' WriteFileGather kernel32 0 5 +imp 'WritePrivateProfileSection' WritePrivateProfileSectionW kernel32 1566 +imp 'WritePrivateProfileSectionA' WritePrivateProfileSectionA kernel32 1565 +imp 'WritePrivateProfileString' WritePrivateProfileStringW kernel32 1568 +imp 'WritePrivateProfileStringA' WritePrivateProfileStringA kernel32 1567 +imp 'WritePrivateProfileStruct' WritePrivateProfileStructW kernel32 1570 +imp 'WritePrivateProfileStructA' WritePrivateProfileStructA kernel32 1569 +imp 'WriteProcessMemory' WriteProcessMemory kernel32 0 +imp 'WriteProfileSection' WriteProfileSectionW kernel32 1573 +imp 'WriteProfileSectionA' WriteProfileSectionA kernel32 1572 +imp 'WriteProfileString' WriteProfileStringW kernel32 1575 +imp 'WriteProfileStringA' WriteProfileStringA kernel32 1574 +imp 'WriteTapemark' WriteTapemark kernel32 1576 +imp 'ZombifyActCtx' ZombifyActCtx kernel32 0 +imp 'ZombifyActCtxWorker' ZombifyActCtxWorker kernel32 1578 +imp '__CloseHandle' CloseHandle kernel32 0 1 +imp '__CreateDirectory' CreateDirectoryW kernel32 0 2 +imp '__CreateFile' CreateFileW kernel32 0 7 +imp '__CreateFileMapping' CreateFileMappingW kernel32 0 6 +imp '__CreateFileMappingNuma' CreateFileMappingNumaW kernel32 0 7 +imp '__CreateNamedPipe' CreateNamedPipeW kernel32 0 8 +imp '__CreatePipe' CreatePipe kernel32 0 4 +imp '__CreateProcess' CreateProcessW kernel32 0 10 +imp '__CreateSymbolicLink' CreateSymbolicLinkW kernel32 0 3 +imp '__CreateThread' CreateThread kernel32 0 6 +imp '__DeleteFile' DeleteFileW kernel32 0 1 +imp '__DeviceIoControl' DeviceIoControl kernel32 0 8 +imp '__FindClose' FindClose kernel32 0 1 +imp '__FindFirstFile' FindFirstFileW kernel32 0 2 +imp '__FindNextFile' FindNextFileW kernel32 0 2 +imp '__FlushFileBuffers' FlushFileBuffers kernel32 0 1 +imp '__FlushViewOfFile' FlushViewOfFile kernel32 0 2 +imp '__GenerateConsoleCtrlEvent' GenerateConsoleCtrlEvent kernel32 0 2 +imp '__GetExitCodeProcess' GetExitCodeProcess kernel32 0 2 +imp '__GetFileAttributes' GetFileAttributesW kernel32 0 1 +imp '__MapViewOfFileEx' MapViewOfFileEx kernel32 0 6 +imp '__MapViewOfFileExNuma' MapViewOfFileExNuma kernel32 0 7 +imp '__MoveFileEx' MoveFileExW kernel32 0 3 +imp '__OpenProcess' OpenProcess kernel32 0 3 +imp '__ReOpenFile' ReOpenFile kernel32 0 4 # TODO(jart): 6.2 and higher +imp '__RemoveDirectory' RemoveDirectoryW kernel32 0 1 +imp '__SetCurrentDirectory' SetCurrentDirectoryW kernel32 0 1 +imp '__TerminateProcess' TerminateProcess kernel32 0 2 +imp '__TlsAlloc' TlsAlloc kernel32 0 0 +imp '__TlsFree' TlsFree kernel32 0 1 +imp '__TlsGetValue' TlsGetValue kernel32 0 1 +imp '__TlsSetValue' TlsSetValue kernel32 0 2 +imp '__UnmapViewOfFile' UnmapViewOfFile kernel32 0 1 +imp '__VirtualProtect' VirtualProtect kernel32 0 4 +imp '__WaitForMultipleObjects' WaitForMultipleObjects kernel32 0 4 +imp '__WaitForSingleObject' WaitForSingleObject kernel32 0 2 + +# ADVAPI32.DLL +# +# Name Actual DLL Hint Arity +imp 'AbortSystemShutdown' AbortSystemShutdownW advapi32 1006 +imp 'AbortSystemShutdownA' AbortSystemShutdownA advapi32 1005 +imp 'AccessCheck' AccessCheck advapi32 0 8 +imp 'AccessCheckAndAuditAlarm' AccessCheckAndAuditAlarmW advapi32 0 +imp 'AccessCheckAndAuditAlarmA' AccessCheckAndAuditAlarmA advapi32 1008 +imp 'AccessCheckByType' AccessCheckByType advapi32 0 +imp 'AccessCheckByTypeAndAuditAlarm' AccessCheckByTypeAndAuditAlarmW advapi32 0 +imp 'AccessCheckByTypeAndAuditAlarmA' AccessCheckByTypeAndAuditAlarmA advapi32 1011 +imp 'AccessCheckByTypeResultList' AccessCheckByTypeResultList advapi32 0 +imp 'AccessCheckByTypeResultListAndAuditAlarm' AccessCheckByTypeResultListAndAuditAlarmW advapi32 0 +imp 'AccessCheckByTypeResultListAndAuditAlarmA' AccessCheckByTypeResultListAndAuditAlarmA advapi32 1014 +imp 'AccessCheckByTypeResultListAndAuditAlarmByHandle' AccessCheckByTypeResultListAndAuditAlarmByHandleW advapi32 0 +imp 'AccessCheckByTypeResultListAndAuditAlarmByHandleA' AccessCheckByTypeResultListAndAuditAlarmByHandleA advapi32 1015 +imp 'AddAccessAllowedAce' AddAccessAllowedAce advapi32 0 +imp 'AddAccessAllowedAceEx' AddAccessAllowedAceEx advapi32 0 +imp 'AddAccessAllowedObjectAce' AddAccessAllowedObjectAce advapi32 0 +imp 'AddAccessDeniedAce' AddAccessDeniedAce advapi32 0 +imp 'AddAccessDeniedAceEx' AddAccessDeniedAceEx advapi32 0 +imp 'AddAccessDeniedObjectAce' AddAccessDeniedObjectAce advapi32 0 +imp 'AddAce' AddAce advapi32 0 +imp 'AddAuditAccessAce' AddAuditAccessAce advapi32 0 +imp 'AddAuditAccessAceEx' AddAuditAccessAceEx advapi32 0 +imp 'AddAuditAccessObjectAce' AddAuditAccessObjectAce advapi32 0 +imp 'AddConditionalAce' AddConditionalAce advapi32 1028 +imp 'AddMandatoryAce' AddMandatoryAce advapi32 0 +imp 'AddUsersToEncryptedFile' AddUsersToEncryptedFile advapi32 1030 +imp 'AddUsersToEncryptedFileEx' AddUsersToEncryptedFileEx advapi32 1031 +imp 'AdjustTokenGroups' AdjustTokenGroups advapi32 0 +imp 'AdjustTokenPrivileges' AdjustTokenPrivileges advapi32 0 6 +imp 'AllocateAndInitializeSid' AllocateAndInitializeSid advapi32 0 +imp 'AllocateLocallyUniqueId' AllocateLocallyUniqueId advapi32 0 +imp 'AreAllAccessesGranted' AreAllAccessesGranted advapi32 0 +imp 'AreAnyAccessesGranted' AreAnyAccessesGranted advapi32 0 imp 'AuditComputeEffectivePolicyBySid' AuditComputeEffectivePolicyBySid advapi32 1038 imp 'AuditComputeEffectivePolicyByToken' AuditComputeEffectivePolicyByToken advapi32 1039 imp 'AuditEnumerateCategories' AuditEnumerateCategories advapi32 1040 @@ -174,62 +1417,22 @@ imp 'AuditEnumerateSubCategories' AuditEnumerateSubCategories advapi32 104 imp 'AuditFree' AuditFree advapi32 1043 imp 'AuditLookupCategoryGuidFromCategoryId' AuditLookupCategoryGuidFromCategoryId advapi32 1044 imp 'AuditLookupCategoryIdFromCategoryGuid' AuditLookupCategoryIdFromCategoryGuid advapi32 1045 -imp 'AuditLookupCategoryNameA' AuditLookupCategoryNameA advapi32 1046 imp 'AuditLookupCategoryName' AuditLookupCategoryNameW advapi32 1047 -imp 'AuditLookupSubCategoryNameA' AuditLookupSubCategoryNameA advapi32 1048 +imp 'AuditLookupCategoryNameA' AuditLookupCategoryNameA advapi32 1046 imp 'AuditLookupSubCategoryName' AuditLookupSubCategoryNameW advapi32 1049 -imp 'AuditQueryGlobalSaclA' AuditQueryGlobalSaclA advapi32 1050 +imp 'AuditLookupSubCategoryNameA' AuditLookupSubCategoryNameA advapi32 1048 imp 'AuditQueryGlobalSacl' AuditQueryGlobalSaclW advapi32 1051 +imp 'AuditQueryGlobalSaclA' AuditQueryGlobalSaclA advapi32 1050 imp 'AuditQueryPerUserPolicy' AuditQueryPerUserPolicy advapi32 1052 imp 'AuditQuerySecurity' AuditQuerySecurity advapi32 1053 imp 'AuditQuerySystemPolicy' AuditQuerySystemPolicy advapi32 1054 -imp 'AuditSetGlobalSaclA' AuditSetGlobalSaclA advapi32 1055 imp 'AuditSetGlobalSacl' AuditSetGlobalSaclW advapi32 1056 +imp 'AuditSetGlobalSaclA' AuditSetGlobalSaclA advapi32 1055 imp 'AuditSetPerUserPolicy' AuditSetPerUserPolicy advapi32 1057 imp 'AuditSetSecurity' AuditSetSecurity advapi32 1058 imp 'AuditSetSystemPolicy' AuditSetSystemPolicy advapi32 1059 -imp 'AutodialHookCallback' AutodialHookCallback url 103 -imp 'BRUSHOBJ_hGetColorTransform' BRUSHOBJ_hGetColorTransform gdi32 1028 -imp 'BRUSHOBJ_pvAllocRbrush' BRUSHOBJ_pvAllocRbrush gdi32 1029 -imp 'BRUSHOBJ_pvGetRbrush' BRUSHOBJ_pvGetRbrush gdi32 1030 -imp 'BRUSHOBJ_ulGetBrushColor' BRUSHOBJ_ulGetBrushColor gdi32 1031 -imp 'BackupEventLogA' BackupEventLogA advapi32 1060 imp 'BackupEventLog' BackupEventLogW advapi32 1061 -imp 'BackupRead' BackupRead kernel32 39 -imp 'BackupSeek' BackupSeek kernel32 40 -imp 'BackupWrite' BackupWrite kernel32 41 -imp 'BaseCheckAppcompatCache' BaseCheckAppcompatCache KernelBase 76 -imp 'BaseCheckAppcompatCacheEx' BaseCheckAppcompatCacheEx KernelBase 77 -imp 'BaseCheckAppcompatCacheExWorker' BaseCheckAppcompatCacheExWorker kernel32 44 -imp 'BaseCheckAppcompatCacheWorker' BaseCheckAppcompatCacheWorker kernel32 45 -imp 'BaseCheckElevation' BaseCheckElevation kernel32 46 -imp 'BaseCleanupAppcompatCacheSupport' BaseCleanupAppcompatCacheSupport KernelBase 78 -imp 'BaseCleanupAppcompatCacheSupportWorker' BaseCleanupAppcompatCacheSupportWorker kernel32 48 -imp 'BaseDestroyVDMEnvironment' BaseDestroyVDMEnvironment kernel32 49 -imp 'BaseDllFreeResourceId' BaseDllFreeResourceId KernelBase 79 -imp 'BaseDllMapResourceId' BaseDllMapResourceIdW KernelBase 80 -imp 'BaseDllReadWriteIniFile' BaseDllReadWriteIniFile kernel32 50 -imp 'BaseDumpAppcompatCache' BaseDumpAppcompatCache KernelBase 81 -imp 'BaseDumpAppcompatCacheWorker' BaseDumpAppcompatCacheWorker kernel32 52 -imp 'BaseElevationPostProcessing' BaseElevationPostProcessing kernel32 53 -imp 'BaseFlushAppcompatCache' BaseFlushAppcompatCache KernelBase 82 -imp 'BaseFlushAppcompatCacheWorker' BaseFlushAppcompatCacheWorker kernel32 55 -imp 'BaseFormatObjectAttributes' BaseFormatObjectAttributes KernelBase 83 -imp 'BaseFormatTimeOut' BaseFormatTimeOut kernel32 57 -imp 'BaseFreeAppCompatDataForProcess' BaseFreeAppCompatDataForProcess KernelBase 84 -imp 'BaseFreeAppCompatDataForProcessWorker' BaseFreeAppCompatDataForProcessWorker kernel32 58 -imp 'BaseGenerateAppCompatData' BaseGenerateAppCompatData kernel32 59 -imp 'BaseGetConsoleReference' BaseGetConsoleReference KernelBase 85 -imp 'BaseGetNamedObjectDirectory' BaseGetNamedObjectDirectory KernelBase 86 -imp 'BaseInitAppcompatCacheSupport' BaseInitAppcompatCacheSupport KernelBase 87 -imp 'BaseInitAppcompatCacheSupportWorker' BaseInitAppcompatCacheSupportWorker kernel32 62 -imp 'BaseIsAppcompatInfrastructureDisabled' BaseIsAppcompatInfrastructureDisabled KernelBase 88 -imp 'BaseIsAppcompatInfrastructureDisabledWorker' BaseIsAppcompatInfrastructureDisabledWorker kernel32 64 -imp 'BaseIsDosApplication' BaseIsDosApplication kernel32 65 -imp 'BaseMarkFileForDelete' BaseMarkFileForDelete KernelBase 89 -imp 'BaseQueryModuleData' BaseQueryModuleData kernel32 66 -imp 'BaseReadAppCompatDataForProcess' BaseReadAppCompatDataForProcess KernelBase 90 -imp 'BaseReadAppCompatDataForProcessWorker' BaseReadAppCompatDataForProcessWorker kernel32 67 +imp 'BackupEventLogA' BackupEventLogA advapi32 1060 imp 'BaseRegCloseKey' BaseRegCloseKey advapi32 1062 imp 'BaseRegCreateKey' BaseRegCreateKey advapi32 1063 imp 'BaseRegDeleteKeyEx' BaseRegDeleteKeyEx advapi32 1064 @@ -243,532 +1446,127 @@ imp 'BaseRegSaveKeyEx' BaseRegSaveKeyEx advapi32 1071 imp 'BaseRegSetKeySecurity' BaseRegSetKeySecurity advapi32 1072 imp 'BaseRegSetValue' BaseRegSetValue advapi32 1073 imp 'BaseRegUnLoadKey' BaseRegUnLoadKey advapi32 1074 -imp 'BaseSetLastNTError' BaseSetLastNTError kernel32 68 -imp 'BaseThreadInitThunk' BaseThreadInitThunk kernel32 69 -imp 'BaseUpdateAppcompatCache' BaseUpdateAppcompatCache KernelBase 91 -imp 'BaseUpdateAppcompatCacheWorker' BaseUpdateAppcompatCacheWorker kernel32 71 -imp 'BaseUpdateVDMEntry' BaseUpdateVDMEntry kernel32 72 -imp 'BaseVerifyUnicodeString' BaseVerifyUnicodeString kernel32 73 -imp 'BaseWriteErrorElevationRequiredEvent' BaseWriteErrorElevationRequiredEvent kernel32 74 -imp 'Basep8BitStringToDynamicUnicodeString' Basep8BitStringToDynamicUnicodeString kernel32 75 -imp 'BasepAdjustObjectAttributesForPrivateNamespace' BasepAdjustObjectAttributesForPrivateNamespace KernelBase 92 -imp 'BasepAllocateActivationContextActivationBlock' BasepAllocateActivationContextActivationBlock kernel32 76 -imp 'BasepAnsiStringToDynamicUnicodeString' BasepAnsiStringToDynamicUnicodeString kernel32 77 -imp 'BasepAppContainerEnvironmentExtension' BasepAppContainerEnvironmentExtension kernel32 78 -imp 'BasepAppXExtension' BasepAppXExtension kernel32 79 -imp 'BasepCheckAppCompat' BasepCheckAppCompat kernel32 80 -imp 'BasepCheckWebBladeHashes' BasepCheckWebBladeHashes kernel32 81 -imp 'BasepCheckWinSaferRestrictions' BasepCheckWinSaferRestrictions kernel32 82 -imp 'BasepConstructSxsCreateProcessMessage' BasepConstructSxsCreateProcessMessage kernel32 83 -imp 'BasepCopyEncryption' BasepCopyEncryption kernel32 84 -imp 'BasepCopyFileCallback' BasepCopyFileCallback KernelBase 93 -imp 'BasepCopyFileEx' BasepCopyFileExW KernelBase 94 -imp 'BasepFreeActivationContextActivationBlock' BasepFreeActivationContextActivationBlock kernel32 85 -imp 'BasepFreeAppCompatData' BasepFreeAppCompatData kernel32 86 -imp 'BasepGetAppCompatData' BasepGetAppCompatData kernel32 87 -imp 'BasepGetComputerNameFromNtPath' BasepGetComputerNameFromNtPath kernel32 88 -imp 'BasepGetExeArchType' BasepGetExeArchType kernel32 89 -imp 'BasepInitAppCompatData' BasepInitAppCompatData kernel32 90 -imp 'BasepIsProcessAllowed' BasepIsProcessAllowed kernel32 91 -imp 'BasepMapModuleHandle' BasepMapModuleHandle kernel32 92 -imp 'BasepNotifyLoadStringResource' BasepNotifyLoadStringResource kernel32 93 -imp 'BasepNotifyTrackingService' BasepNotifyTrackingService KernelBase 95 -imp 'BasepPostSuccessAppXExtension' BasepPostSuccessAppXExtension kernel32 94 -imp 'BasepProcessInvalidImage' BasepProcessInvalidImage kernel32 95 -imp 'BasepQueryAppCompat' BasepQueryAppCompat kernel32 96 -imp 'BasepQueryModuleChpeSettings' BasepQueryModuleChpeSettings kernel32 97 -imp 'BasepReleaseAppXContext' BasepReleaseAppXContext kernel32 98 -imp 'BasepReleaseSxsCreateProcessUtilityStruct' BasepReleaseSxsCreateProcessUtilityStruct kernel32 99 -imp 'BasepReportFault' BasepReportFault kernel32 100 -imp 'BasepSetFileEncryptionCompression' BasepSetFileEncryptionCompression kernel32 101 -imp 'Beep' Beep kernel32 0 # KernelBase -imp 'BeginDeferWindowPos' BeginDeferWindowPos user32 1520 -imp 'BeginGdiRendering' BeginGdiRendering gdi32 1032 -imp 'BeginPaint' BeginPaint user32 1521 2 -imp 'BeginPath' BeginPath gdi32 1033 -imp 'BeginUpdateResourceA' BeginUpdateResourceA kernel32 103 -imp 'BeginUpdateResource' BeginUpdateResourceW kernel32 104 -imp 'BindIoCompletionCallback' BindIoCompletionCallback kernel32 105 -imp 'BitBlt' BitBlt gdi32 1034 9 -imp 'BlockInput' BlockInput user32 1522 -imp 'BringWindowToTop' BringWindowToTop user32 1523 1 -imp 'BroadcastSystemMessageA' BroadcastSystemMessageA user32 1525 -imp 'BroadcastSystemMessageExA' BroadcastSystemMessageExA user32 1526 -imp 'BroadcastSystemMessageEx' BroadcastSystemMessageExW user32 1527 -imp 'BroadcastSystemMessage' BroadcastSystemMessageW user32 1528 -imp 'BuildCommDCBA' BuildCommDCBA kernel32 106 -imp 'BuildCommDCBAndTimeoutsA' BuildCommDCBAndTimeoutsA kernel32 107 -imp 'BuildCommDCBAndTimeouts' BuildCommDCBAndTimeoutsW kernel32 108 -imp 'BuildCommDCBW' BuildCommDCBW kernel32 109 -imp 'BuildExplicitAccessWithNameA' BuildExplicitAccessWithNameA advapi32 1075 imp 'BuildExplicitAccessWithName' BuildExplicitAccessWithNameW advapi32 1076 -imp 'BuildImpersonateExplicitAccessWithNameA' BuildImpersonateExplicitAccessWithNameA advapi32 1077 +imp 'BuildExplicitAccessWithNameA' BuildExplicitAccessWithNameA advapi32 1075 imp 'BuildImpersonateExplicitAccessWithName' BuildImpersonateExplicitAccessWithNameW advapi32 1078 -imp 'BuildImpersonateTrusteeA' BuildImpersonateTrusteeA advapi32 1079 +imp 'BuildImpersonateExplicitAccessWithNameA' BuildImpersonateExplicitAccessWithNameA advapi32 1077 imp 'BuildImpersonateTrustee' BuildImpersonateTrusteeW advapi32 1080 -imp 'BuildReasonArray' BuildReasonArray user32 1529 -imp 'BuildSecurityDescriptorA' BuildSecurityDescriptorA advapi32 1081 +imp 'BuildImpersonateTrusteeA' BuildImpersonateTrusteeA advapi32 1079 imp 'BuildSecurityDescriptor' BuildSecurityDescriptorW advapi32 1082 -imp 'BuildTrusteeWithNameA' BuildTrusteeWithNameA advapi32 1083 +imp 'BuildSecurityDescriptorA' BuildSecurityDescriptorA advapi32 1081 imp 'BuildTrusteeWithName' BuildTrusteeWithNameW advapi32 1084 -imp 'BuildTrusteeWithObjectsAndNameA' BuildTrusteeWithObjectsAndNameA advapi32 1085 +imp 'BuildTrusteeWithNameA' BuildTrusteeWithNameA advapi32 1083 imp 'BuildTrusteeWithObjectsAndName' BuildTrusteeWithObjectsAndNameW advapi32 1086 -imp 'BuildTrusteeWithObjectsAndSidA' BuildTrusteeWithObjectsAndSidA advapi32 1087 +imp 'BuildTrusteeWithObjectsAndNameA' BuildTrusteeWithObjectsAndNameA advapi32 1085 imp 'BuildTrusteeWithObjectsAndSid' BuildTrusteeWithObjectsAndSidW advapi32 1088 -imp 'BuildTrusteeWithSidA' BuildTrusteeWithSidA advapi32 1089 +imp 'BuildTrusteeWithObjectsAndSidA' BuildTrusteeWithObjectsAndSidA advapi32 1087 imp 'BuildTrusteeWithSid' BuildTrusteeWithSidW advapi32 1090 -imp 'CDefFolderMenu_Create2' CDefFolderMenu_Create2 shell32 701 -imp 'CIDLData_CreateFromIDArray' CIDLData_CreateFromIDArray shell32 83 -imp 'CLIPOBJ_bEnum' CLIPOBJ_bEnum gdi32 1035 -imp 'CLIPOBJ_cEnumStart' CLIPOBJ_cEnumStart gdi32 1036 -imp 'CLIPOBJ_ppoGetPath' CLIPOBJ_ppoGetPath gdi32 1037 -imp 'CLOSE_LOCAL_HANDLE_INTERNAL' CLOSE_LOCAL_HANDLE_INTERNAL KernelBase 97 -imp 'CStorageItem_GetValidatedStorageItemObject' CStorageItem_GetValidatedStorageItemObject shell32 937 -imp 'CalcMenuBar' CalcMenuBar user32 1530 -imp 'CalculatePopupWindowPosition' CalculatePopupWindowPosition user32 1531 -imp 'CallEnclave' CallEnclave KernelBase 98 -imp 'CallMsgFilter' CallMsgFilterW user32 1534 -imp 'CallMsgFilterA' CallMsgFilterA user32 1533 -imp 'CallNamedPipe' CallNamedPipeW kernel32 0 7 # KernelBase -imp 'CallNamedPipeA' CallNamedPipeA kernel32 110 7 -imp 'CallNextHookEx' CallNextHookEx user32 1535 4 -imp 'CallWindowProcA' CallWindowProcA user32 1536 -imp 'CallWindowProc' CallWindowProcW user32 1537 -imp 'CallbackMayRunLong' CallbackMayRunLong kernel32 0 # KernelBase -imp 'CancelDC' CancelDC gdi32 1038 -imp 'CancelDeviceWakeupRequest' CancelDeviceWakeupRequest kernel32 113 -imp 'CancelIo' CancelIo kernel32 0 1 # KernelBase -imp 'CancelIoEx' CancelIoEx kernel32 0 2 # KernelBase +imp 'BuildTrusteeWithSidA' BuildTrusteeWithSidA advapi32 1089 imp 'CancelOverlappedAccess' CancelOverlappedAccess advapi32 1091 -imp 'CancelShutdown' CancelShutdown user32 1538 -imp 'CancelSynchronousIo' CancelSynchronousIo kernel32 0 1 # KernelBase -imp 'CancelTimerQueueTimer' CancelTimerQueueTimer kernel32 118 -imp 'CancelWaitableTimer' CancelWaitableTimer kernel32 0 # KernelBase -imp 'CascadeChildWindows' CascadeChildWindows user32 1539 -imp 'CascadeWindows' CascadeWindows user32 1540 -imp 'CeipIsOptedIn' CeipIsOptedIn kernel32 0 # KernelBase -imp 'ChangeClipboardChain' ChangeClipboardChain user32 1541 -imp 'ChangeDisplaySettingsA' ChangeDisplaySettingsA user32 1542 -imp 'ChangeDisplaySettingsExA' ChangeDisplaySettingsExA user32 1543 -imp 'ChangeDisplaySettingsEx' ChangeDisplaySettingsExW user32 1544 -imp 'ChangeDisplaySettings' ChangeDisplaySettingsW user32 1545 -imp 'ChangeMenuA' ChangeMenuA user32 1546 -imp 'ChangeMenu' ChangeMenuW user32 1547 +imp 'ChangeServiceConfig' ChangeServiceConfigW advapi32 1095 imp 'ChangeServiceConfig2A' ChangeServiceConfig2A advapi32 1092 imp 'ChangeServiceConfig2W' ChangeServiceConfig2W advapi32 1093 imp 'ChangeServiceConfigA' ChangeServiceConfigA advapi32 1094 -imp 'ChangeServiceConfig' ChangeServiceConfigW advapi32 1095 -imp 'ChangeTimerQueueTimer' ChangeTimerQueueTimer kernel32 0 # KernelBase -imp 'ChangeWindowMessageFilter' ChangeWindowMessageFilter user32 1548 -imp 'ChangeWindowMessageFilterEx' ChangeWindowMessageFilterEx user32 1549 -imp 'CharLowerA' CharLowerA KernelBase 108 -imp 'CharLowerBuffA' CharLowerBuffA KernelBase 109 -imp 'CharLowerBuff' CharLowerBuffW KernelBase 110 -imp 'CharLower' CharLowerW KernelBase 111 -imp 'CharNextA' CharNextA KernelBase 112 -imp 'CharNextExA' CharNextExA KernelBase 113 -imp 'CharNext' CharNextW KernelBase 114 -imp 'CharPrevA' CharPrevA KernelBase 115 -imp 'CharPrevExA' CharPrevExA KernelBase 116 -imp 'CharPrev' CharPrevW KernelBase 117 -imp 'CharToOemA' CharToOemA user32 1565 -imp 'CharToOemBuff' CharToOemBuffW user32 1567 -imp 'CharToOemBuffA' CharToOemBuffA user32 1566 -imp 'CharToOem' CharToOemW user32 1568 -imp 'CharUpper' CharUpperW KernelBase 121 -imp 'CharUpperA' CharUpperA KernelBase 118 -imp 'CharUpperBuffA' CharUpperBuffA KernelBase 119 -imp 'CharUpperBuff' CharUpperBuffW KernelBase 120 -imp 'CheckAllowDecryptedRemoteDestinationPolicy' CheckAllowDecryptedRemoteDestinationPolicy KernelBase 122 -imp 'CheckColorsInGamut' CheckColorsInGamut gdi32 1039 -imp 'CheckDBCSEnabledExt' CheckDBCSEnabledExt user32 1573 -imp 'CheckDlgButton' CheckDlgButton user32 1574 -imp 'CheckElevation' CheckElevation kernel32 123 -imp 'CheckElevationEnabled' CheckElevationEnabled kernel32 124 -imp 'CheckEscapes' CheckEscapesW shell32 268 imp 'CheckForHiberboot' CheckForHiberboot advapi32 1096 -imp 'CheckForReadOnlyResource' CheckForReadOnlyResource kernel32 125 -imp 'CheckForReadOnlyResourceFilter' CheckForReadOnlyResourceFilter kernel32 126 -imp 'CheckGroupPolicyEnabled' CheckGroupPolicyEnabled KernelBase 123 -imp 'CheckIfStateChangeNotificationExists' CheckIfStateChangeNotificationExists KernelBase 124 -imp 'CheckMenuItem' CheckMenuItem user32 1575 -imp 'CheckMenuRadioItem' CheckMenuRadioItem user32 1576 -imp 'CheckNameLegalDOS8Dot3A' CheckNameLegalDOS8Dot3A kernel32 127 -imp 'CheckNameLegalDOS8Dot3W' CheckNameLegalDOS8Dot3W kernel32 128 -imp 'CheckProcessForClipboardAccess' CheckProcessForClipboardAccess user32 1577 -imp 'CheckProcessSession' CheckProcessSession user32 1578 -imp 'CheckRadioButton' CheckRadioButton user32 1579 -imp 'CheckRemoteDebuggerPresent' CheckRemoteDebuggerPresent kernel32 0 2 # KernelBase -imp 'CheckTokenCapability' CheckTokenCapability kernel32 0 # KernelBase -imp 'CheckTokenMembership' CheckTokenMembership advapi32 0 # KernelBase -imp 'CheckTokenMembershipEx' CheckTokenMembershipEx kernel32 0 # KernelBase -imp 'CheckWindowThreadDesktop' CheckWindowThreadDesktop user32 1580 -imp 'ChildWindowFromPoint' ChildWindowFromPoint user32 1581 -imp 'ChildWindowFromPointEx' ChildWindowFromPointEx user32 1582 -imp 'ChooseColorA' ChooseColorA comdlg32 102 1 -imp 'ChooseColor' ChooseColorW comdlg32 103 1 -imp 'ChooseFontA' ChooseFontA comdlg32 104 1 -imp 'ChooseFont' ChooseFontW comdlg32 105 1 -imp 'ChoosePixelFormat' ChoosePixelFormat gdi32 1040 2 -imp 'Chord' Chord gdi32 1041 -imp 'ChrCmpIA' ChrCmpIA KernelBase 129 -imp 'ChrCmpIW' ChrCmpIW KernelBase 130 -imp 'ClearBitmapAttributes' ClearBitmapAttributes gdi32 1042 -imp 'ClearBrushAttributes' ClearBrushAttributes gdi32 1043 -imp 'ClearCommBreak' ClearCommBreak kernel32 0 # KernelBase -imp 'ClearCommError' ClearCommError kernel32 0 # KernelBase -imp 'ClearEventLogA' ClearEventLogA advapi32 1098 +imp 'CheckTokenMembership' CheckTokenMembership advapi32 0 imp 'ClearEventLog' ClearEventLogW advapi32 1099 -imp 'CliImmSetHotKey' CliImmSetHotKey user32 1583 -imp 'ClientThreadSetup' ClientThreadSetup user32 1584 -imp 'ClientToScreen' ClientToScreen user32 1585 -imp 'ClipCursor' ClipCursor user32 1586 -imp 'CloseClipboard' CloseClipboard user32 1587 +imp 'ClearEventLogA' ClearEventLogA advapi32 1098 imp 'CloseCodeAuthzLevel' CloseCodeAuthzLevel advapi32 1100 -imp 'CloseConsoleHandle' CloseConsoleHandle kernel32 134 -imp 'CloseDesktop' CloseDesktop user32 1588 imp 'CloseEncryptedFileRaw' CloseEncryptedFileRaw advapi32 1101 -imp 'CloseEnhMetaFile' CloseEnhMetaFile gdi32 1044 imp 'CloseEventLog' CloseEventLog advapi32 1102 -imp 'CloseFigure' CloseFigure gdi32 1045 -imp 'CloseGestureInfoHandle' CloseGestureInfoHandle user32 1589 -imp 'CloseGlobalizationUserSettingsKey' CloseGlobalizationUserSettingsKey KernelBase 133 -imp 'CloseHandle' CloseHandle kernel32 0 1 # KernelBase -imp 'CloseMetaFile' CloseMetaFile gdi32 1046 -imp 'ClosePackageInfo' ClosePackageInfo kernel32 0 # KernelBase -imp 'ClosePrivateNamespace' ClosePrivateNamespace kernel32 0 # KernelBase -imp 'CloseProfileUserMapping' CloseProfileUserMapping kernel32 138 imp 'CloseServiceHandle' CloseServiceHandle advapi32 1103 -imp 'CloseState' CloseState KernelBase 137 -imp 'CloseStateAtom' CloseStateAtom KernelBase 138 -imp 'CloseStateChangeNotification' CloseStateChangeNotification KernelBase 139 -imp 'CloseStateContainer' CloseStateContainer KernelBase 140 -imp 'CloseStateLock' CloseStateLock KernelBase 141 imp 'CloseThreadWaitChainSession' CloseThreadWaitChainSession advapi32 1104 -imp 'CloseTouchInputHandle' CloseTouchInputHandle user32 1590 imp 'CloseTrace' CloseTrace advapi32 1105 -imp 'CloseWindow' CloseWindow user32 1591 1 -imp 'CloseWindowStation' CloseWindowStation user32 1592 -imp 'CmdBatNotification' CmdBatNotification kernel32 147 -imp 'ColorCorrectPalette' ColorCorrectPalette gdi32 1047 -imp 'ColorMatchToTarget' ColorMatchToTarget gdi32 1048 -imp 'CombineRgn' CombineRgn gdi32 1049 -imp 'CombineTransform' CombineTransform gdi32 1050 -imp 'CommConfigDialogA' CommConfigDialogA kernel32 148 -imp 'CommConfigDialog' CommConfigDialogW kernel32 149 -imp 'CommDlgExtendedError' CommDlgExtendedError comdlg32 106 imp 'CommandLineFromMsiDescriptor' CommandLineFromMsiDescriptor advapi32 1106 -imp 'CommandLineToArgv' CommandLineToArgvW shell32 269 -imp 'CommitStateAtom' CommitStateAtom KernelBase 149 -imp 'CompareCalendarDates' CompareCalendarDates kernel32 150 -imp 'CompareFileTime' CompareFileTime kernel32 0 # KernelBase -imp 'CompareObjectHandles' CompareObjectHandles KernelBase 151 -imp 'CompareStringA' CompareStringA kernel32 0 # KernelBase -imp 'CompareStringEx' CompareStringEx kernel32 0 # KernelBase -imp 'CompareStringOrdinal' CompareStringOrdinal kernel32 0 # KernelBase -imp 'CompareString' CompareStringW kernel32 0 # KernelBase imp 'ComputeAccessTokenFromCodeAuthzLevel' ComputeAccessTokenFromCodeAuthzLevel advapi32 1107 -imp 'ConfigureOPMProtectedOutput' ConfigureOPMProtectedOutput gdi32 1051 -imp 'ConnectNamedPipe' ConnectNamedPipe kernel32 0 2 # KernelBase -imp 'ConsoleControl' ConsoleControl user32 1593 -imp 'ConsoleMenuControl' ConsoleMenuControl kernel32 157 -imp 'ContinueDebugEvent' ContinueDebugEvent kernel32 0 3 # KernelBase -imp 'ControlMagnification' ControlMagnification user32 1594 imp 'ControlService' ControlService advapi32 1108 -imp 'ControlServiceExA' ControlServiceExA advapi32 1109 imp 'ControlServiceEx' ControlServiceExW advapi32 1110 -imp 'ControlTraceA' ControlTraceA advapi32 1111 +imp 'ControlServiceExA' ControlServiceExA advapi32 1109 imp 'ControlTrace' ControlTraceW advapi32 1112 -imp 'Control_RunDLL' Control_RunDLL shell32 272 -imp 'Control_RunDLLA' Control_RunDLLA shell32 273 -imp 'Control_RunDLLAsUser' Control_RunDLLAsUserW shell32 274 -imp 'Control_RunDLLW' Control_RunDLLW shell32 275 -imp 'ConvertAccessToSecurityDescriptorA' ConvertAccessToSecurityDescriptorA advapi32 1113 +imp 'ControlTraceA' ControlTraceA advapi32 1111 imp 'ConvertAccessToSecurityDescriptor' ConvertAccessToSecurityDescriptorW advapi32 1114 -imp 'ConvertAuxiliaryCounterToPerformanceCounter' ConvertAuxiliaryCounterToPerformanceCounter KernelBase 158 -imp 'ConvertCalDateTimeToSystemTime' ConvertCalDateTimeToSystemTime kernel32 159 -imp 'ConvertDefaultLocale' ConvertDefaultLocale kernel32 0 # KernelBase -imp 'ConvertFiberToThread' ConvertFiberToThread kernel32 0 # KernelBase -imp 'ConvertNLSDayOfWeekToWin32DayOfWeek' ConvertNLSDayOfWeekToWin32DayOfWeek kernel32 162 -imp 'ConvertPerformanceCounterToAuxiliaryCounter' ConvertPerformanceCounterToAuxiliaryCounter KernelBase 161 +imp 'ConvertAccessToSecurityDescriptorA' ConvertAccessToSecurityDescriptorA advapi32 1113 imp 'ConvertSDToStringSDDomain' ConvertSDToStringSDDomainW advapi32 1115 -imp 'ConvertSDToStringSDRootDomainA' ConvertSDToStringSDRootDomainA advapi32 1116 imp 'ConvertSDToStringSDRootDomain' ConvertSDToStringSDRootDomainW advapi32 1117 -imp 'ConvertSecurityDescriptorToAccessA' ConvertSecurityDescriptorToAccessA advapi32 1118 -imp 'ConvertSecurityDescriptorToAccessNamedA' ConvertSecurityDescriptorToAccessNamedA advapi32 1119 -imp 'ConvertSecurityDescriptorToAccessNamed' ConvertSecurityDescriptorToAccessNamedW advapi32 1120 +imp 'ConvertSDToStringSDRootDomainA' ConvertSDToStringSDRootDomainA advapi32 1116 imp 'ConvertSecurityDescriptorToAccess' ConvertSecurityDescriptorToAccessW advapi32 1121 -imp 'ConvertSecurityDescriptorToStringSecurityDescriptorA' ConvertSecurityDescriptorToStringSecurityDescriptorA advapi32 1122 +imp 'ConvertSecurityDescriptorToAccessA' ConvertSecurityDescriptorToAccessA advapi32 1118 +imp 'ConvertSecurityDescriptorToAccessNamed' ConvertSecurityDescriptorToAccessNamedW advapi32 1120 +imp 'ConvertSecurityDescriptorToAccessNamedA' ConvertSecurityDescriptorToAccessNamedA advapi32 1119 imp 'ConvertSecurityDescriptorToStringSecurityDescriptor' ConvertSecurityDescriptorToStringSecurityDescriptorW advapi32 1123 -imp 'ConvertSidToStringSidA' ConvertSidToStringSidA advapi32 1124 +imp 'ConvertSecurityDescriptorToStringSecurityDescriptorA' ConvertSecurityDescriptorToStringSecurityDescriptorA advapi32 1122 imp 'ConvertSidToStringSid' ConvertSidToStringSidW advapi32 1125 -imp 'ConvertStringSDToSDDomainA' ConvertStringSDToSDDomainA advapi32 1126 +imp 'ConvertSidToStringSidA' ConvertSidToStringSidA advapi32 1124 imp 'ConvertStringSDToSDDomain' ConvertStringSDToSDDomainW advapi32 1127 -imp 'ConvertStringSDToSDRootDomainA' ConvertStringSDToSDRootDomainA advapi32 1128 +imp 'ConvertStringSDToSDDomainA' ConvertStringSDToSDDomainA advapi32 1126 imp 'ConvertStringSDToSDRootDomain' ConvertStringSDToSDRootDomainW advapi32 1129 -imp 'ConvertStringSecurityDescriptorToSecurityDescriptorA' ConvertStringSecurityDescriptorToSecurityDescriptorA advapi32 1130 +imp 'ConvertStringSDToSDRootDomainA' ConvertStringSDToSDRootDomainA advapi32 1128 imp 'ConvertStringSecurityDescriptorToSecurityDescriptor' ConvertStringSecurityDescriptorToSecurityDescriptorW advapi32 1131 -imp 'ConvertStringSidToSidA' ConvertStringSidToSidA advapi32 1132 +imp 'ConvertStringSecurityDescriptorToSecurityDescriptorA' ConvertStringSecurityDescriptorToSecurityDescriptorA advapi32 1130 imp 'ConvertStringSidToSid' ConvertStringSidToSidW advapi32 1133 -imp 'ConvertSystemTimeToCalDateTime' ConvertSystemTimeToCalDateTime kernel32 163 -imp 'ConvertThreadToFiber' ConvertThreadToFiber kernel32 0 # KernelBase -imp 'ConvertThreadToFiberEx' ConvertThreadToFiberEx kernel32 0 # KernelBase -imp 'ConvertToAutoInheritPrivateObjectSecurity' ConvertToAutoInheritPrivateObjectSecurity advapi32 0 # KernelBase -imp 'CopyAcceleratorTable' CopyAcceleratorTableW user32 1596 -imp 'CopyAcceleratorTableA' CopyAcceleratorTableA user32 1595 -imp 'CopyContext' CopyContext kernel32 0 # KernelBase -imp 'CopyEnhMetaFile' CopyEnhMetaFileW gdi32 1053 -imp 'CopyEnhMetaFileA' CopyEnhMetaFileA gdi32 1052 -imp 'CopyFile2' CopyFile2 kernel32 0 # KernelBase -imp 'CopyFile' CopyFileW kernel32 0 3 # KernelBase -imp 'CopyFileA' CopyFileA kernel32 168 3 -imp 'CopyFileEx' CopyFileExW kernel32 0 # KernelBase -imp 'CopyFileExA' CopyFileExA kernel32 169 -imp 'CopyFileTransacted' CopyFileTransactedW kernel32 172 -imp 'CopyFileTransactedA' CopyFileTransactedA kernel32 171 -imp 'CopyIcon' CopyIcon user32 1597 -imp 'CopyImage' CopyImage user32 1598 -imp 'CopyLZFile' CopyLZFile kernel32 174 -imp 'CopyMetaFileA' CopyMetaFileA gdi32 1054 -imp 'CopyMetaFile' CopyMetaFileW gdi32 1055 -imp 'CopyRect' CopyRect user32 1599 -imp 'CopySid' CopySid advapi32 0 # KernelBase -imp 'CouldMultiUserAppsBehaviorBePossibleForPackage' CouldMultiUserAppsBehaviorBePossibleForPackage KernelBase 171 -imp 'CountClipboardFormats' CountClipboardFormats user32 1600 -imp 'CreateAcceleratorTableA' CreateAcceleratorTableA user32 1601 -imp 'CreateAcceleratorTable' CreateAcceleratorTableW user32 1602 -imp 'CreateActCtxA' CreateActCtxA kernel32 175 -imp 'CreateActCtx' CreateActCtxW kernel32 0 # KernelBase -imp 'CreateActCtxWWorker' CreateActCtxWWorker kernel32 177 -imp 'CreateAppContainerToken' CreateAppContainerToken KernelBase 173 -imp 'CreateAppContainerTokenForUser' CreateAppContainerTokenForUser KernelBase 174 -imp 'CreateBitmap' CreateBitmap gdi32 1056 5 -imp 'CreateBitmapFromDxSurface' CreateBitmapFromDxSurface gdi32 1057 -imp 'CreateBitmapFromDxSurface2' CreateBitmapFromDxSurface2 gdi32 1058 -imp 'CreateBitmapIndirect' CreateBitmapIndirect gdi32 1059 -imp 'CreateBoundaryDescriptorA' CreateBoundaryDescriptorA kernel32 178 -imp 'CreateBoundaryDescriptor' CreateBoundaryDescriptorW kernel32 0 # KernelBase -imp 'CreateBrushIndirect' CreateBrushIndirect gdi32 1060 -imp 'CreateCaret' CreateCaret user32 1603 +imp 'ConvertStringSidToSidA' ConvertStringSidToSidA advapi32 1132 +imp 'ConvertToAutoInheritPrivateObjectSecurity' ConvertToAutoInheritPrivateObjectSecurity advapi32 0 +imp 'CopySid' CopySid advapi32 0 imp 'CreateCodeAuthzLevel' CreateCodeAuthzLevel advapi32 1136 -imp 'CreateColorSpaceA' CreateColorSpaceA gdi32 1061 -imp 'CreateColorSpace' CreateColorSpaceW gdi32 1062 -imp 'CreateCompatibleBitmap' CreateCompatibleBitmap gdi32 1063 3 -imp 'CreateCompatibleDC' CreateCompatibleDC gdi32 1064 1 -imp 'CreateConsoleScreenBuffer' CreateConsoleScreenBuffer kernel32 0 # KernelBase -imp 'CreateCursor' CreateCursor user32 1604 -imp 'CreateDCA' CreateDCA gdi32 1065 -imp 'CreateDCEx' CreateDCExW gdi32 2000 -imp 'CreateDCW' CreateDCW gdi32 1066 -imp 'CreateDCompositionHwndTarget' CreateDCompositionHwndTarget user32 1605 -imp 'CreateDIBPatternBrush' CreateDIBPatternBrush gdi32 1067 -imp 'CreateDIBPatternBrushPt' CreateDIBPatternBrushPt gdi32 1068 -imp 'CreateDIBSection' CreateDIBSection gdi32 1069 6 -imp 'CreateDIBitmap' CreateDIBitmap gdi32 1070 -imp 'CreateDPIScaledDIBSection' CreateDPIScaledDIBSection gdi32 1071 -imp 'CreateDesktopA' CreateDesktopA user32 1606 -imp 'CreateDesktopEx' CreateDesktopExW user32 1608 -imp 'CreateDesktopExA' CreateDesktopExA user32 1607 -imp 'CreateDesktop' CreateDesktopW user32 1609 -imp 'CreateDialogIndirectParamA' CreateDialogIndirectParamA user32 1610 -imp 'CreateDialogIndirectParamAor' CreateDialogIndirectParamAorW user32 1611 -imp 'CreateDialogIndirectParam' CreateDialogIndirectParamW user32 1612 -imp 'CreateDialogParamA' CreateDialogParamA user32 1613 -imp 'CreateDialogParam' CreateDialogParamW user32 1614 -imp 'CreateDirectory' CreateDirectoryW kernel32 0 2 # KernelBase -imp 'CreateDirectoryA' CreateDirectoryA kernel32 0 2 # KernelBase -imp 'CreateDirectoryExA' CreateDirectoryExA kernel32 182 -imp 'CreateDirectoryEx' CreateDirectoryExW kernel32 0 # KernelBase -imp 'CreateDirectoryTransactedA' CreateDirectoryTransactedA kernel32 184 -imp 'CreateDirectoryTransacted' CreateDirectoryTransactedW kernel32 185 -imp 'CreateDiscardableBitmap' CreateDiscardableBitmap gdi32 1072 -imp 'CreateEllipticRgn' CreateEllipticRgn gdi32 1073 -imp 'CreateEllipticRgnIndirect' CreateEllipticRgnIndirect gdi32 1074 -imp 'CreateEnclave' CreateEnclave KernelBase 180 -imp 'CreateEnhMetaFileA' CreateEnhMetaFileA gdi32 1075 -imp 'CreateEnhMetaFile' CreateEnhMetaFileW gdi32 1076 -imp 'CreateEventA' CreateEventA kernel32 0 4 # KernelBase -imp 'CreateEventExA' CreateEventExA kernel32 0 4 # KernelBase -imp 'CreateEventEx' CreateEventExW kernel32 0 4 # KernelBase -imp 'CreateEvent' CreateEventW kernel32 0 4 # KernelBase -imp 'CreateFiber' CreateFiber kernel32 0 # KernelBase -imp 'CreateFiberEx' CreateFiberEx kernel32 0 # KernelBase -imp 'CreateFile' CreateFileW kernel32 0 7 # KernelBase -imp 'CreateFileA' CreateFileA kernel32 0 7 # KernelBase -imp 'CreateFileMappingNuma' CreateFileMappingNumaW kernel32 0 7 # Kernelbase -imp 'CreateFileMappingNumaA' CreateFileMappingNumaA kernel32 198 7 -imp 'CreateFileMapping' CreateFileMappingW kernel32 0 7 # KernelBase -imp 'CreateFileMappingA' CreateFileMappingA kernel32 196 7 -imp 'CreateFileTransacted' CreateFileTransactedW kernel32 202 -imp 'CreateFileTransactedA' CreateFileTransactedA kernel32 201 -imp 'CreateFile2' CreateFile2 kernel32 0 # KernelBase -imp 'CreateFileMappingFromApp' CreateFileMappingFromApp kernel32 0 # KernelBase -imp 'CreateFontA' CreateFontA gdi32 1077 -imp 'CreateFontIndirectA' CreateFontIndirectA gdi32 1078 -imp 'CreateFontIndirectExA' CreateFontIndirectExA gdi32 1079 -imp 'CreateFontIndirectEx' CreateFontIndirectExW gdi32 1080 -imp 'CreateFontIndirect' CreateFontIndirectW gdi32 1081 -imp 'CreateFont' CreateFontW gdi32 1082 -imp 'CreateHalftonePalette' CreateHalftonePalette gdi32 1083 -imp 'CreateHardLink' CreateHardLinkW kernel32 0 3 # KernelBase -imp 'CreateHardLinkA' CreateHardLinkA kernel32 0 3 # KernelBase -imp 'CreateHardLinkTransactedA' CreateHardLinkTransactedA kernel32 205 -imp 'CreateHardLinkTransacted' CreateHardLinkTransactedW kernel32 206 -imp 'CreateHatchBrush' CreateHatchBrush gdi32 1084 -imp 'CreateICA' CreateICA gdi32 1085 -imp 'CreateICW' CreateICW gdi32 1086 -imp 'CreateIcon' CreateIcon user32 1615 -imp 'CreateIconFromResource' CreateIconFromResource user32 1616 -imp 'CreateIconFromResourceEx' CreateIconFromResourceEx user32 1617 -imp 'CreateIconIndirect' CreateIconIndirect user32 1618 1 -imp 'CreateIoCompletionPort' CreateIoCompletionPort kernel32 0 4 # KernelBase -imp 'CreateJobObjectA' CreateJobObjectA kernel32 209 -imp 'CreateJobObject' CreateJobObjectW kernel32 210 -imp 'CreateJobSet' CreateJobSet kernel32 211 -imp 'CreateMDIWindowA' CreateMDIWindowA user32 1619 -imp 'CreateMDIWindow' CreateMDIWindowW user32 1620 -imp 'CreateMailslotA' CreateMailslotA kernel32 212 -imp 'CreateMailslot' CreateMailslotW kernel32 213 -imp 'CreateMemoryResourceNotification' CreateMemoryResourceNotification kernel32 0 # KernelBase -imp 'CreateMenu' CreateMenu user32 1621 0 -imp 'CreateMetaFileA' CreateMetaFileA gdi32 1087 -imp 'CreateMetaFile' CreateMetaFileW gdi32 1088 -imp 'CreateMutex' CreateMutexW kernel32 0 # KernelBase -imp 'CreateMutexA' CreateMutexA kernel32 0 # KernelBase -imp 'CreateMutexEx' CreateMutexExW kernel32 0 # KernelBase -imp 'CreateMutexExA' CreateMutexExA kernel32 0 # KernelBase -imp 'CreateNamedPipe' CreateNamedPipeW kernel32 0 8 # KernelBase -imp 'CreateNamedPipeA' CreateNamedPipeA kernel32 219 8 -imp 'CreateOPMProtectedOutput' CreateOPMProtectedOutput gdi32 1089 -imp 'CreateOPMProtectedOutputs' CreateOPMProtectedOutputs gdi32 1090 -imp 'CreatePalette' CreatePalette gdi32 1091 -imp 'CreatePalmRejectionDelayZone' CreatePalmRejectionDelayZone user32 1503 -imp 'CreatePatternBrush' CreatePatternBrush gdi32 1092 -imp 'CreatePen' CreatePen gdi32 1093 -imp 'CreatePenIndirect' CreatePenIndirect gdi32 1094 -imp 'CreatePipe' CreatePipe kernel32 0 4 # KernelBase -imp 'CreatePolyPolygonRgn' CreatePolyPolygonRgn gdi32 1095 -imp 'CreatePolygonRgn' CreatePolygonRgn gdi32 1096 -imp 'CreatePopupMenu' CreatePopupMenu user32 1622 0 -imp 'CreatePrivateNamespaceA' CreatePrivateNamespaceA kernel32 222 -imp 'CreatePrivateNamespace' CreatePrivateNamespaceW kernel32 0 # KernelBase -imp 'CreatePrivateObjectSecurity' CreatePrivateObjectSecurity advapi32 0 # KernelBase -imp 'CreatePrivateObjectSecurityEx' CreatePrivateObjectSecurityEx advapi32 0 # KernelBase -imp 'CreatePrivateObjectSecurityWithMultipleInheritance' CreatePrivateObjectSecurityWithMultipleInheritance advapi32 0 # KernelBase -imp 'CreateProcessA' CreateProcessA kernel32 0 10 # KernelBase -imp 'CreateProcess' CreateProcessW kernel32 0 10 # KernelBase -imp 'CreateProcessAsUserA' CreateProcessAsUserA advapi32 0 11 # KernelBase -imp 'CreateProcessAsUser' CreateProcessAsUserW advapi32 0 11 # KernelBase -imp 'CreateProcessInternal' CreateProcessInternalW KernelBase 211 -imp 'CreateProcessInternalA' CreateProcessInternalA KernelBase 210 +imp 'CreatePrivateObjectSecurity' CreatePrivateObjectSecurity advapi32 0 +imp 'CreatePrivateObjectSecurityEx' CreatePrivateObjectSecurityEx advapi32 0 +imp 'CreatePrivateObjectSecurityWithMultipleInheritance' CreatePrivateObjectSecurityWithMultipleInheritance advapi32 0 +imp 'CreateProcessAsUser' CreateProcessAsUserW advapi32 0 11 +imp 'CreateProcessAsUserA' CreateProcessAsUserA advapi32 0 11 imp 'CreateProcessWithLogon' CreateProcessWithLogonW advapi32 1142 imp 'CreateProcessWithToken' CreateProcessWithTokenW advapi32 1143 -imp 'CreateRectRgn' CreateRectRgn gdi32 1097 4 -imp 'CreateRectRgnIndirect' CreateRectRgnIndirect gdi32 1098 -imp 'CreateRemoteThread' CreateRemoteThread kernel32 0 # KernelBase -imp 'CreateRemoteThreadEx' CreateRemoteThreadEx kernel32 0 # KernelBase -imp 'CreateRestrictedToken' CreateRestrictedToken advapi32 0 # KernelBase -imp 'CreateRoundRectRgn' CreateRoundRectRgn gdi32 1099 -imp 'CreateScalableFontResourceA' CreateScalableFontResourceA gdi32 1100 -imp 'CreateScalableFontResource' CreateScalableFontResourceW gdi32 1101 -imp 'CreateSemaphoreA' CreateSemaphoreA kernel32 232 -imp 'CreateSemaphoreExA' CreateSemaphoreExA kernel32 233 -imp 'CreateSemaphoreEx' CreateSemaphoreExW kernel32 0 # KernelBase -imp 'CreateSemaphore' CreateSemaphoreW kernel32 0 # KernelBase +imp 'CreateRestrictedToken' CreateRestrictedToken advapi32 0 +imp 'CreateService' CreateServiceW advapi32 1147 imp 'CreateServiceA' CreateServiceA advapi32 1145 imp 'CreateServiceEx' CreateServiceEx advapi32 1146 -imp 'CreateService' CreateServiceW advapi32 1147 -imp 'CreateSessionMappedDIBSection' CreateSessionMappedDIBSection gdi32 1102 -imp 'CreateSolidBrush' CreateSolidBrush gdi32 1103 -imp 'CreateStateAtom' CreateStateAtom KernelBase 218 -imp 'CreateStateChangeNotification' CreateStateChangeNotification KernelBase 219 -imp 'CreateStateContainer' CreateStateContainer KernelBase 220 -imp 'CreateStateLock' CreateStateLock KernelBase 221 -imp 'CreateStateSubcontainer' CreateStateSubcontainer KernelBase 222 -imp 'CreateStorageItemFromPath_FullTrustCaller' CreateStorageItemFromPath_FullTrustCaller shell32 935 -imp 'CreateStorageItemFromPath_FullTrustCaller_ForPackage' CreateStorageItemFromPath_FullTrustCaller_ForPackage shell32 936 -imp 'CreateStorageItemFromPath_PartialTrustCaller' CreateStorageItemFromPath_PartialTrustCaller shell32 920 -imp 'CreateStorageItemFromShellItem_FullTrustCaller' CreateStorageItemFromShellItem_FullTrustCaller shell32 921 -imp 'CreateStorageItemFromShellItem_FullTrustCaller_ForPackage' CreateStorageItemFromShellItem_FullTrustCaller_ForPackage shell32 925 -imp 'CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle' CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle shell32 929 -imp 'CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage' CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage shell32 931 -imp 'CreateSymbolicLink' CreateSymbolicLinkW kernel32 0 3 # KernelBase -imp 'CreateSymbolicLinkA' CreateSymbolicLinkA kernel32 0 3 # KernelBase -imp 'CreateSymbolicLinkTransactedA' CreateSymbolicLinkTransactedA kernel32 237 -imp 'CreateSymbolicLinkTransacted' CreateSymbolicLinkTransactedW kernel32 238 -imp 'CreateSystemThreads' CreateSystemThreads user32 1623 -imp 'CreateTapePartition' CreateTapePartition kernel32 240 -imp 'CreateThread' CreateThread kernel32 0 6 # KernelBase -imp 'CreateThreadpool' CreateThreadpool kernel32 0 # KernelBase -imp 'CreateThreadpoolCleanupGroup' CreateThreadpoolCleanupGroup kernel32 0 # KernelBase -imp 'CreateThreadpoolIo' CreateThreadpoolIo kernel32 0 # KernelBase -imp 'CreateThreadpoolTimer' CreateThreadpoolTimer kernel32 0 # KernelBase -imp 'CreateThreadpoolWait' CreateThreadpoolWait kernel32 0 # KernelBase -imp 'CreateThreadpoolWork' CreateThreadpoolWork kernel32 0 # KernelBase -imp 'CreateTimerQueue' CreateTimerQueue kernel32 0 # KernelBase -imp 'CreateTimerQueueTimer' CreateTimerQueueTimer kernel32 0 # KernelBase -imp 'CreateToolhelp32Snapshot' CreateToolhelp32Snapshot kernel32 250 -imp 'CreateUmsCompletionList' CreateUmsCompletionList kernel32 251 -imp 'CreateUmsThreadContext' CreateUmsThreadContext kernel32 252 -imp 'CreateWaitableTimerA' CreateWaitableTimerA kernel32 253 3 -imp 'CreateWaitableTimerExA' CreateWaitableTimerExA kernel32 254 4 -imp 'CreateWaitableTimerEx' CreateWaitableTimerExW kernel32 0 4 # KernelBase -imp 'CreateWaitableTimer' CreateWaitableTimerW kernel32 0 3 # KernelBase -imp 'CreateWellKnownSid' CreateWellKnownSid advapi32 0 # KernelBase -imp 'CreateWindowEx' CreateWindowExW user32 1625 12 -imp 'CreateWindowExA' CreateWindowExA user32 1624 12 -imp 'CreateWindowInBand' CreateWindowInBand user32 1626 -imp 'CreateWindowInBandEx' CreateWindowInBandEx user32 1627 -imp 'CreateWindowIndirect' CreateWindowIndirect user32 1628 -imp 'CreateWindowStationA' CreateWindowStationA user32 1629 -imp 'CreateWindowStation' CreateWindowStationW user32 1630 +imp 'CreateWellKnownSid' CreateWellKnownSid advapi32 0 imp 'CredBackupCredentials' CredBackupCredentials advapi32 1150 -imp 'CredDeleteA' CredDeleteA advapi32 1151 imp 'CredDelete' CredDeleteW advapi32 1152 +imp 'CredDeleteA' CredDeleteA advapi32 1151 imp 'CredEncryptAndMarshalBinaryBlob' CredEncryptAndMarshalBinaryBlob advapi32 1153 -imp 'CredEnumerateA' CredEnumerateA advapi32 1154 imp 'CredEnumerate' CredEnumerateW advapi32 1155 -imp 'CredFindBestCredentialA' CredFindBestCredentialA advapi32 1156 +imp 'CredEnumerateA' CredEnumerateA advapi32 1154 imp 'CredFindBestCredential' CredFindBestCredentialW advapi32 1157 +imp 'CredFindBestCredentialA' CredFindBestCredentialA advapi32 1156 imp 'CredFree' CredFree advapi32 1158 imp 'CredGetSessionTypes' CredGetSessionTypes advapi32 1159 -imp 'CredGetTargetInfoA' CredGetTargetInfoA advapi32 1160 imp 'CredGetTargetInfo' CredGetTargetInfoW advapi32 1161 -imp 'CredIsMarshaledCredentialA' CredIsMarshaledCredentialA advapi32 1162 +imp 'CredGetTargetInfoA' CredGetTargetInfoA advapi32 1160 imp 'CredIsMarshaledCredential' CredIsMarshaledCredentialW advapi32 1163 -imp 'CredIsProtectedA' CredIsProtectedA advapi32 1164 +imp 'CredIsMarshaledCredentialA' CredIsMarshaledCredentialA advapi32 1162 imp 'CredIsProtected' CredIsProtectedW advapi32 1165 -imp 'CredMarshalCredentialA' CredMarshalCredentialA advapi32 1166 +imp 'CredIsProtectedA' CredIsProtectedA advapi32 1164 imp 'CredMarshalCredential' CredMarshalCredentialW advapi32 1167 +imp 'CredMarshalCredentialA' CredMarshalCredentialA advapi32 1166 imp 'CredProfileLoaded' CredProfileLoaded advapi32 1168 imp 'CredProfileLoadedEx' CredProfileLoadedEx advapi32 1169 imp 'CredProfileUnloaded' CredProfileUnloaded advapi32 1170 -imp 'CredProtectA' CredProtectA advapi32 1171 imp 'CredProtect' CredProtectW advapi32 1172 +imp 'CredProtectA' CredProtectA advapi32 1171 +imp 'CredRead' CredReadW advapi32 1177 imp 'CredReadA' CredReadA advapi32 1173 imp 'CredReadByTokenHandle' CredReadByTokenHandle advapi32 1174 -imp 'CredReadDomainCredentialsA' CredReadDomainCredentialsA advapi32 1175 imp 'CredReadDomainCredentials' CredReadDomainCredentialsW advapi32 1176 -imp 'CredRead' CredReadW advapi32 1177 -imp 'CredRenameA' CredRenameA advapi32 1178 +imp 'CredReadDomainCredentialsA' CredReadDomainCredentialsA advapi32 1175 imp 'CredRename' CredRenameW advapi32 1179 +imp 'CredRenameA' CredRenameA advapi32 1178 imp 'CredRestoreCredentials' CredRestoreCredentials advapi32 1180 -imp 'CredUnmarshalCredentialA' CredUnmarshalCredentialA advapi32 1181 imp 'CredUnmarshalCredential' CredUnmarshalCredentialW advapi32 1182 -imp 'CredUnprotectA' CredUnprotectA advapi32 1183 +imp 'CredUnmarshalCredentialA' CredUnmarshalCredentialA advapi32 1181 imp 'CredUnprotect' CredUnprotectW advapi32 1184 -imp 'CredWriteA' CredWriteA advapi32 1185 -imp 'CredWriteDomainCredentialsA' CredWriteDomainCredentialsA advapi32 1186 -imp 'CredWriteDomainCredentials' CredWriteDomainCredentialsW advapi32 1187 +imp 'CredUnprotectA' CredUnprotectA advapi32 1183 imp 'CredWrite' CredWriteW advapi32 1188 +imp 'CredWriteA' CredWriteA advapi32 1185 +imp 'CredWriteDomainCredentials' CredWriteDomainCredentialsW advapi32 1187 +imp 'CredWriteDomainCredentialsA' CredWriteDomainCredentialsA advapi32 1186 imp 'CredpConvertCredential' CredpConvertCredential advapi32 1189 imp 'CredpConvertOneCredentialSize' CredpConvertOneCredentialSize advapi32 1190 imp 'CredpConvertTargetInfo' CredpConvertTargetInfo advapi32 1191 imp 'CredpDecodeCredential' CredpDecodeCredential advapi32 1192 imp 'CredpEncodeCredential' CredpEncodeCredential advapi32 1193 imp 'CredpEncodeSecret' CredpEncodeSecret advapi32 1194 -imp 'CryptAcquireContextA' CryptAcquireContextA advapi32 1195 imp 'CryptAcquireContext' CryptAcquireContextW advapi32 1196 +imp 'CryptAcquireContextA' CryptAcquireContextA advapi32 1195 imp 'CryptContextAddRef' CryptContextAddRef advapi32 1197 imp 'CryptCreateHash' CryptCreateHash advapi32 1198 imp 'CryptDecrypt' CryptDecrypt advapi32 1199 @@ -778,15 +1576,15 @@ imp 'CryptDestroyKey' CryptDestroyKey advapi32 1202 imp 'CryptDuplicateHash' CryptDuplicateHash advapi32 1203 imp 'CryptDuplicateKey' CryptDuplicateKey advapi32 1204 imp 'CryptEncrypt' CryptEncrypt advapi32 1205 -imp 'CryptEnumProviderTypesA' CryptEnumProviderTypesA advapi32 1206 imp 'CryptEnumProviderTypes' CryptEnumProviderTypesW advapi32 1207 -imp 'CryptEnumProvidersA' CryptEnumProvidersA advapi32 1208 +imp 'CryptEnumProviderTypesA' CryptEnumProviderTypesA advapi32 1206 imp 'CryptEnumProviders' CryptEnumProvidersW advapi32 1209 +imp 'CryptEnumProvidersA' CryptEnumProvidersA advapi32 1208 imp 'CryptExportKey' CryptExportKey advapi32 1210 imp 'CryptGenKey' CryptGenKey advapi32 1211 imp 'CryptGenRandom' CryptGenRandom advapi32 1212 -imp 'CryptGetDefaultProviderA' CryptGetDefaultProviderA advapi32 1213 imp 'CryptGetDefaultProvider' CryptGetDefaultProviderW advapi32 1214 +imp 'CryptGetDefaultProviderA' CryptGetDefaultProviderA advapi32 1213 imp 'CryptGetHashParam' CryptGetHashParam advapi32 1215 imp 'CryptGetKeyParam' CryptGetKeyParam advapi32 1216 imp 'CryptGetProvParam' CryptGetProvParam advapi32 1217 @@ -798,31 +1596,1443 @@ imp 'CryptReleaseContext' CryptReleaseContext advapi32 1222 imp 'CryptSetHashParam' CryptSetHashParam advapi32 1223 imp 'CryptSetKeyParam' CryptSetKeyParam advapi32 1224 imp 'CryptSetProvParam' CryptSetProvParam advapi32 1225 -imp 'CryptSetProviderA' CryptSetProviderA advapi32 1226 -imp 'CryptSetProviderExA' CryptSetProviderExA advapi32 1227 -imp 'CryptSetProviderEx' CryptSetProviderExW advapi32 1228 imp 'CryptSetProvider' CryptSetProviderW advapi32 1229 -imp 'CryptSignHashA' CryptSignHashA advapi32 1230 +imp 'CryptSetProviderA' CryptSetProviderA advapi32 1226 +imp 'CryptSetProviderEx' CryptSetProviderExW advapi32 1228 +imp 'CryptSetProviderExA' CryptSetProviderExA advapi32 1227 imp 'CryptSignHash' CryptSignHashW advapi32 1231 -imp 'CryptVerifySignatureA' CryptVerifySignatureA advapi32 1232 +imp 'CryptSignHashA' CryptSignHashA advapi32 1230 imp 'CryptVerifySignature' CryptVerifySignatureW advapi32 1233 -imp 'CsrAllocateCaptureBuffer' CsrAllocateCaptureBuffer ntdll 28 -imp 'CsrAllocateMessagePointer' CsrAllocateMessagePointer ntdll 29 +imp 'CryptVerifySignatureA' CryptVerifySignatureA advapi32 1232 +imp 'DecryptFile' DecryptFileW advapi32 1236 +imp 'DecryptFileA' DecryptFileA advapi32 1235 +imp 'DeleteAce' DeleteAce advapi32 0 +imp 'DeleteService' DeleteService advapi32 1238 +imp 'DeregisterEventSource' DeregisterEventSource advapi32 1239 1 +imp 'DestroyPrivateObjectSecurity' DestroyPrivateObjectSecurity advapi32 0 +imp 'DuplicateEncryptionInfoFile' DuplicateEncryptionInfoFile advapi32 1241 +imp 'DuplicateToken' DuplicateToken advapi32 0 3 +imp 'DuplicateTokenEx' DuplicateTokenEx advapi32 0 6 +imp 'ElfBackupEventLogFile' ElfBackupEventLogFileW advapi32 1245 +imp 'ElfBackupEventLogFileA' ElfBackupEventLogFileA advapi32 1244 +imp 'ElfChangeNotify' ElfChangeNotify advapi32 1246 +imp 'ElfClearEventLogFile' ElfClearEventLogFileW advapi32 1248 +imp 'ElfClearEventLogFileA' ElfClearEventLogFileA advapi32 1247 +imp 'ElfCloseEventLog' ElfCloseEventLog advapi32 1249 +imp 'ElfDeregisterEventSource' ElfDeregisterEventSource advapi32 1250 +imp 'ElfFlushEventLog' ElfFlushEventLog advapi32 1251 +imp 'ElfNumberOfRecords' ElfNumberOfRecords advapi32 1252 +imp 'ElfOldestRecord' ElfOldestRecord advapi32 1253 +imp 'ElfOpenBackupEventLog' ElfOpenBackupEventLogW advapi32 1255 +imp 'ElfOpenBackupEventLogA' ElfOpenBackupEventLogA advapi32 1254 +imp 'ElfOpenEventLog' ElfOpenEventLogW advapi32 1257 +imp 'ElfOpenEventLogA' ElfOpenEventLogA advapi32 1256 +imp 'ElfReadEventLog' ElfReadEventLogW advapi32 1259 +imp 'ElfReadEventLogA' ElfReadEventLogA advapi32 1258 +imp 'ElfRegisterEventSource' ElfRegisterEventSourceW advapi32 1261 +imp 'ElfRegisterEventSourceA' ElfRegisterEventSourceA advapi32 1260 +imp 'ElfReportEvent' ElfReportEventW advapi32 1264 +imp 'ElfReportEventA' ElfReportEventA advapi32 1262 +imp 'ElfReportEventAndSource' ElfReportEventAndSourceW advapi32 1263 +imp 'EnableTrace' EnableTrace advapi32 1265 +imp 'EnableTraceEx' EnableTraceEx advapi32 1266 +imp 'EnableTraceEx2' EnableTraceEx2 advapi32 1267 +imp 'EncryptFile' EncryptFileW advapi32 1269 +imp 'EncryptFileA' EncryptFileA advapi32 1268 +imp 'EncryptedFileKeyInfo' EncryptedFileKeyInfo advapi32 1270 +imp 'EncryptionDisable' EncryptionDisable advapi32 1271 +imp 'EnumDependentServices' EnumDependentServicesW advapi32 1273 +imp 'EnumDependentServicesA' EnumDependentServicesA advapi32 1272 +imp 'EnumServiceGroup' EnumServiceGroupW advapi32 1275 +imp 'EnumServicesStatus' EnumServicesStatusW advapi32 1279 +imp 'EnumServicesStatusA' EnumServicesStatusA advapi32 1276 +imp 'EnumServicesStatusEx' EnumServicesStatusExW advapi32 1278 +imp 'EnumServicesStatusExA' EnumServicesStatusExA advapi32 1277 +imp 'EnumerateTraceGuids' EnumerateTraceGuids advapi32 1280 +imp 'EnumerateTraceGuidsEx' EnumerateTraceGuidsEx advapi32 1281 +imp 'EqualDomainSid' EqualDomainSid advapi32 0 +imp 'EqualPrefixSid' EqualPrefixSid advapi32 0 +imp 'EqualSid' EqualSid advapi32 0 +imp 'EventAccessControl' EventAccessControl advapi32 1285 +imp 'EventAccessQuery' EventAccessQuery advapi32 1286 +imp 'EventAccessRemove' EventAccessRemove advapi32 1287 +imp 'FileEncryptionStatus' FileEncryptionStatusW advapi32 1301 +imp 'FileEncryptionStatusA' FileEncryptionStatusA advapi32 1300 +imp 'FindFirstFreeAce' FindFirstFreeAce advapi32 0 +imp 'FlushEfsCache' FlushEfsCache advapi32 1303 +imp 'FlushTrace' FlushTraceW advapi32 1305 +imp 'FlushTraceA' FlushTraceA advapi32 1304 +imp 'FreeEncryptedFileKeyInfo' FreeEncryptedFileKeyInfo advapi32 1306 +imp 'FreeEncryptedFileMetadata' FreeEncryptedFileMetadata advapi32 1307 +imp 'FreeEncryptionCertificateHashList' FreeEncryptionCertificateHashList advapi32 1308 +imp 'FreeInheritedFromArray' FreeInheritedFromArray advapi32 1309 +imp 'FreeSid' FreeSid advapi32 0 +imp 'GetAccessPermissionsForObject' GetAccessPermissionsForObjectW advapi32 1312 +imp 'GetAccessPermissionsForObjectA' GetAccessPermissionsForObjectA advapi32 1311 +imp 'GetAce' GetAce advapi32 0 +imp 'GetAclInformation' GetAclInformation advapi32 0 +imp 'GetAuditedPermissionsFromAcl' GetAuditedPermissionsFromAclW advapi32 1316 +imp 'GetAuditedPermissionsFromAclA' GetAuditedPermissionsFromAclA advapi32 1315 +imp 'GetCurrentHwProfile' GetCurrentHwProfileW advapi32 1318 +imp 'GetCurrentHwProfileA' GetCurrentHwProfileA advapi32 1317 +imp 'GetEffectiveRightsFromAcl' GetEffectiveRightsFromAclW advapi32 1321 +imp 'GetEffectiveRightsFromAclA' GetEffectiveRightsFromAclA advapi32 1320 +imp 'GetEncryptedFileMetadata' GetEncryptedFileMetadata advapi32 1322 +imp 'GetEventLogInformation' GetEventLogInformation advapi32 1323 +imp 'GetExplicitEntriesFromAcl' GetExplicitEntriesFromAclW advapi32 1325 +imp 'GetExplicitEntriesFromAclA' GetExplicitEntriesFromAclA advapi32 1324 +imp 'GetFileSecurity' GetFileSecurityW advapi32 0 5 +imp 'GetFileSecurityA' GetFileSecurityA advapi32 1326 5 +imp 'GetInformationCodeAuthzLevel' GetInformationCodeAuthzLevelW advapi32 1328 +imp 'GetInformationCodeAuthzPolicy' GetInformationCodeAuthzPolicyW advapi32 1329 +imp 'GetInheritanceSource' GetInheritanceSourceW advapi32 1331 +imp 'GetInheritanceSourceA' GetInheritanceSourceA advapi32 1330 +imp 'GetKernelObjectSecurity' GetKernelObjectSecurity advapi32 0 +imp 'GetLengthSid' GetLengthSid advapi32 0 +imp 'GetLocalManagedApplicationData' GetLocalManagedApplicationData advapi32 1334 +imp 'GetLocalManagedApplications' GetLocalManagedApplications advapi32 1335 +imp 'GetManagedApplicationCategories' GetManagedApplicationCategories advapi32 1336 +imp 'GetManagedApplications' GetManagedApplications advapi32 1337 +imp 'GetMultipleTrustee' GetMultipleTrusteeW advapi32 1341 +imp 'GetMultipleTrusteeA' GetMultipleTrusteeA advapi32 1338 +imp 'GetMultipleTrusteeOperation' GetMultipleTrusteeOperationW advapi32 1340 +imp 'GetMultipleTrusteeOperationA' GetMultipleTrusteeOperationA advapi32 1339 +imp 'GetNamedSecurityInfo' GetNamedSecurityInfoW advapi32 1345 +imp 'GetNamedSecurityInfoA' GetNamedSecurityInfoA advapi32 1342 +imp 'GetNamedSecurityInfoEx' GetNamedSecurityInfoExW advapi32 1344 +imp 'GetNamedSecurityInfoExA' GetNamedSecurityInfoExA advapi32 1343 +imp 'GetNumberOfEventLogRecords' GetNumberOfEventLogRecords advapi32 1346 +imp 'GetOldestEventLogRecord' GetOldestEventLogRecord advapi32 1347 +imp 'GetOverlappedAccessResults' GetOverlappedAccessResults advapi32 1348 +imp 'GetPrivateObjectSecurity' GetPrivateObjectSecurity advapi32 0 +imp 'GetSecurityDescriptorControl' GetSecurityDescriptorControl advapi32 0 +imp 'GetSecurityDescriptorDacl' GetSecurityDescriptorDacl advapi32 0 +imp 'GetSecurityDescriptorGroup' GetSecurityDescriptorGroup advapi32 0 +imp 'GetSecurityDescriptorLength' GetSecurityDescriptorLength advapi32 0 +imp 'GetSecurityDescriptorOwner' GetSecurityDescriptorOwner advapi32 0 +imp 'GetSecurityDescriptorRMControl' GetSecurityDescriptorRMControl advapi32 0 +imp 'GetSecurityDescriptorSacl' GetSecurityDescriptorSacl advapi32 0 +imp 'GetSecurityInfo' GetSecurityInfo advapi32 1357 +imp 'GetSecurityInfoEx' GetSecurityInfoExW advapi32 1359 +imp 'GetSecurityInfoExA' GetSecurityInfoExA advapi32 1358 +imp 'GetServiceDisplayName' GetServiceDisplayNameW advapi32 1361 +imp 'GetServiceDisplayNameA' GetServiceDisplayNameA advapi32 1360 +imp 'GetServiceKeyName' GetServiceKeyNameW advapi32 1363 +imp 'GetServiceKeyNameA' GetServiceKeyNameA advapi32 1362 +imp 'GetSidIdentifierAuthority' GetSidIdentifierAuthority advapi32 0 +imp 'GetSidLengthRequired' GetSidLengthRequired advapi32 0 +imp 'GetSidSubAuthority' GetSidSubAuthority advapi32 0 +imp 'GetSidSubAuthorityCount' GetSidSubAuthorityCount advapi32 0 +imp 'GetStringConditionFromBinary' GetStringConditionFromBinary advapi32 1368 +imp 'GetThreadWaitChain' GetThreadWaitChain advapi32 1369 +imp 'GetTokenInformation' GetTokenInformation advapi32 0 +imp 'GetTrusteeForm' GetTrusteeFormW advapi32 1375 +imp 'GetTrusteeFormA' GetTrusteeFormA advapi32 1374 +imp 'GetTrusteeName' GetTrusteeNameW advapi32 1377 +imp 'GetTrusteeNameA' GetTrusteeNameA advapi32 1376 +imp 'GetTrusteeType' GetTrusteeTypeW advapi32 1379 +imp 'GetTrusteeTypeA' GetTrusteeTypeA advapi32 1378 +imp 'GetUserName' GetUserNameW advapi32 1381 2 +imp 'GetUserNameA' GetUserNameA advapi32 1380 2 +imp 'GetWindowsAccountDomainSid' GetWindowsAccountDomainSid advapi32 0 +imp 'I_ScGetCurrentGroupState' I_ScGetCurrentGroupStateW advapi32 1001 +imp 'I_ScReparseServiceDatabase' I_ScReparseServiceDatabase advapi32 1388 +imp 'I_ScSetServiceBits' I_ScSetServiceBitsW advapi32 1392 +imp 'I_ScSetServiceBitsA' I_ScSetServiceBitsA advapi32 1391 +imp 'IdentifyCodeAuthzLevel' IdentifyCodeAuthzLevelW advapi32 1394 +imp 'ImpersonateAnonymousToken' ImpersonateAnonymousToken advapi32 0 +imp 'ImpersonateLoggedOnUser' ImpersonateLoggedOnUser advapi32 0 +imp 'ImpersonateNamedPipeClient' ImpersonateNamedPipeClient advapi32 0 +imp 'ImpersonateSelf' ImpersonateSelf advapi32 0 1 +imp 'InitializeAcl' InitializeAcl advapi32 0 +imp 'InitializeSecurityDescriptor' InitializeSecurityDescriptor advapi32 0 +imp 'InitializeSid' InitializeSid advapi32 0 +imp 'InitiateShutdown' InitiateShutdownW advapi32 1403 5 +imp 'InitiateShutdownA' InitiateShutdownA advapi32 1402 5 +imp 'InitiateSystemShutdown' InitiateSystemShutdownW advapi32 1407 +imp 'InitiateSystemShutdownA' InitiateSystemShutdownA advapi32 1404 +imp 'InitiateSystemShutdownEx' InitiateSystemShutdownExW advapi32 1406 +imp 'InitiateSystemShutdownExA' InitiateSystemShutdownExA advapi32 1405 +imp 'InstallApplication' InstallApplication advapi32 1408 +imp 'IsTextUnicode' IsTextUnicode advapi32 1409 +imp 'IsTokenRestricted' IsTokenRestricted advapi32 0 +imp 'IsTokenUntrusted' IsTokenUntrusted advapi32 1411 +imp 'IsValidAcl' IsValidAcl advapi32 0 +imp 'IsValidSecurityDescriptor' IsValidSecurityDescriptor advapi32 0 +imp 'IsValidSid' IsValidSid advapi32 0 +imp 'IsWellKnownSid' IsWellKnownSid advapi32 0 +imp 'LockServiceDatabase' LockServiceDatabase advapi32 1417 +imp 'LogonUser' LogonUserW advapi32 1422 +imp 'LogonUserA' LogonUserA advapi32 1418 +imp 'LogonUserEx' LogonUserExW advapi32 1421 +imp 'LogonUserExA' LogonUserExA advapi32 1419 +imp 'LogonUserExEx' LogonUserExExW advapi32 1420 +imp 'LookupAccountName' LookupAccountNameW advapi32 1424 +imp 'LookupAccountNameA' LookupAccountNameA advapi32 1423 +imp 'LookupAccountSid' LookupAccountSidW advapi32 1426 +imp 'LookupAccountSidA' LookupAccountSidA advapi32 1425 +imp 'LookupPrivilegeDisplayName' LookupPrivilegeDisplayNameW advapi32 1428 +imp 'LookupPrivilegeDisplayNameA' LookupPrivilegeDisplayNameA advapi32 1427 +imp 'LookupPrivilegeName' LookupPrivilegeNameW advapi32 1430 +imp 'LookupPrivilegeNameA' LookupPrivilegeNameA advapi32 1429 +imp 'LookupPrivilegeValue' LookupPrivilegeValueW advapi32 1432 3 +imp 'LookupPrivilegeValueA' LookupPrivilegeValueA advapi32 1431 3 +imp 'LookupSecurityDescriptorParts' LookupSecurityDescriptorPartsW advapi32 1434 +imp 'LookupSecurityDescriptorPartsA' LookupSecurityDescriptorPartsA advapi32 1433 +imp 'LsaAddAccountRights' LsaAddAccountRights advapi32 1435 +imp 'LsaAddPrivilegesToAccount' LsaAddPrivilegesToAccount advapi32 1436 +imp 'LsaClearAuditLog' LsaClearAuditLog advapi32 1437 +imp 'LsaClose' LsaClose advapi32 1438 +imp 'LsaCreateAccount' LsaCreateAccount advapi32 1439 +imp 'LsaCreateSecret' LsaCreateSecret advapi32 1440 +imp 'LsaCreateTrustedDomain' LsaCreateTrustedDomain advapi32 1441 +imp 'LsaCreateTrustedDomainEx' LsaCreateTrustedDomainEx advapi32 1442 +imp 'LsaDelete' LsaDelete advapi32 1443 +imp 'LsaDeleteTrustedDomain' LsaDeleteTrustedDomain advapi32 1444 +imp 'LsaEnumerateAccountRights' LsaEnumerateAccountRights advapi32 1445 +imp 'LsaEnumerateAccounts' LsaEnumerateAccounts advapi32 1446 +imp 'LsaEnumerateAccountsWithUserRight' LsaEnumerateAccountsWithUserRight advapi32 1447 +imp 'LsaEnumeratePrivileges' LsaEnumeratePrivileges advapi32 1448 +imp 'LsaEnumeratePrivilegesOfAccount' LsaEnumeratePrivilegesOfAccount advapi32 1449 +imp 'LsaEnumerateTrustedDomains' LsaEnumerateTrustedDomains advapi32 1450 +imp 'LsaEnumerateTrustedDomainsEx' LsaEnumerateTrustedDomainsEx advapi32 1451 +imp 'LsaFreeMemory' LsaFreeMemory advapi32 1452 +imp 'LsaGetAppliedCAPIDs' LsaGetAppliedCAPIDs advapi32 1453 +imp 'LsaGetQuotasForAccount' LsaGetQuotasForAccount advapi32 1454 +imp 'LsaGetRemoteUserName' LsaGetRemoteUserName advapi32 1455 +imp 'LsaGetSystemAccessAccount' LsaGetSystemAccessAccount advapi32 1456 +imp 'LsaGetUserName' LsaGetUserName advapi32 1457 +imp 'LsaICLookupNames' LsaICLookupNames advapi32 1458 +imp 'LsaICLookupNamesWithCreds' LsaICLookupNamesWithCreds advapi32 1459 +imp 'LsaICLookupSids' LsaICLookupSids advapi32 1460 +imp 'LsaICLookupSidsWithCreds' LsaICLookupSidsWithCreds advapi32 1461 +imp 'LsaLookupNames' LsaLookupNames advapi32 1462 +imp 'LsaLookupNames2' LsaLookupNames2 advapi32 1463 +imp 'LsaLookupPrivilegeDisplayName' LsaLookupPrivilegeDisplayName advapi32 1464 +imp 'LsaLookupPrivilegeName' LsaLookupPrivilegeName advapi32 1465 +imp 'LsaLookupPrivilegeValue' LsaLookupPrivilegeValue advapi32 1466 +imp 'LsaLookupSids' LsaLookupSids advapi32 1467 +imp 'LsaLookupSids2' LsaLookupSids2 advapi32 1468 +imp 'LsaManageSidNameMapping' LsaManageSidNameMapping advapi32 1469 +imp 'LsaNtStatusToWinError' LsaNtStatusToWinError advapi32 1470 +imp 'LsaOpenAccount' LsaOpenAccount advapi32 1471 +imp 'LsaOpenPolicy' LsaOpenPolicy advapi32 1472 +imp 'LsaOpenPolicySce' LsaOpenPolicySce advapi32 1473 +imp 'LsaOpenSecret' LsaOpenSecret advapi32 1474 +imp 'LsaOpenTrustedDomain' LsaOpenTrustedDomain advapi32 1475 +imp 'LsaOpenTrustedDomainByName' LsaOpenTrustedDomainByName advapi32 1476 +imp 'LsaQueryCAPs' LsaQueryCAPs advapi32 1477 +imp 'LsaQueryDomainInformationPolicy' LsaQueryDomainInformationPolicy advapi32 1478 +imp 'LsaQueryForestTrustInformation' LsaQueryForestTrustInformation advapi32 1479 +imp 'LsaQueryInfoTrustedDomain' LsaQueryInfoTrustedDomain advapi32 1480 +imp 'LsaQueryInformationPolicy' LsaQueryInformationPolicy advapi32 1481 +imp 'LsaQuerySecret' LsaQuerySecret advapi32 1482 +imp 'LsaQuerySecurityObject' LsaQuerySecurityObject advapi32 1483 +imp 'LsaQueryTrustedDomainInfo' LsaQueryTrustedDomainInfo advapi32 1484 +imp 'LsaQueryTrustedDomainInfoByName' LsaQueryTrustedDomainInfoByName advapi32 1485 +imp 'LsaRemoveAccountRights' LsaRemoveAccountRights advapi32 1486 +imp 'LsaRemovePrivilegesFromAccount' LsaRemovePrivilegesFromAccount advapi32 1487 +imp 'LsaRetrievePrivateData' LsaRetrievePrivateData advapi32 1488 +imp 'LsaSetCAPs' LsaSetCAPs advapi32 1489 +imp 'LsaSetDomainInformationPolicy' LsaSetDomainInformationPolicy advapi32 1490 +imp 'LsaSetForestTrustInformation' LsaSetForestTrustInformation advapi32 1491 +imp 'LsaSetInformationPolicy' LsaSetInformationPolicy advapi32 1492 +imp 'LsaSetInformationTrustedDomain' LsaSetInformationTrustedDomain advapi32 1493 +imp 'LsaSetQuotasForAccount' LsaSetQuotasForAccount advapi32 1494 +imp 'LsaSetSecret' LsaSetSecret advapi32 1495 +imp 'LsaSetSecurityObject' LsaSetSecurityObject advapi32 1496 +imp 'LsaSetSystemAccessAccount' LsaSetSystemAccessAccount advapi32 1497 +imp 'LsaSetTrustedDomainInfoByName' LsaSetTrustedDomainInfoByName advapi32 1498 +imp 'LsaSetTrustedDomainInformation' LsaSetTrustedDomainInformation advapi32 1499 +imp 'LsaStorePrivateData' LsaStorePrivateData advapi32 1500 +imp 'MIDL_user_free_Ext' MIDL_user_free_Ext advapi32 1507 +imp 'MSChapSrvChangePassword' MSChapSrvChangePassword advapi32 1508 +imp 'MSChapSrvChangePassword2' MSChapSrvChangePassword2 advapi32 1509 +imp 'MakeAbsoluteSD' MakeAbsoluteSD advapi32 0 +imp 'MakeSelfRelativeSD' MakeSelfRelativeSD advapi32 0 +imp 'MapGenericMask' MapGenericMask advapi32 0 2 +imp 'NotifyBootConfigStatus' NotifyBootConfigStatus advapi32 1514 +imp 'NotifyChangeEventLog' NotifyChangeEventLog advapi32 1515 +imp 'NotifyServiceStatusChange' NotifyServiceStatusChangeW advapi32 1518 +imp 'NotifyServiceStatusChangeA' NotifyServiceStatusChangeA advapi32 1517 +imp 'NpGetUserName' NpGetUserName advapi32 1519 +imp 'ObjectCloseAuditAlarm' ObjectCloseAuditAlarmW advapi32 0 +imp 'ObjectCloseAuditAlarmA' ObjectCloseAuditAlarmA advapi32 1520 +imp 'ObjectDeleteAuditAlarm' ObjectDeleteAuditAlarmW advapi32 0 +imp 'ObjectDeleteAuditAlarmA' ObjectDeleteAuditAlarmA advapi32 1522 +imp 'ObjectOpenAuditAlarm' ObjectOpenAuditAlarmW advapi32 0 +imp 'ObjectOpenAuditAlarmA' ObjectOpenAuditAlarmA advapi32 1524 +imp 'ObjectPrivilegeAuditAlarm' ObjectPrivilegeAuditAlarmW advapi32 0 +imp 'ObjectPrivilegeAuditAlarmA' ObjectPrivilegeAuditAlarmA advapi32 1526 +imp 'OpenBackupEventLog' OpenBackupEventLogW advapi32 1529 +imp 'OpenBackupEventLogA' OpenBackupEventLogA advapi32 1528 +imp 'OpenEncryptedFileRaw' OpenEncryptedFileRawW advapi32 1531 +imp 'OpenEncryptedFileRawA' OpenEncryptedFileRawA advapi32 1530 +imp 'OpenEventLog' OpenEventLogW advapi32 1533 +imp 'OpenEventLogA' OpenEventLogA advapi32 1532 +imp 'OpenProcessToken' OpenProcessToken advapi32 0 3 +imp 'OpenSCManager' OpenSCManagerW advapi32 1536 +imp 'OpenSCManagerA' OpenSCManagerA advapi32 1535 +imp 'OpenService' OpenServiceW advapi32 1538 +imp 'OpenServiceA' OpenServiceA advapi32 1537 +imp 'OpenThreadToken' OpenThreadToken advapi32 0 4 +imp 'OpenThreadWaitChainSession' OpenThreadWaitChainSession advapi32 1540 +imp 'OpenTrace' OpenTraceW advapi32 1542 +imp 'OpenTraceA' OpenTraceA advapi32 1541 +imp 'OperationEnd' OperationEnd advapi32 1543 +imp 'OperationStart' OperationStart advapi32 1544 +imp 'PerfAddCounters' PerfAddCounters advapi32 1545 +imp 'PerfCloseQueryHandle' PerfCloseQueryHandle advapi32 1546 +imp 'PerfCreateInstance' PerfCreateInstance advapi32 0 +imp 'PerfDecrementULongCounterValue' PerfDecrementULongCounterValue advapi32 0 +imp 'PerfDecrementULongLongCounterValue' PerfDecrementULongLongCounterValue advapi32 0 +imp 'PerfDeleteCounters' PerfDeleteCounters advapi32 1550 +imp 'PerfDeleteInstance' PerfDeleteInstance advapi32 0 +imp 'PerfEnumerateCounterSet' PerfEnumerateCounterSet advapi32 1552 +imp 'PerfEnumerateCounterSetInstances' PerfEnumerateCounterSetInstances advapi32 1553 +imp 'PerfIncrementULongCounterValue' PerfIncrementULongCounterValue advapi32 0 +imp 'PerfIncrementULongLongCounterValue' PerfIncrementULongLongCounterValue advapi32 0 +imp 'PerfOpenQueryHandle' PerfOpenQueryHandle advapi32 1556 +imp 'PerfQueryCounterData' PerfQueryCounterData advapi32 1557 +imp 'PerfQueryCounterInfo' PerfQueryCounterInfo advapi32 1558 +imp 'PerfQueryCounterSetRegistrationInfo' PerfQueryCounterSetRegistrationInfo advapi32 1559 +imp 'PerfQueryInstance' PerfQueryInstance advapi32 0 +imp 'PerfRegCloseKey' PerfRegCloseKey advapi32 1561 +imp 'PerfRegEnumKey' PerfRegEnumKey advapi32 1562 +imp 'PerfRegEnumValue' PerfRegEnumValue advapi32 1563 +imp 'PerfRegQueryInfoKey' PerfRegQueryInfoKey advapi32 1564 +imp 'PerfRegQueryValue' PerfRegQueryValue advapi32 1565 +imp 'PerfRegSetValue' PerfRegSetValue advapi32 1566 +imp 'PerfSetCounterRefValue' PerfSetCounterRefValue advapi32 0 +imp 'PerfSetCounterSetInfo' PerfSetCounterSetInfo advapi32 0 +imp 'PerfSetULongCounterValue' PerfSetULongCounterValue advapi32 0 +imp 'PerfSetULongLongCounterValue' PerfSetULongLongCounterValue advapi32 0 +imp 'PerfStartProvider' PerfStartProvider advapi32 0 +imp 'PerfStartProviderEx' PerfStartProviderEx advapi32 0 +imp 'PerfStopProvider' PerfStopProvider advapi32 0 +imp 'PrivilegeCheck' PrivilegeCheck advapi32 0 +imp 'PrivilegedServiceAuditAlarm' PrivilegedServiceAuditAlarmW advapi32 0 +imp 'PrivilegedServiceAuditAlarmA' PrivilegedServiceAuditAlarmA advapi32 1575 +imp 'ProcessIdleTasks' ProcessIdleTasksW advapi32 1578 +imp 'ProcessTrace' ProcessTrace advapi32 1579 +imp 'QueryAllTraces' QueryAllTracesW advapi32 1581 +imp 'QueryAllTracesA' QueryAllTracesA advapi32 1580 +imp 'QueryLocalUserServiceName' QueryLocalUserServiceName advapi32 1582 +imp 'QueryRecoveryAgentsOnEncryptedFile' QueryRecoveryAgentsOnEncryptedFile advapi32 1583 +imp 'QuerySecurityAccessMask' QuerySecurityAccessMask advapi32 0 +imp 'QueryServiceConfig' QueryServiceConfigW advapi32 1588 +imp 'QueryServiceConfig2A' QueryServiceConfig2A advapi32 1585 +imp 'QueryServiceConfig2W' QueryServiceConfig2W advapi32 1586 +imp 'QueryServiceConfigA' QueryServiceConfigA advapi32 1587 +imp 'QueryServiceDynamicInformation' QueryServiceDynamicInformation advapi32 1589 +imp 'QueryServiceLockStatus' QueryServiceLockStatusW advapi32 1591 +imp 'QueryServiceLockStatusA' QueryServiceLockStatusA advapi32 1590 +imp 'QueryServiceObjectSecurity' QueryServiceObjectSecurity advapi32 1592 +imp 'QueryServiceStatus' QueryServiceStatus advapi32 1593 +imp 'QueryServiceStatusEx' QueryServiceStatusEx advapi32 1594 +imp 'QueryTrace' QueryTraceW advapi32 1597 +imp 'QueryTraceA' QueryTraceA advapi32 1595 +imp 'QueryTraceProcessingHandle' QueryTraceProcessingHandle advapi32 1596 +imp 'QueryUserServiceName' QueryUserServiceName advapi32 1598 +imp 'QueryUserServiceNameForContext' QueryUserServiceNameForContext advapi32 1599 +imp 'QueryUsersOnEncryptedFile' QueryUsersOnEncryptedFile advapi32 1600 +imp 'ReadEncryptedFileRaw' ReadEncryptedFileRaw advapi32 1601 +imp 'ReadEventLog' ReadEventLogW advapi32 1603 +imp 'ReadEventLogA' ReadEventLogA advapi32 1602 +imp 'RegCloseKey' RegCloseKey advapi32 0 1 +imp 'RegConnectRegistry' RegConnectRegistryW advapi32 1608 3 +imp 'RegConnectRegistryA' RegConnectRegistryA advapi32 1605 3 +imp 'RegConnectRegistryEx' RegConnectRegistryExW advapi32 1607 4 +imp 'RegConnectRegistryExA' RegConnectRegistryExA advapi32 1606 4 +imp 'RegCopyTree' RegCopyTreeW advapi32 0 +imp 'RegCopyTreeA' RegCopyTreeA advapi32 1609 +imp 'RegCreateKey' RegCreateKeyW advapi32 1616 3 +imp 'RegCreateKeyA' RegCreateKeyA advapi32 1611 3 +imp 'RegCreateKeyEx' RegCreateKeyExW advapi32 0 9 +imp 'RegCreateKeyExA' RegCreateKeyExA advapi32 0 9 +imp 'RegCreateKeyTransacted' RegCreateKeyTransactedW advapi32 1615 +imp 'RegCreateKeyTransactedA' RegCreateKeyTransactedA advapi32 1614 +imp 'RegDeleteKey' RegDeleteKeyW advapi32 1624 2 +imp 'RegDeleteKeyA' RegDeleteKeyA advapi32 1617 2 +imp 'RegDeleteKeyEx' RegDeleteKeyExW advapi32 0 4 +imp 'RegDeleteKeyExA' RegDeleteKeyExA advapi32 0 4 +imp 'RegDeleteKeyTransacted' RegDeleteKeyTransactedW advapi32 1621 +imp 'RegDeleteKeyTransactedA' RegDeleteKeyTransactedA advapi32 1620 +imp 'RegDeleteKeyValue' RegDeleteKeyValueW advapi32 0 +imp 'RegDeleteKeyValueA' RegDeleteKeyValueA advapi32 0 +imp 'RegDeleteTree' RegDeleteTreeW advapi32 0 2 +imp 'RegDeleteTreeA' RegDeleteTreeA advapi32 0 2 +imp 'RegDeleteValue' RegDeleteValueW advapi32 0 2 +imp 'RegDeleteValueA' RegDeleteValueA advapi32 0 2 +imp 'RegDisablePredefinedCache' RegDisablePredefinedCache advapi32 1629 1 +imp 'RegDisableReflectionKey' RegDisableReflectionKey advapi32 1631 1 +imp 'RegEnableReflectionKey' RegEnableReflectionKey advapi32 1632 1 +imp 'RegEnumKey' RegEnumKeyW advapi32 1636 4 +imp 'RegEnumKeyA' RegEnumKeyA advapi32 1633 4 +imp 'RegEnumKeyEx' RegEnumKeyExW advapi32 0 8 +imp 'RegEnumKeyExA' RegEnumKeyExA advapi32 0 8 +imp 'RegEnumValue' RegEnumValueW advapi32 0 8 +imp 'RegEnumValueA' RegEnumValueA advapi32 0 8 +imp 'RegFlushKey' RegFlushKey advapi32 0 1 +imp 'RegGetKeySecurity' RegGetKeySecurity advapi32 0 4 +imp 'RegGetValue' RegGetValueW advapi32 0 7 +imp 'RegGetValueA' RegGetValueA advapi32 0 7 +imp 'RegLoadAppKey' RegLoadAppKeyW advapi32 0 +imp 'RegLoadAppKeyA' RegLoadAppKeyA advapi32 0 +imp 'RegLoadKey' RegLoadKeyW advapi32 0 3 +imp 'RegLoadKeyA' RegLoadKeyA advapi32 0 3 +imp 'RegLoadMUIString' RegLoadMUIStringW advapi32 0 +imp 'RegNotifyChangeKeyValue' RegNotifyChangeKeyValue advapi32 0 5 +imp 'RegOpenCurrentUser' RegOpenCurrentUser advapi32 0 2 +imp 'RegOpenKey' RegOpenKeyW advapi32 1656 +imp 'RegOpenKeyA' RegOpenKeyA advapi32 1651 3 +imp 'RegOpenKeyEx' RegOpenKeyExW advapi32 0 5 +imp 'RegOpenKeyExA' RegOpenKeyExA advapi32 0 5 +imp 'RegOpenKeyTransacted' RegOpenKeyTransactedW advapi32 1655 +imp 'RegOpenKeyTransactedA' RegOpenKeyTransactedA advapi32 1654 +imp 'RegOpenUserClassesRoot' RegOpenUserClassesRoot advapi32 0 4 +imp 'RegOverridePredefKey' RegOverridePredefKey advapi32 1658 2 +imp 'RegQueryInfoKey' RegQueryInfoKeyW advapi32 0 12 +imp 'RegQueryInfoKeyA' RegQueryInfoKeyA advapi32 0 12 +imp 'RegQueryMultipleValues' RegQueryMultipleValuesW advapi32 0 5 +imp 'RegQueryMultipleValuesA' RegQueryMultipleValuesA advapi32 0 5 +imp 'RegQueryReflectionKey' RegQueryReflectionKey advapi32 1663 2 +imp 'RegQueryValue' RegQueryValueW advapi32 1667 4 +imp 'RegQueryValueA' RegQueryValueA advapi32 1664 4 +imp 'RegQueryValueEx' RegQueryValueExW advapi32 0 6 +imp 'RegQueryValueExA' RegQueryValueExA advapi32 0 6 +imp 'RegRenameKey' RegRenameKey advapi32 1668 +imp 'RegReplaceKey' RegReplaceKeyW advapi32 1670 4 +imp 'RegReplaceKeyA' RegReplaceKeyA advapi32 1669 4 +imp 'RegRestoreKey' RegRestoreKeyW advapi32 0 3 +imp 'RegRestoreKeyA' RegRestoreKeyA advapi32 0 3 +imp 'RegSaveKey' RegSaveKeyW advapi32 1676 3 +imp 'RegSaveKeyA' RegSaveKeyA advapi32 1673 3 +imp 'RegSaveKeyEx' RegSaveKeyExW advapi32 0 +imp 'RegSetKeySecurity' RegSetKeySecurity advapi32 0 3 +imp 'RegSetKeyValue' RegSetKeyValueW advapi32 0 +imp 'RegSetKeyValueA' RegSetKeyValueA advapi32 0 +imp 'RegSetValue' RegSetValueW advapi32 1683 5 +imp 'RegSetValueA' RegSetValueA advapi32 1680 5 +imp 'RegSetValueEx' RegSetValueExW advapi32 0 6 +imp 'RegSetValueExA' RegSetValueExA advapi32 0 6 +imp 'RegUnLoadKey' RegUnLoadKeyW advapi32 0 2 +imp 'RegUnLoadKeyA' RegUnLoadKeyA advapi32 0 2 +imp 'RegisterEventSource' RegisterEventSourceW advapi32 1687 2 +imp 'RegisterIdleTask' RegisterIdleTask advapi32 1688 +imp 'RegisterServiceCtrlHandler' RegisterServiceCtrlHandlerW advapi32 1692 +imp 'RegisterServiceCtrlHandlerEx' RegisterServiceCtrlHandlerExW advapi32 1691 +imp 'RegisterWaitChainCOMCallback' RegisterWaitChainCOMCallback advapi32 1695 +imp 'RemoteRegEnumKeyWrapper' RemoteRegEnumKeyWrapper advapi32 1696 +imp 'RemoteRegEnumValueWrapper' RemoteRegEnumValueWrapper advapi32 1697 +imp 'RemoteRegQueryInfoKeyWrapper' RemoteRegQueryInfoKeyWrapper advapi32 1698 +imp 'RemoteRegQueryMultipleValues2Wrapper' RemoteRegQueryMultipleValues2Wrapper advapi32 1699 +imp 'RemoteRegQueryMultipleValuesWrapper' RemoteRegQueryMultipleValuesWrapper advapi32 1700 +imp 'RemoteRegQueryValueWrapper' RemoteRegQueryValueWrapper advapi32 1701 +imp 'RemoveUsersFromEncryptedFile' RemoveUsersFromEncryptedFile advapi32 1703 +imp 'ReportEvent' ReportEventW advapi32 0 9 +imp 'ReportEventA' ReportEventA advapi32 0 9 +imp 'RevertToSelf' RevertToSelf advapi32 0 0 +imp 'RtlGenRandom' SystemFunction036 advapi32 0 2 +imp 'SafeBaseRegGetKeySecurity' SafeBaseRegGetKeySecurity advapi32 1707 +imp 'SaferCloseLevel' SaferCloseLevel advapi32 1708 +imp 'SaferComputeTokenFromLevel' SaferComputeTokenFromLevel advapi32 1709 +imp 'SaferCreateLevel' SaferCreateLevel advapi32 1710 +imp 'SaferGetLevelInformation' SaferGetLevelInformation advapi32 1711 +imp 'SaferGetPolicyInformation' SaferGetPolicyInformation advapi32 1712 +imp 'SaferIdentifyLevel' SaferIdentifyLevel advapi32 1713 +imp 'SaferRecordEventLogEntry' SaferRecordEventLogEntry advapi32 1714 +imp 'SaferSetLevelInformation' SaferSetLevelInformation advapi32 1715 +imp 'SaferSetPolicyInformation' SaferSetPolicyInformation advapi32 1716 +imp 'SaferiChangeRegistryScope' SaferiChangeRegistryScope advapi32 1717 +imp 'SaferiCompareTokenLevels' SaferiCompareTokenLevels advapi32 1718 +imp 'SaferiIsDllAllowed' SaferiIsDllAllowed advapi32 1719 +imp 'SaferiIsExecutableFileType' SaferiIsExecutableFileType advapi32 1720 +imp 'SaferiPopulateDefaultsInRegistry' SaferiPopulateDefaultsInRegistry advapi32 1721 +imp 'SaferiRecordEventLogEntry' SaferiRecordEventLogEntry advapi32 1722 +imp 'SaferiSearchMatchingHashRules' SaferiSearchMatchingHashRules advapi32 1723 +imp 'SetAclInformation' SetAclInformation advapi32 0 +imp 'SetEncryptedFileMetadata' SetEncryptedFileMetadata advapi32 1725 +imp 'SetEntriesInAccessList' SetEntriesInAccessListW advapi32 1727 +imp 'SetEntriesInAcl' SetEntriesInAclW advapi32 1729 +imp 'SetEntriesInAuditList' SetEntriesInAuditListW advapi32 1731 +imp 'SetFileSecurity' SetFileSecurityW advapi32 0 +imp 'SetInformationCodeAuthzLevel' SetInformationCodeAuthzLevelW advapi32 1734 +imp 'SetInformationCodeAuthzPolicy' SetInformationCodeAuthzPolicyW advapi32 1735 +imp 'SetKernelObjectSecurity' SetKernelObjectSecurity advapi32 0 +imp 'SetNamedSecurityInfo' SetNamedSecurityInfoW advapi32 1740 +imp 'SetNamedSecurityInfoEx' SetNamedSecurityInfoExW advapi32 1739 +imp 'SetPrivateObjectSecurity' SetPrivateObjectSecurity advapi32 0 +imp 'SetPrivateObjectSecurityEx' SetPrivateObjectSecurityEx advapi32 0 +imp 'SetSecurityAccessMask' SetSecurityAccessMask advapi32 0 +imp 'SetSecurityDescriptorControl' SetSecurityDescriptorControl advapi32 0 +imp 'SetSecurityDescriptorDacl' SetSecurityDescriptorDacl advapi32 0 +imp 'SetSecurityDescriptorGroup' SetSecurityDescriptorGroup advapi32 0 +imp 'SetSecurityDescriptorOwner' SetSecurityDescriptorOwner advapi32 0 +imp 'SetSecurityDescriptorRMControl' SetSecurityDescriptorRMControl advapi32 0 +imp 'SetSecurityDescriptorSacl' SetSecurityDescriptorSacl advapi32 0 +imp 'SetSecurityInfo' SetSecurityInfo advapi32 1750 +imp 'SetSecurityInfoEx' SetSecurityInfoExW advapi32 1752 +imp 'SetServiceBits' SetServiceBits advapi32 1753 +imp 'SetServiceObjectSecurity' SetServiceObjectSecurity advapi32 1754 +imp 'SetServiceStatus' SetServiceStatus advapi32 1755 +imp 'SetThreadToken' SetThreadToken advapi32 0 +imp 'SetTokenInformation' SetTokenInformation advapi32 0 +imp 'SetUserFileEncryptionKey' SetUserFileEncryptionKey advapi32 1759 +imp 'SetUserFileEncryptionKeyEx' SetUserFileEncryptionKeyEx advapi32 1760 +imp 'StartService' StartServiceW advapi32 1764 +imp 'StartServiceCtrlDispatcher' StartServiceCtrlDispatcherW advapi32 1763 +imp 'StartTrace' StartTraceW advapi32 1766 +imp 'StopTrace' StopTraceW advapi32 1768 +imp 'SystemFunction017' SystemFunction017 advapi32 1785 +imp 'SystemFunction019' SystemFunction019 advapi32 1787 +imp 'TraceSetInformation' TraceSetInformation advapi32 1812 +imp 'TreeResetNamedSecurityInfo' TreeResetNamedSecurityInfoW advapi32 1814 +imp 'TreeSetNamedSecurityInfo' TreeSetNamedSecurityInfoW advapi32 1816 +imp 'TrusteeAccessToObject' TrusteeAccessToObjectW advapi32 1818 +imp 'UninstallApplication' UninstallApplication advapi32 1819 +imp 'UnlockServiceDatabase' UnlockServiceDatabase advapi32 1820 +imp 'UnregisterIdleTask' UnregisterIdleTask advapi32 1821 +imp 'UpdateTrace' UpdateTraceW advapi32 1824 +imp 'UsePinForEncryptedFiles' UsePinForEncryptedFilesW advapi32 1826 +imp 'WaitServiceState' WaitServiceState advapi32 1827 +imp 'WmiCloseBlock' WmiCloseBlock advapi32 1828 +imp 'WmiDevInstToInstanceName' WmiDevInstToInstanceNameW advapi32 1830 +imp 'WmiEnumerateGuids' WmiEnumerateGuids advapi32 1831 +imp 'WmiExecuteMethod' WmiExecuteMethodW advapi32 1833 +imp 'WmiFileHandleToInstanceName' WmiFileHandleToInstanceNameW advapi32 1835 +imp 'WmiFreeBuffer' WmiFreeBuffer advapi32 1836 +imp 'WmiMofEnumerateResources' WmiMofEnumerateResourcesW advapi32 1838 +imp 'WmiNotificationRegistration' WmiNotificationRegistrationW advapi32 1840 +imp 'WmiOpenBlock' WmiOpenBlock advapi32 1841 +imp 'WmiQueryAllData' WmiQueryAllDataW advapi32 1845 +imp 'WmiQueryAllDataMultiple' WmiQueryAllDataMultipleW advapi32 1844 +imp 'WmiQueryGuidInformation' WmiQueryGuidInformation advapi32 1846 +imp 'WmiQuerySingleInstance' WmiQuerySingleInstanceW advapi32 1850 +imp 'WmiQuerySingleInstanceMultiple' WmiQuerySingleInstanceMultipleW advapi32 1849 +imp 'WmiReceiveNotifications' WmiReceiveNotificationsW advapi32 1852 +imp 'WmiSetSingleInstance' WmiSetSingleInstanceW advapi32 1854 +imp 'WmiSetSingleItem' WmiSetSingleItemW advapi32 1856 +imp 'WriteEncryptedFileRaw' WriteEncryptedFileRaw advapi32 1857 + +# USER32.DLL +# +# Name Actual DLL Hint Arity +imp 'ActivateKeyboardLayout' ActivateKeyboardLayout user32 1505 +imp 'AddClipboardFormatListener' AddClipboardFormatListener user32 1506 +imp 'AdjustWindowRect' AdjustWindowRect user32 1507 3 +imp 'AdjustWindowRectEx' AdjustWindowRectEx user32 1508 +imp 'AdjustWindowRectExForDpi' AdjustWindowRectExForDpi user32 1509 +imp 'AlignRects' AlignRects user32 1510 +imp 'AllowForegroundActivation' AllowForegroundActivation user32 1511 +imp 'AllowSetForegroundWindow' AllowSetForegroundWindow user32 1512 +imp 'AnimateWindow' AnimateWindow user32 1513 3 +imp 'AnyPopup' AnyPopup user32 1514 +imp 'AppendMenuA' AppendMenuA user32 1515 4 +imp 'AppendMenu' AppendMenuW user32 1516 4 +imp 'AreDpiAwarenessContextsEqual' AreDpiAwarenessContextsEqual user32 1517 +imp 'ArrangeIconicWindows' ArrangeIconicWindows user32 1518 +imp 'AttachThreadInput' AttachThreadInput user32 1519 +imp 'BeginDeferWindowPos' BeginDeferWindowPos user32 1520 +imp 'BeginPaint' BeginPaint user32 1521 2 +imp 'BlockInput' BlockInput user32 1522 +imp 'BringWindowToTop' BringWindowToTop user32 1523 1 +imp 'BroadcastSystemMessage' BroadcastSystemMessageW user32 1528 +imp 'BroadcastSystemMessageEx' BroadcastSystemMessageExW user32 1527 +imp 'BuildReasonArray' BuildReasonArray user32 1529 +imp 'CalcMenuBar' CalcMenuBar user32 1530 +imp 'CalculatePopupWindowPosition' CalculatePopupWindowPosition user32 1531 +imp 'CallMsgFilter' CallMsgFilterW user32 1534 +imp 'CallNextHookEx' CallNextHookEx user32 1535 4 +imp 'CallWindowProc' CallWindowProcW user32 1537 +imp 'CancelShutdown' CancelShutdown user32 1538 +imp 'CascadeChildWindows' CascadeChildWindows user32 1539 +imp 'CascadeWindows' CascadeWindows user32 1540 +imp 'ChangeClipboardChain' ChangeClipboardChain user32 1541 +imp 'ChangeDisplaySettings' ChangeDisplaySettingsW user32 1545 +imp 'ChangeDisplaySettingsEx' ChangeDisplaySettingsExW user32 1544 +imp 'ChangeMenu' ChangeMenuW user32 1547 +imp 'ChangeWindowMessageFilter' ChangeWindowMessageFilter user32 1548 +imp 'ChangeWindowMessageFilterEx' ChangeWindowMessageFilterEx user32 1549 +imp 'CharToOem' CharToOemW user32 1568 +imp 'CharToOemBuff' CharToOemBuffW user32 1567 +imp 'CheckDBCSEnabledExt' CheckDBCSEnabledExt user32 1573 +imp 'CheckDlgButton' CheckDlgButton user32 1574 +imp 'CheckMenuItem' CheckMenuItem user32 1575 +imp 'CheckMenuRadioItem' CheckMenuRadioItem user32 1576 +imp 'CheckProcessForClipboardAccess' CheckProcessForClipboardAccess user32 1577 +imp 'CheckProcessSession' CheckProcessSession user32 1578 +imp 'CheckRadioButton' CheckRadioButton user32 1579 +imp 'CheckWindowThreadDesktop' CheckWindowThreadDesktop user32 1580 +imp 'ChildWindowFromPoint' ChildWindowFromPoint user32 1581 +imp 'ChildWindowFromPointEx' ChildWindowFromPointEx user32 1582 +imp 'CliImmSetHotKey' CliImmSetHotKey user32 1583 +imp 'ClientThreadSetup' ClientThreadSetup user32 1584 +imp 'ClientToScreen' ClientToScreen user32 1585 +imp 'ClipCursor' ClipCursor user32 1586 +imp 'CloseClipboard' CloseClipboard user32 1587 +imp 'CloseDesktop' CloseDesktop user32 1588 +imp 'CloseGestureInfoHandle' CloseGestureInfoHandle user32 1589 +imp 'CloseTouchInputHandle' CloseTouchInputHandle user32 1590 +imp 'CloseWindow' CloseWindow user32 1591 1 +imp 'CloseWindowStation' CloseWindowStation user32 1592 +imp 'ConsoleControl' ConsoleControl user32 1593 +imp 'ControlMagnification' ControlMagnification user32 1594 +imp 'CopyAcceleratorTable' CopyAcceleratorTableW user32 1596 +imp 'CopyIcon' CopyIcon user32 1597 +imp 'CopyImage' CopyImage user32 1598 +imp 'CopyRect' CopyRect user32 1599 +imp 'CountClipboardFormats' CountClipboardFormats user32 1600 +imp 'CreateAcceleratorTable' CreateAcceleratorTableW user32 1602 +imp 'CreateCaret' CreateCaret user32 1603 +imp 'CreateCursor' CreateCursor user32 1604 +imp 'CreateDCompositionHwndTarget' CreateDCompositionHwndTarget user32 1605 +imp 'CreateDesktop' CreateDesktopW user32 1609 +imp 'CreateDesktopEx' CreateDesktopExW user32 1608 +imp 'CreateDialogIndirectParam' CreateDialogIndirectParamW user32 1612 +imp 'CreateDialogIndirectParamAor' CreateDialogIndirectParamAorW user32 1611 +imp 'CreateDialogParam' CreateDialogParamW user32 1614 +imp 'CreateIcon' CreateIcon user32 1615 +imp 'CreateIconFromResource' CreateIconFromResource user32 1616 +imp 'CreateIconFromResourceEx' CreateIconFromResourceEx user32 1617 +imp 'CreateIconIndirect' CreateIconIndirect user32 1618 1 +imp 'CreateMDIWindow' CreateMDIWindowW user32 1620 +imp 'CreateMenu' CreateMenu user32 1621 0 +imp 'CreatePalmRejectionDelayZone' CreatePalmRejectionDelayZone user32 1503 +imp 'CreatePopupMenu' CreatePopupMenu user32 1622 0 +imp 'CreateSystemThreads' CreateSystemThreads user32 1623 +imp 'CreateWindowEx' CreateWindowExW user32 1625 12 +imp 'CreateWindowInBand' CreateWindowInBand user32 1626 +imp 'CreateWindowInBandEx' CreateWindowInBandEx user32 1627 +imp 'CreateWindowIndirect' CreateWindowIndirect user32 1628 +imp 'CreateWindowStation' CreateWindowStationW user32 1630 imp 'CsrBroadcastSystemMessageEx' CsrBroadcastSystemMessageExW user32 1631 -imp 'CsrCaptureMessageBuffer' CsrCaptureMessageBuffer ntdll 30 -imp 'CsrCaptureMessageMultiUnicodeStringsInPlace' CsrCaptureMessageMultiUnicodeStringsInPlace ntdll 31 -imp 'CsrCaptureMessageString' CsrCaptureMessageString ntdll 32 -imp 'CsrCaptureTimeout' CsrCaptureTimeout ntdll 33 -imp 'CsrClientCallServer' CsrClientCallServer ntdll 34 4 -imp 'CsrClientConnectToServer' CsrClientConnectToServer ntdll 35 -imp 'CsrFreeCaptureBuffer' CsrFreeCaptureBuffer ntdll 36 -imp 'CsrGetProcessId' CsrGetProcessId ntdll 37 -imp 'CsrIdentifyAlertableThread' CsrIdentifyAlertableThread ntdll 38 -imp 'CsrSetPriorityClass' CsrSetPriorityClass ntdll 39 -imp 'CsrVerifyRegion' CsrVerifyRegion ntdll 40 -imp 'CtrlRoutine' CtrlRoutine KernelBase 236 imp 'CtxInitUser32' CtxInitUser32 user32 1632 -imp 'CveEventWrite' CveEventWrite KernelBase 237 +imp 'DWMBindCursorToOutputConfig' DWMBindCursorToOutputConfig user32 1633 +imp 'DWMCommitInputSystemOutputConfig' DWMCommitInputSystemOutputConfig user32 1634 +imp 'DWMSetCursorOrientation' DWMSetCursorOrientation user32 1635 +imp 'DWMSetInputSystemOutputConfig' DWMSetInputSystemOutputConfig user32 1636 +imp 'DdeAbandonTransaction' DdeAbandonTransaction user32 1637 +imp 'DdeAccessData' DdeAccessData user32 1638 +imp 'DdeAddData' DdeAddData user32 1639 +imp 'DdeClientTransaction' DdeClientTransaction user32 1640 +imp 'DdeCmpStringHandles' DdeCmpStringHandles user32 1641 +imp 'DdeConnect' DdeConnect user32 1642 +imp 'DdeConnectList' DdeConnectList user32 1643 +imp 'DdeCreateDataHandle' DdeCreateDataHandle user32 1644 +imp 'DdeCreateStringHandle' DdeCreateStringHandleW user32 1646 +imp 'DdeDisconnect' DdeDisconnect user32 1647 +imp 'DdeDisconnectList' DdeDisconnectList user32 1648 +imp 'DdeEnableCallback' DdeEnableCallback user32 1649 +imp 'DdeFreeDataHandle' DdeFreeDataHandle user32 1650 +imp 'DdeFreeStringHandle' DdeFreeStringHandle user32 1651 +imp 'DdeGetData' DdeGetData user32 1652 +imp 'DdeGetLastError' DdeGetLastError user32 1653 +imp 'DdeGetQualityOfService' DdeGetQualityOfService user32 1654 +imp 'DdeImpersonateClient' DdeImpersonateClient user32 1655 +imp 'DdeInitialize' DdeInitializeW user32 1657 +imp 'DdeKeepStringHandle' DdeKeepStringHandle user32 1658 +imp 'DdeNameService' DdeNameService user32 1659 +imp 'DdePostAdvise' DdePostAdvise user32 1660 +imp 'DdeQueryConvInfo' DdeQueryConvInfo user32 1661 +imp 'DdeQueryNextServer' DdeQueryNextServer user32 1662 +imp 'DdeQueryString' DdeQueryStringW user32 1664 +imp 'DdeReconnect' DdeReconnect user32 1665 +imp 'DdeSetQualityOfService' DdeSetQualityOfService user32 1666 +imp 'DdeSetUserHandle' DdeSetUserHandle user32 1667 +imp 'DdeUnaccessData' DdeUnaccessData user32 1668 +imp 'DdeUninitialize' DdeUninitialize user32 1669 +imp 'DefFrameProc' DefFrameProcW user32 1673 +imp 'DefMDIChildProc' DefMDIChildProcW user32 1675 +imp 'DefRawInputProc' DefRawInputProc user32 1676 +imp 'DefWindowProc' DefWindowProcW user32 174 4 +imp 'DeferWindowPos' DeferWindowPos user32 1679 +imp 'DeferWindowPosAndBand' DeferWindowPosAndBand user32 1680 +imp 'DelegateInput' DelegateInput user32 2503 +imp 'DeleteMenu' DeleteMenu user32 1681 3 +imp 'DeregisterShellHookWindow' DeregisterShellHookWindow user32 1682 +imp 'DestroyAcceleratorTable' DestroyAcceleratorTable user32 1683 +imp 'DestroyCaret' DestroyCaret user32 1684 +imp 'DestroyCursor' DestroyCursor user32 1685 +imp 'DestroyDCompositionHwndTarget' DestroyDCompositionHwndTarget user32 1686 +imp 'DestroyIcon' DestroyIcon user32 1687 1 +imp 'DestroyMenu' DestroyMenu user32 1688 1 +imp 'DestroyPalmRejectionDelayZone' DestroyPalmRejectionDelayZone user32 1504 +imp 'DestroyReasons' DestroyReasons user32 1689 +imp 'DestroyWindow' DestroyWindow user32 1690 1 +imp 'DialogBoxIndirectParam' DialogBoxIndirectParamW user32 1693 +imp 'DialogBoxIndirectParamAor' DialogBoxIndirectParamAorW user32 1692 +imp 'DialogBoxParam' DialogBoxParamW user32 1695 +imp 'DisableProcessWindowsGhosting' DisableProcessWindowsGhosting user32 1696 +imp 'DispatchMessage' DispatchMessageW user32 1698 1 +imp 'DisplayConfigGetDeviceInfo' DisplayConfigGetDeviceInfo user32 1699 +imp 'DisplayConfigSetDeviceInfo' DisplayConfigSetDeviceInfo user32 1700 +imp 'DisplayExitWindowsWarnings' DisplayExitWindowsWarnings user32 1701 +imp 'DlgDirList' DlgDirListW user32 1705 +imp 'DlgDirListComboBox' DlgDirListComboBoxW user32 1704 +imp 'DlgDirSelectComboBoxEx' DlgDirSelectComboBoxExW user32 1707 +imp 'DlgDirSelectEx' DlgDirSelectExW user32 1709 +imp 'DoSoundConnect' DoSoundConnect user32 1710 +imp 'DoSoundDisconnect' DoSoundDisconnect user32 1711 +imp 'DragDetect' DragDetect user32 1712 +imp 'DragObject' DragObject user32 1713 +imp 'DrawAnimatedRects' DrawAnimatedRects user32 1714 +imp 'DrawCaption' DrawCaption user32 1715 +imp 'DrawCaptionTemp' DrawCaptionTempW user32 1717 +imp 'DrawEdge' DrawEdge user32 1718 +imp 'DrawFocusRect' DrawFocusRect user32 1719 +imp 'DrawFrame' DrawFrame user32 1720 +imp 'DrawFrameControl' DrawFrameControl user32 1721 +imp 'DrawIcon' DrawIcon user32 1722 +imp 'DrawIconEx' DrawIconEx user32 1723 +imp 'DrawMenuBar' DrawMenuBar user32 1724 +imp 'DrawMenuBarTemp' DrawMenuBarTemp user32 1725 +imp 'DrawState' DrawStateW user32 1727 +imp 'DrawText' DrawTextW user32 1731 5 +imp 'DrawTextEx' DrawTextExW user32 1730 6 +imp 'DwmGetDxRgn' DwmGetDxRgn user32 1553 +imp 'DwmGetDxSharedSurface' DwmGetDxSharedSurface user32 1732 +imp 'DwmGetRemoteSessionOcclusionEvent' DwmGetRemoteSessionOcclusionEvent user32 1733 +imp 'DwmGetRemoteSessionOcclusionState' DwmGetRemoteSessionOcclusionState user32 1734 +imp 'DwmKernelShutdown' DwmKernelShutdown user32 1735 +imp 'DwmKernelStartup' DwmKernelStartup user32 1736 +imp 'DwmLockScreenUpdates' DwmLockScreenUpdates user32 1737 +imp 'DwmValidateWindow' DwmValidateWindow user32 1738 +imp 'EditWndProc' EditWndProc user32 1739 +imp 'EmptyClipboard' EmptyClipboard user32 1704 +imp 'EnableMenuItem' EnableMenuItem user32 1741 +imp 'EnableMouseInPointer' EnableMouseInPointer user32 1742 +imp 'EnableNonClientDpiScaling' EnableNonClientDpiScaling user32 1743 +imp 'EnableOneCoreTransformMode' EnableOneCoreTransformMode user32 1744 +imp 'EnableScrollBar' EnableScrollBar user32 1745 +imp 'EnableSessionForMMCSS' EnableSessionForMMCSS user32 1746 +imp 'EnableWindow' EnableWindow user32 1747 +imp 'EndDeferWindowPos' EndDeferWindowPos user32 1748 +imp 'EndDeferWindowPosEx' EndDeferWindowPosEx user32 1749 +imp 'EndDialog' EndDialog user32 1750 +imp 'EndMenu' EndMenu user32 1751 +imp 'EndPaint' EndPaint user32 1752 2 +imp 'EndTask' EndTask user32 1753 +imp 'EnterReaderModeHelper' EnterReaderModeHelper user32 1754 +imp 'EnumChildWindows' EnumChildWindows user32 1755 3 +imp 'EnumClipboardFormats' EnumClipboardFormats user32 1756 +imp 'EnumDesktopWindows' EnumDesktopWindows user32 1757 +imp 'EnumDesktops' EnumDesktopsW user32 1759 +imp 'EnumDisplayDevices' EnumDisplayDevicesW user32 1761 +imp 'EnumDisplayMonitors' EnumDisplayMonitors user32 1762 +imp 'EnumDisplaySettings' EnumDisplaySettingsW user32 1766 +imp 'EnumDisplaySettingsEx' EnumDisplaySettingsExW user32 1765 +imp 'EnumProps' EnumPropsW user32 1770 +imp 'EnumPropsEx' EnumPropsExW user32 1769 +imp 'EnumThreadWindows' EnumThreadWindows user32 1771 +imp 'EnumWindowStations' EnumWindowStationsW user32 1773 +imp 'EnumWindows' EnumWindows user32 1774 +imp 'EqualRect' EqualRect user32 1775 +imp 'EvaluateProximityToPolygon' EvaluateProximityToPolygon user32 1776 +imp 'EvaluateProximityToRect' EvaluateProximityToRect user32 1777 +imp 'ExcludeUpdateRgn' ExcludeUpdateRgn user32 1778 +imp 'ExitWindowsEx' ExitWindowsEx user32 1779 +imp 'FillRect' FillRect user32 1780 3 +imp 'FindWindow' FindWindowW user32 1784 2 +imp 'FindWindowEx' FindWindowExW user32 1783 4 +imp 'FlashWindow' FlashWindow user32 1785 +imp 'FlashWindowEx' FlashWindowEx user32 1786 +imp 'FrameRect' FrameRect user32 1787 +imp 'FreeDDElParam' FreeDDElParam user32 1788 +imp 'FrostCrashedWindow' FrostCrashedWindow user32 1789 +imp 'GetActiveWindow' GetActiveWindow user32 1790 +imp 'GetAltTabInfo' GetAltTabInfoW user32 1793 +imp 'GetAncestor' GetAncestor user32 1794 +imp 'GetAppCompatFlags' GetAppCompatFlags user32 1795 +imp 'GetAppCompatFlags2' GetAppCompatFlags2 user32 1796 +imp 'GetAsyncKeyState' GetAsyncKeyState user32 1797 +imp 'GetAutoRotationState' GetAutoRotationState user32 1798 +imp 'GetAwarenessFromDpiAwarenessContext' GetAwarenessFromDpiAwarenessContext user32 1799 +imp 'GetCIMSSM' GetCIMSSM user32 1800 +imp 'GetCapture' GetCapture user32 1801 +imp 'GetCaretBlinkTime' GetCaretBlinkTime user32 1802 +imp 'GetCaretPos' GetCaretPos user32 1803 +imp 'GetClassInfo' GetClassInfoW user32 1807 +imp 'GetClassInfoEx' GetClassInfoExW user32 1806 +imp 'GetClassLong' GetClassLongW user32 1811 +imp 'GetClassLongPtr' GetClassLongPtrW user32 1810 +imp 'GetClassName' GetClassNameW user32 1813 +imp 'GetClassWord' GetClassWord user32 1814 +imp 'GetClientRect' GetClientRect user32 1815 2 +imp 'GetClipCursor' GetClipCursor user32 1816 +imp 'GetClipboardAccessToken' GetClipboardAccessToken user32 1817 +imp 'GetClipboardData' GetClipboardData user32 1818 +imp 'GetClipboardFormatName' GetClipboardFormatNameW user32 1820 +imp 'GetClipboardOwner' GetClipboardOwner user32 1821 +imp 'GetClipboardSequenceNumber' GetClipboardSequenceNumber user32 1822 +imp 'GetClipboardViewer' GetClipboardViewer user32 1823 +imp 'GetComboBoxInfo' GetComboBoxInfo user32 1824 +imp 'GetCurrentInputMessageSource' GetCurrentInputMessageSource user32 1825 +imp 'GetCursor' GetCursor user32 1826 0 +imp 'GetCursorFrameInfo' GetCursorFrameInfo user32 1827 +imp 'GetCursorInfo' GetCursorInfo user32 1828 +imp 'GetCursorPos' GetCursorPos user32 1829 1 +imp 'GetDC' GetDC user32 1830 1 +imp 'GetDCEx' GetDCEx user32 1831 +imp 'GetDesktopID' GetDesktopID user32 1832 +imp 'GetDesktopWindow' GetDesktopWindow user32 1833 0 +imp 'GetDialogBaseUnits' GetDialogBaseUnits user32 1834 +imp 'GetDialogControlDpiChangeBehavior' GetDialogControlDpiChangeBehavior user32 1835 +imp 'GetDialogDpiChangeBehavior' GetDialogDpiChangeBehavior user32 1836 +imp 'GetDisplayAutoRotationPreferences' GetDisplayAutoRotationPreferences user32 1837 +imp 'GetDisplayConfigBufferSizes' GetDisplayConfigBufferSizes user32 1838 +imp 'GetDlgCtrlID' GetDlgCtrlID user32 1839 +imp 'GetDlgItem' GetDlgItem user32 1840 +imp 'GetDlgItemInt' GetDlgItemInt user32 1841 +imp 'GetDlgItemText' GetDlgItemTextW user32 1843 +imp 'GetDoubleClickTime' GetDoubleClickTime user32 1844 +imp 'GetDpiForMonitorInternal' GetDpiForMonitorInternal user32 1845 +imp 'GetDpiForSystem' GetDpiForSystem user32 1846 +imp 'GetDpiForWindow' GetDpiForWindow user32 1847 +imp 'GetDpiFromDpiAwarenessContext' GetDpiFromDpiAwarenessContext user32 1848 +imp 'GetFocus' GetFocus user32 1849 +imp 'GetForegroundWindow' GetForegroundWindow user32 1850 +imp 'GetGUIThreadInfo' GetGUIThreadInfo user32 1851 +imp 'GetGestureConfig' GetGestureConfig user32 1852 +imp 'GetGestureExtraArgs' GetGestureExtraArgs user32 1853 +imp 'GetGestureInfo' GetGestureInfo user32 1854 +imp 'GetGuiResources' GetGuiResources user32 1855 +imp 'GetIconInfo' GetIconInfo user32 1856 +imp 'GetIconInfoEx' GetIconInfoExW user32 1858 +imp 'GetInputDesktop' GetInputDesktop user32 1859 +imp 'GetInputLocaleInfo' GetInputLocaleInfo user32 1860 +imp 'GetInputState' GetInputState user32 1861 +imp 'GetInternalWindowPos' GetInternalWindowPos user32 1862 +imp 'GetKBCodePage' GetKBCodePage user32 1863 +imp 'GetKeyNameText' GetKeyNameTextW user32 1865 +imp 'GetKeyState' GetKeyState user32 1866 1 +imp 'GetKeyboardLayout' GetKeyboardLayout user32 1867 1 +imp 'GetKeyboardLayoutList' GetKeyboardLayoutList user32 1868 +imp 'GetKeyboardLayoutName' GetKeyboardLayoutNameW user32 1870 +imp 'GetKeyboardState' GetKeyboardState user32 1871 +imp 'GetKeyboardType' GetKeyboardType user32 1872 +imp 'GetLastActivePopup' GetLastActivePopup user32 1873 +imp 'GetLastInputInfo' GetLastInputInfo user32 1874 +imp 'GetLayeredWindowAttributes' GetLayeredWindowAttributes user32 1875 +imp 'GetListBoxInfo' GetListBoxInfo user32 1876 +imp 'GetMagnificationDesktopColorEffect' GetMagnificationDesktopColorEffect user32 1877 +imp 'GetMagnificationDesktopMagnification' GetMagnificationDesktopMagnification user32 1878 +imp 'GetMagnificationDesktopSamplingMode' GetMagnificationDesktopSamplingMode user32 1879 +imp 'GetMagnificationLensCtxInformation' GetMagnificationLensCtxInformation user32 1880 +imp 'GetMenu' GetMenu user32 1881 1 +imp 'GetMenuBarInfo' GetMenuBarInfo user32 1882 +imp 'GetMenuCheckMarkDimensions' GetMenuCheckMarkDimensions user32 1883 +imp 'GetMenuContextHelpId' GetMenuContextHelpId user32 1884 +imp 'GetMenuDefaultItem' GetMenuDefaultItem user32 1885 +imp 'GetMenuInfo' GetMenuInfo user32 1886 +imp 'GetMenuItemCount' GetMenuItemCount user32 1887 +imp 'GetMenuItemID' GetMenuItemID user32 1888 +imp 'GetMenuItemInfo' GetMenuItemInfoW user32 1890 +imp 'GetMenuItemRect' GetMenuItemRect user32 1891 +imp 'GetMenuState' GetMenuState user32 1892 +imp 'GetMenuString' GetMenuStringW user32 1894 +imp 'GetMessage' GetMessageW user32 1899 4 +imp 'GetMessageExtraInfo' GetMessageExtraInfo user32 1896 +imp 'GetMessagePos' GetMessagePos user32 1897 +imp 'GetMessageTime' GetMessageTime user32 1898 +imp 'GetMonitorInfo' GetMonitorInfoW user32 1901 +imp 'GetMouseMovePointsEx' GetMouseMovePointsEx user32 1902 +imp 'GetNextDlgGroupItem' GetNextDlgGroupItem user32 1903 +imp 'GetNextDlgTabItem' GetNextDlgTabItem user32 1904 +imp 'GetOpenClipboardWindow' GetOpenClipboardWindow user32 1905 +imp 'GetParent' GetParent user32 1906 1 +imp 'GetPhysicalCursorPos' GetPhysicalCursorPos user32 1907 +imp 'GetPointerCursorId' GetPointerCursorId user32 1908 +imp 'GetPointerDevice' GetPointerDevice user32 1909 +imp 'GetPointerDeviceCursors' GetPointerDeviceCursors user32 1910 +imp 'GetPointerDeviceProperties' GetPointerDeviceProperties user32 1911 +imp 'GetPointerDeviceRects' GetPointerDeviceRects user32 1912 +imp 'GetPointerDevices' GetPointerDevices user32 1913 +imp 'GetPointerFrameArrivalTimes' GetPointerFrameArrivalTimes user32 1914 +imp 'GetPointerFrameInfo' GetPointerFrameInfo user32 1915 +imp 'GetPointerFrameInfoHistory' GetPointerFrameInfoHistory user32 1916 +imp 'GetPointerFramePenInfo' GetPointerFramePenInfo user32 1917 +imp 'GetPointerFramePenInfoHistory' GetPointerFramePenInfoHistory user32 1918 +imp 'GetPointerFrameTouchInfo' GetPointerFrameTouchInfo user32 1919 +imp 'GetPointerFrameTouchInfoHistory' GetPointerFrameTouchInfoHistory user32 1920 +imp 'GetPointerInfo' GetPointerInfo user32 1921 +imp 'GetPointerInfoHistory' GetPointerInfoHistory user32 1922 +imp 'GetPointerInputTransform' GetPointerInputTransform user32 1923 +imp 'GetPointerPenInfo' GetPointerPenInfo user32 1924 +imp 'GetPointerPenInfoHistory' GetPointerPenInfoHistory user32 1925 +imp 'GetPointerTouchInfo' GetPointerTouchInfo user32 1926 +imp 'GetPointerTouchInfoHistory' GetPointerTouchInfoHistory user32 1927 +imp 'GetPointerType' GetPointerType user32 1928 +imp 'GetPriorityClipboardFormat' GetPriorityClipboardFormat user32 1929 +imp 'GetProcessDefaultLayout' GetProcessDefaultLayout user32 1930 +imp 'GetProcessDpiAwarenessInternal' GetProcessDpiAwarenessInternal user32 1931 +imp 'GetProcessUIContextInformation' GetProcessUIContextInformation user32 2521 +imp 'GetProcessWindowStation' GetProcessWindowStation user32 1932 +imp 'GetProgmanWindow' GetProgmanWindow user32 1933 +imp 'GetProp' GetPropW user32 1935 +imp 'GetQueueStatus' GetQueueStatus user32 1936 +imp 'GetRawInputBuffer' GetRawInputBuffer user32 1937 +imp 'GetRawInputData' GetRawInputData user32 1938 +imp 'GetRawInputDeviceInfo' GetRawInputDeviceInfoW user32 1940 +imp 'GetRawInputDeviceList' GetRawInputDeviceList user32 1941 +imp 'GetRawPointerDeviceData' GetRawPointerDeviceData user32 1942 +imp 'GetReasonTitleFromReasonCode' GetReasonTitleFromReasonCode user32 1943 +imp 'GetRegisteredRawInputDevices' GetRegisteredRawInputDevices user32 1944 +imp 'GetScrollBarInfo' GetScrollBarInfo user32 1945 +imp 'GetScrollInfo' GetScrollInfo user32 1946 +imp 'GetScrollPos' GetScrollPos user32 1947 +imp 'GetScrollRange' GetScrollRange user32 1948 +imp 'GetSendMessageReceiver' GetSendMessageReceiver user32 1949 +imp 'GetShellWindow' GetShellWindow user32 1950 0 +imp 'GetSubMenu' GetSubMenu user32 1951 +imp 'GetSysColor' GetSysColor user32 1952 +imp 'GetSysColorBrush' GetSysColorBrush user32 1953 +imp 'GetSystemDpiForProcess' GetSystemDpiForProcess user32 1954 +imp 'GetSystemMenu' GetSystemMenu user32 1955 2 +imp 'GetSystemMetrics' GetSystemMetrics user32 1956 +imp 'GetSystemMetricsForDpi' GetSystemMetricsForDpi user32 1957 +imp 'GetTabbedTextExtent' GetTabbedTextExtentW user32 1959 +imp 'GetTaskmanWindow' GetTaskmanWindow user32 1960 +imp 'GetThreadDesktop' GetThreadDesktop user32 1961 +imp 'GetThreadDpiAwarenessContext' GetThreadDpiAwarenessContext user32 1962 +imp 'GetThreadDpiHostingBehavior' GetThreadDpiHostingBehavior user32 1963 +imp 'GetTitleBarInfo' GetTitleBarInfo user32 1964 +imp 'GetTopLevelWindow' GetTopLevelWindow user32 1965 +imp 'GetTopWindow' GetTopWindow user32 1966 +imp 'GetTouchInputInfo' GetTouchInputInfo user32 1967 +imp 'GetUnpredictedMessagePos' GetUnpredictedMessagePos user32 1968 +imp 'GetUpdateRect' GetUpdateRect user32 1969 +imp 'GetUpdateRgn' GetUpdateRgn user32 1970 +imp 'GetUpdatedClipboardFormats' GetUpdatedClipboardFormats user32 1971 +imp 'GetUserObjectInformation' GetUserObjectInformationW user32 1973 +imp 'GetUserObjectSecurity' GetUserObjectSecurity user32 1974 +imp 'GetWinStationInfo' GetWinStationInfo user32 1975 +imp 'GetWindow' GetWindow user32 1976 2 +imp 'GetWindowBand' GetWindowBand user32 1977 +imp 'GetWindowCompositionAttribute' GetWindowCompositionAttribute user32 1978 +imp 'GetWindowCompositionInfo' GetWindowCompositionInfo user32 1979 +imp 'GetWindowContextHelpId' GetWindowContextHelpId user32 1980 +imp 'GetWindowDC' GetWindowDC user32 1981 +imp 'GetWindowDisplayAffinity' GetWindowDisplayAffinity user32 1982 +imp 'GetWindowDpiAwarenessContext' GetWindowDpiAwarenessContext user32 1983 +imp 'GetWindowDpiHostingBehavior' GetWindowDpiHostingBehavior user32 1984 +imp 'GetWindowFeedbackSetting' GetWindowFeedbackSetting user32 1985 +imp 'GetWindowInfo' GetWindowInfo user32 1986 +imp 'GetWindowLong' GetWindowLongW user32 1990 +imp 'GetWindowLongPtr' GetWindowLongPtrW user32 1989 +imp 'GetWindowMinimizeRect' GetWindowMinimizeRect user32 1991 +imp 'GetWindowModuleFileName' GetWindowModuleFileNameW user32 1994 +imp 'GetWindowPlacement' GetWindowPlacement user32 1995 2 +imp 'GetWindowProcessHandle' GetWindowProcessHandle user32 1996 +imp 'GetWindowRect' GetWindowRect user32 1997 2 +imp 'GetWindowRgn' GetWindowRgn user32 1998 +imp 'GetWindowRgnBox' GetWindowRgnBox user32 1999 +imp 'GetWindowRgnEx' GetWindowRgnEx user32 2000 +imp 'GetWindowText' GetWindowTextW user32 2007 3 +imp 'GetWindowTextLength' GetWindowTextLengthW user32 2006 +imp 'GetWindowThreadProcessId' GetWindowThreadProcessId user32 2008 +imp 'GetWindowWord' GetWindowWord user32 2009 +imp 'GhostWindowFromHungWindow' GhostWindowFromHungWindow user32 2011 +imp 'GrayString' GrayStringW user32 2013 +imp 'HandleDelegatedInput' HandleDelegatedInput user32 2505 +imp 'HideCaret' HideCaret user32 2014 +imp 'HiliteMenuItem' HiliteMenuItem user32 2015 +imp 'HungWindowFromGhostWindow' HungWindowFromGhostWindow user32 2016 +imp 'IMPGetIMEW' IMPGetIMEW user32 2018 +imp 'IMPQueryIMEW' IMPQueryIMEW user32 2020 +imp 'IMPSetIMEW' IMPSetIMEW user32 2022 +imp 'ImpersonateDdeClientWindow' ImpersonateDdeClientWindow user32 2023 +imp 'InSendMessage' InSendMessage user32 2024 +imp 'InSendMessageEx' InSendMessageEx user32 2025 +imp 'InflateRect' InflateRect user32 2026 +imp 'InheritWindowMonitor' InheritWindowMonitor user32 2027 +imp 'InitDManipHook' InitDManipHook user32 2028 +imp 'InitializeGenericHidInjection' InitializeGenericHidInjection user32 2029 +imp 'InitializeInputDeviceInjection' InitializeInputDeviceInjection user32 2030 +imp 'InitializeLpkHooks' InitializeLpkHooks user32 2031 +imp 'InitializePointerDeviceInjection' InitializePointerDeviceInjection user32 2032 +imp 'InitializePointerDeviceInjectionEx' InitializePointerDeviceInjectionEx user32 2033 +imp 'InitializeTouchInjection' InitializeTouchInjection user32 2034 +imp 'InjectDeviceInput' InjectDeviceInput user32 2035 +imp 'InjectGenericHidInput' InjectGenericHidInput user32 2036 +imp 'InjectKeyboardInput' InjectKeyboardInput user32 2037 +imp 'InjectMouseInput' InjectMouseInput user32 2038 +imp 'InjectPointerInput' InjectPointerInput user32 2039 +imp 'InjectTouchInput' InjectTouchInput user32 2040 +imp 'InsertMenu' InsertMenuW user32 2044 5 +imp 'InsertMenuItem' InsertMenuItemW user32 2043 +imp 'InternalGetWindowIcon' InternalGetWindowIcon user32 2045 +imp 'InternalGetWindowText' InternalGetWindowText user32 2046 +imp 'IntersectRect' IntersectRect user32 2047 +imp 'InvalidateRect' InvalidateRect user32 2048 3 +imp 'InvalidateRgn' InvalidateRgn user32 2049 +imp 'InvertRect' InvertRect user32 2050 +imp 'IsChild' IsChild user32 2059 2 +imp 'IsClipboardFormatAvailable' IsClipboardFormatAvailable user32 2060 +imp 'IsDialogMessage' IsDialogMessageW user32 2063 +imp 'IsDlgButtonChecked' IsDlgButtonChecked user32 2064 +imp 'IsGUIThread' IsGUIThread user32 2065 +imp 'IsHungAppWindow' IsHungAppWindow user32 2066 +imp 'IsIconic' IsIconic user32 2067 1 +imp 'IsImmersiveProcess' IsImmersiveProcess user32 2068 +imp 'IsInDesktopWindowBand' IsInDesktopWindowBand user32 2069 +imp 'IsMenu' IsMenu user32 2070 1 +imp 'IsMouseInPointerEnabled' IsMouseInPointerEnabled user32 2071 +imp 'IsOneCoreTransformMode' IsOneCoreTransformMode user32 2072 +imp 'IsProcessDPIAware' IsProcessDPIAware user32 2073 +imp 'IsQueueAttached' IsQueueAttached user32 2074 +imp 'IsRectEmpty' IsRectEmpty user32 2075 +imp 'IsSETEnabled' IsSETEnabled user32 2076 +imp 'IsServerSideWindow' IsServerSideWindow user32 2077 +imp 'IsThreadDesktopComposited' IsThreadDesktopComposited user32 2078 +imp 'IsThreadMessageQueueAttached' IsThreadMessageQueueAttached user32 2528 +imp 'IsThreadTSFEventAware' IsThreadTSFEventAware user32 2079 +imp 'IsTopLevelWindow' IsTopLevelWindow user32 2080 +imp 'IsTouchWindow' IsTouchWindow user32 2081 +imp 'IsValidDpiAwarenessContext' IsValidDpiAwarenessContext user32 2082 +imp 'IsWinEventHookInstalled' IsWinEventHookInstalled user32 2083 +imp 'IsWindow' IsWindow user32 2084 1 +imp 'IsWindowArranged' IsWindowArranged user32 2085 +imp 'IsWindowEnabled' IsWindowEnabled user32 2086 +imp 'IsWindowInDestroy' IsWindowInDestroy user32 2087 +imp 'IsWindowRedirectedForPrint' IsWindowRedirectedForPrint user32 2088 +imp 'IsWindowUnicode' IsWindowUnicode user32 2089 +imp 'IsWindowVisible' IsWindowVisible user32 2090 1 +imp 'IsWow64Message' IsWow64Message user32 2091 +imp 'IsZoomed' IsZoomed user32 2092 1 +imp 'KillTimer' KillTimer user32 2093 2 +imp 'LoadAccelerators' LoadAcceleratorsW user32 2095 +imp 'LoadBitmap' LoadBitmapW user32 2097 +imp 'LoadCursor' LoadCursorW user32 2101 2 +imp 'LoadCursorFromFile' LoadCursorFromFileW user32 2100 +imp 'LoadIcon' LoadIconW user32 2103 2 +imp 'LoadImage' LoadImageW user32 2105 6 +imp 'LoadKeyboardLayout' LoadKeyboardLayoutW user32 2108 +imp 'LoadKeyboardLayoutEx' LoadKeyboardLayoutEx user32 2107 +imp 'LoadLocalFonts' LoadLocalFonts user32 2109 +imp 'LoadMenu' LoadMenuW user32 2113 +imp 'LoadMenuIndirect' LoadMenuIndirectW user32 2112 +imp 'LoadRemoteFonts' LoadRemoteFonts user32 2114 +imp 'LockSetForegroundWindow' LockSetForegroundWindow user32 2117 +imp 'LockWindowStation' LockWindowStation user32 2118 +imp 'LockWindowUpdate' LockWindowUpdate user32 2119 +imp 'LockWorkStation' LockWorkStation user32 2120 +imp 'LogicalToPhysicalPoint' LogicalToPhysicalPoint user32 2121 +imp 'LogicalToPhysicalPointForPerMonitorDPI' LogicalToPhysicalPointForPerMonitorDPI user32 2122 +imp 'LookupIconIdFromDirectory' LookupIconIdFromDirectory user32 2123 +imp 'LookupIconIdFromDirectoryEx' LookupIconIdFromDirectoryEx user32 2124 +imp 'MBToWCSEx' MBToWCSEx user32 2125 +imp 'MBToWCSExt' MBToWCSExt user32 2126 +imp 'MB_GetString' MB_GetString user32 2127 +imp 'MITActivateInputProcessing' MITActivateInputProcessing user32 2128 +imp 'MITBindInputTypeToMonitors' MITBindInputTypeToMonitors user32 2129 +imp 'MITCoreMsgKGetConnectionHandle' MITCoreMsgKGetConnectionHandle user32 2130 +imp 'MITCoreMsgKOpenConnectionTo' MITCoreMsgKOpenConnectionTo user32 2131 +imp 'MITCoreMsgKSend' MITCoreMsgKSend user32 2132 +imp 'MITDeactivateInputProcessing' MITDeactivateInputProcessing user32 2133 +imp 'MITDisableMouseIntercept' MITDisableMouseIntercept user32 2134 +imp 'MITDispatchCompletion' MITDispatchCompletion user32 2135 +imp 'MITEnableMouseIntercept' MITEnableMouseIntercept user32 2136 +imp 'MITGetCursorUpdateHandle' MITGetCursorUpdateHandle user32 2137 +imp 'MITInjectLegacyISMTouchFrame' MITInjectLegacyISMTouchFrame user32 2138 +imp 'MITRegisterManipulationThread' MITRegisterManipulationThread user32 2139 +imp 'MITSetForegroundRoutingInfo' MITSetForegroundRoutingInfo user32 2140 +imp 'MITSetInputCallbacks' MITSetInputCallbacks user32 2141 +imp 'MITSetInputDelegationMode' MITSetInputDelegationMode user32 2142 +imp 'MITSetLastInputRecipient' MITSetLastInputRecipient user32 2143 +imp 'MITSetManipulationInputTarget' MITSetManipulationInputTarget user32 2144 +imp 'MITStopAndEndInertia' MITStopAndEndInertia user32 2145 +imp 'MITSynthesizeMouseInput' MITSynthesizeMouseInput user32 2146 +imp 'MITSynthesizeMouseWheel' MITSynthesizeMouseWheel user32 2147 +imp 'MITSynthesizeTouchInput' MITSynthesizeTouchInput user32 2148 +imp 'MITUpdateInputGlobals' MITUpdateInputGlobals user32 2149 +imp 'MITWaitForMultipleObjectsEx' MITWaitForMultipleObjectsEx user32 2150 +imp 'MakeThreadTSFEventAware' MakeThreadTSFEventAware user32 2151 +imp 'MapDialogRect' MapDialogRect user32 2152 +imp 'MapVirtualKey' MapVirtualKeyW user32 2156 +imp 'MapVirtualKeyEx' MapVirtualKeyExW user32 2155 3 +imp 'MapVisualRelativePoints' MapVisualRelativePoints user32 2157 +imp 'MapWindowPoints' MapWindowPoints user32 2158 +imp 'MenuItemFromPoint' MenuItemFromPoint user32 2159 +imp 'MenuWindowProc' MenuWindowProcW user32 2161 +imp 'MessageBeep' MessageBeep user32 2162 +imp 'MessageBox' MessageBoxW user32 2170 4 +imp 'MessageBoxEx' MessageBoxExW user32 2165 5 +imp 'MessageBoxIndirect' MessageBoxIndirectW user32 2167 +imp 'MessageBoxTimeout' MessageBoxTimeoutW user32 2169 +imp 'ModifyMenu' ModifyMenuW user32 2172 +imp 'MonitorFromPoint' MonitorFromPoint user32 2173 +imp 'MonitorFromRect' MonitorFromRect user32 2174 +imp 'MonitorFromWindow' MonitorFromWindow user32 2175 +imp 'MoveWindow' MoveWindow user32 2176 6 +imp 'MsgWaitForMultipleObjects' MsgWaitForMultipleObjects user32 2177 +imp 'MsgWaitForMultipleObjectsEx' MsgWaitForMultipleObjectsEx user32 2178 +imp 'NotifyOverlayWindow' NotifyOverlayWindow user32 2179 +imp 'NotifyWinEvent' NotifyWinEvent user32 2180 +imp 'OemKeyScan' OemKeyScan user32 2181 +imp 'OemToChar' OemToCharW user32 2185 +imp 'OemToCharBuff' OemToCharBuffW user32 2184 +imp 'OffsetRect' OffsetRect user32 2186 +imp 'OpenClipboard' OpenClipboard user32 2187 +imp 'OpenDesktop' OpenDesktopW user32 2189 +imp 'OpenIcon' OpenIcon user32 2190 +imp 'OpenInputDesktop' OpenInputDesktop user32 2191 +imp 'OpenThreadDesktop' OpenThreadDesktop user32 2192 +imp 'OpenWindowStation' OpenWindowStationW user32 2194 +imp 'PackDDElParam' PackDDElParam user32 2195 +imp 'PackTouchHitTestingProximityEvaluation' PackTouchHitTestingProximityEvaluation user32 2196 +imp 'PaintDesktop' PaintDesktop user32 2197 +imp 'PaintMenuBar' PaintMenuBar user32 2198 +imp 'PaintMonitor' PaintMonitor user32 2199 +imp 'PeekMessage' PeekMessageW user32 2201 5 +imp 'PhysicalToLogicalPoint' PhysicalToLogicalPoint user32 2202 +imp 'PhysicalToLogicalPointForPerMonitorDPI' PhysicalToLogicalPointForPerMonitorDPI user32 2203 +imp 'PostMessage' PostMessageW user32 2205 +imp 'PostQuitMessage' PostQuitMessage user32 2206 1 +imp 'PostThreadMessage' PostThreadMessageW user32 2208 +imp 'PrintWindow' PrintWindow user32 2209 +imp 'PrivateExtractIconEx' PrivateExtractIconExW user32 2211 +imp 'PrivateExtractIcons' PrivateExtractIconsW user32 2213 +imp 'PrivateRegisterICSProc' PrivateRegisterICSProc user32 2214 +imp 'PtInRect' PtInRect user32 2215 +imp 'QueryBSDRWindow' QueryBSDRWindow user32 2216 +imp 'QueryDisplayConfig' QueryDisplayConfig user32 2217 +imp 'QuerySendMessage' QuerySendMessage user32 2218 +imp 'RIMAddInputObserver' RIMAddInputObserver user32 2219 +imp 'RIMAreSiblingDevices' RIMAreSiblingDevices user32 2220 +imp 'RIMDeviceIoControl' RIMDeviceIoControl user32 2221 +imp 'RIMEnableMonitorMappingForDevice' RIMEnableMonitorMappingForDevice user32 2222 +imp 'RIMFreeInputBuffer' RIMFreeInputBuffer user32 2223 +imp 'RIMGetDevicePreparsedData' RIMGetDevicePreparsedData user32 2224 +imp 'RIMGetDevicePreparsedDataLockfree' RIMGetDevicePreparsedDataLockfree user32 2225 +imp 'RIMGetDeviceProperties' RIMGetDeviceProperties user32 2226 +imp 'RIMGetDevicePropertiesLockfree' RIMGetDevicePropertiesLockfree user32 2227 +imp 'RIMGetPhysicalDeviceRect' RIMGetPhysicalDeviceRect user32 2228 +imp 'RIMGetSourceProcessId' RIMGetSourceProcessId user32 2229 +imp 'RIMObserveNextInput' RIMObserveNextInput user32 2230 +imp 'RIMOnPnpNotification' RIMOnPnpNotification user32 2231 +imp 'RIMOnTimerNotification' RIMOnTimerNotification user32 2232 +imp 'RIMReadInput' RIMReadInput user32 2233 +imp 'RIMRegisterForInput' RIMRegisterForInput user32 2234 +imp 'RIMRemoveInputObserver' RIMRemoveInputObserver user32 2235 +imp 'RIMSetTestModeStatus' RIMSetTestModeStatus user32 2236 +imp 'RIMUnregisterForInput' RIMUnregisterForInput user32 2237 +imp 'RIMUpdateInputObserverRegistration' RIMUpdateInputObserverRegistration user32 2238 +imp 'RealChildWindowFromPoint' RealChildWindowFromPoint user32 2239 +imp 'RealGetWindowClass' RealGetWindowClassW user32 2242 +imp 'ReasonCodeNeedsBugID' ReasonCodeNeedsBugID user32 2243 +imp 'ReasonCodeNeedsComment' ReasonCodeNeedsComment user32 2244 +imp 'RecordShutdownReason' RecordShutdownReason user32 2245 +imp 'RedrawWindow' RedrawWindow user32 2246 4 +imp 'RegisterBSDRWindow' RegisterBSDRWindow user32 2247 +imp 'RegisterClass' RegisterClassW user32 2251 1 +imp 'RegisterClassEx' RegisterClassExW user32 2250 1 +imp 'RegisterClipboardFormat' RegisterClipboardFormatW user32 2253 +imp 'RegisterDManipHook' RegisterDManipHook user32 2254 +imp 'RegisterDeviceNotification' RegisterDeviceNotificationW user32 2256 +imp 'RegisterErrorReportingDialog' RegisterErrorReportingDialog user32 2257 +imp 'RegisterFrostWindow' RegisterFrostWindow user32 2258 +imp 'RegisterGhostWindow' RegisterGhostWindow user32 2259 +imp 'RegisterHotKey' RegisterHotKey user32 2260 +imp 'RegisterLogonProcess' RegisterLogonProcess user32 2261 +imp 'RegisterMessagePumpHook' RegisterMessagePumpHook user32 2262 +imp 'RegisterPointerDeviceNotifications' RegisterPointerDeviceNotifications user32 2263 +imp 'RegisterPointerInputTarget' RegisterPointerInputTarget user32 2264 +imp 'RegisterPointerInputTargetEx' RegisterPointerInputTargetEx user32 2265 +imp 'RegisterPowerSettingNotification' RegisterPowerSettingNotification user32 2266 +imp 'RegisterRawInputDevices' RegisterRawInputDevices user32 2267 +imp 'RegisterServicesProcess' RegisterServicesProcess user32 2268 +imp 'RegisterSessionPort' RegisterSessionPort user32 2269 +imp 'RegisterShellHookWindow' RegisterShellHookWindow user32 2270 +imp 'RegisterSuspendResumeNotification' RegisterSuspendResumeNotification user32 2271 +imp 'RegisterSystemThread' RegisterSystemThread user32 2272 +imp 'RegisterTasklist' RegisterTasklist user32 2273 +imp 'RegisterTouchHitTestingWindow' RegisterTouchHitTestingWindow user32 2274 +imp 'RegisterTouchWindow' RegisterTouchWindow user32 2275 +imp 'RegisterUserApiHook' RegisterUserApiHook user32 2276 +imp 'RegisterWindowMessage' RegisterWindowMessageW user32 2278 +imp 'ReleaseCapture' ReleaseCapture user32 2279 0 +imp 'ReleaseDC' ReleaseDC user32 2280 2 +imp 'ReleaseDwmHitTestWaiters' ReleaseDwmHitTestWaiters user32 2281 +imp 'RemoveClipboardFormatListener' RemoveClipboardFormatListener user32 2282 +imp 'RemoveInjectionDevice' RemoveInjectionDevice user32 2283 +imp 'RemoveMenu' RemoveMenu user32 2284 +imp 'RemoveProp' RemovePropW user32 2286 +imp 'RemoveThreadTSFEventAwareness' RemoveThreadTSFEventAwareness user32 2287 +imp 'ReplyMessage' ReplyMessage user32 2288 +imp 'ReportInertia' ReportInertia user32 2551 +imp 'ResolveDesktopForWOW' ResolveDesktopForWOW user32 2289 +imp 'ReuseDDElParam' ReuseDDElParam user32 2290 +imp 'ScreenToClient' ScreenToClient user32 2291 +imp 'ScrollChildren' ScrollChildren user32 2292 +imp 'ScrollDC' ScrollDC user32 2293 +imp 'ScrollWindow' ScrollWindow user32 2294 +imp 'ScrollWindowEx' ScrollWindowEx user32 2295 +imp 'SendDlgItemMessage' SendDlgItemMessageW user32 2297 +imp 'SendIMEMessageEx' SendIMEMessageExW user32 2299 +imp 'SendInput' SendInput user32 2300 +imp 'SendMessage' SendMessageW user32 2306 4 +imp 'SendMessageCallback' SendMessageCallbackW user32 2303 +imp 'SendMessageTimeout' SendMessageTimeoutW user32 2305 +imp 'SendNotifyMessage' SendNotifyMessageW user32 2308 +imp 'SetActiveWindow' SetActiveWindow user32 2309 +imp 'SetCapture' SetCapture user32 2310 1 +imp 'SetCaretBlinkTime' SetCaretBlinkTime user32 2311 +imp 'SetCaretPos' SetCaretPos user32 2312 +imp 'SetClassLong' SetClassLongW user32 2316 3 +imp 'SetClassLongPtr' SetClassLongPtrW user32 2315 +imp 'SetClassWord' SetClassWord user32 2317 +imp 'SetClipboardData' SetClipboardData user32 2318 +imp 'SetClipboardViewer' SetClipboardViewer user32 2319 +imp 'SetCoalescableTimer' SetCoalescableTimer user32 2320 +imp 'SetCoreWindow' SetCoreWindow user32 2571 +imp 'SetCursor' SetCursor user32 2321 1 +imp 'SetCursorContents' SetCursorContents user32 2322 +imp 'SetCursorPos' SetCursorPos user32 2323 +imp 'SetDebugErrorLevel' SetDebugErrorLevel user32 2324 +imp 'SetDeskWallpaper' SetDeskWallpaper user32 2325 +imp 'SetDesktopColorTransform' SetDesktopColorTransform user32 2326 +imp 'SetDialogControlDpiChangeBehavior' SetDialogControlDpiChangeBehavior user32 2327 +imp 'SetDialogDpiChangeBehavior' SetDialogDpiChangeBehavior user32 2328 +imp 'SetDisplayAutoRotationPreferences' SetDisplayAutoRotationPreferences user32 2329 +imp 'SetDisplayConfig' SetDisplayConfig user32 2330 +imp 'SetDlgItemInt' SetDlgItemInt user32 2331 +imp 'SetDlgItemText' SetDlgItemTextW user32 2333 +imp 'SetDoubleClickTime' SetDoubleClickTime user32 2334 +imp 'SetFeatureReportResponse' SetFeatureReportResponse user32 2335 +imp 'SetFocus' SetFocus user32 2336 +imp 'SetForegroundWindow' SetForegroundWindow user32 2337 +imp 'SetGestureConfig' SetGestureConfig user32 2338 +imp 'SetInternalWindowPos' SetInternalWindowPos user32 2339 +imp 'SetKeyboardState' SetKeyboardState user32 2340 +imp 'SetLastErrorEx' SetLastErrorEx user32 2341 +imp 'SetLayeredWindowAttributes' SetLayeredWindowAttributes user32 2342 +imp 'SetMagnificationDesktopColorEffect' SetMagnificationDesktopColorEffect user32 2343 +imp 'SetMagnificationDesktopMagnification' SetMagnificationDesktopMagnification user32 2344 +imp 'SetMagnificationDesktopSamplingMode' SetMagnificationDesktopSamplingMode user32 2345 +imp 'SetMagnificationLensCtxInformation' SetMagnificationLensCtxInformation user32 2346 +imp 'SetMenu' SetMenu user32 2347 +imp 'SetMenuContextHelpId' SetMenuContextHelpId user32 2348 +imp 'SetMenuDefaultItem' SetMenuDefaultItem user32 2349 +imp 'SetMenuInfo' SetMenuInfo user32 2350 +imp 'SetMenuItemBitmaps' SetMenuItemBitmaps user32 2351 +imp 'SetMenuItemInfo' SetMenuItemInfoW user32 2353 +imp 'SetMessageExtraInfo' SetMessageExtraInfo user32 2354 +imp 'SetMessageQueue' SetMessageQueue user32 2355 +imp 'SetMirrorRendering' SetMirrorRendering user32 2356 +imp 'SetParent' SetParent user32 2357 2 +imp 'SetPhysicalCursorPos' SetPhysicalCursorPos user32 2358 +imp 'SetProcessDPIAware' SetProcessDPIAware user32 2359 +imp 'SetProcessDefaultLayout' SetProcessDefaultLayout user32 2360 +imp 'SetProcessDpiAwarenessContext' SetProcessDpiAwarenessContext user32 2361 +imp 'SetProcessDpiAwarenessInternal' SetProcessDpiAwarenessInternal user32 2362 +imp 'SetProcessRestrictionExemption' SetProcessRestrictionExemption user32 2363 +imp 'SetProcessWindowStation' SetProcessWindowStation user32 2364 +imp 'SetProgmanWindow' SetProgmanWindow user32 2365 +imp 'SetProp' SetPropW user32 2367 +imp 'SetRect' SetRect user32 2368 +imp 'SetRectEmpty' SetRectEmpty user32 2369 +imp 'SetScrollInfo' SetScrollInfo user32 2370 +imp 'SetScrollPos' SetScrollPos user32 2371 +imp 'SetScrollRange' SetScrollRange user32 2372 +imp 'SetShellWindow' SetShellWindow user32 2373 +imp 'SetShellWindowEx' SetShellWindowEx user32 2374 +imp 'SetSysColors' SetSysColors user32 2375 +imp 'SetSysColorsTemp' SetSysColorsTemp user32 2376 +imp 'SetSystemCursor' SetSystemCursor user32 2377 +imp 'SetSystemMenu' SetSystemMenu user32 2378 +imp 'SetTaskmanWindow' SetTaskmanWindow user32 2379 +imp 'SetThreadDesktop' SetThreadDesktop user32 2380 +imp 'SetThreadDpiAwarenessContext' SetThreadDpiAwarenessContext user32 2381 +imp 'SetThreadDpiHostingBehavior' SetThreadDpiHostingBehavior user32 2382 +imp 'SetThreadInputBlocked' SetThreadInputBlocked user32 2383 +imp 'SetTimer' SetTimer user32 2384 4 +imp 'SetUserObjectInformation' SetUserObjectInformationW user32 2386 +imp 'SetUserObjectSecurity' SetUserObjectSecurity user32 2387 +imp 'SetWinEventHook' SetWinEventHook user32 2388 +imp 'SetWindowBand' SetWindowBand user32 2389 +imp 'SetWindowCompositionAttribute' SetWindowCompositionAttribute user32 2390 +imp 'SetWindowCompositionTransition' SetWindowCompositionTransition user32 2391 +imp 'SetWindowContextHelpId' SetWindowContextHelpId user32 2392 +imp 'SetWindowDisplayAffinity' SetWindowDisplayAffinity user32 2393 +imp 'SetWindowFeedbackSetting' SetWindowFeedbackSetting user32 2394 +imp 'SetWindowLong' SetWindowLongW user32 2398 3 +imp 'SetWindowLongPtr' SetWindowLongPtrW user32 2397 +imp 'SetWindowPlacement' SetWindowPlacement user32 2399 2 +imp 'SetWindowPos' SetWindowPos user32 2400 7 +imp 'SetWindowRgn' SetWindowRgn user32 2401 +imp 'SetWindowRgnEx' SetWindowRgnEx user32 2402 +imp 'SetWindowStationUser' SetWindowStationUser user32 2403 +imp 'SetWindowText' SetWindowTextW user32 2405 2 +imp 'SetWindowWord' SetWindowWord user32 2406 +imp 'SetWindowsHook' SetWindowsHookW user32 2410 2 +imp 'SetWindowsHookEx' SetWindowsHookExW user32 2409 4 +imp 'ShowCaret' ShowCaret user32 2411 1 +imp 'ShowCursor' ShowCursor user32 2412 1 +imp 'ShowOwnedPopups' ShowOwnedPopups user32 2413 +imp 'ShowScrollBar' ShowScrollBar user32 2414 +imp 'ShowStartGlass' ShowStartGlass user32 2415 +imp 'ShowSystemCursor' ShowSystemCursor user32 2416 +imp 'ShowWindow' ShowWindow user32 2417 2 +imp 'ShowWindowAsync' ShowWindowAsync user32 2418 +imp 'ShutdownBlockReasonCreate' ShutdownBlockReasonCreate user32 2419 +imp 'ShutdownBlockReasonDestroy' ShutdownBlockReasonDestroy user32 2420 +imp 'ShutdownBlockReasonQuery' ShutdownBlockReasonQuery user32 2421 +imp 'SignalRedirectionStartComplete' SignalRedirectionStartComplete user32 2422 +imp 'SkipPointerFrameMessages' SkipPointerFrameMessages user32 2423 +imp 'SoftModalMessageBox' SoftModalMessageBox user32 2424 +imp 'SoundSentry' SoundSentry user32 2425 +imp 'SubtractRect' SubtractRect user32 2426 +imp 'SwapMouseButton' SwapMouseButton user32 2427 +imp 'SwitchDesktop' SwitchDesktop user32 2428 +imp 'SwitchDesktopWithFade' SwitchDesktopWithFade user32 2429 +imp 'SwitchToThisWindow' SwitchToThisWindow user32 2430 +imp 'SystemParametersInfo' SystemParametersInfoW user32 2433 +imp 'SystemParametersInfoForDpi' SystemParametersInfoForDpi user32 2432 +imp 'TabbedTextOut' TabbedTextOutW user32 2435 +imp 'TileChildWindows' TileChildWindows user32 2436 +imp 'TileWindows' TileWindows user32 2437 +imp 'ToAscii' ToAscii user32 2438 +imp 'ToAsciiEx' ToAsciiEx user32 2439 +imp 'ToUnicode' ToUnicode user32 2440 +imp 'ToUnicodeEx' ToUnicodeEx user32 2441 +imp 'TrackMouseEvent' TrackMouseEvent user32 2442 +imp 'TrackPopupMenu' TrackPopupMenu user32 2443 7 +imp 'TrackPopupMenuEx' TrackPopupMenuEx user32 2444 +imp 'TranslateAccelerator' TranslateAcceleratorW user32 2447 +imp 'TranslateMDISysAccel' TranslateMDISysAccel user32 2448 +imp 'TranslateMessage' TranslateMessage user32 2449 1 +imp 'TranslateMessageEx' TranslateMessageEx user32 2450 +imp 'UndelegateInput' UndelegateInput user32 2504 +imp 'UnhookWinEvent' UnhookWinEvent user32 2451 +imp 'UnhookWindowsHook' UnhookWindowsHook user32 2452 2 +imp 'UnhookWindowsHookEx' UnhookWindowsHookEx user32 2453 1 +imp 'UnionRect' UnionRect user32 2454 +imp 'UnloadKeyboardLayout' UnloadKeyboardLayout user32 2455 +imp 'UnlockWindowStation' UnlockWindowStation user32 2456 +imp 'UnpackDDElParam' UnpackDDElParam user32 2457 +imp 'UnregisterClass' UnregisterClassW user32 2459 +imp 'UnregisterDeviceNotification' UnregisterDeviceNotification user32 2460 +imp 'UnregisterHotKey' UnregisterHotKey user32 2461 +imp 'UnregisterMessagePumpHook' UnregisterMessagePumpHook user32 2462 +imp 'UnregisterPointerInputTarget' UnregisterPointerInputTarget user32 2463 +imp 'UnregisterPointerInputTargetEx' UnregisterPointerInputTargetEx user32 2464 +imp 'UnregisterPowerSettingNotification' UnregisterPowerSettingNotification user32 2465 +imp 'UnregisterSessionPort' UnregisterSessionPort user32 2466 +imp 'UnregisterSuspendResumeNotification' UnregisterSuspendResumeNotification user32 2467 +imp 'UnregisterTouchWindow' UnregisterTouchWindow user32 2468 +imp 'UnregisterUserApiHook' UnregisterUserApiHook user32 2469 +imp 'UpdateDefaultDesktopThumbnail' UpdateDefaultDesktopThumbnail user32 2470 +imp 'UpdateLayeredWindow' UpdateLayeredWindow user32 2471 +imp 'UpdateLayeredWindowIndirect' UpdateLayeredWindowIndirect user32 2472 +imp 'UpdatePerUserSystemParameters' UpdatePerUserSystemParameters user32 2473 +imp 'UpdateWindow' UpdateWindow user32 2474 1 +imp 'UpdateWindowInputSinkHints' UpdateWindowInputSinkHints user32 2475 +imp 'User32InitializeImmEntryTable' User32InitializeImmEntryTable user32 2476 +imp 'UserClientDllInitialize' UserClientDllInitialize user32 2477 +imp 'UserHandleGrantAccess' UserHandleGrantAccess user32 2478 +imp 'UserLpkPSMTextOut' UserLpkPSMTextOut user32 2479 +imp 'UserLpkTabbedTextOut' UserLpkTabbedTextOut user32 2480 +imp 'UserRealizePalette' UserRealizePalette user32 2481 +imp 'UserRegisterWowHandlers' UserRegisterWowHandlers user32 2482 +imp 'VRipOutput' VRipOutput user32 2483 +imp 'VTagOutput' VTagOutput user32 2484 +imp 'ValidateRect' ValidateRect user32 2485 +imp 'ValidateRgn' ValidateRgn user32 2486 +imp 'VkKeyScan' VkKeyScanW user32 2490 +imp 'VkKeyScanEx' VkKeyScanExW user32 2489 +imp 'WCSToMBEx' WCSToMBEx user32 2491 +imp 'WINNLSEnableIME' WINNLSEnableIME user32 2492 +imp 'WINNLSGetEnableStatus' WINNLSGetEnableStatus user32 2493 +imp 'WINNLSGetIMEHotkey' WINNLSGetIMEHotkey user32 2494 +imp 'WaitForInputIdle' WaitForInputIdle user32 2495 2 +imp 'WaitForRedirectionStartComplete' WaitForRedirectionStartComplete user32 2496 +imp 'WaitMessage' WaitMessage user32 2497 +imp 'WinHelp' WinHelpW user32 2499 +imp 'WindowFromDC' WindowFromDC user32 2500 +imp 'WindowFromPhysicalPoint' WindowFromPhysicalPoint user32 2501 +imp 'WindowFromPoint' WindowFromPoint user32 2502 + +# GDI32.DLL +# +# Name Actual DLL Hint Arity +imp 'AbortDoc' AbortDoc gdi32 1011 +imp 'AbortPath' AbortPath gdi32 1012 +imp 'AddFontMemResourceEx' AddFontMemResourceEx gdi32 1017 +imp 'AddFontResource' AddFontResourceW gdi32 1022 +imp 'AddFontResourceEx' AddFontResourceExW gdi32 1020 +imp 'AddFontResourceTracking' AddFontResourceTracking gdi32 1021 +imp 'AngleArc' AngleArc gdi32 1023 +imp 'AnimatePalette' AnimatePalette gdi32 1024 +imp 'AnyLinkedFonts' AnyLinkedFonts gdi32 1025 +imp 'Arc' Arc gdi32 1026 +imp 'ArcTo' ArcTo gdi32 1027 +imp 'BRUSHOBJ_hGetColorTransform' BRUSHOBJ_hGetColorTransform gdi32 1028 +imp 'BRUSHOBJ_pvAllocRbrush' BRUSHOBJ_pvAllocRbrush gdi32 1029 +imp 'BRUSHOBJ_pvGetRbrush' BRUSHOBJ_pvGetRbrush gdi32 1030 +imp 'BRUSHOBJ_ulGetBrushColor' BRUSHOBJ_ulGetBrushColor gdi32 1031 +imp 'BeginGdiRendering' BeginGdiRendering gdi32 1032 +imp 'BeginPath' BeginPath gdi32 1033 +imp 'BitBlt' BitBlt gdi32 1034 9 +imp 'CLIPOBJ_bEnum' CLIPOBJ_bEnum gdi32 1035 +imp 'CLIPOBJ_cEnumStart' CLIPOBJ_cEnumStart gdi32 1036 +imp 'CLIPOBJ_ppoGetPath' CLIPOBJ_ppoGetPath gdi32 1037 +imp 'CancelDC' CancelDC gdi32 1038 +imp 'CheckColorsInGamut' CheckColorsInGamut gdi32 1039 +imp 'ChoosePixelFormat' ChoosePixelFormat gdi32 1040 2 +imp 'Chord' Chord gdi32 1041 +imp 'ClearBitmapAttributes' ClearBitmapAttributes gdi32 1042 +imp 'ClearBrushAttributes' ClearBrushAttributes gdi32 1043 +imp 'CloseEnhMetaFile' CloseEnhMetaFile gdi32 1044 +imp 'CloseFigure' CloseFigure gdi32 1045 +imp 'CloseMetaFile' CloseMetaFile gdi32 1046 +imp 'ColorCorrectPalette' ColorCorrectPalette gdi32 1047 +imp 'ColorMatchToTarget' ColorMatchToTarget gdi32 1048 +imp 'CombineRgn' CombineRgn gdi32 1049 +imp 'CombineTransform' CombineTransform gdi32 1050 +imp 'ConfigureOPMProtectedOutput' ConfigureOPMProtectedOutput gdi32 1051 +imp 'CopyEnhMetaFile' CopyEnhMetaFileW gdi32 1053 +imp 'CopyMetaFile' CopyMetaFileW gdi32 1055 +imp 'CreateBitmap' CreateBitmap gdi32 1056 5 +imp 'CreateBitmapFromDxSurface' CreateBitmapFromDxSurface gdi32 1057 +imp 'CreateBitmapFromDxSurface2' CreateBitmapFromDxSurface2 gdi32 1058 +imp 'CreateBitmapIndirect' CreateBitmapIndirect gdi32 1059 +imp 'CreateBrushIndirect' CreateBrushIndirect gdi32 1060 +imp 'CreateColorSpace' CreateColorSpaceW gdi32 1062 +imp 'CreateCompatibleBitmap' CreateCompatibleBitmap gdi32 1063 3 +imp 'CreateCompatibleDC' CreateCompatibleDC gdi32 1064 1 +imp 'CreateDCEx' CreateDCExW gdi32 2000 +imp 'CreateDCW' CreateDCW gdi32 1066 +imp 'CreateDIBPatternBrush' CreateDIBPatternBrush gdi32 1067 +imp 'CreateDIBPatternBrushPt' CreateDIBPatternBrushPt gdi32 1068 +imp 'CreateDIBSection' CreateDIBSection gdi32 1069 6 +imp 'CreateDIBitmap' CreateDIBitmap gdi32 1070 +imp 'CreateDPIScaledDIBSection' CreateDPIScaledDIBSection gdi32 1071 +imp 'CreateDiscardableBitmap' CreateDiscardableBitmap gdi32 1072 +imp 'CreateEllipticRgn' CreateEllipticRgn gdi32 1073 +imp 'CreateEllipticRgnIndirect' CreateEllipticRgnIndirect gdi32 1074 +imp 'CreateEnhMetaFile' CreateEnhMetaFileW gdi32 1076 +imp 'CreateFont' CreateFontW gdi32 1082 +imp 'CreateFontIndirect' CreateFontIndirectW gdi32 1081 +imp 'CreateFontIndirectEx' CreateFontIndirectExW gdi32 1080 +imp 'CreateHalftonePalette' CreateHalftonePalette gdi32 1083 +imp 'CreateHatchBrush' CreateHatchBrush gdi32 1084 +imp 'CreateICW' CreateICW gdi32 1086 +imp 'CreateMetaFile' CreateMetaFileW gdi32 1088 +imp 'CreateOPMProtectedOutput' CreateOPMProtectedOutput gdi32 1089 +imp 'CreateOPMProtectedOutputs' CreateOPMProtectedOutputs gdi32 1090 +imp 'CreatePalette' CreatePalette gdi32 1091 +imp 'CreatePatternBrush' CreatePatternBrush gdi32 1092 +imp 'CreatePen' CreatePen gdi32 1093 +imp 'CreatePenIndirect' CreatePenIndirect gdi32 1094 +imp 'CreatePolyPolygonRgn' CreatePolyPolygonRgn gdi32 1095 +imp 'CreatePolygonRgn' CreatePolygonRgn gdi32 1096 +imp 'CreateRectRgn' CreateRectRgn gdi32 1097 4 +imp 'CreateRectRgnIndirect' CreateRectRgnIndirect gdi32 1098 +imp 'CreateRoundRectRgn' CreateRoundRectRgn gdi32 1099 +imp 'CreateScalableFontResource' CreateScalableFontResourceW gdi32 1101 +imp 'CreateSessionMappedDIBSection' CreateSessionMappedDIBSection gdi32 1102 +imp 'CreateSolidBrush' CreateSolidBrush gdi32 1103 imp 'D3DKMTAbandonSwapChain' D3DKMTAbandonSwapChain gdi32 1104 imp 'D3DKMTAcquireKeyedMutex' D3DKMTAcquireKeyedMutex gdi32 1105 imp 'D3DKMTAcquireKeyedMutex2' D3DKMTAcquireKeyedMutex2 gdi32 1106 @@ -1034,13 +3244,6 @@ imp 'D3DKMTWaitForSynchronizationObjectFromCpu' D3DKMTWaitForSynchronizationObj imp 'D3DKMTWaitForSynchronizationObjectFromGpu' D3DKMTWaitForSynchronizationObjectFromGpu gdi32 1312 imp 'D3DKMTWaitForVerticalBlankEvent' D3DKMTWaitForVerticalBlankEvent gdi32 1313 imp 'D3DKMTWaitForVerticalBlankEvent2' D3DKMTWaitForVerticalBlankEvent2 gdi32 1314 -imp 'DAD_AutoScroll' DAD_AutoScroll shell32 129 -imp 'DAD_DragEnterEx' DAD_DragEnterEx shell32 131 -imp 'DAD_DragEnterEx2' DAD_DragEnterEx2 shell32 22 -imp 'DAD_DragLeave' DAD_DragLeave shell32 132 -imp 'DAD_DragMove' DAD_DragMove shell32 134 -imp 'DAD_SetDragImage' DAD_SetDragImage shell32 136 -imp 'DAD_ShowDragImage' DAD_ShowDragImage shell32 137 imp 'DDCCIGetCapabilitiesString' DDCCIGetCapabilitiesString gdi32 1315 imp 'DDCCIGetCapabilitiesStringLength' DDCCIGetCapabilitiesStringLength gdi32 1316 imp 'DDCCIGetTimingReport' DDCCIGetTimingReport gdi32 1317 @@ -1048,29 +3251,6 @@ imp 'DDCCIGetVCPFeature' DDCCIGetVCPFeature gdi32 1318 imp 'DDCCISaveCurrentSettings' DDCCISaveCurrentSettings gdi32 1319 imp 'DDCCISetVCPFeature' DDCCISetVCPFeature gdi32 1320 imp 'DPtoLP' DPtoLP gdi32 1321 -imp 'DWMBindCursorToOutputConfig' DWMBindCursorToOutputConfig user32 1633 -imp 'DWMCommitInputSystemOutputConfig' DWMCommitInputSystemOutputConfig user32 1634 -imp 'DWMSetCursorOrientation' DWMSetCursorOrientation user32 1635 -imp 'DWMSetInputSystemOutputConfig' DWMSetInputSystemOutputConfig user32 1636 -imp 'DbgBreakPoint' DbgBreakPoint ntdll 41 -imp 'DbgPrint' DbgPrint ntdll 42 -imp 'DbgPrintEx' DbgPrintEx ntdll 43 -imp 'DbgPrintReturnControlC' DbgPrintReturnControlC ntdll 44 -imp 'DbgPrompt' DbgPrompt ntdll 45 -imp 'DbgQueryDebugFilterState' DbgQueryDebugFilterState ntdll 46 -imp 'DbgSetDebugFilterState' DbgSetDebugFilterState ntdll 47 -imp 'DbgUiConnectToDbg' DbgUiConnectToDbg ntdll 48 -imp 'DbgUiContinue' DbgUiContinue ntdll 49 -imp 'DbgUiConvertStateChangeStructure' DbgUiConvertStateChangeStructure ntdll 50 -imp 'DbgUiConvertStateChangeStructureEx' DbgUiConvertStateChangeStructureEx ntdll 51 -imp 'DbgUiDebugActiveProcess' DbgUiDebugActiveProcess ntdll 52 -imp 'DbgUiGetThreadDebugObject' DbgUiGetThreadDebugObject ntdll 53 -imp 'DbgUiIssueRemoteBreakin' DbgUiIssueRemoteBreakin ntdll 54 -imp 'DbgUiRemoteBreakin' DbgUiRemoteBreakin ntdll 55 -imp 'DbgUiSetThreadDebugObject' DbgUiSetThreadDebugObject ntdll 56 -imp 'DbgUiStopDebugging' DbgUiStopDebugging ntdll 57 -imp 'DbgUiWaitStateChange' DbgUiWaitStateChange ntdll 58 -imp 'DbgUserBreakPoint' DbgUserBreakPoint ntdll 59 imp 'DdCreateFullscreenSprite' DdCreateFullscreenSprite gdi32 1322 imp 'DdDestroyFullscreenSprite' DdDestroyFullscreenSprite gdi32 1323 imp 'DdEntry0' DdEntry0 gdi32 1324 @@ -1132,258 +3312,24 @@ imp 'DdEntry8' DdEntry8 gdi32 1379 imp 'DdEntry9' DdEntry9 gdi32 1380 imp 'DdNotifyFullscreenSpriteUpdate' DdNotifyFullscreenSpriteUpdate gdi32 1381 imp 'DdQueryVisRgnUniqueness' DdQueryVisRgnUniqueness gdi32 1382 -imp 'DdeAbandonTransaction' DdeAbandonTransaction user32 1637 -imp 'DdeAccessData' DdeAccessData user32 1638 -imp 'DdeAddData' DdeAddData user32 1639 -imp 'DdeClientTransaction' DdeClientTransaction user32 1640 -imp 'DdeCmpStringHandles' DdeCmpStringHandles user32 1641 -imp 'DdeConnect' DdeConnect user32 1642 -imp 'DdeConnectList' DdeConnectList user32 1643 -imp 'DdeCreateDataHandle' DdeCreateDataHandle user32 1644 -imp 'DdeCreateStringHandleA' DdeCreateStringHandleA user32 1645 -imp 'DdeCreateStringHandle' DdeCreateStringHandleW user32 1646 -imp 'DdeDisconnect' DdeDisconnect user32 1647 -imp 'DdeDisconnectList' DdeDisconnectList user32 1648 -imp 'DdeEnableCallback' DdeEnableCallback user32 1649 -imp 'DdeFreeDataHandle' DdeFreeDataHandle user32 1650 -imp 'DdeFreeStringHandle' DdeFreeStringHandle user32 1651 -imp 'DdeGetData' DdeGetData user32 1652 -imp 'DdeGetLastError' DdeGetLastError user32 1653 -imp 'DdeGetQualityOfService' DdeGetQualityOfService user32 1654 -imp 'DdeImpersonateClient' DdeImpersonateClient user32 1655 -imp 'DdeInitializeA' DdeInitializeA user32 1656 -imp 'DdeInitialize' DdeInitializeW user32 1657 -imp 'DdeKeepStringHandle' DdeKeepStringHandle user32 1658 -imp 'DdeNameService' DdeNameService user32 1659 -imp 'DdePostAdvise' DdePostAdvise user32 1660 -imp 'DdeQueryConvInfo' DdeQueryConvInfo user32 1661 -imp 'DdeQueryNextServer' DdeQueryNextServer user32 1662 -imp 'DdeQueryStringA' DdeQueryStringA user32 1663 -imp 'DdeQueryString' DdeQueryStringW user32 1664 -imp 'DdeReconnect' DdeReconnect user32 1665 -imp 'DdeSetQualityOfService' DdeSetQualityOfService user32 1666 -imp 'DdeSetUserHandle' DdeSetUserHandle user32 1667 -imp 'DdeUnaccessData' DdeUnaccessData user32 1668 -imp 'DdeUninitialize' DdeUninitialize user32 1669 -imp 'DeactivateActCtx' DeactivateActCtx kernel32 0 # KernelBase -imp 'DeactivateActCtxWorker' DeactivateActCtxWorker kernel32 259 -imp 'DebugActiveProcess' DebugActiveProcess kernel32 0 1 # KernelBase -imp 'DebugActiveProcessStop' DebugActiveProcessStop kernel32 0 1 # KernelBase -imp 'DebugBreakProcess' DebugBreakProcess kernel32 263 1 -imp 'DebugSetProcessKillOnExit' DebugSetProcessKillOnExit kernel32 264 -imp 'DecryptFileA' DecryptFileA advapi32 1235 -imp 'DecryptFile' DecryptFileW advapi32 1236 -imp 'DefFrameProcA' DefFrameProcA user32 1672 -imp 'DefFrameProc' DefFrameProcW user32 1673 -imp 'DefMDIChildProcA' DefMDIChildProcA user32 1674 -imp 'DefMDIChildProc' DefMDIChildProcW user32 1675 -imp 'DefRawInputProc' DefRawInputProc user32 1676 -imp 'DeferWindowPos' DeferWindowPos user32 1679 -imp 'DeferWindowPosAndBand' DeferWindowPosAndBand user32 1680 -imp 'DefineDosDeviceA' DefineDosDeviceA kernel32 267 -imp 'DefineDosDevice' DefineDosDeviceW kernel32 0 # KernelBase -imp 'DelayLoadFailureHook' DelayLoadFailureHook KernelBase 246 -imp 'DelayLoadFailureHookLookup' DelayLoadFailureHookLookup KernelBase 247 -imp 'DelegateInput' DelegateInput user32 2503 -imp 'DeleteAce' DeleteAce advapi32 0 # KernelBase -imp 'DeleteAtom' DeleteAtom kernel32 270 -imp 'DeleteBoundaryDescriptor' DeleteBoundaryDescriptor kernel32 0 # KernelBase imp 'DeleteColorSpace' DeleteColorSpace gdi32 1383 imp 'DeleteDC' DeleteDC gdi32 1384 1 -imp 'DeleteEnclave' DeleteEnclave KernelBase 251 imp 'DeleteEnhMetaFile' DeleteEnhMetaFile gdi32 1385 -imp 'DeleteFiber' DeleteFiber kernel32 0 # KernelBase -imp 'DeleteFile' DeleteFileW kernel32 0 1 # KernelBase -imp 'DeleteFileA' DeleteFileA kernel32 0 1 # KernelBase -imp 'DeleteFileTransactedA' DeleteFileTransactedA kernel32 275 -imp 'DeleteFileTransacted' DeleteFileTransactedW kernel32 276 -imp 'DeleteMenu' DeleteMenu user32 1681 3 imp 'DeleteMetaFile' DeleteMetaFile gdi32 1386 imp 'DeleteObject' DeleteObject gdi32 1387 1 -imp 'DeleteProcThreadAttributeList' DeleteProcThreadAttributeList kernel32 0 1 # KernelBase -imp 'DeleteService' DeleteService advapi32 1238 -imp 'DeleteStateAtomValue' DeleteStateAtomValue KernelBase 256 -imp 'DeleteStateContainer' DeleteStateContainer KernelBase 257 -imp 'DeleteStateContainerValue' DeleteStateContainerValue KernelBase 258 -imp 'DeleteSynchronizationBarrier' DeleteSynchronizationBarrier kernel32 279 -imp 'DeleteTimerQueue' DeleteTimerQueue kernel32 280 -imp 'DeleteTimerQueueEx' DeleteTimerQueueEx kernel32 0 # KernelBase -imp 'DeleteTimerQueueTimer' DeleteTimerQueueTimer kernel32 0 # KernelBase -imp 'DeleteUmsCompletionList' DeleteUmsCompletionList kernel32 283 -imp 'DeleteUmsThreadContext' DeleteUmsThreadContext kernel32 284 -imp 'DeleteVolumeMountPointA' DeleteVolumeMountPointA kernel32 285 -imp 'DeleteVolumeMountPoint' DeleteVolumeMountPointW kernel32 0 # KernelBase -imp 'DequeueUmsCompletionListItems' DequeueUmsCompletionListItems kernel32 287 -imp 'DeregisterEventSource' DeregisterEventSource advapi32 1239 1 -imp 'DeregisterShellHookWindow' DeregisterShellHookWindow user32 1682 -imp 'DeriveCapabilitySidsFromName' DeriveCapabilitySidsFromName KernelBase 263 imp 'DescribePixelFormat' DescribePixelFormat gdi32 1388 -imp 'DestroyAcceleratorTable' DestroyAcceleratorTable user32 1683 -imp 'DestroyCaret' DestroyCaret user32 1684 -imp 'DestroyCursor' DestroyCursor user32 1685 -imp 'DestroyDCompositionHwndTarget' DestroyDCompositionHwndTarget user32 1686 -imp 'DestroyIcon' DestroyIcon user32 1687 1 -imp 'DestroyMenu' DestroyMenu user32 1688 1 imp 'DestroyOPMProtectedOutput' DestroyOPMProtectedOutput gdi32 1389 -imp 'DestroyPalmRejectionDelayZone' DestroyPalmRejectionDelayZone user32 1504 imp 'DestroyPhysicalMonitorInternal' DestroyPhysicalMonitorInternal gdi32 1390 -imp 'DestroyPrivateObjectSecurity' DestroyPrivateObjectSecurity advapi32 0 # KernelBase -imp 'DestroyReasons' DestroyReasons user32 1689 -imp 'DestroyWindow' DestroyWindow user32 1690 1 -imp 'DeviceCapabilitiesExA' DeviceCapabilitiesExA gdi32 1391 -imp 'DeviceIoControl' DeviceIoControl kernel32 0 8 # KernelBase -imp 'DialogBoxIndirectParamA' DialogBoxIndirectParamA user32 1691 -imp 'DialogBoxIndirectParamAor' DialogBoxIndirectParamAorW user32 1692 -imp 'DialogBoxIndirectParam' DialogBoxIndirectParamW user32 1693 -imp 'DialogBoxParamA' DialogBoxParamA user32 1694 -imp 'DialogBoxParam' DialogBoxParamW user32 1695 -imp 'DisablePredefinedHandleTableInternal' DisablePredefinedHandleTableInternal KernelBase 266 -imp 'DisableProcessWindowsGhosting' DisableProcessWindowsGhosting user32 1696 -imp 'DisableThreadLibraryCalls' DisableThreadLibraryCalls kernel32 0 # KernelBase -imp 'DisableThreadProfiling' DisableThreadProfiling kernel32 290 -imp 'DiscardVirtualMemory' DiscardVirtualMemory kernel32 0 # KernelBase -imp 'DisconnectNamedPipe' DisconnectNamedPipe kernel32 0 1 # KernelBase -imp 'DispatchMessage' DispatchMessageW user32 1698 1 -imp 'DispatchMessageA' DispatchMessageA user32 1697 1 -imp 'DisplayConfigGetDeviceInfo' DisplayConfigGetDeviceInfo user32 1699 -imp 'DisplayConfigSetDeviceInfo' DisplayConfigSetDeviceInfo user32 1700 -imp 'DisplayExitWindowsWarnings' DisplayExitWindowsWarnings user32 1701 -imp 'DlgDirListA' DlgDirListA user32 1702 -imp 'DlgDirListComboBoxA' DlgDirListComboBoxA user32 1703 -imp 'DlgDirListComboBox' DlgDirListComboBoxW user32 1704 -imp 'DlgDirList' DlgDirListW user32 1705 -imp 'DlgDirSelectComboBoxExA' DlgDirSelectComboBoxExA user32 1706 -imp 'DlgDirSelectComboBoxEx' DlgDirSelectComboBoxExW user32 1707 -imp 'DlgDirSelectExA' DlgDirSelectExA user32 1708 -imp 'DlgDirSelectEx' DlgDirSelectExW user32 1709 -imp 'DllCanUnloadNow' DllCanUnloadNow comdlg32 107 -imp 'DllGetActivationFactory' DllGetActivationFactory shell32 277 -imp 'DllGetClassObject' DllGetClassObject comdlg32 108 -imp 'DllGetVersion' DllGetVersion shell32 279 -imp 'DllInstall' DllInstall shell32 280 -imp 'DllRegisterServer' DllRegisterServer shell32 281 -imp 'DllUnregisterServer' DllUnregisterServer shell32 282 -imp 'DnsHostnameToComputerNameA' DnsHostnameToComputerNameA kernel32 294 -imp 'DnsHostnameToComputerNameEx' DnsHostnameToComputerNameExW KernelBase 271 -imp 'DnsHostnameToComputerName' DnsHostnameToComputerNameW kernel32 296 -imp 'DoEnvironmentSubstA' DoEnvironmentSubstA shell32 283 -imp 'DoEnvironmentSubst' DoEnvironmentSubstW shell32 284 -imp 'DoSoundConnect' DoSoundConnect user32 1710 -imp 'DoSoundDisconnect' DoSoundDisconnect user32 1711 -imp 'DosDateTimeToFileTime' DosDateTimeToFileTime kernel32 297 -imp 'DosPathToSessionPathA' DosPathToSessionPathA kernel32 298 -imp 'DosPathToSessionPath' DosPathToSessionPathW kernel32 299 -imp 'DragAcceptFiles' DragAcceptFiles shell32 285 -imp 'DragDetect' DragDetect user32 1712 -imp 'DragFinish' DragFinish shell32 286 -imp 'DragObject' DragObject user32 1713 -imp 'DragQueryFileA' DragQueryFileA shell32 288 -imp 'DragQueryFileAor' DragQueryFileAorW shell32 289 -imp 'DragQueryFile' DragQueryFileW shell32 290 -imp 'DragQueryPoint' DragQueryPoint shell32 291 -imp 'DrawAnimatedRects' DrawAnimatedRects user32 1714 -imp 'DrawCaption' DrawCaption user32 1715 -imp 'DrawCaptionTempA' DrawCaptionTempA user32 1716 -imp 'DrawCaptionTemp' DrawCaptionTempW user32 1717 -imp 'DrawEdge' DrawEdge user32 1718 imp 'DrawEscape' DrawEscape gdi32 1393 -imp 'DrawFocusRect' DrawFocusRect user32 1719 -imp 'DrawFrame' DrawFrame user32 1720 -imp 'DrawFrameControl' DrawFrameControl user32 1721 -imp 'DrawIcon' DrawIcon user32 1722 -imp 'DrawIconEx' DrawIconEx user32 1723 -imp 'DrawMenuBar' DrawMenuBar user32 1724 -imp 'DrawMenuBarTemp' DrawMenuBarTemp user32 1725 -imp 'DrawStateA' DrawStateA user32 1726 -imp 'DrawState' DrawStateW user32 1727 -imp 'DrawText' DrawTextW user32 1731 5 -imp 'DrawTextA' DrawTextA user32 1728 5 -imp 'DrawTextEx' DrawTextExW user32 1730 6 -imp 'DrawTextExA' DrawTextExA user32 1729 6 -imp 'DriveType' DriveType shell32 64 -imp 'DsBindWithSpnEx' DsBindWithSpnExW KernelBase 272 -imp 'DsCrackNames' DsCrackNamesW KernelBase 273 -imp 'DsFreeDomainControllerInfo' DsFreeDomainControllerInfoW KernelBase 274 -imp 'DsFreeNameResult' DsFreeNameResultW KernelBase 275 -imp 'DsFreeNgcKey' DsFreeNgcKey KernelBase 276 -imp 'DsFreePasswordCredentials' DsFreePasswordCredentials KernelBase 277 -imp 'DsGetDomainControllerInfo' DsGetDomainControllerInfoW KernelBase 278 -imp 'DsMakePasswordCredentials' DsMakePasswordCredentialsW KernelBase 279 -imp 'DsReadNgcKey' DsReadNgcKeyW KernelBase 280 -imp 'DsUnBind' DsUnBindW KernelBase 281 -imp 'DsWriteNgcKey' DsWriteNgcKeyW KernelBase 282 -imp 'DuplicateConsoleHandle' DuplicateConsoleHandle kernel32 300 -imp 'DuplicateEncryptionInfoFile' DuplicateEncryptionInfoFile advapi32 1241 -imp 'DuplicateEncryptionInfoFileExt' DuplicateEncryptionInfoFileExt kernel32 301 -imp 'DuplicateHandle' DuplicateHandle kernel32 0 7 # KernelBase -imp 'DuplicateIcon' DuplicateIcon shell32 292 -imp 'DuplicateStateContainerHandle' DuplicateStateContainerHandle KernelBase 284 -imp 'DuplicateToken' DuplicateToken advapi32 0 3 # KernelBase -imp 'DuplicateTokenEx' DuplicateTokenEx advapi32 0 6 # KernelBase imp 'DwmCreatedBitmapRemotingOutput' DwmCreatedBitmapRemotingOutput gdi32 1014 -imp 'DwmGetDxRgn' DwmGetDxRgn user32 1553 -imp 'DwmGetDxSharedSurface' DwmGetDxSharedSurface user32 1732 -imp 'DwmGetRemoteSessionOcclusionEvent' DwmGetRemoteSessionOcclusionEvent user32 1733 -imp 'DwmGetRemoteSessionOcclusionState' DwmGetRemoteSessionOcclusionState user32 1734 -imp 'DwmKernelShutdown' DwmKernelShutdown user32 1735 -imp 'DwmKernelStartup' DwmKernelStartup user32 1736 -imp 'DwmLockScreenUpdates' DwmLockScreenUpdates user32 1737 -imp 'DwmValidateWindow' DwmValidateWindow user32 1738 imp 'DxTrimNotificationListHead' DxTrimNotificationListHead gdi32 1394 -imp 'EditWndProc' EditWndProc user32 1739 -imp 'ElfBackupEventLogFileA' ElfBackupEventLogFileA advapi32 1244 -imp 'ElfBackupEventLogFile' ElfBackupEventLogFileW advapi32 1245 -imp 'ElfChangeNotify' ElfChangeNotify advapi32 1246 -imp 'ElfClearEventLogFileA' ElfClearEventLogFileA advapi32 1247 -imp 'ElfClearEventLogFile' ElfClearEventLogFileW advapi32 1248 -imp 'ElfCloseEventLog' ElfCloseEventLog advapi32 1249 -imp 'ElfDeregisterEventSource' ElfDeregisterEventSource advapi32 1250 -imp 'ElfFlushEventLog' ElfFlushEventLog advapi32 1251 -imp 'ElfNumberOfRecords' ElfNumberOfRecords advapi32 1252 -imp 'ElfOldestRecord' ElfOldestRecord advapi32 1253 -imp 'ElfOpenBackupEventLogA' ElfOpenBackupEventLogA advapi32 1254 -imp 'ElfOpenBackupEventLog' ElfOpenBackupEventLogW advapi32 1255 -imp 'ElfOpenEventLogA' ElfOpenEventLogA advapi32 1256 -imp 'ElfOpenEventLog' ElfOpenEventLogW advapi32 1257 -imp 'ElfReadEventLogA' ElfReadEventLogA advapi32 1258 -imp 'ElfReadEventLog' ElfReadEventLogW advapi32 1259 -imp 'ElfRegisterEventSourceA' ElfRegisterEventSourceA advapi32 1260 -imp 'ElfRegisterEventSource' ElfRegisterEventSourceW advapi32 1261 -imp 'ElfReportEventA' ElfReportEventA advapi32 1262 -imp 'ElfReportEventAndSource' ElfReportEventAndSourceW advapi32 1263 -imp 'ElfReportEvent' ElfReportEventW advapi32 1264 imp 'Ellipse' Ellipse gdi32 1395 -imp 'EmptyClipboard' EmptyClipboard user32 1740 -imp 'EmptyWorkingSet' EmptyWorkingSet KernelBase 287 imp 'EnableEUDC' EnableEUDC gdi32 1396 -imp 'EnableMenuItem' EnableMenuItem user32 1741 -imp 'EnableMouseInPointer' EnableMouseInPointer user32 1742 -imp 'EnableNonClientDpiScaling' EnableNonClientDpiScaling user32 1743 -imp 'EnableOneCoreTransformMode' EnableOneCoreTransformMode user32 1744 -imp 'EnableScrollBar' EnableScrollBar user32 1745 -imp 'EnableSessionForMMCSS' EnableSessionForMMCSS user32 1746 -imp 'EnableThreadProfiling' EnableThreadProfiling kernel32 303 -imp 'EnableTrace' EnableTrace advapi32 1265 -imp 'EnableTraceEx' EnableTraceEx advapi32 1266 -imp 'EnableTraceEx2' EnableTraceEx2 advapi32 1267 -imp 'EnableWindow' EnableWindow user32 1747 -imp 'EncryptFileA' EncryptFileA advapi32 1268 -imp 'EncryptFile' EncryptFileW advapi32 1269 -imp 'EncryptedFileKeyInfo' EncryptedFileKeyInfo advapi32 1270 -imp 'EncryptionDisable' EncryptionDisable advapi32 1271 -imp 'EndDeferWindowPos' EndDeferWindowPos user32 1748 -imp 'EndDeferWindowPosEx' EndDeferWindowPosEx user32 1749 -imp 'EndDialog' EndDialog user32 1750 imp 'EndDoc' EndDoc gdi32 1397 imp 'EndFormPage' EndFormPage gdi32 1398 imp 'EndGdiRendering' EndGdiRendering gdi32 1399 -imp 'EndMenu' EndMenu user32 1751 imp 'EndPage' EndPage gdi32 1400 -imp 'EndPaint' EndPaint user32 1752 2 imp 'EndPath' EndPath gdi32 1401 -imp 'EndTask' EndTask user32 1753 -imp 'EndUpdateResourceA' EndUpdateResourceA kernel32 306 -imp 'EndUpdateResource' EndUpdateResourceW kernel32 307 imp 'EngAcquireSemaphore' EngAcquireSemaphore gdi32 1402 imp 'EngAlphaBlend' EngAlphaBlend gdi32 1403 imp 'EngAssociateSurface' EngAssociateSurface gdi32 1404 @@ -1430,185 +3376,24 @@ imp 'EngTransparentBlt' EngTransparentBlt gdi32 1444 imp 'EngUnicodeToMultiByteN' EngUnicodeToMultiByteN gdi32 1445 imp 'EngUnlockSurface' EngUnlockSurface gdi32 1446 imp 'EngWideCharToMultiByte' EngWideCharToMultiByte gdi32 1447 -imp 'EnterCriticalPolicySectionInternal' EnterCriticalPolicySectionInternal KernelBase 291 -imp 'EnterReaderModeHelper' EnterReaderModeHelper user32 1754 -imp 'EnterSynchronizationBarrier' EnterSynchronizationBarrier kernel32 0 # KernelBase -imp 'EnterUmsSchedulingMode' EnterUmsSchedulingMode kernel32 310 -imp 'EnumCalendarInfoA' EnumCalendarInfoA kernel32 311 -imp 'EnumCalendarInfoExA' EnumCalendarInfoExA kernel32 312 -imp 'EnumCalendarInfoExEx' EnumCalendarInfoExEx kernel32 0 # KernelBase -imp 'EnumCalendarInfoEx' EnumCalendarInfoExW kernel32 0 # KernelBase -imp 'EnumCalendarInfo' EnumCalendarInfoW kernel32 0 # KernelBase -imp 'EnumChildWindows' EnumChildWindows user32 1755 3 -imp 'EnumClipboardFormats' EnumClipboardFormats user32 1756 -imp 'EnumDateFormatsA' EnumDateFormatsA kernel32 316 -imp 'EnumDateFormatsExA' EnumDateFormatsExA kernel32 317 -imp 'EnumDateFormatsExEx' EnumDateFormatsExEx kernel32 0 # KernelBase -imp 'EnumDateFormatsEx' EnumDateFormatsExW kernel32 0 # KernelBase -imp 'EnumDateFormats' EnumDateFormatsW kernel32 0 # KernelBase -imp 'EnumDependentServicesA' EnumDependentServicesA advapi32 1272 -imp 'EnumDependentServices' EnumDependentServicesW advapi32 1273 -imp 'EnumDesktopWindows' EnumDesktopWindows user32 1757 -imp 'EnumDesktopsA' EnumDesktopsA user32 1758 -imp 'EnumDesktops' EnumDesktopsW user32 1759 -imp 'EnumDeviceDrivers' EnumDeviceDrivers KernelBase 300 -imp 'EnumDisplayDevicesA' EnumDisplayDevicesA user32 1760 -imp 'EnumDisplayDevices' EnumDisplayDevicesW user32 1761 -imp 'EnumDisplayMonitors' EnumDisplayMonitors user32 1762 -imp 'EnumDisplaySettingsA' EnumDisplaySettingsA user32 1763 -imp 'EnumDisplaySettingsExA' EnumDisplaySettingsExA user32 1764 -imp 'EnumDisplaySettingsEx' EnumDisplaySettingsExW user32 1765 -imp 'EnumDisplaySettings' EnumDisplaySettingsW user32 1766 -imp 'EnumDynamicTimeZoneInformation' EnumDynamicTimeZoneInformation KernelBase 301 imp 'EnumEnhMetaFile' EnumEnhMetaFile gdi32 1448 -imp 'EnumFontFamiliesA' EnumFontFamiliesA gdi32 1449 -imp 'EnumFontFamiliesExA' EnumFontFamiliesExA gdi32 1450 -imp 'EnumFontFamiliesEx' EnumFontFamiliesExW gdi32 1451 imp 'EnumFontFamilies' EnumFontFamiliesW gdi32 1452 -imp 'EnumFontsA' EnumFontsA gdi32 1453 +imp 'EnumFontFamiliesEx' EnumFontFamiliesExW gdi32 1451 imp 'EnumFonts' EnumFontsW gdi32 1454 -imp 'EnumICMProfilesA' EnumICMProfilesA gdi32 1455 imp 'EnumICMProfiles' EnumICMProfilesW gdi32 1456 -imp 'EnumLanguageGroupLocalesA' EnumLanguageGroupLocalesA kernel32 321 -imp 'EnumLanguageGroupLocales' EnumLanguageGroupLocalesW kernel32 0 # KernelBase imp 'EnumMetaFile' EnumMetaFile gdi32 1457 imp 'EnumObjects' EnumObjects gdi32 1458 -imp 'EnumPageFilesA' EnumPageFilesA KernelBase 303 -imp 'EnumPageFiles' EnumPageFilesW KernelBase 304 -imp 'EnumProcessModules' EnumProcessModules KernelBase 305 -imp 'EnumProcessModulesEx' EnumProcessModulesEx KernelBase 306 -imp 'EnumProcesses' EnumProcesses KernelBase 307 -imp 'EnumPropsA' EnumPropsA user32 1767 -imp 'EnumPropsExA' EnumPropsExA user32 1768 -imp 'EnumPropsEx' EnumPropsExW user32 1769 -imp 'EnumProps' EnumPropsW user32 1770 -imp 'EnumResourceLanguagesA' EnumResourceLanguagesA kernel32 323 -imp 'EnumResourceLanguagesExA' EnumResourceLanguagesExA kernel32 0 # KernelBase -imp 'EnumResourceLanguagesEx' EnumResourceLanguagesExW kernel32 0 # KernelBase -imp 'EnumResourceLanguages' EnumResourceLanguagesW kernel32 326 -imp 'EnumResourceNamesA' EnumResourceNamesA kernel32 327 -imp 'EnumResourceNamesExA' EnumResourceNamesExA kernel32 0 # KernelBase -imp 'EnumResourceNamesEx' EnumResourceNamesExW kernel32 0 # KernelBase -imp 'EnumResourceNames' EnumResourceNamesW kernel32 0 # KernelBase -imp 'EnumResourceTypesA' EnumResourceTypesA kernel32 331 -imp 'EnumResourceTypesExA' EnumResourceTypesExA kernel32 0 # KernelBase -imp 'EnumResourceTypesEx' EnumResourceTypesExW kernel32 0 # KernelBase -imp 'EnumResourceTypes' EnumResourceTypesW kernel32 334 -imp 'EnumServiceGroup' EnumServiceGroupW advapi32 1275 -imp 'EnumServicesStatusA' EnumServicesStatusA advapi32 1276 -imp 'EnumServicesStatusExA' EnumServicesStatusExA advapi32 1277 -imp 'EnumServicesStatusEx' EnumServicesStatusExW advapi32 1278 -imp 'EnumServicesStatus' EnumServicesStatusW advapi32 1279 -imp 'EnumSystemCodePagesA' EnumSystemCodePagesA kernel32 335 -imp 'EnumSystemCodePages' EnumSystemCodePagesW kernel32 0 # KernelBase -imp 'EnumSystemFirmwareTables' EnumSystemFirmwareTables kernel32 0 # KernelBase -imp 'EnumSystemGeoID' EnumSystemGeoID kernel32 0 # KernelBase -imp 'EnumSystemGeoNames' EnumSystemGeoNames KernelBase 318 -imp 'EnumSystemLanguageGroupsA' EnumSystemLanguageGroupsA kernel32 340 -imp 'EnumSystemLanguageGroups' EnumSystemLanguageGroupsW kernel32 0 # KernelBase -imp 'EnumSystemLocalesA' EnumSystemLocalesA kernel32 0 # KernelBase -imp 'EnumSystemLocalesEx' EnumSystemLocalesEx kernel32 0 # KernelBase -imp 'EnumSystemLocales' EnumSystemLocalesW kernel32 0 # KernelBase -imp 'EnumThreadWindows' EnumThreadWindows user32 1771 -imp 'EnumTimeFormatsA' EnumTimeFormatsA kernel32 345 -imp 'EnumTimeFormatsEx' EnumTimeFormatsEx kernel32 0 # KernelBase -imp 'EnumTimeFormats' EnumTimeFormatsW kernel32 0 # KernelBase -imp 'EnumUILanguagesA' EnumUILanguagesA kernel32 348 -imp 'EnumUILanguages' EnumUILanguagesW kernel32 0 # KernelBase -imp 'EnumWindowStationsA' EnumWindowStationsA user32 1772 -imp 'EnumWindowStations' EnumWindowStationsW user32 1773 -imp 'EnumWindows' EnumWindows user32 1774 -imp 'EnumerateExtensionNames' EnumerateExtensionNames KernelBase 326 -imp 'EnumerateLocalComputerNamesA' EnumerateLocalComputerNamesA kernel32 350 -imp 'EnumerateLocalComputerNames' EnumerateLocalComputerNamesW kernel32 351 -imp 'EnumerateStateAtomValues' EnumerateStateAtomValues KernelBase 327 -imp 'EnumerateStateContainerItems' EnumerateStateContainerItems KernelBase 328 -imp 'EnumerateTraceGuids' EnumerateTraceGuids advapi32 1280 -imp 'EnumerateTraceGuidsEx' EnumerateTraceGuidsEx advapi32 1281 -imp 'EqualDomainSid' EqualDomainSid advapi32 0 # KernelBase -imp 'EqualPrefixSid' EqualPrefixSid advapi32 0 # KernelBase -imp 'EqualRect' EqualRect user32 1775 imp 'EqualRgn' EqualRgn gdi32 1459 -imp 'EqualSid' EqualSid advapi32 0 # KernelBase -imp 'EraseTape' EraseTape kernel32 352 imp 'Escape' Escape gdi32 1460 -imp 'EscapeCommFunction' EscapeCommFunction kernel32 0 # KernelBase -imp 'EtwCheckCoverage' EtwCheckCoverage ntdll 60 -imp 'EtwCreateTraceInstanceId' EtwCreateTraceInstanceId ntdll 61 -imp 'EtwDeliverDataBlock' EtwDeliverDataBlock ntdll 62 -imp 'EtwEnumerateProcessRegGuids' EtwEnumerateProcessRegGuids ntdll 63 -imp 'EtwEventActivityIdControl' EtwEventActivityIdControl ntdll 64 -imp 'EtwEventEnabled' EtwEventEnabled ntdll 65 -imp 'EtwEventProviderEnabled' EtwEventProviderEnabled ntdll 66 -imp 'EtwEventRegister' EtwEventRegister ntdll 67 -imp 'EtwEventSetInformation' EtwEventSetInformation ntdll 68 -imp 'EtwEventUnregister' EtwEventUnregister ntdll 69 -imp 'EtwEventWrite' EtwEventWrite ntdll 70 -imp 'EtwEventWriteEndScenario' EtwEventWriteEndScenario ntdll 71 -imp 'EtwEventWriteEx' EtwEventWriteEx ntdll 72 -imp 'EtwEventWriteFull' EtwEventWriteFull ntdll 73 -imp 'EtwEventWriteNoRegistration' EtwEventWriteNoRegistration ntdll 74 -imp 'EtwEventWriteStartScenario' EtwEventWriteStartScenario ntdll 75 -imp 'EtwEventWriteString' EtwEventWriteString ntdll 76 -imp 'EtwEventWriteTransfer' EtwEventWriteTransfer ntdll 77 -imp 'EtwGetTraceEnableFlags' EtwGetTraceEnableFlags ntdll 78 -imp 'EtwGetTraceEnableLevel' EtwGetTraceEnableLevel ntdll 79 -imp 'EtwGetTraceLoggerHandle' EtwGetTraceLoggerHandle ntdll 80 -imp 'EtwLogTraceEvent' EtwLogTraceEvent ntdll 81 -imp 'EtwNotificationRegister' EtwNotificationRegister ntdll 82 -imp 'EtwNotificationUnregister' EtwNotificationUnregister ntdll 83 -imp 'EtwProcessPrivateLoggerRequest' EtwProcessPrivateLoggerRequest ntdll 84 -imp 'EtwRegisterSecurityProvider' EtwRegisterSecurityProvider ntdll 85 -imp 'EtwRegisterTraceGuidsA' EtwRegisterTraceGuidsA ntdll 86 -imp 'EtwRegisterTraceGuids' EtwRegisterTraceGuidsW ntdll 87 -imp 'EtwReplyNotification' EtwReplyNotification ntdll 88 -imp 'EtwSendNotification' EtwSendNotification ntdll 89 -imp 'EtwSetMark' EtwSetMark ntdll 90 -imp 'EtwTraceEventInstance' EtwTraceEventInstance ntdll 91 -imp 'EtwTraceMessage' EtwTraceMessage ntdll 92 -imp 'EtwTraceMessageVa' EtwTraceMessageVa ntdll 93 -imp 'EtwUnregisterTraceGuids' EtwUnregisterTraceGuids ntdll 94 -imp 'EtwWriteUMSecurityEvent' EtwWriteUMSecurityEvent ntdll 95 -imp 'EtwpCreateEtwThread' EtwpCreateEtwThread ntdll 96 -imp 'EtwpGetCpuSpeed' EtwpGetCpuSpeed ntdll 97 imp 'EudcLoadLink' EudcLoadLinkW gdi32 1461 imp 'EudcUnloadLink' EudcUnloadLinkW gdi32 1462 -imp 'EvaluateProximityToPolygon' EvaluateProximityToPolygon user32 1776 -imp 'EvaluateProximityToRect' EvaluateProximityToRect user32 1777 -imp 'EventAccessControl' EventAccessControl advapi32 1285 -imp 'EventAccessQuery' EventAccessQuery advapi32 1286 -imp 'EventAccessRemove' EventAccessRemove advapi32 1287 -imp 'EvtIntReportAuthzEventAndSourceAsync' EvtIntReportAuthzEventAndSourceAsync ntdll 98 -imp 'EvtIntReportEventAndSourceAsync' EvtIntReportEventAndSourceAsync ntdll 99 imp 'ExcludeClipRect' ExcludeClipRect gdi32 1463 -imp 'ExcludeUpdateRgn' ExcludeUpdateRgn user32 1778 -imp 'ExecuteUmsThread' ExecuteUmsThread kernel32 354 -imp 'ExitProcess' ExitProcess kernel32 0 1 # a.k.a. RtlExitUserProcess # KernelBase -imp 'ExitVDM' ExitVDM kernel32 357 -imp 'ExitWindowsEx' ExitWindowsEx user32 1779 -imp 'ExpInterlockedPopEntrySListEnd' ExpInterlockedPopEntrySListEnd ntdll 100 -imp 'ExpInterlockedPopEntrySListFault' ExpInterlockedPopEntrySListFault ntdll 101 -imp 'ExpInterlockedPopEntrySListResume' ExpInterlockedPopEntrySListResume ntdll 102 -imp 'ExpandEnvironmentStringsA' ExpandEnvironmentStringsA kernel32 0 # KernelBase -imp 'ExpandEnvironmentStrings' ExpandEnvironmentStringsW kernel32 0 # KernelBase -imp 'ExpungeConsoleCommandHistoryA' ExpungeConsoleCommandHistoryA KernelBase 347 -imp 'ExpungeConsoleCommandHistory' ExpungeConsoleCommandHistoryW KernelBase 348 imp 'ExtCreatePen' ExtCreatePen gdi32 1464 imp 'ExtCreateRegion' ExtCreateRegion gdi32 1465 imp 'ExtEscape' ExtEscape gdi32 1466 imp 'ExtFloodFill' ExtFloodFill gdi32 1467 imp 'ExtSelectClipRgn' ExtSelectClipRgn gdi32 1468 -imp 'ExtTextOutA' ExtTextOutA gdi32 1469 imp 'ExtTextOut' ExtTextOutW gdi32 1470 -imp 'ExtensionProgIdExists' ExtensionProgIdExists KernelBase 349 -imp 'ExtractAssociatedIconA' ExtractAssociatedIconA shell32 293 -imp 'ExtractAssociatedIconExA' ExtractAssociatedIconExA shell32 294 -imp 'ExtractAssociatedIconEx' ExtractAssociatedIconExW shell32 295 -imp 'ExtractAssociatedIcon' ExtractAssociatedIconW shell32 296 -imp 'ExtractIconA' ExtractIconA shell32 297 -imp 'ExtractIconExA' ExtractIconExA shell32 299 -imp 'ExtractIconEx' ExtractIconExW shell32 300 -imp 'ExtractIcon' ExtractIconW shell32 301 imp 'FONTOBJ_cGetAllGlyphHandles' FONTOBJ_cGetAllGlyphHandles gdi32 1471 imp 'FONTOBJ_cGetGlyphs' FONTOBJ_cGetGlyphs gdi32 1472 imp 'FONTOBJ_pQueryGlyphAttrs' FONTOBJ_pQueryGlyphAttrs gdi32 1473 @@ -1617,121 +3402,13 @@ imp 'FONTOBJ_pifi' FONTOBJ_pifi gdi32 1475 imp 'FONTOBJ_pvTrueTypeFontFile' FONTOBJ_pvTrueTypeFontFile gdi32 1476 imp 'FONTOBJ_pxoGetXform' FONTOBJ_pxoGetXform gdi32 1477 imp 'FONTOBJ_vGetInfo' FONTOBJ_vGetInfo gdi32 1478 -imp 'FatalAppExitA' FatalAppExitA kernel32 0 # KernelBase -imp 'FatalAppExit' FatalAppExitW kernel32 0 # KernelBase -imp 'FatalExit' FatalExit kernel32 364 1 -imp 'FileEncryptionStatusA' FileEncryptionStatusA advapi32 1300 -imp 'FileEncryptionStatus' FileEncryptionStatusW advapi32 1301 -imp 'FileProtocolHandler' FileProtocolHandler url 104 -imp 'FileProtocolHandlerA' FileProtocolHandlerA url 105 -imp 'FileTimeToDosDateTime' FileTimeToDosDateTime kernel32 365 -imp 'FileTimeToLocalFileTime' FileTimeToLocalFileTime kernel32 0 # KernelBase -imp 'FileTimeToSystemTime' FileTimeToSystemTime kernel32 0 # KernelBase -imp 'FillConsoleOutputAttribute' FillConsoleOutputAttribute kernel32 0 5 # KernelBase -imp 'FillConsoleOutputCharacter' FillConsoleOutputCharacterW kernel32 0 5 # KernelBase -imp 'FillConsoleOutputCharacterA' FillConsoleOutputCharacterA kernel32 0 5 # KernelBase imp 'FillPath' FillPath gdi32 1479 -imp 'FillRect' FillRect user32 1780 3 imp 'FillRgn' FillRgn gdi32 1480 -imp 'FindActCtxSectionGuid' FindActCtxSectionGuid kernel32 0 # KernelBase -imp 'FindActCtxSectionGuidWorker' FindActCtxSectionGuidWorker kernel32 372 -imp 'FindActCtxSectionStringA' FindActCtxSectionStringA kernel32 373 -imp 'FindActCtxSectionString' FindActCtxSectionStringW kernel32 0 # KernelBase -imp 'FindActCtxSectionStringWWorker' FindActCtxSectionStringWWorker kernel32 375 -imp 'FindAtomA' FindAtomA kernel32 376 -imp 'FindAtom' FindAtomW kernel32 377 -imp 'FindClose' FindClose kernel32 0 1 # KernelBase -imp 'FindCloseChangeNotification' FindCloseChangeNotification kernel32 0 # KernelBase -imp 'FindExecutableA' FindExecutableA shell32 302 -imp 'FindExecutable' FindExecutableW shell32 303 -imp 'FindFirstChangeNotificationA' FindFirstChangeNotificationA kernel32 0 # KernelBase -imp 'FindFirstChangeNotification' FindFirstChangeNotificationW kernel32 0 # KernelBase -imp 'FindFirstFile' FindFirstFileW kernel32 0 2 # KernelBase -imp 'FindFirstFileA' FindFirstFileA kernel32 0 2 # KernelBase -imp 'FindFirstFileEx' FindFirstFileExW kernel32 0 6 # KernelBase -imp 'FindFirstFileExA' FindFirstFileExA kernel32 0 6 # KernelBase -imp 'FindFirstFileNameTransacted' FindFirstFileNameTransactedW kernel32 385 -imp 'FindFirstFileName' FindFirstFileNameW kernel32 0 # KernelBase -imp 'FindFirstFileTransactedA' FindFirstFileTransactedA kernel32 387 -imp 'FindFirstFileTransacted' FindFirstFileTransactedW kernel32 388 -imp 'FindFirstFreeAce' FindFirstFreeAce advapi32 0 # KernelBase -imp 'FindFirstStream' FindFirstStreamW kernel32 0 # KernelBase -imp 'FindFirstStreamTransacted' FindFirstStreamTransactedW kernel32 390 -imp 'FindFirstVolume' FindFirstVolumeW kernel32 0 2 # KernelBase -imp 'FindFirstVolumeA' FindFirstVolumeA kernel32 392 2 -imp 'FindFirstVolumeMountPointA' FindFirstVolumeMountPointA kernel32 393 -imp 'FindFirstVolumeMountPoint' FindFirstVolumeMountPointW kernel32 394 -imp 'FindNLSString' FindNLSString kernel32 0 # KernelBase -imp 'FindNLSStringEx' FindNLSStringEx kernel32 0 # KernelBase -imp 'FindNextChangeNotification' FindNextChangeNotification kernel32 0 # KernelBase -imp 'FindNextFile' FindNextFileW kernel32 0 2 # KernelBase -imp 'FindNextFileA' FindNextFileA kernel32 0 2 # KernelBase -imp 'FindNextFileName' FindNextFileNameW kernel32 0 # KernelBase -imp 'FindNextStream' FindNextStreamW kernel32 0 # KernelBase -imp 'FindNextVolume' FindNextVolumeW kernel32 0 3 # KernelBase -imp 'FindNextVolumeA' FindNextVolumeA kernel32 403 3 -imp 'FindNextVolumeMountPointA' FindNextVolumeMountPointA kernel32 404 -imp 'FindNextVolumeMountPoint' FindNextVolumeMountPointW kernel32 405 -imp 'FindPackagesByPackageFamily' FindPackagesByPackageFamily kernel32 0 # KernelBase -imp 'FindResourceA' FindResourceA kernel32 408 -imp 'FindResourceExA' FindResourceExA kernel32 409 -imp 'FindResourceEx' FindResourceExW kernel32 0 # KernelBase -imp 'FindResource' FindResourceW kernel32 0 # KernelBase -imp 'FindStringOrdinal' FindStringOrdinal kernel32 0 # KernelBase -imp 'FindTextA' FindTextA comdlg32 109 -imp 'FindText' FindTextW comdlg32 110 -imp 'FindVolumeClose' FindVolumeClose kernel32 0 1 # KernelBase -imp 'FindVolumeMountPointClose' FindVolumeMountPointClose kernel32 414 -imp 'FindWindow' FindWindowW user32 1784 2 -imp 'FindWindowA' FindWindowA user32 1781 2 -imp 'FindWindowEx' FindWindowExW user32 1783 4 -imp 'FindWindowExA' FindWindowExA user32 1782 4 imp 'FixBrushOrgEx' FixBrushOrgEx gdi32 1481 -imp 'FlashWindow' FlashWindow user32 1785 -imp 'FlashWindowEx' FlashWindowEx user32 1786 imp 'FlattenPath' FlattenPath gdi32 1482 imp 'FloodFill' FloodFill gdi32 1483 -imp 'FlsAlloc' FlsAlloc kernel32 0 # KernelBase -imp 'FlsFree' FlsFree kernel32 0 # KernelBase -imp 'FlsGetValue' FlsGetValue kernel32 0 # KernelBase -imp 'FlsSetValue' FlsSetValue kernel32 0 # KernelBase -imp 'FlushConsoleInputBuffer' FlushConsoleInputBuffer kernel32 0 1 # KernelBase -imp 'FlushEfsCache' FlushEfsCache advapi32 1303 -imp 'FlushFileBuffers' FlushFileBuffers kernel32 0 1 # KernelBase -imp 'FlushInstructionCache' FlushInstructionCache kernel32 0 # KernelBase -imp 'FlushTraceA' FlushTraceA advapi32 1304 -imp 'FlushTrace' FlushTraceW advapi32 1305 -imp 'FlushViewOfFile' FlushViewOfFile kernel32 0 2 # KernelBase -imp 'FoldStringA' FoldStringA kernel32 424 -imp 'FoldString' FoldStringW kernel32 0 # KernelBase imp 'FontIsLinked' FontIsLinked gdi32 1484 -imp 'ForceSyncFgPolicyInternal' ForceSyncFgPolicyInternal KernelBase 394 -imp 'FormatApplicationUserModelId' FormatApplicationUserModelId kernel32 0 # KernelBase -imp 'FormatApplicationUserModelIdA' FormatApplicationUserModelIdA KernelBase 396 -imp 'FormatMessage' FormatMessageW kernel32 0 7 # KernelBase -imp 'FormatMessageA' FormatMessageA kernel32 0 7 # KernelBase -imp 'FrameRect' FrameRect user32 1787 imp 'FrameRgn' FrameRgn gdi32 1485 -imp 'FreeAddrInfoEx' FreeAddrInfoExW ws2_32 26 -imp 'FreeAddrInfo' FreeAddrInfoW ws2_32 27 -imp 'FreeConsole' FreeConsole kernel32 0 0 # KernelBase -imp 'FreeDDElParam' FreeDDElParam user32 1788 -imp 'FreeEncryptedFileKeyInfo' FreeEncryptedFileKeyInfo advapi32 1306 -imp 'FreeEncryptedFileMetadata' FreeEncryptedFileMetadata advapi32 1307 -imp 'FreeEncryptionCertificateHashList' FreeEncryptionCertificateHashList advapi32 1308 -imp 'FreeEnvironmentStrings' FreeEnvironmentStringsW kernel32 0 1 # KernelBase -imp 'FreeEnvironmentStringsA' FreeEnvironmentStringsA kernel32 0 1 # KernelBase -imp 'FreeGPOListInternalA' FreeGPOListInternalA KernelBase 402 -imp 'FreeGPOListInternal' FreeGPOListInternalW KernelBase 403 -imp 'FreeIconList' FreeIconList shell32 304 -imp 'FreeInheritedFromArray' FreeInheritedFromArray advapi32 1309 -imp 'FreeLibrary' FreeLibrary kernel32 0 1 # KernelBase -imp 'FreeLibraryAndExitThread' FreeLibraryAndExitThread kernel32 0 # KernelBase -imp 'FreeMemoryJobObject' FreeMemoryJobObject kernel32 435 -imp 'FreeResource' FreeResource kernel32 0 1 # KernelBase -imp 'FreeSid' FreeSid advapi32 0 # KernelBase -imp 'FreeUserPhysicalPages' FreeUserPhysicalPages kernel32 0 # KernelBase -imp 'FrostCrashedWindow' FrostCrashedWindow user32 1789 imp 'Gdi32DllInitialize' Gdi32DllInitialize gdi32 1486 imp 'GdiAddFontResource' GdiAddFontResourceW gdi32 1487 imp 'GdiAddGlsBounds' GdiAddGlsBounds gdi32 1488 @@ -1835,54 +3512,8 @@ imp 'GdiTrackHCreate' GdiTrackHCreate gdi32 1585 imp 'GdiTrackHDelete' GdiTrackHDelete gdi32 1586 imp 'GdiTransparentBlt' GdiTransparentBlt gdi32 1587 imp 'GdiValidateHandle' GdiValidateHandle gdi32 1588 -imp 'GenerateConsoleCtrlEvent' GenerateConsoleCtrlEvent kernel32 0 2 # KernelBase -imp 'GenerateGPNotificationInternal' GenerateGPNotificationInternal KernelBase 411 -imp 'GetACP' GetACP kernel32 0 # KernelBase -imp 'GetAcceptExSockaddrs' GetAcceptExSockaddrs MsWSock 4 8 -imp 'GetAcceptLanguagesA' GetAcceptLanguagesA KernelBase 413 -imp 'GetAcceptLanguages' GetAcceptLanguagesW KernelBase 414 -imp 'GetAccessPermissionsForObjectA' GetAccessPermissionsForObjectA advapi32 1311 -imp 'GetAccessPermissionsForObject' GetAccessPermissionsForObjectW advapi32 1312 -imp 'GetAce' GetAce advapi32 0 # KernelBase -imp 'GetAclInformation' GetAclInformation advapi32 0 # KernelBase -imp 'GetActiveProcessorCount' GetActiveProcessorCount kernel32 440 -imp 'GetActiveProcessorGroupCount' GetActiveProcessorGroupCount kernel32 441 -imp 'GetActiveWindow' GetActiveWindow user32 1790 -imp 'GetAddrInfoExA' GetAddrInfoExA ws2_32 28 -imp 'GetAddrInfoExCancel' GetAddrInfoExCancel ws2_32 29 -imp 'GetAddrInfoExOverlappedResult' GetAddrInfoExOverlappedResult ws2_32 30 -imp 'GetAddrInfoEx' GetAddrInfoExW ws2_32 31 -imp 'GetAddrInfo' GetAddrInfoW ws2_32 32 -imp 'GetAdjustObjectAttributesForPrivateNamespaceRoutine' GetAdjustObjectAttributesForPrivateNamespaceRoutine KernelBase 417 -imp 'GetAltTabInfoA' GetAltTabInfoA user32 1792 -imp 'GetAltTabInfo' GetAltTabInfoW user32 1793 -imp 'GetAlternatePackageRoots' GetAlternatePackageRoots KernelBase 418 -imp 'GetAncestor' GetAncestor user32 1794 -imp 'GetAppCompatFlags' GetAppCompatFlags user32 1795 -imp 'GetAppCompatFlags2' GetAppCompatFlags2 user32 1796 -imp 'GetAppContainerAce' GetAppContainerAce KernelBase 419 -imp 'GetAppContainerNamedObjectPath' GetAppContainerNamedObjectPath kernel32 0 # KernelBase -imp 'GetAppDataFolder' GetAppDataFolder KernelBase 421 -imp 'GetAppModelVersion' GetAppModelVersion KernelBase 422 -imp 'GetApplicationRecoveryCallback' GetApplicationRecoveryCallback kernel32 0 # KernelBase -imp 'GetApplicationRecoveryCallbackWorker' GetApplicationRecoveryCallbackWorker kernel32 445 -imp 'GetApplicationRestartSettings' GetApplicationRestartSettings kernel32 0 # KernelBase -imp 'GetApplicationRestartSettingsWorker' GetApplicationRestartSettingsWorker kernel32 447 -imp 'GetApplicationUserModelId' GetApplicationUserModelId kernel32 0 # KernelBase -imp 'GetApplicationUserModelIdFromToken' GetApplicationUserModelIdFromToken KernelBase 426 -imp 'GetAppliedGPOListInternalA' GetAppliedGPOListInternalA KernelBase 427 -imp 'GetAppliedGPOListInternal' GetAppliedGPOListInternalW KernelBase 428 imp 'GetArcDirection' GetArcDirection gdi32 1589 imp 'GetAspectRatioFilterEx' GetAspectRatioFilterEx gdi32 1590 -imp 'GetAsyncKeyState' GetAsyncKeyState user32 1797 -imp 'GetAtomNameA' GetAtomNameA kernel32 449 -imp 'GetAtomName' GetAtomNameW kernel32 450 -imp 'GetAuditedPermissionsFromAclA' GetAuditedPermissionsFromAclA advapi32 1315 -imp 'GetAuditedPermissionsFromAcl' GetAuditedPermissionsFromAclW advapi32 1316 -imp 'GetAutoRotationState' GetAutoRotationState user32 1798 -imp 'GetAwarenessFromDpiAwarenessContext' GetAwarenessFromDpiAwarenessContext user32 1799 -imp 'GetBinaryTypeA' GetBinaryTypeA kernel32 452 -imp 'GetBinaryType' GetBinaryTypeW kernel32 453 imp 'GetBitmapAttributes' GetBitmapAttributes gdi32 1591 imp 'GetBitmapBits' GetBitmapBits gdi32 1592 imp 'GetBitmapDimensionEx' GetBitmapDimensionEx gdi32 1593 @@ -1892,295 +3523,45 @@ imp 'GetBkMode' GetBkMode gdi32 1596 imp 'GetBoundsRect' GetBoundsRect gdi32 1597 imp 'GetBrushAttributes' GetBrushAttributes gdi32 1598 imp 'GetBrushOrgEx' GetBrushOrgEx gdi32 1599 -imp 'GetCIMSSM' GetCIMSSM user32 1800 imp 'GetCOPPCompatibleOPMInformation' GetCOPPCompatibleOPMInformation gdi32 1600 -imp 'GetCPFileNameFromRegistry' GetCPFileNameFromRegistry KernelBase 429 -imp 'GetCPHashNode' GetCPHashNode KernelBase 430 -imp 'GetCPInfo' GetCPInfo kernel32 0 # KernelBase -imp 'GetCPInfoExA' GetCPInfoExA kernel32 455 -imp 'GetCPInfoEx' GetCPInfoExW kernel32 0 # KernelBase -imp 'GetCachedSigningLevel' GetCachedSigningLevel KernelBase 433 -imp 'GetCalendar' GetCalendar KernelBase 434 -imp 'GetCalendarDateFormat' GetCalendarDateFormat kernel32 458 -imp 'GetCalendarDateFormatEx' GetCalendarDateFormatEx kernel32 459 -imp 'GetCalendarDaysInMonth' GetCalendarDaysInMonth kernel32 460 -imp 'GetCalendarDifferenceInDays' GetCalendarDifferenceInDays kernel32 461 -imp 'GetCalendarInfoA' GetCalendarInfoA kernel32 462 -imp 'GetCalendarInfoEx' GetCalendarInfoEx kernel32 0 # KernelBase -imp 'GetCalendarInfo' GetCalendarInfoW kernel32 0 # KernelBase -imp 'GetCalendarMonthsInYear' GetCalendarMonthsInYear kernel32 465 -imp 'GetCalendarSupportedDateRange' GetCalendarSupportedDateRange kernel32 466 -imp 'GetCalendarWeekNumber' GetCalendarWeekNumber kernel32 467 -imp 'GetCapture' GetCapture user32 1801 -imp 'GetCaretBlinkTime' GetCaretBlinkTime user32 1802 -imp 'GetCaretPos' GetCaretPos user32 1803 imp 'GetCertificate' GetCertificate gdi32 1601 imp 'GetCertificateByHandle' GetCertificateByHandle gdi32 1602 imp 'GetCertificateSize' GetCertificateSize gdi32 1603 imp 'GetCertificateSizeByHandle' GetCertificateSizeByHandle gdi32 1604 -imp 'GetCharABCWidthsA' GetCharABCWidthsA gdi32 1605 -imp 'GetCharABCWidthsFloatA' GetCharABCWidthsFloatA gdi32 1606 -imp 'GetCharABCWidthsFloatI' GetCharABCWidthsFloatI gdi32 1607 -imp 'GetCharABCWidthsFloat' GetCharABCWidthsFloatW gdi32 1608 -imp 'GetCharABCWidthsI' GetCharABCWidthsI gdi32 1609 imp 'GetCharABCWidths' GetCharABCWidthsW gdi32 1610 -imp 'GetCharWidth32A' GetCharWidth32A gdi32 1611 +imp 'GetCharABCWidthsFloat' GetCharABCWidthsFloatW gdi32 1608 +imp 'GetCharABCWidthsFloatI' GetCharABCWidthsFloatI gdi32 1607 +imp 'GetCharABCWidthsI' GetCharABCWidthsI gdi32 1609 +imp 'GetCharWidth' GetCharWidthW gdi32 1618 imp 'GetCharWidth32W' GetCharWidth32W gdi32 1612 -imp 'GetCharWidthA' GetCharWidthA gdi32 1613 -imp 'GetCharWidthFloatA' GetCharWidthFloatA gdi32 1614 imp 'GetCharWidthFloat' GetCharWidthFloatW gdi32 1615 imp 'GetCharWidthI' GetCharWidthI gdi32 1616 imp 'GetCharWidthInfo' GetCharWidthInfo gdi32 1617 -imp 'GetCharWidth' GetCharWidthW gdi32 1618 -imp 'GetCharacterPlacementA' GetCharacterPlacementA gdi32 1619 imp 'GetCharacterPlacement' GetCharacterPlacementW gdi32 1620 -imp 'GetClassInfoA' GetClassInfoA user32 1804 -imp 'GetClassInfoExA' GetClassInfoExA user32 1805 -imp 'GetClassInfoEx' GetClassInfoExW user32 1806 -imp 'GetClassInfo' GetClassInfoW user32 1807 -imp 'GetClassLongA' GetClassLongA user32 1808 -imp 'GetClassLongPtrA' GetClassLongPtrA user32 1809 -imp 'GetClassLongPtr' GetClassLongPtrW user32 1810 -imp 'GetClassLong' GetClassLongW user32 1811 -imp 'GetClassNameA' GetClassNameA user32 1812 -imp 'GetClassName' GetClassNameW user32 1813 -imp 'GetClassWord' GetClassWord user32 1814 -imp 'GetClientRect' GetClientRect user32 1815 2 imp 'GetClipBox' GetClipBox gdi32 1621 -imp 'GetClipCursor' GetClipCursor user32 1816 imp 'GetClipRgn' GetClipRgn gdi32 1622 -imp 'GetClipboardAccessToken' GetClipboardAccessToken user32 1817 -imp 'GetClipboardData' GetClipboardData user32 1818 -imp 'GetClipboardFormatNameA' GetClipboardFormatNameA user32 1819 -imp 'GetClipboardFormatName' GetClipboardFormatNameW user32 1820 -imp 'GetClipboardOwner' GetClipboardOwner user32 1821 -imp 'GetClipboardSequenceNumber' GetClipboardSequenceNumber user32 1822 -imp 'GetClipboardViewer' GetClipboardViewer user32 1823 imp 'GetColorAdjustment' GetColorAdjustment gdi32 1623 imp 'GetColorSpace' GetColorSpace gdi32 1624 -imp 'GetComPlusPackageInstallStatus' GetComPlusPackageInstallStatus kernel32 468 -imp 'GetComboBoxInfo' GetComboBoxInfo user32 1824 -imp 'GetCommConfig' GetCommConfig kernel32 0 # KernelBase -imp 'GetCommMask' GetCommMask kernel32 0 # KernelBase -imp 'GetCommModemStatus' GetCommModemStatus kernel32 0 # KernelBase -imp 'GetCommPorts' GetCommPorts KernelBase 440 -imp 'GetCommProperties' GetCommProperties kernel32 0 # KernelBase -imp 'GetCommState' GetCommState kernel32 0 # KernelBase -imp 'GetCommTimeouts' GetCommTimeouts kernel32 0 # KernelBase -imp 'GetCommandLine' GetCommandLineW kernel32 0 0 # KernelBase -imp 'GetCommandLineA' GetCommandLineA kernel32 0 0 # KernelBase -imp 'GetCompressedFileSize' GetCompressedFileSizeW kernel32 0 2 # KernelBase -imp 'GetCompressedFileSizeA' GetCompressedFileSizeA kernel32 0 2 # KernelBase -imp 'GetCompressedFileSizeTransactedA' GetCompressedFileSizeTransactedA kernel32 478 -imp 'GetCompressedFileSizeTransacted' GetCompressedFileSizeTransactedW kernel32 479 -imp 'GetComputerNameA' GetComputerNameA kernel32 481 -imp 'GetComputerNameExA' GetComputerNameExA kernel32 0 3 # KernelBase -imp 'GetComputerNameEx' GetComputerNameExW kernel32 0 3 # KernelBase -imp 'GetComputerName' GetComputerNameW kernel32 484 -imp 'GetConsoleAliasA' GetConsoleAliasA kernel32 0 # KernelBase -imp 'GetConsoleAliasExesA' GetConsoleAliasExesA kernel32 0 # KernelBase -imp 'GetConsoleAliasExesLengthA' GetConsoleAliasExesLengthA kernel32 0 # KernelBase -imp 'GetConsoleAliasExesLength' GetConsoleAliasExesLengthW kernel32 0 # KernelBase -imp 'GetConsoleAliasExes' GetConsoleAliasExesW kernel32 0 # KernelBase -imp 'GetConsoleAlias' GetConsoleAliasW kernel32 0 # KernelBase -imp 'GetConsoleAliasesA' GetConsoleAliasesA kernel32 0 # KernelBase -imp 'GetConsoleAliasesLengthA' GetConsoleAliasesLengthA kernel32 0 # KernelBase -imp 'GetConsoleAliasesLength' GetConsoleAliasesLengthW kernel32 0 # KernelBase -imp 'GetConsoleAliases' GetConsoleAliasesW kernel32 0 # KernelBase -imp 'GetConsoleCP' GetConsoleCP kernel32 0 0 # KernelBase -imp 'GetConsoleCharType' GetConsoleCharType kernel32 496 -imp 'GetConsoleCommandHistoryA' GetConsoleCommandHistoryA KernelBase 461 -imp 'GetConsoleCommandHistoryLengthA' GetConsoleCommandHistoryLengthA KernelBase 462 -imp 'GetConsoleCommandHistoryLength' GetConsoleCommandHistoryLengthW KernelBase 463 -imp 'GetConsoleCommandHistory' GetConsoleCommandHistoryW KernelBase 464 -imp 'GetConsoleCursorInfo' GetConsoleCursorInfo kernel32 0 2 # KernelBase -imp 'GetConsoleCursorMode' GetConsoleCursorMode kernel32 502 -imp 'GetConsoleDisplayMode' GetConsoleDisplayMode kernel32 0 # KernelBase -imp 'GetConsoleFontInfo' GetConsoleFontInfo kernel32 504 -imp 'GetConsoleFontSize' GetConsoleFontSize kernel32 0 # KernelBase -imp 'GetConsoleHardwareState' GetConsoleHardwareState kernel32 506 -imp 'GetConsoleHistoryInfo' GetConsoleHistoryInfo kernel32 0 # KernelBase -imp 'GetConsoleInputExeNameA' GetConsoleInputExeNameA KernelBase 469 -imp 'GetConsoleInputExeName' GetConsoleInputExeNameW KernelBase 470 -imp 'GetConsoleInputWaitHandle' GetConsoleInputWaitHandle kernel32 510 -imp 'GetConsoleKeyboardLayoutNameA' GetConsoleKeyboardLayoutNameA kernel32 511 -imp 'GetConsoleKeyboardLayoutName' GetConsoleKeyboardLayoutNameW kernel32 512 -imp 'GetConsoleMode' GetConsoleMode kernel32 0 2 # KernelBase -imp 'GetConsoleNlsMode' GetConsoleNlsMode kernel32 514 -imp 'GetConsoleOriginalTitleA' GetConsoleOriginalTitleA kernel32 0 # KernelBase -imp 'GetConsoleOriginalTitle' GetConsoleOriginalTitleW kernel32 0 # KernelBase -imp 'GetConsoleOutputCP' GetConsoleOutputCP kernel32 0 0 # KernelBase -imp 'GetConsoleProcessList' GetConsoleProcessList kernel32 0 # KernelBase -imp 'GetConsoleScreenBufferInfo' GetConsoleScreenBufferInfo kernel32 0 2 # KernelBase -imp 'GetConsoleScreenBufferInfoEx' GetConsoleScreenBufferInfoEx kernel32 0 2 # KernelBase -imp 'GetConsoleSelectionInfo' GetConsoleSelectionInfo kernel32 0 1 # KernelBase -imp 'GetConsoleTitleA' GetConsoleTitleA kernel32 0 2 # KernelBase -imp 'GetConsoleTitle' GetConsoleTitleW kernel32 0 2 # KernelBase -imp 'GetConsoleWindow' GetConsoleWindow kernel32 0 0 # KernelBase -imp 'GetCurrencyFormatA' GetCurrencyFormatA kernel32 525 -imp 'GetCurrencyFormatEx' GetCurrencyFormatEx kernel32 0 # KernelBase -imp 'GetCurrencyFormat' GetCurrencyFormatW kernel32 0 # KernelBase -imp 'GetCurrentActCtx' GetCurrentActCtx kernel32 0 # KernelBase -imp 'GetCurrentActCtxWorker' GetCurrentActCtxWorker kernel32 529 -imp 'GetCurrentApplicationUserModelId' GetCurrentApplicationUserModelId kernel32 0 # KernelBase -imp 'GetCurrentConsoleFont' GetCurrentConsoleFont kernel32 0 # KernelBase -imp 'GetCurrentConsoleFontEx' GetCurrentConsoleFontEx kernel32 0 # KernelBase -imp 'GetCurrentDirectory' GetCurrentDirectoryW kernel32 0 2 # KernelBase -imp 'GetCurrentDirectoryA' GetCurrentDirectoryA kernel32 0 2 # KernelBase imp 'GetCurrentDpiInfo' GetCurrentDpiInfo gdi32 1625 -imp 'GetCurrentHwProfileA' GetCurrentHwProfileA advapi32 1317 -imp 'GetCurrentHwProfile' GetCurrentHwProfileW advapi32 1318 -imp 'GetCurrentInputMessageSource' GetCurrentInputMessageSource user32 1825 imp 'GetCurrentObject' GetCurrentObject gdi32 1626 -imp 'GetCurrentPackageApplicationContext' GetCurrentPackageApplicationContext KernelBase 490 -imp 'GetCurrentPackageApplicationResourcesContext' GetCurrentPackageApplicationResourcesContext KernelBase 491 -imp 'GetCurrentPackageContext' GetCurrentPackageContext KernelBase 492 -imp 'GetCurrentPackageFamilyName' GetCurrentPackageFamilyName kernel32 0 # KernelBase -imp 'GetCurrentPackageFullName' GetCurrentPackageFullName kernel32 0 # KernelBase -imp 'GetCurrentPackageId' GetCurrentPackageId kernel32 0 # KernelBase -imp 'GetCurrentPackageInfo' GetCurrentPackageInfo kernel32 0 # KernelBase -imp 'GetCurrentPackagePath' GetCurrentPackagePath kernel32 0 # KernelBase -imp 'GetCurrentPackageResourcesContext' GetCurrentPackageResourcesContext KernelBase 498 -imp 'GetCurrentPackageSecurityContext' GetCurrentPackageSecurityContext KernelBase 499 imp 'GetCurrentPositionEx' GetCurrentPositionEx gdi32 1627 -imp 'GetCurrentProcess' GetCurrentProcess kernel32 0 0 # KernelBase -imp 'GetCurrentProcessExplicitAppUserModelID' GetCurrentProcessExplicitAppUserModelID shell32 305 -imp 'GetCurrentProcessId' GetCurrentProcessId kernel32 0 0 # KernelBase -imp 'GetCurrentTargetPlatformContext' GetCurrentTargetPlatformContext KernelBase 504 -imp 'GetCurrentThread' GetCurrentThread kernel32 0 0 # KernelBase -imp 'GetCurrentThreadId' GetCurrentThreadId kernel32 0 0 # KernelBase -imp 'GetCurrentThreadStackLimits' GetCurrentThreadStackLimits kernel32 0 # KernelBase -imp 'GetCurrentUmsThread' GetCurrentUmsThread kernel32 547 -imp 'GetCursor' GetCursor user32 1826 0 -imp 'GetCursorFrameInfo' GetCursorFrameInfo user32 1827 -imp 'GetCursorInfo' GetCursorInfo user32 1828 -imp 'GetCursorPos' GetCursorPos user32 1829 1 -imp 'GetDC' GetDC user32 1830 1 imp 'GetDCBrushColor' GetDCBrushColor gdi32 1628 imp 'GetDCDpiScaleValue' GetDCDpiScaleValue gdi32 1629 -imp 'GetDCEx' GetDCEx user32 1831 imp 'GetDCOrgEx' GetDCOrgEx gdi32 1630 imp 'GetDCPenColor' GetDCPenColor gdi32 1631 imp 'GetDIBColorTable' GetDIBColorTable gdi32 1632 imp 'GetDIBits' GetDIBits gdi32 1633 -imp 'GetDateFormatA' GetDateFormatA kernel32 0 # KernelBase -imp 'GetDateFormatAWorker' GetDateFormatAWorker kernel32 549 -imp 'GetDateFormatEx' GetDateFormatEx kernel32 0 # KernelBase -imp 'GetDateFormat' GetDateFormatW kernel32 0 # KernelBase -imp 'GetDateFormatWWorker' GetDateFormatWWorker kernel32 552 -imp 'GetDefaultCommConfigA' GetDefaultCommConfigA kernel32 553 -imp 'GetDefaultCommConfig' GetDefaultCommConfigW kernel32 554 -imp 'GetDesktopID' GetDesktopID user32 1832 -imp 'GetDesktopWindow' GetDesktopWindow user32 1833 0 imp 'GetDeviceCaps' GetDeviceCaps gdi32 1634 -imp 'GetDeviceDriverBaseNameA' GetDeviceDriverBaseNameA KernelBase 511 -imp 'GetDeviceDriverBaseName' GetDeviceDriverBaseNameW KernelBase 512 -imp 'GetDeviceDriverFileNameA' GetDeviceDriverFileNameA KernelBase 513 -imp 'GetDeviceDriverFileName' GetDeviceDriverFileNameW KernelBase 514 imp 'GetDeviceGammaRamp' GetDeviceGammaRamp gdi32 1635 -imp 'GetDevicePowerState' GetDevicePowerState kernel32 555 -imp 'GetDialogBaseUnits' GetDialogBaseUnits user32 1834 -imp 'GetDialogControlDpiChangeBehavior' GetDialogControlDpiChangeBehavior user32 1835 -imp 'GetDialogDpiChangeBehavior' GetDialogDpiChangeBehavior user32 1836 -imp 'GetDiskFreeSpaceA' GetDiskFreeSpaceA kernel32 0 # KernelBase -imp 'GetDiskFreeSpaceExA' GetDiskFreeSpaceExA kernel32 0 # KernelBase -imp 'GetDiskFreeSpaceEx' GetDiskFreeSpaceExW kernel32 0 # KernelBase -imp 'GetDiskFreeSpace' GetDiskFreeSpaceW kernel32 0 # KernelBase -imp 'GetDisplayAutoRotationPreferences' GetDisplayAutoRotationPreferences user32 1837 -imp 'GetDisplayConfigBufferSizes' GetDisplayConfigBufferSizes user32 1838 -imp 'GetDlgCtrlID' GetDlgCtrlID user32 1839 -imp 'GetDlgItem' GetDlgItem user32 1840 -imp 'GetDlgItemInt' GetDlgItemInt user32 1841 -imp 'GetDlgItemTextA' GetDlgItemTextA user32 1842 -imp 'GetDlgItemText' GetDlgItemTextW user32 1843 -imp 'GetDllDirectoryA' GetDllDirectoryA kernel32 560 -imp 'GetDllDirectory' GetDllDirectoryW kernel32 561 -imp 'GetDoubleClickTime' GetDoubleClickTime user32 1844 -imp 'GetDpiForMonitorInternal' GetDpiForMonitorInternal user32 1845 -imp 'GetDpiForSystem' GetDpiForSystem user32 1846 -imp 'GetDpiForWindow' GetDpiForWindow user32 1847 -imp 'GetDpiFromDpiAwarenessContext' GetDpiFromDpiAwarenessContext user32 1848 -imp 'GetDriveTypeA' GetDriveTypeA kernel32 0 # KernelBase -imp 'GetDriveType' GetDriveTypeW kernel32 0 # KernelBase -imp 'GetDurationFormat' GetDurationFormat kernel32 564 -imp 'GetDurationFormatEx' GetDurationFormatEx kernel32 0 # KernelBase -imp 'GetDynamicTimeZoneInformation' GetDynamicTimeZoneInformation kernel32 0 # KernelBase -imp 'GetDynamicTimeZoneInformationEffectiveYears' GetDynamicTimeZoneInformationEffectiveYears KernelBase 523 imp 'GetETM' GetETM gdi32 1636 imp 'GetEUDCTimeStamp' GetEUDCTimeStamp gdi32 1637 imp 'GetEUDCTimeStampEx' GetEUDCTimeStampExW gdi32 1638 -imp 'GetEffectivePackageStatusForUser' GetEffectivePackageStatusForUser KernelBase 524 -imp 'GetEffectivePackageStatusForUserSid' GetEffectivePackageStatusForUserSid KernelBase 525 -imp 'GetEffectiveRightsFromAclA' GetEffectiveRightsFromAclA advapi32 1320 -imp 'GetEffectiveRightsFromAcl' GetEffectiveRightsFromAclW advapi32 1321 -imp 'GetEightBitStringToUnicodeSizeRoutine' GetEightBitStringToUnicodeSizeRoutine KernelBase 526 -imp 'GetEightBitStringToUnicodeStringRoutine' GetEightBitStringToUnicodeStringRoutine KernelBase 527 -imp 'GetEnabledXStateFeatures' GetEnabledXStateFeatures kernel32 0 # KernelBase -imp 'GetEncryptedFileMetadata' GetEncryptedFileMetadata advapi32 1322 -imp 'GetEncryptedFileVersionExt' GetEncryptedFileVersionExt kernel32 568 -imp 'GetEnhMetaFileA' GetEnhMetaFileA gdi32 1639 +imp 'GetEnhMetaFile' GetEnhMetaFileW gdi32 1646 imp 'GetEnhMetaFileBits' GetEnhMetaFileBits gdi32 1640 -imp 'GetEnhMetaFileDescriptionA' GetEnhMetaFileDescriptionA gdi32 1641 imp 'GetEnhMetaFileDescription' GetEnhMetaFileDescriptionW gdi32 1642 imp 'GetEnhMetaFileHeader' GetEnhMetaFileHeader gdi32 1643 imp 'GetEnhMetaFilePaletteEntries' GetEnhMetaFilePaletteEntries gdi32 1644 imp 'GetEnhMetaFilePixelFormat' GetEnhMetaFilePixelFormat gdi32 1645 -imp 'GetEnhMetaFile' GetEnhMetaFileW gdi32 1646 -imp 'GetEnvironmentStrings' GetEnvironmentStringsW kernel32 0 1 # KernelBase -imp 'GetEnvironmentStringsA' GetEnvironmentStringsA kernel32 0 1 # KernelBase -imp 'GetEnvironmentVariable' GetEnvironmentVariableW kernel32 0 3 # KernelBase -imp 'GetEnvironmentVariableA' GetEnvironmentVariableA kernel32 0 3 # KernelBase -imp 'GetEraNameCountedString' GetEraNameCountedString KernelBase 534 -imp 'GetErrorMode' GetErrorMode kernel32 0 # KernelBase -imp 'GetEventLogInformation' GetEventLogInformation advapi32 1323 -imp 'GetExitCodeProcess' GetExitCodeProcess kernel32 0 2 # KernelBase -imp 'GetExitCodeThread' GetExitCodeThread kernel32 0 2 # KernelBase -imp 'GetExpandedNameA' GetExpandedNameA kernel32 578 -imp 'GetExpandedName' GetExpandedNameW kernel32 579 -imp 'GetExplicitEntriesFromAclA' GetExplicitEntriesFromAclA advapi32 1324 -imp 'GetExplicitEntriesFromAcl' GetExplicitEntriesFromAclW advapi32 1325 -imp 'GetExtensionApplicationUserModelId' GetExtensionApplicationUserModelId KernelBase 538 -imp 'GetExtensionProgIds' GetExtensionProgIds KernelBase 539 -imp 'GetExtensionProperty' GetExtensionProperty KernelBase 540 -imp 'GetExtensionProperty2' GetExtensionProperty2 KernelBase 541 -imp 'GetFallbackDisplayName' GetFallbackDisplayName KernelBase 542 -imp 'GetFileAttributesA' GetFileAttributesA kernel32 0 1 # KernelBase -imp 'GetFileAttributes' GetFileAttributesW kernel32 0 1 # KernelBase -imp 'GetFileAttributesExA' GetFileAttributesExA kernel32 0 3 # KernelBase -imp 'GetFileAttributesEx' GetFileAttributesExW kernel32 0 3 # KernelBase -imp 'GetFileAttributesTransactedA' GetFileAttributesTransactedA kernel32 583 -imp 'GetFileAttributesTransacted' GetFileAttributesTransactedW kernel32 584 -imp 'GetFileBandwidthReservation' GetFileBandwidthReservation kernel32 586 -imp 'GetFileInformationByHandle' GetFileInformationByHandle kernel32 0 2 # KernelBase -imp 'GetFileInformationByHandleEx' GetFileInformationByHandleEx kernel32 0 4 # KernelBase -imp 'GetFileMUIInfo' GetFileMUIInfo kernel32 0 # KernelBase -imp 'GetFileMUIPath' GetFileMUIPath kernel32 0 # KernelBase -imp 'GetFileNameFromBrowse' GetFileNameFromBrowse shell32 63 -imp 'GetFileSecurity' GetFileSecurityW advapi32 0 5 # KernelBase -imp 'GetFileSecurityA' GetFileSecurityA advapi32 1326 5 -imp 'GetFileSize' GetFileSize kernel32 0 2 # KernelBase -imp 'GetFileSizeEx' GetFileSizeEx kernel32 0 2 # KernelBase -imp 'GetFileTime' GetFileTime kernel32 0 4 # KernelBase -imp 'GetFileTitleA' GetFileTitleA comdlg32 111 3 -imp 'GetFileTitle' GetFileTitleW comdlg32 112 3 -imp 'GetFileType' GetFileType kernel32 0 1 # KernelBase -imp 'GetFileVersionInfoA' GetFileVersionInfoA KernelBase 556 -imp 'GetFileVersionInfoByHandle' GetFileVersionInfoByHandle KernelBase 557 -imp 'GetFileVersionInfoExA' GetFileVersionInfoExA KernelBase 558 -imp 'GetFileVersionInfoEx' GetFileVersionInfoExW KernelBase 559 -imp 'GetFileVersionInfoSizeA' GetFileVersionInfoSizeA KernelBase 560 -imp 'GetFileVersionInfoSizeExA' GetFileVersionInfoSizeExA KernelBase 561 -imp 'GetFileVersionInfoSizeEx' GetFileVersionInfoSizeExW KernelBase 562 -imp 'GetFileVersionInfoSize' GetFileVersionInfoSizeW KernelBase 563 -imp 'GetFileVersionInfo' GetFileVersionInfoW KernelBase 564 -imp 'GetFinalPathNameByHandleA' GetFinalPathNameByHandleA kernel32 0 4 # KernelBase -imp 'GetFinalPathNameByHandle' GetFinalPathNameByHandleW kernel32 0 4 # KernelBase -imp 'GetFirmwareEnvironmentVariableA' GetFirmwareEnvironmentVariableA kernel32 597 -imp 'GetFirmwareEnvironmentVariableExA' GetFirmwareEnvironmentVariableExA kernel32 598 -imp 'GetFirmwareEnvironmentVariableEx' GetFirmwareEnvironmentVariableExW kernel32 599 -imp 'GetFirmwareEnvironmentVariable' GetFirmwareEnvironmentVariableW kernel32 600 -imp 'GetFirmwareType' GetFirmwareType kernel32 601 -imp 'GetFocus' GetFocus user32 1849 imp 'GetFontAssocStatus' GetFontAssocStatus gdi32 1647 imp 'GetFontData' GetFontData gdi32 1648 imp 'GetFontFileData' GetFontFileData gdi32 1649 @@ -2189,653 +3570,748 @@ imp 'GetFontLanguageInfo' GetFontLanguageInfo gdi32 1651 imp 'GetFontRealizationInfo' GetFontRealizationInfo gdi32 1652 imp 'GetFontResourceInfo' GetFontResourceInfoW gdi32 1653 imp 'GetFontUnicodeRanges' GetFontUnicodeRanges gdi32 1654 -imp 'GetForegroundWindow' GetForegroundWindow user32 1850 -imp 'GetFullPathName' GetFullPathNameW kernel32 0 4 # KernelBase -imp 'GetFullPathNameA' GetFullPathNameA kernel32 0 4 # KernelBase -imp 'GetFullPathNameTransactedA' GetFullPathNameTransactedA kernel32 603 -imp 'GetFullPathNameTransacted' GetFullPathNameTransactedW kernel32 604 -imp 'GetGPOListInternalA' GetGPOListInternalA KernelBase 569 -imp 'GetGPOListInternal' GetGPOListInternalW KernelBase 570 -imp 'GetGUIThreadInfo' GetGUIThreadInfo user32 1851 -imp 'GetGamingDeviceModelInformation' GetGamingDeviceModelInformation KernelBase 571 -imp 'GetGeoInfoA' GetGeoInfoA kernel32 606 -imp 'GetGeoInfoEx' GetGeoInfoEx KernelBase 572 -imp 'GetGeoInfo' GetGeoInfoW kernel32 0 # KernelBase -imp 'GetGestureConfig' GetGestureConfig user32 1852 -imp 'GetGestureExtraArgs' GetGestureExtraArgs user32 1853 -imp 'GetGestureInfo' GetGestureInfo user32 1854 -imp 'GetGlyphIndicesA' GetGlyphIndicesA gdi32 1655 imp 'GetGlyphIndices' GetGlyphIndicesW gdi32 1656 -imp 'GetGlyphOutlineA' GetGlyphOutlineA gdi32 1658 imp 'GetGlyphOutline' GetGlyphOutlineW gdi32 1659 imp 'GetGlyphOutlineWow' GetGlyphOutlineWow gdi32 1660 imp 'GetGraphicsMode' GetGraphicsMode gdi32 1661 -imp 'GetGuiResources' GetGuiResources user32 1855 imp 'GetHFONT' GetHFONT gdi32 1662 -imp 'GetHandleInformation' GetHandleInformation kernel32 0 2 # KernelBase -imp 'GetHivePath' GetHivePath KernelBase 575 -imp 'GetHostName' GetHostNameW ws2_32 33 -imp 'GetICMProfileA' GetICMProfileA gdi32 1663 imp 'GetICMProfile' GetICMProfileW gdi32 1664 -imp 'GetIconInfo' GetIconInfo user32 1856 -imp 'GetIconInfoExA' GetIconInfoExA user32 1857 -imp 'GetIconInfoEx' GetIconInfoExW user32 1858 -imp 'GetInformationCodeAuthzLevel' GetInformationCodeAuthzLevelW advapi32 1328 -imp 'GetInformationCodeAuthzPolicy' GetInformationCodeAuthzPolicyW advapi32 1329 -imp 'GetInheritanceSourceA' GetInheritanceSourceA advapi32 1330 -imp 'GetInheritanceSource' GetInheritanceSourceW advapi32 1331 -imp 'GetInputDesktop' GetInputDesktop user32 1859 -imp 'GetInputLocaleInfo' GetInputLocaleInfo user32 1860 -imp 'GetInputState' GetInputState user32 1861 -imp 'GetIntegratedDisplaySize' GetIntegratedDisplaySize KernelBase 576 -imp 'GetInternalWindowPos' GetInternalWindowPos user32 1862 -imp 'GetIsEdpEnabled' GetIsEdpEnabled KernelBase 577 -imp 'GetKBCodePage' GetKBCodePage user32 1863 -imp 'GetKernelObjectSecurity' GetKernelObjectSecurity advapi32 0 # KernelBase -imp 'GetKerningPairsA' GetKerningPairsA gdi32 1666 imp 'GetKerningPairs' GetKerningPairsW gdi32 1667 -imp 'GetKeyNameTextA' GetKeyNameTextA user32 1864 -imp 'GetKeyNameText' GetKeyNameTextW user32 1865 -imp 'GetKeyState' GetKeyState user32 1866 1 -imp 'GetKeyboardLayout' GetKeyboardLayout user32 1867 1 -imp 'GetKeyboardLayoutList' GetKeyboardLayoutList user32 1868 -imp 'GetKeyboardLayoutNameA' GetKeyboardLayoutNameA user32 1869 -imp 'GetKeyboardLayoutName' GetKeyboardLayoutNameW user32 1870 -imp 'GetKeyboardState' GetKeyboardState user32 1871 -imp 'GetKeyboardType' GetKeyboardType user32 1872 -imp 'GetLargePageMinimum' GetLargePageMinimum kernel32 0 # KernelBase -imp 'GetLargestConsoleWindowSize' GetLargestConsoleWindowSize kernel32 0 1 # KernelBase -imp 'GetLastActivePopup' GetLastActivePopup user32 1873 -imp 'GetLastError' GetLastError kernel32 0 0 # KernelBase -imp 'GetLastInputInfo' GetLastInputInfo user32 1874 -imp 'GetLayeredWindowAttributes' GetLayeredWindowAttributes user32 1875 imp 'GetLayout' GetLayout gdi32 1668 -imp 'GetLengthSid' GetLengthSid advapi32 0 # KernelBase -imp 'GetListBoxInfo' GetListBoxInfo user32 1876 -imp 'GetLocalManagedApplicationData' GetLocalManagedApplicationData advapi32 1334 -imp 'GetLocalManagedApplications' GetLocalManagedApplications advapi32 1335 -imp 'GetLocalTime' GetLocalTime kernel32 0 # KernelBase -imp 'GetLocaleInfoA' GetLocaleInfoA kernel32 0 # KernelBase -imp 'GetLocaleInfoEx' GetLocaleInfoEx kernel32 0 # KernelBase -imp 'GetLocaleInfoHelper' GetLocaleInfoHelper KernelBase 586 -imp 'GetLocaleInfo' GetLocaleInfoW kernel32 0 # KernelBase -imp 'GetLogColorSpaceA' GetLogColorSpaceA gdi32 1669 imp 'GetLogColorSpace' GetLogColorSpaceW gdi32 1670 -imp 'GetLogicalDriveStringsA' GetLogicalDriveStringsA kernel32 617 -imp 'GetLogicalDriveStrings' GetLogicalDriveStringsW kernel32 0 # KernelBase -imp 'GetLogicalDrives' GetLogicalDrives kernel32 0 0 # KernelBase -imp 'GetLogicalProcessorInformation' GetLogicalProcessorInformation kernel32 0 # KernelBase -imp 'GetLogicalProcessorInformationEx' GetLogicalProcessorInformationEx kernel32 0 # KernelBase -imp 'GetLongPathNameA' GetLongPathNameA kernel32 0 # KernelBase -imp 'GetLongPathNameTransactedA' GetLongPathNameTransactedA kernel32 623 -imp 'GetLongPathNameTransacted' GetLongPathNameTransactedW kernel32 624 -imp 'GetLongPathName' GetLongPathNameW kernel32 0 # KernelBase -imp 'GetMagnificationDesktopColorEffect' GetMagnificationDesktopColorEffect user32 1877 -imp 'GetMagnificationDesktopMagnification' GetMagnificationDesktopMagnification user32 1878 -imp 'GetMagnificationDesktopSamplingMode' GetMagnificationDesktopSamplingMode user32 1879 -imp 'GetMagnificationLensCtxInformation' GetMagnificationLensCtxInformation user32 1880 -imp 'GetMailslotInfo' GetMailslotInfo kernel32 626 -imp 'GetManagedApplicationCategories' GetManagedApplicationCategories advapi32 1336 -imp 'GetManagedApplications' GetManagedApplications advapi32 1337 imp 'GetMapMode' GetMapMode gdi32 1671 -imp 'GetMappedFileNameA' GetMappedFileNameA KernelBase 594 -imp 'GetMappedFileName' GetMappedFileNameW KernelBase 595 -imp 'GetMaximumProcessorCount' GetMaximumProcessorCount kernel32 627 1 # Windows 7+ -imp 'GetMaximumProcessorGroupCount' GetMaximumProcessorGroupCount kernel32 628 -imp 'GetMemoryErrorHandlingCapabilities' GetMemoryErrorHandlingCapabilities kernel32 0 # KernelBase -imp 'GetMenu' GetMenu user32 1881 1 -imp 'GetMenuBarInfo' GetMenuBarInfo user32 1882 -imp 'GetMenuCheckMarkDimensions' GetMenuCheckMarkDimensions user32 1883 -imp 'GetMenuContextHelpId' GetMenuContextHelpId user32 1884 -imp 'GetMenuDefaultItem' GetMenuDefaultItem user32 1885 -imp 'GetMenuInfo' GetMenuInfo user32 1886 -imp 'GetMenuItemCount' GetMenuItemCount user32 1887 -imp 'GetMenuItemID' GetMenuItemID user32 1888 -imp 'GetMenuItemInfoA' GetMenuItemInfoA user32 1889 -imp 'GetMenuItemInfo' GetMenuItemInfoW user32 1890 -imp 'GetMenuItemRect' GetMenuItemRect user32 1891 -imp 'GetMenuState' GetMenuState user32 1892 -imp 'GetMenuStringA' GetMenuStringA user32 1893 -imp 'GetMenuString' GetMenuStringW user32 1894 -imp 'GetMessage' GetMessageW user32 1899 4 -imp 'GetMessageA' GetMessageA user32 1895 4 -imp 'GetMessageExtraInfo' GetMessageExtraInfo user32 1896 -imp 'GetMessagePos' GetMessagePos user32 1897 -imp 'GetMessageTime' GetMessageTime user32 1898 -imp 'GetMetaFileA' GetMetaFileA gdi32 1672 -imp 'GetMetaFileBitsEx' GetMetaFileBitsEx gdi32 1673 imp 'GetMetaFile' GetMetaFileW gdi32 1674 +imp 'GetMetaFileBitsEx' GetMetaFileBitsEx gdi32 1673 imp 'GetMetaRgn' GetMetaRgn gdi32 1675 imp 'GetMiterLimit' GetMiterLimit gdi32 1676 -imp 'GetModuleBaseNameA' GetModuleBaseNameA KernelBase 597 -imp 'GetModuleBaseName' GetModuleBaseNameW KernelBase 598 -imp 'GetModuleFileName' GetModuleFileNameW kernel32 0 3 # KernelBase -imp 'GetModuleFileNameA' GetModuleFileNameA kernel32 0 3 # KernelBase -imp 'GetModuleFileNameExA' GetModuleFileNameExA KernelBase 600 -imp 'GetModuleFileNameEx' GetModuleFileNameExW KernelBase 601 -imp 'GetModuleHandle' GetModuleHandleA kernel32 0 1 # KernelBase -imp 'GetModuleHandleW' GetModuleHandleW kernel32 0 1 # KernelBase -imp 'GetModuleHandleExA' GetModuleHandleExA kernel32 0 3 # KernelBase -imp 'GetModuleHandleEx' GetModuleHandleExW kernel32 0 3 # KernelBase -imp 'GetModuleInformation' GetModuleInformation KernelBase 607 -imp 'GetMonitorInfoA' GetMonitorInfoA user32 1900 -imp 'GetMonitorInfo' GetMonitorInfoW user32 1901 -imp 'GetMouseMovePointsEx' GetMouseMovePointsEx user32 1902 -imp 'GetMultipleTrusteeA' GetMultipleTrusteeA advapi32 1338 -imp 'GetMultipleTrusteeOperationA' GetMultipleTrusteeOperationA advapi32 1339 -imp 'GetMultipleTrusteeOperation' GetMultipleTrusteeOperationW advapi32 1340 -imp 'GetMultipleTrustee' GetMultipleTrusteeW advapi32 1341 -imp 'GetNLSVersion' GetNLSVersion kernel32 0 # KernelBase -imp 'GetNLSVersionEx' GetNLSVersionEx kernel32 0 # KernelBase -imp 'GetNameInfo' GetNameInfoW ws2_32 34 -imp 'GetNamedLocaleHashNode' GetNamedLocaleHashNode KernelBase 610 -imp 'GetNamedPipeAttribute' GetNamedPipeAttribute KernelBase 611 -imp 'GetNamedPipeClientComputerNameA' GetNamedPipeClientComputerNameA kernel32 639 -imp 'GetNamedPipeClientComputerName' GetNamedPipeClientComputerNameW kernel32 0 # KernelBase -imp 'GetNamedPipeClientProcessId' GetNamedPipeClientProcessId kernel32 641 -imp 'GetNamedPipeClientSessionId' GetNamedPipeClientSessionId kernel32 642 -imp 'GetNamedPipeHandleStateA' GetNamedPipeHandleStateA kernel32 643 -imp 'GetNamedPipeHandleState' GetNamedPipeHandleStateW kernel32 0 # KernelBase -imp 'GetNamedPipeInfo' GetNamedPipeInfo kernel32 0 # KernelBase -imp 'GetNamedPipeServerProcessId' GetNamedPipeServerProcessId kernel32 646 -imp 'GetNamedPipeServerSessionId' GetNamedPipeServerSessionId kernel32 647 -imp 'GetNamedSecurityInfoA' GetNamedSecurityInfoA advapi32 1342 -imp 'GetNamedSecurityInfoExA' GetNamedSecurityInfoExA advapi32 1343 -imp 'GetNamedSecurityInfoEx' GetNamedSecurityInfoExW advapi32 1344 -imp 'GetNamedSecurityInfo' GetNamedSecurityInfoW advapi32 1345 -imp 'GetNativeSystemInfo' GetNativeSystemInfo kernel32 0 # KernelBase imp 'GetNearestColor' GetNearestColor gdi32 1677 imp 'GetNearestPaletteIndex' GetNearestPaletteIndex gdi32 1678 -imp 'GetNextDlgGroupItem' GetNextDlgGroupItem user32 1903 -imp 'GetNextDlgTabItem' GetNextDlgTabItem user32 1904 -imp 'GetNextFgPolicyRefreshInfoInternal' GetNextFgPolicyRefreshInfoInternal KernelBase 616 -imp 'GetNextUmsListItem' GetNextUmsListItem kernel32 649 -imp 'GetNextVDMCommand' GetNextVDMCommand kernel32 650 -imp 'GetNumaAvailableMemoryNode' GetNumaAvailableMemoryNode kernel32 651 -imp 'GetNumaAvailableMemoryNodeEx' GetNumaAvailableMemoryNodeEx kernel32 652 -imp 'GetNumaHighestNodeNumber' GetNumaHighestNodeNumber kernel32 0 # KernelBase -imp 'GetNumaNodeNumberFromHandle' GetNumaNodeNumberFromHandle kernel32 654 -imp 'GetNumaNodeProcessorMask' GetNumaNodeProcessorMask kernel32 655 -imp 'GetNumaNodeProcessorMaskEx' GetNumaNodeProcessorMaskEx kernel32 0 # KernelBase -imp 'GetNumaProcessorNode' GetNumaProcessorNode kernel32 657 -imp 'GetNumaProcessorNodeEx' GetNumaProcessorNodeEx kernel32 658 -imp 'GetNumaProximityNode' GetNumaProximityNode kernel32 659 -imp 'GetNumaProximityNodeEx' GetNumaProximityNodeEx kernel32 0 # KernelBase -imp 'GetNumberFormatA' GetNumberFormatA kernel32 661 -imp 'GetNumberFormatEx' GetNumberFormatEx kernel32 0 # KernelBase -imp 'GetNumberFormat' GetNumberFormatW kernel32 0 # KernelBase -imp 'GetNumberOfConsoleFonts' GetNumberOfConsoleFonts kernel32 664 -imp 'GetNumberOfConsoleInputEvents' GetNumberOfConsoleInputEvents kernel32 0 2 # KernelBase -imp 'GetNumberOfConsoleMouseButtons' GetNumberOfConsoleMouseButtons kernel32 0 1 # KernelBase -imp 'GetNumberOfEventLogRecords' GetNumberOfEventLogRecords advapi32 1346 imp 'GetNumberOfPhysicalMonitors' GetNumberOfPhysicalMonitors gdi32 1679 -imp 'GetOEMCP' GetOEMCP kernel32 0 # KernelBase imp 'GetOPMInformation' GetOPMInformation gdi32 1680 imp 'GetOPMRandomNumber' GetOPMRandomNumber gdi32 1681 -imp 'GetObjectA' GetObjectA gdi32 1682 -imp 'GetObjectType' GetObjectType gdi32 1683 imp 'GetObject' GetObjectW gdi32 1684 -imp 'GetOldestEventLogRecord' GetOldestEventLogRecord advapi32 1347 -imp 'GetOpenClipboardWindow' GetOpenClipboardWindow user32 1905 -imp 'GetOpenFileNameA' GetOpenFileNameA comdlg32 113 1 -imp 'GetOpenFileName' GetOpenFileNameW comdlg32 114 1 -imp 'GetOsManufacturingMode' GetOsManufacturingMode KernelBase 625 -imp 'GetOsSafeBootMode' GetOsSafeBootMode KernelBase 626 -imp 'GetOutlineTextMetricsA' GetOutlineTextMetricsA gdi32 1685 +imp 'GetObjectType' GetObjectType gdi32 1683 imp 'GetOutlineTextMetrics' GetOutlineTextMetricsW gdi32 1686 -imp 'GetOverlappedAccessResults' GetOverlappedAccessResults advapi32 1348 -imp 'GetOverlappedResult' GetOverlappedResult kernel32 0 4 # KernelBase -imp 'GetOverlappedResultEx' GetOverlappedResultEx kernel32 0 5 # KernelBase -imp 'GetPackageApplicationContext' GetPackageApplicationContext KernelBase 629 -imp 'GetPackageApplicationIds' GetPackageApplicationIds kernel32 0 # KernelBase -imp 'GetPackageApplicationProperty' GetPackageApplicationProperty KernelBase 631 -imp 'GetPackageApplicationPropertyString' GetPackageApplicationPropertyString KernelBase 632 -imp 'GetPackageApplicationResourcesContext' GetPackageApplicationResourcesContext KernelBase 633 -imp 'GetPackageContext' GetPackageContext KernelBase 634 -imp 'GetPackageFamilyName' GetPackageFamilyName kernel32 0 # KernelBase -imp 'GetPackageFamilyNameFromProgId' GetPackageFamilyNameFromProgId KernelBase 636 -imp 'GetPackageFamilyNameFromToken' GetPackageFamilyNameFromToken KernelBase 637 -imp 'GetPackageFullName' GetPackageFullName kernel32 0 # KernelBase -imp 'GetPackageFullNameFromToken' GetPackageFullNameFromToken KernelBase 639 -imp 'GetPackageId' GetPackageId kernel32 0 # KernelBase -imp 'GetPackageInfo' GetPackageInfo kernel32 0 # KernelBase -imp 'GetPackageInstallTime' GetPackageInstallTime KernelBase 642 -imp 'GetPackageOSMaxVersionTested' GetPackageOSMaxVersionTested KernelBase 643 -imp 'GetPackagePath' GetPackagePath kernel32 0 # KernelBase -imp 'GetPackagePathByFullName' GetPackagePathByFullName kernel32 0 # KernelBase -imp 'GetPackagePathOnVolume' GetPackagePathOnVolume KernelBase 646 -imp 'GetPackageProperty' GetPackageProperty KernelBase 647 -imp 'GetPackagePropertyString' GetPackagePropertyString KernelBase 648 -imp 'GetPackageResourcesContext' GetPackageResourcesContext KernelBase 649 -imp 'GetPackageResourcesProperty' GetPackageResourcesProperty KernelBase 650 -imp 'GetPackageSecurityContext' GetPackageSecurityContext KernelBase 651 -imp 'GetPackageSecurityProperty' GetPackageSecurityProperty KernelBase 652 -imp 'GetPackageStatus' GetPackageStatus KernelBase 653 -imp 'GetPackageStatusForUser' GetPackageStatusForUser KernelBase 654 -imp 'GetPackageStatusForUserSid' GetPackageStatusForUserSid KernelBase 655 -imp 'GetPackageTargetPlatformProperty' GetPackageTargetPlatformProperty KernelBase 656 -imp 'GetPackageVolumeSisPath' GetPackageVolumeSisPath KernelBase 657 -imp 'GetPackagesByPackageFamily' GetPackagesByPackageFamily kernel32 0 # KernelBase imp 'GetPaletteEntries' GetPaletteEntries gdi32 1687 -imp 'GetParent' GetParent user32 1906 1 imp 'GetPath' GetPath gdi32 1688 -imp 'GetPerformanceInfo' GetPerformanceInfo KernelBase 659 -imp 'GetPersistedFileLocation' GetPersistedFileLocationW KernelBase 660 -imp 'GetPersistedRegistryLocation' GetPersistedRegistryLocationW KernelBase 661 -imp 'GetPersistedRegistryValue' GetPersistedRegistryValueW KernelBase 662 -imp 'GetPhysicalCursorPos' GetPhysicalCursorPos user32 1907 imp 'GetPhysicalMonitorDescription' GetPhysicalMonitorDescription gdi32 1689 imp 'GetPhysicalMonitors' GetPhysicalMonitors gdi32 1690 -imp 'GetPhysicallyInstalledSystemMemory' GetPhysicallyInstalledSystemMemory kernel32 0 # KernelBase imp 'GetPixel' GetPixel gdi32 1691 3 imp 'GetPixelFormat' GetPixelFormat gdi32 1692 -imp 'GetPointerCursorId' GetPointerCursorId user32 1908 -imp 'GetPointerDevice' GetPointerDevice user32 1909 -imp 'GetPointerDeviceCursors' GetPointerDeviceCursors user32 1910 -imp 'GetPointerDeviceProperties' GetPointerDeviceProperties user32 1911 -imp 'GetPointerDeviceRects' GetPointerDeviceRects user32 1912 -imp 'GetPointerDevices' GetPointerDevices user32 1913 -imp 'GetPointerFrameArrivalTimes' GetPointerFrameArrivalTimes user32 1914 -imp 'GetPointerFrameInfo' GetPointerFrameInfo user32 1915 -imp 'GetPointerFrameInfoHistory' GetPointerFrameInfoHistory user32 1916 -imp 'GetPointerFramePenInfo' GetPointerFramePenInfo user32 1917 -imp 'GetPointerFramePenInfoHistory' GetPointerFramePenInfoHistory user32 1918 -imp 'GetPointerFrameTouchInfo' GetPointerFrameTouchInfo user32 1919 -imp 'GetPointerFrameTouchInfoHistory' GetPointerFrameTouchInfoHistory user32 1920 -imp 'GetPointerInfo' GetPointerInfo user32 1921 -imp 'GetPointerInfoHistory' GetPointerInfoHistory user32 1922 -imp 'GetPointerInputTransform' GetPointerInputTransform user32 1923 -imp 'GetPointerPenInfo' GetPointerPenInfo user32 1924 -imp 'GetPointerPenInfoHistory' GetPointerPenInfoHistory user32 1925 -imp 'GetPointerTouchInfo' GetPointerTouchInfo user32 1926 -imp 'GetPointerTouchInfoHistory' GetPointerTouchInfoHistory user32 1927 -imp 'GetPointerType' GetPointerType user32 1928 imp 'GetPolyFillMode' GetPolyFillMode gdi32 1693 -imp 'GetPreviousFgPolicyRefreshInfoInternal' GetPreviousFgPolicyRefreshInfoInternal KernelBase 664 -imp 'GetPriorityClass' GetPriorityClass kernel32 0 1 # KernelBase -imp 'GetPriorityClipboardFormat' GetPriorityClipboardFormat user32 1929 -imp 'GetPrivateObjectSecurity' GetPrivateObjectSecurity advapi32 0 # KernelBase -imp 'GetPrivateProfileIntA' GetPrivateProfileIntA kernel32 680 -imp 'GetPrivateProfileInt' GetPrivateProfileIntW kernel32 681 -imp 'GetPrivateProfileSectionA' GetPrivateProfileSectionA kernel32 682 -imp 'GetPrivateProfileSectionNamesA' GetPrivateProfileSectionNamesA kernel32 683 -imp 'GetPrivateProfileSectionNames' GetPrivateProfileSectionNamesW kernel32 684 -imp 'GetPrivateProfileSection' GetPrivateProfileSectionW kernel32 685 -imp 'GetPrivateProfileStringA' GetPrivateProfileStringA kernel32 686 -imp 'GetPrivateProfileString' GetPrivateProfileStringW kernel32 687 -imp 'GetPrivateProfileStructA' GetPrivateProfileStructA kernel32 688 -imp 'GetPrivateProfileStruct' GetPrivateProfileStructW kernel32 689 -imp 'GetProcAddress' GetProcAddress kernel32 0 2 # KernelBase -imp 'GetProcAddressForCaller' GetProcAddressForCaller KernelBase 668 -imp 'GetProcessAffinityMask' GetProcessAffinityMask kernel32 0 3 # KernelBase -imp 'GetProcessDEPPolicy' GetProcessDEPPolicy kernel32 692 -imp 'GetProcessDefaultCpuSets' GetProcessDefaultCpuSets kernel32 0 # KernelBase -imp 'GetProcessDefaultLayout' GetProcessDefaultLayout user32 1930 -imp 'GetProcessDpiAwarenessInternal' GetProcessDpiAwarenessInternal user32 1931 -imp 'GetProcessGroupAffinity' GetProcessGroupAffinity kernel32 0 # KernelBase -imp 'GetProcessHandleCount' GetProcessHandleCount kernel32 0 2 # KernelBase -imp 'GetProcessHeap' GetProcessHeap kernel32 0 # KernelBase -imp 'GetProcessHeaps' GetProcessHeaps kernel32 0 # KernelBase -imp 'GetProcessId' GetProcessId kernel32 0 1 # KernelBase -imp 'GetProcessIdOfThread' GetProcessIdOfThread kernel32 0 1 # KernelBase -imp 'GetProcessImageFileNameA' GetProcessImageFileNameA kernel32 676 3 -imp 'GetProcessImageFileName' GetProcessImageFileNameW kernel32 677 3 -imp 'GetProcessInformation' GetProcessInformation kernel32 0 4 # KernelBase -imp 'GetProcessIoCounters' GetProcessIoCounters kernel32 701 2 -imp 'GetProcessMemoryInfo' GetProcessMemoryInfo KernelBase 679 -imp 'GetProcessMitigationPolicy' GetProcessMitigationPolicy kernel32 0 # KernelBase -imp 'GetProcessPreferredUILanguages' GetProcessPreferredUILanguages kernel32 0 # KernelBase -imp 'GetProcessPriorityBoost' GetProcessPriorityBoost kernel32 0 2 # KernelBase imp 'GetProcessSessionFonts' GetProcessSessionFonts gdi32 1694 -imp 'GetProcessShutdownParameters' GetProcessShutdownParameters kernel32 0 # KernelBase -imp 'GetProcessTimes' GetProcessTimes kernel32 0 5 # KernelBase -imp 'GetProcessUIContextInformation' GetProcessUIContextInformation user32 2521 -imp 'GetProcessVersion' GetProcessVersion kernel32 0 # KernelBase -imp 'GetProcessWindowStation' GetProcessWindowStation user32 1932 -imp 'GetProcessWorkingSetSize' GetProcessWorkingSetSize kernel32 708 3 -imp 'GetProcessWorkingSetSizeEx' GetProcessWorkingSetSizeEx kernel32 0 4 # KernelBase -imp 'GetProcessorSystemCycleTime' GetProcessorSystemCycleTime kernel32 0 # KernelBase -imp 'GetProductInfo' GetProductInfo kernel32 0 # KernelBase -imp 'GetProfileIntA' GetProfileIntA kernel32 712 -imp 'GetProfileInt' GetProfileIntW kernel32 713 -imp 'GetProfileSectionA' GetProfileSectionA kernel32 714 -imp 'GetProfileSection' GetProfileSectionW kernel32 715 -imp 'GetProfileStringA' GetProfileStringA kernel32 716 -imp 'GetProfileString' GetProfileStringW kernel32 717 -imp 'GetProgmanWindow' GetProgmanWindow user32 1933 -imp 'GetPropA' GetPropA user32 1934 -imp 'GetProp' GetPropW user32 1935 -imp 'GetProtocolAumid' GetProtocolAumid KernelBase 689 -imp 'GetProtocolProperty' GetProtocolProperty KernelBase 690 -imp 'GetPtrCalData' GetPtrCalData KernelBase 691 -imp 'GetPtrCalDataArray' GetPtrCalDataArray KernelBase 692 -imp 'GetPublisherCacheFolder' GetPublisherCacheFolder KernelBase 693 -imp 'GetPublisherRootFolder' GetPublisherRootFolder KernelBase 694 -imp 'GetQueueStatus' GetQueueStatus user32 1936 -imp 'GetQueuedCompletionStatus' GetQueuedCompletionStatus kernel32 0 5 # KernelBase -imp 'GetQueuedCompletionStatusEx' GetQueuedCompletionStatusEx kernel32 0 6 # KernelBase imp 'GetROP2' GetROP2 gdi32 1695 imp 'GetRandomRgn' GetRandomRgn gdi32 1696 imp 'GetRasterizerCaps' GetRasterizerCaps gdi32 1697 -imp 'GetRawInputBuffer' GetRawInputBuffer user32 1937 -imp 'GetRawInputData' GetRawInputData user32 1938 -imp 'GetRawInputDeviceInfoA' GetRawInputDeviceInfoA user32 1939 -imp 'GetRawInputDeviceInfo' GetRawInputDeviceInfoW user32 1940 -imp 'GetRawInputDeviceList' GetRawInputDeviceList user32 1941 -imp 'GetRawPointerDeviceData' GetRawPointerDeviceData user32 1942 -imp 'GetReasonTitleFromReasonCode' GetReasonTitleFromReasonCode user32 1943 imp 'GetRegionData' GetRegionData gdi32 1698 -imp 'GetRegisteredRawInputDevices' GetRegisteredRawInputDevices user32 1944 -imp 'GetRegistryExtensionFlags' GetRegistryExtensionFlags KernelBase 697 -imp 'GetRegistryValueWithFallback' GetRegistryValueWithFallbackW KernelBase 698 imp 'GetRelAbs' GetRelAbs gdi32 1699 imp 'GetRgnBox' GetRgnBox gdi32 1700 -imp 'GetRoamingLastObservedChangeTime' GetRoamingLastObservedChangeTime KernelBase 699 -imp 'GetSaveFileNameA' GetSaveFileNameA comdlg32 115 1 -imp 'GetSaveFileName' GetSaveFileNameW comdlg32 116 1 -imp 'GetScrollBarInfo' GetScrollBarInfo user32 1945 -imp 'GetScrollInfo' GetScrollInfo user32 1946 -imp 'GetScrollPos' GetScrollPos user32 1947 -imp 'GetScrollRange' GetScrollRange user32 1948 -imp 'GetSecureSystemAppDataFolder' GetSecureSystemAppDataFolder KernelBase 700 -imp 'GetSecurityDescriptorControl' GetSecurityDescriptorControl advapi32 0 # KernelBase -imp 'GetSecurityDescriptorDacl' GetSecurityDescriptorDacl advapi32 0 # KernelBase -imp 'GetSecurityDescriptorGroup' GetSecurityDescriptorGroup advapi32 0 # KernelBase -imp 'GetSecurityDescriptorLength' GetSecurityDescriptorLength advapi32 0 # KernelBase -imp 'GetSecurityDescriptorOwner' GetSecurityDescriptorOwner advapi32 0 # KernelBase -imp 'GetSecurityDescriptorRMControl' GetSecurityDescriptorRMControl advapi32 0 # KernelBase -imp 'GetSecurityDescriptorSacl' GetSecurityDescriptorSacl advapi32 0 # KernelBase -imp 'GetSecurityInfo' GetSecurityInfo advapi32 1357 -imp 'GetSecurityInfoExA' GetSecurityInfoExA advapi32 1358 -imp 'GetSecurityInfoEx' GetSecurityInfoExW advapi32 1359 -imp 'GetSendMessageReceiver' GetSendMessageReceiver user32 1949 -imp 'GetSerializedAtomBytes' GetSerializedAtomBytes KernelBase 708 -imp 'GetServiceDisplayNameA' GetServiceDisplayNameA advapi32 1360 -imp 'GetServiceDisplayName' GetServiceDisplayNameW advapi32 1361 -imp 'GetServiceKeyNameA' GetServiceKeyNameA advapi32 1362 -imp 'GetServiceKeyName' GetServiceKeyNameW advapi32 1363 -imp 'GetSharedLocalFolder' GetSharedLocalFolder KernelBase 709 -imp 'GetShellWindow' GetShellWindow user32 1950 0 -imp 'GetShortPathNameA' GetShortPathNameA kernel32 720 -imp 'GetShortPathName' GetShortPathNameW kernel32 0 # KernelBase -imp 'GetSidIdentifierAuthority' GetSidIdentifierAuthority advapi32 0 # KernelBase -imp 'GetSidLengthRequired' GetSidLengthRequired advapi32 0 # KernelBase -imp 'GetSidSubAuthority' GetSidSubAuthority advapi32 0 # KernelBase -imp 'GetSidSubAuthorityCount' GetSidSubAuthorityCount advapi32 0 # KernelBase -imp 'GetStagedPackageOrigin' GetStagedPackageOrigin KernelBase 715 -imp 'GetStagedPackagePathByFullName' GetStagedPackagePathByFullName kernel32 0 # KernelBase -imp 'GetStartupInfo' GetStartupInfoW kernel32 0 1 # KernelBase -imp 'GetStartupInfoA' GetStartupInfoA kernel32 723 1 -imp 'GetStateContainerDepth' GetStateContainerDepth KernelBase 718 -imp 'GetStateFolder' GetStateFolder KernelBase 719 -imp 'GetStateRootFolder' GetStateRootFolder KernelBase 720 -imp 'GetStateRootFolderBase' GetStateRootFolderBase KernelBase 721 -imp 'GetStateSettingsFolder' GetStateSettingsFolder KernelBase 722 -imp 'GetStateVersion' GetStateVersion KernelBase 723 -imp 'GetStdHandle' GetStdHandle kernel32 0 1 # KernelBase imp 'GetStockObject' GetStockObject gdi32 1701 imp 'GetStretchBltMode' GetStretchBltMode gdi32 1702 -imp 'GetStringBitmapA' GetStringBitmapA gdi32 1703 imp 'GetStringBitmap' GetStringBitmapW gdi32 1704 -imp 'GetStringConditionFromBinary' GetStringConditionFromBinary advapi32 1368 -imp 'GetStringScripts' GetStringScripts kernel32 0 # KernelBase -imp 'GetStringTableEntry' GetStringTableEntry KernelBase 726 -imp 'GetStringTypeA' GetStringTypeA kernel32 0 # KernelBase -imp 'GetStringTypeExA' GetStringTypeExA kernel32 729 -imp 'GetStringTypeEx' GetStringTypeExW kernel32 0 # KernelBase -imp 'GetStringType' GetStringTypeW kernel32 0 # KernelBase -imp 'GetSubMenu' GetSubMenu user32 1951 imp 'GetSuggestedOPMProtectedOutputArraySize' GetSuggestedOPMProtectedOutputArraySize gdi32 1705 -imp 'GetSysColor' GetSysColor user32 1952 -imp 'GetSysColorBrush' GetSysColorBrush user32 1953 -imp 'GetSystemAppDataFolder' GetSystemAppDataFolder KernelBase 730 -imp 'GetSystemAppDataKey' GetSystemAppDataKey KernelBase 731 -imp 'GetSystemCpuSetInformation' GetSystemCpuSetInformation kernel32 0 # KernelBase -imp 'GetSystemDEPPolicy' GetSystemDEPPolicy kernel32 734 -imp 'GetSystemDefaultLCID' GetSystemDefaultLCID kernel32 0 # KernelBase -imp 'GetSystemDefaultLangID' GetSystemDefaultLangID kernel32 0 # KernelBase -imp 'GetSystemDefaultLocaleName' GetSystemDefaultLocaleName kernel32 0 # KernelBase -imp 'GetSystemDefaultUILanguage' GetSystemDefaultUILanguage kernel32 0 # KernelBase -imp 'GetSystemDirectory' GetSystemDirectoryW kernel32 0 2 # KernelBase -imp 'GetSystemDirectoryA' GetSystemDirectoryA kernel32 0 2 # KernelBase -imp 'GetSystemDpiForProcess' GetSystemDpiForProcess user32 1954 -imp 'GetSystemFileCacheSize' GetSystemFileCacheSize kernel32 0 # KernelBase -imp 'GetSystemFirmwareTable' GetSystemFirmwareTable kernel32 0 # KernelBase -imp 'GetSystemInfo' GetSystemInfo kernel32 0 1 # KernelBase -imp 'GetSystemMenu' GetSystemMenu user32 1955 2 -imp 'GetSystemMetadataPath' GetSystemMetadataPath KernelBase 742 -imp 'GetSystemMetadataPathForPackage' GetSystemMetadataPathForPackage KernelBase 743 -imp 'GetSystemMetadataPathForPackageFamily' GetSystemMetadataPathForPackageFamily KernelBase 744 -imp 'GetSystemMetrics' GetSystemMetrics user32 1956 -imp 'GetSystemMetricsForDpi' GetSystemMetricsForDpi user32 1957 imp 'GetSystemPaletteEntries' GetSystemPaletteEntries gdi32 1706 imp 'GetSystemPaletteUse' GetSystemPaletteUse gdi32 1707 -imp 'GetSystemPersistedStorageItemList' GetSystemPersistedStorageItemList shell32 919 -imp 'GetSystemPowerStatus' GetSystemPowerStatus kernel32 744 -imp 'GetSystemPreferredUILanguages' GetSystemPreferredUILanguages kernel32 0 # KernelBase -imp 'GetSystemRegistryQuota' GetSystemRegistryQuota kernel32 746 -imp 'GetSystemStateRootFolder' GetSystemStateRootFolder KernelBase 746 -imp 'GetSystemTime' GetSystemTime kernel32 0 1 # KernelBase -imp 'GetSystemTimeAdjustment' GetSystemTimeAdjustment kernel32 0 3 # KernelBase -imp 'GetSystemTimeAdjustmentPrecise' GetSystemTimeAdjustmentPrecise KernelBase 749 -imp 'GetSystemTimeAsFileTime' GetSystemTimeAsFileTime kernel32 0 1 # KernelBase -imp 'GetSystemTimePreciseAsFileTime' GetSystemTimePreciseAsFileTime kernel32 0 1 # KernelBase -imp 'GetSystemTimes' GetSystemTimes kernel32 0 # KernelBase -imp 'GetSystemWindowsDirectoryA' GetSystemWindowsDirectoryA kernel32 0 # KernelBase -imp 'GetSystemWindowsDirectory' GetSystemWindowsDirectoryW kernel32 0 # KernelBase -imp 'GetSystemWow64Directory2A' GetSystemWow64Directory2A KernelBase 755 -imp 'GetSystemWow64Directory2W' GetSystemWow64Directory2W KernelBase 756 -imp 'GetSystemWow64DirectoryA' GetSystemWow64DirectoryA kernel32 0 # KernelBase -imp 'GetSystemWow64Directory' GetSystemWow64DirectoryW kernel32 0 # KernelBase -imp 'GetTabbedTextExtentA' GetTabbedTextExtentA user32 1958 -imp 'GetTabbedTextExtent' GetTabbedTextExtentW user32 1959 -imp 'GetTapeParameters' GetTapeParameters kernel32 756 -imp 'GetTapePosition' GetTapePosition kernel32 757 -imp 'GetTapeStatus' GetTapeStatus kernel32 758 -imp 'GetTargetPlatformContext' GetTargetPlatformContext KernelBase 759 -imp 'GetTaskmanWindow' GetTaskmanWindow user32 1960 -imp 'GetTempFileNameA' GetTempFileNameA kernel32 0 # KernelBase -imp 'GetTempFileName' GetTempFileNameW kernel32 0 # KernelBase -imp 'GetTempPath' GetTempPathW kernel32 0 2 # KernelBase -imp 'GetTempPathA' GetTempPathA kernel32 0 2 # KernelBase imp 'GetTextAlign' GetTextAlign gdi32 1708 imp 'GetTextCharacterExtra' GetTextCharacterExtra gdi32 1709 imp 'GetTextCharset' GetTextCharset gdi32 1710 imp 'GetTextCharsetInfo' GetTextCharsetInfo gdi32 1711 imp 'GetTextColor' GetTextColor gdi32 1712 -imp 'GetTextExtentExPointA' GetTextExtentExPointA gdi32 1713 -imp 'GetTextExtentExPointI' GetTextExtentExPointI gdi32 1714 imp 'GetTextExtentExPoint' GetTextExtentExPointW gdi32 1715 +imp 'GetTextExtentExPointI' GetTextExtentExPointI gdi32 1714 imp 'GetTextExtentExPointWPri' GetTextExtentExPointWPri gdi32 1716 -imp 'GetTextExtentPoint32A' GetTextExtentPoint32A gdi32 1717 -imp 'GetTextExtentPoint32W' GetTextExtentPoint32W gdi32 1718 -imp 'GetTextExtentPointA' GetTextExtentPointA gdi32 1719 -imp 'GetTextExtentPointI' GetTextExtentPointI gdi32 1720 imp 'GetTextExtentPoint' GetTextExtentPointW gdi32 1721 -imp 'GetTextFaceA' GetTextFaceA gdi32 1722 -imp 'GetTextFaceAlias' GetTextFaceAliasW gdi32 1723 +imp 'GetTextExtentPoint32W' GetTextExtentPoint32W gdi32 1718 +imp 'GetTextExtentPointI' GetTextExtentPointI gdi32 1720 imp 'GetTextFace' GetTextFaceW gdi32 1724 -imp 'GetTextMetricsA' GetTextMetricsA gdi32 1725 +imp 'GetTextFaceAlias' GetTextFaceAliasW gdi32 1723 imp 'GetTextMetrics' GetTextMetricsW gdi32 1726 -imp 'GetThreadContext' GetThreadContext kernel32 0 # KernelBase -imp 'GetThreadDescription' GetThreadDescription KernelBase 765 -imp 'GetThreadDesktop' GetThreadDesktop user32 1961 -imp 'GetThreadDpiAwarenessContext' GetThreadDpiAwarenessContext user32 1962 -imp 'GetThreadDpiHostingBehavior' GetThreadDpiHostingBehavior user32 1963 -imp 'GetThreadErrorMode' GetThreadErrorMode kernel32 0 # KernelBase -imp 'GetThreadGroupAffinity' GetThreadGroupAffinity kernel32 0 # KernelBase -imp 'GetThreadIOPendingFlag' GetThreadIOPendingFlag kernel32 0 2 # KernelBase -imp 'GetThreadId' GetThreadId kernel32 0 1 # KernelBase -imp 'GetThreadIdealProcessorEx' GetThreadIdealProcessorEx kernel32 0 # KernelBase -imp 'GetThreadInformation' GetThreadInformation kernel32 0 # KernelBase -imp 'GetThreadLocale' GetThreadLocale kernel32 0 # KernelBase -imp 'GetThreadPreferredUILanguages' GetThreadPreferredUILanguages kernel32 0 # KernelBase -imp 'GetThreadPriority' GetThreadPriority kernel32 0 1 # KernelBase -imp 'GetThreadPriorityBoost' GetThreadPriorityBoost kernel32 0 2 # KernelBase -imp 'GetThreadSelectedCpuSets' GetThreadSelectedCpuSets kernel32 0 # KernelBase -imp 'GetThreadSelectorEntry' GetThreadSelectorEntry kernel32 776 -imp 'GetThreadTimes' GetThreadTimes kernel32 0 5 # KernelBase -imp 'GetThreadUILanguage' GetThreadUILanguage kernel32 0 # KernelBase -imp 'GetThreadWaitChain' GetThreadWaitChain advapi32 1369 -imp 'GetTickCount' GetTickCount kernel32 0 # KernelBase -imp 'GetTickCount64' GetTickCount64 kernel32 0 0 # KernelBase -imp 'GetTimeFormatA' GetTimeFormatA kernel32 0 # KernelBase -imp 'GetTimeFormatAWorker' GetTimeFormatAWorker kernel32 782 -imp 'GetTimeFormatEx' GetTimeFormatEx kernel32 0 # KernelBase -imp 'GetTimeFormat' GetTimeFormatW kernel32 0 # KernelBase -imp 'GetTimeFormatWWorker' GetTimeFormatWWorker kernel32 785 -imp 'GetTimeZoneInformation' GetTimeZoneInformation kernel32 0 # KernelBase -imp 'GetTimeZoneInformationForYear' GetTimeZoneInformationForYear kernel32 0 # KernelBase -imp 'GetTitleBarInfo' GetTitleBarInfo user32 1964 -imp 'GetTokenInformation' GetTokenInformation advapi32 0 # KernelBase -imp 'GetTopLevelWindow' GetTopLevelWindow user32 1965 -imp 'GetTopWindow' GetTopWindow user32 1966 -imp 'GetTouchInputInfo' GetTouchInputInfo user32 1967 imp 'GetTransform' GetTransform gdi32 1727 -imp 'GetTrusteeFormA' GetTrusteeFormA advapi32 1374 -imp 'GetTrusteeForm' GetTrusteeFormW advapi32 1375 -imp 'GetTrusteeNameA' GetTrusteeNameA advapi32 1376 -imp 'GetTrusteeName' GetTrusteeNameW advapi32 1377 -imp 'GetTrusteeTypeA' GetTrusteeTypeA advapi32 1378 -imp 'GetTrusteeType' GetTrusteeTypeW advapi32 1379 -imp 'GetUILanguageInfo' GetUILanguageInfo kernel32 0 # KernelBase -imp 'GetUmsCompletionListEvent' GetUmsCompletionListEvent kernel32 789 -imp 'GetUmsSystemThreadInformation' GetUmsSystemThreadInformation kernel32 790 -imp 'GetUnicodeStringToEightBitSizeRoutine' GetUnicodeStringToEightBitSizeRoutine KernelBase 791 -imp 'GetUnicodeStringToEightBitStringRoutine' GetUnicodeStringToEightBitStringRoutine KernelBase 792 -imp 'GetUnpredictedMessagePos' GetUnpredictedMessagePos user32 1968 -imp 'GetUpdateRect' GetUpdateRect user32 1969 -imp 'GetUpdateRgn' GetUpdateRgn user32 1970 -imp 'GetUpdatedClipboardFormats' GetUpdatedClipboardFormats user32 1971 -imp 'GetUserDefaultGeoName' GetUserDefaultGeoName KernelBase 793 -imp 'GetUserDefaultLCID' GetUserDefaultLCID kernel32 0 # KernelBase -imp 'GetUserDefaultLangID' GetUserDefaultLangID kernel32 0 # KernelBase -imp 'GetUserDefaultLocaleName' GetUserDefaultLocaleName kernel32 0 # KernelBase -imp 'GetUserDefaultUILanguage' GetUserDefaultUILanguage kernel32 0 # KernelBase -imp 'GetUserGeoID' GetUserGeoID kernel32 0 # KernelBase -imp 'GetUserInfo' GetUserInfo KernelBase 799 -imp 'GetUserInfoWord' GetUserInfoWord KernelBase 800 -imp 'GetUserName' GetUserNameW advapi32 1381 2 -imp 'GetUserNameA' GetUserNameA advapi32 1380 2 -imp 'GetUserObjectInformationA' GetUserObjectInformationA user32 1972 -imp 'GetUserObjectInformation' GetUserObjectInformationW user32 1973 -imp 'GetUserObjectSecurity' GetUserObjectSecurity user32 1974 -imp 'GetUserOverrideString' GetUserOverrideString KernelBase 801 -imp 'GetUserOverrideWord' GetUserOverrideWord KernelBase 802 -imp 'GetUserPreferredUILanguages' GetUserPreferredUILanguages kernel32 0 # KernelBase -imp 'GetVDMCurrentDirectories' GetVDMCurrentDirectories kernel32 798 -imp 'GetVersion' GetVersion kernel32 0 # KernelBase -imp 'GetVersionExA' GetVersionExA kernel32 0 1 # KernelBase -imp 'GetVersionEx' GetVersionExW kernel32 0 1 # KernelBase imp 'GetViewportExtEx' GetViewportExtEx gdi32 1728 imp 'GetViewportOrgEx' GetViewportOrgEx gdi32 1729 -imp 'GetVolumeInformationA' GetVolumeInformationA kernel32 0 # KernelBase -imp 'GetVolumeInformationByHandle' GetVolumeInformationByHandleW kernel32 0 # KernelBase -imp 'GetVolumeInformation' GetVolumeInformationW kernel32 0 # KernelBase -imp 'GetVolumeNameForVolumeMountPointA' GetVolumeNameForVolumeMountPointA kernel32 805 -imp 'GetVolumeNameForVolumeMountPoint' GetVolumeNameForVolumeMountPointW kernel32 0 # KernelBase -imp 'GetVolumePathNameA' GetVolumePathNameA kernel32 807 3 -imp 'GetVolumePathName' GetVolumePathNameW kernel32 0 3 # KernelBase -imp 'GetVolumePathNamesForVolumeNameA' GetVolumePathNamesForVolumeNameA kernel32 809 -imp 'GetVolumePathNamesForVolumeName' GetVolumePathNamesForVolumeNameW kernel32 0 # KernelBase imp 'GetWinMetaFileBits' GetWinMetaFileBits gdi32 1730 -imp 'GetWinStationInfo' GetWinStationInfo user32 1975 -imp 'GetWindow' GetWindow user32 1976 2 -imp 'GetWindowBand' GetWindowBand user32 1977 -imp 'GetWindowCompositionAttribute' GetWindowCompositionAttribute user32 1978 -imp 'GetWindowCompositionInfo' GetWindowCompositionInfo user32 1979 -imp 'GetWindowContextHelpId' GetWindowContextHelpId user32 1980 -imp 'GetWindowDC' GetWindowDC user32 1981 -imp 'GetWindowDisplayAffinity' GetWindowDisplayAffinity user32 1982 -imp 'GetWindowDpiAwarenessContext' GetWindowDpiAwarenessContext user32 1983 -imp 'GetWindowDpiHostingBehavior' GetWindowDpiHostingBehavior user32 1984 imp 'GetWindowExtEx' GetWindowExtEx gdi32 1731 -imp 'GetWindowFeedbackSetting' GetWindowFeedbackSetting user32 1985 -imp 'GetWindowInfo' GetWindowInfo user32 1986 -imp 'GetWindowLongA' GetWindowLongA user32 1987 -imp 'GetWindowLongPtrA' GetWindowLongPtrA user32 1988 -imp 'GetWindowLongPtr' GetWindowLongPtrW user32 1989 -imp 'GetWindowLong' GetWindowLongW user32 1990 -imp 'GetWindowMinimizeRect' GetWindowMinimizeRect user32 1991 -imp 'GetWindowModuleFileNameA' GetWindowModuleFileNameA user32 1993 -imp 'GetWindowModuleFileName' GetWindowModuleFileNameW user32 1994 imp 'GetWindowOrgEx' GetWindowOrgEx gdi32 1732 -imp 'GetWindowPlacement' GetWindowPlacement user32 1995 2 -imp 'GetWindowProcessHandle' GetWindowProcessHandle user32 1996 -imp 'GetWindowRect' GetWindowRect user32 1997 2 -imp 'GetWindowRgn' GetWindowRgn user32 1998 -imp 'GetWindowRgnBox' GetWindowRgnBox user32 1999 -imp 'GetWindowRgnEx' GetWindowRgnEx user32 2000 -imp 'GetWindowText' GetWindowTextW user32 2007 3 -imp 'GetWindowTextA' GetWindowTextA user32 2003 3 -imp 'GetWindowTextLengthA' GetWindowTextLengthA user32 2004 -imp 'GetWindowTextLength' GetWindowTextLengthW user32 2006 -imp 'GetWindowThreadProcessId' GetWindowThreadProcessId user32 2008 -imp 'GetWindowWord' GetWindowWord user32 2009 -imp 'GetWindowsAccountDomainSid' GetWindowsAccountDomainSid advapi32 0 # KernelBase -imp 'GetWindowsDirectory' GetWindowsDirectoryW kernel32 0 2 # KernelBase -imp 'GetWindowsDirectoryA' GetWindowsDirectoryA kernel32 0 2 # KernelBase imp 'GetWorldTransform' GetWorldTransform gdi32 1733 -imp 'GetWriteWatch' GetWriteWatch kernel32 0 # KernelBase -imp 'GetWsChanges' GetWsChanges KernelBase 817 -imp 'GetWsChangesEx' GetWsChangesEx KernelBase 818 -imp 'GetXStateFeaturesMask' GetXStateFeaturesMask kernel32 0 # KernelBase -imp 'GhostWindowFromHungWindow' GhostWindowFromHungWindow user32 2011 -imp 'GlobalAddAtomA' GlobalAddAtomA kernel32 815 -imp 'GlobalAddAtomExA' GlobalAddAtomExA kernel32 816 -imp 'GlobalAddAtomEx' GlobalAddAtomExW kernel32 817 -imp 'GlobalAddAtom' GlobalAddAtomW kernel32 818 -imp 'GlobalAlloc' GlobalAlloc kernel32 0 2 # KernelBase -imp 'GlobalCompact' GlobalCompact kernel32 820 -imp 'GlobalDeleteAtom' GlobalDeleteAtom kernel32 821 -imp 'GlobalFindAtomA' GlobalFindAtomA kernel32 822 -imp 'GlobalFindAtom' GlobalFindAtomW kernel32 823 -imp 'GlobalFix' GlobalFix kernel32 824 -imp 'GlobalFlags' GlobalFlags kernel32 825 -imp 'GlobalFree' GlobalFree kernel32 0 1 # KernelBase -imp 'GlobalGetAtomNameA' GlobalGetAtomNameA kernel32 827 -imp 'GlobalGetAtomName' GlobalGetAtomNameW kernel32 828 -imp 'GlobalHandle' GlobalHandle kernel32 829 -imp 'GlobalLock' GlobalLock kernel32 830 -imp 'GlobalMemoryStatus' GlobalMemoryStatus kernel32 831 -imp 'GlobalMemoryStatusEx' GlobalMemoryStatusEx kernel32 0 1 # KernelBase -imp 'GlobalReAlloc' GlobalReAlloc kernel32 833 -imp 'GlobalSize' GlobalSize kernel32 834 -imp 'GlobalUnWire' GlobalUnWire kernel32 835 -imp 'GlobalUnfix' GlobalUnfix kernel32 836 -imp 'GlobalUnlock' GlobalUnlock kernel32 837 -imp 'GlobalWire' GlobalWire kernel32 838 -imp 'GrayStringA' GrayStringA user32 2012 -imp 'GrayString' GrayStringW user32 2013 -imp 'GuardCheckLongJumpTarget' GuardCheckLongJumpTarget KernelBase 823 imp 'HT_Get8BPPFormatPalette' HT_Get8BPPFormatPalette gdi32 1734 imp 'HT_Get8BPPMaskPalette' HT_Get8BPPMaskPalette gdi32 1735 -imp 'HandleDelegatedInput' HandleDelegatedInput user32 2505 -imp 'HasPolicyForegroundProcessingCompletedInternal' HasPolicyForegroundProcessingCompletedInternal KernelBase 824 -imp 'HashData' HashData KernelBase 825 -imp 'Heap32First' Heap32First kernel32 839 -imp 'Heap32ListFirst' Heap32ListFirst kernel32 840 -imp 'Heap32ListNext' Heap32ListNext kernel32 841 -imp 'Heap32Next' Heap32Next kernel32 842 -imp 'HeapCompact' HeapCompact kernel32 0 # KernelBase -imp 'HeapCreate' HeapCreate kernel32 0 # KernelBase -imp 'HeapDestroy' HeapDestroy kernel32 0 # KernelBase -imp 'HeapFree' HeapFree kernel32 847 -imp 'HeapLock' HeapLock kernel32 0 # KernelBase -imp 'HeapQueryInformation' HeapQueryInformation kernel32 0 # KernelBase -imp 'HeapSetInformation' HeapSetInformation kernel32 0 # KernelBase -imp 'HeapSummary' HeapSummary KernelBase 836 -imp 'HeapUnlock' HeapUnlock kernel32 0 # KernelBase -imp 'HeapValidate' HeapValidate kernel32 0 # KernelBase -imp 'HeapWalk' HeapWalk kernel32 0 # KernelBase -imp 'HideCaret' HideCaret user32 2014 -imp 'HiliteMenuItem' HiliteMenuItem user32 2015 -imp 'HungWindowFromGhostWindow' HungWindowFromGhostWindow user32 2016 +imp 'InternalDeleteDC' InternalDeleteDC gdi32 1736 +imp 'IntersectClipRect' IntersectClipRect gdi32 1737 +imp 'InvertRgn' InvertRgn gdi32 1738 +imp 'IsValidEnhMetaRecord' IsValidEnhMetaRecord gdi32 1739 +imp 'IsValidEnhMetaRecordOffExt' IsValidEnhMetaRecordOffExt gdi32 1740 +imp 'LPtoDP' LPtoDP gdi32 1741 +imp 'LineTo' LineTo gdi32 1743 +imp 'LpkEditControl' LpkEditControl gdi32 1745 +imp 'LpkGetEditControl' LpkGetEditControl gdi32 1748 +imp 'LpkpEditControlSize' LpkpEditControlSize gdi32 1755 +imp 'LpkpInitializeEditControl' LpkpInitializeEditControl gdi32 1756 +imp 'MaskBlt' MaskBlt gdi32 1757 +imp 'MirrorRgn' MirrorRgn gdi32 1758 +imp 'ModerncoreGdiInit' ModerncoreGdiInit gdi32 1759 +imp 'ModifyWorldTransform' ModifyWorldTransform gdi32 1760 +imp 'MoveToEx' MoveToEx gdi32 1761 +imp 'NamedEscape' NamedEscape gdi32 1762 +imp 'OffsetClipRgn' OffsetClipRgn gdi32 1763 +imp 'OffsetRgn' OffsetRgn gdi32 1764 +imp 'OffsetViewportOrgEx' OffsetViewportOrgEx gdi32 1765 +imp 'OffsetWindowOrgEx' OffsetWindowOrgEx gdi32 1766 +imp 'PATHOBJ_bEnum' PATHOBJ_bEnum gdi32 1767 +imp 'PATHOBJ_bEnumClipLines' PATHOBJ_bEnumClipLines gdi32 1768 +imp 'PATHOBJ_vEnumStart' PATHOBJ_vEnumStart gdi32 1769 +imp 'PATHOBJ_vEnumStartClipLines' PATHOBJ_vEnumStartClipLines gdi32 1770 +imp 'PATHOBJ_vGetBounds' PATHOBJ_vGetBounds gdi32 1771 +imp 'PaintRgn' PaintRgn gdi32 1772 +imp 'PatBlt' PatBlt gdi32 1773 +imp 'PathToRegion' PathToRegion gdi32 1774 +imp 'Pie' Pie gdi32 1775 +imp 'PlayEnhMetaFile' PlayEnhMetaFile gdi32 1776 +imp 'PlayEnhMetaFileRecord' PlayEnhMetaFileRecord gdi32 1777 +imp 'PlayMetaFile' PlayMetaFile gdi32 1778 +imp 'PlayMetaFileRecord' PlayMetaFileRecord gdi32 1779 +imp 'PlgBlt' PlgBlt gdi32 1780 +imp 'PolyBezier' PolyBezier gdi32 1781 +imp 'PolyBezierTo' PolyBezierTo gdi32 1782 +imp 'PolyDraw' PolyDraw gdi32 1783 +imp 'PolyPatBlt' PolyPatBlt gdi32 1784 +imp 'PolyPolygon' PolyPolygon gdi32 1785 +imp 'PolyPolyline' PolyPolyline gdi32 1786 +imp 'PolyTextOut' PolyTextOutW gdi32 1788 +imp 'Polygon' Polygon gdi32 1789 +imp 'Polyline' Polyline gdi32 1790 +imp 'PolylineTo' PolylineTo gdi32 1791 +imp 'PtInRegion' PtInRegion gdi32 1792 +imp 'PtVisible' PtVisible gdi32 1793 +imp 'QueryFontAssocStatus' QueryFontAssocStatus gdi32 1794 +imp 'RealizePalette' RealizePalette gdi32 1795 +imp 'RectInRegion' RectInRegion gdi32 1796 +imp 'RectVisible' RectVisible gdi32 1797 +imp 'Rectangle' Rectangle gdi32 1798 +imp 'RemoveFontMemResourceEx' RemoveFontMemResourceEx gdi32 1799 +imp 'RemoveFontResource' RemoveFontResourceW gdi32 1804 +imp 'RemoveFontResourceEx' RemoveFontResourceExW gdi32 1802 +imp 'RemoveFontResourceTracking' RemoveFontResourceTracking gdi32 1803 +imp 'ResetDCW' ResetDCW gdi32 1806 +imp 'ResizePalette' ResizePalette gdi32 1807 +imp 'RestoreDC' RestoreDC gdi32 1808 2 +imp 'RoundRect' RoundRect gdi32 1809 +imp 'STROBJ_bEnum' STROBJ_bEnum gdi32 1810 +imp 'STROBJ_bEnumPositionsOnly' STROBJ_bEnumPositionsOnly gdi32 1811 +imp 'STROBJ_bGetAdvanceWidths' STROBJ_bGetAdvanceWidths gdi32 1812 +imp 'STROBJ_dwGetCodePage' STROBJ_dwGetCodePage gdi32 1813 +imp 'STROBJ_vEnumStart' STROBJ_vEnumStart gdi32 1814 +imp 'SaveDC' SaveDC gdi32 1815 1 +imp 'ScaleRgn' ScaleRgn gdi32 1816 +imp 'ScaleValues' ScaleValues gdi32 1817 +imp 'ScaleViewportExtEx' ScaleViewportExtEx gdi32 1818 +imp 'ScaleWindowExtEx' ScaleWindowExtEx gdi32 1819 +imp 'SelectBrushLocal' SelectBrushLocal gdi32 1860 +imp 'SelectClipPath' SelectClipPath gdi32 1861 +imp 'SelectClipRgn' SelectClipRgn gdi32 1862 +imp 'SelectFontLocal' SelectFontLocal gdi32 1863 +imp 'SelectObject' SelectObject gdi32 1864 2 +imp 'SelectPalette' SelectPalette gdi32 1865 +imp 'SetAbortProc' SetAbortProc gdi32 1866 +imp 'SetArcDirection' SetArcDirection gdi32 1867 +imp 'SetBitmapAttributes' SetBitmapAttributes gdi32 1868 +imp 'SetBitmapBits' SetBitmapBits gdi32 1869 +imp 'SetBitmapDimensionEx' SetBitmapDimensionEx gdi32 1870 +imp 'SetBkColor' SetBkColor gdi32 1871 +imp 'SetBkMode' SetBkMode gdi32 1872 2 +imp 'SetBoundsRect' SetBoundsRect gdi32 1873 +imp 'SetBrushAttributes' SetBrushAttributes gdi32 1874 +imp 'SetBrushOrgEx' SetBrushOrgEx gdi32 1875 +imp 'SetColorAdjustment' SetColorAdjustment gdi32 1876 +imp 'SetColorSpace' SetColorSpace gdi32 1877 +imp 'SetDCBrushColor' SetDCBrushColor gdi32 1878 +imp 'SetDCDpiScaleValue' SetDCDpiScaleValue gdi32 1879 +imp 'SetDCPenColor' SetDCPenColor gdi32 1880 +imp 'SetDIBColorTable' SetDIBColorTable gdi32 1881 +imp 'SetDIBits' SetDIBits gdi32 1882 +imp 'SetDIBitsToDevice' SetDIBitsToDevice gdi32 1883 +imp 'SetDeviceGammaRamp' SetDeviceGammaRamp gdi32 1884 +imp 'SetEnhMetaFileBits' SetEnhMetaFileBits gdi32 1885 +imp 'SetFontEnumeration' SetFontEnumeration gdi32 1886 +imp 'SetGraphicsMode' SetGraphicsMode gdi32 1887 +imp 'SetICMMode' SetICMMode gdi32 1888 +imp 'SetICMProfile' SetICMProfileW gdi32 1890 +imp 'SetLayout' SetLayout gdi32 1891 +imp 'SetLayoutWidth' SetLayoutWidth gdi32 1892 +imp 'SetMagicColors' SetMagicColors gdi32 1893 +imp 'SetMapMode' SetMapMode gdi32 1894 +imp 'SetMapperFlags' SetMapperFlags gdi32 1895 +imp 'SetMetaFileBitsEx' SetMetaFileBitsEx gdi32 1896 +imp 'SetMetaRgn' SetMetaRgn gdi32 1897 +imp 'SetMiterLimit' SetMiterLimit gdi32 1898 +imp 'SetOPMSigningKeyAndSequenceNumbers' SetOPMSigningKeyAndSequenceNumbers gdi32 1899 +imp 'SetPaletteEntries' SetPaletteEntries gdi32 1900 +imp 'SetPixel' SetPixel gdi32 1901 4 +imp 'SetPixelFormat' SetPixelFormat gdi32 1902 3 +imp 'SetPixelV' SetPixelV gdi32 1903 +imp 'SetPolyFillMode' SetPolyFillMode gdi32 1904 +imp 'SetROP2' SetROP2 gdi32 1905 +imp 'SetRectRgn' SetRectRgn gdi32 1906 +imp 'SetRelAbs' SetRelAbs gdi32 1907 +imp 'SetStretchBltMode' SetStretchBltMode gdi32 1908 +imp 'SetSystemPaletteUse' SetSystemPaletteUse gdi32 1909 +imp 'SetTextAlign' SetTextAlign gdi32 1910 2 +imp 'SetTextCharacterExtra' SetTextCharacterExtra gdi32 1911 +imp 'SetTextColor' SetTextColor gdi32 1912 2 +imp 'SetTextJustification' SetTextJustification gdi32 1913 3 +imp 'SetViewportExtEx' SetViewportExtEx gdi32 1914 +imp 'SetViewportOrgEx' SetViewportOrgEx gdi32 1915 +imp 'SetVirtualResolution' SetVirtualResolution gdi32 1916 +imp 'SetWinMetaFileBits' SetWinMetaFileBits gdi32 1917 +imp 'SetWindowExtEx' SetWindowExtEx gdi32 1918 +imp 'SetWindowOrgEx' SetWindowOrgEx gdi32 1919 +imp 'SetWorldTransform' SetWorldTransform gdi32 1920 +imp 'StartDoc' StartDocW gdi32 1922 +imp 'StartFormPage' StartFormPage gdi32 1923 +imp 'StartPage' StartPage gdi32 1924 +imp 'StretchBlt' StretchBlt gdi32 1925 +imp 'StretchDIBits' StretchDIBits gdi32 1926 +imp 'StrokeAndFillPath' StrokeAndFillPath gdi32 1927 +imp 'StrokePath' StrokePath gdi32 1928 +imp 'SwapBuffers' SwapBuffers gdi32 1929 1 +imp 'TextOut' TextOutW gdi32 1931 +imp 'TranslateCharsetInfo' TranslateCharsetInfo gdi32 1932 +imp 'UnloadNetworkFonts' UnloadNetworkFonts gdi32 1933 +imp 'UnrealizeObject' UnrealizeObject gdi32 1934 +imp 'UpdateColors' UpdateColors gdi32 1935 +imp 'UpdateICMRegKey' UpdateICMRegKeyW gdi32 1937 +imp 'WidenPath' WidenPath gdi32 1941 +imp 'XFORMOBJ_bApplyXform' XFORMOBJ_bApplyXform gdi32 1942 +imp 'XFORMOBJ_iGetXform' XFORMOBJ_iGetXform gdi32 1943 +imp 'XLATEOBJ_cGetPalette' XLATEOBJ_cGetPalette gdi32 1944 +imp 'XLATEOBJ_hGetColorTransform' XLATEOBJ_hGetColorTransform gdi32 1945 +imp 'XLATEOBJ_iXlate' XLATEOBJ_iXlate gdi32 1946 +imp 'XLATEOBJ_piVector' XLATEOBJ_piVector gdi32 1947 +imp 'cGetTTFFromFOT' cGetTTFFromFOT gdi32 1952 +imp 'fpClosePrinter' fpClosePrinter gdi32 1953 +imp 'gMaxGdiHandleCount' gMaxGdiHandleCount gdi32 1955 +imp 'gW32PID' gW32PID gdi32 1956 +imp 'g_systemCallFilterId' g_systemCallFilterId gdi32 1957 +imp 'gdiPlaySpoolStream' gdiPlaySpoolStream gdi32 1958 + +# COMDLG32.DLL +# +# Name Actual DLL Hint Arity +imp 'ChooseColor' ChooseColorW comdlg32 103 1 +imp 'ChooseFont' ChooseFontW comdlg32 105 1 +imp 'CommDlgExtendedError' CommDlgExtendedError comdlg32 106 +imp 'DllCanUnloadNow' DllCanUnloadNow comdlg32 107 +imp 'DllGetClassObject' DllGetClassObject comdlg32 108 +imp 'FindText' FindTextW comdlg32 110 +imp 'GetFileTitle' GetFileTitleW comdlg32 112 3 +imp 'GetOpenFileName' GetOpenFileNameW comdlg32 114 1 +imp 'GetSaveFileName' GetSaveFileNameW comdlg32 116 1 +imp 'LoadAlterBitmap' LoadAlterBitmap comdlg32 117 +imp 'PageSetupDlg' PageSetupDlgW comdlg32 119 +imp 'PrintDlg' PrintDlgW comdlg32 123 1 +imp 'PrintDlgEx' PrintDlgExW comdlg32 122 +imp 'ReplaceText' ReplaceTextW comdlg32 125 1 +imp 'Ssync_ANSI_UNICODE_Struct_For_WOW' Ssync_ANSI_UNICODE_Struct_For_WOW comdlg32 126 +imp 'WantArrows' WantArrows comdlg32 127 + +# MSWSOCK.DLL +# +# Name Actual DLL Hint Arity +imp 'AcceptEx' AcceptEx MsWSock 0 8 +imp 'DisconnectEx' DisconnectEx MsWSock 0 4 +imp 'GetAcceptExSockaddrs' GetAcceptExSockaddrs MsWSock 0 8 +imp 'TransmitFile' TransmitFile MsWSock 0 7 +imp 'WSARecvEx' WSARecvEx MsWSock 0 4 + +# WS2_32.DLL +# +# Name Actual DLL Hint Arity +imp 'FreeAddrInfo' FreeAddrInfoW ws2_32 27 1 +imp 'FreeAddrInfoEx' FreeAddrInfoExW ws2_32 26 1 +imp 'GetAddrInfo' GetAddrInfoW ws2_32 32 4 +imp 'GetAddrInfoEx' GetAddrInfoExW ws2_32 31 10 +imp 'GetAddrInfoExCancel' GetAddrInfoExCancel ws2_32 29 1 +imp 'GetAddrInfoExOverlappedResult' GetAddrInfoExOverlappedResult ws2_32 30 1 +imp 'GetHostName' GetHostNameW ws2_32 33 2 +imp 'GetNameInfo' GetNameInfoW ws2_32 34 7 +imp 'SetAddrInfoEx' SetAddrInfoExW ws2_32 38 12 +imp 'WSAAccept' WSAAccept ws2_32 41 5 +imp 'WSAAddressToString' WSAAddressToStringW ws2_32 43 5 +imp 'WSAAsyncGetHostByAddr' WSAAsyncGetHostByAddr ws2_32 102 7 +imp 'WSAAsyncGetHostByName' WSAAsyncGetHostByName ws2_32 103 5 +imp 'WSAAsyncGetProtoByName' WSAAsyncGetProtoByName ws2_32 105 5 +imp 'WSAAsyncGetProtoByNumber' WSAAsyncGetProtoByNumber ws2_32 104 5 +imp 'WSAAsyncGetServByName' WSAAsyncGetServByName ws2_32 107 +imp 'WSAAsyncGetServByPort' WSAAsyncGetServByPort ws2_32 106 +imp 'WSAAsyncSelect' WSAAsyncSelect ws2_32 101 +imp 'WSACancelAsyncRequest' WSACancelAsyncRequest ws2_32 108 +imp 'WSACancelBlockingCall' WSACancelBlockingCall ws2_32 113 +imp 'WSACleanup' WSACleanup ws2_32 116 0 +imp 'WSACloseEvent' WSACloseEvent ws2_32 45 1 +imp 'WSAConnect' WSAConnect ws2_32 46 7 +imp 'WSAConnectByList' WSAConnectByList ws2_32 47 8 +imp 'WSAConnectByName' WSAConnectByNameW ws2_32 49 9 +imp 'WSACreateEvent' WSACreateEvent ws2_32 50 0 +imp 'WSADuplicateSocket' WSADuplicateSocketW ws2_32 59 3 +imp 'WSAEnumNameSpaceProviders' WSAEnumNameSpaceProvidersW ws2_32 63 2 +imp 'WSAEnumNameSpaceProvidersEx' WSAEnumNameSpaceProvidersExW ws2_32 62 2 +imp 'WSAEnumNetworkEvents' WSAEnumNetworkEvents ws2_32 64 3 +imp 'WSAEnumProtocols' WSAEnumProtocolsW ws2_32 66 3 +imp 'WSAEventSelect' WSAEventSelect ws2_32 67 3 +imp 'WSAGetLastError' WSAGetLastError ws2_32 111 0 +imp 'WSAGetOverlappedResult' WSAGetOverlappedResult ws2_32 68 5 +imp 'WSAGetQOSByName' WSAGetQOSByName ws2_32 69 3 +imp 'WSAGetServiceClassInfo' WSAGetServiceClassInfoW ws2_32 71 4 +imp 'WSAGetServiceClassNameByClassId' WSAGetServiceClassNameByClassIdW ws2_32 73 3 +imp 'WSAInstallServiceClass' WSAInstallServiceClassW ws2_32 77 1 +imp 'WSAIoctl' WSAIoctl ws2_32 78 9 +imp 'WSAJoinLeaf' WSAJoinLeaf ws2_32 79 8 +imp 'WSALookupServiceBegin' WSALookupServiceBeginW ws2_32 81 3 +imp 'WSALookupServiceEnd' WSALookupServiceEnd ws2_32 82 1 +imp 'WSALookupServiceNext' WSALookupServiceNextW ws2_32 84 4 +imp 'WSANSPIoctl' WSANSPIoctl ws2_32 85 8 +imp 'WSAPoll' WSAPoll ws2_32 88 3 +imp 'WSAProviderCompleteAsyncCall' WSAProviderCompleteAsyncCall ws2_32 89 +imp 'WSAProviderConfigChange' WSAProviderConfigChange ws2_32 90 3 +imp 'WSARecv' WSARecv ws2_32 91 7 +imp 'WSARecvDisconnect' WSARecvDisconnect ws2_32 92 2 +imp 'WSARecvFrom' WSARecvFrom ws2_32 93 9 +imp 'WSARemoveServiceClass' WSARemoveServiceClass ws2_32 94 1 +imp 'WSAResetEvent' WSAResetEvent ws2_32 95 1 +imp 'WSASend' WSASend ws2_32 96 7 +imp 'WSASendDisconnect' WSASendDisconnect ws2_32 97 2 +imp 'WSASendMsg' WSASendMsg ws2_32 98 6 +imp 'WSASendTo' WSASendTo ws2_32 99 9 +imp 'WSASetBlockingHook' WSASetBlockingHook ws2_32 109 +imp 'WSASetEvent' WSASetEvent ws2_32 100 1 +imp 'WSASetLastError' WSASetLastError ws2_32 112 1 +imp 'WSASetService' WSASetServiceW ws2_32 118 3 +imp 'WSASocket' WSASocketW ws2_32 120 6 +imp 'WSAStartup' WSAStartup ws2_32 115 2 +imp 'WSAStringToAddress' WSAStringToAddressW ws2_32 122 +imp 'WSAUnadvertiseProvider' WSAUnadvertiseProvider ws2_32 123 +imp 'WSAUnhookBlockingHook' WSAUnhookBlockingHook ws2_32 110 +imp 'WSAWaitForMultipleEvents' WSAWaitForMultipleEvents ws2_32 124 5 +imp 'WSApSetPostRoutine' WSApSetPostRoutine ws2_32 24 +imp 'WSCDeinstallProvider' WSCDeinstallProvider ws2_32 125 +imp 'WSCDeinstallProvider32' WSCDeinstallProvider32 ws2_32 126 +imp 'WSCDeinstallProviderEx' WSCDeinstallProviderEx ws2_32 127 +imp 'WSCEnableNSProvider' WSCEnableNSProvider ws2_32 128 +imp 'WSCEnableNSProvider32' WSCEnableNSProvider32 ws2_32 129 +imp 'WSCEnumNameSpaceProviders32' WSCEnumNameSpaceProviders32 ws2_32 130 +imp 'WSCEnumNameSpaceProvidersEx32' WSCEnumNameSpaceProvidersEx32 ws2_32 131 +imp 'WSCEnumProtocols' WSCEnumProtocols ws2_32 132 +imp 'WSCEnumProtocols32' WSCEnumProtocols32 ws2_32 133 +imp 'WSCEnumProtocolsEx' WSCEnumProtocolsEx ws2_32 134 +imp 'WSCGetApplicationCategory' WSCGetApplicationCategory ws2_32 135 +imp 'WSCGetApplicationCategoryEx' WSCGetApplicationCategoryEx ws2_32 136 +imp 'WSCGetProviderInfo' WSCGetProviderInfo ws2_32 137 +imp 'WSCGetProviderInfo32' WSCGetProviderInfo32 ws2_32 138 +imp 'WSCGetProviderPath' WSCGetProviderPath ws2_32 139 +imp 'WSCGetProviderPath32' WSCGetProviderPath32 ws2_32 140 +imp 'WSCInstallNameSpace' WSCInstallNameSpace ws2_32 141 +imp 'WSCInstallNameSpace32' WSCInstallNameSpace32 ws2_32 142 +imp 'WSCInstallNameSpaceEx' WSCInstallNameSpaceEx ws2_32 143 +imp 'WSCInstallNameSpaceEx2' WSCInstallNameSpaceEx2 ws2_32 144 +imp 'WSCInstallNameSpaceEx32' WSCInstallNameSpaceEx32 ws2_32 145 +imp 'WSCInstallProvider' WSCInstallProvider ws2_32 146 +imp 'WSCInstallProvider64_32' WSCInstallProvider64_32 ws2_32 147 +imp 'WSCInstallProviderAndChains64_32' WSCInstallProviderAndChains64_32 ws2_32 148 +imp 'WSCInstallProviderEx' WSCInstallProviderEx ws2_32 149 +imp 'WSCSetApplicationCategory' WSCSetApplicationCategory ws2_32 150 +imp 'WSCSetApplicationCategoryEx' WSCSetApplicationCategoryEx ws2_32 152 +imp 'WSCSetProviderInfo' WSCSetProviderInfo ws2_32 153 +imp 'WSCSetProviderInfo32' WSCSetProviderInfo32 ws2_32 154 +imp 'WSCUnInstallNameSpace' WSCUnInstallNameSpace ws2_32 155 +imp 'WSCUnInstallNameSpace32' WSCUnInstallNameSpace32 ws2_32 156 +imp 'WSCUnInstallNameSpaceEx2' WSCUnInstallNameSpaceEx2 ws2_32 157 +imp 'WSCUpdateProvider' WSCUpdateProvider ws2_32 158 +imp 'WSCUpdateProvider32' WSCUpdateProvider32 ws2_32 159 +imp 'WSCUpdateProviderEx' WSCUpdateProviderEx ws2_32 160 +imp 'WSCWriteNameSpaceOrder' WSCWriteNameSpaceOrder ws2_32 161 +imp 'WSCWriteNameSpaceOrder32' WSCWriteNameSpaceOrder32 ws2_32 162 +imp 'WSCWriteProviderOrder' WSCWriteProviderOrder ws2_32 163 +imp 'WSCWriteProviderOrder32' WSCWriteProviderOrder32 ws2_32 164 +imp 'WSCWriteProviderOrderEx' WSCWriteProviderOrderEx ws2_32 165 +imp '__sys_accept_nt' accept ws2_32 1 3 # we're using WSAAccept() +imp '__sys_bind_nt' bind ws2_32 2 3 +imp '__sys_closesocket_nt' closesocket ws2_32 3 1 +imp '__sys_connect_nt' connect ws2_32 4 +imp '__sys_getpeername_nt' getpeername ws2_32 5 3 +imp '__sys_getsockname_nt' getsockname ws2_32 6 3 +imp '__sys_getsockopt_nt' getsockopt ws2_32 7 5 +imp '__sys_ioctlsocket_nt' ioctlsocket ws2_32 10 3 +imp '__sys_listen_nt' listen ws2_32 13 2 +imp '__sys_recvfrom_nt' recvfrom ws2_32 17 6 # we're using WSARecvFrom() +imp '__sys_select_nt' select ws2_32 18 5 +imp '__sys_sendto_nt' sendto ws2_32 20 6 # we're using WSASendTo() +imp '__sys_setsockopt_nt' setsockopt ws2_32 21 5 +imp '__sys_shutdown_nt' shutdown ws2_32 22 2 +imp '__sys_socket_nt' socket ws2_32 23 3 +imp 'sys_freeaddrinfo_nt' freeaddrinfo ws2_32 190 +imp 'sys_getaddrinfo_nt' getaddrinfo ws2_32 191 +imp 'sys_gethostbyaddr_nt' gethostbyaddr ws2_32 51 +imp 'sys_gethostbyname_nt' gethostbyname ws2_32 52 +imp 'sys_gethostname_nt' gethostname ws2_32 57 +imp 'sys_getnameinfo_nt' getnameinfo ws2_32 192 +imp 'sys_getprotobyname_nt' getprotobyname ws2_32 53 +imp 'sys_getprotobynumber_nt' getprotobynumber ws2_32 54 +imp 'sys_getservbyname_nt' getservbyname ws2_32 55 +imp 'sys_getservbyport_nt' getservbyport ws2_32 56 +imp '__sys_recv_nt' recv ws2_32 16 4 # we're using WSARecvFrom() +imp '__sys_send_nt' send ws2_32 19 4 # we're using WSASendTo() + +# IPHLPAPI.DLL +# +# Name Actual DLL Hint Arity +imp 'AddIPAddress' AddIPAddress iphlpapi 0 5 +imp 'AllocateAndGetTcpExTableFromStack' AllocateAndGetTcpExTableFromStack iphlpapi 0 5 +imp 'AllocateAndGetUdpExTableFromStack' AllocateAndGetUdpExTableFromStack iphlpapi 0 5 +imp 'CancelIPChangeNotify' CancelIPChangeNotify iphlpapi 0 1 +imp 'CaptureInterfaceHardwareCrossTimestamp' CaptureInterfaceHardwareCrossTimestamp iphlpapi 0 2 +imp 'CreateIpForwardEntry' CreateIpForwardEntry iphlpapi 0 1 +imp 'CreateIpNetEntry' CreateIpNetEntry iphlpapi 0 +imp 'CreatePersistentTcpPortReservation' CreatePersistentTcpPortReservation iphlpapi 0 +imp 'CreatePersistentUdpPortReservation' CreatePersistentUdpPortReservation iphlpapi 0 +imp 'CreateProxyArpEntry' CreateProxyArpEntry iphlpapi 0 +imp 'DeleteIPAddress' DeleteIPAddress iphlpapi 0 +imp 'DeleteIpForwardEntry' DeleteIpForwardEntry iphlpapi 0 +imp 'DeleteIpNetEntry' DeleteIpNetEntry iphlpapi 0 +imp 'DeletePersistentTcpPortReservation' DeletePersistentTcpPortReservation iphlpapi 0 +imp 'DeletePersistentUdpPortReservation' DeletePersistentUdpPortReservation iphlpapi 0 +imp 'DeleteProxyArpEntry' DeleteProxyArpEntry iphlpapi 0 +imp 'DisableMediaSense' DisableMediaSense iphlpapi 0 +imp 'EnableRouter' EnableRouter iphlpapi 0 +imp 'FlushIpNetTable' FlushIpNetTable iphlpapi 0 1 +imp 'GetAdapterIndex' GetAdapterIndex iphlpapi 0 2 +imp 'GetAdapterOrderMap' GetAdapterOrderMap iphlpapi 0 0 +imp 'GetAdaptersAddresses' GetAdaptersAddresses iphlpapi 67 5 +imp 'GetAdaptersInfo' GetAdaptersInfo iphlpapi 0 2 +imp 'GetBestInterface' GetBestInterface iphlpapi 0 2 +imp 'GetBestInterfaceEx' GetBestInterfaceEx iphlpapi 0 2 +imp 'GetBestRoute' GetBestRoute iphlpapi 0 3 +imp 'GetExtendedTcpTable' GetExtendedTcpTable iphlpapi 0 +imp 'GetExtendedUdpTable' GetExtendedUdpTable iphlpapi 0 +imp 'GetFriendlyIfIndex' GetFriendlyIfIndex iphlpapi 0 +imp 'GetIcmpStatistics' GetIcmpStatistics iphlpapi 0 +imp 'GetIcmpStatisticsEx' GetIcmpStatisticsEx iphlpapi 0 +imp 'GetIfEntry' GetIfEntry iphlpapi 0 +imp 'GetIfTable' GetIfTable iphlpapi 0 +imp 'GetInterfaceActiveTimestampCapabilities' GetInterfaceActiveTimestampCapabilities iphlpapi 0 +imp 'GetInterfaceInfo' GetInterfaceInfo iphlpapi 0 +imp 'GetInterfaceSupportedTimestampCapabilities' GetInterfaceSupportedTimestampCapabilities iphlpapi 0 +imp 'GetIpAddrTable' GetIpAddrTable iphlpapi 0 +imp 'GetIpErrorString' GetIpErrorString iphlpapi 0 +imp 'GetIpForwardTable' GetIpForwardTable iphlpapi 0 +imp 'GetIpNetTable' GetIpNetTable iphlpapi 0 +imp 'GetIpStatistics' GetIpStatistics iphlpapi 0 +imp 'GetIpStatisticsEx' GetIpStatisticsEx iphlpapi 0 +imp 'GetNetworkParams' GetNetworkParams iphlpapi 0 +imp 'GetNumberOfInterfaces' GetNumberOfInterfaces iphlpapi 0 1 +imp 'GetOwnerModuleFromTcp6Entry' GetOwnerModuleFromTcp6Entry iphlpapi 0 +imp 'GetOwnerModuleFromTcpEntry' GetOwnerModuleFromTcpEntry iphlpapi 0 +imp 'GetOwnerModuleFromUdp6Entry' GetOwnerModuleFromUdp6Entry iphlpapi 0 +imp 'GetOwnerModuleFromUdpEntry' GetOwnerModuleFromUdpEntry iphlpapi 0 +imp 'GetPerAdapterInfo' GetPerAdapterInfo iphlpapi 0 +imp 'GetPerTcp6ConnectionEStats' GetPerTcp6ConnectionEStats iphlpapi 0 +imp 'GetPerTcpConnectionEStats' GetPerTcpConnectionEStats iphlpapi 0 +imp 'GetRTTAndHopCount' GetRTTAndHopCount iphlpapi 0 +imp 'GetTcp6Table' GetTcp6Table iphlpapi 0 +imp 'GetTcp6Table2' GetTcp6Table2 iphlpapi 0 +imp 'GetTcpStatistics' GetTcpStatistics iphlpapi 0 +imp 'GetTcpStatisticsEx' GetTcpStatisticsEx iphlpapi 0 +imp 'GetTcpStatisticsEx2' GetTcpStatisticsEx2 iphlpapi 0 +imp 'GetTcpTable' GetTcpTable iphlpapi 0 3 +imp 'GetTcpTable2' GetTcpTable2 iphlpapi 0 3 +imp 'GetUdp6Table' GetUdp6Table iphlpapi 0 +imp 'GetUdpStatistics' GetUdpStatistics iphlpapi 0 +imp 'GetUdpStatisticsEx' GetUdpStatisticsEx iphlpapi 0 +imp 'GetUdpStatisticsEx2' GetUdpStatisticsEx2 iphlpapi 0 +imp 'GetUdpTable' GetUdpTable iphlpapi 0 +imp 'GetUniDirectionalAdapterInfo' GetUniDirectionalAdapterInfo iphlpapi 0 +imp 'IpReleaseAddress' IpReleaseAddress iphlpapi 0 +imp 'IpRenewAddress' IpRenewAddress iphlpapi 0 +imp 'LookupPersistentTcpPortReservation' LookupPersistentTcpPortReservation iphlpapi 0 +imp 'LookupPersistentUdpPortReservation' LookupPersistentUdpPortReservation iphlpapi 0 +imp 'NhpAllocateAndGetInterfaceInfoFromStack' NhpAllocateAndGetInterfaceInfoFromStack iphlpapi 0 +imp 'NotifyAddrChange' NotifyAddrChange iphlpapi 0 +imp 'NotifyRouteChange' NotifyRouteChange iphlpapi 0 +imp 'ParseNetworkString' ParseNetworkString iphlpapi 0 +imp 'RegisterInterfaceTimestampConfigChange' RegisterInterfaceTimestampConfigChange iphlpapi 0 +imp 'ResolveNeighbor' ResolveNeighbor iphlpapi 0 +imp 'RestoreMediaSense' RestoreMediaSense iphlpapi 0 +imp 'SendARP' SendARP iphlpapi 0 +imp 'SetIfEntry' SetIfEntry iphlpapi 0 +imp 'SetIpForwardEntry' SetIpForwardEntry iphlpapi 0 +imp 'SetIpNetEntry' SetIpNetEntry iphlpapi 0 +imp 'SetIpStatistics' SetIpStatistics iphlpapi 0 +imp 'SetIpStatisticsEx' SetIpStatisticsEx iphlpapi 0 +imp 'SetIpTTL' SetIpTTL iphlpapi 0 +imp 'SetPerTcp6ConnectionEStats' SetPerTcp6ConnectionEStats iphlpapi 0 +imp 'SetPerTcpConnectionEStats' SetPerTcpConnectionEStats iphlpapi 0 +imp 'SetTcpEntry' SetTcpEntry iphlpapi 0 +imp 'UnenableRouter' UnenableRouter iphlpapi 0 +imp 'UnregisterInterfaceTimestampConfigChange' UnregisterInterfaceTimestampConfigChange iphlpapi 0 + +# POWRPROF.DLL +# +# Name Actual DLL Hint Arity +imp 'SetSuspendState' SetSuspendState PowrProf 0 3 + +# PDH.DLL +# +# Name Actual DLL Hint Arity +imp 'CounterPathCallBack' CounterPathCallBack pdh 0 # Applications implement the CounterPathCallBack function to process the counter path strings returned by the Browse dialog box. +imp 'LoadPerfCounterTextStrings' LoadPerfCounterTextStringsW pdh 0 # Loads onto the computer the performance objects and counters defined in the specified initialization file. +imp 'PdhAddCounter' PdhAddCounterW pdh 0 # Adds the specified counter to the query. +imp 'PdhAddEnglishCounter' PdhAddEnglishCounterW pdh 0 4 # Adds the specified language-neutral counter to the query. +imp 'PdhBindInputDataSource' PdhBindInputDataSourceW pdh 0 # Binds one or more binary log files together for reading log data. +imp 'PdhBrowseCounters' PdhBrowseCountersW pdh 0 # Displays a Browse Counters dialog box that the user can use to select one or more counters that they want to add to the query. To use handles to data sources, use the PdhBrowseCountersH function. +imp 'PdhBrowseCountersH' PdhBrowseCountersHW pdh 0 # Displays a Browse Counters dialog box that the user can use to select one or more counters that they want to add to the query. This function is identical to the PdhBrowseCounters function, except that it supports the use of handles to data sources. +imp 'PdhCalculateCounterFromRawValue' PdhCalculateCounterFromRawValue pdh 0 # Calculates the displayable value of two raw counter values. +imp 'PdhCloseLog' PdhCloseLog pdh 0 # Closes the specified log file. +imp 'PdhCloseQuery' PdhCloseQuery pdh 0 # Closes all counters contained in the specified query, closes all handles related to the query, and frees all memory associated with the query. +imp 'PdhCollectQueryData' PdhCollectQueryData pdh 0 # Collects the current raw data value for all counters in the specified query and updates the status code of each counter. +imp 'PdhCollectQueryDataEx' PdhCollectQueryDataEx pdh 0 3 # Uses a separate thread to collect the current raw data value for all counters in the specified query. The function then signals the application-defined event and waits the specified time interval before returning. +imp 'PdhCollectQueryDataWithTime' PdhCollectQueryDataWithTime pdh 0 # Collects the current raw data value for all counters in the specified query and updates the status code of each counter. +imp 'PdhComputeCounterStatistics' PdhComputeCounterStatistics pdh 0 # Computes statistics for a counter from an array of raw values. +imp 'PdhConnectMachine' PdhConnectMachineW pdh 0 # Connects to the specified computer. +imp 'PdhEnumLogSetNames' PdhEnumLogSetNamesW pdh 0 # Enumerates the names of the log sets within the DSN. +imp 'PdhEnumMachines' PdhEnumMachinesW pdh 0 # Returns a list of the computer names associated with counters in a log file. +imp 'PdhEnumMachinesH' PdhEnumMachinesHW pdh 0 # Returns a list of the computer names associated with counters in a log file. +imp 'PdhEnumObjectItems' PdhEnumObjectItemsW pdh 0 # Returns the specified object's counter and instance names that exist on the specified computer or in the specified log file. To use handles to data sources, use the PdhEnumObjectItemsH function. +imp 'PdhEnumObjectItemsH' PdhEnumObjectItemsHW pdh 0 # Returns the specified object's counter and instance names that exist on the specified computer or in the specified log file. This function is identical to the PdhEnumObjectItems function, except that it supports the use of handles to data sources. +imp 'PdhEnumObjects' PdhEnumObjectsW pdh 0 # Returns a list of objects available on the specified computer or in the specified log file. To use handles to data sources, use the PdhEnumObjectsH function. +imp 'PdhEnumObjectsH' PdhEnumObjectsHW pdh 0 # Returns a list of objects available on the specified computer or in the specified log file.This function is identical to PdhEnumObjects, except that it supports the use of handles to data sources. +imp 'PdhExpandCounterPath' PdhExpandCounterPathW pdh 0 # Examines the specified computer (or local computer if none is specified) for counters and instances of counters that match the wildcard strings in the counter path. +imp 'PdhExpandWildCardPath' PdhExpandWildCardPathW pdh 0 # Examines the specified computer or log file and returns those counter paths that match the given counter path which contains wildcard characters. To use handles to data sources, use the PdhExpandWildCardPathH function. +imp 'PdhExpandWildCardPathH' PdhExpandWildCardPathHW pdh 0 # Examines the specified computer or log file and returns those counter paths that match the given counter path which contains wildcard characters.This function is identical to the PdhExpandWildCardPath function, except that it supports the use of handles to data sources. +imp 'PdhFormatFromRawValue' PdhFormatFromRawValue pdh 0 # Computes a displayable value for the given raw counter values. +imp 'PdhGetCounterInfo' PdhGetCounterInfoW pdh 0 # Retrieves information about a counter, such as data size, counter type, path, and user-supplied data values. +imp 'PdhGetCounterTimeBase' PdhGetCounterTimeBase pdh 0 # Returns the time base of the specified counter. +imp 'PdhGetDataSourceTimeRange' PdhGetDataSourceTimeRangeW pdh 0 # Determines the time range, number of entries and, if applicable, the size of the buffer containing the performance data from the specified input source. To use handles to data sources, use the PdhGetDataSourceTimeRangeH function. +imp 'PdhGetDataSourceTimeRangeH' PdhGetDataSourceTimeRangeH pdh 0 # Determines the time range, number of entries and, if applicable, the size of the buffer containing the performance data from the specified input source.This function is identical to the PdhGetDataSourceTimeRange function, except that it supports the use of handles to data sources. +imp 'PdhGetDefaultPerfCounter' PdhGetDefaultPerfCounterW pdh 0 # Retrieves the name of the default counter for the specified object. This name can be used to set the initial counter selection in the Browse Counter dialog box. To use handles to data sources, use the PdhGetDefaultPerfCounterH function. +imp 'PdhGetDefaultPerfCounterH' PdhGetDefaultPerfCounterHW pdh 0 # Retrieves the name of the default counter for the specified object. +imp 'PdhGetDefaultPerfObject' PdhGetDefaultPerfObjectW pdh 0 # Retrieves the name of the default object. This name can be used to set the initial object selection in the Browse Counter dialog box. To use handles to data sources, use the PdhGetDefaultPerfObjectH function. +imp 'PdhGetDefaultPerfObjectH' PdhGetDefaultPerfObjectHW pdh 0 # Retrieves the name of the default object. +imp 'PdhGetDllVersion' PdhGetDllVersion pdh 0 # Returns the version of the currently installed Pdh.dll file. +imp 'PdhGetFormattedCounterArray' PdhGetFormattedCounterArrayW pdh 0 # Returns an array of formatted counter values. Use this function when you want to format the counter values of a counter that contains a wildcard character for the instance name. +imp 'PdhGetFormattedCounterValue' PdhGetFormattedCounterValue pdh 0 4 # Computes a displayable value for the specified counter. +imp 'PdhGetLogFileSize' PdhGetLogFileSize pdh 0 # Returns the size of the specified log file. +imp 'PdhGetRawCounterArray' PdhGetRawCounterArrayW pdh 0 # Returns an array of raw values from the specified counter. Use this function when you want to retrieve the raw counter values of a counter that contains a wildcard character for the instance name. +imp 'PdhGetRawCounterValue' PdhGetRawCounterValue pdh 0 # Returns the current raw value of the counter. +imp 'PdhIsRealTimeQuery' PdhIsRealTimeQuery pdh 0 # Determines if the specified query is a real-time query. +imp 'PdhLookupPerfIndexByName' PdhLookupPerfIndexByNameW pdh 0 # Returns the counter index corresponding to the specified counter name. +imp 'PdhLookupPerfNameByIndex' PdhLookupPerfNameByIndexW pdh 0 # Returns the performance object name or counter name corresponding to the specified index. +imp 'PdhMakeCounterPath' PdhMakeCounterPathW pdh 0 # Creates a full counter path using the members specified in the PDH_COUNTER_PATH_ELEMENTS structure. +imp 'PdhOpenLog' PdhOpenLogW pdh 0 # Opens the specified log file for reading or writing. +imp 'PdhOpenQuery' PdhOpenQueryW pdh 0 3 # Creates a new query that is used to manage the collection of performance data. To use handles to data sources, use the PdhOpenQueryH function. +imp 'PdhOpenQueryH' PdhOpenQueryH pdh 0 # Creates a new query that is used to manage the collection of performance data. This function is identical to the PdhOpenQuery function, except that it supports the use of handles to data sources. +imp 'PdhParseCounterPath' PdhParseCounterPathW pdh 0 # Parses the elements of the counter path and stores the results in the PDH_COUNTER_PATH_ELEMENTS structure. +imp 'PdhParseInstanceName' PdhParseInstanceNameW pdh 0 # Parses the elements of an instance string. +imp 'PdhReadRawLogRecord' PdhReadRawLogRecord pdh 0 # Reads the information in the specified binary trace log file. +imp 'PdhRemoveCounter' PdhRemoveCounter pdh 0 # Removes a counter from a query. +imp 'PdhSelectDataSource' PdhSelectDataSourceW pdh 0 # Displays a dialog window that prompts the user to specify the source of the performance data. +imp 'PdhSetCounterScaleFactor' PdhSetCounterScaleFactor pdh 0 # Sets the scale factor that is applied to the calculated value of the specified counter when you request the formatted counter value. If the PDH_FMT_NOSCALE flag is set, then this scale factor is ignored. +imp 'PdhSetDefaultRealTimeDataSource' PdhSetDefaultRealTimeDataSource pdh 0 # Specifies the source of the real-time data. +imp 'PdhSetQueryTimeRange' PdhSetQueryTimeRange pdh 0 # Limits the samples that you can read from a log file to those within the specified time range, inclusively. +imp 'PdhUpdateLog' PdhUpdateLogW pdh 0 # Collects counter data for the current query and writes the data to the log file. +imp 'PdhUpdateLogFileCatalog' PdhUpdateLogFileCatalog pdh 0 # Synchronizes the information in the log file catalog with the performance data in the log file. +imp 'PdhValidatePath' PdhValidatePathW pdh 0 # Validates that the counter is present on the computer specified in the counter path. +imp 'PdhValidatePathEx' PdhValidatePathExW pdh 0 # Validates that the specified counter is present on the computer or in the log file. +imp 'PerfAddCounters' PerfAddCounters pdh 0 # Adds performance counter specifications to the specified query. +imp 'PerfCloseQueryHandle' PerfCloseQueryHandle pdh 0 # Closes a query handle that you opened by calling PerfOpenQueryHandle. +imp 'PerfCreateInstance' PerfCreateInstance pdh 0 # Creates an instance of the specified counter set. +imp 'PerfDecrementULongCounterValue' PerfDecrementULongCounterValue pdh 0 # Decrements the value of a counter whose value is a 4-byte unsigned integer. Providers use this function. +imp 'PerfDecrementULongLongCounterValue' PerfDecrementULongLongCounterValue pdh 0 # Decrements the value of a counter whose value is an 8-byte unsigned integer. Providers use this function. +imp 'PerfDeleteCounters' PerfDeleteCounters pdh 0 # Removes the specified performance counter specifications from the specified query. +imp 'PerfDeleteInstance' PerfDeleteInstance pdh 0 # Deletes an instance of the counter set created by the PerfCreateInstance function. +imp 'PerfEnumerateCounterSet' PerfEnumerateCounterSet pdh 0 # Gets the counter set identifiers of the counter sets that are registered on the specified system. Counter set identifiers are globally unique identifiers (GUIDs). +imp 'PerfEnumerateCounterSetInstances' PerfEnumerateCounterSetInstances pdh 0 # Gets the names and identifiers of the active instances of a counter set on the specified system. +imp 'PerfIncrementULongCounterValue' PerfIncrementULongCounterValue pdh 0 # Increments the value of a counter whose value is a 4-byte unsigned integer. Providers use this function. +imp 'PerfIncrementULongLongCounterValue' PerfIncrementULongLongCounterValue pdh 0 # Increments the value of a counter whose value is an 8-byte unsigned integer. Providers use this function. +imp 'PerfOpenQueryHandle' PerfOpenQueryHandle pdh 0 # Creates a handle that references a query on the specified system. A query is a list of counter specifications. +imp 'PerfQueryCounterData' PerfQueryCounterData pdh 0 # Gets the values of the performance counters that match the counter specifications in the specified query. +imp 'PerfQueryCounterInfo' PerfQueryCounterInfo pdh 0 # Gets the counter specifications in the specified query. +imp 'PerfQueryCounterSetRegistrationInfo' PerfQueryCounterSetRegistrationInfo pdh 0 # Gets information about a counter set on the specified system. +imp 'PerfQueryInstance' PerfQueryInstance pdh 0 # Retrieves a pointer to the specified counter set instance. Providers use this function. +imp 'PerfSetCounterRefValue' PerfSetCounterRefValue pdh 0 # Updates the value of a counter whose value is a pointer to the actual data. Providers use this function. +imp 'PerfSetCounterSetInfo' PerfSetCounterSetInfo pdh 0 # Specifies the layout of a particular counter set. +imp 'PerfSetULongCounterValue' PerfSetULongCounterValue pdh 0 # Updates the value of a counter whose value is a 4-byte unsigned integer. Providers use this function. +imp 'PerfSetULongLongCounterValue' PerfSetULongLongCounterValue pdh 0 # Updates the value of a counter whose value is an 8-byte unsigned integer. Providers use this function. +imp 'PerfStartProvider' PerfStartProvider pdh 0 # Registers the provider. +imp 'PerfStartProviderEx' PerfStartProviderEx pdh 0 # Registers the provider. +imp 'PerfStopProvider' PerfStopProvider pdh 0 # Removes the provider's registration from the list of registered providers and frees all resources associated with the provider. +imp 'UnloadPerfCounterTextStrings' UnloadPerfCounterTextStringsW pdh 0 # Unloads performance objects and counters from the computer for the specified application. + +# PSAPI.DLL +# +# Name Actual DLL Hint Arity +imp 'EmptyWorkingSet' EmptyWorkingSet psapi 0 +imp 'EnumDeviceDrivers' EnumDeviceDrivers psapi 0 +imp 'EnumPageFiles' EnumPageFilesW psapi 0 +imp 'EnumProcessModules' EnumProcessModules psapi 0 +imp 'EnumProcessModulesEx' EnumProcessModulesEx psapi 0 +imp 'EnumProcesses' EnumProcesses psapi 0 +imp 'GetDeviceDriverBaseName' GetDeviceDriverBaseNameW psapi 0 +imp 'GetDeviceDriverFileName' GetDeviceDriverFileNameW psapi 0 +imp 'GetMappedFileName' GetMappedFileNameW psapi 0 +imp 'GetModuleBaseName' GetModuleBaseNameW psapi 0 +imp 'GetModuleFileNameEx' GetModuleFileNameExW psapi 0 +imp 'GetModuleInformation' GetModuleInformation psapi 0 +imp 'GetPerformanceInfo' GetPerformanceInfo psapi 0 +imp 'GetProcessImageFileName' GetProcessImageFileNameW psapi 0 3 +imp 'GetProcessMemoryInfo' GetProcessMemoryInfo psapi 0 3 +imp 'GetWsChanges' GetWsChanges psapi 0 +imp 'GetWsChangesEx' GetWsChangesEx psapi 0 +imp 'InitializeProcessForWsWatch' InitializeProcessForWsWatch psapi 0 +imp 'QueryWorkingSet' QueryWorkingSet psapi 0 +imp 'QueryWorkingSetEx' QueryWorkingSetEx psapi 0 + +# NETAPI32.DLL +# +# Name Actual DLL Hint Arity +imp 'I_BrowserSetNetlogonState' I_BrowserSetNetlogonState netapi32 34 +imp 'NetAccessAdd' NetAccessAdd netapi32 71 +imp 'NetAccessDel' NetAccessDel netapi32 72 +imp 'NetAccessEnum' NetAccessEnum netapi32 73 +imp 'NetAccessGetInfo' NetAccessGetInfo netapi32 74 +imp 'NetAccessGetUserPerms' NetAccessGetUserPerms netapi32 75 +imp 'NetAccessSetInfo' NetAccessSetInfo netapi32 76 +imp 'NetAlertRaise' NetAlertRaise netapi32 79 +imp 'NetAlertRaiseEx' NetAlertRaiseEx netapi32 80 +imp 'NetAuditClear' NetAuditClear netapi32 85 +imp 'NetAuditRead' NetAuditRead netapi32 86 +imp 'NetAuditWrite' NetAuditWrite netapi32 87 +imp 'NetConfigGet' NetConfigGet netapi32 88 +imp 'NetConfigGetAll' NetConfigGetAll netapi32 89 +imp 'NetConfigSet' NetConfigSet netapi32 90 +imp 'NetErrorLogClear' NetErrorLogClear netapi32 124 +imp 'NetErrorLogRead' NetErrorLogRead netapi32 125 +imp 'NetErrorLogWrite' NetErrorLogWrite netapi32 126 +imp 'NetMessageBufferSend' NetMessageBufferSend netapi32 161 +imp 'NetMessageNameAdd' NetMessageNameAdd netapi32 162 +imp 'NetMessageNameDel' NetMessageNameDel netapi32 163 +imp 'NetMessageNameEnum' NetMessageNameEnum netapi32 164 +imp 'NetMessageNameGetInfo' NetMessageNameGetInfo netapi32 165 +imp 'NetRegisterDomainNameChangeNotification' NetRegisterDomainNameChangeNotification netapi32 169 +imp 'NetReplExportDirAdd' NetReplExportDirAdd netapi32 175 +imp 'NetReplExportDirDel' NetReplExportDirDel netapi32 176 +imp 'NetReplExportDirEnum' NetReplExportDirEnum netapi32 177 +imp 'NetReplExportDirGetInfo' NetReplExportDirGetInfo netapi32 178 +imp 'NetReplExportDirLock' NetReplExportDirLock netapi32 179 +imp 'NetReplExportDirSetInfo' NetReplExportDirSetInfo netapi32 180 +imp 'NetReplExportDirUnlock' NetReplExportDirUnlock netapi32 181 +imp 'NetReplGetInfo' NetReplGetInfo netapi32 182 +imp 'NetReplImportDirAdd' NetReplImportDirAdd netapi32 183 +imp 'NetReplImportDirDel' NetReplImportDirDel netapi32 184 +imp 'NetReplImportDirEnum' NetReplImportDirEnum netapi32 185 +imp 'NetReplImportDirGetInfo' NetReplImportDirGetInfo netapi32 186 +imp 'NetReplImportDirLock' NetReplImportDirLock netapi32 187 +imp 'NetReplImportDirUnlock' NetReplImportDirUnlock netapi32 188 +imp 'NetReplSetInfo' NetReplSetInfo netapi32 189 +imp 'NetServerEnum' NetServerEnum netapi32 202 +imp 'NetServerEnumEx' NetServerEnumEx netapi32 203 +imp 'NetServiceControl' NetServiceControl netapi32 210 +imp 'NetServiceEnum' NetServiceEnum netapi32 211 +imp 'NetServiceGetInfo' NetServiceGetInfo netapi32 212 +imp 'NetServiceInstall' NetServiceInstall netapi32 213 +imp 'NetStatisticsGet' NetStatisticsGet netapi32 227 +imp 'NetUnregisterDomainNameChangeNotification' NetUnregisterDomainNameChangeNotification netapi32 229 +imp 'NetWkstaGetInfo' NetWkstaGetInfo netapi32 248 +imp 'NetWkstaSetInfo' NetWkstaSetInfo netapi32 249 +imp 'Netbios' Netbios netapi32 257 +imp 'NetpAddTlnFtinfoEntry' NetpAddTlnFtinfoEntry netapi32 258 +imp 'NetpAllocFtinfoEntry' NetpAllocFtinfoEntry netapi32 259 +imp 'NetpAssertFailed' NetpAssertFailed netapi32 260 +imp 'NetpCleanFtinfoContext' NetpCleanFtinfoContext netapi32 261 +imp 'NetpCloseConfigData' NetpCloseConfigData netapi32 262 +imp 'NetpCopyFtinfoContext' NetpCopyFtinfoContext netapi32 263 +imp 'NetpDbgPrint' NetpDbgPrint netapi32 264 +imp 'NetpGetConfigBool' NetpGetConfigBool netapi32 265 +imp 'NetpGetConfigDword' NetpGetConfigDword netapi32 266 +imp 'NetpGetConfigTStrArray' NetpGetConfigTStrArray netapi32 267 +imp 'NetpGetConfigValue' NetpGetConfigValue netapi32 268 +imp 'NetpGetFileSecurity' NetpGetFileSecurity netapi32 269 +imp 'NetpHexDump' NetpHexDump netapi32 270 +imp 'NetpInitFtinfoContext' NetpInitFtinfoContext netapi32 271 +imp 'NetpIsUncComputerNameValid' NetpIsUncComputerNameValid netapi32 273 +imp 'NetpMergeFtinfo' NetpMergeFtinfo netapi32 274 +imp 'NetpNetBiosReset' NetpNetBiosReset netapi32 275 +imp 'NetpNetBiosStatusToApiStatus' NetpNetBiosStatusToApiStatus netapi32 276 +imp 'NetpOpenConfigData' NetpOpenConfigData netapi32 277 +imp 'NetpSetFileSecurity' NetpSetFileSecurity netapi32 278 +imp 'RxNetAccessAdd' RxNetAccessAdd netapi32 288 +imp 'RxNetAccessDel' RxNetAccessDel netapi32 289 +imp 'RxNetAccessEnum' RxNetAccessEnum netapi32 290 +imp 'RxNetAccessGetInfo' RxNetAccessGetInfo netapi32 291 +imp 'RxNetAccessGetUserPerms' RxNetAccessGetUserPerms netapi32 292 +imp 'RxNetAccessSetInfo' RxNetAccessSetInfo netapi32 293 +imp 'RxNetServerEnum' RxNetServerEnum netapi32 294 +imp 'RxNetUserPasswordSet' RxNetUserPasswordSet netapi32 295 +imp 'RxRemoteApi' RxRemoteApi netapi32 296 + +# URL.DLL +# +# Name Actual DLL Hint Arity +imp 'OpenURL' OpenURL url 111 +imp 'TelnetProtocolHandler' TelnetProtocolHandler url 113 +imp 'TranslateURLW' TranslateURLW url 116 +imp 'URLAssociationDialog' URLAssociationDialogW url 118 +imp 'AddMIMEFileTypesPS' AddMIMEFileTypesPS url 102 +imp 'AutodialHookCallback' AutodialHookCallback url 103 +imp 'FileProtocolHandler' FileProtocolHandler url 104 +imp 'InetIsOffline' InetIsOffline url 106 +imp 'MIMEAssociationDialog' MIMEAssociationDialogW url 108 +imp 'MailToProtocolHandler' MailToProtocolHandler url 109 + +# SHELL32.DLL +# +# Name Actual DLL Hint Arity +imp 'AppCompat_RunDLLW' AppCompat_RunDLLW shell32 255 +imp 'AssocCreateForClasses' AssocCreateForClasses shell32 263 +imp 'AssocGetDetailsOfPropKey' AssocGetDetailsOfPropKey shell32 267 +imp 'CDefFolderMenu_Create2' CDefFolderMenu_Create2 shell32 701 +imp 'CIDLData_CreateFromIDArray' CIDLData_CreateFromIDArray shell32 83 +imp 'CStorageItem_GetValidatedStorageItemObject' CStorageItem_GetValidatedStorageItemObject shell32 937 +imp 'CheckEscapes' CheckEscapesW shell32 268 +imp 'CommandLineToArgv' CommandLineToArgvW shell32 269 +imp 'Control_RunDLL' Control_RunDLL shell32 272 +imp 'Control_RunDLLAsUser' Control_RunDLLAsUserW shell32 274 +imp 'Control_RunDLLW' Control_RunDLLW shell32 275 +imp 'DAD_AutoScroll' DAD_AutoScroll shell32 129 +imp 'DAD_DragEnterEx' DAD_DragEnterEx shell32 131 +imp 'DAD_DragEnterEx2' DAD_DragEnterEx2 shell32 22 +imp 'DAD_DragLeave' DAD_DragLeave shell32 132 +imp 'DAD_DragMove' DAD_DragMove shell32 134 +imp 'DAD_SetDragImage' DAD_SetDragImage shell32 136 +imp 'DAD_ShowDragImage' DAD_ShowDragImage shell32 137 +imp 'DllGetActivationFactory' DllGetActivationFactory shell32 277 +imp 'DllGetVersion' DllGetVersion shell32 279 +imp 'DllInstall' DllInstall shell32 280 +imp 'DllRegisterServer' DllRegisterServer shell32 281 +imp 'DllUnregisterServer' DllUnregisterServer shell32 282 +imp 'DoEnvironmentSubst' DoEnvironmentSubstW shell32 284 +imp 'DragAcceptFiles' DragAcceptFiles shell32 285 +imp 'DragFinish' DragFinish shell32 286 +imp 'DragQueryFile' DragQueryFileW shell32 290 +imp 'DragQueryFileAor' DragQueryFileAorW shell32 289 +imp 'DragQueryPoint' DragQueryPoint shell32 291 +imp 'DriveType' DriveType shell32 64 +imp 'DuplicateIcon' DuplicateIcon shell32 292 +imp 'ExtractAssociatedIcon' ExtractAssociatedIconW shell32 296 +imp 'ExtractAssociatedIconEx' ExtractAssociatedIconExW shell32 295 +imp 'ExtractIcon' ExtractIconW shell32 301 +imp 'ExtractIconEx' ExtractIconExW shell32 300 +imp 'FindExecutable' FindExecutableW shell32 303 +imp 'FreeIconList' FreeIconList shell32 304 +imp 'GetCurrentProcessExplicitAppUserModelID' GetCurrentProcessExplicitAppUserModelID shell32 305 +imp 'GetFileNameFromBrowse' GetFileNameFromBrowse shell32 63 +imp 'GetSystemPersistedStorageItemList' GetSystemPersistedStorageItemList shell32 919 imp 'ILAppendID' ILAppendID shell32 154 imp 'ILClone' ILClone shell32 18 imp 'ILCloneFirst' ILCloneFirst shell32 19 imp 'ILCombine' ILCombine shell32 25 -imp 'ILCreateFromPathA' ILCreateFromPathA shell32 189 imp 'ILCreateFromPath' ILCreateFromPathW shell32 190 imp 'ILFindChild' ILFindChild shell32 24 imp 'ILFindLastID' ILFindLastID shell32 16 @@ -2847,257 +4323,311 @@ imp 'ILIsParent' ILIsParent shell32 23 imp 'ILLoadFromStreamEx' ILLoadFromStreamEx shell32 846 imp 'ILRemoveLastID' ILRemoveLastID shell32 17 imp 'ILSaveToStream' ILSaveToStream shell32 27 -imp 'IMPGetIMEA' IMPGetIMEA user32 2017 -imp 'IMPGetIMEW' IMPGetIMEW user32 2018 -imp 'IMPQueryIMEA' IMPQueryIMEA user32 2019 -imp 'IMPQueryIMEW' IMPQueryIMEW user32 2020 -imp 'IMPSetIMEA' IMPSetIMEA user32 2021 -imp 'IMPSetIMEW' IMPSetIMEW user32 2022 -imp 'I_BrowserSetNetlogonState' I_BrowserSetNetlogonState netapi32 34 -imp 'I_ScGetCurrentGroupState' I_ScGetCurrentGroupStateW advapi32 1001 -imp 'I_ScReparseServiceDatabase' I_ScReparseServiceDatabase advapi32 1388 -imp 'I_ScSetServiceBitsA' I_ScSetServiceBitsA advapi32 1391 -imp 'I_ScSetServiceBits' I_ScSetServiceBitsW advapi32 1392 -imp 'IdentifyCodeAuthzLevel' IdentifyCodeAuthzLevelW advapi32 1394 -imp 'IdnToAscii' IdnToAscii kernel32 0 # KernelBase -imp 'IdnToNameprepUnicode' IdnToNameprepUnicode kernel32 0 # KernelBase -imp 'IdnToUnicode' IdnToUnicode kernel32 0 # KernelBase -imp 'ImpersonateAnonymousToken' ImpersonateAnonymousToken advapi32 0 # KernelBase -imp 'ImpersonateDdeClientWindow' ImpersonateDdeClientWindow user32 2023 -imp 'ImpersonateLoggedOnUser' ImpersonateLoggedOnUser advapi32 0 # KernelBase -imp 'ImpersonateNamedPipeClient' ImpersonateNamedPipeClient advapi32 0 # KernelBase -imp 'ImpersonateSelf' ImpersonateSelf advapi32 0 # KernelBase -imp 'InSendMessage' InSendMessage user32 2024 -imp 'InSendMessageEx' InSendMessageEx user32 2025 -imp 'IncrementPackageStatusVersion' IncrementPackageStatusVersion KernelBase 847 -imp 'InetIsOffline' InetIsOffline url 106 -imp 'InetNtop' InetNtopW ws2_32 35 -imp 'InetPton' InetPtonW ws2_32 36 -imp 'InflateRect' InflateRect user32 2026 -imp 'InheritWindowMonitor' InheritWindowMonitor user32 2027 -imp 'InitAtomTable' InitAtomTable kernel32 860 -imp 'InitDManipHook' InitDManipHook user32 2028 imp 'InitNetworkAddressControl' InitNetworkAddressControl shell32 306 -imp 'InitOnceBeginInitialize' InitOnceBeginInitialize kernel32 0 # KernelBase -imp 'InitOnceComplete' InitOnceComplete kernel32 0 # KernelBase -imp 'InitOnceExecuteOnce' InitOnceExecuteOnce kernel32 0 # KernelBase -imp 'InitializeAcl' InitializeAcl advapi32 0 # KernelBase -imp 'InitializeContext' InitializeContext kernel32 0 # KernelBase -imp 'InitializeCriticalSectionAndSpinCount' InitializeCriticalSectionAndSpinCount kernel32 0 2 # KernelBase -imp 'InitializeCriticalSectionEx' InitializeCriticalSectionEx kernel32 0 # KernelBase -imp 'InitializeEnclave' InitializeEnclave KernelBase 858 -imp 'InitializeGenericHidInjection' InitializeGenericHidInjection user32 2029 -imp 'InitializeInputDeviceInjection' InitializeInputDeviceInjection user32 2030 -imp 'InitializeLpkHooks' InitializeLpkHooks user32 2031 -imp 'InitializePointerDeviceInjection' InitializePointerDeviceInjection user32 2032 -imp 'InitializePointerDeviceInjectionEx' InitializePointerDeviceInjectionEx user32 2033 -imp 'InitializeProcThreadAttributeList' InitializeProcThreadAttributeList kernel32 0 4 # KernelBase -imp 'InitializeProcessForWsWatch' InitializeProcessForWsWatch KernelBase 860 -imp 'InitializeSecurityDescriptor' InitializeSecurityDescriptor advapi32 0 # KernelBase -imp 'InitializeSid' InitializeSid advapi32 0 # KernelBase -imp 'InitializeSynchronizationBarrier' InitializeSynchronizationBarrier kernel32 0 # KernelBase -imp 'InitializeTouchInjection' InitializeTouchInjection user32 2034 -imp 'InitiateShutdownA' InitiateShutdownA advapi32 1402 5 -imp 'InitiateShutdown' InitiateShutdownW advapi32 1403 5 -imp 'InitiateSystemShutdownA' InitiateSystemShutdownA advapi32 1404 -imp 'InitiateSystemShutdownExA' InitiateSystemShutdownExA advapi32 1405 -imp 'InitiateSystemShutdownEx' InitiateSystemShutdownExW advapi32 1406 -imp 'InitiateSystemShutdown' InitiateSystemShutdownW advapi32 1407 -imp 'InjectDeviceInput' InjectDeviceInput user32 2035 -imp 'InjectGenericHidInput' InjectGenericHidInput user32 2036 -imp 'InjectKeyboardInput' InjectKeyboardInput user32 2037 -imp 'InjectMouseInput' InjectMouseInput user32 2038 -imp 'InjectPointerInput' InjectPointerInput user32 2039 -imp 'InjectTouchInput' InjectTouchInput user32 2040 -imp 'InsertMenuA' InsertMenuA user32 2041 5 -imp 'InsertMenuItemA' InsertMenuItemA user32 2042 -imp 'InsertMenuItem' InsertMenuItemW user32 2043 -imp 'InsertMenu' InsertMenuW user32 2044 5 -imp 'InstallApplication' InstallApplication advapi32 1408 -imp 'InstallELAMCertificateInfo' InstallELAMCertificateInfo kernel32 0 # KernelBase -imp 'InternalDeleteDC' InternalDeleteDC gdi32 1736 -imp 'InternalExtractIconListA' InternalExtractIconListA shell32 307 imp 'InternalExtractIconList' InternalExtractIconListW shell32 308 -imp 'InternalGetWindowIcon' InternalGetWindowIcon user32 2045 -imp 'InternalGetWindowText' InternalGetWindowText user32 2046 -imp 'InternalLcidToName' InternalLcidToName KernelBase 872 -imp 'Internal_EnumCalendarInfo' Internal_EnumCalendarInfo KernelBase 873 -imp 'Internal_EnumDateFormats' Internal_EnumDateFormats KernelBase 874 -imp 'Internal_EnumLanguageGroupLocales' Internal_EnumLanguageGroupLocales KernelBase 875 -imp 'Internal_EnumSystemCodePages' Internal_EnumSystemCodePages KernelBase 876 -imp 'Internal_EnumSystemLanguageGroups' Internal_EnumSystemLanguageGroups KernelBase 877 -imp 'Internal_EnumSystemLocales' Internal_EnumSystemLocales KernelBase 878 -imp 'Internal_EnumTimeFormats' Internal_EnumTimeFormats KernelBase 879 -imp 'Internal_EnumUILanguages' Internal_EnumUILanguages KernelBase 880 -imp 'InternetTimeFromSystemTimeA' InternetTimeFromSystemTimeA KernelBase 881 -imp 'InternetTimeFromSystemTime' InternetTimeFromSystemTimeW KernelBase 882 -imp 'InternetTimeToSystemTimeA' InternetTimeToSystemTimeA KernelBase 883 -imp 'InternetTimeToSystemTime' InternetTimeToSystemTimeW KernelBase 884 -imp 'IntersectClipRect' IntersectClipRect gdi32 1737 -imp 'IntersectRect' IntersectRect user32 2047 -imp 'InvalidateAppModelVersionCache' InvalidateAppModelVersionCache KernelBase 885 -imp 'InvalidateConsoleDIBits' InvalidateConsoleDIBits kernel32 881 -imp 'InvalidateRect' InvalidateRect user32 2048 3 -imp 'InvalidateRgn' InvalidateRgn user32 2049 -imp 'InvertRect' InvertRect user32 2050 -imp 'InvertRgn' InvertRgn gdi32 1738 -imp 'IsBadCodePtr' IsBadCodePtr kernel32 882 -imp 'IsBadHugeReadPtr' IsBadHugeReadPtr kernel32 883 -imp 'IsBadHugeWritePtr' IsBadHugeWritePtr kernel32 884 -imp 'IsBadReadPtr' IsBadReadPtr kernel32 885 -imp 'IsBadStringPtrA' IsBadStringPtrA kernel32 886 -imp 'IsBadStringPtr' IsBadStringPtrW kernel32 887 -imp 'IsBadWritePtr' IsBadWritePtr kernel32 888 -imp 'IsCalendarLeapDay' IsCalendarLeapDay kernel32 889 -imp 'IsCalendarLeapMonth' IsCalendarLeapMonth kernel32 890 -imp 'IsCalendarLeapYear' IsCalendarLeapYear kernel32 891 -imp 'IsCharAlphaA' IsCharAlphaA KernelBase 886 -imp 'IsCharAlphaNumericA' IsCharAlphaNumericA KernelBase 887 -imp 'IsCharAlphaNumeric' IsCharAlphaNumericW KernelBase 888 -imp 'IsCharAlpha' IsCharAlphaW KernelBase 889 -imp 'IsCharBlank' IsCharBlankW KernelBase 890 -imp 'IsCharCntrl' IsCharCntrlW KernelBase 891 -imp 'IsCharDigit' IsCharDigitW KernelBase 892 -imp 'IsCharLowerA' IsCharLowerA KernelBase 893 -imp 'IsCharLower' IsCharLowerW KernelBase 894 -imp 'IsCharPunct' IsCharPunctW KernelBase 895 -imp 'IsCharSpaceA' IsCharSpaceA KernelBase 896 -imp 'IsCharSpace' IsCharSpaceW KernelBase 897 -imp 'IsCharUpperA' IsCharUpperA KernelBase 898 -imp 'IsCharUpper' IsCharUpperW KernelBase 899 -imp 'IsCharXDigit' IsCharXDigitW KernelBase 900 -imp 'IsChild' IsChild user32 2059 2 -imp 'IsClipboardFormatAvailable' IsClipboardFormatAvailable user32 2060 -imp 'IsDBCSLeadByte' IsDBCSLeadByte kernel32 0 # KernelBase -imp 'IsDBCSLeadByteEx' IsDBCSLeadByteEx kernel32 0 # KernelBase -imp 'sys_IsDebuggerPresent_nt' IsDebuggerPresent KernelBase 903 imp 'IsDesktopExplorerProcess' IsDesktopExplorerProcess shell32 942 -imp 'IsDeveloperModeEnabled' IsDeveloperModeEnabled KernelBase 904 -imp 'IsDeveloperModePolicyApplied' IsDeveloperModePolicyApplied KernelBase 905 -imp 'IsDialogMessageA' IsDialogMessageA user32 2062 -imp 'IsDialogMessage' IsDialogMessageW user32 2063 -imp 'IsDlgButtonChecked' IsDlgButtonChecked user32 2064 -imp 'IsEnclaveTypeSupported' IsEnclaveTypeSupported KernelBase 906 -imp 'IsGUIThread' IsGUIThread user32 2065 -imp 'IsGlobalizationUserSettingsKeyRedirected' IsGlobalizationUserSettingsKeyRedirected KernelBase 907 -imp 'IsHungAppWindow' IsHungAppWindow user32 2066 -imp 'IsIconic' IsIconic user32 2067 1 -imp 'IsImmersiveProcess' IsImmersiveProcess user32 2068 -imp 'IsInDesktopWindowBand' IsInDesktopWindowBand user32 2069 -imp 'IsInternetESCEnabled' IsInternetESCEnabled KernelBase 908 -imp 'IsLFNDriveA' IsLFNDriveA shell32 41 imp 'IsLFNDrive' IsLFNDriveW shell32 42 -imp 'IsMenu' IsMenu user32 2070 1 -imp 'IsMouseInPointerEnabled' IsMouseInPointerEnabled user32 2071 -imp 'IsNLSDefinedString' IsNLSDefinedString kernel32 0 # KernelBase -imp 'IsNativeVhdBoot' IsNativeVhdBoot kernel32 897 imp 'IsNetDrive' IsNetDrive shell32 66 -imp 'IsNormalizedString' IsNormalizedString kernel32 0 # KernelBase -imp 'IsOnDemandRegistrationSupportedForExtensionCategory' IsOnDemandRegistrationSupportedForExtensionCategory KernelBase 911 -imp 'IsOneCoreTransformMode' IsOneCoreTransformMode user32 2072 imp 'IsProcessAnExplorer' IsProcessAnExplorer shell32 941 -imp 'IsProcessCritical' IsProcessCritical kernel32 0 # KernelBase -imp 'IsProcessDPIAware' IsProcessDPIAware user32 2073 -imp 'IsProcessInJob' IsProcessInJob kernel32 0 # KernelBase -imp 'IsProcessorFeaturePresent' IsProcessorFeaturePresent kernel32 0 # KernelBase -imp 'IsQueueAttached' IsQueueAttached user32 2074 -imp 'IsRectEmpty' IsRectEmpty user32 2075 -imp 'IsSETEnabled' IsSETEnabled user32 2076 -imp 'IsServerSideWindow' IsServerSideWindow user32 2077 -imp 'IsSideloadingEnabled' IsSideloadingEnabled KernelBase 915 -imp 'IsSideloadingPolicyApplied' IsSideloadingPolicyApplied KernelBase 916 -imp 'IsSyncForegroundPolicyRefresh' IsSyncForegroundPolicyRefresh KernelBase 917 -imp 'IsSystemResumeAutomatic' IsSystemResumeAutomatic kernel32 902 -imp 'IsTextUnicode' IsTextUnicode advapi32 1409 -imp 'IsThreadAFiber' IsThreadAFiber kernel32 0 # KernelBase -imp 'IsThreadDesktopComposited' IsThreadDesktopComposited user32 2078 -imp 'IsThreadMessageQueueAttached' IsThreadMessageQueueAttached user32 2528 -imp 'IsThreadTSFEventAware' IsThreadTSFEventAware user32 2079 -imp 'IsTimeZoneRedirectionEnabled' IsTimeZoneRedirectionEnabled KernelBase 920 -imp 'IsTokenRestricted' IsTokenRestricted advapi32 0 # KernelBase -imp 'IsTokenUntrusted' IsTokenUntrusted advapi32 1411 -imp 'IsTopLevelWindow' IsTopLevelWindow user32 2080 -imp 'IsTouchWindow' IsTouchWindow user32 2081 imp 'IsUserAnAdmin' IsUserAnAdmin shell32 680 -imp 'IsValidAcl' IsValidAcl advapi32 0 # KernelBase -imp 'IsValidCalDateTime' IsValidCalDateTime kernel32 905 -imp 'IsValidCodePage' IsValidCodePage kernel32 0 # KernelBase -imp 'IsValidDpiAwarenessContext' IsValidDpiAwarenessContext user32 2082 -imp 'IsValidEnhMetaRecord' IsValidEnhMetaRecord gdi32 1739 -imp 'IsValidEnhMetaRecordOffExt' IsValidEnhMetaRecordOffExt gdi32 1740 -imp 'IsValidLanguageGroup' IsValidLanguageGroup kernel32 0 # KernelBase -imp 'IsValidLocale' IsValidLocale kernel32 0 # KernelBase -imp 'IsValidLocaleName' IsValidLocaleName kernel32 0 # KernelBase -imp 'IsValidNLSVersion' IsValidNLSVersion kernel32 0 # KernelBase -imp 'IsValidRelativeSecurityDescriptor' IsValidRelativeSecurityDescriptor KernelBase 928 -imp 'IsValidSecurityDescriptor' IsValidSecurityDescriptor advapi32 0 # KernelBase -imp 'IsValidSid' IsValidSid advapi32 0 # KernelBase -imp 'IsWellKnownSid' IsWellKnownSid advapi32 0 # KernelBase -imp 'IsWinEventHookInstalled' IsWinEventHookInstalled user32 2083 -imp 'IsWindow' IsWindow user32 2084 1 -imp 'IsWindowArranged' IsWindowArranged user32 2085 -imp 'IsWindowEnabled' IsWindowEnabled user32 2086 -imp 'IsWindowInDestroy' IsWindowInDestroy user32 2087 -imp 'IsWindowRedirectedForPrint' IsWindowRedirectedForPrint user32 2088 -imp 'IsWindowUnicode' IsWindowUnicode user32 2089 -imp 'IsWindowVisible' IsWindowVisible user32 2090 1 -imp 'IsWow64GuestMachineSupported' IsWow64GuestMachineSupported KernelBase 932 -imp 'IsWow64Message' IsWow64Message user32 2091 -imp 'IsWow64Process' IsWow64Process kernel32 0 # KernelBase -imp 'IsWow64Process2' IsWow64Process2 KernelBase 934 -imp 'IsZoomed' IsZoomed user32 2092 1 -imp 'K32EmptyWorkingSet' K32EmptyWorkingSet kernel32 0 # KernelBase -imp 'K32EnumDeviceDrivers' K32EnumDeviceDrivers kernel32 0 # KernelBase -imp 'K32EnumPageFilesA' K32EnumPageFilesA kernel32 0 # KernelBase -imp 'K32EnumPageFiles' K32EnumPageFilesW kernel32 0 # KernelBase -imp 'K32EnumProcessModules' K32EnumProcessModules kernel32 0 # KernelBase -imp 'K32EnumProcessModulesEx' K32EnumProcessModulesEx kernel32 0 # KernelBase -imp 'K32EnumProcesses' K32EnumProcesses kernel32 0 # KernelBase -imp 'K32GetDeviceDriverBaseNameA' K32GetDeviceDriverBaseNameA kernel32 0 # KernelBase -imp 'K32GetDeviceDriverBaseName' K32GetDeviceDriverBaseNameW kernel32 0 # KernelBase -imp 'K32GetDeviceDriverFileNameA' K32GetDeviceDriverFileNameA kernel32 0 # KernelBase -imp 'K32GetDeviceDriverFileName' K32GetDeviceDriverFileNameW kernel32 0 # KernelBase -imp 'K32GetMappedFileNameA' K32GetMappedFileNameA kernel32 0 # KernelBase -imp 'K32GetMappedFileName' K32GetMappedFileNameW kernel32 0 # KernelBase -imp 'K32GetModuleBaseNameA' K32GetModuleBaseNameA kernel32 0 # KernelBase -imp 'K32GetModuleBaseName' K32GetModuleBaseNameW kernel32 0 # KernelBase -imp 'K32GetModuleFileNameExA' K32GetModuleFileNameExA kernel32 0 # KernelBase -imp 'K32GetModuleFileNameEx' K32GetModuleFileNameExW kernel32 0 # KernelBase -imp 'K32GetModuleInformation' K32GetModuleInformation kernel32 0 # KernelBase -imp 'K32GetPerformanceInfo' K32GetPerformanceInfo kernel32 0 # KernelBase -imp 'K32GetProcessImageFileNameA' K32GetProcessImageFileNameA kernel32 0 # KernelBase -imp 'K32GetProcessImageFileName' K32GetProcessImageFileNameW kernel32 0 # KernelBase -imp 'K32GetProcessMemoryInfo' K32GetProcessMemoryInfo kernel32 0 # KernelBase -imp 'K32GetWsChanges' K32GetWsChanges kernel32 0 # KernelBase -imp 'K32GetWsChangesEx' K32GetWsChangesEx kernel32 0 # KernelBase -imp 'K32InitializeProcessForWsWatch' K32InitializeProcessForWsWatch kernel32 0 # KernelBase -imp 'K32QueryWorkingSet' K32QueryWorkingSet kernel32 0 # KernelBase -imp 'K32QueryWorkingSetEx' K32QueryWorkingSetEx kernel32 0 # KernelBase -imp 'KernelBaseGetGlobalData' KernelBaseGetGlobalData KernelBase 962 -imp 'KernelbasePostInit' KernelbasePostInit KernelBase 963 +imp 'LaunchMSHelp_RunDLLW' LaunchMSHelp_RunDLLW shell32 309 +imp 'OpenAs_RunDLL' OpenAs_RunDLL shell32 81 +imp 'OpenAs_RunDLLW' OpenAs_RunDLLW shell32 133 +imp 'OpenRegStream' OpenRegStream shell32 85 +imp 'Options_RunDLL' Options_RunDLL shell32 310 +imp 'Options_RunDLLW' Options_RunDLLW shell32 312 +imp 'PathCleanupSpec' PathCleanupSpec shell32 171 +imp 'PathGetShortPath' PathGetShortPath shell32 92 +imp 'PathIsExe' PathIsExe shell32 43 +imp 'PathIsSlow' PathIsSlowW shell32 239 +imp 'PathMakeUniqueName' PathMakeUniqueName shell32 47 +imp 'PathQualify' PathQualify shell32 49 +imp 'PathResolve' PathResolve shell32 51 +imp 'PathYetAnotherMakeUniqueName' PathYetAnotherMakeUniqueName shell32 75 +imp 'PickIconDlg' PickIconDlg shell32 62 +imp 'PifMgr_CloseProperties' PifMgr_CloseProperties shell32 13 +imp 'PifMgr_GetProperties' PifMgr_GetProperties shell32 10 +imp 'PifMgr_OpenProperties' PifMgr_OpenProperties shell32 9 +imp 'PifMgr_SetProperties' PifMgr_SetProperties shell32 11 +imp 'PrepareDiscForBurnRunDll' PrepareDiscForBurnRunDllW shell32 135 +imp 'PrintersGetCommand_RunDLL' PrintersGetCommand_RunDLL shell32 138 +imp 'PrintersGetCommand_RunDLLW' PrintersGetCommand_RunDLLW shell32 150 +imp 'ReadCabinetState' ReadCabinetState shell32 654 +imp 'RealDriveType' RealDriveType shell32 524 +imp 'RealShellExecute' RealShellExecuteW shell32 226 +imp 'RealShellExecuteEx' RealShellExecuteExW shell32 208 +imp 'RegenerateUserEnvironment' RegenerateUserEnvironment shell32 313 +imp 'RestartDialog' RestartDialog shell32 59 +imp 'RestartDialogEx' RestartDialogEx shell32 730 +imp 'RunAsNewUser_RunDLLW' RunAsNewUser_RunDLLW shell32 314 +imp 'SHAddDefaultPropertiesByExt' SHAddDefaultPropertiesByExt shell32 315 +imp 'SHAddFromPropSheetExtArray' SHAddFromPropSheetExtArray shell32 167 +imp 'SHAddToRecentDocs' SHAddToRecentDocs shell32 316 +imp 'SHAlloc' SHAlloc shell32 196 +imp 'SHAppBarMessage' SHAppBarMessage shell32 317 +imp 'SHAssocEnumHandlers' SHAssocEnumHandlers shell32 318 +imp 'SHAssocEnumHandlersForProtocolByApplication' SHAssocEnumHandlersForProtocolByApplication shell32 319 +imp 'SHBindToFolderIDListParent' SHBindToFolderIDListParent shell32 320 +imp 'SHBindToFolderIDListParentEx' SHBindToFolderIDListParentEx shell32 321 +imp 'SHBindToObject' SHBindToObject shell32 322 +imp 'SHBindToParent' SHBindToParent shell32 323 +imp 'SHBrowseForFolder' SHBrowseForFolderW shell32 326 +imp 'SHCLSIDFromString' SHCLSIDFromString shell32 147 +imp 'SHChangeNotification_Lock' SHChangeNotification_Lock shell32 644 +imp 'SHChangeNotification_Unlock' SHChangeNotification_Unlock shell32 645 +imp 'SHChangeNotify' SHChangeNotify shell32 327 +imp 'SHChangeNotifyDeregister' SHChangeNotifyDeregister shell32 4 +imp 'SHChangeNotifyRegister' SHChangeNotifyRegister shell32 2 +imp 'SHChangeNotifyRegisterThread' SHChangeNotifyRegisterThread shell32 328 +imp 'SHChangeNotifySuspendResume' SHChangeNotifySuspendResume shell32 329 +imp 'SHCloneSpecialIDList' SHCloneSpecialIDList shell32 89 +imp 'SHCoCreateInstanceWorker' SHCoCreateInstanceWorker shell32 330 +imp 'SHCreateAssociationRegistration' SHCreateAssociationRegistration shell32 331 +imp 'SHCreateCategoryEnum' SHCreateCategoryEnum shell32 332 +imp 'SHCreateDataObject' SHCreateDataObject shell32 333 +imp 'SHCreateDefaultContextMenu' SHCreateDefaultContextMenu shell32 334 +imp 'SHCreateDefaultExtractIcon' SHCreateDefaultExtractIcon shell32 335 +imp 'SHCreateDefaultPropertiesOp' SHCreateDefaultPropertiesOp shell32 336 +imp 'SHCreateDirectory' SHCreateDirectory shell32 165 +imp 'SHCreateDirectoryEx' SHCreateDirectoryExW shell32 338 +imp 'SHCreateDrvExtIcon' SHCreateDrvExtIcon shell32 339 +imp 'SHCreateFileExtractIcon' SHCreateFileExtractIconW shell32 743 +imp 'SHCreateItemFromIDList' SHCreateItemFromIDList shell32 340 +imp 'SHCreateItemFromParsingName' SHCreateItemFromParsingName shell32 341 +imp 'SHCreateItemFromRelativeName' SHCreateItemFromRelativeName shell32 342 +imp 'SHCreateItemInKnownFolder' SHCreateItemInKnownFolder shell32 343 +imp 'SHCreateItemWithParent' SHCreateItemWithParent shell32 344 +imp 'SHCreateLocalServerRunDll' SHCreateLocalServerRunDll shell32 345 +imp 'SHCreateProcessAsUser' SHCreateProcessAsUserW shell32 346 +imp 'SHCreatePropSheetExtArray' SHCreatePropSheetExtArray shell32 168 +imp 'SHCreateQueryCancelAutoPlayMoniker' SHCreateQueryCancelAutoPlayMoniker shell32 347 +imp 'SHCreateShellFolderView' SHCreateShellFolderView shell32 256 +imp 'SHCreateShellFolderViewEx' SHCreateShellFolderViewEx shell32 174 +imp 'SHCreateShellItem' SHCreateShellItem shell32 348 +imp 'SHCreateShellItemArray' SHCreateShellItemArray shell32 349 +imp 'SHCreateShellItemArrayFromDataObject' SHCreateShellItemArrayFromDataObject shell32 350 +imp 'SHCreateShellItemArrayFromIDLists' SHCreateShellItemArrayFromIDLists shell32 351 +imp 'SHCreateShellItemArrayFromShellItem' SHCreateShellItemArrayFromShellItem shell32 352 +imp 'SHCreateStdEnumFmtEtc' SHCreateStdEnumFmtEtc shell32 74 +imp 'SHDefExtractIcon' SHDefExtractIconW shell32 6 +imp 'SHDestroyPropSheetExtArray' SHDestroyPropSheetExtArray shell32 169 +imp 'SHDoDragDrop' SHDoDragDrop shell32 88 +imp 'SHEmptyRecycleBin' SHEmptyRecycleBinW shell32 487 +imp 'SHEnableServiceObject' SHEnableServiceObject shell32 488 +imp 'SHEnumerateUnreadMailAccounts' SHEnumerateUnreadMailAccountsW shell32 489 +imp 'SHEvaluateSystemCommandTemplate' SHEvaluateSystemCommandTemplate shell32 490 +imp 'SHExtractIcons' SHExtractIconsW shell32 491 +imp 'SHFileOperation' SHFileOperationW shell32 494 +imp 'SHFindFiles' SHFindFiles shell32 90 +imp 'SHFind_InitMenuPopup' SHFind_InitMenuPopup shell32 149 +imp 'SHFlushSFCache' SHFlushSFCache shell32 526 +imp 'SHFormatDrive' SHFormatDrive shell32 495 +imp 'SHFree' SHFree shell32 195 +imp 'SHFreeNameMappings' SHFreeNameMappings shell32 496 +imp 'SHGetAttributesFromDataObject' SHGetAttributesFromDataObject shell32 750 +imp 'SHGetDataFromIDList' SHGetDataFromIDListW shell32 498 +imp 'SHGetDesktopFolder' SHGetDesktopFolder shell32 499 +imp 'SHGetDiskFreeSpaceEx' SHGetDiskFreeSpaceExW shell32 502 +imp 'SHGetDriveMedia' SHGetDriveMedia shell32 503 +imp 'SHGetFileInfo' SHGetFileInfoW shell32 506 +imp 'SHGetFolderLocation' SHGetFolderLocation shell32 507 +imp 'SHGetFolderPath' SHGetFolderPathW shell32 512 +imp 'SHGetFolderPathAndSubDir' SHGetFolderPathAndSubDirW shell32 510 +imp 'SHGetFolderPathEx' SHGetFolderPathEx shell32 511 +imp 'SHGetIDListFromObject' SHGetIDListFromObject shell32 513 +imp 'SHGetIconOverlayIndex' SHGetIconOverlayIndexW shell32 515 +imp 'SHGetImageList' SHGetImageList shell32 727 +imp 'SHGetInstanceExplorer' SHGetInstanceExplorer shell32 516 +imp 'SHGetItemFromDataObject' SHGetItemFromDataObject shell32 517 +imp 'SHGetItemFromObject' SHGetItemFromObject shell32 518 +imp 'SHGetKnownFolderIDList' SHGetKnownFolderIDList shell32 519 +imp 'SHGetKnownFolderItem' SHGetKnownFolderItem shell32 527 +imp 'SHGetKnownFolderPath' SHGetKnownFolderPath shell32 528 +imp 'SHGetLocalizedName' SHGetLocalizedName shell32 529 +imp 'SHGetMalloc' SHGetMalloc shell32 530 +imp 'SHGetNameFromIDList' SHGetNameFromIDList shell32 531 +imp 'SHGetNewLinkInfo' SHGetNewLinkInfoW shell32 180 +imp 'SHGetPathFromIDList' SHGetPathFromIDListW shell32 536 +imp 'SHGetPathFromIDListEx' SHGetPathFromIDListEx shell32 535 +imp 'SHGetPropertyStoreForWindow' SHGetPropertyStoreForWindow shell32 537 +imp 'SHGetPropertyStoreFromIDList' SHGetPropertyStoreFromIDList shell32 538 +imp 'SHGetPropertyStoreFromParsingName' SHGetPropertyStoreFromParsingName shell32 539 +imp 'SHGetRealIDL' SHGetRealIDL shell32 98 +imp 'SHGetSetFolderCustomSettings' SHGetSetFolderCustomSettings shell32 709 +imp 'SHGetSetSettings' SHGetSetSettings shell32 68 +imp 'SHGetSettings' SHGetSettings shell32 540 +imp 'SHGetSpecialFolderLocation' SHGetSpecialFolderLocation shell32 541 +imp 'SHGetSpecialFolderPath' SHGetSpecialFolderPathW shell32 543 +imp 'SHGetStockIconInfo' SHGetStockIconInfo shell32 544 +imp 'SHGetTemporaryPropertyForItem' SHGetTemporaryPropertyForItem shell32 545 +imp 'SHGetUnreadMailCount' SHGetUnreadMailCountW shell32 546 +imp 'SHHandleUpdateImage' SHHandleUpdateImage shell32 193 +imp 'SHHelpShortcuts_RunDLL' SHHelpShortcuts_RunDLL shell32 228 +imp 'SHHelpShortcuts_RunDLLW' SHHelpShortcuts_RunDLLW shell32 238 +imp 'SHILCreateFromPath' SHILCreateFromPath shell32 28 +imp 'SHInvokePrinterCommand' SHInvokePrinterCommandW shell32 548 +imp 'SHIsFileAvailableOffline' SHIsFileAvailableOffline shell32 549 +imp 'SHLimitInputEdit' SHLimitInputEdit shell32 747 +imp 'SHLoadInProc' SHLoadInProc shell32 550 +imp 'SHLoadNonloadedIconOverlayIdentifiers' SHLoadNonloadedIconOverlayIdentifiers shell32 551 +imp 'SHMapPIDLToSystemImageListIndex' SHMapPIDLToSystemImageListIndex shell32 77 +imp 'SHMultiFileProperties' SHMultiFileProperties shell32 716 +imp 'SHObjectProperties' SHObjectProperties shell32 178 +imp 'SHOpenFolderAndSelectItems' SHOpenFolderAndSelectItems shell32 552 +imp 'SHOpenPropSheet' SHOpenPropSheetW shell32 80 +imp 'SHOpenWithDialog' SHOpenWithDialog shell32 553 +imp 'SHParseDisplayName' SHParseDisplayName shell32 554 +imp 'SHPathPrepareForWrite' SHPathPrepareForWriteW shell32 556 +imp 'SHPropStgCreate' SHPropStgCreate shell32 685 +imp 'SHPropStgReadMultiple' SHPropStgReadMultiple shell32 688 +imp 'SHPropStgWriteMultiple' SHPropStgWriteMultiple shell32 689 +imp 'SHQueryRecycleBin' SHQueryRecycleBinW shell32 558 +imp 'SHQueryUserNotificationState' SHQueryUserNotificationState shell32 559 +imp 'SHRemoveLocalizedName' SHRemoveLocalizedName shell32 560 +imp 'SHReplaceFromPropSheetExtArray' SHReplaceFromPropSheetExtArray shell32 170 +imp 'SHResolveLibrary' SHResolveLibrary shell32 561 +imp 'SHRestricted' SHRestricted shell32 100 +imp 'SHSetDefaultProperties' SHSetDefaultProperties shell32 562 +imp 'SHSetFolderPath' SHSetFolderPathW shell32 232 +imp 'SHSetInstanceExplorer' SHSetInstanceExplorer shell32 176 +imp 'SHSetKnownFolderPath' SHSetKnownFolderPath shell32 563 +imp 'SHSetLocalizedName' SHSetLocalizedName shell32 564 +imp 'SHSetTemporaryPropertyForItem' SHSetTemporaryPropertyForItem shell32 565 +imp 'SHSetUnreadMailCount' SHSetUnreadMailCountW shell32 566 +imp 'SHShellFolderView_Message' SHShellFolderView_Message shell32 73 +imp 'SHShowManageLibraryUI' SHShowManageLibraryUI shell32 567 +imp 'SHSimpleIDListFromPath' SHSimpleIDListFromPath shell32 162 +imp 'SHStartNetConnectionDialog' SHStartNetConnectionDialogW shell32 14 +imp 'SHTestTokenMembership' SHTestTokenMembership shell32 245 +imp 'SHUpdateImage' SHUpdateImageW shell32 192 +imp 'SHUpdateRecycleBinIcon' SHUpdateRecycleBinIcon shell32 568 +imp 'SHValidateUNC' SHValidateUNC shell32 173 +imp 'SetCurrentProcessExplicitAppUserModelID' SetCurrentProcessExplicitAppUserModelID shell32 569 +imp 'SheChangeDirEx' SheChangeDirExW shell32 571 +imp 'SheSetCurDrive' SheSetCurDrive shell32 573 +imp 'ShellAbout' ShellAboutW shell32 575 +imp 'ShellExec_RunDLL' ShellExec_RunDLL shell32 576 +imp 'ShellExec_RunDLLW' ShellExec_RunDLLW shell32 578 +imp 'ShellExecute' ShellExecuteW shell32 583 +imp 'ShellExecuteEx' ShellExecuteExW shell32 582 +imp 'ShellHookProc' ShellHookProc shell32 584 +imp 'Shell_GetCachedImageIndex' Shell_GetCachedImageIndexW shell32 586 +imp 'Shell_GetImageLists' Shell_GetImageLists shell32 71 +imp 'Shell_MergeMenus' Shell_MergeMenus shell32 67 +imp 'Shell_NotifyIcon' Shell_NotifyIconW shell32 590 +imp 'Shell_NotifyIconGetRect' Shell_NotifyIconGetRect shell32 589 +imp 'SignalFileOpen' SignalFileOpen shell32 103 +imp 'StgMakeUniqueName' StgMakeUniqueName shell32 682 +imp 'UsersLibrariesFolderUI_CreateInstance' UsersLibrariesFolderUI_CreateInstance shell32 615 +imp 'WOWShellExecute' WOWShellExecute shell32 616 +imp 'WaitForExplorerRestart' WaitForExplorerRestartW shell32 617 +imp 'Win32DeleteFile' Win32DeleteFile shell32 164 +imp 'WriteCabinetState' WriteCabinetState shell32 652 + +# NTDLL.DLL +# BEYOND THE PALE +# +# “The functions and structures in [for these APIs] are internal to +# the operating system and subject to change from one release of +# Windows to the next, and possibly even between service packs for +# each release.” ──Quoth MSDN */ +# +# Name Actual DLL Hint Arity +imp 'AlpcAdjustCompletionListConcurrencyCount' AlpcAdjustCompletionListConcurrencyCount ntdll 12 +imp 'AlpcFreeCompletionListMessage' AlpcFreeCompletionListMessage ntdll 13 +imp 'AlpcGetCompletionListLastMessageInformation' AlpcGetCompletionListLastMessageInformation ntdll 14 +imp 'AlpcGetCompletionListMessageAttributes' AlpcGetCompletionListMessageAttributes ntdll 15 +imp 'AlpcGetHeaderSize' AlpcGetHeaderSize ntdll 16 +imp 'AlpcGetMessageAttribute' AlpcGetMessageAttribute ntdll 17 +imp 'AlpcGetMessageFromCompletionList' AlpcGetMessageFromCompletionList ntdll 18 +imp 'AlpcGetOutstandingCompletionListMessageCount' AlpcGetOutstandingCompletionListMessageCount ntdll 19 +imp 'AlpcInitializeMessageAttribute' AlpcInitializeMessageAttribute ntdll 20 +imp 'AlpcMaxAllowedMessageLength' AlpcMaxAllowedMessageLength ntdll 21 +imp 'AlpcRegisterCompletionList' AlpcRegisterCompletionList ntdll 22 +imp 'AlpcRegisterCompletionListWorkerThread' AlpcRegisterCompletionListWorkerThread ntdll 23 +imp 'AlpcRundownCompletionList' AlpcRundownCompletionList ntdll 24 +imp 'AlpcUnregisterCompletionList' AlpcUnregisterCompletionList ntdll 25 +imp 'AlpcUnregisterCompletionListWorkerThread' AlpcUnregisterCompletionListWorkerThread ntdll 26 +imp 'ApiSetQueryApiSetPresence' ApiSetQueryApiSetPresence ntdll 27 +imp 'CsrAllocateCaptureBuffer' CsrAllocateCaptureBuffer ntdll 28 +imp 'CsrAllocateMessagePointer' CsrAllocateMessagePointer ntdll 29 +imp 'CsrCaptureMessageBuffer' CsrCaptureMessageBuffer ntdll 30 +imp 'CsrCaptureMessageMultiUnicodeStringsInPlace' CsrCaptureMessageMultiUnicodeStringsInPlace ntdll 31 +imp 'CsrCaptureMessageString' CsrCaptureMessageString ntdll 32 +imp 'CsrCaptureTimeout' CsrCaptureTimeout ntdll 33 +imp 'CsrClientCallServer' CsrClientCallServer ntdll 34 4 +imp 'CsrClientConnectToServer' CsrClientConnectToServer ntdll 35 +imp 'CsrFreeCaptureBuffer' CsrFreeCaptureBuffer ntdll 36 +imp 'CsrGetProcessId' CsrGetProcessId ntdll 37 +imp 'CsrIdentifyAlertableThread' CsrIdentifyAlertableThread ntdll 38 +imp 'CsrSetPriorityClass' CsrSetPriorityClass ntdll 39 +imp 'CsrVerifyRegion' CsrVerifyRegion ntdll 40 +imp 'DbgBreakPoint' DbgBreakPoint ntdll 41 +imp 'DbgPrint' DbgPrint ntdll 42 +imp 'DbgPrintEx' DbgPrintEx ntdll 43 +imp 'DbgPrintReturnControlC' DbgPrintReturnControlC ntdll 44 +imp 'DbgPrompt' DbgPrompt ntdll 45 +imp 'DbgQueryDebugFilterState' DbgQueryDebugFilterState ntdll 46 +imp 'DbgSetDebugFilterState' DbgSetDebugFilterState ntdll 47 +imp 'DbgUiConnectToDbg' DbgUiConnectToDbg ntdll 48 +imp 'DbgUiContinue' DbgUiContinue ntdll 49 +imp 'DbgUiConvertStateChangeStructure' DbgUiConvertStateChangeStructure ntdll 50 +imp 'DbgUiConvertStateChangeStructureEx' DbgUiConvertStateChangeStructureEx ntdll 51 +imp 'DbgUiDebugActiveProcess' DbgUiDebugActiveProcess ntdll 52 +imp 'DbgUiGetThreadDebugObject' DbgUiGetThreadDebugObject ntdll 53 +imp 'DbgUiIssueRemoteBreakin' DbgUiIssueRemoteBreakin ntdll 54 +imp 'DbgUiRemoteBreakin' DbgUiRemoteBreakin ntdll 55 +imp 'DbgUiSetThreadDebugObject' DbgUiSetThreadDebugObject ntdll 56 +imp 'DbgUiStopDebugging' DbgUiStopDebugging ntdll 57 +imp 'DbgUiWaitStateChange' DbgUiWaitStateChange ntdll 58 +imp 'DbgUserBreakPoint' DbgUserBreakPoint ntdll 59 +imp 'EtwCheckCoverage' EtwCheckCoverage ntdll 60 +imp 'EtwCreateTraceInstanceId' EtwCreateTraceInstanceId ntdll 61 +imp 'EtwDeliverDataBlock' EtwDeliverDataBlock ntdll 62 +imp 'EtwEnumerateProcessRegGuids' EtwEnumerateProcessRegGuids ntdll 63 +imp 'EtwEventActivityIdControl' EtwEventActivityIdControl ntdll 64 +imp 'EtwEventEnabled' EtwEventEnabled ntdll 65 +imp 'EtwEventProviderEnabled' EtwEventProviderEnabled ntdll 66 +imp 'EtwEventRegister' EtwEventRegister ntdll 67 +imp 'EtwEventSetInformation' EtwEventSetInformation ntdll 68 +imp 'EtwEventUnregister' EtwEventUnregister ntdll 69 +imp 'EtwEventWrite' EtwEventWrite ntdll 70 +imp 'EtwEventWriteEndScenario' EtwEventWriteEndScenario ntdll 71 +imp 'EtwEventWriteEx' EtwEventWriteEx ntdll 72 +imp 'EtwEventWriteFull' EtwEventWriteFull ntdll 73 +imp 'EtwEventWriteNoRegistration' EtwEventWriteNoRegistration ntdll 74 +imp 'EtwEventWriteStartScenario' EtwEventWriteStartScenario ntdll 75 +imp 'EtwEventWriteString' EtwEventWriteString ntdll 76 +imp 'EtwEventWriteTransfer' EtwEventWriteTransfer ntdll 77 +imp 'EtwGetTraceEnableFlags' EtwGetTraceEnableFlags ntdll 78 +imp 'EtwGetTraceEnableLevel' EtwGetTraceEnableLevel ntdll 79 +imp 'EtwGetTraceLoggerHandle' EtwGetTraceLoggerHandle ntdll 80 +imp 'EtwLogTraceEvent' EtwLogTraceEvent ntdll 81 +imp 'EtwNotificationRegister' EtwNotificationRegister ntdll 82 +imp 'EtwNotificationUnregister' EtwNotificationUnregister ntdll 83 +imp 'EtwProcessPrivateLoggerRequest' EtwProcessPrivateLoggerRequest ntdll 84 +imp 'EtwRegisterSecurityProvider' EtwRegisterSecurityProvider ntdll 85 +imp 'EtwRegisterTraceGuids' EtwRegisterTraceGuidsW ntdll 87 +imp 'EtwReplyNotification' EtwReplyNotification ntdll 88 +imp 'EtwSendNotification' EtwSendNotification ntdll 89 +imp 'EtwSetMark' EtwSetMark ntdll 90 +imp 'EtwTraceEventInstance' EtwTraceEventInstance ntdll 91 +imp 'EtwTraceMessage' EtwTraceMessage ntdll 92 +imp 'EtwTraceMessageVa' EtwTraceMessageVa ntdll 93 +imp 'EtwUnregisterTraceGuids' EtwUnregisterTraceGuids ntdll 94 +imp 'EtwWriteUMSecurityEvent' EtwWriteUMSecurityEvent ntdll 95 +imp 'EtwpCreateEtwThread' EtwpCreateEtwThread ntdll 96 +imp 'EtwpGetCpuSpeed' EtwpGetCpuSpeed ntdll 97 +imp 'EvtIntReportAuthzEventAndSourceAsync' EvtIntReportAuthzEventAndSourceAsync ntdll 98 +imp 'EvtIntReportEventAndSourceAsync' EvtIntReportEventAndSourceAsync ntdll 99 +imp 'ExpInterlockedPopEntrySListEnd' ExpInterlockedPopEntrySListEnd ntdll 100 +imp 'ExpInterlockedPopEntrySListFault' ExpInterlockedPopEntrySListFault ntdll 101 +imp 'ExpInterlockedPopEntrySListResume' ExpInterlockedPopEntrySListResume ntdll 102 imp 'KiRaiseUserExceptionDispatcher' KiRaiseUserExceptionDispatcher ntdll 103 imp 'KiUserApcDispatcher' KiUserApcDispatcher ntdll 104 imp 'KiUserCallbackDispatcher' KiUserCallbackDispatcher ntdll 105 imp 'KiUserExceptionDispatcher' KiUserExceptionDispatcher ntdll 106 imp 'KiUserInvertedFunctionTable' KiUserInvertedFunctionTable ntdll 107 -imp 'KillTimer' KillTimer user32 2093 2 -imp 'LCIDToLocaleName' LCIDToLocaleName kernel32 0 # KernelBase -imp 'LCMapStringA' LCMapStringA kernel32 0 # KernelBase -imp 'LCMapStringEx' LCMapStringEx kernel32 0 # KernelBase -imp 'LCMapString' LCMapStringW kernel32 0 # KernelBase -imp 'LPtoDP' LPtoDP gdi32 1741 -imp 'LZClose' LZClose kernel32 945 -imp 'LZCloseFile' LZCloseFile kernel32 946 -imp 'LZCopy' LZCopy kernel32 947 -imp 'LZCreateFile' LZCreateFileW kernel32 948 -imp 'LZDone' LZDone kernel32 949 -imp 'LZInit' LZInit kernel32 950 -imp 'LZOpenFileA' LZOpenFileA kernel32 951 -imp 'LZOpenFile' LZOpenFileW kernel32 952 -imp 'LZRead' LZRead kernel32 953 -imp 'LZSeek' LZSeek kernel32 954 -imp 'LZStart' LZStart kernel32 955 -imp 'LaunchMSHelp_RunDLLW' LaunchMSHelp_RunDLLW shell32 309 imp 'LdrAccessResource' LdrAccessResource ntdll 108 imp 'LdrAddDllDirectory' LdrAddDllDirectory ntdll 109 imp 'LdrAddLoadAsDataTable' LdrAddLoadAsDataTable ntdll 110 @@ -3178,353 +4708,12 @@ imp 'LdrVerifyImageMatchesChecksum' LdrVerifyImageMatchesChecksum ntdll 1 imp 'LdrVerifyImageMatchesChecksumEx' LdrVerifyImageMatchesChecksumEx ntdll 185 imp 'LdrpResGetMappingSize' LdrpResGetMappingSize ntdll 186 imp 'LdrpResGetResourceDirectory' LdrpResGetResourceDirectory ntdll 187 -imp 'LeaveCriticalPolicySectionInternal' LeaveCriticalPolicySectionInternal KernelBase 968 -imp 'LineDDA' LineDDA gdi32 1742 -imp 'LineTo' LineTo gdi32 1743 -imp 'LoadAcceleratorsA' LoadAcceleratorsA user32 2094 -imp 'LoadAccelerators' LoadAcceleratorsW user32 2095 -imp 'LoadAlterBitmap' LoadAlterBitmap comdlg32 117 -imp 'LoadAppInitDlls' LoadAppInitDlls KernelBase 971 -imp 'LoadBitmapA' LoadBitmapA user32 2096 -imp 'LoadBitmap' LoadBitmapW user32 2097 -imp 'LoadCursorA' LoadCursorA user32 2098 2 -imp 'LoadCursorFromFileA' LoadCursorFromFileA user32 2099 -imp 'LoadCursorFromFile' LoadCursorFromFileW user32 2100 -imp 'LoadCursor' LoadCursorW user32 2101 2 -imp 'LoadEnclaveData' LoadEnclaveData KernelBase 972 -imp 'LoadEnclaveImageA' LoadEnclaveImageA KernelBase 973 -imp 'LoadEnclaveImage' LoadEnclaveImageW KernelBase 974 -imp 'LoadIcon' LoadIconW user32 2103 2 -imp 'LoadIconA' LoadIconA user32 2102 2 -imp 'LoadImageA' LoadImageA user32 2104 6 -imp 'LoadImage' LoadImageW user32 2105 6 -imp 'LoadKeyboardLayoutA' LoadKeyboardLayoutA user32 2106 -imp 'LoadKeyboardLayoutEx' LoadKeyboardLayoutEx user32 2107 -imp 'LoadKeyboardLayout' LoadKeyboardLayoutW user32 2108 -imp 'LoadLibrary' LoadLibraryW kernel32 0 1 # KernelBase -imp 'LoadLibraryA' LoadLibraryA kernel32 0 1 # KernelBase -imp 'LoadLibraryExA' LoadLibraryExA kernel32 0 3 # KernelBase -imp 'LoadLibraryEx' LoadLibraryExW kernel32 0 3 # KernelBase -imp 'LoadLocalFonts' LoadLocalFonts user32 2109 -imp 'LoadMenuA' LoadMenuA user32 2110 -imp 'LoadMenuIndirectA' LoadMenuIndirectA user32 2111 -imp 'LoadMenuIndirect' LoadMenuIndirectW user32 2112 -imp 'LoadMenu' LoadMenuW user32 2113 -imp 'LoadModule' LoadModule kernel32 964 -imp 'LoadPackagedLibrary' LoadPackagedLibrary kernel32 0 # KernelBase -imp 'LoadRemoteFonts' LoadRemoteFonts user32 2114 -imp 'LoadResource' LoadResource kernel32 0 2 # KernelBase -imp 'LoadStringA' LoadStringA KernelBase 981 -imp 'LoadStringBaseEx' LoadStringBaseExW KernelBase 982 -imp 'LoadStringBase' LoadStringBaseW kernel32 968 -imp 'LoadStringByReference' LoadStringByReference KernelBase 983 -imp 'LoadString' LoadStringW KernelBase 984 -imp 'LocalAlloc' LocalAlloc kernel32 0 # KernelBase -imp 'LocalCompact' LocalCompact kernel32 970 -imp 'LocalFileTimeToFileTime' LocalFileTimeToFileTime kernel32 0 # KernelBase -imp 'LocalFlags' LocalFlags kernel32 972 -imp 'LocalFree' LocalFree kernel32 0 1 # KernelBase -imp 'LocalHandle' LocalHandle kernel32 974 -imp 'LocalLock' LocalLock kernel32 0 # KernelBase -imp 'LocalReAlloc' LocalReAlloc kernel32 0 # KernelBase -imp 'LocalShrink' LocalShrink kernel32 977 -imp 'LocalSize' LocalSize kernel32 978 -imp 'LocalUnlock' LocalUnlock kernel32 0 # KernelBase -imp 'LocaleNameToLCID' LocaleNameToLCID kernel32 0 # KernelBase -imp 'LocateXStateFeature' LocateXStateFeature kernel32 0 # KernelBase -imp 'LockFile' LockFile kernel32 0 5 # KernelBase -imp 'LockFileEx' LockFileEx kernel32 0 6 # KernelBase -imp 'LockResource' LockResource kernel32 0 1 # KernelBase -imp 'LockServiceDatabase' LockServiceDatabase advapi32 1417 -imp 'LockSetForegroundWindow' LockSetForegroundWindow user32 2117 -imp 'LockWindowStation' LockWindowStation user32 2118 -imp 'LockWindowUpdate' LockWindowUpdate user32 2119 -imp 'LockWorkStation' LockWorkStation user32 2120 -imp 'LogicalToPhysicalPoint' LogicalToPhysicalPoint user32 2121 -imp 'LogicalToPhysicalPointForPerMonitorDPI' LogicalToPhysicalPointForPerMonitorDPI user32 2122 -imp 'LogonUserA' LogonUserA advapi32 1418 -imp 'LogonUserExA' LogonUserExA advapi32 1419 -imp 'LogonUserExEx' LogonUserExExW advapi32 1420 -imp 'LogonUserEx' LogonUserExW advapi32 1421 -imp 'LogonUser' LogonUserW advapi32 1422 -imp 'LookupAccountNameA' LookupAccountNameA advapi32 1423 -imp 'LookupAccountName' LookupAccountNameW advapi32 1424 -imp 'LookupAccountSidA' LookupAccountSidA advapi32 1425 -imp 'LookupAccountSid' LookupAccountSidW advapi32 1426 -imp 'LookupIconIdFromDirectory' LookupIconIdFromDirectory user32 2123 -imp 'LookupIconIdFromDirectoryEx' LookupIconIdFromDirectoryEx user32 2124 -imp 'LookupPrivilegeDisplayNameA' LookupPrivilegeDisplayNameA advapi32 1427 -imp 'LookupPrivilegeDisplayName' LookupPrivilegeDisplayNameW advapi32 1428 -imp 'LookupPrivilegeNameA' LookupPrivilegeNameA advapi32 1429 -imp 'LookupPrivilegeName' LookupPrivilegeNameW advapi32 1430 -imp 'LookupPrivilegeValue' LookupPrivilegeValueW advapi32 1432 3 -imp 'LookupPrivilegeValueA' LookupPrivilegeValueA advapi32 1431 3 -imp 'LookupSecurityDescriptorPartsA' LookupSecurityDescriptorPartsA advapi32 1433 -imp 'LookupSecurityDescriptorParts' LookupSecurityDescriptorPartsW advapi32 1434 -imp 'LpkEditControl' LpkEditControl gdi32 1745 -imp 'LpkGetEditControl' LpkGetEditControl gdi32 1748 -imp 'LpkpEditControlSize' LpkpEditControlSize gdi32 1755 -imp 'LpkpInitializeEditControl' LpkpInitializeEditControl gdi32 1756 -imp 'LsaAddAccountRights' LsaAddAccountRights advapi32 1435 -imp 'LsaAddPrivilegesToAccount' LsaAddPrivilegesToAccount advapi32 1436 -imp 'LsaClearAuditLog' LsaClearAuditLog advapi32 1437 -imp 'LsaClose' LsaClose advapi32 1438 -imp 'LsaCreateAccount' LsaCreateAccount advapi32 1439 -imp 'LsaCreateSecret' LsaCreateSecret advapi32 1440 -imp 'LsaCreateTrustedDomain' LsaCreateTrustedDomain advapi32 1441 -imp 'LsaCreateTrustedDomainEx' LsaCreateTrustedDomainEx advapi32 1442 -imp 'LsaDelete' LsaDelete advapi32 1443 -imp 'LsaDeleteTrustedDomain' LsaDeleteTrustedDomain advapi32 1444 -imp 'LsaEnumerateAccountRights' LsaEnumerateAccountRights advapi32 1445 -imp 'LsaEnumerateAccounts' LsaEnumerateAccounts advapi32 1446 -imp 'LsaEnumerateAccountsWithUserRight' LsaEnumerateAccountsWithUserRight advapi32 1447 -imp 'LsaEnumeratePrivileges' LsaEnumeratePrivileges advapi32 1448 -imp 'LsaEnumeratePrivilegesOfAccount' LsaEnumeratePrivilegesOfAccount advapi32 1449 -imp 'LsaEnumerateTrustedDomains' LsaEnumerateTrustedDomains advapi32 1450 -imp 'LsaEnumerateTrustedDomainsEx' LsaEnumerateTrustedDomainsEx advapi32 1451 -imp 'LsaFreeMemory' LsaFreeMemory advapi32 1452 -imp 'LsaGetAppliedCAPIDs' LsaGetAppliedCAPIDs advapi32 1453 -imp 'LsaGetQuotasForAccount' LsaGetQuotasForAccount advapi32 1454 -imp 'LsaGetRemoteUserName' LsaGetRemoteUserName advapi32 1455 -imp 'LsaGetSystemAccessAccount' LsaGetSystemAccessAccount advapi32 1456 -imp 'LsaGetUserName' LsaGetUserName advapi32 1457 -imp 'LsaICLookupNames' LsaICLookupNames advapi32 1458 -imp 'LsaICLookupNamesWithCreds' LsaICLookupNamesWithCreds advapi32 1459 -imp 'LsaICLookupSids' LsaICLookupSids advapi32 1460 -imp 'LsaICLookupSidsWithCreds' LsaICLookupSidsWithCreds advapi32 1461 -imp 'LsaLookupNames' LsaLookupNames advapi32 1462 -imp 'LsaLookupNames2' LsaLookupNames2 advapi32 1463 -imp 'LsaLookupPrivilegeDisplayName' LsaLookupPrivilegeDisplayName advapi32 1464 -imp 'LsaLookupPrivilegeName' LsaLookupPrivilegeName advapi32 1465 -imp 'LsaLookupPrivilegeValue' LsaLookupPrivilegeValue advapi32 1466 -imp 'LsaLookupSids' LsaLookupSids advapi32 1467 -imp 'LsaLookupSids2' LsaLookupSids2 advapi32 1468 -imp 'LsaManageSidNameMapping' LsaManageSidNameMapping advapi32 1469 -imp 'LsaNtStatusToWinError' LsaNtStatusToWinError advapi32 1470 -imp 'LsaOpenAccount' LsaOpenAccount advapi32 1471 -imp 'LsaOpenPolicy' LsaOpenPolicy advapi32 1472 -imp 'LsaOpenPolicySce' LsaOpenPolicySce advapi32 1473 -imp 'LsaOpenSecret' LsaOpenSecret advapi32 1474 -imp 'LsaOpenTrustedDomain' LsaOpenTrustedDomain advapi32 1475 -imp 'LsaOpenTrustedDomainByName' LsaOpenTrustedDomainByName advapi32 1476 -imp 'LsaQueryCAPs' LsaQueryCAPs advapi32 1477 -imp 'LsaQueryDomainInformationPolicy' LsaQueryDomainInformationPolicy advapi32 1478 -imp 'LsaQueryForestTrustInformation' LsaQueryForestTrustInformation advapi32 1479 -imp 'LsaQueryInfoTrustedDomain' LsaQueryInfoTrustedDomain advapi32 1480 -imp 'LsaQueryInformationPolicy' LsaQueryInformationPolicy advapi32 1481 -imp 'LsaQuerySecret' LsaQuerySecret advapi32 1482 -imp 'LsaQuerySecurityObject' LsaQuerySecurityObject advapi32 1483 -imp 'LsaQueryTrustedDomainInfo' LsaQueryTrustedDomainInfo advapi32 1484 -imp 'LsaQueryTrustedDomainInfoByName' LsaQueryTrustedDomainInfoByName advapi32 1485 -imp 'LsaRemoveAccountRights' LsaRemoveAccountRights advapi32 1486 -imp 'LsaRemovePrivilegesFromAccount' LsaRemovePrivilegesFromAccount advapi32 1487 -imp 'LsaRetrievePrivateData' LsaRetrievePrivateData advapi32 1488 -imp 'LsaSetCAPs' LsaSetCAPs advapi32 1489 -imp 'LsaSetDomainInformationPolicy' LsaSetDomainInformationPolicy advapi32 1490 -imp 'LsaSetForestTrustInformation' LsaSetForestTrustInformation advapi32 1491 -imp 'LsaSetInformationPolicy' LsaSetInformationPolicy advapi32 1492 -imp 'LsaSetInformationTrustedDomain' LsaSetInformationTrustedDomain advapi32 1493 -imp 'LsaSetQuotasForAccount' LsaSetQuotasForAccount advapi32 1494 -imp 'LsaSetSecret' LsaSetSecret advapi32 1495 -imp 'LsaSetSecurityObject' LsaSetSecurityObject advapi32 1496 -imp 'LsaSetSystemAccessAccount' LsaSetSystemAccessAccount advapi32 1497 -imp 'LsaSetTrustedDomainInfoByName' LsaSetTrustedDomainInfoByName advapi32 1498 -imp 'LsaSetTrustedDomainInformation' LsaSetTrustedDomainInformation advapi32 1499 -imp 'LsaStorePrivateData' LsaStorePrivateData advapi32 1500 -imp 'MBToWCSEx' MBToWCSEx user32 2125 -imp 'MBToWCSExt' MBToWCSExt user32 2126 -imp 'MB_GetString' MB_GetString user32 2127 imp 'MD4Final' MD4Final ntdll 188 imp 'MD4Init' MD4Init ntdll 189 imp 'MD4Update' MD4Update ntdll 190 -imp 'MIDL_user_free_Ext' MIDL_user_free_Ext advapi32 1507 -imp 'MIMEAssociationDialogA' MIMEAssociationDialogA url 107 -imp 'MIMEAssociationDialog' MIMEAssociationDialogW url 108 -imp 'MITActivateInputProcessing' MITActivateInputProcessing user32 2128 -imp 'MITBindInputTypeToMonitors' MITBindInputTypeToMonitors user32 2129 -imp 'MITCoreMsgKGetConnectionHandle' MITCoreMsgKGetConnectionHandle user32 2130 -imp 'MITCoreMsgKOpenConnectionTo' MITCoreMsgKOpenConnectionTo user32 2131 -imp 'MITCoreMsgKSend' MITCoreMsgKSend user32 2132 -imp 'MITDeactivateInputProcessing' MITDeactivateInputProcessing user32 2133 -imp 'MITDisableMouseIntercept' MITDisableMouseIntercept user32 2134 -imp 'MITDispatchCompletion' MITDispatchCompletion user32 2135 -imp 'MITEnableMouseIntercept' MITEnableMouseIntercept user32 2136 -imp 'MITGetCursorUpdateHandle' MITGetCursorUpdateHandle user32 2137 -imp 'MITInjectLegacyISMTouchFrame' MITInjectLegacyISMTouchFrame user32 2138 -imp 'MITRegisterManipulationThread' MITRegisterManipulationThread user32 2139 -imp 'MITSetForegroundRoutingInfo' MITSetForegroundRoutingInfo user32 2140 -imp 'MITSetInputCallbacks' MITSetInputCallbacks user32 2141 -imp 'MITSetInputDelegationMode' MITSetInputDelegationMode user32 2142 -imp 'MITSetLastInputRecipient' MITSetLastInputRecipient user32 2143 -imp 'MITSetManipulationInputTarget' MITSetManipulationInputTarget user32 2144 -imp 'MITStopAndEndInertia' MITStopAndEndInertia user32 2145 -imp 'MITSynthesizeMouseInput' MITSynthesizeMouseInput user32 2146 -imp 'MITSynthesizeMouseWheel' MITSynthesizeMouseWheel user32 2147 -imp 'MITSynthesizeTouchInput' MITSynthesizeTouchInput user32 2148 -imp 'MITUpdateInputGlobals' MITUpdateInputGlobals user32 2149 -imp 'MITWaitForMultipleObjectsEx' MITWaitForMultipleObjectsEx user32 2150 -imp 'MSChapSrvChangePassword' MSChapSrvChangePassword advapi32 1508 -imp 'MSChapSrvChangePassword2' MSChapSrvChangePassword2 advapi32 1509 -imp 'MailToProtocolHandler' MailToProtocolHandler url 109 -imp 'MailToProtocolHandlerA' MailToProtocolHandlerA url 110 -imp 'MakeAbsoluteSD' MakeAbsoluteSD advapi32 0 # KernelBase -imp 'MakeAbsoluteSD2' MakeAbsoluteSD2 KernelBase 997 -imp 'MakeSelfRelativeSD' MakeSelfRelativeSD advapi32 0 # KernelBase -imp 'MakeThreadTSFEventAware' MakeThreadTSFEventAware user32 2151 -imp 'MapDialogRect' MapDialogRect user32 2152 -imp 'MapGenericMask' MapGenericMask advapi32 0 2 # KernelBase -imp 'MapPredefinedHandleInternal' MapPredefinedHandleInternal KernelBase 1000 -imp 'MapUserPhysicalPages' MapUserPhysicalPages kernel32 0 # KernelBase -imp 'MapUserPhysicalPagesScatter' MapUserPhysicalPagesScatter kernel32 986 -imp 'MapViewOfFile' MapViewOfFile kernel32 0 # KernelBase -imp 'MapViewOfFile3' MapViewOfFile3 KernelBase 1003 -imp 'MapViewOfFile3FromApp' MapViewOfFile3FromApp KernelBase 1004 -imp 'MapViewOfFileEx' MapViewOfFileEx kernel32 0 # KernelBase -imp 'MapViewOfFileExNuma' MapViewOfFileExNuma kernel32 0 7 # KernelBase -imp 'MapViewOfFileFromApp' MapViewOfFileFromApp kernel32 0 # KernelBase -imp 'MapViewOfFileNuma2' MapViewOfFileNuma2 KernelBase 1008 -imp 'MapVirtualKeyA' MapVirtualKeyA user32 2153 -imp 'MapVirtualKeyExA' MapVirtualKeyExA user32 2154 -imp 'MapVirtualKeyEx' MapVirtualKeyExW user32 2155 3 -imp 'MapVirtualKey' MapVirtualKeyW user32 2156 -imp 'MapVisualRelativePoints' MapVisualRelativePoints user32 2157 -imp 'MapWindowPoints' MapWindowPoints user32 2158 -imp 'MaskBlt' MaskBlt gdi32 1757 -imp 'MenuItemFromPoint' MenuItemFromPoint user32 2159 -imp 'MenuWindowProcA' MenuWindowProcA user32 2160 -imp 'MenuWindowProc' MenuWindowProcW user32 2161 -imp 'MessageBeep' MessageBeep user32 2162 -imp 'MessageBox' MessageBoxW user32 2170 4 -imp 'MessageBoxA' MessageBoxA user32 2163 4 -imp 'MessageBoxEx' MessageBoxExW user32 2165 5 -imp 'MessageBoxExA' MessageBoxExA user32 2164 5 -imp 'MessageBoxIndirectA' MessageBoxIndirectA user32 2166 -imp 'MessageBoxIndirect' MessageBoxIndirectW user32 2167 -imp 'MessageBoxTimeoutA' MessageBoxTimeoutA user32 2168 -imp 'MessageBoxTimeout' MessageBoxTimeoutW user32 2169 -imp 'MirrorRgn' MirrorRgn gdi32 1758 -imp 'ModerncoreGdiInit' ModerncoreGdiInit gdi32 1759 -imp 'ModifyMenuA' ModifyMenuA user32 2171 -imp 'ModifyMenu' ModifyMenuW user32 2172 -imp 'ModifyWorldTransform' ModifyWorldTransform gdi32 1760 -imp 'Module32First' Module32FirstW kernel32 992 -imp 'Module32Next' Module32NextW kernel32 994 -imp 'MonitorFromPoint' MonitorFromPoint user32 2173 -imp 'MonitorFromRect' MonitorFromRect user32 2174 -imp 'MonitorFromWindow' MonitorFromWindow user32 2175 -imp 'MoveFile' MoveFileW kernel32 1000 2 -imp 'MoveFileA' MoveFileA kernel32 995 2 -imp 'MoveFileEx' MoveFileExW kernel32 0 3 # KernelBase -imp 'MoveFileExA' MoveFileExA kernel32 996 3 -imp 'MoveFileTransactedA' MoveFileTransactedA kernel32 998 -imp 'MoveFileTransacted' MoveFileTransactedW kernel32 999 -imp 'MoveFileWithProgressA' MoveFileWithProgressA kernel32 1001 -imp 'MoveFileWithProgressTransacted' MoveFileWithProgressTransactedW KernelBase 1010 -imp 'MoveFileWithProgress' MoveFileWithProgressW kernel32 0 # KernelBase -imp 'MoveToEx' MoveToEx gdi32 1761 -imp 'MoveWindow' MoveWindow user32 2176 6 -imp 'MsgWaitForMultipleObjects' MsgWaitForMultipleObjects user32 2177 -imp 'MsgWaitForMultipleObjectsEx' MsgWaitForMultipleObjectsEx user32 2178 -imp 'MulDiv' MulDiv kernel32 0 # KernelBase -imp 'MultiByteToWideChar' MultiByteToWideChar kernel32 0 6 # KernelBase -imp 'NamedEscape' NamedEscape gdi32 1762 -imp 'NamedPipeEventEnum' NamedPipeEventEnum KernelBase 1014 -imp 'NamedPipeEventSelect' NamedPipeEventSelect KernelBase 1015 -imp 'NeedCurrentDirectoryForExePathA' NeedCurrentDirectoryForExePathA kernel32 0 # KernelBase -imp 'NeedCurrentDirectoryForExePath' NeedCurrentDirectoryForExePathW kernel32 0 # KernelBase -imp 'NetAccessAdd' NetAccessAdd netapi32 71 -imp 'NetAccessDel' NetAccessDel netapi32 72 -imp 'NetAccessEnum' NetAccessEnum netapi32 73 -imp 'NetAccessGetInfo' NetAccessGetInfo netapi32 74 -imp 'NetAccessGetUserPerms' NetAccessGetUserPerms netapi32 75 -imp 'NetAccessSetInfo' NetAccessSetInfo netapi32 76 -imp 'NetAlertRaise' NetAlertRaise netapi32 79 -imp 'NetAlertRaiseEx' NetAlertRaiseEx netapi32 80 -imp 'NetAuditClear' NetAuditClear netapi32 85 -imp 'NetAuditRead' NetAuditRead netapi32 86 -imp 'NetAuditWrite' NetAuditWrite netapi32 87 -imp 'NetConfigGet' NetConfigGet netapi32 88 -imp 'NetConfigGetAll' NetConfigGetAll netapi32 89 -imp 'NetConfigSet' NetConfigSet netapi32 90 -imp 'NetErrorLogClear' NetErrorLogClear netapi32 124 -imp 'NetErrorLogRead' NetErrorLogRead netapi32 125 -imp 'NetErrorLogWrite' NetErrorLogWrite netapi32 126 -imp 'NetMessageBufferSend' NetMessageBufferSend netapi32 161 -imp 'NetMessageNameAdd' NetMessageNameAdd netapi32 162 -imp 'NetMessageNameDel' NetMessageNameDel netapi32 163 -imp 'NetMessageNameEnum' NetMessageNameEnum netapi32 164 -imp 'NetMessageNameGetInfo' NetMessageNameGetInfo netapi32 165 -imp 'NetRegisterDomainNameChangeNotification' NetRegisterDomainNameChangeNotification netapi32 169 -imp 'NetReplExportDirAdd' NetReplExportDirAdd netapi32 175 -imp 'NetReplExportDirDel' NetReplExportDirDel netapi32 176 -imp 'NetReplExportDirEnum' NetReplExportDirEnum netapi32 177 -imp 'NetReplExportDirGetInfo' NetReplExportDirGetInfo netapi32 178 -imp 'NetReplExportDirLock' NetReplExportDirLock netapi32 179 -imp 'NetReplExportDirSetInfo' NetReplExportDirSetInfo netapi32 180 -imp 'NetReplExportDirUnlock' NetReplExportDirUnlock netapi32 181 -imp 'NetReplGetInfo' NetReplGetInfo netapi32 182 -imp 'NetReplImportDirAdd' NetReplImportDirAdd netapi32 183 -imp 'NetReplImportDirDel' NetReplImportDirDel netapi32 184 -imp 'NetReplImportDirEnum' NetReplImportDirEnum netapi32 185 -imp 'NetReplImportDirGetInfo' NetReplImportDirGetInfo netapi32 186 -imp 'NetReplImportDirLock' NetReplImportDirLock netapi32 187 -imp 'NetReplImportDirUnlock' NetReplImportDirUnlock netapi32 188 -imp 'NetReplSetInfo' NetReplSetInfo netapi32 189 -imp 'NetServerEnum' NetServerEnum netapi32 202 -imp 'NetServerEnumEx' NetServerEnumEx netapi32 203 -imp 'NetServiceControl' NetServiceControl netapi32 210 -imp 'NetServiceEnum' NetServiceEnum netapi32 211 -imp 'NetServiceGetInfo' NetServiceGetInfo netapi32 212 -imp 'NetServiceInstall' NetServiceInstall netapi32 213 -imp 'NetStatisticsGet' NetStatisticsGet netapi32 227 -imp 'NetUnregisterDomainNameChangeNotification' NetUnregisterDomainNameChangeNotification netapi32 229 -imp 'NetWkstaGetInfo' NetWkstaGetInfo netapi32 248 -imp 'NetWkstaSetInfo' NetWkstaSetInfo netapi32 249 -imp 'Netbios' Netbios netapi32 257 -imp 'NetpAddTlnFtinfoEntry' NetpAddTlnFtinfoEntry netapi32 258 -imp 'NetpAllocFtinfoEntry' NetpAllocFtinfoEntry netapi32 259 -imp 'NetpAssertFailed' NetpAssertFailed netapi32 260 -imp 'NetpCleanFtinfoContext' NetpCleanFtinfoContext netapi32 261 -imp 'NetpCloseConfigData' NetpCloseConfigData netapi32 262 -imp 'NetpCopyFtinfoContext' NetpCopyFtinfoContext netapi32 263 -imp 'NetpDbgPrint' NetpDbgPrint netapi32 264 -imp 'NetpGetConfigBool' NetpGetConfigBool netapi32 265 -imp 'NetpGetConfigDword' NetpGetConfigDword netapi32 266 -imp 'NetpGetConfigTStrArray' NetpGetConfigTStrArray netapi32 267 -imp 'NetpGetConfigValue' NetpGetConfigValue netapi32 268 -imp 'NetpGetFileSecurity' NetpGetFileSecurity netapi32 269 -imp 'NetpHexDump' NetpHexDump netapi32 270 -imp 'NetpInitFtinfoContext' NetpInitFtinfoContext netapi32 271 -imp 'NetpIsUncComputerNameValid' NetpIsUncComputerNameValid netapi32 273 -imp 'NetpMergeFtinfo' NetpMergeFtinfo netapi32 274 -imp 'NetpNetBiosReset' NetpNetBiosReset netapi32 275 -imp 'NetpNetBiosStatusToApiStatus' NetpNetBiosStatusToApiStatus netapi32 276 -imp 'NetpOpenConfigData' NetpOpenConfigData netapi32 277 -imp 'NetpSetFileSecurity' NetpSetFileSecurity netapi32 278 imp 'NlsAnsiCodePage' NlsAnsiCodePage ntdll 194 -imp 'NlsCheckPolicy' NlsCheckPolicy KernelBase 1018 -imp 'NlsDispatchAnsiEnumProc' NlsDispatchAnsiEnumProc KernelBase 1019 -imp 'NlsEventDataDescCreate' NlsEventDataDescCreate KernelBase 1020 -imp 'NlsGetACPFromLocale' NlsGetACPFromLocale KernelBase 1021 -imp 'NlsGetCacheUpdateCount' NlsGetCacheUpdateCount KernelBase 1022 -imp 'NlsIsUserDefaultLocale' NlsIsUserDefaultLocale KernelBase 1023 imp 'NlsMbCodePageTag' NlsMbCodePageTag ntdll 195 imp 'NlsMbOemCodePageTag' NlsMbOemCodePageTag ntdll 196 -imp 'NlsUpdateLocale' NlsUpdateLocale KernelBase 1024 -imp 'NlsUpdateSystemLocale' NlsUpdateSystemLocale KernelBase 1025 -imp 'NlsValidateLocale' NlsValidateLocale KernelBase 1026 -imp 'NlsWriteEtwEvent' NlsWriteEtwEvent KernelBase 1027 -imp 'NormalizeString' NormalizeString kernel32 0 # KernelBase -imp 'NotifyBootConfigStatus' NotifyBootConfigStatus advapi32 1514 -imp 'NotifyChangeEventLog' NotifyChangeEventLog advapi32 1515 -imp 'NotifyMountMgr' NotifyMountMgr KernelBase 1029 -imp 'NotifyOverlayWindow' NotifyOverlayWindow user32 2179 -imp 'NotifyRedirectedStringChange' NotifyRedirectedStringChange KernelBase 1030 -imp 'NotifyServiceStatusChangeA' NotifyServiceStatusChangeA advapi32 1517 -imp 'NotifyServiceStatusChange' NotifyServiceStatusChangeW advapi32 1518 -imp 'NotifyUILanguageChange' NotifyUILanguageChange kernel32 1015 -imp 'NotifyWinEvent' NotifyWinEvent user32 2180 -imp 'NpGetUserName' NpGetUserName advapi32 1519 imp 'NtAcceptConnectPort' NtAcceptConnectPort ntdll 197 imp 'NtAccessCheck' NtAccessCheck ntdll 198 imp 'NtAccessCheckAndAuditAlarm' NtAccessCheckAndAuditAlarm ntdll 199 @@ -3989,380 +5178,12 @@ imp 'NtWriteFileGather' NtWriteFileGather ntdll 656 imp 'NtWriteRequestData' NtWriteRequestData ntdll 657 imp 'NtWriteVirtualMemory' NtWriteVirtualMemory ntdll 658 5 imp 'NtYieldExecution' NtYieldExecution ntdll 659 0 -imp 'DefWindowProcA' DefWindowProcA user32 173 4 -imp 'DefWindowProc' DefWindowProcW user32 174 4 -imp 'NtdllDefWindowProc_A' NtdllDefWindowProc_A ntdll 660 imp 'NtdllDefWindowProc_W' NtdllDefWindowProc_W ntdll 661 -imp 'NtdllDialogWndProc_A' NtdllDialogWndProc_A ntdll 662 imp 'NtdllDialogWndProc_W' NtdllDialogWndProc_W ntdll 663 -imp 'OOBEComplete' OOBEComplete kernel32 1017 -imp 'ObjectCloseAuditAlarmA' ObjectCloseAuditAlarmA advapi32 1520 -imp 'ObjectCloseAuditAlarm' ObjectCloseAuditAlarmW advapi32 0 # KernelBase -imp 'ObjectDeleteAuditAlarmA' ObjectDeleteAuditAlarmA advapi32 1522 -imp 'ObjectDeleteAuditAlarm' ObjectDeleteAuditAlarmW advapi32 0 # KernelBase -imp 'ObjectOpenAuditAlarmA' ObjectOpenAuditAlarmA advapi32 1524 -imp 'ObjectOpenAuditAlarm' ObjectOpenAuditAlarmW advapi32 0 # KernelBase -imp 'ObjectPrivilegeAuditAlarmA' ObjectPrivilegeAuditAlarmA advapi32 1526 -imp 'ObjectPrivilegeAuditAlarm' ObjectPrivilegeAuditAlarmW advapi32 0 # KernelBase -imp 'OemKeyScan' OemKeyScan user32 2181 -imp 'OemToCharA' OemToCharA user32 2182 -imp 'OemToCharBuffA' OemToCharBuffA user32 2183 -imp 'OemToCharBuff' OemToCharBuffW user32 2184 -imp 'OemToChar' OemToCharW user32 2185 -imp 'OfferVirtualMemory' OfferVirtualMemory kernel32 0 3 # KernelBase -imp 'OffsetClipRgn' OffsetClipRgn gdi32 1763 -imp 'OffsetRect' OffsetRect user32 2186 -imp 'OffsetRgn' OffsetRgn gdi32 1764 -imp 'OffsetViewportOrgEx' OffsetViewportOrgEx gdi32 1765 -imp 'OffsetWindowOrgEx' OffsetWindowOrgEx gdi32 1766 -imp 'OpenAs_RunDLL' OpenAs_RunDLL shell32 81 -imp 'OpenAs_RunDLLA' OpenAs_RunDLLA shell32 125 -imp 'OpenAs_RunDLLW' OpenAs_RunDLLW shell32 133 -imp 'OpenBackupEventLogA' OpenBackupEventLogA advapi32 1528 -imp 'OpenBackupEventLog' OpenBackupEventLogW advapi32 1529 -imp 'OpenClipboard' OpenClipboard user32 2187 -imp 'OpenCommPort' OpenCommPort KernelBase 1036 -imp 'OpenConsole' OpenConsoleW kernel32 1019 -imp 'OpenConsoleWStub' OpenConsoleWStub kernel32 1020 -imp 'OpenDesktopA' OpenDesktopA user32 2188 -imp 'OpenDesktop' OpenDesktopW user32 2189 -imp 'OpenEncryptedFileRawA' OpenEncryptedFileRawA advapi32 1530 -imp 'OpenEncryptedFileRaw' OpenEncryptedFileRawW advapi32 1531 -imp 'OpenEventA' OpenEventA kernel32 0 # KernelBase -imp 'OpenEventLogA' OpenEventLogA advapi32 1532 -imp 'OpenEventLog' OpenEventLogW advapi32 1533 -imp 'OpenEvent' OpenEventW kernel32 0 # KernelBase -imp 'OpenFile' OpenFile kernel32 1023 -imp 'OpenFileById' OpenFileById kernel32 0 # KernelBase -imp 'OpenFileMappingA' OpenFileMappingA kernel32 1025 -imp 'OpenFileMappingFromApp' OpenFileMappingFromApp KernelBase 1040 -imp 'OpenFileMapping' OpenFileMappingW kernel32 0 # KernelBase -imp 'OpenGlobalizationUserSettingsKey' OpenGlobalizationUserSettingsKey KernelBase 1042 -imp 'OpenIcon' OpenIcon user32 2190 -imp 'OpenInputDesktop' OpenInputDesktop user32 2191 -imp 'OpenJobObjectA' OpenJobObjectA kernel32 1027 -imp 'OpenJobObject' OpenJobObjectW kernel32 1028 -imp 'OpenMutexA' OpenMutexA kernel32 1029 -imp 'OpenMutex' OpenMutexW kernel32 0 # KernelBase -imp 'OpenPackageInfoByFullName' OpenPackageInfoByFullName kernel32 0 # KernelBase -imp 'OpenPackageInfoByFullNameForUser' OpenPackageInfoByFullNameForUser KernelBase 1045 -imp 'OpenPrivateNamespaceA' OpenPrivateNamespaceA kernel32 1032 -imp 'OpenPrivateNamespace' OpenPrivateNamespaceW kernel32 0 # KernelBase -imp 'OpenProcess' OpenProcess kernel32 0 3 # KernelBase -imp 'OpenProcessToken' OpenProcessToken advapi32 0 3 # KernelBase -imp 'OpenProfileUserMapping' OpenProfileUserMapping kernel32 1036 -imp 'OpenRegKey' OpenRegKey KernelBase 1049 -imp 'OpenRegStream' OpenRegStream shell32 85 -imp 'OpenSCManagerA' OpenSCManagerA advapi32 1535 -imp 'OpenSCManager' OpenSCManagerW advapi32 1536 -imp 'OpenSemaphoreA' OpenSemaphoreA kernel32 1037 -imp 'OpenSemaphore' OpenSemaphoreW kernel32 0 # KernelBase -imp 'OpenServiceA' OpenServiceA advapi32 1537 -imp 'OpenService' OpenServiceW advapi32 1538 -imp 'OpenState' OpenState KernelBase 1051 -imp 'OpenStateAtom' OpenStateAtom KernelBase 1052 -imp 'OpenStateExplicit' OpenStateExplicit KernelBase 1053 -imp 'OpenStateExplicitForUserSid' OpenStateExplicitForUserSid KernelBase 1054 -imp 'OpenStateExplicitForUserSidString' OpenStateExplicitForUserSidString KernelBase 1055 -imp 'OpenThread' OpenThread kernel32 0 3 # KernelBase -imp 'OpenThreadDesktop' OpenThreadDesktop user32 2192 -imp 'OpenThreadToken' OpenThreadToken advapi32 0 4 # KernelBase -imp 'OpenThreadWaitChainSession' OpenThreadWaitChainSession advapi32 1540 -imp 'OpenTraceA' OpenTraceA advapi32 1541 -imp 'OpenTrace' OpenTraceW advapi32 1542 -imp 'OpenURL' OpenURL url 111 -imp 'OpenURLA' OpenURLA url 112 -imp 'OpenWaitableTimerA' OpenWaitableTimerA kernel32 1043 -imp 'OpenWaitableTimer' OpenWaitableTimerW kernel32 0 # KernelBase -imp 'OpenWindowStationA' OpenWindowStationA user32 2193 -imp 'OpenWindowStation' OpenWindowStationW user32 2194 -imp 'OperationEnd' OperationEnd advapi32 1543 -imp 'OperationStart' OperationStart advapi32 1544 -imp 'Options_RunDLL' Options_RunDLL shell32 310 -imp 'Options_RunDLLA' Options_RunDLLA shell32 311 -imp 'Options_RunDLLW' Options_RunDLLW shell32 312 -imp 'OutputDebugStringA' OutputDebugStringA kernel32 0 # KernelBase -imp 'OutputDebugString' OutputDebugStringW kernel32 0 # KernelBase -imp 'OverrideRoamingDataModificationTimesInRange' OverrideRoamingDataModificationTimesInRange KernelBase 1061 -imp 'PATHOBJ_bEnum' PATHOBJ_bEnum gdi32 1767 -imp 'PATHOBJ_bEnumClipLines' PATHOBJ_bEnumClipLines gdi32 1768 -imp 'PATHOBJ_vEnumStart' PATHOBJ_vEnumStart gdi32 1769 -imp 'PATHOBJ_vEnumStartClipLines' PATHOBJ_vEnumStartClipLines gdi32 1770 -imp 'PATHOBJ_vGetBounds' PATHOBJ_vGetBounds gdi32 1771 -imp 'PackDDElParam' PackDDElParam user32 2195 -imp 'PackTouchHitTestingProximityEvaluation' PackTouchHitTestingProximityEvaluation user32 2196 -imp 'PackageFamilyNameFromFullName' PackageFamilyNameFromFullName kernel32 0 # KernelBase -imp 'PackageFamilyNameFromFullNameA' PackageFamilyNameFromFullNameA KernelBase 1063 -imp 'PackageFamilyNameFromId' PackageFamilyNameFromId kernel32 0 # KernelBase -imp 'PackageFamilyNameFromIdA' PackageFamilyNameFromIdA KernelBase 1065 -imp 'PackageFamilyNameFromProductId' PackageFamilyNameFromProductId KernelBase 1066 -imp 'PackageFullNameFromId' PackageFullNameFromId kernel32 0 # KernelBase -imp 'PackageFullNameFromIdA' PackageFullNameFromIdA KernelBase 1068 -imp 'PackageFullNameFromProductId' PackageFullNameFromProductId KernelBase 1069 -imp 'PackageIdFromFullName' PackageIdFromFullName kernel32 0 # KernelBase -imp 'PackageIdFromFullNameA' PackageIdFromFullNameA KernelBase 1071 -imp 'PackageIdFromProductId' PackageIdFromProductId KernelBase 1072 -imp 'PackageNameAndPublisherIdFromFamilyName' PackageNameAndPublisherIdFromFamilyName kernel32 0 # KernelBase -imp 'PackageNameAndPublisherIdFromFamilyNameA' PackageNameAndPublisherIdFromFamilyNameA KernelBase 1074 -imp 'PackageRelativeApplicationIdFromProductId' PackageRelativeApplicationIdFromProductId KernelBase 1075 -imp 'PackageSidFromFamilyName' PackageSidFromFamilyName KernelBase 1076 -imp 'PackageSidFromProductId' PackageSidFromProductId KernelBase 1 -imp 'PageSetupDlgA' PageSetupDlgA comdlg32 118 -imp 'PageSetupDlg' PageSetupDlgW comdlg32 119 -imp 'PaintDesktop' PaintDesktop user32 2197 -imp 'PaintMenuBar' PaintMenuBar user32 2198 -imp 'PaintMonitor' PaintMonitor user32 2199 -imp 'PaintRgn' PaintRgn gdi32 1772 -imp 'ParseApplicationUserModelId' ParseApplicationUserModelId kernel32 0 # KernelBase -imp 'ParseApplicationUserModelIdA' ParseApplicationUserModelIdA KernelBase 1078 -imp 'ParseURLA' ParseURLA KernelBase 1079 -imp 'ParseURLW' ParseURLW KernelBase 1080 -imp 'PatBlt' PatBlt gdi32 1773 -imp 'PathAddBackslashA' PathAddBackslashA KernelBase 1081 -imp 'PathAddBackslash' PathAddBackslashW KernelBase 1082 -imp 'PathAddExtensionA' PathAddExtensionA KernelBase 1083 -imp 'PathAddExtension' PathAddExtensionW KernelBase 1084 -imp 'PathAllocCanonicalize' PathAllocCanonicalize KernelBase 1085 -imp 'PathAllocCombine' PathAllocCombine KernelBase 1086 -imp 'PathAppendA' PathAppendA KernelBase 1087 -imp 'PathAppend' PathAppendW KernelBase 1088 -imp 'PathCanonicalizeA' PathCanonicalizeA KernelBase 1089 -imp 'PathCanonicalize' PathCanonicalizeW KernelBase 1090 -imp 'PathCchAddBackslash' PathCchAddBackslash KernelBase 1091 -imp 'PathCchAddBackslashEx' PathCchAddBackslashEx KernelBase 1092 -imp 'PathCchAddExtension' PathCchAddExtension KernelBase 1093 -imp 'PathCchAppend' PathCchAppend KernelBase 1094 -imp 'PathCchAppendEx' PathCchAppendEx KernelBase 1095 -imp 'PathCchCanonicalize' PathCchCanonicalize KernelBase 1096 -imp 'PathCchCanonicalizeEx' PathCchCanonicalizeEx KernelBase 1097 -imp 'PathCchCombine' PathCchCombine KernelBase 1098 -imp 'PathCchCombineEx' PathCchCombineEx KernelBase 1099 -imp 'PathCchFindExtension' PathCchFindExtension KernelBase 1100 -imp 'PathCchIsRoot' PathCchIsRoot KernelBase 1101 -imp 'PathCchRemoveBackslash' PathCchRemoveBackslash KernelBase 1102 -imp 'PathCchRemoveBackslashEx' PathCchRemoveBackslashEx KernelBase 1103 -imp 'PathCchRemoveExtension' PathCchRemoveExtension KernelBase 1104 -imp 'PathCchRemoveFileSpec' PathCchRemoveFileSpec KernelBase 1105 -imp 'PathCchRenameExtension' PathCchRenameExtension KernelBase 1106 -imp 'PathCchSkipRoot' PathCchSkipRoot KernelBase 1107 -imp 'PathCchStripPrefix' PathCchStripPrefix KernelBase 1108 -imp 'PathCchStripToRoot' PathCchStripToRoot KernelBase 1109 -imp 'PathCleanupSpec' PathCleanupSpec shell32 171 -imp 'PathCombineA' PathCombineA KernelBase 1110 -imp 'PathCombine' PathCombineW KernelBase 1111 -imp 'PathCommonPrefixA' PathCommonPrefixA KernelBase 1112 -imp 'PathCommonPrefix' PathCommonPrefixW KernelBase 1113 -imp 'PathCreateFromUrlA' PathCreateFromUrlA KernelBase 1114 -imp 'PathCreateFromUrlAlloc' PathCreateFromUrlAlloc KernelBase 1115 -imp 'PathCreateFromUrl' PathCreateFromUrlW KernelBase 1116 -imp 'PathFileExistsA' PathFileExistsA KernelBase 1117 -imp 'PathFileExists' PathFileExistsW KernelBase 1118 -imp 'PathFindExtensionA' PathFindExtensionA KernelBase 1119 -imp 'PathFindExtension' PathFindExtensionW KernelBase 1120 -imp 'PathFindFileNameA' PathFindFileNameA KernelBase 1121 -imp 'PathFindFileName' PathFindFileNameW KernelBase 1122 -imp 'PathFindNextComponentA' PathFindNextComponentA KernelBase 1123 -imp 'PathFindNextComponent' PathFindNextComponentW KernelBase 1124 -imp 'PathGetArgsA' PathGetArgsA KernelBase 1125 -imp 'PathGetArgs' PathGetArgsW KernelBase 1126 -imp 'PathGetCharTypeA' PathGetCharTypeA KernelBase 1127 -imp 'PathGetCharType' PathGetCharTypeW KernelBase 1128 -imp 'PathGetDriveNumberA' PathGetDriveNumberA KernelBase 1129 -imp 'PathGetDriveNumber' PathGetDriveNumberW KernelBase 1130 -imp 'PathGetShortPath' PathGetShortPath shell32 92 -imp 'PathIsExe' PathIsExe shell32 43 -imp 'PathIsFileSpecA' PathIsFileSpecA KernelBase 1131 -imp 'PathIsFileSpec' PathIsFileSpecW KernelBase 1132 -imp 'PathIsLFNFileSpecA' PathIsLFNFileSpecA KernelBase 1133 -imp 'PathIsLFNFileSpec' PathIsLFNFileSpecW KernelBase 1134 -imp 'PathIsPrefixA' PathIsPrefixA KernelBase 1135 -imp 'PathIsPrefix' PathIsPrefixW KernelBase 1136 -imp 'PathIsRelativeA' PathIsRelativeA KernelBase 1137 -imp 'PathIsRelative' PathIsRelativeW KernelBase 1138 -imp 'PathIsRootA' PathIsRootA KernelBase 1139 -imp 'PathIsRoot' PathIsRootW KernelBase 1140 -imp 'PathIsSameRootA' PathIsSameRootA KernelBase 1141 -imp 'PathIsSameRoot' PathIsSameRootW KernelBase 1142 -imp 'PathIsSlowA' PathIsSlowA shell32 240 -imp 'PathIsSlow' PathIsSlowW shell32 239 -imp 'PathIsUNCA' PathIsUNCA KernelBase 1143 -imp 'PathIsUNCEx' PathIsUNCEx KernelBase 1144 -imp 'PathIsUNCServerA' PathIsUNCServerA KernelBase 1145 -imp 'PathIsUNCServerShareA' PathIsUNCServerShareA KernelBase 1146 -imp 'PathIsUNCServerShare' PathIsUNCServerShareW KernelBase 1147 -imp 'PathIsUNCServer' PathIsUNCServerW KernelBase 1148 -imp 'PathIsUNCW' PathIsUNCW KernelBase 1149 -imp 'PathIsURLA' PathIsURLA KernelBase 1150 -imp 'PathIsURLW' PathIsURLW KernelBase 1151 -imp 'PathIsValidCharA' PathIsValidCharA KernelBase 1152 -imp 'PathIsValidChar' PathIsValidCharW KernelBase 1153 -imp 'PathMakeUniqueName' PathMakeUniqueName shell32 47 -imp 'PathMatchSpecA' PathMatchSpecA KernelBase 1154 -imp 'PathMatchSpecExA' PathMatchSpecExA KernelBase 1155 -imp 'PathMatchSpecEx' PathMatchSpecExW KernelBase 1156 -imp 'PathMatchSpec' PathMatchSpecW KernelBase 1157 -imp 'PathParseIconLocationA' PathParseIconLocationA KernelBase 1158 -imp 'PathParseIconLocation' PathParseIconLocationW KernelBase 1159 -imp 'PathQualify' PathQualify shell32 49 -imp 'PathQuoteSpacesA' PathQuoteSpacesA KernelBase 1160 -imp 'PathQuoteSpaces' PathQuoteSpacesW KernelBase 1161 -imp 'PathRelativePathToA' PathRelativePathToA KernelBase 1162 -imp 'PathRelativePathTo' PathRelativePathToW KernelBase 1163 -imp 'PathRemoveBackslashA' PathRemoveBackslashA KernelBase 1164 -imp 'PathRemoveBackslash' PathRemoveBackslashW KernelBase 1165 -imp 'PathRemoveBlanksA' PathRemoveBlanksA KernelBase 1166 -imp 'PathRemoveBlanks' PathRemoveBlanksW KernelBase 1167 -imp 'PathRemoveExtensionA' PathRemoveExtensionA KernelBase 1168 -imp 'PathRemoveExtension' PathRemoveExtensionW KernelBase 1169 -imp 'PathRemoveFileSpecA' PathRemoveFileSpecA KernelBase 1170 -imp 'PathRemoveFileSpec' PathRemoveFileSpecW KernelBase 1171 -imp 'PathRenameExtensionA' PathRenameExtensionA KernelBase 1172 -imp 'PathRenameExtension' PathRenameExtensionW KernelBase 1173 -imp 'PathResolve' PathResolve shell32 51 -imp 'PathSearchAndQualifyA' PathSearchAndQualifyA KernelBase 1174 -imp 'PathSearchAndQualify' PathSearchAndQualifyW KernelBase 1175 -imp 'PathSkipRootA' PathSkipRootA KernelBase 1176 -imp 'PathSkipRoot' PathSkipRootW KernelBase 1177 -imp 'PathStripPathA' PathStripPathA KernelBase 1178 -imp 'PathStripPath' PathStripPathW KernelBase 1179 -imp 'PathStripToRootA' PathStripToRootA KernelBase 1180 -imp 'PathStripToRoot' PathStripToRootW KernelBase 1181 -imp 'PathToRegion' PathToRegion gdi32 1774 -imp 'PathUnExpandEnvStringsA' PathUnExpandEnvStringsA KernelBase 1182 -imp 'PathUnExpandEnvStrings' PathUnExpandEnvStringsW KernelBase 1183 -imp 'PathUnquoteSpacesA' PathUnquoteSpacesA KernelBase 1184 -imp 'PathUnquoteSpaces' PathUnquoteSpacesW KernelBase 1185 -imp 'PathYetAnotherMakeUniqueName' PathYetAnotherMakeUniqueName shell32 75 -imp 'PcwAddQueryItem' PcwAddQueryItem KernelBase 1186 -imp 'PcwClearCounterSetSecurity' PcwClearCounterSetSecurity KernelBase 1187 -imp 'PcwCollectData' PcwCollectData KernelBase 1188 -imp 'PcwCompleteNotification' PcwCompleteNotification KernelBase 1189 -imp 'PcwCreateNotifier' PcwCreateNotifier KernelBase 1190 -imp 'PcwCreateQuery' PcwCreateQuery KernelBase 1191 -imp 'PcwDisconnectCounterSet' PcwDisconnectCounterSet KernelBase 1192 -imp 'PcwEnumerateInstances' PcwEnumerateInstances KernelBase 1193 -imp 'PcwIsNotifierAlive' PcwIsNotifierAlive KernelBase 1194 -imp 'PcwQueryCounterSetSecurity' PcwQueryCounterSetSecurity KernelBase 1195 -imp 'PcwReadNotificationData' PcwReadNotificationData KernelBase 1196 -imp 'PcwRegisterCounterSet' PcwRegisterCounterSet KernelBase 1197 -imp 'PcwRemoveQueryItem' PcwRemoveQueryItem KernelBase 1198 -imp 'PcwSendNotification' PcwSendNotification KernelBase 1199 -imp 'PcwSendStatelessNotification' PcwSendStatelessNotification KernelBase 1200 -imp 'PcwSetCounterSetSecurity' PcwSetCounterSetSecurity KernelBase 1201 -imp 'PcwSetQueryItemUserData' PcwSetQueryItemUserData KernelBase 1202 -imp 'PeekConsoleInput' PeekConsoleInputW kernel32 0 4 # KernelBase -imp 'PeekConsoleInputA' PeekConsoleInputA kernel32 0 4 # KernelBase -imp 'PeekMessageA' PeekMessageA user32 2200 -imp 'PeekMessage' PeekMessageW user32 2201 5 -imp 'PeekNamedPipe' PeekNamedPipe kernel32 0 6 # KernelBase -imp 'PerfAddCounters' PerfAddCounters advapi32 1545 -imp 'PerfCloseQueryHandle' PerfCloseQueryHandle advapi32 1546 -imp 'PerfCreateInstance' PerfCreateInstance advapi32 0 # KernelBase -imp 'PerfDecrementULongCounterValue' PerfDecrementULongCounterValue advapi32 0 # KernelBase -imp 'PerfDecrementULongLongCounterValue' PerfDecrementULongLongCounterValue advapi32 0 # KernelBase -imp 'PerfDeleteCounters' PerfDeleteCounters advapi32 1550 -imp 'PerfDeleteInstance' PerfDeleteInstance advapi32 0 # KernelBase -imp 'PerfEnumerateCounterSet' PerfEnumerateCounterSet advapi32 1552 -imp 'PerfEnumerateCounterSetInstances' PerfEnumerateCounterSetInstances advapi32 1553 -imp 'PerfIncrementULongCounterValue' PerfIncrementULongCounterValue advapi32 0 # KernelBase -imp 'PerfIncrementULongLongCounterValue' PerfIncrementULongLongCounterValue advapi32 0 # KernelBase -imp 'PerfOpenQueryHandle' PerfOpenQueryHandle advapi32 1556 -imp 'PerfQueryCounterData' PerfQueryCounterData advapi32 1557 -imp 'PerfQueryCounterInfo' PerfQueryCounterInfo advapi32 1558 -imp 'PerfQueryCounterSetRegistrationInfo' PerfQueryCounterSetRegistrationInfo advapi32 1559 -imp 'PerfQueryInstance' PerfQueryInstance advapi32 0 # KernelBase -imp 'PerfRegCloseKey' PerfRegCloseKey advapi32 1561 -imp 'PerfRegEnumKey' PerfRegEnumKey advapi32 1562 -imp 'PerfRegEnumValue' PerfRegEnumValue advapi32 1563 -imp 'PerfRegQueryInfoKey' PerfRegQueryInfoKey advapi32 1564 -imp 'PerfRegQueryValue' PerfRegQueryValue advapi32 1565 -imp 'PerfRegSetValue' PerfRegSetValue advapi32 1566 -imp 'PerfSetCounterRefValue' PerfSetCounterRefValue advapi32 0 # KernelBase -imp 'PerfSetCounterSetInfo' PerfSetCounterSetInfo advapi32 0 # KernelBase -imp 'PerfSetULongCounterValue' PerfSetULongCounterValue advapi32 0 # KernelBase -imp 'PerfSetULongLongCounterValue' PerfSetULongLongCounterValue advapi32 0 # KernelBase -imp 'PerfStartProvider' PerfStartProvider advapi32 0 # KernelBase -imp 'PerfStartProviderEx' PerfStartProviderEx advapi32 0 # KernelBase -imp 'PerfStopProvider' PerfStopProvider advapi32 0 # KernelBase imp 'PfxFindPrefix' PfxFindPrefix ntdll 664 imp 'PfxInitialize' PfxInitialize ntdll 665 imp 'PfxInsertPrefix' PfxInsertPrefix ntdll 666 imp 'PfxRemovePrefix' PfxRemovePrefix ntdll 667 -imp 'PhysicalToLogicalPoint' PhysicalToLogicalPoint user32 2202 -imp 'PhysicalToLogicalPointForPerMonitorDPI' PhysicalToLogicalPointForPerMonitorDPI user32 2203 -imp 'PickIconDlg' PickIconDlg shell32 62 -imp 'Pie' Pie gdi32 1775 -imp 'PifMgr_CloseProperties' PifMgr_CloseProperties shell32 13 -imp 'PifMgr_GetProperties' PifMgr_GetProperties shell32 10 -imp 'PifMgr_OpenProperties' PifMgr_OpenProperties shell32 9 -imp 'PifMgr_SetProperties' PifMgr_SetProperties shell32 11 -imp 'PlayEnhMetaFile' PlayEnhMetaFile gdi32 1776 -imp 'PlayEnhMetaFileRecord' PlayEnhMetaFileRecord gdi32 1777 -imp 'PlayMetaFile' PlayMetaFile gdi32 1778 -imp 'PlayMetaFileRecord' PlayMetaFileRecord gdi32 1779 -imp 'PlgBlt' PlgBlt gdi32 1780 -imp 'PolyBezier' PolyBezier gdi32 1781 -imp 'PolyBezierTo' PolyBezierTo gdi32 1782 -imp 'PolyDraw' PolyDraw gdi32 1783 -imp 'PolyPatBlt' PolyPatBlt gdi32 1784 -imp 'PolyPolygon' PolyPolygon gdi32 1785 -imp 'PolyPolyline' PolyPolyline gdi32 1786 -imp 'PolyTextOutA' PolyTextOutA gdi32 1787 -imp 'PolyTextOut' PolyTextOutW gdi32 1788 -imp 'Polygon' Polygon gdi32 1789 -imp 'Polyline' Polyline gdi32 1790 -imp 'PolylineTo' PolylineTo gdi32 1791 -imp 'PoolPerAppKeyStateInternal' PoolPerAppKeyStateInternal KernelBase 1220 -imp 'PostMessageA' PostMessageA user32 2204 -imp 'PostMessage' PostMessageW user32 2205 -imp 'PostQueuedCompletionStatus' PostQueuedCompletionStatus kernel32 0 4 # KernelBase -imp 'PostQuitMessage' PostQuitMessage user32 2206 1 -imp 'PostThreadMessageA' PostThreadMessageA user32 2207 -imp 'PostThreadMessage' PostThreadMessageW user32 2208 -imp 'PowerClearRequest' PowerClearRequest kernel32 1057 -imp 'PowerCreateRequest' PowerCreateRequest kernel32 1058 -imp 'PowerSetRequest' PowerSetRequest kernel32 1059 -imp 'PrefetchVirtualMemory' PrefetchVirtualMemory kernel32 0 4 # KernelBase -imp 'PrepareDiscForBurnRunDll' PrepareDiscForBurnRunDllW shell32 135 -imp 'PrepareTape' PrepareTape kernel32 1061 -imp 'PrintDlgA' PrintDlgA comdlg32 120 1 -imp 'PrintDlgExA' PrintDlgExA comdlg32 121 -imp 'PrintDlgEx' PrintDlgExW comdlg32 122 -imp 'PrintDlg' PrintDlgW comdlg32 123 1 -imp 'PrintWindow' PrintWindow user32 2209 -imp 'PrintersGetCommand_RunDLL' PrintersGetCommand_RunDLL shell32 138 -imp 'PrintersGetCommand_RunDLLA' PrintersGetCommand_RunDLLA shell32 139 -imp 'PrintersGetCommand_RunDLLW' PrintersGetCommand_RunDLLW shell32 150 -imp 'PrivCopyFileEx' PrivCopyFileExW KernelBase 1223 -imp 'PrivMoveFileIdentity' PrivMoveFileIdentityW kernel32 1063 -imp 'PrivateExtractIconExA' PrivateExtractIconExA user32 2210 -imp 'PrivateExtractIconEx' PrivateExtractIconExW user32 2211 -imp 'PrivateExtractIconsA' PrivateExtractIconsA user32 2212 -imp 'PrivateExtractIcons' PrivateExtractIconsW user32 2213 -imp 'PrivateRegisterICSProc' PrivateRegisterICSProc user32 2214 -imp 'PrivilegeCheck' PrivilegeCheck advapi32 0 # KernelBase -imp 'PrivilegedServiceAuditAlarmA' PrivilegedServiceAuditAlarmA advapi32 1575 -imp 'PrivilegedServiceAuditAlarm' PrivilegedServiceAuditAlarmW advapi32 0 # KernelBase -imp 'Process32First' Process32FirstW kernel32 1065 -imp 'Process32Next' Process32NextW kernel32 1067 -imp 'ProcessIdToSessionId' ProcessIdToSessionId kernel32 0 # KernelBase -imp 'ProcessIdleTasks' ProcessIdleTasksW advapi32 1578 -imp 'ProcessTrace' ProcessTrace advapi32 1579 -imp 'ProductIdFromPackageFamilyName' ProductIdFromPackageFamilyName KernelBase 1227 -imp 'PsmCreateKey' PsmCreateKey KernelBase 1228 -imp 'PsmCreateKeyWithDynamicId' PsmCreateKeyWithDynamicId KernelBase 1229 -imp 'PsmEqualApplication' PsmEqualApplication KernelBase 1230 -imp 'PsmEqualPackage' PsmEqualPackage KernelBase 1231 -imp 'PsmGetApplicationNameFromKey' PsmGetApplicationNameFromKey KernelBase 1232 -imp 'PsmGetKeyFromProcess' PsmGetKeyFromProcess KernelBase 1233 -imp 'PsmGetKeyFromToken' PsmGetKeyFromToken KernelBase 1234 -imp 'PsmGetPackageFullNameFromKey' PsmGetPackageFullNameFromKey KernelBase 1235 -imp 'PsmIsChildKey' PsmIsChildKey KernelBase 1236 -imp 'PsmIsDynamicKey' PsmIsDynamicKey KernelBase 1237 -imp 'PsmIsValidKey' PsmIsValidKey KernelBase 1238 -imp 'PssCaptureSnapshot' PssCaptureSnapshot kernel32 0 # KernelBase -imp 'PssDuplicateSnapshot' PssDuplicateSnapshot kernel32 0 # KernelBase -imp 'PssFreeSnapshot' PssFreeSnapshot kernel32 0 # KernelBase imp 'PssNtCaptureSnapshot' PssNtCaptureSnapshot ntdll 668 imp 'PssNtDuplicateSnapshot' PssNtDuplicateSnapshot ntdll 669 imp 'PssNtFreeRemoteSnapshot' PssNtFreeRemoteSnapshot ntdll 670 @@ -4371,395 +5192,6 @@ imp 'PssNtFreeWalkMarker' PssNtFreeWalkMarker ntdll 672 imp 'PssNtQuerySnapshot' PssNtQuerySnapshot ntdll 673 imp 'PssNtValidateDescriptor' PssNtValidateDescriptor ntdll 674 imp 'PssNtWalkSnapshot' PssNtWalkSnapshot ntdll 675 -imp 'PssQuerySnapshot' PssQuerySnapshot kernel32 0 # KernelBase -imp 'PssWalkMarkerCreate' PssWalkMarkerCreate kernel32 0 # KernelBase -imp 'PssWalkMarkerFree' PssWalkMarkerFree kernel32 0 # KernelBase -imp 'PssWalkMarkerGetPosition' PssWalkMarkerGetPosition kernel32 0 # KernelBase -imp 'PssWalkMarkerRewind' PssWalkMarkerRewind kernel32 1076 -imp 'PssWalkMarkerSeek' PssWalkMarkerSeek kernel32 1077 -imp 'PssWalkMarkerSeekToBeginning' PssWalkMarkerSeekToBeginning kernel32 0 # KernelBase -imp 'PssWalkMarkerSetPosition' PssWalkMarkerSetPosition kernel32 0 # KernelBase -imp 'PssWalkMarkerTell' PssWalkMarkerTell kernel32 1080 -imp 'PssWalkSnapshot' PssWalkSnapshot kernel32 0 # KernelBase -imp 'PtInRect' PtInRect user32 2215 -imp 'PtInRegion' PtInRegion gdi32 1792 -imp 'PtVisible' PtVisible gdi32 1793 -imp 'PublishStateChangeNotification' PublishStateChangeNotification KernelBase 1249 -imp 'PulseEvent' PulseEvent kernel32 0 1 # KernelBase -imp 'PurgeComm' PurgeComm kernel32 0 # KernelBase -imp 'QISearch' QISearch KernelBase 1252 -imp 'QueryActCtxSettings' QueryActCtxSettingsW kernel32 0 # KernelBase -imp 'QueryActCtxSettingsWWorker' QueryActCtxSettingsWWorker kernel32 1085 -imp 'QueryActCtx' QueryActCtxW kernel32 0 # KernelBase -imp 'QueryActCtxWWorker' QueryActCtxWWorker kernel32 1087 -imp 'QueryAllTracesA' QueryAllTracesA advapi32 1580 -imp 'QueryAllTraces' QueryAllTracesW advapi32 1581 -imp 'QueryAuxiliaryCounterFrequency' QueryAuxiliaryCounterFrequency KernelBase 1255 -imp 'QueryBSDRWindow' QueryBSDRWindow user32 2216 -imp 'QueryDisplayConfig' QueryDisplayConfig user32 2217 -imp 'QueryDosDeviceA' QueryDosDeviceA kernel32 1089 -imp 'QueryDosDevice' QueryDosDeviceW kernel32 0 # KernelBase -imp 'QueryFontAssocStatus' QueryFontAssocStatus gdi32 1794 -imp 'QueryFullProcessImageNameA' QueryFullProcessImageNameA kernel32 0 # KernelBase -imp 'QueryFullProcessImageName' QueryFullProcessImageNameW kernel32 0 # KernelBase -imp 'QueryIdleProcessorCycleTime' QueryIdleProcessorCycleTime kernel32 0 # KernelBase -imp 'QueryIdleProcessorCycleTimeEx' QueryIdleProcessorCycleTimeEx kernel32 0 # KernelBase -imp 'QueryInformationJobObject' QueryInformationJobObject kernel32 1095 -imp 'QueryInterruptTime' QueryInterruptTime KernelBase 1262 -imp 'QueryInterruptTimePrecise' QueryInterruptTimePrecise KernelBase 1263 -imp 'QueryIoRateControlInformationJobObject' QueryIoRateControlInformationJobObject kernel32 1096 -imp 'QueryLocalUserServiceName' QueryLocalUserServiceName advapi32 1582 -imp 'QueryMemoryResourceNotification' QueryMemoryResourceNotification kernel32 0 # KernelBase -imp 'QueryOptionalDelayLoadedAPI' QueryOptionalDelayLoadedAPI KernelBase 1265 -imp 'QueryPerformanceCounter' QueryPerformanceCounter kernel32 1098 1 -imp 'QueryPerformanceFrequency' QueryPerformanceFrequency kernel32 1099 1 -imp 'QueryProcessAffinityUpdateMode' QueryProcessAffinityUpdateMode kernel32 0 # KernelBase -imp 'QueryProcessCycleTime' QueryProcessCycleTime kernel32 0 # KernelBase -imp 'QueryProtectedPolicy' QueryProtectedPolicy kernel32 0 # KernelBase -imp 'QueryRecoveryAgentsOnEncryptedFile' QueryRecoveryAgentsOnEncryptedFile advapi32 1583 -imp 'QuerySecurityAccessMask' QuerySecurityAccessMask advapi32 0 # KernelBase -imp 'QuerySendMessage' QuerySendMessage user32 2218 -imp 'QueryServiceConfig2A' QueryServiceConfig2A advapi32 1585 -imp 'QueryServiceConfig2W' QueryServiceConfig2W advapi32 1586 -imp 'QueryServiceConfigA' QueryServiceConfigA advapi32 1587 -imp 'QueryServiceConfig' QueryServiceConfigW advapi32 1588 -imp 'QueryServiceDynamicInformation' QueryServiceDynamicInformation advapi32 1589 -imp 'QueryServiceLockStatusA' QueryServiceLockStatusA advapi32 1590 -imp 'QueryServiceLockStatus' QueryServiceLockStatusW advapi32 1591 -imp 'QueryServiceObjectSecurity' QueryServiceObjectSecurity advapi32 1592 -imp 'QueryServiceStatus' QueryServiceStatus advapi32 1593 -imp 'QueryServiceStatusEx' QueryServiceStatusEx advapi32 1594 -imp 'QueryStateAtomValueInfo' QueryStateAtomValueInfo KernelBase 1272 -imp 'QueryStateContainerCreatedNew' QueryStateContainerCreatedNew KernelBase 1273 -imp 'QueryStateContainerItemInfo' QueryStateContainerItemInfo KernelBase 1274 -imp 'QueryThreadCycleTime' QueryThreadCycleTime kernel32 0 # KernelBase -imp 'QueryThreadProfiling' QueryThreadProfiling kernel32 1104 -imp 'QueryThreadpoolStackInformation' QueryThreadpoolStackInformation kernel32 0 # KernelBase -imp 'QueryTraceA' QueryTraceA advapi32 1595 -imp 'QueryTraceProcessingHandle' QueryTraceProcessingHandle advapi32 1596 -imp 'QueryTrace' QueryTraceW advapi32 1597 -imp 'QueryUmsThreadInformation' QueryUmsThreadInformation kernel32 1106 -imp 'QueryUnbiasedInterruptTime' QueryUnbiasedInterruptTime kernel32 1107 -imp 'QueryUnbiasedInterruptTimePrecise' QueryUnbiasedInterruptTimePrecise KernelBase 1278 -imp 'QueryUserServiceName' QueryUserServiceName advapi32 1598 -imp 'QueryUserServiceNameForContext' QueryUserServiceNameForContext advapi32 1599 -imp 'QueryUsersOnEncryptedFile' QueryUsersOnEncryptedFile advapi32 1600 -imp 'QueryVirtualMemoryInformation' QueryVirtualMemoryInformation KernelBase 1279 -imp 'QueryWorkingSet' QueryWorkingSet KernelBase 1280 -imp 'QueryWorkingSetEx' QueryWorkingSetEx KernelBase 1281 -imp 'QueueUserAPC' QueueUserAPC kernel32 0 # KernelBase -imp 'QueueUserWorkItem' QueueUserWorkItem kernel32 0 # KernelBase -imp 'QuirkGetData' QuirkGetData KernelBase 1284 -imp 'QuirkGetData2' QuirkGetData2 KernelBase 1285 -imp 'QuirkGetData2Worker' QuirkGetData2Worker kernel32 1110 -imp 'QuirkGetDataWorker' QuirkGetDataWorker kernel32 1111 -imp 'QuirkIsEnabled' QuirkIsEnabled KernelBase 1286 -imp 'QuirkIsEnabled2' QuirkIsEnabled2 KernelBase 1287 -imp 'QuirkIsEnabled2Worker' QuirkIsEnabled2Worker kernel32 1112 -imp 'QuirkIsEnabled3' QuirkIsEnabled3 KernelBase 1288 -imp 'QuirkIsEnabled3Worker' QuirkIsEnabled3Worker kernel32 1113 -imp 'QuirkIsEnabledForPackage' QuirkIsEnabledForPackage KernelBase 1289 -imp 'QuirkIsEnabledForPackage2' QuirkIsEnabledForPackage2 KernelBase 1290 -imp 'QuirkIsEnabledForPackage2Worker' QuirkIsEnabledForPackage2Worker kernel32 1114 -imp 'QuirkIsEnabledForPackage3' QuirkIsEnabledForPackage3 KernelBase 1291 -imp 'QuirkIsEnabledForPackage3Worker' QuirkIsEnabledForPackage3Worker kernel32 1115 -imp 'QuirkIsEnabledForPackage4' QuirkIsEnabledForPackage4 KernelBase 1292 -imp 'QuirkIsEnabledForPackage4Worker' QuirkIsEnabledForPackage4Worker kernel32 1116 -imp 'QuirkIsEnabledForPackageWorker' QuirkIsEnabledForPackageWorker kernel32 1117 -imp 'QuirkIsEnabledForProcess' QuirkIsEnabledForProcess KernelBase 1293 -imp 'QuirkIsEnabledForProcessWorker' QuirkIsEnabledForProcessWorker kernel32 1118 -imp 'QuirkIsEnabledWorker' QuirkIsEnabledWorker kernel32 1119 -imp 'RIMAddInputObserver' RIMAddInputObserver user32 2219 -imp 'RIMAreSiblingDevices' RIMAreSiblingDevices user32 2220 -imp 'RIMDeviceIoControl' RIMDeviceIoControl user32 2221 -imp 'RIMEnableMonitorMappingForDevice' RIMEnableMonitorMappingForDevice user32 2222 -imp 'RIMFreeInputBuffer' RIMFreeInputBuffer user32 2223 -imp 'RIMGetDevicePreparsedData' RIMGetDevicePreparsedData user32 2224 -imp 'RIMGetDevicePreparsedDataLockfree' RIMGetDevicePreparsedDataLockfree user32 2225 -imp 'RIMGetDeviceProperties' RIMGetDeviceProperties user32 2226 -imp 'RIMGetDevicePropertiesLockfree' RIMGetDevicePropertiesLockfree user32 2227 -imp 'RIMGetPhysicalDeviceRect' RIMGetPhysicalDeviceRect user32 2228 -imp 'RIMGetSourceProcessId' RIMGetSourceProcessId user32 2229 -imp 'RIMObserveNextInput' RIMObserveNextInput user32 2230 -imp 'RIMOnPnpNotification' RIMOnPnpNotification user32 2231 -imp 'RIMOnTimerNotification' RIMOnTimerNotification user32 2232 -imp 'RIMReadInput' RIMReadInput user32 2233 -imp 'RIMRegisterForInput' RIMRegisterForInput user32 2234 -imp 'RIMRemoveInputObserver' RIMRemoveInputObserver user32 2235 -imp 'RIMSetTestModeStatus' RIMSetTestModeStatus user32 2236 -imp 'RIMUnregisterForInput' RIMUnregisterForInput user32 2237 -imp 'RIMUpdateInputObserverRegistration' RIMUpdateInputObserverRegistration user32 2238 -imp 'RaiseCustomSystemEventTrigger' RaiseCustomSystemEventTrigger KernelBase 1294 -imp 'RaiseException' RaiseException kernel32 0 # KernelBase -imp 'RaiseFailFastException' RaiseFailFastException kernel32 0 # KernelBase -imp 'RaiseInvalid16BitExeError' RaiseInvalid16BitExeError kernel32 1122 -imp 'ReOpenFile' ReOpenFile kernel32 0 4 # TODO(jart): 6.2 and higher # KernelBase -imp 'ReadCabinetState' ReadCabinetState shell32 654 -imp 'ReadConsole' ReadConsoleW kernel32 0 5 # KernelBase -imp 'ReadConsoleA' ReadConsoleA kernel32 0 5 # KernelBase -imp 'ReadConsoleInput' ReadConsoleInputW kernel32 0 4 # KernelBase -imp 'ReadConsoleInputA' ReadConsoleInputA kernel32 0 4 # KernelBase -imp 'ReadConsoleInputExA' ReadConsoleInputExA KernelBase 1300 -imp 'ReadConsoleInputEx' ReadConsoleInputExW KernelBase 1301 -imp 'ReadConsoleOutput' ReadConsoleOutputW kernel32 0 5 # KernelBase -imp 'ReadConsoleOutputA' ReadConsoleOutputA kernel32 0 5 # KernelBase -imp 'ReadConsoleOutputAttribute' ReadConsoleOutputAttribute kernel32 0 5 # KernelBase -imp 'ReadConsoleOutputCharacter' ReadConsoleOutputCharacterW kernel32 0 5 # KernelBase -imp 'ReadConsoleOutputCharacterA' ReadConsoleOutputCharacterA kernel32 0 5 # KernelBase -imp 'ReadDirectoryChangesEx' ReadDirectoryChangesExW KernelBase 1309 -imp 'ReadDirectoryChanges' ReadDirectoryChangesW kernel32 0 # KernelBase -imp 'ReadEncryptedFileRaw' ReadEncryptedFileRaw advapi32 1601 -imp 'ReadEventLogA' ReadEventLogA advapi32 1602 -imp 'ReadEventLog' ReadEventLogW advapi32 1603 -imp 'ReadFile' ReadFile kernel32 0 5 # KernelBase -imp 'ReadFileEx' ReadFileEx kernel32 0 5 # KernelBase -imp 'ReadFileScatter' ReadFileScatter kernel32 0 5 # KernelBase -imp 'ReadProcessMemory' ReadProcessMemory kernel32 0 # KernelBase -imp 'ReadStateAtomValue' ReadStateAtomValue KernelBase 1315 -imp 'ReadStateContainerValue' ReadStateContainerValue KernelBase 1316 -imp 'ReadThreadProfilingData' ReadThreadProfilingData kernel32 1141 -imp 'RealChildWindowFromPoint' RealChildWindowFromPoint user32 2239 -imp 'RealDriveType' RealDriveType shell32 524 -imp 'RealGetWindowClassA' RealGetWindowClassA user32 2241 -imp 'RealGetWindowClass' RealGetWindowClassW user32 2242 -imp 'RealShellExecuteA' RealShellExecuteA shell32 199 -imp 'RealShellExecuteExA' RealShellExecuteExA shell32 207 -imp 'RealShellExecuteEx' RealShellExecuteExW shell32 208 -imp 'RealShellExecute' RealShellExecuteW shell32 226 -imp 'RealizePalette' RealizePalette gdi32 1795 -imp 'ReasonCodeNeedsBugID' ReasonCodeNeedsBugID user32 2243 -imp 'ReasonCodeNeedsComment' ReasonCodeNeedsComment user32 2244 -imp 'ReclaimVirtualMemory' ReclaimVirtualMemory kernel32 0 # KernelBase -imp 'RecordShutdownReason' RecordShutdownReason user32 2245 -imp 'RectInRegion' RectInRegion gdi32 1796 -imp 'RectVisible' RectVisible gdi32 1797 -imp 'Rectangle' Rectangle gdi32 1798 -imp 'RedrawWindow' RedrawWindow user32 2246 4 -imp 'RefreshPackageInfo' RefreshPackageInfo KernelBase 1318 -imp 'RefreshPolicyExInternal' RefreshPolicyExInternal KernelBase 1319 -imp 'RefreshPolicyInternal' RefreshPolicyInternal KernelBase 1320 -imp 'RegCloseKey' RegCloseKey advapi32 0 1 # KernelBase -imp 'RegConnectRegistry' RegConnectRegistryW advapi32 1608 3 -imp 'RegConnectRegistryA' RegConnectRegistryA advapi32 1605 3 -imp 'RegConnectRegistryEx' RegConnectRegistryExW advapi32 1607 4 -imp 'RegConnectRegistryExA' RegConnectRegistryExA advapi32 1606 4 -imp 'RegCopyTreeA' RegCopyTreeA advapi32 1609 -imp 'RegCopyTree' RegCopyTreeW advapi32 0 # KernelBase -imp 'RegCreateKey' RegCreateKeyW advapi32 1616 3 -imp 'RegCreateKeyA' RegCreateKeyA advapi32 1611 3 -imp 'RegCreateKeyEx' RegCreateKeyExW advapi32 0 9 # KernelBase -imp 'RegCreateKeyExA' RegCreateKeyExA advapi32 0 9 # KernelBase -imp 'RegCreateKeyExInternalA' RegCreateKeyExInternalA KernelBase 1324 -imp 'RegCreateKeyExInternal' RegCreateKeyExInternalW KernelBase 1325 -imp 'RegCreateKeyTransactedA' RegCreateKeyTransactedA advapi32 1614 -imp 'RegCreateKeyTransacted' RegCreateKeyTransactedW advapi32 1615 -imp 'RegDeleteKey' RegDeleteKeyW advapi32 1624 2 -imp 'RegDeleteKeyA' RegDeleteKeyA advapi32 1617 2 -imp 'RegDeleteKeyEx' RegDeleteKeyExW advapi32 0 4 # KernelBase -imp 'RegDeleteKeyExA' RegDeleteKeyExA advapi32 0 4 # KernelBase -imp 'RegDeleteKeyExInternalA' RegDeleteKeyExInternalA KernelBase 1328 -imp 'RegDeleteKeyExInternal' RegDeleteKeyExInternalW KernelBase 1329 -imp 'RegDeleteKeyTransactedA' RegDeleteKeyTransactedA advapi32 1620 -imp 'RegDeleteKeyTransacted' RegDeleteKeyTransactedW advapi32 1621 -imp 'RegDeleteKeyValueA' RegDeleteKeyValueA advapi32 0 # KernelBase -imp 'RegDeleteKeyValue' RegDeleteKeyValueW advapi32 0 # KernelBase -imp 'RegDeleteTree' RegDeleteTreeW advapi32 0 2 # KernelBase -imp 'RegDeleteTreeA' RegDeleteTreeA advapi32 0 2 # KernelBase -imp 'RegDeleteValue' RegDeleteValueW advapi32 0 2 # KernelBase -imp 'RegDeleteValueA' RegDeleteValueA advapi32 0 2 # KernelBase -imp 'RegDisablePredefinedCache' RegDisablePredefinedCache advapi32 1629 1 -imp 'RegDisablePredefinedCacheEx' RegDisablePredefinedCacheEx kernel32 0 # KernelBase -imp 'RegDisableReflectionKey' RegDisableReflectionKey advapi32 1631 1 -imp 'RegEnableReflectionKey' RegEnableReflectionKey advapi32 1632 1 -imp 'RegEnumKey' RegEnumKeyW advapi32 1636 4 -imp 'RegEnumKeyA' RegEnumKeyA advapi32 1633 4 -imp 'RegEnumKeyEx' RegEnumKeyExW advapi32 0 8 # KernelBase -imp 'RegEnumKeyExA' RegEnumKeyExA advapi32 0 8 # KernelBase -imp 'RegEnumValue' RegEnumValueW advapi32 0 8 # KernelBase -imp 'RegEnumValueA' RegEnumValueA advapi32 0 8 # KernelBase -imp 'RegFlushKey' RegFlushKey advapi32 0 1 # KernelBase -imp 'RegGetKeySecurity' RegGetKeySecurity advapi32 0 4 # KernelBase -imp 'RegGetValue' RegGetValueW advapi32 0 7 # KernelBase -imp 'RegGetValueA' RegGetValueA advapi32 0 7 # KernelBase -imp 'RegKrnGetAppKeyEventAddressInternal' RegKrnGetAppKeyEventAddressInternal KernelBase 1346 -imp 'RegKrnGetAppKeyLoaded' RegKrnGetAppKeyLoaded KernelBase 1347 -imp 'RegKrnGetClassesEnumTableAddressInternal' RegKrnGetClassesEnumTableAddressInternal KernelBase 1348 -imp 'RegKrnGetHKEY_ClassesRootAddress' RegKrnGetHKEY_ClassesRootAddress KernelBase 1349 -imp 'RegKrnGetTermsrvRegistryExtensionFlags' RegKrnGetTermsrvRegistryExtensionFlags KernelBase 1350 -imp 'RegKrnResetAppKeyLoaded' RegKrnResetAppKeyLoaded KernelBase 1351 -imp 'RegKrnSetDllHasThreadStateGlobal' RegKrnSetDllHasThreadStateGlobal KernelBase 1352 -imp 'RegKrnSetTermsrvRegistryExtensionFlags' RegKrnSetTermsrvRegistryExtensionFlags KernelBase 1353 -imp 'RegLoadAppKeyA' RegLoadAppKeyA advapi32 0 # KernelBase -imp 'RegLoadAppKey' RegLoadAppKeyW advapi32 0 # KernelBase -imp 'RegLoadKey' RegLoadKeyW advapi32 0 3 # KernelBase -imp 'RegLoadKeyA' RegLoadKeyA advapi32 0 3 # KernelBase -imp 'RegLoadMUIStringA' RegLoadMUIStringA kernel32 0 # KernelBase -imp 'RegLoadMUIString' RegLoadMUIStringW advapi32 0 # KernelBase -imp 'RegNotifyChangeKeyValue' RegNotifyChangeKeyValue advapi32 0 5 # KernelBase -imp 'RegOpenCurrentUser' RegOpenCurrentUser advapi32 0 2 # KernelBase -imp 'RegOpenKeyA' RegOpenKeyA advapi32 1651 3 -imp 'RegOpenKeyEx' RegOpenKeyExW advapi32 0 5 # KernelBase -imp 'RegOpenKeyExA' RegOpenKeyExA advapi32 0 5 # KernelBase -imp 'RegOpenKeyExInternalA' RegOpenKeyExInternalA KernelBase 1363 -imp 'RegOpenKeyExInternal' RegOpenKeyExInternalW KernelBase 1364 -imp 'RegOpenKeyTransactedA' RegOpenKeyTransactedA advapi32 1654 -imp 'RegOpenKeyTransacted' RegOpenKeyTransactedW advapi32 1655 -imp 'RegOpenKey' RegOpenKeyW advapi32 1656 -imp 'RegOpenUserClassesRoot' RegOpenUserClassesRoot advapi32 0 4 # KernelBase -imp 'RegOverridePredefKey' RegOverridePredefKey advapi32 1658 2 -imp 'RegQueryInfoKey' RegQueryInfoKeyW advapi32 0 12 # KernelBase -imp 'RegQueryInfoKeyA' RegQueryInfoKeyA advapi32 0 12 # KernelBase -imp 'RegQueryMultipleValues' RegQueryMultipleValuesW advapi32 0 5 # KernelBase -imp 'RegQueryMultipleValuesA' RegQueryMultipleValuesA advapi32 0 5 # KernelBase -imp 'RegQueryReflectionKey' RegQueryReflectionKey advapi32 1663 2 -imp 'RegQueryValue' RegQueryValueW advapi32 1667 4 -imp 'RegQueryValueA' RegQueryValueA advapi32 1664 4 -imp 'RegQueryValueEx' RegQueryValueExW advapi32 0 6 # KernelBase -imp 'RegQueryValueExA' RegQueryValueExA advapi32 0 6 # KernelBase -imp 'RegRenameKey' RegRenameKey advapi32 1668 -imp 'RegReplaceKey' RegReplaceKeyW advapi32 1670 4 -imp 'RegReplaceKeyA' RegReplaceKeyA advapi32 1669 4 -imp 'RegRestoreKey' RegRestoreKeyW advapi32 0 3 # KernelBase -imp 'RegRestoreKeyA' RegRestoreKeyA advapi32 0 3 # KernelBase -imp 'RegSaveKey' RegSaveKeyW advapi32 1676 3 -imp 'RegSaveKeyA' RegSaveKeyA advapi32 1673 3 -imp 'RegSaveKeyExA' RegSaveKeyExA kernel32 0 # KernelBase -imp 'RegSaveKeyEx' RegSaveKeyExW advapi32 0 # KernelBase -imp 'RegSetKeySecurity' RegSetKeySecurity advapi32 0 3 # KernelBase -imp 'RegSetKeyValueA' RegSetKeyValueA advapi32 0 # KernelBase -imp 'RegSetKeyValue' RegSetKeyValueW advapi32 0 # KernelBase -imp 'RegSetValue' RegSetValueW advapi32 1683 5 -imp 'RegSetValueA' RegSetValueA advapi32 1680 5 -imp 'RegSetValueEx' RegSetValueExW advapi32 0 6 # KernelBase -imp 'RegSetValueExA' RegSetValueExA advapi32 0 6 # KernelBase -imp 'RegUnLoadKey' RegUnLoadKeyW advapi32 0 2 # KernelBase -imp 'RegUnLoadKeyA' RegUnLoadKeyA advapi32 0 2 # KernelBase -imp 'RegenerateUserEnvironment' RegenerateUserEnvironment shell32 313 -imp 'RegisterApplicationRecoveryCallback' RegisterApplicationRecoveryCallback kernel32 1184 -imp 'RegisterApplicationRestart' RegisterApplicationRestart kernel32 1185 -imp 'RegisterBSDRWindow' RegisterBSDRWindow user32 2247 -imp 'RegisterBadMemoryNotification' RegisterBadMemoryNotification kernel32 0 # KernelBase -imp 'RegisterClassA' RegisterClassA user32 2248 1 -imp 'RegisterClassExA' RegisterClassExA user32 2249 1 -imp 'RegisterClassEx' RegisterClassExW user32 2250 1 -imp 'RegisterClass' RegisterClassW user32 2251 1 -imp 'RegisterClipboardFormatA' RegisterClipboardFormatA user32 2252 -imp 'RegisterClipboardFormat' RegisterClipboardFormatW user32 2253 -imp 'RegisterConsoleIME' RegisterConsoleIME kernel32 1187 -imp 'RegisterConsoleOS2' RegisterConsoleOS2 kernel32 1188 -imp 'RegisterConsoleVDM' RegisterConsoleVDM kernel32 1189 -imp 'RegisterDManipHook' RegisterDManipHook user32 2254 -imp 'RegisterDeviceNotificationA' RegisterDeviceNotificationA user32 2255 -imp 'RegisterDeviceNotification' RegisterDeviceNotificationW user32 2256 -imp 'RegisterErrorReportingDialog' RegisterErrorReportingDialog user32 2257 -imp 'RegisterEventSourceA' RegisterEventSourceA advapi32 1686 2 -imp 'RegisterEventSource' RegisterEventSourceW advapi32 1687 2 -imp 'RegisterFrostWindow' RegisterFrostWindow user32 2258 -imp 'RegisterGPNotificationInternal' RegisterGPNotificationInternal KernelBase 1385 -imp 'RegisterGhostWindow' RegisterGhostWindow user32 2259 -imp 'RegisterHotKey' RegisterHotKey user32 2260 -imp 'RegisterIdleTask' RegisterIdleTask advapi32 1688 -imp 'RegisterLogonProcess' RegisterLogonProcess user32 2261 -imp 'RegisterMessagePumpHook' RegisterMessagePumpHook user32 2262 -imp 'RegisterPointerDeviceNotifications' RegisterPointerDeviceNotifications user32 2263 -imp 'RegisterPointerInputTarget' RegisterPointerInputTarget user32 2264 -imp 'RegisterPointerInputTargetEx' RegisterPointerInputTargetEx user32 2265 -imp 'RegisterPowerSettingNotification' RegisterPowerSettingNotification user32 2266 -imp 'RegisterRawInputDevices' RegisterRawInputDevices user32 2267 -imp 'RegisterServiceCtrlHandlerA' RegisterServiceCtrlHandlerA advapi32 1689 -imp 'RegisterServiceCtrlHandlerExA' RegisterServiceCtrlHandlerExA advapi32 1690 -imp 'RegisterServiceCtrlHandlerEx' RegisterServiceCtrlHandlerExW advapi32 1691 -imp 'RegisterServiceCtrlHandler' RegisterServiceCtrlHandlerW advapi32 1692 -imp 'RegisterServicesProcess' RegisterServicesProcess user32 2268 -imp 'RegisterSessionPort' RegisterSessionPort user32 2269 -imp 'RegisterShellHookWindow' RegisterShellHookWindow user32 2270 -imp 'RegisterStateChangeNotification' RegisterStateChangeNotification KernelBase 1386 -imp 'RegisterStateLock' RegisterStateLock KernelBase 1387 -imp 'RegisterSuspendResumeNotification' RegisterSuspendResumeNotification user32 2271 -imp 'RegisterSystemThread' RegisterSystemThread user32 2272 -imp 'RegisterTasklist' RegisterTasklist user32 2273 -imp 'RegisterTouchHitTestingWindow' RegisterTouchHitTestingWindow user32 2274 -imp 'RegisterTouchWindow' RegisterTouchWindow user32 2275 -imp 'RegisterUserApiHook' RegisterUserApiHook user32 2276 -imp 'RegisterWaitChainCOMCallback' RegisterWaitChainCOMCallback advapi32 1695 -imp 'RegisterWaitForInputIdle' RegisterWaitForInputIdle kernel32 1190 -imp 'RegisterWaitForSingleObject' RegisterWaitForSingleObject kernel32 1191 6 -imp 'RegisterWaitForSingleObjectEx' RegisterWaitForSingleObjectEx KernelBase 1389 -imp 'RegisterWaitUntilOOBECompleted' RegisterWaitUntilOOBECompleted kernel32 1193 -imp 'RegisterWindowMessageA' RegisterWindowMessageA user32 2277 -imp 'RegisterWindowMessage' RegisterWindowMessageW user32 2278 -imp 'RegisterWowBaseHandlers' RegisterWowBaseHandlers kernel32 1194 -imp 'RegisterWowExec' RegisterWowExec kernel32 1195 -imp 'ReleaseActCtx' ReleaseActCtx kernel32 0 # KernelBase -imp 'ReleaseActCtxWorker' ReleaseActCtxWorker kernel32 1197 -imp 'ReleaseCapture' ReleaseCapture user32 2279 0 -imp 'ReleaseDC' ReleaseDC user32 2280 2 -imp 'ReleaseDwmHitTestWaiters' ReleaseDwmHitTestWaiters user32 2281 -imp 'ReleaseMutex' ReleaseMutex kernel32 0 1 # KernelBase -imp 'ReleaseSemaphore' ReleaseSemaphore kernel32 0 3 # KernelBase -imp 'ReleaseStateLock' ReleaseStateLock KernelBase 1397 -imp 'RemapPredefinedHandleInternal' RemapPredefinedHandleInternal KernelBase 1398 -imp 'RemoteRegEnumKeyWrapper' RemoteRegEnumKeyWrapper advapi32 1696 -imp 'RemoteRegEnumValueWrapper' RemoteRegEnumValueWrapper advapi32 1697 -imp 'RemoteRegQueryInfoKeyWrapper' RemoteRegQueryInfoKeyWrapper advapi32 1698 -imp 'RemoteRegQueryMultipleValues2Wrapper' RemoteRegQueryMultipleValues2Wrapper advapi32 1699 -imp 'RemoteRegQueryMultipleValuesWrapper' RemoteRegQueryMultipleValuesWrapper advapi32 1700 -imp 'RemoteRegQueryValueWrapper' RemoteRegQueryValueWrapper advapi32 1701 -imp 'RemoveClipboardFormatListener' RemoveClipboardFormatListener user32 2282 -imp 'RemoveDirectory' RemoveDirectoryW kernel32 0 1 # KernelBase -imp 'RemoveDirectoryA' RemoveDirectoryA kernel32 0 1 # KernelBase -imp 'RemoveDirectoryTransactedA' RemoveDirectoryTransactedA kernel32 1205 -imp 'RemoveDirectoryTransacted' RemoveDirectoryTransactedW kernel32 1206 -imp 'RemoveDllDirectory' RemoveDllDirectory kernel32 0 # KernelBase -imp 'RemoveExtensionProgIds' RemoveExtensionProgIds KernelBase 1402 -imp 'RemoveFontMemResourceEx' RemoveFontMemResourceEx gdi32 1799 -imp 'RemoveFontResourceA' RemoveFontResourceA gdi32 1800 -imp 'RemoveFontResourceExA' RemoveFontResourceExA gdi32 1801 -imp 'RemoveFontResourceEx' RemoveFontResourceExW gdi32 1802 -imp 'RemoveFontResourceTracking' RemoveFontResourceTracking gdi32 1803 -imp 'RemoveFontResource' RemoveFontResourceW gdi32 1804 -imp 'RemoveInjectionDevice' RemoveInjectionDevice user32 2283 -imp 'RemoveLocalAlternateComputerNameA' RemoveLocalAlternateComputerNameA kernel32 1209 -imp 'RemoveLocalAlternateComputerName' RemoveLocalAlternateComputerNameW kernel32 1210 -imp 'RemoveMenu' RemoveMenu user32 2284 -imp 'RemovePackageFromFamilyXref' RemovePackageFromFamilyXref KernelBase 1403 -imp 'RemovePackageStatus' RemovePackageStatus KernelBase 1404 -imp 'RemovePackageStatusForUser' RemovePackageStatusForUser KernelBase 1405 -imp 'RemovePropA' RemovePropA user32 2285 -imp 'RemoveProp' RemovePropW user32 2286 -imp 'RemoveSecureMemoryCacheCallback' RemoveSecureMemoryCacheCallback kernel32 1211 -imp 'RemoveThreadTSFEventAwareness' RemoveThreadTSFEventAwareness user32 2287 -imp 'RemoveUsersFromEncryptedFile' RemoveUsersFromEncryptedFile advapi32 1703 -imp 'ReplaceFileA' ReplaceFileA kernel32 1215 -imp 'ReplaceFileExInternal' ReplaceFileExInternal KernelBase 1408 -imp 'ReplaceFile' ReplaceFileW kernel32 0 # KernelBase -imp 'ReplacePartitionUnit' ReplacePartitionUnit kernel32 1217 -imp 'ReplaceTextA' ReplaceTextA comdlg32 124 1 -imp 'ReplaceText' ReplaceTextW comdlg32 125 1 -imp 'ReplyMessage' ReplyMessage user32 2288 -imp 'ReportEventA' ReportEventA advapi32 1704 9 -imp 'ReportEvent' ReportEventW advapi32 1705 9 -imp 'ReportInertia' ReportInertia user32 2551 -imp 'RequestDeviceWakeup' RequestDeviceWakeup kernel32 1218 -imp 'RequestWakeupLatency' RequestWakeupLatency kernel32 1219 -imp 'ResetDCA' ResetDCA gdi32 1805 -imp 'ResetDCW' ResetDCW gdi32 1806 -imp 'ResetEvent' ResetEvent kernel32 0 1 # KernelBase -imp 'ResetState' ResetState KernelBase 1411 -imp 'ResetWriteWatch' ResetWriteWatch kernel32 0 # KernelBase -imp 'ResizePalette' ResizePalette gdi32 1807 -imp 'ResolveDelayLoadedAPI' ResolveDelayLoadedAPI kernel32 0 # KernelBase -imp 'ResolveDelayLoadsFromDll' ResolveDelayLoadsFromDll kernel32 0 # KernelBase -imp 'ResolveDesktopForWOW' ResolveDesktopForWOW user32 2289 -imp 'ResolveLocaleName' ResolveLocaleName kernel32 0 # KernelBase -imp 'RestartDialog' RestartDialog shell32 59 -imp 'RestartDialogEx' RestartDialogEx shell32 730 -imp 'RestoreDC' RestoreDC gdi32 1808 2 -imp 'ResumeThread' ResumeThread kernel32 0 # KernelBase -imp 'ReuseDDElParam' ReuseDDElParam user32 2290 -imp 'RevertToSelf' RevertToSelf advapi32 0 # KernelBase -imp 'RoundRect' RoundRect gdi32 1809 -imp 'RsopLoggingEnabledInternal' RsopLoggingEnabledInternal KernelBase 1419 imp 'RtlAbortRXact' RtlAbortRXact ntdll 676 imp 'RtlAbsoluteToSelfRelativeSD' RtlAbsoluteToSelfRelativeSD ntdll 677 imp 'RtlAcquirePebLock' RtlAcquirePebLock ntdll 678 @@ -5030,9 +5462,7 @@ imp 'RtlEqualString' RtlEqualString ntdll 942 imp 'RtlEqualUnicodeString' RtlEqualUnicodeString ntdll 943 imp 'RtlEqualWnfChangeStamps' RtlEqualWnfChangeStamps ntdll 944 imp 'RtlEraseUnicodeString' RtlEraseUnicodeString ntdll 945 -imp 'RtlEthernetAddressToStringA' RtlEthernetAddressToStringA ntdll 946 imp 'RtlEthernetAddressToString' RtlEthernetAddressToStringW ntdll 947 -imp 'RtlEthernetStringToAddressA' RtlEthernetStringToAddressA ntdll 948 imp 'RtlEthernetStringToAddress' RtlEthernetStringToAddressW ntdll 949 imp 'RtlExecuteUmsThread' RtlExecuteUmsThread ntdll 950 imp 'RtlExitUserProcess' RtlExitUserProcess ntdll 951 @@ -5087,7 +5517,6 @@ imp 'RtlFreeThreadActivationContextStack' RtlFreeThreadActivationContextStack imp 'RtlFreeUnicodeString' RtlFreeUnicodeString ntdll 1000 1 imp 'RtlFreeUserStack' RtlFreeUserStack ntdll 1001 imp 'RtlGUIDFromString' RtlGUIDFromString ntdll 1002 -imp 'RtlGenRandom' SystemFunction036 advapi32 0 2 imp 'RtlGenerate8dot3Name' RtlGenerate8dot3Name ntdll 1003 imp 'RtlGetAce' RtlGetAce ntdll 1004 imp 'RtlGetActiveActivationContext' RtlGetActiveActivationContext ntdll 1005 @@ -5234,22 +5663,14 @@ imp 'RtlInterlockedPushListSListEx' RtlInterlockedPushListSListEx ntdll 1 imp 'RtlInterlockedSetBitRun' RtlInterlockedSetBitRun ntdll 1146 imp 'RtlIoDecodeMemIoResource' RtlIoDecodeMemIoResource ntdll 1147 imp 'RtlIoEncodeMemIoResource' RtlIoEncodeMemIoResource ntdll 1148 -imp 'RtlIpv4AddressToStringA' RtlIpv4AddressToStringA ntdll 1149 -imp 'RtlIpv4AddressToStringExA' RtlIpv4AddressToStringExA ntdll 1150 -imp 'RtlIpv4AddressToStringEx' RtlIpv4AddressToStringExW ntdll 1151 imp 'RtlIpv4AddressToString' RtlIpv4AddressToStringW ntdll 1152 -imp 'RtlIpv4StringToAddressA' RtlIpv4StringToAddressA ntdll 1153 -imp 'RtlIpv4StringToAddressExA' RtlIpv4StringToAddressExA ntdll 1154 -imp 'RtlIpv4StringToAddressEx' RtlIpv4StringToAddressExW ntdll 1155 +imp 'RtlIpv4AddressToStringEx' RtlIpv4AddressToStringExW ntdll 1151 imp 'RtlIpv4StringToAddress' RtlIpv4StringToAddressW ntdll 1156 -imp 'RtlIpv6AddressToStringA' RtlIpv6AddressToStringA ntdll 1157 -imp 'RtlIpv6AddressToStringExA' RtlIpv6AddressToStringExA ntdll 1158 -imp 'RtlIpv6AddressToStringEx' RtlIpv6AddressToStringExW ntdll 1159 +imp 'RtlIpv4StringToAddressEx' RtlIpv4StringToAddressExW ntdll 1155 imp 'RtlIpv6AddressToString' RtlIpv6AddressToStringW ntdll 1160 -imp 'RtlIpv6StringToAddressA' RtlIpv6StringToAddressA ntdll 1161 -imp 'RtlIpv6StringToAddressExA' RtlIpv6StringToAddressExA ntdll 1162 -imp 'RtlIpv6StringToAddressEx' RtlIpv6StringToAddressExW ntdll 1163 +imp 'RtlIpv6AddressToStringEx' RtlIpv6AddressToStringExW ntdll 1159 imp 'RtlIpv6StringToAddress' RtlIpv6StringToAddressW ntdll 1164 +imp 'RtlIpv6StringToAddressEx' RtlIpv6StringToAddressExW ntdll 1163 imp 'RtlIsActivationContextActive' RtlIsActivationContextActive ntdll 1165 imp 'RtlIsCapabilitySid' RtlIsCapabilitySid ntdll 1166 imp 'RtlIsCloudFilesPlaceholder' RtlIsCloudFilesPlaceholder ntdll 1167 @@ -5695,965 +6116,11 @@ imp 'RtlxAnsiStringToUnicodeSize' RtlxAnsiStringToUnicodeSize ntdll 1606 imp 'RtlxOemStringToUnicodeSize' RtlxOemStringToUnicodeSize ntdll 1607 imp 'RtlxUnicodeStringToAnsiSize' RtlxUnicodeStringToAnsiSize ntdll 1608 imp 'RtlxUnicodeStringToOemSize' RtlxUnicodeStringToOemSize ntdll 1609 -imp 'RunAsNewUser_RunDLLW' RunAsNewUser_RunDLLW shell32 314 -imp 'RxNetAccessAdd' RxNetAccessAdd netapi32 288 -imp 'RxNetAccessDel' RxNetAccessDel netapi32 289 -imp 'RxNetAccessEnum' RxNetAccessEnum netapi32 290 -imp 'RxNetAccessGetInfo' RxNetAccessGetInfo netapi32 291 -imp 'RxNetAccessGetUserPerms' RxNetAccessGetUserPerms netapi32 292 -imp 'RxNetAccessSetInfo' RxNetAccessSetInfo netapi32 293 -imp 'RxNetServerEnum' RxNetServerEnum netapi32 294 -imp 'RxNetUserPasswordSet' RxNetUserPasswordSet netapi32 295 -imp 'RxRemoteApi' RxRemoteApi netapi32 296 -imp 'SHAddDefaultPropertiesByExt' SHAddDefaultPropertiesByExt shell32 315 -imp 'SHAddFromPropSheetExtArray' SHAddFromPropSheetExtArray shell32 167 -imp 'SHAddToRecentDocs' SHAddToRecentDocs shell32 316 -imp 'SHAlloc' SHAlloc shell32 196 -imp 'SHAppBarMessage' SHAppBarMessage shell32 317 -imp 'SHAssocEnumHandlers' SHAssocEnumHandlers shell32 318 -imp 'SHAssocEnumHandlersForProtocolByApplication' SHAssocEnumHandlersForProtocolByApplication shell32 319 -imp 'SHBindToFolderIDListParent' SHBindToFolderIDListParent shell32 320 -imp 'SHBindToFolderIDListParentEx' SHBindToFolderIDListParentEx shell32 321 -imp 'SHBindToObject' SHBindToObject shell32 322 -imp 'SHBindToParent' SHBindToParent shell32 323 -imp 'SHBrowseForFolderA' SHBrowseForFolderA shell32 325 -imp 'SHBrowseForFolder' SHBrowseForFolderW shell32 326 -imp 'SHCLSIDFromString' SHCLSIDFromString shell32 147 -imp 'SHChangeNotification_Lock' SHChangeNotification_Lock shell32 644 -imp 'SHChangeNotification_Unlock' SHChangeNotification_Unlock shell32 645 -imp 'SHChangeNotify' SHChangeNotify shell32 327 -imp 'SHChangeNotifyDeregister' SHChangeNotifyDeregister shell32 4 -imp 'SHChangeNotifyRegister' SHChangeNotifyRegister shell32 2 -imp 'SHChangeNotifyRegisterThread' SHChangeNotifyRegisterThread shell32 328 -imp 'SHChangeNotifySuspendResume' SHChangeNotifySuspendResume shell32 329 -imp 'SHCloneSpecialIDList' SHCloneSpecialIDList shell32 89 -imp 'SHCoCreateInstance' SHCoCreateInstance KernelBase 1420 -imp 'SHCoCreateInstanceWorker' SHCoCreateInstanceWorker shell32 330 -imp 'SHCreateAssociationRegistration' SHCreateAssociationRegistration shell32 331 -imp 'SHCreateCategoryEnum' SHCreateCategoryEnum shell32 332 -imp 'SHCreateDataObject' SHCreateDataObject shell32 333 -imp 'SHCreateDefaultContextMenu' SHCreateDefaultContextMenu shell32 334 -imp 'SHCreateDefaultExtractIcon' SHCreateDefaultExtractIcon shell32 335 -imp 'SHCreateDefaultPropertiesOp' SHCreateDefaultPropertiesOp shell32 336 -imp 'SHCreateDirectory' SHCreateDirectory shell32 165 -imp 'SHCreateDirectoryExA' SHCreateDirectoryExA shell32 337 -imp 'SHCreateDirectoryEx' SHCreateDirectoryExW shell32 338 -imp 'SHCreateDrvExtIcon' SHCreateDrvExtIcon shell32 339 -imp 'SHCreateFileExtractIcon' SHCreateFileExtractIconW shell32 743 -imp 'SHCreateItemFromIDList' SHCreateItemFromIDList shell32 340 -imp 'SHCreateItemFromParsingName' SHCreateItemFromParsingName shell32 341 -imp 'SHCreateItemFromRelativeName' SHCreateItemFromRelativeName shell32 342 -imp 'SHCreateItemInKnownFolder' SHCreateItemInKnownFolder shell32 343 -imp 'SHCreateItemWithParent' SHCreateItemWithParent shell32 344 -imp 'SHCreateLocalServerRunDll' SHCreateLocalServerRunDll shell32 345 -imp 'SHCreateProcessAsUser' SHCreateProcessAsUserW shell32 346 -imp 'SHCreatePropSheetExtArray' SHCreatePropSheetExtArray shell32 168 -imp 'SHCreateQueryCancelAutoPlayMoniker' SHCreateQueryCancelAutoPlayMoniker shell32 347 -imp 'SHCreateShellFolderView' SHCreateShellFolderView shell32 256 -imp 'SHCreateShellFolderViewEx' SHCreateShellFolderViewEx shell32 174 -imp 'SHCreateShellItem' SHCreateShellItem shell32 348 -imp 'SHCreateShellItemArray' SHCreateShellItemArray shell32 349 -imp 'SHCreateShellItemArrayFromDataObject' SHCreateShellItemArrayFromDataObject shell32 350 -imp 'SHCreateShellItemArrayFromIDLists' SHCreateShellItemArrayFromIDLists shell32 351 -imp 'SHCreateShellItemArrayFromShellItem' SHCreateShellItemArrayFromShellItem shell32 352 -imp 'SHCreateStdEnumFmtEtc' SHCreateStdEnumFmtEtc shell32 74 -imp 'SHDefExtractIconA' SHDefExtractIconA shell32 3 -imp 'SHDefExtractIcon' SHDefExtractIconW shell32 6 -imp 'SHDestroyPropSheetExtArray' SHDestroyPropSheetExtArray shell32 169 -imp 'SHDoDragDrop' SHDoDragDrop shell32 88 -imp 'SHELL32_AddToBackIconTable' SHELL32_AddToBackIconTable shell32 353 -imp 'SHELL32_AddToFrontIconTable' SHELL32_AddToFrontIconTable shell32 354 -imp 'SHELL32_AreAllItemsAvailable' SHELL32_AreAllItemsAvailable shell32 355 -imp 'SHELL32_BindToFilePlaceholderHandler' SHELL32_BindToFilePlaceholderHandler shell32 356 -imp 'SHELL32_CCommonPlacesFolder_CreateInstance' SHELL32_CCommonPlacesFolder_CreateInstance shell32 357 -imp 'SHELL32_CDBurn_CloseSession' SHELL32_CDBurn_CloseSession shell32 358 -imp 'SHELL32_CDBurn_DriveSupportedForDataBurn' SHELL32_CDBurn_DriveSupportedForDataBurn shell32 359 -imp 'SHELL32_CDBurn_Erase' SHELL32_CDBurn_Erase shell32 360 -imp 'SHELL32_CDBurn_GetCDInfo' SHELL32_CDBurn_GetCDInfo shell32 361 -imp 'SHELL32_CDBurn_GetLiveFSDiscInfo' SHELL32_CDBurn_GetLiveFSDiscInfo shell32 362 -imp 'SHELL32_CDBurn_GetStagingPathOrNormalPath' SHELL32_CDBurn_GetStagingPathOrNormalPath shell32 363 -imp 'SHELL32_CDBurn_GetTaskInfo' SHELL32_CDBurn_GetTaskInfo shell32 364 -imp 'SHELL32_CDBurn_IsBlankDisc' SHELL32_CDBurn_IsBlankDisc shell32 365 -imp 'SHELL32_CDBurn_IsBlankDisc2' SHELL32_CDBurn_IsBlankDisc2 shell32 366 -imp 'SHELL32_CDBurn_IsLiveFS' SHELL32_CDBurn_IsLiveFS shell32 367 -imp 'SHELL32_CDBurn_OnDeviceChange' SHELL32_CDBurn_OnDeviceChange shell32 368 -imp 'SHELL32_CDBurn_OnEject' SHELL32_CDBurn_OnEject shell32 369 -imp 'SHELL32_CDBurn_OnMediaChange' SHELL32_CDBurn_OnMediaChange shell32 370 -imp 'SHELL32_CDefFolderMenu_Create2' SHELL32_CDefFolderMenu_Create2 shell32 371 -imp 'SHELL32_CDefFolderMenu_Create2Ex' SHELL32_CDefFolderMenu_Create2Ex shell32 372 -imp 'SHELL32_CDefFolderMenu_MergeMenu' SHELL32_CDefFolderMenu_MergeMenu shell32 373 -imp 'SHELL32_CDrivesContextMenu_Create' SHELL32_CDrivesContextMenu_Create shell32 374 -imp 'SHELL32_CDrivesDropTarget_Create' SHELL32_CDrivesDropTarget_Create shell32 375 -imp 'SHELL32_CDrives_CreateSFVCB' SHELL32_CDrives_CreateSFVCB shell32 376 -imp 'SHELL32_CFSDropTarget_CreateInstance' SHELL32_CFSDropTarget_CreateInstance shell32 377 -imp 'SHELL32_CFSFolderCallback_Create' SHELL32_CFSFolderCallback_Create shell32 378 -imp 'SHELL32_CFillPropertiesTask_CreateInstance' SHELL32_CFillPropertiesTask_CreateInstance shell32 379 -imp 'SHELL32_CLibraryDropTarget_CreateInstance' SHELL32_CLibraryDropTarget_CreateInstance shell32 380 -imp 'SHELL32_CLocationContextMenu_Create' SHELL32_CLocationContextMenu_Create shell32 381 -imp 'SHELL32_CLocationFolderUI_CreateInstance' SHELL32_CLocationFolderUI_CreateInstance shell32 382 -imp 'SHELL32_CMountPoint_DoAutorun' SHELL32_CMountPoint_DoAutorun shell32 383 -imp 'SHELL32_CMountPoint_DoAutorunPrompt' SHELL32_CMountPoint_DoAutorunPrompt shell32 384 -imp 'SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy' SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy shell32 385 -imp 'SHELL32_CMountPoint_ProcessAutoRunFile' SHELL32_CMountPoint_ProcessAutoRunFile shell32 386 -imp 'SHELL32_CMountPoint_WantAutorunUI' SHELL32_CMountPoint_WantAutorunUI shell32 387 -imp 'SHELL32_CMountPoint_WantAutorunUIGetReady' SHELL32_CMountPoint_WantAutorunUIGetReady shell32 388 -imp 'SHELL32_CPL_CategoryIdArrayFromVariant' SHELL32_CPL_CategoryIdArrayFromVariant shell32 389 -imp 'SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey' SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey shell32 390 -imp 'SHELL32_CPL_ModifyWowDisplayName' SHELL32_CPL_ModifyWowDisplayName shell32 391 -imp 'SHELL32_CRecentDocsContextMenu_CreateInstance' SHELL32_CRecentDocsContextMenu_CreateInstance shell32 392 -imp 'SHELL32_CSyncRootManager_CreateInstance' SHELL32_CSyncRootManager_CreateInstance shell32 393 -imp 'SHELL32_CTransferConfirmation_CreateInstance' SHELL32_CTransferConfirmation_CreateInstance shell32 394 -imp 'SHELL32_CallFileCopyHooks' SHELL32_CallFileCopyHooks shell32 395 -imp 'SHELL32_CanDisplayWin8CopyDialog' SHELL32_CanDisplayWin8CopyDialog shell32 396 -imp 'SHELL32_CloseAutoplayPrompt' SHELL32_CloseAutoplayPrompt shell32 397 -imp 'SHELL32_CommandLineFromMsiDescriptor' SHELL32_CommandLineFromMsiDescriptor shell32 398 -imp 'SHELL32_CopyFilePlaceholderToNewFile' SHELL32_CopyFilePlaceholderToNewFile shell32 399 -imp 'SHELL32_CopySecondaryTiles' SHELL32_CopySecondaryTiles shell32 400 -imp 'SHELL32_CreateConfirmationInterrupt' SHELL32_CreateConfirmationInterrupt shell32 401 -imp 'SHELL32_CreateConflictInterrupt' SHELL32_CreateConflictInterrupt shell32 402 -imp 'SHELL32_CreateDefaultOperationDataProvider' SHELL32_CreateDefaultOperationDataProvider shell32 403 -imp 'SHELL32_CreateFileFolderContextMenu' SHELL32_CreateFileFolderContextMenu shell32 404 -imp 'SHELL32_CreateLinkInfo' SHELL32_CreateLinkInfoW shell32 405 -imp 'SHELL32_CreatePlaceholderFile' SHELL32_CreatePlaceholderFile shell32 406 -imp 'SHELL32_CreateQosRecorder' SHELL32_CreateQosRecorder shell32 407 -imp 'SHELL32_CreateSharePointView' SHELL32_CreateSharePointView shell32 408 -imp 'SHELL32_Create_IEnumUICommand' SHELL32_Create_IEnumUICommand shell32 409 -imp 'SHELL32_DestroyLinkInfo' SHELL32_DestroyLinkInfo shell32 410 -imp 'SHELL32_EncryptDirectory' SHELL32_EncryptDirectory shell32 411 -imp 'SHELL32_EncryptedFileKeyInfo' SHELL32_EncryptedFileKeyInfo shell32 412 -imp 'SHELL32_EnumCommonTasks' SHELL32_EnumCommonTasks shell32 413 -imp 'SHELL32_FilePlaceholder_BindToPrimaryStream' SHELL32_FilePlaceholder_BindToPrimaryStream shell32 414 -imp 'SHELL32_FilePlaceholder_CreateInstance' SHELL32_FilePlaceholder_CreateInstance shell32 415 -imp 'SHELL32_FreeEncryptedFileKeyInfo' SHELL32_FreeEncryptedFileKeyInfo shell32 416 -imp 'SHELL32_GenerateAppID' SHELL32_GenerateAppID shell32 417 -imp 'SHELL32_GetAppIDRoot' SHELL32_GetAppIDRoot shell32 418 -imp 'SHELL32_GetCommandProviderForFolderType' SHELL32_GetCommandProviderForFolderType shell32 419 -imp 'SHELL32_GetDPIAdjustedLogicalSize' SHELL32_GetDPIAdjustedLogicalSize shell32 420 -imp 'SHELL32_GetDiskCleanupPath' SHELL32_GetDiskCleanupPath shell32 421 -imp 'SHELL32_GetFileNameFromBrowse' SHELL32_GetFileNameFromBrowse shell32 422 -imp 'SHELL32_GetIconOverlayManager' SHELL32_GetIconOverlayManager shell32 423 -imp 'SHELL32_GetLinkInfoData' SHELL32_GetLinkInfoData shell32 424 -imp 'SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag' SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag shell32 425 -imp 'SHELL32_GetRatingBucket' SHELL32_GetRatingBucket shell32 426 -imp 'SHELL32_GetSkyDriveNetworkStates' SHELL32_GetSkyDriveNetworkStates shell32 427 -imp 'SHELL32_GetSqmableFileName' SHELL32_GetSqmableFileName shell32 428 -imp 'SHELL32_GetThumbnailAdornerFromFactory' SHELL32_GetThumbnailAdornerFromFactory shell32 429 -imp 'SHELL32_GetThumbnailAdornerFromFactory2' SHELL32_GetThumbnailAdornerFromFactory2 shell32 430 -imp 'SHELL32_HandleUnrecognizedFileSystem' SHELL32_HandleUnrecognizedFileSystem shell32 431 -imp 'SHELL32_IconCacheCreate' SHELL32_IconCacheCreate shell32 432 -imp 'SHELL32_IconCacheDestroy' SHELL32_IconCacheDestroy shell32 433 -imp 'SHELL32_IconCacheHandleAssociationChanged' SHELL32_IconCacheHandleAssociationChanged shell32 434 -imp 'SHELL32_IconCacheRestore' SHELL32_IconCacheRestore shell32 435 -imp 'SHELL32_IconCache_AboutToExtractIcons' SHELL32_IconCache_AboutToExtractIcons shell32 436 -imp 'SHELL32_IconCache_DoneExtractingIcons' SHELL32_IconCache_DoneExtractingIcons shell32 437 -imp 'SHELL32_IconCache_ExpandEnvAndSearchPath' SHELL32_IconCache_ExpandEnvAndSearchPath shell32 438 -imp 'SHELL32_IconCache_RememberRecentlyExtractedIcons' SHELL32_IconCache_RememberRecentlyExtractedIconsW shell32 439 -imp 'SHELL32_IconOverlayManagerInit' SHELL32_IconOverlayManagerInit shell32 440 -imp 'SHELL32_IsGetKeyboardLayoutPresent' SHELL32_IsGetKeyboardLayoutPresent shell32 441 -imp 'SHELL32_IsSystemUpgradeInProgress' SHELL32_IsSystemUpgradeInProgress shell32 442 -imp 'SHELL32_IsValidLinkInfo' SHELL32_IsValidLinkInfo shell32 443 -imp 'SHELL32_LegacyEnumSpecialTasksByType' SHELL32_LegacyEnumSpecialTasksByType shell32 444 -imp 'SHELL32_LegacyEnumTasks' SHELL32_LegacyEnumTasks shell32 445 -imp 'SHELL32_LookupBackIconIndex' SHELL32_LookupBackIconIndex shell32 446 -imp 'SHELL32_LookupFrontIconIndex' SHELL32_LookupFrontIconIndex shell32 447 -imp 'SHELL32_NormalizeRating' SHELL32_NormalizeRating shell32 448 -imp 'SHELL32_NotifyLinkTrackingServiceOfMove' SHELL32_NotifyLinkTrackingServiceOfMove shell32 449 -imp 'SHELL32_PifMgr_CloseProperties' SHELL32_PifMgr_CloseProperties shell32 450 -imp 'SHELL32_PifMgr_GetProperties' SHELL32_PifMgr_GetProperties shell32 451 -imp 'SHELL32_PifMgr_OpenProperties' SHELL32_PifMgr_OpenProperties shell32 452 -imp 'SHELL32_PifMgr_SetProperties' SHELL32_PifMgr_SetProperties shell32 453 -imp 'SHELL32_Printers_CreateBindInfo' SHELL32_Printers_CreateBindInfo shell32 454 -imp 'SHELL32_Printjob_GetPidl' SHELL32_Printjob_GetPidl shell32 455 -imp 'SHELL32_PurgeSystemIcon' SHELL32_PurgeSystemIcon shell32 456 -imp 'SHELL32_RefreshOverlayImages' SHELL32_RefreshOverlayImages shell32 457 -imp 'SHELL32_ResolveLinkInfo' SHELL32_ResolveLinkInfoW shell32 458 -imp 'SHELL32_SHAddSparseIcon' SHELL32_SHAddSparseIcon shell32 459 -imp 'SHELL32_SHCreateByValueOperationInterrupt' SHELL32_SHCreateByValueOperationInterrupt shell32 460 -imp 'SHELL32_SHCreateDefaultContextMenu' SHELL32_SHCreateDefaultContextMenu shell32 461 -imp 'SHELL32_SHCreateLocalServer' SHELL32_SHCreateLocalServer shell32 462 -imp 'SHELL32_SHCreateShellFolderView' SHELL32_SHCreateShellFolderView shell32 463 -imp 'SHELL32_SHDuplicateEncryptionInfoFile' SHELL32_SHDuplicateEncryptionInfoFile shell32 464 -imp 'SHELL32_SHEncryptFile' SHELL32_SHEncryptFile shell32 465 -imp 'SHELL32_SHFormatDriveAsync' SHELL32_SHFormatDriveAsync shell32 466 -imp 'SHELL32_SHGetThreadUndoManager' SHELL32_SHGetThreadUndoManager shell32 467 -imp 'SHELL32_SHGetUserName' SHELL32_SHGetUserNameW shell32 468 -imp 'SHELL32_SHIsVirtualDevice' SHELL32_SHIsVirtualDevice shell32 469 -imp 'SHELL32_SHLaunchPropSheet' SHELL32_SHLaunchPropSheet shell32 470 -imp 'SHELL32_SHLogILFromFSIL' SHELL32_SHLogILFromFSIL shell32 471 -imp 'SHELL32_SHOpenWithDialog' SHELL32_SHOpenWithDialog shell32 472 -imp 'SHELL32_SHStartNetConnectionDialog' SHELL32_SHStartNetConnectionDialogW shell32 473 -imp 'SHELL32_SHUICommandFromGUID' SHELL32_SHUICommandFromGUID shell32 474 -imp 'SHELL32_SendToMenu_InvokeTargetedCommand' SHELL32_SendToMenu_InvokeTargetedCommand shell32 475 -imp 'SHELL32_SendToMenu_VerifyTargetedCommand' SHELL32_SendToMenu_VerifyTargetedCommand shell32 476 -imp 'SHELL32_SetPlaceholderReparsePointAttribute' SHELL32_SetPlaceholderReparsePointAttribute shell32 477 -imp 'SHELL32_SetPlaceholderReparsePointAttribute2' SHELL32_SetPlaceholderReparsePointAttribute2 shell32 478 -imp 'SHELL32_ShowHideIconOnlyOnDesktop' SHELL32_ShowHideIconOnlyOnDesktop shell32 479 -imp 'SHELL32_SimpleRatingToFilterCondition' SHELL32_SimpleRatingToFilterCondition shell32 480 -imp 'SHELL32_StampIconForFile' SHELL32_StampIconForFile shell32 481 -imp 'SHELL32_SuspendUndo' SHELL32_SuspendUndo shell32 482 -imp 'SHELL32_TryVirtualDiscImageDriveEject' SHELL32_TryVirtualDiscImageDriveEject shell32 483 -imp 'SHELL32_UpdateFilePlaceholderStates' SHELL32_UpdateFilePlaceholderStates shell32 484 -imp 'SHELL32_VerifySaferTrust' SHELL32_VerifySaferTrust shell32 485 -imp 'SHEmptyRecycleBinA' SHEmptyRecycleBinA shell32 486 -imp 'SHEmptyRecycleBin' SHEmptyRecycleBinW shell32 487 -imp 'SHEnableServiceObject' SHEnableServiceObject shell32 488 -imp 'SHEnumerateUnreadMailAccounts' SHEnumerateUnreadMailAccountsW shell32 489 -imp 'SHEvaluateSystemCommandTemplate' SHEvaluateSystemCommandTemplate shell32 490 -imp 'SHExpandEnvironmentStringsA' SHExpandEnvironmentStringsA KernelBase 1421 -imp 'SHExpandEnvironmentStrings' SHExpandEnvironmentStringsW KernelBase 1422 -imp 'SHExtractIcons' SHExtractIconsW shell32 491 -imp 'SHFileOperationA' SHFileOperationA shell32 493 -imp 'SHFileOperation' SHFileOperationW shell32 494 -imp 'SHFindFiles' SHFindFiles shell32 90 -imp 'SHFind_InitMenuPopup' SHFind_InitMenuPopup shell32 149 -imp 'SHFlushSFCache' SHFlushSFCache shell32 526 -imp 'SHFormatDrive' SHFormatDrive shell32 495 -imp 'SHFree' SHFree shell32 195 -imp 'SHFreeNameMappings' SHFreeNameMappings shell32 496 -imp 'SHGetAttributesFromDataObject' SHGetAttributesFromDataObject shell32 750 -imp 'SHGetDataFromIDListA' SHGetDataFromIDListA shell32 497 -imp 'SHGetDataFromIDList' SHGetDataFromIDListW shell32 498 -imp 'SHGetDesktopFolder' SHGetDesktopFolder shell32 499 -imp 'SHGetDiskFreeSpaceA' SHGetDiskFreeSpaceA shell32 500 -imp 'SHGetDiskFreeSpaceExA' SHGetDiskFreeSpaceExA shell32 501 -imp 'SHGetDiskFreeSpaceEx' SHGetDiskFreeSpaceExW shell32 502 -imp 'SHGetDriveMedia' SHGetDriveMedia shell32 503 -imp 'SHGetFileInfoA' SHGetFileInfoA shell32 505 -imp 'SHGetFileInfo' SHGetFileInfoW shell32 506 -imp 'SHGetFolderLocation' SHGetFolderLocation shell32 507 -imp 'SHGetFolderPathA' SHGetFolderPathA shell32 508 -imp 'SHGetFolderPathAndSubDirA' SHGetFolderPathAndSubDirA shell32 509 -imp 'SHGetFolderPathAndSubDir' SHGetFolderPathAndSubDirW shell32 510 -imp 'SHGetFolderPathEx' SHGetFolderPathEx shell32 511 -imp 'SHGetFolderPath' SHGetFolderPathW shell32 512 -imp 'SHGetIDListFromObject' SHGetIDListFromObject shell32 513 -imp 'SHGetIconOverlayIndexA' SHGetIconOverlayIndexA shell32 514 -imp 'SHGetIconOverlayIndex' SHGetIconOverlayIndexW shell32 515 -imp 'SHGetImageList' SHGetImageList shell32 727 -imp 'SHGetInstanceExplorer' SHGetInstanceExplorer shell32 516 -imp 'SHGetItemFromDataObject' SHGetItemFromDataObject shell32 517 -imp 'SHGetItemFromObject' SHGetItemFromObject shell32 518 -imp 'SHGetKnownFolderIDList' SHGetKnownFolderIDList shell32 519 -imp 'SHGetKnownFolderItem' SHGetKnownFolderItem shell32 527 -imp 'SHGetKnownFolderPath' SHGetKnownFolderPath shell32 528 -imp 'SHGetLocalizedName' SHGetLocalizedName shell32 529 -imp 'SHGetMalloc' SHGetMalloc shell32 530 -imp 'SHGetNameFromIDList' SHGetNameFromIDList shell32 531 -imp 'SHGetNewLinkInfoA' SHGetNewLinkInfoA shell32 179 -imp 'SHGetNewLinkInfo' SHGetNewLinkInfoW shell32 180 -imp 'SHGetPathFromIDListA' SHGetPathFromIDListA shell32 534 -imp 'SHGetPathFromIDListEx' SHGetPathFromIDListEx shell32 535 -imp 'SHGetPathFromIDList' SHGetPathFromIDListW shell32 536 -imp 'SHGetPropertyStoreForWindow' SHGetPropertyStoreForWindow shell32 537 -imp 'SHGetPropertyStoreFromIDList' SHGetPropertyStoreFromIDList shell32 538 -imp 'SHGetPropertyStoreFromParsingName' SHGetPropertyStoreFromParsingName shell32 539 -imp 'SHGetRealIDL' SHGetRealIDL shell32 98 -imp 'SHGetSetFolderCustomSettings' SHGetSetFolderCustomSettings shell32 709 -imp 'SHGetSetSettings' SHGetSetSettings shell32 68 -imp 'SHGetSettings' SHGetSettings shell32 540 -imp 'SHGetSpecialFolderLocation' SHGetSpecialFolderLocation shell32 541 -imp 'SHGetSpecialFolderPathA' SHGetSpecialFolderPathA shell32 542 -imp 'SHGetSpecialFolderPath' SHGetSpecialFolderPathW shell32 543 -imp 'SHGetStockIconInfo' SHGetStockIconInfo shell32 544 -imp 'SHGetTemporaryPropertyForItem' SHGetTemporaryPropertyForItem shell32 545 -imp 'SHGetUnreadMailCount' SHGetUnreadMailCountW shell32 546 -imp 'SHHandleUpdateImage' SHHandleUpdateImage shell32 193 -imp 'SHHelpShortcuts_RunDLL' SHHelpShortcuts_RunDLL shell32 228 -imp 'SHHelpShortcuts_RunDLLA' SHHelpShortcuts_RunDLLA shell32 229 -imp 'SHHelpShortcuts_RunDLLW' SHHelpShortcuts_RunDLLW shell32 238 -imp 'SHILCreateFromPath' SHILCreateFromPath shell32 28 -imp 'SHInvokePrinterCommandA' SHInvokePrinterCommandA shell32 547 -imp 'SHInvokePrinterCommand' SHInvokePrinterCommandW shell32 548 -imp 'SHIsFileAvailableOffline' SHIsFileAvailableOffline shell32 549 -imp 'SHLimitInputEdit' SHLimitInputEdit shell32 747 -imp 'SHLoadInProc' SHLoadInProc shell32 550 -imp 'SHLoadIndirectString' SHLoadIndirectString KernelBase 1423 -imp 'SHLoadIndirectStringInternal' SHLoadIndirectStringInternal KernelBase 1424 -imp 'SHLoadNonloadedIconOverlayIdentifiers' SHLoadNonloadedIconOverlayIdentifiers shell32 551 -imp 'SHMapPIDLToSystemImageListIndex' SHMapPIDLToSystemImageListIndex shell32 77 -imp 'SHMultiFileProperties' SHMultiFileProperties shell32 716 -imp 'SHObjectProperties' SHObjectProperties shell32 178 -imp 'SHOpenFolderAndSelectItems' SHOpenFolderAndSelectItems shell32 552 -imp 'SHOpenPropSheet' SHOpenPropSheetW shell32 80 -imp 'SHOpenWithDialog' SHOpenWithDialog shell32 553 -imp 'SHParseDisplayName' SHParseDisplayName shell32 554 -imp 'SHPathPrepareForWriteA' SHPathPrepareForWriteA shell32 555 -imp 'SHPathPrepareForWrite' SHPathPrepareForWriteW shell32 556 -imp 'SHPropStgCreate' SHPropStgCreate shell32 685 -imp 'SHPropStgReadMultiple' SHPropStgReadMultiple shell32 688 -imp 'SHPropStgWriteMultiple' SHPropStgWriteMultiple shell32 689 -imp 'SHQueryRecycleBinA' SHQueryRecycleBinA shell32 557 -imp 'SHQueryRecycleBin' SHQueryRecycleBinW shell32 558 -imp 'SHQueryUserNotificationState' SHQueryUserNotificationState shell32 559 -imp 'SHRegCloseUSKey' SHRegCloseUSKey KernelBase 1425 -imp 'SHRegCreateUSKeyA' SHRegCreateUSKeyA KernelBase 1426 -imp 'SHRegCreateUSKey' SHRegCreateUSKeyW KernelBase 1427 -imp 'SHRegDeleteEmptyUSKeyA' SHRegDeleteEmptyUSKeyA KernelBase 1428 -imp 'SHRegDeleteEmptyUSKey' SHRegDeleteEmptyUSKeyW KernelBase 1429 -imp 'SHRegDeleteUSValueA' SHRegDeleteUSValueA KernelBase 1430 -imp 'SHRegDeleteUSValue' SHRegDeleteUSValueW KernelBase 1431 -imp 'SHRegEnumUSKeyA' SHRegEnumUSKeyA KernelBase 1432 -imp 'SHRegEnumUSKey' SHRegEnumUSKeyW KernelBase 1433 -imp 'SHRegEnumUSValueA' SHRegEnumUSValueA KernelBase 1434 -imp 'SHRegEnumUSValue' SHRegEnumUSValueW KernelBase 1435 -imp 'SHRegGetBoolUSValueA' SHRegGetBoolUSValueA KernelBase 1436 -imp 'SHRegGetBoolUSValue' SHRegGetBoolUSValueW KernelBase 1437 -imp 'SHRegGetUSValueA' SHRegGetUSValueA KernelBase 1438 -imp 'SHRegGetUSValue' SHRegGetUSValueW KernelBase 1439 -imp 'SHRegOpenUSKeyA' SHRegOpenUSKeyA KernelBase 1440 -imp 'SHRegOpenUSKey' SHRegOpenUSKeyW KernelBase 1441 -imp 'SHRegQueryInfoUSKeyA' SHRegQueryInfoUSKeyA KernelBase 1442 -imp 'SHRegQueryInfoUSKey' SHRegQueryInfoUSKeyW KernelBase 1443 -imp 'SHRegQueryUSValueA' SHRegQueryUSValueA KernelBase 1444 -imp 'SHRegQueryUSValue' SHRegQueryUSValueW KernelBase 1445 -imp 'SHRegSetUSValueA' SHRegSetUSValueA KernelBase 1446 -imp 'SHRegSetUSValue' SHRegSetUSValueW KernelBase 1447 -imp 'SHRegWriteUSValueA' SHRegWriteUSValueA KernelBase 1448 -imp 'SHRegWriteUSValue' SHRegWriteUSValueW KernelBase 1449 -imp 'SHRemoveLocalizedName' SHRemoveLocalizedName shell32 560 -imp 'SHReplaceFromPropSheetExtArray' SHReplaceFromPropSheetExtArray shell32 170 -imp 'SHResolveLibrary' SHResolveLibrary shell32 561 -imp 'SHRestricted' SHRestricted shell32 100 -imp 'SHSetDefaultProperties' SHSetDefaultProperties shell32 562 -imp 'SHSetFolderPathA' SHSetFolderPathA shell32 231 -imp 'SHSetFolderPath' SHSetFolderPathW shell32 232 -imp 'SHSetInstanceExplorer' SHSetInstanceExplorer shell32 176 -imp 'SHSetKnownFolderPath' SHSetKnownFolderPath shell32 563 -imp 'SHSetLocalizedName' SHSetLocalizedName shell32 564 -imp 'SHSetTemporaryPropertyForItem' SHSetTemporaryPropertyForItem shell32 565 -imp 'SHSetUnreadMailCount' SHSetUnreadMailCountW shell32 566 -imp 'SHShellFolderView_Message' SHShellFolderView_Message shell32 73 -imp 'SHShowManageLibraryUI' SHShowManageLibraryUI shell32 567 -imp 'SHSimpleIDListFromPath' SHSimpleIDListFromPath shell32 162 -imp 'SHStartNetConnectionDialog' SHStartNetConnectionDialogW shell32 14 -imp 'SHTestTokenMembership' SHTestTokenMembership shell32 245 -imp 'SHTruncateString' SHTruncateString KernelBase 1450 -imp 'SHUpdateImageA' SHUpdateImageA shell32 191 -imp 'SHUpdateImage' SHUpdateImageW shell32 192 -imp 'SHUpdateRecycleBinIcon' SHUpdateRecycleBinIcon shell32 568 -imp 'SHValidateUNC' SHValidateUNC shell32 173 -imp 'STROBJ_bEnum' STROBJ_bEnum gdi32 1810 -imp 'STROBJ_bEnumPositionsOnly' STROBJ_bEnumPositionsOnly gdi32 1811 -imp 'STROBJ_bGetAdvanceWidths' STROBJ_bGetAdvanceWidths gdi32 1812 -imp 'STROBJ_dwGetCodePage' STROBJ_dwGetCodePage gdi32 1813 -imp 'STROBJ_vEnumStart' STROBJ_vEnumStart gdi32 1814 -imp 'SafeBaseRegGetKeySecurity' SafeBaseRegGetKeySecurity advapi32 1707 -imp 'SaferCloseLevel' SaferCloseLevel advapi32 1708 -imp 'SaferComputeTokenFromLevel' SaferComputeTokenFromLevel advapi32 1709 -imp 'SaferCreateLevel' SaferCreateLevel advapi32 1710 -imp 'SaferGetLevelInformation' SaferGetLevelInformation advapi32 1711 -imp 'SaferGetPolicyInformation' SaferGetPolicyInformation advapi32 1712 -imp 'SaferIdentifyLevel' SaferIdentifyLevel advapi32 1713 -imp 'SaferRecordEventLogEntry' SaferRecordEventLogEntry advapi32 1714 -imp 'SaferSetLevelInformation' SaferSetLevelInformation advapi32 1715 -imp 'SaferSetPolicyInformation' SaferSetPolicyInformation advapi32 1716 -imp 'SaferiChangeRegistryScope' SaferiChangeRegistryScope advapi32 1717 -imp 'SaferiCompareTokenLevels' SaferiCompareTokenLevels advapi32 1718 -imp 'SaferiIsDllAllowed' SaferiIsDllAllowed advapi32 1719 -imp 'SaferiIsExecutableFileType' SaferiIsExecutableFileType advapi32 1720 -imp 'SaferiPopulateDefaultsInRegistry' SaferiPopulateDefaultsInRegistry advapi32 1721 -imp 'SaferiRecordEventLogEntry' SaferiRecordEventLogEntry advapi32 1722 -imp 'SaferiSearchMatchingHashRules' SaferiSearchMatchingHashRules advapi32 1723 -imp 'SaveAlternatePackageRootPath' SaveAlternatePackageRootPath KernelBase 1451 -imp 'SaveDC' SaveDC gdi32 1815 1 -imp 'SaveStateRootFolderPath' SaveStateRootFolderPath KernelBase 1452 imp 'SbExecuteProcedure' SbExecuteProcedure ntdll 1610 imp 'SbSelectProcedure' SbSelectProcedure ntdll 1611 -imp 'ScaleRgn' ScaleRgn gdi32 1816 -imp 'ScaleValues' ScaleValues gdi32 1817 -imp 'ScaleViewportExtEx' ScaleViewportExtEx gdi32 1818 -imp 'ScaleWindowExtEx' ScaleWindowExtEx gdi32 1819 -imp 'ScreenToClient' ScreenToClient user32 2291 -imp 'ScrollChildren' ScrollChildren user32 2292 -imp 'ScrollConsoleScreenBufferA' ScrollConsoleScreenBufferA kernel32 0 # KernelBase -imp 'ScrollConsoleScreenBuffer' ScrollConsoleScreenBufferW kernel32 0 # KernelBase -imp 'ScrollDC' ScrollDC user32 2293 -imp 'ScrollWindow' ScrollWindow user32 2294 -imp 'ScrollWindowEx' ScrollWindowEx user32 2295 -imp 'SearchPathA' SearchPathA kernel32 0 # KernelBase -imp 'SearchPath' SearchPathW kernel32 0 # KernelBase -imp 'SelectBrushLocal' SelectBrushLocal gdi32 1860 -imp 'SelectClipPath' SelectClipPath gdi32 1861 -imp 'SelectClipRgn' SelectClipRgn gdi32 1862 -imp 'SelectFontLocal' SelectFontLocal gdi32 1863 -imp 'SelectObject' SelectObject gdi32 1864 2 -imp 'SelectPalette' SelectPalette gdi32 1865 -imp 'SendDlgItemMessageA' SendDlgItemMessageA user32 2296 -imp 'SendDlgItemMessage' SendDlgItemMessageW user32 2297 -imp 'SendIMEMessageExA' SendIMEMessageExA user32 2298 -imp 'SendIMEMessageEx' SendIMEMessageExW user32 2299 -imp 'SendInput' SendInput user32 2300 -imp 'SendMessageA' SendMessageA user32 2301 -imp 'SendMessageCallbackA' SendMessageCallbackA user32 2302 -imp 'SendMessageCallback' SendMessageCallbackW user32 2303 -imp 'SendMessageTimeoutA' SendMessageTimeoutA user32 2304 -imp 'SendMessageTimeout' SendMessageTimeoutW user32 2305 -imp 'SendMessage' SendMessageW user32 2306 4 -imp 'SendNotifyMessageA' SendNotifyMessageA user32 2307 -imp 'SendNotifyMessage' SendNotifyMessageW user32 2308 -imp 'SetAbortProc' SetAbortProc gdi32 1866 -imp 'SetAclInformation' SetAclInformation advapi32 0 # KernelBase -imp 'SetActiveWindow' SetActiveWindow user32 2309 -imp 'SetAddrInfoExA' SetAddrInfoExA ws2_32 37 -imp 'SetAddrInfoEx' SetAddrInfoExW ws2_32 38 -imp 'SetArcDirection' SetArcDirection gdi32 1867 -imp 'SetBitmapAttributes' SetBitmapAttributes gdi32 1868 -imp 'SetBitmapBits' SetBitmapBits gdi32 1869 -imp 'SetBitmapDimensionEx' SetBitmapDimensionEx gdi32 1870 -imp 'SetBkColor' SetBkColor gdi32 1871 -imp 'SetBkMode' SetBkMode gdi32 1872 2 -imp 'SetBoundsRect' SetBoundsRect gdi32 1873 -imp 'SetBrushAttributes' SetBrushAttributes gdi32 1874 -imp 'SetBrushOrgEx' SetBrushOrgEx gdi32 1875 -imp 'SetCachedSigningLevel' SetCachedSigningLevel KernelBase 1458 -imp 'SetCalendarInfoA' SetCalendarInfoA kernel32 1249 -imp 'SetCalendarInfo' SetCalendarInfoW kernel32 0 # KernelBase -imp 'SetCapture' SetCapture user32 2310 1 -imp 'SetCaretBlinkTime' SetCaretBlinkTime user32 2311 -imp 'SetCaretPos' SetCaretPos user32 2312 -imp 'SetClassLongA' SetClassLongA user32 2313 3 -imp 'SetClassLongPtrA' SetClassLongPtrA user32 2314 -imp 'SetClassLongPtr' SetClassLongPtrW user32 2315 -imp 'SetClassLong' SetClassLongW user32 2316 3 -imp 'SetClassWord' SetClassWord user32 2317 -imp 'SetClientDynamicTimeZoneInformation' SetClientDynamicTimeZoneInformation KernelBase 1460 -imp 'SetClientTimeZoneInformation' SetClientTimeZoneInformation KernelBase 1461 -imp 'SetClipboardData' SetClipboardData user32 2318 -imp 'SetClipboardViewer' SetClipboardViewer user32 2319 -imp 'SetCoalescableTimer' SetCoalescableTimer user32 2320 -imp 'SetColorAdjustment' SetColorAdjustment gdi32 1876 -imp 'SetColorSpace' SetColorSpace gdi32 1877 -imp 'SetComPlusPackageInstallStatus' SetComPlusPackageInstallStatus kernel32 1251 -imp 'SetCommBreak' SetCommBreak kernel32 0 # KernelBase -imp 'SetCommConfig' SetCommConfig kernel32 0 # KernelBase -imp 'SetCommMask' SetCommMask kernel32 0 # KernelBase -imp 'SetCommState' SetCommState kernel32 0 # KernelBase -imp 'SetCommTimeouts' SetCommTimeouts kernel32 0 # KernelBase -imp 'SetComputerNameA' SetComputerNameA kernel32 0 # KernelBase -imp 'SetComputerNameEx2W' SetComputerNameEx2W KernelBase 1468 -imp 'SetComputerNameExA' SetComputerNameExA kernel32 0 # KernelBase -imp 'SetComputerNameEx' SetComputerNameExW kernel32 0 # KernelBase -imp 'SetComputerName' SetComputerNameW kernel32 0 # KernelBase -imp 'SetConsoleActiveScreenBuffer' SetConsoleActiveScreenBuffer kernel32 0 1 # TODO(jart): 6.2 and higher # KernelBase -imp 'SetConsoleCP' SetConsoleCP kernel32 0 1 # TODO(jart): 6.2 and higher # KernelBase -imp 'SetConsoleCtrlHandler' SetConsoleCtrlHandler kernel32 0 2 # KernelBase -imp 'SetConsoleCursor' SetConsoleCursor kernel32 1265 -imp 'SetConsoleCursorInfo' SetConsoleCursorInfo kernel32 0 2 # KernelBase -imp 'SetConsoleCursorMode' SetConsoleCursorMode kernel32 1267 -imp 'SetConsoleCursorPosition' SetConsoleCursorPosition kernel32 0 2 # KernelBase -imp 'SetConsoleDisplayMode' SetConsoleDisplayMode kernel32 0 # KernelBase -imp 'SetConsoleFont' SetConsoleFont kernel32 1270 -imp 'SetConsoleHardwareState' SetConsoleHardwareState kernel32 1271 -imp 'SetConsoleHistoryInfo' SetConsoleHistoryInfo kernel32 0 # KernelBase -imp 'SetConsoleIcon' SetConsoleIcon kernel32 1273 -imp 'SetConsoleInputExeNameA' SetConsoleInputExeNameA KernelBase 1479 -imp 'SetConsoleInputExeName' SetConsoleInputExeNameW KernelBase 1480 -imp 'SetConsoleKeyShortcuts' SetConsoleKeyShortcuts kernel32 1276 -imp 'SetConsoleLocalEUDC' SetConsoleLocalEUDC kernel32 1277 -imp 'SetConsoleMaximumWindowSize' SetConsoleMaximumWindowSize kernel32 1278 -imp 'SetConsoleMenuClose' SetConsoleMenuClose kernel32 1279 -imp 'SetConsoleMode' SetConsoleMode kernel32 0 2 # KernelBase -imp 'SetConsoleNlsMode' SetConsoleNlsMode kernel32 1281 -imp 'SetConsoleNumberOfCommandsA' SetConsoleNumberOfCommandsA KernelBase 1482 -imp 'SetConsoleNumberOfCommands' SetConsoleNumberOfCommandsW KernelBase 1483 -imp 'SetConsoleOS2OemFormat' SetConsoleOS2OemFormat kernel32 1284 -imp 'SetConsoleOutputCP' SetConsoleOutputCP kernel32 0 1 # KernelBase -imp 'SetConsolePalette' SetConsolePalette kernel32 1286 -imp 'SetConsoleScreenBufferInfoEx' SetConsoleScreenBufferInfoEx kernel32 0 2 # KernelBase -imp 'SetConsoleScreenBufferSize' SetConsoleScreenBufferSize kernel32 0 2 # KernelBase -imp 'SetConsoleTextAttribute' SetConsoleTextAttribute kernel32 0 # KernelBase -imp 'SetConsoleTitle' SetConsoleTitleW kernel32 0 1 # KernelBase -imp 'SetConsoleTitleA' SetConsoleTitleA kernel32 0 1 # KernelBase -imp 'SetConsoleWindowInfo' SetConsoleWindowInfo kernel32 0 3 # KernelBase -imp 'SetCoreWindow' SetCoreWindow user32 2571 -imp 'SetCurrentConsoleFontEx' SetCurrentConsoleFontEx kernel32 0 # KernelBase -imp 'SetCurrentDirectory' SetCurrentDirectoryW kernel32 0 1 # KernelBase -imp 'SetCurrentDirectoryA' SetCurrentDirectoryA kernel32 0 1 # KernelBase -imp 'SetCurrentProcessExplicitAppUserModelID' SetCurrentProcessExplicitAppUserModelID shell32 569 -imp 'SetCursor' SetCursor user32 2321 1 -imp 'SetCursorContents' SetCursorContents user32 2322 -imp 'SetCursorPos' SetCursorPos user32 2323 -imp 'SetDCBrushColor' SetDCBrushColor gdi32 1878 -imp 'SetDCDpiScaleValue' SetDCDpiScaleValue gdi32 1879 -imp 'SetDCPenColor' SetDCPenColor gdi32 1880 -imp 'SetDIBColorTable' SetDIBColorTable gdi32 1881 -imp 'SetDIBits' SetDIBits gdi32 1882 -imp 'SetDIBitsToDevice' SetDIBitsToDevice gdi32 1883 -imp 'SetDebugErrorLevel' SetDebugErrorLevel user32 2324 -imp 'SetDefaultCommConfigA' SetDefaultCommConfigA kernel32 1297 -imp 'SetDefaultCommConfig' SetDefaultCommConfigW kernel32 1298 -imp 'SetDefaultDllDirectories' SetDefaultDllDirectories kernel32 0 1 # KernelBase, Windows 8+, KB2533623 on Windows 7 -imp 'SetDeskWallpaper' SetDeskWallpaper user32 2325 -imp 'SetDesktopColorTransform' SetDesktopColorTransform user32 2326 -imp 'SetDeviceGammaRamp' SetDeviceGammaRamp gdi32 1884 -imp 'SetDialogControlDpiChangeBehavior' SetDialogControlDpiChangeBehavior user32 2327 -imp 'SetDialogDpiChangeBehavior' SetDialogDpiChangeBehavior user32 2328 -imp 'SetDisplayAutoRotationPreferences' SetDisplayAutoRotationPreferences user32 2329 -imp 'SetDisplayConfig' SetDisplayConfig user32 2330 -imp 'SetDlgItemInt' SetDlgItemInt user32 2331 -imp 'SetDlgItemTextA' SetDlgItemTextA user32 2332 -imp 'SetDlgItemText' SetDlgItemTextW user32 2333 -imp 'SetDllDirectoryA' SetDllDirectoryA kernel32 1300 -imp 'SetDllDirectory' SetDllDirectoryW kernel32 1301 -imp 'SetDoubleClickTime' SetDoubleClickTime user32 2334 -imp 'SetDynamicTimeZoneInformation' SetDynamicTimeZoneInformation kernel32 0 # KernelBase -imp 'SetEncryptedFileMetadata' SetEncryptedFileMetadata advapi32 1725 -imp 'SetEndOfFile' SetEndOfFile kernel32 0 1 # KernelBase -imp 'SetEnhMetaFileBits' SetEnhMetaFileBits gdi32 1885 -imp 'SetEntriesInAccessListA' SetEntriesInAccessListA advapi32 1726 -imp 'SetEntriesInAccessList' SetEntriesInAccessListW advapi32 1727 -imp 'SetEntriesInAclA' SetEntriesInAclA advapi32 1728 -imp 'SetEntriesInAcl' SetEntriesInAclW advapi32 1729 -imp 'SetEntriesInAuditListA' SetEntriesInAuditListA advapi32 1730 -imp 'SetEntriesInAuditList' SetEntriesInAuditListW advapi32 1731 -imp 'SetEnvironmentStrings' SetEnvironmentStringsW KernelBase 1498 1 -imp 'SetEnvironmentStringsA' SetEnvironmentStringsA kernel32 1304 1 -imp 'SetEnvironmentVariable' SetEnvironmentVariableW kernel32 0 2 # KernelBase -imp 'SetEnvironmentVariableA' SetEnvironmentVariableA kernel32 0 2 # KernelBase -imp 'SetErrorMode' SetErrorMode kernel32 0 1 # KernelBase -imp 'SetEvent' SetEvent kernel32 0 1 # KernelBase -imp 'SetExtensionProperty' SetExtensionProperty KernelBase 1504 -imp 'SetFeatureReportResponse' SetFeatureReportResponse user32 2335 -imp 'SetFileApisToANSI' SetFileApisToANSI kernel32 0 # KernelBase -imp 'SetFileApisToOEM' SetFileApisToOEM kernel32 0 # KernelBase -imp 'SetFileAttributes' SetFileAttributesW kernel32 0 2 # KernelBase -imp 'SetFileAttributesA' SetFileAttributesA kernel32 0 2 # KernelBase -imp 'SetFileAttributesTransactedA' SetFileAttributesTransactedA kernel32 1314 -imp 'SetFileAttributesTransacted' SetFileAttributesTransactedW kernel32 1315 -imp 'SetFileBandwidthReservation' SetFileBandwidthReservation kernel32 1317 -imp 'SetFileCompletionNotificationModes' SetFileCompletionNotificationModes kernel32 1318 2 -imp 'SetFileInformationByHandle' SetFileInformationByHandle kernel32 0 # KernelBase -imp 'SetFileIoOverlappedRange' SetFileIoOverlappedRange kernel32 0 # KernelBase -imp 'SetFilePointer' SetFilePointer kernel32 0 4 # KernelBase -imp 'SetFilePointerEx' SetFilePointerEx kernel32 0 4 # KernelBase -imp 'SetFileSecurityA' SetFileSecurityA advapi32 1732 -imp 'SetFileSecurity' SetFileSecurityW advapi32 0 # KernelBase -imp 'SetFileShortNameA' SetFileShortNameA kernel32 1323 -imp 'SetFileShortName' SetFileShortNameW kernel32 1324 -imp 'SetFileTime' SetFileTime kernel32 0 4 # KernelBase -imp 'SetFileValidData' SetFileValidData kernel32 0 2 # KernelBase -imp 'SetFirmwareEnvironmentVariableA' SetFirmwareEnvironmentVariableA kernel32 1327 -imp 'SetFirmwareEnvironmentVariableExA' SetFirmwareEnvironmentVariableExA kernel32 1328 -imp 'SetFirmwareEnvironmentVariableEx' SetFirmwareEnvironmentVariableExW kernel32 1329 -imp 'SetFirmwareEnvironmentVariable' SetFirmwareEnvironmentVariableW kernel32 1330 -imp 'SetFocus' SetFocus user32 2336 -imp 'SetFontEnumeration' SetFontEnumeration gdi32 1886 -imp 'SetForegroundWindow' SetForegroundWindow user32 2337 -imp 'SetGestureConfig' SetGestureConfig user32 2338 -imp 'SetGraphicsMode' SetGraphicsMode gdi32 1887 -imp 'SetHandleCount' SetHandleCount kernel32 0 1 # KernelBase -imp 'SetHandleInformation' SetHandleInformation kernel32 0 3 # KernelBase -imp 'SetICMMode' SetICMMode gdi32 1888 -imp 'SetICMProfileA' SetICMProfileA gdi32 1889 -imp 'SetICMProfile' SetICMProfileW gdi32 1890 -imp 'SetInformationCodeAuthzLevel' SetInformationCodeAuthzLevelW advapi32 1734 -imp 'SetInformationCodeAuthzPolicy' SetInformationCodeAuthzPolicyW advapi32 1735 -imp 'SetInformationJobObject' SetInformationJobObject kernel32 1333 -imp 'SetInternalWindowPos' SetInternalWindowPos user32 2339 -imp 'SetIoRateControlInformationJobObject' SetIoRateControlInformationJobObject kernel32 1334 -imp 'SetIsDeveloperModeEnabled' SetIsDeveloperModeEnabled KernelBase 1518 -imp 'SetIsSideloadingEnabled' SetIsSideloadingEnabled KernelBase 1519 -imp 'SetKernelObjectSecurity' SetKernelObjectSecurity advapi32 0 # KernelBase -imp 'SetKeyboardState' SetKeyboardState user32 2340 -imp 'SetLastConsoleEventActive' SetLastConsoleEventActive KernelBase 1521 -imp 'SetLastError' SetLastError kernel32 1336 1 -imp 'SetLastErrorEx' SetLastErrorEx user32 2341 -imp 'SetLayeredWindowAttributes' SetLayeredWindowAttributes user32 2342 -imp 'SetLayout' SetLayout gdi32 1891 -imp 'SetLayoutWidth' SetLayoutWidth gdi32 1892 -imp 'SetLocalPrimaryComputerNameA' SetLocalPrimaryComputerNameA kernel32 1337 -imp 'SetLocalPrimaryComputerName' SetLocalPrimaryComputerNameW kernel32 1338 -imp 'SetLocalTime' SetLocalTime kernel32 0 # KernelBase -imp 'SetLocaleInfoA' SetLocaleInfoA kernel32 1340 -imp 'SetLocaleInfo' SetLocaleInfoW kernel32 0 # KernelBase -imp 'SetMagicColors' SetMagicColors gdi32 1893 -imp 'SetMagnificationDesktopColorEffect' SetMagnificationDesktopColorEffect user32 2343 -imp 'SetMagnificationDesktopMagnification' SetMagnificationDesktopMagnification user32 2344 -imp 'SetMagnificationDesktopSamplingMode' SetMagnificationDesktopSamplingMode user32 2345 -imp 'SetMagnificationLensCtxInformation' SetMagnificationLensCtxInformation user32 2346 -imp 'SetMailslotInfo' SetMailslotInfo kernel32 1342 -imp 'SetMapMode' SetMapMode gdi32 1894 -imp 'SetMapperFlags' SetMapperFlags gdi32 1895 -imp 'SetMenu' SetMenu user32 2347 -imp 'SetMenuContextHelpId' SetMenuContextHelpId user32 2348 -imp 'SetMenuDefaultItem' SetMenuDefaultItem user32 2349 -imp 'SetMenuInfo' SetMenuInfo user32 2350 -imp 'SetMenuItemBitmaps' SetMenuItemBitmaps user32 2351 -imp 'SetMenuItemInfoA' SetMenuItemInfoA user32 2352 -imp 'SetMenuItemInfo' SetMenuItemInfoW user32 2353 -imp 'SetMessageExtraInfo' SetMessageExtraInfo user32 2354 -imp 'SetMessageQueue' SetMessageQueue user32 2355 -imp 'SetMessageWaitingIndicator' SetMessageWaitingIndicator kernel32 1343 -imp 'SetMetaFileBitsEx' SetMetaFileBitsEx gdi32 1896 -imp 'SetMetaRgn' SetMetaRgn gdi32 1897 -imp 'SetMirrorRendering' SetMirrorRendering user32 2356 -imp 'SetMiterLimit' SetMiterLimit gdi32 1898 -imp 'SetNamedPipeAttribute' SetNamedPipeAttribute kernel32 1344 -imp 'SetNamedPipeHandleState' SetNamedPipeHandleState kernel32 0 4 # KernelBase -imp 'SetNamedSecurityInfoA' SetNamedSecurityInfoA advapi32 1737 -imp 'SetNamedSecurityInfoExA' SetNamedSecurityInfoExA advapi32 1738 -imp 'SetNamedSecurityInfoEx' SetNamedSecurityInfoExW advapi32 1739 -imp 'SetNamedSecurityInfo' SetNamedSecurityInfoW advapi32 1740 -imp 'SetOPMSigningKeyAndSequenceNumbers' SetOPMSigningKeyAndSequenceNumbers gdi32 1899 -imp 'SetPaletteEntries' SetPaletteEntries gdi32 1900 -imp 'SetParent' SetParent user32 2357 2 -imp 'SetPhysicalCursorPos' SetPhysicalCursorPos user32 2358 -imp 'SetPixel' SetPixel gdi32 1901 4 -imp 'SetPixelFormat' SetPixelFormat gdi32 1902 3 -imp 'SetPixelV' SetPixelV gdi32 1903 -imp 'SetPolyFillMode' SetPolyFillMode gdi32 1904 -imp 'SetPriorityClass' SetPriorityClass kernel32 0 2 # KernelBase -imp 'SetPrivateObjectSecurity' SetPrivateObjectSecurity advapi32 0 # KernelBase -imp 'SetPrivateObjectSecurityEx' SetPrivateObjectSecurityEx advapi32 0 # KernelBase -imp 'SetProcessAffinityMask' SetProcessAffinityMask kernel32 1347 2 -imp 'SetProcessAffinityUpdateMode' SetProcessAffinityUpdateMode kernel32 0 # KernelBase -imp 'SetProcessDEPPolicy' SetProcessDEPPolicy kernel32 1349 -imp 'SetProcessDPIAware' SetProcessDPIAware user32 2359 -imp 'SetProcessDefaultCpuSets' SetProcessDefaultCpuSets kernel32 0 # KernelBase -imp 'SetProcessDefaultLayout' SetProcessDefaultLayout user32 2360 -imp 'SetProcessDpiAwarenessContext' SetProcessDpiAwarenessContext user32 2361 -imp 'SetProcessDpiAwarenessInternal' SetProcessDpiAwarenessInternal user32 2362 -imp 'SetProcessGroupAffinity' SetProcessGroupAffinity KernelBase 1531 -imp 'SetProcessInformation' SetProcessInformation kernel32 0 # KernelBase -imp 'SetProcessMitigationPolicy' SetProcessMitigationPolicy kernel32 0 # KernelBase -imp 'SetProcessPreferredUILanguages' SetProcessPreferredUILanguages kernel32 0 # KernelBase -imp 'SetProcessPriorityBoost' SetProcessPriorityBoost kernel32 0 2 # KernelBase -imp 'SetProcessRestrictionExemption' SetProcessRestrictionExemption user32 2363 -imp 'SetProcessShutdownParameters' SetProcessShutdownParameters kernel32 0 # KernelBase -imp 'SetProcessValidCallTargets' SetProcessValidCallTargets KernelBase 1537 -imp 'SetProcessWindowStation' SetProcessWindowStation user32 2364 -imp 'SetProcessWorkingSetSize' SetProcessWorkingSetSize kernel32 1356 3 -imp 'SetProcessWorkingSetSizeEx' SetProcessWorkingSetSizeEx kernel32 0 4 # KernelBase -imp 'SetProgmanWindow' SetProgmanWindow user32 2365 -imp 'SetPropA' SetPropA user32 2366 -imp 'SetProp' SetPropW user32 2367 -imp 'SetProtectedPolicy' SetProtectedPolicy kernel32 0 # KernelBase -imp 'SetProtocolProperty' SetProtocolProperty KernelBase 1540 -imp 'SetROP2' SetROP2 gdi32 1905 -imp 'SetRect' SetRect user32 2368 -imp 'SetRectEmpty' SetRectEmpty user32 2369 -imp 'SetRectRgn' SetRectRgn gdi32 1906 -imp 'SetRelAbs' SetRelAbs gdi32 1907 -imp 'SetRoamingLastObservedChangeTime' SetRoamingLastObservedChangeTime KernelBase 1541 -imp 'SetScrollInfo' SetScrollInfo user32 2370 -imp 'SetScrollPos' SetScrollPos user32 2371 -imp 'SetScrollRange' SetScrollRange user32 2372 -imp 'SetSearchPathMode' SetSearchPathMode kernel32 1359 -imp 'SetSecurityAccessMask' SetSecurityAccessMask advapi32 0 # KernelBase -imp 'SetSecurityDescriptorControl' SetSecurityDescriptorControl advapi32 0 # KernelBase -imp 'SetSecurityDescriptorDacl' SetSecurityDescriptorDacl advapi32 0 # KernelBase -imp 'SetSecurityDescriptorGroup' SetSecurityDescriptorGroup advapi32 0 # KernelBase -imp 'SetSecurityDescriptorOwner' SetSecurityDescriptorOwner advapi32 0 # KernelBase -imp 'SetSecurityDescriptorRMControl' SetSecurityDescriptorRMControl advapi32 0 # KernelBase -imp 'SetSecurityDescriptorSacl' SetSecurityDescriptorSacl advapi32 0 # KernelBase -imp 'SetSecurityInfo' SetSecurityInfo advapi32 1750 -imp 'SetSecurityInfoExA' SetSecurityInfoExA advapi32 1751 -imp 'SetSecurityInfoEx' SetSecurityInfoExW advapi32 1752 -imp 'SetServiceBits' SetServiceBits advapi32 1753 -imp 'SetServiceObjectSecurity' SetServiceObjectSecurity advapi32 1754 -imp 'SetServiceStatus' SetServiceStatus advapi32 1755 -imp 'SetShellWindow' SetShellWindow user32 2373 -imp 'SetShellWindowEx' SetShellWindowEx user32 2374 -imp 'SetStateVersion' SetStateVersion KernelBase 1549 -imp 'SetStdHandle' SetStdHandle kernel32 0 2 # KernelBase -imp 'SetStdHandleEx' SetStdHandleEx KernelBase 1551 -imp 'SetStretchBltMode' SetStretchBltMode gdi32 1908 -imp 'SetSuspendState' SetSuspendState PowerProf 0 3 -imp 'SetSysColors' SetSysColors user32 2375 -imp 'SetSysColorsTemp' SetSysColorsTemp user32 2376 -imp 'SetSystemCursor' SetSystemCursor user32 2377 -imp 'SetSystemFileCacheSize' SetSystemFileCacheSize kernel32 0 # KernelBase -imp 'SetSystemMenu' SetSystemMenu user32 2378 -imp 'SetSystemPaletteUse' SetSystemPaletteUse gdi32 1909 -imp 'SetSystemPowerState' SetSystemPowerState kernel32 1363 -imp 'SetSystemTime' SetSystemTime kernel32 0 # KernelBase -imp 'SetSystemTimeAdjustment' SetSystemTimeAdjustment kernel32 0 # KernelBase -imp 'SetSystemTimeAdjustmentPrecise' SetSystemTimeAdjustmentPrecise KernelBase 1555 -imp 'SetTapeParameters' SetTapeParameters kernel32 1366 -imp 'SetTapePosition' SetTapePosition kernel32 1367 -imp 'SetTaskmanWindow' SetTaskmanWindow user32 2379 -imp 'SetTermsrvAppInstallMode' SetTermsrvAppInstallMode kernel32 1368 -imp 'SetTextAlign' SetTextAlign gdi32 1910 2 -imp 'SetTextCharacterExtra' SetTextCharacterExtra gdi32 1911 -imp 'SetTextColor' SetTextColor gdi32 1912 2 -imp 'SetTextJustification' SetTextJustification gdi32 1913 3 -imp 'SetThreadAffinityMask' SetThreadAffinityMask kernel32 1369 2 -imp 'SetThreadContext' SetThreadContext kernel32 0 # KernelBase -imp 'SetThreadDescription' SetThreadDescription KernelBase 1557 -imp 'SetThreadDesktop' SetThreadDesktop user32 2380 -imp 'SetThreadDpiAwarenessContext' SetThreadDpiAwarenessContext user32 2381 -imp 'SetThreadDpiHostingBehavior' SetThreadDpiHostingBehavior user32 2382 -imp 'SetThreadErrorMode' SetThreadErrorMode kernel32 0 # KernelBase -imp 'SetThreadExecutionState' SetThreadExecutionState kernel32 1373 -imp 'SetThreadGroupAffinity' SetThreadGroupAffinity kernel32 0 # KernelBase -imp 'SetThreadIdealProcessor' SetThreadIdealProcessor kernel32 0 # KernelBase -imp 'SetThreadIdealProcessorEx' SetThreadIdealProcessorEx kernel32 0 # KernelBase -imp 'SetThreadInformation' SetThreadInformation kernel32 0 # KernelBase -imp 'SetThreadInputBlocked' SetThreadInputBlocked user32 2383 -imp 'SetThreadLocale' SetThreadLocale kernel32 0 # KernelBase -imp 'SetThreadPreferredUILanguages' SetThreadPreferredUILanguages kernel32 0 # KernelBase -imp 'SetThreadPriority' SetThreadPriority kernel32 0 2 # KernelBase -imp 'SetThreadPriorityBoost' SetThreadPriorityBoost kernel32 0 2 # KernelBase -imp 'SetThreadSelectedCpuSets' SetThreadSelectedCpuSets kernel32 0 # KernelBase -imp 'SetThreadStackGuarantee' SetThreadStackGuarantee kernel32 0 # KernelBase -imp 'SetThreadToken' SetThreadToken advapi32 0 # KernelBase -imp 'SetThreadUILanguage' SetThreadUILanguage kernel32 0 # KernelBase -imp 'SetThreadpoolStackInformation' SetThreadpoolStackInformation kernel32 0 # KernelBase -imp 'SetThreadpoolThreadMinimum' SetThreadpoolThreadMinimum kernel32 0 # KernelBase -imp 'SetTimeZoneInformation' SetTimeZoneInformation kernel32 0 # KernelBase -imp 'SetTimer' SetTimer user32 2384 4 -imp 'SetTimerQueueTimer' SetTimerQueueTimer kernel32 1394 -imp 'SetTokenInformation' SetTokenInformation advapi32 0 # KernelBase -imp 'SetUmsThreadInformation' SetUmsThreadInformation kernel32 1395 -imp 'SetUnhandledExceptionFilter' SetUnhandledExceptionFilter kernel32 0 1 # KernelBase -imp 'SetUserFileEncryptionKey' SetUserFileEncryptionKey advapi32 1759 -imp 'SetUserFileEncryptionKeyEx' SetUserFileEncryptionKeyEx advapi32 1760 -imp 'SetUserGeoID' SetUserGeoID kernel32 0 # KernelBase -imp 'SetUserGeoName' SetUserGeoName KernelBase 1582 -imp 'SetUserObjectInformationA' SetUserObjectInformationA user32 2385 -imp 'SetUserObjectInformation' SetUserObjectInformationW user32 2386 -imp 'SetUserObjectSecurity' SetUserObjectSecurity user32 2387 -imp 'SetVDMCurrentDirectories' SetVDMCurrentDirectories kernel32 1399 -imp 'SetViewportExtEx' SetViewportExtEx gdi32 1914 -imp 'SetViewportOrgEx' SetViewportOrgEx gdi32 1915 -imp 'SetVirtualResolution' SetVirtualResolution gdi32 1916 -imp 'SetVolumeLabelA' SetVolumeLabelA kernel32 1400 -imp 'SetVolumeLabel' SetVolumeLabelW kernel32 1401 -imp 'SetVolumeMountPointA' SetVolumeMountPointA kernel32 1402 -imp 'SetVolumeMountPoint' SetVolumeMountPointW kernel32 1403 -imp 'SetVolumeMountPointWStub' SetVolumeMountPointWStub kernel32 1404 -imp 'SetWaitableTimer' SetWaitableTimer kernel32 0 6 # KernelBase -imp 'SetWaitableTimerEx' SetWaitableTimerEx kernel32 0 # KernelBase -imp 'SetWinEventHook' SetWinEventHook user32 2388 -imp 'SetWinMetaFileBits' SetWinMetaFileBits gdi32 1917 -imp 'SetWindowBand' SetWindowBand user32 2389 -imp 'SetWindowCompositionAttribute' SetWindowCompositionAttribute user32 2390 -imp 'SetWindowCompositionTransition' SetWindowCompositionTransition user32 2391 -imp 'SetWindowContextHelpId' SetWindowContextHelpId user32 2392 -imp 'SetWindowDisplayAffinity' SetWindowDisplayAffinity user32 2393 -imp 'SetWindowExtEx' SetWindowExtEx gdi32 1918 -imp 'SetWindowFeedbackSetting' SetWindowFeedbackSetting user32 2394 -imp 'SetWindowLongA' SetWindowLongA user32 2395 -imp 'SetWindowLongPtrA' SetWindowLongPtrA user32 2396 -imp 'SetWindowLongPtr' SetWindowLongPtrW user32 2397 -imp 'SetWindowLong' SetWindowLongW user32 2398 3 -imp 'SetWindowOrgEx' SetWindowOrgEx gdi32 1919 -imp 'SetWindowPlacement' SetWindowPlacement user32 2399 2 -imp 'SetWindowPos' SetWindowPos user32 2400 7 -imp 'SetWindowRgn' SetWindowRgn user32 2401 -imp 'SetWindowRgnEx' SetWindowRgnEx user32 2402 -imp 'SetWindowStationUser' SetWindowStationUser user32 2403 -imp 'SetWindowText' SetWindowTextW user32 2405 2 -imp 'SetWindowTextA' SetWindowTextA user32 2404 2 -imp 'SetWindowWord' SetWindowWord user32 2406 -imp 'SetWindowsHook' SetWindowsHookW user32 2410 2 -imp 'SetWindowsHookA' SetWindowsHookA user32 2407 2 -imp 'SetWindowsHookEx' SetWindowsHookExW user32 2409 4 -imp 'SetWindowsHookExA' SetWindowsHookExA user32 2408 4 -imp 'SetWorldTransform' SetWorldTransform gdi32 1920 -imp 'SetXStateFeaturesMask' SetXStateFeaturesMask kernel32 0 # KernelBase -imp 'SetupComm' SetupComm kernel32 0 # KernelBase -imp 'SharedLocalIsEnabled' SharedLocalIsEnabled KernelBase 1587 -imp 'SheChangeDirA' SheChangeDirA shell32 570 -imp 'SheChangeDirEx' SheChangeDirExW shell32 571 -imp 'SheGetDirA' SheGetDirA shell32 572 -imp 'SheSetCurDrive' SheSetCurDrive shell32 573 -imp 'ShellAboutA' ShellAboutA shell32 574 -imp 'ShellAbout' ShellAboutW shell32 575 -imp 'ShellExec_RunDLL' ShellExec_RunDLL shell32 576 -imp 'ShellExec_RunDLLA' ShellExec_RunDLLA shell32 577 -imp 'ShellExec_RunDLLW' ShellExec_RunDLLW shell32 578 -imp 'ShellExecuteA' ShellExecuteA shell32 579 -imp 'ShellExecuteExA' ShellExecuteExA shell32 581 -imp 'ShellExecuteEx' ShellExecuteExW shell32 582 -imp 'ShellExecute' ShellExecuteW shell32 583 -imp 'ShellHookProc' ShellHookProc shell32 584 -imp 'Shell_GetCachedImageIndexA' Shell_GetCachedImageIndexA shell32 585 -imp 'Shell_GetCachedImageIndex' Shell_GetCachedImageIndexW shell32 586 -imp 'Shell_GetImageLists' Shell_GetImageLists shell32 71 -imp 'Shell_MergeMenus' Shell_MergeMenus shell32 67 -imp 'Shell_NotifyIconA' Shell_NotifyIconA shell32 588 -imp 'Shell_NotifyIconGetRect' Shell_NotifyIconGetRect shell32 589 -imp 'Shell_NotifyIcon' Shell_NotifyIconW shell32 590 imp 'ShipAssert' ShipAssert ntdll 1612 imp 'ShipAssertGetBufferInfo' ShipAssertGetBufferInfo ntdll 1613 -imp 'ShipAssertMsgA' ShipAssertMsgA ntdll 1614 imp 'ShipAssertMsg' ShipAssertMsgW ntdll 1615 -imp 'ShowCaret' ShowCaret user32 2411 1 -imp 'ShowConsoleCursor' ShowConsoleCursor kernel32 1409 -imp 'ShowCursor' ShowCursor user32 2412 1 -imp 'ShowOwnedPopups' ShowOwnedPopups user32 2413 -imp 'ShowScrollBar' ShowScrollBar user32 2414 -imp 'ShowStartGlass' ShowStartGlass user32 2415 -imp 'ShowSystemCursor' ShowSystemCursor user32 2416 -imp 'ShowWindow' ShowWindow user32 2417 2 -imp 'ShowWindowAsync' ShowWindowAsync user32 2418 -imp 'ShutdownBlockReasonCreate' ShutdownBlockReasonCreate user32 2419 -imp 'ShutdownBlockReasonDestroy' ShutdownBlockReasonDestroy user32 2420 -imp 'ShutdownBlockReasonQuery' ShutdownBlockReasonQuery user32 2421 -imp 'SignalFileOpen' SignalFileOpen shell32 103 -imp 'SignalObjectAndWait' SignalObjectAndWait kernel32 0 # KernelBase -imp 'SignalRedirectionStartComplete' SignalRedirectionStartComplete user32 2422 -imp 'SizeofResource' SizeofResource kernel32 0 # KernelBase -imp 'SkipPointerFrameMessages' SkipPointerFrameMessages user32 2423 -imp 'Sleep' Sleep kernel32 0 1 # KernelBase -imp 'SleepConditionVariableCS' SleepConditionVariableCS kernel32 0 # KernelBase -imp 'SleepConditionVariableSRW' SleepConditionVariableSRW kernel32 0 # KernelBase -imp 'SleepEx' SleepEx kernel32 0 2 # KernelBase -imp 'SoftModalMessageBox' SoftModalMessageBox user32 2424 -imp 'SortCloseHandle' SortCloseHandle kernel32 1416 -imp 'SortGetHandle' SortGetHandle kernel32 1417 -imp 'SoundSentry' SoundSentry user32 2425 -imp 'SpecialMBToWC' SpecialMBToWC KernelBase 1594 -imp 'Ssync_ANSI_UNICODE_Struct_For_WOW' Ssync_ANSI_UNICODE_Struct_For_WOW comdlg32 126 -imp 'StartDocA' StartDocA gdi32 1921 -imp 'StartDoc' StartDocW gdi32 1922 -imp 'StartFormPage' StartFormPage gdi32 1923 -imp 'StartPage' StartPage gdi32 1924 -imp 'StartServiceA' StartServiceA advapi32 1761 -imp 'StartServiceCtrlDispatcherA' StartServiceCtrlDispatcherA advapi32 1762 -imp 'StartServiceCtrlDispatcher' StartServiceCtrlDispatcherW advapi32 1763 -imp 'StartService' StartServiceW advapi32 1764 -imp 'StartTraceA' StartTraceA advapi32 1765 -imp 'StartTrace' StartTraceW advapi32 1766 -imp 'StgMakeUniqueName' StgMakeUniqueName shell32 682 -imp 'StmAlignSize' StmAlignSize KernelBase 1596 -imp 'StmAllocateFlat' StmAllocateFlat KernelBase 1597 -imp 'StmCoalesceChunks' StmCoalesceChunks KernelBase 1598 -imp 'StmDeinitialize' StmDeinitialize KernelBase 1599 -imp 'StmInitialize' StmInitialize KernelBase 1600 -imp 'StmReduceSize' StmReduceSize KernelBase 1601 -imp 'StmReserve' StmReserve KernelBase 1602 -imp 'StmWrite' StmWrite KernelBase 1603 -imp 'StopTraceA' StopTraceA advapi32 1767 -imp 'StopTrace' StopTraceW advapi32 1768 -imp 'StrCSpnA' StrCSpnA KernelBase 1604 -imp 'StrCSpnIA' StrCSpnIA KernelBase 1605 -imp 'StrCSpnIW' StrCSpnIW KernelBase 1606 -imp 'StrCSpn' StrCSpnW KernelBase 1607 -imp 'StrCatBuffA' StrCatBuffA KernelBase 1608 -imp 'StrCatBuff' StrCatBuffW KernelBase 1609 -imp 'StrCatChain' StrCatChainW KernelBase 1610 -imp 'StrChrA' StrChrA KernelBase 1611 -imp 'StrChrA_MB' StrChrA_MB KernelBase 1612 -imp 'StrChrIA' StrChrIA KernelBase 1613 -imp 'StrChrIW' StrChrIW KernelBase 1614 -imp 'StrChrNIW' StrChrNIW KernelBase 1615 -imp 'StrChrNW' StrChrNW KernelBase 1616 -imp 'StrChr' StrChrW KernelBase 1617 -imp 'StrCmpCA' StrCmpCA KernelBase 1618 -imp 'StrCmpCW' StrCmpCW KernelBase 1619 -imp 'StrCmpICA' StrCmpICA KernelBase 1620 -imp 'StrCmpICW' StrCmpICW KernelBase 1621 -imp 'StrCmpIW' StrCmpIW KernelBase 1622 -imp 'StrCmpLogical' StrCmpLogicalW KernelBase 1623 -imp 'StrCmpNA' StrCmpNA KernelBase 1624 -imp 'StrCmpNCA' StrCmpNCA KernelBase 1625 -imp 'StrCmpNCW' StrCmpNCW KernelBase 1626 -imp 'StrCmpNIA' StrCmpNIA KernelBase 1627 -imp 'StrCmpNICA' StrCmpNICA KernelBase 1628 -imp 'StrCmpNICW' StrCmpNICW KernelBase 1629 -imp 'StrCmpNIW' StrCmpNIW KernelBase 1630 -imp 'StrCmpNW' StrCmpNW KernelBase 1631 -imp 'StrCmp' StrCmpW KernelBase 1632 -imp 'StrCpyNW' StrCpyNW KernelBase 1633 -imp 'StrCpyNXA' StrCpyNXA KernelBase 1634 -imp 'StrCpyNXW' StrCpyNXW KernelBase 1635 -imp 'StrDupA' StrDupA KernelBase 1636 -imp 'StrDup' StrDupW KernelBase 1637 -imp 'StrIsIntlEqualA' StrIsIntlEqualA KernelBase 1638 -imp 'StrIsIntlEqual' StrIsIntlEqualW KernelBase 1639 -imp 'StrNCmpA' StrNCmpA shell32 599 -imp 'StrNCmpIA' StrNCmpIA shell32 600 -imp 'StrNCmpIW' StrNCmpIW shell32 601 -imp 'StrNCmp' StrNCmpW shell32 602 -imp 'StrPBrkA' StrPBrkA KernelBase 1640 -imp 'StrPBrk' StrPBrkW KernelBase 1641 -imp 'StrRChrA' StrRChrA KernelBase 1642 -imp 'StrRChrIA' StrRChrIA KernelBase 1643 -imp 'StrRChrIW' StrRChrIW KernelBase 1644 -imp 'StrRChr' StrRChrW KernelBase 1645 -imp 'StrRStrA' StrRStrA shell32 607 -imp 'StrRStrIA' StrRStrIA KernelBase 1646 -imp 'StrRStrIW' StrRStrIW KernelBase 1647 -imp 'StrRStr' StrRStrW shell32 610 -imp 'StrSpnA' StrSpnA KernelBase 1648 -imp 'StrSpn' StrSpnW KernelBase 1649 -imp 'StrStrA' StrStrA KernelBase 1650 -imp 'StrStrIA' StrStrIA KernelBase 1651 -imp 'StrStrIW' StrStrIW KernelBase 1652 -imp 'StrStrNIW' StrStrNIW KernelBase 1653 -imp 'StrStrNW' StrStrNW KernelBase 1654 -imp 'StrStr' StrStrW KernelBase 1655 -imp 'StrToInt64ExA' StrToInt64ExA KernelBase 1656 -imp 'StrToInt64Ex' StrToInt64ExW KernelBase 1657 -imp 'StrToIntA' StrToIntA KernelBase 1658 -imp 'StrToIntExA' StrToIntExA KernelBase 1659 -imp 'StrToIntEx' StrToIntExW KernelBase 1660 -imp 'StrToInt' StrToIntW KernelBase 1661 -imp 'StrTrimA' StrTrimA KernelBase 1662 -imp 'StrTrim' StrTrimW KernelBase 1663 -imp 'StretchBlt' StretchBlt gdi32 1925 -imp 'StretchDIBits' StretchDIBits gdi32 1926 -imp 'StrokeAndFillPath' StrokeAndFillPath gdi32 1927 -imp 'StrokePath' StrokePath gdi32 1928 -imp 'SubscribeEdpEnabledStateChange' SubscribeEdpEnabledStateChange KernelBase 1665 -imp 'SubscribeStateChangeNotification' SubscribeStateChangeNotification KernelBase 1666 -imp 'SubtractRect' SubtractRect user32 2426 -imp 'SuspendThread' SuspendThread kernel32 0 # KernelBase -imp 'SwapBuffers' SwapBuffers gdi32 1929 1 -imp 'SwapMouseButton' SwapMouseButton user32 2427 -imp 'SwitchDesktop' SwitchDesktop user32 2428 -imp 'SwitchDesktopWithFade' SwitchDesktopWithFade user32 2429 -imp 'SwitchToFiber' SwitchToFiber kernel32 0 # KernelBase -imp 'SwitchToThisWindow' SwitchToThisWindow user32 2430 -imp 'SwitchToThread' SwitchToThread kernel32 0 # KernelBase -imp 'SystemFunction017' SystemFunction017 advapi32 1785 -imp 'SystemFunction019' SystemFunction019 advapi32 1787 -imp 'SystemParametersInfoA' SystemParametersInfoA user32 2431 -imp 'SystemParametersInfoForDpi' SystemParametersInfoForDpi user32 2432 -imp 'SystemParametersInfo' SystemParametersInfoW user32 2433 -imp 'SystemTimeToFileTime' SystemTimeToFileTime kernel32 0 2 # KernelBase -imp 'SystemTimeToTzSpecificLocalTime' SystemTimeToTzSpecificLocalTime kernel32 0 # KernelBase -imp 'SystemTimeToTzSpecificLocalTimeEx' SystemTimeToTzSpecificLocalTimeEx kernel32 0 # KernelBase -imp 'TabbedTextOutA' TabbedTextOutA user32 2434 -imp 'TabbedTextOut' TabbedTextOutW user32 2435 -imp 'TelnetProtocolHandler' TelnetProtocolHandler url 113 -imp 'TelnetProtocolHandlerA' TelnetProtocolHandlerA url 114 -imp 'TerminateEnclave' TerminateEnclave KernelBase 1673 -imp 'TerminateJobObject' TerminateJobObject kernel32 1426 -imp 'TerminateProcess' TerminateProcess kernel32 0 2 # KernelBase -imp 'TerminateProcessOnMemoryExhaustion' TerminateProcessOnMemoryExhaustion KernelBase 1675 -imp 'TerminateThread' TerminateThread kernel32 0 # KernelBase -imp 'TermsrvAppInstallMode' TermsrvAppInstallMode kernel32 1429 -imp 'TermsrvConvertSysRootToUserDir' TermsrvConvertSysRootToUserDir kernel32 1430 -imp 'TermsrvCreateRegEntry' TermsrvCreateRegEntry kernel32 1431 -imp 'TermsrvDeleteKey' TermsrvDeleteKey kernel32 1432 -imp 'TermsrvDeleteValue' TermsrvDeleteValue kernel32 1433 -imp 'TermsrvGetPreSetValue' TermsrvGetPreSetValue kernel32 1434 -imp 'TermsrvGetWindowsDirectoryA' TermsrvGetWindowsDirectoryA kernel32 1435 -imp 'TermsrvGetWindowsDirectory' TermsrvGetWindowsDirectoryW kernel32 1436 -imp 'TermsrvOpenRegEntry' TermsrvOpenRegEntry kernel32 1437 -imp 'TermsrvOpenUserClasses' TermsrvOpenUserClasses kernel32 1438 -imp 'TermsrvRestoreKey' TermsrvRestoreKey kernel32 1439 -imp 'TermsrvSetKeySecurity' TermsrvSetKeySecurity kernel32 1440 -imp 'TermsrvSetValueKey' TermsrvSetValueKey kernel32 1441 -imp 'TermsrvSyncUserIniFileExt' TermsrvSyncUserIniFileExt kernel32 1442 -imp 'TextOutA' TextOutA gdi32 1930 -imp 'TextOut' TextOutW gdi32 1931 -imp 'Thread32First' Thread32First kernel32 1443 -imp 'Thread32Next' Thread32Next kernel32 1444 -imp 'TileChildWindows' TileChildWindows user32 2436 -imp 'TileWindows' TileWindows user32 2437 -imp 'TlsAlloc' TlsAlloc kernel32 0 # KernelBase -imp 'TlsFree' TlsFree kernel32 0 # KernelBase -imp 'TlsGetValue' TlsGetValue kernel32 0 # KernelBase -imp 'TlsSetValue' TlsSetValue kernel32 0 # KernelBase -imp 'ToAscii' ToAscii user32 2438 -imp 'ToAsciiEx' ToAsciiEx user32 2439 -imp 'ToUnicode' ToUnicode user32 2440 -imp 'ToUnicodeEx' ToUnicodeEx user32 2441 -imp 'Toolhelp32ReadProcessMemory' Toolhelp32ReadProcessMemory kernel32 1449 imp 'TpAllocAlpcCompletion' TpAllocAlpcCompletion ntdll 1616 imp 'TpAllocAlpcCompletionEx' TpAllocAlpcCompletionEx ntdll 1617 imp 'TpAllocCleanupGroup' TpAllocCleanupGroup ntdll 1618 @@ -6716,391 +6183,9 @@ imp 'TpWaitForJobNotification' TpWaitForJobNotification ntdll 1674 imp 'TpWaitForTimer' TpWaitForTimer ntdll 1675 imp 'TpWaitForWait' TpWaitForWait ntdll 1676 imp 'TpWaitForWork' TpWaitForWork ntdll 1677 -imp 'TraceSetInformation' TraceSetInformation advapi32 1812 -imp 'TrackMouseEvent' TrackMouseEvent user32 2442 -imp 'TrackPopupMenu' TrackPopupMenu user32 2443 7 -imp 'TrackPopupMenuEx' TrackPopupMenuEx user32 2444 -imp 'TransactNamedPipe' TransactNamedPipe kernel32 0 7 # KernelBase -imp 'TranslateAcceleratorA' TranslateAcceleratorA user32 2446 -imp 'TranslateAccelerator' TranslateAcceleratorW user32 2447 -imp 'TranslateCharsetInfo' TranslateCharsetInfo gdi32 1932 -imp 'TranslateMDISysAccel' TranslateMDISysAccel user32 2448 -imp 'TranslateMessage' TranslateMessage user32 2449 1 -imp 'TranslateMessageEx' TranslateMessageEx user32 2450 -imp 'TranslateURLA' TranslateURLA url 115 -imp 'TranslateURLW' TranslateURLW url 116 -imp 'TransmitFile' TransmitFile MsWSock 53 7 -imp 'TransmitCommChar' TransmitCommChar kernel32 0 # KernelBase -imp 'TreeResetNamedSecurityInfoA' TreeResetNamedSecurityInfoA advapi32 1813 -imp 'TreeResetNamedSecurityInfo' TreeResetNamedSecurityInfoW advapi32 1814 -imp 'TreeSetNamedSecurityInfoA' TreeSetNamedSecurityInfoA advapi32 1815 -imp 'TreeSetNamedSecurityInfo' TreeSetNamedSecurityInfoW advapi32 1816 -imp 'TrusteeAccessToObjectA' TrusteeAccessToObjectA advapi32 1817 -imp 'TrusteeAccessToObject' TrusteeAccessToObjectW advapi32 1818 -imp 'TrySubmitThreadpoolCallback' TrySubmitThreadpoolCallback kernel32 0 # KernelBase -imp 'TzSpecificLocalTimeToSystemTime' TzSpecificLocalTimeToSystemTime kernel32 0 # KernelBase -imp 'TzSpecificLocalTimeToSystemTimeEx' TzSpecificLocalTimeToSystemTimeEx kernel32 0 # KernelBase -imp 'URLAssociationDialogA' URLAssociationDialogA url 117 -imp 'URLAssociationDialog' URLAssociationDialogW url 118 -imp 'UTRegister' UTRegister kernel32 1458 -imp 'UTUnRegister' UTUnRegister kernel32 1459 -imp 'UmsThreadYield' UmsThreadYield kernel32 1460 -imp 'UndelegateInput' UndelegateInput user32 2504 -imp 'UnhandledExceptionFilter' UnhandledExceptionFilter kernel32 0 # KernelBase -imp 'UnhookWinEvent' UnhookWinEvent user32 2451 -imp 'UnhookWindowsHook' UnhookWindowsHook user32 2452 2 -imp 'UnhookWindowsHookEx' UnhookWindowsHookEx user32 2453 1 -imp 'UninstallApplication' UninstallApplication advapi32 1819 -imp 'UnionRect' UnionRect user32 2454 -imp 'UnloadKeyboardLayout' UnloadKeyboardLayout user32 2455 -imp 'UnloadNetworkFonts' UnloadNetworkFonts gdi32 1933 -imp 'UnlockFile' UnlockFile kernel32 0 5 # KernelBase -imp 'UnlockFileEx' UnlockFileEx kernel32 0 5 # KernelBase -imp 'UnlockServiceDatabase' UnlockServiceDatabase advapi32 1820 -imp 'UnlockWindowStation' UnlockWindowStation user32 2456 -imp 'UnmapViewOfFile' UnmapViewOfFile kernel32 0 1 # KernelBase -imp 'UnmapViewOfFile2' UnmapViewOfFile2 KernelBase 1696 -imp 'UnmapViewOfFileEx' UnmapViewOfFileEx KernelBase 1697 -imp 'UnpackDDElParam' UnpackDDElParam user32 2457 -imp 'UnrealizeObject' UnrealizeObject gdi32 1934 -imp 'UnregisterApplicationRecoveryCallback' UnregisterApplicationRecoveryCallback kernel32 1466 -imp 'UnregisterApplicationRestart' UnregisterApplicationRestart kernel32 1467 -imp 'UnregisterBadMemoryNotification' UnregisterBadMemoryNotification kernel32 0 # KernelBase -imp 'UnregisterClassA' UnregisterClassA user32 2458 -imp 'UnregisterClass' UnregisterClassW user32 2459 -imp 'UnregisterConsoleIME' UnregisterConsoleIME kernel32 1469 -imp 'UnregisterDeviceNotification' UnregisterDeviceNotification user32 2460 -imp 'UnregisterGPNotificationInternal' UnregisterGPNotificationInternal KernelBase 1699 -imp 'UnregisterHotKey' UnregisterHotKey user32 2461 -imp 'UnregisterIdleTask' UnregisterIdleTask advapi32 1821 -imp 'UnregisterMessagePumpHook' UnregisterMessagePumpHook user32 2462 -imp 'UnregisterPointerInputTarget' UnregisterPointerInputTarget user32 2463 -imp 'UnregisterPointerInputTargetEx' UnregisterPointerInputTargetEx user32 2464 -imp 'UnregisterPowerSettingNotification' UnregisterPowerSettingNotification user32 2465 -imp 'UnregisterSessionPort' UnregisterSessionPort user32 2466 -imp 'UnregisterStateChangeNotification' UnregisterStateChangeNotification KernelBase 1700 -imp 'UnregisterStateLock' UnregisterStateLock KernelBase 1701 -imp 'UnregisterSuspendResumeNotification' UnregisterSuspendResumeNotification user32 2467 -imp 'UnregisterTouchWindow' UnregisterTouchWindow user32 2468 -imp 'UnregisterUserApiHook' UnregisterUserApiHook user32 2469 -imp 'UnregisterWait' UnregisterWait kernel32 1470 -imp 'UnregisterWaitEx' UnregisterWaitEx kernel32 0 # KernelBase -imp 'UnregisterWaitUntilOOBECompleted' UnregisterWaitUntilOOBECompleted kernel32 1472 -imp 'UnsubscribeEdpEnabledStateChange' UnsubscribeEdpEnabledStateChange KernelBase 1704 -imp 'UnsubscribeStateChangeNotification' UnsubscribeStateChangeNotification KernelBase 1705 -imp 'UpdateCalendarDayOfWeek' UpdateCalendarDayOfWeek kernel32 1473 -imp 'UpdateColors' UpdateColors gdi32 1935 -imp 'UpdateDefaultDesktopThumbnail' UpdateDefaultDesktopThumbnail user32 2470 -imp 'UpdateICMRegKeyA' UpdateICMRegKeyA gdi32 1936 -imp 'UpdateICMRegKey' UpdateICMRegKeyW gdi32 1937 -imp 'UpdateLayeredWindow' UpdateLayeredWindow user32 2471 -imp 'UpdateLayeredWindowIndirect' UpdateLayeredWindowIndirect user32 2472 -imp 'UpdatePackageStatus' UpdatePackageStatus KernelBase 1706 -imp 'UpdatePackageStatusForUser' UpdatePackageStatusForUser KernelBase 1707 -imp 'UpdatePackageStatusForUserSid' UpdatePackageStatusForUserSid KernelBase 1708 -imp 'UpdatePerUserSystemParameters' UpdatePerUserSystemParameters user32 2473 -imp 'UpdateProcThreadAttribute' UpdateProcThreadAttribute kernel32 0 7 # KernelBase -imp 'UpdateResourceA' UpdateResourceA kernel32 1475 -imp 'UpdateResource' UpdateResourceW kernel32 1476 -imp 'UpdateTraceA' UpdateTraceA advapi32 1823 -imp 'UpdateTrace' UpdateTraceW advapi32 1824 -imp 'UpdateWindow' UpdateWindow user32 2474 1 -imp 'UpdateWindowInputSinkHints' UpdateWindowInputSinkHints user32 2475 -imp 'UrlApplySchemeA' UrlApplySchemeA KernelBase 1710 -imp 'UrlApplyScheme' UrlApplySchemeW KernelBase 1711 -imp 'UrlCanonicalizeA' UrlCanonicalizeA KernelBase 1712 -imp 'UrlCanonicalize' UrlCanonicalizeW KernelBase 1713 -imp 'UrlCombineA' UrlCombineA KernelBase 1714 -imp 'UrlCombine' UrlCombineW KernelBase 1715 -imp 'UrlCompareA' UrlCompareA KernelBase 1716 -imp 'UrlCompare' UrlCompareW KernelBase 1717 -imp 'UrlCreateFromPathA' UrlCreateFromPathA KernelBase 1718 -imp 'UrlCreateFromPath' UrlCreateFromPathW KernelBase 1719 -imp 'UrlEscapeA' UrlEscapeA KernelBase 1720 -imp 'UrlEscape' UrlEscapeW KernelBase 1721 -imp 'UrlFixup' UrlFixupW KernelBase 1722 -imp 'UrlGetLocationA' UrlGetLocationA KernelBase 1723 -imp 'UrlGetLocation' UrlGetLocationW KernelBase 1724 -imp 'UrlGetPartA' UrlGetPartA KernelBase 1725 -imp 'UrlGetPart' UrlGetPartW KernelBase 1726 -imp 'UrlHashA' UrlHashA KernelBase 1727 -imp 'UrlHash' UrlHashW KernelBase 1728 -imp 'UrlIsA' UrlIsA KernelBase 1729 -imp 'UrlIsNoHistoryA' UrlIsNoHistoryA KernelBase 1730 -imp 'UrlIsNoHistory' UrlIsNoHistoryW KernelBase 1731 -imp 'UrlIsOpaqueA' UrlIsOpaqueA KernelBase 1732 -imp 'UrlIsOpaque' UrlIsOpaqueW KernelBase 1733 -imp 'UrlIs' UrlIsW KernelBase 1734 -imp 'UrlUnescapeA' UrlUnescapeA KernelBase 1735 -imp 'UrlUnescape' UrlUnescapeW KernelBase 1736 -imp 'UsePinForEncryptedFilesA' UsePinForEncryptedFilesA advapi32 1825 -imp 'UsePinForEncryptedFiles' UsePinForEncryptedFilesW advapi32 1826 -imp 'User32InitializeImmEntryTable' User32InitializeImmEntryTable user32 2476 -imp 'UserClientDllInitialize' UserClientDllInitialize user32 2477 -imp 'UserHandleGrantAccess' UserHandleGrantAccess user32 2478 -imp 'UserLpkPSMTextOut' UserLpkPSMTextOut user32 2479 -imp 'UserLpkTabbedTextOut' UserLpkTabbedTextOut user32 2480 -imp 'UserRealizePalette' UserRealizePalette user32 2481 -imp 'UserRegisterWowHandlers' UserRegisterWowHandlers user32 2482 -imp 'UsersLibrariesFolderUI_CreateInstance' UsersLibrariesFolderUI_CreateInstance shell32 615 -imp 'VDMConsoleOperation' VDMConsoleOperation kernel32 1477 -imp 'VDMOperationStarted' VDMOperationStarted kernel32 1478 -imp 'VRipOutput' VRipOutput user32 2483 -imp 'VTagOutput' VTagOutput user32 2484 -imp 'ValidateRect' ValidateRect user32 2485 -imp 'ValidateRgn' ValidateRgn user32 2486 -imp 'VerFindFileA' VerFindFileA KernelBase 1737 -imp 'VerFindFile' VerFindFileW KernelBase 1738 -imp 'VerLanguageNameA' VerLanguageNameA kernel32 0 # KernelBase -imp 'VerLanguageName' VerLanguageNameW kernel32 0 # KernelBase -imp 'VerQueryValueA' VerQueryValueA KernelBase 1741 -imp 'VerQueryValue' VerQueryValueW KernelBase 1742 imp 'VerSetConditionMask' VerSetConditionMask ntdll 1678 -imp 'VerifyApplicationUserModelId' VerifyApplicationUserModelId KernelBase 1744 -imp 'VerifyApplicationUserModelIdA' VerifyApplicationUserModelIdA KernelBase 1745 -imp 'VerifyConsoleIoHandle' VerifyConsoleIoHandle kernel32 1482 -imp 'VerifyPackageFamilyName' VerifyPackageFamilyName KernelBase 1746 -imp 'VerifyPackageFamilyNameA' VerifyPackageFamilyNameA KernelBase 1747 -imp 'VerifyPackageFullName' VerifyPackageFullName KernelBase 1748 -imp 'VerifyPackageFullNameA' VerifyPackageFullNameA KernelBase 1749 -imp 'VerifyPackageId' VerifyPackageId KernelBase 1750 -imp 'VerifyPackageIdA' VerifyPackageIdA KernelBase 1751 -imp 'VerifyPackageRelativeApplicationId' VerifyPackageRelativeApplicationId KernelBase 1752 -imp 'VerifyPackageRelativeApplicationIdA' VerifyPackageRelativeApplicationIdA KernelBase 1753 -imp 'VerifyScripts' VerifyScripts kernel32 0 # KernelBase -imp 'VerifyVersionInfoA' VerifyVersionInfoA kernel32 1484 -imp 'VerifyVersionInfo' VerifyVersionInfoW kernel32 1485 -imp 'VirtualAlloc' VirtualAlloc kernel32 0 4 # KernelBase -imp 'VirtualAlloc2' VirtualAlloc2 KernelBase 1756 -imp 'VirtualAlloc2FromApp' VirtualAlloc2FromApp KernelBase 1757 -imp 'VirtualAllocEx' VirtualAllocEx kernel32 0 5 # KernelBase -imp 'VirtualAllocExNuma' VirtualAllocExNuma kernel32 0 # KernelBase -imp 'VirtualAllocFromApp' VirtualAllocFromApp KernelBase 1760 -imp 'VirtualFree' VirtualFree kernel32 0 3 # KernelBase -imp 'VirtualFreeEx' VirtualFreeEx kernel32 0 # KernelBase -imp 'VirtualLock' VirtualLock kernel32 0 # KernelBase -imp 'VirtualProtect' VirtualProtect kernel32 0 4 # KernelBase -imp 'VirtualProtectEx' VirtualProtectEx kernel32 0 # KernelBase -imp 'VirtualProtectFromApp' VirtualProtectFromApp KernelBase 1766 -imp 'VirtualQuery' VirtualQuery kernel32 0 3 # KernelBase -imp 'VirtualQueryEx' VirtualQueryEx kernel32 0 # KernelBase -imp 'VirtualUnlock' VirtualUnlock kernel32 0 # KernelBase -imp 'VirtualUnlockEx' VirtualUnlockEx KernelBase 1770 -imp 'VkKeyScanA' VkKeyScanA user32 2487 -imp 'VkKeyScanExA' VkKeyScanExA user32 2488 -imp 'VkKeyScanEx' VkKeyScanExW user32 2489 -imp 'VkKeyScan' VkKeyScanW user32 2490 -imp 'WCSToMBEx' WCSToMBEx user32 2491 -imp 'WEP' WEP ws2_32 500 -imp 'WINNLSEnableIME' WINNLSEnableIME user32 2492 -imp 'WINNLSGetEnableStatus' WINNLSGetEnableStatus user32 2493 -imp 'WINNLSGetIMEHotkey' WINNLSGetIMEHotkey user32 2494 -imp 'WOWShellExecute' WOWShellExecute shell32 616 -imp 'WPUCompleteOverlappedRequest' WPUCompleteOverlappedRequest ws2_32 39 -imp 'WPUGetProviderPathEx' WPUGetProviderPathEx ws2_32 40 -imp 'WSAAccept' WSAAccept ws2_32 41 5 -imp 'WSAAddressToString' WSAAddressToStringW ws2_32 43 5 -imp 'WSAAddressToStringA' WSAAddressToStringA ws2_32 42 5 -imp 'WSAAdvertiseProvider' WSAAdvertiseProvider ws2_32 44 -imp 'WSAAsyncGetHostByAddr' WSAAsyncGetHostByAddr ws2_32 102 -imp 'WSAAsyncGetHostByName' WSAAsyncGetHostByName ws2_32 103 -imp 'WSAAsyncGetProtoByName' WSAAsyncGetProtoByName ws2_32 105 -imp 'WSAAsyncGetProtoByNumber' WSAAsyncGetProtoByNumber ws2_32 104 -imp 'WSAAsyncGetServByName' WSAAsyncGetServByName ws2_32 107 -imp 'WSAAsyncGetServByPort' WSAAsyncGetServByPort ws2_32 106 -imp 'WSAAsyncSelect' WSAAsyncSelect ws2_32 101 -imp 'WSACancelAsyncRequest' WSACancelAsyncRequest ws2_32 108 -imp 'WSACancelBlockingCall' WSACancelBlockingCall ws2_32 113 -imp 'WSACleanup' WSACleanup ws2_32 116 0 -imp 'WSACloseEvent' WSACloseEvent ws2_32 45 1 -imp 'WSAConnect' WSAConnect ws2_32 46 7 -imp 'WSAConnectByList' WSAConnectByList ws2_32 47 8 -imp 'WSAConnectByName' WSAConnectByNameW ws2_32 49 9 -imp 'WSAConnectByNameA' WSAConnectByNameA ws2_32 48 9 -imp 'WSACreateEvent' WSACreateEvent ws2_32 50 0 -imp 'WSADuplicateSocket' WSADuplicateSocketW ws2_32 59 3 -imp 'WSADuplicateSocketA' WSADuplicateSocketA ws2_32 58 3 -imp 'WSAEnumNameSpaceProvidersEx' WSAEnumNameSpaceProvidersExW ws2_32 62 2 -imp 'WSAEnumNameSpaceProvidersExA' WSAEnumNameSpaceProvidersExA ws2_32 61 2 -imp 'WSAEnumNameSpaceProviders' WSAEnumNameSpaceProvidersW ws2_32 63 -imp 'WSAEnumNameSpaceProvidersA' WSAEnumNameSpaceProvidersA ws2_32 60 -imp 'WSAEnumNetworkEvents' WSAEnumNetworkEvents ws2_32 64 3 -imp 'WSAEnumProtocols' WSAEnumProtocolsW ws2_32 66 3 -imp 'WSAEnumProtocolsA' WSAEnumProtocolsA ws2_32 65 3 -imp 'WSAEventSelect' WSAEventSelect ws2_32 67 3 -imp 'WSAGetLastError' WSAGetLastError ws2_32 111 0 -imp 'WSAGetOverlappedResult' WSAGetOverlappedResult ws2_32 68 5 -imp 'WSAGetQOSByName' WSAGetQOSByName ws2_32 69 3 -imp 'WSAGetServiceClassInfo' WSAGetServiceClassInfoW ws2_32 71 4 -imp 'WSAGetServiceClassInfoA' WSAGetServiceClassInfoA ws2_32 70 4 -imp 'WSAGetServiceClassNameByClassId' WSAGetServiceClassNameByClassIdW ws2_32 73 3 -imp 'WSAGetServiceClassNameByClassIdA' WSAGetServiceClassNameByClassIdA ws2_32 72 3 -imp 'WSAHtonl' WSAHtonl ws2_32 74 -imp 'WSAHtons' WSAHtons ws2_32 75 -imp 'WSAInstallServiceClass' WSAInstallServiceClassW ws2_32 77 1 -imp 'WSAInstallServiceClassA' WSAInstallServiceClassA ws2_32 76 1 -imp 'WSAIoctl' WSAIoctl ws2_32 78 9 -imp 'WSAIsBlocking' WSAIsBlocking ws2_32 114 -imp 'WSAJoinLeaf' WSAJoinLeaf ws2_32 79 8 -imp 'WSALookupServiceBegin' WSALookupServiceBeginW ws2_32 81 3 -imp 'WSALookupServiceBeginA' WSALookupServiceBeginA ws2_32 80 3 -imp 'WSALookupServiceEnd' WSALookupServiceEnd ws2_32 82 1 -imp 'WSALookupServiceNext' WSALookupServiceNextW ws2_32 84 4 -imp 'WSALookupServiceNextA' WSALookupServiceNextA ws2_32 83 4 -imp 'WSANSPIoctl' WSANSPIoctl ws2_32 85 8 -imp 'WSANtohl' WSANtohl ws2_32 86 -imp 'WSANtohs' WSANtohs ws2_32 87 -imp 'WSAPoll' WSAPoll ws2_32 88 3 -imp 'WSAProviderCompleteAsyncCall' WSAProviderCompleteAsyncCall ws2_32 89 -imp 'WSAProviderConfigChange' WSAProviderConfigChange ws2_32 90 3 -imp 'WSARecv' WSARecv ws2_32 91 7 -imp 'WSARecvDisconnect' WSARecvDisconnect ws2_32 92 2 -imp 'WSARecvFrom' WSARecvFrom ws2_32 93 9 -imp 'WSARecvEx' WSARecvEx MsWSock 54 -imp 'WSARemoveServiceClass' WSARemoveServiceClass ws2_32 94 1 -imp 'WSAResetEvent' WSAResetEvent ws2_32 95 1 -imp 'WSASend' WSASend ws2_32 96 7 -imp 'WSASendDisconnect' WSASendDisconnect ws2_32 97 -imp 'WSASendMsg' WSASendMsg ws2_32 98 6 -imp 'WSASendTo' WSASendTo ws2_32 99 9 -imp 'WSASetBlockingHook' WSASetBlockingHook ws2_32 109 -imp 'WSASetEvent' WSASetEvent ws2_32 100 1 -imp 'WSASetLastError' WSASetLastError ws2_32 112 1 -imp 'WSASetService' WSASetServiceW ws2_32 118 3 -imp 'WSASetServiceA' WSASetServiceA ws2_32 117 3 -imp 'WSASocket' WSASocketW ws2_32 120 6 -imp 'WSASocketA' WSASocketA ws2_32 119 6 -imp 'WSAStartup' WSAStartup ws2_32 115 2 -imp 'WSAStringToAddressA' WSAStringToAddressA ws2_32 121 5 -imp 'WSAStringToAddress' WSAStringToAddressW ws2_32 122 -imp 'WSAUnadvertiseProvider' WSAUnadvertiseProvider ws2_32 123 -imp 'WSAUnhookBlockingHook' WSAUnhookBlockingHook ws2_32 110 -imp 'WSAWaitForMultipleEvents' WSAWaitForMultipleEvents ws2_32 124 5 -imp 'WSApSetPostRoutine' WSApSetPostRoutine ws2_32 24 -imp 'WSCDeinstallProvider' WSCDeinstallProvider ws2_32 125 -imp 'WSCDeinstallProvider32' WSCDeinstallProvider32 ws2_32 126 -imp 'WSCDeinstallProviderEx' WSCDeinstallProviderEx ws2_32 127 -imp 'WSCEnableNSProvider' WSCEnableNSProvider ws2_32 128 -imp 'WSCEnableNSProvider32' WSCEnableNSProvider32 ws2_32 129 -imp 'WSCEnumNameSpaceProviders32' WSCEnumNameSpaceProviders32 ws2_32 130 -imp 'WSCEnumNameSpaceProvidersEx32' WSCEnumNameSpaceProvidersEx32 ws2_32 131 -imp 'WSCEnumProtocols' WSCEnumProtocols ws2_32 132 -imp 'WSCEnumProtocols32' WSCEnumProtocols32 ws2_32 133 -imp 'WSCEnumProtocolsEx' WSCEnumProtocolsEx ws2_32 134 -imp 'WSCGetApplicationCategory' WSCGetApplicationCategory ws2_32 135 -imp 'WSCGetApplicationCategoryEx' WSCGetApplicationCategoryEx ws2_32 136 -imp 'WSCGetProviderInfo' WSCGetProviderInfo ws2_32 137 -imp 'WSCGetProviderInfo32' WSCGetProviderInfo32 ws2_32 138 -imp 'WSCGetProviderPath' WSCGetProviderPath ws2_32 139 -imp 'WSCGetProviderPath32' WSCGetProviderPath32 ws2_32 140 -imp 'WSCInstallNameSpace' WSCInstallNameSpace ws2_32 141 -imp 'WSCInstallNameSpace32' WSCInstallNameSpace32 ws2_32 142 -imp 'WSCInstallNameSpaceEx' WSCInstallNameSpaceEx ws2_32 143 -imp 'WSCInstallNameSpaceEx2' WSCInstallNameSpaceEx2 ws2_32 144 -imp 'WSCInstallNameSpaceEx32' WSCInstallNameSpaceEx32 ws2_32 145 -imp 'WSCInstallProvider' WSCInstallProvider ws2_32 146 -imp 'WSCInstallProvider64_32' WSCInstallProvider64_32 ws2_32 147 -imp 'WSCInstallProviderAndChains64_32' WSCInstallProviderAndChains64_32 ws2_32 148 -imp 'WSCInstallProviderEx' WSCInstallProviderEx ws2_32 149 -imp 'WSCSetApplicationCategory' WSCSetApplicationCategory ws2_32 150 -imp 'WSCSetApplicationCategoryEx' WSCSetApplicationCategoryEx ws2_32 152 -imp 'WSCSetProviderInfo' WSCSetProviderInfo ws2_32 153 -imp 'WSCSetProviderInfo32' WSCSetProviderInfo32 ws2_32 154 -imp 'WSCUnInstallNameSpace' WSCUnInstallNameSpace ws2_32 155 -imp 'WSCUnInstallNameSpace32' WSCUnInstallNameSpace32 ws2_32 156 -imp 'WSCUnInstallNameSpaceEx2' WSCUnInstallNameSpaceEx2 ws2_32 157 -imp 'WSCUpdateProvider' WSCUpdateProvider ws2_32 158 -imp 'WSCUpdateProvider32' WSCUpdateProvider32 ws2_32 159 -imp 'WSCUpdateProviderEx' WSCUpdateProviderEx ws2_32 160 -imp 'WSCWriteNameSpaceOrder' WSCWriteNameSpaceOrder ws2_32 161 -imp 'WSCWriteNameSpaceOrder32' WSCWriteNameSpaceOrder32 ws2_32 162 -imp 'WSCWriteProviderOrder' WSCWriteProviderOrder ws2_32 163 -imp 'WSCWriteProviderOrder32' WSCWriteProviderOrder32 ws2_32 164 -imp 'WSCWriteProviderOrderEx' WSCWriteProviderOrderEx ws2_32 165 -imp 'WTSGetActiveConsoleSessionId' WTSGetActiveConsoleSessionId kernel32 1497 -imp 'WTSGetServiceSessionId' WTSGetServiceSessionId KernelBase 1771 -imp 'WTSIsServerContainer' WTSIsServerContainer KernelBase 1772 -imp 'WahCloseApcHelper' WahCloseApcHelper ws2_32 166 -imp 'WahCloseHandleHelper' WahCloseHandleHelper ws2_32 167 -imp 'WahCloseNotificationHandleHelper' WahCloseNotificationHandleHelper ws2_32 168 -imp 'WahCloseSocketHandle' WahCloseSocketHandle ws2_32 169 -imp 'WahCloseThread' WahCloseThread ws2_32 170 -imp 'WahCompleteRequest' WahCompleteRequest ws2_32 171 -imp 'WahCreateHandleContextTable' WahCreateHandleContextTable ws2_32 172 -imp 'WahCreateNotificationHandle' WahCreateNotificationHandle ws2_32 173 -imp 'WahCreateSocketHandle' WahCreateSocketHandle ws2_32 174 -imp 'WahDestroyHandleContextTable' WahDestroyHandleContextTable ws2_32 175 -imp 'WahDisableNonIFSHandleSupport' WahDisableNonIFSHandleSupport ws2_32 176 -imp 'WahEnableNonIFSHandleSupport' WahEnableNonIFSHandleSupport ws2_32 177 -imp 'WahEnumerateHandleContexts' WahEnumerateHandleContexts ws2_32 178 -imp 'WahInsertHandleContext' WahInsertHandleContext ws2_32 179 -imp 'WahNotifyAllProcesses' WahNotifyAllProcesses ws2_32 180 -imp 'WahOpenApcHelper' WahOpenApcHelper ws2_32 181 -imp 'WahOpenCurrentThread' WahOpenCurrentThread ws2_32 182 -imp 'WahOpenHandleHelper' WahOpenHandleHelper ws2_32 183 -imp 'WahOpenNotificationHandleHelper' WahOpenNotificationHandleHelper ws2_32 184 -imp 'WahQueueUserApc' WahQueueUserApc ws2_32 185 -imp 'WahReferenceContextByHandle' WahReferenceContextByHandle ws2_32 186 -imp 'WahRemoveHandleContext' WahRemoveHandleContext ws2_32 187 -imp 'WahWaitForNotification' WahWaitForNotification ws2_32 188 -imp 'WahWriteLSPEvent' WahWriteLSPEvent ws2_32 189 -imp 'WaitCommEvent' WaitCommEvent kernel32 0 # KernelBase -imp 'WaitForDebugEvent' WaitForDebugEvent kernel32 0 # KernelBase -imp 'WaitForDebugEventEx' WaitForDebugEventEx KernelBase 1775 -imp 'WaitForExplorerRestart' WaitForExplorerRestartW shell32 617 -imp 'WaitForInputIdle' WaitForInputIdle user32 2495 2 -imp 'WaitForMachinePolicyForegroundProcessingInternal' WaitForMachinePolicyForegroundProcessingInternal KernelBase 1776 -imp 'WaitForMultipleObjects' WaitForMultipleObjects kernel32 0 4 # KernelBase -imp 'WaitForMultipleObjectsEx' WaitForMultipleObjectsEx kernel32 0 5 # KernelBase -imp 'WaitForRedirectionStartComplete' WaitForRedirectionStartComplete user32 2496 -imp 'WaitForSingleObject' WaitForSingleObject kernel32 0 2 # KernelBase -imp 'WaitForSingleObjectEx' WaitForSingleObjectEx kernel32 0 3 # KernelBase -imp 'WaitForUserPolicyForegroundProcessingInternal' WaitForUserPolicyForegroundProcessingInternal KernelBase 1785 -imp 'WaitMessage' WaitMessage user32 2497 -imp 'WaitNamedPipeA' WaitNamedPipeA kernel32 1509 2 -imp 'WaitNamedPipe' WaitNamedPipeW kernel32 0 # KernelBase -imp 'WaitOnAddress' WaitOnAddress KernelBase 1787 -imp 'WaitServiceState' WaitServiceState advapi32 1827 -imp 'WantArrows' WantArrows comdlg32 127 -imp 'WerGetFlags' WerGetFlags kernel32 0 # KernelBase -imp 'WerGetFlagsWorker' WerGetFlagsWorker kernel32 1514 -imp 'WerRegisterAdditionalProcess' WerRegisterAdditionalProcess KernelBase 1793 -imp 'WerRegisterAppLocalDump' WerRegisterAppLocalDump KernelBase 1794 -imp 'WerRegisterCustomMetadata' WerRegisterCustomMetadata KernelBase 1795 -imp 'WerRegisterExcludedMemoryBlock' WerRegisterExcludedMemoryBlock KernelBase 1796 -imp 'WerRegisterFile' WerRegisterFile kernel32 0 # KernelBase -imp 'WerRegisterFileWorker' WerRegisterFileWorker kernel32 1520 -imp 'WerRegisterMemoryBlock' WerRegisterMemoryBlock kernel32 0 # KernelBase -imp 'WerRegisterMemoryBlockWorker' WerRegisterMemoryBlockWorker kernel32 1522 -imp 'WerRegisterRuntimeExceptionModule' WerRegisterRuntimeExceptionModule kernel32 0 # KernelBase -imp 'WerRegisterRuntimeExceptionModuleWorker' WerRegisterRuntimeExceptionModuleWorker kernel32 1524 imp 'WerReportExceptionWorker' WerReportExceptionWorker ntdll 1679 imp 'WerReportSQMEvent' WerReportSQMEvent ntdll 1680 -imp 'WerSetFlags' WerSetFlags kernel32 0 # KernelBase -imp 'WerSetFlagsWorker' WerSetFlagsWorker kernel32 1526 -imp 'WerUnregisterAdditionalProcess' WerUnregisterAdditionalProcess KernelBase 1801 -imp 'WerUnregisterAppLocalDump' WerUnregisterAppLocalDump KernelBase 1802 -imp 'WerUnregisterCustomMetadata' WerUnregisterCustomMetadata KernelBase 1803 -imp 'WerUnregisterExcludedMemoryBlock' WerUnregisterExcludedMemoryBlock KernelBase 1804 -imp 'WerUnregisterFile' WerUnregisterFile kernel32 0 # KernelBase -imp 'WerUnregisterFileWorker' WerUnregisterFileWorker kernel32 1532 -imp 'WerUnregisterMemoryBlock' WerUnregisterMemoryBlock kernel32 0 # KernelBase -imp 'WerUnregisterMemoryBlockWorker' WerUnregisterMemoryBlockWorker kernel32 1534 -imp 'WerUnregisterRuntimeExceptionModule' WerUnregisterRuntimeExceptionModule kernel32 0 # KernelBase -imp 'WerUnregisterRuntimeExceptionModuleWorker' WerUnregisterRuntimeExceptionModuleWorker kernel32 1536 -imp 'WerpGetDebugger' WerpGetDebugger kernel32 1537 -imp 'WerpInitiateRemoteRecovery' WerpInitiateRemoteRecovery kernel32 1538 -imp 'WerpLaunchAeDebug' WerpLaunchAeDebug kernel32 1539 -imp 'WerpNotifyLoadStringResource' WerpNotifyLoadStringResource KernelBase 1808 -imp 'WerpNotifyLoadStringResourceWorker' WerpNotifyLoadStringResourceWorker kernel32 1540 -imp 'WerpNotifyUseStringResource' WerpNotifyUseStringResource KernelBase 1809 -imp 'WerpNotifyUseStringResourceWorker' WerpNotifyUseStringResourceWorker kernel32 1541 -imp 'WideCharToMultiByte' WideCharToMultiByte kernel32 1553 8 -imp 'WidenPath' WidenPath gdi32 1941 -imp 'Win32DeleteFile' Win32DeleteFile shell32 164 -imp 'WinExec' WinExec kernel32 1543 -imp 'WinHelpA' WinHelpA user32 2498 -imp 'WinHelp' WinHelpW user32 2499 imp 'WinSqmAddToAverageDWORD' WinSqmAddToAverageDWORD ntdll 1681 imp 'WinSqmAddToStream' WinSqmAddToStream ntdll 1682 imp 'WinSqmAddToStreamEx' WinSqmAddToStreamEx ntdll 1683 @@ -7131,84 +6216,6 @@ imp 'WinSqmSetString' WinSqmSetString ntdll 1707 imp 'WinSqmStartSession' WinSqmStartSession ntdll 1708 imp 'WinSqmStartSessionForPartner' WinSqmStartSessionForPartner ntdll 1709 imp 'WinSqmStartSqmOptinListener' WinSqmStartSqmOptinListener ntdll 1710 -imp 'WindowFromDC' WindowFromDC user32 2500 -imp 'WindowFromPhysicalPoint' WindowFromPhysicalPoint user32 2501 -imp 'WindowFromPoint' WindowFromPoint user32 2502 -imp 'WmiCloseBlock' WmiCloseBlock advapi32 1828 -imp 'WmiDevInstToInstanceNameA' WmiDevInstToInstanceNameA advapi32 1829 -imp 'WmiDevInstToInstanceName' WmiDevInstToInstanceNameW advapi32 1830 -imp 'WmiEnumerateGuids' WmiEnumerateGuids advapi32 1831 -imp 'WmiExecuteMethodA' WmiExecuteMethodA advapi32 1832 -imp 'WmiExecuteMethod' WmiExecuteMethodW advapi32 1833 -imp 'WmiFileHandleToInstanceNameA' WmiFileHandleToInstanceNameA advapi32 1834 -imp 'WmiFileHandleToInstanceName' WmiFileHandleToInstanceNameW advapi32 1835 -imp 'WmiFreeBuffer' WmiFreeBuffer advapi32 1836 -imp 'WmiMofEnumerateResourcesA' WmiMofEnumerateResourcesA advapi32 1837 -imp 'WmiMofEnumerateResources' WmiMofEnumerateResourcesW advapi32 1838 -imp 'WmiNotificationRegistrationA' WmiNotificationRegistrationA advapi32 1839 -imp 'WmiNotificationRegistration' WmiNotificationRegistrationW advapi32 1840 -imp 'WmiOpenBlock' WmiOpenBlock advapi32 1841 -imp 'WmiQueryAllDataA' WmiQueryAllDataA advapi32 1842 -imp 'WmiQueryAllDataMultipleA' WmiQueryAllDataMultipleA advapi32 1843 -imp 'WmiQueryAllDataMultiple' WmiQueryAllDataMultipleW advapi32 1844 -imp 'WmiQueryAllData' WmiQueryAllDataW advapi32 1845 -imp 'WmiQueryGuidInformation' WmiQueryGuidInformation advapi32 1846 -imp 'WmiQuerySingleInstanceA' WmiQuerySingleInstanceA advapi32 1847 -imp 'WmiQuerySingleInstanceMultipleA' WmiQuerySingleInstanceMultipleA advapi32 1848 -imp 'WmiQuerySingleInstanceMultiple' WmiQuerySingleInstanceMultipleW advapi32 1849 -imp 'WmiQuerySingleInstance' WmiQuerySingleInstanceW advapi32 1850 -imp 'WmiReceiveNotificationsA' WmiReceiveNotificationsA advapi32 1851 -imp 'WmiReceiveNotifications' WmiReceiveNotificationsW advapi32 1852 -imp 'WmiSetSingleInstanceA' WmiSetSingleInstanceA advapi32 1853 -imp 'WmiSetSingleInstance' WmiSetSingleInstanceW advapi32 1854 -imp 'WmiSetSingleItemA' WmiSetSingleItemA advapi32 1855 -imp 'WmiSetSingleItem' WmiSetSingleItemW advapi32 1856 -imp 'Wow64DisableWow64FsRedirection' Wow64DisableWow64FsRedirection kernel32 0 # KernelBase -imp 'Wow64EnableWow64FsRedirection' Wow64EnableWow64FsRedirection kernel32 1545 -imp 'Wow64GetThreadContext' Wow64GetThreadContext kernel32 1546 -imp 'Wow64GetThreadSelectorEntry' Wow64GetThreadSelectorEntry kernel32 1547 -imp 'Wow64RevertWow64FsRedirection' Wow64RevertWow64FsRedirection kernel32 0 # KernelBase -imp 'Wow64SetThreadContext' Wow64SetThreadContext kernel32 1549 -imp 'Wow64SetThreadDefaultGuestMachine' Wow64SetThreadDefaultGuestMachine KernelBase 1813 -imp 'Wow64SuspendThread' Wow64SuspendThread kernel32 1550 -imp 'WriteCabinetState' WriteCabinetState shell32 652 -imp 'WriteConsole' WriteConsoleW kernel32 0 5 # KernelBase -imp 'WriteConsoleA' WriteConsoleA kernel32 0 5 # KernelBase -imp 'WriteConsoleInput' WriteConsoleInputW kernel32 0 4 # KernelBase -imp 'WriteConsoleInputA' WriteConsoleInputA kernel32 0 4 # KernelBase -imp 'WriteConsoleInputVDMA' WriteConsoleInputVDMA kernel32 1553 -imp 'WriteConsoleInputVDMW' WriteConsoleInputVDMW kernel32 1554 -imp 'WriteConsoleOutput' WriteConsoleOutputW kernel32 0 # KernelBase -imp 'WriteConsoleOutputA' WriteConsoleOutputA kernel32 0 # KernelBase -imp 'WriteConsoleOutputAttribute' WriteConsoleOutputAttribute kernel32 0 5 # KernelBase -imp 'WriteConsoleOutputCharacter' WriteConsoleOutputCharacterW kernel32 0 5 # KernelBase -imp 'WriteConsoleOutputCharacterA' WriteConsoleOutputCharacterA kernel32 0 5 # KernelBase -imp 'WriteEncryptedFileRaw' WriteEncryptedFileRaw advapi32 1857 -imp 'WriteFile' WriteFile kernel32 0 5 # KernelBase -imp 'WriteFileEx' WriteFileEx kernel32 0 5 # KernelBase -imp 'WriteFileGather' WriteFileGather kernel32 0 5 # KernelBase -imp 'WritePrivateProfileSectionA' WritePrivateProfileSectionA kernel32 1565 -imp 'WritePrivateProfileSection' WritePrivateProfileSectionW kernel32 1566 -imp 'WritePrivateProfileStringA' WritePrivateProfileStringA kernel32 1567 -imp 'WritePrivateProfileString' WritePrivateProfileStringW kernel32 1568 -imp 'WritePrivateProfileStructA' WritePrivateProfileStructA kernel32 1569 -imp 'WritePrivateProfileStruct' WritePrivateProfileStructW kernel32 1570 -imp 'WriteProcessMemory' WriteProcessMemory kernel32 0 # KernelBase -imp 'WriteProfileSectionA' WriteProfileSectionA kernel32 1572 -imp 'WriteProfileSection' WriteProfileSectionW kernel32 1573 -imp 'WriteProfileStringA' WriteProfileStringA kernel32 1574 -imp 'WriteProfileString' WriteProfileStringW kernel32 1575 -imp 'WriteStateAtomValue' WriteStateAtomValue KernelBase 1827 -imp 'WriteStateContainerValue' WriteStateContainerValue KernelBase 1828 -imp 'WriteTapemark' WriteTapemark kernel32 1576 -imp 'XFORMOBJ_bApplyXform' XFORMOBJ_bApplyXform gdi32 1942 -imp 'XFORMOBJ_iGetXform' XFORMOBJ_iGetXform gdi32 1943 -imp 'XLATEOBJ_cGetPalette' XLATEOBJ_cGetPalette gdi32 1944 -imp 'XLATEOBJ_hGetColorTransform' XLATEOBJ_hGetColorTransform gdi32 1945 -imp 'XLATEOBJ_iXlate' XLATEOBJ_iXlate gdi32 1946 -imp 'XLATEOBJ_piVector' XLATEOBJ_piVector gdi32 1947 -imp 'ZombifyActCtx' ZombifyActCtx kernel32 0 # KernelBase -imp 'ZombifyActCtxWorker' ZombifyActCtxWorker kernel32 1578 imp 'ZwAcceptConnectPort' ZwAcceptConnectPort ntdll 1711 imp 'ZwAccessCheck' ZwAccessCheck ntdll 1712 imp 'ZwAccessCheckAndAuditAlarm' ZwAccessCheckAndAuditAlarm ntdll 1713 @@ -7671,220 +6678,3 @@ imp 'ZwWriteFileGather' ZwWriteFileGather ntdll 2169 imp 'ZwWriteRequestData' ZwWriteRequestData ntdll 2170 imp 'ZwWriteVirtualMemory' ZwWriteVirtualMemory ntdll 2171 imp 'ZwYieldExecution' ZwYieldExecution ntdll 2172 -imp '_AddMUIStringToCache' _AddMUIStringToCache KernelBase 1830 -imp '_GetMUIStringFromCache' _GetMUIStringFromCache KernelBase 1831 -imp '_OpenMuiStringCache' _OpenMuiStringCache KernelBase 1832 -imp '_UserTestTokenForInteractive' _UserTestTokenForInteractive user32 2543 -imp '_amsg_exit' _amsg_exit KernelBase 1838 -imp '_atoi64' _atoi64 ntdll 2180 -imp '_c_exit' _c_exit KernelBase 1839 -imp '_cexit' _cexit KernelBase 1840 -imp '_errno' _errno ntdll 2181 -imp 'sys__exit_nt' _exit KernelBase 1841 -imp '_fltused' _fltused ntdll 2182 -imp '_hread' _hread kernel32 1582 -imp '_hwrite' _hwrite kernel32 1583 -imp '_initterm' _initterm KernelBase 1842 -imp '_initterm_e' _initterm_e KernelBase 1843 -imp '_invalid_parameter' _invalid_parameter KernelBase 1844 -imp '_lclose' _lclose kernel32 1584 -imp '_lcreat' _lcreat kernel32 1585 -imp '_lfind' _lfind ntdll 2191 -imp '_llseek' _llseek kernel32 1586 -imp '_local_unwind' _local_unwind ntdll 2192 -imp '_lopen' _lopen kernel32 1588 -imp '_lread' _lread kernel32 1589 -imp '_lwrite' _lwrite kernel32 1590 -imp '_makepath_s' _makepath_s ntdll 2197 -imp '_memccpy' _memccpy ntdll 2198 -imp '_memicmp' _memicmp ntdll 2199 -imp '_onexit' _onexit KernelBase 1846 -imp '_purecall' _purecall KernelBase 1847 -imp 'sys__setjmp_nt' _setjmp ntdll 2200 -imp '_setjmpex' _setjmpex ntdll 2201 -imp '_time64' _time64 KernelBase 1848 -imp '_wmakepath_s' _wmakepath_s ntdll 2245 -imp '_wsplitpath_s' _wsplitpath_s ntdll 2246 -imp '_wtoi' _wtoi ntdll 2247 -imp '_wtoi64' _wtoi64 ntdll 2248 -imp '_wtol' _wtol ntdll 2249 -imp 'sys_abs_nt' abs ntdll 2250 -imp '__sys_accept_nt' accept ws2_32 1 -imp 'sys_atan_nt' atan ntdll 2251 -imp 'sys_atan2_nt' atan2 ntdll 2252 -imp 'sys_atexit_nt' atexit KernelBase 1849 -imp 'sys_atoi_nt' atoi ntdll 2253 -imp 'sys_atol_nt' atol ntdll 2254 -imp 'bCreateDCW' bCreateDCW gdi32 1948 -imp 'bDeleteLDC' bDeleteLDC gdi32 1949 -imp 'bInitSystemAndFontsDirectories' bInitSystemAndFontsDirectoriesW gdi32 1950 -imp 'bMakePathName' bMakePathNameW gdi32 1951 -imp '__sys_bind_nt' bind ws2_32 2 3 -imp 'sys_bsearch_nt' bsearch ntdll 2255 -imp 'bsearch_s' bsearch_s ntdll 2256 -imp 'cGetTTFFromFOT' cGetTTFFromFOT gdi32 1952 -imp 'sys_ceil_nt' ceil ntdll 2257 -imp '__sys_closesocket_nt' closesocket ws2_32 3 1 -imp '__sys_connect_nt' connect ws2_32 4 -imp 'sys_cos_nt' cos ntdll 2258 -imp 'dwLBSubclass' dwLBSubclass comdlg32 128 -imp 'dwOKSubclass' dwOKSubclass comdlg32 129 -imp 'sys_exit_nt' exit KernelBase 1850 -imp 'sys_fabs_nt' fabs ntdll 2259 -imp 'sys_floor_nt' floor ntdll 2260 -imp 'fpClosePrinter' fpClosePrinter gdi32 1953 -imp 'sys_freeaddrinfo_nt' freeaddrinfo ws2_32 190 -imp 'gMaxGdiHandleCount' gMaxGdiHandleCount gdi32 1955 -imp 'gSharedInfo' gSharedInfo user32 2547 -imp 'gW32PID' gW32PID gdi32 1956 -imp 'g_systemCallFilterId' g_systemCallFilterId gdi32 1957 -imp 'gapfnScSendMessage' gapfnScSendMessage user32 2562 -imp 'gdiPlaySpoolStream' gdiPlaySpoolStream gdi32 1958 -imp 'sys_getaddrinfo_nt' getaddrinfo ws2_32 191 -imp 'sys_gethostbyaddr_nt' gethostbyaddr ws2_32 51 -imp 'sys_gethostbyname_nt' gethostbyname ws2_32 52 -imp 'sys_gethostname_nt' gethostname ws2_32 57 -imp 'sys_getnameinfo_nt' getnameinfo ws2_32 192 -imp '__sys_getpeername_nt' getpeername ws2_32 5 3 -imp 'sys_getprotobyname_nt' getprotobyname ws2_32 53 -imp 'sys_getprotobynumber_nt' getprotobynumber ws2_32 54 -imp 'sys_getservbyname_nt' getservbyname ws2_32 55 -imp 'sys_getservbyport_nt' getservbyport ws2_32 56 -imp '__sys_getsockname_nt' getsockname ws2_32 6 3 -imp '__sys_getsockopt_nt' getsockopt ws2_32 7 5 -imp 'ghICM' ghICM gdi32 1959 -imp 'hGetPEBHandle' hGetPEBHandle gdi32 1960 -imp 'hgets' hgets KernelBase 1851 -imp 'hwprintf' hwprintf KernelBase 1852 -imp '__sys_ioctlsocket_nt' ioctlsocket ws2_32 10 3 -imp 'iswascii' iswascii ntdll 2273 -imp 'keybd_event' keybd_event user32 2580 -imp 'sys_labs_nt' labs ntdll 2282 -imp '__sys_listen_nt' listen ws2_32 13 2 -imp 'sys_log_nt' log ntdll 2283 -imp 'sys_longjmp_nt' longjmp ntdll 2284 -imp 'mouse_event' mouse_event user32 2583 -imp 'pGdiDevCaps' pGdiDevCaps gdi32 1961 -imp 'pGdiSharedHandleTable' pGdiSharedHandleTable gdi32 1962 -imp 'pGdiSharedMemory' pGdiSharedMemory gdi32 1963 -imp 'pldcGet' pldcGet gdi32 1964 -imp 'sys_recv_nt' recv ws2_32 16 -imp '__sys_recvfrom_nt' recvfrom ws2_32 17 -imp '__sys_select_nt' select ws2_32 18 5 -imp 'semDxTrimNotification' semDxTrimNotification gdi32 1965 -imp 'sys_send_nt' send ws2_32 19 -imp '__sys_sendto_nt' sendto ws2_32 20 -imp '__sys_setsockopt_nt' setsockopt ws2_32 21 5 -imp '__sys_shutdown_nt' shutdown ws2_32 22 2 -imp 'sys_sin_nt' sin ntdll 2296 -imp '__sys_socket_nt' socket ws2_32 23 -imp 'timeBeginPeriod' timeBeginPeriod kernel32 1609 -imp 'timeEndPeriod' timeEndPeriod kernel32 1610 -imp 'timeGetDevCaps' timeGetDevCaps kernel32 1611 -imp 'timeGetSystemTime' timeGetSystemTime kernel32 1612 -imp 'timeGetTime' timeGetTime kernel32 1613 - -imp 'InitializeCriticalSection' InitializeCriticalSection kernel32 0 1 # KernelBase -imp 'EnterCriticalSection' EnterCriticalSection kernel32 0 1 # KernelBase -imp 'LeaveCriticalSection' LeaveCriticalSection kernel32 0 1 # KernelBase -imp 'TryEnterCriticalSection' TryEnterCriticalSection kernel32 0 1 # KernelBase -imp 'DeleteCriticalSection' DeleteCriticalSection kernel32 0 1 # KernelBase -imp 'InitializeCriticalSectionAndSpinCount' InitializeCriticalSectionAndSpinCount kernel32 0 2 # KernelBase -imp 'SetCriticalSectionSpinCount' SetCriticalSectionSpinCount kernel32 0 2 # KernelBase - -imp 'InitializeSRWLock' InitializeSRWLock kernel32 0 1 # KernelBase -imp 'AcquireSRWLockExclusive' AcquireSRWLockExclusive kernel32 0 1 # KernelBase -imp 'AcquireSRWLockShared' AcquireSRWLockShared kernel32 0 1 # KernelBase -imp 'ReleaseSRWLockExclusive' ReleaseSRWLockExclusive kernel32 0 1 # KernelBase -imp 'ReleaseSRWLockShared' ReleaseSRWLockShared kernel32 0 1 # KernelBase -imp 'TryAcquireSRWLockExclusive' TryAcquireSRWLockExclusive kernel32 0 1 # KernelBase -imp 'TryAcquireSRWLockShared' TryAcquireSRWLockShared kernel32 0 1 # KernelBase - -imp 'AddIPAddress' AddIPAddress iphlpapi 0 5 -imp 'AllocateAndGetTcpExTableFromStack' AllocateAndGetTcpExTableFromStack iphlpapi 0 5 -imp 'AllocateAndGetUdpExTableFromStack' AllocateAndGetUdpExTableFromStack iphlpapi 0 5 -imp 'CancelIPChangeNotify' CancelIPChangeNotify iphlpapi 0 1 -imp 'CaptureInterfaceHardwareCrossTimestamp' CaptureInterfaceHardwareCrossTimestamp iphlpapi 0 2 -imp 'CreateIpForwardEntry' CreateIpForwardEntry iphlpapi 0 1 -imp 'CreateIpNetEntry' CreateIpNetEntry iphlpapi 0 -imp 'CreatePersistentTcpPortReservation' CreatePersistentTcpPortReservation iphlpapi 0 -imp 'CreatePersistentUdpPortReservation' CreatePersistentUdpPortReservation iphlpapi 0 -imp 'CreateProxyArpEntry' CreateProxyArpEntry iphlpapi 0 -imp 'DeleteIPAddress' DeleteIPAddress iphlpapi 0 -imp 'DeleteIpForwardEntry' DeleteIpForwardEntry iphlpapi 0 -imp 'DeleteIpNetEntry' DeleteIpNetEntry iphlpapi 0 -imp 'DeletePersistentTcpPortReservation' DeletePersistentTcpPortReservation iphlpapi 0 -imp 'DeletePersistentUdpPortReservation' DeletePersistentUdpPortReservation iphlpapi 0 -imp 'DeleteProxyArpEntry' DeleteProxyArpEntry iphlpapi 0 -imp 'DisableMediaSense' DisableMediaSense iphlpapi 0 -imp 'EnableRouter' EnableRouter iphlpapi 0 -imp 'FlushIpNetTable' FlushIpNetTable iphlpapi 0 1 -imp 'GetAdapterIndex' GetAdapterIndex iphlpapi 0 2 -imp 'GetAdapterOrderMap' GetAdapterOrderMap iphlpapi 0 0 -imp 'GetAdaptersAddresses' GetAdaptersAddresses iphlpapi 67 5 -imp 'GetAdaptersInfo' GetAdaptersInfo iphlpapi 0 2 -imp 'GetBestInterface' GetBestInterface iphlpapi 0 2 -imp 'GetBestInterfaceEx' GetBestInterfaceEx iphlpapi 0 2 -imp 'GetBestRoute' GetBestRoute iphlpapi 0 3 -imp 'GetExtendedTcpTable' GetExtendedTcpTable iphlpapi 0 -imp 'GetExtendedUdpTable' GetExtendedUdpTable iphlpapi 0 -imp 'GetFriendlyIfIndex' GetFriendlyIfIndex iphlpapi 0 -imp 'GetIcmpStatistics' GetIcmpStatistics iphlpapi 0 -imp 'GetIcmpStatisticsEx' GetIcmpStatisticsEx iphlpapi 0 -imp 'GetIfEntry' GetIfEntry iphlpapi 0 -imp 'GetIfTable' GetIfTable iphlpapi 0 -imp 'GetInterfaceActiveTimestampCapabilities' GetInterfaceActiveTimestampCapabilities iphlpapi 0 -imp 'GetInterfaceInfo' GetInterfaceInfo iphlpapi 0 -imp 'GetInterfaceSupportedTimestampCapabilities' GetInterfaceSupportedTimestampCapabilities iphlpapi 0 -imp 'GetIpAddrTable' GetIpAddrTable iphlpapi 0 -imp 'GetIpErrorString' GetIpErrorString iphlpapi 0 -imp 'GetIpForwardTable' GetIpForwardTable iphlpapi 0 -imp 'GetIpNetTable' GetIpNetTable iphlpapi 0 -imp 'GetIpStatistics' GetIpStatistics iphlpapi 0 -imp 'GetIpStatisticsEx' GetIpStatisticsEx iphlpapi 0 -imp 'GetNetworkParams' GetNetworkParams iphlpapi 0 -imp 'GetNumberOfInterfaces' GetNumberOfInterfaces iphlpapi 0 1 -imp 'GetOwnerModuleFromTcp6Entry' GetOwnerModuleFromTcp6Entry iphlpapi 0 -imp 'GetOwnerModuleFromTcpEntry' GetOwnerModuleFromTcpEntry iphlpapi 0 -imp 'GetOwnerModuleFromUdp6Entry' GetOwnerModuleFromUdp6Entry iphlpapi 0 -imp 'GetOwnerModuleFromUdpEntry' GetOwnerModuleFromUdpEntry iphlpapi 0 -imp 'GetPerAdapterInfo' GetPerAdapterInfo iphlpapi 0 -imp 'GetPerTcp6ConnectionEStats' GetPerTcp6ConnectionEStats iphlpapi 0 -imp 'GetPerTcpConnectionEStats' GetPerTcpConnectionEStats iphlpapi 0 -imp 'GetRTTAndHopCount' GetRTTAndHopCount iphlpapi 0 -imp 'GetTcp6Table' GetTcp6Table iphlpapi 0 -imp 'GetTcp6Table2' GetTcp6Table2 iphlpapi 0 -imp 'GetTcpStatistics' GetTcpStatistics iphlpapi 0 -imp 'GetTcpStatisticsEx' GetTcpStatisticsEx iphlpapi 0 -imp 'GetTcpStatisticsEx2' GetTcpStatisticsEx2 iphlpapi 0 -imp 'GetTcpTable' GetTcpTable iphlpapi 0 3 -imp 'GetTcpTable2' GetTcpTable2 iphlpapi 0 3 -imp 'GetUdp6Table' GetUdp6Table iphlpapi 0 -imp 'GetUdpStatistics' GetUdpStatistics iphlpapi 0 -imp 'GetUdpStatisticsEx' GetUdpStatisticsEx iphlpapi 0 -imp 'GetUdpStatisticsEx2' GetUdpStatisticsEx2 iphlpapi 0 -imp 'GetUdpTable' GetUdpTable iphlpapi 0 -imp 'GetUniDirectionalAdapterInfo' GetUniDirectionalAdapterInfo iphlpapi 0 -imp 'IpReleaseAddress' IpReleaseAddress iphlpapi 0 -imp 'IpRenewAddress' IpRenewAddress iphlpapi 0 -imp 'LookupPersistentTcpPortReservation' LookupPersistentTcpPortReservation iphlpapi 0 -imp 'LookupPersistentUdpPortReservation' LookupPersistentUdpPortReservation iphlpapi 0 -imp 'NhpAllocateAndGetInterfaceInfoFromStack' NhpAllocateAndGetInterfaceInfoFromStack iphlpapi 0 -imp 'NotifyAddrChange' NotifyAddrChange iphlpapi 0 -imp 'NotifyRouteChange' NotifyRouteChange iphlpapi 0 -imp 'ParseNetworkString' ParseNetworkString iphlpapi 0 -imp 'RegisterInterfaceTimestampConfigChange' RegisterInterfaceTimestampConfigChange iphlpapi 0 -imp 'ResolveNeighbor' ResolveNeighbor iphlpapi 0 -imp 'RestoreMediaSense' RestoreMediaSense iphlpapi 0 -imp 'SendARP' SendARP iphlpapi 0 -imp 'SetIfEntry' SetIfEntry iphlpapi 0 -imp 'SetIpForwardEntry' SetIpForwardEntry iphlpapi 0 -imp 'SetIpNetEntry' SetIpNetEntry iphlpapi 0 -imp 'SetIpStatistics' SetIpStatistics iphlpapi 0 -imp 'SetIpStatisticsEx' SetIpStatisticsEx iphlpapi 0 -imp 'SetIpTTL' SetIpTTL iphlpapi 0 -imp 'SetPerTcp6ConnectionEStats' SetPerTcp6ConnectionEStats iphlpapi 0 -imp 'SetPerTcpConnectionEStats' SetPerTcpConnectionEStats iphlpapi 0 -imp 'SetTcpEntry' SetTcpEntry iphlpapi 0 -imp 'UnenableRouter' UnenableRouter iphlpapi 0 -imp 'UnregisterInterfaceTimestampConfigChange' UnregisterInterfaceTimestampConfigChange iphlpapi 0 diff --git a/libc/nt/memory.h b/libc/nt/memory.h index c729f9726..9086f4025 100644 --- a/libc/nt/memory.h +++ b/libc/nt/memory.h @@ -36,18 +36,26 @@ COSMOPOLITAN_C_START_ void *LocalFree(void *hMem); +int64_t CreateFileMapping( + int64_t opt_hFile, + const struct NtSecurityAttributes *opt_lpFileMappingAttributes, + uint32_t flProtect, uint32_t dwMaximumSizeHigh, uint32_t dwMaximumSizeLow, + const char16_t *opt_lpName); int64_t CreateFileMappingNuma( - int64_t opt_hFile /* -1ul is MAP_ANONYMOUS */, + int64_t opt_hFile, const struct NtSecurityAttributes *opt_lpFileMappingAttributes, uint32_t flProtect, uint32_t dwMaximumSizeHigh, uint32_t dwMaximumSizeLow, const char16_t *opt_lpName, uint32_t nndDesiredNumaNode); -void *MapViewOfFileExNuma( - int64_t hFileMappingObject, /* @see CreateFileMapping() */ - uint32_t dwDesiredAccess, uint32_t dwFileOffsetHigh, /* high order bits */ - uint32_t dwFileOffsetLow, /* low order bits */ - size_t dwNumberOfBytesToMap, void *opt_lpDesiredBaseAddress, - uint32_t nndDesiredNumaNode); +void *MapViewOfFileEx(int64_t hFileMappingObject, uint32_t dwDesiredAccess, + uint32_t dwFileOffsetHigh, uint32_t dwFileOffsetLow, + size_t dwNumberOfBytesToMap, + void *opt_lpDesiredBaseAddress); +void *MapViewOfFileExNuma(int64_t hFileMappingObject, uint32_t dwDesiredAccess, + uint32_t dwFileOffsetHigh, uint32_t dwFileOffsetLow, + size_t dwNumberOfBytesToMap, + void *opt_lpDesiredBaseAddress, + uint32_t nndDesiredNumaNode); bool32 UnmapViewOfFile(const void *lpBaseAddress); bool32 FlushViewOfFile(const void *lpBaseAddress, @@ -70,7 +78,13 @@ bool32 PrefetchVirtualMemory(int64_t hProcess, const uint32_t *NumberOfEntries, bool32 OfferVirtualMemory(void *inout_VirtualAddress, size_t Size, int Priority); -void *GlobalAlloc(uint32_t uFlags, uint64_t dwBytes) nodiscard; +int64_t GetProcessHeap(void); +void *HeapAlloc(int64_t hHeap, uint32_t dwFlags, size_t dwBytes) dontdiscard; +bool32 HeapFree(int64_t hHeap, uint32_t dwFlags, void *opt_lpMem); +void *HeapReAlloc(int64_t hHeap, uint32_t dwFlags, void *lpMem, + size_t dwBytes) dontdiscard; + +void *GlobalAlloc(uint32_t uFlags, uint64_t dwBytes) dontdiscard; void *GlobalFree(void *hMem); #if ShouldUseMsabiAttribute() diff --git a/libc/nt/nt.mk b/libc/nt/nt.mk index 767e793db..67d25a6a4 100644 --- a/libc/nt/nt.mk +++ b/libc/nt/nt.mk @@ -112,27 +112,6 @@ $(LIBC_NT_GDI32_A).pkg: \ #─────────────────────────────────────────────────────────────────────────────── -LIBC_NT_ARTIFACTS += LIBC_NT_KERNELBASE_A -LIBC_NT_KERNELBASE = $(LIBC_NT_KERNELBASE_A_DEPS) $(LIBC_NT_KERNELBASE_A) -LIBC_NT_KERNELBASE_A = o/$(MODE)/libc/nt/KernelBase.a -LIBC_NT_KERNELBASE_A_SRCS := $(wildcard libc/nt/KernelBase/*.s) -LIBC_NT_KERNELBASE_A_OBJS = $(LIBC_NT_KERNELBASE_A_SRCS:%.s=o/$(MODE)/%.o) -LIBC_NT_KERNELBASE_A_CHECKS = $(LIBC_NT_KERNELBASE_A).pkg -LIBC_NT_KERNELBASE_A_DIRECTDEPS = LIBC_NT_KERNEL32 -LIBC_NT_KERNELBASE_A_DEPS := \ - $(call uniq,$(foreach x,$(LIBC_NT_KERNELBASE_A_DIRECTDEPS),$($(x)))) - -$(LIBC_NT_KERNELBASE_A): \ - libc/nt/KernelBase/ \ - $(LIBC_NT_KERNELBASE_A).pkg \ - $(LIBC_NT_KERNELBASE_A_OBJS) - -$(LIBC_NT_KERNELBASE_A).pkg: \ - $(LIBC_NT_KERNELBASE_A_OBJS) \ - $(foreach x,$(LIBC_NT_KERNELBASE_A_DIRECTDEPS),$($(x)_A).pkg) - -#─────────────────────────────────────────────────────────────────────────────── - LIBC_NT_ARTIFACTS += LIBC_NT_NTDLL_A LIBC_NT_NTDLL = $(LIBC_NT_NTDLL_A_DEPS) $(LIBC_NT_NTDLL_A) LIBC_NT_NTDLL_A = o/$(MODE)/libc/nt/ntdll.a @@ -332,22 +311,60 @@ $(LIBC_NT_IPHLPAPI_A).pkg: \ #─────────────────────────────────────────────────────────────────────────────── -LIBC_NT_ARTIFACTS += LIBC_NT_POWERPROF_A -LIBC_NT_POWERPROF = $(LIBC_NT_POWERPROF_A_DEPS) $(LIBC_NT_POWERPROF_A) -LIBC_NT_POWERPROF_A = o/$(MODE)/libc/nt/powerprof.a -LIBC_NT_POWERPROF_A_SRCS := $(wildcard libc/nt/PowerProf/*.s) -LIBC_NT_POWERPROF_A_OBJS = $(LIBC_NT_POWERPROF_A_SRCS:%.s=o/$(MODE)/%.o) -LIBC_NT_POWERPROF_A_CHECKS = $(LIBC_NT_POWERPROF_A).pkg -LIBC_NT_POWERPROF_A_DIRECTDEPS = LIBC_NT_KERNEL32 -LIBC_NT_POWERPROF_A_DEPS := \ - $(call uniq,$(foreach x,$(LIBC_NT_POWERPROF_A_DIRECTDEPS),$($(x)))) -$(LIBC_NT_POWERPROF_A): \ - libc/nt/PowerProf/ \ - $(LIBC_NT_POWERPROF_A).pkg \ - $(LIBC_NT_POWERPROF_A_OBJS) -$(LIBC_NT_POWERPROF_A).pkg: \ - $(LIBC_NT_POWERPROF_A_OBJS) \ - $(foreach x,$(LIBC_NT_POWERPROF_A_DIRECTDEPS),$($(x)_A).pkg) +LIBC_NT_ARTIFACTS += LIBC_NT_POWRPROF_A +LIBC_NT_POWRPROF = $(LIBC_NT_POWRPROF_A_DEPS) $(LIBC_NT_POWRPROF_A) +LIBC_NT_POWRPROF_A = o/$(MODE)/libc/nt/powrprof.a +LIBC_NT_POWRPROF_A_SRCS := $(wildcard libc/nt/PowrProf/*.s) +LIBC_NT_POWRPROF_A_OBJS = $(LIBC_NT_POWRPROF_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_POWRPROF_A_CHECKS = $(LIBC_NT_POWRPROF_A).pkg +LIBC_NT_POWRPROF_A_DIRECTDEPS = LIBC_NT_KERNEL32 +LIBC_NT_POWRPROF_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_POWRPROF_A_DIRECTDEPS),$($(x)))) +$(LIBC_NT_POWRPROF_A): \ + libc/nt/PowrProf/ \ + $(LIBC_NT_POWRPROF_A).pkg \ + $(LIBC_NT_POWRPROF_A_OBJS) +$(LIBC_NT_POWRPROF_A).pkg: \ + $(LIBC_NT_POWRPROF_A_OBJS) \ + $(foreach x,$(LIBC_NT_POWRPROF_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_PDH_A +LIBC_NT_PDH = $(LIBC_NT_PDH_A_DEPS) $(LIBC_NT_PDH_A) +LIBC_NT_PDH_A = o/$(MODE)/libc/nt/pdh.a +LIBC_NT_PDH_A_SRCS := $(wildcard libc/nt/pdh/*.s) +LIBC_NT_PDH_A_OBJS = $(LIBC_NT_PDH_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_PDH_A_CHECKS = $(LIBC_NT_PDH_A).pkg +LIBC_NT_PDH_A_DIRECTDEPS = LIBC_NT_KERNEL32 +LIBC_NT_PDH_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_PDH_A_DIRECTDEPS),$($(x)))) +$(LIBC_NT_PDH_A): \ + libc/nt/pdh/ \ + $(LIBC_NT_PDH_A).pkg \ + $(LIBC_NT_PDH_A_OBJS) +$(LIBC_NT_PDH_A).pkg: \ + $(LIBC_NT_PDH_A_OBJS) \ + $(foreach x,$(LIBC_NT_PDH_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_PSAPI_A +LIBC_NT_PSAPI = $(LIBC_NT_PSAPI_A_DEPS) $(LIBC_NT_PSAPI_A) +LIBC_NT_PSAPI_A = o/$(MODE)/libc/nt/psapi.a +LIBC_NT_PSAPI_A_SRCS := $(wildcard libc/nt/psapi/*.s) +LIBC_NT_PSAPI_A_OBJS = $(LIBC_NT_PSAPI_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_PSAPI_A_CHECKS = $(LIBC_NT_PSAPI_A).pkg +LIBC_NT_PSAPI_A_DIRECTDEPS = LIBC_NT_KERNEL32 +LIBC_NT_PSAPI_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_PSAPI_A_DIRECTDEPS),$($(x)))) +$(LIBC_NT_PSAPI_A): \ + libc/nt/psapi/ \ + $(LIBC_NT_PSAPI_A).pkg \ + $(LIBC_NT_PSAPI_A_OBJS) +$(LIBC_NT_PSAPI_A).pkg: \ + $(LIBC_NT_PSAPI_A_OBJS) \ + $(foreach x,$(LIBC_NT_PSAPI_A_DIRECTDEPS),$($(x)_A).pkg) #─────────────────────────────────────────────────────────────────────────────── diff --git a/libc/nt/ntdll/EtwRegisterTraceGuidsA.s b/libc/nt/ntdll/EtwRegisterTraceGuidsA.s deleted file mode 100644 index 3aa28c326..000000000 --- a/libc/nt/ntdll/EtwRegisterTraceGuidsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp EtwRegisterTraceGuidsA diff --git a/libc/nt/ntdll/NtdllDefWindowProc_A.s b/libc/nt/ntdll/NtdllDefWindowProc_A.s deleted file mode 100644 index 3cd3bb870..000000000 --- a/libc/nt/ntdll/NtdllDefWindowProc_A.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp NtdllDefWindowProc_A diff --git a/libc/nt/ntdll/NtdllDialogWndProc_A.s b/libc/nt/ntdll/NtdllDialogWndProc_A.s deleted file mode 100644 index 32b492cda..000000000 --- a/libc/nt/ntdll/NtdllDialogWndProc_A.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp NtdllDialogWndProc_A diff --git a/libc/nt/ntdll/RtlEthernetAddressToStringA.s b/libc/nt/ntdll/RtlEthernetAddressToStringA.s deleted file mode 100644 index a76641a00..000000000 --- a/libc/nt/ntdll/RtlEthernetAddressToStringA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlEthernetAddressToStringA diff --git a/libc/nt/ntdll/RtlEthernetStringToAddressA.s b/libc/nt/ntdll/RtlEthernetStringToAddressA.s deleted file mode 100644 index d234cefc1..000000000 --- a/libc/nt/ntdll/RtlEthernetStringToAddressA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlEthernetStringToAddressA diff --git a/libc/nt/ntdll/RtlIpv4AddressToStringA.s b/libc/nt/ntdll/RtlIpv4AddressToStringA.s deleted file mode 100644 index c9f6fe8bf..000000000 --- a/libc/nt/ntdll/RtlIpv4AddressToStringA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlIpv4AddressToStringA diff --git a/libc/nt/ntdll/RtlIpv4AddressToStringExA.s b/libc/nt/ntdll/RtlIpv4AddressToStringExA.s deleted file mode 100644 index 4184755e6..000000000 --- a/libc/nt/ntdll/RtlIpv4AddressToStringExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlIpv4AddressToStringExA diff --git a/libc/nt/ntdll/RtlIpv4StringToAddressA.s b/libc/nt/ntdll/RtlIpv4StringToAddressA.s deleted file mode 100644 index 010e104b1..000000000 --- a/libc/nt/ntdll/RtlIpv4StringToAddressA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlIpv4StringToAddressA diff --git a/libc/nt/ntdll/RtlIpv4StringToAddressExA.s b/libc/nt/ntdll/RtlIpv4StringToAddressExA.s deleted file mode 100644 index d8714c933..000000000 --- a/libc/nt/ntdll/RtlIpv4StringToAddressExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlIpv4StringToAddressExA diff --git a/libc/nt/ntdll/RtlIpv6AddressToStringA.s b/libc/nt/ntdll/RtlIpv6AddressToStringA.s deleted file mode 100644 index 6e61b4452..000000000 --- a/libc/nt/ntdll/RtlIpv6AddressToStringA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlIpv6AddressToStringA diff --git a/libc/nt/ntdll/RtlIpv6AddressToStringExA.s b/libc/nt/ntdll/RtlIpv6AddressToStringExA.s deleted file mode 100644 index c543f766f..000000000 --- a/libc/nt/ntdll/RtlIpv6AddressToStringExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlIpv6AddressToStringExA diff --git a/libc/nt/ntdll/RtlIpv6StringToAddressA.s b/libc/nt/ntdll/RtlIpv6StringToAddressA.s deleted file mode 100644 index ecebc8a49..000000000 --- a/libc/nt/ntdll/RtlIpv6StringToAddressA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlIpv6StringToAddressA diff --git a/libc/nt/ntdll/RtlIpv6StringToAddressExA.s b/libc/nt/ntdll/RtlIpv6StringToAddressExA.s deleted file mode 100644 index 14b73d8d5..000000000 --- a/libc/nt/ntdll/RtlIpv6StringToAddressExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp RtlIpv6StringToAddressExA diff --git a/libc/nt/ntdll/ShipAssertMsgA.s b/libc/nt/ntdll/ShipAssertMsgA.s deleted file mode 100644 index 24696c068..000000000 --- a/libc/nt/ntdll/ShipAssertMsgA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp ShipAssertMsgA diff --git a/libc/nt/ntdll/_atoi64.s b/libc/nt/ntdll/_atoi64.s deleted file mode 100644 index 627372f1d..000000000 --- a/libc/nt/ntdll/_atoi64.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _atoi64 diff --git a/libc/nt/ntdll/_errno.s b/libc/nt/ntdll/_errno.s deleted file mode 100644 index 4b5180ad1..000000000 --- a/libc/nt/ntdll/_errno.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _errno diff --git a/libc/nt/ntdll/_fltused.s b/libc/nt/ntdll/_fltused.s deleted file mode 100644 index c6e484479..000000000 --- a/libc/nt/ntdll/_fltused.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _fltused diff --git a/libc/nt/ntdll/_lfind.s b/libc/nt/ntdll/_lfind.s deleted file mode 100644 index e35607168..000000000 --- a/libc/nt/ntdll/_lfind.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _lfind diff --git a/libc/nt/ntdll/_local_unwind.s b/libc/nt/ntdll/_local_unwind.s deleted file mode 100644 index 62016943e..000000000 --- a/libc/nt/ntdll/_local_unwind.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _local_unwind diff --git a/libc/nt/ntdll/_makepath_s.s b/libc/nt/ntdll/_makepath_s.s deleted file mode 100644 index 1ac6a4d28..000000000 --- a/libc/nt/ntdll/_makepath_s.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _makepath_s diff --git a/libc/nt/ntdll/_memccpy.s b/libc/nt/ntdll/_memccpy.s deleted file mode 100644 index 9d5ee9d46..000000000 --- a/libc/nt/ntdll/_memccpy.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _memccpy diff --git a/libc/nt/ntdll/_memicmp.s b/libc/nt/ntdll/_memicmp.s deleted file mode 100644 index 26ee4f9ab..000000000 --- a/libc/nt/ntdll/_memicmp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _memicmp diff --git a/libc/nt/ntdll/_setjmp.s b/libc/nt/ntdll/_setjmp.s deleted file mode 100644 index 0d191e1b8..000000000 --- a/libc/nt/ntdll/_setjmp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _setjmp diff --git a/libc/nt/ntdll/_setjmpex.s b/libc/nt/ntdll/_setjmpex.s deleted file mode 100644 index 4a10e3867..000000000 --- a/libc/nt/ntdll/_setjmpex.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _setjmpex diff --git a/libc/nt/ntdll/_wmakepath_s.s b/libc/nt/ntdll/_wmakepath_s.s deleted file mode 100644 index b7c7a87c8..000000000 --- a/libc/nt/ntdll/_wmakepath_s.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _wmakepath_s diff --git a/libc/nt/ntdll/_wsplitpath_s.s b/libc/nt/ntdll/_wsplitpath_s.s deleted file mode 100644 index 6c3f5c7fc..000000000 --- a/libc/nt/ntdll/_wsplitpath_s.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _wsplitpath_s diff --git a/libc/nt/ntdll/_wtoi.s b/libc/nt/ntdll/_wtoi.s deleted file mode 100644 index ee6b579de..000000000 --- a/libc/nt/ntdll/_wtoi.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _wtoi diff --git a/libc/nt/ntdll/_wtoi64.s b/libc/nt/ntdll/_wtoi64.s deleted file mode 100644 index 11b722b3f..000000000 --- a/libc/nt/ntdll/_wtoi64.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _wtoi64 diff --git a/libc/nt/ntdll/_wtol.s b/libc/nt/ntdll/_wtol.s deleted file mode 100644 index 5e313f73e..000000000 --- a/libc/nt/ntdll/_wtol.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp _wtol diff --git a/libc/nt/ntdll/abs.s b/libc/nt/ntdll/abs.s deleted file mode 100644 index e35980ba0..000000000 --- a/libc/nt/ntdll/abs.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp abs diff --git a/libc/nt/ntdll/atan.s b/libc/nt/ntdll/atan.s deleted file mode 100644 index cbc1e6d9f..000000000 --- a/libc/nt/ntdll/atan.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp atan diff --git a/libc/nt/ntdll/atan2.s b/libc/nt/ntdll/atan2.s deleted file mode 100644 index 7034bfeae..000000000 --- a/libc/nt/ntdll/atan2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp atan2 diff --git a/libc/nt/ntdll/atoi.s b/libc/nt/ntdll/atoi.s deleted file mode 100644 index 7f018c96b..000000000 --- a/libc/nt/ntdll/atoi.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp atoi diff --git a/libc/nt/ntdll/atol.s b/libc/nt/ntdll/atol.s deleted file mode 100644 index 7f62fd421..000000000 --- a/libc/nt/ntdll/atol.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp atol diff --git a/libc/nt/ntdll/bsearch.s b/libc/nt/ntdll/bsearch.s deleted file mode 100644 index 088ef2b1a..000000000 --- a/libc/nt/ntdll/bsearch.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp bsearch diff --git a/libc/nt/ntdll/bsearch_s.s b/libc/nt/ntdll/bsearch_s.s deleted file mode 100644 index 807cf55cc..000000000 --- a/libc/nt/ntdll/bsearch_s.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp bsearch_s diff --git a/libc/nt/ntdll/ceil.s b/libc/nt/ntdll/ceil.s deleted file mode 100644 index 3620a156d..000000000 --- a/libc/nt/ntdll/ceil.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp ceil diff --git a/libc/nt/ntdll/cos.s b/libc/nt/ntdll/cos.s deleted file mode 100644 index 2a4c20554..000000000 --- a/libc/nt/ntdll/cos.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp cos diff --git a/libc/nt/ntdll/fabs.s b/libc/nt/ntdll/fabs.s deleted file mode 100644 index b36fb18e3..000000000 --- a/libc/nt/ntdll/fabs.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp fabs diff --git a/libc/nt/ntdll/floor.s b/libc/nt/ntdll/floor.s deleted file mode 100644 index 26f5229a5..000000000 --- a/libc/nt/ntdll/floor.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp floor diff --git a/libc/nt/ntdll/iswascii.s b/libc/nt/ntdll/iswascii.s deleted file mode 100644 index ca5a3b876..000000000 --- a/libc/nt/ntdll/iswascii.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp iswascii diff --git a/libc/nt/ntdll/labs.s b/libc/nt/ntdll/labs.s deleted file mode 100644 index f2abdb428..000000000 --- a/libc/nt/ntdll/labs.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp labs diff --git a/libc/nt/ntdll/log.s b/libc/nt/ntdll/log.s deleted file mode 100644 index 0a2e2c134..000000000 --- a/libc/nt/ntdll/log.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp log diff --git a/libc/nt/ntdll/longjmp.s b/libc/nt/ntdll/longjmp.s deleted file mode 100644 index cd225e259..000000000 --- a/libc/nt/ntdll/longjmp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp longjmp diff --git a/libc/nt/ntdll/sin.s b/libc/nt/ntdll/sin.s deleted file mode 100644 index 4e5d229f2..000000000 --- a/libc/nt/ntdll/sin.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/ntdllimport.inc" -.ntimp sin diff --git a/libc/nt/pdh.h b/libc/nt/pdh.h new file mode 100644 index 000000000..c3e0b09c5 --- /dev/null +++ b/libc/nt/pdh.h @@ -0,0 +1,48 @@ +#ifndef COSMOPOLITAN_LIBC_NT_PDH_H_ +#define COSMOPOLITAN_LIBC_NT_PDH_H_ +#include "libc/nt/struct/pdhfmtcountervalue.h" + +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » performance counters ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int PdhOpenQuery(const char16_t *opt_szDataSource, uint32_t *dwUserData, + int64_t *out_phQuery); + +int PdhAddEnglishCounter(int64_t hQuery, const char16_t *szFullCounterPath, + uint32_t *dwUserData, int64_t *out_phCounter); + +int PdhCollectQueryDataEx(int64_t hQuery, uint32_t dwIntervalTime, + int64_t hNewDataEvent); + +int PdhGetFormattedCounterValue(int64_t hCounter, uint32_t dwFormat, + uint32_t *out_opt_lpdwType, + struct NtPdhFmtCountervalue *out_pValue); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_PDH_H_ */ diff --git a/libc/nt/pdh/CounterPathCallBack.s b/libc/nt/pdh/CounterPathCallBack.s new file mode 100644 index 000000000..25dd6bb6e --- /dev/null +++ b/libc/nt/pdh/CounterPathCallBack.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_CounterPathCallBack,CounterPathCallBack,0 diff --git a/libc/nt/pdh/LoadPerfCounterTextStringsW.s b/libc/nt/pdh/LoadPerfCounterTextStringsW.s new file mode 100644 index 000000000..ac8c7dafa --- /dev/null +++ b/libc/nt/pdh/LoadPerfCounterTextStringsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_LoadPerfCounterTextStringsW,LoadPerfCounterTextStringsW,0 diff --git a/libc/nt/pdh/PdhAddCounterW.s b/libc/nt/pdh/PdhAddCounterW.s new file mode 100644 index 000000000..62bbe29f5 --- /dev/null +++ b/libc/nt/pdh/PdhAddCounterW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhAddCounterW,PdhAddCounterW,0 diff --git a/libc/nt/pdh/PdhAddEnglishCounterW.s b/libc/nt/pdh/PdhAddEnglishCounterW.s new file mode 100644 index 000000000..5910c3932 --- /dev/null +++ b/libc/nt/pdh/PdhAddEnglishCounterW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhAddEnglishCounterW,PdhAddEnglishCounterW,0 + + .text.windows +PdhAddEnglishCounter: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_PdhAddEnglishCounterW(%rip),%rax + jmp __sysv2nt + .endfn PdhAddEnglishCounter,globl + .previous diff --git a/libc/nt/pdh/PdhBindInputDataSourceW.s b/libc/nt/pdh/PdhBindInputDataSourceW.s new file mode 100644 index 000000000..3743d1f40 --- /dev/null +++ b/libc/nt/pdh/PdhBindInputDataSourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhBindInputDataSourceW,PdhBindInputDataSourceW,0 diff --git a/libc/nt/pdh/PdhBrowseCountersHW.s b/libc/nt/pdh/PdhBrowseCountersHW.s new file mode 100644 index 000000000..c3028ea22 --- /dev/null +++ b/libc/nt/pdh/PdhBrowseCountersHW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhBrowseCountersHW,PdhBrowseCountersHW,0 diff --git a/libc/nt/pdh/PdhBrowseCountersW.s b/libc/nt/pdh/PdhBrowseCountersW.s new file mode 100644 index 000000000..69eeb1d70 --- /dev/null +++ b/libc/nt/pdh/PdhBrowseCountersW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhBrowseCountersW,PdhBrowseCountersW,0 diff --git a/libc/nt/pdh/PdhCalculateCounterFromRawValue.s b/libc/nt/pdh/PdhCalculateCounterFromRawValue.s new file mode 100644 index 000000000..22e414390 --- /dev/null +++ b/libc/nt/pdh/PdhCalculateCounterFromRawValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhCalculateCounterFromRawValue,PdhCalculateCounterFromRawValue,0 diff --git a/libc/nt/pdh/PdhCloseLog.s b/libc/nt/pdh/PdhCloseLog.s new file mode 100644 index 000000000..b71f8cbe6 --- /dev/null +++ b/libc/nt/pdh/PdhCloseLog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhCloseLog,PdhCloseLog,0 diff --git a/libc/nt/pdh/PdhCloseQuery.s b/libc/nt/pdh/PdhCloseQuery.s new file mode 100644 index 000000000..e79564a4b --- /dev/null +++ b/libc/nt/pdh/PdhCloseQuery.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhCloseQuery,PdhCloseQuery,0 diff --git a/libc/nt/pdh/PdhCollectQueryData.s b/libc/nt/pdh/PdhCollectQueryData.s new file mode 100644 index 000000000..8ea943130 --- /dev/null +++ b/libc/nt/pdh/PdhCollectQueryData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhCollectQueryData,PdhCollectQueryData,0 diff --git a/libc/nt/pdh/PdhCollectQueryDataEx.s b/libc/nt/pdh/PdhCollectQueryDataEx.s new file mode 100644 index 000000000..94b3acb38 --- /dev/null +++ b/libc/nt/pdh/PdhCollectQueryDataEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhCollectQueryDataEx,PdhCollectQueryDataEx,0 + + .text.windows +PdhCollectQueryDataEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_PdhCollectQueryDataEx(%rip),%rax + jmp __sysv2nt + .endfn PdhCollectQueryDataEx,globl + .previous diff --git a/libc/nt/pdh/PdhCollectQueryDataWithTime.s b/libc/nt/pdh/PdhCollectQueryDataWithTime.s new file mode 100644 index 000000000..e79b7812a --- /dev/null +++ b/libc/nt/pdh/PdhCollectQueryDataWithTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhCollectQueryDataWithTime,PdhCollectQueryDataWithTime,0 diff --git a/libc/nt/pdh/PdhComputeCounterStatistics.s b/libc/nt/pdh/PdhComputeCounterStatistics.s new file mode 100644 index 000000000..3ec3bfb56 --- /dev/null +++ b/libc/nt/pdh/PdhComputeCounterStatistics.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhComputeCounterStatistics,PdhComputeCounterStatistics,0 diff --git a/libc/nt/pdh/PdhConnectMachineW.s b/libc/nt/pdh/PdhConnectMachineW.s new file mode 100644 index 000000000..24a27a93f --- /dev/null +++ b/libc/nt/pdh/PdhConnectMachineW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhConnectMachineW,PdhConnectMachineW,0 diff --git a/libc/nt/pdh/PdhEnumLogSetNamesW.s b/libc/nt/pdh/PdhEnumLogSetNamesW.s new file mode 100644 index 000000000..cc7009ba3 --- /dev/null +++ b/libc/nt/pdh/PdhEnumLogSetNamesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhEnumLogSetNamesW,PdhEnumLogSetNamesW,0 diff --git a/libc/nt/pdh/PdhEnumMachinesHW.s b/libc/nt/pdh/PdhEnumMachinesHW.s new file mode 100644 index 000000000..c7edcbbf2 --- /dev/null +++ b/libc/nt/pdh/PdhEnumMachinesHW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhEnumMachinesHW,PdhEnumMachinesHW,0 diff --git a/libc/nt/pdh/PdhEnumMachinesW.s b/libc/nt/pdh/PdhEnumMachinesW.s new file mode 100644 index 000000000..5b9dd0c9e --- /dev/null +++ b/libc/nt/pdh/PdhEnumMachinesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhEnumMachinesW,PdhEnumMachinesW,0 diff --git a/libc/nt/pdh/PdhEnumObjectItemsHW.s b/libc/nt/pdh/PdhEnumObjectItemsHW.s new file mode 100644 index 000000000..ade6c4950 --- /dev/null +++ b/libc/nt/pdh/PdhEnumObjectItemsHW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhEnumObjectItemsHW,PdhEnumObjectItemsHW,0 diff --git a/libc/nt/pdh/PdhEnumObjectItemsW.s b/libc/nt/pdh/PdhEnumObjectItemsW.s new file mode 100644 index 000000000..f0a7fffef --- /dev/null +++ b/libc/nt/pdh/PdhEnumObjectItemsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhEnumObjectItemsW,PdhEnumObjectItemsW,0 diff --git a/libc/nt/pdh/PdhEnumObjectsHW.s b/libc/nt/pdh/PdhEnumObjectsHW.s new file mode 100644 index 000000000..15469b45b --- /dev/null +++ b/libc/nt/pdh/PdhEnumObjectsHW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhEnumObjectsHW,PdhEnumObjectsHW,0 diff --git a/libc/nt/pdh/PdhEnumObjectsW.s b/libc/nt/pdh/PdhEnumObjectsW.s new file mode 100644 index 000000000..9992fd00c --- /dev/null +++ b/libc/nt/pdh/PdhEnumObjectsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhEnumObjectsW,PdhEnumObjectsW,0 diff --git a/libc/nt/pdh/PdhExpandCounterPathW.s b/libc/nt/pdh/PdhExpandCounterPathW.s new file mode 100644 index 000000000..aee0c7aff --- /dev/null +++ b/libc/nt/pdh/PdhExpandCounterPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhExpandCounterPathW,PdhExpandCounterPathW,0 diff --git a/libc/nt/pdh/PdhExpandWildCardPathHW.s b/libc/nt/pdh/PdhExpandWildCardPathHW.s new file mode 100644 index 000000000..607e9d590 --- /dev/null +++ b/libc/nt/pdh/PdhExpandWildCardPathHW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhExpandWildCardPathHW,PdhExpandWildCardPathHW,0 diff --git a/libc/nt/pdh/PdhExpandWildCardPathW.s b/libc/nt/pdh/PdhExpandWildCardPathW.s new file mode 100644 index 000000000..2378bba8f --- /dev/null +++ b/libc/nt/pdh/PdhExpandWildCardPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhExpandWildCardPathW,PdhExpandWildCardPathW,0 diff --git a/libc/nt/pdh/PdhFormatFromRawValue.s b/libc/nt/pdh/PdhFormatFromRawValue.s new file mode 100644 index 000000000..2eaa0158f --- /dev/null +++ b/libc/nt/pdh/PdhFormatFromRawValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhFormatFromRawValue,PdhFormatFromRawValue,0 diff --git a/libc/nt/pdh/PdhGetCounterInfoW.s b/libc/nt/pdh/PdhGetCounterInfoW.s new file mode 100644 index 000000000..9903cd1db --- /dev/null +++ b/libc/nt/pdh/PdhGetCounterInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetCounterInfoW,PdhGetCounterInfoW,0 diff --git a/libc/nt/pdh/PdhGetCounterTimeBase.s b/libc/nt/pdh/PdhGetCounterTimeBase.s new file mode 100644 index 000000000..ce6db166e --- /dev/null +++ b/libc/nt/pdh/PdhGetCounterTimeBase.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetCounterTimeBase,PdhGetCounterTimeBase,0 diff --git a/libc/nt/pdh/PdhGetDataSourceTimeRangeH.s b/libc/nt/pdh/PdhGetDataSourceTimeRangeH.s new file mode 100644 index 000000000..1d646f5af --- /dev/null +++ b/libc/nt/pdh/PdhGetDataSourceTimeRangeH.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetDataSourceTimeRangeH,PdhGetDataSourceTimeRangeH,0 diff --git a/libc/nt/pdh/PdhGetDataSourceTimeRangeW.s b/libc/nt/pdh/PdhGetDataSourceTimeRangeW.s new file mode 100644 index 000000000..1c8e2d844 --- /dev/null +++ b/libc/nt/pdh/PdhGetDataSourceTimeRangeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetDataSourceTimeRangeW,PdhGetDataSourceTimeRangeW,0 diff --git a/libc/nt/pdh/PdhGetDefaultPerfCounterHW.s b/libc/nt/pdh/PdhGetDefaultPerfCounterHW.s new file mode 100644 index 000000000..f02c0a014 --- /dev/null +++ b/libc/nt/pdh/PdhGetDefaultPerfCounterHW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetDefaultPerfCounterHW,PdhGetDefaultPerfCounterHW,0 diff --git a/libc/nt/pdh/PdhGetDefaultPerfCounterW.s b/libc/nt/pdh/PdhGetDefaultPerfCounterW.s new file mode 100644 index 000000000..31d98dd06 --- /dev/null +++ b/libc/nt/pdh/PdhGetDefaultPerfCounterW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetDefaultPerfCounterW,PdhGetDefaultPerfCounterW,0 diff --git a/libc/nt/pdh/PdhGetDefaultPerfObjectHW.s b/libc/nt/pdh/PdhGetDefaultPerfObjectHW.s new file mode 100644 index 000000000..7fd0c35a9 --- /dev/null +++ b/libc/nt/pdh/PdhGetDefaultPerfObjectHW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetDefaultPerfObjectHW,PdhGetDefaultPerfObjectHW,0 diff --git a/libc/nt/pdh/PdhGetDefaultPerfObjectW.s b/libc/nt/pdh/PdhGetDefaultPerfObjectW.s new file mode 100644 index 000000000..8fa5c376c --- /dev/null +++ b/libc/nt/pdh/PdhGetDefaultPerfObjectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetDefaultPerfObjectW,PdhGetDefaultPerfObjectW,0 diff --git a/libc/nt/pdh/PdhGetDllVersion.s b/libc/nt/pdh/PdhGetDllVersion.s new file mode 100644 index 000000000..03de14368 --- /dev/null +++ b/libc/nt/pdh/PdhGetDllVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetDllVersion,PdhGetDllVersion,0 diff --git a/libc/nt/pdh/PdhGetFormattedCounterArrayW.s b/libc/nt/pdh/PdhGetFormattedCounterArrayW.s new file mode 100644 index 000000000..cda96c436 --- /dev/null +++ b/libc/nt/pdh/PdhGetFormattedCounterArrayW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetFormattedCounterArrayW,PdhGetFormattedCounterArrayW,0 diff --git a/libc/nt/pdh/PdhGetFormattedCounterValue.s b/libc/nt/pdh/PdhGetFormattedCounterValue.s new file mode 100644 index 000000000..0c2a6c48b --- /dev/null +++ b/libc/nt/pdh/PdhGetFormattedCounterValue.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetFormattedCounterValue,PdhGetFormattedCounterValue,0 + + .text.windows +PdhGetFormattedCounterValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_PdhGetFormattedCounterValue(%rip),%rax + jmp __sysv2nt + .endfn PdhGetFormattedCounterValue,globl + .previous diff --git a/libc/nt/pdh/PdhGetLogFileSize.s b/libc/nt/pdh/PdhGetLogFileSize.s new file mode 100644 index 000000000..71794e7cd --- /dev/null +++ b/libc/nt/pdh/PdhGetLogFileSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetLogFileSize,PdhGetLogFileSize,0 diff --git a/libc/nt/pdh/PdhGetRawCounterArrayW.s b/libc/nt/pdh/PdhGetRawCounterArrayW.s new file mode 100644 index 000000000..f52d908ce --- /dev/null +++ b/libc/nt/pdh/PdhGetRawCounterArrayW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetRawCounterArrayW,PdhGetRawCounterArrayW,0 diff --git a/libc/nt/pdh/PdhGetRawCounterValue.s b/libc/nt/pdh/PdhGetRawCounterValue.s new file mode 100644 index 000000000..b9e7839ca --- /dev/null +++ b/libc/nt/pdh/PdhGetRawCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhGetRawCounterValue,PdhGetRawCounterValue,0 diff --git a/libc/nt/pdh/PdhIsRealTimeQuery.s b/libc/nt/pdh/PdhIsRealTimeQuery.s new file mode 100644 index 000000000..880402dd6 --- /dev/null +++ b/libc/nt/pdh/PdhIsRealTimeQuery.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhIsRealTimeQuery,PdhIsRealTimeQuery,0 diff --git a/libc/nt/pdh/PdhLookupPerfIndexByNameW.s b/libc/nt/pdh/PdhLookupPerfIndexByNameW.s new file mode 100644 index 000000000..35def11bb --- /dev/null +++ b/libc/nt/pdh/PdhLookupPerfIndexByNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhLookupPerfIndexByNameW,PdhLookupPerfIndexByNameW,0 diff --git a/libc/nt/pdh/PdhLookupPerfNameByIndexW.s b/libc/nt/pdh/PdhLookupPerfNameByIndexW.s new file mode 100644 index 000000000..f58bb7fcf --- /dev/null +++ b/libc/nt/pdh/PdhLookupPerfNameByIndexW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhLookupPerfNameByIndexW,PdhLookupPerfNameByIndexW,0 diff --git a/libc/nt/pdh/PdhMakeCounterPathW.s b/libc/nt/pdh/PdhMakeCounterPathW.s new file mode 100644 index 000000000..98541e00a --- /dev/null +++ b/libc/nt/pdh/PdhMakeCounterPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhMakeCounterPathW,PdhMakeCounterPathW,0 diff --git a/libc/nt/pdh/PdhOpenLogW.s b/libc/nt/pdh/PdhOpenLogW.s new file mode 100644 index 000000000..0886535f0 --- /dev/null +++ b/libc/nt/pdh/PdhOpenLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhOpenLogW,PdhOpenLogW,0 diff --git a/libc/nt/pdh/PdhOpenQueryH.s b/libc/nt/pdh/PdhOpenQueryH.s new file mode 100644 index 000000000..5e0a601b5 --- /dev/null +++ b/libc/nt/pdh/PdhOpenQueryH.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhOpenQueryH,PdhOpenQueryH,0 diff --git a/libc/nt/pdh/PdhOpenQueryW.s b/libc/nt/pdh/PdhOpenQueryW.s new file mode 100644 index 000000000..3cd48bbdd --- /dev/null +++ b/libc/nt/pdh/PdhOpenQueryW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhOpenQueryW,PdhOpenQueryW,0 + + .text.windows +PdhOpenQuery: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_PdhOpenQueryW(%rip),%rax + jmp __sysv2nt + .endfn PdhOpenQuery,globl + .previous diff --git a/libc/nt/pdh/PdhParseCounterPathW.s b/libc/nt/pdh/PdhParseCounterPathW.s new file mode 100644 index 000000000..162a1520f --- /dev/null +++ b/libc/nt/pdh/PdhParseCounterPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhParseCounterPathW,PdhParseCounterPathW,0 diff --git a/libc/nt/pdh/PdhParseInstanceNameW.s b/libc/nt/pdh/PdhParseInstanceNameW.s new file mode 100644 index 000000000..ebb598a6f --- /dev/null +++ b/libc/nt/pdh/PdhParseInstanceNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhParseInstanceNameW,PdhParseInstanceNameW,0 diff --git a/libc/nt/pdh/PdhReadRawLogRecord.s b/libc/nt/pdh/PdhReadRawLogRecord.s new file mode 100644 index 000000000..467bfcb7d --- /dev/null +++ b/libc/nt/pdh/PdhReadRawLogRecord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhReadRawLogRecord,PdhReadRawLogRecord,0 diff --git a/libc/nt/pdh/PdhRemoveCounter.s b/libc/nt/pdh/PdhRemoveCounter.s new file mode 100644 index 000000000..d530fbc9f --- /dev/null +++ b/libc/nt/pdh/PdhRemoveCounter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhRemoveCounter,PdhRemoveCounter,0 diff --git a/libc/nt/pdh/PdhSelectDataSourceW.s b/libc/nt/pdh/PdhSelectDataSourceW.s new file mode 100644 index 000000000..6ee75cb3e --- /dev/null +++ b/libc/nt/pdh/PdhSelectDataSourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhSelectDataSourceW,PdhSelectDataSourceW,0 diff --git a/libc/nt/pdh/PdhSetCounterScaleFactor.s b/libc/nt/pdh/PdhSetCounterScaleFactor.s new file mode 100644 index 000000000..aa998a144 --- /dev/null +++ b/libc/nt/pdh/PdhSetCounterScaleFactor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhSetCounterScaleFactor,PdhSetCounterScaleFactor,0 diff --git a/libc/nt/pdh/PdhSetDefaultRealTimeDataSource.s b/libc/nt/pdh/PdhSetDefaultRealTimeDataSource.s new file mode 100644 index 000000000..e41cd825e --- /dev/null +++ b/libc/nt/pdh/PdhSetDefaultRealTimeDataSource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhSetDefaultRealTimeDataSource,PdhSetDefaultRealTimeDataSource,0 diff --git a/libc/nt/pdh/PdhSetQueryTimeRange.s b/libc/nt/pdh/PdhSetQueryTimeRange.s new file mode 100644 index 000000000..dc4e7b159 --- /dev/null +++ b/libc/nt/pdh/PdhSetQueryTimeRange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhSetQueryTimeRange,PdhSetQueryTimeRange,0 diff --git a/libc/nt/pdh/PdhUpdateLogFileCatalog.s b/libc/nt/pdh/PdhUpdateLogFileCatalog.s new file mode 100644 index 000000000..067da7a51 --- /dev/null +++ b/libc/nt/pdh/PdhUpdateLogFileCatalog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhUpdateLogFileCatalog,PdhUpdateLogFileCatalog,0 diff --git a/libc/nt/pdh/PdhUpdateLogW.s b/libc/nt/pdh/PdhUpdateLogW.s new file mode 100644 index 000000000..f2f30b44b --- /dev/null +++ b/libc/nt/pdh/PdhUpdateLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhUpdateLogW,PdhUpdateLogW,0 diff --git a/libc/nt/pdh/PdhValidatePathExW.s b/libc/nt/pdh/PdhValidatePathExW.s new file mode 100644 index 000000000..2d150ebfb --- /dev/null +++ b/libc/nt/pdh/PdhValidatePathExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhValidatePathExW,PdhValidatePathExW,0 diff --git a/libc/nt/pdh/PdhValidatePathW.s b/libc/nt/pdh/PdhValidatePathW.s new file mode 100644 index 000000000..bb6811c22 --- /dev/null +++ b/libc/nt/pdh/PdhValidatePathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PdhValidatePathW,PdhValidatePathW,0 diff --git a/libc/nt/pdh/PerfAddCounters.s b/libc/nt/pdh/PerfAddCounters.s new file mode 100644 index 000000000..faacea528 --- /dev/null +++ b/libc/nt/pdh/PerfAddCounters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfAddCounters,PerfAddCounters,0 diff --git a/libc/nt/pdh/PerfCloseQueryHandle.s b/libc/nt/pdh/PerfCloseQueryHandle.s new file mode 100644 index 000000000..bda6507bb --- /dev/null +++ b/libc/nt/pdh/PerfCloseQueryHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfCloseQueryHandle,PerfCloseQueryHandle,0 diff --git a/libc/nt/pdh/PerfCreateInstance.s b/libc/nt/pdh/PerfCreateInstance.s new file mode 100644 index 000000000..d4668cbd8 --- /dev/null +++ b/libc/nt/pdh/PerfCreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfCreateInstance,PerfCreateInstance,0 diff --git a/libc/nt/pdh/PerfDecrementULongCounterValue.s b/libc/nt/pdh/PerfDecrementULongCounterValue.s new file mode 100644 index 000000000..8a4220ef6 --- /dev/null +++ b/libc/nt/pdh/PerfDecrementULongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfDecrementULongCounterValue,PerfDecrementULongCounterValue,0 diff --git a/libc/nt/pdh/PerfDecrementULongLongCounterValue.s b/libc/nt/pdh/PerfDecrementULongLongCounterValue.s new file mode 100644 index 000000000..bfab227b5 --- /dev/null +++ b/libc/nt/pdh/PerfDecrementULongLongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfDecrementULongLongCounterValue,PerfDecrementULongLongCounterValue,0 diff --git a/libc/nt/pdh/PerfDeleteCounters.s b/libc/nt/pdh/PerfDeleteCounters.s new file mode 100644 index 000000000..4adb33980 --- /dev/null +++ b/libc/nt/pdh/PerfDeleteCounters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfDeleteCounters,PerfDeleteCounters,0 diff --git a/libc/nt/pdh/PerfDeleteInstance.s b/libc/nt/pdh/PerfDeleteInstance.s new file mode 100644 index 000000000..f253b4de3 --- /dev/null +++ b/libc/nt/pdh/PerfDeleteInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfDeleteInstance,PerfDeleteInstance,0 diff --git a/libc/nt/pdh/PerfEnumerateCounterSet.s b/libc/nt/pdh/PerfEnumerateCounterSet.s new file mode 100644 index 000000000..e19de7668 --- /dev/null +++ b/libc/nt/pdh/PerfEnumerateCounterSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfEnumerateCounterSet,PerfEnumerateCounterSet,0 diff --git a/libc/nt/pdh/PerfEnumerateCounterSetInstances.s b/libc/nt/pdh/PerfEnumerateCounterSetInstances.s new file mode 100644 index 000000000..4491b9462 --- /dev/null +++ b/libc/nt/pdh/PerfEnumerateCounterSetInstances.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfEnumerateCounterSetInstances,PerfEnumerateCounterSetInstances,0 diff --git a/libc/nt/pdh/PerfIncrementULongCounterValue.s b/libc/nt/pdh/PerfIncrementULongCounterValue.s new file mode 100644 index 000000000..1a3358222 --- /dev/null +++ b/libc/nt/pdh/PerfIncrementULongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfIncrementULongCounterValue,PerfIncrementULongCounterValue,0 diff --git a/libc/nt/pdh/PerfIncrementULongLongCounterValue.s b/libc/nt/pdh/PerfIncrementULongLongCounterValue.s new file mode 100644 index 000000000..accb87e3c --- /dev/null +++ b/libc/nt/pdh/PerfIncrementULongLongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfIncrementULongLongCounterValue,PerfIncrementULongLongCounterValue,0 diff --git a/libc/nt/pdh/PerfOpenQueryHandle.s b/libc/nt/pdh/PerfOpenQueryHandle.s new file mode 100644 index 000000000..0945f43c9 --- /dev/null +++ b/libc/nt/pdh/PerfOpenQueryHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfOpenQueryHandle,PerfOpenQueryHandle,0 diff --git a/libc/nt/pdh/PerfQueryCounterData.s b/libc/nt/pdh/PerfQueryCounterData.s new file mode 100644 index 000000000..37af4c287 --- /dev/null +++ b/libc/nt/pdh/PerfQueryCounterData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfQueryCounterData,PerfQueryCounterData,0 diff --git a/libc/nt/pdh/PerfQueryCounterInfo.s b/libc/nt/pdh/PerfQueryCounterInfo.s new file mode 100644 index 000000000..42f10abe4 --- /dev/null +++ b/libc/nt/pdh/PerfQueryCounterInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfQueryCounterInfo,PerfQueryCounterInfo,0 diff --git a/libc/nt/pdh/PerfQueryCounterSetRegistrationInfo.s b/libc/nt/pdh/PerfQueryCounterSetRegistrationInfo.s new file mode 100644 index 000000000..113a24e3a --- /dev/null +++ b/libc/nt/pdh/PerfQueryCounterSetRegistrationInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfQueryCounterSetRegistrationInfo,PerfQueryCounterSetRegistrationInfo,0 diff --git a/libc/nt/pdh/PerfQueryInstance.s b/libc/nt/pdh/PerfQueryInstance.s new file mode 100644 index 000000000..413579ebe --- /dev/null +++ b/libc/nt/pdh/PerfQueryInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfQueryInstance,PerfQueryInstance,0 diff --git a/libc/nt/pdh/PerfSetCounterRefValue.s b/libc/nt/pdh/PerfSetCounterRefValue.s new file mode 100644 index 000000000..54c374a0d --- /dev/null +++ b/libc/nt/pdh/PerfSetCounterRefValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfSetCounterRefValue,PerfSetCounterRefValue,0 diff --git a/libc/nt/pdh/PerfSetCounterSetInfo.s b/libc/nt/pdh/PerfSetCounterSetInfo.s new file mode 100644 index 000000000..80c0e9c5b --- /dev/null +++ b/libc/nt/pdh/PerfSetCounterSetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfSetCounterSetInfo,PerfSetCounterSetInfo,0 diff --git a/libc/nt/pdh/PerfSetULongCounterValue.s b/libc/nt/pdh/PerfSetULongCounterValue.s new file mode 100644 index 000000000..dbe0690e0 --- /dev/null +++ b/libc/nt/pdh/PerfSetULongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfSetULongCounterValue,PerfSetULongCounterValue,0 diff --git a/libc/nt/pdh/PerfSetULongLongCounterValue.s b/libc/nt/pdh/PerfSetULongLongCounterValue.s new file mode 100644 index 000000000..584f098ee --- /dev/null +++ b/libc/nt/pdh/PerfSetULongLongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfSetULongLongCounterValue,PerfSetULongLongCounterValue,0 diff --git a/libc/nt/pdh/PerfStartProvider.s b/libc/nt/pdh/PerfStartProvider.s new file mode 100644 index 000000000..54421fc03 --- /dev/null +++ b/libc/nt/pdh/PerfStartProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfStartProvider,PerfStartProvider,0 diff --git a/libc/nt/pdh/PerfStartProviderEx.s b/libc/nt/pdh/PerfStartProviderEx.s new file mode 100644 index 000000000..ab60ea386 --- /dev/null +++ b/libc/nt/pdh/PerfStartProviderEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfStartProviderEx,PerfStartProviderEx,0 diff --git a/libc/nt/pdh/PerfStopProvider.s b/libc/nt/pdh/PerfStopProvider.s new file mode 100644 index 000000000..72a2323e8 --- /dev/null +++ b/libc/nt/pdh/PerfStopProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_PerfStopProvider,PerfStopProvider,0 diff --git a/libc/nt/pdh/UnloadPerfCounterTextStringsW.s b/libc/nt/pdh/UnloadPerfCounterTextStringsW.s new file mode 100644 index 000000000..47bce47d3 --- /dev/null +++ b/libc/nt/pdh/UnloadPerfCounterTextStringsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp pdh,__imp_UnloadPerfCounterTextStringsW,UnloadPerfCounterTextStringsW,0 diff --git a/libc/nt/privilege.h b/libc/nt/privilege.h index 0f49ba915..988d9340f 100644 --- a/libc/nt/privilege.h +++ b/libc/nt/privilege.h @@ -44,6 +44,9 @@ bool32 AdjustTokenPrivileges(int64_t TokenHandle, bool32 DisableAllPrivileges, struct NtTokenPrivileges *opt_out_PreviousState, uint32_t *opt_out_ReturnLength); +bool32 ImpersonateSelf(int kNtSecurityImpersonationLevel); +bool32 RevertToSelf(void); + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_NT_PRIVILEGE_H_ */ diff --git a/libc/nt/process.h b/libc/nt/process.h index 02ff6d4b1..480e1b851 100644 --- a/libc/nt/process.h +++ b/libc/nt/process.h @@ -2,6 +2,7 @@ #define COSMOPOLITAN_LIBC_NT_PROCESS_H_ #include "libc/nt/startupinfo.h" #include "libc/nt/struct/processinformation.h" +#include "libc/nt/struct/processmemorycounters.h" #include "libc/nt/struct/securityattributes.h" #include "libc/nt/thunk/msabi.h" /* ░░░░ @@ -41,7 +42,7 @@ bool32 CreateProcess(const char16_t *opt_lpApplicationName, const char16_t *opt_lpCurrentDirectory, const struct NtStartupInfo *lpStartupInfo, struct NtProcessInformation *opt_out_lpProcessInformation) - paramsnonnull((2, 9)); + paramsnonnull((9)); uint32_t GetThreadId(int64_t hThread); /* cf. NT_TID */ uint32_t GetProcessId(int64_t hProcess); /* cf. NT_PID */ @@ -68,6 +69,10 @@ bool32 SetPriorityClass(int64_t hProcess, uint32_t dwPriorityClass); bool32 SetProcessPriorityBoost(int64_t hProcess, bool32 bDisablePriorityBoost); bool32 GetProcessPriorityBoost(int64_t hProcess, bool32 *pDisablePriorityBoost); +bool32 GetProcessMemoryInfo( + int64_t hProcess, struct NtProcessMemoryCountersEx *out_ppsmemCounters, + uint32_t cb); + #if ShouldUseMsabiAttribute() #include "libc/nt/thunk/process.inc" #endif /* ShouldUseMsabiAttribute() */ diff --git a/libc/nt/psapi/EmptyWorkingSet.s b/libc/nt/psapi/EmptyWorkingSet.s new file mode 100644 index 000000000..bb1c21f7d --- /dev/null +++ b/libc/nt/psapi/EmptyWorkingSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_EmptyWorkingSet,EmptyWorkingSet,0 diff --git a/libc/nt/psapi/EnumDeviceDrivers.s b/libc/nt/psapi/EnumDeviceDrivers.s new file mode 100644 index 000000000..3882481f1 --- /dev/null +++ b/libc/nt/psapi/EnumDeviceDrivers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_EnumDeviceDrivers,EnumDeviceDrivers,0 diff --git a/libc/nt/psapi/EnumPageFilesW.s b/libc/nt/psapi/EnumPageFilesW.s new file mode 100644 index 000000000..72fa3494f --- /dev/null +++ b/libc/nt/psapi/EnumPageFilesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_EnumPageFilesW,EnumPageFilesW,0 diff --git a/libc/nt/psapi/EnumProcessModules.s b/libc/nt/psapi/EnumProcessModules.s new file mode 100644 index 000000000..6f93ab8f0 --- /dev/null +++ b/libc/nt/psapi/EnumProcessModules.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_EnumProcessModules,EnumProcessModules,0 diff --git a/libc/nt/psapi/EnumProcessModulesEx.s b/libc/nt/psapi/EnumProcessModulesEx.s new file mode 100644 index 000000000..c9cf50f39 --- /dev/null +++ b/libc/nt/psapi/EnumProcessModulesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_EnumProcessModulesEx,EnumProcessModulesEx,0 diff --git a/libc/nt/psapi/EnumProcesses.s b/libc/nt/psapi/EnumProcesses.s new file mode 100644 index 000000000..895b1121f --- /dev/null +++ b/libc/nt/psapi/EnumProcesses.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_EnumProcesses,EnumProcesses,0 diff --git a/libc/nt/psapi/GetDeviceDriverBaseNameW.s b/libc/nt/psapi/GetDeviceDriverBaseNameW.s new file mode 100644 index 000000000..9e50059a9 --- /dev/null +++ b/libc/nt/psapi/GetDeviceDriverBaseNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetDeviceDriverBaseNameW,GetDeviceDriverBaseNameW,0 diff --git a/libc/nt/psapi/GetDeviceDriverFileNameW.s b/libc/nt/psapi/GetDeviceDriverFileNameW.s new file mode 100644 index 000000000..d165528ee --- /dev/null +++ b/libc/nt/psapi/GetDeviceDriverFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetDeviceDriverFileNameW,GetDeviceDriverFileNameW,0 diff --git a/libc/nt/psapi/GetMappedFileNameW.s b/libc/nt/psapi/GetMappedFileNameW.s new file mode 100644 index 000000000..e582bb488 --- /dev/null +++ b/libc/nt/psapi/GetMappedFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetMappedFileNameW,GetMappedFileNameW,0 diff --git a/libc/nt/psapi/GetModuleBaseNameW.s b/libc/nt/psapi/GetModuleBaseNameW.s new file mode 100644 index 000000000..fcd7fa8eb --- /dev/null +++ b/libc/nt/psapi/GetModuleBaseNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetModuleBaseNameW,GetModuleBaseNameW,0 diff --git a/libc/nt/psapi/GetModuleFileNameExW.s b/libc/nt/psapi/GetModuleFileNameExW.s new file mode 100644 index 000000000..052f45dc0 --- /dev/null +++ b/libc/nt/psapi/GetModuleFileNameExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetModuleFileNameExW,GetModuleFileNameExW,0 diff --git a/libc/nt/psapi/GetModuleInformation.s b/libc/nt/psapi/GetModuleInformation.s new file mode 100644 index 000000000..c490e0628 --- /dev/null +++ b/libc/nt/psapi/GetModuleInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetModuleInformation,GetModuleInformation,0 diff --git a/libc/nt/psapi/GetPerformanceInfo.s b/libc/nt/psapi/GetPerformanceInfo.s new file mode 100644 index 000000000..c09bf8397 --- /dev/null +++ b/libc/nt/psapi/GetPerformanceInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetPerformanceInfo,GetPerformanceInfo,0 diff --git a/libc/nt/kernel32/GetProcessImageFileNameW.s b/libc/nt/psapi/GetProcessImageFileNameW.s similarity index 75% rename from libc/nt/kernel32/GetProcessImageFileNameW.s rename to libc/nt/psapi/GetProcessImageFileNameW.s index e52caecda..d9205e732 100644 --- a/libc/nt/kernel32/GetProcessImageFileNameW.s +++ b/libc/nt/psapi/GetProcessImageFileNameW.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_GetProcessImageFileNameW,GetProcessImageFileNameW,677 +.imp psapi,__imp_GetProcessImageFileNameW,GetProcessImageFileNameW,0 .text.windows GetProcessImageFileName: diff --git a/libc/nt/psapi/GetProcessMemoryInfo.s b/libc/nt/psapi/GetProcessMemoryInfo.s new file mode 100644 index 000000000..b5e8d936f --- /dev/null +++ b/libc/nt/psapi/GetProcessMemoryInfo.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetProcessMemoryInfo,GetProcessMemoryInfo,0 + + .text.windows +GetProcessMemoryInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessMemoryInfo(%rip),%rax + jmp __sysv2nt + .endfn GetProcessMemoryInfo,globl + .previous diff --git a/libc/nt/psapi/GetWsChanges.s b/libc/nt/psapi/GetWsChanges.s new file mode 100644 index 000000000..ce4b33875 --- /dev/null +++ b/libc/nt/psapi/GetWsChanges.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetWsChanges,GetWsChanges,0 diff --git a/libc/nt/psapi/GetWsChangesEx.s b/libc/nt/psapi/GetWsChangesEx.s new file mode 100644 index 000000000..3ced55868 --- /dev/null +++ b/libc/nt/psapi/GetWsChangesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_GetWsChangesEx,GetWsChangesEx,0 diff --git a/libc/nt/psapi/InitializeProcessForWsWatch.s b/libc/nt/psapi/InitializeProcessForWsWatch.s new file mode 100644 index 000000000..69c6a193b --- /dev/null +++ b/libc/nt/psapi/InitializeProcessForWsWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_InitializeProcessForWsWatch,InitializeProcessForWsWatch,0 diff --git a/libc/nt/psapi/QueryWorkingSet.s b/libc/nt/psapi/QueryWorkingSet.s new file mode 100644 index 000000000..25e5852cb --- /dev/null +++ b/libc/nt/psapi/QueryWorkingSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_QueryWorkingSet,QueryWorkingSet,0 diff --git a/libc/nt/psapi/QueryWorkingSetEx.s b/libc/nt/psapi/QueryWorkingSetEx.s new file mode 100644 index 000000000..34158f94d --- /dev/null +++ b/libc/nt/psapi/QueryWorkingSetEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp psapi,__imp_QueryWorkingSetEx,QueryWorkingSetEx,0 diff --git a/libc/nt/runtime.h b/libc/nt/runtime.h index 6ac4befb1..39bedab34 100644 --- a/libc/nt/runtime.h +++ b/libc/nt/runtime.h @@ -22,7 +22,7 @@ COSMOPOLITAN_C_START_ char16_t *GetCommandLine(void) nosideeffect; -char16_t *GetEnvironmentStrings(void) nodiscard; +char16_t *GetEnvironmentStrings(void) dontdiscard; bool32 FreeEnvironmentStrings(char16_t *) paramsnonnull(); bool32 ReadFile(int64_t hFile, void *lpBuffer, uint32_t nNumberOfBytesToRead, uint32_t *lpNumberOfBytesRead, @@ -35,7 +35,7 @@ bool32 TerminateProcess(int64_t hProcess, uint32_t uExitCode); int64_t GetCurrentProcess(void) pureconst; void ExitProcess(uint32_t uExitCode) wontreturn; uint32_t GetLastError(void) nosideeffect; -bool32 CloseHandle(int64_t hObject) nothrow nocallback; +bool32 CloseHandle(int64_t hObject) dontthrow nocallback; intptr_t GetStdHandle(int64_t nStdHandle) nosideeffect; bool32 SetStdHandle(int64_t nStdHandle, int64_t hHandle); bool32 SetDefaultDllDirectories(unsigned dirflags); diff --git a/libc/nt/shell32/Control_RunDLLA.s b/libc/nt/shell32/Control_RunDLLA.s deleted file mode 100644 index 8141371b0..000000000 --- a/libc/nt/shell32/Control_RunDLLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_Control_RunDLLA,Control_RunDLLA,273 diff --git a/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller.s b/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller.s deleted file mode 100644 index b1a5d9a04..000000000 --- a/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_CreateStorageItemFromPath_FullTrustCaller,CreateStorageItemFromPath_FullTrustCaller,935 diff --git a/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller_ForPackage.s b/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller_ForPackage.s deleted file mode 100644 index 26d6e5abf..000000000 --- a/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller_ForPackage.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_CreateStorageItemFromPath_FullTrustCaller_ForPackage,CreateStorageItemFromPath_FullTrustCaller_ForPackage,936 diff --git a/libc/nt/shell32/CreateStorageItemFromPath_PartialTrustCaller.s b/libc/nt/shell32/CreateStorageItemFromPath_PartialTrustCaller.s deleted file mode 100644 index 4cb344fab..000000000 --- a/libc/nt/shell32/CreateStorageItemFromPath_PartialTrustCaller.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_CreateStorageItemFromPath_PartialTrustCaller,CreateStorageItemFromPath_PartialTrustCaller,920 diff --git a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller.s b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller.s deleted file mode 100644 index 1a82b1bbf..000000000 --- a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_CreateStorageItemFromShellItem_FullTrustCaller,CreateStorageItemFromShellItem_FullTrustCaller,921 diff --git a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage.s b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage.s deleted file mode 100644 index a907a6605..000000000 --- a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_CreateStorageItemFromShellItem_FullTrustCaller_ForPackage,CreateStorageItemFromShellItem_FullTrustCaller_ForPackage,925 diff --git a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle.s b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle.s deleted file mode 100644 index 18301d7c9..000000000 --- a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle,CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle,929 diff --git a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage.s b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage.s deleted file mode 100644 index 27f241b97..000000000 --- a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage,CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage,931 diff --git a/libc/nt/shell32/DoEnvironmentSubstA.s b/libc/nt/shell32/DoEnvironmentSubstA.s deleted file mode 100644 index dabfde0fb..000000000 --- a/libc/nt/shell32/DoEnvironmentSubstA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_DoEnvironmentSubstA,DoEnvironmentSubstA,283 diff --git a/libc/nt/shell32/DragQueryFileA.s b/libc/nt/shell32/DragQueryFileA.s deleted file mode 100644 index 207f5a3af..000000000 --- a/libc/nt/shell32/DragQueryFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_DragQueryFileA,DragQueryFileA,288 diff --git a/libc/nt/shell32/ExtractAssociatedIconA.s b/libc/nt/shell32/ExtractAssociatedIconA.s deleted file mode 100644 index 07bf1762d..000000000 --- a/libc/nt/shell32/ExtractAssociatedIconA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ExtractAssociatedIconA,ExtractAssociatedIconA,293 diff --git a/libc/nt/shell32/ExtractAssociatedIconExA.s b/libc/nt/shell32/ExtractAssociatedIconExA.s deleted file mode 100644 index 01d10fd7c..000000000 --- a/libc/nt/shell32/ExtractAssociatedIconExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ExtractAssociatedIconExA,ExtractAssociatedIconExA,294 diff --git a/libc/nt/shell32/ExtractIconA.s b/libc/nt/shell32/ExtractIconA.s deleted file mode 100644 index bb2a35b81..000000000 --- a/libc/nt/shell32/ExtractIconA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ExtractIconA,ExtractIconA,297 diff --git a/libc/nt/shell32/ExtractIconExA.s b/libc/nt/shell32/ExtractIconExA.s deleted file mode 100644 index 80cbfe68d..000000000 --- a/libc/nt/shell32/ExtractIconExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ExtractIconExA,ExtractIconExA,299 diff --git a/libc/nt/shell32/FindExecutableA.s b/libc/nt/shell32/FindExecutableA.s deleted file mode 100644 index 1f96574e3..000000000 --- a/libc/nt/shell32/FindExecutableA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_FindExecutableA,FindExecutableA,302 diff --git a/libc/nt/shell32/ILCreateFromPathA.s b/libc/nt/shell32/ILCreateFromPathA.s deleted file mode 100644 index 4d7207ee3..000000000 --- a/libc/nt/shell32/ILCreateFromPathA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ILCreateFromPathA,ILCreateFromPathA,189 diff --git a/libc/nt/shell32/InternalExtractIconListA.s b/libc/nt/shell32/InternalExtractIconListA.s deleted file mode 100644 index 2744e8b4d..000000000 --- a/libc/nt/shell32/InternalExtractIconListA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_InternalExtractIconListA,InternalExtractIconListA,307 diff --git a/libc/nt/shell32/IsLFNDriveA.s b/libc/nt/shell32/IsLFNDriveA.s deleted file mode 100644 index ba5abd7e4..000000000 --- a/libc/nt/shell32/IsLFNDriveA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_IsLFNDriveA,IsLFNDriveA,41 diff --git a/libc/nt/shell32/OpenAs_RunDLLA.s b/libc/nt/shell32/OpenAs_RunDLLA.s deleted file mode 100644 index 276f73a16..000000000 --- a/libc/nt/shell32/OpenAs_RunDLLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_OpenAs_RunDLLA,OpenAs_RunDLLA,125 diff --git a/libc/nt/shell32/Options_RunDLLA.s b/libc/nt/shell32/Options_RunDLLA.s deleted file mode 100644 index e8de7273d..000000000 --- a/libc/nt/shell32/Options_RunDLLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_Options_RunDLLA,Options_RunDLLA,311 diff --git a/libc/nt/shell32/PathIsSlowA.s b/libc/nt/shell32/PathIsSlowA.s deleted file mode 100644 index a3bd7fa47..000000000 --- a/libc/nt/shell32/PathIsSlowA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_PathIsSlowA,PathIsSlowA,240 diff --git a/libc/nt/shell32/PrintersGetCommand_RunDLLA.s b/libc/nt/shell32/PrintersGetCommand_RunDLLA.s deleted file mode 100644 index 6fa562d0b..000000000 --- a/libc/nt/shell32/PrintersGetCommand_RunDLLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_PrintersGetCommand_RunDLLA,PrintersGetCommand_RunDLLA,139 diff --git a/libc/nt/shell32/RealShellExecuteA.s b/libc/nt/shell32/RealShellExecuteA.s deleted file mode 100644 index 4f4342edd..000000000 --- a/libc/nt/shell32/RealShellExecuteA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_RealShellExecuteA,RealShellExecuteA,199 diff --git a/libc/nt/shell32/RealShellExecuteExA.s b/libc/nt/shell32/RealShellExecuteExA.s deleted file mode 100644 index 4744a6be3..000000000 --- a/libc/nt/shell32/RealShellExecuteExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_RealShellExecuteExA,RealShellExecuteExA,207 diff --git a/libc/nt/shell32/SHBrowseForFolderA.s b/libc/nt/shell32/SHBrowseForFolderA.s deleted file mode 100644 index d0254e68c..000000000 --- a/libc/nt/shell32/SHBrowseForFolderA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHBrowseForFolderA,SHBrowseForFolderA,325 diff --git a/libc/nt/shell32/SHCreateDirectoryExA.s b/libc/nt/shell32/SHCreateDirectoryExA.s deleted file mode 100644 index 27309fd2b..000000000 --- a/libc/nt/shell32/SHCreateDirectoryExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHCreateDirectoryExA,SHCreateDirectoryExA,337 diff --git a/libc/nt/shell32/SHDefExtractIconA.s b/libc/nt/shell32/SHDefExtractIconA.s deleted file mode 100644 index bd55e899e..000000000 --- a/libc/nt/shell32/SHDefExtractIconA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHDefExtractIconA,SHDefExtractIconA,3 diff --git a/libc/nt/shell32/SHELL32_AddToBackIconTable.s b/libc/nt/shell32/SHELL32_AddToBackIconTable.s deleted file mode 100644 index c6a9e93fb..000000000 --- a/libc/nt/shell32/SHELL32_AddToBackIconTable.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_AddToBackIconTable,SHELL32_AddToBackIconTable,353 diff --git a/libc/nt/shell32/SHELL32_AddToFrontIconTable.s b/libc/nt/shell32/SHELL32_AddToFrontIconTable.s deleted file mode 100644 index 67823a790..000000000 --- a/libc/nt/shell32/SHELL32_AddToFrontIconTable.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_AddToFrontIconTable,SHELL32_AddToFrontIconTable,354 diff --git a/libc/nt/shell32/SHELL32_AreAllItemsAvailable.s b/libc/nt/shell32/SHELL32_AreAllItemsAvailable.s deleted file mode 100644 index 1571a62bc..000000000 --- a/libc/nt/shell32/SHELL32_AreAllItemsAvailable.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_AreAllItemsAvailable,SHELL32_AreAllItemsAvailable,355 diff --git a/libc/nt/shell32/SHELL32_BindToFilePlaceholderHandler.s b/libc/nt/shell32/SHELL32_BindToFilePlaceholderHandler.s deleted file mode 100644 index e44623460..000000000 --- a/libc/nt/shell32/SHELL32_BindToFilePlaceholderHandler.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_BindToFilePlaceholderHandler,SHELL32_BindToFilePlaceholderHandler,356 diff --git a/libc/nt/shell32/SHELL32_CCommonPlacesFolder_CreateInstance.s b/libc/nt/shell32/SHELL32_CCommonPlacesFolder_CreateInstance.s deleted file mode 100644 index 7efc1ddeb..000000000 --- a/libc/nt/shell32/SHELL32_CCommonPlacesFolder_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CCommonPlacesFolder_CreateInstance,SHELL32_CCommonPlacesFolder_CreateInstance,357 diff --git a/libc/nt/shell32/SHELL32_CDBurn_CloseSession.s b/libc/nt/shell32/SHELL32_CDBurn_CloseSession.s deleted file mode 100644 index e89ebdffc..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_CloseSession.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_CloseSession,SHELL32_CDBurn_CloseSession,358 diff --git a/libc/nt/shell32/SHELL32_CDBurn_DriveSupportedForDataBurn.s b/libc/nt/shell32/SHELL32_CDBurn_DriveSupportedForDataBurn.s deleted file mode 100644 index 2001dee8c..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_DriveSupportedForDataBurn.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_DriveSupportedForDataBurn,SHELL32_CDBurn_DriveSupportedForDataBurn,359 diff --git a/libc/nt/shell32/SHELL32_CDBurn_Erase.s b/libc/nt/shell32/SHELL32_CDBurn_Erase.s deleted file mode 100644 index b06330f61..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_Erase.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_Erase,SHELL32_CDBurn_Erase,360 diff --git a/libc/nt/shell32/SHELL32_CDBurn_GetCDInfo.s b/libc/nt/shell32/SHELL32_CDBurn_GetCDInfo.s deleted file mode 100644 index 2bd2f291e..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_GetCDInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_GetCDInfo,SHELL32_CDBurn_GetCDInfo,361 diff --git a/libc/nt/shell32/SHELL32_CDBurn_GetLiveFSDiscInfo.s b/libc/nt/shell32/SHELL32_CDBurn_GetLiveFSDiscInfo.s deleted file mode 100644 index c6b120a76..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_GetLiveFSDiscInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_GetLiveFSDiscInfo,SHELL32_CDBurn_GetLiveFSDiscInfo,362 diff --git a/libc/nt/shell32/SHELL32_CDBurn_GetStagingPathOrNormalPath.s b/libc/nt/shell32/SHELL32_CDBurn_GetStagingPathOrNormalPath.s deleted file mode 100644 index c8023799d..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_GetStagingPathOrNormalPath.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_GetStagingPathOrNormalPath,SHELL32_CDBurn_GetStagingPathOrNormalPath,363 diff --git a/libc/nt/shell32/SHELL32_CDBurn_GetTaskInfo.s b/libc/nt/shell32/SHELL32_CDBurn_GetTaskInfo.s deleted file mode 100644 index 06e955b1c..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_GetTaskInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_GetTaskInfo,SHELL32_CDBurn_GetTaskInfo,364 diff --git a/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc.s b/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc.s deleted file mode 100644 index 276ed379c..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_IsBlankDisc,SHELL32_CDBurn_IsBlankDisc,365 diff --git a/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc2.s b/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc2.s deleted file mode 100644 index 07be70991..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_IsBlankDisc2,SHELL32_CDBurn_IsBlankDisc2,366 diff --git a/libc/nt/shell32/SHELL32_CDBurn_IsLiveFS.s b/libc/nt/shell32/SHELL32_CDBurn_IsLiveFS.s deleted file mode 100644 index a34ee6440..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_IsLiveFS.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_IsLiveFS,SHELL32_CDBurn_IsLiveFS,367 diff --git a/libc/nt/shell32/SHELL32_CDBurn_OnDeviceChange.s b/libc/nt/shell32/SHELL32_CDBurn_OnDeviceChange.s deleted file mode 100644 index 59970ec42..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_OnDeviceChange.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_OnDeviceChange,SHELL32_CDBurn_OnDeviceChange,368 diff --git a/libc/nt/shell32/SHELL32_CDBurn_OnEject.s b/libc/nt/shell32/SHELL32_CDBurn_OnEject.s deleted file mode 100644 index fd045efa2..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_OnEject.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_OnEject,SHELL32_CDBurn_OnEject,369 diff --git a/libc/nt/shell32/SHELL32_CDBurn_OnMediaChange.s b/libc/nt/shell32/SHELL32_CDBurn_OnMediaChange.s deleted file mode 100644 index cd9e00564..000000000 --- a/libc/nt/shell32/SHELL32_CDBurn_OnMediaChange.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDBurn_OnMediaChange,SHELL32_CDBurn_OnMediaChange,370 diff --git a/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2.s b/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2.s deleted file mode 100644 index f80d1763d..000000000 --- a/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDefFolderMenu_Create2,SHELL32_CDefFolderMenu_Create2,371 diff --git a/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2Ex.s b/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2Ex.s deleted file mode 100644 index 3cc868860..000000000 --- a/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2Ex.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDefFolderMenu_Create2Ex,SHELL32_CDefFolderMenu_Create2Ex,372 diff --git a/libc/nt/shell32/SHELL32_CDefFolderMenu_MergeMenu.s b/libc/nt/shell32/SHELL32_CDefFolderMenu_MergeMenu.s deleted file mode 100644 index b7ec9c440..000000000 --- a/libc/nt/shell32/SHELL32_CDefFolderMenu_MergeMenu.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDefFolderMenu_MergeMenu,SHELL32_CDefFolderMenu_MergeMenu,373 diff --git a/libc/nt/shell32/SHELL32_CDrivesContextMenu_Create.s b/libc/nt/shell32/SHELL32_CDrivesContextMenu_Create.s deleted file mode 100644 index b7c094076..000000000 --- a/libc/nt/shell32/SHELL32_CDrivesContextMenu_Create.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDrivesContextMenu_Create,SHELL32_CDrivesContextMenu_Create,374 diff --git a/libc/nt/shell32/SHELL32_CDrivesDropTarget_Create.s b/libc/nt/shell32/SHELL32_CDrivesDropTarget_Create.s deleted file mode 100644 index c072222ac..000000000 --- a/libc/nt/shell32/SHELL32_CDrivesDropTarget_Create.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDrivesDropTarget_Create,SHELL32_CDrivesDropTarget_Create,375 diff --git a/libc/nt/shell32/SHELL32_CDrives_CreateSFVCB.s b/libc/nt/shell32/SHELL32_CDrives_CreateSFVCB.s deleted file mode 100644 index c0521b2ca..000000000 --- a/libc/nt/shell32/SHELL32_CDrives_CreateSFVCB.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CDrives_CreateSFVCB,SHELL32_CDrives_CreateSFVCB,376 diff --git a/libc/nt/shell32/SHELL32_CFSDropTarget_CreateInstance.s b/libc/nt/shell32/SHELL32_CFSDropTarget_CreateInstance.s deleted file mode 100644 index b5eba867a..000000000 --- a/libc/nt/shell32/SHELL32_CFSDropTarget_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CFSDropTarget_CreateInstance,SHELL32_CFSDropTarget_CreateInstance,377 diff --git a/libc/nt/shell32/SHELL32_CFSFolderCallback_Create.s b/libc/nt/shell32/SHELL32_CFSFolderCallback_Create.s deleted file mode 100644 index 149a25d73..000000000 --- a/libc/nt/shell32/SHELL32_CFSFolderCallback_Create.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CFSFolderCallback_Create,SHELL32_CFSFolderCallback_Create,378 diff --git a/libc/nt/shell32/SHELL32_CFillPropertiesTask_CreateInstance.s b/libc/nt/shell32/SHELL32_CFillPropertiesTask_CreateInstance.s deleted file mode 100644 index 2688fd5ff..000000000 --- a/libc/nt/shell32/SHELL32_CFillPropertiesTask_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CFillPropertiesTask_CreateInstance,SHELL32_CFillPropertiesTask_CreateInstance,379 diff --git a/libc/nt/shell32/SHELL32_CLibraryDropTarget_CreateInstance.s b/libc/nt/shell32/SHELL32_CLibraryDropTarget_CreateInstance.s deleted file mode 100644 index 60cdf7b39..000000000 --- a/libc/nt/shell32/SHELL32_CLibraryDropTarget_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CLibraryDropTarget_CreateInstance,SHELL32_CLibraryDropTarget_CreateInstance,380 diff --git a/libc/nt/shell32/SHELL32_CLocationContextMenu_Create.s b/libc/nt/shell32/SHELL32_CLocationContextMenu_Create.s deleted file mode 100644 index fa30c2c51..000000000 --- a/libc/nt/shell32/SHELL32_CLocationContextMenu_Create.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CLocationContextMenu_Create,SHELL32_CLocationContextMenu_Create,381 diff --git a/libc/nt/shell32/SHELL32_CLocationFolderUI_CreateInstance.s b/libc/nt/shell32/SHELL32_CLocationFolderUI_CreateInstance.s deleted file mode 100644 index b51ce2d6a..000000000 --- a/libc/nt/shell32/SHELL32_CLocationFolderUI_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CLocationFolderUI_CreateInstance,SHELL32_CLocationFolderUI_CreateInstance,382 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_DoAutorun.s b/libc/nt/shell32/SHELL32_CMountPoint_DoAutorun.s deleted file mode 100644 index ffa76fe8b..000000000 --- a/libc/nt/shell32/SHELL32_CMountPoint_DoAutorun.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CMountPoint_DoAutorun,SHELL32_CMountPoint_DoAutorun,383 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_DoAutorunPrompt.s b/libc/nt/shell32/SHELL32_CMountPoint_DoAutorunPrompt.s deleted file mode 100644 index 2f09b8a84..000000000 --- a/libc/nt/shell32/SHELL32_CMountPoint_DoAutorunPrompt.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CMountPoint_DoAutorunPrompt,SHELL32_CMountPoint_DoAutorunPrompt,384 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy.s b/libc/nt/shell32/SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy.s deleted file mode 100644 index 8ec67fdfd..000000000 --- a/libc/nt/shell32/SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy,SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy,385 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_ProcessAutoRunFile.s b/libc/nt/shell32/SHELL32_CMountPoint_ProcessAutoRunFile.s deleted file mode 100644 index 5b6d71cd7..000000000 --- a/libc/nt/shell32/SHELL32_CMountPoint_ProcessAutoRunFile.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CMountPoint_ProcessAutoRunFile,SHELL32_CMountPoint_ProcessAutoRunFile,386 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUI.s b/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUI.s deleted file mode 100644 index 1816777c2..000000000 --- a/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUI.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CMountPoint_WantAutorunUI,SHELL32_CMountPoint_WantAutorunUI,387 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUIGetReady.s b/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUIGetReady.s deleted file mode 100644 index f607c484a..000000000 --- a/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUIGetReady.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CMountPoint_WantAutorunUIGetReady,SHELL32_CMountPoint_WantAutorunUIGetReady,388 diff --git a/libc/nt/shell32/SHELL32_CPL_CategoryIdArrayFromVariant.s b/libc/nt/shell32/SHELL32_CPL_CategoryIdArrayFromVariant.s deleted file mode 100644 index 61e0b55ed..000000000 --- a/libc/nt/shell32/SHELL32_CPL_CategoryIdArrayFromVariant.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CPL_CategoryIdArrayFromVariant,SHELL32_CPL_CategoryIdArrayFromVariant,389 diff --git a/libc/nt/shell32/SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey.s b/libc/nt/shell32/SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey.s deleted file mode 100644 index e75eae819..000000000 --- a/libc/nt/shell32/SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey,SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey,390 diff --git a/libc/nt/shell32/SHELL32_CPL_ModifyWowDisplayName.s b/libc/nt/shell32/SHELL32_CPL_ModifyWowDisplayName.s deleted file mode 100644 index a94e10a9d..000000000 --- a/libc/nt/shell32/SHELL32_CPL_ModifyWowDisplayName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CPL_ModifyWowDisplayName,SHELL32_CPL_ModifyWowDisplayName,391 diff --git a/libc/nt/shell32/SHELL32_CRecentDocsContextMenu_CreateInstance.s b/libc/nt/shell32/SHELL32_CRecentDocsContextMenu_CreateInstance.s deleted file mode 100644 index 72b40362e..000000000 --- a/libc/nt/shell32/SHELL32_CRecentDocsContextMenu_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CRecentDocsContextMenu_CreateInstance,SHELL32_CRecentDocsContextMenu_CreateInstance,392 diff --git a/libc/nt/shell32/SHELL32_CSyncRootManager_CreateInstance.s b/libc/nt/shell32/SHELL32_CSyncRootManager_CreateInstance.s deleted file mode 100644 index ba58b7013..000000000 --- a/libc/nt/shell32/SHELL32_CSyncRootManager_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CSyncRootManager_CreateInstance,SHELL32_CSyncRootManager_CreateInstance,393 diff --git a/libc/nt/shell32/SHELL32_CTransferConfirmation_CreateInstance.s b/libc/nt/shell32/SHELL32_CTransferConfirmation_CreateInstance.s deleted file mode 100644 index be45e05cf..000000000 --- a/libc/nt/shell32/SHELL32_CTransferConfirmation_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CTransferConfirmation_CreateInstance,SHELL32_CTransferConfirmation_CreateInstance,394 diff --git a/libc/nt/shell32/SHELL32_CallFileCopyHooks.s b/libc/nt/shell32/SHELL32_CallFileCopyHooks.s deleted file mode 100644 index 0f1c6c8b7..000000000 --- a/libc/nt/shell32/SHELL32_CallFileCopyHooks.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CallFileCopyHooks,SHELL32_CallFileCopyHooks,395 diff --git a/libc/nt/shell32/SHELL32_CanDisplayWin8CopyDialog.s b/libc/nt/shell32/SHELL32_CanDisplayWin8CopyDialog.s deleted file mode 100644 index 3bc284131..000000000 --- a/libc/nt/shell32/SHELL32_CanDisplayWin8CopyDialog.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CanDisplayWin8CopyDialog,SHELL32_CanDisplayWin8CopyDialog,396 diff --git a/libc/nt/shell32/SHELL32_CloseAutoplayPrompt.s b/libc/nt/shell32/SHELL32_CloseAutoplayPrompt.s deleted file mode 100644 index a13aec038..000000000 --- a/libc/nt/shell32/SHELL32_CloseAutoplayPrompt.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CloseAutoplayPrompt,SHELL32_CloseAutoplayPrompt,397 diff --git a/libc/nt/shell32/SHELL32_CommandLineFromMsiDescriptor.s b/libc/nt/shell32/SHELL32_CommandLineFromMsiDescriptor.s deleted file mode 100644 index 4fb321483..000000000 --- a/libc/nt/shell32/SHELL32_CommandLineFromMsiDescriptor.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CommandLineFromMsiDescriptor,SHELL32_CommandLineFromMsiDescriptor,398 diff --git a/libc/nt/shell32/SHELL32_CopyFilePlaceholderToNewFile.s b/libc/nt/shell32/SHELL32_CopyFilePlaceholderToNewFile.s deleted file mode 100644 index 341cfeba8..000000000 --- a/libc/nt/shell32/SHELL32_CopyFilePlaceholderToNewFile.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CopyFilePlaceholderToNewFile,SHELL32_CopyFilePlaceholderToNewFile,399 diff --git a/libc/nt/shell32/SHELL32_CopySecondaryTiles.s b/libc/nt/shell32/SHELL32_CopySecondaryTiles.s deleted file mode 100644 index 445cc1447..000000000 --- a/libc/nt/shell32/SHELL32_CopySecondaryTiles.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CopySecondaryTiles,SHELL32_CopySecondaryTiles,400 diff --git a/libc/nt/shell32/SHELL32_CreateConfirmationInterrupt.s b/libc/nt/shell32/SHELL32_CreateConfirmationInterrupt.s deleted file mode 100644 index 1545afe85..000000000 --- a/libc/nt/shell32/SHELL32_CreateConfirmationInterrupt.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CreateConfirmationInterrupt,SHELL32_CreateConfirmationInterrupt,401 diff --git a/libc/nt/shell32/SHELL32_CreateConflictInterrupt.s b/libc/nt/shell32/SHELL32_CreateConflictInterrupt.s deleted file mode 100644 index 8d56bf462..000000000 --- a/libc/nt/shell32/SHELL32_CreateConflictInterrupt.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CreateConflictInterrupt,SHELL32_CreateConflictInterrupt,402 diff --git a/libc/nt/shell32/SHELL32_CreateDefaultOperationDataProvider.s b/libc/nt/shell32/SHELL32_CreateDefaultOperationDataProvider.s deleted file mode 100644 index de973b39c..000000000 --- a/libc/nt/shell32/SHELL32_CreateDefaultOperationDataProvider.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CreateDefaultOperationDataProvider,SHELL32_CreateDefaultOperationDataProvider,403 diff --git a/libc/nt/shell32/SHELL32_CreateFileFolderContextMenu.s b/libc/nt/shell32/SHELL32_CreateFileFolderContextMenu.s deleted file mode 100644 index a2ed86153..000000000 --- a/libc/nt/shell32/SHELL32_CreateFileFolderContextMenu.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CreateFileFolderContextMenu,SHELL32_CreateFileFolderContextMenu,404 diff --git a/libc/nt/shell32/SHELL32_CreateLinkInfoW.s b/libc/nt/shell32/SHELL32_CreateLinkInfoW.s deleted file mode 100644 index bc03f8b2e..000000000 --- a/libc/nt/shell32/SHELL32_CreateLinkInfoW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CreateLinkInfoW,SHELL32_CreateLinkInfoW,405 diff --git a/libc/nt/shell32/SHELL32_CreatePlaceholderFile.s b/libc/nt/shell32/SHELL32_CreatePlaceholderFile.s deleted file mode 100644 index 7e0647582..000000000 --- a/libc/nt/shell32/SHELL32_CreatePlaceholderFile.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CreatePlaceholderFile,SHELL32_CreatePlaceholderFile,406 diff --git a/libc/nt/shell32/SHELL32_CreateQosRecorder.s b/libc/nt/shell32/SHELL32_CreateQosRecorder.s deleted file mode 100644 index 94b47b6f2..000000000 --- a/libc/nt/shell32/SHELL32_CreateQosRecorder.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CreateQosRecorder,SHELL32_CreateQosRecorder,407 diff --git a/libc/nt/shell32/SHELL32_CreateSharePointView.s b/libc/nt/shell32/SHELL32_CreateSharePointView.s deleted file mode 100644 index 9fcda67b1..000000000 --- a/libc/nt/shell32/SHELL32_CreateSharePointView.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_CreateSharePointView,SHELL32_CreateSharePointView,408 diff --git a/libc/nt/shell32/SHELL32_Create_IEnumUICommand.s b/libc/nt/shell32/SHELL32_Create_IEnumUICommand.s deleted file mode 100644 index 47ed45ac3..000000000 --- a/libc/nt/shell32/SHELL32_Create_IEnumUICommand.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_Create_IEnumUICommand,SHELL32_Create_IEnumUICommand,409 diff --git a/libc/nt/shell32/SHELL32_DestroyLinkInfo.s b/libc/nt/shell32/SHELL32_DestroyLinkInfo.s deleted file mode 100644 index dcce08f66..000000000 --- a/libc/nt/shell32/SHELL32_DestroyLinkInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_DestroyLinkInfo,SHELL32_DestroyLinkInfo,410 diff --git a/libc/nt/shell32/SHELL32_EncryptDirectory.s b/libc/nt/shell32/SHELL32_EncryptDirectory.s deleted file mode 100644 index a834c6316..000000000 --- a/libc/nt/shell32/SHELL32_EncryptDirectory.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_EncryptDirectory,SHELL32_EncryptDirectory,411 diff --git a/libc/nt/shell32/SHELL32_EncryptedFileKeyInfo.s b/libc/nt/shell32/SHELL32_EncryptedFileKeyInfo.s deleted file mode 100644 index 9f30cc102..000000000 --- a/libc/nt/shell32/SHELL32_EncryptedFileKeyInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_EncryptedFileKeyInfo,SHELL32_EncryptedFileKeyInfo,412 diff --git a/libc/nt/shell32/SHELL32_EnumCommonTasks.s b/libc/nt/shell32/SHELL32_EnumCommonTasks.s deleted file mode 100644 index dbd2fe7f8..000000000 --- a/libc/nt/shell32/SHELL32_EnumCommonTasks.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_EnumCommonTasks,SHELL32_EnumCommonTasks,413 diff --git a/libc/nt/shell32/SHELL32_FilePlaceholder_BindToPrimaryStream.s b/libc/nt/shell32/SHELL32_FilePlaceholder_BindToPrimaryStream.s deleted file mode 100644 index bfb8e80d6..000000000 --- a/libc/nt/shell32/SHELL32_FilePlaceholder_BindToPrimaryStream.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_FilePlaceholder_BindToPrimaryStream,SHELL32_FilePlaceholder_BindToPrimaryStream,414 diff --git a/libc/nt/shell32/SHELL32_FilePlaceholder_CreateInstance.s b/libc/nt/shell32/SHELL32_FilePlaceholder_CreateInstance.s deleted file mode 100644 index c4876c4a0..000000000 --- a/libc/nt/shell32/SHELL32_FilePlaceholder_CreateInstance.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_FilePlaceholder_CreateInstance,SHELL32_FilePlaceholder_CreateInstance,415 diff --git a/libc/nt/shell32/SHELL32_FreeEncryptedFileKeyInfo.s b/libc/nt/shell32/SHELL32_FreeEncryptedFileKeyInfo.s deleted file mode 100644 index 21b1a7ca6..000000000 --- a/libc/nt/shell32/SHELL32_FreeEncryptedFileKeyInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_FreeEncryptedFileKeyInfo,SHELL32_FreeEncryptedFileKeyInfo,416 diff --git a/libc/nt/shell32/SHELL32_GenerateAppID.s b/libc/nt/shell32/SHELL32_GenerateAppID.s deleted file mode 100644 index 377d0bd37..000000000 --- a/libc/nt/shell32/SHELL32_GenerateAppID.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GenerateAppID,SHELL32_GenerateAppID,417 diff --git a/libc/nt/shell32/SHELL32_GetAppIDRoot.s b/libc/nt/shell32/SHELL32_GetAppIDRoot.s deleted file mode 100644 index b950019a1..000000000 --- a/libc/nt/shell32/SHELL32_GetAppIDRoot.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetAppIDRoot,SHELL32_GetAppIDRoot,418 diff --git a/libc/nt/shell32/SHELL32_GetCommandProviderForFolderType.s b/libc/nt/shell32/SHELL32_GetCommandProviderForFolderType.s deleted file mode 100644 index eb970bbe7..000000000 --- a/libc/nt/shell32/SHELL32_GetCommandProviderForFolderType.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetCommandProviderForFolderType,SHELL32_GetCommandProviderForFolderType,419 diff --git a/libc/nt/shell32/SHELL32_GetDPIAdjustedLogicalSize.s b/libc/nt/shell32/SHELL32_GetDPIAdjustedLogicalSize.s deleted file mode 100644 index e2b7c85e7..000000000 --- a/libc/nt/shell32/SHELL32_GetDPIAdjustedLogicalSize.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetDPIAdjustedLogicalSize,SHELL32_GetDPIAdjustedLogicalSize,420 diff --git a/libc/nt/shell32/SHELL32_GetDiskCleanupPath.s b/libc/nt/shell32/SHELL32_GetDiskCleanupPath.s deleted file mode 100644 index da917cd60..000000000 --- a/libc/nt/shell32/SHELL32_GetDiskCleanupPath.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetDiskCleanupPath,SHELL32_GetDiskCleanupPath,421 diff --git a/libc/nt/shell32/SHELL32_GetFileNameFromBrowse.s b/libc/nt/shell32/SHELL32_GetFileNameFromBrowse.s deleted file mode 100644 index a3d56cceb..000000000 --- a/libc/nt/shell32/SHELL32_GetFileNameFromBrowse.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetFileNameFromBrowse,SHELL32_GetFileNameFromBrowse,422 diff --git a/libc/nt/shell32/SHELL32_GetIconOverlayManager.s b/libc/nt/shell32/SHELL32_GetIconOverlayManager.s deleted file mode 100644 index fdb016208..000000000 --- a/libc/nt/shell32/SHELL32_GetIconOverlayManager.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetIconOverlayManager,SHELL32_GetIconOverlayManager,423 diff --git a/libc/nt/shell32/SHELL32_GetLinkInfoData.s b/libc/nt/shell32/SHELL32_GetLinkInfoData.s deleted file mode 100644 index 37e3689f7..000000000 --- a/libc/nt/shell32/SHELL32_GetLinkInfoData.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetLinkInfoData,SHELL32_GetLinkInfoData,424 diff --git a/libc/nt/shell32/SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag.s b/libc/nt/shell32/SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag.s deleted file mode 100644 index eeff03da3..000000000 --- a/libc/nt/shell32/SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag,SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag,425 diff --git a/libc/nt/shell32/SHELL32_GetRatingBucket.s b/libc/nt/shell32/SHELL32_GetRatingBucket.s deleted file mode 100644 index fdf5e3d60..000000000 --- a/libc/nt/shell32/SHELL32_GetRatingBucket.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetRatingBucket,SHELL32_GetRatingBucket,426 diff --git a/libc/nt/shell32/SHELL32_GetSkyDriveNetworkStates.s b/libc/nt/shell32/SHELL32_GetSkyDriveNetworkStates.s deleted file mode 100644 index 90faa199f..000000000 --- a/libc/nt/shell32/SHELL32_GetSkyDriveNetworkStates.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetSkyDriveNetworkStates,SHELL32_GetSkyDriveNetworkStates,427 diff --git a/libc/nt/shell32/SHELL32_GetSqmableFileName.s b/libc/nt/shell32/SHELL32_GetSqmableFileName.s deleted file mode 100644 index 8d23e3811..000000000 --- a/libc/nt/shell32/SHELL32_GetSqmableFileName.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetSqmableFileName,SHELL32_GetSqmableFileName,428 diff --git a/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory.s b/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory.s deleted file mode 100644 index 8254bc2f4..000000000 --- a/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetThumbnailAdornerFromFactory,SHELL32_GetThumbnailAdornerFromFactory,429 diff --git a/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory2.s b/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory2.s deleted file mode 100644 index b3e16ac03..000000000 --- a/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_GetThumbnailAdornerFromFactory2,SHELL32_GetThumbnailAdornerFromFactory2,430 diff --git a/libc/nt/shell32/SHELL32_HandleUnrecognizedFileSystem.s b/libc/nt/shell32/SHELL32_HandleUnrecognizedFileSystem.s deleted file mode 100644 index a61f7e236..000000000 --- a/libc/nt/shell32/SHELL32_HandleUnrecognizedFileSystem.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_HandleUnrecognizedFileSystem,SHELL32_HandleUnrecognizedFileSystem,431 diff --git a/libc/nt/shell32/SHELL32_IconCacheCreate.s b/libc/nt/shell32/SHELL32_IconCacheCreate.s deleted file mode 100644 index 4f20016f4..000000000 --- a/libc/nt/shell32/SHELL32_IconCacheCreate.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconCacheCreate,SHELL32_IconCacheCreate,432 diff --git a/libc/nt/shell32/SHELL32_IconCacheDestroy.s b/libc/nt/shell32/SHELL32_IconCacheDestroy.s deleted file mode 100644 index 0572b4ac3..000000000 --- a/libc/nt/shell32/SHELL32_IconCacheDestroy.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconCacheDestroy,SHELL32_IconCacheDestroy,433 diff --git a/libc/nt/shell32/SHELL32_IconCacheHandleAssociationChanged.s b/libc/nt/shell32/SHELL32_IconCacheHandleAssociationChanged.s deleted file mode 100644 index f7aca4f68..000000000 --- a/libc/nt/shell32/SHELL32_IconCacheHandleAssociationChanged.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconCacheHandleAssociationChanged,SHELL32_IconCacheHandleAssociationChanged,434 diff --git a/libc/nt/shell32/SHELL32_IconCacheRestore.s b/libc/nt/shell32/SHELL32_IconCacheRestore.s deleted file mode 100644 index 45f9c85c4..000000000 --- a/libc/nt/shell32/SHELL32_IconCacheRestore.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconCacheRestore,SHELL32_IconCacheRestore,435 diff --git a/libc/nt/shell32/SHELL32_IconCache_AboutToExtractIcons.s b/libc/nt/shell32/SHELL32_IconCache_AboutToExtractIcons.s deleted file mode 100644 index 791de0872..000000000 --- a/libc/nt/shell32/SHELL32_IconCache_AboutToExtractIcons.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconCache_AboutToExtractIcons,SHELL32_IconCache_AboutToExtractIcons,436 diff --git a/libc/nt/shell32/SHELL32_IconCache_DoneExtractingIcons.s b/libc/nt/shell32/SHELL32_IconCache_DoneExtractingIcons.s deleted file mode 100644 index 957fa189d..000000000 --- a/libc/nt/shell32/SHELL32_IconCache_DoneExtractingIcons.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconCache_DoneExtractingIcons,SHELL32_IconCache_DoneExtractingIcons,437 diff --git a/libc/nt/shell32/SHELL32_IconCache_ExpandEnvAndSearchPath.s b/libc/nt/shell32/SHELL32_IconCache_ExpandEnvAndSearchPath.s deleted file mode 100644 index e43425f66..000000000 --- a/libc/nt/shell32/SHELL32_IconCache_ExpandEnvAndSearchPath.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconCache_ExpandEnvAndSearchPath,SHELL32_IconCache_ExpandEnvAndSearchPath,438 diff --git a/libc/nt/shell32/SHELL32_IconCache_RememberRecentlyExtractedIconsW.s b/libc/nt/shell32/SHELL32_IconCache_RememberRecentlyExtractedIconsW.s deleted file mode 100644 index af4b8d36b..000000000 --- a/libc/nt/shell32/SHELL32_IconCache_RememberRecentlyExtractedIconsW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconCache_RememberRecentlyExtractedIconsW,SHELL32_IconCache_RememberRecentlyExtractedIconsW,439 diff --git a/libc/nt/shell32/SHELL32_IconOverlayManagerInit.s b/libc/nt/shell32/SHELL32_IconOverlayManagerInit.s deleted file mode 100644 index 65c0e3fc9..000000000 --- a/libc/nt/shell32/SHELL32_IconOverlayManagerInit.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IconOverlayManagerInit,SHELL32_IconOverlayManagerInit,440 diff --git a/libc/nt/shell32/SHELL32_IsGetKeyboardLayoutPresent.s b/libc/nt/shell32/SHELL32_IsGetKeyboardLayoutPresent.s deleted file mode 100644 index 3bc3dba75..000000000 --- a/libc/nt/shell32/SHELL32_IsGetKeyboardLayoutPresent.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IsGetKeyboardLayoutPresent,SHELL32_IsGetKeyboardLayoutPresent,441 diff --git a/libc/nt/shell32/SHELL32_IsSystemUpgradeInProgress.s b/libc/nt/shell32/SHELL32_IsSystemUpgradeInProgress.s deleted file mode 100644 index 936628f5c..000000000 --- a/libc/nt/shell32/SHELL32_IsSystemUpgradeInProgress.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IsSystemUpgradeInProgress,SHELL32_IsSystemUpgradeInProgress,442 diff --git a/libc/nt/shell32/SHELL32_IsValidLinkInfo.s b/libc/nt/shell32/SHELL32_IsValidLinkInfo.s deleted file mode 100644 index 2f7035a52..000000000 --- a/libc/nt/shell32/SHELL32_IsValidLinkInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_IsValidLinkInfo,SHELL32_IsValidLinkInfo,443 diff --git a/libc/nt/shell32/SHELL32_LegacyEnumSpecialTasksByType.s b/libc/nt/shell32/SHELL32_LegacyEnumSpecialTasksByType.s deleted file mode 100644 index e05b207c6..000000000 --- a/libc/nt/shell32/SHELL32_LegacyEnumSpecialTasksByType.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_LegacyEnumSpecialTasksByType,SHELL32_LegacyEnumSpecialTasksByType,444 diff --git a/libc/nt/shell32/SHELL32_LegacyEnumTasks.s b/libc/nt/shell32/SHELL32_LegacyEnumTasks.s deleted file mode 100644 index d1f42c7b2..000000000 --- a/libc/nt/shell32/SHELL32_LegacyEnumTasks.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_LegacyEnumTasks,SHELL32_LegacyEnumTasks,445 diff --git a/libc/nt/shell32/SHELL32_LookupBackIconIndex.s b/libc/nt/shell32/SHELL32_LookupBackIconIndex.s deleted file mode 100644 index 35b87ad7e..000000000 --- a/libc/nt/shell32/SHELL32_LookupBackIconIndex.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_LookupBackIconIndex,SHELL32_LookupBackIconIndex,446 diff --git a/libc/nt/shell32/SHELL32_LookupFrontIconIndex.s b/libc/nt/shell32/SHELL32_LookupFrontIconIndex.s deleted file mode 100644 index 49b18e3ee..000000000 --- a/libc/nt/shell32/SHELL32_LookupFrontIconIndex.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_LookupFrontIconIndex,SHELL32_LookupFrontIconIndex,447 diff --git a/libc/nt/shell32/SHELL32_NormalizeRating.s b/libc/nt/shell32/SHELL32_NormalizeRating.s deleted file mode 100644 index 3b845be4c..000000000 --- a/libc/nt/shell32/SHELL32_NormalizeRating.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_NormalizeRating,SHELL32_NormalizeRating,448 diff --git a/libc/nt/shell32/SHELL32_NotifyLinkTrackingServiceOfMove.s b/libc/nt/shell32/SHELL32_NotifyLinkTrackingServiceOfMove.s deleted file mode 100644 index a5b6e0603..000000000 --- a/libc/nt/shell32/SHELL32_NotifyLinkTrackingServiceOfMove.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_NotifyLinkTrackingServiceOfMove,SHELL32_NotifyLinkTrackingServiceOfMove,449 diff --git a/libc/nt/shell32/SHELL32_PifMgr_CloseProperties.s b/libc/nt/shell32/SHELL32_PifMgr_CloseProperties.s deleted file mode 100644 index 38a6c761a..000000000 --- a/libc/nt/shell32/SHELL32_PifMgr_CloseProperties.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_PifMgr_CloseProperties,SHELL32_PifMgr_CloseProperties,450 diff --git a/libc/nt/shell32/SHELL32_PifMgr_GetProperties.s b/libc/nt/shell32/SHELL32_PifMgr_GetProperties.s deleted file mode 100644 index 2dd11b35c..000000000 --- a/libc/nt/shell32/SHELL32_PifMgr_GetProperties.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_PifMgr_GetProperties,SHELL32_PifMgr_GetProperties,451 diff --git a/libc/nt/shell32/SHELL32_PifMgr_OpenProperties.s b/libc/nt/shell32/SHELL32_PifMgr_OpenProperties.s deleted file mode 100644 index a1943e232..000000000 --- a/libc/nt/shell32/SHELL32_PifMgr_OpenProperties.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_PifMgr_OpenProperties,SHELL32_PifMgr_OpenProperties,452 diff --git a/libc/nt/shell32/SHELL32_PifMgr_SetProperties.s b/libc/nt/shell32/SHELL32_PifMgr_SetProperties.s deleted file mode 100644 index d00605e2a..000000000 --- a/libc/nt/shell32/SHELL32_PifMgr_SetProperties.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_PifMgr_SetProperties,SHELL32_PifMgr_SetProperties,453 diff --git a/libc/nt/shell32/SHELL32_Printers_CreateBindInfo.s b/libc/nt/shell32/SHELL32_Printers_CreateBindInfo.s deleted file mode 100644 index 4acbf93ac..000000000 --- a/libc/nt/shell32/SHELL32_Printers_CreateBindInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_Printers_CreateBindInfo,SHELL32_Printers_CreateBindInfo,454 diff --git a/libc/nt/shell32/SHELL32_Printjob_GetPidl.s b/libc/nt/shell32/SHELL32_Printjob_GetPidl.s deleted file mode 100644 index 0db335fcc..000000000 --- a/libc/nt/shell32/SHELL32_Printjob_GetPidl.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_Printjob_GetPidl,SHELL32_Printjob_GetPidl,455 diff --git a/libc/nt/shell32/SHELL32_PurgeSystemIcon.s b/libc/nt/shell32/SHELL32_PurgeSystemIcon.s deleted file mode 100644 index 856883fb6..000000000 --- a/libc/nt/shell32/SHELL32_PurgeSystemIcon.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_PurgeSystemIcon,SHELL32_PurgeSystemIcon,456 diff --git a/libc/nt/shell32/SHELL32_RefreshOverlayImages.s b/libc/nt/shell32/SHELL32_RefreshOverlayImages.s deleted file mode 100644 index 7ce6388c1..000000000 --- a/libc/nt/shell32/SHELL32_RefreshOverlayImages.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_RefreshOverlayImages,SHELL32_RefreshOverlayImages,457 diff --git a/libc/nt/shell32/SHELL32_ResolveLinkInfoW.s b/libc/nt/shell32/SHELL32_ResolveLinkInfoW.s deleted file mode 100644 index d4ab19d67..000000000 --- a/libc/nt/shell32/SHELL32_ResolveLinkInfoW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_ResolveLinkInfoW,SHELL32_ResolveLinkInfoW,458 diff --git a/libc/nt/shell32/SHELL32_SHAddSparseIcon.s b/libc/nt/shell32/SHELL32_SHAddSparseIcon.s deleted file mode 100644 index 46ff5a9a8..000000000 --- a/libc/nt/shell32/SHELL32_SHAddSparseIcon.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHAddSparseIcon,SHELL32_SHAddSparseIcon,459 diff --git a/libc/nt/shell32/SHELL32_SHCreateByValueOperationInterrupt.s b/libc/nt/shell32/SHELL32_SHCreateByValueOperationInterrupt.s deleted file mode 100644 index 73461fc46..000000000 --- a/libc/nt/shell32/SHELL32_SHCreateByValueOperationInterrupt.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHCreateByValueOperationInterrupt,SHELL32_SHCreateByValueOperationInterrupt,460 diff --git a/libc/nt/shell32/SHELL32_SHCreateDefaultContextMenu.s b/libc/nt/shell32/SHELL32_SHCreateDefaultContextMenu.s deleted file mode 100644 index 32c544e3a..000000000 --- a/libc/nt/shell32/SHELL32_SHCreateDefaultContextMenu.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHCreateDefaultContextMenu,SHELL32_SHCreateDefaultContextMenu,461 diff --git a/libc/nt/shell32/SHELL32_SHCreateLocalServer.s b/libc/nt/shell32/SHELL32_SHCreateLocalServer.s deleted file mode 100644 index 879925e00..000000000 --- a/libc/nt/shell32/SHELL32_SHCreateLocalServer.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHCreateLocalServer,SHELL32_SHCreateLocalServer,462 diff --git a/libc/nt/shell32/SHELL32_SHCreateShellFolderView.s b/libc/nt/shell32/SHELL32_SHCreateShellFolderView.s deleted file mode 100644 index 7be8765ac..000000000 --- a/libc/nt/shell32/SHELL32_SHCreateShellFolderView.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHCreateShellFolderView,SHELL32_SHCreateShellFolderView,463 diff --git a/libc/nt/shell32/SHELL32_SHDuplicateEncryptionInfoFile.s b/libc/nt/shell32/SHELL32_SHDuplicateEncryptionInfoFile.s deleted file mode 100644 index e963873d2..000000000 --- a/libc/nt/shell32/SHELL32_SHDuplicateEncryptionInfoFile.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHDuplicateEncryptionInfoFile,SHELL32_SHDuplicateEncryptionInfoFile,464 diff --git a/libc/nt/shell32/SHELL32_SHEncryptFile.s b/libc/nt/shell32/SHELL32_SHEncryptFile.s deleted file mode 100644 index 89fc04b07..000000000 --- a/libc/nt/shell32/SHELL32_SHEncryptFile.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHEncryptFile,SHELL32_SHEncryptFile,465 diff --git a/libc/nt/shell32/SHELL32_SHFormatDriveAsync.s b/libc/nt/shell32/SHELL32_SHFormatDriveAsync.s deleted file mode 100644 index b970862a3..000000000 --- a/libc/nt/shell32/SHELL32_SHFormatDriveAsync.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHFormatDriveAsync,SHELL32_SHFormatDriveAsync,466 diff --git a/libc/nt/shell32/SHELL32_SHGetThreadUndoManager.s b/libc/nt/shell32/SHELL32_SHGetThreadUndoManager.s deleted file mode 100644 index 03dab2bbf..000000000 --- a/libc/nt/shell32/SHELL32_SHGetThreadUndoManager.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHGetThreadUndoManager,SHELL32_SHGetThreadUndoManager,467 diff --git a/libc/nt/shell32/SHELL32_SHGetUserNameW.s b/libc/nt/shell32/SHELL32_SHGetUserNameW.s deleted file mode 100644 index 489dedbdd..000000000 --- a/libc/nt/shell32/SHELL32_SHGetUserNameW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHGetUserNameW,SHELL32_SHGetUserNameW,468 diff --git a/libc/nt/shell32/SHELL32_SHIsVirtualDevice.s b/libc/nt/shell32/SHELL32_SHIsVirtualDevice.s deleted file mode 100644 index bd8f5b907..000000000 --- a/libc/nt/shell32/SHELL32_SHIsVirtualDevice.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHIsVirtualDevice,SHELL32_SHIsVirtualDevice,469 diff --git a/libc/nt/shell32/SHELL32_SHLaunchPropSheet.s b/libc/nt/shell32/SHELL32_SHLaunchPropSheet.s deleted file mode 100644 index ea78cec4e..000000000 --- a/libc/nt/shell32/SHELL32_SHLaunchPropSheet.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHLaunchPropSheet,SHELL32_SHLaunchPropSheet,470 diff --git a/libc/nt/shell32/SHELL32_SHLogILFromFSIL.s b/libc/nt/shell32/SHELL32_SHLogILFromFSIL.s deleted file mode 100644 index 5992b9df7..000000000 --- a/libc/nt/shell32/SHELL32_SHLogILFromFSIL.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHLogILFromFSIL,SHELL32_SHLogILFromFSIL,471 diff --git a/libc/nt/shell32/SHELL32_SHOpenWithDialog.s b/libc/nt/shell32/SHELL32_SHOpenWithDialog.s deleted file mode 100644 index a19f97b20..000000000 --- a/libc/nt/shell32/SHELL32_SHOpenWithDialog.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHOpenWithDialog,SHELL32_SHOpenWithDialog,472 diff --git a/libc/nt/shell32/SHELL32_SHStartNetConnectionDialogW.s b/libc/nt/shell32/SHELL32_SHStartNetConnectionDialogW.s deleted file mode 100644 index dca3f8d4c..000000000 --- a/libc/nt/shell32/SHELL32_SHStartNetConnectionDialogW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHStartNetConnectionDialogW,SHELL32_SHStartNetConnectionDialogW,473 diff --git a/libc/nt/shell32/SHELL32_SHUICommandFromGUID.s b/libc/nt/shell32/SHELL32_SHUICommandFromGUID.s deleted file mode 100644 index 65ef908ce..000000000 --- a/libc/nt/shell32/SHELL32_SHUICommandFromGUID.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SHUICommandFromGUID,SHELL32_SHUICommandFromGUID,474 diff --git a/libc/nt/shell32/SHELL32_SendToMenu_InvokeTargetedCommand.s b/libc/nt/shell32/SHELL32_SendToMenu_InvokeTargetedCommand.s deleted file mode 100644 index 7ff680bf9..000000000 --- a/libc/nt/shell32/SHELL32_SendToMenu_InvokeTargetedCommand.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SendToMenu_InvokeTargetedCommand,SHELL32_SendToMenu_InvokeTargetedCommand,475 diff --git a/libc/nt/shell32/SHELL32_SendToMenu_VerifyTargetedCommand.s b/libc/nt/shell32/SHELL32_SendToMenu_VerifyTargetedCommand.s deleted file mode 100644 index bbbed7e41..000000000 --- a/libc/nt/shell32/SHELL32_SendToMenu_VerifyTargetedCommand.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SendToMenu_VerifyTargetedCommand,SHELL32_SendToMenu_VerifyTargetedCommand,476 diff --git a/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute.s b/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute.s deleted file mode 100644 index 92247577d..000000000 --- a/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SetPlaceholderReparsePointAttribute,SHELL32_SetPlaceholderReparsePointAttribute,477 diff --git a/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute2.s b/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute2.s deleted file mode 100644 index 30cea6fe1..000000000 --- a/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute2.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SetPlaceholderReparsePointAttribute2,SHELL32_SetPlaceholderReparsePointAttribute2,478 diff --git a/libc/nt/shell32/SHELL32_ShowHideIconOnlyOnDesktop.s b/libc/nt/shell32/SHELL32_ShowHideIconOnlyOnDesktop.s deleted file mode 100644 index acdaa50a2..000000000 --- a/libc/nt/shell32/SHELL32_ShowHideIconOnlyOnDesktop.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_ShowHideIconOnlyOnDesktop,SHELL32_ShowHideIconOnlyOnDesktop,479 diff --git a/libc/nt/shell32/SHELL32_SimpleRatingToFilterCondition.s b/libc/nt/shell32/SHELL32_SimpleRatingToFilterCondition.s deleted file mode 100644 index 5c41b7121..000000000 --- a/libc/nt/shell32/SHELL32_SimpleRatingToFilterCondition.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SimpleRatingToFilterCondition,SHELL32_SimpleRatingToFilterCondition,480 diff --git a/libc/nt/shell32/SHELL32_StampIconForFile.s b/libc/nt/shell32/SHELL32_StampIconForFile.s deleted file mode 100644 index ac9625c40..000000000 --- a/libc/nt/shell32/SHELL32_StampIconForFile.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_StampIconForFile,SHELL32_StampIconForFile,481 diff --git a/libc/nt/shell32/SHELL32_SuspendUndo.s b/libc/nt/shell32/SHELL32_SuspendUndo.s deleted file mode 100644 index 23ef64108..000000000 --- a/libc/nt/shell32/SHELL32_SuspendUndo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_SuspendUndo,SHELL32_SuspendUndo,482 diff --git a/libc/nt/shell32/SHELL32_TryVirtualDiscImageDriveEject.s b/libc/nt/shell32/SHELL32_TryVirtualDiscImageDriveEject.s deleted file mode 100644 index 4ef517eaa..000000000 --- a/libc/nt/shell32/SHELL32_TryVirtualDiscImageDriveEject.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_TryVirtualDiscImageDriveEject,SHELL32_TryVirtualDiscImageDriveEject,483 diff --git a/libc/nt/shell32/SHELL32_UpdateFilePlaceholderStates.s b/libc/nt/shell32/SHELL32_UpdateFilePlaceholderStates.s deleted file mode 100644 index e4e516f53..000000000 --- a/libc/nt/shell32/SHELL32_UpdateFilePlaceholderStates.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_UpdateFilePlaceholderStates,SHELL32_UpdateFilePlaceholderStates,484 diff --git a/libc/nt/shell32/SHELL32_VerifySaferTrust.s b/libc/nt/shell32/SHELL32_VerifySaferTrust.s deleted file mode 100644 index 012e4bff2..000000000 --- a/libc/nt/shell32/SHELL32_VerifySaferTrust.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHELL32_VerifySaferTrust,SHELL32_VerifySaferTrust,485 diff --git a/libc/nt/shell32/SHEmptyRecycleBinA.s b/libc/nt/shell32/SHEmptyRecycleBinA.s deleted file mode 100644 index 91a864f90..000000000 --- a/libc/nt/shell32/SHEmptyRecycleBinA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHEmptyRecycleBinA,SHEmptyRecycleBinA,486 diff --git a/libc/nt/shell32/SHFileOperationA.s b/libc/nt/shell32/SHFileOperationA.s deleted file mode 100644 index cf28a8ac1..000000000 --- a/libc/nt/shell32/SHFileOperationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHFileOperationA,SHFileOperationA,493 diff --git a/libc/nt/shell32/SHGetDataFromIDListA.s b/libc/nt/shell32/SHGetDataFromIDListA.s deleted file mode 100644 index 577cb4789..000000000 --- a/libc/nt/shell32/SHGetDataFromIDListA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetDataFromIDListA,SHGetDataFromIDListA,497 diff --git a/libc/nt/shell32/SHGetDiskFreeSpaceA.s b/libc/nt/shell32/SHGetDiskFreeSpaceA.s deleted file mode 100644 index 67c04941a..000000000 --- a/libc/nt/shell32/SHGetDiskFreeSpaceA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetDiskFreeSpaceA,SHGetDiskFreeSpaceA,500 diff --git a/libc/nt/shell32/SHGetDiskFreeSpaceExA.s b/libc/nt/shell32/SHGetDiskFreeSpaceExA.s deleted file mode 100644 index 36c4008cf..000000000 --- a/libc/nt/shell32/SHGetDiskFreeSpaceExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetDiskFreeSpaceExA,SHGetDiskFreeSpaceExA,501 diff --git a/libc/nt/shell32/SHGetFileInfoA.s b/libc/nt/shell32/SHGetFileInfoA.s deleted file mode 100644 index 54786a07f..000000000 --- a/libc/nt/shell32/SHGetFileInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetFileInfoA,SHGetFileInfoA,505 diff --git a/libc/nt/shell32/SHGetFolderPathA.s b/libc/nt/shell32/SHGetFolderPathA.s deleted file mode 100644 index 8b20154a8..000000000 --- a/libc/nt/shell32/SHGetFolderPathA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetFolderPathA,SHGetFolderPathA,508 diff --git a/libc/nt/shell32/SHGetFolderPathAndSubDirA.s b/libc/nt/shell32/SHGetFolderPathAndSubDirA.s deleted file mode 100644 index e8f1265d9..000000000 --- a/libc/nt/shell32/SHGetFolderPathAndSubDirA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetFolderPathAndSubDirA,SHGetFolderPathAndSubDirA,509 diff --git a/libc/nt/shell32/SHGetIconOverlayIndexA.s b/libc/nt/shell32/SHGetIconOverlayIndexA.s deleted file mode 100644 index b78116dee..000000000 --- a/libc/nt/shell32/SHGetIconOverlayIndexA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetIconOverlayIndexA,SHGetIconOverlayIndexA,514 diff --git a/libc/nt/shell32/SHGetNewLinkInfoA.s b/libc/nt/shell32/SHGetNewLinkInfoA.s deleted file mode 100644 index 4c42a6274..000000000 --- a/libc/nt/shell32/SHGetNewLinkInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetNewLinkInfoA,SHGetNewLinkInfoA,179 diff --git a/libc/nt/shell32/SHGetPathFromIDListA.s b/libc/nt/shell32/SHGetPathFromIDListA.s deleted file mode 100644 index 593cf4fa0..000000000 --- a/libc/nt/shell32/SHGetPathFromIDListA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetPathFromIDListA,SHGetPathFromIDListA,534 diff --git a/libc/nt/shell32/SHGetSpecialFolderPathA.s b/libc/nt/shell32/SHGetSpecialFolderPathA.s deleted file mode 100644 index 80876d1af..000000000 --- a/libc/nt/shell32/SHGetSpecialFolderPathA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHGetSpecialFolderPathA,SHGetSpecialFolderPathA,542 diff --git a/libc/nt/shell32/SHHelpShortcuts_RunDLLA.s b/libc/nt/shell32/SHHelpShortcuts_RunDLLA.s deleted file mode 100644 index 2f15a6695..000000000 --- a/libc/nt/shell32/SHHelpShortcuts_RunDLLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHHelpShortcuts_RunDLLA,SHHelpShortcuts_RunDLLA,229 diff --git a/libc/nt/shell32/SHInvokePrinterCommandA.s b/libc/nt/shell32/SHInvokePrinterCommandA.s deleted file mode 100644 index 453820326..000000000 --- a/libc/nt/shell32/SHInvokePrinterCommandA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHInvokePrinterCommandA,SHInvokePrinterCommandA,547 diff --git a/libc/nt/shell32/SHPathPrepareForWriteA.s b/libc/nt/shell32/SHPathPrepareForWriteA.s deleted file mode 100644 index b3c78ae7a..000000000 --- a/libc/nt/shell32/SHPathPrepareForWriteA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHPathPrepareForWriteA,SHPathPrepareForWriteA,555 diff --git a/libc/nt/shell32/SHQueryRecycleBinA.s b/libc/nt/shell32/SHQueryRecycleBinA.s deleted file mode 100644 index 99d5f6001..000000000 --- a/libc/nt/shell32/SHQueryRecycleBinA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHQueryRecycleBinA,SHQueryRecycleBinA,557 diff --git a/libc/nt/shell32/SHSetFolderPathA.s b/libc/nt/shell32/SHSetFolderPathA.s deleted file mode 100644 index a33397f76..000000000 --- a/libc/nt/shell32/SHSetFolderPathA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHSetFolderPathA,SHSetFolderPathA,231 diff --git a/libc/nt/shell32/SHUpdateImageA.s b/libc/nt/shell32/SHUpdateImageA.s deleted file mode 100644 index 98c7962ea..000000000 --- a/libc/nt/shell32/SHUpdateImageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SHUpdateImageA,SHUpdateImageA,191 diff --git a/libc/nt/shell32/SheChangeDirA.s b/libc/nt/shell32/SheChangeDirA.s deleted file mode 100644 index a3d2328db..000000000 --- a/libc/nt/shell32/SheChangeDirA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SheChangeDirA,SheChangeDirA,570 diff --git a/libc/nt/shell32/SheGetDirA.s b/libc/nt/shell32/SheGetDirA.s deleted file mode 100644 index 6ec00953e..000000000 --- a/libc/nt/shell32/SheGetDirA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_SheGetDirA,SheGetDirA,572 diff --git a/libc/nt/shell32/ShellAboutA.s b/libc/nt/shell32/ShellAboutA.s deleted file mode 100644 index bde321116..000000000 --- a/libc/nt/shell32/ShellAboutA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ShellAboutA,ShellAboutA,574 diff --git a/libc/nt/shell32/ShellExec_RunDLLA.s b/libc/nt/shell32/ShellExec_RunDLLA.s deleted file mode 100644 index 05a75b9dc..000000000 --- a/libc/nt/shell32/ShellExec_RunDLLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ShellExec_RunDLLA,ShellExec_RunDLLA,577 diff --git a/libc/nt/shell32/ShellExecuteA.s b/libc/nt/shell32/ShellExecuteA.s deleted file mode 100644 index 5fd2fd99c..000000000 --- a/libc/nt/shell32/ShellExecuteA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ShellExecuteA,ShellExecuteA,579 diff --git a/libc/nt/shell32/ShellExecuteExA.s b/libc/nt/shell32/ShellExecuteExA.s deleted file mode 100644 index 17f1404f9..000000000 --- a/libc/nt/shell32/ShellExecuteExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_ShellExecuteExA,ShellExecuteExA,581 diff --git a/libc/nt/shell32/Shell_GetCachedImageIndexA.s b/libc/nt/shell32/Shell_GetCachedImageIndexA.s deleted file mode 100644 index 2186828df..000000000 --- a/libc/nt/shell32/Shell_GetCachedImageIndexA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_Shell_GetCachedImageIndexA,Shell_GetCachedImageIndexA,585 diff --git a/libc/nt/shell32/Shell_NotifyIconA.s b/libc/nt/shell32/Shell_NotifyIconA.s deleted file mode 100644 index 06d9eaad6..000000000 --- a/libc/nt/shell32/Shell_NotifyIconA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_Shell_NotifyIconA,Shell_NotifyIconA,588 diff --git a/libc/nt/shell32/StrNCmpA.s b/libc/nt/shell32/StrNCmpA.s deleted file mode 100644 index 864500e1c..000000000 --- a/libc/nt/shell32/StrNCmpA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_StrNCmpA,StrNCmpA,599 diff --git a/libc/nt/shell32/StrNCmpIA.s b/libc/nt/shell32/StrNCmpIA.s deleted file mode 100644 index 50eea456b..000000000 --- a/libc/nt/shell32/StrNCmpIA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_StrNCmpIA,StrNCmpIA,600 diff --git a/libc/nt/shell32/StrNCmpIW.s b/libc/nt/shell32/StrNCmpIW.s deleted file mode 100644 index 0d88f8b9b..000000000 --- a/libc/nt/shell32/StrNCmpIW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_StrNCmpIW,StrNCmpIW,601 diff --git a/libc/nt/shell32/StrNCmpW.s b/libc/nt/shell32/StrNCmpW.s deleted file mode 100644 index 59c37dabf..000000000 --- a/libc/nt/shell32/StrNCmpW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_StrNCmpW,StrNCmpW,602 diff --git a/libc/nt/shell32/StrRStrA.s b/libc/nt/shell32/StrRStrA.s deleted file mode 100644 index 96fef5ab6..000000000 --- a/libc/nt/shell32/StrRStrA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_StrRStrA,StrRStrA,607 diff --git a/libc/nt/shell32/StrRStrW.s b/libc/nt/shell32/StrRStrW.s deleted file mode 100644 index b4ab46dbb..000000000 --- a/libc/nt/shell32/StrRStrW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp shell32,__imp_StrRStrW,StrRStrW,610 diff --git a/libc/nt/struct/linger.h b/libc/nt/struct/linger.h new file mode 100644 index 000000000..0267d205a --- /dev/null +++ b/libc/nt/struct/linger.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_LINGER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_LINGER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct linger_nt { + uint16_t l_onoff; /* on/off */ + uint16_t l_linger; /* seconds */ +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_LINGER_H_ */ diff --git a/libc/nt/struct/pdhfmtcountervalue.h b/libc/nt/struct/pdhfmtcountervalue.h new file mode 100644 index 000000000..644c98fb7 --- /dev/null +++ b/libc/nt/struct/pdhfmtcountervalue.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_PDHFMTCOUNTERVALUE_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_PDHFMTCOUNTERVALUE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtPdhFmtCountervalue { + uint32_t CStatus; + union { + int32_t longValue; + double doubleValue; + int64_t largeValue; + const char *AnsiStringValue; + const char16_t *WideStringValue; + }; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_PDHFMTCOUNTERVALUE_H_ */ diff --git a/libc/nt/struct/processmemorycounters.h b/libc/nt/struct/processmemorycounters.h new file mode 100644 index 000000000..43bad8814 --- /dev/null +++ b/libc/nt/struct/processmemorycounters.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSMEMORYCOUNTERS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSMEMORYCOUNTERS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtProcessMemoryCountersEx { + uint32_t cb; /* count bytes */ + uint32_t PageFaultCount; + uint64_t PeakWorkingSetSize; + uint64_t WorkingSetSize; + uint64_t QuotaPeakPagedPoolUsage; + uint64_t QuotaPagedPoolUsage; + uint64_t QuotaPeakNonPagedPoolUsage; + uint64_t QuotaNonPagedPoolUsage; + uint64_t PagefileUsage; + uint64_t PeakPagefileUsage; + uint64_t PrivateUsage; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSMEMORYCOUNTERS_H_ */ diff --git a/libc/nt/struct/teb.h b/libc/nt/struct/teb.h index cf1e7f008..23d4d9c16 100644 --- a/libc/nt/struct/teb.h +++ b/libc/nt/struct/teb.h @@ -21,7 +21,7 @@ #define _NtGetFib() gs((void **)(0x20)) #define _NtGetEnv() gs((char16_t **)(0x38)) #define _NtGetRpc() gs((void **)(0x50)) -#define _NtGetTls() gs((void **)(0x58)) +#define _NtGetTls() gs((void **)(0x58)) /* cf. gs((long *)0x1480 + i0..64) */ #endif /* __GNUC__ && !__STRICT_ANSI__ */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/nt/synchronization.h b/libc/nt/synchronization.h index ef11d095e..cdf052d95 100644 --- a/libc/nt/synchronization.h +++ b/libc/nt/synchronization.h @@ -5,6 +5,7 @@ #include "libc/nt/struct/linkedlist.h" #include "libc/nt/struct/securityattributes.h" #include "libc/nt/struct/systemtime.h" +#include "libc/nt/thunk/msabi.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ /* ░░░░ @@ -115,6 +116,9 @@ bool32 GetSystemTimeAdjustment(uint32_t *lpTimeAdjustment, uint32_t *lpTimeIncrement, bool32 *lpTimeAdjustmentDisabled); +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/synchronization.inc" +#endif /* ShouldUseMsabiAttribute() */ COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_NT_SYNCHRONIZATION_H_ */ diff --git a/libc/nt/thunk/accounting.inc b/libc/nt/thunk/accounting.inc index 860f1f14b..5c1bcbf64 100644 --- a/libc/nt/thunk/accounting.inc +++ b/libc/nt/thunk/accounting.inc @@ -6,6 +6,3 @@ extern typeof(GetThreadTimes) *const __imp_GetThreadTimes __msabi; #define GetUserName(...) __imp_GetUserNameW(__VA_ARGS__) extern typeof(GetUserName) *const __imp_GetUserNameW __msabi; - -#define GetExitCodeProcess(...) __imp_GetExitCodeProcess(__VA_ARGS__) -extern typeof(GetExitCodeProcess) *const __imp_GetExitCodeProcess __msabi; diff --git a/libc/nt/thunk/files.inc b/libc/nt/thunk/files.inc index ae316538f..4dc056500 100644 --- a/libc/nt/thunk/files.inc +++ b/libc/nt/thunk/files.inc @@ -1,8 +1,5 @@ #define CopyFile(...) __imp_CopyFileW(__VA_ARGS__) extern typeof(CopyFile) *const __imp_CopyFileW __msabi; -#define FlushFileBuffers(...) __imp_FlushFileBuffers(__VA_ARGS__) -extern typeof(FlushFileBuffers) *const __imp_FlushFileBuffers __msabi; - #define GetFileType(...) __imp_GetFileType(__VA_ARGS__) extern typeof(GetFileType) *const __imp_GetFileType __msabi; diff --git a/libc/nt/thunk/memory.inc b/libc/nt/thunk/memory.inc index fe36ff37b..e0abe9a71 100644 --- a/libc/nt/thunk/memory.inc +++ b/libc/nt/thunk/memory.inc @@ -1,10 +1 @@ -#define CreateFileMappingNuma(...) __imp_CreateFileMappingNumaW(__VA_ARGS__) -#define MapViewOfFileExNuma(...) __imp_MapViewOfFileExNuma(__VA_ARGS__) -#define FlushViewOfFile(...) __imp_FlushViewOfFile(__VA_ARGS__) -#define UnmapViewOfFile(...) __imp_UnmapViewOfFile(__VA_ARGS__) - -extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile __msabi; -extern typeof(FlushViewOfFile) *const __imp_FlushViewOfFile __msabi; -extern typeof(MapViewOfFileExNuma) *const __imp_MapViewOfFileExNuma __msabi; -extern typeof(CreateFileMappingNuma) *const - __imp_CreateFileMappingNumaW __msabi; +extern typeof(LocalFree) *const __imp_LocalFree __msabi; diff --git a/libc/nt/thunk/process.inc b/libc/nt/thunk/process.inc index e483b043e..e81ff9d66 100644 --- a/libc/nt/thunk/process.inc +++ b/libc/nt/thunk/process.inc @@ -15,5 +15,5 @@ extern typeof(SetPriorityClass) *const __imp_SetPriorityClass __msabi; #define GetCurrentProcessId(...) __imp_GetCurrentProcessId(__VA_ARGS__) extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId __msabi; -#define CreateProcess(...) __imp_CreateProcessW(__VA_ARGS__) -extern typeof(CreateProcess) *const __imp_CreateProcessW __msabi; +extern typeof(FormatMessage) *const __imp_FormatMessageW __msabi; +extern typeof(SetLastError) *const __imp_SetLastError __msabi; diff --git a/libc/nt/thunk/runtime.inc b/libc/nt/thunk/runtime.inc index dae9cc513..a389fa8d2 100644 --- a/libc/nt/thunk/runtime.inc +++ b/libc/nt/thunk/runtime.inc @@ -31,3 +31,6 @@ extern typeof(GetCurrentProcess) *const __imp_GetCurrentProcess __msabi; #define GetModuleFileName(...) __imp_GetModuleFileNameW(__VA_ARGS__) extern typeof(GetModuleFileName) *const __imp_GetModuleFileNameW __msabi; + +extern typeof(GetLastError) *const __imp_GetLastError __msabi; +extern typeof(ExitProcess) *const __imp_ExitProcess __msabi; diff --git a/libc/nt/thunk/synchronization.inc b/libc/nt/thunk/synchronization.inc new file mode 100644 index 000000000..fa73a16cd --- /dev/null +++ b/libc/nt/thunk/synchronization.inc @@ -0,0 +1 @@ +extern typeof(SleepEx) *const __imp_SleepEx __msabi; diff --git a/libc/nt/url/FileProtocolHandlerA.s b/libc/nt/url/FileProtocolHandlerA.s deleted file mode 100644 index 71e17f79e..000000000 --- a/libc/nt/url/FileProtocolHandlerA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp url,__imp_FileProtocolHandlerA,FileProtocolHandlerA,105 diff --git a/libc/nt/url/MIMEAssociationDialogA.s b/libc/nt/url/MIMEAssociationDialogA.s deleted file mode 100644 index ff082a453..000000000 --- a/libc/nt/url/MIMEAssociationDialogA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp url,__imp_MIMEAssociationDialogA,MIMEAssociationDialogA,107 diff --git a/libc/nt/url/MailToProtocolHandlerA.s b/libc/nt/url/MailToProtocolHandlerA.s deleted file mode 100644 index fdf10d149..000000000 --- a/libc/nt/url/MailToProtocolHandlerA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp url,__imp_MailToProtocolHandlerA,MailToProtocolHandlerA,110 diff --git a/libc/nt/url/OpenURLA.s b/libc/nt/url/OpenURLA.s deleted file mode 100644 index 361a716a5..000000000 --- a/libc/nt/url/OpenURLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp url,__imp_OpenURLA,OpenURLA,112 diff --git a/libc/nt/url/TelnetProtocolHandlerA.s b/libc/nt/url/TelnetProtocolHandlerA.s deleted file mode 100644 index a835cea8f..000000000 --- a/libc/nt/url/TelnetProtocolHandlerA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp url,__imp_TelnetProtocolHandlerA,TelnetProtocolHandlerA,114 diff --git a/libc/nt/url/TranslateURLA.s b/libc/nt/url/TranslateURLA.s deleted file mode 100644 index 9091728f0..000000000 --- a/libc/nt/url/TranslateURLA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp url,__imp_TranslateURLA,TranslateURLA,115 diff --git a/libc/nt/url/URLAssociationDialogA.s b/libc/nt/url/URLAssociationDialogA.s deleted file mode 100644 index 31aef3799..000000000 --- a/libc/nt/url/URLAssociationDialogA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp url,__imp_URLAssociationDialogA,URLAssociationDialogA,117 diff --git a/libc/nt/user32/BroadcastSystemMessageA.s b/libc/nt/user32/BroadcastSystemMessageA.s deleted file mode 100644 index 3952224cf..000000000 --- a/libc/nt/user32/BroadcastSystemMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_BroadcastSystemMessageA,BroadcastSystemMessageA,1525 diff --git a/libc/nt/user32/BroadcastSystemMessageExA.s b/libc/nt/user32/BroadcastSystemMessageExA.s deleted file mode 100644 index 52d3cb714..000000000 --- a/libc/nt/user32/BroadcastSystemMessageExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_BroadcastSystemMessageExA,BroadcastSystemMessageExA,1526 diff --git a/libc/nt/user32/CallMsgFilterA.s b/libc/nt/user32/CallMsgFilterA.s deleted file mode 100644 index 2db1621a0..000000000 --- a/libc/nt/user32/CallMsgFilterA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CallMsgFilterA,CallMsgFilterA,1533 diff --git a/libc/nt/user32/CallWindowProcA.s b/libc/nt/user32/CallWindowProcA.s deleted file mode 100644 index 316d1225a..000000000 --- a/libc/nt/user32/CallWindowProcA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CallWindowProcA,CallWindowProcA,1536 diff --git a/libc/nt/user32/ChangeDisplaySettingsA.s b/libc/nt/user32/ChangeDisplaySettingsA.s deleted file mode 100644 index 76ee2f26d..000000000 --- a/libc/nt/user32/ChangeDisplaySettingsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_ChangeDisplaySettingsA,ChangeDisplaySettingsA,1542 diff --git a/libc/nt/user32/ChangeDisplaySettingsExA.s b/libc/nt/user32/ChangeDisplaySettingsExA.s deleted file mode 100644 index 3b9b13893..000000000 --- a/libc/nt/user32/ChangeDisplaySettingsExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_ChangeDisplaySettingsExA,ChangeDisplaySettingsExA,1543 diff --git a/libc/nt/user32/ChangeMenuA.s b/libc/nt/user32/ChangeMenuA.s deleted file mode 100644 index 3df49bfe9..000000000 --- a/libc/nt/user32/ChangeMenuA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_ChangeMenuA,ChangeMenuA,1546 diff --git a/libc/nt/user32/CharToOemA.s b/libc/nt/user32/CharToOemA.s deleted file mode 100644 index 7518ac046..000000000 --- a/libc/nt/user32/CharToOemA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CharToOemA,CharToOemA,1565 diff --git a/libc/nt/user32/CharToOemBuffA.s b/libc/nt/user32/CharToOemBuffA.s deleted file mode 100644 index 19cc9eea9..000000000 --- a/libc/nt/user32/CharToOemBuffA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CharToOemBuffA,CharToOemBuffA,1566 diff --git a/libc/nt/user32/CopyAcceleratorTableA.s b/libc/nt/user32/CopyAcceleratorTableA.s deleted file mode 100644 index e38cd62de..000000000 --- a/libc/nt/user32/CopyAcceleratorTableA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CopyAcceleratorTableA,CopyAcceleratorTableA,1595 diff --git a/libc/nt/user32/CreateAcceleratorTableA.s b/libc/nt/user32/CreateAcceleratorTableA.s deleted file mode 100644 index 255ffe062..000000000 --- a/libc/nt/user32/CreateAcceleratorTableA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CreateAcceleratorTableA,CreateAcceleratorTableA,1601 diff --git a/libc/nt/user32/CreateDesktopA.s b/libc/nt/user32/CreateDesktopA.s deleted file mode 100644 index 09f7ec960..000000000 --- a/libc/nt/user32/CreateDesktopA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CreateDesktopA,CreateDesktopA,1606 diff --git a/libc/nt/user32/CreateDesktopExA.s b/libc/nt/user32/CreateDesktopExA.s deleted file mode 100644 index 824063afc..000000000 --- a/libc/nt/user32/CreateDesktopExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CreateDesktopExA,CreateDesktopExA,1607 diff --git a/libc/nt/user32/CreateDialogIndirectParamA.s b/libc/nt/user32/CreateDialogIndirectParamA.s deleted file mode 100644 index 37a4c7b5d..000000000 --- a/libc/nt/user32/CreateDialogIndirectParamA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CreateDialogIndirectParamA,CreateDialogIndirectParamA,1610 diff --git a/libc/nt/user32/CreateDialogParamA.s b/libc/nt/user32/CreateDialogParamA.s deleted file mode 100644 index 2d707f9b5..000000000 --- a/libc/nt/user32/CreateDialogParamA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CreateDialogParamA,CreateDialogParamA,1613 diff --git a/libc/nt/user32/CreateMDIWindowA.s b/libc/nt/user32/CreateMDIWindowA.s deleted file mode 100644 index 9933634b7..000000000 --- a/libc/nt/user32/CreateMDIWindowA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CreateMDIWindowA,CreateMDIWindowA,1619 diff --git a/libc/nt/user32/CreateWindowExA.s b/libc/nt/user32/CreateWindowExA.s deleted file mode 100644 index e02cd2d20..000000000 --- a/libc/nt/user32/CreateWindowExA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CreateWindowExA,CreateWindowExA,1624 - - .text.windows -CreateWindowExA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_CreateWindowExA(%rip),%rax - jmp __sysv2nt12 - .endfn CreateWindowExA,globl - .previous diff --git a/libc/nt/user32/CreateWindowStationA.s b/libc/nt/user32/CreateWindowStationA.s deleted file mode 100644 index 43ef77e12..000000000 --- a/libc/nt/user32/CreateWindowStationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_CreateWindowStationA,CreateWindowStationA,1629 diff --git a/libc/nt/user32/DdeCreateStringHandleA.s b/libc/nt/user32/DdeCreateStringHandleA.s deleted file mode 100644 index 58c7c08e7..000000000 --- a/libc/nt/user32/DdeCreateStringHandleA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DdeCreateStringHandleA,DdeCreateStringHandleA,1645 diff --git a/libc/nt/user32/DdeInitializeA.s b/libc/nt/user32/DdeInitializeA.s deleted file mode 100644 index 3223a7ead..000000000 --- a/libc/nt/user32/DdeInitializeA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DdeInitializeA,DdeInitializeA,1656 diff --git a/libc/nt/user32/DdeQueryStringA.s b/libc/nt/user32/DdeQueryStringA.s deleted file mode 100644 index 36619ce7c..000000000 --- a/libc/nt/user32/DdeQueryStringA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DdeQueryStringA,DdeQueryStringA,1663 diff --git a/libc/nt/user32/DefFrameProcA.s b/libc/nt/user32/DefFrameProcA.s deleted file mode 100644 index 965d84e7b..000000000 --- a/libc/nt/user32/DefFrameProcA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DefFrameProcA,DefFrameProcA,1672 diff --git a/libc/nt/user32/DefMDIChildProcA.s b/libc/nt/user32/DefMDIChildProcA.s deleted file mode 100644 index 4eeda69e7..000000000 --- a/libc/nt/user32/DefMDIChildProcA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DefMDIChildProcA,DefMDIChildProcA,1674 diff --git a/libc/nt/user32/DefWindowProcA.s b/libc/nt/user32/DefWindowProcA.s deleted file mode 100644 index 4ceb4441c..000000000 --- a/libc/nt/user32/DefWindowProcA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DefWindowProcA,DefWindowProcA,173 - - .text.windows -DefWindowProcA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_DefWindowProcA(%rip),%rax - jmp __sysv2nt - .endfn DefWindowProcA,globl - .previous diff --git a/libc/nt/user32/DialogBoxIndirectParamA.s b/libc/nt/user32/DialogBoxIndirectParamA.s deleted file mode 100644 index 3be9d925f..000000000 --- a/libc/nt/user32/DialogBoxIndirectParamA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DialogBoxIndirectParamA,DialogBoxIndirectParamA,1691 diff --git a/libc/nt/user32/DialogBoxParamA.s b/libc/nt/user32/DialogBoxParamA.s deleted file mode 100644 index 9b2a446d4..000000000 --- a/libc/nt/user32/DialogBoxParamA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DialogBoxParamA,DialogBoxParamA,1694 diff --git a/libc/nt/user32/DispatchMessageA.s b/libc/nt/user32/DispatchMessageA.s deleted file mode 100644 index 1d4aa7acd..000000000 --- a/libc/nt/user32/DispatchMessageA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DispatchMessageA,DispatchMessageA,1697 - - .text.windows -DispatchMessageA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_DispatchMessageA(%rip) - leave - ret - .endfn DispatchMessageA,globl - .previous diff --git a/libc/nt/user32/DlgDirListA.s b/libc/nt/user32/DlgDirListA.s deleted file mode 100644 index 32988e34e..000000000 --- a/libc/nt/user32/DlgDirListA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DlgDirListA,DlgDirListA,1702 diff --git a/libc/nt/user32/DlgDirListComboBoxA.s b/libc/nt/user32/DlgDirListComboBoxA.s deleted file mode 100644 index f984f53da..000000000 --- a/libc/nt/user32/DlgDirListComboBoxA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DlgDirListComboBoxA,DlgDirListComboBoxA,1703 diff --git a/libc/nt/user32/DlgDirSelectComboBoxExA.s b/libc/nt/user32/DlgDirSelectComboBoxExA.s deleted file mode 100644 index eac68f1d4..000000000 --- a/libc/nt/user32/DlgDirSelectComboBoxExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DlgDirSelectComboBoxExA,DlgDirSelectComboBoxExA,1706 diff --git a/libc/nt/user32/DlgDirSelectExA.s b/libc/nt/user32/DlgDirSelectExA.s deleted file mode 100644 index ec1720753..000000000 --- a/libc/nt/user32/DlgDirSelectExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DlgDirSelectExA,DlgDirSelectExA,1708 diff --git a/libc/nt/user32/DrawCaptionTempA.s b/libc/nt/user32/DrawCaptionTempA.s deleted file mode 100644 index d29688aaf..000000000 --- a/libc/nt/user32/DrawCaptionTempA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DrawCaptionTempA,DrawCaptionTempA,1716 diff --git a/libc/nt/user32/DrawStateA.s b/libc/nt/user32/DrawStateA.s deleted file mode 100644 index a14d02b84..000000000 --- a/libc/nt/user32/DrawStateA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DrawStateA,DrawStateA,1726 diff --git a/libc/nt/user32/DrawTextA.s b/libc/nt/user32/DrawTextA.s deleted file mode 100644 index ee7f93b43..000000000 --- a/libc/nt/user32/DrawTextA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DrawTextA,DrawTextA,1728 - - .text.windows -DrawTextA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_DrawTextA(%rip),%rax - jmp __sysv2nt6 - .endfn DrawTextA,globl - .previous diff --git a/libc/nt/user32/DrawTextExA.s b/libc/nt/user32/DrawTextExA.s deleted file mode 100644 index 8dc9af149..000000000 --- a/libc/nt/user32/DrawTextExA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_DrawTextExA,DrawTextExA,1729 - - .text.windows -DrawTextExA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_DrawTextExA(%rip),%rax - jmp __sysv2nt6 - .endfn DrawTextExA,globl - .previous diff --git a/libc/nt/user32/EmptyClipboard.s b/libc/nt/user32/EmptyClipboard.s index d01c76c20..8de1b75c4 100644 --- a/libc/nt/user32/EmptyClipboard.s +++ b/libc/nt/user32/EmptyClipboard.s @@ -1,2 +1,2 @@ .include "o/libc/nt/codegen.inc" -.imp user32,__imp_EmptyClipboard,EmptyClipboard,1740 +.imp user32,__imp_EmptyClipboard,EmptyClipboard,1704 diff --git a/libc/nt/user32/EnumDesktopsA.s b/libc/nt/user32/EnumDesktopsA.s deleted file mode 100644 index 4ec65d1e5..000000000 --- a/libc/nt/user32/EnumDesktopsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_EnumDesktopsA,EnumDesktopsA,1758 diff --git a/libc/nt/user32/EnumDisplayDevicesA.s b/libc/nt/user32/EnumDisplayDevicesA.s deleted file mode 100644 index 83feba45e..000000000 --- a/libc/nt/user32/EnumDisplayDevicesA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_EnumDisplayDevicesA,EnumDisplayDevicesA,1760 diff --git a/libc/nt/user32/EnumDisplaySettingsA.s b/libc/nt/user32/EnumDisplaySettingsA.s deleted file mode 100644 index 736878de8..000000000 --- a/libc/nt/user32/EnumDisplaySettingsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_EnumDisplaySettingsA,EnumDisplaySettingsA,1763 diff --git a/libc/nt/user32/EnumDisplaySettingsExA.s b/libc/nt/user32/EnumDisplaySettingsExA.s deleted file mode 100644 index bb73928fa..000000000 --- a/libc/nt/user32/EnumDisplaySettingsExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_EnumDisplaySettingsExA,EnumDisplaySettingsExA,1764 diff --git a/libc/nt/user32/EnumPropsA.s b/libc/nt/user32/EnumPropsA.s deleted file mode 100644 index 0996a54f2..000000000 --- a/libc/nt/user32/EnumPropsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_EnumPropsA,EnumPropsA,1767 diff --git a/libc/nt/user32/EnumPropsExA.s b/libc/nt/user32/EnumPropsExA.s deleted file mode 100644 index 4aae02d2e..000000000 --- a/libc/nt/user32/EnumPropsExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_EnumPropsExA,EnumPropsExA,1768 diff --git a/libc/nt/user32/EnumWindowStationsA.s b/libc/nt/user32/EnumWindowStationsA.s deleted file mode 100644 index 3a87274f6..000000000 --- a/libc/nt/user32/EnumWindowStationsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_EnumWindowStationsA,EnumWindowStationsA,1772 diff --git a/libc/nt/user32/FindWindowA.s b/libc/nt/user32/FindWindowA.s deleted file mode 100644 index 982cd56ad..000000000 --- a/libc/nt/user32/FindWindowA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_FindWindowA,FindWindowA,1781 - - .text.windows -FindWindowA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_FindWindowA(%rip),%rax - jmp __sysv2nt - .endfn FindWindowA,globl - .previous diff --git a/libc/nt/user32/FindWindowExA.s b/libc/nt/user32/FindWindowExA.s deleted file mode 100644 index ae2a6e7b0..000000000 --- a/libc/nt/user32/FindWindowExA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_FindWindowExA,FindWindowExA,1782 - - .text.windows -FindWindowExA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_FindWindowExA(%rip),%rax - jmp __sysv2nt - .endfn FindWindowExA,globl - .previous diff --git a/libc/nt/user32/GetAltTabInfoA.s b/libc/nt/user32/GetAltTabInfoA.s deleted file mode 100644 index 0d6897d1e..000000000 --- a/libc/nt/user32/GetAltTabInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetAltTabInfoA,GetAltTabInfoA,1792 diff --git a/libc/nt/user32/GetClassInfoA.s b/libc/nt/user32/GetClassInfoA.s deleted file mode 100644 index c86e42540..000000000 --- a/libc/nt/user32/GetClassInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetClassInfoA,GetClassInfoA,1804 diff --git a/libc/nt/user32/GetClassInfoExA.s b/libc/nt/user32/GetClassInfoExA.s deleted file mode 100644 index 095c43482..000000000 --- a/libc/nt/user32/GetClassInfoExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetClassInfoExA,GetClassInfoExA,1805 diff --git a/libc/nt/user32/GetClassLongA.s b/libc/nt/user32/GetClassLongA.s deleted file mode 100644 index 25b41e6db..000000000 --- a/libc/nt/user32/GetClassLongA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetClassLongA,GetClassLongA,1808 diff --git a/libc/nt/user32/GetClassLongPtrA.s b/libc/nt/user32/GetClassLongPtrA.s deleted file mode 100644 index f41e1fba3..000000000 --- a/libc/nt/user32/GetClassLongPtrA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetClassLongPtrA,GetClassLongPtrA,1809 diff --git a/libc/nt/user32/GetClassNameA.s b/libc/nt/user32/GetClassNameA.s deleted file mode 100644 index 943fc0b23..000000000 --- a/libc/nt/user32/GetClassNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetClassNameA,GetClassNameA,1812 diff --git a/libc/nt/user32/GetClipboardFormatNameA.s b/libc/nt/user32/GetClipboardFormatNameA.s deleted file mode 100644 index 7689d217b..000000000 --- a/libc/nt/user32/GetClipboardFormatNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetClipboardFormatNameA,GetClipboardFormatNameA,1819 diff --git a/libc/nt/user32/GetDlgItemTextA.s b/libc/nt/user32/GetDlgItemTextA.s deleted file mode 100644 index 3f855f89e..000000000 --- a/libc/nt/user32/GetDlgItemTextA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetDlgItemTextA,GetDlgItemTextA,1842 diff --git a/libc/nt/user32/GetIconInfoExA.s b/libc/nt/user32/GetIconInfoExA.s deleted file mode 100644 index ded0bdf05..000000000 --- a/libc/nt/user32/GetIconInfoExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetIconInfoExA,GetIconInfoExA,1857 diff --git a/libc/nt/user32/GetKeyNameTextA.s b/libc/nt/user32/GetKeyNameTextA.s deleted file mode 100644 index 5956b01a1..000000000 --- a/libc/nt/user32/GetKeyNameTextA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetKeyNameTextA,GetKeyNameTextA,1864 diff --git a/libc/nt/user32/GetKeyboardLayoutNameA.s b/libc/nt/user32/GetKeyboardLayoutNameA.s deleted file mode 100644 index 1b35ac950..000000000 --- a/libc/nt/user32/GetKeyboardLayoutNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetKeyboardLayoutNameA,GetKeyboardLayoutNameA,1869 diff --git a/libc/nt/user32/GetMenuItemInfoA.s b/libc/nt/user32/GetMenuItemInfoA.s deleted file mode 100644 index 3fe0f2a41..000000000 --- a/libc/nt/user32/GetMenuItemInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetMenuItemInfoA,GetMenuItemInfoA,1889 diff --git a/libc/nt/user32/GetMenuStringA.s b/libc/nt/user32/GetMenuStringA.s deleted file mode 100644 index 1f1148d9f..000000000 --- a/libc/nt/user32/GetMenuStringA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetMenuStringA,GetMenuStringA,1893 diff --git a/libc/nt/user32/GetMessageA.s b/libc/nt/user32/GetMessageA.s deleted file mode 100644 index cbf3670d4..000000000 --- a/libc/nt/user32/GetMessageA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetMessageA,GetMessageA,1895 - - .text.windows -GetMessageA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_GetMessageA(%rip),%rax - jmp __sysv2nt - .endfn GetMessageA,globl - .previous diff --git a/libc/nt/user32/GetMonitorInfoA.s b/libc/nt/user32/GetMonitorInfoA.s deleted file mode 100644 index 402b47df0..000000000 --- a/libc/nt/user32/GetMonitorInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetMonitorInfoA,GetMonitorInfoA,1900 diff --git a/libc/nt/user32/GetPropA.s b/libc/nt/user32/GetPropA.s deleted file mode 100644 index 207e1118d..000000000 --- a/libc/nt/user32/GetPropA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetPropA,GetPropA,1934 diff --git a/libc/nt/user32/GetRawInputDeviceInfoA.s b/libc/nt/user32/GetRawInputDeviceInfoA.s deleted file mode 100644 index 6e6770e8d..000000000 --- a/libc/nt/user32/GetRawInputDeviceInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetRawInputDeviceInfoA,GetRawInputDeviceInfoA,1939 diff --git a/libc/nt/user32/GetTabbedTextExtentA.s b/libc/nt/user32/GetTabbedTextExtentA.s deleted file mode 100644 index ff42066e8..000000000 --- a/libc/nt/user32/GetTabbedTextExtentA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetTabbedTextExtentA,GetTabbedTextExtentA,1958 diff --git a/libc/nt/user32/GetUserObjectInformationA.s b/libc/nt/user32/GetUserObjectInformationA.s deleted file mode 100644 index c448503cb..000000000 --- a/libc/nt/user32/GetUserObjectInformationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetUserObjectInformationA,GetUserObjectInformationA,1972 diff --git a/libc/nt/user32/GetWindowLongA.s b/libc/nt/user32/GetWindowLongA.s deleted file mode 100644 index 66f0c8128..000000000 --- a/libc/nt/user32/GetWindowLongA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetWindowLongA,GetWindowLongA,1987 diff --git a/libc/nt/user32/GetWindowLongPtrA.s b/libc/nt/user32/GetWindowLongPtrA.s deleted file mode 100644 index 44fb0a810..000000000 --- a/libc/nt/user32/GetWindowLongPtrA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetWindowLongPtrA,GetWindowLongPtrA,1988 diff --git a/libc/nt/user32/GetWindowModuleFileNameA.s b/libc/nt/user32/GetWindowModuleFileNameA.s deleted file mode 100644 index f9f5c543f..000000000 --- a/libc/nt/user32/GetWindowModuleFileNameA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetWindowModuleFileNameA,GetWindowModuleFileNameA,1993 diff --git a/libc/nt/user32/GetWindowTextA.s b/libc/nt/user32/GetWindowTextA.s deleted file mode 100644 index 65af805bd..000000000 --- a/libc/nt/user32/GetWindowTextA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetWindowTextA,GetWindowTextA,2003 - - .text.windows -GetWindowTextA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_GetWindowTextA(%rip),%rax - jmp __sysv2nt - .endfn GetWindowTextA,globl - .previous diff --git a/libc/nt/user32/GetWindowTextLengthA.s b/libc/nt/user32/GetWindowTextLengthA.s deleted file mode 100644 index 06dd3bb75..000000000 --- a/libc/nt/user32/GetWindowTextLengthA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GetWindowTextLengthA,GetWindowTextLengthA,2004 diff --git a/libc/nt/user32/GrayStringA.s b/libc/nt/user32/GrayStringA.s deleted file mode 100644 index 8cb2581ba..000000000 --- a/libc/nt/user32/GrayStringA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_GrayStringA,GrayStringA,2012 diff --git a/libc/nt/user32/IMPGetIMEA.s b/libc/nt/user32/IMPGetIMEA.s deleted file mode 100644 index 6fd07d267..000000000 --- a/libc/nt/user32/IMPGetIMEA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_IMPGetIMEA,IMPGetIMEA,2017 diff --git a/libc/nt/user32/IMPQueryIMEA.s b/libc/nt/user32/IMPQueryIMEA.s deleted file mode 100644 index e8669606c..000000000 --- a/libc/nt/user32/IMPQueryIMEA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_IMPQueryIMEA,IMPQueryIMEA,2019 diff --git a/libc/nt/user32/IMPSetIMEA.s b/libc/nt/user32/IMPSetIMEA.s deleted file mode 100644 index 336874340..000000000 --- a/libc/nt/user32/IMPSetIMEA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_IMPSetIMEA,IMPSetIMEA,2021 diff --git a/libc/nt/user32/InsertMenuA.s b/libc/nt/user32/InsertMenuA.s deleted file mode 100644 index 755310c94..000000000 --- a/libc/nt/user32/InsertMenuA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_InsertMenuA,InsertMenuA,2041 - - .text.windows -InsertMenuA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_InsertMenuA(%rip),%rax - jmp __sysv2nt6 - .endfn InsertMenuA,globl - .previous diff --git a/libc/nt/user32/InsertMenuItemA.s b/libc/nt/user32/InsertMenuItemA.s deleted file mode 100644 index 68c019baa..000000000 --- a/libc/nt/user32/InsertMenuItemA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_InsertMenuItemA,InsertMenuItemA,2042 diff --git a/libc/nt/user32/IsDialogMessageA.s b/libc/nt/user32/IsDialogMessageA.s deleted file mode 100644 index b79356464..000000000 --- a/libc/nt/user32/IsDialogMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_IsDialogMessageA,IsDialogMessageA,2062 diff --git a/libc/nt/user32/LoadAcceleratorsA.s b/libc/nt/user32/LoadAcceleratorsA.s deleted file mode 100644 index e91c26781..000000000 --- a/libc/nt/user32/LoadAcceleratorsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadAcceleratorsA,LoadAcceleratorsA,2094 diff --git a/libc/nt/user32/LoadBitmapA.s b/libc/nt/user32/LoadBitmapA.s deleted file mode 100644 index 944927ff0..000000000 --- a/libc/nt/user32/LoadBitmapA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadBitmapA,LoadBitmapA,2096 diff --git a/libc/nt/user32/LoadCursorA.s b/libc/nt/user32/LoadCursorA.s deleted file mode 100644 index 2be2ab678..000000000 --- a/libc/nt/user32/LoadCursorA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadCursorA,LoadCursorA,2098 - - .text.windows -LoadCursorA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_LoadCursorA(%rip),%rax - jmp __sysv2nt - .endfn LoadCursorA,globl - .previous diff --git a/libc/nt/user32/LoadCursorFromFileA.s b/libc/nt/user32/LoadCursorFromFileA.s deleted file mode 100644 index ba1c2274c..000000000 --- a/libc/nt/user32/LoadCursorFromFileA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadCursorFromFileA,LoadCursorFromFileA,2099 diff --git a/libc/nt/user32/LoadIconA.s b/libc/nt/user32/LoadIconA.s deleted file mode 100644 index abe4c4a92..000000000 --- a/libc/nt/user32/LoadIconA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadIconA,LoadIconA,2102 - - .text.windows -LoadIconA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_LoadIconA(%rip),%rax - jmp __sysv2nt - .endfn LoadIconA,globl - .previous diff --git a/libc/nt/user32/LoadImageA.s b/libc/nt/user32/LoadImageA.s deleted file mode 100644 index 9a7767a18..000000000 --- a/libc/nt/user32/LoadImageA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadImageA,LoadImageA,2104 - - .text.windows -LoadImageA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_LoadImageA(%rip),%rax - jmp __sysv2nt6 - .endfn LoadImageA,globl - .previous diff --git a/libc/nt/user32/LoadKeyboardLayoutA.s b/libc/nt/user32/LoadKeyboardLayoutA.s deleted file mode 100644 index 167913ac8..000000000 --- a/libc/nt/user32/LoadKeyboardLayoutA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadKeyboardLayoutA,LoadKeyboardLayoutA,2106 diff --git a/libc/nt/user32/LoadMenuA.s b/libc/nt/user32/LoadMenuA.s deleted file mode 100644 index b13133c8b..000000000 --- a/libc/nt/user32/LoadMenuA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadMenuA,LoadMenuA,2110 diff --git a/libc/nt/user32/LoadMenuIndirectA.s b/libc/nt/user32/LoadMenuIndirectA.s deleted file mode 100644 index dca707221..000000000 --- a/libc/nt/user32/LoadMenuIndirectA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_LoadMenuIndirectA,LoadMenuIndirectA,2111 diff --git a/libc/nt/user32/MapVirtualKeyA.s b/libc/nt/user32/MapVirtualKeyA.s deleted file mode 100644 index 7162c7a00..000000000 --- a/libc/nt/user32/MapVirtualKeyA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_MapVirtualKeyA,MapVirtualKeyA,2153 diff --git a/libc/nt/user32/MapVirtualKeyExA.s b/libc/nt/user32/MapVirtualKeyExA.s deleted file mode 100644 index 1a997fd56..000000000 --- a/libc/nt/user32/MapVirtualKeyExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_MapVirtualKeyExA,MapVirtualKeyExA,2154 diff --git a/libc/nt/user32/MenuWindowProcA.s b/libc/nt/user32/MenuWindowProcA.s deleted file mode 100644 index 059f3b338..000000000 --- a/libc/nt/user32/MenuWindowProcA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_MenuWindowProcA,MenuWindowProcA,2160 diff --git a/libc/nt/user32/MessageBoxA.s b/libc/nt/user32/MessageBoxA.s deleted file mode 100644 index e79836144..000000000 --- a/libc/nt/user32/MessageBoxA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_MessageBoxA,MessageBoxA,2163 - - .text.windows -MessageBoxA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_MessageBoxA(%rip),%rax - jmp __sysv2nt - .endfn MessageBoxA,globl - .previous diff --git a/libc/nt/user32/MessageBoxExA.s b/libc/nt/user32/MessageBoxExA.s deleted file mode 100644 index 0cd8e4fce..000000000 --- a/libc/nt/user32/MessageBoxExA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_MessageBoxExA,MessageBoxExA,2164 - - .text.windows -MessageBoxExA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_MessageBoxExA(%rip),%rax - jmp __sysv2nt6 - .endfn MessageBoxExA,globl - .previous diff --git a/libc/nt/user32/MessageBoxIndirectA.s b/libc/nt/user32/MessageBoxIndirectA.s deleted file mode 100644 index 6df3b5565..000000000 --- a/libc/nt/user32/MessageBoxIndirectA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_MessageBoxIndirectA,MessageBoxIndirectA,2166 diff --git a/libc/nt/user32/MessageBoxTimeoutA.s b/libc/nt/user32/MessageBoxTimeoutA.s deleted file mode 100644 index 6ee565367..000000000 --- a/libc/nt/user32/MessageBoxTimeoutA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_MessageBoxTimeoutA,MessageBoxTimeoutA,2168 diff --git a/libc/nt/user32/ModifyMenuA.s b/libc/nt/user32/ModifyMenuA.s deleted file mode 100644 index 6dd007ab0..000000000 --- a/libc/nt/user32/ModifyMenuA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_ModifyMenuA,ModifyMenuA,2171 diff --git a/libc/nt/user32/OemToCharA.s b/libc/nt/user32/OemToCharA.s deleted file mode 100644 index e68750bdc..000000000 --- a/libc/nt/user32/OemToCharA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_OemToCharA,OemToCharA,2182 diff --git a/libc/nt/user32/OemToCharBuffA.s b/libc/nt/user32/OemToCharBuffA.s deleted file mode 100644 index bac11de99..000000000 --- a/libc/nt/user32/OemToCharBuffA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_OemToCharBuffA,OemToCharBuffA,2183 diff --git a/libc/nt/user32/OpenDesktopA.s b/libc/nt/user32/OpenDesktopA.s deleted file mode 100644 index 81be7999c..000000000 --- a/libc/nt/user32/OpenDesktopA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_OpenDesktopA,OpenDesktopA,2188 diff --git a/libc/nt/user32/OpenWindowStationA.s b/libc/nt/user32/OpenWindowStationA.s deleted file mode 100644 index b5d7c051d..000000000 --- a/libc/nt/user32/OpenWindowStationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_OpenWindowStationA,OpenWindowStationA,2193 diff --git a/libc/nt/user32/PeekMessageA.s b/libc/nt/user32/PeekMessageA.s deleted file mode 100644 index 869dff5ac..000000000 --- a/libc/nt/user32/PeekMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_PeekMessageA,PeekMessageA,2200 diff --git a/libc/nt/user32/PostMessageA.s b/libc/nt/user32/PostMessageA.s deleted file mode 100644 index 2cef48871..000000000 --- a/libc/nt/user32/PostMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_PostMessageA,PostMessageA,2204 diff --git a/libc/nt/user32/PostThreadMessageA.s b/libc/nt/user32/PostThreadMessageA.s deleted file mode 100644 index 3ec4102d3..000000000 --- a/libc/nt/user32/PostThreadMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_PostThreadMessageA,PostThreadMessageA,2207 diff --git a/libc/nt/user32/PrivateExtractIconExA.s b/libc/nt/user32/PrivateExtractIconExA.s deleted file mode 100644 index c549eb7ea..000000000 --- a/libc/nt/user32/PrivateExtractIconExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_PrivateExtractIconExA,PrivateExtractIconExA,2210 diff --git a/libc/nt/user32/PrivateExtractIconsA.s b/libc/nt/user32/PrivateExtractIconsA.s deleted file mode 100644 index 39c48fd00..000000000 --- a/libc/nt/user32/PrivateExtractIconsA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_PrivateExtractIconsA,PrivateExtractIconsA,2212 diff --git a/libc/nt/user32/RealGetWindowClassA.s b/libc/nt/user32/RealGetWindowClassA.s deleted file mode 100644 index 695483e15..000000000 --- a/libc/nt/user32/RealGetWindowClassA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_RealGetWindowClassA,RealGetWindowClassA,2241 diff --git a/libc/nt/user32/RegisterClassA.s b/libc/nt/user32/RegisterClassA.s deleted file mode 100644 index 3303a552c..000000000 --- a/libc/nt/user32/RegisterClassA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_RegisterClassA,RegisterClassA,2248 - - .text.windows -RegisterClassA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_RegisterClassA(%rip) - leave - ret - .endfn RegisterClassA,globl - .previous diff --git a/libc/nt/user32/RegisterClassExA.s b/libc/nt/user32/RegisterClassExA.s deleted file mode 100644 index 8ba6005f3..000000000 --- a/libc/nt/user32/RegisterClassExA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_RegisterClassExA,RegisterClassExA,2249 - - .text.windows -RegisterClassExA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_RegisterClassExA(%rip) - leave - ret - .endfn RegisterClassExA,globl - .previous diff --git a/libc/nt/user32/RegisterClipboardFormatA.s b/libc/nt/user32/RegisterClipboardFormatA.s deleted file mode 100644 index df44dc3c1..000000000 --- a/libc/nt/user32/RegisterClipboardFormatA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_RegisterClipboardFormatA,RegisterClipboardFormatA,2252 diff --git a/libc/nt/user32/RegisterDeviceNotificationA.s b/libc/nt/user32/RegisterDeviceNotificationA.s deleted file mode 100644 index 4e8dab326..000000000 --- a/libc/nt/user32/RegisterDeviceNotificationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_RegisterDeviceNotificationA,RegisterDeviceNotificationA,2255 diff --git a/libc/nt/user32/RegisterWindowMessageA.s b/libc/nt/user32/RegisterWindowMessageA.s deleted file mode 100644 index a7520a4e8..000000000 --- a/libc/nt/user32/RegisterWindowMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_RegisterWindowMessageA,RegisterWindowMessageA,2277 diff --git a/libc/nt/user32/RemovePropA.s b/libc/nt/user32/RemovePropA.s deleted file mode 100644 index 9feb0631f..000000000 --- a/libc/nt/user32/RemovePropA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_RemovePropA,RemovePropA,2285 diff --git a/libc/nt/user32/SendDlgItemMessageA.s b/libc/nt/user32/SendDlgItemMessageA.s deleted file mode 100644 index 0365be78e..000000000 --- a/libc/nt/user32/SendDlgItemMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SendDlgItemMessageA,SendDlgItemMessageA,2296 diff --git a/libc/nt/user32/SendIMEMessageExA.s b/libc/nt/user32/SendIMEMessageExA.s deleted file mode 100644 index a9432360e..000000000 --- a/libc/nt/user32/SendIMEMessageExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SendIMEMessageExA,SendIMEMessageExA,2298 diff --git a/libc/nt/user32/SendMessageA.s b/libc/nt/user32/SendMessageA.s deleted file mode 100644 index d854968fc..000000000 --- a/libc/nt/user32/SendMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SendMessageA,SendMessageA,2301 diff --git a/libc/nt/user32/SendMessageCallbackA.s b/libc/nt/user32/SendMessageCallbackA.s deleted file mode 100644 index 83d7c30ab..000000000 --- a/libc/nt/user32/SendMessageCallbackA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SendMessageCallbackA,SendMessageCallbackA,2302 diff --git a/libc/nt/user32/SendMessageTimeoutA.s b/libc/nt/user32/SendMessageTimeoutA.s deleted file mode 100644 index 01d07bd1a..000000000 --- a/libc/nt/user32/SendMessageTimeoutA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SendMessageTimeoutA,SendMessageTimeoutA,2304 diff --git a/libc/nt/user32/SendNotifyMessageA.s b/libc/nt/user32/SendNotifyMessageA.s deleted file mode 100644 index d760ff4bb..000000000 --- a/libc/nt/user32/SendNotifyMessageA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SendNotifyMessageA,SendNotifyMessageA,2307 diff --git a/libc/nt/user32/SetClassLongA.s b/libc/nt/user32/SetClassLongA.s deleted file mode 100644 index 6df2f777c..000000000 --- a/libc/nt/user32/SetClassLongA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetClassLongA,SetClassLongA,2313 - - .text.windows -SetClassLongA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_SetClassLongA(%rip),%rax - jmp __sysv2nt - .endfn SetClassLongA,globl - .previous diff --git a/libc/nt/user32/SetClassLongPtrA.s b/libc/nt/user32/SetClassLongPtrA.s deleted file mode 100644 index 94b92806d..000000000 --- a/libc/nt/user32/SetClassLongPtrA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetClassLongPtrA,SetClassLongPtrA,2314 diff --git a/libc/nt/user32/SetDlgItemTextA.s b/libc/nt/user32/SetDlgItemTextA.s deleted file mode 100644 index b5c158d56..000000000 --- a/libc/nt/user32/SetDlgItemTextA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetDlgItemTextA,SetDlgItemTextA,2332 diff --git a/libc/nt/user32/SetMenuItemInfoA.s b/libc/nt/user32/SetMenuItemInfoA.s deleted file mode 100644 index 322079191..000000000 --- a/libc/nt/user32/SetMenuItemInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetMenuItemInfoA,SetMenuItemInfoA,2352 diff --git a/libc/nt/user32/SetPropA.s b/libc/nt/user32/SetPropA.s deleted file mode 100644 index 445f16e43..000000000 --- a/libc/nt/user32/SetPropA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetPropA,SetPropA,2366 diff --git a/libc/nt/user32/SetUserObjectInformationA.s b/libc/nt/user32/SetUserObjectInformationA.s deleted file mode 100644 index 6ec7b556c..000000000 --- a/libc/nt/user32/SetUserObjectInformationA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetUserObjectInformationA,SetUserObjectInformationA,2385 diff --git a/libc/nt/user32/SetWindowLongA.s b/libc/nt/user32/SetWindowLongA.s deleted file mode 100644 index 28deade3a..000000000 --- a/libc/nt/user32/SetWindowLongA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetWindowLongA,SetWindowLongA,2395 diff --git a/libc/nt/user32/SetWindowLongPtrA.s b/libc/nt/user32/SetWindowLongPtrA.s deleted file mode 100644 index 252441d84..000000000 --- a/libc/nt/user32/SetWindowLongPtrA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetWindowLongPtrA,SetWindowLongPtrA,2396 diff --git a/libc/nt/user32/SetWindowTextA.s b/libc/nt/user32/SetWindowTextA.s deleted file mode 100644 index b5c4040b4..000000000 --- a/libc/nt/user32/SetWindowTextA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetWindowTextA,SetWindowTextA,2404 - - .text.windows -SetWindowTextA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_SetWindowTextA(%rip),%rax - jmp __sysv2nt - .endfn SetWindowTextA,globl - .previous diff --git a/libc/nt/user32/SetWindowsHookA.s b/libc/nt/user32/SetWindowsHookA.s deleted file mode 100644 index 37ca05f8f..000000000 --- a/libc/nt/user32/SetWindowsHookA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetWindowsHookA,SetWindowsHookA,2407 - - .text.windows -SetWindowsHookA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_SetWindowsHookA(%rip),%rax - jmp __sysv2nt - .endfn SetWindowsHookA,globl - .previous diff --git a/libc/nt/user32/SetWindowsHookExA.s b/libc/nt/user32/SetWindowsHookExA.s deleted file mode 100644 index 21b73239e..000000000 --- a/libc/nt/user32/SetWindowsHookExA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SetWindowsHookExA,SetWindowsHookExA,2408 - - .text.windows -SetWindowsHookExA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_SetWindowsHookExA(%rip),%rax - jmp __sysv2nt - .endfn SetWindowsHookExA,globl - .previous diff --git a/libc/nt/user32/SystemParametersInfoA.s b/libc/nt/user32/SystemParametersInfoA.s deleted file mode 100644 index 2dab6d656..000000000 --- a/libc/nt/user32/SystemParametersInfoA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_SystemParametersInfoA,SystemParametersInfoA,2431 diff --git a/libc/nt/user32/TabbedTextOutA.s b/libc/nt/user32/TabbedTextOutA.s deleted file mode 100644 index 65f70b2f0..000000000 --- a/libc/nt/user32/TabbedTextOutA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_TabbedTextOutA,TabbedTextOutA,2434 diff --git a/libc/nt/user32/TranslateAcceleratorA.s b/libc/nt/user32/TranslateAcceleratorA.s deleted file mode 100644 index 894e28085..000000000 --- a/libc/nt/user32/TranslateAcceleratorA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_TranslateAcceleratorA,TranslateAcceleratorA,2446 diff --git a/libc/nt/user32/UnregisterClassA.s b/libc/nt/user32/UnregisterClassA.s deleted file mode 100644 index ae91b90c0..000000000 --- a/libc/nt/user32/UnregisterClassA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_UnregisterClassA,UnregisterClassA,2458 diff --git a/libc/nt/user32/VkKeyScanA.s b/libc/nt/user32/VkKeyScanA.s deleted file mode 100644 index 80f92a961..000000000 --- a/libc/nt/user32/VkKeyScanA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_VkKeyScanA,VkKeyScanA,2487 diff --git a/libc/nt/user32/VkKeyScanExA.s b/libc/nt/user32/VkKeyScanExA.s deleted file mode 100644 index 910db4861..000000000 --- a/libc/nt/user32/VkKeyScanExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_VkKeyScanExA,VkKeyScanExA,2488 diff --git a/libc/nt/user32/WinHelpA.s b/libc/nt/user32/WinHelpA.s deleted file mode 100644 index e8e0e25ab..000000000 --- a/libc/nt/user32/WinHelpA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_WinHelpA,WinHelpA,2498 diff --git a/libc/nt/user32/_UserTestTokenForInteractive.s b/libc/nt/user32/_UserTestTokenForInteractive.s deleted file mode 100644 index 16fd5e756..000000000 --- a/libc/nt/user32/_UserTestTokenForInteractive.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp__UserTestTokenForInteractive,_UserTestTokenForInteractive,2543 diff --git a/libc/nt/user32/gSharedInfo.s b/libc/nt/user32/gSharedInfo.s deleted file mode 100644 index 14dd57d39..000000000 --- a/libc/nt/user32/gSharedInfo.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_gSharedInfo,gSharedInfo,2547 diff --git a/libc/nt/user32/gapfnScSendMessage.s b/libc/nt/user32/gapfnScSendMessage.s deleted file mode 100644 index d46a63e88..000000000 --- a/libc/nt/user32/gapfnScSendMessage.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_gapfnScSendMessage,gapfnScSendMessage,2562 diff --git a/libc/nt/user32/keybd_event.s b/libc/nt/user32/keybd_event.s deleted file mode 100644 index b0e1ca1e9..000000000 --- a/libc/nt/user32/keybd_event.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_keybd_event,keybd_event,2580 diff --git a/libc/nt/user32/mouse_event.s b/libc/nt/user32/mouse_event.s deleted file mode 100644 index e4a0b74bd..000000000 --- a/libc/nt/user32/mouse_event.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp user32,__imp_mouse_event,mouse_event,2583 diff --git a/libc/nt/version.h b/libc/nt/version.h index 7acf9f290..f7ade11de 100644 --- a/libc/nt/version.h +++ b/libc/nt/version.h @@ -4,8 +4,22 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +bool IsAtLeastWindows10(void) pureconst; bool32 GetVersionEx(struct NtOsVersionInfo *lpVersionInformation); +#if defined(__GCC_ASM_FLAG_OUTPUTS__) && !defined(__STRICT_ANSI__) +#define IsAtLeastWindows10() \ + ({ \ + long ReG; \ + bool NoTbelow; \ + asm("mov\t%%gs:96,%1\r\n" \ + "cmpb\t%2,280(%1)" \ + : "=@ccnb"(NoTbelow), "=l"(ReG) \ + : "i"(10)); \ + NoTbelow; \ + }) +#endif + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_NT_VERSION_H_ */ diff --git a/libc/nt/winsock.h b/libc/nt/winsock.h index 77890a725..8f819fbd7 100644 --- a/libc/nt/winsock.h +++ b/libc/nt/winsock.h @@ -43,12 +43,12 @@ │ cosmopolitan § new technology » winsock ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ -#define kNtCompEqual 0 -#define kNtCompNotless 1 - #define kNtWsaFlagOverlapped 0x01 #define kNtWsaFlagNoHandleInherit 0x80 +#define kNtCompEqual 0 +#define kNtCompNotless 1 + #define kNtTfDisconnect 0x01 #define kNtTfReuseSocket 0x02 #define kNtTfWriteBehind 0x04 @@ -60,33 +60,6 @@ #define kNtSoUpdateAcceptContext 0x700B #define kNtSoUpdateConnectContext 0x7010 -#define kNtSioAddressListChange 0x28000017u -#define kNtSioAddressListQuery 0x48000016u -#define kNtSioAddressListSort 0xC8000019u -#define kNtSioAssociateHandle 0x88000001u -#define kNtSioEnableCircularQueueing 0x28000002u -#define kNtSioFindRoute 0x48000003u -#define kNtSioFlush 0x28000004u -#define kNtSioGetBroadcastAddress 0x48000005u -#define kNtSioGetExtensionFunctionPointer 0xC8000006u -#define kNtSioGetGroupQos 0xC8000008u -#define kNtSioGetQos 0xC8000007u -#define kNtSioMulticastScope 0x8800000Au -#define kNtSioMultipointLoopback 0x88000009u -#define kNtSioQueryRssProcessorInfo 0x48000025u -#define kNtSioQueryTargetPnpHandle 0x48000018u -#define kNtSioReserved1 0x8800001Au -#define kNtSioReserved2 0x88000021u -#define kNtSioRoutingInterfaceChange 0x88000015u -#define kNtSioRoutingInterfaceQuery 0xC8000014u -#define kNtSioSetGroupQos 0x8800000Cu -#define kNtSioSetQos 0x8800000Bu -#define kNtSioSocketCloseNotify 0x9800000Du -#define kNtSioTranslateHandle 0xC800000Du -#define kNtSioUdpConnreset 0x9800000Cu -#define kNtSioUdpNetreset 0x9800000Fu -#define kNtSioGetInterfaceList 0x4008747fu /* _IOR('t', 127, ULONG) */ - #define kNtNspNotifyImmediately 0 #define kNtNspNotifyHwnd 1 #define kNtNspNotifyEvent 2 @@ -328,7 +301,7 @@ struct NtInterfaceInfo { */ int32_t WSAStartup(uint16_t wVersionRequested, struct NtWsaData *lpWSAData) - paramsnonnull() nodiscard; + paramsnonnull() dontdiscard; int WSACleanup(void); int WSAGetLastError(void); @@ -348,7 +321,7 @@ int __sys_select_nt(int, struct NtFdSet *, struct NtFdSet *, struct NtFdSet *, uint64_t WSASocket(int af, int type, int protocol, const struct NtWsaProtocolInfo *opt_lpProtocolInfo, - const uint32_t opt_group, uint32_t dwFlags) nodiscard; + const uint32_t opt_group, uint32_t dwFlags) dontdiscard; int WSAConnect(uint64_t s, const struct sockaddr *name, const int namelen, const struct NtIovec *opt_lpCallerData, @@ -378,7 +351,7 @@ int64_t WSAAccept(uint64_t s, struct sockaddr *out_addr, int32_t *opt_inout_addrlen, const NtConditionProc opt_lpfnCondition, const uint32_t *opt_dwCallbackData) - paramsnonnull((2)) nodiscard; + paramsnonnull((2)) dontdiscard; int WSASend(uint64_t s, const struct NtIovec *lpBuffers, uint32_t dwBufferCount, uint32_t *opt_out_lpNumberOfBytesSent, uint32_t dwFlags, @@ -419,8 +392,8 @@ int WSARecvFrom(uint64_t s, const struct NtIovec *out_lpBuffers, const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) paramsnonnull((2, 5)); -int WSARecvDisconnect(uint64_t s, - const struct NtIovec *opt_lpInboundDisconnectData); +int WSARecvDisconnect(uint64_t s, struct NtIovec *out_InboundDisconnectData); +int WSASendDisconnect(int64_t s, struct NtIovec *opt_OutboundDisconnectData); int WSADuplicateSocket(uint64_t s, uint32_t dwProcessId, struct NtWsaProtocolInfo *out_lpProtocolInfo) @@ -440,7 +413,7 @@ int WSANSPIoctl(int64_t hLookup, uint32_t dwControlCode, const struct NtWsaCompletion *opt_lpCompletion) paramsnonnull((3, 5, 7)); -int64_t WSACreateEvent(void) nodiscard; +int64_t WSACreateEvent(void) dontdiscard; bool32 WSACloseEvent(const int64_t hEvent); bool32 WSAResetEvent(const int64_t hEvent); bool32 WSASetEvent(const int64_t hEvent); @@ -548,11 +521,6 @@ void GetAcceptExSockaddrs( struct sockaddr **out_RemoteSockaddr /*[*RemoteSockaddrLength]*/, int *out_RemoteSockaddrLength); -bool32 ConnectEx(int64_t s, const struct sockaddr *name, int namelen, - const void *opt_lpSendBuffer, uint32_t dwSendDataLength, - uint32_t *out_lpdwBytesSent, - struct NtOverlapped *inout_lpOverlapped); - bool32 DisconnectEx(int64_t s, struct NtOverlapped *inout_opt_lpOverlapped, uint32_t dwFlags, uint32_t dwReserved); diff --git a/libc/nt/ws2_32/FreeAddrInfoExW.s b/libc/nt/ws2_32/FreeAddrInfoExW.s index 2632bbcc5..16dfa5493 100644 --- a/libc/nt/ws2_32/FreeAddrInfoExW.s +++ b/libc/nt/ws2_32/FreeAddrInfoExW.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_FreeAddrInfoExW,FreeAddrInfoExW,26 + + .text.windows +FreeAddrInfoEx: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FreeAddrInfoExW(%rip) + leave + ret + .endfn FreeAddrInfoEx,globl + .previous diff --git a/libc/nt/ws2_32/FreeAddrInfoW.s b/libc/nt/ws2_32/FreeAddrInfoW.s index 3eb3ba0ab..38a4c2684 100644 --- a/libc/nt/ws2_32/FreeAddrInfoW.s +++ b/libc/nt/ws2_32/FreeAddrInfoW.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_FreeAddrInfoW,FreeAddrInfoW,27 + + .text.windows +FreeAddrInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FreeAddrInfoW(%rip) + leave + ret + .endfn FreeAddrInfo,globl + .previous diff --git a/libc/nt/ws2_32/GetAddrInfoExA.s b/libc/nt/ws2_32/GetAddrInfoExA.s deleted file mode 100644 index f82df9e8e..000000000 --- a/libc/nt/ws2_32/GetAddrInfoExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_GetAddrInfoExA,GetAddrInfoExA,28 diff --git a/libc/nt/ws2_32/GetAddrInfoExCancel.s b/libc/nt/ws2_32/GetAddrInfoExCancel.s index 26c3f2103..6c2b7efd9 100644 --- a/libc/nt/ws2_32/GetAddrInfoExCancel.s +++ b/libc/nt/ws2_32/GetAddrInfoExCancel.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_GetAddrInfoExCancel,GetAddrInfoExCancel,29 + + .text.windows +GetAddrInfoExCancel: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetAddrInfoExCancel(%rip) + leave + ret + .endfn GetAddrInfoExCancel,globl + .previous diff --git a/libc/nt/ws2_32/GetAddrInfoExOverlappedResult.s b/libc/nt/ws2_32/GetAddrInfoExOverlappedResult.s index ecc018e12..982e352a7 100644 --- a/libc/nt/ws2_32/GetAddrInfoExOverlappedResult.s +++ b/libc/nt/ws2_32/GetAddrInfoExOverlappedResult.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_GetAddrInfoExOverlappedResult,GetAddrInfoExOverlappedResult,30 + + .text.windows +GetAddrInfoExOverlappedResult: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetAddrInfoExOverlappedResult(%rip) + leave + ret + .endfn GetAddrInfoExOverlappedResult,globl + .previous diff --git a/libc/nt/ws2_32/GetAddrInfoExW.s b/libc/nt/ws2_32/GetAddrInfoExW.s index a38009ab6..b9d0fe6d3 100644 --- a/libc/nt/ws2_32/GetAddrInfoExW.s +++ b/libc/nt/ws2_32/GetAddrInfoExW.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_GetAddrInfoExW,GetAddrInfoExW,31 + + .text.windows +GetAddrInfoEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetAddrInfoExW(%rip),%rax + jmp __sysv2nt10 + .endfn GetAddrInfoEx,globl + .previous diff --git a/libc/nt/ws2_32/GetAddrInfoW.s b/libc/nt/ws2_32/GetAddrInfoW.s index 555724a69..b9662e5af 100644 --- a/libc/nt/ws2_32/GetAddrInfoW.s +++ b/libc/nt/ws2_32/GetAddrInfoW.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_GetAddrInfoW,GetAddrInfoW,32 + + .text.windows +GetAddrInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetAddrInfoW(%rip),%rax + jmp __sysv2nt + .endfn GetAddrInfo,globl + .previous diff --git a/libc/nt/ws2_32/GetHostNameW.s b/libc/nt/ws2_32/GetHostNameW.s index 80c9b385a..6e85d6ed8 100644 --- a/libc/nt/ws2_32/GetHostNameW.s +++ b/libc/nt/ws2_32/GetHostNameW.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_GetHostNameW,GetHostNameW,33 + + .text.windows +GetHostName: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetHostNameW(%rip),%rax + jmp __sysv2nt + .endfn GetHostName,globl + .previous diff --git a/libc/nt/ws2_32/GetNameInfoW.s b/libc/nt/ws2_32/GetNameInfoW.s index 5282af106..d7803f640 100644 --- a/libc/nt/ws2_32/GetNameInfoW.s +++ b/libc/nt/ws2_32/GetNameInfoW.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_GetNameInfoW,GetNameInfoW,34 + + .text.windows +GetNameInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetNameInfoW(%rip),%rax + jmp __sysv2nt8 + .endfn GetNameInfo,globl + .previous diff --git a/libc/nt/ws2_32/InetNtopW.s b/libc/nt/ws2_32/InetNtopW.s deleted file mode 100644 index 0dd929277..000000000 --- a/libc/nt/ws2_32/InetNtopW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_InetNtopW,InetNtopW,35 diff --git a/libc/nt/ws2_32/InetPtonW.s b/libc/nt/ws2_32/InetPtonW.s deleted file mode 100644 index c01ac598d..000000000 --- a/libc/nt/ws2_32/InetPtonW.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_InetPtonW,InetPtonW,36 diff --git a/libc/nt/ws2_32/SetAddrInfoExA.s b/libc/nt/ws2_32/SetAddrInfoExA.s deleted file mode 100644 index f16c0ff1a..000000000 --- a/libc/nt/ws2_32/SetAddrInfoExA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_SetAddrInfoExA,SetAddrInfoExA,37 diff --git a/libc/nt/ws2_32/SetAddrInfoExW.s b/libc/nt/ws2_32/SetAddrInfoExW.s index b9b0ad939..65e9adedf 100644 --- a/libc/nt/ws2_32/SetAddrInfoExW.s +++ b/libc/nt/ws2_32/SetAddrInfoExW.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_SetAddrInfoExW,SetAddrInfoExW,38 + + .text.windows +SetAddrInfoEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetAddrInfoExW(%rip),%rax + jmp __sysv2nt12 + .endfn SetAddrInfoEx,globl + .previous diff --git a/libc/nt/ws2_32/WEP.s b/libc/nt/ws2_32/WEP.s deleted file mode 100644 index 67475c3f2..000000000 --- a/libc/nt/ws2_32/WEP.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WEP,WEP,500 diff --git a/libc/nt/ws2_32/WPUCompleteOverlappedRequest.s b/libc/nt/ws2_32/WPUCompleteOverlappedRequest.s deleted file mode 100644 index f7cb885bc..000000000 --- a/libc/nt/ws2_32/WPUCompleteOverlappedRequest.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WPUCompleteOverlappedRequest,WPUCompleteOverlappedRequest,39 diff --git a/libc/nt/ws2_32/WPUGetProviderPathEx.s b/libc/nt/ws2_32/WPUGetProviderPathEx.s deleted file mode 100644 index 597207d16..000000000 --- a/libc/nt/ws2_32/WPUGetProviderPathEx.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WPUGetProviderPathEx,WPUGetProviderPathEx,40 diff --git a/libc/nt/ws2_32/WSAAddressToStringA.s b/libc/nt/ws2_32/WSAAddressToStringA.s deleted file mode 100644 index e394acb04..000000000 --- a/libc/nt/ws2_32/WSAAddressToStringA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAAddressToStringA,WSAAddressToStringA,42 - - .text.windows -WSAAddressToStringA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSAAddressToStringA(%rip),%rax - jmp __sysv2nt6 - .endfn WSAAddressToStringA,globl - .previous diff --git a/libc/nt/ws2_32/WSAAdvertiseProvider.s b/libc/nt/ws2_32/WSAAdvertiseProvider.s deleted file mode 100644 index e2862fdc4..000000000 --- a/libc/nt/ws2_32/WSAAdvertiseProvider.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAAdvertiseProvider,WSAAdvertiseProvider,44 diff --git a/libc/nt/ws2_32/WSAAsyncGetHostByAddr.s b/libc/nt/ws2_32/WSAAsyncGetHostByAddr.s index 03f44b28e..c3ca8781a 100644 --- a/libc/nt/ws2_32/WSAAsyncGetHostByAddr.s +++ b/libc/nt/ws2_32/WSAAsyncGetHostByAddr.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_WSAAsyncGetHostByAddr,WSAAsyncGetHostByAddr,102 + + .text.windows +WSAAsyncGetHostByAddr: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAAsyncGetHostByAddr(%rip),%rax + jmp __sysv2nt8 + .endfn WSAAsyncGetHostByAddr,globl + .previous diff --git a/libc/nt/ws2_32/WSAAsyncGetHostByName.s b/libc/nt/ws2_32/WSAAsyncGetHostByName.s index e8f72e416..efbf7212d 100644 --- a/libc/nt/ws2_32/WSAAsyncGetHostByName.s +++ b/libc/nt/ws2_32/WSAAsyncGetHostByName.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_WSAAsyncGetHostByName,WSAAsyncGetHostByName,103 + + .text.windows +WSAAsyncGetHostByName: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAAsyncGetHostByName(%rip),%rax + jmp __sysv2nt6 + .endfn WSAAsyncGetHostByName,globl + .previous diff --git a/libc/nt/ws2_32/WSAAsyncGetProtoByName.s b/libc/nt/ws2_32/WSAAsyncGetProtoByName.s index 22a983fc7..85c7f9abe 100644 --- a/libc/nt/ws2_32/WSAAsyncGetProtoByName.s +++ b/libc/nt/ws2_32/WSAAsyncGetProtoByName.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_WSAAsyncGetProtoByName,WSAAsyncGetProtoByName,105 + + .text.windows +WSAAsyncGetProtoByName: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAAsyncGetProtoByName(%rip),%rax + jmp __sysv2nt6 + .endfn WSAAsyncGetProtoByName,globl + .previous diff --git a/libc/nt/ws2_32/WSAAsyncGetProtoByNumber.s b/libc/nt/ws2_32/WSAAsyncGetProtoByNumber.s index 0263e0d18..6e8a2d016 100644 --- a/libc/nt/ws2_32/WSAAsyncGetProtoByNumber.s +++ b/libc/nt/ws2_32/WSAAsyncGetProtoByNumber.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_WSAAsyncGetProtoByNumber,WSAAsyncGetProtoByNumber,104 + + .text.windows +WSAAsyncGetProtoByNumber: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAAsyncGetProtoByNumber(%rip),%rax + jmp __sysv2nt6 + .endfn WSAAsyncGetProtoByNumber,globl + .previous diff --git a/libc/nt/ws2_32/WSAConnectByNameA.s b/libc/nt/ws2_32/WSAConnectByNameA.s deleted file mode 100644 index 306f9686f..000000000 --- a/libc/nt/ws2_32/WSAConnectByNameA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAConnectByNameA,WSAConnectByNameA,48 - - .text.windows -WSAConnectByNameA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSAConnectByNameA(%rip),%rax - jmp __sysv2nt10 - .endfn WSAConnectByNameA,globl - .previous diff --git a/libc/nt/ws2_32/WSADuplicateSocketA.s b/libc/nt/ws2_32/WSADuplicateSocketA.s deleted file mode 100644 index e303b41c2..000000000 --- a/libc/nt/ws2_32/WSADuplicateSocketA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSADuplicateSocketA,WSADuplicateSocketA,58 - - .text.windows -WSADuplicateSocketA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSADuplicateSocketA(%rip),%rax - jmp __sysv2nt - .endfn WSADuplicateSocketA,globl - .previous diff --git a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersA.s b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersA.s deleted file mode 100644 index 41fe7cde2..000000000 --- a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersA.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAEnumNameSpaceProvidersA,WSAEnumNameSpaceProvidersA,60 diff --git a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExA.s b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExA.s deleted file mode 100644 index 689d45a16..000000000 --- a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAEnumNameSpaceProvidersExA,WSAEnumNameSpaceProvidersExA,61 - - .text.windows -WSAEnumNameSpaceProvidersExA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSAEnumNameSpaceProvidersExA(%rip),%rax - jmp __sysv2nt - .endfn WSAEnumNameSpaceProvidersExA,globl - .previous diff --git a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersW.s b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersW.s index 3537e5d6d..ff2961dd0 100644 --- a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersW.s +++ b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersW.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_WSAEnumNameSpaceProvidersW,WSAEnumNameSpaceProvidersW,63 + + .text.windows +WSAEnumNameSpaceProviders: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAEnumNameSpaceProvidersW(%rip),%rax + jmp __sysv2nt + .endfn WSAEnumNameSpaceProviders,globl + .previous diff --git a/libc/nt/ws2_32/WSAEnumProtocolsA.s b/libc/nt/ws2_32/WSAEnumProtocolsA.s deleted file mode 100644 index 91265c01e..000000000 --- a/libc/nt/ws2_32/WSAEnumProtocolsA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAEnumProtocolsA,WSAEnumProtocolsA,65 - - .text.windows -WSAEnumProtocolsA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSAEnumProtocolsA(%rip),%rax - jmp __sysv2nt - .endfn WSAEnumProtocolsA,globl - .previous diff --git a/libc/nt/ws2_32/WSAGetServiceClassInfoA.s b/libc/nt/ws2_32/WSAGetServiceClassInfoA.s deleted file mode 100644 index 3bdca9d3c..000000000 --- a/libc/nt/ws2_32/WSAGetServiceClassInfoA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAGetServiceClassInfoA,WSAGetServiceClassInfoA,70 - - .text.windows -WSAGetServiceClassInfoA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSAGetServiceClassInfoA(%rip),%rax - jmp __sysv2nt - .endfn WSAGetServiceClassInfoA,globl - .previous diff --git a/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdA.s b/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdA.s deleted file mode 100644 index 201b3514f..000000000 --- a/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAGetServiceClassNameByClassIdA,WSAGetServiceClassNameByClassIdA,72 - - .text.windows -WSAGetServiceClassNameByClassIdA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSAGetServiceClassNameByClassIdA(%rip),%rax - jmp __sysv2nt - .endfn WSAGetServiceClassNameByClassIdA,globl - .previous diff --git a/libc/nt/ws2_32/WSAHtonl.s b/libc/nt/ws2_32/WSAHtonl.s deleted file mode 100644 index 6e5743924..000000000 --- a/libc/nt/ws2_32/WSAHtonl.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAHtonl,WSAHtonl,74 diff --git a/libc/nt/ws2_32/WSAHtons.s b/libc/nt/ws2_32/WSAHtons.s deleted file mode 100644 index 838e6bc66..000000000 --- a/libc/nt/ws2_32/WSAHtons.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAHtons,WSAHtons,75 diff --git a/libc/nt/ws2_32/WSAInstallServiceClassA.s b/libc/nt/ws2_32/WSAInstallServiceClassA.s deleted file mode 100644 index d64e25b97..000000000 --- a/libc/nt/ws2_32/WSAInstallServiceClassA.s +++ /dev/null @@ -1,15 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAInstallServiceClassA,WSAInstallServiceClassA,76 - - .text.windows -WSAInstallServiceClassA: - push %rbp - mov %rsp,%rbp - .profilable - mov %rdi,%rcx - sub $32,%rsp - call *__imp_WSAInstallServiceClassA(%rip) - leave - ret - .endfn WSAInstallServiceClassA,globl - .previous diff --git a/libc/nt/ws2_32/WSAIsBlocking.s b/libc/nt/ws2_32/WSAIsBlocking.s deleted file mode 100644 index 37e8ed2a2..000000000 --- a/libc/nt/ws2_32/WSAIsBlocking.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAIsBlocking,WSAIsBlocking,114 diff --git a/libc/nt/ws2_32/WSALookupServiceBeginA.s b/libc/nt/ws2_32/WSALookupServiceBeginA.s deleted file mode 100644 index cf969b31a..000000000 --- a/libc/nt/ws2_32/WSALookupServiceBeginA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSALookupServiceBeginA,WSALookupServiceBeginA,80 - - .text.windows -WSALookupServiceBeginA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSALookupServiceBeginA(%rip),%rax - jmp __sysv2nt - .endfn WSALookupServiceBeginA,globl - .previous diff --git a/libc/nt/ws2_32/WSALookupServiceNextA.s b/libc/nt/ws2_32/WSALookupServiceNextA.s deleted file mode 100644 index 493b89781..000000000 --- a/libc/nt/ws2_32/WSALookupServiceNextA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSALookupServiceNextA,WSALookupServiceNextA,83 - - .text.windows -WSALookupServiceNextA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSALookupServiceNextA(%rip),%rax - jmp __sysv2nt - .endfn WSALookupServiceNextA,globl - .previous diff --git a/libc/nt/ws2_32/WSANtohl.s b/libc/nt/ws2_32/WSANtohl.s deleted file mode 100644 index 5f7c9a05a..000000000 --- a/libc/nt/ws2_32/WSANtohl.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSANtohl,WSANtohl,86 diff --git a/libc/nt/ws2_32/WSANtohs.s b/libc/nt/ws2_32/WSANtohs.s deleted file mode 100644 index c5b5fb9e7..000000000 --- a/libc/nt/ws2_32/WSANtohs.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSANtohs,WSANtohs,87 diff --git a/libc/nt/ws2_32/WSASendDisconnect.s b/libc/nt/ws2_32/WSASendDisconnect.s index 50870e347..0e3f10fd8 100644 --- a/libc/nt/ws2_32/WSASendDisconnect.s +++ b/libc/nt/ws2_32/WSASendDisconnect.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_WSASendDisconnect,WSASendDisconnect,97 + + .text.windows +WSASendDisconnect: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSASendDisconnect(%rip),%rax + jmp __sysv2nt + .endfn WSASendDisconnect,globl + .previous diff --git a/libc/nt/ws2_32/WSASetServiceA.s b/libc/nt/ws2_32/WSASetServiceA.s deleted file mode 100644 index a6ce4e66f..000000000 --- a/libc/nt/ws2_32/WSASetServiceA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSASetServiceA,WSASetServiceA,117 - - .text.windows -WSASetServiceA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSASetServiceA(%rip),%rax - jmp __sysv2nt - .endfn WSASetServiceA,globl - .previous diff --git a/libc/nt/ws2_32/WSASocketA.s b/libc/nt/ws2_32/WSASocketA.s deleted file mode 100644 index 6ee0ee9d8..000000000 --- a/libc/nt/ws2_32/WSASocketA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSASocketA,WSASocketA,119 - - .text.windows -WSASocketA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSASocketA(%rip),%rax - jmp __sysv2nt6 - .endfn WSASocketA,globl - .previous diff --git a/libc/nt/ws2_32/WSAStringToAddressA.s b/libc/nt/ws2_32/WSAStringToAddressA.s deleted file mode 100644 index 8650a7ff4..000000000 --- a/libc/nt/ws2_32/WSAStringToAddressA.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WSAStringToAddressA,WSAStringToAddressA,121 - - .text.windows -WSAStringToAddressA: - push %rbp - mov %rsp,%rbp - .profilable - mov __imp_WSAStringToAddressA(%rip),%rax - jmp __sysv2nt6 - .endfn WSAStringToAddressA,globl - .previous diff --git a/libc/nt/ws2_32/WahCloseApcHelper.s b/libc/nt/ws2_32/WahCloseApcHelper.s deleted file mode 100644 index d54329eca..000000000 --- a/libc/nt/ws2_32/WahCloseApcHelper.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCloseApcHelper,WahCloseApcHelper,166 diff --git a/libc/nt/ws2_32/WahCloseHandleHelper.s b/libc/nt/ws2_32/WahCloseHandleHelper.s deleted file mode 100644 index eaed01380..000000000 --- a/libc/nt/ws2_32/WahCloseHandleHelper.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCloseHandleHelper,WahCloseHandleHelper,167 diff --git a/libc/nt/ws2_32/WahCloseNotificationHandleHelper.s b/libc/nt/ws2_32/WahCloseNotificationHandleHelper.s deleted file mode 100644 index 081591328..000000000 --- a/libc/nt/ws2_32/WahCloseNotificationHandleHelper.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCloseNotificationHandleHelper,WahCloseNotificationHandleHelper,168 diff --git a/libc/nt/ws2_32/WahCloseSocketHandle.s b/libc/nt/ws2_32/WahCloseSocketHandle.s deleted file mode 100644 index 3bc65ba8a..000000000 --- a/libc/nt/ws2_32/WahCloseSocketHandle.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCloseSocketHandle,WahCloseSocketHandle,169 diff --git a/libc/nt/ws2_32/WahCloseThread.s b/libc/nt/ws2_32/WahCloseThread.s deleted file mode 100644 index e51b5427a..000000000 --- a/libc/nt/ws2_32/WahCloseThread.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCloseThread,WahCloseThread,170 diff --git a/libc/nt/ws2_32/WahCompleteRequest.s b/libc/nt/ws2_32/WahCompleteRequest.s deleted file mode 100644 index 0d70c2228..000000000 --- a/libc/nt/ws2_32/WahCompleteRequest.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCompleteRequest,WahCompleteRequest,171 diff --git a/libc/nt/ws2_32/WahCreateHandleContextTable.s b/libc/nt/ws2_32/WahCreateHandleContextTable.s deleted file mode 100644 index 64760609a..000000000 --- a/libc/nt/ws2_32/WahCreateHandleContextTable.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCreateHandleContextTable,WahCreateHandleContextTable,172 diff --git a/libc/nt/ws2_32/WahCreateNotificationHandle.s b/libc/nt/ws2_32/WahCreateNotificationHandle.s deleted file mode 100644 index 6da9cd910..000000000 --- a/libc/nt/ws2_32/WahCreateNotificationHandle.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCreateNotificationHandle,WahCreateNotificationHandle,173 diff --git a/libc/nt/ws2_32/WahCreateSocketHandle.s b/libc/nt/ws2_32/WahCreateSocketHandle.s deleted file mode 100644 index 6d6bd47af..000000000 --- a/libc/nt/ws2_32/WahCreateSocketHandle.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahCreateSocketHandle,WahCreateSocketHandle,174 diff --git a/libc/nt/ws2_32/WahDestroyHandleContextTable.s b/libc/nt/ws2_32/WahDestroyHandleContextTable.s deleted file mode 100644 index 7bb7529ef..000000000 --- a/libc/nt/ws2_32/WahDestroyHandleContextTable.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahDestroyHandleContextTable,WahDestroyHandleContextTable,175 diff --git a/libc/nt/ws2_32/WahDisableNonIFSHandleSupport.s b/libc/nt/ws2_32/WahDisableNonIFSHandleSupport.s deleted file mode 100644 index 39400bc56..000000000 --- a/libc/nt/ws2_32/WahDisableNonIFSHandleSupport.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahDisableNonIFSHandleSupport,WahDisableNonIFSHandleSupport,176 diff --git a/libc/nt/ws2_32/WahEnableNonIFSHandleSupport.s b/libc/nt/ws2_32/WahEnableNonIFSHandleSupport.s deleted file mode 100644 index 452470769..000000000 --- a/libc/nt/ws2_32/WahEnableNonIFSHandleSupport.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahEnableNonIFSHandleSupport,WahEnableNonIFSHandleSupport,177 diff --git a/libc/nt/ws2_32/WahEnumerateHandleContexts.s b/libc/nt/ws2_32/WahEnumerateHandleContexts.s deleted file mode 100644 index 4e1ace5ba..000000000 --- a/libc/nt/ws2_32/WahEnumerateHandleContexts.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahEnumerateHandleContexts,WahEnumerateHandleContexts,178 diff --git a/libc/nt/ws2_32/WahInsertHandleContext.s b/libc/nt/ws2_32/WahInsertHandleContext.s deleted file mode 100644 index 828784d7d..000000000 --- a/libc/nt/ws2_32/WahInsertHandleContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahInsertHandleContext,WahInsertHandleContext,179 diff --git a/libc/nt/ws2_32/WahNotifyAllProcesses.s b/libc/nt/ws2_32/WahNotifyAllProcesses.s deleted file mode 100644 index f857aca6e..000000000 --- a/libc/nt/ws2_32/WahNotifyAllProcesses.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahNotifyAllProcesses,WahNotifyAllProcesses,180 diff --git a/libc/nt/ws2_32/WahOpenApcHelper.s b/libc/nt/ws2_32/WahOpenApcHelper.s deleted file mode 100644 index 30cc52640..000000000 --- a/libc/nt/ws2_32/WahOpenApcHelper.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahOpenApcHelper,WahOpenApcHelper,181 diff --git a/libc/nt/ws2_32/WahOpenCurrentThread.s b/libc/nt/ws2_32/WahOpenCurrentThread.s deleted file mode 100644 index cd32c3230..000000000 --- a/libc/nt/ws2_32/WahOpenCurrentThread.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahOpenCurrentThread,WahOpenCurrentThread,182 diff --git a/libc/nt/ws2_32/WahOpenHandleHelper.s b/libc/nt/ws2_32/WahOpenHandleHelper.s deleted file mode 100644 index ed001860c..000000000 --- a/libc/nt/ws2_32/WahOpenHandleHelper.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahOpenHandleHelper,WahOpenHandleHelper,183 diff --git a/libc/nt/ws2_32/WahOpenNotificationHandleHelper.s b/libc/nt/ws2_32/WahOpenNotificationHandleHelper.s deleted file mode 100644 index 153ff26ce..000000000 --- a/libc/nt/ws2_32/WahOpenNotificationHandleHelper.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahOpenNotificationHandleHelper,WahOpenNotificationHandleHelper,184 diff --git a/libc/nt/ws2_32/WahQueueUserApc.s b/libc/nt/ws2_32/WahQueueUserApc.s deleted file mode 100644 index 3f45bb170..000000000 --- a/libc/nt/ws2_32/WahQueueUserApc.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahQueueUserApc,WahQueueUserApc,185 diff --git a/libc/nt/ws2_32/WahReferenceContextByHandle.s b/libc/nt/ws2_32/WahReferenceContextByHandle.s deleted file mode 100644 index e614159fe..000000000 --- a/libc/nt/ws2_32/WahReferenceContextByHandle.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahReferenceContextByHandle,WahReferenceContextByHandle,186 diff --git a/libc/nt/ws2_32/WahRemoveHandleContext.s b/libc/nt/ws2_32/WahRemoveHandleContext.s deleted file mode 100644 index 558baf1f2..000000000 --- a/libc/nt/ws2_32/WahRemoveHandleContext.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahRemoveHandleContext,WahRemoveHandleContext,187 diff --git a/libc/nt/ws2_32/WahWaitForNotification.s b/libc/nt/ws2_32/WahWaitForNotification.s deleted file mode 100644 index 09b13abac..000000000 --- a/libc/nt/ws2_32/WahWaitForNotification.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahWaitForNotification,WahWaitForNotification,188 diff --git a/libc/nt/ws2_32/WahWriteLSPEvent.s b/libc/nt/ws2_32/WahWriteLSPEvent.s deleted file mode 100644 index b16af195b..000000000 --- a/libc/nt/ws2_32/WahWriteLSPEvent.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/nt/codegen.inc" -.imp ws2_32,__imp_WahWriteLSPEvent,WahWriteLSPEvent,189 diff --git a/libc/nt/ws2_32/accept.s b/libc/nt/ws2_32/accept.s index cb18ee705..a0541b4e7 100644 --- a/libc/nt/ws2_32/accept.s +++ b/libc/nt/ws2_32/accept.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_accept,accept,1 + + .text.windows +__sys_accept_nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_accept(%rip),%rax + jmp __sysv2nt + .endfn __sys_accept_nt,globl + .previous diff --git a/libc/nt/ws2_32/recv.s b/libc/nt/ws2_32/recv.s index a4ed1fc26..d13d28f26 100644 --- a/libc/nt/ws2_32/recv.s +++ b/libc/nt/ws2_32/recv.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_recv,recv,16 + + .text.windows +__sys_recv_nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_recv(%rip),%rax + jmp __sysv2nt + .endfn __sys_recv_nt,globl + .previous diff --git a/libc/nt/ws2_32/recvfrom.s b/libc/nt/ws2_32/recvfrom.s index fbe79e667..bd35c88b7 100644 --- a/libc/nt/ws2_32/recvfrom.s +++ b/libc/nt/ws2_32/recvfrom.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_recvfrom,recvfrom,17 + + .text.windows +__sys_recvfrom_nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_recvfrom(%rip),%rax + jmp __sysv2nt6 + .endfn __sys_recvfrom_nt,globl + .previous diff --git a/libc/nt/ws2_32/send.s b/libc/nt/ws2_32/send.s index 012a81e56..6a9ef24cc 100644 --- a/libc/nt/ws2_32/send.s +++ b/libc/nt/ws2_32/send.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_send,send,19 + + .text.windows +__sys_send_nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_send(%rip),%rax + jmp __sysv2nt + .endfn __sys_send_nt,globl + .previous diff --git a/libc/nt/ws2_32/sendto.s b/libc/nt/ws2_32/sendto.s index 35192d294..ed0220462 100644 --- a/libc/nt/ws2_32/sendto.s +++ b/libc/nt/ws2_32/sendto.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_sendto,sendto,20 + + .text.windows +__sys_sendto_nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_sendto(%rip),%rax + jmp __sysv2nt6 + .endfn __sys_sendto_nt,globl + .previous diff --git a/libc/nt/ws2_32/socket.s b/libc/nt/ws2_32/socket.s index 8372b3b63..cc72cc2b7 100644 --- a/libc/nt/ws2_32/socket.s +++ b/libc/nt/ws2_32/socket.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp ws2_32,__imp_socket,socket,23 + + .text.windows +__sys_socket_nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_socket(%rip),%rax + jmp __sysv2nt + .endfn __sys_socket_nt,globl + .previous diff --git a/libc/ohmyplus/ohmyplus.mk b/libc/ohmyplus/ohmyplus.mk deleted file mode 100644 index 312b6b50c..000000000 --- a/libc/ohmyplus/ohmyplus.mk +++ /dev/null @@ -1,56 +0,0 @@ -#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ -#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ - -PKGS += LIBC_OHMYPLUS - -LIBC_OHMYPLUS_ARTIFACTS += LIBC_OHMYPLUS_A -LIBC_OHMYPLUS = $(LIBC_OHMYPLUS_A_DEPS) $(LIBC_OHMYPLUS_A) -LIBC_OHMYPLUS_A = o/$(MODE)/libc/ohmyplus/ohmyplus.a -LIBC_OHMYPLUS_A_FILES := $(wildcard libc/ohmyplus/*) -LIBC_OHMYPLUS_A_HDRS = $(filter %.h,$(LIBC_OHMYPLUS_A_FILES)) -LIBC_OHMYPLUS_A_SRCS_S = $(filter %.S,$(LIBC_OHMYPLUS_A_FILES)) -LIBC_OHMYPLUS_A_SRCS_C = $(filter %.c,$(LIBC_OHMYPLUS_A_FILES)) -LIBC_OHMYPLUS_A_SRCS_CXX = $(filter %.cc,$(LIBC_OHMYPLUS_A_FILES)) - -LIBC_OHMYPLUS_A_SRCS = \ - $(LIBC_OHMYPLUS_A_SRCS_S) \ - $(LIBC_OHMYPLUS_A_SRCS_C) \ - $(LIBC_OHMYPLUS_A_SRCS_CXX) - -LIBC_OHMYPLUS_A_OBJS = \ - $(LIBC_OHMYPLUS_A_SRCS_S:%.S=o/$(MODE)/%.o) \ - $(LIBC_OHMYPLUS_A_SRCS_C:%.c=o/$(MODE)/%.o) \ - $(LIBC_OHMYPLUS_A_SRCS_CXX:%.cc=o/$(MODE)/%.o) - -LIBC_OHMYPLUS_A_CHECKS = \ - $(LIBC_OHMYPLUS_A).pkg \ - $(LIBC_OHMYPLUS_A_HDRS:%=o/$(MODE)/%.okk) - -LIBC_OHMYPLUS_A_DIRECTDEPS = \ - LIBC_BITS \ - LIBC_INTRIN \ - LIBC_MEM \ - LIBC_STUBS \ - LIBC_NEXGEN32E - -LIBC_OHMYPLUS_A_DEPS := \ - $(call uniq,$(foreach x,$(LIBC_OHMYPLUS_A_DIRECTDEPS),$($(x)))) - -$(LIBC_OHMYPLUS_A): \ - libc/ohmyplus/ \ - $(LIBC_OHMYPLUS_A).pkg \ - $(LIBC_OHMYPLUS_A_OBJS) - -$(LIBC_OHMYPLUS_A).pkg: \ - $(LIBC_OHMYPLUS_A_OBJS) \ - $(foreach x,$(LIBC_OHMYPLUS_A_DIRECTDEPS),$($(x)_A).pkg) - -LIBC_OHMYPLUS_LIBS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x))) -LIBC_OHMYPLUS_SRCS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)_SRCS)) -LIBC_OHMYPLUS_HDRS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)_HDRS)) -LIBC_OHMYPLUS_CHECKS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)_CHECKS)) -LIBC_OHMYPLUS_OBJS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)_OBJS)) -$(LIBC_OHMYPLUS_OBJS): $(BUILD_FILES) libc/ohmyplus/ohmyplus.mk - -.PHONY: o/$(MODE)/libc/ohmyplus -o/$(MODE)/libc/ohmyplus: $(LIBC_OHMYPLUS_CHECKS) diff --git a/libc/ohmyplus/vector.c b/libc/ohmyplus/vector.c deleted file mode 100644 index 5740e591b..000000000 --- a/libc/ohmyplus/vector.c +++ /dev/null @@ -1,27 +0,0 @@ -/*-*- 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 "libc/bits/bits.h" -#include "libc/mem/mem.h" - -void __vector_reserve(size_t n, size_t m, intptr_t **data, size_t *toto) { - if ((n = roundup2pow(n)) > *toto) { - *toto = n; - *data = realloc(*data, n * m); - } -} diff --git a/libc/ohmyplus/vector.h b/libc/ohmyplus/vector.h deleted file mode 100644 index f4255e93b..000000000 --- a/libc/ohmyplus/vector.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_OHMYPLUS_VECTOR_H_ -#define COSMOPOLITAN_LIBC_OHMYPLUS_VECTOR_H_ -#ifdef __cplusplus -extern "C" { -void __vector_reserve(size_t, size_t, intptr_t **, size_t *); -} /* extern c */ -namespace std { - -template -class vector { - public: - vector() : data_(NULL), size_(0), toto_(0) { - } - vector(size_t n) : data_(NULL), size_(n), toto_(0) { - VectorReserve(n); - } - size_t size() const { - return size_; - } - size_t capacity() const { - return toto_; - } - T &front() { - return data_[0]; - } - T &back() { - return data_[size_ - 1]; - } - void clear() { - size_ = 0; - } - void reserve(size_t n) { - VectorReserve(n); - } - void resize(size_t n) { - reserve((size_ = n)); - } - bool empty() const { - return !size_; - } - T &operator[](size_t i) { - return data_[i]; - } - - private: - T *data_; - size_t size_; - size_t toto_; - void VectorReserve(size_t n) { - __vector_reserve(n, sizeof(T), (intptr_t **)&data_, &toto_); - } -}; - -}; /* namespace std */ -#endif /* __cplusplus */ -#endif /* COSMOPOLITAN_LIBC_OHMYPLUS_VECTOR_H_ */ diff --git a/libc/rand/g_rando.S b/libc/rand/g_rando.S index ab9d3bc25..4061d04b3 100644 --- a/libc/rand/g_rando.S +++ b/libc/rand/g_rando.S @@ -28,5 +28,3 @@ g_rando: .init.start 100,_init_g_rando movb $1,g_rando(%rip) .init.end 100,_init_g_rando - - .source __FILE__ diff --git a/libc/rand/getrandom.c b/libc/rand/getrandom.c index d90ef332d..866dd671e 100644 --- a/libc/rand/getrandom.c +++ b/libc/rand/getrandom.c @@ -19,6 +19,7 @@ #include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/nexgen32e/kcpuids.h" @@ -42,7 +43,7 @@ static bool have_getrandom; /** * Returns cryptographic random data. * - * This random number seed generator blends information from: + * This random number seed generator obtains information from: * * - getrandom() on Linux * - RtlGenRandom() on Windows @@ -60,25 +61,32 @@ static bool have_getrandom; * This function is safe to use with fork() and vfork(). It will also * close any file descriptor it ends up needing before it returns. * + * @note this function could block a nontrivial time on old computers + * @note this function is indeed intended for cryptography + * @note this function takes around 900 cycles * @asyncsignalsafe + * @restartable * @vforksafe */ ssize_t getrandom(void *p, size_t n, unsigned f) { char cf; ssize_t rc; uint64_t x; - size_t i, j, m; int fd, cmd[2]; + size_t i, j, m; + const char *via; sigset_t neu, old; if (n > 256) n = 256; if ((f & ~(GRND_RANDOM | GRND_NONBLOCK))) return einval(); if (IsWindows()) { + via = "RtlGenRandom"; if (RtlGenRandom(p, n)) { rc = n; } else { - return __winerr(); + rc = __winerr(); } } else if (IsFreebsd() || IsNetbsd()) { + via = "KERN_ARND"; if (IsFreebsd()) { cmd[0] = 1; /* CTL_KERN */ cmd[1] = 37; /* KERN_ARND */ @@ -91,27 +99,34 @@ ssize_t getrandom(void *p, size_t n, unsigned f) { rc = m; } } else if (have_getrandom) { + via = "getrandom"; if ((rc = sys_getrandom(p, n, f & (GRND_RANDOM | GRND_NONBLOCK))) != -1) { if (!rc && (IsXnu() || IsOpenbsd())) { rc = n; } } } else if ((fd = __sys_openat( - AT_FDCWD, (f & GRND_RANDOM) ? "/dev/random" : "/dev/urandom", + AT_FDCWD, + (via = (f & GRND_RANDOM) ? "/dev/random" : "/dev/urandom"), O_RDONLY | ((f & GRND_NONBLOCK) ? O_NONBLOCK : 0), 0)) != -1) { rc = sys_read(fd, p, n); sys_close(fd); } else { - return enosys(); + rc = enosys(); } + STRACE("getrandom(%p, %'zu, %#x) via %s → %'ld% m", p, n, f, via, rc); return rc; } static textstartup void getrandom_init(void) { - if (sys_getrandom(0, 0, 0) == 0) { + int e, rc; + e = errno; + if (!(rc = sys_getrandom(0, 0, 0))) { have_getrandom = true; } + KERNTRACE("sys_getrandom(0,0,0) → %d% m"); + errno = e; } const void *const g_getrandom_init[] initarray = {getrandom_init}; diff --git a/libc/rand/lcg.internal.h b/libc/rand/lcg.internal.h index bdb57d3d7..6efd36d42 100644 --- a/libc/rand/lcg.internal.h +++ b/libc/rand/lcg.internal.h @@ -7,7 +7,7 @@ forceinline uint64_t KnuthLinearCongruentialGenerator(uint64_t prev[1]) { Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998, p. 106 (line 26) & p. 108 */ prev[0] = prev[0] * 6364136223846793005 + 1442695040888963407; - return prev[0]; + return prev[0]; /* be sure to shift! */ } #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/rand/lemur64.c b/libc/rand/lemur64.c new file mode 100644 index 000000000..a21c9cb40 --- /dev/null +++ b/libc/rand/lemur64.c @@ -0,0 +1,45 @@ +/*-*- 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 2022 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/rand/rand.h" + +/** + * Returns linear congruential deterministic pseudorandom data, e.g. + * + * uint64_t x = lemur64(); + * + * You can generate different types of numbers as follows: + * + * int64_t x = lemur64() >> 1; // make positive signed integer + * double x = _real1(lemur64()); // make float on [0,1]-interval + * + * If you want a fast pseudorandom number generator that seeds itself + * automatically on startup and fork() then consider rand64(). If you + * want true random data then consider rdseed, rdrand, and getrandom. + * + * @return 64 bits of pseudorandom data + * @note this is Lemire's Lehmer generator + * @note this function takes at minimum 1 cycle + * @note this function passes bigcrush and practrand + * @note this function is not intended for cryptography + * @see rand64(), rngset(), _real1(), _real2(), _real3() + */ +uint64_t lemur64(void) { + static uint128_t s = 2131259787901769494; + return (s *= 15750249268501108917ull) >> 64; +} diff --git a/libc/rand/rand.c b/libc/rand/rand.c index a275efa7c..8188de536 100644 --- a/libc/rand/rand.c +++ b/libc/rand/rand.c @@ -21,11 +21,18 @@ #include "libc/rand/rand.h" /** - * Returns 31-bit random number using a linear congruential generator. + * Returns 31-bit linear congruential pseudorandom number, e.g. * - * Please note that, unlike rand32(), the rand() function uses the same - * seed at startup by default, unless srand() is called. This makes it - * useful in cases where deterministic behavior is needed. + * int x = rand(); + * assert(x >= 0); + * + * This function always returns a positive number. If srand() isn't + * called, then it'll return the same sequence each time your program + * runs. Faster and more modern alternatives exist to this function. + * + * @note this function does well on bigcrush and practrand + * @note this function is not intended for cryptography + * @see lemur64(), rand64(), rdrand() */ int rand(void) { return KnuthLinearCongruentialGenerator(&g_rando) >> 33; diff --git a/libc/rand/rand.h b/libc/rand/rand.h index 33a17ef64..48cf0824c 100644 --- a/libc/rand/rand.h +++ b/libc/rand/rand.h @@ -17,18 +17,18 @@ void rt_end(double *, double *, double *, double *, double *); char *strfry(char *); int getentropy(void *, size_t); ssize_t getrandom(void *, size_t, unsigned); -float randf(void); char *initstate(unsigned, char *, size_t); char *setstate(char *); long random(void); void srandom(unsigned); +uint64_t lemur64(void); +uint64_t rand64(void); uint64_t vigna(void); uint64_t vigna_r(uint64_t[hasatleast 1]); void svigna(uint64_t); uint64_t rdrand(void); uint64_t rdseed(void); -uint64_t rand64(void); void _smt19937(uint64_t); void _Smt19937(uint64_t[], size_t); uint64_t _mt19937(void); diff --git a/libc/rand/rand64.c b/libc/rand/rand64.c index 037a7932d..6d24f19ee 100644 --- a/libc/rand/rand64.c +++ b/libc/rand/rand64.c @@ -16,59 +16,65 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/bits/bits.h" -#include "libc/bits/xadd.h" +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" +#include "libc/intrin/spinlock.h" #include "libc/nexgen32e/rdtsc.h" -#include "libc/nexgen32e/x86feature.h" +#include "libc/nt/thread.h" #include "libc/rand/rand.h" +#include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/auxv.h" +#include "libc/thread/create.h" -static uint64_t thepool; +static int thepid; +static uint128_t thepool; +_Alignas(64) static char rand64_lock; /** * Returns nondeterministic random data. * - * This function automatically seeds itself on startup and reseeds - * itself after fork() and vfork(). It takes about nanosecond to run. - * That makes it much slower than vigna() and rand() but much faster - * than rdrand() and rdseed(). + * This function is similar to lemur64() except that it's intended to be + * unpredictable. This PRNG automatically seeds itself on startup using + * a much stronger and faster random source than `srand(time(0))`. This + * function will automatically reseed itself when new processes and + * threads are spawned. This function is thread safe in the sense that a + * race condition can't happen where two threads return the same result. * * @see rdseed(), rdrand(), rand(), random(), rngset() - * @note based on vigna's algorithm + * @note this function is not intended for cryptography + * @note this function passes bigcrush and practrand + * @note this function takes at minimum 15 cycles * @asyncsignalsafe + * @threadsafe * @vforksafe */ uint64_t rand64(void) { - bool cf; - register uint64_t t; - if (X86_HAVE(RDSEED)) { - asm volatile(CFLAG_ASM("rdseed\t%1") - : CFLAG_CONSTRAINT(cf), "=r"(t) - : /* no inputs */ - : "cc"); - if (cf) { - thepool ^= t; - return t; + void *p; + uint128_t s; + _spinlock(&rand64_lock); + if (__pid == thepid) { + s = thepool; // normal path + } else { + if (!thepid) { + if (AT_RANDOM && (p = (void *)getauxval(AT_RANDOM))) { + // linux / freebsd kernel supplied entropy + memcpy(&s, p, 16); + } else { + // otherwise initialize w/ cheap timestamp + s = kStartTsc; + } + } else { + // blend another timestamp on fork contention + s = thepool ^ rdtsc(); } + // blend the pid on startup and fork contention + s ^= __pid; + thepid = __pid; } - t = _xadd(&thepool, 0x9e3779b97f4a7c15); - t ^= (getpid() * 0x1001111111110001ull + 0xdeaadead) >> 31; - t = (t ^ (t >> 30)) * 0xbf58476d1ce4e5b9; - t = (t ^ (t >> 27)) * 0x94d049bb133111eb; - return t ^ (t >> 31); + thepool = (s *= 15750249268501108917ull); // lemur64 + _spunlock(&rand64_lock); + return s >> 64; } - -static textstartup void rand64_init(int argc, char **argv, char **envp, - intptr_t *auxv) { - for (; auxv[0]; auxv += 2) { - if (auxv[0] == AT_RANDOM) { - thepool = READ64LE((const char *)auxv[1]); - return; - } - } - thepool = kStartTsc; -} - -const void *const g_rand64_init[] initarray = {rand64_init}; diff --git a/libc/rand/randf.c b/libc/rand/randf.c deleted file mode 100644 index 7bb29080c..000000000 --- a/libc/rand/randf.c +++ /dev/null @@ -1,27 +0,0 @@ -/*-*- 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 "libc/limits.h" -#include "libc/rand/internal.h" -#include "libc/rand/lcg.internal.h" -#include "libc/rand/rand.h" - -float randf(void) { - return (double)(int)(KnuthLinearCongruentialGenerator(&g_rando) >> 32) / - INT_MAX; -} diff --git a/libc/rand/rdrand.c b/libc/rand/rdrand.c index 8a42afb1c..b431b4ee5 100644 --- a/libc/rand/rdrand.c +++ b/libc/rand/rdrand.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/bits/asmflag.h" #include "libc/errno.h" #include "libc/nexgen32e/x86feature.h" #include "libc/rand/rand.h" @@ -55,9 +55,12 @@ static dontinline uint64_t rdrand_failover(void) { * aren't available then we try /dev/urandom and if that fails, we try * getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid(). * - * This function takes between 10 nanoseconds to several microseconds. - * + * @note this function could block a nontrivial time on old computers + * @note this function is indeed intended for cryptography + * @note this function takes around 300 cycles * @see rngset(), rdseed(), rand64() + * @asyncsignalsafe + * @vforksafe */ uint64_t rdrand(void) { int i; diff --git a/libc/rand/rdseed.c b/libc/rand/rdseed.c index 192ec71be..3852f3175 100644 --- a/libc/rand/rdseed.c +++ b/libc/rand/rdseed.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/bits/asmflag.h" #include "libc/nexgen32e/x86feature.h" #include "libc/rand/rand.h" #include "libc/stdio/stdio.h" @@ -31,9 +31,12 @@ * sysctl(KERN_ARND). If those aren't available then we try /dev/urandom * and if that fails, we use RDTSC and getpid(). * - * This function takes about 32 nanoseconds. - * + * @note this function could block a nontrivial time on old computers + * @note this function is indeed intended for cryptography + * @note this function takes around 800 cycles * @see rngset(), rdrand(), rand64() + * @asyncsignalsafe + * @vforksafe */ uint64_t rdseed(void) { int i; diff --git a/libc/rand/real1.c b/libc/rand/real1.c index 1d053fb36..d73469c38 100644 --- a/libc/rand/real1.c +++ b/libc/rand/real1.c @@ -21,9 +21,9 @@ /** * Generates number on [0,1]-real-interval, e.g. * - * double x = _real1(vigna()) + * double x = _real1(lemur64()) * - * @see vigna(), mt19937() + * @see lemur64(), mt19937() */ double _real1(uint64_t x) { return 1. / 9007199254740991. * (x >> 11); diff --git a/libc/rand/real2.c b/libc/rand/real2.c index 9b8b28e0a..b722b3b34 100644 --- a/libc/rand/real2.c +++ b/libc/rand/real2.c @@ -21,9 +21,9 @@ /** * Generates number on [0,1)-real-interval, e.g. * - * double x = _real2(vigna()) + * double x = _real2(lemur64()) * - * @see vigna(), mt19937() + * @see lemur64(), mt19937() */ double _real2(uint64_t x) { return 1. / 9007199254740992. * (x >> 11); diff --git a/libc/rand/real3.c b/libc/rand/real3.c index 1a59b3713..ac0cadb3a 100644 --- a/libc/rand/real3.c +++ b/libc/rand/real3.c @@ -21,9 +21,9 @@ /** * Generates number on (0,1)-real-interval, e.g. * - * double x = _real3(vigna()) + * double x = _real3(lemur64()) * - * @see vigna(), mt19937() + * @see lemur64(), mt19937() */ double _real3(uint64_t x) { return 1. / 4503599627370496. * ((x >> 12) + .5); diff --git a/libc/rand/vigna.c b/libc/rand/vigna.c index 803dd45b5..36443295c 100644 --- a/libc/rand/vigna.c +++ b/libc/rand/vigna.c @@ -16,7 +16,6 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/xadd.h" #include "libc/rand/rand.h" static uint64_t g_vigna; @@ -40,9 +39,8 @@ static uint64_t g_vigna; * static uint64_t s = 0; * uint64_t x = svigna_r(&s); * - * This function is the fastest way to generate good scalar pseudorandom - * numbers that aren't truncated. If you want to fill a buffer with data - * then rngset() implements vigna's algorithm to do that extremely well: + * If you want to fill a buffer with data then rngset() implements + * vigna's algorithm to do that extremely well: * * char buf[4096]; * rngset(buf, sizeof(buf), vigna, 0); @@ -52,6 +50,9 @@ static uint64_t g_vigna; * want true random data then consider rdseed, rdrand, and getrandom. * * @return 64 bits of pseudorandom data + * @note this function is not intended for cryptography + * @note this function passes bigcrush and practrand + * @note this function takes at minimum 4 cycles */ uint64_t vigna(void) { return vigna_r(&g_vigna); diff --git a/libc/runtime/abort-nt.c b/libc/runtime/abort-nt.c deleted file mode 100644 index fc095cb61..000000000 --- a/libc/runtime/abort-nt.c +++ /dev/null @@ -1,35 +0,0 @@ -/*-*- 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 "libc/calls/internal.h" -#include "libc/calls/typedef/sigaction_f.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/sig.h" - -textwindows wontreturn void sys_abort_nt(void) { - int rva; - siginfo_t info; - bzero(&info, sizeof(info)); - info.si_signo = SIGABRT; - rva = __sighandrvas[SIGABRT]; - if (rva >= kSigactionMinRva) { - ((sigaction_f)(_base + rva))(SIGABRT, &info, NULL); - } - _Exit(128 + SIGABRT); -} diff --git a/libc/runtime/abort.S b/libc/runtime/abort.S deleted file mode 100644 index 2d7bf3e08..000000000 --- a/libc/runtime/abort.S +++ /dev/null @@ -1,61 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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 "libc/dce.h" -#include "libc/runtime/internal.h" -#include "libc/sysv/consts/sig.h" -#include "libc/sysv/consts/nr.h" -#include "libc/macros.internal.h" -.privileged - -// Terminates program abnormally. -// -// This function first tries to trigger your SIGABRT handler. If -// there isn't one or execution resumes, then abort() terminates -// the program using an escalating variety methods of increasing -// brutality. -// -// @forcealignargpointer -// @asyncsignalsafe -// @noreturn -abort: push %rbp - mov %rsp,%rbp - and $-16,%rsp - sub $16,%rsp -#if SupportsWindows() - testb IsWindows() - jnz sys_abort_nt -#endif - mov SIG_SETMASK,%edi - mov %rsp,%rsi - push $0xffffffffffffffdf # all bits blocked but SIGABRT - push $0xffffffffffffffff # assumes von neum. arithmetic - pop 8(%rsi) - pop (%rsi) - xor %edx,%edx # don't care about old sigmask - pushpop 4*4,%r10 # sizeof(sigset_t) for systemd - mov __NR_sigprocmask,%eax # sys_sigprocmask is hookable - syscall - mov __NR_getpid,%eax - syscall - mov %eax,%edi - mov SIGABRT,%esi - mov __NR_kill,%eax - syscall # avoid hook and less bt noise - call _Exit - .endfn abort,globl,protected diff --git a/libc/runtime/abort.greg.c b/libc/runtime/abort.greg.c new file mode 100644 index 000000000..883542945 --- /dev/null +++ b/libc/runtime/abort.greg.c @@ -0,0 +1,47 @@ +/*-*- 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 2022 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/sig.internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/struct/sigset.h" +#include "libc/dce.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/sig.h" + +/** + * Terminates program abnormally. + * + * This function first tries to trigger your SIGABRT handler. If + * there isn't one or execution resumes, then abort() terminates + * the program using an escalating variety methods of increasing + * brutality. + * + * @asyncsignalsafe + * @noreturn + */ +privileged void abort(void) { + sigset_t sm; + sigfillset(&sm); + sigdelset(&sm, SIGABRT); + sigprocmask(SIG_SETMASK, &sm, 0); + raise(SIGABRT); + __restorewintty(); + _Exit(128 + SIGABRT); +} diff --git a/libc/runtime/arch_prctl.c b/libc/runtime/arch_prctl.c index 6cd3ec76b..b8123e1e2 100644 --- a/libc/runtime/arch_prctl.c +++ b/libc/runtime/arch_prctl.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/asmflag.h" #include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/dce.h" @@ -113,12 +114,14 @@ static int arch_prctl_freebsd(int code, int64_t addr) { static privileged dontinline int arch_prctl_xnu(int code, int64_t addr) { int ax; + bool failed; switch (code) { case ARCH_SET_GS: - asm volatile("syscall" - : "=a"(ax) - : "0"(0x3000003), "D"(addr - 0x8a0 /* wat */) + asm volatile(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(failed), "=a"(ax) + : "1"(0x3000003), "D"(addr - 0x8a0 /* wat */) : "rcx", "r11", "memory", "cc"); + if (failed) errno = ax, ax = -1; return ax; case ARCH_GET_FS: case ARCH_SET_FS: @@ -130,21 +133,30 @@ static privileged dontinline int arch_prctl_xnu(int code, int64_t addr) { } static privileged dontinline int arch_prctl_openbsd(int code, int64_t addr) { + bool failed; int64_t rax; switch (code) { case ARCH_GET_FS: - asm volatile("syscall" - : "=a"(rax) - : "0"(0x014a /* __get_tcb */) + asm volatile(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(failed), "=a"(rax) + : "1"(0x014a /* __get_tcb */) : "rcx", "r11", "cc", "memory"); + if (failed) { + errno = rax; + return -1; + } *(int64_t *)addr = rax; return 0; case ARCH_SET_FS: - asm volatile("syscall" - : "=a"(rax) - : "0"(0x0149 /* __set_tcb */), "D"(addr) + asm volatile(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(failed), "=a"(rax) + : "1"(0x0149 /* __set_tcb */), "D"(addr) : "rcx", "r11", "cc", "memory"); - return 0; + if (failed) { + errno = rax; + rax = -1; + } + return rax; case ARCH_GET_GS: case ARCH_SET_GS: return enosys(); @@ -161,6 +173,8 @@ static struct InterruptibleCall g_fsgs_icall; */ int arch_prctl(int code, int64_t addr) { void *fn = arch_prctl_fsgsbase; + +#if 0 if (!g_fsgs_once) { g_fsgs_once = true; if (X86_HAVE(FSGSBASE)) { @@ -180,6 +194,8 @@ int arch_prctl(int code, int64_t addr) { if (g_fsgs_once == 2) { return arch_prctl_fsgsbase(code, addr); } +#endif + switch (__hostos) { case METAL: return arch_prctl_msr(code, addr); diff --git a/libc/runtime/arememoryintervalsok.c b/libc/runtime/arememoryintervalsok.c index 8c20eb623..1a4969a14 100644 --- a/libc/runtime/arememoryintervalsok.c +++ b/libc/runtime/arememoryintervalsok.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/runtime/memtrack.internal.h" noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) { @@ -24,7 +24,7 @@ noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) { int i; for (i = 0; i < mm->i; ++i) { if (mm->p[i].y < mm->p[i].x) { - SYSDEBUG("AreMemoryIntervalsOk() y should be >= x!"); + STRACE("AreMemoryIntervalsOk() y should be >= x!"); return false; } if (i) { @@ -34,7 +34,7 @@ noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) { } } else { if (!(mm->p[i - 1].y + 1 <= mm->p[i].x)) { - SYSDEBUG("AreMemoryIntervalsOk() out of order or overlap!"); + STRACE("AreMemoryIntervalsOk() out of order or overlap!"); return false; } } diff --git a/libc/runtime/clearenv.c b/libc/runtime/clearenv.c index 46308f92a..c37f1fb53 100644 --- a/libc/runtime/clearenv.c +++ b/libc/runtime/clearenv.c @@ -16,12 +16,14 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/strace.internal.h" #include "libc/runtime/runtime.h" /** * Removes all environment variables. */ int clearenv(void) { + STRACE("clearenv() → 0"); environ = NULL; return 0; } diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c deleted file mode 100644 index 7481f84b2..000000000 --- a/libc/runtime/clone.c +++ /dev/null @@ -1,107 +0,0 @@ -/*-*- 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/internal.h" -#include "libc/dce.h" -#include "libc/nexgen32e/nt2sysv.h" -#include "libc/nexgen32e/stackframe.h" -#include "libc/nt/runtime.h" -#include "libc/nt/thread.h" -#include "libc/sysv/consts/clone.h" -#include "libc/sysv/consts/nr.h" -#include "libc/sysv/errfuns.h" - -struct WinThread { - int (*func)(void *); - void *param; - void *stack; -}; - -static noasan textwindows uint32_t winthread(void *param) { - struct WinThread *wt = param; - asm volatile("mov\t%%rbp,%%r14\n\t" - "mov\t%%rsp,%%r15\n\t" - "xor\t%%ebp,%%ebp\n\t" - "mov\t%2,%%rsp\n\t" - "call\t*%0\n\t" - "mov\t%%r14,%%rbp\n\t" - "mov\t%%r15,%%rsp" - : /* no outputs */ - : "m"(wt->func), "D"(wt->param), "m"(wt->stack) - : "r14", "r15", "memory"); - return 0; -} - -/** - * Creates thread. - * - * @note CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND creates thread - * @note CLONE_VFORK|CLONE_VM|SIGCHLD does vfork() - * @note SIGCHLD does fork() - */ -privileged int clone(int (*f)(void *), void *stack, int flags, void *arg, ...) { - int64_t h; - va_list va; - intptr_t ax; - uint32_t tid; - int32_t *ptid; - register void *tls asm("r8"); - register int32_t *ctid asm("r10"); - register int (*func)(void *) asm("r9"); - if (IsLinux() || IsNetbsd()) { - va_start(va, arg); - ptid = va_arg(va, int32_t *); - tls = va_arg(va, void *); - ctid = va_arg(va, int32_t *); - va_end(va); - func = f; - stack = (void *)(((uintptr_t)stack & -16) - 8); - *(intptr_t *)stack = (intptr_t)arg; - asm volatile("syscall" - : "=a"(ax) - : "0"(__NR_clone), "D"(flags), "S"(stack), "d"(ptid), - "r"(ctid), "r"(tls), "r"(func) - : "rcx", "r11", "memory"); - if (ax) return ax; - asm volatile("xor\t%%ebp,%%ebp\n\t" - "pop\t%%rdi\n\t" - "call\t%1" - : "=a"(ax) - : "r"(func) - : "memory"); - asm volatile("syscall" - : /* no outputs */ - : "a"(__NR_exit), "D"(ax) - : "memory"); - unreachable; - } else if (IsWindows()) { - if (flags == (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)) { - if ((h = CreateThread(0, PAGESIZE, NT2SYSV(winthread), - &(struct WinThread){f, arg, stack}, 0, &tid))) { - CloseHandle(h); - return tid; - } else { - return __winerr(); - } - } else { - return einval(); - } - } else { - return enosys(); - } -} diff --git a/libc/runtime/close_s.c b/libc/runtime/close_s.c index 3246b090f..431f251f9 100644 --- a/libc/runtime/close_s.c +++ b/libc/runtime/close_s.c @@ -16,8 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" #include "libc/calls/calls.h" +#include "libc/intrin/lockxchg.h" #include "libc/runtime/runtime.h" /** diff --git a/libc/runtime/construct.S b/libc/runtime/construct.S index a127b9b15..953e8b4d1 100644 --- a/libc/runtime/construct.S +++ b/libc/runtime/construct.S @@ -19,7 +19,6 @@ #include "libc/runtime/internal.h" #include "libc/macros.internal.h" .text.startup -.source __FILE__ // Calls global initialization functions. // diff --git a/libc/runtime/cosmo.S b/libc/runtime/cosmo.S index 5760a93b0..df505099e 100644 --- a/libc/runtime/cosmo.S +++ b/libc/runtime/cosmo.S @@ -21,6 +21,7 @@ #include "libc/notice.inc" #include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/map.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" .text.startup @@ -37,6 +38,10 @@ cosmo: push %rbp mov %rsi,%r13 mov %rdx,%r14 mov %rcx,%r15 +#ifdef SYSDEBUG + call __strace_init + mov %eax,%r12d +#endif /* SYSDEBUG */ #ifdef __FAST_MATH__ push %rax stmxcsr (%rsp) @@ -72,19 +77,27 @@ cosmo: push %rbp .endfn cosmo,weak #ifdef __PG__ - .init.start 800,_init_ftrace + .init.start 306,_init_ftrace push %rdi push %rsi - mov %r12d,%edi - mov %r13,%rsi - mov %r14,%rdx - mov %r15,%rcx - call program_executable_name_init - mov %r12d,%edi - mov %r13,%rsi call ftrace_init mov %eax,%r12d pop %rsi pop %rdi - .init.end 800,_init_ftrace + .init.end 306,_init_ftrace +#endif + +#if IsModeDbg() +#ifdef SYSDEBUG + .init.start 307,_init_printargs + cmpl $0,__strace(%rip) + jz 1f + push %rdi + push %rsi + loadstr STRACE_PROLOGUE,di + call __printargs + pop %rsi + pop %rdi +1: .init.end 307,_init_printargs +#endif #endif diff --git a/libc/runtime/cxaatexit.internal.h b/libc/runtime/cxaatexit.internal.h index bb7c17254..9da432b53 100644 --- a/libc/runtime/cxaatexit.internal.h +++ b/libc/runtime/cxaatexit.internal.h @@ -1,8 +1,8 @@ #ifndef COSMOPOLITAN_LIBC_RUNTIME_CXAATEXIT_H_ #define COSMOPOLITAN_LIBC_RUNTIME_CXAATEXIT_H_ +#include "libc/stdio/stdio.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#include "libc/stdio/stdio.h" struct CxaAtexitBlocks { struct CxaAtexitBlock { diff --git a/libc/runtime/describeos.c b/libc/runtime/describeos.c deleted file mode 100644 index ded8f3185..000000000 --- a/libc/runtime/describeos.c +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- 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 "libc/dce.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" - -char *describeos(char *buf, size_t size) { - const char *s; - if (IsLinux()) { - s = "gnu/systemd"; - } else if (IsXnu()) { - s = "xnu's not unix"; - } else if (IsFreebsd()) { - s = "freebesiyatadishmaya"; - } else if (IsOpenbsd()) { - s = "openbsd"; - } else if (IsWindows()) { - s = "the new technology"; - } else { - s = "wut"; - } - return memccpy(buf, s, '\0', size); -} diff --git a/libc/runtime/directmap-nt.c b/libc/runtime/directmap-nt.c deleted file mode 100644 index e50ce99d6..000000000 --- a/libc/runtime/directmap-nt.c +++ /dev/null @@ -1,105 +0,0 @@ -/*-*- 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 "libc/calls/calls.h" -#include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" -#include "libc/macros.internal.h" -#include "libc/nt/enum/filemapflags.h" -#include "libc/nt/enum/pageflags.h" -#include "libc/nt/memory.h" -#include "libc/nt/runtime.h" -#include "libc/nt/struct/overlapped.h" -#include "libc/runtime/directmap.internal.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/prot.h" - -textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size, - int prot, int flags, - int64_t handle, int64_t off) { - /* asan runtime depends on this function */ - uint32_t got; - size_t i, upsize; - struct DirectMap dm; - struct NtOverlapped op; - if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE) && handle != -1) { - /* - * WIN32 claims it can do COW mappings but we still haven't found a - * combination of flags, that'll cause Windows to actually do this! - */ - upsize = ROUNDUP(size, FRAMESIZE); - dm.maphandle = CreateFileMappingNuma(-1, &kNtIsInheritable, - kNtPageExecuteReadwrite, upsize >> 32, - upsize, NULL, kNtNumaNoPreferredNode); - SYSDEBUG("CreateFileMappingNuma(-1, kNtPageExecuteReadwrite, 0x%x/0x%x) -> " - "0x%x", - upsize, size, dm.maphandle); - if (dm.maphandle) { - dm.addr = - MapViewOfFileExNuma(dm.maphandle, kNtFileMapWrite | kNtFileMapExecute, - 0, 0, upsize, addr, kNtNumaNoPreferredNode); - SYSDEBUG("MapViewOfFileExNuma(WX, 0x%x) -> addr:0x%x", addr, dm.addr); - if (dm.addr) { - for (i = 0; i < size; i += got) { - got = 0; - op.Internal = 0; - op.InternalHigh = 0; - op.Pointer = (void *)(uintptr_t)i; - op.hEvent = 0; - if (!ReadFile(handle, (char *)dm.addr + i, size - i, &got, &op)) { - break; - } - } - if (i == size) { - return dm; - } - UnmapViewOfFile(dm.addr); - } - CloseHandle(dm.maphandle); - } - } else { - dm.maphandle = CreateFileMappingNuma( - handle, &kNtIsInheritable, - (prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead, - handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL, - kNtNumaNoPreferredNode); - SYSDEBUG("CreateFileMappingNuma(fhand:%d, prot:%s, size:0x%x) -> " - "handle:0x%x", - handle, (prot & PROT_WRITE) ? "XRW" : "XR", - handle != -1 ? 0 : size); - if (dm.maphandle) { - dm.addr = MapViewOfFileExNuma( - dm.maphandle, - (prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute - : kNtFileMapRead | kNtFileMapExecute, - off >> 32, off, size, addr, kNtNumaNoPreferredNode); - SYSDEBUG( - "MapViewOfFileExNuma(prot:%s, off:0x%x, size:0x%x, addr:0x%x) -> " - "addr:0x%x", - (prot & PROT_WRITE) ? "WX" : "RX", off, size, addr, dm.addr); - if (dm.addr) { - return dm; - } else { - CloseHandle(dm.maphandle); - } - } - } - dm.maphandle = kNtInvalidHandleValue; - dm.addr = (void *)(intptr_t)__winerr(); - return dm; -} diff --git a/libc/runtime/directmap.internal.h b/libc/runtime/directmap.internal.h index 6bafebc93..a8f9911e6 100644 --- a/libc/runtime/directmap.internal.h +++ b/libc/runtime/directmap.internal.h @@ -3,15 +3,21 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +struct ProtectNt { + uint32_t flags1; + uint32_t flags2; +}; + struct DirectMap { void *addr; int64_t maphandle; }; struct DirectMap sys_mmap(void *, size_t, int, int, int, int64_t); -struct DirectMap sys_mmap_nt(void *, size_t, int, int, int64_t, int64_t); +struct DirectMap sys_mmap_nt(void *, size_t, int, int, int, int64_t); struct DirectMap sys_mmap_metal(void *, size_t, int, int, int, int64_t); int sys_munmap_metal(void *, size_t); +uint32_t __prot2nt(int, bool); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/runtime/dsohandle.S b/libc/runtime/dsohandle.S index 698c09d99..136dd405b 100644 --- a/libc/runtime/dsohandle.S +++ b/libc/runtime/dsohandle.S @@ -18,9 +18,10 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" #include "libc/notice.inc" -.source __FILE__ + .underrun // Uniquely identifies each artifact linked in an address space. __dso_handle: .quad __dso_handle .endobj __dso_handle,globl,hidden + .overrun diff --git a/libc/runtime/exit.c b/libc/runtime/exit.c index e2a177998..da4e882d1 100644 --- a/libc/runtime/exit.c +++ b/libc/runtime/exit.c @@ -16,13 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/pushpop.h" #include "libc/bits/weaken.h" -#include "libc/dce.h" -#include "libc/nt/console.h" -#include "libc/nt/enum/consolemodeflags.h" -#include "libc/nt/pedef.internal.h" -#include "libc/nt/runtime.h" +#include "libc/calls/strace.internal.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" @@ -39,17 +34,13 @@ */ wontreturn void exit(int exitcode) { const uintptr_t *p; + STRACE("exit(%d)", exitcode); if (weaken(__cxa_finalize)) { weaken(__cxa_finalize)(NULL); } for (p = __fini_array_end; p > __fini_array_start;) { ((void (*)(void))(*--p))(); } - if (SupportsWindows() && __ntconsolemode) { - SetConsoleMode(GetStdHandle(pushpop(kNtStdInputHandle)), __ntconsolemode); - SetConsoleMode(GetStdHandle(pushpop(kNtStdOutputHandle)), - kNtEnableProcessedOutput | kNtEnableWrapAtEolOutput | - kNtEnableVirtualTerminalProcessing); - } + __restorewintty(); _Exit(exitcode); } diff --git a/libc/runtime/findcombinary.c b/libc/runtime/findcombinary.c index 9a0cad457..f780ade4d 100644 --- a/libc/runtime/findcombinary.c +++ b/libc/runtime/findcombinary.c @@ -39,7 +39,7 @@ const char *FindComBinary(void) { const char *p; if (!g_findcombinary.once) { g_findcombinary.once = true; - if ((p = program_executable_name) && + if ((p = GetProgramExecutableName()) && (len = strlen(p)) < ARRAYLEN(g_findcombinary.buf)) { g_findcombinary.res = memcpy(g_findcombinary.buf, p, len + 1); if (len > 4 && memcmp(&g_findcombinary.buf[len - 4], ".dbg", 4) == 0) { diff --git a/libc/runtime/finddebugbinary.c b/libc/runtime/finddebugbinary.c index 98ab23545..aee215169 100644 --- a/libc/runtime/finddebugbinary.c +++ b/libc/runtime/finddebugbinary.c @@ -17,15 +17,11 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" -#include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" -#include "libc/calls/sysdebug.internal.h" -#include "libc/errno.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" #include "libc/str/str.h" -#include "libc/sysv/consts/auxv.h" /** * Returns path of binary with the debug information, or null. @@ -35,22 +31,22 @@ const char *FindDebugBinary(void) { static bool once; static char *res; - static char buf[PATH_MAX + 1]; + static char buf[PATH_MAX]; char *p; size_t n; if (!once) { if (!(res = getenv("COMDBG"))) { - p = program_executable_name; + p = GetProgramExecutableName(); n = strlen(p); if (n > 4 && READ32LE(p + n - 4) == READ32LE(".dbg")) { res = p; } else if (n > 4 && READ32LE(p + n - 4) == READ32LE(".com") && - n + 4 <= PATH_MAX) { + n + 4 < ARRAYLEN(buf)) { mempcpy(mempcpy(buf, p, n), ".dbg", 5); if (fileexists(buf)) { res = buf; } - } else if (n + 8 <= PATH_MAX) { + } else if (n + 8 < ARRAYLEN(buf)) { mempcpy(mempcpy(buf, p, n), ".com.dbg", 9); if (fileexists(buf)) { res = buf; diff --git a/libc/runtime/fork-nt.c b/libc/runtime/fork-nt.c index c455c792c..4fd7fc4c5 100644 --- a/libc/runtime/fork-nt.c +++ b/libc/runtime/fork-nt.c @@ -16,40 +16,56 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" #include "libc/bits/weaken.h" -#include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/ntspawn.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/fmt/itoa.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" +#include "libc/mem/alloca.h" +#include "libc/mem/mem.h" #include "libc/nexgen32e/nt2sysv.h" -#include "libc/nt/dll.h" +#include "libc/nt/console.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/creationdisposition.h" +#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/enum/filemapflags.h" -#include "libc/nt/enum/memflags.h" #include "libc/nt/enum/pageflags.h" +#include "libc/nt/enum/processcreationflags.h" #include "libc/nt/enum/startf.h" -#include "libc/nt/enum/wt.h" #include "libc/nt/ipc.h" #include "libc/nt/memory.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/nt/signals.h" -#include "libc/nt/synchronization.h" -#include "libc/nt/thread.h" +#include "libc/nt/struct/ntexceptionpointers.h" #include "libc/runtime/directmap.internal.h" +#include "libc/runtime/internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/auxv.h" +#include "libc/sock/ntstdin.internal.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" -#include "libc/sysv/consts/sig.h" -#include "libc/sysv/errfuns.h" -static textwindows noasan char16_t *ParseInt(char16_t *p, int64_t *x) { +STATIC_YOINK("_check_sigchld"); + +extern int64_t __wincrashearly; +extern unsigned long long __kbirth; +extern unsigned char __data_start[]; /* αpε */ +extern unsigned char __data_end[]; /* αpε */ +extern unsigned char __bss_start[]; /* αpε */ +extern unsigned char __bss_end[]; /* αpε */ +bool32 __onntconsoleevent_nt(uint32_t); + +static textwindows wontreturn void AbortFork(const char *func) { + STRACE("fork() %s() failed %d", func, GetLastError()); + ExitProcess(177); +} + +static textwindows char16_t *ParseInt(char16_t *p, int64_t *x) { *x = 0; while (*p == ' ') p++; while ('0' <= *p && *p <= '9') { @@ -59,138 +75,252 @@ static textwindows noasan char16_t *ParseInt(char16_t *p, int64_t *x) { return p; } -static dontinline textwindows noasan bool ForkIo(int64_t h, void *buf, size_t n, - bool32 (*f)()) { - char *p; +static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n, + bool32 (*f)()) { size_t i; uint32_t x; - for (p = buf, i = 0; i < n; i += x) { + for (i = 0; i < n; i += x) { if (!f(h, p + i, n - i, &x, NULL)) { - return false; + return -1; } } - return true; + return i; } -static dontinline textwindows noasan void WriteAll(int64_t h, void *buf, - size_t n) { - if (!ForkIo(h, buf, n, WriteFile)) { - SYSDEBUG("fork() WriteFile(%zu) failed %d\n", n, GetLastError()); +static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n, + bool32 (*fn)(), const char *sf) { + ssize_t rc = ForkIo(h, buf, n, fn); + NTTRACE("%s(%ld, %'zu) → %'zd% m", sf, h, n, rc); + return rc != -1; +} + +static dontinline textwindows bool WriteAll(int64_t h, void *buf, size_t n) { + return ForkIo2(h, buf, n, WriteFile, "WriteFile"); +} + +static textwindows dontinline void ReadOrDie(int64_t h, void *buf, size_t n) { + if (!ForkIo2(h, buf, n, ReadFile, "ReadFile")) { + AbortFork("ReadFile"); } } -static textwindows dontinline noasan void ReadAll(int64_t h, void *buf, - size_t n) { - if (!ForkIo(h, buf, n, ReadFile)) { - SYSDEBUG("fork() ReadFile(%zu) failed %d\n", n, GetLastError()); +static textwindows int64_t MapOrDie(uint32_t prot, uint64_t size) { + int64_t h; + if ((h = CreateFileMapping(-1, 0, prot, size >> 32, size, 0))) { + return h; + } else { + AbortFork("MapOrDie"); } } -textwindows noasan noinstrument void WinMainForked(void) { - void *addr; +static textwindows void ViewOrDie(int64_t h, uint32_t access, size_t pos, + size_t size, void *base) { + void *got; + got = MapViewOfFileEx(h, access, pos >> 32, pos, size, base); + if (!got || (base && got != base)) { + AbortFork("ViewOrDie"); + } +} + +textwindows void WinMainForked(void) { + bool ok; jmp_buf jb; - long mapcount; - uint64_t size; - uint32_t i, varlen; + int64_t reader; + char *addr, *shad; struct DirectMap dm; - int64_t reader, writer; + uint64_t size, upsize; + int64_t savetsc, savebir; struct MemoryInterval *maps; - char16_t var[21 + 1 + 21 + 1]; - varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var)); - if (!varlen) return; - if (varlen >= ARRAYLEN(var)) ExitProcess(123); + char16_t fvar[21 + 1 + 21 + 1]; + uint32_t i, varlen, oldprot, savepid; + long mapcount, mapcapacity, specialz; + extern uint64_t ts asm("kStartTsc"); + + // check to see if the process was actually forked + // this variable should have the pipe handle numba + varlen = GetEnvironmentVariable(u"_FORK", fvar, ARRAYLEN(fvar)); + if (!varlen || varlen >= ARRAYLEN(fvar)) return; + NTTRACE("WinMainForked()"); SetEnvironmentVariable(u"_FORK", NULL); - ParseInt(ParseInt(var, &reader), &writer); - ReadAll(reader, jb, sizeof(jb)); - ReadAll(reader, &mapcount, sizeof(_mmi.i)); - maps = GlobalAlloc(0, mapcount * sizeof(*_mmi.p)); - ReadAll(reader, maps, mapcount * sizeof(*_mmi.p)); + ParseInt(fvar, &reader); + + // read the cpu state from the parent process & plus + // read the list of mappings from the parent process + // this is stored in a special secretive memory map! + // read ExtendMemoryIntervals for further details :| + maps = (void *)kMemtrackStart; + ReadOrDie(reader, jb, sizeof(jb)); + ReadOrDie(reader, &mapcount, sizeof(_mmi.i)); + ReadOrDie(reader, &mapcapacity, sizeof(_mmi.n)); + specialz = ROUNDUP(mapcapacity * sizeof(_mmi.p[0]), kMemtrackGran); + ViewOrDie(MapOrDie(kNtPageReadwrite, specialz), kNtFileMapWrite, 0, specialz, + maps); + ReadOrDie(reader, maps, mapcount * sizeof(_mmi.p[0])); + if (IsAsan()) { + shad = (char *)(((intptr_t)maps >> 3) + 0x7fff8000); + size = ROUNDUP(specialz >> 3, FRAMESIZE); + ViewOrDie(MapOrDie(kNtPageReadwrite, size), kNtFileMapWrite, 0, size, maps); + ReadOrDie(reader, shad, (mapcount * sizeof(_mmi.p[0])) >> 3); + } + + // read the heap mappings from the parent process for (i = 0; i < mapcount; ++i) { - addr = (void *)((uint64_t)maps[i].x << 16); - size = ((uint64_t)(maps[i].y - maps[i].x) << 16) + FRAMESIZE; + addr = (char *)((uint64_t)maps[i].x << 16); + size = maps[i].size; if (maps[i].flags & MAP_PRIVATE) { - CloseHandle(maps[i].h); - maps[i].h = - sys_mmap_nt(addr, size, maps[i].prot, maps[i].flags, -1, 0).maphandle; - ReadAll(reader, addr, size); + upsize = ROUNDUP(size, FRAMESIZE); + // we don't need to close the map handle because sys_mmap_nt + // doesn't mark it inheritable across fork() for MAP_PRIVATE + ViewOrDie((maps[i].h = MapOrDie(kNtPageExecuteReadwrite, upsize)), + kNtFileMapWrite | kNtFileMapExecute, 0, upsize, addr); + ReadOrDie(reader, addr, size); } else { - MapViewOfFileExNuma( - maps[i].h, - (maps[i].prot & PROT_WRITE) - ? kNtFileMapWrite | kNtFileMapExecute | kNtFileMapRead - : kNtFileMapExecute | kNtFileMapRead, - 0, 0, size, addr, kNtNumaNoPreferredNode); + // we can however safely inherit MAP_SHARED with zero copy + ViewOrDie(maps[i].h, + maps[i].readonlyfile ? kNtFileMapRead | kNtFileMapExecute + : kNtFileMapWrite | kNtFileMapExecute, + maps[i].offset, size, addr); } } - ReadAll(reader, _etext, _end - _etext); + + // read the .data and .bss program image sections + savepid = __pid; + savebir = __kbirth; + savetsc = ts; + ReadOrDie(reader, __data_start, __data_end - __data_start); + ReadOrDie(reader, __bss_start, __bss_end - __bss_start); + __pid = savepid; + __kbirth = savebir; + ts = savetsc; + + // apply fixups and reapply memory protections + _mmi.p = maps; + _mmi.n = specialz / sizeof(_mmi.p[0]); for (i = 0; i < mapcount; ++i) { - _mmi.p[i].h = maps[i].h; + if (!VirtualProtect((void *)((uint64_t)maps[i].x << 16), maps[i].size, + __prot2nt(maps[i].prot, maps[i].iscow), &oldprot)) { + AbortFork("VirtualProtect"); + } } - CloseHandle(reader); - CloseHandle(writer); - GlobalFree(maps); + + // mitosis complete + if (!CloseHandle(reader)) { + AbortFork("CloseHandle"); + } + + // rewrap the stdin named pipe hack + // since the handles closed on fork + if (weaken(ForkNtStdinWorker)) weaken(ForkNtStdinWorker)(); + struct Fds *fds = VEIL("r", &g_fds); + fds->p[0].handle = fds->__init_p[0].handle = GetStdHandle(kNtStdInputHandle); + fds->p[1].handle = fds->__init_p[1].handle = GetStdHandle(kNtStdOutputHandle); + fds->p[2].handle = fds->__init_p[2].handle = GetStdHandle(kNtStdErrorHandle); + + // untrack the forked children of the parent since we marked the + // CreateProcess() process handle below as non-inheritable + for (i = 0; i < fds->n; ++i) { + if (fds->p[i].kind == kFdProcess) { + fds->p[i].kind = 0; + fds->f = MIN(i, fds->f); + } + } + + // restore the crash reporting stuff if (weaken(__wincrash_nt)) { + RemoveVectoredExceptionHandler(__wincrashearly); AddVectoredExceptionHandler(1, (void *)weaken(__wincrash_nt)); } + if (weaken(__onntconsoleevent_nt)) { + SetConsoleCtrlHandler(weaken(__onntconsoleevent_nt), 1); + } + + // jump back into function below longjmp(jb, 1); } textwindows int sys_fork_nt(void) { + bool ok; jmp_buf jb; + char **args, **args2; + char16_t pipename[64]; int64_t reader, writer; - int i, rc, pid, releaseme; - char *p, forkvar[6 + 21 + 1 + 21 + 1]; struct NtStartupInfo startinfo; + int i, n, pid, untrackpid, rc = -1; + char *p, forkvar[6 + 21 + 1 + 21 + 1]; struct NtProcessInformation procinfo; - if ((pid = releaseme = __reservefd()) == -1) return -1; if (!setjmp(jb)) { - if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) { + pid = untrackpid = __reservefd(-1); + reader = CreateNamedPipe(CreatePipeName(pipename), + kNtPipeAccessInbound | kNtFileFlagOverlapped, + kNtPipeTypeMessage | kNtPipeReadmodeMessage, 1, + 65536, 65536, 0, &kNtIsInheritable); + writer = CreateFile(pipename, kNtGenericWrite, 0, 0, kNtOpenExisting, + kNtFileFlagOverlapped, 0); + if (pid != -1 && reader != -1 && writer != -1) { p = stpcpy(forkvar, "_FORK="); - p += uint64toarray_radix10(reader, p), *p++ = ' '; - p += uint64toarray_radix10(writer, p); + p = FormatUint64(p, reader); bzero(&startinfo, sizeof(startinfo)); startinfo.cb = sizeof(struct NtStartupInfo); startinfo.dwFlags = kNtStartfUsestdhandles; - startinfo.hStdInput = g_fds.p[0].handle; - startinfo.hStdOutput = g_fds.p[1].handle; - startinfo.hStdError = g_fds.p[2].handle; - if (ntspawn(program_executable_name, __argv, environ, forkvar, - &kNtIsInheritable, NULL, true, 0, NULL, &startinfo, - &procinfo) != -1) { - CloseHandle(reader); + startinfo.hStdInput = __getfdhandleactual(0); + startinfo.hStdOutput = __getfdhandleactual(1); + startinfo.hStdError = __getfdhandleactual(2); + args = __argv; +#ifdef SYSDEBUG + // If --strace was passed to this program, then propagate it the + // forked process since the flag was removed by __intercept_flag + if (__strace > 0) { + for (n = 0; args[n];) ++n; + args2 = alloca((n + 2) * sizeof(char *)); + for (i = 0; i < n; ++i) args2[i] = args[i]; + args2[i++] = "--strace"; + args2[i] = 0; + args = args2; + } +#endif + if (ntspawn(GetProgramExecutableName(), args, environ, forkvar, 0, 0, + true, 0, 0, &startinfo, &procinfo) != -1) { CloseHandle(procinfo.hThread); - if (weaken(__sighandrvas) && - weaken(__sighandrvas)[SIGCHLD] == SIG_IGN) { - CloseHandle(procinfo.hProcess); - } else { + ok = WriteAll(writer, jb, sizeof(jb)) && + WriteAll(writer, &_mmi.i, sizeof(_mmi.i)) && + WriteAll(writer, &_mmi.n, sizeof(_mmi.n)) && + WriteAll(writer, _mmi.p, _mmi.i * sizeof(_mmi.p[0])); + if (IsAsan() && ok) { + ok = WriteAll(writer, (char *)(((intptr_t)_mmi.p >> 3) + 0x7fff8000), + (_mmi.i * sizeof(_mmi.p[0])) >> 3); + } + for (i = 0; i < _mmi.i && ok; ++i) { + if (_mmi.p[i].flags & MAP_PRIVATE) { + ok = WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16), + _mmi.p[i].size); + } + } + if (ok) ok = WriteAll(writer, __data_start, __data_end - __data_start); + if (ok) ok = WriteAll(writer, __bss_start, __bss_end - __bss_start); + if (ok) { + if (!CloseHandle(writer)) ok = false; + writer = -1; + } + if (ok) { g_fds.p[pid].kind = kFdProcess; g_fds.p[pid].handle = procinfo.hProcess; g_fds.p[pid].flags = O_CLOEXEC; - releaseme = -1; + g_fds.p[pid].zombie = false; + untrackpid = -1; + rc = pid; + } else { + TerminateProcess(procinfo.hProcess, 127); + CloseHandle(procinfo.hProcess); } - WriteAll(writer, jb, sizeof(jb)); - WriteAll(writer, &_mmi.i, sizeof(_mmi.i)); - WriteAll(writer, _mmi.p, _mmi.i * sizeof(*_mmi.p)); - for (i = 0; i < _mmi.i; ++i) { - if (_mmi.p[i].flags & MAP_PRIVATE) { - WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16), - ((uint64_t)(_mmi.p[i].y - _mmi.p[i].x) << 16) + FRAMESIZE); - } - } - WriteAll(writer, _etext, _end - _etext); - CloseHandle(writer); - } else { - rc = -1; } - rc = pid; - } else { - rc = __winerr(); } + if (reader != -1) CloseHandle(reader); + if (writer != -1) CloseHandle(writer); } else { rc = 0; } - if (releaseme != -1) { - __releasefd(releaseme); + if (untrackpid != -1) { + __releasefd(untrackpid); } return rc; } diff --git a/libc/runtime/fork.c b/libc/runtime/fork.c index 2c86fd8d6..ae9d242f3 100644 --- a/libc/runtime/fork.c +++ b/libc/runtime/fork.c @@ -17,9 +17,13 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/nt/process.h" +#include "libc/runtime/internal.h" /** * Creates new process. @@ -29,7 +33,7 @@ */ int fork(void) { axdx_t ad; - int ax, dx; + int ax, dx, parent; if (!IsWindows()) { ad = sys_fork(); ax = ad.ax; @@ -43,7 +47,19 @@ int fork(void) { ax = sys_fork_nt(); } if (!ax) { - __onfork(); + if (!IsWindows()) { + dx = sys_getpid().ax; + } else { + dx = GetCurrentProcessId(); + } + parent = __pid; + __pid = dx; + STRACE("fork() → 0 (child of %d)", parent); + if (weaken(__onfork)) { + weaken(__onfork)(); + } + } else { + STRACE("fork() → %d% m", ax); } return ax; } diff --git a/libc/runtime/fpreset.S b/libc/runtime/fpreset.S index 8aad22603..59a812b92 100644 --- a/libc/runtime/fpreset.S +++ b/libc/runtime/fpreset.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Re-initializes FPU. fpreset: diff --git a/libc/runtime/free_s.c b/libc/runtime/free_s.c index 84622ec8a..b0c8bc545 100644 --- a/libc/runtime/free_s.c +++ b/libc/runtime/free_s.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/intrin/lockxchg.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" diff --git a/libc/runtime/ftrace-hook.S b/libc/runtime/ftrace-hook.S index f17c1bb7a..a679c52b1 100644 --- a/libc/runtime/ftrace-hook.S +++ b/libc/runtime/ftrace-hook.S @@ -21,7 +21,7 @@ ftrace_hook: cmp $0,g_ftrace(%rip) - je 1f + jg 1f ret 1: push %rbp mov %rsp,%rbp diff --git a/libc/runtime/ftraceinit.c b/libc/runtime/ftraceinit.c deleted file mode 100644 index cd6af1c9f..000000000 --- a/libc/runtime/ftraceinit.c +++ /dev/null @@ -1,56 +0,0 @@ -/*-*- 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/runtime/runtime.h" -#include "libc/str/str.h" - -/** - * Enables plaintext function tracing if `--ftrace` flag is passed. - * - * The `--ftrace` CLI arg is removed before main() is called. This code - * is intended for diagnostic purposes and assumes binaries are - * trustworthy and stack isn't corrupted. Logging plain text allows - * program structure to easily be visualized and hotspots identified w/ - * `sed | sort | uniq -c | sort`. A compressed trace can be made by - * appending `--ftrace 2>&1 | gzip -4 >trace.gz` to the CLI arguments. - * - * @see libc/runtime/_init.S for documentation - */ -textstartup int ftrace_init(int argc, char *argv[]) { - int i; - bool foundflag; - foundflag = false; - for (i = 1; i <= argc; ++i) { - if (!foundflag) { - if (argv[i]) { - if (strcmp(argv[i], "--ftrace") == 0) { - foundflag = true; - } else if (strcmp(argv[i], "----ftrace") == 0) { - strcpy(argv[i], "--ftrace"); - } - } - } else { - argv[i - 1] = argv[i]; - } - } - if (foundflag) { - --argc; - ftrace_install(); - } - return argc; -} diff --git a/libc/runtime/ftraceinit.greg.c b/libc/runtime/ftraceinit.greg.c new file mode 100644 index 000000000..48bbc05aa --- /dev/null +++ b/libc/runtime/ftraceinit.greg.c @@ -0,0 +1,41 @@ +/*-*- 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/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" + +/** + * Enables plaintext function tracing if `--ftrace` flag is passed. + * + * The `--ftrace` CLI arg is removed before main() is called. This code + * is intended for diagnostic purposes and assumes binaries are + * trustworthy and stack isn't corrupted. Logging plain text allows + * program structure to easily be visualized and hotspots identified w/ + * `sed | sort | uniq -c | sort`. A compressed trace can be made by + * appending `--ftrace 2>&1 | gzip -4 >trace.gz` to the CLI arguments. + * + * @see libc/runtime/_init.S for documentation + */ +textstartup int ftrace_init(void) { + if (__intercept_flag(&__argc, __argv, "--ftrace")) { + ftrace_install(); + ++g_ftrace; + } + return __argc; +} diff --git a/libc/runtime/ftracer.c b/libc/runtime/ftracer.c index 013b724b2..6f79f9b15 100644 --- a/libc/runtime/ftracer.c +++ b/libc/runtime/ftracer.c @@ -16,8 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" #include "libc/bits/safemacros.internal.h" +#include "libc/intrin/cmpxchg.h" +#include "libc/intrin/kprintf.h" #include "libc/log/libfatal.internal.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/rdtsc.h" @@ -30,6 +31,7 @@ #include "libc/stdio/stdio.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" +#include "libc/time/clockstonanos.internal.h" #pragma weak stderr @@ -47,9 +49,8 @@ void ftrace_hook(void); bool ftrace_enabled; static int g_skew; -static int g_lastsymbol; -static uint64_t laststamp; -static struct SymbolTable *g_symbols; +static int64_t g_lastaddr; +static uint64_t g_laststamp; static privileged noinstrument noasan noubsan int GetNestingLevelImpl( struct StackFrame *frame) { @@ -79,40 +80,33 @@ static privileged noinstrument noasan noubsan int GetNestingLevel( */ privileged noinstrument noasan noubsan void ftracer(void) { /* asan runtime depends on this function */ - int symbol; uint64_t stamp; static bool noreentry; struct StackFrame *frame; - if (!cmpxchg(&noreentry, 0, 1)) return; - if (ftrace_enabled && g_symbols) { + if (!_cmpxchg(&noreentry, 0, 1)) return; + if (ftrace_enabled) { stamp = rdtsc(); frame = __builtin_frame_address(0); frame = frame->next; - if ((symbol = __get_symbol(g_symbols, frame->addr)) != -1 && - symbol != g_lastsymbol) { - g_lastsymbol = symbol; - __printf("+ %*s%s %d\r\n", GetNestingLevel(frame) * 2, "", - __get_symbol_name(g_symbols, symbol), - (long)(unsignedsubtract(stamp, laststamp) / 3.3)); - laststamp = X86_HAVE(RDTSCP) ? rdtscp(0) : rdtsc(); + if (frame->addr != g_lastaddr) { + kprintf("+ %*s%t %d\r\n", GetNestingLevel(frame) * 2, "", frame->addr, + ClocksToNanos(stamp, g_laststamp)); + g_laststamp = X86_HAVE(RDTSCP) ? rdtscp(0) : rdtsc(); + g_lastaddr = frame->addr; } } noreentry = 0; } -textstartup void ftrace_install(void) { - const char *path; - if ((path = FindDebugBinary())) { - if ((g_symbols = OpenSymbolTable(path))) { - laststamp = kStartTsc; - g_lastsymbol = -1; - g_skew = GetNestingLevelImpl(__builtin_frame_address(0)); - ftrace_enabled = 1; - __hook(ftrace_hook, g_symbols); - } else { - __printf("error: --ftrace failed to open symbol table\r\n"); - } +textstartup int ftrace_install(void) { + if (GetSymbolTable()) { + g_lastaddr = -1; + g_laststamp = kStartTsc; + g_skew = GetNestingLevelImpl(__builtin_frame_address(0)); + ftrace_enabled = 1; + return __hook(ftrace_hook, GetSymbolTable()); } else { - __printf("error: --ftrace needs concomitant .com.dbg binary\r\n"); + kprintf("error: --ftrace failed to open symbol table\r\n"); + return -1; } } diff --git a/libc/runtime/gc.h b/libc/runtime/gc.h index 7229b65c9..5f507652e 100644 --- a/libc/runtime/gc.h +++ b/libc/runtime/gc.h @@ -10,7 +10,7 @@ void *_gc(void *) hidden; void *_defer(void *, void *) hidden; void __defer(struct StackFrame *, void *, void *) hidden; void __deferer(struct StackFrame *, void *, void *) hidden; -void _gclongjmp(jmp_buf, int) nothrow wontreturn; +void _gclongjmp(jmp_buf, int) dontthrow wontreturn; #if defined(__GNUC__) && !defined(__STRICT_ANSI__) #define _gc(THING) _defer((void *)_weakfree, (void *)(THING)) diff --git a/libc/runtime/getargmax.c b/libc/runtime/getargmax.c new file mode 100644 index 000000000..25aabc1ae --- /dev/null +++ b/libc/runtime/getargmax.c @@ -0,0 +1,33 @@ +/*-*- 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 2022 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/dce.h" +#include "libc/runtime/runtime.h" + +/** + * Returns `ARG_MAX` for host platform. + */ +int __arg_max(void) { + if (IsWindows()) return 32767; + if (IsLinux()) return 128 * 1024; + if (IsNetbsd()) return 256 * 1024; + if (IsFreebsd()) return 512 * 1024; + if (IsOpenbsd()) return 512 * 1024; + if (IsXnu()) return 1024 * 1024; + return ARG_MAX; +} diff --git a/libc/runtime/getdosargv.c b/libc/runtime/getdosargv.c index d21113715..ff97895fb 100644 --- a/libc/runtime/getdosargv.c +++ b/libc/runtime/getdosargv.c @@ -16,10 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" #include "libc/bits/bits.h" -#include "libc/bits/pushpop.h" #include "libc/bits/safemacros.internal.h" +#include "libc/nt/thunk/msabi.h" #include "libc/runtime/internal.h" #include "libc/str/str.h" #include "libc/str/tpenc.h" @@ -32,25 +31,23 @@ struct DosArgv { wint_t wc; }; -static textwindows noasan wint_t DecodeDosArgv(const char16_t **s) { +textwindows noasan void DecodeDosArgv(int ignore, struct DosArgv *st) { wint_t x, y; for (;;) { - if (!(x = *(*s)++)) break; - if (IsUtf16Cont(x)) continue; - if (IsUcs2(x)) { - return x; - } else { - if ((y = *(*s)++)) { - return MergeUtf16(x, y); + if (!(x = *st->s++)) break; + if (!IsUcs2(x)) { + if ((y = *st->s++)) { + x = MergeUtf16(x, y); } else { - return 0; + x = 0; } } + break; } - return x; + st->wc = x; } -static textwindows noasan void AppendDosArgv(struct DosArgv *st, wint_t wc) { +static textwindows noasan void AppendDosArgv(wint_t wc, struct DosArgv *st) { uint64_t w; w = tpenc(wc); do { @@ -59,6 +56,16 @@ static textwindows noasan void AppendDosArgv(struct DosArgv *st, wint_t wc) { } while (w >>= 8); } +static textwindows noasan int Count(int c, struct DosArgv *st) { + int ignore, n = 0; + asm("" : "=g"(ignore)); + while (st->wc == c) { + DecodeDosArgv(ignore, st); + n++; + } + return n; +} + /** * Tokenizes and transcodes Windows NT CLI args, thus avoiding * CommandLineToArgv() schlepping in forty megs of dependencies. @@ -81,49 +88,60 @@ static textwindows noasan void AppendDosArgv(struct DosArgv *st, wint_t wc) { textwindows noasan int GetDosArgv(const char16_t *cmdline, char *buf, size_t size, char **argv, size_t max) { bool inquote; - size_t i, argc, slashes, quotes; - struct DosArgv st; - st.s = cmdline; - st.p = buf; - st.pe = buf + size; + int i, argc, slashes, quotes, ignore; + static struct DosArgv st_; + struct DosArgv *st = &st_; + asm("" : "=g"(ignore)); + asm("" : "+r"(st)); + st->s = cmdline; + st->p = buf; + st->pe = buf + size; argc = 0; - st.wc = DecodeDosArgv(&st.s); - while (st.wc) { - while (st.wc && (st.wc == ' ' || st.wc == '\t')) { - st.wc = DecodeDosArgv(&st.s); + DecodeDosArgv(ignore, st); + while (st->wc) { + while (st->wc && (st->wc == ' ' || st->wc == '\t')) { + DecodeDosArgv(ignore, st); } - if (!st.wc) break; + if (!st->wc) break; if (++argc < max) { - argv[argc - 1] = st.p < st.pe ? st.p : NULL; + argv[argc - 1] = st->p < st->pe ? st->p : NULL; } inquote = false; - while (st.wc) { - if (!inquote && (st.wc == ' ' || st.wc == '\t')) break; - if (st.wc == '"' || st.wc == '\\') { - slashes = 0; - quotes = 0; - while (st.wc == '\\') st.wc = DecodeDosArgv(&st.s), slashes++; - while (st.wc == '"') st.wc = DecodeDosArgv(&st.s), quotes++; + while (st->wc) { + if (!inquote && (st->wc == ' ' || st->wc == '\t')) break; + if (st->wc == '"' || st->wc == '\\') { + slashes = Count('\\', st); + quotes = Count('"', st); if (!quotes) { - while (slashes--) AppendDosArgv(&st, '\\'); + while (slashes--) { + AppendDosArgv('\\', st); + } } else { - while (slashes >= 2) AppendDosArgv(&st, '\\'), slashes -= 2; - if (slashes) AppendDosArgv(&st, '"'), quotes--; + while (slashes >= 2) { + AppendDosArgv('\\', st); + slashes -= 2; + } + if (slashes) { + AppendDosArgv('"', st); + quotes--; + } if (quotes > 0) { if (!inquote) quotes--; - for (i = 3; i <= quotes + 1; i += 3) AppendDosArgv(&st, '"'); + for (i = 3; i <= quotes + 1; i += 3) { + AppendDosArgv('"', st); + } inquote = (quotes % 3 == 0); } } } else { - AppendDosArgv(&st, st.wc); - st.wc = DecodeDosArgv(&st.s); + AppendDosArgv(st->wc, st); + DecodeDosArgv(ignore, st); } } - AppendDosArgv(&st, '\0'); + AppendDosArgv('\0', st); } - AppendDosArgv(&st, '\0'); - if (size) buf[min(st.p - buf, size - 1)] = '\0'; + AppendDosArgv('\0', st); + if (size) buf[min(st->p - buf, size - 1)] = '\0'; if (max) argv[min(argc, max - 1)] = NULL; return argc; } diff --git a/libc/runtime/getdosenviron.c b/libc/runtime/getdosenviron.c index f1a4117d9..58f3e3bf1 100644 --- a/libc/runtime/getdosenviron.c +++ b/libc/runtime/getdosenviron.c @@ -32,7 +32,6 @@ static textwindows noasan noinstrument axdx_t Recode16to8(char *dst, wint_t x, y; for (v = r.ax = 0, r.dx = 0;;) { if (!(x = src[r.dx++])) break; - if (IsUtf16Cont(x)) continue; if (!IsUcs2(x)) { y = src[r.dx++]; x = MergeUtf16(x, y); diff --git a/libc/runtime/getinterpreterexecutablename.c b/libc/runtime/getinterpreterexecutablename.c new file mode 100644 index 000000000..2f3aa6c24 --- /dev/null +++ b/libc/runtime/getinterpreterexecutablename.c @@ -0,0 +1,82 @@ +/*-*- 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/internal.h" +#include "libc/dce.h" +#include "libc/macros.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/errfuns.h" + +/** + * Returns path of executable interperter. + * + * Unlike `program_executable_name` which is designed to figure out the + * absolute path of the first argument passed to `execve()`, what we do + * here is probe things like `/proc` and `sysctl()` to figure out if we + * were launched by something like `ape-loader`, and then we return its + * path. If we can't determine that path, possibly because we're on XNU + * or OpenBSD, then we return -1 with an error code. + * + * @param p receives utf8 output + * @param n is byte size of res buffer + * @return p on success or null w/ errno if out of buf or error + * @see program_invocation_short_name + * @see program_invocation_name + * @see program_executable_name + */ +char *GetInterpreterExecutableName(char *p, size_t n) { + int e; + size_t m; + int cmd[4]; + ssize_t rc; + char *r, *t; + e = errno; + if (n < 2) { + errno = ENAMETOOLONG; + } else if (IsWindows() || IsXnu()) { + if (strlen(GetProgramExecutableName()) < n) { + strcpy(p, GetProgramExecutableName()); + return p; + } + errno = ENAMETOOLONG; + } else if ((rc = sys_readlinkat(AT_FDCWD, "/proc/self/exe", p, n - 1)) > 0) { + p[rc] = 0; + return p; + } else if ((rc = sys_readlinkat(AT_FDCWD, "/proc/curproc/file", p, n - 1)) > + 0) { + errno = e; + p[rc] = 0; + return p; + } else if (IsFreebsd() || IsNetbsd()) { + cmd[0] = 1; // CTL_KERN + cmd[1] = 14; // KERN_PROC + if (IsFreebsd()) { // + cmd[2] = 12; // KERN_PROC_PATHNAME + } else { // + cmd[2] = 5; // KERN_PROC_PATHNAME + } // + cmd[3] = -1; // current process + if (sysctl(cmd, ARRAYLEN(cmd), p, &n, 0, 0) != -1) { + errno = e; + return p; + } + } + return 0; +} diff --git a/libc/runtime/getpagesize.S b/libc/runtime/getpagesize.S index f837fbb65..0db4acd92 100644 --- a/libc/runtime/getpagesize.S +++ b/libc/runtime/getpagesize.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns granularity of memory manager. getpagesize: diff --git a/libc/runtime/getsymbol.c b/libc/runtime/getsymbol.c deleted file mode 100644 index a480051d0..000000000 --- a/libc/runtime/getsymbol.c +++ /dev/null @@ -1,42 +0,0 @@ -/*-*- 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/runtime/symbols.internal.h" - -privileged noinstrument noasan noubsan int __get_symbol(struct SymbolTable *t, - intptr_t a) { - /* asan runtime depends on this function */ - unsigned l, m, r, n, k; - if (t) { - l = 0; - r = n = t->count; - k = a - t->addr_base; - while (l < r) { - m = (l + r) >> 1; - if (t->symbols[m].y < k) { - l = m + 1; - } else { - r = m; - } - } - if (l < n && t->symbols[l].x <= k && k <= t->symbols[l].y) { - return l; - } - } - return -1; -} diff --git a/libc/runtime/getsymboltable.greg.c b/libc/runtime/getsymboltable.greg.c new file mode 100644 index 000000000..60af4749a --- /dev/null +++ b/libc/runtime/getsymboltable.greg.c @@ -0,0 +1,166 @@ +/*-*- 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 "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/weaken.h" +#include "libc/calls/strace.internal.h" +#include "libc/macros.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.internal.h" +#include "libc/str/str.h" +#include "libc/str/undeflate.h" +#include "libc/x/x.h" +#include "libc/zip.h" +#include "libc/zipos/zipos.internal.h" + +static struct SymbolTable *g_symtab; + +/** + * Looks for `.symtab` in zip central directory. + */ +static ssize_t FindSymtabInZip(struct Zipos *zipos) { + size_t i, n, c; + c = GetZipCdirOffset(zipos->cdir); + n = GetZipCdirRecords(zipos->cdir); + for (i = 0; i < n; ++i, c += ZIP_CFILE_HDRSIZE(zipos->map + c)) { + if (ZIP_CFILE_NAMESIZE(zipos->map + c) == 7 && + READ32LE(ZIP_CFILE_NAME(zipos->map + c + 0)) == READ32LE(".sym") && + READ16LE(ZIP_CFILE_NAME(zipos->map + c + 4)) == READ16LE("ta") && + *ZIP_CFILE_NAME(zipos->map + c + 6) == 'b') { + return c; + } + } + return -1; +} + +/** + * Reads symbol table from zip directory. + * @note This code can't depend on dlmalloc() + */ +static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) { + ssize_t rc, cf, lf; + size_t size, size2; + struct DeflateState ds; + struct SymbolTable *res = 0; + if ((cf = FindSymtabInZip(zipos)) != -1) { + lf = GetZipCfileOffset(zipos->map + cf); + size = GetZipLfileUncompressedSize(zipos->map + lf); + size2 = ROUNDUP(size, FRAMESIZE); + if ((res = mapanon(size2))) { + switch (ZIP_LFILE_COMPRESSIONMETHOD(zipos->map + lf)) { + case kZipCompressionNone: + memcpy(res, (void *)ZIP_LFILE_CONTENT(zipos->map + lf), size); + break; +#if 0 + case kZipCompressionDeflate: + rc = undeflate(res, size, (void *)ZIP_LFILE_CONTENT(zipos->map + lf), + GetZipLfileCompressedSize(zipos->map + lf), &ds); + if (rc == -1) { + munmap(res, size2); + res = 0; + } + break; +#endif + default: + munmap(res, size2); + res = 0; + break; + } + } + } + STRACE("GetSymbolTableFromZip() → %p", res); + return res; +} + +/** + * Reads symbol table from .com.dbg file. + * @note This code can't depend on dlmalloc() + */ +static struct SymbolTable *GetSymbolTableFromElf(void) { + return OpenSymbolTable(FindDebugBinary()); +} + +/** + * Returns symbol table singleton. + * + * This uses multiple strategies to find the symbol table. The first + * strategy, depends on whether or not the following is linked: + * + * STATIC_YOINK("__zipos_get"); + * + * In that case, the symbol table may be read from `/zip/.symtab` which + * is generated by `o//tool/build/symtab.com`. The second strategy is to + * look for the concomitant `.com.dbg` executable, which may very well + * be the one currently executing, or it could be placed in the same + * folder as your `.com` binary, or lastly, it could be explicitly + * specified via the `COMDBG` environment variable. + * + * Function tracing is disabled throughout the duration of this call. + * Backtraces and other core runtime functionality depend on this. + * + * @return symbol table, or NULL w/ errno on first call + */ +struct SymbolTable *GetSymbolTable(void) { + struct Zipos *z; + if (!g_symtab && !__isworker) { + if (weaken(__zipos_get) && (z = weaken(__zipos_get)())) { + if ((g_symtab = GetSymbolTableFromZip(z))) { + g_symtab->names = + (uint32_t *)((char *)g_symtab + g_symtab->names_offset); + g_symtab->name_base = + (char *)((char *)g_symtab + g_symtab->name_base_offset); + } + } + if (!g_symtab) { + g_symtab = GetSymbolTableFromElf(); + } + } + return g_symtab; +} + +/** + * Returns low index into symbol table for address. + * + * @param t if null will be auto-populated only if already open + * @return index or -1 if nothing found + */ +privileged int __get_symbol(struct SymbolTable *t, intptr_t a) { + /* asan runtime depends on this function */ + unsigned l, m, r, n, k; + if (!t && g_symtab) { + t = g_symtab; + } + if (t) { + l = 0; + r = n = t->count; + k = a - t->addr_base; + while (l < r) { + m = (l + r) >> 1; + if (t->symbols[m].y < k) { + l = m + 1; + } else { + r = m; + } + } + if (l < n && t->symbols[l].x <= k && k <= t->symbols[l].y) { + return l; + } + } + return -1; +} diff --git a/libc/runtime/hook.greg.c b/libc/runtime/hook.greg.c index 98e20e67e..a6fea7f8d 100644 --- a/libc/runtime/hook.greg.c +++ b/libc/runtime/hook.greg.c @@ -21,6 +21,7 @@ #include "libc/calls/internal.h" #include "libc/calls/sigbits.h" #include "libc/calls/struct/sigset.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/log/libfatal.internal.h" #include "libc/runtime/runtime.h" @@ -58,8 +59,10 @@ privileged noinstrument noasan int __hook(void *ifunc, intptr_t kProgramCodeStart = (intptr_t)&_ereal; intptr_t kPrivilegedStart = (intptr_t)&__privileged_start; bool kIsBinaryAligned = !(kPrivilegedStart & (PAGESIZE - 1)); - sigfillset(&mask); - sigprocmask(SIG_BLOCK, &mask, &oldmask); + if (!IsWindows()) { + sigfillset(&mask); + sys_sigprocmask(SIG_BLOCK, &mask, &oldmask); + } if ((rc = mprotect( (void *)symbols->addr_base, kPrivilegedStart - symbols->addr_base, kIsBinaryAligned ? PROT_READ | PROT_WRITE @@ -127,6 +130,8 @@ privileged noinstrument noasan int __hook(void *ifunc, mprotect((void *)symbols->addr_base, kPrivilegedStart - symbols->addr_base, PROT_READ | PROT_EXEC); } - sigprocmask(SIG_SETMASK, &oldmask, NULL); + if (!IsWindows()) { + sys_sigprocmask(SIG_SETMASK, &oldmask, NULL); + } return rc; } diff --git a/libc/runtime/init.S b/libc/runtime/init.S index c48d82549..4c675b285 100644 --- a/libc/runtime/init.S +++ b/libc/runtime/init.S @@ -20,7 +20,6 @@ #include "libc/runtime/internal.h" #include "libc/sysv/consts/prot.h" #include "libc/dce.h" -.source __FILE__ // Decentralized function for process initialization. // @@ -85,6 +84,7 @@ _woot: leave .globl __init_rodata_start,__init_rodata_end .hidden __init_rodata_start,__init_rodata_end .align __SIZEOF_POINTER__ + .underrun __init_rodata_start: .previous/* ... @@ -93,6 +93,7 @@ __init_rodata_start: */.section .initroepilogue,"a",@progbits __init_rodata_end: .byte 0x90 + .overrun .previous // Decentralized section for unpacked data structures. @@ -108,6 +109,7 @@ __init_rodata_end: .globl __init_bss_start,__init_bss_end .hidden __init_bss_start,__init_bss_end .align __SIZEOF_POINTER__ + .underrun __init_bss_start: .previous/* ... @@ -116,6 +118,7 @@ __init_bss_start: */.section .piro.bss.init.3,"aw",@nobits __init_bss_end: .byte 0 + .overrun .previous // Special area for Windows NT support code. diff --git a/libc/runtime/interceptflag.greg.c b/libc/runtime/interceptflag.greg.c new file mode 100644 index 000000000..026ea4dbe --- /dev/null +++ b/libc/runtime/interceptflag.greg.c @@ -0,0 +1,46 @@ +/*-*- 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/log/libfatal.internal.h" +#include "libc/runtime/internal.h" +#include "libc/str/str.h" + +textstartup bool __intercept_flag(int *argc, char *argv[], const char *flag) { + /* asan isn't initialized yet at runlevel 300 */ + char *a; + int i, j; + bool found; + found = false; + for (j = i = 1; i <= *argc;) { + a = argv[j++]; + if (a && !__strcmp(a, flag)) { + found = true; + --*argc; + } else { + /* + * e.g. turns ----strace → --strace for execve. + * todo: update this to allow ------strace etc. + */ + if (a && a[0] == '-' && a[1] == '-' && !__strcmp(a + 2, flag)) { + a = flag; + } + argv[i++] = a; + } + } + return found; +} diff --git a/libc/runtime/internal.h b/libc/runtime/internal.h index 32aaa564e..135130d48 100644 --- a/libc/runtime/internal.h +++ b/libc/runtime/internal.h @@ -12,21 +12,25 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern uint32_t __ntconsolemode; +extern int __pid; +extern uint32_t __ntconsolemode[3]; extern const char v_ntsubsystem[] __attribute__((__weak__)); extern const uintptr_t __fini_array_end[] __attribute__((__weak__)); extern const uintptr_t __fini_array_start[] __attribute__((__weak__)); void _init(void) hidden; +void __restorewintty(void) hidden; void *__cxa_finalize(void *) hidden; void cosmo(int, char **, char **, long (*)[2]) hidden wontreturn; void __stack_chk_fail(void) wontreturn relegated; void __stack_chk_fail_local(void) wontreturn relegated hidden; void _jmpstack(void *, void *, ...) hidden wontreturn; long _setstack(void *, void *, ...) hidden; -int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden; +int GetDosArgv(const char16_t *, char *, size_t, char **, size_t); Elf64_Ehdr *MapElfRead(const char *, struct MappedFile *) hidden; -int GetDosEnviron(const char16_t *, char *, size_t, char **, size_t) hidden; +int GetDosEnviron(const char16_t *, char *, size_t, char **, size_t); +bool __intercept_flag(int *, char *[], const char *); +int sys_mprotect_nt(void *, size_t, int) hidden; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/runtime/ismemtracked.greg.c b/libc/runtime/ismemtracked.greg.c new file mode 100644 index 000000000..becbd54aa --- /dev/null +++ b/libc/runtime/ismemtracked.greg.c @@ -0,0 +1,37 @@ +/*-*- 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 2022 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/runtime/memtrack.internal.h" + +static inline bool IsMemtrackedImpl(int x, int y) { + unsigned i; + i = FindMemoryInterval(&_mmi, x); + if (i == _mmi.i) return false; + if (x < _mmi.p[i].x) return false; + for (;;) { + if (y <= _mmi.p[i].y) return true; + if (++i == _mmi.i) return false; + if (_mmi.p[i].x != _mmi.p[i - 1].y + 1) return false; + } +} + +bool IsMemtracked(int x, int y) { + bool res; + res = IsMemtrackedImpl(x, y); + return res; +} diff --git a/libc/runtime/jmpstack.S b/libc/runtime/jmpstack.S index 7044ad3b1..10226f342 100644 --- a/libc/runtime/jmpstack.S +++ b/libc/runtime/jmpstack.S @@ -31,7 +31,7 @@ _jmpstack: mov %rcx,%rsi mov %r8,%rdx mov %r9,%rcx - xor %rbp,%rbp + xor %ebp,%ebp call *%rax - ud2 + .unreachable .endfn _jmpstack,globl,hidden diff --git a/libc/runtime/mapanon.c b/libc/runtime/mapanon.c index f59f46585..6b31c87b6 100644 --- a/libc/runtime/mapanon.c +++ b/libc/runtime/mapanon.c @@ -59,6 +59,8 @@ noasan void *mapanon(size_t size) { /* asan runtime depends on this function */ void *m; m = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (m == MAP_FAILED && weaken(__oom_hook)) weaken(__oom_hook)(size); + if (m == MAP_FAILED && weaken(__oom_hook)) { + weaken(__oom_hook)(size); + } return m; } diff --git a/libc/runtime/memtrack.c b/libc/runtime/memtrack.c deleted file mode 100644 index 127bef8a7..000000000 --- a/libc/runtime/memtrack.c +++ /dev/null @@ -1,199 +0,0 @@ -/*-*- 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 "libc/assert.h" -#include "libc/bits/bits.h" -#include "libc/bits/likely.h" -#include "libc/bits/weaken.h" -#include "libc/calls/calls.h" -#include "libc/calls/sysdebug.internal.h" -#include "libc/dce.h" -#include "libc/errno.h" -#include "libc/intrin/asan.internal.h" -#include "libc/log/libfatal.internal.h" -#include "libc/macros.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/directmap.internal.h" -#include "libc/runtime/memtrack.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/prot.h" -#include "libc/sysv/errfuns.h" - -static noasan void *MoveMemoryIntervals(struct MemoryInterval *d, - const struct MemoryInterval *s, int n) { - /* asan runtime depends on this function */ - int i; - assert(n >= 0); - if (d > s) { - for (i = n; i--;) { - d[i] = s[i]; - } - } else { - for (i = 0; i < n; ++i) { - d[i] = s[i]; - } - } - return d; -} - -static noasan void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i, - int n) { - /* asan runtime depends on this function */ - assert(i >= 0); - assert(i + n <= mm->i); - MoveMemoryIntervals(mm->p + i, mm->p + i + n, mm->i - (i + n)); - mm->i -= n; -} - -static noasan bool ExtendMemoryIntervals(struct MemoryIntervals *mm) { - int prot, flags; - char *base, *shad; - size_t gran, size; - struct DirectMap dm; - gran = kMemtrackGran; - base = (char *)kMemtrackStart; - prot = PROT_READ | PROT_WRITE; - flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED; - if (mm->p == mm->s) { - if (IsAsan()) { - shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000); - dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0); - if (!dm.addr) { - SYSDEBUG("ExtendMemoryIntervals() fail #1"); - return false; - } - } - dm = sys_mmap(base, gran, prot, flags, -1, 0); - if (!dm.addr) { - SYSDEBUG("ExtendMemoryIntervals() fail #2"); - return false; - } - MoveMemoryIntervals(dm.addr, mm->p, mm->i); - mm->p = dm.addr; - mm->n = gran / sizeof(*mm->p); - } else { - size = ROUNDUP(mm->n * sizeof(*mm->p), gran); - base += size; - if (IsAsan()) { - shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000); - dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0); - if (!dm.addr) { - SYSDEBUG("ExtendMemoryIntervals() fail #3"); - return false; - } - } - dm = sys_mmap(base, gran, prot, flags, -1, 0); - if (!dm.addr) { - SYSDEBUG("ExtendMemoryIntervals() fail #4"); - return false; - } - mm->n = (size + gran) / sizeof(*mm->p); - } - assert(AreMemoryIntervalsOk(mm)); - return true; -} - -noasan int CreateMemoryInterval(struct MemoryIntervals *mm, int i) { - /* asan runtime depends on this function */ - int rc; - rc = 0; - assert(i >= 0); - assert(i <= mm->i); - assert(mm->n >= 0); - if (UNLIKELY(mm->i == mm->n) && !ExtendMemoryIntervals(mm)) return enomem(); - MoveMemoryIntervals(mm->p + i + 1, mm->p + i, mm->i++ - i); - return 0; -} - -static noasan int PunchHole(struct MemoryIntervals *mm, int x, int y, int i) { - if (CreateMemoryInterval(mm, i) == -1) return -1; - mm->p[i].y = x - 1; - mm->p[i + 1].x = y + 1; - return 0; -} - -noasan int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, - void wf(struct MemoryIntervals *, int, int)) { - unsigned l, r; - assert(y >= x); - assert(AreMemoryIntervalsOk(mm)); - if (!mm->i) return 0; - l = FindMemoryInterval(mm, x); - if (l == mm->i) return 0; - if (!l && y < mm->p[l].x) return 0; - if (y < mm->p[l].x) return 0; - r = FindMemoryInterval(mm, y); - if (r == mm->i || (r > l && y < mm->p[r].x)) --r; - assert(r >= l); - assert(x <= mm->p[r].y); - if (l == r && x > mm->p[l].x && y < mm->p[l].y) { - return PunchHole(mm, x, y, l); - } - if (x > mm->p[l].x && x <= mm->p[l].y) { - assert(y >= mm->p[l].y); - if (IsWindows()) return einval(); - mm->p[l].y = x - 1; - assert(mm->p[l].x <= mm->p[l].y); - ++l; - } - if (y >= mm->p[r].x && y < mm->p[r].y) { - assert(x <= mm->p[r].x); - if (IsWindows()) return einval(); - mm->p[r].x = y + 1; - assert(mm->p[r].x <= mm->p[r].y); - --r; - } - if (l <= r) { - if (IsWindows() && wf) { - wf(mm, l, r); - } - RemoveMemoryIntervals(mm, l, r - l + 1); - } - return 0; -} - -noasan int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h, - int prot, int flags) { - /* asan runtime depends on this function */ - unsigned i; - assert(y >= x); - assert(AreMemoryIntervalsOk(mm)); - i = FindMemoryInterval(mm, x); - if (i && x == mm->p[i - 1].y + 1 && h == mm->p[i - 1].h && - prot == mm->p[i - 1].prot && flags == mm->p[i - 1].flags) { - mm->p[i - 1].y = y; - if (i < mm->i && y + 1 == mm->p[i].x && h == mm->p[i].h && - prot == mm->p[i].prot && flags == mm->p[i].flags) { - mm->p[i - 1].y = mm->p[i].y; - RemoveMemoryIntervals(mm, i, 1); - } - } else if (i < mm->i && y + 1 == mm->p[i].x && h == mm->p[i].h && - prot == mm->p[i].prot && flags == mm->p[i].flags) { - mm->p[i].x = x; - } else { - if (CreateMemoryInterval(mm, i) == -1) return -1; - mm->p[i].x = x; - mm->p[i].y = y; - mm->p[i].h = h; - mm->p[i].prot = prot; - mm->p[i].flags = flags; - } - return 0; -} diff --git a/libc/runtime/memtrack.greg.c b/libc/runtime/memtrack.greg.c new file mode 100644 index 000000000..2d69982d6 --- /dev/null +++ b/libc/runtime/memtrack.greg.c @@ -0,0 +1,192 @@ +/*-*- 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 "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/likely.h" +#include "libc/bits/weaken.h" +#include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/asan.internal.h" +#include "libc/log/libfatal.internal.h" +#include "libc/macros.internal.h" +#include "libc/mem/mem.h" +#include "libc/runtime/directmap.internal.h" +#include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/errfuns.h" + +static void *MoveMemoryIntervals(struct MemoryInterval *d, + const struct MemoryInterval *s, int n) { + /* asan runtime depends on this function */ + int i; + assert(n >= 0); + if (d > s) { + for (i = n; i--;) { + d[i] = s[i]; + } + } else { + for (i = 0; i < n; ++i) { + d[i] = s[i]; + } + } + return d; +} + +static void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i, int n) { + /* asan runtime depends on this function */ + assert(i >= 0); + assert(i + n <= mm->i); + MoveMemoryIntervals(mm->p + i, mm->p + i + n, mm->i - (i + n)); + mm->i -= n; +} + +static bool ExtendMemoryIntervals(struct MemoryIntervals *mm) { + int prot, flags; + char *base, *shad; + size_t gran, size; + struct DirectMap dm; + gran = kMemtrackGran; + base = (char *)kMemtrackStart; + prot = PROT_READ | PROT_WRITE; + flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED; + /* TODO(jart): These map handles should not leak across NT fork() */ + if (mm->p == mm->s) { + if (IsAsan()) { + shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000); + dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0); + if (!dm.addr) return false; + } + dm = sys_mmap(base, gran, prot, flags, -1, 0); + if (!dm.addr) return false; + MoveMemoryIntervals(dm.addr, mm->p, mm->i); + mm->p = dm.addr; + mm->n = gran / sizeof(*mm->p); + } else { + size = ROUNDUP(mm->n * sizeof(*mm->p), gran); + base += size; + if (IsAsan()) { + shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000); + dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0); + if (!dm.addr) return false; + } + dm = sys_mmap(base, gran, prot, flags, -1, 0); + if (!dm.addr) return false; + mm->n = (size + gran) / sizeof(*mm->p); + } + assert(AreMemoryIntervalsOk(mm)); + return true; +} + +int CreateMemoryInterval(struct MemoryIntervals *mm, int i) { + /* asan runtime depends on this function */ + int rc; + rc = 0; + assert(i >= 0); + assert(i <= mm->i); + assert(mm->n >= 0); + if (UNLIKELY(mm->i == mm->n) && !ExtendMemoryIntervals(mm)) return enomem(); + MoveMemoryIntervals(mm->p + i + 1, mm->p + i, mm->i++ - i); + return 0; +} + +static int PunchHole(struct MemoryIntervals *mm, int x, int y, int i) { + if (CreateMemoryInterval(mm, i) == -1) return -1; + mm->p[i].y = x - 1; + mm->p[i + 1].x = y + 1; + return 0; +} + +int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, + void wf(struct MemoryIntervals *, int, int)) { + unsigned l, r; + assert(y >= x); + assert(AreMemoryIntervalsOk(mm)); + if (!mm->i) return 0; + l = FindMemoryInterval(mm, x); + if (l == mm->i) return 0; + if (!l && y < mm->p[l].x) return 0; + if (y < mm->p[l].x) return 0; + r = FindMemoryInterval(mm, y); + if (r == mm->i || (r > l && y < mm->p[r].x)) --r; + assert(r >= l); + assert(x <= mm->p[r].y); + if (l == r && x > mm->p[l].x && y < mm->p[l].y) { + return PunchHole(mm, x, y, l); + } + if (x > mm->p[l].x && x <= mm->p[l].y) { + assert(y >= mm->p[l].y); + if (IsWindows()) return einval(); + mm->p[l].y = x - 1; + assert(mm->p[l].x <= mm->p[l].y); + ++l; + } + if (y >= mm->p[r].x && y < mm->p[r].y) { + assert(x <= mm->p[r].x); + if (IsWindows()) return einval(); + mm->p[r].x = y + 1; + assert(mm->p[r].x <= mm->p[r].y); + --r; + } + if (l <= r) { + if (IsWindows() && wf) { + wf(mm, l, r); + } + RemoveMemoryIntervals(mm, l, r - l + 1); + } + return 0; +} + +int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h, + int prot, int flags, bool readonlyfile, bool iscow, + long offset, long size) { + /* asan runtime depends on this function */ + unsigned i; + assert(y >= x); + assert(AreMemoryIntervalsOk(mm)); + i = FindMemoryInterval(mm, x); + if (i && x == mm->p[i - 1].y + 1 && h == mm->p[i - 1].h && + prot == mm->p[i - 1].prot && flags == mm->p[i - 1].flags) { + mm->p[i - 1].y = y; + if (i < mm->i && y + 1 == mm->p[i].x && h == mm->p[i].h && + prot == mm->p[i].prot && flags == mm->p[i].flags) { + mm->p[i - 1].y = mm->p[i].y; + RemoveMemoryIntervals(mm, i, 1); + } + } else if (i < mm->i && y + 1 == mm->p[i].x && h == mm->p[i].h && + prot == mm->p[i].prot && flags == mm->p[i].flags) { + mm->p[i].x = x; + } else { + if (CreateMemoryInterval(mm, i) == -1) return -1; + mm->p[i].x = x; + mm->p[i].y = y; + mm->p[i].h = h; + mm->p[i].prot = prot; + mm->p[i].flags = flags; + mm->p[i].offset = offset; + mm->p[i].size = size; + mm->p[i].iscow = iscow; + mm->p[i].readonlyfile = readonlyfile; + } + return 0; +} diff --git a/libc/runtime/memtrack.internal.h b/libc/runtime/memtrack.internal.h index ae844bda0..ce551b24b 100644 --- a/libc/runtime/memtrack.internal.h +++ b/libc/runtime/memtrack.internal.h @@ -1,5 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ #define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ +#include "libc/assert.h" #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/nt/enum/version.h" @@ -13,16 +14,19 @@ COSMOPOLITAN_C_START_ #define kAutomapSize \ _kMem(0x200000000000 - 0x100080000000 - _kMmi(0x800000000000), \ 0x000040000000 - 0x000010000000 - _kMmi(0x000080000000)) -#define kMemtrackStart \ - _kMem(0x200000000000 - _kMmi(0x800000000000), \ - 0x000040000000 - _kMmi(0x000080000000)) +#define kMemtrackStart \ + (ROUNDDOWN(_kMem(0x200000000000 - _kMmi(0x800000000000), \ + 0x000040000000 - _kMmi(0x000080000000)), \ + FRAMESIZE * 8) - \ + 0x8000 * 8 /* so frame aligned after adding 0x7fff8000 */) #define kMemtrackSize _kMem(_kMmi(0x800000000000), _kMmi(0x000080000000)) #define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8) #define kFixedmapStart _kMem(0x300000000000, 0x000040000000) #define kFixedmapSize \ _kMem(0x400000000000 - 0x300000000000, 0x000070000000 - 0x000040000000) -#define _kMmi(VSPACE) \ - ROUNDUP(VSPACE / FRAMESIZE * sizeof(struct MemoryInterval), FRAMESIZE) +#define _kMmi(VSPACE) \ + ROUNDUP(VSPACE / FRAMESIZE * (intptr_t)sizeof(struct MemoryInterval), \ + FRAMESIZE) #define _kMem(NORMAL, WIN7) \ (!(IsWindows() && NtGetVersion() < kNtVersionWindows10) ? NORMAL : WIN7) @@ -32,23 +36,29 @@ struct MemoryInterval { long h; int prot; int flags; + long offset; + long size; + bool iscow; + bool readonlyfile; }; struct MemoryIntervals { - long i, n; + size_t i, n; struct MemoryInterval *p; struct MemoryInterval s[OPEN_MAX]; + _Alignas(64) char lock; }; extern hidden struct MemoryIntervals _mmi; -const char *DescribeFrame(int); +bool IsMemtracked(int, int) hidden; void PrintSystemMappings(int) hidden; +const char *DescribeFrame(int) hidden; char *DescribeMapping(int, int, char[hasatleast 8]) hidden; bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden; void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden; -int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int, - int) hidden; +int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int, int, + bool, bool, long, long) hidden; int ReleaseMemoryIntervals(struct MemoryIntervals *, int, int, void (*)(struct MemoryIntervals *, int, int)) hidden; void ReleaseMemoryNt(struct MemoryIntervals *, int, int) hidden; @@ -57,6 +67,10 @@ int UntrackMemoryIntervals(void *, size_t) hidden; #define IsLegalPointer(p) \ (-0x800000000000 <= (intptr_t)(p) && (intptr_t)(p) <= 0x7fffffffffff) +forceinline pureconst bool IsLegalSize(size_t n) { + return n <= 0x7fffffffffff; +} + forceinline pureconst bool IsAutoFrame(int x) { return (kAutomapStart >> 16) <= x && x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16); @@ -75,14 +89,26 @@ forceinline pureconst bool IsShadowFrame(int x) { return 0x7fff <= x && x < 0x10008000; } +forceinline pureconst bool IsKernelFrame(int x) { + return (int)(GetStaticStackAddr(0) >> 16) <= x && + x <= (int)((GetStaticStackAddr(0) + (GetStackSize() - FRAMESIZE)) >> + 16); +} + forceinline pureconst bool IsStaticStackFrame(int x) { - return (GetStaticStackAddr(0) >> 16) <= x && - x <= ((GetStaticStackAddr(0) + (GetStackSize() - FRAMESIZE)) >> 16); + return (int)(GetStaticStackAddr(0) >> 16) <= x && + x <= (int)((GetStaticStackAddr(0) + (GetStackSize() - FRAMESIZE)) >> + 16); +} + +forceinline pureconst bool IsStackFrame(int x) { + return (int)(GetStackAddr(0) >> 16) <= x && + x <= (int)((GetStackAddr(0) + (GetStackSize() - FRAMESIZE)) >> 16); } forceinline pureconst bool IsSigAltStackFrame(int x) { - return (GetStackAddr(0) >> 16) <= x && - x <= ((GetStackAddr(0) + (SIGSTKSZ - FRAMESIZE)) >> 16); + return (int)(GetStackAddr(0) >> 16) <= x && + x <= (int)((GetStackAddr(0) + (SIGSTKSZ - FRAMESIZE)) >> 16); } forceinline pureconst bool IsOldStackFrame(int x) { @@ -147,21 +173,10 @@ forceinline unsigned FindMemoryInterval(const struct MemoryIntervals *mm, r = m; } } + assert(l == mm->i || x <= mm->p[l].y); return l; } -forceinline bool IsMemtracked(int x, int y) { - unsigned i; - i = FindMemoryInterval(&_mmi, x); - if (i == _mmi.i) return false; - if (!(_mmi.p[i].x <= x && x <= _mmi.p[i].y)) return false; - for (;;) { - if (y <= _mmi.p[i].y) return true; - if (++i == _mmi.i) return false; - if (_mmi.p[i].x != _mmi.p[i - 1].y + 1) return false; - } -} - COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ */ diff --git a/libc/runtime/memtracknt.c b/libc/runtime/memtracknt.c index f6dc682ca..c1a9a6828 100644 --- a/libc/runtime/memtracknt.c +++ b/libc/runtime/memtracknt.c @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/nt/memory.h" #include "libc/nt/runtime.h" #include "libc/runtime/memtrack.internal.h" @@ -37,11 +37,7 @@ noasan void ReleaseMemoryNt(struct MemoryIntervals *mm, int l, int r) { for (i = l; i <= r; ++i) { addr = GetFrameAddr(mm->p[i].x); last = GetFrameAddr(mm->p[i].y); - SYSDEBUG("UnmapViewOfFile(addr:0x%x, size:0x%x, hand:0x%x)", addr, - last - addr + FRAMESIZE, mm->p[i].h); - ok = UnmapViewOfFile(addr); - assert(ok); - ok = CloseHandle(mm->p[i].h); - assert(ok); + UnmapViewOfFile(addr); + CloseHandle(mm->p[i].h); } } diff --git a/libc/runtime/metalprintf.greg.c b/libc/runtime/metalprintf.greg.c index 93781a6c4..4da5570fd 100644 --- a/libc/runtime/metalprintf.greg.c +++ b/libc/runtime/metalprintf.greg.c @@ -23,7 +23,7 @@ #define PUTC(C) \ do { \ while (!(inb(0x3F8 + UART_LSR) & UART_TTYTXR)) { \ - asm("pause"); \ + __builtin_ia32_pause(); \ } \ outb(0x3F8, C); \ } while (0) diff --git a/libc/runtime/mmap.c b/libc/runtime/mmap.c index ee58ac8cf..c929999a8 100644 --- a/libc/runtime/mmap.c +++ b/libc/runtime/mmap.c @@ -21,34 +21,44 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/spinlock.h" +#include "libc/limits.h" #include "libc/log/backtrace.internal.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" #include "libc/macros.internal.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/processmemorycounters.h" #include "libc/rand/rand.h" #include "libc/runtime/directmap.internal.h" +#include "libc/runtime/internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" #define IP(X) (intptr_t)(X) #define VIP(X) (void *)IP(X) -#define SMALL(n) ((n) <= 0xffffffffffff) #define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1))) #define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16) #define SHADE(x) (((intptr_t)(x) >> 3) + 0x7fff8000) #define FRAME(x) ((int)((intptr_t)(x) >> 16)) -forceinline wontreturn void Die(void) { +static wontreturn void OnUnrecoverableMmapError(const char *s) { if (weaken(__die)) weaken(__die)(); - abort(); + STRACE("%s %m", s); + __restorewintty(); + _Exit(199); } noasan static bool IsMapped(char *p, size_t n) { @@ -60,7 +70,7 @@ noasan static bool NeedAutomap(char *p, size_t n) { IsMapped(p, n); } -noasan static bool ChooseInterval(int x, int n, int *res) { +noasan static bool ChooseMemoryInterval(int x, int n, int *res) { int i; if (_mmi.i) { i = FindMemoryInterval(&_mmi, x); @@ -89,52 +99,52 @@ noasan static bool ChooseInterval(int x, int n, int *res) { noasan static bool Automap(int n, int *res) { *res = -1; - if (ChooseInterval(FRAME(kAutomapStart), n, res)) { + if (ChooseMemoryInterval(FRAME(kAutomapStart), n, res)) { assert(*res >= FRAME(kAutomapStart)); if (*res + n <= FRAME(kAutomapStart + (kAutomapStart - 1))) { return true; } else { - SYSDEBUG("mmap(0x%p, 0x%x) ENOMEM (automap interval exhausted)", - ADDR(*res), ADDR(n + 1)); + STRACE("mmap(%.12p, %p) ENOMEM (automap interval exhausted)", ADDR(*res), + ADDR(n + 1)); return false; } } else { - SYSDEBUG("mmap(0x%p, 0x%x) ENOMEM (automap failed)", ADDR(*res), - ADDR(n + 1)); + STRACE("mmap(%.12p, %p) ENOMEM (automap failed)", ADDR(*res), ADDR(n + 1)); return false; } } +noasan static size_t GetMemtrackSize(struct MemoryIntervals *mm) { + size_t i, n; + for (n = i = 0; i < mm->i; ++i) { + n += ((size_t)(mm->p[i].y - mm->p[i].x) + 1) << 16; + } + return n; +} + static noasan void *MapMemory(void *addr, size_t size, int prot, int flags, int fd, int64_t off, int f, int x, int n) { struct DirectMap dm; dm = sys_mmap(addr, size, prot, f, fd, off); if (UNLIKELY(dm.addr == MAP_FAILED)) { if (IsWindows() && (flags & MAP_FIXED)) { - SYSDEBUG("mmap(0x%p, 0x%x) -> %s (%s)", addr, size, strerror(errno), - "can't recover from MAP_FIXED errors on Windows"); - assert(!"MapMemory() failed"); - Die(); + OnUnrecoverableMmapError( + "can't recover from MAP_FIXED errors on Windows"); } return MAP_FAILED; } if (UNLIKELY(dm.addr != addr)) { - SYSDEBUG("KERNEL DIDN'T RESPECT MAP_FIXED"); - assert(!"MapMemory() failed"); - Die(); + OnUnrecoverableMmapError("KERNEL DIDN'T RESPECT MAP_FIXED"); } if (!IsWindows() && (flags & MAP_FIXED)) { if (UntrackMemoryIntervals(addr, size)) { - SYSDEBUG("FIXED UNTRACK FAILED %s", strerror(errno)); - assert(!"MapMemory() failed"); - Die(); + OnUnrecoverableMmapError("FIXED UNTRACK FAILED"); } } - if (TrackMemoryInterval(&_mmi, x, x + (n - 1), dm.maphandle, prot, flags)) { + if (TrackMemoryInterval(&_mmi, x, x + (n - 1), dm.maphandle, prot, flags, + false, false, off, size)) { if (sys_munmap(addr, n) == -1) { - SYSDEBUG("TRACK MUNMAP FAILED %s", strerror(errno)); - assert(!"MapMemory() failed"); - Die(); + OnUnrecoverableMmapError("TRACK MUNMAP FAILED"); } return MAP_FAILED; } @@ -151,33 +161,36 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags, * punch holes into existing mappings. */ static textwindows dontinline noasan void *MapMemories(char *addr, size_t size, - int prot, int flags, - int fd, int64_t off, int f, - int x, size_t n) { + int prot, int flags, + int fd, int64_t off, + int f, int x, int n) { + size_t i, m; + int64_t oi, sz; struct DirectMap dm; - size_t i, m = (n - 1) * FRAMESIZE; - assert(m < size && m + FRAMESIZE >= size); - dm = sys_mmap(addr + m, size - m, prot, f, fd, fd == -1 ? 0 : off + m); - if (dm.addr == MAP_FAILED) { - SYSDEBUG("MapMemories(%p+%x/%x) %s", addr, m, size, strerror(errno)); - return MAP_FAILED; - } + bool iscow, readonlyfile; + m = (size_t)(n - 1) << 16; + assert(m < size); + assert(m + FRAMESIZE >= size); + oi = fd == -1 ? 0 : off + m; + sz = size - m; + dm = sys_mmap(addr + m, sz, prot, f, fd, oi); + if (dm.addr == MAP_FAILED) return MAP_FAILED; + iscow = (flags & MAP_PRIVATE) && fd != -1; + readonlyfile = (flags & MAP_SHARED) && fd != -1 && + (g_fds.p[fd].flags & O_ACCMODE) == O_RDONLY; if (TrackMemoryInterval(&_mmi, x + (n - 1), x + (n - 1), dm.maphandle, prot, - flags) == -1) { - SYSDEBUG("MapMemories(%p+%x/%x) unrecoverable failure #1 %s", addr, m, size, - strerror(errno)); - assert(!"MapMemories() failed"); - Die(); + flags, readonlyfile, iscow, oi, sz) == -1) { + OnUnrecoverableMmapError("MapMemories unrecoverable #1"); } for (i = 0; i < m; i += FRAMESIZE) { - dm = sys_mmap(addr + i, FRAMESIZE, prot, f, fd, fd == -1 ? 0 : off + i); + oi = fd == -1 ? 0 : off + i; + sz = FRAMESIZE; + dm = sys_mmap(addr + i, sz, prot, f, fd, oi); if (dm.addr == MAP_FAILED || TrackMemoryInterval(&_mmi, x + i / FRAMESIZE, x + i / FRAMESIZE, - dm.maphandle, prot, flags) == -1) { - SYSDEBUG("MapMemories(%p+%x/%x) unrecoverable failure #2 %s", addr, i, - size, strerror(errno)); - assert(!"MapMemories() failed"); - Die(); + dm.maphandle, prot, flags, readonlyfile, iscow, oi, + sz) == -1) { + OnUnrecoverableMmapError("MapMemories unrecoverable #2"); } } if (weaken(__asan_map_shadow) && !OverlapsShadowSpace(addr, size)) { @@ -186,6 +199,133 @@ static textwindows dontinline noasan void *MapMemories(char *addr, size_t size, return addr; } +static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags, + int fd, int64_t off) { +#if defined(SYSDEBUG) && (_KERNTRACE || _NTTRACE) + if (IsWindows()) { + STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) → ...", addr, size, + DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off); + } +#endif + char *p = addr; + struct DirectMap dm; + size_t virtualused, virtualneed; + int a, b, i, f, m, n, x; + + if (UNLIKELY(!size)) { + STRACE("size=0"); + return VIP(einval()); + } + + if (UNLIKELY(!IsLegalSize(size))) { + STRACE("size isn't 48-bit"); + return VIP(einval()); + } + + if (UNLIKELY(!IsLegalPointer(p))) { + STRACE("p isn't 48-bit"); + return VIP(einval()); + } + + if (UNLIKELY(!ALIGNED(p))) { + STRACE("p isn't 64kb aligned"); + return VIP(einval()); + } + + if (UNLIKELY(fd < -1)) { + STRACE("mmap(%.12p, %'zu, fd=%d) EBADF", p, size, fd); + return VIP(ebadf()); + } + + if (UNLIKELY(!((fd != -1) ^ !!(flags & MAP_ANONYMOUS)))) { + STRACE("fd anonymous mismatch"); + return VIP(einval()); + } + + if (UNLIKELY(!(!!(flags & MAP_PRIVATE) ^ !!(flags & MAP_SHARED)))) { + STRACE("MAP_SHARED ^ MAP_PRIVATE"); + return VIP(einval()); + } + + if (UNLIKELY(off < 0)) { + STRACE("neg off"); + return VIP(einval()); + } + + if (UNLIKELY(INT64_MAX - size < off)) { + STRACE("too large"); + return VIP(einval()); + } + + if (UNLIKELY(!ALIGNED(off))) { + STRACE("p isn't 64kb aligned"); + return VIP(einval()); + } + + if ((flags & MAP_FIXED_NOREPLACE) && IsMapped(p, size)) { +#ifdef SYSDEBUG + if (OverlapsImageSpace(p, size)) { + STRACE("overlaps image"); + } else { + STRACE("overlaps existing"); + } +#endif + return VIP(efault()); + } + + if (__isfdkind(fd, kFdZip)) { + STRACE("fd is zipos handle"); + return VIP(einval()); + } + + if (__virtualmax < LONG_MAX && + (__builtin_add_overflow((virtualused = GetMemtrackSize(&_mmi)), size, + &virtualneed) || + virtualneed > __virtualmax)) { + STRACE("%'zu size + %'zu inuse exceeds virtual memory limit %'zu", size, + virtualused, __virtualmax); + return VIP(enomem()); + } + + if (fd == -1) { + size = ROUNDUP(size, FRAMESIZE); + if (IsWindows()) { + prot |= PROT_WRITE; /* kludge */ + } + } + + n = (int)(size >> 16) + !!(size & (FRAMESIZE - 1)); + assert(n > 0); + f = (flags & ~MAP_FIXED_NOREPLACE) | MAP_FIXED; + if (flags & MAP_FIXED) { + x = FRAME(p); + if (IsWindows()) { + if (UntrackMemoryIntervals(p, size)) { + OnUnrecoverableMmapError("FIXED UNTRACK FAILED"); + } + } + } else if (!NeedAutomap(p, size)) { + x = FRAME(p); + } else if (!Automap(n, &x)) { + STRACE("AUTOMAP OUT OF MEMORY D:"); + return VIP(enomem()); + } + + p = (char *)ADDR(x); + if (IsOpenbsd() && (f & MAP_GROWSDOWN)) { /* openbsd:dubstack */ + dm = sys_mmap(p, size, prot, f & ~MAP_GROWSDOWN, fd, off); + if (dm.addr == MAP_FAILED) { + return MAP_FAILED; + } + } + + if (!IsWindows()) { + return MapMemory(p, size, prot, flags, fd, off, f, x, n); + } else { + return MapMemories(p, size, prot, flags, fd, off, f, x, n); + } +} + /** * Beseeches system for page-table entries, e.g. * @@ -217,90 +357,11 @@ static textwindows dontinline noasan void *MapMemories(char *addr, size_t size, */ noasan void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { - struct DirectMap dm; - int a, b, i, f, m, n, x; - char mode[8], *p = addr; - if (UNLIKELY(!size)) { - SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (size=0)", p, size); - return VIP(einval()); - } - if (UNLIKELY(!SMALL(size))) { - SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (size isn't 48-bit)", p, size); - return VIP(einval()); - } - if (UNLIKELY(!IsLegalPointer(p))) { - SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (p isn't 48-bit)", p, size); - return VIP(einval()); - } - if (UNLIKELY(!ALIGNED(p))) { - SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (p isn't 64kb aligned)", p, size); - return VIP(einval()); - } - if (UNLIKELY(fd < -1)) { - SYSDEBUG("mmap(0x%p, 0x%x, fd=%d) EBADF", p, size, (long)fd); - return VIP(ebadf()); - } - if (UNLIKELY(!((fd != -1) ^ !!(flags & MAP_ANONYMOUS)))) { - SYSDEBUG("mmap(0x%p, 0x%x, %s, %d, %d) EINVAL (fd anonymous mismatch)", p, - size, DescribeMapping(prot, flags, mode), (long)fd, off); - return VIP(einval()); - } - if (UNLIKELY(!(!!(flags & MAP_PRIVATE) ^ !!(flags & MAP_SHARED)))) { - SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (MAP_SHARED ^ MAP_PRIVATE)", p, size); - return VIP(einval()); - } - if (UNLIKELY(off < 0)) { - SYSDEBUG("mmap(0x%p, 0x%x, off=%d) EINVAL (neg off)", p, size, off); - return VIP(einval()); - } - if (UNLIKELY(INT64_MAX - size < off)) { - SYSDEBUG("mmap(0x%p, 0x%x, off=%d) EINVAL (too large)", p, size, off); - return VIP(einval()); - } - if (UNLIKELY(!ALIGNED(off))) { - SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (p isn't 64kb aligned)", p, size); - return VIP(einval()); - } - if ((flags & MAP_FIXED_NOREPLACE) && IsMapped(p, size)) { - if (OverlapsImageSpace(p, size)) { - SYSDEBUG("mmap(0x%p, 0x%x) EFAULT (overlaps image)", p, size); - } else { - SYSDEBUG("mmap(0x%p, 0x%x) EFAULT (overlaps existing)", p, size); - } - return VIP(efault()); - } - SYSDEBUG("mmap(0x%p, 0x%x, %s, %d, %d)", p, size, - DescribeMapping(prot, flags, mode), (long)fd, off); - if (fd == -1) { - size = ROUNDUP(size, FRAMESIZE); - if (IsWindows()) { - prot |= PROT_WRITE; /* kludge */ - } - } - n = FRAME(size) + !!(size & (FRAMESIZE - 1)); - f = (flags & ~MAP_FIXED_NOREPLACE) | MAP_FIXED; - if (flags & MAP_FIXED) { - x = FRAME(p); - if (IsWindows()) { - if (UntrackMemoryIntervals(p, size)) { - SYSDEBUG("FIXED UNTRACK FAILED %s", strerror(errno)); - assert(!"mmap() failed"); - Die(); - } - } - } else if (!NeedAutomap(p, size)) { - x = FRAME(p); - } else if (!Automap(n, &x)) { - return VIP(enomem()); - } - p = (char *)ADDR(x); - if (IsOpenbsd() && (f & MAP_GROWSDOWN)) { /* openbsd:dubstack */ - dm = sys_mmap(p, size, prot, f & ~MAP_GROWSDOWN, fd, off); - if (dm.addr == MAP_FAILED) return MAP_FAILED; - } - if (!IsWindows()) { - return MapMemory(p, size, prot, flags, fd, off, f, x, n); - } else { - return MapMemories(p, size, prot, flags, fd, off, f, x, n); - } + void *res; + _spinlock(&_mmi.lock); + res = Mmap(addr, size, prot, flags, fd, off); + _spunlock(&_mmi.lock); + STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) → %p% m", addr, size, + DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off, res); + return res; } diff --git a/libc/runtime/mprotect-nt.greg.c b/libc/runtime/mprotect-nt.greg.c new file mode 100644 index 000000000..5172e6e55 --- /dev/null +++ b/libc/runtime/mprotect-nt.greg.c @@ -0,0 +1,63 @@ +/*-*- 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 2022 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/intrin/spinlock.h" +#include "libc/nt/memory.h" +#include "libc/runtime/directmap.internal.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/memtrack.internal.h" + +#define ADDR(x) ((char *)((int64_t)((uint64_t)(x) << 32) >> 16)) + +textwindows int sys_mprotect_nt(void *addr, size_t size, int prot) { + int rc = 0; + unsigned i; + uint32_t op; + char *a, *b, *x, *y, *p; + _spinlock(&_mmi.lock); + p = addr; + i = FindMemoryInterval(&_mmi, (intptr_t)p >> 16); + if (i == _mmi.i || (!i && p + size <= ADDR(_mmi.p[0].x))) { + // memory isn't in memtrack + // let's just trust the user then + // it's probably part of the executable + if (!VirtualProtect(addr, size, __prot2nt(prot, false), &op)) { + rc = -1; + } + } else { + // memory is in memtrack, so use memtrack, to do dimensioning + // we unfortunately must do something similar to this for cow + for (; i < _mmi.i; ++i) { + x = ADDR(_mmi.p[i].x); + y = x + _mmi.p[i].size; + if ((x <= p && p < y) || (x < p + size && p + size <= y) || + (p < x && y < p + size)) { + a = MIN(MAX(p, x), y); + b = MAX(MIN(p + size, y), x); + if (!VirtualProtect(a, b - a, __prot2nt(prot, _mmi.p[i].iscow), &op)) { + rc = -1; + break; + } + } else { + break; + } + } + } + _spunlock(&_mmi.lock); + return rc; +} diff --git a/libc/runtime/mprotect.greg.c b/libc/runtime/mprotect.greg.c new file mode 100644 index 000000000..14b27b7db --- /dev/null +++ b/libc/runtime/mprotect.greg.c @@ -0,0 +1,54 @@ +/*-*- 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 "libc/bits/likely.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/errfuns.h" + +/** + * Modifies restrictions on virtual memory address range. + * + * @param addr needs to be 4kb aligned + * @param prot can have PROT_{NONE,READ,WRITE,EXEC,GROWSDOWN,GROWSUP} + * @return 0 on success, or -1 w/ errno + * @see mmap() + */ +privileged int mprotect(void *addr, size_t size, int prot) { + int64_t rc; + if (SupportsWindows() && (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | + PROT_GROWSDOWN | PROT_GROWSUP))) { + rc = einval(); // unix checks prot before checking size + } else if (!size) { + return 0; // make new technology consistent with unix + } else if (UNLIKELY((intptr_t)addr & 4095)) { + rc = einval(); + } else if (!IsWindows()) { + rc = sys_mprotect(addr, size, prot); + } else { + rc = sys_mprotect_nt(addr, size, prot); + } + STRACE("mprotect(%p, %'zu, %s) → %d% m", addr, size, DescribeProtFlags(prot), + rc); + return rc; +} diff --git a/libc/runtime/mremap-sysv.c b/libc/runtime/mremap-sysv.c deleted file mode 100644 index 76303f161..000000000 --- a/libc/runtime/mremap-sysv.c +++ /dev/null @@ -1,55 +0,0 @@ -/*-*- 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/bits/bits.h" -#include "libc/calls/calls.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/mremap.h" -#include "libc/sysv/errfuns.h" - -privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) { - bool cf; - uintptr_t rax, rdi, rsi, rdx; - register uintptr_t r8 asm("r8"); - register uintptr_t r10 asm("r10"); - if (IsLinux()) { - r10 = f; - r8 = (uintptr_t)q; - asm("syscall" - : "=a"(rax) - : "0"(0x019), "D"(p), "S"(n), "d"(m), "r"(r10), "r"(r8) - : "rcx", "r11", "memory", "cc"); - if (rax > -4096ul) errno = -rax, rax = -1; - } else if (IsNetbsd()) { - if (f & MREMAP_MAYMOVE) { - rax = 0x19B; - r10 = m; - r8 = (f & MREMAP_FIXED) ? MAP_FIXED : 0; - asm(CFLAG_ASM("syscall") - : CFLAG_CONSTRAINT(cf), "+a"(rax) - : "D"(p), "S"(n), "d"(q), "r"(r10), "r"(r8) - : "rcx", "r11", "memory", "cc"); - if (cf) errno = rax, rax = -1; - } else { - rax = einval(); - } - } else { - rax = enosys(); - } - return (void *)rax; -} diff --git a/libc/runtime/mremap.c b/libc/runtime/mremap.c index dc9b8ead1..0233e962d 100644 --- a/libc/runtime/mremap.c +++ b/libc/runtime/mremap.c @@ -21,10 +21,10 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" -#include "libc/log/libfatal.internal.h" +#include "libc/intrin/describeflags.internal.h" #include "libc/macros.internal.h" #include "libc/nt/runtime.h" #include "libc/runtime/directmap.internal.h" @@ -36,7 +36,6 @@ #define IP(X) (intptr_t)(X) #define VIP(X) (void *)IP(X) -#define SMALL(n) ((n) <= 0xffffffffffff) #define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1))) #define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16) #define SHADE(x) (((intptr_t)(x) >> 3) + 0x7fff8000) @@ -71,48 +70,58 @@ static bool MustMoveMap(intptr_t y, size_t j) { void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) { enosys(); return MAP_FAILED; - void *q; + +#if 0 va_list va; + void *res, *q; + if (f & MREMAP_FIXED) { + va_start(va, f); + q = va_arg(va, void *); + va_end(va); + } else { + q = 0; + } + enosys(); + res = MAP_FAILED; + STRACE("mremap(%p, %'zu, %'zu, %s, %p) → %p% m", p, n, m, + DescribeRemapFlags(f), q, res); + return res; + + // TODO(jart): perhaps some day? + // probably not a big perf gain at this point :| size_t i, j, k; struct DirectMap dm; int a, b, prot, flags; + assert(!__vforked); if (UNLIKELY(!m)) { - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (m=0)", p, n, m, f); + STRACE("m=0"); return VIP(einval()); - } - if (UNLIKELY(!n)) { - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EOPNOTSUPP (n=0)", p, n, m, f); + } else if (UNLIKELY(!n)) { + STRACE("n=0"); return VIP(eopnotsupp()); - } - if (UNLIKELY(!ALIGNED(n))) { - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EOPNOTSUPP (n align)", p, n, m, f); + } else if (UNLIKELY(!ALIGNED(n))) { + STRACE("n align"); return VIP(eopnotsupp()); - } - if (UNLIKELY(!ALIGNED(m))) { - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EOPNOTSUPP (n align)", p, n, m, f); + } else if (UNLIKELY(!ALIGNED(m))) { + STRACE("n align"); return VIP(eopnotsupp()); - } - if (UNLIKELY(!ALIGNED(p))) { - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (64kb align)", p, n, m, f); + } else if (UNLIKELY(!ALIGNED(p))) { + STRACE("64kb align"); return VIP(einval()); - } - if (UNLIKELY(!SMALL(n))) { - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (n too big)", p, n, m, f); + } else if (UNLIKELY(!IsLegalSize(n))) { + STRACE("n too big"); return VIP(enomem()); - } - if (UNLIKELY(!SMALL(m))) { - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (m too big)", p, n, m, f); + } else if (UNLIKELY(!IsLegalSize(m))) { + STRACE("m too big"); return VIP(enomem()); - } - if (f & ~(MREMAP_MAYMOVE | MREMAP_FIXED)) { - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (bad flag)", p, n, m, f); + } else if (f & ~(MREMAP_MAYMOVE | MREMAP_FIXED)) { + STRACE("bad flag"); return VIP(einval()); - } - if (!IsMemtracked(FRAME(p), FRAME((intptr_t)p + (n - 1)))) { - SYSDEBUG("munmap(0x%x, 0x%x) EFAULT (interval not tracked)", p, n); + } else if (!IsMemtracked(FRAME(p), FRAME((intptr_t)p + (n - 1)))) { + STRACE("interval not tracked"); return VIP(efault()); } - SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x)", p, n, m, f); + STRACE("mremap(%p, %'zu, %'zu, %#b)", p, n, m, f); i = FindMemoryInterval(&_mmi, FRAME(p)); if (i >= _mmi.i) return VIP(efault()); flags = _mmi.p[i].flags; @@ -120,9 +129,6 @@ void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) { return VIP(eopnotsupp()); /* TODO */ } if (f & MREMAP_FIXED) { - va_start(va, f); - q = va_arg(va, void *); - va_end(va); if (!ALIGNED(q)) return VIP(einval()); return VIP(eopnotsupp()); /* TODO */ } @@ -146,7 +152,7 @@ void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) { if (dm.addr == MAP_FAILED) return 0; if (TrackMemoryInterval(&_mmi, ((uintptr_t)p + n) >> 16, ((uintptr_t)p + m - FRAMESIZE) >> 16, dm.maphandle, - prot, flags) != -1) { + prot, flags, false, false, 0, m - n) != -1) { if (weaken(__asan_map_shadow)) { weaken(__asan_map_shadow)((uintptr_t)dm.addr, m - n); } @@ -174,12 +180,13 @@ void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) { } q = sys_mremap((void *)p, n, m, MREMAP_MAYMOVE | MREMAP_FIXED, (void *)ADDR(a)); - SYSDEBUG("sys_mremap(0x%p, 0x%x, 0x%x, 0x%x, 0x%x) -> 0x%p", p, n, m, - MREMAP_MAYMOVE | MREMAP_FIXED, ADDR(a)); + KERNTRACE("sys_mremap(%p, %'zu, %'zu, %#b, %p) → %p", p, n, m, + MREMAP_MAYMOVE | MREMAP_FIXED, ADDR(a), q); if (q == MAP_FAILED) return 0; if (ReleaseMemoryIntervals(&_mmi, (uintptr_t)p >> 16, ((uintptr_t)p + n - FRAMESIZE) >> 16, 0) != -1 && - TrackMemoryInterval(&_mmi, a, b, -1, prot, flags) != -1) { + TrackMemoryInterval(&_mmi, a, b, -1, prot, flags, false, false, 0, m) != + -1) { if (weaken(__asan_poison)) { if (!OverlapsShadowSpace(p, n)) { weaken(__asan_poison)((intptr_t)p, n, kAsanUnmapped); @@ -199,4 +206,5 @@ void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) { } else { return q; } +#endif } diff --git a/libc/runtime/msync-nt.c b/libc/runtime/msync-nt.c index 79475fdbd..22e680587 100644 --- a/libc/runtime/msync-nt.c +++ b/libc/runtime/msync-nt.c @@ -17,22 +17,38 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/intrin/spinlock.h" #include "libc/macros.internal.h" #include "libc/nt/files.h" #include "libc/nt/memory.h" #include "libc/runtime/memtrack.internal.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/msync.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" -noasan textwindows int sys_msync_nt(void *addr, size_t size, int flags) { - int x, y, l, r, i; - x = ROUNDDOWN((intptr_t)addr, FRAMESIZE) >> 16; - y = ROUNDDOWN((intptr_t)addr + size - 1, FRAMESIZE) >> 16; - for (i = FindMemoryInterval(&_mmi, x); i < _mmi.i; ++i) { - if ((x >= _mmi.p[i].x && x <= _mmi.p[i].y) || - (y >= _mmi.p[i].x && y <= _mmi.p[i].y)) { - FlushFileBuffers(_mmi.p[i].h); +#define ADDR(x) ((char *)((int64_t)((uint64_t)(x) << 32) >> 16)) + +noasan textwindows int sys_msync_nt(char *addr, size_t size, int flags) { + int i, rc = 0; + char *a, *b, *x, *y; + _spinlock(&_mmi.lock); + for (i = FindMemoryInterval(&_mmi, (intptr_t)addr >> 16); i < _mmi.i; ++i) { + x = ADDR(_mmi.p[i].x); + y = x + _mmi.p[i].size; + if ((x <= addr && addr < y) || (x < addr + size && addr + size <= y) || + (addr < x && y < addr + size)) { + a = MIN(MAX(addr, x), y); + b = MAX(MIN(addr + size, y), x); + if (!FlushViewOfFile(a, b - a)) { + rc = -1; + break; + } + // TODO(jart): FlushFileBuffers too on g_fds handle if MS_SYNC? } else { break; } } - return 0; + _spunlock(&_mmi.lock); + return rc; } diff --git a/libc/runtime/msync.c b/libc/runtime/msync.c index adcd9a0e9..b23370cf3 100644 --- a/libc/runtime/msync.c +++ b/libc/runtime/msync.c @@ -19,6 +19,7 @@ #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/sysv/consts/msync.h" @@ -26,18 +27,21 @@ /** * Synchronize memory mapping changes to disk. * - * Without this, there's no guarantee memory is written back to disk. In - * practice, what that means is just Windows NT. + * Without this, there's no guarantee memory is written back to disk. + * Particularly on RHEL5, OpenBSD, and Windows NT. * * @param addr needs to be 4096-byte page aligned * @param flags needs MS_ASYNC or MS_SYNC and can have MS_INVALIDATE * @return 0 on success or -1 w/ errno */ int msync(void *addr, size_t size, int flags) { + int rc; assert(((flags & MS_SYNC) ^ (flags & MS_ASYNC)) || !(MS_SYNC && MS_ASYNC)); if (!IsWindows()) { - return sys_msync(addr, size, flags); + rc = sys_msync(addr, size, flags); } else { - return sys_msync_nt(addr, size, flags); + rc = sys_msync_nt(addr, size, flags); } + STRACE("msync(%p, %'zu, %#x) → %d% m", addr, size, flags, rc); + return rc; } diff --git a/libc/runtime/munmap.c b/libc/runtime/munmap.c index 45098727e..19146c221 100644 --- a/libc/runtime/munmap.c +++ b/libc/runtime/munmap.c @@ -18,10 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/likely.h" #include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/spinlock.h" #include "libc/log/libfatal.internal.h" #include "libc/macros.internal.h" #include "libc/runtime/directmap.internal.h" @@ -31,12 +32,80 @@ #include "libc/sysv/errfuns.h" #define IP(X) (intptr_t)(X) -#define SMALL(n) ((n) <= 0xffffffffffff) #define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1))) #define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16) -#define SHADE(x) (((intptr_t)(x) >> 3) + 0x7fff8000) #define FRAME(x) ((int)((intptr_t)(x) >> 16)) +static noasan int Munmap(void *v, size_t n) { + char poison, *p = v; + intptr_t a, b, x, y; + assert(!__vforked); + + if (UNLIKELY(!n)) { + STRACE("munmap(%.12p, %'zu) %s (n=0)", p, n); + return einval(); + } + + if (UNLIKELY(!IsLegalSize(n))) { + STRACE("munmap(%.12p, %'zu) EINVAL (n isn't 48-bit)", p, n); + return einval(); + } + + if (UNLIKELY(!IsLegalPointer(p))) { + STRACE("munmap(%.12p, %'zu) EINVAL (p isn't 48-bit)", p, n); + return einval(); + } + + if (UNLIKELY(!IsLegalPointer(p + (n - 1)))) { + STRACE("munmap(%.12p, %'zu) EINVAL (p+(n-1) isn't 48-bit)", p, n); + return einval(); + } + + if (UNLIKELY(!ALIGNED(p))) { + STRACE("munmap(%.12p, %'zu) EINVAL (p isn't 64kb aligned)", p, n); + return einval(); + } + + if (!IsMemtracked(FRAME(p), FRAME(p + (n - 1)))) { + STRACE("munmap(%.12p, %'zu) EFAULT (interval not tracked)", p, n); + return efault(); + } + + if (UntrackMemoryIntervals(p, n) == -1) { + return -1; + } + + if (IsWindows()) { + return 0; // UntrackMemoryIntervals does it for NT + } + + if (sys_munmap(p, n) == -1) { + return -1; // ouch + } + + if (IsAsan() && !OverlapsShadowSpace(p, n)) { + a = ((intptr_t)p >> 3) + 0x7fff8000; + b = a + (n >> 3); + if (IsMemtracked(FRAME(a), FRAME(b - 1))) { + x = ROUNDUP(a, FRAMESIZE); + y = ROUNDDOWN(b, FRAMESIZE); + if (x < y) { + // delete shadowspace if unmapping ≥512kb + __repstosb((void *)a, kAsanUnmapped, x - a); + Munmap((void *)x, y - x); + __repstosb((void *)y, kAsanUnmapped, b - y); + } else { + // otherwise just poison and assume reuse + __repstosb((void *)a, kAsanUnmapped, b - a); + } + } else { + STRACE("unshadow(%.12p, %p) EFAULT", a, b - a); + } + } + + return 0; +} + /** * Releases memory pages. * @@ -51,66 +120,11 @@ * and for files size needs to be perfect to the byte bc openbsd * @return 0 on success, or -1 w/ errno */ -noasan int munmap(void *v, size_t n) { - /* asan runtime depends on this function */ +noasan int munmap(void *p, size_t n) { int rc; - char poison, *p = v; - intptr_t a, b, x, y; - if (UNLIKELY(!n)) { - SYSDEBUG("munmap(0x%p, 0x%x) %s (n=0)", p, n); - return einval(); - } - if (UNLIKELY(!SMALL(n))) { - SYSDEBUG("munmap(0x%p, 0x%x) EINVAL (n isn't 48-bit)", p, n); - return einval(); - } - if (UNLIKELY(!IsLegalPointer(p))) { - SYSDEBUG("munmap(0x%p, 0x%x) EINVAL (p isn't 48-bit)", p, n); - return einval(); - } - if (UNLIKELY(!IsLegalPointer(p + (n - 1)))) { - SYSDEBUG("munmap(0x%p, 0x%x) EINVAL (p+(n-1) isn't 48-bit)", p, n); - return einval(); - } - if (UNLIKELY(!ALIGNED(p))) { - SYSDEBUG("munmap(0x%p, 0x%x) EINVAL (p isn't 64kb aligned)", p, n); - return einval(); - } - if (!IsMemtracked(FRAME(p), FRAME(p + (n - 1)))) { - SYSDEBUG("munmap(0x%p, 0x%x) EFAULT (interval not tracked)", p, n); - return efault(); - } - if (UntrackMemoryIntervals(p, n) != -1) { - if (!IsWindows()) { - rc = sys_munmap(p, n); - if (rc != -1) { - if (IsAsan() && !OverlapsShadowSpace(p, n)) { - a = SHADE(p); - b = a + (n >> 3); - if (IsMemtracked(FRAME(a), FRAME(b - 1))) { - x = ROUNDUP(a, FRAMESIZE); - y = ROUNDDOWN(b, FRAMESIZE); - if (x < y) { - /* delete shadowspace if unmapping ≥512kb */ - __repstosb((void *)a, kAsanUnmapped, x - a); - munmap((void *)x, y - x); - __repstosb((void *)y, kAsanUnmapped, b - y); - } else { - /* otherwise just poison and assume reuse */ - __repstosb((void *)a, kAsanUnmapped, b - a); - } - } else { - SYSDEBUG("unshadow(0x%x, 0x%x) EFAULT", a, b - a); - } - } - } - } else { - rc = 0; /* UntrackMemoryIntervals does it for NT */ - } - } else { - rc = -1; - } - SYSDEBUG("munmap(0x%p, 0x%x) -> %d %s", p, n, (long)rc, - rc == -1 ? strerror(errno) : ""); + _spinlock(&_mmi.lock); + rc = Munmap(p, n); + _spunlock(&_mmi.lock); + STRACE("munmap(%.12p, %'zu) → %d% m", p, n, rc); return rc; } diff --git a/libc/runtime/openexecutable.S b/libc/runtime/openexecutable.S index c76f03139..8ed1ae5f5 100644 --- a/libc/runtime/openexecutable.S +++ b/libc/runtime/openexecutable.S @@ -41,6 +41,7 @@ OpenExecutable: pushq MAP_PRIVATE(%rip) # -0x30(%rbp) pushq MAP_FIXED(%rip) # -0x38(%rbp) pushq __NR_mprotect(%rip) # -0x40(%rbp) + pushq O_RDONLY(%rip) # -0x48(%rbp) push %rbx # code buffer push %r12 # data buffer push %r14 # filename @@ -120,8 +121,20 @@ OpenExecutable: mov -0x08(%rbp),%eax # __NR_open mov %r14,%rdi mov -0x20(%rbp),%esi # O_RDWR - syscall - mov %eax,%r15d + clc # clear carry flag + syscall + jc .Lohno # bsd error + cmp $-4095,%eax + jae .Lohno # linux error + jmp .Lok + +// Open executable in read-only mode. +.Lohno: mov -0x08(%rbp),%eax # __NR_open + mov %r14,%rdi + mov -0x48(%rbp),%esi # O_RDONLY + syscall + +.Lok: mov %eax,%r15d // Map code segment. mov -0x10(%rbp),%eax # __NR_mmap diff --git a/libc/runtime/opensymboltable.c b/libc/runtime/opensymboltable.c deleted file mode 100644 index 6d2d229c4..000000000 --- a/libc/runtime/opensymboltable.c +++ /dev/null @@ -1,196 +0,0 @@ -/*-*- 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 "libc/alg/alg.h" -#include "libc/assert.h" -#include "libc/bits/bits.h" -#include "libc/calls/calls.h" -#include "libc/calls/sysdebug.internal.h" -#include "libc/dce.h" -#include "libc/elf/def.h" -#include "libc/elf/scalar.h" -#include "libc/elf/struct/phdr.h" -#include "libc/elf/struct/shdr.h" -#include "libc/elf/struct/sym.h" -#include "libc/errno.h" -#include "libc/limits.h" -#include "libc/log/libfatal.internal.h" -#include "libc/macros.internal.h" -#include "libc/runtime/internal.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/symbols.internal.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/o.h" -#include "libc/sysv/consts/prot.h" -#include "libc/sysv/errfuns.h" - -#define GetStr(tab, rva) ((char *)(tab) + (rva)) -#define GetSection(e, s) ((void *)((intptr_t)(e) + (size_t)(s)->sh_offset)) -#define GetShstrtab(e) GetSection(e, GetShdr(e, (e)->e_shstrndx)) -#define GetSectionName(e, s) GetStr(GetShstrtab(e), (s)->sh_name) -#define GetPhdr(e, i) \ - ((Elf64_Phdr *)((intptr_t)(e) + (e)->e_phoff + \ - (size_t)(e)->e_phentsize * (i))) -#define GetShdr(e, i) \ - ((Elf64_Shdr *)((intptr_t)(e) + (e)->e_shoff + \ - (size_t)(e)->e_shentsize * (i))) - -noasan static char *GetStrtab(Elf64_Ehdr *e, size_t *n) { - char *name; - Elf64_Half i; - Elf64_Shdr *shdr; - for (i = 0; i < e->e_shnum; ++i) { - shdr = GetShdr(e, i); - if (shdr->sh_type == SHT_STRTAB) { - name = GetSectionName(e, GetShdr(e, i)); - if (name && !__strcmp(name, ".strtab")) { - if (n) *n = shdr->sh_size; - return GetSection(e, shdr); - } - } - } - return 0; -} - -noasan static Elf64_Sym *GetSymtab(Elf64_Ehdr *e, Elf64_Xword *n) { - Elf64_Half i; - Elf64_Shdr *shdr; - for (i = e->e_shnum; i > 0; --i) { - shdr = GetShdr(e, i - 1); - if (shdr->sh_type == SHT_SYMTAB) { - if (shdr->sh_entsize != sizeof(Elf64_Sym)) continue; - if (n) *n = shdr->sh_size / shdr->sh_entsize; - return GetSection(e, shdr); - } - } - return 0; -} - -noasan static void GetImageRange(Elf64_Ehdr *elf, intptr_t *x, intptr_t *y) { - unsigned i; - Elf64_Phdr *phdr; - intptr_t start, end, pstart, pend; - start = INTPTR_MAX; - end = 0; - for (i = 0; i < elf->e_phnum; ++i) { - phdr = GetPhdr(elf, i); - if (phdr->p_type != PT_LOAD) continue; - pstart = phdr->p_vaddr; - pend = phdr->p_vaddr + phdr->p_memsz; - if (pstart < start) start = pstart; - if (pend > end) end = pend; - } - if (x) *x = start; - if (y) *y = end; -} - -/** - * Maps debuggable binary into memory and indexes symbol addresses. - * - * @return object freeable with CloseSymbolTable(), or NULL w/ errno - */ -noasan struct SymbolTable *OpenSymbolTable(const char *filename) { - int fd; - void *map; - long *stp; - struct stat st; - size_t n, m, tsz; - unsigned i, j, x; - const Elf64_Ehdr *elf; - const char *name_base; - struct SymbolTable *t; - const Elf64_Sym *symtab, *sym; - ptrdiff_t names_offset, name_base_offset, stp_offset; - map = MAP_FAILED; - if ((fd = open(filename, O_RDONLY)) == -1) return 0; - if (fstat(fd, &st) == -1) goto SystemError; - if (st.st_size > INT_MAX) goto RaiseE2big; - if (st.st_size < 64) goto RaiseEnoexec; - elf = map = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) goto SystemError; - if (READ32LE(map) != READ32LE("\177ELF")) goto RaiseEnoexec; - if (!(name_base = GetStrtab(map, &m))) goto RaiseEnobufs; - if (!(symtab = GetSymtab(map, &n))) goto RaiseEnobufs; - tsz = 0; - tsz += sizeof(struct SymbolTable); - tsz += sizeof(struct Symbol) * n; - names_offset = tsz; - tsz += sizeof(unsigned) * n; - name_base_offset = tsz; - tsz += m; - tsz = ROUNDUP(tsz, FRAMESIZE); - stp_offset = tsz; - tsz += sizeof(const Elf64_Sym *) * n; - tsz = ROUNDUP(tsz, FRAMESIZE); - t = mmap(0, tsz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (t == MAP_FAILED) goto SystemError; - t->mapsize = tsz; - t->names = (unsigned *)((char *)t + names_offset); - t->name_base = (char *)((char *)t + name_base_offset); - GetImageRange(elf, &t->addr_base, &t->addr_end); - memcpy(t->name_base, name_base, m); - --t->addr_end; - stp = (long *)((char *)t + stp_offset); - for (m = i = 0; i < n; ++i) { - sym = symtab + i; - if (!(sym->st_size > 0 && (ELF64_ST_TYPE(sym->st_info) == STT_FUNC || - ELF64_ST_TYPE(sym->st_info) == STT_OBJECT))) { - continue; - } - if (sym->st_value > t->addr_end) continue; - if (sym->st_value < t->addr_base) continue; - x = sym->st_value - t->addr_base; - stp[m++] = (unsigned long)x << 32 | i; - } - longsort(stp, m); - for (j = i = 0; i < m; ++i) { - sym = symtab + (stp[i] & 0x7fffffff); - x = stp[i] >> 32; - if (j && x == t->symbols[j - 1].x) --j; - if (j && t->symbols[j - 1].y >= x) t->symbols[j - 1].y = x - 1; - t->names[j] = sym->st_name; - t->symbols[j].x = x; - if (sym->st_size) { - t->symbols[j].y = x + sym->st_size - 1; - } else { - t->symbols[j].y = t->addr_end - t->addr_base; - } - ++j; - } - t->count = j; - munmap(stp, ROUNDUP(sizeof(const Elf64_Sym *) * n, FRAMESIZE)); - munmap(map, st.st_size); - close(fd); - return t; -RaiseE2big: - errno = E2BIG; - goto SystemError; -RaiseEnobufs: - errno = ENOBUFS; - goto SystemError; -RaiseEnoexec: - errno = ENOEXEC; -SystemError: - SYSDEBUG("OpenSymbolTable() %s", strerror(errno)); - if (map != MAP_FAILED) { - munmap(map, st.st_size); - } - close(fd); - return 0; -} diff --git a/libc/runtime/opensymboltable.greg.c b/libc/runtime/opensymboltable.greg.c new file mode 100644 index 000000000..e126a84ec --- /dev/null +++ b/libc/runtime/opensymboltable.greg.c @@ -0,0 +1,203 @@ +/*-*- 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 "libc/alg/alg.h" +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/elf/def.h" +#include "libc/elf/scalar.h" +#include "libc/elf/struct/phdr.h" +#include "libc/elf/struct/shdr.h" +#include "libc/elf/struct/sym.h" +#include "libc/errno.h" +#include "libc/intrin/kprintf.h" +#include "libc/limits.h" +#include "libc/log/libfatal.internal.h" +#include "libc/macros.internal.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.internal.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/errfuns.h" + +#define GetStr(tab, rva) ((char *)(tab) + (rva)) +#define GetSection(e, s) ((void *)((intptr_t)(e) + (size_t)(s)->sh_offset)) +#define GetShstrtab(e) GetSection(e, GetShdr(e, (e)->e_shstrndx)) +#define GetSectionName(e, s) GetStr(GetShstrtab(e), (s)->sh_name) +#define GetPhdr(e, i) \ + ((Elf64_Phdr *)((intptr_t)(e) + (e)->e_phoff + \ + (size_t)(e)->e_phentsize * (i))) +#define GetShdr(e, i) \ + ((Elf64_Shdr *)((intptr_t)(e) + (e)->e_shoff + \ + (size_t)(e)->e_shentsize * (i))) + +static char *GetStrtab(Elf64_Ehdr *e, size_t *n) { + char *name; + Elf64_Half i; + Elf64_Shdr *shdr; + for (i = 0; i < e->e_shnum; ++i) { + shdr = GetShdr(e, i); + if (shdr->sh_type == SHT_STRTAB) { + name = GetSectionName(e, GetShdr(e, i)); + if (name && !__strcmp(name, ".strtab")) { + if (n) *n = shdr->sh_size; + return GetSection(e, shdr); + } + } + } + return 0; +} + +static Elf64_Sym *GetSymtab(Elf64_Ehdr *e, Elf64_Xword *n) { + Elf64_Half i; + Elf64_Shdr *shdr; + for (i = e->e_shnum; i > 0; --i) { + shdr = GetShdr(e, i - 1); + if (shdr->sh_type == SHT_SYMTAB) { + if (shdr->sh_entsize != sizeof(Elf64_Sym)) continue; + if (n) *n = shdr->sh_size / shdr->sh_entsize; + return GetSection(e, shdr); + } + } + return 0; +} + +static void GetImageRange(Elf64_Ehdr *elf, intptr_t *x, intptr_t *y) { + unsigned i; + Elf64_Phdr *phdr; + intptr_t start, end, pstart, pend; + start = INTPTR_MAX; + end = 0; + for (i = 0; i < elf->e_phnum; ++i) { + phdr = GetPhdr(elf, i); + if (phdr->p_type != PT_LOAD) continue; + pstart = phdr->p_vaddr; + pend = phdr->p_vaddr + phdr->p_memsz; + if (pstart < start) start = pstart; + if (pend > end) end = pend; + } + if (x) *x = start; + if (y) *y = end; +} + +/** + * Maps debuggable binary into memory and indexes symbol addresses. + * + * @return object freeable with CloseSymbolTable(), or NULL w/ errno + */ +struct SymbolTable *OpenSymbolTable(const char *filename) { + int fd; + void *map; + long *stp; + ssize_t filesize; + unsigned i, j, x; + const Elf64_Ehdr *elf; + const char *name_base; + struct SymbolTable *t; + size_t n, m, tsz, size; + const Elf64_Sym *symtab, *sym; + ptrdiff_t names_offset, name_base_offset, stp_offset; + map = MAP_FAILED; + if ((fd = open(filename, O_RDONLY)) == -1) return 0; + if ((filesize = getfiledescriptorsize(fd)) == -1) goto SystemError; + if (filesize > INT_MAX) goto RaiseE2big; + if (filesize < 64) goto RaiseEnoexec; + elf = map = mmap(0, filesize, PROT_READ, MAP_PRIVATE, fd, 0); + if (map == MAP_FAILED) goto SystemError; + if (READ32LE(map) != READ32LE("\177ELF")) goto RaiseEnoexec; + if (!(name_base = GetStrtab(map, &m))) goto RaiseEnobufs; + if (!(symtab = GetSymtab(map, &n))) goto RaiseEnobufs; + tsz = 0; + tsz += sizeof(struct SymbolTable); + tsz += sizeof(struct Symbol) * n; + names_offset = tsz; + tsz += sizeof(unsigned) * n; + name_base_offset = tsz; + tsz += m; + tsz = ROUNDUP(tsz, FRAMESIZE); + stp_offset = tsz; + size = tsz; + tsz += sizeof(const Elf64_Sym *) * n; + tsz = ROUNDUP(tsz, FRAMESIZE); + t = mmap(0, tsz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (t == MAP_FAILED) goto SystemError; + t->magic = SYMBOLS_MAGIC; + t->abi = SYMBOLS_ABI; + t->size = size; + t->mapsize = size; + t->names_offset = names_offset; + t->name_base_offset = name_base_offset; + t->names = (uint32_t *)((char *)t + t->names_offset); + t->name_base = (char *)((char *)t + t->name_base_offset); + GetImageRange(elf, &t->addr_base, &t->addr_end); + memcpy(t->name_base, name_base, m); + --t->addr_end; + stp = (long *)((char *)t + stp_offset); + for (m = i = 0; i < n; ++i) { + sym = symtab + i; + if (!(sym->st_size > 0 && (ELF64_ST_TYPE(sym->st_info) == STT_FUNC || + ELF64_ST_TYPE(sym->st_info) == STT_OBJECT))) { + continue; + } + if (sym->st_value > t->addr_end) continue; + if (sym->st_value < t->addr_base) continue; + x = sym->st_value - t->addr_base; + stp[m++] = (unsigned long)x << 32 | i; + } + longsort(stp, m); + for (j = i = 0; i < m; ++i) { + sym = symtab + (stp[i] & 0x7fffffff); + x = stp[i] >> 32; + if (j && x == t->symbols[j - 1].x) --j; + if (j && t->symbols[j - 1].y >= x) t->symbols[j - 1].y = x - 1; + t->names[j] = sym->st_name; + t->symbols[j].x = x; + if (sym->st_size) { + t->symbols[j].y = x + sym->st_size - 1; + } else { + t->symbols[j].y = t->addr_end - t->addr_base; + } + ++j; + } + t->count = j; + munmap(stp, ROUNDUP(sizeof(const Elf64_Sym *) * n, FRAMESIZE)); + munmap(map, filesize); + close(fd); + return t; +RaiseE2big: + errno = E2BIG; + goto SystemError; +RaiseEnobufs: + errno = ENOBUFS; + goto SystemError; +RaiseEnoexec: + errno = ENOEXEC; +SystemError: + STRACE("OpenSymbolTable()% m"); + if (map != MAP_FAILED) { + munmap(map, filesize); + } + close(fd); + return 0; +} diff --git a/libc/runtime/paginate.c b/libc/runtime/paginate.c new file mode 100644 index 000000000..c37a00e0b --- /dev/null +++ b/libc/runtime/paginate.c @@ -0,0 +1,57 @@ +/*-*- 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 2022 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/bits/safemacros.internal.h" +#include "libc/calls/calls.h" +#include "libc/fmt/fmt.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/x/x.h" + +/** + * Displays wall of text in terminal with pagination. + */ +void __paginate(int fd, const char *s) { + int tfd, pid; + char *args[3] = {0}; + char tmppath[PATH_MAX]; + char progpath[PATH_MAX]; + if (strcmp(nulltoempty(getenv("TERM")), "dumb") && isatty(0) && isatty(1) && + ((args[0] = commandv("less", progpath, sizeof(progpath))) || + (args[0] = commandv("more", progpath, sizeof(progpath))))) { + snprintf(tmppath, sizeof(tmppath), "%s%s-%s-%d.txt", kTmpPath, + program_invocation_short_name, "paginate", getpid()); + if ((tfd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0644)) != -1) { + write(tfd, s, strlen(s)); + close(tfd); + args[1] = tmppath; + if ((pid = vfork()) != -1) { + if (!pid) { + execv(args[0], args); + _Exit(127); + } + waitpid(pid, 0, 0); + unlink(tmppath); + return; + } + unlink(tmppath); + } + } + write(fd, s, strlen(s)); +} diff --git a/libc/runtime/printargs.greg.c b/libc/runtime/printargs.greg.c new file mode 100644 index 000000000..8f18b5f02 --- /dev/null +++ b/libc/runtime/printargs.greg.c @@ -0,0 +1,553 @@ +/*-*- 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/strace.internal.h" +#include "libc/calls/struct/sigset.h" +#include "libc/calls/struct/termios.h" +#include "libc/calls/termios.h" +#include "libc/calls/ttydefaults.h" +#include "libc/dce.h" +#include "libc/dns/dns.h" +#include "libc/errno.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/nexgen32e/cpuid4.internal.h" +#include "libc/nexgen32e/kcpuids.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/nexgen32e/x86info.h" +#include "libc/nt/enum/startf.h" +#include "libc/nt/runtime.h" +#include "libc/nt/startupinfo.h" +#include "libc/nt/struct/ldrdatatableentry.h" +#include "libc/nt/struct/startupinfo.h" +#include "libc/nt/struct/teb.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/stack.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" +#include "libc/sysv/consts/f.h" +#include "libc/sysv/consts/poll.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/consts/termios.h" +#include "tool/decode/lib/idname.h" +#include "tool/decode/lib/x86idnames.h" + +STATIC_YOINK("strerror"); // for kprintf() +STATIC_YOINK("strsignal"); // for kprintf() + +#define PRINT(FMT, ...) \ + do { \ + kprintf(prologue); \ + kprintf(FMT "\n", ##__VA_ARGS__); \ + } while (0) + +static const struct AuxiliaryValue { + const char *fmt; + long *id; + const char *name; +} kAuxiliaryValues[] = { + {"%-14p", &AT_EXECFD, "AT_EXECFD"}, + {"%-14p", &AT_PHDR, "AT_PHDR"}, + {"%-14p", &AT_PHENT, "AT_PHENT"}, + {"%-14p", &AT_PHNUM, "AT_PHNUM"}, + {"%-14p", &AT_PAGESZ, "AT_PAGESZ"}, + {"%-14p", &AT_BASE, "AT_BASE"}, + {"%-14p", &AT_ENTRY, "AT_ENTRY"}, + {"%-14p", &AT_NOTELF, "AT_NOTELF"}, + {"%-14d", &AT_UID, "AT_UID"}, + {"%-14d", &AT_EUID, "AT_EUID"}, + {"%-14d", &AT_GID, "AT_GID"}, + {"%-14d", &AT_EGID, "AT_EGID"}, + {"%-14d", &AT_CLKTCK, "AT_CLKTCK"}, + {"%-14d", &AT_OSRELDATE, "AT_OSRELDATE"}, + {"%-14p", &AT_PLATFORM, "AT_PLATFORM"}, + {"%-14p", &AT_DCACHEBSIZE, "AT_DCACHEBSIZE"}, + {"%-14p", &AT_ICACHEBSIZE, "AT_ICACHEBSIZE"}, + {"%-14p", &AT_UCACHEBSIZE, "AT_UCACHEBSIZE"}, + {"%-14p", &AT_SECURE, "AT_SECURE"}, + {"%-14s", &AT_BASE_PLATFORM, "AT_BASE_PLATFORM"}, + {"%-14p", &AT_RANDOM, "AT_RANDOM"}, + {"%-14s", &AT_EXECFN, "AT_EXECFN"}, + {"%-14p", &AT_SYSINFO_EHDR, "AT_SYSINFO_EHDR"}, + {"%-14p", &AT_FLAGS, "AT_FLAGS"}, + {"%-14p", &AT_HWCAP, "AT_HWCAP"}, + {"%-14p", &AT_HWCAP2, "AT_HWCAP2"}, + {"%-14p", &AT_STACKBASE, "AT_STACKBASE"}, + {"%-14p", &AT_CANARY, "AT_CANARY"}, + {"%-14p", &AT_CANARYLEN, "AT_CANARYLEN"}, + {"%-14ld", &AT_NCPUS, "AT_NCPUS"}, + {"%-14p", &AT_PAGESIZES, "AT_PAGESIZES"}, + {"%-14d", &AT_PAGESIZESLEN, "AT_PAGESIZESLEN"}, + {"%-14p", &AT_TIMEKEEP, "AT_TIMEKEEP"}, + {"%-14p", &AT_STACKPROT, "AT_STACKPROT"}, + {"%-14p", &AT_EHDRFLAGS, "AT_EHDRFLAGS"}, +}; + +static const char *FindNameById(const struct IdName *names, unsigned long id) { + for (; names->name; names++) { + if (names->id == id) { + return names->name; + } + } + return NULL; +} + +static const struct AuxiliaryValue *DescribeAuxv(unsigned long x) { + int i; + for (i = 0; i < ARRAYLEN(kAuxiliaryValues); ++i) { + if (*kAuxiliaryValues[i].id && x == *kAuxiliaryValues[i].id) { + return kAuxiliaryValues + i; + } + } + return NULL; +} + +/** + * Prints lots of information about this process, e.g. + * + * __printargs(""); + * + * This is called automatically in MODE=dbg if `--strace` is used. + * + * @param prologue needs to be a .rodata kprintf string + */ +textstartup void __printargs(const char *prologue) { + long key; + char **env; + sigset_t ss; + unsigned i, n; + uintptr_t *auxp; + struct utsname uts; + struct termios termios; + int e, x, st, ft, flags; + struct AuxiliaryValue *auxinfo; + union { + char path[PATH_MAX]; + struct pollfd pfds[128]; + } u; + + st = __strace, __strace = 0; + ft = g_ftrace, g_ftrace = 0; + e = errno; + + PRINT(""); + PRINT("SYSTEM"); + if (!uname(&uts)) { + kprintf(prologue); + kprintf(" %s", uts.nodename); + if (*uts.sysname) { + kprintf(" on %s", uts.sysname); + if (*uts.release) { + kprintf(" %s", uts.release); + } + } + kprintf("\n"); + } else { + PRINT(" uname() failed %m"); + } + + PRINT(""); + PRINT("MICROPROCESSOR"); + kprintf(prologue); + kprintf(" %.*s%.*s%.*s", 4, &KCPUIDS(0H, EBX), 4, &KCPUIDS(0H, EDX), 4, + &KCPUIDS(0H, ECX)); + if (getx86processormodel(kX86ProcessorModelKey)) { + kprintf(" %s", + FindNameById(kX86MarchNames, + getx86processormodel(kX86ProcessorModelKey)->march)); + } + if (getx86processormodel(kX86ProcessorModelKey)) { + kprintf(" (%s Grade)", + FindNameById(kX86GradeNames, + getx86processormodel(kX86ProcessorModelKey)->grade)); + } + kprintf("\n"); + if ((x = KCPUIDS(16H, EAX) & 0x7fff)) { + kprintf(prologue); + kprintf(" %dmhz %s", x, "freq"); + if ((x = KCPUIDS(16H, EBX) & 0x7fff)) { + kprintf(" / %dmhz %s", x, "turbo"); + } + if ((x = KCPUIDS(16H, ECX) & 0x7fff)) { + kprintf(" / %dmhz %s", x, "bus"); + } + kprintf("\n"); + } + if (X86_HAVE(HYPERVISOR)) { + unsigned eax, ebx, ecx, edx; + asm("push\t%%rbx\n\t" + "cpuid\n\t" + "mov\t%%ebx,%1\n\t" + "pop\t%%rbx" + : "=a"(eax), "=rm"(ebx), "=c"(ecx), "=d"(edx) + : "0"(0x40000000), "2"(0)); + PRINT(" Running inside %.4s%.4s%.4s (eax=%#x)", &ebx, &ecx, &edx, eax); + } + CPUID4_ITERATE(i, { + PRINT(" L%d%s%s %u-way %,u byte cache w/%s " + "%,u sets of %,u byte lines shared across %u threads%s", + CPUID4_CACHE_LEVEL, + CPUID4_CACHE_TYPE == 1 ? " data" + : CPUID4_CACHE_TYPE == 2 ? " code" + : "", + CPUID4_IS_FULLY_ASSOCIATIVE ? " fully-associative" : "", + CPUID4_WAYS_OF_ASSOCIATIVITY, CPUID4_CACHE_SIZE_IN_BYTES, + CPUID4_PHYSICAL_LINE_PARTITIONS > 1 ? " physically partitioned" : "", + CPUID4_NUMBER_OF_SETS, CPUID4_SYSTEM_COHERENCY_LINE_SIZE, + CPUID4_MAX_THREADS_SHARING_CACHE, + CPUID4_COMPLEX_INDEXING ? " complexly-indexed" : ""); + }); + kprintf(prologue); + kprintf(" "); + if (X86_HAVE(SSE3)) kprintf(" SSE3"); + if (X86_HAVE(SSSE3)) kprintf(" SSSE3"); + if (X86_HAVE(SSE4_2)) kprintf(" SSE4_2"); + if (X86_HAVE(POPCNT)) kprintf(" POPCNT"); + if (X86_HAVE(AVX)) kprintf(" AVX"); + if (X86_HAVE(AVX2)) kprintf(" AVX2"); + if (X86_HAVE(FMA)) kprintf(" FMA"); + if (X86_HAVE(BMI)) kprintf(" BMI"); + if (X86_HAVE(BMI2)) kprintf(" BMI2"); + if (X86_HAVE(ADX)) kprintf(" ADX"); + if (X86_HAVE(F16C)) kprintf(" F16C"); + if (X86_HAVE(SHA)) kprintf(" SHA"); + if (X86_HAVE(AES)) kprintf(" AES"); + if (X86_HAVE(RDRND)) kprintf(" RDRND"); + if (X86_HAVE(RDSEED)) kprintf(" RDSEED"); + if (X86_HAVE(RDTSCP)) kprintf(" RDTSCP"); + if (X86_HAVE(RDPID)) kprintf(" RDPID"); + if (X86_HAVE(LA57)) kprintf(" LA57"); + if (X86_HAVE(FSGSBASE)) kprintf(" FSGSBASE"); + kprintf("\n"); + + PRINT(""); + PRINT("FILE DESCRIPTORS"); + for (i = 0; i < ARRAYLEN(u.pfds); ++i) { + u.pfds[i].fd = i; + u.pfds[i].events = POLLIN; + } + if ((n = poll(u.pfds, ARRAYLEN(u.pfds), 0)) != -1) { + for (i = 0; i < ARRAYLEN(u.pfds); ++i) { + if (i && (u.pfds[i].revents & POLLNVAL)) continue; + PRINT(" ☼ %d (revents=%#hx fcntl(F_GETFL)=%#x isatty()=%hhhd)", i, + u.pfds[i].revents, fcntl(i, F_GETFL), isatty(i)); + } + } else { + PRINT(" poll() returned %d %m", n); + } + + if (!sigprocmask(SIG_BLOCK, 0, &ss)) { + PRINT(""); + PRINT("SIGNALS {%#lx, %#lx}", ss.__bits[0], ss.__bits[1]); + if (ss.__bits[0] || ss.__bits[1]) { + for (i = 0; i < 32; ++i) { + if (ss.__bits[0] & (1u << i)) { + PRINT(" ☼ %G (%d) is masked", i + 1, i + 1); + } + } + } else { + PRINT(" no signals blocked"); + } + } else { + PRINT(""); + PRINT("SIGNALS"); + PRINT(" error: sigprocmask() failed %m"); + } + + PRINT(""); + PRINT("ARGUMENTS (%p)", __argv); + if (*__argv) { + for (i = 0; i < __argc; ++i) { + PRINT(" ☼ %s", __argv[i]); + } + } else { + PRINT(" none"); + } + + PRINT(""); + PRINT("ENVIRONMENT (%p)", __envp); + if (*__envp) { + for (env = __envp; *env; ++env) { + PRINT(" ☼ %s", *env); + } + } else { + PRINT(" none"); + } + + PRINT(""); + PRINT("AUXILIARY (%p)", __auxv); + if (*__auxv) { + if (*__auxv) { + for (auxp = __auxv; *auxp; auxp += 2) { + if ((auxinfo = DescribeAuxv(auxp[0]))) { + ksnprintf(u.path, sizeof(u.path), auxinfo->fmt, auxp[1]); + PRINT(" ☼ %16s[%4ld] = %s", auxinfo->name, auxp[0], u.path); + } else { + PRINT(" ☼ %16s[%4ld] = %014p", "unknown", auxp[0], auxp[1]); + } + } + } + } else { + PRINT(" none"); + } + + PRINT(""); + PRINT("SPECIALS"); + umask((i = umask(022))); + PRINT(" ☼ %s = %#o", "umask()", i); + PRINT(" ☼ %s = %d", "getpid()", getpid()); + PRINT(" ☼ %s = %d", "getppid()", getppid()); + PRINT(" ☼ %s = %d", "getpgrp()", getpgrp()); + PRINT(" ☼ %s = %d", "getsid()", getsid(0)); + PRINT(" ☼ %s = %d", "getuid()", getuid()); + PRINT(" ☼ %s = %d", "geteuid()", geteuid()); + PRINT(" ☼ %s = %d", "getgid()", getgid()); + PRINT(" ☼ %s = %d", "getegid()", getegid()); + PRINT(" ☼ %s = %#s", "kTmpPath", kTmpPath); + PRINT(" ☼ %s = %#s", "kNtSystemDirectory", kNtSystemDirectory); + PRINT(" ☼ %s = %#s", "kNtWindowsDirectory", kNtWindowsDirectory); + PRINT(" ☼ %s = %#s", "GetProgramExecutableName", GetProgramExecutableName()); + PRINT(" ☼ %s = %#s", "GetInterpreterExecutableName", + GetInterpreterExecutableName(u.path, sizeof(u.path))); + PRINT(" ☼ %s = %p", "RSP", __builtin_frame_address(0)); + PRINT(" ☼ %s = %p", "GetStackAddr()", GetStackAddr(0)); + PRINT(" ☼ %s = %p", "GetStaticStackAddr(0)", GetStaticStackAddr(0)); + PRINT(" ☼ %s = %p", "GetStackSize()", GetStackSize()); + + PRINT(""); + PRINT("MEMTRACK"); + PrintMemoryIntervals(2, &_mmi); + + PRINT(""); + PRINT("TERMIOS"); + for (i = 0; i < 2; ++i) { + if (!tcgetattr(i, &termios)) { + PRINT(" - stdin"); + kprintf(prologue); + kprintf(" c_iflag ="); + if (termios.c_iflag & IGNBRK) kprintf(" IGNBRK"); + if (termios.c_iflag & BRKINT) kprintf(" BRKINT"); + if (termios.c_iflag & IGNPAR) kprintf(" IGNPAR"); + if (termios.c_iflag & PARMRK) kprintf(" PARMRK"); + if (termios.c_iflag & INPCK) kprintf(" INPCK"); + if (termios.c_iflag & ISTRIP) kprintf(" ISTRIP"); + if (termios.c_iflag & INLCR) kprintf(" INLCR"); + if (termios.c_iflag & IGNCR) kprintf(" IGNCR"); + if (termios.c_iflag & ICRNL) kprintf(" ICRNL"); + if (termios.c_iflag & IXON) kprintf(" IXON"); + if (termios.c_iflag & IXANY) kprintf(" IXANY"); + if (termios.c_iflag & IXOFF) kprintf(" IXOFF"); + if (termios.c_iflag & IMAXBEL) kprintf(" IMAXBEL"); + if (termios.c_iflag & IUTF8) kprintf(" IUTF8"); + if (termios.c_iflag & IUCLC) kprintf(" IUCLC"); + kprintf("\n"); + kprintf(prologue); + kprintf(" c_oflag ="); + if (termios.c_oflag & OPOST) kprintf(" OPOST"); + if (termios.c_oflag & ONLCR) kprintf(" ONLCR"); + if (termios.c_oflag & OCRNL) kprintf(" OCRNL"); + if (termios.c_oflag & ONOCR) kprintf(" ONOCR"); + if (termios.c_oflag & ONLRET) kprintf(" ONLRET"); + if (termios.c_oflag & OFILL) kprintf(" OFILL"); + if (termios.c_oflag & OFDEL) kprintf(" OFDEL"); + if (termios.c_oflag & OLCUC) kprintf(" OLCUC"); + if ((termios.c_oflag & NLDLY) == NL0) { + kprintf(" NL0"); + } else if ((termios.c_oflag & NLDLY) == NL1) { + kprintf(" NL1"); + } else if ((termios.c_oflag & NLDLY) == NL2) { + kprintf(" NL2"); + } else if ((termios.c_oflag & NLDLY) == NL3) { + kprintf(" NL3"); + } + if ((termios.c_oflag & CRDLY) == CR0) { + kprintf(" CR0"); + } else if ((termios.c_oflag & CRDLY) == CR1) { + kprintf(" CR1"); + } else if ((termios.c_oflag & CRDLY) == CR2) { + kprintf(" CR2"); + } else if ((termios.c_oflag & CRDLY) == CR3) { + kprintf(" CR3"); + } + if ((termios.c_oflag & TABDLY) == TAB0) { + kprintf(" TAB0"); + } else if ((termios.c_oflag & TABDLY) == TAB1) { + kprintf(" TAB1"); + } else if ((termios.c_oflag & TABDLY) == TAB2) { + kprintf(" TAB2"); + } else if ((termios.c_oflag & TABDLY) == TAB3) { + kprintf(" TAB3"); + } + if ((termios.c_oflag & BSDLY) == BS0) { + kprintf(" BS0"); + } else if ((termios.c_oflag & BSDLY) == BS1) { + kprintf(" BS1"); + } + if ((termios.c_oflag & VTDLY) == VT0) { + kprintf(" VT0"); + } else if ((termios.c_oflag & VTDLY) == VT1) { + kprintf(" VT1"); + } + if ((termios.c_oflag & FFDLY) == FF0) { + kprintf(" FF0"); + } else if ((termios.c_oflag & FFDLY) == FF1) { + kprintf(" FF1"); + } + kprintf("\n"); + kprintf(prologue); + kprintf(" c_cflag ="); + if (termios.c_cflag & PARENB) kprintf(" PARENB"); + if (termios.c_cflag & PARODD) kprintf(" PARODD"); + if (termios.c_cflag & CSTOPB) kprintf(" CSTOPB"); + if (termios.c_cflag & PARODD) kprintf(" PARODD"); + if (termios.c_cflag & HUPCL) kprintf(" HUPCL"); + if (termios.c_cflag & CREAD) kprintf(" CREAD"); + if (termios.c_cflag & CLOCAL) kprintf(" CLOCAL"); + if ((termios.c_cflag & CSIZE) == CS5) { + kprintf(" CS5"); + } else if ((termios.c_cflag & CSIZE) == CS6) { + kprintf(" CS6"); + } else if ((termios.c_cflag & CSIZE) == CS7) { + kprintf(" CS7"); + } else if ((termios.c_cflag & CSIZE) == CS8) { + kprintf(" CS8"); + } + kprintf("\n"); + kprintf(prologue); + kprintf(" c_lflag ="); + if (termios.c_lflag & ISIG) kprintf(" ISIG"); + if (termios.c_lflag & ICANON) kprintf(" ICANON"); + if (termios.c_lflag & ECHO) kprintf(" ECHO"); + if (termios.c_lflag & ECHOE) kprintf(" ECHOE"); + if (termios.c_lflag & ECHOK) kprintf(" ECHOK"); + if (termios.c_lflag & ECHONL) kprintf(" ECHONL"); + if (termios.c_lflag & NOFLSH) kprintf(" NOFLSH"); + if (termios.c_lflag & TOSTOP) kprintf(" TOSTOP"); + if (termios.c_lflag & IEXTEN) kprintf(" IEXTEN"); + if (termios.c_lflag & ECHOCTL) kprintf(" ECHOCTL"); + if (termios.c_lflag & ECHOPRT) kprintf(" ECHOPRT"); + if (termios.c_lflag & ECHOKE) kprintf(" ECHOKE"); + if (termios.c_lflag & FLUSHO) kprintf(" FLUSHO"); + if (termios.c_lflag & PENDIN) kprintf(" PENDIN"); + if (termios.c_lflag & XCASE) kprintf(" XCASE"); + kprintf("\n"); + PRINT(" c_ispeed = %u", termios.c_ispeed); + PRINT(" c_ospeed = %u", termios.c_ospeed); + PRINT(" c_cc[VINTR] = CTRL-%c", CTRL(termios.c_cc[VINTR])); + PRINT(" c_cc[VQUIT] = CTRL-%c", CTRL(termios.c_cc[VQUIT])); + PRINT(" c_cc[VERASE] = CTRL-%c", CTRL(termios.c_cc[VERASE])); + PRINT(" c_cc[VKILL] = CTRL-%c", CTRL(termios.c_cc[VKILL])); + PRINT(" c_cc[VEOF] = CTRL-%c", CTRL(termios.c_cc[VEOF])); + PRINT(" c_cc[VTIME] = CTRL-%c", CTRL(termios.c_cc[VTIME])); + PRINT(" c_cc[VMIN] = CTRL-%c", CTRL(termios.c_cc[VMIN])); + PRINT(" c_cc[VSTART] = CTRL-%c", CTRL(termios.c_cc[VSTART])); + PRINT(" c_cc[VSTOP] = CTRL-%c", CTRL(termios.c_cc[VSTOP])); + PRINT(" c_cc[VSUSP] = CTRL-%c", CTRL(termios.c_cc[VSUSP])); + PRINT(" c_cc[VEOL] = CTRL-%c", CTRL(termios.c_cc[VEOL])); + PRINT(" c_cc[VSWTC] = CTRL-%c", CTRL(termios.c_cc[VSWTC])); + PRINT(" c_cc[VREPRINT] = CTRL-%c", CTRL(termios.c_cc[VREPRINT])); + PRINT(" c_cc[VDISCARD] = CTRL-%c", CTRL(termios.c_cc[VDISCARD])); + PRINT(" c_cc[VWERASE] = CTRL-%c", CTRL(termios.c_cc[VWERASE])); + PRINT(" c_cc[VLNEXT] = CTRL-%c", CTRL(termios.c_cc[VLNEXT])); + PRINT(" c_cc[VEOL2] = CTRL-%c", CTRL(termios.c_cc[VEOL2])); + } else { + PRINT(" - tcgetattr(%d) failed %m", i); + } + } + + if (IsWindows()) { + struct NtStartupInfo startinfo; + GetStartupInfo(&startinfo); + + PRINT(""); + PRINT("GETSTARTUPINFO"); + if (startinfo.lpDesktop) + PRINT(" ☼ %s = %#!hs", "lpDesktop", startinfo.lpDesktop); + if (startinfo.lpTitle) PRINT(" ☼ %s = %#!hs", "lpTitle", startinfo.lpTitle); + if (startinfo.dwX) PRINT(" ☼ %s = %u", "dwX", startinfo.dwX); + if (startinfo.dwY) PRINT(" ☼ %s = %u", "dwY", startinfo.dwY); + if (startinfo.dwXSize) PRINT(" ☼ %s = %u", "dwXSize", startinfo.dwXSize); + if (startinfo.dwYSize) PRINT(" ☼ %s = %u", "dwYSize", startinfo.dwYSize); + if (startinfo.dwXCountChars) + PRINT(" ☼ %s = %u", "dwXCountChars", startinfo.dwXCountChars); + if (startinfo.dwYCountChars) + PRINT(" ☼ %s = %u", "dwYCountChars", startinfo.dwYCountChars); + if (startinfo.dwFillAttribute) + PRINT(" ☼ %s = %u", "dwFillAttribute", startinfo.dwFillAttribute); + if (startinfo.dwFlags) + PRINT(" ☼ %s = %s", "dwFlags", DescribeNtStartFlags(startinfo.dwFlags)); + if (startinfo.wShowWindow) + PRINT(" ☼ %s = %hu", "wShowWindow", startinfo.wShowWindow); + if (startinfo.cbReserved2) + PRINT(" ☼ %s = %hu", "cbReserved2", startinfo.cbReserved2); + if (startinfo.hStdInput) + PRINT(" ☼ %s = %ld", "hStdInput", startinfo.hStdInput); + if (startinfo.hStdOutput) + PRINT(" ☼ %s = %ld", "hStdOutput", startinfo.hStdOutput); + if (startinfo.hStdError) + PRINT(" ☼ %s = %ld", "hStdError", startinfo.hStdError); + + PRINT(""); + PRINT("STANDARD HANDLES"); + PRINT(" ☼ %s = %ld", "GetStdHandle(kNtStdInputHandle)", + GetStdHandle(kNtStdInputHandle)); + PRINT(" ☼ %s = %ld", "GetStdHandle(kNtStdOutputHandle)", + GetStdHandle(kNtStdOutputHandle)); + PRINT(" ☼ %s = %ld", "GetStdHandle(kNtStdErrorHandle)", + GetStdHandle(kNtStdErrorHandle)); + + PRINT(""); + PRINT("TEB"); + PRINT(" ☼ gs:0x%02x %s = %p", 0x00, "NtGetSeh()", _NtGetSeh()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x08, "NtGetStackHigh()", _NtGetStackHigh()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x10, "NtGetStackLow()", _NtGetStackLow()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x18, "_NtGetSubsystemTib()", + _NtGetSubsystemTib()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x20, "NtGetFib()", _NtGetFib()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x30, "NtGetTeb()", NtGetTeb()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x38, "NtGetEnv()", _NtGetEnv()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x40, "NtGetPid()", NtGetPid()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x48, "NtGetTid()", NtGetTid()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x50, "NtGetRpc()", _NtGetRpc()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x58, "NtGetTls()", _NtGetTls()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x60, "NtGetPeb()", NtGetPeb()); + PRINT(" ☼ gs:0x%02x %s = %p", 0x68, "NtGetErr()", NtGetErr()); + + PRINT(""); + PRINT("DEPENDENCIES"); + struct NtLinkedList *head = &NtGetPeb()->Ldr->InLoadOrderModuleList; + struct NtLinkedList *ldr = head->Next; + do { + const struct NtLdrDataTableEntry *dll = + (const struct NtLdrDataTableEntry *)ldr; + PRINT(" ☼ %.*!hs (%'zukb)", dll->FullDllName.Length, + dll->FullDllName.Data, dll->SizeOfImage / 1024); + } while ((ldr = ldr->Next) && ldr != head); + } + + PRINT(""); + __strace = st; + g_ftrace = ft; + errno = e; +} diff --git a/libc/runtime/printmemoryintervals.c b/libc/runtime/printmemoryintervals.c index 3569334b9..2fdfebce4 100644 --- a/libc/runtime/printmemoryintervals.c +++ b/libc/runtime/printmemoryintervals.c @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/itoa.h" -#include "libc/log/libfatal.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/runtime/memtrack.internal.h" @@ -41,20 +41,20 @@ void PrintMemoryIntervals(int fd, const struct MemoryIntervals *mm) { for (i = 0; i < mm->i; ++i) { frames = mm->p[i].y + 1 - mm->p[i].x; maptally += frames; - __printf("%012x-%012x %s %,*dx%s", ADDR(mm->p[i].x), ADDR(mm->p[i].y + 1), - DescribeMapping(mm->p[i].prot, mm->p[i].flags, mode), w, frames, - DescribeFrame(mm->p[i].x)); + kprintf("%012lx-%012lx %s %'*ldx%s", ADDR(mm->p[i].x), ADDR(mm->p[i].y + 1), + DescribeMapping(mm->p[i].prot, mm->p[i].flags, mode), w, frames, + DescribeFrame(mm->p[i].x)); if (i + 1 < _mmi.i) { frames = mm->p[i + 1].x - mm->p[i].y - 1; if (frames && IsNoteworthyHole(i, mm)) { gaptally += frames; - __printf(" w/ %,d frame hole", frames); + kprintf(" w/ %'ld frame hole", frames); } } if (mm->p[i].h != -1) { - __printf(" h=%d", mm->p[i].h); + kprintf(" h=%ld", mm->p[i].h); } - __printf("\r\n"); + kprintf("\n"); } - __printf("# %d frames mapped w/ %,d frames gapped\r\n", maptally, gaptally); + kprintf("# %ld frames mapped w/ %'ld frames gapped\n", maptally, gaptally); } diff --git a/libc/runtime/progname.S b/libc/runtime/progname.S index d10a94011..46e92d2db 100644 --- a/libc/runtime/progname.S +++ b/libc/runtime/progname.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Provides argv[0] The BSD Way. .initbss 300,_init___progname diff --git a/libc/runtime/program_executable_name.c b/libc/runtime/program_executable_name.c deleted file mode 100644 index eeea10d6a..000000000 --- a/libc/runtime/program_executable_name.c +++ /dev/null @@ -1,135 +0,0 @@ -/*-*- 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/assert.h" -#include "libc/bits/bits.h" -#include "libc/calls/calls.h" -#include "libc/calls/internal.h" -#include "libc/calls/sysdebug.internal.h" -#include "libc/dce.h" -#include "libc/log/libfatal.internal.h" -#include "libc/macros.internal.h" -#include "libc/mem/alloca.h" -#include "libc/nt/runtime.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/str/tpenc.h" -#include "libc/str/utf16.h" -#include "libc/sysv/consts/at.h" -#include "libc/sysv/consts/auxv.h" -#include "libc/sysv/consts/ok.h" -#include "libc/sysv/consts/prot.h" - -#define SIZE 1024 -#define CTL_KERN 1 -#define KERN_PROC 14 -#define KERN_PROC_PATHNAME_FREEBSD 12 -#define KERN_PROC_PATHNAME_NETBSD 5 - -/** - * Absolute path of executable. - * - * This variable is initialized automatically at startup. The path is - * guaranteed to exist, except on XNU and OpenBSD. It may be a symlink. - * It may be spoofed. - */ -char program_executable_name[SIZE]; - -static textwindows bool GetNtExePath(char executable[SIZE]) { - uint64_t w; - wint_t x, y; - uint32_t i, j; - char16_t path16[PATH_MAX + 1]; - if (!GetModuleFileName(0, path16, ARRAYLEN(path16))) return 0; - for (i = j = 0; (x = path16[i++] & 0xffff);) { - if (!IsUcs2(x)) { - y = path16[i++] & 0xffff; - x = MergeUtf16(x, y); - } - if (x == '\\') x = '/'; - w = tpenc(x); - do { - executable[j] = w; - if (++j == SIZE) { - return false; - } - } while ((w >>= 8)); - } - executable[j] = 0; - return true; -} - -static textstartup void GetProgramExecutableName(char executable[SIZE], - char *p) { - char *t; - size_t m; - ssize_t n; - int cmd[4]; - if (IsWindows() && GetNtExePath(executable)) return; - n = 0; - if (fileexists(p)) { - if (!_isabspath(p)) { - if (getcwd(executable, SIZE - 1)) { - n = strlen(executable); - executable[n++] = '/'; - } - } - } else if ((n = sys_readlinkat(AT_FDCWD, "/proc/self/exe", executable, - SIZE - 1)) > 0) { - executable[n] = 0; - return; - } else if ((n = sys_readlinkat(AT_FDCWD, "/proc/curproc/file", executable, - SIZE - 1)) > 0) { - executable[n] = 0; - return; - } else if (IsFreebsd() || IsNetbsd()) { - cmd[0] = CTL_KERN; - cmd[1] = KERN_PROC; - if (IsFreebsd()) { - cmd[2] = KERN_PROC_PATHNAME_FREEBSD; - } else { - cmd[2] = KERN_PROC_PATHNAME_NETBSD; - } - cmd[3] = -1; - m = SIZE; - if (sysctl(cmd, ARRAYLEN(cmd), executable, &m, 0, 0) != -1) { - return; - } - } - for (; *p; ++p) { - if (n + 1 < SIZE) { - executable[n++] = *p; - } - } - executable[n] = 0; -} - -textstartup void program_executable_name_init(int argc, char **argv, - char **envp, intptr_t *auxv) { - static bool once; - char executable[SIZE]; - if (!cmpxchg(&once, 0, 1)) return; - __stpcpy(program_executable_name, argv[0]); - GetProgramExecutableName(executable, argv[0]); - __stpcpy(program_executable_name, executable); - SYSDEBUG("GetProgramExecutableName() -> %s", program_executable_name); -} - -const void *const program_executable_name_init_ctor[] initarray = { - program_executable_name_init, -}; diff --git a/libc/runtime/program_invocation_short_name.S b/libc/runtime/program_invocation_short_name.S index ee0c2d871..f6874d53f 100644 --- a/libc/runtime/program_invocation_short_name.S +++ b/libc/runtime/program_invocation_short_name.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Supplies basename(argv[0]) The GNU Way. .initbss 400,_init_program_invocation_short_name diff --git a/libc/runtime/pthread.c b/libc/runtime/pthread.c index 62fda4684..89f6b9af8 100644 --- a/libc/runtime/pthread.c +++ b/libc/runtime/pthread.c @@ -16,8 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" #include "libc/errno.h" +#include "libc/intrin/lockcmpxchg.h" #include "libc/runtime/runtime.h" typedef void *pthread_t; @@ -25,7 +25,7 @@ typedef bool pthread_once_t; typedef int pthread_mutex_t; int pthread_once(pthread_once_t *once, void init(void)) { - if (lockcmpxchg(once, 0, 1)) init(); + if (_lockcmpxchg(once, 0, 1)) init(); return 0; } diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index c46add19e..989c6b2de 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -9,12 +9,11 @@ COSMOPOLITAN_C_START_ typedef long jmp_buf[8] forcealign(CACHELINE); extern char **environ; /* CRT */ -extern const int __argc; /* CRT */ -extern char **const __argv; /* CRT */ -extern char **const __envp; /* CRT */ -extern unsigned long *const __auxv; /* CRT */ +extern int __argc; /* CRT */ +extern char **__argv; /* CRT */ +extern char **__envp; /* CRT */ +extern unsigned long *__auxv; /* CRT */ extern intptr_t __oldstack; /* CRT */ -extern char program_executable_name[]; /* RII */ extern char *program_invocation_name; /* RII */ extern char *program_invocation_short_name; /* RII */ extern int g_ftrace; /* CRT */ @@ -27,6 +26,7 @@ extern unsigned char _base[] forcealign(PAGESIZE); /* αpε */ extern unsigned char _ehead[] forcealign(PAGESIZE); /* αpε */ extern unsigned char _etext[] forcealign(PAGESIZE); /* αpε */ extern unsigned char _edata[] forcealign(PAGESIZE); /* αpε */ +extern unsigned char _ezip[]; /* αpε */ extern unsigned char _end[] forcealign(FRAMESIZE); /* αpε */ extern unsigned char _ereal; /* αpε */ extern unsigned char __privileged_start; /* αpε */ @@ -37,6 +37,8 @@ extern unsigned char *__relo_end[]; /* αpε */ extern uint8_t __zip_start[]; /* αpε */ extern uint8_t __zip_end[]; /* αpε */ extern bool ftrace_enabled; +extern size_t __virtualmax; +extern bool __isworker; void mcount(void); unsigned long getauxval(unsigned long); @@ -48,6 +50,7 @@ void _longjmp(jmp_buf, int) libcesque wontreturn paramsnonnull(); void exit(int) wontreturn; void _exit(int) libcesque wontreturn; void _Exit(int) libcesque wontreturn; +void _Exit1(int) libcesque wontreturn; void quick_exit(int) wontreturn; void abort(void) wontreturn noinstrument; int __cxa_atexit(void *, void *, void *) libcesque; @@ -94,9 +97,14 @@ void _weakfree(void *); void free_s(void *) paramsnonnull() libcesque; int close_s(int *) paramsnonnull() libcesque; int OpenExecutable(void); -void ftrace_install(void); +int ftrace_install(void); long GetResourceLimit(int); long GetMaxFd(void); +char *GetProgramExecutableName(void); +char *GetInterpreterExecutableName(char *, size_t); +void __printargs(const char *); +void __paginate(int, const char *); +int __arg_max(void); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/runtime/runtime.mk b/libc/runtime/runtime.mk index e012c0de1..1892b2408 100644 --- a/libc/runtime/runtime.mk +++ b/libc/runtime/runtime.mk @@ -57,10 +57,9 @@ $(LIBC_RUNTIME_A).pkg: \ $(LIBC_RUNTIME_A_OBJS) \ $(foreach x,$(LIBC_RUNTIME_A_DIRECTDEPS),$($(x)_A).pkg) -o/$(MODE)/libc/runtime/printf.o \ -o/$(MODE)/libc/runtime/abort-nt.o \ +o/$(MODE)/libc/runtime/fork-nt.o \ +o/$(MODE)/libc/runtime/printmemoryintervals.o \ o/$(MODE)/libc/runtime/arememoryintervalsok.o \ -o/$(MODE)/libc/runtime/assertfail.o \ o/$(MODE)/libc/runtime/directmap.o \ o/$(MODE)/libc/runtime/directmapnt.o \ o/$(MODE)/libc/runtime/findmemoryinterval.o \ @@ -70,28 +69,43 @@ o/$(MODE)/libc/runtime/ezmap.o \ o/$(MODE)/libc/runtime/getdosargv.o \ o/$(MODE)/libc/runtime/getdosenviron.o \ o/$(MODE)/libc/runtime/hook.greg.o \ +o/$(MODE)/libc/runtime/mprotect.greg.o \ +o/$(MODE)/libc/runtime/mprotect-nt.greg.o \ +o/$(MODE)/libc/runtime/ismemtracked.greg.o \ o/$(MODE)/libc/runtime/isheap.o \ -o/$(MODE)/libc/runtime/memtrack.o \ o/$(MODE)/libc/runtime/memtracknt.o \ +o/$(MODE)/libc/runtime/memtrack.greg.o \ +o/$(MODE)/libc/runtime/metalprintf.greg.o \ +o/$(MODE)/libc/runtime/printargs.greg.o \ o/$(MODE)/libc/runtime/mman.greg.o \ o/$(MODE)/libc/runtime/print.greg.o \ o/$(MODE)/libc/runtime/stackchkfail.o \ o/$(MODE)/libc/runtime/stackchkfaillocal.o \ -o/$(MODE)/libc/runtime/winmain.greg.o: \ - OVERRIDE_CFLAGS += \ - $(NO_MAGIC) - -o/$(MODE)/libc/runtime/printf.o \ -o/$(MODE)/libc/runtime/memtrack.o \ -o/$(MODE)/libc/runtime/mman.greg.o: \ +o/$(MODE)/libc/runtime/winmain.greg.o \ +o/$(MODE)/libc/runtime/opensymboltable.o \ +o/$(MODE)/libc/runtime/getsymboltable.greg.o: \ OVERRIDE_CFLAGS += \ -ffreestanding \ - -mgeneral-regs-only + $(NO_MAGIC) + +# must use alloca() +# can't use asan or any runtime services +o/$(MODE)/libc/runtime/fork-nt.o: \ + OVERRIDE_CPPFLAGS += \ + -DSTACK_FRAME_UNLIMITED o/$(MODE)/libc/runtime/qsort.o: \ OVERRIDE_CFLAGS += \ -Og +# make always linked runtimes less huge when it's profitable +o//libc/runtime/mmap.o \ +o//libc/runtime/munmap.o \ +o//libc/runtime/memtrack.greg.o \ +o//libc/runtime/opensymboltable.greg.o: \ + OVERRIDE_CFLAGS += \ + -Os + o/$(MODE)/libc/runtime/ftrace.greg.o: \ OVERRIDE_CFLAGS += \ -mgeneral-regs-only diff --git a/libc/runtime/stack.h b/libc/runtime/stack.h index a5d580fcf..789094553 100644 --- a/libc/runtime/stack.h +++ b/libc/runtime/stack.h @@ -2,6 +2,7 @@ #define COSMOPOLITAN_LIBC_RUNTIME_STACK_H_ #include "ape/config.h" #include "libc/dce.h" +#include "libc/nt/version.h" #include "libc/runtime/runtime.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) @@ -27,7 +28,7 @@ /** * Tunes APE stack virtual address. * - * This defaults to `0x700000000000 - STACKSIZE`. The value defined by + * This defaults to `0x7e0000000000 - STACKSIZE`. The value defined by * this macro will be respected, with two exceptions: (1) in MODE=tiny * the operating system provided stack is used instead and (2) Windows * Seven doesn't support 64-bit addresses so 0x10000000 - GetStackSize @@ -48,10 +49,12 @@ #define _STACK_EXTRA "" #endif -#if defined(__GNUC__) && defined(__ELF__) +#if defined(__GNUC__) && defined(__ELF__) && !defined(__STRICT_ANSI__) COSMOPOLITAN_C_START_ +extern char ape_stack_prot[] __attribute__((__weak__)); extern char ape_stack_memsz[] __attribute__((__weak__)); +extern char ape_stack_align[] __attribute__((__weak__)); #define GetStackSize() ((uintptr_t)ape_stack_memsz) @@ -59,23 +62,23 @@ extern char ape_stack_memsz[] __attribute__((__weak__)); * Returns address of bottom of stack. */ #define GetStackAddr(ADDEND) \ - (((intptr_t)__builtin_frame_address(0) & -GetStackSize()) + (ADDEND)) + ((((intptr_t)__builtin_frame_address(0) - 1) & -GetStackSize()) + (ADDEND)) /** * Returns preferred bottom address of stack. */ -#define GetStaticStackAddr(ADDEND) \ - ({ \ - intptr_t vAddr; \ - if (!IsWindows() || NtGetVersion() >= kNtVersionWindows10) { \ - asm(".weak\tape_stack_vaddr\n\t" \ - "movabs\t%1+ape_stack_vaddr,%0" \ - : "=r"(vAddr) \ - : "i"(ADDEND)); \ - } else { \ - vAddr = 0x10000000; \ - } \ - vAddr; \ +#define GetStaticStackAddr(ADDEND) \ + ({ \ + intptr_t vAddr; \ + if (!IsWindows() || IsAtLeastWindows10()) { \ + __asm__(".weak\tape_stack_vaddr\n\t" \ + "movabs\t%1+ape_stack_vaddr,%0" \ + : "=r"(vAddr) \ + : "i"(ADDEND)); \ + } else { \ + vAddr = 0x10000000; \ + } \ + vAddr; \ }) COSMOPOLITAN_C_END_ diff --git a/libc/runtime/straceinit.greg.c b/libc/runtime/straceinit.greg.c new file mode 100644 index 000000000..848d96cf3 --- /dev/null +++ b/libc/runtime/straceinit.greg.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/bits/safemacros.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/log/libfatal.internal.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" + +/** + * Enables plaintext system call logging if `--strace` flag is passed. + */ +textstartup int __strace_init(int argc, char **argv, char **envp, long *auxv) { + /* asan isn't initialized yet at runlevel 300 */ + if (__intercept_flag(&argc, argv, "--strace") || + __atoul(nulltoempty(__getenv(envp, "STRACE")))) { + ++__strace; + } + return (__argc = argc); +} diff --git a/libc/runtime/symbols.internal.h b/libc/runtime/symbols.internal.h index 6ee2ed1d5..566c7e018 100644 --- a/libc/runtime/symbols.internal.h +++ b/libc/runtime/symbols.internal.h @@ -1,21 +1,30 @@ #ifndef COSMOPOLITAN_LIBC_SYMBOLS_H_ #define COSMOPOLITAN_LIBC_SYMBOLS_H_ +#include "libc/bits/bits.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +#define SYMBOLS_MAGIC READ32LE("SYMT") +#define SYMBOLS_ABI 1 + struct Symbol { unsigned x; /* start (relative to addr_base) */ unsigned y; /* start + size - 1 (inclusive) */ }; struct SymbolTable { - size_t count; /* of `symbols` */ - size_t mapsize; /* of this object */ - intptr_t addr_base; /* IMAGE_BASE_VIRTUAL */ - intptr_t addr_end; /* _end - 1 */ - unsigned *names; /* relative to `name_base` */ - char *name_base; /* double-nul terminated w/ empty first */ - struct Symbol symbols[]; /* sorted and non-overlapping intervals */ + uint32_t magic; /* 0xFEEDABEE little endian */ + uint32_t abi; /* 1 */ + uint64_t count; /* of `symbols` */ + uint64_t size; /* file size */ + uint64_t mapsize; /* of this object */ + int64_t addr_base; /* IMAGE_BASE_VIRTUAL */ + int64_t addr_end; /* _end - 1 */ + uint32_t *names; /* relative to `name_base` */ + char *name_base; /* double-nul terminated w/ empty first */ + uint32_t names_offset; /* for file loading */ + uint32_t name_base_offset; /* for file loading */ + struct Symbol symbols[]; /* sorted and non-overlapping intervals */ }; struct SymbolTable *GetSymbolTable(void); diff --git a/libc/runtime/sysconf.c b/libc/runtime/sysconf.c index cec42e6ad..6c685d528 100644 --- a/libc/runtime/sysconf.c +++ b/libc/runtime/sysconf.c @@ -22,6 +22,7 @@ #include "libc/macros.internal.h" #include "libc/runtime/clktck.h" #include "libc/runtime/sysconf.h" +#include "libc/sysv/consts/limits.h" #include "libc/sysv/consts/rlim.h" #include "libc/sysv/consts/rlimit.h" @@ -42,7 +43,7 @@ long sysconf(int name) { int n; switch (name) { case _SC_ARG_MAX: - return ARG_MAX; + return _ARG_MAX; case _SC_CHILD_MAX: return GetResourceLimit(RLIMIT_NPROC); case _SC_CLK_TCK: diff --git a/libc/runtime/vfork.S b/libc/runtime/vfork.S index 197d6f763..b09a0ff36 100644 --- a/libc/runtime/vfork.S +++ b/libc/runtime/vfork.S @@ -17,14 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" +#include "libc/calls/strace.internal.h" #include "libc/macros.internal.h" .privileged -#ifdef __FSANITIZE_ADDRESS__ -vfork: jmp fork # TODO: asan and vfork don't mix? - .endfn vfork,globl -#else - // Forks process without copying page tables. // // This is the same as fork() except it's optimized for the case @@ -40,11 +36,24 @@ vfork: jmp fork # TODO: asan and vfork don't mix? // @returnstwice // @vforksafe vfork: +#ifdef __SANITIZE_ADDRESS__ + jmp fork # TODO: asan and vfork don't mix? + .endfn vfork,globl +#else #if SupportsWindows() testb IsWindows() - jnz sys_fork_nt + jnz sys_fork_nt # and we're lucky to have that #endif +#if SupportsOpenbsd() + testb IsOpenbsd() + jnz fork # fake vfork plus msyscall issues +#endif +#ifdef SYSDEBUG + ezlea .Llog,di + call __stracef +#endif /* SYSDEBUG */ mov __NR_vfork(%rip),%eax + mov errno(%rip),%r8d # avoid question of @vforksafe errno pop %rsi # saves return address in a register #if SupportsBsd() testb IsBsd() @@ -56,7 +65,8 @@ vfork: cmp $-4095,%eax jae systemfive_error #endif -0: ezlea __vforked,di +0: mov %r8d,errno(%rip) + ezlea __vforked,di test %eax,%eax jz 1f decl (%rdi) @@ -81,4 +91,11 @@ vfork.bsd: .endfn vfork.bsd #endif /* BSD */ -#endif /* __FSANITIZE_ADDRESS__ */ +#ifdef SYSDEBUG + .rodata.str1.1 +.Llog: .ascii STRACE_PROLOGUE + .asciz "vfork()\n" + .previous +#endif /* DEBUGSYS */ + +#endif /* __SANITIZE_ADDRESS__ */ diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index 8f0498b4c..21a40d890 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -20,11 +20,19 @@ #include "libc/bits/pushpop.h" #include "libc/bits/weaken.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/elf/pf2prot.internal.h" +#include "libc/errno.h" #include "libc/fmt/fmt.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/nomultics.internal.h" #include "libc/log/libfatal.internal.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/bsr.h" +#include "libc/nexgen32e/nt2sysv.h" +#include "libc/nexgen32e/rdtsc.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/nt/enum/filemapflags.h" @@ -37,15 +45,29 @@ #include "libc/nt/pedef.internal.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" +#include "libc/nt/signals.h" +#include "libc/nt/struct/ntexceptionpointers.h" #include "libc/nt/struct/teb.h" +#include "libc/nt/synchronization.h" +#include "libc/nt/thunk/msabi.h" #include "libc/runtime/directmap.internal.h" #include "libc/runtime/internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" #include "libc/sock/internal.h" +#include "libc/str/str.h" #include "libc/str/tpenc.h" #include "libc/str/utf16.h" +#if IsTiny() +__msabi extern typeof(CreateFileMapping) *const __imp_CreateFileMappingW; +__msabi extern typeof(MapViewOfFileEx) *const __imp_MapViewOfFileEx; +__msabi extern typeof(VirtualProtect) *const __imp_VirtualProtect; +#define CreateFileMapping __imp_CreateFileMappingW +#define MapViewOfFileEx __imp_MapViewOfFileEx +#define VirtualProtect __imp_VirtualProtect +#endif + #define AT_EXECFN 31L #define MAP_ANONYMOUS 32 #define MAP_PRIVATE 2 @@ -62,13 +84,26 @@ struct WinArgs { char *argv[4096]; char *envp[4092]; intptr_t auxv[2][2]; - char argblock[ARG_MAX]; - char envblock[ARG_MAX]; + char argblock[ARG_MAX / 2]; + char envblock[ARG_MAX / 2]; }; -uint32_t __ntconsolemode; +extern uint32_t __winmainpid; +extern int64_t __wincrashearly; +extern const char kConsoleHandles[3]; -static noasan textwindows noinstrument void MakeLongDoubleLongAgain(void) { +static const short kConsoleModes[3] = { + kNtEnableProcessedInput | kNtEnableLineInput | kNtEnableEchoInput | + kNtEnableMouseInput | kNtEnableQuickEditMode | kNtEnableExtendedFlags | + kNtEnableAutoPosition | kNtEnableInsertMode | + kNtEnableVirtualTerminalInput, + kNtEnableProcessedOutput | kNtEnableWrapAtEolOutput | + kNtEnableVirtualTerminalProcessing, + kNtEnableProcessedOutput | kNtEnableWrapAtEolOutput | + kNtEnableVirtualTerminalProcessing, +}; + +forceinline void MakeLongDoubleLongAgain(void) { /* 8087 FPU Control Word IM: Invalid Operation ───────────────┐ DM: Denormal Operand ───────────────┐│ @@ -86,33 +121,69 @@ static noasan textwindows noinstrument void MakeLongDoubleLongAgain(void) { asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw)); } -static noasan textwindows wontreturn noinstrument void WinMainNew(void) { - int64_t h; - int version; - int i, count; - int64_t inhand; +static inline size_t StrLen16(const char16_t *s) { + size_t n; + for (n = 0;; ++n) { + if (!s[n]) { + return n; + } + } +} + +__msabi static textwindows int OnEarlyWinCrash(struct NtExceptionPointers *ep) { + uint32_t wrote; + char buf[64], *p = buf; + *p++ = 'c'; + *p++ = 'r'; + *p++ = 'a'; + *p++ = 's'; + *p++ = 'h'; + *p++ = ' '; + *p++ = '0'; + *p++ = 'x'; + p = __fixcpy(p, ep->ExceptionRecord->ExceptionCode, 32); + *p++ = ' '; + *p++ = 'r'; + *p++ = 'i'; + *p++ = 'p'; + *p++ = ' '; + p = __fixcpy(p, ep->ContextRecord ? ep->ContextRecord->Rip : -1, 32); + *p++ = '\r'; + *p++ = '\n'; + WriteFile(GetStdHandle(kNtStdErrorHandle), buf, p - buf, &wrote, 0); + ExitProcess(200); +} + +__msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) { + bool32 rc; + int64_t h, hand; + uint32_t oldprot; struct WinArgs *wa; const char16_t *env16; + int i, prot, count, version; intptr_t stackaddr, allocaddr; size_t allocsize, argsize, stacksize; - extern char os asm("__hostos"); - os = WINDOWS; /* madness https://news.ycombinator.com/item?id=21019722 */ version = NtGetPeb()->OSMajorVersion; __oldstack = (intptr_t)__builtin_frame_address(0); if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) { - SetConsoleCP(kNtCpUtf8); - SetConsoleOutputCP(kNtCpUtf8); - inhand = GetStdHandle(pushpop(kNtStdInputHandle)); - SetEnvironmentVariable(u"TERM", u"xterm-truecolor"); - GetConsoleMode(inhand, &__ntconsolemode); - SetConsoleMode(inhand, kNtEnableProcessedInput | kNtEnableLineInput | - kNtEnableEchoInput | kNtEnableMouseInput | - kNtEnableQuickEditMode | kNtEnableExtendedFlags | - kNtEnableAutoPosition | - kNtEnableVirtualTerminalInput); - SetConsoleMode(GetStdHandle(pushpop(kNtStdOutputHandle)), - kNtEnableProcessedOutput | kNtEnableWrapAtEolOutput | - kNtEnableVirtualTerminalProcessing); + __winmainpid = __pid; + rc = SetConsoleCP(kNtCpUtf8); + NTTRACE("SetConsoleCP(kNtCpUtf8) → %hhhd", rc); + rc = SetConsoleOutputCP(kNtCpUtf8); + NTTRACE("SetConsoleOutputCP(kNtCpUtf8) → %hhhd", rc); + for (i = 0; i < 3; ++i) { + hand = GetStdHandle(kConsoleHandles[i]); + rc = GetConsoleMode(hand, __ntconsolemode + i); + NTTRACE("GetConsoleMode(%p, [%s]) → %hhhd", hand, + i ? DescribeNtConsoleModeOutputFlags(__ntconsolemode[i]) + : DescribeNtConsoleModeInputFlags(__ntconsolemode[i]), + rc); + rc = SetConsoleMode(hand, kConsoleModes[i]); + NTTRACE("SetConsoleMode(%p, %s) → %hhhd", hand, + i ? DescribeNtConsoleModeOutputFlags(kConsoleModes[i]) + : DescribeNtConsoleModeInputFlags(kConsoleModes[i]), + rc); + } } _mmi.p = _mmi.s; _mmi.n = ARRAYLEN(_mmi.s); @@ -121,33 +192,40 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) { stacksize = GetStackSize(); allocsize = argsize + stacksize; allocaddr = stackaddr - argsize; - MapViewOfFileExNuma( - (_mmi.p[0].h = CreateFileMappingNuma( - -1, &kNtIsInheritable, kNtPageExecuteReadwrite, allocsize >> 32, - allocsize, NULL, kNtNumaNoPreferredNode)), - kNtFileMapWrite | kNtFileMapExecute, 0, 0, allocsize, (void *)allocaddr, - kNtNumaNoPreferredNode); + NTTRACE("WinMainNew() mapping %'zu byte arg block + stack at %p", allocsize, + allocaddr); + MapViewOfFileEx( + (_mmi.p[0].h = + CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite, + allocsize >> 32, allocsize, NULL)), + kNtFileMapWrite | kNtFileMapExecute, 0, 0, allocsize, (void *)allocaddr); + prot = (intptr_t)ape_stack_prot; + if (~prot & PROT_EXEC) { + VirtualProtect((void *)allocaddr, allocsize, kNtPageReadwrite, &oldprot); + } _mmi.p[0].x = allocaddr >> 16; _mmi.p[0].y = (allocaddr >> 16) + ((allocsize >> 16) - 1); - _mmi.p[0].prot = PROT_READ | PROT_WRITE | PROT_EXEC; + _mmi.p[0].prot = prot; _mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS; + _mmi.p[0].size = allocsize; _mmi.i = 1; wa = (struct WinArgs *)allocaddr; - count = GetDosArgv(GetCommandLine(), wa->argblock, ARRAYLEN(wa->argblock), - wa->argv, ARRAYLEN(wa->argv)); + NTTRACE("WinMainNew() loading arg block"); + count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv, + ARRAYLEN(wa->argv)); for (i = 0; wa->argv[0][i]; ++i) { if (wa->argv[0][i] == '\\') { wa->argv[0][i] = '/'; } } env16 = GetEnvironmentStrings(); + NTTRACE("WinMainNew() loading environment"); GetDosEnviron(env16, wa->envblock, ARRAYLEN(wa->envblock) - 8, wa->envp, ARRAYLEN(wa->envp) - 1); FreeEnvironmentStrings(env16); - wa->auxv[0][0] = pushpop(AT_EXECFN); - wa->auxv[0][1] = (intptr_t)wa->argv[0]; - _jmpstack((char *)stackaddr + stacksize, cosmo, count, wa->argv, wa->envp, - wa->auxv); + NTTRACE("WinMainNew() switching stacks"); + _jmpstack((char *)(stackaddr + stacksize - (intptr_t)ape_stack_align), cosmo, + count, wa->argv, wa->envp, wa->auxv); } /** @@ -182,12 +260,23 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) { * * @param hInstance call GetModuleHandle(NULL) from main if you need it */ -noasan textwindows noinstrument int64_t WinMain(int64_t hInstance, - int64_t hPrevInstance, - const char *lpCmdLine, - int nCmdShow) { +__msabi textwindows int64_t WinMain(int64_t hInstance, int64_t hPrevInstance, + const char *lpCmdLine, int64_t nCmdShow) { + const char16_t *cmdline; + extern char os asm("__hostos"); + extern uint64_t ts asm("kStartTsc"); + os = WINDOWS; /* madness https://news.ycombinator.com/item?id=21019722 */ + ts = rdtsc(); + __pid = GetCurrentProcessId(); + __wincrashearly = AddVectoredExceptionHandler(1, (void *)OnEarlyWinCrash); + cmdline = GetCommandLine(); +#ifdef SYSDEBUG + /* sloppy flag-only check for early initialization */ + if (__strstr16(cmdline, u"--strace")) ++__strace; +#endif + NTTRACE("WinMain()"); MakeLongDoubleLongAgain(); if (weaken(WinSockInit)) weaken(WinSockInit)(); if (weaken(WinMainForked)) weaken(WinMainForked)(); - WinMainNew(); + WinMainNew(cmdline); } diff --git a/libc/sock/accept-nt.c b/libc/sock/accept-nt.c index 8ac2cd7c9..d0bd84f4d 100644 --- a/libc/sock/accept-nt.c +++ b/libc/sock/accept-nt.c @@ -17,6 +17,8 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/mem/mem.h" #include "libc/nt/files.h" #include "libc/nt/struct/pollfd.h" @@ -38,9 +40,13 @@ textwindows int sys_accept_nt(struct Fd *fd, void *addr, uint32_t *addrsize, int client, oflags; struct SockFd *sockfd, *sockfd2; sockfd = (struct SockFd *)fd->extra; + if (_check_interrupts(true, g_fds.p)) return eintr(); for (;;) { - if (!WSAPoll(&(struct sys_pollfd_nt){fd->handle, POLLIN}, 1, 1000)) + if (!WSAPoll(&(struct sys_pollfd_nt){fd->handle, POLLIN}, 1, + __SIG_POLLING_INTERVAL_MS)) { + if (_check_interrupts(true, g_fds.p)) return eintr(); continue; + } if ((h = WSAAccept(fd->handle, addr, (int32_t *)addrsize, 0, 0)) != -1) { oflags = 0; if (flags & SOCK_CLOEXEC) oflags |= O_CLOEXEC; @@ -48,13 +54,13 @@ textwindows int sys_accept_nt(struct Fd *fd, void *addr, uint32_t *addrsize, if ((!(flags & SOCK_NONBLOCK) || __sys_ioctlsocket_nt(h, FIONBIO, (uint32_t[]){1}) != -1) && (sockfd2 = calloc(1, sizeof(struct SockFd)))) { - if ((client = __reservefd()) != -1) { + if ((client = __reservefd(-1)) != -1) { sockfd2->family = sockfd->family; sockfd2->type = sockfd->type; sockfd2->protocol = sockfd->protocol; - sockfd2->event = WSACreateEvent(); g_fds.p[client].kind = kFdSocket; g_fds.p[client].flags = oflags; + g_fds.p[client].mode = 0140666; g_fds.p[client].handle = h; g_fds.p[client].extra = (uintptr_t)sockfd2; return client; diff --git a/libc/sock/accept.c b/libc/sock/accept.c index e49b7d143..bd40fbc9f 100644 --- a/libc/sock/accept.c +++ b/libc/sock/accept.c @@ -26,6 +26,7 @@ * @param inout_addrsize provides and receives addr's byte length * @return client fd which needs close(), or -1 w/ errno * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ int accept(int fd, void *out_addr, uint32_t *inout_addrsize) { return accept4(fd, out_addr, inout_addrsize, 0); diff --git a/libc/sock/accept4.c b/libc/sock/accept4.c index 1d24bb048..168ca77b7 100644 --- a/libc/sock/accept4.c +++ b/libc/sock/accept4.c @@ -17,10 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" +#include "libc/sock/sockdebug.h" #include "libc/sysv/errfuns.h" /** @@ -33,16 +35,23 @@ * both the newly created socket and the server one * @return client fd which needs close(), or -1 w/ errno * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ int accept4(int fd, void *out_addr, uint32_t *inout_addrsize, int flags) { - if (!out_addr) return efault(); - if (!inout_addrsize) return efault(); - if (IsAsan() && !__asan_is_valid(out_addr, *inout_addrsize)) return efault(); - if (!IsWindows()) { - return sys_accept4(fd, out_addr, inout_addrsize, flags); + int rc; + char addrbuf[72]; + if (!out_addr || !inout_addrsize || + (IsAsan() && !__asan_is_valid(out_addr, *inout_addrsize))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_accept4(fd, out_addr, inout_addrsize, flags); } else if (__isfdkind(fd, kFdSocket)) { - return sys_accept_nt(&g_fds.p[fd], out_addr, inout_addrsize, flags); + rc = sys_accept_nt(&g_fds.p[fd], out_addr, inout_addrsize, flags); } else { - return ebadf(); + rc = ebadf(); } + STRACE("accept4(%d, [%s]) -> %d% lm", fd, + __describe_sockaddr(out_addr, inout_addrsize ? *inout_addrsize : 0), + rc); + return rc; } diff --git a/libc/sock/asanmsghdr.c b/libc/sock/asanmsghdr.c new file mode 100644 index 000000000..3d826738e --- /dev/null +++ b/libc/sock/asanmsghdr.c @@ -0,0 +1,31 @@ +/*-*- 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 2022 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/intrin/asan.internal.h" +#include "libc/sock/sock.h" + +bool __asan_is_valid_msghdr(const struct msghdr *msg) { + if (!__asan_is_valid(msg, sizeof(struct msghdr))) return false; + if (msg->msg_name) { + if (!__asan_is_valid(msg->msg_name, msg->msg_namelen)) return false; + } + if (msg->msg_control) { + if (!__asan_is_valid(msg->msg_control, msg->msg_controllen)) return false; + } + return __asan_is_valid_iov(msg->msg_iov, msg->msg_iovlen); +} diff --git a/libc/sock/basesocket.c b/libc/sock/basesocket.c new file mode 100644 index 000000000..cf82d7660 --- /dev/null +++ b/libc/sock/basesocket.c @@ -0,0 +1,61 @@ +/*-*- 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 2022 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/nt/enum/sio.h" +#include "libc/nt/errors.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" + +static textwindows int64_t GetNtBspSocket(int64_t socket, uint32_t ioctl) { + uint32_t bytes; + int64_t bsp_socket; + if (WSAIoctl(socket, ioctl, NULL, 0, &bsp_socket, sizeof(bsp_socket), &bytes, + NULL, NULL) != -1) { + return bsp_socket; + } else { + return -1; + } +} + +textwindows int64_t GetNtBaseSocket(int64_t socket) { + int64_t base_socket; + for (;;) { + base_socket = GetNtBspSocket(socket, kNtSioBaseHandle); + if (base_socket != -1) return base_socket; + if (WSAGetLastError() == WSAENOTSOCK) return __winsockerr(); + /* + * Even though Microsoft documentation clearly states that Layered + * Spyware Providers must never ever intercept the SIO_BASE_HANDLE + * ioctl, Komodia LSPs (that Lenovo got sued for preinstalling) do + * so anyway in order to redirect decrypted https requests through + * some foreign proxy and inject ads which breaks high-performance + * network event io. However it doesn't handle SIO_BSP_HANDLE_POLL + * which will at least let us obtain the socket associated with the + * next winsock protocol chain entry. If this succeeds, loop around + * and call SIO_BASE_HANDLE again with the returned BSP socket, to + * make sure we unwrap all layers and retrieve the real base socket. + */ + base_socket = GetNtBspSocket(socket, kNtSioBspHandlePoll); + if (base_socket != -1 && base_socket != socket) { + socket = base_socket; + } else { + return __winsockerr(); + } + } +} diff --git a/libc/sock/bind.c b/libc/sock/bind.c index 28cb9c689..a269b21a0 100644 --- a/libc/sock/bind.c +++ b/libc/sock/bind.c @@ -18,10 +18,12 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" +#include "libc/sock/sockdebug.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" @@ -31,31 +33,35 @@ * @param fd is the file descriptor returned by socket() * @param addr is usually the binary-encoded ip:port on which to listen * @param addrsize is the byte-length of addr's true polymorphic form - * @return socket file descriptor or -1 w/ errno + * @return 0 on success or -1 w/ errno * @error ENETDOWN, EPFNOSUPPORT, etc. * @asyncsignalsafe */ int bind(int fd, const void *addr, uint32_t addrsize) { - if (!addr) return efault(); - if (IsAsan() && !__asan_is_valid(addr, addrsize)) return efault(); - if (addrsize == sizeof(struct sockaddr_in)) { + int rc; + char addrbuf[72]; + if (!addr || (IsAsan() && !__asan_is_valid(addr, addrsize))) { + rc = efault(); + } else if (addrsize >= sizeof(struct sockaddr_in)) { if (!IsWindows()) { if (!IsBsd()) { - return sys_bind(fd, addr, addrsize); + rc = sys_bind(fd, addr, addrsize); } else { char addr2[sizeof( struct sockaddr_un_bsd)]; /* sockaddr_un_bsd is the largest */ assert(addrsize <= sizeof(addr2)); memcpy(&addr2, addr, addrsize); sockaddr2bsd(&addr2[0]); - return sys_bind(fd, &addr2, addrsize); + rc = sys_bind(fd, &addr2, addrsize); } } else if (__isfdkind(fd, kFdSocket)) { - return sys_bind_nt(&g_fds.p[fd], addr, addrsize); + rc = sys_bind_nt(&g_fds.p[fd], addr, addrsize); } else { - return ebadf(); + rc = ebadf(); } } else { - return einval(); + rc = einval(); } + STRACE("bind(%d, %s) -> %d% lm", fd, __describe_sockaddr(addr, addrsize), rc); + return rc; } diff --git a/libc/sock/closesocket-nt.c b/libc/sock/closesocket-nt.c index b87e62542..baf2352ef 100644 --- a/libc/sock/closesocket-nt.c +++ b/libc/sock/closesocket-nt.c @@ -27,7 +27,6 @@ textwindows int sys_closesocket_nt(struct Fd *fd) { struct SockFd *sockfd; sockfd = (struct SockFd *)fd->extra; - WSACloseEvent(sockfd->event); free(sockfd); if (__sys_closesocket_nt(fd->handle) != -1) { return 0; diff --git a/libc/sock/connect.c b/libc/sock/connect.c index 279312481..814cc18d4 100644 --- a/libc/sock/connect.c +++ b/libc/sock/connect.c @@ -16,9 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sock/internal.h" +#include "libc/sock/sockdebug.h" #include "libc/sysv/errfuns.h" /** @@ -30,17 +32,23 @@ * * @return 0 on success or -1 w/ errno * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ int connect(int fd, const void *addr, uint32_t addrsize) { - uint32_t ip; - if (!addr) return efault(); - if (IsAsan() && !__asan_is_valid(addr, addrsize)) return efault(); - _firewall(addr, addrsize); - if (!IsWindows()) { - return sys_connect(fd, addr, addrsize); - } else if (__isfdkind(fd, kFdSocket)) { - return sys_connect_nt(&g_fds.p[fd], addr, addrsize); + int rc; + if (addr && !(IsAsan() && !__asan_is_valid(addr, addrsize))) { + _firewall(addr, addrsize); + if (!IsWindows()) { + rc = sys_connect(fd, addr, addrsize); + } else if (__isfdkind(fd, kFdSocket)) { + rc = sys_connect_nt(&g_fds.p[fd], addr, addrsize); + } else { + rc = ebadf(); + } } else { - return ebadf(); + rc = efault(); } + STRACE("connect(%d, %s) -> %d% lm", fd, __describe_sockaddr(addr, addrsize), + rc); + return rc; } diff --git a/libc/sock/describesocklevel.greg.c b/libc/sock/describesocklevel.greg.c new file mode 100644 index 000000000..7dd91118b --- /dev/null +++ b/libc/sock/describesocklevel.greg.c @@ -0,0 +1,33 @@ +/*-*- 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 2022 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/fmt/itoa.h" +#include "libc/sysv/consts/sol.h" + +/** + * Describes setsockopt() level arguments. + */ +char *DescribeSockLevel(int x) { + static char buf[12]; + if (x == SOL_IP) return "SOL_IP"; + if (x == SOL_TCP) return "SOL_TCP"; + if (x == SOL_UDP) return "SOL_UDP"; + if (x == SOL_SOCKET) return "SOL_SOCKET"; + FormatInt32(buf, x); + return buf; +} diff --git a/libc/sock/describesockoptname.greg.c b/libc/sock/describesockoptname.greg.c new file mode 100644 index 000000000..09213b2a0 --- /dev/null +++ b/libc/sock/describesockoptname.greg.c @@ -0,0 +1,51 @@ +/*-*- 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 2022 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/fmt/itoa.h" +#include "libc/fmt/magnumstrs.internal.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sol.h" + +/** + * Describes setsockopt() optname arguments. + */ +char *DescribeSockOptname(int l, int x) { + int i; + char *ps, *s; + const struct MagnumStr *ms = 0; + _Alignas(char) static char buf[32]; + if (x) { + if (l == SOL_SOCKET) { + ps = "SO_"; + ms = kSockOptnames; + } else if (l == SOL_TCP) { + ps = "TCP_"; + ms = kTcpOptnames; + } else if (l == SOL_IP) { + ps = "IP_"; + ms = kIpOptnames; + } + } + if (ms && (s = GetMagnumStr(ms, x))) { + stpcpy(stpcpy(buf, ps), s); + return buf; + } else { + FormatInt32(buf, x); + return buf; + } +} diff --git a/libc/sock/dupsockfd.c b/libc/sock/dupsockfd.c new file mode 100644 index 000000000..f665d56e6 --- /dev/null +++ b/libc/sock/dupsockfd.c @@ -0,0 +1,31 @@ +/*-*- 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 2022 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/mem/mem.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" + +textwindows struct SockFd *_dupsockfd(struct SockFd *sockfd) { + struct SockFd *newsf; + if ((newsf = calloc(1, sizeof(struct SockFd)))) { + newsf->family = sockfd->family; + newsf->type = sockfd->type; + newsf->protocol = sockfd->protocol; + } + return newsf; +} diff --git a/libc/sock/epoll.c b/libc/sock/epoll.c index 4425fc2db..99e508734 100644 --- a/libc/sock/epoll.c +++ b/libc/sock/epoll.c @@ -1324,7 +1324,7 @@ static textwindows dontinline int sys_epoll_create1_nt(uint32_t flags) { struct PortState *port_state; struct TsTreeNode *tree_node; if (wepoll_init() < 0) return -1; - if ((fd = __reservefd()) == -1) return -1; + if ((fd = __reservefd(-1)) == -1) return -1; port_state = port_new(&ephnd); if (!port_state) { __releasefd(fd); @@ -1341,11 +1341,12 @@ static textwindows dontinline int sys_epoll_create1_nt(uint32_t flags) { g_fds.p[fd].kind = kFdEpoll; g_fds.p[fd].handle = ephnd; g_fds.p[fd].flags = flags; + g_fds.p[fd].mode = 0140666; return fd; } static textwindows dontinline int sys_epoll_ctl_nt(int epfd, int op, int fd, - struct epoll_event *ev) { + struct epoll_event *ev) { int r; struct PortState *port_state; struct TsTreeNode *tree_node; @@ -1375,9 +1376,9 @@ static textwindows dontinline int sys_epoll_ctl_nt(int epfd, int op, int fd, } static textwindows dontinline int sys_epoll_wait_nt(int epfd, - struct epoll_event *events, - int maxevents, - int timeoutms) { + struct epoll_event *events, + int maxevents, + int timeoutms) { int num_events; struct PortState *port_state; struct TsTreeNode *tree_node; @@ -1493,6 +1494,7 @@ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev) { * @param maxevents is array length of events * @param timeoutms is milliseconds, 0 to not block, or -1 for forever * @return number of events stored, 0 on timeout, or -1 w/ errno + * @norestart */ int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeoutms) { diff --git a/libc/sock/getpeername.c b/libc/sock/getpeername.c index 444a3e60c..677a2e5cf 100644 --- a/libc/sock/getpeername.c +++ b/libc/sock/getpeername.c @@ -17,10 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" +#include "libc/sock/sockdebug.h" #include "libc/sysv/errfuns.h" /** @@ -29,12 +31,19 @@ * @see getsockname() */ int getpeername(int fd, void *out_addr, uint32_t *out_addrsize) { - if (IsAsan() && !__asan_is_valid(out_addr, *out_addrsize)) return efault(); - if (!IsWindows()) { - return sys_getpeername(fd, out_addr, out_addrsize); + int rc; + if (!out_addr || !out_addrsize || + (IsAsan() && (!__asan_is_valid(out_addrsize, 4) || + !__asan_is_valid(out_addr, *out_addrsize)))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_getpeername(fd, out_addr, out_addrsize); } else if (__isfdkind(fd, kFdSocket)) { - return sys_getpeername_nt(&g_fds.p[fd], out_addr, out_addrsize); + rc = sys_getpeername_nt(&g_fds.p[fd], out_addr, out_addrsize); } else { - return ebadf(); + rc = ebadf(); } + STRACE("getpeername(%d, [%s]) -> %d% lm", fd, + __describe_sockaddr(out_addr, out_addrsize ? *out_addrsize : 0), rc); + return rc; } diff --git a/libc/sock/getsockname.c b/libc/sock/getsockname.c index 49c7e9dbe..3def705a9 100644 --- a/libc/sock/getsockname.c +++ b/libc/sock/getsockname.c @@ -17,10 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" +#include "libc/sock/sockdebug.h" #include "libc/sysv/errfuns.h" /** @@ -29,12 +31,19 @@ * @see getpeername() */ int getsockname(int fd, void *out_addr, uint32_t *out_addrsize) { - if (IsAsan() && !__asan_is_valid(out_addr, *out_addrsize)) return efault(); - if (!IsWindows()) { - return sys_getsockname(fd, out_addr, out_addrsize); + int rc; + if (!out_addrsize || !out_addrsize || + (IsAsan() && (!__asan_is_valid(out_addrsize, 4) || + !__asan_is_valid(out_addr, *out_addrsize)))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_getsockname(fd, out_addr, out_addrsize); } else if (__isfdkind(fd, kFdSocket)) { - return sys_getsockname_nt(&g_fds.p[fd], out_addr, out_addrsize); + rc = sys_getsockname_nt(&g_fds.p[fd], out_addr, out_addrsize); } else { - return ebadf(); + rc = ebadf(); } + STRACE("getsockname(%d, [%s]) -> %d% lm", fd, + __describe_sockaddr(out_addr, out_addrsize ? *out_addrsize : 0), rc); + return rc; } diff --git a/libc/sock/getsockopt-nt.c b/libc/sock/getsockopt-nt.c index 49ccc4ee7..d64f6c5f6 100644 --- a/libc/sock/getsockopt-nt.c +++ b/libc/sock/getsockopt-nt.c @@ -17,20 +17,62 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" +#include "libc/bits/bits.h" #include "libc/calls/internal.h" +#include "libc/calls/struct/timeval.h" +#include "libc/nt/struct/linger.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" +#include "libc/sock/sock.h" #include "libc/sock/yoink.inc" +#include "libc/str/str.h" +#include "libc/sysv/consts/so.h" +#include "libc/sysv/consts/sol.h" #include "libc/sysv/errfuns.h" textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname, - void *out_opt_optval, uint32_t *out_optlen) { - /* TODO(jart): Use WSAIoctl? */ + void *out_opt_optval, + uint32_t *inout_optlen) { + uint64_t ms; + uint32_t in_optlen; + struct linger_nt linger; assert(fd->kind == kFdSocket); - if (__sys_getsockopt_nt(fd->handle, level, optname, out_opt_optval, - out_optlen) != -1) { - return 0; + + if (out_opt_optval && inout_optlen) { + in_optlen = *inout_optlen; } else { + in_optlen = 0; + } + + // TODO(jart): Use WSAIoctl? + if (__sys_getsockopt_nt(fd->handle, level, optname, out_opt_optval, + inout_optlen) == -1) { return __winsockerr(); } + + if (level == SOL_SOCKET) { + if ((optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) && + in_optlen == sizeof(struct timeval) && + *inout_optlen == sizeof(uint32_t)) { + ms = *(uint32_t *)out_opt_optval; + ((struct timeval *)out_opt_optval)->tv_sec = ms / 1000; + ((struct timeval *)out_opt_optval)->tv_usec = ms % 1000 * 1000; + *inout_optlen = sizeof(struct timeval); + } else if (optname == SO_LINGER && in_optlen == sizeof(struct linger)) { + linger = *(struct linger_nt *)out_opt_optval; + ((struct linger *)out_opt_optval)->l_onoff = !!linger.l_onoff; + ((struct linger *)out_opt_optval)->l_linger = linger.l_linger; + *inout_optlen = sizeof(struct linger); + } + } + + if (in_optlen == 4 && *inout_optlen == 1) { + // handle cases like this + // getsockopt(8, SOL_TCP, TCP_FASTOPEN, [u"☺"], [1]) → 0 + int32_t wut = *(signed char *)out_opt_optval; + memcpy(out_opt_optval, &wut, 4); + *inout_optlen = 4; + } + + return 0; } diff --git a/libc/sock/getsockopt.c b/libc/sock/getsockopt.c index 2b5a9f673..d60d8d601 100644 --- a/libc/sock/getsockopt.c +++ b/libc/sock/getsockopt.c @@ -17,7 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/fmt/magnumstrs.internal.h" +#include "libc/intrin/asan.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sysv/errfuns.h" @@ -34,14 +37,36 @@ */ int getsockopt(int fd, int level, int optname, void *out_opt_optval, uint32_t *out_optlen) { - if (!level || !optname) return enoprotoopt(); /* our sysvconsts definition */ - if (optname == -1) return 0; /* our sysvconsts definition */ - if (!IsWindows()) { - return sys_getsockopt(fd, level, optname, out_opt_optval, out_optlen); + int rc; + + if (!level || !optname) { + rc = enoprotoopt(); /* our sysvconsts definition */ + } else if (optname == -1) { + rc = 0; /* our sysvconsts definition */ + } else if (IsAsan() && (out_opt_optval && out_optlen && + (!__asan_is_valid(out_optlen, sizeof(uint32_t)) || + !__asan_is_valid(out_opt_optval, *out_optlen)))) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_getsockopt(fd, level, optname, out_opt_optval, out_optlen); } else if (__isfdkind(fd, kFdSocket)) { - return sys_getsockopt_nt(&g_fds.p[fd], level, optname, out_opt_optval, - out_optlen); + rc = sys_getsockopt_nt(&g_fds.p[fd], level, optname, out_opt_optval, + out_optlen); } else { - return ebadf(); + rc = ebadf(); } + +#ifdef SYSDEBUG + if (out_opt_optval && out_optlen && rc != -1) { + STRACE("getsockopt(%d, %s, %s, [%#.*hhs], [%d]) → %d% lm", fd, + DescribeSockLevel(level), DescribeSockOptname(level, optname), + *out_optlen, out_opt_optval, *out_optlen, rc); + } else { + STRACE("getsockopt(%d, %s, %s, %p, %p) → %d% lm", fd, + DescribeSockLevel(level), DescribeSockOptname(level, optname), + out_opt_optval, out_optlen, rc); + } +#endif + + return rc; } diff --git a/libc/sock/inet_ntoa.c b/libc/sock/inet_ntoa.c index cd6c0d8b1..648815920 100644 --- a/libc/sock/inet_ntoa.c +++ b/libc/sock/inet_ntoa.c @@ -25,12 +25,12 @@ char *inet_ntoa(struct in_addr in) { static char buf[16]; char *p = buf; - p += int64toarray_radix10((in.s_addr >> 000) & 255, p); + p = FormatUint32(p, (in.s_addr >> 000) & 255); *p++ = '.'; - p += int64toarray_radix10((in.s_addr >> 010) & 255, p); + p = FormatUint32(p, (in.s_addr >> 010) & 255); *p++ = '.'; - p += int64toarray_radix10((in.s_addr >> 020) & 255, p); + p = FormatUint32(p, (in.s_addr >> 020) & 255); *p++ = '.'; - p += int64toarray_radix10((in.s_addr >> 030) & 255, p); + p = FormatUint32(p, (in.s_addr >> 030) & 255); return buf; } diff --git a/libc/sock/inet_ntop.c b/libc/sock/inet_ntop.c index 3e8fbe99c..afbc88d94 100644 --- a/libc/sock/inet_ntop.c +++ b/libc/sock/inet_ntop.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/itoa.h" +#include "libc/str/str.h" #include "libc/sysv/consts/af.h" #include "libc/sysv/errfuns.h" @@ -34,16 +35,17 @@ const char *inet_ntop(int af, const void *src, char *dst, uint32_t size) { unsigned char *ip; int i, t, a, b, c, d; p = dst; + if (!size) return dst; if ((ip = src)) { if (af == AF_INET) { if (size >= 16) { - p += uint64toarray_radix10(ip[0], p); + p = FormatUint32(p, ip[0]); *p++ = '.'; - p += uint64toarray_radix10(ip[1], p); + p = FormatUint32(p, ip[1]); *p++ = '.'; - p += uint64toarray_radix10(ip[2], p); + p = FormatUint32(p, ip[2]); *p++ = '.'; - p += uint64toarray_radix10(ip[3], p); + p = FormatUint32(p, ip[3]); *p = '\0'; return dst; } else { @@ -98,6 +100,5 @@ const char *inet_ntop(int af, const void *src, char *dst, uint32_t size) { } else { einval(); } - if (size) dst[0] = '\0'; - return NULL; + return 0; } diff --git a/libc/sock/internal.h b/libc/sock/internal.h index 312826592..50486fb8a 100644 --- a/libc/sock/internal.h +++ b/libc/sock/internal.h @@ -1,7 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_ #define COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_ -#include "libc/bits/bits.h" #include "libc/calls/internal.h" +#include "libc/nt/struct/overlapped.h" #include "libc/nt/thunk/msabi.h" #include "libc/nt/winsock.h" #include "libc/sock/select.h" @@ -55,35 +55,38 @@ struct sockaddr_un_bsd { /* ------------------------------------------------------------------------------------*/ +#define SOCKFD_OVERLAP_BUFSIZ 128 + struct SockFd { int family; int type; int protocol; - int64_t event; - bool32 (*AcceptEx)(int64_t sListenSocket, int64_t sAcceptSocket, - void *out_lpOutputBuffer /*[recvlen+local+remoteaddrlen]*/, - uint32_t dwReceiveDataLength, - uint32_t dwLocalAddressLength, - uint32_t dwRemoteAddressLength, - uint32_t *out_lpdwBytesReceived, - struct NtOverlapped *inout_lpOverlapped) __msabi; + bool32 (*__msabi ConnectEx)(int64_t s, const struct sockaddr *name, + int namelen, const void *opt_lpSendBuffer, + uint32_t dwSendDataLength, + uint32_t *out_lpdwBytesSent, + struct NtOverlapped *inout_lpOverlapped); + bool32 (*__msabi AcceptEx)( + int64_t sListenSocket, int64_t sAcceptSocket, + void *out_lpOutputBuffer /*[recvlen+local+remoteaddrlen]*/, + uint32_t dwReceiveDataLength, uint32_t dwLocalAddressLength, + uint32_t dwRemoteAddressLength, uint32_t *out_lpdwBytesReceived, + struct NtOverlapped *inout_lpOverlapped); }; -hidden extern int64_t __iocp; - -errno_t __dos2errno(uint32_t); +errno_t __dos2errno(uint32_t) hidden; void _firewall(const void *, uint32_t) hidden; -int32_t __sys_accept(int32_t, void *, uint32_t *, int) nodiscard hidden; -int32_t __sys_accept4(int32_t, void *, uint32_t *, int) nodiscard hidden; +int32_t __sys_accept(int32_t, void *, uint32_t *, int) dontdiscard hidden; +int32_t __sys_accept4(int32_t, void *, uint32_t *, int) dontdiscard hidden; int32_t __sys_connect(int32_t, const void *, uint32_t) hidden; int32_t __sys_socket(int32_t, int32_t, int32_t) hidden; int32_t __sys_getsockname(int32_t, void *, uint32_t *) hidden; int32_t __sys_getpeername(int32_t, void *, uint32_t *) hidden; int32_t __sys_socketpair(int32_t, int32_t, int32_t, int32_t[2]) hidden; -int32_t sys_accept4(int32_t, void *, uint32_t *, int) nodiscard hidden; +int32_t sys_accept4(int32_t, void *, uint32_t *, int) dontdiscard hidden; int32_t sys_accept(int32_t, void *, uint32_t *) hidden; int32_t sys_bind(int32_t, const void *, uint32_t) hidden; int32_t sys_connect(int32_t, const void *, uint32_t) hidden; @@ -110,7 +113,7 @@ int32_t sys_epoll_ctl(int32_t, int32_t, int32_t, void *) hidden; int32_t sys_epoll_wait(int32_t, void *, int32_t, int32_t) hidden; int sys_poll_metal(struct pollfd *, size_t, unsigned); -int sys_poll_nt(struct pollfd *, uint64_t, uint64_t) hidden; +int sys_poll_nt(struct pollfd *, uint64_t, uint64_t *) hidden; int sys_getsockopt_nt(struct Fd *, int, int, void *, uint32_t *) hidden; int sys_getsockname_nt(struct Fd *, void *, uint32_t *) hidden; int sys_getpeername_nt(struct Fd *, void *, uint32_t *) hidden; @@ -129,18 +132,23 @@ int sys_select_nt(int, fd_set *, fd_set *, fd_set *, struct timeval *) hidden; int sys_shutdown_nt(struct Fd *, int) hidden; int sys_setsockopt_nt(struct Fd *, int, int, const void *, uint32_t) hidden; +bool __asan_is_valid_msghdr(const struct msghdr *); +ssize_t sys_send_nt(int, const struct iovec *, size_t, uint32_t) hidden; +ssize_t sys_recv_nt(struct Fd *, const struct iovec *, size_t, uint32_t) hidden; size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *, size_t) hidden; -ssize_t sys_sendto_nt(struct Fd *, const struct iovec *, size_t, uint32_t, - void *, uint32_t) hidden; +ssize_t sys_sendto_nt(int, const struct iovec *, size_t, uint32_t, void *, + uint32_t) hidden; ssize_t sys_recvfrom_nt(struct Fd *, const struct iovec *, size_t, uint32_t, void *, uint32_t *) hidden; void WinSockInit(void) hidden; int64_t __winsockerr(void) nocallback hidden; int __fixupnewsockfd(int, int) hidden; +int __wsablock(int64_t, struct NtOverlapped *, uint32_t *, bool) hidden; int64_t __winsockblock(int64_t, unsigned, int64_t) hidden; - +struct SockFd *_dupsockfd(struct SockFd *) hidden; +int64_t GetNtBaseSocket(int64_t) hidden; int sys_close_epoll(int) hidden; /** @@ -148,12 +156,10 @@ int sys_close_epoll(int) hidden; */ forceinline void sockaddr2bsd(void *saddr) { char *p; - uint16_t fam; if (saddr) { p = saddr; - fam = READ16LE(p); + p[1] = p[0]; p[0] = sizeof(struct sockaddr_in_bsd); - p[1] = fam; } } @@ -161,11 +167,11 @@ forceinline void sockaddr2bsd(void *saddr) { * Converts sockaddr_in_bsd (XNU/BSD) → sockaddr (Linux/Windows). */ forceinline void sockaddr2linux(void *saddr) { - char *p, fam; + char *p; if (saddr) { p = saddr; - fam = p[1]; - WRITE16LE(p, fam); + p[0] = p[1]; + p[1] = 0; } } diff --git a/libc/sock/kipoptnames.S b/libc/sock/kipoptnames.S new file mode 100644 index 000000000..cee04e63c --- /dev/null +++ b/libc/sock/kipoptnames.S @@ -0,0 +1,40 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/fmt/magnumstrs.internal.h" +#include "libc/macros.internal.h" + + .macro .e e s + .long \e - kIpOptnames + .long 1f - kIpOptnames + .rodata.str1.1 +1: .string "\s" + .previous + .endm + + .section .rodata + .align 4 + .underrun +kIpOptnames: + .e IP_TOS,"TOS" # int + .e IP_MTU,"MTU" # int + .e IP_TTL,"TTL" # int + .e IP_HDRINCL,"HDRINCL" # bool32 + .long MAGNUM_TERMINATOR + .endobj kIpOptnames,globl,hidden + .overrun diff --git a/libc/sock/kntwsadata.c b/libc/sock/kntwsadata.c index 4e1f015c3..133dffe3c 100644 --- a/libc/sock/kntwsadata.c +++ b/libc/sock/kntwsadata.c @@ -16,7 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" +#include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" +#include "libc/mem/mem.h" #include "libc/nt/runtime.h" #include "libc/nt/winsock.h" #include "libc/runtime/runtime.h" @@ -34,12 +38,22 @@ hidden struct NtWsaData kNtWsaData; static textwindows void WinSockCleanup(void) { - WSACleanup(); + int i, rc; + NTTRACE("WinSockCleanup()"); + for (i = g_fds.n; i--;) { + if (g_fds.p[i].kind == kFdSocket) { + close(i); + } + } + // TODO(jart): Check WSACleanup() result code + rc = WSACleanup(); + NTTRACE("WSACleanup() → %d% lm", rc); } textwindows noasan void WinSockInit(void) { int rc; atexit(WinSockCleanup); + NTTRACE("WSAStartup()"); if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 || kNtWsaData.wVersion != VERSION) { ExitProcess(123); diff --git a/libc/sock/ksockoptnames.S b/libc/sock/ksockoptnames.S new file mode 100644 index 000000000..8b29764a0 --- /dev/null +++ b/libc/sock/ksockoptnames.S @@ -0,0 +1,52 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/fmt/magnumstrs.internal.h" +#include "libc/macros.internal.h" + + .macro .e e s + .long \e - kSockOptnames + .long 1f - kSockOptnames + .rodata.str1.1 +1: .string "\s" + .previous + .endm + + .section .rodata + .align 4 + .underrun +kSockOptnames: + .e SO_DEBUG,"DEBUG" # bool32 + .e SO_ACCEPTCONN,"ACCEPTCONN" # bool32 + .e SO_BROADCAST,"BROADCAST" # bool32 + .e SO_REUSEADDR,"REUSEADDR" # bool32 + .e SO_REUSEPORT,"REUSEPORT" # bool32 + .e SO_KEEPALIVE,"KEEPALIVE" # bool32 + .e SO_DONTROUTE,"DONTROUTE" # bool32 + .e SO_RCVTIMEO,"RCVTIMEO" # timeval + .e SO_SNDTIMEO,"SNDTIMEO" # timeval + .e SO_LINGER,"LINGER" # linger + .e SO_TYPE,"TYPE" # int + .e SO_SNDBUF,"SNDBUF" # int + .e SO_RCVBUF,"RCVBUF" # int + .e SO_RCVLOWAT,"RCVLOWAT" # int + .e SO_SNDLOWAT,"SNDLOWAT" # int + .e SO_ERROR,"ERROR" # int + .long MAGNUM_TERMINATOR + .endobj kSockOptnames,globl,hidden + .overrun diff --git a/libc/sock/ktcpoptnames.S b/libc/sock/ktcpoptnames.S new file mode 100644 index 000000000..444b35922 --- /dev/null +++ b/libc/sock/ktcpoptnames.S @@ -0,0 +1,49 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ 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/fmt/magnumstrs.internal.h" +#include "libc/macros.internal.h" + + .macro .e e s + .long \e - kTcpOptnames + .long 1f - kTcpOptnames + .rodata.str1.1 +1: .string "\s" + .previous + .endm + + .section .rodata + .align 4 + .underrun +kTcpOptnames: + .e TCP_NODELAY,"NODELAY" # bool32 + .e TCP_CORK,"CORK" # bool32 + .e TCP_QUICKACK,"QUICKACK" # bool32 + .e TCP_FASTOPEN_CONNECT,"FASTOPEN_CONNECT" # bool32 + .e TCP_DEFER_ACCEPT,"DEFER_ACCEPT" # bool32 + .e TCP_KEEPIDLE,"KEEPIDLE" # int (seconds) + .e TCP_KEEPINTVL,"KEEPINTVL" # int (seconds) + .e TCP_FASTOPEN,"FASTOPEN" # int + .e TCP_KEEPCNT,"KEEPCNT" # int + .e TCP_MAXSEG,"MAXSEG" # int + .e TCP_SYNCNT,"SYNCNT" # int + .e TCP_NOTSENT_LOWAT,"NOTSENT_LOWAT" # int + .e TCP_WINDOW_CLAMP,"WINDOW_CLAMP" # int + .long MAGNUM_TERMINATOR + .endobj kTcpOptnames,globl,hidden + .overrun diff --git a/libc/sock/listen.c b/libc/sock/listen.c index 65c1465c1..c452a2ae9 100644 --- a/libc/sock/listen.c +++ b/libc/sock/listen.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" @@ -34,11 +35,14 @@ * @return 0 on success or -1 w/ errno */ int listen(int fd, int backlog) { + int rc; if (!IsWindows()) { - return sys_listen(fd, backlog); + rc = sys_listen(fd, backlog); } else if (__isfdkind(fd, kFdSocket)) { - return sys_listen_nt(&g_fds.p[fd], backlog); + rc = sys_listen_nt(&g_fds.p[fd], backlog); } else { - return ebadf(); + rc = ebadf(); } + STRACE("listen(%d, %d) → %d% lm", fd, backlog, rc); + return rc; } diff --git a/libc/sock/ntstdin.greg.c b/libc/sock/ntstdin.greg.c new file mode 100644 index 000000000..b435a91da --- /dev/null +++ b/libc/sock/ntstdin.greg.c @@ -0,0 +1,150 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/refcount.h" +#include "libc/intrin/spinlock.h" +#include "libc/mem/mem.h" +#include "libc/nexgen32e/nt2sysv.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/creationdisposition.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/errors.h" +#include "libc/nt/events.h" +#include "libc/nt/ipc.h" +#include "libc/nt/runtime.h" +#include "libc/nt/synchronization.h" +#include "libc/nt/thread.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/sock/ntstdin.internal.h" + +/** + * @fileoverview Pollable Standard Input for the New Technology. + */ + +static textwindows uint32_t StdinWorkerThread(void *arg) { + char buf[512]; + bool32 ok = true; + uint32_t i, rc, got, err, wrote; + struct NtStdinWorker w, *wp = arg; + NTTRACE("StdinWorkerThread(%ld → %ld → %ld) pid %d tid %d", wp->reader, + wp->writer, wp->consumer, getpid(), gettid()); + _spunlock(&wp->sync); + w = *wp; + do { + ok = ReadFile(w.reader, buf, sizeof(buf), &got, 0); + /* When writing to a non-blocking, byte-mode pipe handle with + insufficient buffer space, WriteFile returns TRUE with + *lpNumberOfBytesWritten < nNumberOfBytesToWrite. + ──Quoth MSDN WriteFile() */ + for (i = 0; ok && i < got; i += wrote) { + ok = WriteFile(w.writer, buf + i, got - i, &wrote, 0); + } + } while (ok && got); + err = GetLastError(); + if (!ok) { + if (err == kNtErrorHandleEof || err == kNtErrorBrokenPipe || + err == kNtErrorNoData) { + ok = true; + } + } + NTTRACE("StdinWorkerThread(%ld → %ld → %ld) → %hhhd %u", w.reader, w.writer, + w.consumer, err); + return !ok; +} + +/** + * Converts read-only file descriptor to pollable named pipe. + * + * @param fd is open file descriptor to convert + * @return new object on success, or 0 w/ errno + */ +textwindows struct NtStdinWorker *NewNtStdinWorker(int fd) { + struct NtStdinWorker *w; + NTTRACE("LaunchNtStdinWorker(%d) pid %d tid %d", fd, getpid(), gettid()); + assert(!g_fds.p[fd].worker); + assert(__isfdopen(fd)); + if (!(w = calloc(1, sizeof(struct NtStdinWorker)))) return 0; + w->refs = 1; + w->sync = 1; + w->reader = g_fds.p[fd].handle; + if ((w->consumer = CreateNamedPipe( + CreatePipeName(w->name), + kNtPipeAccessInbound | kNtFileFlagOverlapped, + kNtPipeTypeByte | kNtPipeReadmodeByte | kNtPipeRejectRemoteClients, + 1, 512, 512, 0, 0)) != -1) { + if ((w->writer = CreateFile(w->name, kNtGenericWrite, 0, 0, kNtOpenExisting, + kNtFileFlagOverlapped, 0)) != -1) { + if ((w->worker = CreateThread(0, 0, NT2SYSV(StdinWorkerThread), w, 0, + &w->tid)) != -1) { + _spinlock(&w->sync); + g_fds.p[fd].handle = w->consumer; + g_fds.p[fd].worker = w; + return w; + } + CloseHandle(w->writer); + } + CloseHandle(w->consumer); + } + free(w); + return w; +} + +/** + * References stdin worker on the New Technology. + * @param w is non-null worker object + * @return worker object for new fd + */ +textwindows struct NtStdinWorker *RefNtStdinWorker(struct NtStdinWorker *w) { + _incref(&w->refs); + return w; +} + +/** + * Dereferences stdin worker on the New Technology. + * @param w is non-null worker object + * @return true if ok otherwise false + */ +textwindows bool UnrefNtStdinWorker(struct NtStdinWorker *w) { + bool ok = true; + if (_decref(&w->refs)) return true; + if (!CloseHandle(w->consumer)) ok = false; + if (!CloseHandle(w->writer)) ok = false; + if (!CloseHandle(w->reader)) ok = false; + if (!CloseHandle(w->worker)) ok = false; + free(w); + return ok; +} + +/** + * Runs post fork for stdin workers on the New Technology. + */ +textwindows void ForkNtStdinWorker(void) { + for (int i = 0; i < g_fds.n; ++i) { + if (g_fds.p[i].kind && g_fds.p[i].worker) { + g_fds.p[i].handle = g_fds.p[i].worker->reader; + free(g_fds.p[i].worker); + g_fds.p[i].worker = 0; + } + } +} diff --git a/libc/sock/ntstdin.internal.h b/libc/sock/ntstdin.internal.h new file mode 100644 index 000000000..4afd2d023 --- /dev/null +++ b/libc/sock/ntstdin.internal.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_SOCK_NTSTDIN_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_SOCK_NTSTDIN_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtStdinWorker { /* non-inherited */ + volatile char sync; /* spin sync start */ + int refs; /* reference count */ + uint32_t tid; /* of the worker */ + int64_t reader; /* the real handle */ + int64_t writer; /* for the worker */ + int64_t worker; /* thread handle */ + int64_t consumer; /* same as Fd::handle */ + char16_t name[64]; /* for named pipe */ +}; + +struct NtStdinWorker *NewNtStdinWorker(int) hidden; +struct NtStdinWorker *RefNtStdinWorker(struct NtStdinWorker *) hidden; +bool UnrefNtStdinWorker(struct NtStdinWorker *) hidden; +void ForkNtStdinWorker(void) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SOCK_NTSTDIN_INTERNAL_H_ */ diff --git a/libc/sock/poll-nt.c b/libc/sock/poll-nt.c deleted file mode 100644 index 94f73e197..000000000 --- a/libc/sock/poll-nt.c +++ /dev/null @@ -1,56 +0,0 @@ -/*-*- 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 "libc/bits/bits.h" -#include "libc/calls/internal.h" -#include "libc/macros.internal.h" -#include "libc/nt/struct/pollfd.h" -#include "libc/nt/winsock.h" -#include "libc/sock/internal.h" -#include "libc/sock/yoink.inc" -#include "libc/sysv/consts/poll.h" -#include "libc/sysv/errfuns.h" - -textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t ms) { - int i, got, waitfor; - struct sys_pollfd_nt ntfds[64]; - if (nfds >= ARRAYLEN(ntfds)) return einval(); - for (i = 0; i < nfds; ++i) { - if (fds[i].fd >= 0) { - if (!__isfdkind(fds[i].fd, kFdSocket)) return enotsock(); - ntfds[i].handle = g_fds.p[fds[i].fd].handle; - ntfds[i].events = fds[i].events & (POLLPRI | POLLIN | POLLOUT); - } else { - ntfds[i].handle = -1; - ntfds[i].events = POLLIN; - } - } - for (;;) { - if (cmpxchg(&__interrupted, true, false)) return eintr(); - waitfor = MIN(1000, ms); /* for ctrl+c */ - if ((got = WSAPoll(ntfds, nfds, waitfor)) != -1) { - if (!got && (ms -= waitfor) > 0) continue; - for (i = 0; i < nfds; ++i) { - fds[i].revents = ntfds[i].handle < 0 ? 0 : ntfds[i].revents; - } - return got; - } else { - return __winsockerr(); - } - } -} diff --git a/libc/sock/poll.c b/libc/sock/poll.c deleted file mode 100644 index 38fa964f7..000000000 --- a/libc/sock/poll.c +++ /dev/null @@ -1,53 +0,0 @@ -/*-*- 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 "libc/calls/calls.h" -#include "libc/calls/internal.h" -#include "libc/dce.h" -#include "libc/intrin/asan.internal.h" -#include "libc/sock/internal.h" -#include "libc/sock/sock.h" -#include "libc/sysv/errfuns.h" - -/** - * Waits for something to happen on multiple file descriptors at once. - * - * @param fds[𝑖].fd should have been created with SOCK_NONBLOCK passed - * to socket() or accept4() - * @param fds[𝑖].events flags can have POLL{IN,OUT,PRI} - * @param timeout_ms if 0 means don't wait and -1 means wait forever - * @return number of items fds whose revents field has been set to - * nonzero to describe its events, or -1 w/ errno - * @return fds[𝑖].revents flags can have: - * (fds[𝑖].events & POLL{IN,OUT,PRI,HUP,ERR,NVAL}) - * @asyncsignalsafe - */ -int poll(struct pollfd *fds, uint64_t nfds, int32_t timeout_ms) { - if (IsAsan() && !__asan_is_valid(fds, nfds * sizeof(struct pollfd))) { - return efault(); - } - if (!IsWindows()) { - if (!IsMetal()) { - return sys_poll(fds, nfds, timeout_ms); - } else { - return sys_poll_metal(fds, nfds, timeout_ms); - } - } else { - return sys_poll_nt(fds, nfds, timeout_ms); - } -} diff --git a/libc/sock/recv-nt.c b/libc/sock/recv-nt.c new file mode 100644 index 000000000..5c2e0bc99 --- /dev/null +++ b/libc/sock/recv-nt.c @@ -0,0 +1,47 @@ +/*-*- 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 "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/nt/struct/overlapped.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +/** + * Performs stream socket receive on New Technology. + * + * @param fd must be a socket + * @return number of bytes received, or -1 w/ errno + */ +textwindows ssize_t sys_recv_nt(struct Fd *fd, const struct iovec *iov, + size_t iovlen, uint32_t flags) { + ssize_t rc; + uint32_t got = 0; + struct NtIovec iovnt[16]; + struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()}; + if (_check_interrupts(true, g_fds.p)) return eintr(); + if (!WSARecv(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &got, &flags, + &overlapped, NULL)) { + rc = got; + } else { + rc = __wsablock(fd->handle, &overlapped, &flags, true); + } + WSACloseEvent(overlapped.hEvent); + return rc; +} diff --git a/libc/sock/recv.c b/libc/sock/recv.c index 07cd3704f..c818bcd83 100644 --- a/libc/sock/recv.c +++ b/libc/sock/recv.c @@ -16,7 +16,13 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/intrin/asan.internal.h" +#include "libc/sock/internal.h" #include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" /** * Receives data from network socket. @@ -29,7 +35,30 @@ * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ ssize_t recv(int fd, void *buf, size_t size, int flags) { - return recvfrom(fd, buf, size, flags, NULL, 0); + ssize_t rc, got; + if (IsAsan() && !__asan_is_valid(buf, size)) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_recvfrom(fd, buf, size, flags, 0, 0); + } else if (__isfdopen(fd)) { + if (__isfdkind(fd, kFdSocket)) { + rc = sys_recv_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, flags); + } else if (__isfdkind(fd, kFdFile)) { + if (flags) { + rc = einval(); + } else { + rc = sys_read_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1); + } + } else { + rc = enotsock(); + } + } else { + rc = ebadf(); + } + DATATRACE("recv(%d, [%#.*hhs%s], %'zu, %#x) → %'ld% lm", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags); + return rc; } diff --git a/libc/sock/recvfrom-nt.c b/libc/sock/recvfrom-nt.c index ac1f8a732..6ce60ca11 100644 --- a/libc/sock/recvfrom-nt.c +++ b/libc/sock/recvfrom-nt.c @@ -1,5 +1,5 @@ -/*-*- 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│ +/*-*- 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 │ │ │ @@ -16,13 +16,15 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" #include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/nt/struct/overlapped.h" +#include "libc/nt/winsock.h" #include "libc/sock/internal.h" -#include "libc/sock/yoink.inc" +#include "libc/sysv/errfuns.h" /** - * Performs recv(), recvfrom(), or readv() on Windows NT. + * Performs datagram receive on New Technology. * * @param fd must be a socket * @return number of bytes received, or -1 w/ errno @@ -31,14 +33,18 @@ textwindows ssize_t sys_recvfrom_nt(struct Fd *fd, const struct iovec *iov, size_t iovlen, uint32_t flags, void *opt_out_srcaddr, uint32_t *opt_inout_srcaddrsize) { - uint32_t got; + ssize_t rc; + uint32_t got = 0; struct NtIovec iovnt[16]; - got = 0; - if (WSARecvFrom(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &got, - &flags, opt_out_srcaddr, opt_inout_srcaddrsize, NULL, - NULL) != -1) { - return got; + struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()}; + if (_check_interrupts(true, g_fds.p)) return eintr(); + if (!WSARecvFrom(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &got, + &flags, opt_out_srcaddr, opt_inout_srcaddrsize, &overlapped, + NULL)) { + rc = got; } else { - return __winsockerr(); + rc = __wsablock(fd->handle, &overlapped, &flags, true); } + WSACloseEvent(overlapped.hEvent); + return rc; } diff --git a/libc/sock/recvfrom.c b/libc/sock/recvfrom.c index 65f2ddc87..7dde89a4a 100644 --- a/libc/sock/recvfrom.c +++ b/libc/sock/recvfrom.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" @@ -40,36 +41,40 @@ * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ ssize_t recvfrom(int fd, void *buf, size_t size, uint32_t flags, void *opt_out_srcaddr, uint32_t *opt_inout_srcaddrsize) { - ssize_t got; + ssize_t rc, got; if (IsAsan() && (!__asan_is_valid(buf, size) || (opt_out_srcaddr && !__asan_is_valid(opt_out_srcaddr, *opt_inout_srcaddrsize)))) { - return efault(); - } - if (!IsWindows()) { + rc = efault(); + } else if (!IsWindows()) { got = sys_recvfrom(fd, buf, size, flags, opt_out_srcaddr, opt_inout_srcaddrsize); if (opt_out_srcaddr && IsBsd() && got != -1) { sockaddr2linux(opt_out_srcaddr); } - return got; - } else { - if (__isfdopen(fd)) { - if (__isfdkind(fd, kFdSocket)) { - return sys_recvfrom_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, - flags, opt_out_srcaddr, opt_inout_srcaddrsize); - } else if (__isfdkind(fd, kFdFile) && !opt_out_srcaddr) { /* socketpair */ - if (flags) return einval(); - return sys_read_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1); + rc = got; + } else if (__isfdopen(fd)) { + if (__isfdkind(fd, kFdSocket)) { + rc = sys_recvfrom_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, + flags, opt_out_srcaddr, opt_inout_srcaddrsize); + } else if (__isfdkind(fd, kFdFile) && !opt_out_srcaddr) { /* socketpair */ + if (flags) { + rc = einval(); } else { - return enotsock(); + rc = sys_read_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1); } } else { - return ebadf(); + rc = enotsock(); } + } else { + rc = ebadf(); } + DATATRACE("recvfrom(%d, [%#.*hhs%s], %'zu, %#x) → %'ld% lm", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags, rc); + return rc; } diff --git a/libc/sock/recvmsg.c b/libc/sock/recvmsg.c index 8fcebdda4..c688f808f 100644 --- a/libc/sock/recvmsg.c +++ b/libc/sock/recvmsg.c @@ -36,36 +36,61 @@ * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ ssize_t recvmsg(int fd, struct msghdr *msg, int flags) { - ssize_t got; - if (!IsWindows()) { + ssize_t rc, got; + if (IsAsan() && !__asan_is_valid_msghdr(msg)) { + rc = efault(); + } else if (!IsWindows()) { got = sys_recvmsg(fd, msg, flags); - /* An address was provided, convert from BSD form */ + // An address was provided, convert from BSD form if (msg->msg_name && IsBsd() && got != -1) { sockaddr2linux(msg->msg_name); } - return got; - } else { - if (__isfdopen(fd)) { - if (msg->msg_control) return einval(); /* control msg not supported */ + rc = got; + } else if (__isfdopen(fd)) { + if (!msg->msg_control) { if (__isfdkind(fd, kFdSocket)) { - return sys_recvfrom_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, - flags, msg->msg_name, &msg->msg_namelen); + rc = sys_recvfrom_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, flags, + msg->msg_name, &msg->msg_namelen); } else if (__isfdkind(fd, kFdFile) && !msg->msg_name) { /* socketpair */ - if (flags) return einval(); - if ((got = sys_read_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, - -1)) != -1) { - msg->msg_flags = 0; - return got; + if (!flags) { + if ((got = sys_read_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, + -1)) != -1) { + msg->msg_flags = 0; + rc = got; + } else { + rc = -1; + } } else { - return -1; + rc = einval(); // flags not supported on nt } } else { - return enotsock(); + rc = enotsock(); } } else { - return ebadf(); + rc = einval(); // control msg not supported on nt + } + } else { + rc = ebadf(); + } +#if defined(SYSDEBUG) && _DATATRACE + if (__strace > 0) { + if (!msg || (rc == -1 && errno == EFAULT)) { + DATATRACE("recvmsg(%d, %p, %#x) → %'ld% m", fd, msg, flags, rc); + } else { + kprintf(STRACE_PROLOGUE "recvmsg(%d, [{"); + if (msg->msg_namelen) + kprintf(".name=%#.*hhs, ", msg->msg_namelen, msg->msg_name); + if (msg->msg_controllen) + kprintf(".control=%#.*hhs, ", msg->msg_controllen, msg->msg_control); + if (msg->msg_flags) kprintf(".flags=%#x, ", msg->msg_flags); + kprintf(".iov=", fd); + __strace_iov(msg->msg_iov, msg->msg_iovlen, rc != -1 ? rc : 0); + kprintf("}], %#x) → %'ld% m\n", flags, rc); } } +#endif + return rc; } diff --git a/libc/sock/select-nt.c b/libc/sock/select-nt.c index 4f358db43..c2080efad 100644 --- a/libc/sock/select-nt.c +++ b/libc/sock/select-nt.c @@ -16,115 +16,66 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/popcnt.h" -#include "libc/calls/internal.h" +#include "libc/calls/struct/timeval.h" #include "libc/macros.internal.h" -#include "libc/mem/mem.h" -#include "libc/nt/winsock.h" #include "libc/sock/internal.h" -#include "libc/sock/yoink.inc" +#include "libc/sock/select.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/poll.h" #include "libc/sysv/errfuns.h" -static int GetFdsPopcnt(int nfds, fd_set *fds) { - int i, n = 0; - if (fds) { - for (i = 0; i < nfds; ++i) { - n += popcnt(fds->fds_bits[i]); - } - } - return n; -} - -static int FindFdByHandle(int nfds, int64_t h) { - int i, n; - n = MIN(nfds << 3, g_fds.n); - for (i = 0; i < n; ++i) { - if (h == g_fds.p[i].handle && g_fds.p[i].kind != kFdEmpty) { - return i; - } - } - return -1; -} - -static struct NtFdSet *FdSetToNtFdSet(int nfds, fd_set *fds) { - int i, j, k, n, m, fd; - struct NtFdSet *ntfds; - if (fds && (n = GetFdsPopcnt(nfds, fds))) { - m = MIN(n, ARRAYLEN(ntfds->fd_array)); - ntfds = malloc(sizeof(struct NtFdSet)); - for (k = i = 0; i < nfds; ++i) { - if (fds->fds_bits[i]) { - for (j = 0; j < 64 && k < m; ++j) { - if ((fds->fds_bits[i] & (1ul << j)) && i * 8 + j < g_fds.n) { - ntfds->fd_array[k++] = g_fds.p[i * 8 + j].handle; - } - } - } - } - ntfds->fd_count = m; - return ntfds; - } else { - return NULL; - } -} - -static void NtFdSetToFdSet(int nfds, fd_set *fds, struct NtFdSet *ntfds) { - int i, fd; - if (ntfds) { - for (i = 0; i < nfds; ++i) { - fds->fds_bits[i] = 0; - } - for (i = 0; i < ntfds->fd_count; ++i) { - if ((fd = FindFdByHandle(nfds, ntfds->fd_array[i])) != -1) { - fds->fds_bits[fd >> 3] |= 1ul << (fd & 7); - } - } - } -} - -static struct NtTimeval *TimevalToNtTimeval(struct timeval *tv, - struct NtTimeval *nttv) { - if (tv) { - nttv->tv_sec = tv->tv_sec; - nttv->tv_usec = tv->tv_usec; - return nttv; - } else { - return NULL; - } -} - int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { - int n, rc; - struct timespec req, rem; - struct NtTimeval nttimeout, *nttimeoutp; - struct NtFdSet *ntreadfds, *ntwritefds, *ntexceptfds; - if (readfds || writefds || exceptfds) { - nfds = MIN(ARRAYLEN(readfds->fds_bits), ROUNDUP(nfds, 8)) >> 3; - ntreadfds = FdSetToNtFdSet(nfds, readfds); - ntwritefds = FdSetToNtFdSet(nfds, writefds); - ntexceptfds = FdSetToNtFdSet(nfds, exceptfds); - nttimeoutp = TimevalToNtTimeval(timeout, &nttimeout); - if ((rc = __sys_select_nt(0, ntreadfds, ntwritefds, ntexceptfds, - nttimeoutp)) != -1) { - NtFdSetToFdSet(nfds, readfds, ntreadfds); - NtFdSetToFdSet(nfds, writefds, ntwritefds); - NtFdSetToFdSet(nfds, exceptfds, ntexceptfds); - } else { - __winsockerr(); + uint64_t millis; + int i, pfds, events, fdcount; + struct pollfd fds[64]; + + // check for interrupts early before doing work + if (_check_interrupts(false, g_fds.p)) return eintr(); + + // convert bitsets to pollfd + for (pfds = i = 0; i < nfds; ++i) { + events = 0; + if (readfds && FD_ISSET(i, readfds)) events |= POLLIN; + if (writefds && FD_ISSET(i, writefds)) events |= POLLOUT; + if (exceptfds && FD_ISSET(i, exceptfds)) events |= POLLERR; + if (events) { + if (pfds < ARRAYLEN(fds)) { + fds[pfds].fd = i; + fds[pfds].events = events; + fds[pfds].revents = 0; + pfds += 1; + } else { + return enomem(); + } } - free(ntreadfds); - free(ntwritefds); - free(ntexceptfds); - } else if (timeout) { - req.tv_sec = timeout->tv_sec; - req.tv_nsec = timeout->tv_usec * 1000; - if ((rc = sys_nanosleep_nt(&req, &rem)) != -1) { - timeout->tv_sec = rem.tv_sec; - timeout->tv_usec = rem.tv_nsec / 1000; - } - } else { - rc = einval(); } - return rc; + + // convert the wait time to a word + if (!timeout || __builtin_add_overflow(timeout->tv_sec, + timeout->tv_usec / 1000, &millis)) { + millis = -1; + } + + // call our nt poll implementation + fdcount = sys_poll_nt(fds, pfds, &millis); + if (fdcount == -1) return -1; + + // convert pollfd back to bitsets + if (readfds) FD_ZERO(readfds); + if (writefds) FD_ZERO(writefds); + if (exceptfds) FD_ZERO(exceptfds); + for (i = 0; i < fdcount; ++i) { + if (fds[i].revents & POLLIN) FD_SET(fds[i].fd, readfds); + if (fds[i].revents & POLLOUT) FD_SET(fds[i].fd, writefds); + if (fds[i].revents & (POLLERR | POLLNVAL)) FD_SET(fds[i].fd, exceptfds); + } + + // store remaining time back in caller's timeval + if (timeout) { + timeout->tv_sec = millis / 1000; + timeout->tv_usec = millis % 1000 * 1000; + } + + return fdcount; } diff --git a/libc/sock/select.c b/libc/sock/select.c index 887872fcd..e322a2db7 100644 --- a/libc/sock/select.c +++ b/libc/sock/select.c @@ -19,11 +19,14 @@ #include "libc/calls/struct/timeval.h" #include "libc/dce.h" #include "libc/sock/internal.h" -#include "libc/sock/sock.h" +#include "libc/sock/select.h" /** - * Does what poll() does except with a complicated bitset API. - * @note windows nt is limited to first 64 socket descriptors + * Does what poll() does except with bitset API. + * + * This system call is supported on all platforms. However, on Windows, + * this is polyfilled to translate into poll(). So it's recommended that + * poll() be used instead. */ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { diff --git a/libc/sock/send-nt.c b/libc/sock/send-nt.c new file mode 100644 index 000000000..69af0c438 --- /dev/null +++ b/libc/sock/send-nt.c @@ -0,0 +1,47 @@ +/*-*- 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 "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/nt/struct/overlapped.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +/** + * Performs stream socket send on the New Technology. + * + * @param fd must be a socket + * @return number of bytes handed off, or -1 w/ errno + */ +textwindows ssize_t sys_send_nt(int fd, const struct iovec *iov, size_t iovlen, + uint32_t flags) { + ssize_t rc; + uint32_t sent = 0; + struct NtIovec iovnt[16]; + struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()}; + if (_check_interrupts(true, g_fds.p)) return eintr(); + if (!WSASend(g_fds.p[fd].handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &sent, + flags, &overlapped, NULL)) { + rc = sent; + } else { + rc = __wsablock(g_fds.p[fd].handle, &overlapped, &flags, true); + } + WSACloseEvent(overlapped.hEvent); + return rc; +} diff --git a/libc/sock/send.c b/libc/sock/send.c index 87a022b45..2fe9ae644 100644 --- a/libc/sock/send.c +++ b/libc/sock/send.c @@ -16,7 +16,15 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/dce.h" +#include "libc/intrin/asan.internal.h" +#include "libc/macros.internal.h" +#include "libc/sock/internal.h" #include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" /** * Sends data to network socket. @@ -29,7 +37,30 @@ * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ ssize_t send(int fd, const void *buf, size_t size, int flags) { - return sendto(fd, buf, size, flags, NULL, 0); + ssize_t rc; + if (IsAsan() && !__asan_is_valid(buf, size)) { + rc = efault(); + } else if (!IsWindows()) { + rc = sys_sendto(fd, buf, size, flags, 0, 0); + } else if (__isfdopen(fd)) { + if (__isfdkind(fd, kFdSocket)) { + rc = sys_send_nt(fd, (struct iovec[]){{buf, size}}, 1, flags); + } else if (__isfdkind(fd, kFdFile)) { + if (flags) { + rc = einval(); + } else { + rc = sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, -1); + } + } else { + rc = enotsock(); + } + } else { + rc = ebadf(); + } + DATATRACE("send(%d, %#.*hhs%s, %'zu, %#x) → %'ld% lm", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags, rc); + return rc; } diff --git a/libc/sock/sendmsg.c b/libc/sock/sendmsg.c index c16cb9822..3c8545229 100644 --- a/libc/sock/sendmsg.c +++ b/libc/sock/sendmsg.c @@ -18,8 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" +#include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/str/str.h" @@ -36,37 +39,60 @@ * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) { - if (!IsWindows()) { + int64_t rc; + char addr2[128]; + struct msghdr msg2; + if (IsAsan() && !__asan_is_valid_msghdr(msg)) { + rc = efault(); + } else if (!IsWindows()) { if (IsBsd() && msg->msg_name) { /* An optional address is provided, convert it to the BSD form */ - char addr2[128]; - struct msghdr msg2; - if (msg->msg_namelen > sizeof(addr2)) return einval(); - memcpy(&addr2[0], msg->msg_name, msg->msg_namelen); - sockaddr2bsd(&addr2[0]); - - /* Copy all of msg (except for msg_name) into the new ephemeral local */ - memcpy(&msg2, msg, sizeof(msg2)); - msg2.msg_name = &addr2[0]; - return sys_sendmsg(fd, &msg2, flags); + if (msg->msg_namelen <= sizeof(addr2)) { + memcpy(&addr2[0], msg->msg_name, msg->msg_namelen); + sockaddr2bsd(&addr2[0]); + /* Copy all of msg (except for msg_name) into the new ephemeral local */ + memcpy(&msg2, msg, sizeof(msg2)); + msg2.msg_name = &addr2[0]; + rc = sys_sendmsg(fd, &msg2, flags); + } else { + rc = einval(); + } } /* else do the syscall */ - return sys_sendmsg(fd, msg, flags); - } else { - if (__isfdopen(fd)) { - if (msg->msg_control) return einval(); /* control msg not supported */ - if (__isfdkind(fd, kFdSocket)) { - return sys_sendto_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, flags, - msg->msg_name, msg->msg_namelen); - } else if (__isfdkind(fd, kFdFile)) { - return sys_write_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, -1); - } else { - return enotsock(); - } + rc = sys_sendmsg(fd, msg, flags); + } else if (__isfdopen(fd)) { + if (msg->msg_control) { + rc = einval(); /* control msg not supported */ + } else if (__isfdkind(fd, kFdSocket)) { + rc = sys_sendto_nt(fd, msg->msg_iov, msg->msg_iovlen, flags, + msg->msg_name, msg->msg_namelen); + } else if (__isfdkind(fd, kFdFile)) { + rc = sys_write_nt(fd, msg->msg_iov, msg->msg_iovlen, -1); } else { - return ebadf(); + rc = enotsock(); + } + } else { + rc = ebadf(); + } +#if defined(SYSDEBUG) && _DATATRACE + if (__strace > 0) { + if (!msg || (rc == -1 && errno == EFAULT)) { + DATATRACE("sendmsg(%d, %p, %#x) → %'ld% m", fd, msg, flags, rc); + } else { + kprintf(STRACE_PROLOGUE "sendmsg(%d, {"); + if (msg->msg_namelen) + kprintf(".name=%#.*hhs, ", msg->msg_namelen, msg->msg_name); + if (msg->msg_controllen) + kprintf(".control=%#.*hhs, ", msg->msg_controllen, msg->msg_control); + if (msg->msg_flags) kprintf(".flags=%#x, ", msg->msg_flags); + kprintf(".iov=", fd); + __strace_iov(msg->msg_iov, msg->msg_iovlen, rc != -1 ? rc : 0); + kprintf("}, %#x) → %'ld% m\n", flags, rc); } } +#endif + return rc; } diff --git a/libc/sock/sendto-nt.c b/libc/sock/sendto-nt.c index c2b034478..43c716979 100644 --- a/libc/sock/sendto-nt.c +++ b/libc/sock/sendto-nt.c @@ -16,29 +16,33 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/nt/struct/overlapped.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" -#include "libc/sock/yoink.inc" -#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/errfuns.h" /** - * Performs send(), sendto(), or writev() on Windows NT. + * Performs datagram socket send on the New Technology. * * @param fd must be a socket * @return number of bytes handed off, or -1 w/ errno */ -textwindows ssize_t sys_sendto_nt(struct Fd *fd, const struct iovec *iov, +textwindows ssize_t sys_sendto_nt(int fd, const struct iovec *iov, size_t iovlen, uint32_t flags, void *opt_in_addr, uint32_t in_addrsize) { - uint32_t sent; + ssize_t rc; + uint32_t sent = 0; struct NtIovec iovnt[16]; - if (WSASendTo(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &sent, flags, - opt_in_addr, in_addrsize, NULL, NULL) != -1) { - return sent; + struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()}; + if (_check_interrupts(true, g_fds.p)) return eintr(); + if (!WSASendTo(g_fds.p[fd].handle, iovnt, __iovec2nt(iovnt, iov, iovlen), + &sent, flags, opt_in_addr, in_addrsize, &overlapped, NULL)) { + rc = sent; } else { - return __winsockerr(); + rc = __wsablock(g_fds.p[fd].handle, &overlapped, &flags, true); } + WSACloseEvent(overlapped.hEvent); + return rc; } diff --git a/libc/sock/sendto.c b/libc/sock/sendto.c index 98afa4ca4..3fcfb0023 100644 --- a/libc/sock/sendto.c +++ b/libc/sock/sendto.c @@ -18,9 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/macros.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/str/str.h" @@ -45,39 +47,48 @@ * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. * @asyncsignalsafe + * @restartable (unless SO_RCVTIMEO) */ ssize_t sendto(int fd, const void *buf, size_t size, uint32_t flags, const void *opt_addr, uint32_t addrsize) { + ssize_t rc; + char addr2[sizeof(struct sockaddr_un_bsd)]; if (IsAsan() && (!__asan_is_valid(buf, size) || (opt_addr && !__asan_is_valid(opt_addr, addrsize)))) { - return efault(); - } - _firewall(opt_addr, addrsize); - if (!IsWindows()) { - if (!IsBsd() || !opt_addr) { - return sys_sendto(fd, buf, size, flags, opt_addr, addrsize); - } else { - char addr2[sizeof( - struct sockaddr_un_bsd)]; /* sockaddr_un_bsd is the largest */ - if (addrsize > sizeof(addr2)) return einval(); - memcpy(&addr2, opt_addr, addrsize); - sockaddr2bsd(&addr2[0]); - return sys_sendto(fd, buf, size, flags, &addr2[0], addrsize); - } + rc = efault(); } else { - if (__isfdopen(fd)) { - if (__isfdkind(fd, kFdSocket)) { - return sys_sendto_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, - flags, opt_addr, addrsize); - } else if (__isfdkind(fd, kFdFile)) { /* e.g. socketpair() */ - if (flags) return einval(); - if (opt_addr) return eisconn(); - return sys_write_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1); + _firewall(opt_addr, addrsize); + if (!IsWindows()) { + if (!IsBsd() || !opt_addr) { + rc = sys_sendto(fd, buf, size, flags, opt_addr, addrsize); + } else if (addrsize > sizeof(addr2)) { + rc = einval(); } else { - return enotsock(); + memcpy(&addr2, opt_addr, addrsize); + sockaddr2bsd(&addr2[0]); + rc = sys_sendto(fd, buf, size, flags, &addr2[0], addrsize); + } + } else if (__isfdopen(fd)) { + if (__isfdkind(fd, kFdSocket)) { + rc = sys_sendto_nt(fd, (struct iovec[]){{buf, size}}, 1, flags, + opt_addr, addrsize); + } else if (__isfdkind(fd, kFdFile)) { + if (flags) { + rc = einval(); + } else if (opt_addr) { + rc = eisconn(); + } else { + rc = sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, -1); + } + } else { + rc = enotsock(); } } else { - return ebadf(); + rc = ebadf(); } } + DATATRACE("sendto(%d, %#.*hhs%s, %'zu, %#x, %p, %u) → %'ld% lm", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags, + opt_addr, addrsize, rc); + return rc; } diff --git a/libc/sock/setsockopt-nt.c b/libc/sock/setsockopt-nt.c index ed31ffda5..4f637d8cd 100644 --- a/libc/sock/setsockopt-nt.c +++ b/libc/sock/setsockopt-nt.c @@ -17,39 +17,44 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/struct/timeval.h" +#include "libc/limits.h" #include "libc/macros.internal.h" +#include "libc/nt/struct/linger.h" #include "libc/sock/internal.h" #include "libc/sysv/consts/so.h" +#include "libc/sysv/consts/sol.h" #include "libc/sysv/errfuns.h" -struct linger_nt { /* Linux+XNU+BSD ABI */ - uint16_t l_onoff; /* on/off */ - uint16_t l_linger; /* seconds */ -}; - textwindows int sys_setsockopt_nt(struct Fd *fd, int level, int optname, const void *optval, uint32_t optlen) { + int64_t ms; struct timeval *tv; struct linger *linger; union { uint32_t millis; struct linger_nt linger; - } nt; + } u; - if (optname == SO_LINGER && optval && optlen == sizeof(struct linger)) { - linger = optval; - nt.linger.l_onoff = linger->l_onoff; - nt.linger.l_linger = MIN(0xFFFF, MAX(0, linger->l_linger)); - optval = &nt.linger; - optlen = sizeof(nt.linger); - } - - if ((optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) && optval && - optlen == sizeof(struct timeval)) { - tv = optval; - nt.millis = MIN(0xFFFFFFFF, MAX(0, tv->tv_sec * 1000 + tv->tv_usec / 1000)); - optval = &nt.millis; - optlen = sizeof(nt.millis); + if (level == SOL_SOCKET) { + if (optname == SO_LINGER && optval && optlen == sizeof(struct linger)) { + linger = optval; + u.linger.l_onoff = linger->l_onoff; + u.linger.l_linger = MIN(0xFFFF, MAX(0, linger->l_linger)); + optval = &u.linger; + optlen = sizeof(u.linger); + } else if ((optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) && optval && + optlen == sizeof(struct timeval)) { + tv = optval; + if (__builtin_mul_overflow(tv->tv_sec, 1000, &ms) || + __builtin_add_overflow(ms, tv->tv_usec / 1000, &ms) || + (ms < 0 || ms > 0xffffffff)) { + u.millis = 0xffffffff; + } else { + u.millis = ms; + } + optval = &u.millis; + optlen = sizeof(u.millis); + } } if (__sys_setsockopt_nt(fd->handle, level, optname, optval, optlen) != -1) { diff --git a/libc/sock/setsockopt.c b/libc/sock/setsockopt.c index e81b97ee9..c66b078eb 100644 --- a/libc/sock/setsockopt.c +++ b/libc/sock/setsockopt.c @@ -17,8 +17,11 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/fmt/magnumstrs.internal.h" +#include "libc/intrin/asan.internal.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" @@ -50,19 +53,40 @@ static bool setsockopt_polyfill(int *optname) { */ int setsockopt(int fd, int level, int optname, const void *optval, uint32_t optlen) { - if (!optval) return efault(); - if (!level || !optname) return enoprotoopt(); /* our sysvconsts definition */ - if (optname == -1) return 0; /* our sysvconsts definition */ - if (!IsWindows()) { + int e, rc; + + if (!optname) { + rc = enosys(); /* see libc/sysv/consts.sh */ + } else if ((!optval && optlen) || + (IsAsan() && !__asan_is_valid(optval, optlen))) { + rc = efault(); + } else if (!IsWindows()) { + rc = -1; + e = errno; do { if (sys_setsockopt(fd, level, optname, optval, optlen) != -1) { - return 0; + errno = e; + rc = 0; + break; } } while (setsockopt_polyfill(&optname)); - return -1; } else if (__isfdkind(fd, kFdSocket)) { - return sys_setsockopt_nt(&g_fds.p[fd], level, optname, optval, optlen); + rc = sys_setsockopt_nt(&g_fds.p[fd], level, optname, optval, optlen); } else { - return ebadf(); + rc = ebadf(); } + +#ifdef SYSDEBUG + if (!(rc == -1 && errno == EFAULT)) { + STRACE("setsockopt(%d, %s, %s, %#.*hhs, %'u) → %d% lm", fd, + DescribeSockLevel(level), DescribeSockOptname(level, optname), + optlen, optval, optlen, rc); + } else { + STRACE("setsockopt(%d, %s, %s, %p, %'u) → %d% lm", fd, + DescribeSockLevel(level), DescribeSockOptname(level, optname), + optval, optlen, rc); + } +#endif + + return rc; } diff --git a/libc/sock/shutdown.c b/libc/sock/shutdown.c index 2183b2f2f..47b0ade0f 100644 --- a/libc/sock/shutdown.c +++ b/libc/sock/shutdown.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" @@ -31,11 +32,14 @@ * @asyncsignalsafe */ int shutdown(int fd, int how) { + int rc; if (!IsWindows()) { - return sys_shutdown(fd, how); + rc = sys_shutdown(fd, how); } else if (__isfdkind(fd, kFdSocket)) { - return sys_shutdown_nt(&g_fds.p[fd], how); + rc = sys_shutdown_nt(&g_fds.p[fd], how); } else { - return ebadf(); + rc = ebadf(); } + STRACE("shutdown(%d, %d) -> %d% lm", fd, how, rc); + return rc; } diff --git a/libc/sock/sock.h b/libc/sock/sock.h index 6eb96b9ca..95c9d7bcc 100644 --- a/libc/sock/sock.h +++ b/libc/sock/sock.h @@ -136,31 +136,30 @@ char *inet_ntoa(struct in_addr); int parseport(const char *); uint32_t *GetHostIps(void); -int socket(int, int, int) nodiscard; -int accept(int, void *, uint32_t *) nodiscard; -int accept4(int, void *, uint32_t *, int) nodiscard; +int socket(int, int, int); +int accept(int, void *, uint32_t *); +int accept4(int, void *, uint32_t *, int); int bind(int, const void *, uint32_t); int connect(int, const void *, uint32_t); int listen(int, int); int shutdown(int, int); -int getsockname(int, void *, uint32_t *) paramsnonnull(); -int getpeername(int, void *, uint32_t *) paramsnonnull(); -ssize_t send(int, const void *, size_t, int) paramsnonnull(); +int getsockname(int, void *, uint32_t *); +int getpeername(int, void *, uint32_t *); +ssize_t send(int, const void *, size_t, int); ssize_t recv(int, void *, size_t, int); -ssize_t recvmsg(int, struct msghdr *, int) paramsnonnull(); +ssize_t recvmsg(int, struct msghdr *, int); ssize_t recvfrom(int, void *, size_t, uint32_t, void *, uint32_t *); -ssize_t sendmsg(int, const struct msghdr *, int) paramsnonnull(); +ssize_t sendmsg(int, const struct msghdr *, int); ssize_t readv(int, const struct iovec *, int); ssize_t writev(int, const struct iovec *, int); ssize_t sendfile(int, int, int64_t *, size_t); -int getsockopt(int, int, int, void *, uint32_t *) paramsnonnull((5)); +int getsockopt(int, int, int, void *, uint32_t *); int setsockopt(int, int, int, const void *, uint32_t); -int socketpair(int, int, int, int[2]) paramsnonnull(); -int poll(struct pollfd *, uint64_t, int32_t) paramsnonnull(); +int socketpair(int, int, int, int[2]); +int poll(struct pollfd *, uint64_t, int32_t); int ppoll(struct pollfd *, uint64_t, const struct timespec *, - const struct sigset *) paramsnonnull((1, 4)); -ssize_t sendto(int, const void *, size_t, uint32_t, const void *, uint32_t) - paramsnonnull((2)); + const struct sigset *); +ssize_t sendto(int, const void *, size_t, uint32_t, const void *, uint32_t); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/sock/sock.mk b/libc/sock/sock.mk index ec58139a3..4ffe02852 100644 --- a/libc/sock/sock.mk +++ b/libc/sock/sock.mk @@ -9,10 +9,16 @@ LIBC_SOCK_A = o/$(MODE)/libc/sock/sock.a LIBC_SOCK_A_FILES := $(wildcard libc/sock/*) LIBC_SOCK_A_HDRS = $(filter %.h,$(LIBC_SOCK_A_FILES)) LIBC_SOCK_A_INCS = $(filter %.inc,$(LIBC_SOCK_A_FILES)) -LIBC_SOCK_A_SRCS = $(filter %.c,$(LIBC_SOCK_A_FILES)) +LIBC_SOCK_A_SRCS_C = $(filter %.c,$(LIBC_SOCK_A_FILES)) +LIBC_SOCK_A_SRCS_S = $(filter %.S,$(LIBC_SOCK_A_FILES)) + +LIBC_SOCK_A_SRCS = \ + $(LIBC_SOCK_A_SRCS_C) \ + $(LIBC_SOCK_A_SRCS_S) LIBC_SOCK_A_OBJS = \ - $(LIBC_SOCK_A_SRCS:%.c=o/$(MODE)/%.o) + $(LIBC_SOCK_A_SRCS_C:%.c=o/$(MODE)/%.o) \ + $(LIBC_SOCK_A_SRCS_S:%.S=o/$(MODE)/%.o) LIBC_SOCK_A_CHECKS = \ $(LIBC_SOCK_A).pkg \ @@ -53,6 +59,11 @@ $(LIBC_SOCK_A).pkg: \ $(LIBC_SOCK_A_OBJS) \ $(foreach x,$(LIBC_SOCK_A_DIRECTDEPS),$($(x)_A).pkg) +o/$(MODE)/libc/sock/ntstdin.greg.o: \ + OVERRIDE_COPTS += \ + -ffreestanding \ + $(NO_MAGIC) + LIBC_SOCK_LIBS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x))) LIBC_SOCK_SRCS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)_SRCS)) LIBC_SOCK_HDRS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)_HDRS)) diff --git a/libc/sock/sockdebug.c b/libc/sock/sockdebug.c new file mode 100644 index 000000000..ff52cf07b --- /dev/null +++ b/libc/sock/sockdebug.c @@ -0,0 +1,118 @@ +/*-*- 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/struct/sockaddr6.h" +#include "libc/errno.h" +#include "libc/fmt/itoa.h" +#include "libc/macros.internal.h" +#include "libc/sock/sock.h" +#include "libc/sock/sockdebug.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" +#include "libc/sysv/consts/ipproto.h" +#include "libc/sysv/consts/sock.h" + +const char *__describe_socket_family(int family) { + static char buf[12]; + if (family == AF_UNIX) return "AF_UNIX"; + if (family == AF_INET) return "AF_INET"; + if (family == AF_INET6) return "AF_INET6"; + FormatInt32(buf, family); + return buf; +} + +const char *__describe_socket_type(int type) { + int x; + char *p; + static char buf[12 + 1 + 12 + 1 + 13 + 1]; + p = buf; + x = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); + if (x == SOCK_STREAM) { + p = stpcpy(p, "SOCK_STREAM"); + } else if (x == SOCK_DGRAM) { + p = stpcpy(p, "SOCK_DGRAM"); + } else if (x == SOCK_RAW) { + p = stpcpy(p, "SOCK_RAW"); + } else if (x == SOCK_RDM) { + p = stpcpy(p, "SOCK_RDM"); + } else if (x == SOCK_SEQPACKET) { + p = stpcpy(p, "SOCK_SEQPACKET"); + } else { + p = FormatInt32(p, x); + } + if (type & SOCK_CLOEXEC) p = stpcpy(p, "|SOCK_CLOEXEC"); + if (type & SOCK_NONBLOCK) p = stpcpy(p, "|SOCK_NONBLOCK"); + return buf; +} + +const char *__describe_socket_protocol(int family) { + static char buf[12]; + if (family == IPPROTO_IP) return "IPPROTO_IP"; + if (family == IPPROTO_ICMP) return "IPPROTO_ICMP"; + if (family == IPPROTO_TCP) return "IPPROTO_TCP"; + if (family == IPPROTO_UDP) return "IPPROTO_UDP"; + if (family == IPPROTO_RAW) return "IPPROTO_RAW"; + if (family == IPPROTO_IPV6) return "IPPROTO_IPv6"; + FormatInt32(buf, family); + return buf; +} + +const char *__describe_sockaddr(const struct sockaddr *sa, size_t sasize) { + int e; + size_t n; + uint16_t port; + char *p, ip[72]; + static char buf[128]; + e = errno; + stpcpy(buf, "NULL"); + if (sa && sasize >= sizeof(sa->sa_family)) { + stpcpy(buf, __describe_socket_family(sa->sa_family)); + if (sa->sa_family == AF_INET && sasize >= sizeof(struct sockaddr_in)) { + const struct sockaddr_in *in; + in = (const struct sockaddr_in *)sa; + if (inet_ntop(AF_INET, &in->sin_addr, ip, sizeof(ip))) { + p = buf; + p = stpcpy(p, ip); + *p++ = ':'; + p = FormatUint32(p, ntohs(in->sin_port)); + } + } else if (sa->sa_family == AF_INET6 && + sasize >= sizeof(struct sockaddr_in6)) { + const struct sockaddr_in6 *in6; + in6 = (const struct sockaddr_in6 *)sa; + if (inet_ntop(AF_INET6, &in6->sin6_addr, ip, sizeof(ip))) { + p = buf; + *p++ = '['; + p = stpcpy(p, ip); + *p++ = ']'; + *p++ = ':'; + p = FormatUint32(p, in6->sin6_port); + } + } else if (sa->sa_family == AF_UNIX && + sasize >= sizeof(struct sockaddr_un)) { + const struct sockaddr_un *unix; + unix = (const struct sockaddr_un *)sa; + n = strnlen(unix->sun_path, sizeof(unix->sun_path)); + n = MIN(n, sizeof(buf) - 1); + memcpy(buf, unix->sun_path, n); + buf[n] = 0; + } + } + errno = e; + return buf; +} diff --git a/libc/sock/sockdebug.h b/libc/sock/sockdebug.h new file mode 100644 index 000000000..f85b99bff --- /dev/null +++ b/libc/sock/sockdebug.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_SOCK_SOCKDEBUG_H_ +#define COSMOPOLITAN_LIBC_SOCK_SOCKDEBUG_H_ +#include "libc/sock/sock.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +const char *__describe_sockaddr(const struct sockaddr *, size_t); +const char *__describe_socket_family(int); +const char *__describe_socket_type(int); +const char *__describe_socket_protocol(int); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SOCK_SOCKDEBUG_H_ */ diff --git a/libc/sock/socket-nt.c b/libc/sock/socket-nt.c index ebe8b79bf..e919f017a 100644 --- a/libc/sock/socket-nt.c +++ b/libc/sock/socket-nt.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/mem/mem.h" +#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/iphlpapi.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" @@ -36,14 +37,16 @@ */ STATIC_YOINK("GetAdaptersAddresses"); STATIC_YOINK("tprecode16to8"); +STATIC_YOINK("_dupsockfd"); textwindows int sys_socket_nt(int family, int type, int protocol) { int64_t h; struct SockFd *sockfd; int fd, oflags, truetype; - if ((fd = __reservefd()) == -1) return -1; + if ((fd = __reservefd(-1)) == -1) return -1; truetype = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); - if ((h = WSASocket(family, truetype, protocol, NULL, 0, 0)) != -1) { + if ((h = WSASocket(family, truetype, protocol, NULL, 0, + kNtWsaFlagOverlapped)) != -1) { oflags = 0; if (type & SOCK_CLOEXEC) oflags |= O_CLOEXEC; if (type & SOCK_NONBLOCK) oflags |= O_NONBLOCK; @@ -58,9 +61,9 @@ textwindows int sys_socket_nt(int family, int type, int protocol) { sockfd->family = family; sockfd->type = truetype; sockfd->protocol = protocol; - sockfd->event = WSACreateEvent(); g_fds.p[fd].kind = kFdSocket; g_fds.p[fd].flags = oflags; + g_fds.p[fd].mode = 0140666; g_fds.p[fd].handle = h; g_fds.p[fd].extra = (uintptr_t)sockfd; return fd; diff --git a/libc/sock/socket.c b/libc/sock/socket.c index f668a5f00..1e6952f45 100644 --- a/libc/sock/socket.c +++ b/libc/sock/socket.c @@ -16,11 +16,12 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" +#include "libc/sock/sockdebug.h" #include "libc/sysv/consts/af.h" -#include "libc/sysv/errfuns.h" /** * Creates new system resource for network communication, e.g. @@ -38,17 +39,15 @@ * @asyncsignalsafe */ int socket(int family, int type, int protocol) { - if (family == AF_UNSPEC) { - family = AF_INET; - } else if (family == AF_INET6) { - /* Recommend IPv6 on frontend serving infrastructure only. That's - what Google Cloud does. It's more secure. It also means poll() - will work on Windows, which doesn't allow mixing third layers. */ - return epfnosupport(); - } + int rc; + if (family == AF_UNSPEC) family = AF_INET; if (!IsWindows()) { - return sys_socket(family, type, protocol); + rc = sys_socket(family, type, protocol); } else { - return sys_socket_nt(family, type, protocol); + rc = sys_socket_nt(family, type, protocol); } + STRACE("socket(%s, %s, %s) → %d% lm", __describe_socket_family(family), + __describe_socket_type(type), __describe_socket_protocol(protocol), + rc); + return rc; } diff --git a/libc/sock/socketpair-nt.c b/libc/sock/socketpair-nt.c index 10899b1fd..fb71e728f 100644 --- a/libc/sock/socketpair-nt.c +++ b/libc/sock/socketpair-nt.c @@ -19,6 +19,7 @@ #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" +#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/ipc.h" #include "libc/nt/runtime.h" #include "libc/sock/internal.h" @@ -42,35 +43,32 @@ textwindows int sys_socketpair_nt(int family, int type, int proto, int sv[2]) { if (type & SOCK_CLOEXEC) oflags |= O_CLOEXEC; type &= ~SOCK_CLOEXEC; - mode = kNtPipeWait; if (type == SOCK_STREAM) { - mode |= kNtPipeReadmodeByte | kNtPipeTypeByte; + mode = kNtPipeTypeByte | kNtPipeReadmodeByte; } else if ((type == SOCK_DGRAM) || (type == SOCK_SEQPACKET)) { - mode |= kNtPipeReadmodeMessage | kNtPipeTypeMessage; + mode = kNtPipeTypeMessage | kNtPipeReadmodeMessage; } else { return eopnotsupp(); } CreatePipeName(pipename); - if ((reader = __reservefd()) == -1) return -1; - if ((writer = __reservefd()) == -1) { + if ((reader = __reservefd(-1)) == -1) return -1; + if ((writer = __reservefd(-1)) == -1) { __releasefd(reader); return -1; } - if ((hpipe = CreateNamedPipe(pipename, kNtPipeAccessDuplex, mode, 1, 65536, - 65536, 0, &kNtIsInheritable)) == -1) { - __winerr(); + if ((hpipe = CreateNamedPipe( + pipename, kNtPipeAccessDuplex | kNtFileFlagOverlapped, mode, 1, + 65536, 65536, 0, &kNtIsInheritable)) == -1) { __releasefd(writer); __releasefd(reader); return -1; } - h1 = CreateFile(pipename, kNtGenericWrite | kNtGenericRead, - 0, // Not shared - &kNtIsInheritable, kNtOpenExisting, 0, 0); + h1 = CreateFile(pipename, kNtGenericWrite | kNtGenericRead, 0, + &kNtIsInheritable, kNtOpenExisting, kNtFileFlagOverlapped, 0); if (h1 == -1) { CloseHandle(hpipe); - __winerr(); __releasefd(writer); __releasefd(reader); return -1; @@ -78,10 +76,12 @@ textwindows int sys_socketpair_nt(int family, int type, int proto, int sv[2]) { g_fds.p[reader].kind = kFdFile; g_fds.p[reader].flags = oflags; + g_fds.p[reader].mode = 0140444; g_fds.p[reader].handle = hpipe; g_fds.p[writer].kind = kFdFile; g_fds.p[writer].flags = oflags; + g_fds.p[writer].mode = 0140222; g_fds.p[writer].handle = h1; sv[0] = reader; diff --git a/libc/sock/socketpair.c b/libc/sock/socketpair.c index c0b928bc8..8ea6dcc60 100644 --- a/libc/sock/socketpair.c +++ b/libc/sock/socketpair.c @@ -25,7 +25,9 @@ * Creates bidirectional pipe. * * @param family should be AF_UNIX or synonymously AF_LOCAL - * @param type may be or'd with SOCK_CLOEXEC + * @param type can be SOCK_STREAM (for TCP), SOCK_DGRAM (e.g. UDP), or + * SOCK_RAW (IP) so long as IP_HDRINCL was passed to setsockopt(); + * and additionally, may be or'd with SOCK_NONBLOCK, SOCK_CLOEXEC * @param sv a vector of 2 integers to store the created sockets * @return 0 if success, -1 in case of error * @error EFAULT, EPFNOSUPPORT, etc. diff --git a/libc/sock/stdinworker.c b/libc/sock/stdinworker.c new file mode 100644 index 000000000..0dc32fe94 --- /dev/null +++ b/libc/sock/stdinworker.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 2022 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/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/ntstdin.internal.h" +#include "libc/sock/sock.h" + +/* STATIC_YOINK("StdinWorker"); */ + +static textexit void StdinWorkerFree(void) { + int i; + NTTRACE("StdinWorkerFree()"); + for (i = g_fds.n; i--;) { + if (g_fds.p[i].kind && g_fds.p[i].worker) { + close(i); + } + } +} + +static textstartup void StdinWorkerInit(void) { + g_fds.p[0].worker = NewNtStdinWorker(0); + atexit(StdinWorkerFree); +} + +const void *const StdinWorker[] initarray = { + StdinWorkerInit, +}; diff --git a/libc/sock/syslog.c b/libc/sock/syslog.c index 36238de8b..1b325ab2b 100644 --- a/libc/sock/syslog.c +++ b/libc/sock/syslog.c @@ -22,6 +22,7 @@ #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/log/internal.h" +#include "libc/macros.internal.h" #include "libc/nt/events.h" #include "libc/nt/runtime.h" #include "libc/runtime/valist.h" @@ -43,13 +44,18 @@ * for the first time. */ static int log_facility = -1; -static char log_ident[32]; +static char16_t log_ident[32]; static int log_opt; static int log_mask; static uint16_t log_id; /* Used for Windows EvtID */ static int64_t log_fd = -1; -static const struct sockaddr_un log_addr = {AF_UNIX, "/dev/log"}; +static const char *const kLogPaths[] = { + "/dev/log", + // "/var/run/log", // TODO: Help with XNU and FreeBSD. +}; + +static struct sockaddr_un log_addr = {AF_UNIX, "/dev/log"}; static int64_t Time(int64_t *tp) { struct timespec ts; @@ -72,16 +78,20 @@ forceinline int is_lost_conn(int e) { } static void __openlog() { + int i; if (IsWindows()) { - log_fd = RegisterEventSourceA(NULL, log_ident); + log_fd = RegisterEventSource(NULL, log_ident); } else { log_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (log_fd >= 0) { - int rc = connect(log_fd, (void *)&log_addr, sizeof(log_addr)); - if (rc < 0) { - printf("ERR: connect(openlog) failed: %s (errno=%d)\n", strerror(errno), - errno); + for (i = 0; i < ARRAYLEN(kLogPaths); ++i) { + strcpy(log_addr.sun_path, kLogPaths[i]); + if (!connect(log_fd, (void *)&log_addr, sizeof(log_addr))) { + return; + } } + printf("ERR: connect(openlog) failed: %s (errno=%d)\n", strerror(errno), + errno); } } } @@ -134,8 +144,8 @@ void vsyslog(int priority, const char *message, va_list ap) { */ l = snprintf(buf, sizeof(buf), "<%d>%s ", priority, timebuf); hlen = l; - l += snprintf(buf + l, sizeof(buf) - l, "%s%s%.0d%s: ", log_ident, "[" + !pid, - pid, "]" + !pid); + l += snprintf(buf + l, sizeof(buf) - l, "%hs%s%.0d%s: ", log_ident, + "[" + !pid, pid, "]" + !pid); errno = errno_save; /* Append user message */ @@ -280,9 +290,7 @@ void openlog(const char *ident, int opt, int facility) { if (!ident) { ident = program_invocation_short_name; } - n = strnlen(ident, sizeof(log_ident) - 1); - memcpy(log_ident, ident, n); - log_ident[n] = 0; + tprecode8to16(log_ident, ARRAYLEN(log_ident), ident); log_opt = opt; log_facility = facility; log_id = 0; diff --git a/libc/sock/syslog.h b/libc/sock/syslog.h index 5342509bb..368fd6c18 100644 --- a/libc/sock/syslog.h +++ b/libc/sock/syslog.h @@ -1,11 +1,9 @@ #ifndef COSMOPOLITAN_LIBC_SOCK_SYSLOG_H_ #define COSMOPOLITAN_LIBC_SOCK_SYSLOG_H_ - - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#define LOG_PRI(p) ((p) & LOG_PRIMASK) +#define LOG_PRI(p) (LOG_PRIMASK & (p)) int setlogmask(int); void openlog(const char *, int, int); diff --git a/libc/sock/winsockblock.c b/libc/sock/winsockblock.c index 5bdb44613..9ccbe4b3e 100644 --- a/libc/sock/winsockblock.c +++ b/libc/sock/winsockblock.c @@ -30,6 +30,11 @@ textwindows int64_t __winsockblock(int64_t fh, unsigned eventbit, int64_t rc) { if (WSAGetLastError() != EWOULDBLOCK) return __winsockerr(); eh = WSACreateEvent(); bzero(&ev, sizeof(ev)); + /* The proper way to reset the state of an event object used with the + WSAEventSelect function is to pass the handle of the event object + to the WSAEnumNetworkEvents function in the hEventObject parameter. + This will reset the event object and adjust the status of active FD + events on the socket in an atomic fashion. -- MSDN */ if (WSAEventSelect(fh, eh, 1u << eventbit) != -1 && WSAEnumNetworkEvents(fh, eh, &ev) != -1) { if (!ev.iErrorCode[eventbit]) { diff --git a/libc/sock/wsablock.c b/libc/sock/wsablock.c new file mode 100644 index 000000000..16883b76d --- /dev/null +++ b/libc/sock/wsablock.c @@ -0,0 +1,54 @@ +/*-*- 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 2022 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/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/nt/enum/wait.h" +#include "libc/nt/errors.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +textwindows int __wsablock(int64_t handle, struct NtOverlapped *overlapped, + uint32_t *flags, bool restartable) { + uint32_t i, got; + if (WSAGetLastError() != kNtErrorIoPending) { + NTTRACE("WSARecv failed %lm"); + return __winsockerr(); + } + for (;;) { + i = WSAWaitForMultipleEvents(1, &overlapped->hEvent, true, + __SIG_POLLING_INTERVAL_MS, true); + if (i == kNtWaitFailed) { + NTTRACE("WSAWaitForMultipleEvents failed %lm"); + return __winsockerr(); + } else if (i == kNtWaitTimeout || i == kNtWaitIoCompletion) { + if (_check_interrupts(restartable, g_fds.p)) return eintr(); +#if _NTTRACE + POLLTRACE("WSAWaitForMultipleEvents..."); +#endif + } else { + break; + } + } + if (!WSAGetOverlappedResult(handle, overlapped, &got, false, flags)) { + NTTRACE("WSAGetOverlappedResult failed %lm"); + return __winsockerr(); + } + return got; +} diff --git a/libc/sock/yoink.inc b/libc/sock/yoink.inc index f17e7eb2f..4a210880d 100644 --- a/libc/sock/yoink.inc +++ b/libc/sock/yoink.inc @@ -1,4 +1,5 @@ STATIC_YOINK("kNtWsaData"); // for winmain +STATIC_YOINK("WSAGetLastError"); // for kprintf STATIC_YOINK("sys_closesocket_nt"); // for close -STATIC_YOINK("sys_recvfrom_nt"); // for readv -STATIC_YOINK("sys_sendto_nt"); // for writev +STATIC_YOINK("sys_recv_nt"); // for readv +STATIC_YOINK("sys_send_nt"); // for writev diff --git a/libc/stdio/append.internal.h b/libc/stdio/append.internal.h index bb71336c1..c6560a99d 100644 --- a/libc/stdio/append.internal.h +++ b/libc/stdio/append.internal.h @@ -19,6 +19,8 @@ ssize_t appendw(char **, uint64_t); ssize_t appends(char **, const char *); ssize_t appendf(char **, const char *, ...); ssize_t vappendf(char **, const char *, va_list); +ssize_t kappendf(char **, const char *, ...); +ssize_t kvappendf(char **, const char *, va_list); #if defined(__GNUC__) && !defined(__STRICT_ANSI__) #define appendf(BUF, FMT, ...) appendf(BUF, PFLINK(FMT), ##__VA_ARGS__) diff --git a/libc/stdio/appendd.c b/libc/stdio/appendd.c index 4a6c63775..b5b3c0468 100644 --- a/libc/stdio/appendd.c +++ b/libc/stdio/appendd.c @@ -59,7 +59,11 @@ ssize_t appendd(char **b, const void *s, size_t l) { return -1; } } - *(char *)mempcpy(p + z.i, s, l) = 0; + if (l) { + *(char *)mempcpy(p + z.i, s, l) = 0; + } else { + p[z.i] = 0; + } z.i += l; if (!IsTiny() && W == 8) z.i |= (size_t)APPEND_COOKIE << 48; *(size_t *)(p + z.n - W) = z.i; diff --git a/libc/stdio/appendr.c b/libc/stdio/appendr.c index 7fb25e265..b29f0e067 100644 --- a/libc/stdio/appendr.c +++ b/libc/stdio/appendr.c @@ -57,8 +57,8 @@ ssize_t appendr(char **b, size_t i) { n = ROUNDUP(i + 1, 8) + W; if (n > z.n || bsrl(n) < bsrl(z.n)) { if ((p = realloc(p, n))) { - n = malloc_usable_size(p); - assert(!(n & (W - 1))); + z.n = malloc_usable_size(p); + assert(!(z.n & (W - 1))); *b = p; } else { return -1; @@ -69,7 +69,7 @@ ssize_t appendr(char **b, size_t i) { } else { p[i] = 0; } - *(size_t *)(p + n - W) = + *(size_t *)(p + z.n - W) = i | (!IsTiny() && W == 8 ? (size_t)APPEND_COOKIE << 48 : 0); } return i; diff --git a/libc/stdio/dirstream.c b/libc/stdio/dirstream.c index 2f8bdb2aa..be831b5c8 100644 --- a/libc/stdio/dirstream.c +++ b/libc/stdio/dirstream.c @@ -21,8 +21,11 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/dirent.h" #include "libc/dce.h" +#include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/nt/enum/fileflagandattributes.h" @@ -115,17 +118,20 @@ struct dirent_netbsd { static textwindows DIR *opendir_nt_impl(char16_t *name, size_t len) { DIR *res; if (len + 2 + 1 <= PATH_MAX) { - if (len > 1 && name[len - 1] != u'\\') { - name[len++] = u'\\'; + if (len == 1 && name[0] == '.') { + name[0] = '*'; + } else { + if (len > 1 && name[len - 1] != u'\\') { + name[len++] = u'\\'; + } + name[len++] = u'*'; } - name[len++] = u'*'; name[len] = u'\0'; if ((res = calloc(1, sizeof(DIR)))) { if ((res->fd = FindFirstFile(name, &res->windata)) != -1) { return res; - } else { - __winerr(); } + __fix_enotdir(-1, name); free(res); } } else { @@ -138,13 +144,17 @@ static textwindows dontinline DIR *opendir_nt(const char *path) { int len; DIR *res; char16_t *name; - if ((name = malloc(PATH_MAX * 2))) { - if ((len = __mkntpath(path, name)) != -1 && - (res = opendir_nt_impl(name, len))) { - res->name = name; - return res; + if (*path) { + if ((name = malloc(PATH_MAX * 2))) { + if ((len = __mkntpath(path, name)) != -1 && + (res = opendir_nt_impl(name, len))) { + res->name = name; + return res; + } + free(name); } - free(name); + } else { + enoent(); } return NULL; } @@ -233,8 +243,11 @@ DIR *opendir(const char *name) { struct stat st; struct Zipos *zip; struct ZiposUri zipname; - if (weaken(__zipos_get) && weaken(__zipos_parseuri)(name, &zipname) != -1) { - ZTRACE("__zipos_opendir(%`'s)", name); + if (!name || (IsAsan() && !__asan_is_valid(name, 1))) { + efault(); + res = 0; + } else if (weaken(__zipos_get) && + weaken(__zipos_parseuri)(name, &zipname) != -1) { if (weaken(__zipos_stat)(&zipname, &st) != -1) { if (S_ISDIR(st.st_mode)) { zip = weaken(__zipos_get)(); @@ -250,25 +263,25 @@ DIR *opendir(const char *name) { } res->zip.prefix[zipname.len] = '\0'; res->zip.prefixlen = zipname.len; - return res; } else { errno = ENOTDIR; - return 0; + res = 0; } } else { - return 0; + res = 0; } } else if (!IsWindows()) { - res = NULL; + res = 0; if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC)) != -1) { if (!(res = fdopendir(fd))) { close(fd); } } - return res; } else { - return opendir_nt(name); + res = opendir_nt(name); } + STRACE("opendir(%#s) → %p% m", name, res); + return res; } /** @@ -284,10 +297,11 @@ DIR *fdopendir(int fd) { if (!IsWindows()) { if (!(dir = calloc(1, sizeof(*dir)))) return NULL; dir->fd = fd; - return dir; } else { - return fdopendir_nt(fd); + dir = fdopendir_nt(fd); } + STRACE("fdopendir(%d) → %p% m", fd, dir); + return dir; } /** @@ -341,6 +355,7 @@ struct dirent *readdir(DIR *dir) { if (dir->buf_pos >= dir->buf_end) { basep = dir->tell; /* TODO(jart): what does xnu do */ rc = getdents(dir->fd, dir->buf, sizeof(dir->buf) - 256, &basep); + STRACE("getdents(%d) → %d% m", dir->fd, rc); if (!rc || rc == -1) return NULL; dir->buf_pos = 0; dir->buf_end = rc; @@ -403,6 +418,7 @@ int closedir(DIR *dir) { } else { rc = 0; } + STRACE("closedir(%p) → %d% m", dir, rc); return rc; } @@ -410,6 +426,7 @@ int closedir(DIR *dir) { * Returns offset into directory data. */ long telldir(DIR *dir) { + STRACE("telldir(%p) → %d", dir, dir->tell); return dir->tell; } @@ -417,9 +434,16 @@ long telldir(DIR *dir) { * Returns file descriptor associated with DIR object. */ int dirfd(DIR *dir) { - if (dir->iszip) return eopnotsupp(); - if (IsWindows()) return eopnotsupp(); - return dir->fd; + int rc; + if (dir->iszip) { + rc = eopnotsupp(); + } else if (IsWindows()) { + rc = eopnotsupp(); + } else { + rc = dir->fd; + } + STRACE("dirfd(%p) → %d% m", dir, rc); + return rc; } /** @@ -443,4 +467,5 @@ void rewinddir(DIR *dir) { dir->isdone = true; } } + STRACE("rewinddir(%p)", dir); } diff --git a/libc/stdio/dtoa.c b/libc/stdio/dtoa.c index f58202db5..6919d56a6 100644 --- a/libc/stdio/dtoa.c +++ b/libc/stdio/dtoa.c @@ -1,7 +1,7 @@ /*-*- 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 │ +│ Copyright 2022 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,10 +16,379 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/fmts.h" +#include "libc/assert.h" +#include "libc/fmt/fmt.h" +#include "libc/fmt/fmt.internal.h" +#include "libc/fmt/internal.h" +#include "libc/macros.internal.h" +#include "libc/nexgen32e/bsr.h" #include "third_party/gdtoa/gdtoa.h" -char *__fmt_dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, - char **rve) { - return dtoa(d0, mode, ndigits, decpt, sign, rve); +static const char kSpecialFloats[2][2][4] = {{"INF", "inf"}, {"NAN", "nan"}}; + +static void __fmt_free_dtoa(char **mem) { + if (*mem) { + freedtoa(*mem); + *mem = 0; + } +} + +int __fmt_dtoa(int (*out)(const char *, void *, size_t), void *arg, int d, + int flags, int prec, int sign, int width, bool longdouble, + char qchar, unsigned char signbit, const char *alphabet, + va_list va) { + union { + double d; + uint32_t u[2]; + uint64_t q; + } pun; + int c, k, i1, ui, bw, bex, sgn, prec1, decpt; + char *s, *p, *q, *se, *mem, special[8]; + mem = 0; + switch (d) { + case 'F': + case 'f': + if (!(flags & FLAGS_PRECISION)) prec = 6; + if (longdouble) { + pun.d = va_arg(va, long double); + } else { + pun.d = va_arg(va, double); + } + FormatDtoa: + assert(!mem); + s = mem = dtoa(pun.d, 3, prec, &decpt, &sgn, &se); + if (decpt == 9999) { + Format9999: + bzero(special, sizeof(special)); + p = q = special; + if (sgn) { + *q++ = '-'; + } else if (flags & FLAGS_PLUS) { + *q++ = '+'; + } else if (flags & FLAGS_SPACE) { + *q++ = ' '; + } + memcpy(q, kSpecialFloats[*s == 'N'][d >= 'a'], 4); + FormatThatThing: + __fmt_free_dtoa(&mem); + mem = 0; + prec = 0; + flags &= ~(FLAGS_PRECISION | FLAGS_PLUS | FLAGS_SPACE); + goto FormatString; + } + FormatReal: + if (sgn) sign = '-'; + if (prec > 0) width -= prec; + if (width > 0) { + if (sign) --width; + if (decpt <= 0) { + --width; + if (prec > 0) --width; + } else { + if (s == se) decpt = 1; + width -= decpt; + if (prec > 0) --width; + } + } + if (width > 0 && !(flags & FLAGS_LEFT)) { + if (flags & FLAGS_ZEROPAD) { + if (sign) __FMT_PUT(sign); + sign = 0; + do + __FMT_PUT('0'); + while (--width > 0); + } else { + do + __FMT_PUT(' '); + while (--width > 0); + } + } + if (sign) __FMT_PUT(sign); + if (decpt <= 0) { + __FMT_PUT('0'); + if (prec > 0) __FMT_PUT('.'); + while (decpt < 0) { + __FMT_PUT('0'); + prec--; + decpt++; + } + } else { + do { + if ((c = *s)) { + s++; + } else { + c = '0'; + } + __FMT_PUT(c); + } while (--decpt > 0); + if (prec > 0) __FMT_PUT('.'); + } + while (--prec >= 0) { + if ((c = *s)) { + s++; + } else { + c = '0'; + } + __FMT_PUT(c); + } + while (--width >= 0) { + __FMT_PUT(' '); + } + __fmt_free_dtoa(&mem); + break; + + case 'G': + case 'g': + if (!(flags & FLAGS_PRECISION)) prec = 6; + if (longdouble) { + pun.d = va_arg(va, long double); + } else { + pun.d = va_arg(va, double); + } + if (prec < 0) prec = 0; + assert(!mem); + s = mem = dtoa(pun.d, prec ? 2 : 0, prec, &decpt, &sgn, &se); + if (decpt == 9999) goto Format9999; + c = se - s; + prec1 = prec; + if (!prec) { + prec = c; + prec1 = c + (s[1] ? 5 : 4); + } + if (decpt > -4 && decpt <= prec1) { + prec = c - decpt; + if (prec < 0) prec = 0; + goto FormatReal; + } + d -= 2; + if (prec > c) prec = c; + --prec; + goto FormatExpo; + + case 'e': + case 'E': + if (!(flags & FLAGS_PRECISION)) prec = 6; + if (longdouble) { + pun.d = va_arg(va, long double); + } else { + pun.d = va_arg(va, double); + } + if (prec < 0) prec = 0; + if (!dtoa) { + p = "?"; + goto FormatThatThing; + } + assert(!mem); + s = mem = dtoa(pun.d, 2, prec + 1, &decpt, &sgn, &se); + if (decpt == 9999) goto Format9999; + FormatExpo: + if (sgn) sign = '-'; + if ((width -= prec + 5) > 0) { + if (sign) --width; + if (prec) --width; + } + if ((c = --decpt) < 0) c = -c; + while (c >= 100) { + --width; + c /= 10; + } + if (width > 0 && !(flags & FLAGS_LEFT)) { + if (flags & FLAGS_ZEROPAD) { + if (sign) __FMT_PUT(sign); + sign = 0; + do + __FMT_PUT('0'); + while (--width > 0); + } else { + do + __FMT_PUT(' '); + while (--width > 0); + } + } + if (sign) __FMT_PUT(sign); + __FMT_PUT(*s++); + if (prec) __FMT_PUT('.'); + while (--prec >= 0) { + if ((c = *s)) { + s++; + } else { + c = '0'; + } + __FMT_PUT(c); + } + __fmt_free_dtoa(&mem); + __FMT_PUT(d); + if (decpt < 0) { + __FMT_PUT('-'); + decpt = -decpt; + } else { + __FMT_PUT('+'); + } + for (c = 2, k = 10; 10 * k <= decpt; c++) k *= 10; + for (;;) { + i1 = decpt / k; + __FMT_PUT(i1 + '0'); + if (--c <= 0) break; + decpt -= i1 * k; + decpt *= 10; + } + while (--width >= 0) { + __FMT_PUT(' '); + } + break; + + case 'a': + alphabet = "0123456789abcdefpx"; + goto FormatBinary; + case 'A': + alphabet = "0123456789ABCDEFPX"; + FormatBinary: + if (longdouble) { + pun.d = va_arg(va, long double); + } else { + pun.d = va_arg(va, double); + } + if ((pun.u[1] & 0x7ff00000) == 0x7ff00000) { + goto FormatDtoa; + } + if (pun.u[1] & 0x80000000) { + sign = '-'; + pun.u[1] &= 0x7fffffff; + } + if (pun.d) { + c = '1'; + bex = (pun.u[1] >> 20) - 1023; + pun.u[1] &= 0xfffff; + if (bex == -1023) { + ++bex; + if (pun.u[1]) { + do { + --bex; + pun.u[1] <<= 1; + if (pun.u[0] & 0x80000000) pun.u[1] |= 1; + pun.u[0] <<= 1; + } while (pun.u[1] < 0x100000); + } else { + while (!(pun.u[0] & 0x80000000)) { + --bex; + pun.u[0] <<= 1; + } + bex -= 21; + pun.u[1] = pun.u[0] >> 11; + pun.u[0] <<= 21; + } + } + } else { + c = '0'; + bex = 0; + } + if (flags & FLAGS_PRECISION) { + if (prec > 13) prec = 13; + if (pun.d && prec < 13) { + pun.u[1] |= 0x100000; + if (prec < 5) { + ui = 1u << ((5 - prec) * 4 - 1); + if (pun.u[1] & ui) { + if (pun.u[1] & ((ui - 1) | (ui << 1)) || pun.u[0]) { + pun.u[1] += ui; + BexCheck: + if (pun.u[1] & 0x200000) { + ++bex; + pun.u[1] >>= 1; + } + } + } + } else if (prec == 5) { + if (pun.u[0] & 0x80000000) { + BumpIt: + ++pun.u[1]; + goto BexCheck; + } + } else { + i1 = (13 - prec) * 4; + ui = 1u << (i1 - 1); + if (pun.u[0] & ui && pun.u[0] & ((ui - 1) | (ui << 1))) { + pun.u[0] += ui; + if (!(pun.u[0] >> i1)) goto BumpIt; + } + } + } + } else { + if ((ui = pun.u[0])) { + ui = __builtin_ctz(ui); + prec = 6 + ((32 - ROUNDDOWN(ui, 4)) >> 2) - 1; + } else if ((ui = pun.u[1] & 0xfffff)) { + ui = __builtin_ctz(ui); + prec = (20 - ROUNDDOWN(ui, 4)) >> 2; + } else { + prec = 0; + } + } + bw = 1; + if (bex) { + if ((i1 = bex) < 0) i1 = -i1; + while (i1 >= 10) { + ++bw; + i1 /= 10; + } + } + if (pun.u[1] & 0x80000000) { + pun.u[1] &= 0x7fffffff; + if (pun.d || sign) sign = '-'; + } + if ((width -= bw + 5) > 0) { + if (sign) --width; + if (prec) --width; + } + if (pun.q && prec > 0) { + width -= ROUNDUP(bsrl(pun.q) + 1, 4) >> 2; + } + if (width > 0 && !(flags & FLAGS_LEFT)) { + if (flags & FLAGS_ZEROPAD) { + if (sign) { + __FMT_PUT(sign); + sign = 0; + } + do + __FMT_PUT('0'); + while (--width > 0); + } else { + do + __FMT_PUT(' '); + while (--width > 0); + } + } + if (sign) __FMT_PUT(sign); + __FMT_PUT('0'); + __FMT_PUT(alphabet[17]); + __FMT_PUT(c); + if (prec > 0) __FMT_PUT('.'); + while (prec-- > 0) { + __FMT_PUT(alphabet[(pun.q >> 48) & 0xf]); + pun.q <<= 4; + } + __FMT_PUT(alphabet[16]); + if (bex < 0) { + __FMT_PUT('-'); + bex = -bex; + } else { + __FMT_PUT('+'); + } + for (c = 1; 10 * c <= bex;) c *= 10; + for (;;) { + i1 = bex / c; + __FMT_PUT('0' + i1); + if (!--bw) break; + bex -= i1 * c; + bex *= 10; + } + break; + + FormatString: + if (__fmt_stoa(out, arg, p, flags, prec, width, signbit, qchar) == -1) { + return -1; + } + break; + } + return 0; } diff --git a/libc/stdio/fclose_s.c b/libc/stdio/fclose_s.c index 7fa0b4165..aeb86aa01 100644 --- a/libc/stdio/fclose_s.c +++ b/libc/stdio/fclose_s.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/intrin/lockxchg.h" #include "libc/stdio/stdio.h" /** diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c index 1750a18f0..3ea545e91 100644 --- a/libc/stdio/fflush.c +++ b/libc/stdio/fflush.c @@ -56,9 +56,9 @@ textstartup int __fflush_register(FILE *f) { struct StdioFlush *sf; sf = &__fflush; if (!sf->handles.p) { - sf->handles.p = &sf->handles_initmem[0]; + sf->handles.p = sf->handles_initmem; pushmov(&sf->handles.n, ARRAYLEN(sf->handles_initmem)); - __cxa_atexit(fflush, NULL, NULL); + __cxa_atexit(fflush, 0, 0); } for (i = sf->handles.i; i; --i) { if (!sf->handles.p[i - 1]) { @@ -76,7 +76,7 @@ void __fflush_unregister(FILE *f) { sf = pushpop(sf); for (i = sf->handles.i; i; --i) { if (sf->handles.p[i - 1] == f) { - pushmov(&sf->handles.p[i - 1], NULL); + pushmov(&sf->handles.p[i - 1], 0); return; } } diff --git a/libc/stdio/fgets.c b/libc/stdio/fgets.c index 195880e62..7e7d77427 100644 --- a/libc/stdio/fgets.c +++ b/libc/stdio/fgets.c @@ -25,7 +25,7 @@ * * This function is similar to getline() except it'll truncate lines * exceeding size. The line ending marker is included and may be removed - * using chomp(). + * using _chomp(). */ char *fgets(char *s, int size, FILE *f) { int c; diff --git a/libc/stdio/fopen.c b/libc/stdio/fopen.c index 722d26480..84dcde81e 100644 --- a/libc/stdio/fopen.c +++ b/libc/stdio/fopen.c @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" -#include "libc/calls/sysdebug.internal.h" +#include "libc/calls/strace.internal.h" #include "libc/mem/mem.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" @@ -56,21 +56,18 @@ static int openpathname(const char *pathname, int flags, bool *out_noclose) { * @note microsoft unilaterally deprecated this function lool */ FILE *fopen(const char *pathname, const char *mode) { - FILE *f; + FILE *f = 0; bool noclose; int fd, flags; - SYSDEBUG("fopen(%s)", pathname); flags = fopenflags(mode); pathname = fixpathname(pathname, flags); if ((fd = openpathname(pathname, flags, &noclose)) != -1) { if ((f = fdopen(fd, mode)) != NULL) { f->noclose = noclose; - return f; - } else { - if (!noclose) close(fd); - return NULL; + } else if (!noclose) { + close(fd); } - } else { - return NULL; } + STRACE("fopen(%#s, %#s) → %p% m", pathname, mode, f); + return f; } diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index 52fea4d94..4b47c862a 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -53,7 +53,7 @@ size_t fread(void *buf, size_t stride, size_t count, FILE *f) { p = buf; n = stride * count; m = f->end - f->beg; - memcpy(p, f->buf + f->beg, MIN(n, m)); + if (MIN(n, m)) memcpy(p, f->buf + f->beg, MIN(n, m)); if (n < m) { f->beg += n; return count; diff --git a/libc/stdio/getdelim.c b/libc/stdio/getdelim.c index 28001bc47..d936d05d3 100644 --- a/libc/stdio/getdelim.c +++ b/libc/stdio/getdelim.c @@ -36,7 +36,7 @@ * @return number of bytes read >0, including delim, excluding NUL, * or -1 w/ errno on EOF or error; see ferror() and feof() * @note this function can't punt EINTR to caller - * @see getline(), chomp(), gettok_r() + * @see getline(), _chomp(), gettok_r() */ ssize_t getdelim(char **s, size_t *n, int delim, FILE *f) { char *p; diff --git a/libc/stdio/getline.c b/libc/stdio/getline.c index 4a5c2594d..6f0fd43b8 100644 --- a/libc/stdio/getline.c +++ b/libc/stdio/getline.c @@ -23,7 +23,7 @@ * * This function delegates to getdelim(), which provides further * documentation. Concerning lines, please note the \n or \r\n are - * included in results, and can be removed with chomp(). + * included in results, and can be removed with _chomp(). * * @param line is the caller's buffer (in/out) which is extended * automatically. *line may be NULL but only if *n is 0; diff --git a/libc/stdio/kappendf.c b/libc/stdio/kappendf.c new file mode 100644 index 000000000..8977758ca --- /dev/null +++ b/libc/stdio/kappendf.c @@ -0,0 +1,40 @@ +/*-*- 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/stdio/append.internal.h" + +/** + * Appends formatted string to buffer w/ kprintf, e.g. + * + * char *b = 0; + * kappendf(&b, "hello %d\n", 123); + * free(b); + * + * @return bytes appended or -1 if `ENOMEM` + * @see appendz(b).i to get buffer length + * @note O(1) amortized buffer growth + * @see kprintf() + */ +ssize_t kappendf(char **b, const char *fmt, ...) { + int n; + va_list va; + va_start(va, fmt); + n = kvappendf(b, fmt, va); + va_end(va); + return n; +} diff --git a/libc/stdio/kvappendf.c b/libc/stdio/kvappendf.c new file mode 100644 index 000000000..e14ea82ce --- /dev/null +++ b/libc/stdio/kvappendf.c @@ -0,0 +1,68 @@ +/*-*- 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/assert.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/mem/mem.h" +#include "libc/stdio/append.internal.h" + +#define W sizeof(size_t) + +/** + * Appends formatted string to buffer. + * + * This is an alternative to vappendf() that uses the kprintf() + * formatting facility. This has some advantages in terms of + * performance, code size, and memory safety. There's also + * disadvantages, such as lack of floating-point directives. + * + * @see kprintf() + */ +ssize_t kvappendf(char **b, const char *f, va_list v) { + char *p; + int r, s; + size_t n; + va_list w; + struct appendz z; + z = appendz((p = *b)); + va_copy(w, v); + if ((r = kvsnprintf(p + z.i, z.n ? z.n - W - z.i : 0, f, v)) >= 0) { + n = ROUNDUP(z.i + r + 1, 8) + W; + if (n > z.n) { + if (!z.n) z.n = W * 2; + while (n > z.n) z.n += z.n >> 1; + z.n = ROUNDUP(z.n, W); + if ((p = realloc(p, z.n))) { + z.n = malloc_usable_size(p); + assert(!(z.n & (W - 1))); + s = kvsnprintf(p + z.i, z.n - W - z.i, f, w); + assert(s == r); + *b = p; + } else { + va_end(w); + return -1; + } + } + z.i += r; + if (!IsTiny() && W == 8) z.i |= (size_t)APPEND_COOKIE << 48; + *(size_t *)(p + z.n - W) = z.i; + } + va_end(w); + return r; +} diff --git a/libc/stdio/mkostemps.c b/libc/stdio/mkostemps.c index 215977062..2efaa0af2 100644 --- a/libc/stdio/mkostemps.c +++ b/libc/stdio/mkostemps.c @@ -21,6 +21,6 @@ /** * Delegates to mkotempsm() w/ owner-only non-execute access. */ -nodiscard int mkostemps(char *template, int suffixlen, unsigned flags) { +dontdiscard int mkostemps(char *template, int suffixlen, unsigned flags) { return mkostempsm(template, suffixlen, flags, 0600); } diff --git a/libc/stdio/mkostempsm.c b/libc/stdio/mkostempsm.c index f42e46f3c..5d887b4d7 100644 --- a/libc/stdio/mkostempsm.c +++ b/libc/stdio/mkostempsm.c @@ -18,9 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" #include "libc/errno.h" #include "libc/rand/lcg.internal.h" #include "libc/rand/rand.h" +#include "libc/runtime/runtime.h" #include "libc/stdio/temp.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" @@ -34,9 +36,7 @@ int mkostempsmi(char *tpl, int slen, unsigned flags, uint64_t *rando, int mode, int openit(const char *file, int flags, ...)) { size_t len = strlen(tpl); size_t wildlen = strlen(WILDCARD); - if (len < wildlen || slen > len - wildlen) { - return einval(); - } + if (len < wildlen || slen > len - wildlen) return einval(); char *ss = tpl + len - wildlen - slen; assert(memcmp(ss, WILDCARD, wildlen) == 0); flags = (flags & ~(flags & O_ACCMODE)) | O_RDWR | O_CREAT | O_EXCL; @@ -74,8 +74,12 @@ static uint64_t g_mkostemps_reseed; * or -1 w/ errno * @see kTmpPath */ -nodiscard int mkostempsm(char *template, int suffixlen, unsigned flags, - int mode) { +dontdiscard int mkostempsm(char *template, int suffixlen, unsigned flags, + int mode) { + int fd; if (g_mkostemps_reseed++ % RESEED == 0) g_mkostemps_rand = rand64(); - return mkostempsmi(template, suffixlen, flags, &g_mkostemps_rand, mode, open); + fd = mkostempsmi(template, suffixlen, flags, &g_mkostemps_rand, mode, open); + STRACE("mkostempsm([%#s], %'d, %#x, %#o) → %d% m", template, suffixlen, flags, + mode, fd); + return fd; } diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c index d99bba671..216a74c43 100644 --- a/libc/stdio/popen.c +++ b/libc/stdio/popen.c @@ -46,7 +46,7 @@ FILE *popen(const char *cmdline, const char *mode) { if (pipe(pipefds) == -1) return NULL; fcntl(pipefds[dir], F_SETFD, FD_CLOEXEC); if ((f = fdopen(pipefds[dir], mode))) { - switch ((pid = vfork())) { + switch ((pid = fork())) { case 0: dup2(pipefds[!dir], !dir); systemexec(cmdline); diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index 8c64c6d32..5dcffa13a 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -22,9 +22,9 @@ * Formats and writes string to stdout. * * Cosmopolitan supports most of the standard formatting behaviors - * described by `man 3 printf`, in addition to the following: + * described by `man 3 printf`, in addition to the following * - * - `%jd`, `%jx`, etc. are {,u}intmax_t which in Cosmopolitan is 128-bit. + * - `%jjd`, `%jjx`, etc. are {,u}int128_t (cosmopolitan only) * * - `%'d` or `%,d` may be used to insert thousands separators. The prior is * consistent with C; the latter is consistent with Python. @@ -32,10 +32,6 @@ * - `%m` inserts strerror(errno) into the formatted output. This is * consistent with glibc, musl, and uclibc. * - * - `%n` inserts "\n" on non-Windows and "\r\n" on Windows. This is the - * same behavior as Java. It's incompatible with glibc's behavior, - * since that's problematic according to Android's security team. - * * - `%hs` converts UTF-16/UCS-2 → UTF-8, which can be helpful on Windows. * Formatting (e.g. %-10hs) will use monospace display width rather * than string length or codepoint count. diff --git a/libc/stdio/spawn.c b/libc/stdio/spawn.c index 5dc3980b3..de6cfa921 100644 --- a/libc/stdio/spawn.c +++ b/libc/stdio/spawn.c @@ -45,7 +45,7 @@ int posix_spawn(int *pid, const char *path, if (!(*pid = vfork())) { if (attrp) { if (attrp->posix_attr_flags & POSIX_SPAWN_SETPGROUP) { - if (setpgid(0, attrp->posix_attr_pgroup)) _exit(127); + if (setpgid(0, attrp->posix_attr_pgroup)) _Exit(127); } if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGMASK) { sigprocmask(SIG_SETMASK, &attrp->posix_attr_sigmask, NULL); @@ -60,7 +60,7 @@ int posix_spawn(int *pid, const char *path, sigfillset(&allsigs); for (s = 0; sigismember(&allsigs, s); s++) { if (sigismember(&attrp->posix_attr_sigdefault, s)) { - if (sigaction(s, &dfl, NULL) == -1) _exit(127); + if (sigaction(s, &dfl, NULL) == -1) _Exit(127); } } } @@ -68,28 +68,28 @@ int posix_spawn(int *pid, const char *path, if (file_actions) { for (p = *file_actions; *p; p = strchr(p, ')') + 1) { if (!strncmp(p, "close(", 6)) { - if (sscanf(p + 6, "%d)", &fd) != 1) _exit(127); - if (close(fd) == -1) _exit(127); + if (sscanf(p + 6, "%d)", &fd) != 1) _Exit(127); + if (close(fd) == -1) _Exit(127); } else if (!strncmp(p, "dup2(", 5)) { - if (sscanf(p + 5, "%d,%d)", &fd, &newfd) != 2) _exit(127); - if (dup2(fd, newfd) == -1) _exit(127); + if (sscanf(p + 5, "%d,%d)", &fd, &newfd) != 2) _Exit(127); + if (dup2(fd, newfd) == -1) _Exit(127); } else if (!strncmp(p, "open(", 5)) { - if (sscanf(p + 5, "%d,", &fd) != 1) _exit(127); + if (sscanf(p + 5, "%d,", &fd) != 1) _Exit(127); p = strchr(p, ',') + 1; q = strchr(p, '*'); - if (!q || q - p + 1 > PATH_MAX) _exit(127); + if (!q || q - p >= PATH_MAX) _Exit(127); strncpy(opath, p, q - p); opath[q - p] = '\0'; - if (sscanf(q + 1, "%o,%o)", &oflag, &mode) != 2) _exit(127); - if (close(fd) == -1 && errno != EBADF) _exit(127); + if (sscanf(q + 1, "%o,%o)", &oflag, &mode) != 2) _Exit(127); + if (close(fd) == -1 && errno != EBADF) _Exit(127); tempfd = open(opath, oflag, mode); - if (tempfd == -1) _exit(127); + if (tempfd == -1) _Exit(127); if (tempfd != fd) { - if (dup2(tempfd, fd) == -1) _exit(127); - if (close(tempfd) == -1) _exit(127); + if (dup2(tempfd, fd) == -1) _Exit(127); + if (close(tempfd) == -1) _Exit(127); } } else { - _exit(127); + _Exit(127); } } } @@ -97,17 +97,17 @@ int posix_spawn(int *pid, const char *path, if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDULER) { if (sched_setscheduler(0, attrp->posix_attr_schedpolicy, &attrp->posix_attr_schedparam) == -1) { - _exit(127); + _Exit(127); } } if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDPARAM) { if (sched_setparam(0, &attrp->posix_attr_schedparam) == -1) { - _exit(127); + _Exit(127); } } } execve(path, argv, envp); - _exit(127); + _Exit(127); } else { if (*pid == -1) return errno; return 0; diff --git a/libc/stdio/spawnp.c b/libc/stdio/spawnp.c index 2191b3c99..67b9d0d67 100644 --- a/libc/stdio/spawnp.c +++ b/libc/stdio/spawnp.c @@ -32,6 +32,6 @@ int posix_spawnp(int *pid, const char *path, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) { char pathbuf[PATH_MAX]; - if (!(path = commandv(path, pathbuf))) return errno; + if (!(path = commandv(path, pathbuf, sizeof(pathbuf)))) return errno; return posix_spawn(pid, path, file_actions, attrp, argv, envp); } diff --git a/libc/stdio/stderr-init.S b/libc/stdio/stderr-init.S index 30acd0516..8b0994cbd 100644 --- a/libc/stdio/stderr-init.S +++ b/libc/stdio/stderr-init.S @@ -21,7 +21,6 @@ #include "libc/calls/calls.h" #include "libc/sysv/consts/fileno.h" #include "libc/macros.internal.h" -.source __FILE__ .init.start 400,_init_stderr ezlea __stderr,ax diff --git a/libc/stdio/stdin-init.S b/libc/stdio/stdin-init.S index 460953796..c9274c982 100644 --- a/libc/stdio/stdin-init.S +++ b/libc/stdio/stdin-init.S @@ -21,7 +21,6 @@ #include "libc/calls/calls.h" #include "libc/sysv/consts/fileno.h" #include "libc/macros.internal.h" -.source __FILE__ .init.start 400,_init_stdin ezlea __stdin,ax diff --git a/libc/stdio/stdio.h b/libc/stdio/stdio.h index 9c11a73be..c869a3774 100644 --- a/libc/stdio/stdio.h +++ b/libc/stdio/stdio.h @@ -57,9 +57,9 @@ int putchar(int); int puts(const char *); ssize_t getline(char **, size_t *, FILE *) paramsnonnull(); ssize_t getdelim(char **, size_t *, int, FILE *) paramsnonnull(); -FILE *fopen(const char *, const char *) paramsnonnull() nodiscard; -FILE *fdopen(int, const char *) paramsnonnull() nodiscard; -FILE *fmemopen(void *, size_t, const char *) paramsnonnull((3)) nodiscard; +FILE *fopen(const char *, const char *) paramsnonnull() dontdiscard; +FILE *fdopen(int, const char *) paramsnonnull() dontdiscard; +FILE *fmemopen(void *, size_t, const char *) paramsnonnull((3)) dontdiscard; FILE *freopen(const char *, const char *, FILE *) paramsnonnull((2, 3)); size_t fread(void *, size_t, size_t, FILE *) paramsnonnull((4)); size_t fwrite(const void *, size_t, size_t, FILE *) paramsnonnull((4)); @@ -90,16 +90,31 @@ int systemexec(const char *); ╚────────────────────────────────────────────────────────────────────────────│*/ int printf(const char *, ...) printfesque(1) - paramsnonnull((1)) nothrow nocallback; -int vprintf(const char *, va_list) paramsnonnull() nothrow nocallback; + paramsnonnull((1)) dontthrow nocallback; +int vprintf(const char *, va_list) paramsnonnull() dontthrow nocallback; int fprintf(FILE *, const char *, ...) printfesque(2) - paramsnonnull((1, 2)) nothrow nocallback; -int vfprintf(FILE *, const char *, va_list) paramsnonnull() nothrow nocallback; + paramsnonnull((1, 2)) dontthrow nocallback; +int vfprintf(FILE *, const char *, va_list) + paramsnonnull() dontthrow nocallback; int scanf(const char *, ...) scanfesque(1); int vscanf(const char *, va_list); int fscanf(FILE *, const char *, ...) scanfesque(2); int vfscanf(FILE *, const char *, va_list); +int fwprintf(FILE *, const wchar_t *, ...); +int fwscanf(FILE *, const wchar_t *, ...); +int swprintf(wchar_t *, size_t, const wchar_t *, ...); +int swscanf(const wchar_t *, const wchar_t *, ...); +int vfwprintf(FILE *, const wchar_t *, va_list); +int vfwscanf(FILE *, const wchar_t *, va_list); +int vswprintf(wchar_t *, size_t, const wchar_t *, va_list); +int vswscanf(const wchar_t *, const wchar_t *, va_list); +int vwprintf(const wchar_t *, va_list); +int vwscanf(const wchar_t *, va_list); +int wprintf(const wchar_t *, ...); +int wscanf(const wchar_t *, ...); +int fwide(FILE *, int); + /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § standard i/o » optimizations ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ diff --git a/libc/stdio/stdout-init.S b/libc/stdio/stdout-init.S index da9efdbcb..7c1f3a537 100644 --- a/libc/stdio/stdout-init.S +++ b/libc/stdio/stdout-init.S @@ -21,7 +21,6 @@ #include "libc/calls/calls.h" #include "libc/sysv/consts/fileno.h" #include "libc/macros.internal.h" -.source __FILE__ .init.start 400,_init_stdout ezlea __stdout,ax diff --git a/libc/stdio/system.c b/libc/stdio/system.c index dd1fee19b..ee88289a5 100644 --- a/libc/stdio/system.c +++ b/libc/stdio/system.c @@ -22,6 +22,7 @@ #include "libc/calls/struct/sigaction.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/log/log.h" #include "libc/paths.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" diff --git a/libc/stdio/systemexec.c b/libc/stdio/systemexec.c index 70134991a..5bda2ef06 100644 --- a/libc/stdio/systemexec.c +++ b/libc/stdio/systemexec.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/dce.h" +#include "libc/macros.internal.h" #include "libc/paths.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" @@ -29,14 +30,16 @@ */ int systemexec(const char *cmdline) { size_t n, m; - char *a, *b, *argv[4], comspec[PATH_MAX + 1]; + char *a, *b, *argv[4], comspec[PATH_MAX]; if (!IsWindows()) { argv[0] = _PATH_BSHELL; argv[1] = "-c"; } else { b = "cmd.exe"; a = kNtSystemDirectory; - if ((n = strlen(a)) + (m = strlen(b)) > PATH_MAX) return enametoolong(); + if ((n = strlen(a)) + (m = strlen(b)) >= ARRAYLEN(comspec)) { + return enametoolong(); + } memcpy(mempcpy(comspec, a, n), b, m + 1); argv[0] = comspec; argv[1] = "/C"; diff --git a/libc/stdio/temp.h b/libc/stdio/temp.h index 9b6113f40..5a1e7544e 100644 --- a/libc/stdio/temp.h +++ b/libc/stdio/temp.h @@ -4,16 +4,17 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -nodiscard FILE *tmpfile(void); -nodiscard int mkstemp(char *); -nodiscard int mkostemp(char *, unsigned); -nodiscard int mkstemps(char *, int); -nodiscard int mkostemps(char *, int, unsigned); -nodiscard int mkostempsm(char *, int, unsigned, int); +dontdiscard FILE *tmpfile(void); +dontdiscard int mkstemp(char *); +dontdiscard int mkostemp(char *, unsigned); +dontdiscard int mkstemps(char *, int); +dontdiscard int mkostemps(char *, int, unsigned); +dontdiscard int mkostempsm(char *, int, unsigned, int); compatfn char *mktemp(char *); +char *tmpnam(char *); int mkostempsmi(char *, int, unsigned, uint64_t *, int, - int (*)(const char *, int, ...)) hidden nodiscard; + int (*)(const char *, int, ...)) hidden dontdiscard; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c index 1bee40c56..8ec1a985a 100644 --- a/libc/stdio/tmpfile.c +++ b/libc/stdio/tmpfile.c @@ -35,7 +35,8 @@ FILE *tmpfile(void) { char *tmp, *sep, tpl[PATH_MAX]; tmp = firstnonnull(getenv("TMPDIR"), kTmpPath); sep = !isempty(tmp) && !endswith(tmp, "/") ? "/" : ""; - if ((snprintf)(tpl, PATH_MAX, "%s%stmp.XXXXXX", tmp, sep) < PATH_MAX) { + if ((snprintf)(tpl, PATH_MAX, "%s%stmp.%s.XXXXXX", tmp, sep, + program_invocation_short_name) <= PATH_MAX) { if ((fd = mkostemps(tpl, 0, 0)) != -1) { return fdopen(fd, "w+"); } diff --git a/libc/stdio/unlocked/clearerr_unlocked.S b/libc/stdio/unlocked/clearerr_unlocked.S index a1da35482..49710de62 100644 --- a/libc/stdio/unlocked/clearerr_unlocked.S +++ b/libc/stdio/unlocked/clearerr_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ clearerr_unlocked: push %rbp diff --git a/libc/stdio/unlocked/feof_unlocked.S b/libc/stdio/unlocked/feof_unlocked.S index a3a80c1a2..6b89b623a 100644 --- a/libc/stdio/unlocked/feof_unlocked.S +++ b/libc/stdio/unlocked/feof_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ feof_unlocked: push %rbp diff --git a/libc/stdio/unlocked/ferror_unlocked.S b/libc/stdio/unlocked/ferror_unlocked.S index e6598fbe6..8d0df702a 100644 --- a/libc/stdio/unlocked/ferror_unlocked.S +++ b/libc/stdio/unlocked/ferror_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ ferror_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fflush_unlocked.S b/libc/stdio/unlocked/fflush_unlocked.S index 280d08028..982aeb84d 100644 --- a/libc/stdio/unlocked/fflush_unlocked.S +++ b/libc/stdio/unlocked/fflush_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fflush_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fgetc_unlocked.S b/libc/stdio/unlocked/fgetc_unlocked.S index f4c77bc31..0d6f97f34 100644 --- a/libc/stdio/unlocked/fgetc_unlocked.S +++ b/libc/stdio/unlocked/fgetc_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fgetc_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fgets_unlocked.S b/libc/stdio/unlocked/fgets_unlocked.S index 7521d8c4f..424362a2a 100644 --- a/libc/stdio/unlocked/fgets_unlocked.S +++ b/libc/stdio/unlocked/fgets_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fgets_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fgetwc_unlocked.S b/libc/stdio/unlocked/fgetwc_unlocked.S index 52bbb7a9a..7a658dc3a 100644 --- a/libc/stdio/unlocked/fgetwc_unlocked.S +++ b/libc/stdio/unlocked/fgetwc_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fgetwc_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fgetws_unlocked.S b/libc/stdio/unlocked/fgetws_unlocked.S index 02b1dd7e5..6c8a377e1 100644 --- a/libc/stdio/unlocked/fgetws_unlocked.S +++ b/libc/stdio/unlocked/fgetws_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fgetws_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fileno_unlocked.S b/libc/stdio/unlocked/fileno_unlocked.S index f90be6127..2f9d0b775 100644 --- a/libc/stdio/unlocked/fileno_unlocked.S +++ b/libc/stdio/unlocked/fileno_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fileno_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fputc_unlocked.S b/libc/stdio/unlocked/fputc_unlocked.S index 7c357889f..152b949e8 100644 --- a/libc/stdio/unlocked/fputc_unlocked.S +++ b/libc/stdio/unlocked/fputc_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fputc_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fputs_unlocked.S b/libc/stdio/unlocked/fputs_unlocked.S index 2adf21027..9c841a471 100644 --- a/libc/stdio/unlocked/fputs_unlocked.S +++ b/libc/stdio/unlocked/fputs_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fputs_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fputwc_unlocked.S b/libc/stdio/unlocked/fputwc_unlocked.S index 1b505fab9..58d33dbc5 100644 --- a/libc/stdio/unlocked/fputwc_unlocked.S +++ b/libc/stdio/unlocked/fputwc_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fputwc_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fputws_unlocked.S b/libc/stdio/unlocked/fputws_unlocked.S index 611be6abd..238489ed5 100644 --- a/libc/stdio/unlocked/fputws_unlocked.S +++ b/libc/stdio/unlocked/fputws_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fputws_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fread_unlocked.S b/libc/stdio/unlocked/fread_unlocked.S index 3cbb06159..84c2407f2 100644 --- a/libc/stdio/unlocked/fread_unlocked.S +++ b/libc/stdio/unlocked/fread_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fread_unlocked: push %rbp diff --git a/libc/stdio/unlocked/fwrite_unlocked.S b/libc/stdio/unlocked/fwrite_unlocked.S index d296e2837..ca5fd20f4 100644 --- a/libc/stdio/unlocked/fwrite_unlocked.S +++ b/libc/stdio/unlocked/fwrite_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fwrite_unlocked: push %rbp diff --git a/libc/stdio/unlocked/getc_unlocked.S b/libc/stdio/unlocked/getc_unlocked.S index 1d6e9c75e..488d48a93 100644 --- a/libc/stdio/unlocked/getc_unlocked.S +++ b/libc/stdio/unlocked/getc_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ getc_unlocked: push %rbp diff --git a/libc/stdio/unlocked/getchar_unlocked.S b/libc/stdio/unlocked/getchar_unlocked.S index ebb6b764a..ff7285685 100644 --- a/libc/stdio/unlocked/getchar_unlocked.S +++ b/libc/stdio/unlocked/getchar_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ getchar_unlocked: push %rbp diff --git a/libc/stdio/unlocked/getwc_unlocked.S b/libc/stdio/unlocked/getwc_unlocked.S index a02438707..1c06b74a3 100644 --- a/libc/stdio/unlocked/getwc_unlocked.S +++ b/libc/stdio/unlocked/getwc_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ getwc_unlocked: push %rbp diff --git a/libc/stdio/unlocked/getwchar_unlocked.S b/libc/stdio/unlocked/getwchar_unlocked.S index bb6710a50..07acd3314 100644 --- a/libc/stdio/unlocked/getwchar_unlocked.S +++ b/libc/stdio/unlocked/getwchar_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ getwchar_unlocked: push %rbp diff --git a/libc/stdio/unlocked/putc_unlocked.S b/libc/stdio/unlocked/putc_unlocked.S index 842d740e7..7784877a7 100644 --- a/libc/stdio/unlocked/putc_unlocked.S +++ b/libc/stdio/unlocked/putc_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ putc_unlocked: push %rbp diff --git a/libc/stdio/unlocked/putchar_unlocked.S b/libc/stdio/unlocked/putchar_unlocked.S index df0b807e9..e7ffcb38e 100644 --- a/libc/stdio/unlocked/putchar_unlocked.S +++ b/libc/stdio/unlocked/putchar_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ putchar_unlocked: push %rbp diff --git a/libc/stdio/unlocked/putwc_unlocked.S b/libc/stdio/unlocked/putwc_unlocked.S index 3890a2d6b..d12280e00 100644 --- a/libc/stdio/unlocked/putwc_unlocked.S +++ b/libc/stdio/unlocked/putwc_unlocked.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ putwc_unlocked: push %rbp diff --git a/libc/stdio/unlocked/putwchar_unlocked.S b/libc/stdio/unlocked/putwchar_unlocked.S index 5e7f38eb5..0fd34dee1 100644 --- a/libc/stdio/unlocked/putwchar_unlocked.S +++ b/libc/stdio/unlocked/putwchar_unlocked.S @@ -18,7 +18,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ putwchar_unlocked: push %rbp diff --git a/libc/str/blake2.c b/libc/str/blake2.c index 5b25ab50e..f00443dea 100644 --- a/libc/str/blake2.c +++ b/libc/str/blake2.c @@ -118,7 +118,7 @@ int BLAKE2B256_Update(struct Blake2b *b2b, const void *in_data, size_t len) { if (todo > len) { todo = len; } - memcpy(&b2b->block.bytes[b2b->block_used], data, todo); + if (todo) memcpy(&b2b->block.bytes[b2b->block_used], data, todo); b2b->block_used += todo; data += todo; len -= todo; @@ -137,7 +137,7 @@ int BLAKE2B256_Update(struct Blake2b *b2b, const void *in_data, size_t len) { data += BLAKE2B_CBLOCK; len -= BLAKE2B_CBLOCK; } - memcpy(b2b->block.bytes, data, len); + if (len) memcpy(b2b->block.bytes, data, len); b2b->block_used = len; return 0; } diff --git a/libc/str/chomp.c b/libc/str/chomp.c index 41c97b371..d1abfd5a2 100644 --- a/libc/str/chomp.c +++ b/libc/str/chomp.c @@ -24,7 +24,7 @@ * @param line is NULL-propagating * @see getline */ -char *chomp(char *line) { +char *_chomp(char *line) { size_t i; if (line) { for (i = strlen(line); i--;) { diff --git a/libc/str/chomp16.c b/libc/str/chomp16.c index cdd558acd..5b777af0c 100644 --- a/libc/str/chomp16.c +++ b/libc/str/chomp16.c @@ -24,7 +24,16 @@ * @param line is NULL-propagating * @see getline */ -char16_t *chomp16(char16_t *line) { - if (line) line[strcspn16(line, u"\r\n")] = '\0'; +char16_t *_chomp16(char16_t *line) { + size_t i; + if (line) { + for (i = strlen16(line); i--;) { + if (line[i] == '\r' || line[i] == '\n') { + line[i] = '\0'; + } else { + break; + } + } + } return line; } diff --git a/libc/str/classifypath.c b/libc/str/classifypath.c new file mode 100644 index 000000000..9f26cc410 --- /dev/null +++ b/libc/str/classifypath.c @@ -0,0 +1,154 @@ +/*-*- 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 2022 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/dce.h" +#include "libc/str/path.h" +#include "libc/str/str.h" + +/** + * Classifies file path name. + * + * For the purposes of this function, we always consider backslash + * interchangeable with forward slash, even though the underlying + * operating system might not. Therefore, for the sake of clarity, + * remaining documentation will only use the forward slash. + * + * This function behaves the same on all platforms. For instance, this + * function will categorize `C:/FOO.BAR` as a DOS path, even if you're + * running on UNIX rather than DOS. + * + * If you wish to check if a pathname is absolute, in a manner that's + * inclusive of DOS drive paths, DOS rooted paths, in addition to the + * New Technology UNC paths, then you may do the following: + * + * if (_classifypath(str) & _PATH_ABS) { ... } + * + * To check if path is a relative path: + * + * if (~_classifypath(str) & _PATH_ABS) { ... } + * + * Please note the above check includes rooted paths such as `\foo` + * which is considered absolute by MSDN and we consider it absolute + * although, it's technically relative to the current drive letter. + * + * Please note that `/foo/bar` is an absolute path on Windows, even + * though it's actually a rooted path that's considered relative to + * current drive by WIN32. + * + * @return integer value that's one of following: + * - `0` if non-weird relative path e.g. `c` + * - `_PATH_ABS` if absolute (or rooted dos) path e.g. `/⋯` + * - `_PATH_DOS` if `c:`, `d:foo` i.e. drive-relative path + * - `_PATH_ABS|_PATH_DOS` if proper dos path e.g. `c:/foo` + * - `_PATH_DOS|_PATH_DEV` if dos device path e.g. `nul`, `conin$` + * - `_PATH_ABS|_PATH_WIN` if `//c`, `//?c`, etc. + * - `_PATH_ABS|_PATH_WIN|_PATH_DEV` if `//./⋯`, `//?/⋯` + * - `_PATH_ABS|_PATH_WIN|_PATH_DEV|_PATH_ROOT` if `//.` or `//?` + * - `_PATH_ABS|_PATH_NT` e.g. `\??\\⋯` (undoc. strict backslash) + * @see "The Definitive Guide on Win32 to NT Path Conversion", James + * Forshaw, Google Project Zero Blog, 2016-02-29 + * @see "Naming Files, Paths, and Namespaces", MSDN 01/04/2021 + */ +int _classifypath(const char *s) { + if (s) { + switch (s[0]) { + case 0: // "" + return 0; + default: + if (!SupportsWindows()) { + return 0; + } + if (((((s[0] == 'a' || s[0] == 'A') && // aux + (s[1] == 'u' || s[1] == 'U') && // + (s[2] == 'x' || s[2] == 'X')) || // + ((s[0] == 'p' || s[0] == 'P') && // prn + (s[1] == 'r' || s[1] == 'R') && // + (s[2] == 'n' || s[2] == 'N')) || // + ((s[0] == 'n' || s[0] == 'N') && // nul + (s[1] == 'u' || s[1] == 'U') && // + (s[2] == 'l' || s[2] == 'L')) || // + ((s[0] == 'c' || s[0] == 'C') && // con + (s[1] == 'o' || s[1] == 'O') && // + (s[2] == 'n' || s[2] == 'N'))) && // + !s[3]) || + ((((s[0] == 'l' || s[0] == 'L') && // lpt + (s[1] == 'p' || s[1] == 'P') && // + (s[2] == 't' || s[2] == 'T')) || // + ((s[0] == 'c' || s[0] == 'C') && // com + (s[1] == 'o' || s[1] == 'O') && // + (s[2] == 'm' || s[2] == 'M'))) && // + ('1' <= s[3] && s[3] <= '9') && // + !s[4])) { + return _PATH_DOS | _PATH_DEV; + } + switch (s[1]) { + case ':': + switch (s[2]) { + case 0: // c: + default: // c:wut⋯ + return _PATH_DOS; + case '/': // c:/⋯ + case '\\': // c:\⋯ + return _PATH_ABS | _PATH_DOS; + } + default: + return 0; + } + case '\\': + if (SupportsWindows()) { + if (s[1] == '?' && s[2] == '?') { + if (!s[3]) { + return _PATH_ABS | _PATH_NT | _PATH_ROOT; // \??\⋯ + } else if (s[3] == '\\') { + return _PATH_ABS | _PATH_NT; // \??\⋯ + } + } + } + // fallthrough + case '/': + if (!SupportsWindows()) { + return _PATH_ABS; + } + switch (s[1]) { + case 0: // / + default: // /⋯ + return _PATH_ABS; + case '/': + case '\\': + switch (s[2]) { + case 0: // // + default: // //⋯ + return _PATH_ABS | _PATH_WIN; + case '.': + case '?': + switch (s[3]) { + case 0: // //? or //. + return _PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT; + default: // //?⋯ or //.⋯ + return _PATH_ABS | _PATH_WIN; + case '/': + case '\\': // //?/⋯ or //./⋯ + return _PATH_ABS | _PATH_WIN | _PATH_DEV; + } + } + } + } + } else { + return 0; + } +} diff --git a/libc/str/crc32.S b/libc/str/crc32.S index ac17b1647..35849c004 100644 --- a/libc/str/crc32.S +++ b/libc/str/crc32.S @@ -26,4 +26,3 @@ crc32: mov %edx,%edx jmp crc32_z .endfn crc32,globl - .source __FILE__ diff --git a/libc/str/crc32c.c b/libc/str/crc32c.c index b41b9340e..122b37942 100644 --- a/libc/str/crc32c.c +++ b/libc/str/crc32c.c @@ -35,6 +35,9 @@ uint32_t crc32c(uint32_t init, const void *data, size_t size) { pe = p + size; h = init ^ 0xffffffff; if (X86_HAVE(SSE4_2)) { + while (p < pe && ((intptr_t)p & 7)) { + h = h >> 8 ^ kCrc32cTab[(h & 0xff) ^ *p++]; + } for (; p + 8 <= pe; p += 8) { asm("crc32q\t%1,%0" : "+r"(h) : "rm"(*(const uint64_t *)p)); } diff --git a/libc/str/escapedos.c b/libc/str/escapedos.c index f4945a65f..b815ed75a 100644 --- a/libc/str/escapedos.c +++ b/libc/str/escapedos.c @@ -43,8 +43,8 @@ static textwindows bool shouldquotedos(const char16_t c) { * Escapes command so DOS can run it. * @see Iain Patterson's NSSM for original code in public domain */ -textwindows bool escapedos(char16_t *buffer, unsigned buflen, - const char16_t *unquoted, unsigned len) { +textwindows bool _escapedos(char16_t *buffer, unsigned buflen, + const char16_t *unquoted, unsigned len) { unsigned i, j, n; if (len > buflen - 1) return false; bool escape = false; diff --git a/libc/str/isabspath.c b/libc/str/isabspath.c index 3cba9103e..4e40be341 100644 --- a/libc/str/isabspath.c +++ b/libc/str/isabspath.c @@ -1,7 +1,7 @@ /*-*- 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 │ +│ 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 │ @@ -16,33 +16,21 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" +#include "libc/str/path.h" #include "libc/str/str.h" /** - * Returns true if pathname is absolute, e.g. + * Returns true if pathname is considered absolute. * * - `/home/jart/foo.txt` is absolute - * - `C:/Users/jart/foo.txt` is absolute on NT - * - `C:\Users\jart\foo.txt` is absolute on NT - * - `\??\C:\Users\jart\foo.txt` is absolute on NT - * - `\\.\C:\Users\jart\foo.txt` is absolute on NT - * - `/Users/jart/foo.txt` we consider it absolute enough on NT - * - `\Users\jart\foo.txt` we consider it absolute enough on NT + * - `C:/Users/jart/foo.txt` is absolute on Windows + * - `C:\Users\jart\foo.txt` is absolute on Windows + * - `\??\C:\Users\jart\foo.txt` is absolute on Windows + * - `\\.\C:\Users\jart\foo.txt` is absolute on Windows + * - `/Users/jart/foo.txt` is effectively absolute on Windows + * - `\Users\jart\foo.txt` is effectively absolute on Windows * - * Please note that the recommended approach to using Cosmopolitan is to - * not use absolute paths at all. If you do use absolute paths then it's - * a good idea on Windows to stay within the C: drive. This is because - * Cosmopolitan Libc doesn't create a virtual filesystem layer and - * instead just replaces `\` characters with `/`. */ -bool _isabspath(const char *p) { - if (*p == '/') { - return true; - } - if (IsWindows() && - (*p == '/' || *p == '\\' || (isalpha(p[0]) && p[1] == ':'))) { - return true; - } - return false; +bool _isabspath(const char *path) { + return _classifypath(path) & _PATH_ABS; } diff --git a/libc/str/isdirsep.c b/libc/str/isdirsep.c new file mode 100644 index 000000000..548d8924e --- /dev/null +++ b/libc/str/isdirsep.c @@ -0,0 +1,27 @@ +/*-*- 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 2022 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/dce.h" +#include "libc/str/str.h" + +/** + * Returns true if character is directory separator slash. + */ +bool _isdirsep(int c) { + return c == '/' || c == '\\'; +} diff --git a/libc/str/istext.c b/libc/str/istext.c index 0a75f6021..460626572 100644 --- a/libc/str/istext.c +++ b/libc/str/istext.c @@ -21,7 +21,7 @@ /** * Returns true if buffer is most likely plaintext. */ -bool IsText(const void *data, size_t size) { +bool _istext(const void *data, size_t size) { const unsigned char *p, *pe; for (p = data, pe = p + size; p < pe; ++p) { if (*p <= 3) { diff --git a/libc/str/isutf8.c b/libc/str/isutf8.c index 983ce7282..9155c5e4a 100644 --- a/libc/str/isutf8.c +++ b/libc/str/isutf8.c @@ -23,7 +23,7 @@ * * This function will return false if a pure ascii string is passed. */ -bool IsUtf8(const void *data, size_t size) { +bool _isutf8(const void *data, size_t size) { const unsigned char *p, *pe; for (p = data, pe = p + size; p + 2 <= pe; ++p) { if (p[0] >= 0300) { diff --git a/libc/str/ksignalnames.S b/libc/str/ksignalnames.S new file mode 100644 index 000000000..0e58a1b70 --- /dev/null +++ b/libc/str/ksignalnames.S @@ -0,0 +1,71 @@ +/*-*- 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│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2022 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/fmt/magnumstrs.internal.h" +#include "libc/macros.internal.h" + + .macro .e e s + .long \e - kSignalNames + .long 1f - kSignalNames + .rodata.str1.1 +1: .string "\s" + .previous + .endm + + .section .rodata + .align 4 + .underrun +kSignalNames: + .e SIGHUP,"HUP" + .e SIGINT,"INT" + .e SIGQUIT,"QUIT" + .e SIGILL,"ILL" + .e SIGTRAP,"TRAP" + .e SIGABRT,"ABRT" + .e SIGBUS,"BUS" + .e SIGFPE,"FPE" + .e SIGKILL,"KILL" + .e SIGUSR1,"USR1" + .e SIGSEGV,"SEGV" + .e SIGUSR2,"USR2" + .e SIGPIPE,"PIPE" + .e SIGALRM,"ALRM" + .e SIGTERM,"TERM" + .e SIGSTKFLT,"STKFLT" + .e SIGCHLD,"CHLD" + .e SIGCONT,"CONT" + .e SIGSTOP,"STOP" + .e SIGTSTP,"TSTP" + .e SIGTTIN,"TTIN" + .e SIGTTOU,"TTOU" + .e SIGURG,"URG" + .e SIGXCPU,"XCPU" + .e SIGXFSZ,"XFSZ" + .e SIGVTALRM,"VTALRM" + .e SIGPROF,"PROF" + .e SIGWINCH,"WINCH" + .e SIGIO,"IO" + .e SIGSYS,"SYS" + .e SIGINFO,"INFO" + .e SIGRTMAX,"RTMAX" + .e SIGRTMIN,"RTMIN" + .e SIGEMT,"EMT" + .e SIGPWR,"PWR" + .long MAGNUM_TERMINATOR + .endobj kSignalNames,globl,hidden + .overrun diff --git a/libc/str/longsort.c b/libc/str/longsort.c index 0155302f4..fcbb9e366 100644 --- a/libc/str/longsort.c +++ b/libc/str/longsort.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/macros.internal.h" @@ -61,6 +62,10 @@ static optimizesize noasan void longsort_pure(long *x, size_t n, size_t t) { /** * Sorting algorithm for longs that doesn't take long. + * + * "What disorder is this? Give me my long sort!" + * -Lord Capulet + * */ void longsort(long *x, size_t n) { size_t t, m; @@ -70,10 +75,13 @@ void longsort(long *x, size_t n) { } if (n > 1) { t = 1ul << bsrl(n - 1); - if (X86_HAVE(AVX2)) { + if (!IsTiny() && X86_HAVE(AVX2)) { longsort_avx2(x, n, t); } else { longsort_pure(x, n, t); } } + if (n > 1000) { + STRACE("longsort(%p, %'zu)", x, n); + } } diff --git a/libc/str/path.h b/libc/str/path.h new file mode 100644 index 000000000..10b1fca62 --- /dev/null +++ b/libc/str/path.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_STR_PATH_H_ +#define COSMOPOLITAN_LIBC_STR_PATH_H_ + +#define _PATH_ABS 1 +#define _PATH_DEV 2 +#define _PATH_ROOT 4 +#define _PATH_DOS 8 +#define _PATH_WIN 16 +#define _PATH_NT 32 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int _classifypath(const char *) libcesque nosideeffect; +bool _isabspath(const char *) libcesque strlenesque; +bool _isdirsep(int) libcesque pureconst; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_PATH_H_ */ diff --git a/libc/str/qsort.c b/libc/str/qsort.c index d280a394b..d0f112e07 100644 --- a/libc/str/qsort.c +++ b/libc/str/qsort.c @@ -53,7 +53,7 @@ static inline int pntz(size_t p[2]) { return 0; } -/* smoothsort_shl() and smoothsort_shr() need n > 0 */ +// smoothsort_shl() and smoothsort_shr() need n > 0 static inline void smoothsort_shl(size_t p[2], int n) { if (n >= CHAR_BIT * sizeof(size_t)) { n -= CHAR_BIT * sizeof(size_t); @@ -163,7 +163,7 @@ static void smoothsort(struct SmoothSort *s, void *base, size_t nel, if (!size) return; head = base; high = head + size - width; - /* Precompute Leonardo numbers, scaled by element width */ + // precompute Leonardo numbers, scaled by element width for (s->lp[0] = s->lp[1] = width, i = 2; (s->lp[i] = s->lp[i - 2] + s->lp[i - 1] + width) < size; i++) { } diff --git a/libc/str/rindex.S b/libc/str/rindex.S index 3fb36e2d3..c90367706 100644 --- a/libc/str/rindex.S +++ b/libc/str/rindex.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns pointer to last instance of character the BSD way. // diff --git a/libc/str/startswithi.c b/libc/str/startswithi.c index 737280807..52a14c949 100644 --- a/libc/str/startswithi.c +++ b/libc/str/startswithi.c @@ -22,6 +22,6 @@ bool startswithi(const char *s, const char *prefix) { for (;;) { if (!*prefix) return true; if (!*s) return false; - if (kToLower[*s++ & 255] != (*prefix++ & 255)) return false; + if (kToLower[*s++ & 255] != kToLower[*prefix++ & 255]) return false; } } diff --git a/libc/str/str.h b/libc/str/str.h index 1f63ad427..fbf461e9a 100644 --- a/libc/str/str.h +++ b/libc/str/str.h @@ -192,21 +192,19 @@ wchar_t *wmempcpy(wchar_t *, const wchar_t *, size_t) memcpyesque; wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t) memcpyesque; void *tinymemccpy(void *, const void *, int, size_t) memcpyesque; void *memmem(const void *, size_t, const void *, size_t) libcesque nosideeffect; -char *strerror(int) returnsnonnull nothrow nocallback; long a64l(const char *); char *l64a(long); -char *strntolower(char *, size_t); -char *strtolower(char *) paramsnonnull(); -char *strntoupper(char *, size_t); -char *strtoupper(char *) paramsnonnull(); -char *chomp(char *); -char16_t *chomp16(char16_t *); -wchar_t *wchomp(wchar_t *); -bool IsText(const void *, size_t); -bool IsUtf8(const void *, size_t); -bool _isabspath(const char *) strlenesque; -bool escapedos(char16_t *, unsigned, const char16_t *, unsigned); +char *strntolower(char *, size_t) libcesque; +char *strtolower(char *) libcesque paramsnonnull(); +char *strntoupper(char *, size_t) libcesque; +char *strtoupper(char *) libcesque paramsnonnull(); +char *_chomp(char *) libcesque; +char16_t *_chomp16(char16_t *) libcesque; +wchar_t *_wchomp(wchar_t *) libcesque; +bool _istext(const void *, size_t) libcesque; +bool _isutf8(const void *, size_t) libcesque; +bool _escapedos(char16_t *, unsigned, const char16_t *, unsigned) libcesque; /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § strings » multibyte ─╬─│┼ @@ -254,19 +252,21 @@ typedef unsigned wctype_t; wctype_t wctype(const char *) strlenesque; int iswctype(wint_t, wctype_t) pureconst; +typedef const int *wctrans_t; +wctrans_t wctrans(const char *); +wint_t towctrans(wint_t, wctrans_t); + /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § strings » system ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ char *strsignal(int) returnsnonnull libcesque; +char *strerror(int) returnsnonnull dontthrow nocallback; +char *strerrno(int) nosideeffect libcesque; +char *strerdoc(int) nosideeffect libcesque; +int strerror_r(int, char *, size_t) dontthrow nocallback; +int strerror_wr(int, uint32_t, char *, size_t) dontthrow nocallback; -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -/* gcc rewrites to memset otherwise :'( */ -void __bzero(void *, size_t) asm("bzero") memcpyesque; -#define bzero(DEST, SIZE) \ - ((void)((__builtin_constant_p(SIZE)) ? memset(DEST, 0, SIZE) \ - : __bzero(DEST, SIZE))) -#endif /* __GNUC__ && !__STRICT_ANSI__ */ COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_STR_STR_H_ */ diff --git a/libc/str/str.mk b/libc/str/str.mk index 18488af09..8b2a34226 100644 --- a/libc/str/str.mk +++ b/libc/str/str.mk @@ -76,6 +76,7 @@ o/$(MODE)/libc/str/iswseparator.o: \ -fno-jump-tables o/$(MODE)/libc/str/bcmp.o \ +o/$(MODE)/libc/str/strcmp.o \ o/$(MODE)/libc/str/windowsdurationtotimeval.o \ o/$(MODE)/libc/str/windowsdurationtotimespec.o \ o/$(MODE)/libc/str/timevaltowindowstime.o \ @@ -83,7 +84,7 @@ o/$(MODE)/libc/str/timespectowindowstime.o \ o/$(MODE)/libc/str/windowstimetotimeval.o \ o/$(MODE)/libc/str/windowstimetotimespec.o: \ OVERRIDE_CFLAGS += \ - -O3 + -O2 LIBC_STR_LIBS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x))) LIBC_STR_SRCS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_SRCS)) diff --git a/libc/str/strchrnul.c b/libc/str/strchrnul.c index 981b9aaa6..3a3125442 100644 --- a/libc/str/strchrnul.c +++ b/libc/str/strchrnul.c @@ -53,6 +53,8 @@ noasan static inline const char *strchrnul_sse(const char *s, unsigned char c) { /** * Returns pointer to first instance of character. * + * If c is not found then a pointer to the nul byte is returned. + * * @param s is a NUL-terminated string * @param c is masked with 255 as byte to search for * @return pointer to first instance of c, or pointer to diff --git a/libc/str/strsignal.c b/libc/str/strsignal.c index a999c589d..ea6b0868f 100644 --- a/libc/str/strsignal.c +++ b/libc/str/strsignal.c @@ -17,31 +17,41 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" +#include "libc/fmt/magnumstrs.internal.h" #include "libc/macros.internal.h" #include "libc/str/str.h" -static const char kSig[4] = "SIG"; -static const char kUnknown[8] = "UNKNOWN"; - -_Alignas(char) static const char kStrSignals[][8] = { - "EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", - "FPE", "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", - "STKFLT", "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", - "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "SYS", -}; - -static char g_strsignal[4 + 8]; +static char g_strsignal[12]; /** - * Returns name associated with signal code. + * Returns string describing signal code. + * + * This returns SIGUNKNOWN for 0 which is the empty value. Textual names + * should be available for signals 1 through 32. Signals in the range 33 + * and 128 are returned as a `SIG%03d` string. Everything else is SIGWUT + * + * @param sig is signal number which should be in range 1 through 128 + * @return pointer to static memory that mutates on subsequent calls * @see sigaction() */ char *strsignal(int sig) { - if (0 <= sig && sig < ARRAYLEN(kStrSignals)) { - memcpy(g_strsignal, kSig, 4); - memcpy(&g_strsignal[3], kStrSignals[sig], 8); + const char *s; + strcpy(g_strsignal, "SIG"); + if (sig) { + if ((s = GetMagnumStr(kSignalNames, sig))) { + strcpy(g_strsignal + 3, s); + return g_strsignal; + } + } + if (!sig) { + strcpy(g_strsignal + 3, "UNKNOWN"); + } else if (1 <= sig && sig <= 128) { + g_strsignal[3] = '0' + sig / 100; + g_strsignal[4] = '0' + sig / 10 % 10; + g_strsignal[5] = '0' + sig % 10; + g_strsignal[6] = 0; } else { - memcpy(g_strsignal, &kUnknown, 8); + strcpy(g_strsignal + 3, "WUT"); } return g_strsignal; } diff --git a/libc/str/towctrans.c b/libc/str/towctrans.c new file mode 100644 index 000000000..e1ac46af8 --- /dev/null +++ b/libc/str/towctrans.c @@ -0,0 +1,25 @@ +/*-*- 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 2022 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/str/str.h" + +wint_t towctrans(wint_t c, wctrans_t t) { + if (t == (wctrans_t)1) return towupper(c); + if (t == (wctrans_t)2) return towlower(c); + return c; +} diff --git a/libc/str/undeflate.c b/libc/str/undeflate.c index b2d67d345..71c1dda05 100644 --- a/libc/str/undeflate.c +++ b/libc/str/undeflate.c @@ -46,7 +46,7 @@ } struct DeflateHold { - size_t word; + uint64_t word; size_t bits; }; diff --git a/libc/str/utf16.h b/libc/str/utf16.h index 0e8e391d7..a0a87854e 100644 --- a/libc/str/utf16.h +++ b/libc/str/utf16.h @@ -1,20 +1,23 @@ #ifndef COSMOPOLITAN_LIBC_STR_UTF16_H_ #define COSMOPOLITAN_LIBC_STR_UTF16_H_ +#include "libc/bits/likely.h" #define UTF16_MASK 0xfc00 #define UTF16_MOAR 0xd800 /* 0xD800..0xDBFF */ -#define UTF16_CONT 0xdc00 /* 0xDC00..0xDBFF */ +#define UTF16_CONT 0xdc00 /* 0xDC00..0xDFFF */ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#define IsUcs2(wc) (((wc)&UTF16_MASK) != UTF16_MOAR) -#define IsUtf16Cont(wc) (((wc)&UTF16_MASK) == UTF16_CONT) -#define MergeUtf16(lo, hi) ((((lo)-0xD800) << 10) + ((hi)-0xDC00) + 0x10000) +#define IsSurrogate(wc) ((0xf800 & (wc)) == 0xd800) +#define IsHighSurrogate(wc) ((UTF16_MASK & (wc)) == UTF16_MOAR) +#define IsLowSurrogate(wc) ((UTF16_MASK & (wc)) == UTF16_CONT) +#define IsUcs2(wc) (((65535 & (wc)) >> 11) != 27) +#define IsUtf16Cont(wc) IsLowSurrogate(wc) /* TODO: DELETE */ +#define MergeUtf16(hi, lo) ((((hi)-0xD800) << 10) + ((lo)-0xDC00) + 0x10000) #define EncodeUtf16(wc) \ - (__builtin_expect(((0x0000 <= (wc) && (wc) <= 0xFFFF) || \ - (0xE000 <= (wc) && (wc) <= 0xFFFF)), \ - 1) \ + (LIKELY((0x0000 <= (wc) && (wc) <= 0xFFFF) || \ + (0xE000 <= (wc) && (wc) <= 0xFFFF)) \ ? (wc) \ : 0x10000 <= (wc) && (wc) <= 0x10FFFF \ ? (((((wc)-0x10000) >> 10) + 0xD800) | \ diff --git a/libc/str/wchomp.c b/libc/str/wchomp.c index 79e7190aa..1c9ce046b 100644 --- a/libc/str/wchomp.c +++ b/libc/str/wchomp.c @@ -24,7 +24,16 @@ * @param line is NULL-propagating * @see getline */ -wchar_t *wchomp(wchar_t *line) { - if (line) line[wcscspn(line, L"\r\n")] = '\0'; +wchar_t *_wchomp(wchar_t *line) { + size_t i; + if (line) { + for (i = wcslen(line); i--;) { + if (line[i] == '\r' || line[i] == '\n') { + line[i] = '\0'; + } else { + break; + } + } + } return line; } diff --git a/libc/str/wctrans.c b/libc/str/wctrans.c new file mode 100644 index 000000000..285d8b556 --- /dev/null +++ b/libc/str/wctrans.c @@ -0,0 +1,25 @@ +/*-*- 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 2022 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/str/str.h" + +wctrans_t wctrans(const char *s) { + if (!strcmp(s, "toupper")) return (wctrans_t)1; + if (!strcmp(s, "tolower")) return (wctrans_t)2; + return 0; +} diff --git a/libc/str/zipfindcentraldir.c b/libc/str/zipfindcentraldir.c deleted file mode 100644 index 42a966d66..000000000 --- a/libc/str/zipfindcentraldir.c +++ /dev/null @@ -1,47 +0,0 @@ -/*-*- 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 "libc/zip.h" - -/* TODO(jart): DELETE */ - -/** - * Locates End Of Central Directory record in ZIP file. - * - * We search backwards for the End Of Central Directory Record magnum. - * The ZIP spec says this can be anywhere in the last 64kb. We go all - * the way since .com.dbg binaries will have lots of DWARF stuff after - * the embedded .com binary. As such, we sanity check the other fields - * too to make sure the record seems legit and it's not just a random - * occurrence of the magnum. - * - * @param p points to file memory - * @param n is byte size of file - */ -uint8_t *zipfindcentraldir(const uint8_t *p, size_t n) { - size_t i; - if (n >= kZipCdirHdrMinSize) { - i = n - kZipCdirHdrMinSize; - do { - if (ZIP_CDIR_MAGIC(p + i) == kZipCdirHdrMagic && IsZipCdir32(p, n, i)) { - return (/*unconst*/ uint8_t *)(p + i); - } - } while (i--); - } - return NULL; -} diff --git a/libc/stubs/abort.S b/libc/stubs/abort.S index a6b47d083..b100e2d8f 100644 --- a/libc/stubs/abort.S +++ b/libc/stubs/abort.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "ape/macros.internal.h" .real -.source __FILE__ .code16 # ∩ .code32 ∩ .code64 // Most basic tier of program self-termination. diff --git a/libc/stubs/assertfail.S b/libc/stubs/assertfail.S index fa791e228..2ceabaad3 100644 --- a/libc/stubs/assertfail.S +++ b/libc/stubs/assertfail.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "ape/macros.internal.h" .real -.source __FILE__ .code16 # ∩ .code32 ∩ .code64 // Lightweight universal overridable assert() macro support. diff --git a/libc/stubs/cxapurevirtual.S b/libc/stubs/cxapurevirtual.S index ec4b0e191..fb0e23fd3 100644 --- a/libc/stubs/cxapurevirtual.S +++ b/libc/stubs/cxapurevirtual.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Did you call a virtual method from a destructor? __cxa_pure_virtual: diff --git a/libc/stubs/debugbreak.S b/libc/stubs/debugbreak.S index ffe0aae5a..95cae0be3 100644 --- a/libc/stubs/debugbreak.S +++ b/libc/stubs/debugbreak.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .real -.source __FILE__ .code16 # ∩ .code32 ∩ .code64 // Triggers breakpoint in software debugger. diff --git a/libc/stubs/gcov.S b/libc/stubs/gcov.S index a934fc37a..c7f0598dd 100644 --- a/libc/stubs/gcov.S +++ b/libc/stubs/gcov.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Magic words to unbreak build if GCOV flags are passed. diff --git a/libc/stubs/instrumentation.S b/libc/stubs/instrumentation.S index f7654bbfa..a008e81a7 100644 --- a/libc/stubs/instrumentation.S +++ b/libc/stubs/instrumentation.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // @fileoverview Function Instrumentation No-Op Runtime // diff --git a/libc/stubs/ld.S b/libc/stubs/ld.S index 23d78e6db..195e33c71 100644 --- a/libc/stubs/ld.S +++ b/libc/stubs/ld.S @@ -35,6 +35,10 @@ __ro = 0 __relo_start = 0 __relo_end = 0 + __data_start = 0 + __data_end = 0 + __bss_start = 0 + __bss_end = 0 // Thread local boundaries defined by linker script // @see ape/ape.lds @@ -59,6 +63,10 @@ .globl _tbss_end .globl _tdata_start .globl _tdata_end + .globl __data_start + .globl __data_end + .globl __bss_start + .globl __bss_end .weak _base .weak ape_xlm @@ -76,3 +84,7 @@ .weak _tbss_end .weak _tdata_start .weak _tdata_end + .weak __data_start + .weak __data_end + .weak __bss_start + .weak __bss_end diff --git a/libc/stubs/panic.S b/libc/stubs/panic.S index daa19b4d6..fc68e0587 100644 --- a/libc/stubs/panic.S +++ b/libc/stubs/panic.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .real -.source __FILE__ .code16 # ∩ .code32 ∩ .code64 // Aborts or hard blocks instruction pointer. diff --git a/libc/stubs/retpoline.S b/libc/stubs/retpoline.S index 3e3330b59..66815678d 100644 --- a/libc/stubs/retpoline.S +++ b/libc/stubs/retpoline.S @@ -22,4 +22,3 @@ __x86_return_thunk: ret .endfn __x86_return_thunk,weak - .source __FILE__ diff --git a/libc/stubs/stackchkguard.S b/libc/stubs/stackchkguard.S index ef31ac6d8..0e89f0292 100644 --- a/libc/stubs/stackchkguard.S +++ b/libc/stubs/stackchkguard.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" #include "libc/notice.inc" -.source __FILE__ // Canary for -fstack-protector. // diff --git a/libc/stubs/stackguard.S b/libc/stubs/stackguard.S index 51c5b5822..9bf9caf43 100644 --- a/libc/stubs/stackguard.S +++ b/libc/stubs/stackguard.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "ape/macros.internal.h" .real -.source __FILE__ .code16 # ∩ .code32 ∩ .code64 /** diff --git a/libc/stubs/typeinfo.S b/libc/stubs/typeinfo.S index 89124acd0..337de4af1 100644 --- a/libc/stubs/typeinfo.S +++ b/libc/stubs/typeinfo.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // __cxxabiv1::__function_type_info (?) // Because Clang in MODE=dbg doesn't respect -fno-rtti diff --git a/libc/stubs/xnu.S b/libc/stubs/xnu.S index 83506016e..465b2c842 100644 --- a/libc/stubs/xnu.S +++ b/libc/stubs/xnu.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ _xnu: ud2 .endfn _xnu,weak diff --git a/libc/sysv/calls/__sys_sigprocmask.s b/libc/sysv/calls/__sys_sigprocmask.s new file mode 100644 index 000000000..a9cc61ef9 --- /dev/null +++ b/libc/sysv/calls/__sys_sigprocmask.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall __sys_sigprocmask,0x125030154214900e,globl,hidden diff --git a/libc/sysv/calls/__syscall.s b/libc/sysv/calls/__syscall.s deleted file mode 100644 index afb98875d..000000000 --- a/libc/sysv/calls/__syscall.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __syscall,0xfff0c6ffffffffff,globl diff --git a/libc/sysv/calls/chroot.s b/libc/sysv/calls/chroot.s deleted file mode 100644 index 702d03be0..000000000 --- a/libc/sysv/calls/chroot.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall chroot,0x03d03d03d203d0a1,globl diff --git a/libc/sysv/calls/clone.s b/libc/sysv/calls/clone.s deleted file mode 100644 index 928425d4c..000000000 --- a/libc/sysv/calls/clone.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall clone,0xfffffffffffff038,globl diff --git a/libc/sysv/calls/getegid.s b/libc/sysv/calls/getegid.s deleted file mode 100644 index c8a7ff412..000000000 --- a/libc/sysv/calls/getegid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall getegid,0xfff02b02b202b06c,globl diff --git a/libc/sysv/calls/geteuid.s b/libc/sysv/calls/geteuid.s deleted file mode 100644 index 070feb0b9..000000000 --- a/libc/sysv/calls/geteuid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall geteuid,0xfff019019201906b,globl diff --git a/libc/sysv/calls/getpgrp.s b/libc/sysv/calls/getpgrp.s deleted file mode 100644 index 10a08f07a..000000000 --- a/libc/sysv/calls/getpgrp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall getpgrp,0x051051051205106f,globl diff --git a/libc/sysv/calls/getresgid.s b/libc/sysv/calls/getresgid.s deleted file mode 100644 index 9ce4dee92..000000000 --- a/libc/sysv/calls/getresgid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall getresgid,0xfff11b169ffff078,globl diff --git a/libc/sysv/calls/getresuid.s b/libc/sysv/calls/getresuid.s deleted file mode 100644 index e50c6a170..000000000 --- a/libc/sysv/calls/getresuid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall getresuid,0xfff119168ffff076,globl diff --git a/libc/sysv/calls/pledge.s b/libc/sysv/calls/pledge.s deleted file mode 100644 index 8015bf37e..000000000 --- a/libc/sysv/calls/pledge.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall pledge,0xfff06cffffffffff,globl diff --git a/libc/sysv/calls/prctl.s b/libc/sysv/calls/prctl.s deleted file mode 100644 index 3fdf8080d..000000000 --- a/libc/sysv/calls/prctl.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall prctl,0xfffffffffffff09d,globl diff --git a/libc/sysv/calls/recv.s b/libc/sysv/calls/recv.s deleted file mode 100644 index 5d163d2bd..000000000 --- a/libc/sysv/calls/recv.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall recv,0xffffff066fffffff,globl diff --git a/libc/sysv/calls/seccomp.s b/libc/sysv/calls/seccomp.s deleted file mode 100644 index bb6be8156..000000000 --- a/libc/sysv/calls/seccomp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall seccomp,0xfffffffffffff13d,globl diff --git a/libc/sysv/calls/sendmmsg.s b/libc/sysv/calls/sendmmsg.s deleted file mode 100644 index 8996506aa..000000000 --- a/libc/sysv/calls/sendmmsg.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall sendmmsg,0x1dcffffffffff133,globl diff --git a/libc/sysv/calls/setgid.s b/libc/sysv/calls/setgid.s deleted file mode 100644 index df63895fe..000000000 --- a/libc/sysv/calls/setgid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall setgid,0x0b50b50b520b506a,globl diff --git a/libc/sysv/calls/setpgid.s b/libc/sysv/calls/setpgid.s deleted file mode 100644 index 065e3d7ab..000000000 --- a/libc/sysv/calls/setpgid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall setpgid,0x052052052205206d,globl diff --git a/libc/sysv/calls/setregid.s b/libc/sysv/calls/setregid.s deleted file mode 100644 index 7daa7a16a..000000000 --- a/libc/sysv/calls/setregid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall setregid,0x07f07f07f207f072,globl diff --git a/libc/sysv/calls/setreuid.s b/libc/sysv/calls/setreuid.s deleted file mode 100644 index e0b88ab32..000000000 --- a/libc/sysv/calls/setreuid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall setreuid,0x07e07e07e207e071,globl diff --git a/libc/sysv/calls/setuid.s b/libc/sysv/calls/setuid.s deleted file mode 100644 index 7e25e3fb5..000000000 --- a/libc/sysv/calls/setuid.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall setuid,0x0170170172017069,globl diff --git a/libc/sysv/calls/sys_chroot.s b/libc/sysv/calls/sys_chroot.s new file mode 100644 index 000000000..5e22b1782 --- /dev/null +++ b/libc/sysv/calls/sys_chroot.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_chroot,0x03d03d03d203d0a1,globl,hidden diff --git a/libc/sysv/calls/sys_clone.s b/libc/sysv/calls/sys_clone.s new file mode 100644 index 000000000..476bf70ef --- /dev/null +++ b/libc/sysv/calls/sys_clone.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_clone,0x11fffffffffff038,globl,hidden diff --git a/libc/sysv/calls/sys_epoll_create.s b/libc/sysv/calls/sys_epoll_create.s index 1c2455e18..865111423 100644 --- a/libc/sysv/calls/sys_epoll_create.s +++ b/libc/sysv/calls/sys_epoll_create.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_epoll_create,0xfffffffffffff0d5,globl +.scall sys_epoll_create,0xfffffffffffff0d5,globl,hidden diff --git a/libc/sysv/calls/sys_epoll_create1.s b/libc/sysv/calls/sys_epoll_create1.s index ff749f988..f6fdbbb9f 100644 --- a/libc/sysv/calls/sys_epoll_create1.s +++ b/libc/sysv/calls/sys_epoll_create1.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_epoll_create1,0xfffffffffffff123,globl +.scall sys_epoll_create1,0xfffffffffffff123,globl,hidden diff --git a/libc/sysv/calls/sys_epoll_ctl.s b/libc/sysv/calls/sys_epoll_ctl.s index f6de57e4a..76c23cd1d 100644 --- a/libc/sysv/calls/sys_epoll_ctl.s +++ b/libc/sysv/calls/sys_epoll_ctl.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_epoll_ctl,0xfffffffffffff0e9,globl +.scall sys_epoll_ctl,0xfffffffffffff0e9,globl,hidden diff --git a/libc/sysv/calls/sys_epoll_wait.s b/libc/sysv/calls/sys_epoll_wait.s index 2c97356a3..f38c97423 100644 --- a/libc/sysv/calls/sys_epoll_wait.s +++ b/libc/sysv/calls/sys_epoll_wait.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_epoll_wait,0xfffffffffffff0e8,globl +.scall sys_epoll_wait,0xfffffffffffff0e8,globl,hidden diff --git a/libc/sysv/calls/sys_getegid.s b/libc/sysv/calls/sys_getegid.s new file mode 100644 index 000000000..8e5dba159 --- /dev/null +++ b/libc/sysv/calls/sys_getegid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_getegid,0x02b02b02b202b06c,globl,hidden diff --git a/libc/sysv/calls/sys_geteuid.s b/libc/sysv/calls/sys_geteuid.s new file mode 100644 index 000000000..9426150e3 --- /dev/null +++ b/libc/sysv/calls/sys_geteuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_geteuid,0x019019019201906b,globl,hidden diff --git a/libc/sysv/calls/sys_getpgrp.s b/libc/sysv/calls/sys_getpgrp.s new file mode 100644 index 000000000..f89e2cc7b --- /dev/null +++ b/libc/sysv/calls/sys_getpgrp.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_getpgrp,0x051051051205106f,globl,hidden diff --git a/libc/sysv/calls/sys_getresgid.s b/libc/sysv/calls/sys_getresgid.s new file mode 100644 index 000000000..f70e7c99d --- /dev/null +++ b/libc/sysv/calls/sys_getresgid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_getresgid,0xfff11b169ffff078,globl diff --git a/libc/sysv/calls/sys_getresuid.s b/libc/sysv/calls/sys_getresuid.s new file mode 100644 index 000000000..4d61c6a0c --- /dev/null +++ b/libc/sysv/calls/sys_getresuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_getresuid,0xfff119168ffff076,globl diff --git a/libc/sysv/calls/sys_mount.s b/libc/sysv/calls/sys_mount.s index ef58d044d..27393826d 100644 --- a/libc/sysv/calls/sys_mount.s +++ b/libc/sysv/calls/sys_mount.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_mount,0x19a01501520a70a5,globl +.scall sys_mount,0x19a01501520a70a5,globl,hidden diff --git a/libc/sysv/calls/sys_pledge.s b/libc/sysv/calls/sys_pledge.s new file mode 100644 index 000000000..18fc40da1 --- /dev/null +++ b/libc/sysv/calls/sys_pledge.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_pledge,0xfff06cffffffffff,globl diff --git a/libc/sysv/calls/sys_preadv.s b/libc/sysv/calls/sys_preadv.s index 5825e1d6c..3a5f810fd 100644 --- a/libc/sysv/calls/sys_preadv.s +++ b/libc/sysv/calls/sys_preadv.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_preadv,0x12110b121ffff127,globl,hidden +.scall sys_preadv,0x12110b121221c127,globl,hidden diff --git a/libc/sysv/calls/sys_pwritev.s b/libc/sysv/calls/sys_pwritev.s index 765c2aad5..985983a7d 100644 --- a/libc/sysv/calls/sys_pwritev.s +++ b/libc/sysv/calls/sys_pwritev.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_pwritev,0x12210c122ffff128,globl,hidden +.scall sys_pwritev,0x12210c122221d128,globl,hidden diff --git a/libc/sysv/calls/sys_setgid.s b/libc/sysv/calls/sys_setgid.s new file mode 100644 index 000000000..71c2a9d6d --- /dev/null +++ b/libc/sysv/calls/sys_setgid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_setgid,0x0b50b50b520b506a,globl,hidden diff --git a/libc/sysv/calls/sys_setpgid.s b/libc/sysv/calls/sys_setpgid.s new file mode 100644 index 000000000..81db109ca --- /dev/null +++ b/libc/sysv/calls/sys_setpgid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_setpgid,0x052052052205206d,globl,hidden diff --git a/libc/sysv/calls/sys_setregid.s b/libc/sysv/calls/sys_setregid.s new file mode 100644 index 000000000..8b42b154a --- /dev/null +++ b/libc/sysv/calls/sys_setregid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_setregid,0x07f07f07f207f072,globl,hidden diff --git a/libc/sysv/calls/sys_setreuid.s b/libc/sysv/calls/sys_setreuid.s new file mode 100644 index 000000000..a3f3fc5b3 --- /dev/null +++ b/libc/sysv/calls/sys_setreuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_setreuid,0x07e07e07e207e071,globl,hidden diff --git a/libc/sysv/calls/sys_setuid.s b/libc/sysv/calls/sys_setuid.s new file mode 100644 index 000000000..6b4afc2c2 --- /dev/null +++ b/libc/sysv/calls/sys_setuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_setuid,0x0170170172017069,globl,hidden diff --git a/libc/sysv/calls/sys_sigprocmask.s b/libc/sysv/calls/sys_sigprocmask.s deleted file mode 100644 index 8aa411f1d..000000000 --- a/libc/sysv/calls/sys_sigprocmask.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall sys_sigprocmask,0x125030154203000e,globl,hidden diff --git a/libc/sysv/calls/sys_sigqueue.s b/libc/sysv/calls/sys_sigqueue.s index 5faa160bf..31271d5ae 100644 --- a/libc/sysv/calls/sys_sigqueue.s +++ b/libc/sysv/calls/sys_sigqueue.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_sigqueue,0xffffff1c8fffffff,globl +.scall sys_sigqueue,0xffffff1c8fffffff,globl,hidden diff --git a/libc/sysv/calls/sys_sigqueueinfo.s b/libc/sysv/calls/sys_sigqueueinfo.s index 4e521ca9f..ce3920e10 100644 --- a/libc/sysv/calls/sys_sigqueueinfo.s +++ b/libc/sysv/calls/sys_sigqueueinfo.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_sigqueueinfo,0x0f5ffffffffff081,globl +.scall sys_sigqueueinfo,0x0f5ffffffffff081,globl,hidden diff --git a/libc/sysv/calls/sys_umask.s b/libc/sysv/calls/sys_umask.s new file mode 100644 index 000000000..17a2e9774 --- /dev/null +++ b/libc/sysv/calls/sys_umask.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_umask,0x03c03c03c203c05f,globl,hidden diff --git a/libc/sysv/calls/umask.s b/libc/sysv/calls/umask.s deleted file mode 100644 index 481f95f92..000000000 --- a/libc/sysv/calls/umask.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall umask,0x03c03c03c203c05f,globl diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 1855299a7..b52068ef5 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -47,15 +47,15 @@ syscon errno ENOTDIR 20 20 20 20 20 3 # not a directory; unix co syscon errno EISDIR 21 21 21 21 21 267 # is a a directory; unix consensus; kNtErrorDirectory; raised by acct(2), copy_file_range(2), execve(2), ioctl_ficlonerange(2), ioctl_fideduperange(2), open(2), read(2), rename(2), truncate(2), unlink(2) syscon errno EINVAL 22 22 22 22 22 87 # invalid argument; unix consensus; kNtErrorInvalidParameter; raised by accept(2), access(2), add_key(2), adjtimex(2), arch_prctl(2), bdflush(2), bind(2), bpf(2), cacheflush(2), capget(2), chmod(2), chown(2), clock_getres(2), clock_nanosleep(2), clone(2), copy_file_range(2), create_module(2), dup(2), epoll_create(2), epoll_ctl(2), epoll_wait(2), eventfd(2), execve(2), execveat(2), fallocate(2), fanotify_init(2), fanotify_mark(2), fcntl(2), flock(2), futex(2), get_mempolicy(2), get_robust_list(2), getdents(2), getdomainname(2), getgroups(2), gethostname(2), getitimer(2), getpeername(2), getpriority(2), getrandom(2), getrlimit(2), getrusage(2), getsockname(2), getsockopt(2), gettimeofday(2), init_module(2), inotify_add_watch(2), inotify_init(2), inotify_rm_watch(2), io_cancel(2), io_destroy(2), io_getevents(2), io_setup(2), io_submit(2), ioctl(2), ioctl_console(2), ioctl_ficlonerange(2), ioctl_fideduperange(2), ioctl_getfsmap(2), ioctl_ns(2), ioctl_tty(2), ioctl_userfaultfd(2), ioperm(2), iopl(2), ioprio_set(2), kcmp(2), kexec_load(2), keyctl(2), kill(2), link(2), llseek(2), lookup_dcookie(2), lseek(2), madvise(2), mbind(2), membarrier(2), memfd_create(2), migrate_pages(2), mincore(2), mkdir(2), mknod(2), mlock(2), mmap(2), mmap2(2), modify_ldt(2), mount(2), move_pages(2), mprotect(2), mremap(2), msgctl(2), msgop(2), msync(2), nanosleep(2), open(2), open_by_handle_at(2), openat2(2), pciconfig_read(2), perf_event_open(2), personality(2), pidfd_getfd(2), pidfd_open(2), pidfd_send_signal(2), pipe(2), pivot_root(2), pkey_alloc(2), poll(2), posix_fadvise(2), prctl(2), process_vm_readv(2), ptrace(2), query_module(2), quotactl(2), read(2), readahead(2), readdir(2), readlink(2), readv(2), reboot(2), recv(2), recvmmsg(2), remap_file_pages(2), rename(2), request_key(2), rmdir(2), rt_sigqueueinfo(2), s390_guarded_storage(2), s390_pci_mmio_write(2), s390_runtime_instr(2), s390_sthyi(2), sched_get_priority_max(2), sched_rr_get_interval(2), sched_setaffinity(2), sched_setattr(2), sched_setparam(2), sched_setscheduler(2), seccomp(2), select(2), semctl(2), semget(2), semop(2), send(2), sendfile(2), set_mempolicy(2), set_thread_area(2), seteuid(2), setfsgid(2), setfsuid(2), setgid(2), setns(2), setpgid(2), setresuid(2), setreuid(2), setuid(2), shmctl(2), shmget(2), shmop(2), shutdown(2), sigaction(2), sigaltstack(2), signal(2), signalfd(2), sigprocmask(2), sigsuspend(2), sigwaitinfo(2), socket(2), splice(2), spu_create(2), spu_run(2), stat(2), statx(2), subpage_prot(2), swapon(2), sync_file_range(2), sysfs(2), syslog(2), tee(2), timer_create(2), timer_delete(2), timer_getoverrun(2), timer_settime(2), timerfd_create(2), tkill(2), truncate(2), umount(2), unlink(2), unshare(2), userfaultfd(2), ustat(2), utimensat(2), vmsplice(2), wait(2), write(2), unix(7), ip(7) syscon errno ENFILE 23 23 23 23 23 331 # too many open files in system; unix consensus; kNtErrorTooManyDescriptors; raised by accept(2), acct(2), epoll_create(2), eventfd(2), execve(2), futex(2), inotify_init(2), memfd_create(2), mmap(2), open(2), pidfd_getfd(2), pidfd_open(2), pipe(2), shmget(2), signalfd(2), socket(2), socketpair(2), spu_create(2), swapon(2), timerfd_create(2), uselib(2), userfaultfd(2) -syscon errno EMFILE 24 24 24 24 24 336 # too many open files; unix consensus; kNtErrorTooManyOpenFiles; raised by accept(2), dup(2), epoll_create(2), eventfd(2), execve(2), fanotify_init(2), fcntl(2), inotify_init(2), memfd_create(2), mount(2), open(2), perf_event_open(2), pidfd_getfd(2), pidfd_open(2), pipe(2), signalfd(2), socket(2), socketpair(2), spu_create(2), timerfd_create(2) +syscon errno EMFILE 24 24 24 24 24 4 # too many open files; unix consensus; kNtErrorTooManyOpenFiles; raised by accept(2), dup(2), epoll_create(2), eventfd(2), execve(2), fanotify_init(2), fcntl(2), inotify_init(2), memfd_create(2), mount(2), open(2), perf_event_open(2), pidfd_getfd(2), pidfd_open(2), pipe(2), signalfd(2), socket(2), socketpair(2), spu_create(2), timerfd_create(2) syscon errno ENOTTY 25 25 25 25 25 1118 # inappropriate i/o control operation; unix consensus; kNtErrorSerialNoDevice; raised by ioctl(2), ioctl_console(2), ioctl_fat(2), ioctl_ns(2), ioctl_tty(2) syscon errno ETXTBSY 26 26 26 26 26 148 # won't open executable that's executing in write mode; try UnlockExecutable(); unix consensus; kNtErrorPathBusy; raised by access(2), copy_file_range(2), execve(2), fallocate(2), ioctl_ficlonerange(2), ioctl_fideduperange(2), mmap(2), open(2), truncate(2) syscon errno EFBIG 27 27 27 27 27 223 # file too large; unix consensus; kNtErrorFileTooLarge; raised by copy_file_range(2), fallocate(2), init_module(2), open(2), semop(2), truncate(2), write(2) syscon errno ENOSPC 28 28 28 28 28 39 # no space left on device; unix consensus; kNtErrorDiskFull; raised by copy_file_range(2), epoll_ctl(2), fallocate(2), fanotify_mark(2), fsync(2), inotify_add_watch(2), link(2), mkdir(2), mknod(2), msgget(2), open(2), perf_event_open(2), pkey_alloc(2), query_module(2), rename(2), semget(2), setxattr(2), shmget(2), spu_create(2), symlink(2), sync_file_range(2), write(2) -syscon errno EDQUOT 122 69 69 69 69 10069 # disk quota exceeded; bsd consensus; raised by add_key(2), keyctl(2), link(2), mkdir(2), mknod(2), open(2), rename(2), request_key(2), setxattr(2), symlink(2), write(2) +syscon errno EDQUOT 122 69 69 69 69 1816 # disk quota exceeded; bsd consensus; kNtErrorNotEnoughQuota; raised by add_key(2), keyctl(2), link(2), mkdir(2), mknod(2), open(2), rename(2), request_key(2), setxattr(2), symlink(2), write(2) syscon errno ESPIPE 29 29 29 29 29 25 # invalid seek; unix consensus; kNtErrorSeek; raised by fallocate(2), lseek(2), posix_fadvise(2), sendfile(2), splice(2), sync_file_range(2) syscon errno EROFS 30 30 30 30 30 6009 # read-only filesystem; unix consensus; kNtErrorFileReadOnly; raised by access(2), acct(2), bind(2), chmod(2), chown(2), link(2), mkdir(2), mknod(2), mount(2), open(2), rename(2), rmdir(2), symlink(2), truncate(2), unlink(2), utime(2), utimensat(2) -syscon errno EMLINK 31 31 31 31 31 4 # too many links; unix consensus; kNtErrorTooManyLinks; raised by link(2), mkdir(2), rename(2) +syscon errno EMLINK 31 31 31 31 31 1142 # too many links; unix consensus; kNtErrorTooManyLinks; raised by link(2), mkdir(2), rename(2) syscon errno EPIPE 32 32 32 32 32 109 # broken pipe; unix consensus; kNtErrorBrokenPipe; raised by send(2), write(2), tcp(7), unix(7), ip(7) syscon errno EDOM 33 33 33 33 33 33 # mathematics argument out of domain of function; bsd consensus; fudged on NT; returned by cos(3), fmod(3), log1p(3), sin(3), tan(3), tgamma(3) syscon errno ERANGE 34 34 34 34 34 34 # result too large; bsd consensus; fudged on NT; raised by getxattr(2), listxattr(2), lookup_dcookie(2), prctl(2), quotactl(2), semctl(2), semop(2), setxattr(2) @@ -125,9 +125,9 @@ syscon errno EOWNERDEAD 130 105 96 94 97 0 # raised by pthread_co syscon errno ENOTRECOVERABLE 131 104 95 93 98 0 # raised by pthread_cond_timedwait(3), pthread_mutex_consistent(3), pthread_mutex_getprioceiling(3), pthread_mutex_lock(3), pthread_mutex_timedlock(3), pthread_mutexattr_getrobust(3), pthread_mutexattr_setrobust(3) syscon errno ENONET 64 0 0 0 0 0 # unilateral; raised by accept(2) syscon errno ERESTART 85 -1 -1 -1 -3 0 # should only be seen in ptrace() +syscon errno ENODATA 61 96 0 0 89 232 # no message is available in xsi stream or named pipe is being closed; no data available; barely in posix; returned by ioctl; very close in spirit to EPIPE? syscon errno ENOSR 63 98 0 90 90 0 # out of streams resources; something like EAGAIN; it's in POSIX; maybe some commercial UNIX returns it with openat, putmsg, putpmsg, posix_openpt, ioctl, open syscon errno ENOSTR 60 99 0 0 91 0 # not a stream; returned by getmsg, putmsg, putpmsg, getpmsg -syscon errno ENODATA 61 96 0 0 89 0 # no data available; barely in posix; returned by ioctl syscon errno EMULTIHOP 72 95 90 0 94 0 # barely in posix syscon errno ENOLINK 67 97 91 0 95 0 # barely in posix syscon errno ENOMEDIUM 123 0 0 85 0 0 # not posix; not documented @@ -171,36 +171,34 @@ syscon sig SIGINFO 0 29 29 29 29 0 # bsd consensus syscon sig SIGRTMAX 64 0 126 0 63 0 syscon sig SIGRTMIN 32 0 65 0 33 0 syscon sig SIGEMT 0 7 7 7 7 0 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead +syscon sig SIGPWR 30 30 30 30 32 30 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead syscon compat SIGPOLL 29 23 23 23 23 29 # same as SIGIO syscon compat SIGIOT 6 6 6 6 6 6 # PDP-11 feature; same as SIGABRT -syscon compat SIGPWR 30 30 30 30 32 30 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead -# open() flags ┌──────hoo boy -# ┌──────┐ -# │┌─<<8─┴───dwFlagsAndAttributes -# ┌││─────┐ -# │││ │ ┌┴───dwDesiredAccess -# N │││ │ │ -# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD T │││┌─┴┐│ Commentary -syscon open O_RDONLY 0 0 0 0 0 0xA0000000 # unix consensus & kNtGenericRead|kNtGenericExecute -syscon open O_WRONLY 1 1 1 1 1 0x40000000 # unix consensus & kNtGenericWrite -syscon open O_RDWR 2 2 2 2 2 0xE0000000 # unix consensus & kNtGenericRead|kNtGenericWrite|kNtGenericExecute -syscon open O_ACCMODE 3 3 3 3 3 0xE0000000 # O_RDONLY|O_WRONLY|O_RDWR -syscon open O_APPEND 0x00000400 8 8 8 8 0x00000004 # bsd consensus & kNtFileAppendData; won't pose issues w/ mknod(S_IFIFO) -syscon open O_CREAT 0x00000040 0x00000200 0x00000200 0x00000200 0x00000200 0x00000040 # bsd consensus & NT faked as Linux -syscon open O_EXCL 0x00000080 0x00000800 0x00000800 0x00000800 0x00000800 0x00000080 # bsd consensus & NT faked as Linux -syscon open O_TRUNC 0x00000200 0x00000400 0x00000400 0x00000400 0x00000400 0x00000200 # bsd consensus & NT faked as Linux -syscon open O_DIRECTORY 0x00010000 0x00100000 0x00020000 0x00020000 0x00200000 0x02000000 # useful hint on UNIX, but required on NT (see kNtFileFlagBackupSemantics) -syscon open O_RANDOM 0 0 0 0 0 0x10000000 # kNtFileFlagRandomAccess -syscon open O_SEQUENTIAL 0 0 0 0 0 0x08000000 # kNtFileFlagSequentialScan -syscon open O_DIRECT 0x00004000 0 0x00010000 0 0x00080000 0x00200000 # kNtFileFlagNoBuffering>>8 -syscon open O_CLOEXEC 0x00080000 0x01000000 0x00100000 0x00010000 0x00400000 0x00080000 # NT faked as Linux -syscon open O_TMPFILE 0x00410000 0 0 0 0 0x00000000 # Linux 3.11+ (c. 2013) & kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose -syscon open O_SPARSE 0 0 0 0 0 0x00040000 # we invented it -syscon open O_NDELAY 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus & kNtFileFlagWriteThrough>>8 → 0x00800000 (???) -syscon open O_NONBLOCK 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus & faked on nt to be same as linux +# open() flags +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD Windoze Commentary +syscon open O_RDONLY 0 0 0 0 0 0 # consensus +syscon open O_WRONLY 1 1 1 1 1 1 # consensus +syscon open O_RDWR 2 2 2 2 2 2 # consensus +syscon open O_ACCMODE 3 3 3 3 3 3 # O_RDONLY|O_WRONLY|O_RDWR +syscon open O_APPEND 0x00000400 8 8 8 8 0x00000400 # bsd consensus & kNtFileAppendData; won't pose issues w/ mknod(S_IFIFO) [SYNC libc/calls/open-nt.c] +syscon open O_CREAT 0x00000040 0x00000200 0x00000200 0x00000200 0x00000200 0x00000040 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c] +syscon open O_EXCL 0x00000080 0x00000800 0x00000800 0x00000800 0x00000800 0x00000080 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c] +syscon open O_TRUNC 0x00000200 0x00000400 0x00000400 0x00000400 0x00000400 0x00000200 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c] +syscon open O_DIRECTORY 0x00010000 0x00100000 0x00020000 0x00020000 0x00200000 0x00010000 # useful hint on UNIX, but required on NT (see kNtFileFlagBackupSemantics) [SYNC libc/calls/open-nt.c] +syscon open O_NOFOLLOW 0x00020000 0x00000100 0x00000100 0x00000100 0x00000100 0x00020000 # bsd consensus; kNtFileFlagOpenReparsePoint +syscon open O_DIRECT 0x00004000 0 0x00010000 0 0x00080000 0x00004000 # kNtFileFlagNoBuffering [SYNC libc/calls/open-nt.c] +syscon open O_NDELAY 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # kNtFileFlagWriteThrough [SYNC libc/calls/open-nt.c] +syscon open O_RANDOM 0 0 0 0 0 0x80000000 # kNtFileFlagRandomAccess [SYNC libc/calls/open-nt.c] +syscon open O_SEQUENTIAL 0 0 0 0 0 0x40000000 # kNtFileFlagSequentialScan [SYNC libc/calls/open-nt.c] +syscon open O_COMPRESSED 0 0 0 0 0 0x20000000 # kNtFileAttributeCompressed [SYNC libc/calls/open-nt.c] +syscon open O_INDEXED 0 0 0 0 0 0x10000000 # !kNtFileAttributeNotContentIndexed [SYNC libc/calls/open-nt.c] +syscon open O_CLOEXEC 0x00080000 0x01000000 0x00100000 0x00010000 0x00400000 0x00080000 # NT faked as Linux [SYNC libc/calls/open-nt.c] +syscon open O_TMPFILE 0x00410000 0 0 0 0 0x00410000 # Linux 3.11+ (c. 2013) & kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose [SYNC libc/calls/open-nt.c] +syscon open O_SPARSE 0 0 0 0 0 0 # wut +syscon open O_NONBLOCK 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus syscon open O_ASYNC 0x00002000 0x00000040 0x00000040 0x00000040 0x00000040 0 # bsd consensus -syscon open O_NOFOLLOW 0x00020000 0x00000100 0x00000100 0x00000100 0x00000100 0 # bsd consensus syscon open O_NOFOLLOW_ANY 0 0x20000000 0 0 0 0 # syscon open O_SYNC 0x00101000 0x00000080 0x00000080 0x00000080 0x00000080 0 # bsd consensus syscon open O_NOCTTY 0x00000100 0x00020000 0x00008000 0x00008000 0x00008000 0 # used for remote viewing (default behavior on freebsd) @@ -224,11 +222,11 @@ syscon compat MAP_FILE 0 0 0 0 0 0 # consensus syscon mmap MAP_SHARED 1 1 1 1 1 1 # forced consensus & faked nt syscon mmap MAP_PRIVATE 2 2 2 2 2 2 # forced consensus & faked nt syscon mmap MAP_TYPE 15 15 15 15 15 15 # mask for type of mapping -syscon mmap MAP_FIXED 0x10 0x10 0x10 0x10 0x10 0x10 # unix consensus; openbsd appears to forbid; faked nt +syscon mmap MAP_FIXED 0x0000010 0x0000010 0x0000010 0x0000010 0x0000010 0x0000010 # unix consensus; openbsd appears to forbid; faked nt syscon mmap MAP_FIXED_NOREPLACE 0x8000000 0x8000000 0x8000000 0x8000000 0x8000000 0x8000000 # handled and defined by cosmo runtime; 0x100000 on linux 4.7+ -syscon mmap MAP_ANONYMOUS 0x20 0x1000 0x1000 0x1000 0x1000 0x20 # bsd consensus; faked nt -syscon mmap MAP_GROWSDOWN 0x0100 0 0x0400 0x4000 0x4000 0x100000 # mandatory for OpenBSD stacks; MAP_STACK on Free/OpenBSD; MEM_TOP_DOWN on NT -syscon mmap MAP_CONCEAL 0 0 0x20000 0x8000 0x8000 0 # omit from core dumps; MAP_NOCORE on FreeBSD +syscon mmap MAP_ANONYMOUS 0x20 0x1000 0x0001000 0x1000 0x1000 0x20 # bsd consensus; faked nt +syscon mmap MAP_GROWSDOWN 0x0100 0 0x0000400 0x4000 0x4000 0x100000 # mandatory for OpenBSD stacks; MAP_STACK on Free/OpenBSD; MEM_TOP_DOWN on NT +syscon mmap MAP_CONCEAL 0 0 0x0020000 0x8000 0x8000 0 # omit from core dumps; MAP_NOCORE on FreeBSD syscon mmap MAP_NORESERVE 0x4000 0x40 0 0 64 0 # Linux calls it "reserve"; NT calls it "commit"? which is default? syscon mmap MAP_HUGETLB 0x040000 0 0 0 0 0x80000000 # kNtSecLargePages syscon mmap MAP_HUGE_MASK 63 0 0 0 0 0 @@ -236,45 +234,43 @@ syscon mmap MAP_HUGE_SHIFT 26 0 0 0 0 0 syscon mmap MAP_LOCKED 0x2000 0 0 0 0 0 syscon mmap MAP_NONBLOCK 0x10000 0 0 0 0 0 syscon mmap MAP_POPULATE 0x8000 0 0 0 0 0 # can avoid madvise(MADV_WILLNEED) on private file mapping -syscon mmap MAP_CONCEAL 0 0 0 0x8000 0 0 # omit from dumps -syscon compat MAP_STACK 0x0100 0 0x0400 0x4000 0x2000 0x100000 # use MAP_GROWSDOWN -syscon compat MAP_NOCORE 0 0 0x20000 0x8000 0x8000 0 # use MAP_CONCEAL -syscon compat MAP_ANON 0x20 0x1000 0x1000 0x1000 0x1000 0x20 # bsd consensus; faked nt +syscon mmap MAP_STACK 0x0100 0 0x0000400 0x4000 0x2000 0x100000 # use MAP_GROWSDOWN +syscon compat MAP_NOCORE 0 0 0x0020000 0x8000 0x8000 0 # use MAP_CONCEAL +syscon compat MAP_ANON 0x20 0x1000 0x0001000 0x1000 0x1000 0x20 # bsd consensus; faked nt syscon compat MAP_EXECUTABLE 0x1000 0 0 0 0 0 # ignored syscon compat MAP_DENYWRITE 0x0800 0 0 0 0 0 syscon compat MAP_32BIT 0x40 0 0x080000 0 0 0 # iffy # madvise() flags -# beneath the iceberg memory management # # group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary -syscon madv MADV_NORMAL 0 0 0 0 0 0x00000080 # consensus & kNtFileAttributeNormal -syscon compat POSIX_FADV_NORMAL 0 0 0 0 0 0x00000080 # consensus & kNtFileAttributeNormal -syscon compat POSIX_MADV_NORMAL 0 0 0 0 0 0x00000080 # consensus & kNtFileAttributeNormal -syscon madv MADV_DONTNEED 4 4 4 4 4 0 # TODO(jart): weird nt decommit thing? -syscon compat POSIX_MADV_DONTNEED 4 4 4 4 4 0 # unix consensus -syscon compat POSIX_FADV_DONTNEED 4 0 4 4 4 0 # unix consensus -syscon madv MADV_RANDOM 1 1 1 1 1 0x10000000 # unix consensus & kNtFileFlagRandomAccess -syscon compat POSIX_MADV_RANDOM 1 1 1 1 1 0x10000000 # unix consensus & kNtFileFlagRandomAccess -syscon compat POSIX_FADV_RANDOM 1 0 1 1 1 0x10000000 # unix consensus & kNtFileFlagRandomAccess -syscon madv MADV_SEQUENTIAL 2 2 2 2 2 0x8000000 # unix consensus & kNtFileFlagSequentialScan -syscon compat POSIX_MADV_SEQUENTIAL 2 2 2 2 2 0x8000000 # unix consensus -syscon compat POSIX_FADV_SEQUENTIAL 2 0 2 2 2 0x8000000 # TODO(jart): double check xnu +syscon madv MADV_NORMAL 0 0 0 0 0 0 # consensus +syscon compat POSIX_FADV_NORMAL 0 0 0 0 0 0 # consensus +syscon compat POSIX_MADV_NORMAL 0 0 0 0 0 0 # consensus +syscon madv MADV_DONTNEED 4 4 4 4 4 127 # TODO(jart): weird nt decommit thing? +syscon compat POSIX_MADV_DONTNEED 4 4 4 4 4 127 # unix consensus +syscon compat POSIX_FADV_DONTNEED 4 127 4 4 4 127 # unix consensus +syscon madv MADV_RANDOM 1 1 1 1 1 1 # unix consensus +syscon compat POSIX_MADV_RANDOM 1 1 1 1 1 1 # unix consensus +syscon compat POSIX_FADV_RANDOM 1 127 1 1 1 1 # unix consensus +syscon madv MADV_SEQUENTIAL 2 2 2 2 2 2 # unix consensus +syscon compat POSIX_MADV_SEQUENTIAL 2 2 2 2 2 2 # unix consensus +syscon compat POSIX_FADV_SEQUENTIAL 2 127 2 2 2 2 # TODO(jart): double check xnu syscon madv MADV_WILLNEED 3 3 3 3 3 3 # unix consensus (faked on NT) syscon compat POSIX_MADV_WILLNEED 3 3 3 3 3 3 # unix consensus -syscon compat POSIX_FADV_WILLNEED 3 0 3 3 3 3 # TODO(jart): double check xnu -syscon madv MADV_MERGEABLE 12 0 0 0 0 0 # turns on (private anon range) page scanning and merging service (linux only) -syscon madv MADV_UNMERGEABLE 13 0 0 0 0 0 # turns off mergeable (linux only) +syscon compat POSIX_FADV_WILLNEED 3 127 3 3 3 3 # TODO(jart): double check xnu +syscon madv MADV_MERGEABLE 12 127 127 127 127 127 # turns on (private anon range) page scanning and merging service (linux only) +syscon madv MADV_UNMERGEABLE 13 127 127 127 127 127 # turns off mergeable (linux only) syscon madv MADV_FREE 8 5 5 6 6 8 # Linux 4.5+ (c. 2016) / NT Faked → VMOfferPriorityNormal (Win8+) -syscon madv MADV_HUGEPAGE 14 0 0 0 0 0 # TODO(jart): why would we need it? -syscon madv MADV_NOHUGEPAGE 15 0 0 0 0 0 # TODO(jart): why would we need it? -syscon madv MADV_DODUMP 17 0 0 0 0 0 # TODO(jart): what is it? -syscon madv MADV_DOFORK 11 0 0 0 0 0 # TODO(jart): what is it? -syscon madv MADV_DONTDUMP 16 0 0 0 0 0 # see MAP_CONCEAL in OpenBSD; TODO(jart): what is it? -syscon madv MADV_DONTFORK 10 0 0 0 0 0 # TODO(jart): what is it? -syscon madv MADV_HWPOISON 100 0 0 0 0 0 # TODO(jart): what is it? -syscon madv MADV_REMOVE 9 0 0 0 0 0 # TODO(jart): what is it? -syscon fadv POSIX_FADV_NOREUSE 5 0 5 0 5 0 # wut +syscon madv MADV_HUGEPAGE 14 127 127 127 127 127 # TODO(jart): why would we need it? +syscon madv MADV_NOHUGEPAGE 15 127 127 127 127 127 # TODO(jart): why would we need it? +syscon madv MADV_DODUMP 17 127 127 127 127 127 # TODO(jart): what is it? +syscon madv MADV_DOFORK 11 127 127 127 127 127 # TODO(jart): what is it? +syscon madv MADV_DONTDUMP 16 127 127 127 127 127 # see MAP_CONCEAL in OpenBSD; TODO(jart): what is it? +syscon madv MADV_DONTFORK 10 127 127 127 127 127 # TODO(jart): what is it? +syscon madv MADV_HWPOISON 100 127 127 127 127 127 # TODO(jart): what is it? +syscon madv MADV_REMOVE 9 127 127 127 127 127 # TODO(jart): what is it? +syscon fadv POSIX_FADV_NOREUSE 5 127 5 127 5 127 # wut # mmap(), mprotect(), etc. # digital restrictions management for the people @@ -439,11 +435,10 @@ syscon ioctl TIOCINQ 0x541b 0x4004667f 0x4004667f 0x4004667f 0x4004667f # # group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary syscon at AT_FDCWD -100 -2 -100 -100 -100 -100 # faked nt -syscon at AT_SYMLINK_FOLLOW 0x0400 0x40 0x0400 4 0x400 0 syscon at AT_SYMLINK_NOFOLLOW 0x0100 0x20 0x0200 2 0x200 0x0100 # faked nt +syscon at AT_SYMLINK_FOLLOW 0x0400 0x40 0x0400 4 0x400 0 # see linkat(2) syscon at AT_REMOVEDIR 0x0200 0x80 0x0800 8 0x800 0x0200 # faked nt syscon at AT_EACCESS 0x0200 0x10 0x0100 1 0x100 0 -syscon at AT_SYMLINK_FOLLOW 0x0400 0x40 0x0400 4 4 0 syscon at AT_EMPTY_PATH 0x1000 0 0 0 0 0 # linux 2.6.39+; see unlink, O_TMPFILE, etc. # memfd_create() flags @@ -471,7 +466,7 @@ syscon auxv AT_PHENT 4 0 4 0 4 0 syscon auxv AT_PHNUM 5 0 5 0 5 0 syscon auxv AT_PAGESZ 6 0 6 0 6 0 syscon auxv AT_BASE 7 0 7 0 7 0 # address of program interpreter -syscon auxv AT_FLAGS 8 0 0 0 0 0 +syscon auxv AT_FLAGS 8 0 8 0 8 0 syscon auxv AT_ENTRY 9 0 9 0 9 0 # entry address of executable syscon auxv AT_NOTELF 10 0 10 0 0 0 syscon auxv AT_OSRELDATE 0 0 18 0 0 0 @@ -487,10 +482,20 @@ syscon auxv AT_ICACHEBSIZE 20 0 0 0 0 0 syscon auxv AT_UCACHEBSIZE 21 0 0 0 0 0 syscon auxv AT_SECURE 23 0 0 0 0 0 syscon auxv AT_BASE_PLATFORM 24 0 0 0 0 0 -syscon auxv AT_RANDOM 25 0 0 0 0 0 # address of sixteen bytes of random data +syscon auxv AT_RANDOM 25 0 16 0 0 0 # address of sixteen bytes of random data; AT_CANARY on FreeBSD whose AT_CANARYLEN should be 64 syscon auxv AT_HWCAP2 26 0 0 0 0 0 -syscon auxv AT_EXECFN 31 31 999 999 2014 31 # address of string containing first argument passed to execve() used when running program [faked on non-linux] +syscon auxv AT_EXECFN 31 31 15 999 2014 31 # address of string containing first argument passed to execve() used when running program; AT_EXECPATH on FreeBSD syscon auxv AT_SYSINFO_EHDR 33 0 0 0 0 0 +syscon auxv AT_STACKBASE 0 0 0 0 13 0 +syscon auxv AT_EXECPATH 31 31 15 999 2014 31 # FreeBSD name for AT_EXECFN +syscon auxv AT_CANARY 0 0 16 0 0 0 +syscon auxv AT_CANARYLEN 0 0 17 0 0 0 +syscon auxv AT_NCPUS 0 0 19 0 0 0 +syscon auxv AT_PAGESIZES 0 0 20 0 0 0 +syscon auxv AT_PAGESIZESLEN 0 0 21 0 0 0 +syscon auxv AT_TIMEKEEP 0 0 22 0 0 0 +syscon auxv AT_STACKPROT 0 0 23 0 0 0 +syscon auxv AT_EHDRFLAGS 0 0 24 0 0 0 syscon auxv AT_NO_AUTOMOUNT 0x0800 0 0 0 0 0 # getrlimit() / setrlimit() resource parameter @@ -507,7 +512,7 @@ syscon rlimit RLIMIT_RSS 5 5 5 5 5 127 # max physical memory size syscon rlimit RLIMIT_NPROC 6 7 7 7 7 127 # max number of processes; see fork()→EAGAIN; bsd consensus syscon rlimit RLIMIT_NOFILE 7 8 8 8 8 127 # max number of open files; see accept()→EMFILE/ENFILE; bsd consensus syscon rlimit RLIMIT_MEMLOCK 8 6 6 6 6 127 # max locked-in-memory address space; bsd consensus -syscon rlimit RLIMIT_AS 9 5 10 127 10 127 # max virtual memory size in bytes; this one actually works; we set this to RLIMIT_DATA on OpenBSD +syscon rlimit RLIMIT_AS 9 5 10 2 10 0 # max virtual memory size in bytes; this one actually works; fudged as RLIMIT_DATA on OpenBSD syscon rlimit RLIMIT_LOCKS 10 127 127 127 127 127 # max flock() / fcntl() locks; bsd consensus syscon rlimit RLIMIT_SIGPENDING 11 127 127 127 127 127 # max sigqueue() can enqueue; bsd consensus syscon rlimit RLIMIT_MSGQUEUE 12 127 127 127 127 127 # meh posix message queues; bsd consensus @@ -522,10 +527,10 @@ syscon compat RLIMIT_VMEM 9 5 10 127 10 127 # same as RLIMIT_AS # resource limit special values # # group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary -syscon rlim RLIM_NLIMITS 16 9 15 9 12 0 # no clue why we need it -syscon rlim RLIM_INFINITY 0xffffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0 -syscon rlim RLIM_SAVED_CUR 0xffffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0 -syscon rlim RLIM_SAVED_MAX 0xffffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0 +syscon rlim RLIM_NLIMITS 16 9 15 9 12 1 +syscon rlim RLIM_INFINITY 0xffffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0xffffffffffffffff +syscon rlim RLIM_SAVED_CUR 0xffffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0xffffffffffffffff +syscon rlim RLIM_SAVED_MAX 0xffffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0x7fffffffffffffff 0xffffffffffffffff # sigaction() codes # @@ -535,7 +540,7 @@ syscon sigact SA_NOCLDWAIT 2 32 32 32 32 2 # changes SIGCHLD so t syscon sigact SA_SIGINFO 4 64 64 64 64 4 # asks kernel to provide ucontext_t argument, which has mutable cpu/fpu state of signalled process; and it is polyfilled by cosmopolitan; bsd consensus syscon sigact SA_ONSTACK 0x08000000 1 1 1 1 0x08000000 # causes signal handler to be called on stack provided by sigaltstack(2); bsd consensus syscon sigact SA_RESTART 0x10000000 2 2 2 2 0x10000000 # prevents signal delivery from triggering EINTR on i/o calls (e.g. read/write/open/wait/accept) but doesn't impact non-i/o blocking calls (e.g. poll, sigsuspend, nanosleep) which will still EINTR; bsd consensus -syscon sigact SA_NODEFER 0x40000000 16 16 16 16 0x40000000 # blocks signal delivery during signal handling (i.e. lets you use longjmp() in the signal handler); bsd consensus +syscon sigact SA_NODEFER 0x40000000 16 16 16 16 0x40000000 # lets signal handler be reentrant (e.g. so you can longjmp() out of signal handler); bsd consensus syscon sigact SA_RESETHAND 0x80000000 4 4 4 4 0x80000000 # causes signal handler to be called at most once and then set to SIG_DFL automatically; bsd consensus syscon compat SA_NOMASK 0x40000000 16 16 16 16 0x40000000 # same as SA_NODEFER syscon compat SA_ONESHOT 0x80000000 4 4 4 4 0x80000000 # same as SA_RESETHAND @@ -565,6 +570,7 @@ syscon sicode TRAP_BRKPT 1 1 1 1 1 1 # SIGTRAP; process breakpoin syscon sicode TRAP_TRACE 2 2 2 2 2 2 # SIGTRAP; process trace trap; unix consensus syscon sicode SEGV_MAPERR 1 1 1 1 1 1 # SIGSEGV; address not mapped to object; unix consensus syscon sicode SEGV_ACCERR 2 2 2 2 2 2 # SIGSEGV; invalid permissions for mapped object; unix consensus +syscon sicode SEGV_PKUERR -1 -1 100 -1 -1 -1 # SIGSEGV: x86: PKU violation syscon sicode FPE_INTDIV 1 7 2 1 1 1 # SIGFPE; integer divide by zero syscon sicode FPE_INTOVF 2 8 1 2 2 2 # SIGFPE; integer overflow syscon sicode FPE_FLTDIV 3 1 3 3 3 3 # SIGFPE; floating point divide by zero @@ -584,6 +590,7 @@ syscon sicode ILL_BADSTK 8 8 8 8 8 8 # SIGILL; internal stack err syscon sicode BUS_ADRALN 1 1 1 1 1 1 # SIGBUS; invalid address alignment; unix consensus syscon sicode BUS_ADRERR 2 2 2 2 2 2 # SIGBUS; non-existent physical address; unix consensus syscon sicode BUS_OBJERR 3 3 3 3 3 3 # SIGBUS; object specific hardware error; unix consensus +syscon sicode BUS_OOMERR -1 -1 100 -1 -1 -1 # SIGBUS; Non-standard: No memory. syscon sicode BUS_MCEERR_AR 4 0x80000000 0x80000000 0x80000000 0x80000000 0x80000000 # SIGBUS; Linux 2.6.32+ syscon sicode BUS_MCEERR_AO 5 0x80000000 0x80000000 0x80000000 0x80000000 0x80000000 # SIGBUS; Linux 2.6.32+ syscon sicode POLL_IN 1 1 1 1 1 1 # SIGIO; data input available; unix consensus @@ -592,6 +599,8 @@ syscon sicode POLL_MSG 3 3 3 3 3 3 # SIGIO; input message availab syscon sicode POLL_ERR 4 4 4 4 4 4 # SIGIO; i/o error; unix consensus syscon sicode POLL_PRI 5 5 5 5 5 5 # SIGIO; high priority input available; unix consensus syscon sicode POLL_HUP 6 6 6 6 6 6 # SIGIO; device disconnected; unix consensus +syscon sicode SYS_SECCOMP 1 -1 -1 -1 -1 -1 # SIGSYS; seccomp triggered +syscon sicode SYS_USER_DISPATCH 2 -1 -1 -1 -1 -1 # SIGSYS; syscall user dispatch triggered # sigaltstack() values # @@ -611,24 +620,24 @@ syscon clock CLOCK_MONOTONIC_RAW 4 4 0x4000 0x4000 0x4000 4 # actu syscon clock CLOCK_REALTIME_COARSE 5 -1 -1 -1 -1 -1 # Linux 2.6.32+; bsd consensus; not available on RHEL5 syscon clock CLOCK_MONOTONIC_COARSE 6 -1 -1 -1 -1 -1 # Linux 2.6.32+; bsd consensus; not available on RHEL5 syscon clock CLOCK_PROF -1 -1 2 -1 2 -1 # -syscon clock CLOCK_BOOTTIME 7 -1 -1 6 6 -1 # -syscon clock CLOCK_REALTIME_ALARM 8 -1 -1 -1 -1 -1 # bsd consensus -syscon clock CLOCK_BOOTTIME_ALARM 9 -1 -1 -1 -1 -1 # bsd consensus -syscon clock CLOCK_TAI 11 -1 -1 -1 -1 -1 # bsd consensus +syscon clock CLOCK_BOOTTIME 7 -1 -1 6 -1 -1 # +syscon clock CLOCK_REALTIME_ALARM 8 -1 -1 -1 -1 -1 # +syscon clock CLOCK_BOOTTIME_ALARM 9 -1 -1 -1 -1 -1 # +syscon clock CLOCK_TAI 11 -1 -1 -1 -1 -1 # # poll() # # group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary -syscon poll POLLIN 1 1 1 1 1 0x300 # unix consensus +syscon poll POLLIN 1 1 1 1 1 0x0300 # unix consensus; POLLRDNORM|POLLRDBAND on Windows syscon poll POLLPRI 2 2 2 2 2 0x0400 # unix consensus -syscon poll POLLOUT 4 4 4 4 4 0x10 # unix consensus -syscon poll POLLERR 8 8 8 8 8 1 # unix consensus -syscon poll POLLHUP 0x10 0x10 0x10 0x10 0x10 2 # unix consensus -syscon poll POLLNVAL 0x20 0x20 0x20 0x20 0x20 4 # unix consensus +syscon poll POLLOUT 4 4 4 4 4 0x0010 # unix consensus; POLLWRNORM on Windows +syscon poll POLLERR 8 8 8 8 8 0x0001 # unix consensus +syscon poll POLLHUP 0x10 0x10 0x10 0x10 0x10 0x0002 # unix consensus +syscon poll POLLNVAL 0x20 0x20 0x20 0x20 0x20 0x0004 # unix consensus syscon poll POLLRDBAND 0x80 0x80 0x80 0x80 0x80 0x0200 # unix consensus syscon poll POLLRDNORM 0x40 0x40 0x40 0x40 0x40 0x0100 # unix consensus -syscon poll POLLWRBAND 0x0200 0x0100 0x0100 0x0100 0x0100 0x20 # bsd consensus -syscon poll POLLWRNORM 0x0100 4 4 4 4 0x10 # bsd consensus +syscon poll POLLWRBAND 0x0200 0x0100 0x0100 0x0100 0x0100 0x0020 # bsd consensus +syscon poll POLLWRNORM 0x0100 4 4 4 4 0x0010 # bsd consensus syscon poll POLLRDHUP 0x2000 0x10 0x10 0x10 0x10 2 # bsd consensus (POLLHUP on non-Linux) # epoll @@ -660,30 +669,32 @@ syscon epoll EPOLLET 0x80000000 0x80000000 0x80000000 0x80000000 0x80000 # * -1 we define as no-op # # group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon so SO_DEBUG 1 1 1 1 1 1 # debugging is enabled; consensus +syscon so SO_TYPE 3 0x1008 0x1008 0x1008 0x1008 0x1008 # bsd consensus +syscon so SO_ERROR 4 0x1007 0x1007 0x1007 0x1007 0x1007 # takes int pointer and stores/clears the pending error code; bsd consensus +syscon so SO_ACCEPTCONN 30 2 2 2 2 2 # takes int pointer and stores boolean indicating if listen() was called on fd; bsd consensus syscon so SO_REUSEPORT 15 0x0200 0x0200 0x0200 0x0200 4 # bsd consensus (NT calls it SO_REUSEADDR) -syscon so SO_REUSEADDR 2 4 4 4 4 0 # bsd consensus (default behavior on NT) +syscon so SO_REUSEADDR 2 4 4 4 4 4 # bsd consensus (default behavior on NT) +syscon so SO_EXCLUSIVEADDRUSE 0 0 0 0 0 ~4 # bsd consensus (default behavior on NT) syscon so SO_KEEPALIVE 9 8 8 8 8 8 # bsd consensus syscon so SO_DONTROUTE 5 0x10 0x10 0x10 0x10 0x10 # bsd consensus -syscon so SO_BROADCAST 6 0x20 0x20 0x20 0x20 0x20 # bsd consensus +syscon so SO_BROADCAST 6 0x20 0x20 0x20 0x20 0x20 # socket is configured for broadcast messages; bsd consensus syscon so SO_USELOOPBACK 0 0x40 0x40 0x40 0x40 0x40 # bsd consensus syscon so SO_LINGER 13 0x80 0x80 0x80 0x80 0x80 # takes struct linger; causes close() return value to actually mean something; bsd consensus -syscon so SO_DEBUG 1 1 1 1 1 1 # consensus -syscon so SO_ACCEPTCONN 30 2 2 2 2 2 # takes int pointer and stores boolean indicating if listen() was called on fd; bsd consensus -syscon so SO_ERROR 4 0x1007 0x1007 0x1007 0x1007 0x1007 # takes int pointer and stores/clears the pending error code; bsd consensus +syscon so SO_DONTLINGER 0 0 0 0 0 ~0x80 # disables so_linger on windows syscon so SO_OOBINLINE 10 0x0100 0x0100 0x0100 0x0100 0x0100 # bsd consensus syscon so SO_SNDBUF 7 0x1001 0x1001 0x1001 0x1001 0x1001 # bsd consensus syscon so SO_RCVBUF 8 0x1002 0x1002 0x1002 0x1002 0x1002 # bsd consensus syscon so SO_RCVTIMEO 20 0x1006 0x1006 0x1006 0x100c 0x1006 # recv timeout; takes struct timeval (overrides SA_RESTART restoring EINTR behavior on recv/send/connect/accept/etc.; bsd consensus) syscon so SO_SNDTIMEO 21 0x1005 0x1005 0x1005 0x100b 0x1005 # send timeout; takes struct timeval; bsd consensus syscon so SO_RCVLOWAT 18 0x1004 0x1004 0x1004 0x1004 0x1004 # bsd consensus -syscon so SO_EXCLUSIVEADDRUSE 0 0 0 0 0 0xfffffffb # hoo boy syscon so SO_SNDLOWAT 19 0x1003 0x1003 0x1003 0x1003 0x1003 # bsd consensus -syscon so SO_TYPE 3 0x1008 0x1008 0x1008 0x1008 0x1008 # bsd consensus syscon so SO_TIMESTAMP 29 0x0400 0x0400 0x0800 0x2000 0 syscon so SO_SETFIB 0 0 0x1014 0 0 0 syscon so SO_DOMAIN 39 0 0x1019 0x1024 0 0 syscon so SO_MAX_PACING_RATE 47 0 0x1018 0 0 0 syscon so SO_PEERCRED 17 0 0 0x1022 0 0 +syscon so SO_EXCLUSIVEADDRUSE 0 0 0 0 0 0xfffffffb # hoo boy syscon so LOCAL_PEERCRED 0 1 1 0 0 0 syscon so SO_PROTOCOL 38 0 0x1016 0x1025 0 0 syscon so SO_ATTACH_BPF 50 0 0 0 0 0 @@ -721,9 +732,10 @@ syscon so SO_TIMESTAMPNS 35 0 0 0 0 0 syscon so SO_WIFI_STATUS 41 0 0 0 0 0 syscon sol SOL_IP 0 0 0 0 0 0 # consensus -syscon sol SOL_SOCKET 1 0xffff 0xffff 0xffff 0xffff 0xffff # bsd+nt consensus (todo: what's up with ipproto_icmp overlap) +syscon sol SOL_SOCKET 1 0xffff 0xffff 0xffff 0xffff 0xffff # yes it's actually 0xffff; bsd+nt consensus (todo: what's up with ipproto_icmp overlap) syscon sol SOL_TCP 6 6 6 6 6 6 # consensus syscon sol SOL_UDP 17 17 17 17 17 17 # consensus +syscon sol SOL_RAW 255 0 0 0 0 0 syscon sol SOL_IPV6 41 41 41 41 41 41 syscon sol SOL_ICMPV6 58 58 58 58 58 0 syscon sol SOL_AAL 265 0 0 0 0 0 @@ -743,7 +755,6 @@ syscon sol SOL_NFC 280 0 0 0 0 0 syscon sol SOL_PACKET 263 0 0 0 0 0 syscon sol SOL_PNPIPE 275 0 0 0 0 0 syscon sol SOL_PPPOL2TP 273 0 0 0 0 0 -syscon sol SOL_RAW 255 0 0 0 0 0 syscon sol SOL_RDS 276 0 0 0 0 0 syscon sol SOL_RXRPC 272 0 0 0 0 0 syscon sol SOL_TIPC 271 0 0 0 0 0 @@ -799,13 +810,14 @@ syscon tcp TCP_REPAIR_QUEUE 20 0 0 0 0 0 # what is it syscon tcp TCP_THIN_LINEAR_TIMEOUTS 16 0 0 0 0 0 # what is it # group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon ip IP_TOS 1 3 3 3 3 8 # bsd consensus +syscon ip IP_TTL 2 4 4 4 4 7 # bsd consensus +syscon ip IP_HDRINCL 3 2 2 2 2 2 # bsd consensus syscon ip IP_DEFAULT_MULTICAST_LOOP 1 1 1 1 1 1 # consensus syscon ip IP_DEFAULT_MULTICAST_TTL 1 1 1 1 1 1 # consensus syscon ip IP_PMTUDISC_DONT 0 0 0 0 0 0 # consensus -syscon ip IP_HDRINCL 3 2 2 2 2 2 # bsd consensus syscon ip IP_MAX_MEMBERSHIPS 20 0x0fff 0x0fff 0x0fff 0x0fff 20 # bsd consensus syscon ip IP_OPTIONS 4 1 1 1 1 1 # bsd consensus -syscon ip IP_TOS 1 3 3 3 3 8 # bsd consensus syscon ip IP_RECVTTL 12 24 65 31 23 21 syscon ip IP_ADD_MEMBERSHIP 35 12 12 12 12 5 # bsd consensus syscon ip IP_DROP_MEMBERSHIP 36 13 13 13 13 6 # bsd consensus @@ -816,7 +828,6 @@ syscon ip IP_RECVOPTS 6 5 5 5 5 0 # bsd consensus syscon ip IP_RECVRETOPTS 7 6 6 6 6 0 # bsd consensus syscon ip IP_RECVDSTADDR 0 7 7 7 7 0 # bsd consensus syscon ip IP_RETOPTS 7 8 8 8 8 0 # bsd consensus -syscon ip IP_TTL 2 4 4 4 4 7 # bsd consensus syscon ip IP_ADD_SOURCE_MEMBERSHIP 39 70 70 0 0 15 syscon ip IP_BLOCK_SOURCE 38 72 72 0 0 17 syscon ip IP_DROP_SOURCE_MEMBERSHIP 40 71 71 0 0 0x10 @@ -894,6 +905,7 @@ syscon ptrace PTRACE_O_TRACECLONE 0x0008 -1 -1 -1 -1 -1 syscon ptrace PTRACE_O_TRACEEXEC 0x0010 -1 -1 -1 -1 -1 syscon ptrace PTRACE_O_TRACEVFORKDONE 0x0020 -1 -1 -1 -1 -1 syscon ptrace PTRACE_O_TRACEEXIT 0x0040 -1 -1 -1 -1 -1 +syscon ptrace PTRACE_O_TRACESECCOMP 0x0080 -1 -1 -1 -1 -1 syscon ptrace PTRACE_O_MASK 0x007f -1 -1 -1 -1 -1 syscon ptrace PTRACE_EVENT_FORK 1 -1 -1 -1 -1 -1 syscon ptrace PTRACE_EVENT_VFORK 2 -1 -1 -1 -1 -1 @@ -901,7 +913,17 @@ syscon ptrace PTRACE_EVENT_CLONE 3 -1 -1 -1 -1 -1 syscon ptrace PTRACE_EVENT_EXEC 4 -1 -1 -1 -1 -1 syscon ptrace PTRACE_EVENT_VFORK_DONE 5 -1 -1 -1 -1 -1 syscon ptrace PTRACE_EVENT_EXIT 6 -1 -1 -1 -1 -1 +syscon ptrace PTRACE_EVENT_SECCOMP 7 -1 -1 -1 -1 -1 +syscon ptrace PTRACE_EVENT_STOP 128 -1 -1 -1 -1 -1 +# clone() codes +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon clone CLONE_VM 0x00000100 0x00000100 0x00000100 0x00000100 0x00000100 0x00000100 # intentionally symbolic so we can tell if clone() is being used to create threads + +# IPPROTO_* +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary syscon iproto IPPROTO_IP 0 0 0 0 0 0 # consensus syscon iproto IPPROTO_ICMP 1 1 1 1 1 1 # consensus syscon iproto IPPROTO_TCP 6 6 6 6 6 6 # consensus @@ -935,109 +957,6 @@ syscon iproto IPPROTO_BEETPH 94 0 0 0 0 0 syscon iproto IPPROTO_COMP 108 0 0 0 0 0 syscon iproto IPPROTO_DCCP 33 0 0 0 0 0 -syscon pr PR_SET_PTRACER_ANY -1 0 0 0 0 0 -syscon pr PR_ENDIAN_BIG 0 0 0 0 0 0 # consensus -syscon pr PR_FP_EXC_DISABLED 0 0 0 0 0 0 # consensus -syscon pr PR_MCE_KILL_CLEAR 0 0 0 0 0 0 # consensus -syscon pr PR_MCE_KILL_LATE 0 0 0 0 0 0 # consensus -syscon pr PR_SPEC_NOT_AFFECTED 0 0 0 0 0 0 # consensus -syscon pr PR_SPEC_STORE_BYPASS 0 0 0 0 0 0 # consensus -syscon pr PR_TIMING_STATISTICAL 0 0 0 0 0 0 # consensus -syscon pr PR_CAP_AMBIENT_IS_SET 1 0 0 0 0 0 -syscon pr PR_ENDIAN_LITTLE 1 0 0 0 0 0 -syscon pr PR_FPEMU_NOPRINT 1 0 0 0 0 0 -syscon pr PR_FP_EXC_NONRECOV 1 0 0 0 0 0 -syscon pr PR_FP_MODE_FR 1 0 0 0 0 0 -syscon pr PR_MCE_KILL_EARLY 1 0 0 0 0 0 -syscon pr PR_MCE_KILL_SET 1 0 0 0 0 0 -syscon pr PR_SET_MM_START_CODE 1 0 0 0 0 0 -syscon pr PR_SET_PDEATHSIG 1 0 0 0 0 0 -syscon pr PR_SPEC_PRCTL 1 0 0 0 0 0 -syscon pr PR_TIMING_TIMESTAMP 1 0 0 0 0 0 -syscon pr PR_TSC_ENABLE 1 0 0 0 0 0 -syscon pr PR_UNALIGN_NOPRINT 1 0 0 0 0 0 -syscon pr PR_CAP_AMBIENT_RAISE 2 0 0 0 0 0 -syscon pr PR_ENDIAN_PPC_LITTLE 2 0 0 0 0 0 -syscon pr PR_FPEMU_SIGFPE 2 0 0 0 0 0 -syscon pr PR_FP_EXC_ASYNC 2 0 0 0 0 0 -syscon pr PR_FP_MODE_FRE 2 0 0 0 0 0 -syscon pr PR_GET_PDEATHSIG 2 0 0 0 0 0 -syscon pr PR_MCE_KILL_DEFAULT 2 0 0 0 0 0 -syscon pr PR_SET_MM_END_CODE 2 0 0 0 0 0 -syscon pr PR_SPEC_ENABLE 2 0 0 0 0 0 -syscon pr PR_TSC_SIGSEGV 2 0 0 0 0 0 -syscon pr PR_UNALIGN_SIGBUS 2 0 0 0 0 0 -syscon pr PR_CAP_AMBIENT_LOWER 3 0 0 0 0 0 -syscon pr PR_FP_EXC_PRECISE 3 0 0 0 0 0 -syscon pr PR_GET_DUMPABLE 3 0 0 0 0 0 -syscon pr PR_SET_MM_START_DATA 3 0 0 0 0 0 -syscon pr PR_CAP_AMBIENT_CLEAR_ALL 4 0 0 0 0 0 -syscon pr PR_SET_DUMPABLE 4 0 0 0 0 0 -syscon pr PR_SET_MM_END_DATA 4 0 0 0 0 0 -syscon pr PR_SPEC_DISABLE 4 0 0 0 0 0 -syscon pr PR_GET_UNALIGN 5 0 0 0 0 0 -syscon pr PR_SET_MM_START_STACK 5 0 0 0 0 0 -syscon pr PR_SET_MM_START_BRK 6 0 0 0 0 0 -syscon pr PR_SET_UNALIGN 6 0 0 0 0 0 -syscon pr PR_GET_KEEPCAPS 7 0 0 0 0 0 -syscon pr PR_SET_MM_BRK 7 0 0 0 0 0 -syscon pr PR_SET_KEEPCAPS 8 0 0 0 0 0 -syscon pr PR_SET_MM_ARG_START 8 0 0 0 0 0 -syscon pr PR_SPEC_FORCE_DISABLE 8 0 0 0 0 0 -syscon pr PR_GET_FPEMU 9 0 0 0 0 0 -syscon pr PR_SET_MM_ARG_END 9 0 0 0 0 0 -syscon pr PR_SET_FPEMU 10 0 0 0 0 0 -syscon pr PR_SET_MM_ENV_START 10 0 0 0 0 0 -syscon pr PR_GET_FPEXC 11 0 0 0 0 0 -syscon pr PR_SET_MM_ENV_END 11 0 0 0 0 0 -syscon pr PR_SET_FPEXC 12 0 0 0 0 0 -syscon pr PR_SET_MM_AUXV 12 0 0 0 0 0 -syscon pr PR_GET_TIMING 13 0 0 0 0 0 -syscon pr PR_SET_MM_EXE_FILE 13 0 0 0 0 0 -syscon pr PR_SET_MM_MAP 14 0 0 0 0 0 -syscon pr PR_SET_TIMING 14 0 0 0 0 0 -syscon pr PR_SET_MM_MAP_SIZE 15 0 0 0 0 0 -syscon pr PR_SET_NAME 15 0 0 0 0 0 -syscon pr PR_GET_NAME 0x10 0 0 0 0 0 -syscon pr PR_GET_ENDIAN 19 0 0 0 0 0 -syscon pr PR_SET_ENDIAN 20 0 0 0 0 0 -syscon pr PR_GET_SECCOMP 21 0 0 0 0 0 -syscon pr PR_SET_SECCOMP 22 0 0 0 0 0 -syscon pr PR_CAPBSET_READ 23 0 0 0 0 0 -syscon pr PR_CAPBSET_DROP 24 0 0 0 0 0 -syscon pr PR_GET_TSC 25 0 0 0 0 0 -syscon pr PR_SET_TSC 26 0 0 0 0 0 -syscon pr PR_GET_SECUREBITS 27 0 0 0 0 0 -syscon pr PR_SET_SECUREBITS 28 0 0 0 0 0 -syscon pr PR_SET_TIMERSLACK 29 0 0 0 0 0 -syscon pr PR_GET_TIMERSLACK 30 0 0 0 0 0 -syscon pr PR_TASK_PERF_EVENTS_DISABLE 31 0 0 0 0 0 -syscon pr PR_TASK_PERF_EVENTS_ENABLE 0x20 0 0 0 0 0 -syscon pr PR_MCE_KILL 33 0 0 0 0 0 -syscon pr PR_MCE_KILL_GET 34 0 0 0 0 0 -syscon pr PR_SET_MM 35 0 0 0 0 0 -syscon pr PR_SET_CHILD_SUBREAPER 36 0 0 0 0 0 -syscon pr PR_GET_CHILD_SUBREAPER 37 0 0 0 0 0 -syscon pr PR_SET_NO_NEW_PRIVS 38 0 0 0 0 0 -syscon pr PR_GET_NO_NEW_PRIVS 39 0 0 0 0 0 -syscon pr PR_GET_TID_ADDRESS 40 0 0 0 0 0 -syscon pr PR_SET_THP_DISABLE 41 0 0 0 0 0 -syscon pr PR_GET_THP_DISABLE 42 0 0 0 0 0 -syscon pr PR_MPX_ENABLE_MANAGEMENT 43 0 0 0 0 0 -syscon pr PR_MPX_DISABLE_MANAGEMENT 44 0 0 0 0 0 -syscon pr PR_SET_FP_MODE 45 0 0 0 0 0 -syscon pr PR_GET_FP_MODE 46 0 0 0 0 0 -syscon pr PR_CAP_AMBIENT 47 0 0 0 0 0 -syscon pr PR_GET_SPECULATION_CTRL 52 0 0 0 0 0 -syscon pr PR_SET_SPECULATION_CTRL 53 0 0 0 0 0 -syscon pr PR_FP_EXC_SW_ENABLE 0x80 0 0 0 0 0 -syscon pr PR_FP_EXC_DIV 0x010000 0 0 0 0 0 -syscon pr PR_FP_EXC_OVF 0x020000 0 0 0 0 0 -syscon pr PR_FP_EXC_UND 0x040000 0 0 0 0 0 -syscon pr PR_FP_EXC_RES 0x080000 0 0 0 0 0 -syscon pr PR_FP_EXC_INV 0x100000 0 0 0 0 0 -syscon pr PR_SET_PTRACER 0x59616d61 0 0 0 0 0 - syscon sio SIOCADDMULTI 0x8931 0x80206931 0x80206931 0x80206931 0x80206931 0 # bsd consensus syscon sio SIOCATMARK 0x8905 0x40047307 0x40047307 0x40047307 0x40047307 0 # bsd consensus syscon sio SIOCDELMULTI 0x8932 0x80206932 0x80206932 0x80206932 0x80206932 0 # bsd consensus @@ -1191,9 +1110,6 @@ syscon pf PF_VSOCK 40 0 0 0 0 0 syscon pf PF_WANPIPE 25 0 0 0 0 0 syscon pf PF_X25 9 0 0 0 0 0 -syscon exit EXIT_SUCCESS 0 0 0 0 0 0 # consensus -syscon exit EXIT_FAILURE 1 1 1 1 1 1 # consensus - # Eric Allman's exit() codes # # - Broadly supported style guideline; @@ -1310,6 +1226,15 @@ syscon mount MNT_NOCLUSTERR 0 0 0x40000000 0 0 0 # disable cluster syscon mount MNT_NOCLUSTERW 0 0 0x80000000 0 0 0 # disable cluster write syscon mount MNT_SNAPSHOT 0 0x40000000 0x01000000 0 0 0 # confusing +# limits +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon limits PIPE_BUF 4096 512 512 512 512 4096 # bsd consensus +syscon limits _ARG_MAX 128*1024 1024*1024 512*1024 512*1024 256*1024 32767*2 # bsd consensus +syscon limits _NAME_MAX 255 255 255 255 511 255 # probably higher on windows? +syscon limits _PATH_MAX 4096 1024 1024 1024 1024 512 # cosmopolitan libc imposes a lower 512 limit; nt theoretically goes up to 32767 +syscon limits _NSIG 64 32 128 32 64 32 # _SIG_MAXSIG on FreeBSD + # unmount() flags # a.k.a. umount2() on linux # @@ -1378,6 +1303,14 @@ syscon prio PRIO_MIN -20 -20 -20 -20 -20 -20 # unix consensus / p syscon prio PRIO_MAX 20 20 20 20 20 20 # unix consensus / poly nt syscon prio NZERO 20 20 20 20 20 20 # unix consensus / polyfilled nt +# getrusage() who +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon rusage RUSAGE_SELF 0 0 0 0 0 0 # unix consensus & faked nt +syscon rusage RUSAGE_THREAD 1 99 1 1 1 1 # faked nt & unavailable on xnu +syscon rusage RUSAGE_CHILDREN -1 -1 -1 -1 -1 99 # unix consensus & unavailable on nt +syscon rusage RUSAGE_BOTH -2 99 99 99 99 99 # woop + # Teletypewriter Control, e.g. # # TCSETS → About 70,800 results (0.31 seconds) @@ -1450,6 +1383,25 @@ syscon termios ENDRUNDISC 0 0 0 0x9 0x9 0 # boop syscon termios TIOCPTMASTER 0 0 0x2000741c 0 0 0 # boop syscon termios NETGRAPHDISC 0 0 0x6 0 0 0 # boop syscon termios H4DISC 0 0 0x7 0 0 0 # boop + +# Teletypewriter Control Modes +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon termios CS5 0b0000000000000000 0b000000000000000000 0b000000000000000000 0b0000000000000000 0b0000000000000000 0b0000000000000000 # termios.c_cflag; consensus +syscon termios CS6 0b0000000000010000 0b000000000100000000 0b000000000100000000 0b0000000100000000 0b0000000100000000 0b0000000000010000 # termios.c_cflag; 6-bit characters +syscon termios CS7 0b0000000000100000 0b000000001000000000 0b000000001000000000 0b0000001000000000 0b0000001000000000 0b0000000000100000 # termios.c_cflag; 7-bit characters +syscon termios CS8 0b0000000000110000 0b000000001100000000 0b000000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 # termios.c_cflag; 8-bit characters +syscon termios CSIZE 0b0000000000110000 0b000000001100000000 0b000000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 # termios.c_cflag; mask for CS𝑥 flags +syscon termios CSTOPB 0b0000000001000000 0b000000010000000000 0b000000010000000000 0b0000010000000000 0b0000010000000000 0b0000000001000000 # termios.c_cflag; bsd consensus +syscon termios CREAD 0b0000000010000000 0b000000100000000000 0b000000100000000000 0b0000100000000000 0b0000100000000000 0b0000000010000000 # termios.c_cflag; bsd consensus +syscon termios PARENB 0b0000000100000000 0b000001000000000000 0b000001000000000000 0b0001000000000000 0b0001000000000000 0b0000000100000000 # termios.c_cflag +syscon termios PARODD 0b0000001000000000 0b000010000000000000 0b000010000000000000 0b0010000000000000 0b0010000000000000 0b0000001000000000 # termios.c_cflag +syscon termios HUPCL 0b0000010000000000 0b000100000000000000 0b000100000000000000 0b0100000000000000 0b0100000000000000 0b0000010000000000 # termios.c_cflag; bsd consensus +syscon termios CLOCAL 0b0000100000000000 0b1000000000000000 0b1000000000000000 0b1000000000000000 0b1000000000000000 0b0000100000000000 # termios.c_cflag; consensus + +# Teletypewriter Local Modes +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary syscon termios ISIG 0b0000000000000001 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000000000001 # termios.c_lflag|=ISIG makes Ctrl-C, Ctrl-\, etc. generate signals syscon termios ICANON 0b0000000000000010 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000000000010 # termios.c_lflag&=~ICANON disables 1960's version of gnu readline (see also VMIN) syscon termios XCASE 0b0000000000000100 0 0 16777216 0 0b0000000000000100 # termios.c_lflag @@ -1466,6 +1418,10 @@ syscon termios FLUSHO 0b0001000000000000 8388608 8388608 8388608 83886 syscon termios PENDIN 0b0100000000000000 536870912 536870912 536870912 536870912 0b0100000000000000 # termios.c_lflag syscon termios IEXTEN 0b1000000000000000 0b0000010000000000 0b0000010000000000 0b0000010000000000 0b0000010000000000 0b1000000000000000 # termios.c_lflag&=~IEXTEN disables platform input processing magic syscon termios EXTPROC 65536 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 65536 # termios.c_lflag + +# Teletypewriter Input Modes +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary syscon termios IGNBRK 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 # termios.c_iflag it's complicated, uart only? UNIXCONSENSUS syscon termios BRKINT 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 # termios.c_iflag it's complicated, uart only? UNIXCONSENSUS syscon termios IGNPAR 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 # termios.c_iflag|=IGNPAR ignores parity and framing errors; see PARMRK UNIXCONSENSUS @@ -1477,13 +1433,17 @@ syscon termios IGNCR 0b0000000010000000 0b0000000010000000 0b000000001000000 syscon termios ICRNL 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 # termios.c_iflag|=ICRNL maps \r → \n input UNIXCONSENSUS syscon termios IUCLC 0b0000001000000000 0 0 0b0001000000000000 0 0b0000001000000000 # termios.c_iflag|=IUCLC maps A-Z → a-z input syscon termios IXON 0b0000010000000000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000010000000000 # termios.c_iflag|=IXON enables flow rida -syscon termios IXANY 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 # termios.c_iflag|=IXANY tying will un-stuck teletype UNIXCONSENSUS +syscon termios IXANY 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 # termios.c_iflag|=IXANY typing will un-stuck teletype UNIXCONSENSUS syscon termios IXOFF 0b0001000000000000 0b0000010000000000 0b0000010000000000 0b0000010000000000 0b0000010000000000 0b0001000000000000 # termios.c_iflag|=IXOFF disables annoying display freeze keys syscon termios IMAXBEL 0b0010000000000000 0b0010000000000000 0b0010000000000000 0b0010000000000000 0b0010000000000000 0b0010000000000000 # termios.c_iflag|=IMAXBEL rings when queue full UNIXCONSENSUS syscon termios IUTF8 0b0100000000000000 0b0100000000000000 0 0 0 0b0100000000000000 # termios.c_iflag|=IUTF8 helps w/ rubout on UTF-8 input -syscon termios OPOST 0b0000000000000001 0b000000000000000001 0b000000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 # termios.c_oflag&=~OPOST disables output processing magic + +# Teletypewriter Output Modes +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon termios OPOST 0b0000000000000001 0b000000000000000001 0b000000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 # termios.c_oflag&=~OPOST disables output processing magic, e.g. MULTICS newlines syscon termios OLCUC 0b0000000000000010 0 0 0b0000000000100000 0 0b0000000000000010 # termios.c_oflag|=OLCUC maps a-z → A-Z output -syscon termios ONLCR 0b0000000000000100 0b000000000000000010 0b000000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000100 # termios.c_oflag|=ONLCR maps \n → \r\n output +syscon termios ONLCR 0b0000000000000100 0b000000000000000010 0b000000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000100 # termios.c_oflag|=ONLCR map \n → \r\n output (MULTICS newline) and requires OPOST syscon termios OCRNL 0b0000000000001000 0b000000000000010000 0b000000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000001000 # termios.c_oflag|=OCRNL maps \r → \n output syscon termios ONOCR 0b0000000000010000 0b000000000000100000 0b000000000000100000 0b0000000001000000 0b0000000001000000 0b0000000000010000 # termios.c_oflag|=ONOCR maps \r → ∅ output iff column 0 syscon termios ONLRET 0b0000000000100000 0b000000000001000000 0b000000000001000000 0b0000000010000000 0b0000000010000000 0b0000000000100000 # termios.c_oflag|=ONLRET maps \r → ∅ output @@ -1514,11 +1474,10 @@ syscon termios VT1 0b0100000000000000 0b010000000000000000 0b0100000000000 syscon termios FFDLY 0b1000000000000000 0b000100000000000000 0b000100000000000000 0 0 0b1000000000000000 # termios.c_oflag syscon termios FF0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0 0b0000000000000000 # termios.c_oflag syscon termios FF1 0b1000000000000000 0b000100000000000000 0b000100000000000000 0 0 0b1000000000000000 # termios.c_oflag -syscon termios CS5 0 0 0 0 0 0 # consensus -syscon termios CS6 0b0000000000010000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000000010000 # termios.c_cflag flag for 6-bit characters -syscon termios CS7 0b0000000000100000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000000000100000 # termios.c_cflag flag for 7-bit characters -syscon termios CS8 0b0000000000110000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 # termios.c_cflag flag for 8-bit characters -syscon termios CSIZE 0b0000000000110000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 # mask for CS𝑥 flags + +# Teletypewriter Special Control Character Assignments +# +# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary syscon termios NCCS 20 20 20 20 20 20 # ARRAYLEN(termios.c_cc); we schlep c_line into c_cc on linux syscon termios VINTR 0+1 8 8 8 8 0 # termios.c_cc[VINTR]=𝑥 syscon termios VQUIT 1+1 9 9 9 9 1 # termios.c_cc[VQUIT]=𝑥 @@ -1537,15 +1496,13 @@ syscon termios VDISCARD 13+1 15 15 15 15 13 # termios.c_cc[VDISCA syscon termios VWERASE 14+1 4 4 4 4 14 # termios.c_cc[VWERASE]=𝑥 syscon termios VLNEXT 15+1 14 14 14 14 15 # termios.c_cc[VLNEXT]=𝑥 syscon termios VEOL2 16+1 2 2 2 2 16 # termios.c_cc[VEOL2]=𝑥 + syscon termios TIOCSERGETLSR 0x5459 0 0 0 0 0 # syscon termios TIOCSERGETMULTI 0x545a 0 0 0 0 0 # syscon termios TIOCSERSETMULTI 0x545b 0 0 0 0 0 # syscon termios TIOCSER_TEMT 1 0 0 0 0 0 # syscon termios VERIFY 47 0 0 0 0 0 -syscon termios PARENB 0x0100 0x1000 0x1000 0x1000 0x1000 0 # -syscon termios PARODD 0x0200 0x2000 0x2000 0x2000 0x2000 0 # syscon termios CIBAUD 0x100f0000 0 0 0 0 0 -syscon termios CLOCAL 0x0800 0x8000 0x8000 0x8000 0x8000 0 # syscon termios CMSPAR 0x40000000 0 0 0 0 0 syscon termios BUSY 4 0 0 0 0 0 syscon termios CANBSIZ 255 0 0 0 0 0 @@ -1571,9 +1528,6 @@ syscon termios TCOON 1 2 2 2 2 1 # see tcflow; bsd consensus syscon termios TCIOFF 2 3 3 3 3 2 # see tcflow; bsd consensus syscon termios TCION 3 4 4 4 4 3 # see tcflow; bsd consensus -syscon termios CREAD 0x80 0x0800 0x0800 0x0800 0x0800 0 # bsd consensus -syscon termios CSTOPB 0x40 0x0400 0x0400 0x0400 0x0400 0 # bsd consensus -syscon termios HUPCL 0x0400 0x4000 0x4000 0x4000 0x4000 0 # bsd consensus syscon termios CSTART 17 17 17 17 17 0 # unix consensus syscon termios CSTOP 19 19 19 19 19 0 # unix consensus @@ -1689,15 +1643,6 @@ syscon misc TCPOPT_WINDOW 3 3 3 3 3 0 # unix consensus syscon lock LOCK_UNLOCK_CACHE 54 0 0 0 0 0 # wut -syscon misc ARPHRD_ETHER 1 1 1 1 1 0 # unix consensus -syscon misc ARPHRD_FCFABRIC 787 0 0 0 0 0 -syscon misc ARPHRD_IEEE80211 801 0 0 0 0 0 -syscon misc ARPHRD_IEEE80211_PRISM 802 0 0 0 0 0 -syscon misc ARPHRD_IEEE80211_RADIOTAP 803 0 0 0 0 0 -syscon misc ARPHRD_IEEE802154 804 0 0 0 0 0 -syscon misc ARPHRD_IEEE802_TR 800 0 0 0 0 0 -syscon misc ARPHRD_LOCALTLK 773 0 0 0 0 0 - syscon misc IP6F_MORE_FRAG 0x0100 0x0100 0x0100 0x0100 0x0100 0x0100 # consensus syscon misc IP6F_OFF_MASK 0xf8ff 0xf8ff 0xf8ff 0xf8ff 0xf8ff 0xf8ff # consensus syscon misc IP6F_RESERVED_MASK 0x0600 0x0600 0x0600 0x0600 0x0600 0x0600 # consensus @@ -1800,11 +1745,6 @@ syscon misc NL_TEXTMAX 0x7fffffff 0x0800 0x0800 255 255 0 syscon misc NL_NMAX 0x7fffffff 1 1 0 0 0 syscon misc NL_SETD 1 1 0 1 1 0 -syscon rusage RUSAGE_SELF 0 0 0 0 0 0 # unix consensus & faked nt -syscon rusage RUSAGE_CHILDREN -1 -1 -1 -1 -1 99 # unix consensus & unavailable on nt -syscon rusage RUSAGE_BOTH -2 99 99 99 99 99 # woop -syscon rusage RUSAGE_THREAD 1 99 1 1 1 1 # faked nt & unavailable on xnu - syscon misc FSETLOCKING_QUERY 0 0 0 0 0 0 # consensus syscon misc FSETLOCKING_BYCALLER 2 0 0 0 0 0 syscon misc FSETLOCKING_INTERNAL 1 0 0 0 0 0 @@ -1865,19 +1805,6 @@ syscon misc SCHED_BATCH 3 0 0 0 0 0 syscon misc SCHED_IDLE 5 0 0 0 0 0 syscon misc SCHED_RESET_ON_FORK 0x40000000 0 0 0 0 0 -syscon misc WRDE_APPEND 0 1 1 0 0 0 -syscon misc WRDE_BADCHAR 0 1 1 0 0 0 -syscon misc WRDE_BADVAL 0 2 2 0 0 0 -syscon misc WRDE_CMDSUB 0 3 3 0 0 0 -syscon misc WRDE_DOOFFS 0 2 2 0 0 0 -syscon misc WRDE_NOCMD 0 4 4 0 0 0 -syscon misc WRDE_NOSPACE 0 4 4 0 0 0 -syscon misc WRDE_NOSYS 0 5 5 0 0 0 -syscon misc WRDE_REUSE 0 8 8 0 0 0 -syscon misc WRDE_SHOWERR 0 0x10 0x10 0 0 0 -syscon misc WRDE_SYNTAX 0 6 6 0 0 0 -syscon misc WRDE_UNDEF 0 0x20 0x20 0 0 0 - syscon misc MCAST_BLOCK_SOURCE 43 84 84 0 0 43 syscon misc MCAST_JOIN_GROUP 42 80 80 0 0 41 syscon misc MCAST_JOIN_SOURCE_GROUP 46 82 82 0 0 45 @@ -1991,8 +1918,8 @@ syscon misc FALLOC_FL_UNSHARE_RANGE 0x40 -1 -1 -1 -1 -1 # bsd cons # System Call Numbers. # # group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology -syscon nr __NR_exit 0x003c 0x2000001 0x0001 0x0001 0x001 0xfff -syscon nr __NR_exit_group 0x00e7 0x2000001 0x0001 0x0001 0x001 0xfff +syscon nr __NR_exit 0x003c 0x2000169 0x01af 0x012e 0x136 0xfff # __bsdthread_terminate() on XNU, thr_exit() on FreeBSD, sys___threxit() on OpenBSD, __lwp_exit() on NetBSD +syscon nr __NR_exit_group 0x00e7 0x2000001 0x0001 0x0001 0x001 0xfff syscon nr __NR_read 0x0000 0x2000003 0x0003 0x0003 0x003 0xfff syscon nr __NR_write 0x0001 0x2000004 0x0004 0x0004 0x004 0xfff syscon nr __NR_open 0x0002 0x2000005 0x0005 0x0005 0x005 0xfff @@ -2008,7 +1935,7 @@ syscon nr __NR_msync 0x001a 0x2000041 0x0041 0x0100 0x115 0xfff syscon nr __NR_mprotect 0x000a 0x200004a 0x004a 0x004a 0x04a 0xfff syscon nr __NR_munmap 0x000b 0x2000049 0x0049 0x0049 0x049 0xfff syscon nr __NR_sigaction 0x000d 0x200002e 0x01a0 0x002e 0x154 0xfff -syscon nr __NR_sigprocmask 0x000e 0x2000030 0x0154 0x0030 0x125 0xfff +syscon nr __NR_sigprocmask 0x000e 0x2000149 0x0154 0x0030 0x125 0xfff syscon nr __NR_ioctl 0x0010 0x2000036 0x0036 0x0036 0x036 0xfff syscon nr __NR_pread 0x0011 0x2000099 0x01db 0x00ad 0x0ad 0xfff syscon nr __NR_pwrite 0x0012 0x200009a 0x01dc 0x00ae 0x0ae 0xfff @@ -2684,7 +2611,6 @@ syscon nr __NR_thr_create 0xfff 0xfff 0x01ae 0xfff 0xfff 0xfff syscon nr __NR_thr_exit 0xfff 0xfff 0x01af 0xfff 0xfff 0xfff syscon nr __NR_thr_kill 0xfff 0xfff 0x01b1 0xfff 0xfff 0xfff syscon nr __NR_thr_kill2 0xfff 0xfff 0x01e1 0xfff 0xfff 0xfff -syscon nr __NR_thr_new 0xfff 0xfff 0x01c7 0xfff 0xfff 0xfff syscon nr __NR_thr_self 0xfff 0xfff 0x01b0 0xfff 0xfff 0xfff syscon nr __NR_thr_set_name 0xfff 0xfff 0x01d0 0xfff 0xfff 0xfff syscon nr __NR_thr_suspend 0xfff 0xfff 0x01ba 0xfff 0xfff 0xfff @@ -2925,6 +2851,7 @@ syscon misc PTHREAD_MUTEX_NORMAL 0 0 0 3 3 0 syscon misc PTHREAD_MUTEX_ROBUST 0 0 1 0 0 0 syscon misc PTHREAD_PROCESS_PRIVATE 0 2 0 0 0 0 +# man fanotify(7) syscon fan FAN_CLASS_NOTIF 0 0 0 0 0 0 # consensus syscon fan FAN_ACCESS 1 0 0 0 0 0 syscon fan FAN_ACCESS_PERM 0x020000 0 0 0 0 0 @@ -3137,7 +3064,6 @@ syscon misc NGREG 23 0 0 0 0 0 syscon misc NOGROUP -1 0xffff 0xffff 0xffff 0xffff 0 # bsd consensus syscon misc ORDERED_QUEUE_TAG 34 0 0 0 0 0 syscon misc ORIG_RAX 15 0 0 0 0 0 -syscon misc PIPE_BUF 0x1000 0x0200 0x0200 0x0200 0x0200 0 # bsd consensus syscon misc PRE_FETCH 52 0 0 0 0 0 syscon misc QUEUE_FULL 20 0 0 0 0 0 syscon misc REASSIGN_BLOCKS 7 0 0 0 0 0 @@ -3236,6 +3162,7 @@ syscon misc USER_PROCESS 7 7 4 0 0 0 syscon misc YESEXPR 0x050000 52 52 47 47 0 syscon misc YESSTR 0x050002 54 54 46 46 0 +# man inotify(7) syscon in IN_LOOPBACKNET 127 127 127 127 127 0 # unix consensus syscon in IN_ACCESS 1 0 0 0 0 0 syscon in IN_ALL_EVENTS 0x0fff 0 0 0 0 0 @@ -3264,84 +3191,6 @@ syscon in IN_OPEN 0x20 0 0 0 0 0 syscon in IN_Q_OVERFLOW 0x4000 0 0 0 0 0 syscon in IN_UNMOUNT 0x2000 0 0 0 0 0 -syscon posix _POSIX_ARG_MAX 0x1000 0x1000 0x1000 0x1000 0x1000 0 # unix consensus -syscon posix _POSIX_CHILD_MAX 25 25 25 25 25 0 # unix consensus -syscon posix _POSIX_HOST_NAME_MAX 255 255 255 255 255 0 # unix consensus -syscon posix _POSIX_LINK_MAX 8 8 8 8 8 0 # unix consensus -syscon posix _POSIX_LOGIN_NAME_MAX 9 9 9 9 9 0 # unix consensus -syscon posix _POSIX_MAX_CANON 255 255 255 255 255 0 # unix consensus -syscon posix _POSIX_MAX_INPUT 255 255 255 255 255 0 # unix consensus -syscon posix _POSIX_NAME_MAX 14 14 14 14 14 14 # forced consensus -syscon posix _POSIX_NGROUPS_MAX 8 8 8 8 8 0 # unix consensus -syscon posix _POSIX_OPEN_MAX 20 20 20 20 20 20 # forced consensus -syscon posix _POSIX_PATH_MAX 255 255 255 255 255 255 # forced consensus -syscon posix _POSIX_PIPE_BUF 0x0200 0x0200 0x0200 0x0200 0x0200 0 # unix consensus -syscon posix _POSIX_RE_DUP_MAX 255 255 255 255 255 0 # unix consensus -syscon posix _POSIX_SEM_NSEMS_MAX 0x0100 0x0100 0x0100 0x0100 0x0100 0 # unix consensus -syscon posix _POSIX_SEM_VALUE_MAX 0x7fff 0x7fff 0x7fff 0x7fff 0x7fff 0 # unix consensus -syscon posix _POSIX_SSIZE_MAX 0x7fff 0x7fff 0x7fff 0x7fff 0x7fff 0 # unix consensus -syscon posix _POSIX_STREAM_MAX 8 8 8 8 8 0 # unix consensus -syscon posix _POSIX_SYMLINK_MAX 255 255 255 255 255 0 # unix consensus -syscon posix _POSIX_SYMLOOP_MAX 8 8 8 8 8 0 # unix consensus -syscon posix _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 4 4 4 4 0 # unix consensus -syscon posix _POSIX_THREAD_KEYS_MAX 0x80 0x80 0x80 0x80 0x80 0 # unix consensus -syscon posix _POSIX_TTY_NAME_MAX 9 9 9 9 9 0 # unix consensus -syscon posix _POSIX_TZNAME_MAX 6 6 6 6 6 0 # unix consensus -syscon posix _POSIX_CLOCK_SELECTION 0x031069 -1 -1 -1 -1 0 # bsd consensus -syscon posix _POSIX_FSYNC 0x031069 0x030db0 0x030db0 0x030db0 0x030db0 0 # bsd consensus -syscon posix _POSIX_MAPPED_FILES 0x031069 0x030db0 0x030db0 0x030db0 0x030db0 0 # bsd consensus -syscon posix _POSIX_MEMORY_PROTECTION 0x031069 0x030db0 0x030db0 0x030db0 0x030db0 0 # bsd consensus -syscon posix _POSIX_READER_WRITER_LOCKS 0x031069 0x030db0 0x030db0 0x030db0 0x030db0 0 # bsd consensus -syscon posix _POSIX_THREADS 0x031069 0x030db0 0x030db0 0x030db0 0x030db0 0 # bsd consensus -syscon posix _POSIX_THREAD_ATTR_STACKADDR 0x031069 0x030db0 0x030db0 0x030db0 0x030db0 0 # bsd consensus -syscon posix _POSIX_THREAD_ATTR_STACKSIZE 0x031069 0x030db0 0x030db0 0x030db0 0x030db0 0 # bsd consensus -syscon posix _POSIX_ADVISORY_INFO 0x031069 -1 0x030db0 -1 -1 0 -syscon posix _POSIX_ASYNCHRONOUS_IO 0x031069 -1 0x030db0 -1 -1 0 -syscon posix _POSIX_BARRIERS 0x031069 -1 0x030db0 0x030db0 0x030db0 0 -syscon posix _POSIX_JOB_CONTROL 1 0x030db0 1 1 1 0 -syscon posix _POSIX_MEMLOCK 0x031069 -1 -1 0x030db0 0x030db0 0 -syscon posix _POSIX_MEMLOCK_RANGE 0x031069 -1 0x030db0 0x030db0 0x030db0 0 -syscon posix _POSIX_MESSAGE_PASSING 0x031069 -1 0x030db0 -1 -1 0 -syscon posix _POSIX_NO_TRUNC 1 0x030db0 1 1 1 0 -syscon posix _POSIX_RAW_SOCKETS 0x031069 -1 0x030db0 0x030db0 0x030db0 0 -syscon posix _POSIX_REALTIME_SIGNALS 0x031069 -1 0x030db0 -1 -1 0 -syscon posix _POSIX_REGEXP 1 0x030db0 1 1 1 0 -syscon posix _POSIX_SEMAPHORES 0x031069 -1 0x030db0 0x030db0 0x030db0 0 -syscon posix _POSIX_SHARED_MEMORY_OBJECTS 0x031069 -1 0x030db0 0x031069 0x031069 0 -syscon posix _POSIX_SHELL 1 0x030db0 1 1 1 0 -syscon posix _POSIX_SPAWN 0x031069 -1 0x030db0 0x030db0 0x030db0 0 -syscon posix _POSIX_SPIN_LOCKS 0x031069 -1 0x030db0 0x030db0 0x030db0 0 -syscon posix _POSIX_THREAD_PRIORITY_SCHEDULING 0x031069 -1 0x030db0 -1 -1 0 -syscon posix _POSIX_THREAD_PROCESS_SHARED 0x031069 0x030db0 0x030db0 -1 -1 0 -syscon posix _POSIX_THREAD_SAFE_FUNCTIONS 0x031069 0x030db0 -1 0x030db0 0x030db0 0 -syscon posix _POSIX_THREAD_THREADS_MAX 0x40 0x40 0x40 4 4 0 -syscon posix _POSIX_TIMEOUTS 0x031069 -1 0x030db0 0x030db0 0x030db0 0 -syscon posix _POSIX_TIMERS 0x031069 -1 0x030db0 -1 -1 0 -syscon posix _POSIX_VERSION 0x031069 0x030db0 0x030db0 0x031069 0x031069 0 -syscon posix _POSIX_VDISABLE 0 255 255 255 255 0 # bsd consensus -syscon posix _POSIX_AIO_LISTIO_MAX 2 2 2 0 0 0 -syscon posix _POSIX_AIO_MAX 1 1 1 0 0 0 -syscon posix _POSIX_CHOWN_RESTRICTED 0 0x030db0 1 1 1 0 -syscon posix _POSIX_CLOCKRES_MIN 0x01312d00 0 0x01312d00 0x01312d00 0x01312d00 0 -syscon posix _POSIX_CPUTIME 0 -1 0x030db0 0x031069 0x031069 0 -syscon posix _POSIX_DELAYTIMER_MAX 0x20 0x20 0x20 0 0 0 -syscon posix _POSIX_MONOTONIC_CLOCK 0 -1 0x030db0 0x030db0 0x030db0 0 -syscon posix _POSIX_MQ_OPEN_MAX 8 8 8 0 0 0 -syscon posix _POSIX_MQ_PRIO_MAX 0x20 0x20 0x20 0 0 0 -syscon posix _POSIX_RTSIG_MAX 8 8 8 0 0 0 -syscon posix _POSIX_SAVED_IDS 1 0x030db0 0 1 1 0 -syscon posix _POSIX_SIGQUEUE_MAX 0x20 0x20 0x20 0 0 0 -syscon posix _POSIX_THREAD_CPUTIME 0 -1 0x030db0 0x031069 0x031069 0 -syscon posix _POSIX_TIMER_MAX 0x20 0x20 0x20 0 0 0 -syscon posix _POSIX_IPV6 0x031069 0x030db0 0 0 0 0 -syscon posix _POSIX_SS_REPL_MAX 0 4 4 0 0 0 -syscon posix _POSIX_TRACE_EVENT_NAME_MAX 0 30 30 0 0 0 -syscon posix _POSIX_TRACE_NAME_MAX 0 8 8 0 0 0 -syscon posix _POSIX_TRACE_SYS_MAX 0 8 8 0 0 0 -syscon posix _POSIX_TRACE_USER_EVENT_MAX 0 0x20 0x20 0 0 0 -syscon posix _POSIX_V6_LP64_OFF64 1 1 0 0 0 0 -syscon posix _POSIX_V7_LP64_OFF64 1 1 0 0 0 0 - syscon misc TYPE_DISK 0 0 0 0 0 0 # consensus syscon misc TYPE_A 1 1 1 1 1 0 # unix consensus syscon misc TYPE_E 2 2 2 2 2 0 # unix consensus @@ -3357,18 +3206,6 @@ syscon misc TYPE_SCANNER 6 0 0 0 0 0 syscon misc TYPE_TAPE 1 0 0 0 0 0 syscon misc TYPE_WORM 4 0 0 0 0 0 -syscon misc _POSIX2_BC_BASE_MAX 99 99 99 99 99 0 # unix consensus -syscon misc _POSIX2_BC_DIM_MAX 0x0800 0x0800 0x0800 0x0800 0x0800 0 # unix consensus -syscon misc _POSIX2_BC_SCALE_MAX 99 99 99 99 99 0 # unix consensus -syscon misc _POSIX2_BC_STRING_MAX 0x03e8 0x03e8 0x03e8 0x03e8 0x03e8 0 # unix consensus -syscon misc _POSIX2_CHARCLASS_NAME_MAX 14 14 14 14 14 0 # unix consensus -syscon misc _POSIX2_COLL_WEIGHTS_MAX 2 2 2 2 2 0 # unix consensus -syscon misc _POSIX2_EXPR_NEST_MAX 0x20 0x20 0x20 0x20 0x20 0 # unix consensus -syscon misc _POSIX2_LINE_MAX 0x0800 0x0800 0x0800 0x0800 0x0800 0 # unix consensus -syscon misc _POSIX2_RE_DUP_MAX 255 255 255 255 255 0 # unix consensus -syscon misc _POSIX2_C_BIND 0x031069 0x030db0 0x030db0 0x030db0 0x030db0 0 # bsd consensus -syscon misc _POSIX2_VERSION 0x031069 0x030db0 0x030a2c 0x031069 0x031069 0 - syscon nd ND_RA_FLAG_MANAGED 0x80 0x80 0x80 0x80 0x80 0x80 # consensus syscon nd ND_RA_FLAG_OTHER 0x40 0x40 0x40 0x40 0x40 0x40 # consensus syscon nd ND_NA_FLAG_OVERRIDE 0x20 0x20 0x20 0x20 0x20 0x20000000 # unix consensus @@ -3398,23 +3235,6 @@ syscon misc N_STRIP 4 0 0 0 0 0 syscon misc N_SYNC_PPP 14 0 0 0 0 0 syscon misc N_X25 6 0 0 0 0 0 -syscon misc BLKTYPE 52 52 52 52 52 0 # unix consensus -syscon misc BLKBSZGET 0x80081270 0 0 0 0 0 -syscon misc BLKBSZSET 0x40081271 0 0 0 0 0 -syscon misc BLKFLSBUF 0x1261 0 0 0 0 0 -syscon misc BLKFRAGET 0x1265 0 0 0 0 0 -syscon misc BLKFRASET 0x1264 0 0 0 0 0 -syscon misc BLKGETSIZE 0x1260 0 0 0 0 0 -syscon misc BLKGETSIZE64 0x80081272 0 0 0 0 0 -syscon misc BLKRAGET 0x1263 0 0 0 0 0 -syscon misc BLKRASET 0x1262 0 0 0 0 0 -syscon misc BLKROGET 0x125e 0 0 0 0 0 -syscon misc BLKROSET 0x125d 0 0 0 0 0 -syscon misc BLKRRPART 0x125f 0 0 0 0 0 -syscon misc BLKSECTGET 0x1267 0 0 0 0 0 -syscon misc BLKSECTSET 0x1266 0 0 0 0 0 -syscon misc BLKSSZGET 0x1268 0 0 0 0 0 - syscon misc ETH_P_CUST 0x6006 0 0 0 0 0 syscon misc ETH_P_DDCMP 6 0 0 0 0 0 syscon misc ETH_P_DEC 0x6000 0 0 0 0 0 @@ -3430,135 +3250,4 @@ syscon misc ETH_P_RARP 0x8035 0 0 0 0 0 syscon misc ETH_P_SCA 0x6007 0 0 0 0 0 syscon misc ETH_P_WAN_PPP 7 0 0 0 0 0 -syscon scsi SCSI_IOCTL_BENCHMARK_COMMAND 3 0 0 0 0 0 -syscon scsi SCSI_IOCTL_DOORLOCK 0x5380 0 0 0 0 0 -syscon scsi SCSI_IOCTL_DOORUNLOCK 0x5381 0 0 0 0 0 -syscon scsi SCSI_IOCTL_GET_BUS_NUMBER 0x5386 0 0 0 0 0 -syscon scsi SCSI_IOCTL_GET_IDLUN 0x5382 0 0 0 0 0 -syscon scsi SCSI_IOCTL_PROBE_HOST 0x5385 0 0 0 0 0 -syscon scsi SCSI_IOCTL_SEND_COMMAND 1 0 0 0 0 0 -syscon scsi SCSI_IOCTL_START_UNIT 5 0 0 0 0 0 -syscon scsi SCSI_IOCTL_STOP_UNIT 6 0 0 0 0 0 -syscon scsi SCSI_IOCTL_SYNC 4 0 0 0 0 0 -syscon scsi SCSI_IOCTL_TAGGED_DISABLE 0x5384 0 0 0 0 0 -syscon scsi SCSI_IOCTL_TAGGED_ENABLE 0x5383 0 0 0 0 0 -syscon scsi SCSI_IOCTL_TEST_UNIT_READY 2 0 0 0 0 0 -syscon scsi BUS_DEVICE_RESET 12 0 0 0 0 0 # SIGBUS; -syscon scsi READ_10 40 0 0 0 0 0 -syscon scsi READ_12 168 0 0 0 0 0 -syscon scsi READ_6 8 0 0 0 0 0 -syscon scsi READ_BLOCK_LIMITS 5 0 0 0 0 0 -syscon scsi READ_BUFFER 60 0 0 0 0 0 -syscon scsi READ_CAPACITY 37 0 0 0 0 0 -syscon scsi READ_DEFECT_DATA 55 0 0 0 0 0 -syscon scsi READ_ELEMENT_STATUS 184 0 0 0 0 0 -syscon scsi READ_LONG 62 0 0 0 0 0 -syscon scsi READ_POSITION 52 0 0 0 0 0 -syscon scsi READ_REVERSE 15 0 0 0 0 0 -syscon scsi READ_TOC 67 0 0 0 0 0 -syscon scsi WRITE_10 42 0 0 0 0 0 -syscon scsi WRITE_12 170 0 0 0 0 0 -syscon scsi WRITE_6 10 0 0 0 0 0 -syscon scsi WRITE_BUFFER 59 0 0 0 0 0 -syscon scsi WRITE_FILEMARKS 0x10 0 0 0 0 0 -syscon scsi WRITE_LONG 63 0 0 0 0 0 -syscon scsi WRITE_LONG_2 234 0 0 0 0 0 -syscon scsi WRITE_SAME 65 0 0 0 0 0 -syscon scsi WRITE_VERIFY 46 0 0 0 0 0 -syscon scsi WRITE_VERIFY_12 174 0 0 0 0 0 - -syscon log LOG_EMERG 0 0 0 0 0 0 # consensus -syscon log LOG_KERN 0 0 0 0 0 0 # consensus -syscon log LOG_ALERT 1 1 1 1 1 1 # unix consensus -syscon log LOG_PID 1 1 1 1 1 1 # unix consensus -syscon log LOG_CONS 2 2 2 2 2 2 # unix consensus -syscon log LOG_CRIT 2 2 2 2 2 2 # unix consensus -syscon log LOG_ERR 3 3 3 3 3 3 # unix consensus -syscon log LOG_ODELAY 4 4 4 4 4 4 # unix consensus -syscon log LOG_WARNING 4 4 4 4 4 4 # unix consensus -syscon log LOG_NOTICE 5 5 5 5 5 5 # unix consensus -syscon log LOG_INFO 6 6 6 6 6 6 # unix consensus -syscon log LOG_DEBUG 7 7 7 7 7 7 # unix consensus -syscon log LOG_PRIMASK 7 7 7 7 7 7 # unix consensus -syscon log LOG_NDELAY 8 8 8 8 8 8 # unix consensus -syscon log LOG_USER 8 8 8 8 8 8 # unix consensus -syscon log LOG_MAIL 0x10 0x10 0x10 0x10 0x10 0x10 # unix consensus -syscon log LOG_NOWAIT 0x10 0x10 0x10 0x10 0x10 0x10 # unix consensus -syscon log LOG_DAEMON 24 24 24 24 24 24 # unix consensus -syscon log LOG_NFACILITIES 24 25 24 24 24 24 -syscon log LOG_AUTH 0x20 0x20 0x20 0x20 0x20 0x20 # unix consensus -syscon log LOG_PERROR 0x20 0x20 0x20 0x20 0x20 0x20 # unix consensus -syscon log LOG_SYSLOG 40 40 40 40 40 40 # unix consensus -syscon log LOG_LPR 48 48 48 48 48 48 # unix consensus -syscon log LOG_NEWS 56 56 56 56 56 56 # unix consensus -syscon log LOG_UUCP 0x40 0x40 0x40 0x40 0x40 40 # unix consensus -syscon log LOG_CRON 72 72 72 72 72 72 # unix consensus -syscon log LOG_SELECT 76 0 0 0 0 0 -syscon log LOG_SENSE 77 0 0 0 0 0 -syscon log LOG_LOCAL0 0x80 0x80 0x80 0x80 0x80 0x80 # unix consensus -syscon log LOG_LOCAL1 136 136 136 136 136 136 # unix consensus -syscon log LOG_LOCAL2 144 144 144 144 144 144 # unix consensus -syscon log LOG_LOCAL3 152 152 152 152 152 152 # unix consensus -syscon log LOG_LOCAL4 160 160 160 160 160 160 # unix consensus -syscon log LOG_LOCAL5 168 168 168 168 168 168 # unix consensus -syscon log LOG_LOCAL6 176 176 176 176 176 176 # unix consensus -syscon log LOG_LOCAL7 184 184 184 184 184 184 # unix consensus -syscon log LOG_FACMASK 0x03f8 0x03f8 0x03f8 0x03f8 0x03f8 0x03f8 # unix consensus - -syscon sg SG_DXFER_TO_FROM_DEV -4 0 0 0 0 0 -syscon sg SG_DXFER_FROM_DEV -3 0 0 0 0 0 -syscon sg SG_DXFER_TO_DEV -2 0 0 0 0 0 -syscon sg SG_DXFER_NONE -1 0 0 0 0 0 -syscon sg SG_DEF_COMMAND_Q 0 0 0 0 0 0 # consensus -syscon sg SG_DEF_FORCE_LOW_DMA 0 0 0 0 0 0 # consensus -syscon sg SG_DEF_FORCE_PACK_ID 0 0 0 0 0 0 # consensus -syscon sg SG_DEF_KEEP_ORPHAN 0 0 0 0 0 0 # consensus -syscon sg SG_DEF_UNDERRUN_FLAG 0 0 0 0 0 0 # consensus -syscon sg SG_INFO_INDIRECT_IO 0 0 0 0 0 0 # consensus -syscon sg SG_INFO_OK 0 0 0 0 0 0 # consensus -syscon sg SG_SCSI_RESET_NOTHING 0 0 0 0 0 0 # consensus -syscon sg SG_DEFAULT_RETRIES 1 0 0 0 0 0 -syscon sg SG_FLAG_DIRECT_IO 1 0 0 0 0 0 -syscon sg SG_INFO_CHECK 1 0 0 0 0 0 -syscon sg SG_INFO_OK_MASK 1 0 0 0 0 0 -syscon sg SG_SCSI_RESET_DEVICE 1 0 0 0 0 0 -syscon sg SG_FLAG_LUN_INHIBIT 2 0 0 0 0 0 -syscon sg SG_INFO_DIRECT_IO 2 0 0 0 0 0 -syscon sg SG_SCSI_RESET_BUS 2 0 0 0 0 0 -syscon sg SG_SCSI_RESET_HOST 3 0 0 0 0 0 -syscon sg SG_INFO_MIXED_IO 4 0 0 0 0 0 -syscon sg SG_INFO_DIRECT_IO_MASK 6 0 0 0 0 0 -syscon misc VOLUME_OVERFLOW 13 0 0 0 0 0 -syscon sg SG_MAX_QUEUE 0x10 0 0 0 0 0 -syscon sg SG_MAX_SENSE 0x10 0 0 0 0 0 -syscon sg SG_DEFAULT_TIMEOUT 0x1770 0 0 0 0 0 -syscon sg SG_SET_TIMEOUT 0x2201 0 0 0 0 0 -syscon sg SG_GET_TIMEOUT 0x2202 0 0 0 0 0 -syscon sg SG_EMULATED_HOST 0x2203 0 0 0 0 0 -syscon sg SG_SET_TRANSFORM 0x2204 0 0 0 0 0 -syscon sg SG_GET_TRANSFORM 0x2205 0 0 0 0 0 -syscon sg SG_GET_COMMAND_Q 0x2270 0 0 0 0 0 -syscon sg SG_SET_COMMAND_Q 0x2271 0 0 0 0 0 -syscon sg SG_GET_RESERVED_SIZE 0x2272 0 0 0 0 0 -syscon sg SG_SET_RESERVED_SIZE 0x2275 0 0 0 0 0 -syscon sg SG_GET_SCSI_ID 0x2276 0 0 0 0 0 -syscon sg SG_SET_FORCE_LOW_DMA 0x2279 0 0 0 0 0 -syscon sg SG_GET_LOW_DMA 0x227a 0 0 0 0 0 -syscon sg SG_SET_FORCE_PACK_ID 0x227b 0 0 0 0 0 -syscon sg SG_GET_PACK_ID 0x227c 0 0 0 0 0 -syscon sg SG_GET_NUM_WAITING 0x227d 0 0 0 0 0 -syscon sg SG_SET_DEBUG 0x227e 0 0 0 0 0 -syscon sg SG_GET_SG_TABLESIZE 0x227f 0 0 0 0 0 -syscon sg SG_GET_VERSION_NUM 0x2282 0 0 0 0 0 -syscon sg SG_NEXT_CMD_LEN 0x2283 0 0 0 0 0 -syscon sg SG_SCSI_RESET 0x2284 0 0 0 0 0 -syscon sg SG_IO 0x2285 0 0 0 0 0 -syscon sg SG_GET_REQUEST_TABLE 0x2286 0 0 0 0 0 -syscon sg SG_SET_KEEP_ORPHAN 0x2287 0 0 0 0 0 -syscon sg SG_GET_KEEP_ORPHAN 0x2288 0 0 0 0 0 -syscon sg SG_BIG_BUFF 0x8000 0 0 0 0 0 -syscon sg SG_DEF_RESERVED_SIZE 0x8000 0 0 0 0 0 -syscon sg SG_SCATTER_SZ 0x8000 0 0 0 0 0 -syscon sg SG_FLAG_NO_DXFER 0x010000 0 0 0 0 0 - # https://youtu.be/GUQUD3IMbb4?t=85 diff --git a/libc/sysv/consts/ARPHRD_ETHER.S b/libc/sysv/consts/ARPHRD_ETHER.S deleted file mode 100644 index 357ff0d06..000000000 --- a/libc/sysv/consts/ARPHRD_ETHER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,ARPHRD_ETHER,1,1,1,1,1,0 diff --git a/libc/sysv/consts/ARPHRD_FCFABRIC.S b/libc/sysv/consts/ARPHRD_FCFABRIC.S deleted file mode 100644 index 2eb31ea88..000000000 --- a/libc/sysv/consts/ARPHRD_FCFABRIC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,ARPHRD_FCFABRIC,787,0,0,0,0,0 diff --git a/libc/sysv/consts/ARPHRD_IEEE80211.S b/libc/sysv/consts/ARPHRD_IEEE80211.S deleted file mode 100644 index 5dc5ccbff..000000000 --- a/libc/sysv/consts/ARPHRD_IEEE80211.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,ARPHRD_IEEE80211,801,0,0,0,0,0 diff --git a/libc/sysv/consts/ARPHRD_IEEE80211_PRISM.S b/libc/sysv/consts/ARPHRD_IEEE80211_PRISM.S deleted file mode 100644 index 26ce1ef13..000000000 --- a/libc/sysv/consts/ARPHRD_IEEE80211_PRISM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,ARPHRD_IEEE80211_PRISM,802,0,0,0,0,0 diff --git a/libc/sysv/consts/ARPHRD_IEEE80211_RADIOTAP.S b/libc/sysv/consts/ARPHRD_IEEE80211_RADIOTAP.S deleted file mode 100644 index 16b3bfed3..000000000 --- a/libc/sysv/consts/ARPHRD_IEEE80211_RADIOTAP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,ARPHRD_IEEE80211_RADIOTAP,803,0,0,0,0,0 diff --git a/libc/sysv/consts/ARPHRD_IEEE802154.S b/libc/sysv/consts/ARPHRD_IEEE802154.S deleted file mode 100644 index ee85d9920..000000000 --- a/libc/sysv/consts/ARPHRD_IEEE802154.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,ARPHRD_IEEE802154,804,0,0,0,0,0 diff --git a/libc/sysv/consts/ARPHRD_IEEE802_TR.S b/libc/sysv/consts/ARPHRD_IEEE802_TR.S deleted file mode 100644 index 8e7eb14ff..000000000 --- a/libc/sysv/consts/ARPHRD_IEEE802_TR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,ARPHRD_IEEE802_TR,800,0,0,0,0,0 diff --git a/libc/sysv/consts/ARPHRD_LOCALTLK.S b/libc/sysv/consts/ARPHRD_LOCALTLK.S deleted file mode 100644 index 53c6d58b7..000000000 --- a/libc/sysv/consts/ARPHRD_LOCALTLK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,ARPHRD_LOCALTLK,773,0,0,0,0,0 diff --git a/libc/sysv/consts/AT_CANARY.S b/libc/sysv/consts/AT_CANARY.S new file mode 100644 index 000000000..9a0fda0b6 --- /dev/null +++ b/libc/sysv/consts/AT_CANARY.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_CANARY,0,0,16,0,0,0 diff --git a/libc/sysv/consts/AT_CANARYLEN.S b/libc/sysv/consts/AT_CANARYLEN.S new file mode 100644 index 000000000..ee5e819d9 --- /dev/null +++ b/libc/sysv/consts/AT_CANARYLEN.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_CANARYLEN,0,0,17,0,0,0 diff --git a/libc/sysv/consts/AT_EHDRFLAGS.S b/libc/sysv/consts/AT_EHDRFLAGS.S new file mode 100644 index 000000000..47b678e3b --- /dev/null +++ b/libc/sysv/consts/AT_EHDRFLAGS.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_EHDRFLAGS,0,0,24,0,0,0 diff --git a/libc/sysv/consts/AT_EXECFN.S b/libc/sysv/consts/AT_EXECFN.S index ec03740c2..0fa809424 100644 --- a/libc/sysv/consts/AT_EXECFN.S +++ b/libc/sysv/consts/AT_EXECFN.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon auxv,AT_EXECFN,31,31,999,999,2014,31 +.syscon auxv,AT_EXECFN,31,31,15,999,2014,31 diff --git a/libc/sysv/consts/AT_EXECPATH.S b/libc/sysv/consts/AT_EXECPATH.S new file mode 100644 index 000000000..119cf8b4f --- /dev/null +++ b/libc/sysv/consts/AT_EXECPATH.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_EXECPATH,31,31,15,999,2014,31 diff --git a/libc/sysv/consts/AT_FLAGS.S b/libc/sysv/consts/AT_FLAGS.S index 79b4bc1e7..b5bf0d555 100644 --- a/libc/sysv/consts/AT_FLAGS.S +++ b/libc/sysv/consts/AT_FLAGS.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon auxv,AT_FLAGS,8,0,0,0,0,0 +.syscon auxv,AT_FLAGS,8,0,8,0,8,0 diff --git a/libc/sysv/consts/AT_NCPUS.S b/libc/sysv/consts/AT_NCPUS.S new file mode 100644 index 000000000..a79325514 --- /dev/null +++ b/libc/sysv/consts/AT_NCPUS.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_NCPUS,0,0,19,0,0,0 diff --git a/libc/sysv/consts/AT_PAGESIZES.S b/libc/sysv/consts/AT_PAGESIZES.S new file mode 100644 index 000000000..7ecb5f2cd --- /dev/null +++ b/libc/sysv/consts/AT_PAGESIZES.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_PAGESIZES,0,0,20,0,0,0 diff --git a/libc/sysv/consts/AT_PAGESIZESLEN.S b/libc/sysv/consts/AT_PAGESIZESLEN.S new file mode 100644 index 000000000..1c2509346 --- /dev/null +++ b/libc/sysv/consts/AT_PAGESIZESLEN.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_PAGESIZESLEN,0,0,21,0,0,0 diff --git a/libc/sysv/consts/AT_RANDOM.S b/libc/sysv/consts/AT_RANDOM.S index 28cce6500..9badd07c8 100644 --- a/libc/sysv/consts/AT_RANDOM.S +++ b/libc/sysv/consts/AT_RANDOM.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon auxv,AT_RANDOM,25,0,0,0,0,0 +.syscon auxv,AT_RANDOM,25,0,16,0,0,0 diff --git a/libc/sysv/consts/AT_STACKBASE.S b/libc/sysv/consts/AT_STACKBASE.S new file mode 100644 index 000000000..a7689a9b0 --- /dev/null +++ b/libc/sysv/consts/AT_STACKBASE.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_STACKBASE,0,0,0,0,13,0 diff --git a/libc/sysv/consts/AT_STACKPROT.S b/libc/sysv/consts/AT_STACKPROT.S new file mode 100644 index 000000000..3e45d2737 --- /dev/null +++ b/libc/sysv/consts/AT_STACKPROT.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_STACKPROT,0,0,23,0,0,0 diff --git a/libc/sysv/consts/AT_SYMLINK_FOLLOW.S b/libc/sysv/consts/AT_SYMLINK_FOLLOW.S index cfe68ec66..a232727ad 100644 --- a/libc/sysv/consts/AT_SYMLINK_FOLLOW.S +++ b/libc/sysv/consts/AT_SYMLINK_FOLLOW.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon at,AT_SYMLINK_FOLLOW,0x0400,0x40,0x0400,4,4,0 +.syscon at,AT_SYMLINK_FOLLOW,0x0400,0x40,0x0400,4,0x400,0 diff --git a/libc/sysv/consts/AT_TIMEKEEP.S b/libc/sysv/consts/AT_TIMEKEEP.S new file mode 100644 index 000000000..f90ab4b4c --- /dev/null +++ b/libc/sysv/consts/AT_TIMEKEEP.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon auxv,AT_TIMEKEEP,0,0,22,0,0,0 diff --git a/libc/sysv/consts/BLKBSZGET.S b/libc/sysv/consts/BLKBSZGET.S deleted file mode 100644 index d55d1780a..000000000 --- a/libc/sysv/consts/BLKBSZGET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKBSZGET,0x80081270,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKBSZSET.S b/libc/sysv/consts/BLKBSZSET.S deleted file mode 100644 index b573fad73..000000000 --- a/libc/sysv/consts/BLKBSZSET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKBSZSET,0x40081271,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKFLSBUF.S b/libc/sysv/consts/BLKFLSBUF.S deleted file mode 100644 index a55b0e12b..000000000 --- a/libc/sysv/consts/BLKFLSBUF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKFLSBUF,0x1261,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKFRAGET.S b/libc/sysv/consts/BLKFRAGET.S deleted file mode 100644 index f41dd56b5..000000000 --- a/libc/sysv/consts/BLKFRAGET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKFRAGET,0x1265,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKFRASET.S b/libc/sysv/consts/BLKFRASET.S deleted file mode 100644 index 02d38a750..000000000 --- a/libc/sysv/consts/BLKFRASET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKFRASET,0x1264,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKGETSIZE.S b/libc/sysv/consts/BLKGETSIZE.S deleted file mode 100644 index 17cdeb6f6..000000000 --- a/libc/sysv/consts/BLKGETSIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKGETSIZE,0x1260,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKGETSIZE64.S b/libc/sysv/consts/BLKGETSIZE64.S deleted file mode 100644 index 827200064..000000000 --- a/libc/sysv/consts/BLKGETSIZE64.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKGETSIZE64,0x80081272,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKRAGET.S b/libc/sysv/consts/BLKRAGET.S deleted file mode 100644 index 923f1015b..000000000 --- a/libc/sysv/consts/BLKRAGET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKRAGET,0x1263,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKRASET.S b/libc/sysv/consts/BLKRASET.S deleted file mode 100644 index 463db8579..000000000 --- a/libc/sysv/consts/BLKRASET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKRASET,0x1262,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKROGET.S b/libc/sysv/consts/BLKROGET.S deleted file mode 100644 index 02a2a9b85..000000000 --- a/libc/sysv/consts/BLKROGET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKROGET,0x125e,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKROSET.S b/libc/sysv/consts/BLKROSET.S deleted file mode 100644 index cc20461e7..000000000 --- a/libc/sysv/consts/BLKROSET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKROSET,0x125d,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKRRPART.S b/libc/sysv/consts/BLKRRPART.S deleted file mode 100644 index 951ce4beb..000000000 --- a/libc/sysv/consts/BLKRRPART.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKRRPART,0x125f,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKSECTGET.S b/libc/sysv/consts/BLKSECTGET.S deleted file mode 100644 index 926dc6553..000000000 --- a/libc/sysv/consts/BLKSECTGET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKSECTGET,0x1267,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKSECTSET.S b/libc/sysv/consts/BLKSECTSET.S deleted file mode 100644 index d1d39ffe2..000000000 --- a/libc/sysv/consts/BLKSECTSET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKSECTSET,0x1266,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKSSZGET.S b/libc/sysv/consts/BLKSSZGET.S deleted file mode 100644 index 0f4beb4ec..000000000 --- a/libc/sysv/consts/BLKSSZGET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKSSZGET,0x1268,0,0,0,0,0 diff --git a/libc/sysv/consts/BLKTYPE.S b/libc/sysv/consts/BLKTYPE.S deleted file mode 100644 index f6eb429c5..000000000 --- a/libc/sysv/consts/BLKTYPE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,BLKTYPE,52,52,52,52,52,0 diff --git a/libc/sysv/consts/BUS_DEVICE_RESET.S b/libc/sysv/consts/BUS_DEVICE_RESET.S deleted file mode 100644 index 0e33b3170..000000000 --- a/libc/sysv/consts/BUS_DEVICE_RESET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,BUS_DEVICE_RESET,12,0,0,0,0,0 diff --git a/libc/sysv/consts/BUS_OOMERR.S b/libc/sysv/consts/BUS_OOMERR.S new file mode 100644 index 000000000..bafccff3a --- /dev/null +++ b/libc/sysv/consts/BUS_OOMERR.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon sicode,BUS_OOMERR,-1,-1,100,-1,-1,-1 diff --git a/libc/sysv/consts/CLOCAL.S b/libc/sysv/consts/CLOCAL.S index 73bdc0a62..d9bcd3c33 100644 --- a/libc/sysv/consts/CLOCAL.S +++ b/libc/sysv/consts/CLOCAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,CLOCAL,0x0800,0x8000,0x8000,0x8000,0x8000,0 +.syscon termios,CLOCAL,0b0000100000000000,0b1000000000000000,0b1000000000000000,0b1000000000000000,0b1000000000000000,0b0000100000000000 diff --git a/libc/sysv/consts/CLOCK_BOOTTIME.S b/libc/sysv/consts/CLOCK_BOOTTIME.S index 4a093dab4..05ce54ce7 100644 --- a/libc/sysv/consts/CLOCK_BOOTTIME.S +++ b/libc/sysv/consts/CLOCK_BOOTTIME.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_BOOTTIME,7,-1,-1,6,6,-1 +.syscon clock,CLOCK_BOOTTIME,7,-1,-1,6,-1,-1 diff --git a/libc/sysv/consts/CLONE_VM.S b/libc/sysv/consts/CLONE_VM.S new file mode 100644 index 000000000..be6328bfa --- /dev/null +++ b/libc/sysv/consts/CLONE_VM.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon clone,CLONE_VM,0x00000100,0x00000100,0x00000100,0x00000100,0x00000100,0x00000100 diff --git a/libc/sysv/consts/CREAD.S b/libc/sysv/consts/CREAD.S index 1eac14cd8..e18ada92d 100644 --- a/libc/sysv/consts/CREAD.S +++ b/libc/sysv/consts/CREAD.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,CREAD,0x80,0x0800,0x0800,0x0800,0x0800,0 +.syscon termios,CREAD,0b0000000010000000,0b000000100000000000,0b000000100000000000,0b0000100000000000,0b0000100000000000,0b0000000010000000 diff --git a/libc/sysv/consts/CS5.S b/libc/sysv/consts/CS5.S index 01a9b5895..ac9704d4c 100644 --- a/libc/sysv/consts/CS5.S +++ b/libc/sysv/consts/CS5.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,CS5,0,0,0,0,0,0 +.syscon termios,CS5,0b0000000000000000,0b000000000000000000,0b000000000000000000,0b0000000000000000,0b0000000000000000,0b0000000000000000 diff --git a/libc/sysv/consts/CS6.S b/libc/sysv/consts/CS6.S index f5031010e..4b5329830 100644 --- a/libc/sysv/consts/CS6.S +++ b/libc/sysv/consts/CS6.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,CS6,0b0000000000010000,0b0000000100000000,0b0000000100000000,0b0000000100000000,0b0000000100000000,0b0000000000010000 +.syscon termios,CS6,0b0000000000010000,0b000000000100000000,0b000000000100000000,0b0000000100000000,0b0000000100000000,0b0000000000010000 diff --git a/libc/sysv/consts/CS7.S b/libc/sysv/consts/CS7.S index d4fb534a7..923e5982c 100644 --- a/libc/sysv/consts/CS7.S +++ b/libc/sysv/consts/CS7.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,CS7,0b0000000000100000,0b0000001000000000,0b0000001000000000,0b0000001000000000,0b0000001000000000,0b0000000000100000 +.syscon termios,CS7,0b0000000000100000,0b000000001000000000,0b000000001000000000,0b0000001000000000,0b0000001000000000,0b0000000000100000 diff --git a/libc/sysv/consts/CS8.S b/libc/sysv/consts/CS8.S index 08ad827a8..21784475b 100644 --- a/libc/sysv/consts/CS8.S +++ b/libc/sysv/consts/CS8.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,CS8,0b0000000000110000,0b0000001100000000,0b0000001100000000,0b0000001100000000,0b0000001100000000,0b0000000000110000 +.syscon termios,CS8,0b0000000000110000,0b000000001100000000,0b000000001100000000,0b0000001100000000,0b0000001100000000,0b0000000000110000 diff --git a/libc/sysv/consts/CSIZE.S b/libc/sysv/consts/CSIZE.S index 90372e69c..59abbeb63 100644 --- a/libc/sysv/consts/CSIZE.S +++ b/libc/sysv/consts/CSIZE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,CSIZE,0b0000000000110000,0b0000001100000000,0b0000001100000000,0b0000001100000000,0b0000001100000000,0b0000000000110000 +.syscon termios,CSIZE,0b0000000000110000,0b000000001100000000,0b000000001100000000,0b0000001100000000,0b0000001100000000,0b0000000000110000 diff --git a/libc/sysv/consts/CSTOPB.S b/libc/sysv/consts/CSTOPB.S index 0e8700592..5374da0e4 100644 --- a/libc/sysv/consts/CSTOPB.S +++ b/libc/sysv/consts/CSTOPB.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,CSTOPB,0x40,0x0400,0x0400,0x0400,0x0400,0 +.syscon termios,CSTOPB,0b0000000001000000,0b000000010000000000,0b000000010000000000,0b0000010000000000,0b0000010000000000,0b0000000001000000 diff --git a/libc/sysv/consts/EDQUOT.S b/libc/sysv/consts/EDQUOT.S index 2d4bae78a..98e5a7360 100644 --- a/libc/sysv/consts/EDQUOT.S +++ b/libc/sysv/consts/EDQUOT.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon errno,EDQUOT,122,69,69,69,69,10069 +.syscon errno,EDQUOT,122,69,69,69,69,1816 diff --git a/libc/sysv/consts/EMFILE.S b/libc/sysv/consts/EMFILE.S index 7877ea505..cf15a0d89 100644 --- a/libc/sysv/consts/EMFILE.S +++ b/libc/sysv/consts/EMFILE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon errno,EMFILE,24,24,24,24,24,336 +.syscon errno,EMFILE,24,24,24,24,24,4 diff --git a/libc/sysv/consts/EMLINK.S b/libc/sysv/consts/EMLINK.S index e9569d2c2..7279d4329 100644 --- a/libc/sysv/consts/EMLINK.S +++ b/libc/sysv/consts/EMLINK.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon errno,EMLINK,31,31,31,31,31,4 +.syscon errno,EMLINK,31,31,31,31,31,1142 diff --git a/libc/sysv/consts/ENODATA.S b/libc/sysv/consts/ENODATA.S index e9b938bbb..0fd7a9733 100644 --- a/libc/sysv/consts/ENODATA.S +++ b/libc/sysv/consts/ENODATA.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon errno,ENODATA,61,96,0,0,89,0 +.syscon errno,ENODATA,61,96,0,0,89,232 diff --git a/libc/sysv/consts/EXIT_FAILURE.S b/libc/sysv/consts/EXIT_FAILURE.S deleted file mode 100644 index 21df576a8..000000000 --- a/libc/sysv/consts/EXIT_FAILURE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon exit,EXIT_FAILURE,1,1,1,1,1,1 diff --git a/libc/sysv/consts/EXIT_SUCCESS.S b/libc/sysv/consts/EXIT_SUCCESS.S deleted file mode 100644 index 8f41a65ed..000000000 --- a/libc/sysv/consts/EXIT_SUCCESS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon exit,EXIT_SUCCESS,0,0,0,0,0,0 diff --git a/libc/sysv/consts/HUPCL.S b/libc/sysv/consts/HUPCL.S index dd03f7ab0..6d27a2fb8 100644 --- a/libc/sysv/consts/HUPCL.S +++ b/libc/sysv/consts/HUPCL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,HUPCL,0x0400,0x4000,0x4000,0x4000,0x4000,0 +.syscon termios,HUPCL,0b0000010000000000,0b000100000000000000,0b000100000000000000,0b0100000000000000,0b0100000000000000,0b0000010000000000 diff --git a/libc/sysv/consts/LOG_ALERT.S b/libc/sysv/consts/LOG_ALERT.S deleted file mode 100644 index e06f8d0fa..000000000 --- a/libc/sysv/consts/LOG_ALERT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_ALERT,1,1,1,1,1,1 diff --git a/libc/sysv/consts/LOG_AUTH.S b/libc/sysv/consts/LOG_AUTH.S deleted file mode 100644 index f810118f8..000000000 --- a/libc/sysv/consts/LOG_AUTH.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_AUTH,0x20,0x20,0x20,0x20,0x20,0x20 diff --git a/libc/sysv/consts/LOG_CONS.S b/libc/sysv/consts/LOG_CONS.S deleted file mode 100644 index ece48311f..000000000 --- a/libc/sysv/consts/LOG_CONS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_CONS,2,2,2,2,2,2 diff --git a/libc/sysv/consts/LOG_CRIT.S b/libc/sysv/consts/LOG_CRIT.S deleted file mode 100644 index d623e5551..000000000 --- a/libc/sysv/consts/LOG_CRIT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_CRIT,2,2,2,2,2,2 diff --git a/libc/sysv/consts/LOG_CRON.S b/libc/sysv/consts/LOG_CRON.S deleted file mode 100644 index f392b84ca..000000000 --- a/libc/sysv/consts/LOG_CRON.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_CRON,72,72,72,72,72,72 diff --git a/libc/sysv/consts/LOG_DAEMON.S b/libc/sysv/consts/LOG_DAEMON.S deleted file mode 100644 index 10f3772dd..000000000 --- a/libc/sysv/consts/LOG_DAEMON.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_DAEMON,24,24,24,24,24,24 diff --git a/libc/sysv/consts/LOG_DEBUG.S b/libc/sysv/consts/LOG_DEBUG.S deleted file mode 100644 index 3e39ee2b6..000000000 --- a/libc/sysv/consts/LOG_DEBUG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_DEBUG,7,7,7,7,7,7 diff --git a/libc/sysv/consts/LOG_EMERG.S b/libc/sysv/consts/LOG_EMERG.S deleted file mode 100644 index 48aa6fd42..000000000 --- a/libc/sysv/consts/LOG_EMERG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_EMERG,0,0,0,0,0,0 diff --git a/libc/sysv/consts/LOG_ERR.S b/libc/sysv/consts/LOG_ERR.S deleted file mode 100644 index bf9507d94..000000000 --- a/libc/sysv/consts/LOG_ERR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_ERR,3,3,3,3,3,3 diff --git a/libc/sysv/consts/LOG_FACMASK.S b/libc/sysv/consts/LOG_FACMASK.S deleted file mode 100644 index 25d730624..000000000 --- a/libc/sysv/consts/LOG_FACMASK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_FACMASK,0x03f8,0x03f8,0x03f8,0x03f8,0x03f8,0x03f8 diff --git a/libc/sysv/consts/LOG_INFO.S b/libc/sysv/consts/LOG_INFO.S deleted file mode 100644 index 1eb6985af..000000000 --- a/libc/sysv/consts/LOG_INFO.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_INFO,6,6,6,6,6,6 diff --git a/libc/sysv/consts/LOG_KERN.S b/libc/sysv/consts/LOG_KERN.S deleted file mode 100644 index 20c97fe34..000000000 --- a/libc/sysv/consts/LOG_KERN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_KERN,0,0,0,0,0,0 diff --git a/libc/sysv/consts/LOG_LOCAL0.S b/libc/sysv/consts/LOG_LOCAL0.S deleted file mode 100644 index fcd14530b..000000000 --- a/libc/sysv/consts/LOG_LOCAL0.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LOCAL0,0x80,0x80,0x80,0x80,0x80,0x80 diff --git a/libc/sysv/consts/LOG_LOCAL1.S b/libc/sysv/consts/LOG_LOCAL1.S deleted file mode 100644 index 36ffdde59..000000000 --- a/libc/sysv/consts/LOG_LOCAL1.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LOCAL1,136,136,136,136,136,136 diff --git a/libc/sysv/consts/LOG_LOCAL2.S b/libc/sysv/consts/LOG_LOCAL2.S deleted file mode 100644 index 1ddfe950c..000000000 --- a/libc/sysv/consts/LOG_LOCAL2.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LOCAL2,144,144,144,144,144,144 diff --git a/libc/sysv/consts/LOG_LOCAL3.S b/libc/sysv/consts/LOG_LOCAL3.S deleted file mode 100644 index d8af1d662..000000000 --- a/libc/sysv/consts/LOG_LOCAL3.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LOCAL3,152,152,152,152,152,152 diff --git a/libc/sysv/consts/LOG_LOCAL4.S b/libc/sysv/consts/LOG_LOCAL4.S deleted file mode 100644 index 6abccdf09..000000000 --- a/libc/sysv/consts/LOG_LOCAL4.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LOCAL4,160,160,160,160,160,160 diff --git a/libc/sysv/consts/LOG_LOCAL5.S b/libc/sysv/consts/LOG_LOCAL5.S deleted file mode 100644 index 6062a680f..000000000 --- a/libc/sysv/consts/LOG_LOCAL5.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LOCAL5,168,168,168,168,168,168 diff --git a/libc/sysv/consts/LOG_LOCAL6.S b/libc/sysv/consts/LOG_LOCAL6.S deleted file mode 100644 index 53c16ccac..000000000 --- a/libc/sysv/consts/LOG_LOCAL6.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LOCAL6,176,176,176,176,176,176 diff --git a/libc/sysv/consts/LOG_LOCAL7.S b/libc/sysv/consts/LOG_LOCAL7.S deleted file mode 100644 index 8b0d73e2a..000000000 --- a/libc/sysv/consts/LOG_LOCAL7.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LOCAL7,184,184,184,184,184,184 diff --git a/libc/sysv/consts/LOG_LPR.S b/libc/sysv/consts/LOG_LPR.S deleted file mode 100644 index 0be5f536c..000000000 --- a/libc/sysv/consts/LOG_LPR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_LPR,48,48,48,48,48,48 diff --git a/libc/sysv/consts/LOG_MAIL.S b/libc/sysv/consts/LOG_MAIL.S deleted file mode 100644 index e534e178f..000000000 --- a/libc/sysv/consts/LOG_MAIL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_MAIL,0x10,0x10,0x10,0x10,0x10,0x10 diff --git a/libc/sysv/consts/LOG_NDELAY.S b/libc/sysv/consts/LOG_NDELAY.S deleted file mode 100644 index af158f72c..000000000 --- a/libc/sysv/consts/LOG_NDELAY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_NDELAY,8,8,8,8,8,8 diff --git a/libc/sysv/consts/LOG_NEWS.S b/libc/sysv/consts/LOG_NEWS.S deleted file mode 100644 index af6bc33e1..000000000 --- a/libc/sysv/consts/LOG_NEWS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_NEWS,56,56,56,56,56,56 diff --git a/libc/sysv/consts/LOG_NFACILITIES.S b/libc/sysv/consts/LOG_NFACILITIES.S deleted file mode 100644 index 924f57b8d..000000000 --- a/libc/sysv/consts/LOG_NFACILITIES.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_NFACILITIES,24,25,24,24,24,24 diff --git a/libc/sysv/consts/LOG_NOTICE.S b/libc/sysv/consts/LOG_NOTICE.S deleted file mode 100644 index 7164aa399..000000000 --- a/libc/sysv/consts/LOG_NOTICE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_NOTICE,5,5,5,5,5,5 diff --git a/libc/sysv/consts/LOG_NOWAIT.S b/libc/sysv/consts/LOG_NOWAIT.S deleted file mode 100644 index 415b564d8..000000000 --- a/libc/sysv/consts/LOG_NOWAIT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_NOWAIT,0x10,0x10,0x10,0x10,0x10,0x10 diff --git a/libc/sysv/consts/LOG_ODELAY.S b/libc/sysv/consts/LOG_ODELAY.S deleted file mode 100644 index 5b97aa3b3..000000000 --- a/libc/sysv/consts/LOG_ODELAY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_ODELAY,4,4,4,4,4,4 diff --git a/libc/sysv/consts/LOG_PERROR.S b/libc/sysv/consts/LOG_PERROR.S deleted file mode 100644 index a80b7f8df..000000000 --- a/libc/sysv/consts/LOG_PERROR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_PERROR,0x20,0x20,0x20,0x20,0x20,0x20 diff --git a/libc/sysv/consts/LOG_PID.S b/libc/sysv/consts/LOG_PID.S deleted file mode 100644 index 7fff6d6b4..000000000 --- a/libc/sysv/consts/LOG_PID.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_PID,1,1,1,1,1,1 diff --git a/libc/sysv/consts/LOG_PRIMASK.S b/libc/sysv/consts/LOG_PRIMASK.S deleted file mode 100644 index bd140bfbe..000000000 --- a/libc/sysv/consts/LOG_PRIMASK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_PRIMASK,7,7,7,7,7,7 diff --git a/libc/sysv/consts/LOG_SELECT.S b/libc/sysv/consts/LOG_SELECT.S deleted file mode 100644 index 431f1f2c2..000000000 --- a/libc/sysv/consts/LOG_SELECT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_SELECT,76,0,0,0,0,0 diff --git a/libc/sysv/consts/LOG_SENSE.S b/libc/sysv/consts/LOG_SENSE.S deleted file mode 100644 index a48c8e947..000000000 --- a/libc/sysv/consts/LOG_SENSE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_SENSE,77,0,0,0,0,0 diff --git a/libc/sysv/consts/LOG_SYSLOG.S b/libc/sysv/consts/LOG_SYSLOG.S deleted file mode 100644 index 42420d291..000000000 --- a/libc/sysv/consts/LOG_SYSLOG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_SYSLOG,40,40,40,40,40,40 diff --git a/libc/sysv/consts/LOG_USER.S b/libc/sysv/consts/LOG_USER.S deleted file mode 100644 index 71538bc39..000000000 --- a/libc/sysv/consts/LOG_USER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_USER,8,8,8,8,8,8 diff --git a/libc/sysv/consts/LOG_UUCP.S b/libc/sysv/consts/LOG_UUCP.S deleted file mode 100644 index daa7b2fbe..000000000 --- a/libc/sysv/consts/LOG_UUCP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_UUCP,0x40,0x40,0x40,0x40,0x40,40 diff --git a/libc/sysv/consts/LOG_WARNING.S b/libc/sysv/consts/LOG_WARNING.S deleted file mode 100644 index 805b9731a..000000000 --- a/libc/sysv/consts/LOG_WARNING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon log,LOG_WARNING,4,4,4,4,4,4 diff --git a/libc/sysv/consts/MADV_DODUMP.S b/libc/sysv/consts/MADV_DODUMP.S index 646221a86..f8e709e27 100644 --- a/libc/sysv/consts/MADV_DODUMP.S +++ b/libc/sysv/consts/MADV_DODUMP.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_DODUMP,17,0,0,0,0,0 +.syscon madv,MADV_DODUMP,17,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_DOFORK.S b/libc/sysv/consts/MADV_DOFORK.S index ed787cfc2..07615b18c 100644 --- a/libc/sysv/consts/MADV_DOFORK.S +++ b/libc/sysv/consts/MADV_DOFORK.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_DOFORK,11,0,0,0,0,0 +.syscon madv,MADV_DOFORK,11,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_DONTDUMP.S b/libc/sysv/consts/MADV_DONTDUMP.S index feba10977..28fcf75b1 100644 --- a/libc/sysv/consts/MADV_DONTDUMP.S +++ b/libc/sysv/consts/MADV_DONTDUMP.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_DONTDUMP,16,0,0,0,0,0 +.syscon madv,MADV_DONTDUMP,16,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_DONTFORK.S b/libc/sysv/consts/MADV_DONTFORK.S index ee1535ff6..28eded7f4 100644 --- a/libc/sysv/consts/MADV_DONTFORK.S +++ b/libc/sysv/consts/MADV_DONTFORK.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_DONTFORK,10,0,0,0,0,0 +.syscon madv,MADV_DONTFORK,10,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_DONTNEED.S b/libc/sysv/consts/MADV_DONTNEED.S index 72ce36e4d..6567e21f8 100644 --- a/libc/sysv/consts/MADV_DONTNEED.S +++ b/libc/sysv/consts/MADV_DONTNEED.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_DONTNEED,4,4,4,4,4,0 +.syscon madv,MADV_DONTNEED,4,4,4,4,4,127 diff --git a/libc/sysv/consts/MADV_HUGEPAGE.S b/libc/sysv/consts/MADV_HUGEPAGE.S index 7d42c5da0..0afab715f 100644 --- a/libc/sysv/consts/MADV_HUGEPAGE.S +++ b/libc/sysv/consts/MADV_HUGEPAGE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_HUGEPAGE,14,0,0,0,0,0 +.syscon madv,MADV_HUGEPAGE,14,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_HWPOISON.S b/libc/sysv/consts/MADV_HWPOISON.S index 85ed35846..c8f76111a 100644 --- a/libc/sysv/consts/MADV_HWPOISON.S +++ b/libc/sysv/consts/MADV_HWPOISON.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_HWPOISON,100,0,0,0,0,0 +.syscon madv,MADV_HWPOISON,100,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_MERGEABLE.S b/libc/sysv/consts/MADV_MERGEABLE.S index 65bf29223..172668fcc 100644 --- a/libc/sysv/consts/MADV_MERGEABLE.S +++ b/libc/sysv/consts/MADV_MERGEABLE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_MERGEABLE,12,0,0,0,0,0 +.syscon madv,MADV_MERGEABLE,12,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_NOHUGEPAGE.S b/libc/sysv/consts/MADV_NOHUGEPAGE.S index d56f15745..9458ebc54 100644 --- a/libc/sysv/consts/MADV_NOHUGEPAGE.S +++ b/libc/sysv/consts/MADV_NOHUGEPAGE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_NOHUGEPAGE,15,0,0,0,0,0 +.syscon madv,MADV_NOHUGEPAGE,15,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_NORMAL.S b/libc/sysv/consts/MADV_NORMAL.S index ec8f1ef00..c38bc7dae 100644 --- a/libc/sysv/consts/MADV_NORMAL.S +++ b/libc/sysv/consts/MADV_NORMAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_NORMAL,0,0,0,0,0,0x00000080 +.syscon madv,MADV_NORMAL,0,0,0,0,0,0 diff --git a/libc/sysv/consts/MADV_RANDOM.S b/libc/sysv/consts/MADV_RANDOM.S index dfeafff6f..e7c7b43c6 100644 --- a/libc/sysv/consts/MADV_RANDOM.S +++ b/libc/sysv/consts/MADV_RANDOM.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_RANDOM,1,1,1,1,1,0x10000000 +.syscon madv,MADV_RANDOM,1,1,1,1,1,1 diff --git a/libc/sysv/consts/MADV_REMOVE.S b/libc/sysv/consts/MADV_REMOVE.S index ea2398627..cc77e67fc 100644 --- a/libc/sysv/consts/MADV_REMOVE.S +++ b/libc/sysv/consts/MADV_REMOVE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_REMOVE,9,0,0,0,0,0 +.syscon madv,MADV_REMOVE,9,127,127,127,127,127 diff --git a/libc/sysv/consts/MADV_SEQUENTIAL.S b/libc/sysv/consts/MADV_SEQUENTIAL.S index b40e06f26..8b54e4626 100644 --- a/libc/sysv/consts/MADV_SEQUENTIAL.S +++ b/libc/sysv/consts/MADV_SEQUENTIAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_SEQUENTIAL,2,2,2,2,2,0x8000000 +.syscon madv,MADV_SEQUENTIAL,2,2,2,2,2,2 diff --git a/libc/sysv/consts/MADV_UNMERGEABLE.S b/libc/sysv/consts/MADV_UNMERGEABLE.S index 2704aabe7..d0335eb72 100644 --- a/libc/sysv/consts/MADV_UNMERGEABLE.S +++ b/libc/sysv/consts/MADV_UNMERGEABLE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon madv,MADV_UNMERGEABLE,13,0,0,0,0,0 +.syscon madv,MADV_UNMERGEABLE,13,127,127,127,127,127 diff --git a/libc/sysv/consts/MAP_ANON.S b/libc/sysv/consts/MAP_ANON.S index 9b6ef77dd..a1eb02bfe 100644 --- a/libc/sysv/consts/MAP_ANON.S +++ b/libc/sysv/consts/MAP_ANON.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,MAP_ANON,0x20,0x1000,0x1000,0x1000,0x1000,0x20 +.syscon compat,MAP_ANON,0x20,0x1000,0x0001000,0x1000,0x1000,0x20 diff --git a/libc/sysv/consts/MAP_ANONYMOUS.S b/libc/sysv/consts/MAP_ANONYMOUS.S index 6872f306a..9aa3781ea 100644 --- a/libc/sysv/consts/MAP_ANONYMOUS.S +++ b/libc/sysv/consts/MAP_ANONYMOUS.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon mmap,MAP_ANONYMOUS,0x20,0x1000,0x1000,0x1000,0x1000,0x20 +.syscon mmap,MAP_ANONYMOUS,0x20,0x1000,0x0001000,0x1000,0x1000,0x20 diff --git a/libc/sysv/consts/MAP_CONCEAL.S b/libc/sysv/consts/MAP_CONCEAL.S index 8077b1792..6f9de260c 100644 --- a/libc/sysv/consts/MAP_CONCEAL.S +++ b/libc/sysv/consts/MAP_CONCEAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon mmap,MAP_CONCEAL,0,0,0,0x8000,0,0 +.syscon mmap,MAP_CONCEAL,0,0,0x0020000,0x8000,0x8000,0 diff --git a/libc/sysv/consts/MAP_FIXED.S b/libc/sysv/consts/MAP_FIXED.S index e47ad4a5d..e9dbc0e9e 100644 --- a/libc/sysv/consts/MAP_FIXED.S +++ b/libc/sysv/consts/MAP_FIXED.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon mmap,MAP_FIXED,0x10,0x10,0x10,0x10,0x10,0x10 +.syscon mmap,MAP_FIXED,0x0000010,0x0000010,0x0000010,0x0000010,0x0000010,0x0000010 diff --git a/libc/sysv/consts/MAP_FIXED_NOREPLACE.S b/libc/sysv/consts/MAP_FIXED_NOREPLACE.S new file mode 100644 index 000000000..2bcb31adf --- /dev/null +++ b/libc/sysv/consts/MAP_FIXED_NOREPLACE.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon mmap,MAP_FIXED_NOREPLACE,0x8000000,0x8000000,0x8000000,0x8000000,0x8000000,0x8000000 diff --git a/libc/sysv/consts/MAP_GROWSDOWN.S b/libc/sysv/consts/MAP_GROWSDOWN.S index e7fc93583..ec4438b6a 100644 --- a/libc/sysv/consts/MAP_GROWSDOWN.S +++ b/libc/sysv/consts/MAP_GROWSDOWN.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon mmap,MAP_GROWSDOWN,0x0100,0,0x0400,0x4000,0x4000,0x100000 +.syscon mmap,MAP_GROWSDOWN,0x0100,0,0x0000400,0x4000,0x4000,0x100000 diff --git a/libc/sysv/consts/MAP_NOCORE.S b/libc/sysv/consts/MAP_NOCORE.S index 90c2c1f44..c0e6b263f 100644 --- a/libc/sysv/consts/MAP_NOCORE.S +++ b/libc/sysv/consts/MAP_NOCORE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,MAP_NOCORE,0,0,0x20000,0x8000,0x8000,0 +.syscon compat,MAP_NOCORE,0,0,0x0020000,0x8000,0x8000,0 diff --git a/libc/sysv/consts/MAP_STACK.S b/libc/sysv/consts/MAP_STACK.S index 1eff99c73..ed26f8ecf 100644 --- a/libc/sysv/consts/MAP_STACK.S +++ b/libc/sysv/consts/MAP_STACK.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,MAP_STACK,0x0100,0,0x0400,0x4000,0x2000,0x100000 +.syscon mmap,MAP_STACK,0x0100,0,0x0000400,0x4000,0x2000,0x100000 diff --git a/libc/sysv/consts/O_ACCMODE.S b/libc/sysv/consts/O_ACCMODE.S index a3fc04fc4..975af5e22 100644 --- a/libc/sysv/consts/O_ACCMODE.S +++ b/libc/sysv/consts/O_ACCMODE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_ACCMODE,3,3,3,3,3,0xE0000000 +.syscon open,O_ACCMODE,3,3,3,3,3,3 diff --git a/libc/sysv/consts/O_APPEND.S b/libc/sysv/consts/O_APPEND.S index ee7a00db2..3a0bab7d5 100644 --- a/libc/sysv/consts/O_APPEND.S +++ b/libc/sysv/consts/O_APPEND.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_APPEND,0x00000400,8,8,8,8,0x00000004 +.syscon open,O_APPEND,0x00000400,8,8,8,8,0x00000400 diff --git a/libc/sysv/consts/O_COMPRESSED.S b/libc/sysv/consts/O_COMPRESSED.S new file mode 100644 index 000000000..251563818 --- /dev/null +++ b/libc/sysv/consts/O_COMPRESSED.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon open,O_COMPRESSED,0,0,0,0,0,0x20000000 diff --git a/libc/sysv/consts/O_DIRECT.S b/libc/sysv/consts/O_DIRECT.S index f9be1eb9c..8a205a29f 100644 --- a/libc/sysv/consts/O_DIRECT.S +++ b/libc/sysv/consts/O_DIRECT.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_DIRECT,0x00004000,0,0x00010000,0,0x00080000,0x00200000 +.syscon open,O_DIRECT,0x00004000,0,0x00010000,0,0x00080000,0x00004000 diff --git a/libc/sysv/consts/O_DIRECTORY.S b/libc/sysv/consts/O_DIRECTORY.S index 00fcac4dd..8a41b6e27 100644 --- a/libc/sysv/consts/O_DIRECTORY.S +++ b/libc/sysv/consts/O_DIRECTORY.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_DIRECTORY,0x00010000,0x00100000,0x00020000,0x00020000,0x00200000,0x02000000 +.syscon open,O_DIRECTORY,0x00010000,0x00100000,0x00020000,0x00020000,0x00200000,0x00010000 diff --git a/libc/sysv/consts/O_INDEXED.S b/libc/sysv/consts/O_INDEXED.S new file mode 100644 index 000000000..3bcd6320a --- /dev/null +++ b/libc/sysv/consts/O_INDEXED.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon open,O_INDEXED,0,0,0,0,0,0x10000000 diff --git a/libc/sysv/consts/O_NOFOLLOW.S b/libc/sysv/consts/O_NOFOLLOW.S index b0b255d23..823dfcb1a 100644 --- a/libc/sysv/consts/O_NOFOLLOW.S +++ b/libc/sysv/consts/O_NOFOLLOW.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_NOFOLLOW,0x00020000,0x00000100,0x00000100,0x00000100,0x00000100,0 +.syscon open,O_NOFOLLOW,0x00020000,0x00000100,0x00000100,0x00000100,0x00000100,0x00020000 diff --git a/libc/sysv/consts/O_RANDOM.S b/libc/sysv/consts/O_RANDOM.S index 88e3552b2..f7cb69d59 100644 --- a/libc/sysv/consts/O_RANDOM.S +++ b/libc/sysv/consts/O_RANDOM.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_RANDOM,0,0,0,0,0,0x10000000 +.syscon open,O_RANDOM,0,0,0,0,0,0x80000000 diff --git a/libc/sysv/consts/O_RDONLY.S b/libc/sysv/consts/O_RDONLY.S index b239e4466..0db270eb7 100644 --- a/libc/sysv/consts/O_RDONLY.S +++ b/libc/sysv/consts/O_RDONLY.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_RDONLY,0,0,0,0,0,0xA0000000 +.syscon open,O_RDONLY,0,0,0,0,0,0 diff --git a/libc/sysv/consts/O_RDWR.S b/libc/sysv/consts/O_RDWR.S index 786c1c138..87de21ff9 100644 --- a/libc/sysv/consts/O_RDWR.S +++ b/libc/sysv/consts/O_RDWR.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_RDWR,2,2,2,2,2,0xE0000000 +.syscon open,O_RDWR,2,2,2,2,2,2 diff --git a/libc/sysv/consts/O_SEQUENTIAL.S b/libc/sysv/consts/O_SEQUENTIAL.S index c0f64b8d5..3a0be8664 100644 --- a/libc/sysv/consts/O_SEQUENTIAL.S +++ b/libc/sysv/consts/O_SEQUENTIAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_SEQUENTIAL,0,0,0,0,0,0x08000000 +.syscon open,O_SEQUENTIAL,0,0,0,0,0,0x40000000 diff --git a/libc/sysv/consts/O_SPARSE.S b/libc/sysv/consts/O_SPARSE.S index f135a0219..7b17bfe52 100644 --- a/libc/sysv/consts/O_SPARSE.S +++ b/libc/sysv/consts/O_SPARSE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_SPARSE,0,0,0,0,0,0x00040000 +.syscon open,O_SPARSE,0,0,0,0,0,0 diff --git a/libc/sysv/consts/O_TMPFILE.S b/libc/sysv/consts/O_TMPFILE.S index 4627550ab..bbff30e4a 100644 --- a/libc/sysv/consts/O_TMPFILE.S +++ b/libc/sysv/consts/O_TMPFILE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_TMPFILE,0x00410000,0,0,0,0,0x00000000 +.syscon open,O_TMPFILE,0x00410000,0,0,0,0,0x00410000 diff --git a/libc/sysv/consts/O_WRONLY.S b/libc/sysv/consts/O_WRONLY.S index 7dd4a3830..0188a8b58 100644 --- a/libc/sysv/consts/O_WRONLY.S +++ b/libc/sysv/consts/O_WRONLY.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_WRONLY,1,1,1,1,1,0x40000000 +.syscon open,O_WRONLY,1,1,1,1,1,1 diff --git a/libc/sysv/consts/PARENB.S b/libc/sysv/consts/PARENB.S index 2a40e7dc4..9900cf43b 100644 --- a/libc/sysv/consts/PARENB.S +++ b/libc/sysv/consts/PARENB.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,PARENB,0x0100,0x1000,0x1000,0x1000,0x1000,0 +.syscon termios,PARENB,0b0000000100000000,0b000001000000000000,0b000001000000000000,0b0001000000000000,0b0001000000000000,0b0000000100000000 diff --git a/libc/sysv/consts/PARODD.S b/libc/sysv/consts/PARODD.S index 0ef8fff7a..1cfe04b15 100644 --- a/libc/sysv/consts/PARODD.S +++ b/libc/sysv/consts/PARODD.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,PARODD,0x0200,0x2000,0x2000,0x2000,0x2000,0 +.syscon termios,PARODD,0b0000001000000000,0b000010000000000000,0b000010000000000000,0b0010000000000000,0b0010000000000000,0b0000001000000000 diff --git a/libc/sysv/consts/PIPE_BUF.S b/libc/sysv/consts/PIPE_BUF.S index 8a0b5b01c..34d0d247e 100644 --- a/libc/sysv/consts/PIPE_BUF.S +++ b/libc/sysv/consts/PIPE_BUF.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon misc,PIPE_BUF,0x1000,0x0200,0x0200,0x0200,0x0200,0 +.syscon limits,PIPE_BUF,4096,512,512,512,512,4096 diff --git a/libc/sysv/consts/POLLERR.S b/libc/sysv/consts/POLLERR.S index 8112ce3bd..4b8129c6c 100644 --- a/libc/sysv/consts/POLLERR.S +++ b/libc/sysv/consts/POLLERR.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon poll,POLLERR,8,8,8,8,8,1 +.syscon poll,POLLERR,8,8,8,8,8,0x0001 diff --git a/libc/sysv/consts/POLLHUP.S b/libc/sysv/consts/POLLHUP.S index 75f733982..f05fc4d9b 100644 --- a/libc/sysv/consts/POLLHUP.S +++ b/libc/sysv/consts/POLLHUP.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon poll,POLLHUP,0x10,0x10,0x10,0x10,0x10,2 +.syscon poll,POLLHUP,0x10,0x10,0x10,0x10,0x10,0x0002 diff --git a/libc/sysv/consts/POLLIN.S b/libc/sysv/consts/POLLIN.S index 16cc67372..02b0ca22e 100644 --- a/libc/sysv/consts/POLLIN.S +++ b/libc/sysv/consts/POLLIN.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon poll,POLLIN,1,1,1,1,1,0x300 +.syscon poll,POLLIN,1,1,1,1,1,0x0300 diff --git a/libc/sysv/consts/POLLNVAL.S b/libc/sysv/consts/POLLNVAL.S index 08d3d6d59..9e146d39b 100644 --- a/libc/sysv/consts/POLLNVAL.S +++ b/libc/sysv/consts/POLLNVAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon poll,POLLNVAL,0x20,0x20,0x20,0x20,0x20,4 +.syscon poll,POLLNVAL,0x20,0x20,0x20,0x20,0x20,0x0004 diff --git a/libc/sysv/consts/POLLOUT.S b/libc/sysv/consts/POLLOUT.S index b59eb9ef1..d1b49b515 100644 --- a/libc/sysv/consts/POLLOUT.S +++ b/libc/sysv/consts/POLLOUT.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon poll,POLLOUT,4,4,4,4,4,0x10 +.syscon poll,POLLOUT,4,4,4,4,4,0x0010 diff --git a/libc/sysv/consts/POLLWRBAND.S b/libc/sysv/consts/POLLWRBAND.S index 6701748cb..a83800d83 100644 --- a/libc/sysv/consts/POLLWRBAND.S +++ b/libc/sysv/consts/POLLWRBAND.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon poll,POLLWRBAND,0x0200,0x0100,0x0100,0x0100,0x0100,0x20 +.syscon poll,POLLWRBAND,0x0200,0x0100,0x0100,0x0100,0x0100,0x0020 diff --git a/libc/sysv/consts/POLLWRNORM.S b/libc/sysv/consts/POLLWRNORM.S index 11d6a1202..917c79ab7 100644 --- a/libc/sysv/consts/POLLWRNORM.S +++ b/libc/sysv/consts/POLLWRNORM.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon poll,POLLWRNORM,0x0100,4,4,4,4,0x10 +.syscon poll,POLLWRNORM,0x0100,4,4,4,4,0x0010 diff --git a/libc/sysv/consts/POSIX_FADV_DONTNEED.S b/libc/sysv/consts/POSIX_FADV_DONTNEED.S index b17a2a8dc..710c85ef1 100644 --- a/libc/sysv/consts/POSIX_FADV_DONTNEED.S +++ b/libc/sysv/consts/POSIX_FADV_DONTNEED.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_FADV_DONTNEED,4,0,4,4,4,0 +.syscon compat,POSIX_FADV_DONTNEED,4,127,4,4,4,127 diff --git a/libc/sysv/consts/POSIX_FADV_NOREUSE.S b/libc/sysv/consts/POSIX_FADV_NOREUSE.S index 7b1286148..ff5f39d9c 100644 --- a/libc/sysv/consts/POSIX_FADV_NOREUSE.S +++ b/libc/sysv/consts/POSIX_FADV_NOREUSE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon fadv,POSIX_FADV_NOREUSE,5,0,5,0,5,0 +.syscon fadv,POSIX_FADV_NOREUSE,5,127,5,127,5,127 diff --git a/libc/sysv/consts/POSIX_FADV_NORMAL.S b/libc/sysv/consts/POSIX_FADV_NORMAL.S index 02d3dc2b5..99b3e2bda 100644 --- a/libc/sysv/consts/POSIX_FADV_NORMAL.S +++ b/libc/sysv/consts/POSIX_FADV_NORMAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_FADV_NORMAL,0,0,0,0,0,0x00000080 +.syscon compat,POSIX_FADV_NORMAL,0,0,0,0,0,0 diff --git a/libc/sysv/consts/POSIX_FADV_RANDOM.S b/libc/sysv/consts/POSIX_FADV_RANDOM.S index 1666daa39..5c197c3bc 100644 --- a/libc/sysv/consts/POSIX_FADV_RANDOM.S +++ b/libc/sysv/consts/POSIX_FADV_RANDOM.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_FADV_RANDOM,1,0,1,1,1,0x10000000 +.syscon compat,POSIX_FADV_RANDOM,1,127,1,1,1,1 diff --git a/libc/sysv/consts/POSIX_FADV_SEQUENTIAL.S b/libc/sysv/consts/POSIX_FADV_SEQUENTIAL.S index 1f6b11052..a8dfb1688 100644 --- a/libc/sysv/consts/POSIX_FADV_SEQUENTIAL.S +++ b/libc/sysv/consts/POSIX_FADV_SEQUENTIAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_FADV_SEQUENTIAL,2,0,2,2,2,0x8000000 +.syscon compat,POSIX_FADV_SEQUENTIAL,2,127,2,2,2,2 diff --git a/libc/sysv/consts/POSIX_FADV_WILLNEED.S b/libc/sysv/consts/POSIX_FADV_WILLNEED.S index e8f60969d..7ae0fe7da 100644 --- a/libc/sysv/consts/POSIX_FADV_WILLNEED.S +++ b/libc/sysv/consts/POSIX_FADV_WILLNEED.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_FADV_WILLNEED,3,0,3,3,3,3 +.syscon compat,POSIX_FADV_WILLNEED,3,127,3,3,3,3 diff --git a/libc/sysv/consts/POSIX_MADV_DONTNEED.S b/libc/sysv/consts/POSIX_MADV_DONTNEED.S index 52f0f9ab6..77d260f6b 100644 --- a/libc/sysv/consts/POSIX_MADV_DONTNEED.S +++ b/libc/sysv/consts/POSIX_MADV_DONTNEED.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_MADV_DONTNEED,4,4,4,4,4,0 +.syscon compat,POSIX_MADV_DONTNEED,4,4,4,4,4,127 diff --git a/libc/sysv/consts/POSIX_MADV_NORMAL.S b/libc/sysv/consts/POSIX_MADV_NORMAL.S index eaf9dba1c..5bf67af47 100644 --- a/libc/sysv/consts/POSIX_MADV_NORMAL.S +++ b/libc/sysv/consts/POSIX_MADV_NORMAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_MADV_NORMAL,0,0,0,0,0,0x00000080 +.syscon compat,POSIX_MADV_NORMAL,0,0,0,0,0,0 diff --git a/libc/sysv/consts/POSIX_MADV_RANDOM.S b/libc/sysv/consts/POSIX_MADV_RANDOM.S index b1b800e01..5e4976e8e 100644 --- a/libc/sysv/consts/POSIX_MADV_RANDOM.S +++ b/libc/sysv/consts/POSIX_MADV_RANDOM.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_MADV_RANDOM,1,1,1,1,1,0x10000000 +.syscon compat,POSIX_MADV_RANDOM,1,1,1,1,1,1 diff --git a/libc/sysv/consts/POSIX_MADV_SEQUENTIAL.S b/libc/sysv/consts/POSIX_MADV_SEQUENTIAL.S index 6aa32f454..0c6183349 100644 --- a/libc/sysv/consts/POSIX_MADV_SEQUENTIAL.S +++ b/libc/sysv/consts/POSIX_MADV_SEQUENTIAL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,POSIX_MADV_SEQUENTIAL,2,2,2,2,2,0x8000000 +.syscon compat,POSIX_MADV_SEQUENTIAL,2,2,2,2,2,2 diff --git a/libc/sysv/consts/PR_CAPBSET_DROP.S b/libc/sysv/consts/PR_CAPBSET_DROP.S deleted file mode 100644 index 4b686464e..000000000 --- a/libc/sysv/consts/PR_CAPBSET_DROP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAPBSET_DROP,24,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAPBSET_READ.S b/libc/sysv/consts/PR_CAPBSET_READ.S deleted file mode 100644 index fa534ace9..000000000 --- a/libc/sysv/consts/PR_CAPBSET_READ.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAPBSET_READ,23,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT.S b/libc/sysv/consts/PR_CAP_AMBIENT.S deleted file mode 100644 index efd1a03af..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT,47,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.S b/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.S deleted file mode 100644 index 294bf1d8a..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT_CLEAR_ALL,4,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.S b/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.S deleted file mode 100644 index 2e13f3454..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT_IS_SET,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.S b/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.S deleted file mode 100644 index cd3cbb4e3..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT_LOWER,3,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.S b/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.S deleted file mode 100644 index da3d27819..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT_RAISE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_ENDIAN_BIG.S b/libc/sysv/consts/PR_ENDIAN_BIG.S deleted file mode 100644 index 83b211d77..000000000 --- a/libc/sysv/consts/PR_ENDIAN_BIG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_ENDIAN_BIG,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_ENDIAN_LITTLE.S b/libc/sysv/consts/PR_ENDIAN_LITTLE.S deleted file mode 100644 index b9b4dbd13..000000000 --- a/libc/sysv/consts/PR_ENDIAN_LITTLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_ENDIAN_LITTLE,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.S b/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.S deleted file mode 100644 index 7fd4aa188..000000000 --- a/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_ENDIAN_PPC_LITTLE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FPEMU_NOPRINT.S b/libc/sysv/consts/PR_FPEMU_NOPRINT.S deleted file mode 100644 index 10925eb6d..000000000 --- a/libc/sysv/consts/PR_FPEMU_NOPRINT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FPEMU_NOPRINT,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FPEMU_SIGFPE.S b/libc/sysv/consts/PR_FPEMU_SIGFPE.S deleted file mode 100644 index 4cbb46164..000000000 --- a/libc/sysv/consts/PR_FPEMU_SIGFPE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FPEMU_SIGFPE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_ASYNC.S b/libc/sysv/consts/PR_FP_EXC_ASYNC.S deleted file mode 100644 index f36d72396..000000000 --- a/libc/sysv/consts/PR_FP_EXC_ASYNC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_ASYNC,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_DISABLED.S b/libc/sysv/consts/PR_FP_EXC_DISABLED.S deleted file mode 100644 index 8cc774685..000000000 --- a/libc/sysv/consts/PR_FP_EXC_DISABLED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_DISABLED,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_DIV.S b/libc/sysv/consts/PR_FP_EXC_DIV.S deleted file mode 100644 index fc8ad75b1..000000000 --- a/libc/sysv/consts/PR_FP_EXC_DIV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_DIV,0x010000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_INV.S b/libc/sysv/consts/PR_FP_EXC_INV.S deleted file mode 100644 index 85475ca11..000000000 --- a/libc/sysv/consts/PR_FP_EXC_INV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_INV,0x100000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_NONRECOV.S b/libc/sysv/consts/PR_FP_EXC_NONRECOV.S deleted file mode 100644 index f57d78bdf..000000000 --- a/libc/sysv/consts/PR_FP_EXC_NONRECOV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_NONRECOV,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_OVF.S b/libc/sysv/consts/PR_FP_EXC_OVF.S deleted file mode 100644 index 07ff9ac8d..000000000 --- a/libc/sysv/consts/PR_FP_EXC_OVF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_OVF,0x020000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_PRECISE.S b/libc/sysv/consts/PR_FP_EXC_PRECISE.S deleted file mode 100644 index f55e2600b..000000000 --- a/libc/sysv/consts/PR_FP_EXC_PRECISE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_PRECISE,3,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_RES.S b/libc/sysv/consts/PR_FP_EXC_RES.S deleted file mode 100644 index 234428b05..000000000 --- a/libc/sysv/consts/PR_FP_EXC_RES.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_RES,0x080000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.S b/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.S deleted file mode 100644 index 7ac6c8101..000000000 --- a/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_SW_ENABLE,0x80,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_UND.S b/libc/sysv/consts/PR_FP_EXC_UND.S deleted file mode 100644 index ba05501ca..000000000 --- a/libc/sysv/consts/PR_FP_EXC_UND.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_UND,0x040000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_MODE_FR.S b/libc/sysv/consts/PR_FP_MODE_FR.S deleted file mode 100644 index 8948def13..000000000 --- a/libc/sysv/consts/PR_FP_MODE_FR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_MODE_FR,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_MODE_FRE.S b/libc/sysv/consts/PR_FP_MODE_FRE.S deleted file mode 100644 index 03f89460c..000000000 --- a/libc/sysv/consts/PR_FP_MODE_FRE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_MODE_FRE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.S b/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.S deleted file mode 100644 index ad1aeec26..000000000 --- a/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_CHILD_SUBREAPER,37,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_DUMPABLE.S b/libc/sysv/consts/PR_GET_DUMPABLE.S deleted file mode 100644 index e1dd69fdb..000000000 --- a/libc/sysv/consts/PR_GET_DUMPABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_DUMPABLE,3,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_ENDIAN.S b/libc/sysv/consts/PR_GET_ENDIAN.S deleted file mode 100644 index 8d2f95582..000000000 --- a/libc/sysv/consts/PR_GET_ENDIAN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_ENDIAN,19,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_FPEMU.S b/libc/sysv/consts/PR_GET_FPEMU.S deleted file mode 100644 index df847914a..000000000 --- a/libc/sysv/consts/PR_GET_FPEMU.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_FPEMU,9,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_FPEXC.S b/libc/sysv/consts/PR_GET_FPEXC.S deleted file mode 100644 index 1e2caa8f9..000000000 --- a/libc/sysv/consts/PR_GET_FPEXC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_FPEXC,11,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_FP_MODE.S b/libc/sysv/consts/PR_GET_FP_MODE.S deleted file mode 100644 index 07252f7df..000000000 --- a/libc/sysv/consts/PR_GET_FP_MODE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_FP_MODE,46,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_KEEPCAPS.S b/libc/sysv/consts/PR_GET_KEEPCAPS.S deleted file mode 100644 index cf71ee7fb..000000000 --- a/libc/sysv/consts/PR_GET_KEEPCAPS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_KEEPCAPS,7,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_NAME.S b/libc/sysv/consts/PR_GET_NAME.S deleted file mode 100644 index ef5987835..000000000 --- a/libc/sysv/consts/PR_GET_NAME.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_NAME,0x10,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.S b/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.S deleted file mode 100644 index 17ace0567..000000000 --- a/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_NO_NEW_PRIVS,39,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_PDEATHSIG.S b/libc/sysv/consts/PR_GET_PDEATHSIG.S deleted file mode 100644 index 6b0883ef3..000000000 --- a/libc/sysv/consts/PR_GET_PDEATHSIG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_PDEATHSIG,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_SECCOMP.S b/libc/sysv/consts/PR_GET_SECCOMP.S deleted file mode 100644 index 5a49f97de..000000000 --- a/libc/sysv/consts/PR_GET_SECCOMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_SECCOMP,21,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_SECUREBITS.S b/libc/sysv/consts/PR_GET_SECUREBITS.S deleted file mode 100644 index 061ece0ae..000000000 --- a/libc/sysv/consts/PR_GET_SECUREBITS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_SECUREBITS,27,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_SPECULATION_CTRL.S b/libc/sysv/consts/PR_GET_SPECULATION_CTRL.S deleted file mode 100644 index fbc620150..000000000 --- a/libc/sysv/consts/PR_GET_SPECULATION_CTRL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_SPECULATION_CTRL,52,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_THP_DISABLE.S b/libc/sysv/consts/PR_GET_THP_DISABLE.S deleted file mode 100644 index 14fbf6d23..000000000 --- a/libc/sysv/consts/PR_GET_THP_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_THP_DISABLE,42,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_TID_ADDRESS.S b/libc/sysv/consts/PR_GET_TID_ADDRESS.S deleted file mode 100644 index 31f35d285..000000000 --- a/libc/sysv/consts/PR_GET_TID_ADDRESS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_TID_ADDRESS,40,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_TIMERSLACK.S b/libc/sysv/consts/PR_GET_TIMERSLACK.S deleted file mode 100644 index b713ba6ca..000000000 --- a/libc/sysv/consts/PR_GET_TIMERSLACK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_TIMERSLACK,30,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_TIMING.S b/libc/sysv/consts/PR_GET_TIMING.S deleted file mode 100644 index 6de7b07b4..000000000 --- a/libc/sysv/consts/PR_GET_TIMING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_TIMING,13,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_TSC.S b/libc/sysv/consts/PR_GET_TSC.S deleted file mode 100644 index 93ec93d88..000000000 --- a/libc/sysv/consts/PR_GET_TSC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_TSC,25,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_UNALIGN.S b/libc/sysv/consts/PR_GET_UNALIGN.S deleted file mode 100644 index cfd961d09..000000000 --- a/libc/sysv/consts/PR_GET_UNALIGN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_UNALIGN,5,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL.S b/libc/sysv/consts/PR_MCE_KILL.S deleted file mode 100644 index 15c958ea3..000000000 --- a/libc/sysv/consts/PR_MCE_KILL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL,33,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_CLEAR.S b/libc/sysv/consts/PR_MCE_KILL_CLEAR.S deleted file mode 100644 index bb9f4c94a..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_CLEAR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_CLEAR,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_DEFAULT.S b/libc/sysv/consts/PR_MCE_KILL_DEFAULT.S deleted file mode 100644 index 739713661..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_DEFAULT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_DEFAULT,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_EARLY.S b/libc/sysv/consts/PR_MCE_KILL_EARLY.S deleted file mode 100644 index 155ddb9a9..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_EARLY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_EARLY,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_GET.S b/libc/sysv/consts/PR_MCE_KILL_GET.S deleted file mode 100644 index e5a7a3234..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_GET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_GET,34,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_LATE.S b/libc/sysv/consts/PR_MCE_KILL_LATE.S deleted file mode 100644 index 36b6c0ff7..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_LATE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_LATE,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_SET.S b/libc/sysv/consts/PR_MCE_KILL_SET.S deleted file mode 100644 index 3956109cc..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_SET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_SET,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.S b/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.S deleted file mode 100644 index aa70185a8..000000000 --- a/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MPX_DISABLE_MANAGEMENT,44,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.S b/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.S deleted file mode 100644 index 40a829d6b..000000000 --- a/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MPX_ENABLE_MANAGEMENT,43,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.S b/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.S deleted file mode 100644 index 1db02010c..000000000 --- a/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_CHILD_SUBREAPER,36,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_DUMPABLE.S b/libc/sysv/consts/PR_SET_DUMPABLE.S deleted file mode 100644 index ce11a6fa1..000000000 --- a/libc/sysv/consts/PR_SET_DUMPABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_DUMPABLE,4,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_ENDIAN.S b/libc/sysv/consts/PR_SET_ENDIAN.S deleted file mode 100644 index 6c0721fde..000000000 --- a/libc/sysv/consts/PR_SET_ENDIAN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_ENDIAN,20,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_FPEMU.S b/libc/sysv/consts/PR_SET_FPEMU.S deleted file mode 100644 index 553118d9d..000000000 --- a/libc/sysv/consts/PR_SET_FPEMU.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_FPEMU,10,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_FPEXC.S b/libc/sysv/consts/PR_SET_FPEXC.S deleted file mode 100644 index 9286d0582..000000000 --- a/libc/sysv/consts/PR_SET_FPEXC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_FPEXC,12,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_FP_MODE.S b/libc/sysv/consts/PR_SET_FP_MODE.S deleted file mode 100644 index c0e0a9633..000000000 --- a/libc/sysv/consts/PR_SET_FP_MODE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_FP_MODE,45,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_KEEPCAPS.S b/libc/sysv/consts/PR_SET_KEEPCAPS.S deleted file mode 100644 index ee5e15f32..000000000 --- a/libc/sysv/consts/PR_SET_KEEPCAPS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_KEEPCAPS,8,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM.S b/libc/sysv/consts/PR_SET_MM.S deleted file mode 100644 index 459d4e9e2..000000000 --- a/libc/sysv/consts/PR_SET_MM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM,35,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_ARG_END.S b/libc/sysv/consts/PR_SET_MM_ARG_END.S deleted file mode 100644 index 4bc2ebe7a..000000000 --- a/libc/sysv/consts/PR_SET_MM_ARG_END.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_ARG_END,9,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_ARG_START.S b/libc/sysv/consts/PR_SET_MM_ARG_START.S deleted file mode 100644 index fd6f32a8a..000000000 --- a/libc/sysv/consts/PR_SET_MM_ARG_START.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_ARG_START,8,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_AUXV.S b/libc/sysv/consts/PR_SET_MM_AUXV.S deleted file mode 100644 index 7f0d3726e..000000000 --- a/libc/sysv/consts/PR_SET_MM_AUXV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_AUXV,12,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_BRK.S b/libc/sysv/consts/PR_SET_MM_BRK.S deleted file mode 100644 index bf84d9aff..000000000 --- a/libc/sysv/consts/PR_SET_MM_BRK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_BRK,7,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_END_CODE.S b/libc/sysv/consts/PR_SET_MM_END_CODE.S deleted file mode 100644 index 39311d767..000000000 --- a/libc/sysv/consts/PR_SET_MM_END_CODE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_END_CODE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_END_DATA.S b/libc/sysv/consts/PR_SET_MM_END_DATA.S deleted file mode 100644 index e8b856808..000000000 --- a/libc/sysv/consts/PR_SET_MM_END_DATA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_END_DATA,4,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_ENV_END.S b/libc/sysv/consts/PR_SET_MM_ENV_END.S deleted file mode 100644 index f23384115..000000000 --- a/libc/sysv/consts/PR_SET_MM_ENV_END.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_ENV_END,11,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_ENV_START.S b/libc/sysv/consts/PR_SET_MM_ENV_START.S deleted file mode 100644 index dbc7f89ca..000000000 --- a/libc/sysv/consts/PR_SET_MM_ENV_START.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_ENV_START,10,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_EXE_FILE.S b/libc/sysv/consts/PR_SET_MM_EXE_FILE.S deleted file mode 100644 index b36a437a4..000000000 --- a/libc/sysv/consts/PR_SET_MM_EXE_FILE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_EXE_FILE,13,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_MAP.S b/libc/sysv/consts/PR_SET_MM_MAP.S deleted file mode 100644 index 9ecc3c198..000000000 --- a/libc/sysv/consts/PR_SET_MM_MAP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_MAP,14,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_MAP_SIZE.S b/libc/sysv/consts/PR_SET_MM_MAP_SIZE.S deleted file mode 100644 index d4a755863..000000000 --- a/libc/sysv/consts/PR_SET_MM_MAP_SIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_MAP_SIZE,15,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_START_BRK.S b/libc/sysv/consts/PR_SET_MM_START_BRK.S deleted file mode 100644 index 424305ca1..000000000 --- a/libc/sysv/consts/PR_SET_MM_START_BRK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_START_BRK,6,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_START_CODE.S b/libc/sysv/consts/PR_SET_MM_START_CODE.S deleted file mode 100644 index 92f18baf1..000000000 --- a/libc/sysv/consts/PR_SET_MM_START_CODE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_START_CODE,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_START_DATA.S b/libc/sysv/consts/PR_SET_MM_START_DATA.S deleted file mode 100644 index 470747118..000000000 --- a/libc/sysv/consts/PR_SET_MM_START_DATA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_START_DATA,3,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_START_STACK.S b/libc/sysv/consts/PR_SET_MM_START_STACK.S deleted file mode 100644 index 5488e02e7..000000000 --- a/libc/sysv/consts/PR_SET_MM_START_STACK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_START_STACK,5,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_NAME.S b/libc/sysv/consts/PR_SET_NAME.S deleted file mode 100644 index f8db3d489..000000000 --- a/libc/sysv/consts/PR_SET_NAME.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_NAME,15,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.S b/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.S deleted file mode 100644 index 8d17b8295..000000000 --- a/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_NO_NEW_PRIVS,38,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_PDEATHSIG.S b/libc/sysv/consts/PR_SET_PDEATHSIG.S deleted file mode 100644 index 3eeb2d91d..000000000 --- a/libc/sysv/consts/PR_SET_PDEATHSIG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_PDEATHSIG,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_PTRACER.S b/libc/sysv/consts/PR_SET_PTRACER.S deleted file mode 100644 index afdb5374f..000000000 --- a/libc/sysv/consts/PR_SET_PTRACER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_PTRACER,0x59616d61,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_PTRACER_ANY.S b/libc/sysv/consts/PR_SET_PTRACER_ANY.S deleted file mode 100644 index d955036a1..000000000 --- a/libc/sysv/consts/PR_SET_PTRACER_ANY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_PTRACER_ANY,-1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_SECCOMP.S b/libc/sysv/consts/PR_SET_SECCOMP.S deleted file mode 100644 index 6cd99bf03..000000000 --- a/libc/sysv/consts/PR_SET_SECCOMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_SECCOMP,22,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_SECUREBITS.S b/libc/sysv/consts/PR_SET_SECUREBITS.S deleted file mode 100644 index dedc7fa57..000000000 --- a/libc/sysv/consts/PR_SET_SECUREBITS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_SECUREBITS,28,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_SPECULATION_CTRL.S b/libc/sysv/consts/PR_SET_SPECULATION_CTRL.S deleted file mode 100644 index 068eadfcd..000000000 --- a/libc/sysv/consts/PR_SET_SPECULATION_CTRL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_SPECULATION_CTRL,53,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_THP_DISABLE.S b/libc/sysv/consts/PR_SET_THP_DISABLE.S deleted file mode 100644 index 5ac7f0af2..000000000 --- a/libc/sysv/consts/PR_SET_THP_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_THP_DISABLE,41,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_TIMERSLACK.S b/libc/sysv/consts/PR_SET_TIMERSLACK.S deleted file mode 100644 index fb7177863..000000000 --- a/libc/sysv/consts/PR_SET_TIMERSLACK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_TIMERSLACK,29,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_TIMING.S b/libc/sysv/consts/PR_SET_TIMING.S deleted file mode 100644 index fee4162b1..000000000 --- a/libc/sysv/consts/PR_SET_TIMING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_TIMING,14,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_TSC.S b/libc/sysv/consts/PR_SET_TSC.S deleted file mode 100644 index 3facbf5c0..000000000 --- a/libc/sysv/consts/PR_SET_TSC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_TSC,26,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_UNALIGN.S b/libc/sysv/consts/PR_SET_UNALIGN.S deleted file mode 100644 index c5f5f0fc7..000000000 --- a/libc/sysv/consts/PR_SET_UNALIGN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_UNALIGN,6,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_DISABLE.S b/libc/sysv/consts/PR_SPEC_DISABLE.S deleted file mode 100644 index 02ed8d3ab..000000000 --- a/libc/sysv/consts/PR_SPEC_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_DISABLE,4,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_ENABLE.S b/libc/sysv/consts/PR_SPEC_ENABLE.S deleted file mode 100644 index dc0756fd9..000000000 --- a/libc/sysv/consts/PR_SPEC_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_ENABLE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.S b/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.S deleted file mode 100644 index a610707ac..000000000 --- a/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_FORCE_DISABLE,8,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.S b/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.S deleted file mode 100644 index d848f40a4..000000000 --- a/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_NOT_AFFECTED,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_PRCTL.S b/libc/sysv/consts/PR_SPEC_PRCTL.S deleted file mode 100644 index abb92d3fb..000000000 --- a/libc/sysv/consts/PR_SPEC_PRCTL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_PRCTL,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_STORE_BYPASS.S b/libc/sysv/consts/PR_SPEC_STORE_BYPASS.S deleted file mode 100644 index 07bf3f364..000000000 --- a/libc/sysv/consts/PR_SPEC_STORE_BYPASS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_STORE_BYPASS,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.S b/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.S deleted file mode 100644 index 8a8d0657e..000000000 --- a/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TASK_PERF_EVENTS_DISABLE,31,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.S b/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.S deleted file mode 100644 index c44f7ba4d..000000000 --- a/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TASK_PERF_EVENTS_ENABLE,0x20,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TIMING_STATISTICAL.S b/libc/sysv/consts/PR_TIMING_STATISTICAL.S deleted file mode 100644 index 287a2a6d8..000000000 --- a/libc/sysv/consts/PR_TIMING_STATISTICAL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TIMING_STATISTICAL,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TIMING_TIMESTAMP.S b/libc/sysv/consts/PR_TIMING_TIMESTAMP.S deleted file mode 100644 index e44d31a21..000000000 --- a/libc/sysv/consts/PR_TIMING_TIMESTAMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TIMING_TIMESTAMP,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TSC_ENABLE.S b/libc/sysv/consts/PR_TSC_ENABLE.S deleted file mode 100644 index 3ac5b3c40..000000000 --- a/libc/sysv/consts/PR_TSC_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TSC_ENABLE,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TSC_SIGSEGV.S b/libc/sysv/consts/PR_TSC_SIGSEGV.S deleted file mode 100644 index c189af59e..000000000 --- a/libc/sysv/consts/PR_TSC_SIGSEGV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TSC_SIGSEGV,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_UNALIGN_NOPRINT.S b/libc/sysv/consts/PR_UNALIGN_NOPRINT.S deleted file mode 100644 index da14fbf25..000000000 --- a/libc/sysv/consts/PR_UNALIGN_NOPRINT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_UNALIGN_NOPRINT,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_UNALIGN_SIGBUS.S b/libc/sysv/consts/PR_UNALIGN_SIGBUS.S deleted file mode 100644 index 3e05888ff..000000000 --- a/libc/sysv/consts/PR_UNALIGN_SIGBUS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_UNALIGN_SIGBUS,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PTRACE_EVENT_SECCOMP.S b/libc/sysv/consts/PTRACE_EVENT_SECCOMP.S new file mode 100644 index 000000000..81f486a31 --- /dev/null +++ b/libc/sysv/consts/PTRACE_EVENT_SECCOMP.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon ptrace,PTRACE_EVENT_SECCOMP,7,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/PTRACE_EVENT_STOP.S b/libc/sysv/consts/PTRACE_EVENT_STOP.S new file mode 100644 index 000000000..8aaf95499 --- /dev/null +++ b/libc/sysv/consts/PTRACE_EVENT_STOP.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon ptrace,PTRACE_EVENT_STOP,128,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/PTRACE_O_TRACESECCOMP.S b/libc/sysv/consts/PTRACE_O_TRACESECCOMP.S new file mode 100644 index 000000000..85d279b86 --- /dev/null +++ b/libc/sysv/consts/PTRACE_O_TRACESECCOMP.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon ptrace,PTRACE_O_TRACESECCOMP,0x0080,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/READ_10.S b/libc/sysv/consts/READ_10.S deleted file mode 100644 index 61042b8e0..000000000 --- a/libc/sysv/consts/READ_10.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_10,40,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_12.S b/libc/sysv/consts/READ_12.S deleted file mode 100644 index 048ee93e2..000000000 --- a/libc/sysv/consts/READ_12.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_12,168,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_6.S b/libc/sysv/consts/READ_6.S deleted file mode 100644 index 00dae3890..000000000 --- a/libc/sysv/consts/READ_6.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_6,8,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_BLOCK_LIMITS.S b/libc/sysv/consts/READ_BLOCK_LIMITS.S deleted file mode 100644 index 91b01f5ff..000000000 --- a/libc/sysv/consts/READ_BLOCK_LIMITS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_BLOCK_LIMITS,5,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_BUFFER.S b/libc/sysv/consts/READ_BUFFER.S deleted file mode 100644 index 66c0bdf8e..000000000 --- a/libc/sysv/consts/READ_BUFFER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_BUFFER,60,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_CAPACITY.S b/libc/sysv/consts/READ_CAPACITY.S deleted file mode 100644 index 6dd06c03e..000000000 --- a/libc/sysv/consts/READ_CAPACITY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_CAPACITY,37,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_DEFECT_DATA.S b/libc/sysv/consts/READ_DEFECT_DATA.S deleted file mode 100644 index 84fb61d8d..000000000 --- a/libc/sysv/consts/READ_DEFECT_DATA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_DEFECT_DATA,55,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_ELEMENT_STATUS.S b/libc/sysv/consts/READ_ELEMENT_STATUS.S deleted file mode 100644 index 14a56851f..000000000 --- a/libc/sysv/consts/READ_ELEMENT_STATUS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_ELEMENT_STATUS,184,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_LONG.S b/libc/sysv/consts/READ_LONG.S deleted file mode 100644 index 7be143b66..000000000 --- a/libc/sysv/consts/READ_LONG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_LONG,62,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_POSITION.S b/libc/sysv/consts/READ_POSITION.S deleted file mode 100644 index 393cb5ca4..000000000 --- a/libc/sysv/consts/READ_POSITION.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_POSITION,52,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_REVERSE.S b/libc/sysv/consts/READ_REVERSE.S deleted file mode 100644 index d206e3f65..000000000 --- a/libc/sysv/consts/READ_REVERSE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_REVERSE,15,0,0,0,0,0 diff --git a/libc/sysv/consts/READ_TOC.S b/libc/sysv/consts/READ_TOC.S deleted file mode 100644 index 46d1301be..000000000 --- a/libc/sysv/consts/READ_TOC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,READ_TOC,67,0,0,0,0,0 diff --git a/libc/sysv/consts/RLIMIT_AS.S b/libc/sysv/consts/RLIMIT_AS.S index 00f1f8ea2..6566a9f46 100644 --- a/libc/sysv/consts/RLIMIT_AS.S +++ b/libc/sysv/consts/RLIMIT_AS.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon rlimit,RLIMIT_AS,9,5,10,127,10,127 +.syscon rlimit,RLIMIT_AS,9,5,10,2,10,0 diff --git a/libc/sysv/consts/RLIM_INFINITY.S b/libc/sysv/consts/RLIM_INFINITY.S index 422e8ccc7..dc4f5dd5f 100644 --- a/libc/sysv/consts/RLIM_INFINITY.S +++ b/libc/sysv/consts/RLIM_INFINITY.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon rlim,RLIM_INFINITY,0xffffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0 +.syscon rlim,RLIM_INFINITY,0xffffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0xffffffffffffffff diff --git a/libc/sysv/consts/RLIM_NLIMITS.S b/libc/sysv/consts/RLIM_NLIMITS.S index ca3b0635d..6d78ad657 100644 --- a/libc/sysv/consts/RLIM_NLIMITS.S +++ b/libc/sysv/consts/RLIM_NLIMITS.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon rlim,RLIM_NLIMITS,16,9,15,9,12,0 +.syscon rlim,RLIM_NLIMITS,16,9,15,9,12,1 diff --git a/libc/sysv/consts/RLIM_SAVED_CUR.S b/libc/sysv/consts/RLIM_SAVED_CUR.S index 78d294007..af38d59b7 100644 --- a/libc/sysv/consts/RLIM_SAVED_CUR.S +++ b/libc/sysv/consts/RLIM_SAVED_CUR.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon rlim,RLIM_SAVED_CUR,0xffffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0 +.syscon rlim,RLIM_SAVED_CUR,0xffffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0xffffffffffffffff diff --git a/libc/sysv/consts/RLIM_SAVED_MAX.S b/libc/sysv/consts/RLIM_SAVED_MAX.S index 67b4fc5d6..40807baa6 100644 --- a/libc/sysv/consts/RLIM_SAVED_MAX.S +++ b/libc/sysv/consts/RLIM_SAVED_MAX.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon rlim,RLIM_SAVED_MAX,0xffffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0 +.syscon rlim,RLIM_SAVED_MAX,0xffffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0x7fffffffffffffff,0xffffffffffffffff diff --git a/libc/sysv/consts/SCSI_IOCTL_BENCHMARK_COMMAND.S b/libc/sysv/consts/SCSI_IOCTL_BENCHMARK_COMMAND.S deleted file mode 100644 index cc60c5210..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_BENCHMARK_COMMAND.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_BENCHMARK_COMMAND,3,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_DOORLOCK.S b/libc/sysv/consts/SCSI_IOCTL_DOORLOCK.S deleted file mode 100644 index 6b409e871..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_DOORLOCK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_DOORLOCK,0x5380,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_DOORUNLOCK.S b/libc/sysv/consts/SCSI_IOCTL_DOORUNLOCK.S deleted file mode 100644 index 9aa9d4b65..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_DOORUNLOCK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_DOORUNLOCK,0x5381,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_GET_BUS_NUMBER.S b/libc/sysv/consts/SCSI_IOCTL_GET_BUS_NUMBER.S deleted file mode 100644 index 1b96bdc54..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_GET_BUS_NUMBER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_GET_BUS_NUMBER,0x5386,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_GET_IDLUN.S b/libc/sysv/consts/SCSI_IOCTL_GET_IDLUN.S deleted file mode 100644 index d5d88ee0b..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_GET_IDLUN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_GET_IDLUN,0x5382,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_PROBE_HOST.S b/libc/sysv/consts/SCSI_IOCTL_PROBE_HOST.S deleted file mode 100644 index 70413e978..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_PROBE_HOST.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_PROBE_HOST,0x5385,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_SEND_COMMAND.S b/libc/sysv/consts/SCSI_IOCTL_SEND_COMMAND.S deleted file mode 100644 index db838a26e..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_SEND_COMMAND.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_SEND_COMMAND,1,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_START_UNIT.S b/libc/sysv/consts/SCSI_IOCTL_START_UNIT.S deleted file mode 100644 index b46792db3..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_START_UNIT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_START_UNIT,5,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_STOP_UNIT.S b/libc/sysv/consts/SCSI_IOCTL_STOP_UNIT.S deleted file mode 100644 index 5ddc444d4..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_STOP_UNIT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_STOP_UNIT,6,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_SYNC.S b/libc/sysv/consts/SCSI_IOCTL_SYNC.S deleted file mode 100644 index d73e8e343..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_SYNC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_SYNC,4,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_TAGGED_DISABLE.S b/libc/sysv/consts/SCSI_IOCTL_TAGGED_DISABLE.S deleted file mode 100644 index 943f46500..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_TAGGED_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_TAGGED_DISABLE,0x5384,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_TAGGED_ENABLE.S b/libc/sysv/consts/SCSI_IOCTL_TAGGED_ENABLE.S deleted file mode 100644 index 5c3ebf578..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_TAGGED_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_TAGGED_ENABLE,0x5383,0,0,0,0,0 diff --git a/libc/sysv/consts/SCSI_IOCTL_TEST_UNIT_READY.S b/libc/sysv/consts/SCSI_IOCTL_TEST_UNIT_READY.S deleted file mode 100644 index eb37c0d1c..000000000 --- a/libc/sysv/consts/SCSI_IOCTL_TEST_UNIT_READY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,SCSI_IOCTL_TEST_UNIT_READY,2,0,0,0,0,0 diff --git a/libc/sysv/consts/SEGV_PKUERR.S b/libc/sysv/consts/SEGV_PKUERR.S new file mode 100644 index 000000000..56b6d5418 --- /dev/null +++ b/libc/sysv/consts/SEGV_PKUERR.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon sicode,SEGV_PKUERR,-1,-1,100,-1,-1,-1 diff --git a/libc/sysv/consts/SG_BIG_BUFF.S b/libc/sysv/consts/SG_BIG_BUFF.S deleted file mode 100644 index f198866a9..000000000 --- a/libc/sysv/consts/SG_BIG_BUFF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_BIG_BUFF,0x8000,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DEFAULT_RETRIES.S b/libc/sysv/consts/SG_DEFAULT_RETRIES.S deleted file mode 100644 index 7914dfae6..000000000 --- a/libc/sysv/consts/SG_DEFAULT_RETRIES.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DEFAULT_RETRIES,1,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DEFAULT_TIMEOUT.S b/libc/sysv/consts/SG_DEFAULT_TIMEOUT.S deleted file mode 100644 index c356cb4dc..000000000 --- a/libc/sysv/consts/SG_DEFAULT_TIMEOUT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DEFAULT_TIMEOUT,0x1770,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DEF_COMMAND_Q.S b/libc/sysv/consts/SG_DEF_COMMAND_Q.S deleted file mode 100644 index d7d57c500..000000000 --- a/libc/sysv/consts/SG_DEF_COMMAND_Q.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DEF_COMMAND_Q,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DEF_FORCE_LOW_DMA.S b/libc/sysv/consts/SG_DEF_FORCE_LOW_DMA.S deleted file mode 100644 index d54248e22..000000000 --- a/libc/sysv/consts/SG_DEF_FORCE_LOW_DMA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DEF_FORCE_LOW_DMA,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DEF_FORCE_PACK_ID.S b/libc/sysv/consts/SG_DEF_FORCE_PACK_ID.S deleted file mode 100644 index b54a99997..000000000 --- a/libc/sysv/consts/SG_DEF_FORCE_PACK_ID.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DEF_FORCE_PACK_ID,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DEF_KEEP_ORPHAN.S b/libc/sysv/consts/SG_DEF_KEEP_ORPHAN.S deleted file mode 100644 index 008812e4d..000000000 --- a/libc/sysv/consts/SG_DEF_KEEP_ORPHAN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DEF_KEEP_ORPHAN,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DEF_RESERVED_SIZE.S b/libc/sysv/consts/SG_DEF_RESERVED_SIZE.S deleted file mode 100644 index f006d7755..000000000 --- a/libc/sysv/consts/SG_DEF_RESERVED_SIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DEF_RESERVED_SIZE,0x8000,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DEF_UNDERRUN_FLAG.S b/libc/sysv/consts/SG_DEF_UNDERRUN_FLAG.S deleted file mode 100644 index d6bee2c02..000000000 --- a/libc/sysv/consts/SG_DEF_UNDERRUN_FLAG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DEF_UNDERRUN_FLAG,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DXFER_FROM_DEV.S b/libc/sysv/consts/SG_DXFER_FROM_DEV.S deleted file mode 100644 index d56bc646f..000000000 --- a/libc/sysv/consts/SG_DXFER_FROM_DEV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DXFER_FROM_DEV,-3,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DXFER_NONE.S b/libc/sysv/consts/SG_DXFER_NONE.S deleted file mode 100644 index 3b797189b..000000000 --- a/libc/sysv/consts/SG_DXFER_NONE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DXFER_NONE,-1,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DXFER_TO_DEV.S b/libc/sysv/consts/SG_DXFER_TO_DEV.S deleted file mode 100644 index 14d9b74e8..000000000 --- a/libc/sysv/consts/SG_DXFER_TO_DEV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DXFER_TO_DEV,-2,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_DXFER_TO_FROM_DEV.S b/libc/sysv/consts/SG_DXFER_TO_FROM_DEV.S deleted file mode 100644 index 1de413c21..000000000 --- a/libc/sysv/consts/SG_DXFER_TO_FROM_DEV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_DXFER_TO_FROM_DEV,-4,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_EMULATED_HOST.S b/libc/sysv/consts/SG_EMULATED_HOST.S deleted file mode 100644 index 27a124916..000000000 --- a/libc/sysv/consts/SG_EMULATED_HOST.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_EMULATED_HOST,0x2203,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_FLAG_DIRECT_IO.S b/libc/sysv/consts/SG_FLAG_DIRECT_IO.S deleted file mode 100644 index 00014849d..000000000 --- a/libc/sysv/consts/SG_FLAG_DIRECT_IO.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_FLAG_DIRECT_IO,1,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_FLAG_LUN_INHIBIT.S b/libc/sysv/consts/SG_FLAG_LUN_INHIBIT.S deleted file mode 100644 index cf3331cf6..000000000 --- a/libc/sysv/consts/SG_FLAG_LUN_INHIBIT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_FLAG_LUN_INHIBIT,2,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_FLAG_NO_DXFER.S b/libc/sysv/consts/SG_FLAG_NO_DXFER.S deleted file mode 100644 index 7c750d0b3..000000000 --- a/libc/sysv/consts/SG_FLAG_NO_DXFER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_FLAG_NO_DXFER,0x010000,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_COMMAND_Q.S b/libc/sysv/consts/SG_GET_COMMAND_Q.S deleted file mode 100644 index 256bb4af4..000000000 --- a/libc/sysv/consts/SG_GET_COMMAND_Q.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_COMMAND_Q,0x2270,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_KEEP_ORPHAN.S b/libc/sysv/consts/SG_GET_KEEP_ORPHAN.S deleted file mode 100644 index 85a401b98..000000000 --- a/libc/sysv/consts/SG_GET_KEEP_ORPHAN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_KEEP_ORPHAN,0x2288,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_LOW_DMA.S b/libc/sysv/consts/SG_GET_LOW_DMA.S deleted file mode 100644 index 2f4ea2c6a..000000000 --- a/libc/sysv/consts/SG_GET_LOW_DMA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_LOW_DMA,0x227a,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_NUM_WAITING.S b/libc/sysv/consts/SG_GET_NUM_WAITING.S deleted file mode 100644 index 1e053731e..000000000 --- a/libc/sysv/consts/SG_GET_NUM_WAITING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_NUM_WAITING,0x227d,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_PACK_ID.S b/libc/sysv/consts/SG_GET_PACK_ID.S deleted file mode 100644 index fc4d3e206..000000000 --- a/libc/sysv/consts/SG_GET_PACK_ID.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_PACK_ID,0x227c,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_REQUEST_TABLE.S b/libc/sysv/consts/SG_GET_REQUEST_TABLE.S deleted file mode 100644 index a6ddb2d01..000000000 --- a/libc/sysv/consts/SG_GET_REQUEST_TABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_REQUEST_TABLE,0x2286,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_RESERVED_SIZE.S b/libc/sysv/consts/SG_GET_RESERVED_SIZE.S deleted file mode 100644 index 8cc5b46d8..000000000 --- a/libc/sysv/consts/SG_GET_RESERVED_SIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_RESERVED_SIZE,0x2272,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_SCSI_ID.S b/libc/sysv/consts/SG_GET_SCSI_ID.S deleted file mode 100644 index 99e338682..000000000 --- a/libc/sysv/consts/SG_GET_SCSI_ID.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_SCSI_ID,0x2276,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_SG_TABLESIZE.S b/libc/sysv/consts/SG_GET_SG_TABLESIZE.S deleted file mode 100644 index 2f82def1e..000000000 --- a/libc/sysv/consts/SG_GET_SG_TABLESIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_SG_TABLESIZE,0x227f,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_TIMEOUT.S b/libc/sysv/consts/SG_GET_TIMEOUT.S deleted file mode 100644 index 290c678a7..000000000 --- a/libc/sysv/consts/SG_GET_TIMEOUT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_TIMEOUT,0x2202,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_TRANSFORM.S b/libc/sysv/consts/SG_GET_TRANSFORM.S deleted file mode 100644 index 81dbb140c..000000000 --- a/libc/sysv/consts/SG_GET_TRANSFORM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_TRANSFORM,0x2205,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_GET_VERSION_NUM.S b/libc/sysv/consts/SG_GET_VERSION_NUM.S deleted file mode 100644 index c0553e518..000000000 --- a/libc/sysv/consts/SG_GET_VERSION_NUM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_GET_VERSION_NUM,0x2282,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_INFO_CHECK.S b/libc/sysv/consts/SG_INFO_CHECK.S deleted file mode 100644 index 62c53d83a..000000000 --- a/libc/sysv/consts/SG_INFO_CHECK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_INFO_CHECK,1,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_INFO_DIRECT_IO.S b/libc/sysv/consts/SG_INFO_DIRECT_IO.S deleted file mode 100644 index 6e540e75d..000000000 --- a/libc/sysv/consts/SG_INFO_DIRECT_IO.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_INFO_DIRECT_IO,2,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_INFO_DIRECT_IO_MASK.S b/libc/sysv/consts/SG_INFO_DIRECT_IO_MASK.S deleted file mode 100644 index fec81aadc..000000000 --- a/libc/sysv/consts/SG_INFO_DIRECT_IO_MASK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_INFO_DIRECT_IO_MASK,6,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_INFO_INDIRECT_IO.S b/libc/sysv/consts/SG_INFO_INDIRECT_IO.S deleted file mode 100644 index 57a9d22e7..000000000 --- a/libc/sysv/consts/SG_INFO_INDIRECT_IO.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_INFO_INDIRECT_IO,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_INFO_MIXED_IO.S b/libc/sysv/consts/SG_INFO_MIXED_IO.S deleted file mode 100644 index 9551646fb..000000000 --- a/libc/sysv/consts/SG_INFO_MIXED_IO.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_INFO_MIXED_IO,4,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_INFO_OK.S b/libc/sysv/consts/SG_INFO_OK.S deleted file mode 100644 index ff402db93..000000000 --- a/libc/sysv/consts/SG_INFO_OK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_INFO_OK,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_INFO_OK_MASK.S b/libc/sysv/consts/SG_INFO_OK_MASK.S deleted file mode 100644 index 4f21161cd..000000000 --- a/libc/sysv/consts/SG_INFO_OK_MASK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_INFO_OK_MASK,1,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_IO.S b/libc/sysv/consts/SG_IO.S deleted file mode 100644 index e82e17b7b..000000000 --- a/libc/sysv/consts/SG_IO.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_IO,0x2285,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_MAX_QUEUE.S b/libc/sysv/consts/SG_MAX_QUEUE.S deleted file mode 100644 index 937a9c9cd..000000000 --- a/libc/sysv/consts/SG_MAX_QUEUE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_MAX_QUEUE,0x10,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_MAX_SENSE.S b/libc/sysv/consts/SG_MAX_SENSE.S deleted file mode 100644 index 6170af0f0..000000000 --- a/libc/sysv/consts/SG_MAX_SENSE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_MAX_SENSE,0x10,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_NEXT_CMD_LEN.S b/libc/sysv/consts/SG_NEXT_CMD_LEN.S deleted file mode 100644 index 391f9a51d..000000000 --- a/libc/sysv/consts/SG_NEXT_CMD_LEN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_NEXT_CMD_LEN,0x2283,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SCATTER_SZ.S b/libc/sysv/consts/SG_SCATTER_SZ.S deleted file mode 100644 index 9af8d3c99..000000000 --- a/libc/sysv/consts/SG_SCATTER_SZ.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SCATTER_SZ,0x8000,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SCSI_RESET.S b/libc/sysv/consts/SG_SCSI_RESET.S deleted file mode 100644 index a94c6f535..000000000 --- a/libc/sysv/consts/SG_SCSI_RESET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SCSI_RESET,0x2284,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SCSI_RESET_BUS.S b/libc/sysv/consts/SG_SCSI_RESET_BUS.S deleted file mode 100644 index 6d46e48cc..000000000 --- a/libc/sysv/consts/SG_SCSI_RESET_BUS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SCSI_RESET_BUS,2,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SCSI_RESET_DEVICE.S b/libc/sysv/consts/SG_SCSI_RESET_DEVICE.S deleted file mode 100644 index e4326f901..000000000 --- a/libc/sysv/consts/SG_SCSI_RESET_DEVICE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SCSI_RESET_DEVICE,1,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SCSI_RESET_HOST.S b/libc/sysv/consts/SG_SCSI_RESET_HOST.S deleted file mode 100644 index ce7ef225f..000000000 --- a/libc/sysv/consts/SG_SCSI_RESET_HOST.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SCSI_RESET_HOST,3,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SCSI_RESET_NOTHING.S b/libc/sysv/consts/SG_SCSI_RESET_NOTHING.S deleted file mode 100644 index a7502a6ff..000000000 --- a/libc/sysv/consts/SG_SCSI_RESET_NOTHING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SCSI_RESET_NOTHING,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SET_COMMAND_Q.S b/libc/sysv/consts/SG_SET_COMMAND_Q.S deleted file mode 100644 index 73ef9f11e..000000000 --- a/libc/sysv/consts/SG_SET_COMMAND_Q.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SET_COMMAND_Q,0x2271,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SET_DEBUG.S b/libc/sysv/consts/SG_SET_DEBUG.S deleted file mode 100644 index df27afcf2..000000000 --- a/libc/sysv/consts/SG_SET_DEBUG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SET_DEBUG,0x227e,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SET_FORCE_LOW_DMA.S b/libc/sysv/consts/SG_SET_FORCE_LOW_DMA.S deleted file mode 100644 index 79b02461a..000000000 --- a/libc/sysv/consts/SG_SET_FORCE_LOW_DMA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SET_FORCE_LOW_DMA,0x2279,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SET_FORCE_PACK_ID.S b/libc/sysv/consts/SG_SET_FORCE_PACK_ID.S deleted file mode 100644 index 26291db49..000000000 --- a/libc/sysv/consts/SG_SET_FORCE_PACK_ID.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SET_FORCE_PACK_ID,0x227b,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SET_KEEP_ORPHAN.S b/libc/sysv/consts/SG_SET_KEEP_ORPHAN.S deleted file mode 100644 index c1883c8b0..000000000 --- a/libc/sysv/consts/SG_SET_KEEP_ORPHAN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SET_KEEP_ORPHAN,0x2287,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SET_RESERVED_SIZE.S b/libc/sysv/consts/SG_SET_RESERVED_SIZE.S deleted file mode 100644 index d4f1d5c94..000000000 --- a/libc/sysv/consts/SG_SET_RESERVED_SIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SET_RESERVED_SIZE,0x2275,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SET_TIMEOUT.S b/libc/sysv/consts/SG_SET_TIMEOUT.S deleted file mode 100644 index ae290c559..000000000 --- a/libc/sysv/consts/SG_SET_TIMEOUT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SET_TIMEOUT,0x2201,0,0,0,0,0 diff --git a/libc/sysv/consts/SG_SET_TRANSFORM.S b/libc/sysv/consts/SG_SET_TRANSFORM.S deleted file mode 100644 index 9cff15090..000000000 --- a/libc/sysv/consts/SG_SET_TRANSFORM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sg,SG_SET_TRANSFORM,0x2204,0,0,0,0,0 diff --git a/libc/sysv/consts/SIGPWR.S b/libc/sysv/consts/SIGPWR.S index 5d15017a3..60286b13b 100644 --- a/libc/sysv/consts/SIGPWR.S +++ b/libc/sysv/consts/SIGPWR.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon compat,SIGPWR,30,30,30,30,32,30 +.syscon sig,SIGPWR,30,30,30,30,32,30 diff --git a/libc/sysv/consts/SO_DONTLINGER.S b/libc/sysv/consts/SO_DONTLINGER.S new file mode 100644 index 000000000..6d61ff314 --- /dev/null +++ b/libc/sysv/consts/SO_DONTLINGER.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon so,SO_DONTLINGER,0,0,0,0,0,~0x80 diff --git a/libc/sysv/consts/SO_REUSEADDR.S b/libc/sysv/consts/SO_REUSEADDR.S index 7c52c3253..b78e3b8d5 100644 --- a/libc/sysv/consts/SO_REUSEADDR.S +++ b/libc/sysv/consts/SO_REUSEADDR.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_REUSEADDR,2,4,4,4,4,0 +.syscon so,SO_REUSEADDR,2,4,4,4,4,4 diff --git a/libc/sysv/consts/SYS_SECCOMP.S b/libc/sysv/consts/SYS_SECCOMP.S new file mode 100644 index 000000000..c99380963 --- /dev/null +++ b/libc/sysv/consts/SYS_SECCOMP.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon sicode,SYS_SECCOMP,1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SYS_USER_DISPATCH.S b/libc/sysv/consts/SYS_USER_DISPATCH.S new file mode 100644 index 000000000..7daf28756 --- /dev/null +++ b/libc/sysv/consts/SYS_USER_DISPATCH.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon sicode,SYS_USER_DISPATCH,2,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/VOLUME_OVERFLOW.S b/libc/sysv/consts/VOLUME_OVERFLOW.S deleted file mode 100644 index 77bb60f77..000000000 --- a/libc/sysv/consts/VOLUME_OVERFLOW.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,VOLUME_OVERFLOW,13,0,0,0,0,0 diff --git a/libc/sysv/consts/WRDE_APPEND.S b/libc/sysv/consts/WRDE_APPEND.S deleted file mode 100644 index 8a43c85f2..000000000 --- a/libc/sysv/consts/WRDE_APPEND.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_APPEND,0,1,1,0,0,0 diff --git a/libc/sysv/consts/WRDE_BADCHAR.S b/libc/sysv/consts/WRDE_BADCHAR.S deleted file mode 100644 index 1ce240649..000000000 --- a/libc/sysv/consts/WRDE_BADCHAR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_BADCHAR,0,1,1,0,0,0 diff --git a/libc/sysv/consts/WRDE_BADVAL.S b/libc/sysv/consts/WRDE_BADVAL.S deleted file mode 100644 index de0603e6c..000000000 --- a/libc/sysv/consts/WRDE_BADVAL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_BADVAL,0,2,2,0,0,0 diff --git a/libc/sysv/consts/WRDE_CMDSUB.S b/libc/sysv/consts/WRDE_CMDSUB.S deleted file mode 100644 index 2262f7180..000000000 --- a/libc/sysv/consts/WRDE_CMDSUB.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_CMDSUB,0,3,3,0,0,0 diff --git a/libc/sysv/consts/WRDE_DOOFFS.S b/libc/sysv/consts/WRDE_DOOFFS.S deleted file mode 100644 index 78ff57175..000000000 --- a/libc/sysv/consts/WRDE_DOOFFS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_DOOFFS,0,2,2,0,0,0 diff --git a/libc/sysv/consts/WRDE_NOCMD.S b/libc/sysv/consts/WRDE_NOCMD.S deleted file mode 100644 index a99dfb40f..000000000 --- a/libc/sysv/consts/WRDE_NOCMD.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_NOCMD,0,4,4,0,0,0 diff --git a/libc/sysv/consts/WRDE_NOSPACE.S b/libc/sysv/consts/WRDE_NOSPACE.S deleted file mode 100644 index 0d33221c7..000000000 --- a/libc/sysv/consts/WRDE_NOSPACE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_NOSPACE,0,4,4,0,0,0 diff --git a/libc/sysv/consts/WRDE_NOSYS.S b/libc/sysv/consts/WRDE_NOSYS.S deleted file mode 100644 index 3196a5bdf..000000000 --- a/libc/sysv/consts/WRDE_NOSYS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_NOSYS,0,5,5,0,0,0 diff --git a/libc/sysv/consts/WRDE_REUSE.S b/libc/sysv/consts/WRDE_REUSE.S deleted file mode 100644 index 178784fd1..000000000 --- a/libc/sysv/consts/WRDE_REUSE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_REUSE,0,8,8,0,0,0 diff --git a/libc/sysv/consts/WRDE_SHOWERR.S b/libc/sysv/consts/WRDE_SHOWERR.S deleted file mode 100644 index a1884676d..000000000 --- a/libc/sysv/consts/WRDE_SHOWERR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_SHOWERR,0,0x10,0x10,0,0,0 diff --git a/libc/sysv/consts/WRDE_SYNTAX.S b/libc/sysv/consts/WRDE_SYNTAX.S deleted file mode 100644 index dfc6c59b5..000000000 --- a/libc/sysv/consts/WRDE_SYNTAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_SYNTAX,0,6,6,0,0,0 diff --git a/libc/sysv/consts/WRDE_UNDEF.S b/libc/sysv/consts/WRDE_UNDEF.S deleted file mode 100644 index 2834fa9f5..000000000 --- a/libc/sysv/consts/WRDE_UNDEF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,WRDE_UNDEF,0,0x20,0x20,0,0,0 diff --git a/libc/sysv/consts/WRITE_10.S b/libc/sysv/consts/WRITE_10.S deleted file mode 100644 index 951e911df..000000000 --- a/libc/sysv/consts/WRITE_10.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_10,42,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_12.S b/libc/sysv/consts/WRITE_12.S deleted file mode 100644 index ce4375bc2..000000000 --- a/libc/sysv/consts/WRITE_12.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_12,170,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_6.S b/libc/sysv/consts/WRITE_6.S deleted file mode 100644 index 63727b623..000000000 --- a/libc/sysv/consts/WRITE_6.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_6,10,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_BUFFER.S b/libc/sysv/consts/WRITE_BUFFER.S deleted file mode 100644 index 80fc29492..000000000 --- a/libc/sysv/consts/WRITE_BUFFER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_BUFFER,59,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_FILEMARKS.S b/libc/sysv/consts/WRITE_FILEMARKS.S deleted file mode 100644 index 5058a5023..000000000 --- a/libc/sysv/consts/WRITE_FILEMARKS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_FILEMARKS,0x10,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_LONG.S b/libc/sysv/consts/WRITE_LONG.S deleted file mode 100644 index 5dc83904e..000000000 --- a/libc/sysv/consts/WRITE_LONG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_LONG,63,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_LONG_2.S b/libc/sysv/consts/WRITE_LONG_2.S deleted file mode 100644 index 6c6cea5e8..000000000 --- a/libc/sysv/consts/WRITE_LONG_2.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_LONG_2,234,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_SAME.S b/libc/sysv/consts/WRITE_SAME.S deleted file mode 100644 index 175f4989a..000000000 --- a/libc/sysv/consts/WRITE_SAME.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_SAME,65,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_VERIFY.S b/libc/sysv/consts/WRITE_VERIFY.S deleted file mode 100644 index 80fcc36d0..000000000 --- a/libc/sysv/consts/WRITE_VERIFY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_VERIFY,46,0,0,0,0,0 diff --git a/libc/sysv/consts/WRITE_VERIFY_12.S b/libc/sysv/consts/WRITE_VERIFY_12.S deleted file mode 100644 index 47d70f139..000000000 --- a/libc/sysv/consts/WRITE_VERIFY_12.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon scsi,WRITE_VERIFY_12,174,0,0,0,0,0 diff --git a/libc/sysv/consts/_ARG_MAX.S b/libc/sysv/consts/_ARG_MAX.S new file mode 100644 index 000000000..1071d0042 --- /dev/null +++ b/libc/sysv/consts/_ARG_MAX.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon limits,_ARG_MAX,128*1024,1024*1024,512*1024,512*1024,256*1024,32767*2 diff --git a/libc/sysv/consts/_NAME_MAX.S b/libc/sysv/consts/_NAME_MAX.S new file mode 100644 index 000000000..42d20d0bb --- /dev/null +++ b/libc/sysv/consts/_NAME_MAX.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon limits,_NAME_MAX,255,255,255,255,511,255 diff --git a/libc/sysv/consts/_NSIG.S b/libc/sysv/consts/_NSIG.S new file mode 100644 index 000000000..12571eff7 --- /dev/null +++ b/libc/sysv/consts/_NSIG.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon limits,_NSIG,64,32,128,32,64,32 diff --git a/libc/sysv/consts/_PATH_MAX.S b/libc/sysv/consts/_PATH_MAX.S new file mode 100644 index 000000000..af56d92f4 --- /dev/null +++ b/libc/sysv/consts/_PATH_MAX.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon limits,_PATH_MAX,4096,1024,1024,1024,1024,512 diff --git a/libc/sysv/consts/_POSIX2_BC_BASE_MAX.S b/libc/sysv/consts/_POSIX2_BC_BASE_MAX.S deleted file mode 100644 index d9def8b3a..000000000 --- a/libc/sysv/consts/_POSIX2_BC_BASE_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_BC_BASE_MAX,99,99,99,99,99,0 diff --git a/libc/sysv/consts/_POSIX2_BC_DIM_MAX.S b/libc/sysv/consts/_POSIX2_BC_DIM_MAX.S deleted file mode 100644 index c998bf8ee..000000000 --- a/libc/sysv/consts/_POSIX2_BC_DIM_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_BC_DIM_MAX,0x0800,0x0800,0x0800,0x0800,0x0800,0 diff --git a/libc/sysv/consts/_POSIX2_BC_SCALE_MAX.S b/libc/sysv/consts/_POSIX2_BC_SCALE_MAX.S deleted file mode 100644 index b72e2963d..000000000 --- a/libc/sysv/consts/_POSIX2_BC_SCALE_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_BC_SCALE_MAX,99,99,99,99,99,0 diff --git a/libc/sysv/consts/_POSIX2_BC_STRING_MAX.S b/libc/sysv/consts/_POSIX2_BC_STRING_MAX.S deleted file mode 100644 index f4ea24f4e..000000000 --- a/libc/sysv/consts/_POSIX2_BC_STRING_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_BC_STRING_MAX,0x03e8,0x03e8,0x03e8,0x03e8,0x03e8,0 diff --git a/libc/sysv/consts/_POSIX2_CHARCLASS_NAME_MAX.S b/libc/sysv/consts/_POSIX2_CHARCLASS_NAME_MAX.S deleted file mode 100644 index 596985ba5..000000000 --- a/libc/sysv/consts/_POSIX2_CHARCLASS_NAME_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_CHARCLASS_NAME_MAX,14,14,14,14,14,0 diff --git a/libc/sysv/consts/_POSIX2_COLL_WEIGHTS_MAX.S b/libc/sysv/consts/_POSIX2_COLL_WEIGHTS_MAX.S deleted file mode 100644 index b6f3057e5..000000000 --- a/libc/sysv/consts/_POSIX2_COLL_WEIGHTS_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_COLL_WEIGHTS_MAX,2,2,2,2,2,0 diff --git a/libc/sysv/consts/_POSIX2_C_BIND.S b/libc/sysv/consts/_POSIX2_C_BIND.S deleted file mode 100644 index 93adee85b..000000000 --- a/libc/sysv/consts/_POSIX2_C_BIND.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_C_BIND,0x031069,0x030db0,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX2_EXPR_NEST_MAX.S b/libc/sysv/consts/_POSIX2_EXPR_NEST_MAX.S deleted file mode 100644 index 238faf31c..000000000 --- a/libc/sysv/consts/_POSIX2_EXPR_NEST_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_EXPR_NEST_MAX,0x20,0x20,0x20,0x20,0x20,0 diff --git a/libc/sysv/consts/_POSIX2_LINE_MAX.S b/libc/sysv/consts/_POSIX2_LINE_MAX.S deleted file mode 100644 index 53324180d..000000000 --- a/libc/sysv/consts/_POSIX2_LINE_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_LINE_MAX,0x0800,0x0800,0x0800,0x0800,0x0800,0 diff --git a/libc/sysv/consts/_POSIX2_RE_DUP_MAX.S b/libc/sysv/consts/_POSIX2_RE_DUP_MAX.S deleted file mode 100644 index c03fc5b6d..000000000 --- a/libc/sysv/consts/_POSIX2_RE_DUP_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_RE_DUP_MAX,255,255,255,255,255,0 diff --git a/libc/sysv/consts/_POSIX2_VERSION.S b/libc/sysv/consts/_POSIX2_VERSION.S deleted file mode 100644 index ef440fb36..000000000 --- a/libc/sysv/consts/_POSIX2_VERSION.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon misc,_POSIX2_VERSION,0x031069,0x030db0,0x030a2c,0x031069,0x031069,0 diff --git a/libc/sysv/consts/_POSIX_ADVISORY_INFO.S b/libc/sysv/consts/_POSIX_ADVISORY_INFO.S deleted file mode 100644 index c2737a52b..000000000 --- a/libc/sysv/consts/_POSIX_ADVISORY_INFO.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_ADVISORY_INFO,0x031069,-1,0x030db0,-1,-1,0 diff --git a/libc/sysv/consts/_POSIX_AIO_LISTIO_MAX.S b/libc/sysv/consts/_POSIX_AIO_LISTIO_MAX.S deleted file mode 100644 index 38fc0e031..000000000 --- a/libc/sysv/consts/_POSIX_AIO_LISTIO_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_AIO_LISTIO_MAX,2,2,2,0,0,0 diff --git a/libc/sysv/consts/_POSIX_AIO_MAX.S b/libc/sysv/consts/_POSIX_AIO_MAX.S deleted file mode 100644 index e342f6a7c..000000000 --- a/libc/sysv/consts/_POSIX_AIO_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_AIO_MAX,1,1,1,0,0,0 diff --git a/libc/sysv/consts/_POSIX_ARG_MAX.S b/libc/sysv/consts/_POSIX_ARG_MAX.S deleted file mode 100644 index 315cf621c..000000000 --- a/libc/sysv/consts/_POSIX_ARG_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_ARG_MAX,0x1000,0x1000,0x1000,0x1000,0x1000,0 diff --git a/libc/sysv/consts/_POSIX_ASYNCHRONOUS_IO.S b/libc/sysv/consts/_POSIX_ASYNCHRONOUS_IO.S deleted file mode 100644 index 4de9f3bbd..000000000 --- a/libc/sysv/consts/_POSIX_ASYNCHRONOUS_IO.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_ASYNCHRONOUS_IO,0x031069,-1,0x030db0,-1,-1,0 diff --git a/libc/sysv/consts/_POSIX_BARRIERS.S b/libc/sysv/consts/_POSIX_BARRIERS.S deleted file mode 100644 index 8fbeb0fac..000000000 --- a/libc/sysv/consts/_POSIX_BARRIERS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_BARRIERS,0x031069,-1,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_CHILD_MAX.S b/libc/sysv/consts/_POSIX_CHILD_MAX.S deleted file mode 100644 index 3495a2ca0..000000000 --- a/libc/sysv/consts/_POSIX_CHILD_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_CHILD_MAX,25,25,25,25,25,0 diff --git a/libc/sysv/consts/_POSIX_CHOWN_RESTRICTED.S b/libc/sysv/consts/_POSIX_CHOWN_RESTRICTED.S deleted file mode 100644 index 4ff35272a..000000000 --- a/libc/sysv/consts/_POSIX_CHOWN_RESTRICTED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_CHOWN_RESTRICTED,0,0x030db0,1,1,1,0 diff --git a/libc/sysv/consts/_POSIX_CLOCKRES_MIN.S b/libc/sysv/consts/_POSIX_CLOCKRES_MIN.S deleted file mode 100644 index 3bd0857d5..000000000 --- a/libc/sysv/consts/_POSIX_CLOCKRES_MIN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_CLOCKRES_MIN,0x01312d00,0,0x01312d00,0x01312d00,0x01312d00,0 diff --git a/libc/sysv/consts/_POSIX_CLOCK_SELECTION.S b/libc/sysv/consts/_POSIX_CLOCK_SELECTION.S deleted file mode 100644 index c6894a953..000000000 --- a/libc/sysv/consts/_POSIX_CLOCK_SELECTION.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_CLOCK_SELECTION,0x031069,-1,-1,-1,-1,0 diff --git a/libc/sysv/consts/_POSIX_CPUTIME.S b/libc/sysv/consts/_POSIX_CPUTIME.S deleted file mode 100644 index 8be5a812d..000000000 --- a/libc/sysv/consts/_POSIX_CPUTIME.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_CPUTIME,0,-1,0x030db0,0x031069,0x031069,0 diff --git a/libc/sysv/consts/_POSIX_DELAYTIMER_MAX.S b/libc/sysv/consts/_POSIX_DELAYTIMER_MAX.S deleted file mode 100644 index 847687eea..000000000 --- a/libc/sysv/consts/_POSIX_DELAYTIMER_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_DELAYTIMER_MAX,0x20,0x20,0x20,0,0,0 diff --git a/libc/sysv/consts/_POSIX_FSYNC.S b/libc/sysv/consts/_POSIX_FSYNC.S deleted file mode 100644 index 98734a460..000000000 --- a/libc/sysv/consts/_POSIX_FSYNC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_FSYNC,0x031069,0x030db0,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_HOST_NAME_MAX.S b/libc/sysv/consts/_POSIX_HOST_NAME_MAX.S deleted file mode 100644 index cdd32150d..000000000 --- a/libc/sysv/consts/_POSIX_HOST_NAME_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_HOST_NAME_MAX,255,255,255,255,255,0 diff --git a/libc/sysv/consts/_POSIX_IPV6.S b/libc/sysv/consts/_POSIX_IPV6.S deleted file mode 100644 index b77770aab..000000000 --- a/libc/sysv/consts/_POSIX_IPV6.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_IPV6,0x031069,0x030db0,0,0,0,0 diff --git a/libc/sysv/consts/_POSIX_JOB_CONTROL.S b/libc/sysv/consts/_POSIX_JOB_CONTROL.S deleted file mode 100644 index 6075f5486..000000000 --- a/libc/sysv/consts/_POSIX_JOB_CONTROL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_JOB_CONTROL,1,0x030db0,1,1,1,0 diff --git a/libc/sysv/consts/_POSIX_LINK_MAX.S b/libc/sysv/consts/_POSIX_LINK_MAX.S deleted file mode 100644 index b4e062ba0..000000000 --- a/libc/sysv/consts/_POSIX_LINK_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_LINK_MAX,8,8,8,8,8,0 diff --git a/libc/sysv/consts/_POSIX_LOGIN_NAME_MAX.S b/libc/sysv/consts/_POSIX_LOGIN_NAME_MAX.S deleted file mode 100644 index deb4123ba..000000000 --- a/libc/sysv/consts/_POSIX_LOGIN_NAME_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_LOGIN_NAME_MAX,9,9,9,9,9,0 diff --git a/libc/sysv/consts/_POSIX_MAPPED_FILES.S b/libc/sysv/consts/_POSIX_MAPPED_FILES.S deleted file mode 100644 index 20e7b821c..000000000 --- a/libc/sysv/consts/_POSIX_MAPPED_FILES.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MAPPED_FILES,0x031069,0x030db0,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_MAX_CANON.S b/libc/sysv/consts/_POSIX_MAX_CANON.S deleted file mode 100644 index 1abaa3203..000000000 --- a/libc/sysv/consts/_POSIX_MAX_CANON.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MAX_CANON,255,255,255,255,255,0 diff --git a/libc/sysv/consts/_POSIX_MAX_INPUT.S b/libc/sysv/consts/_POSIX_MAX_INPUT.S deleted file mode 100644 index cecc9f5a7..000000000 --- a/libc/sysv/consts/_POSIX_MAX_INPUT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MAX_INPUT,255,255,255,255,255,0 diff --git a/libc/sysv/consts/_POSIX_MEMLOCK.S b/libc/sysv/consts/_POSIX_MEMLOCK.S deleted file mode 100644 index 351263a05..000000000 --- a/libc/sysv/consts/_POSIX_MEMLOCK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MEMLOCK,0x031069,-1,-1,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_MEMLOCK_RANGE.S b/libc/sysv/consts/_POSIX_MEMLOCK_RANGE.S deleted file mode 100644 index 5dbf7e4e6..000000000 --- a/libc/sysv/consts/_POSIX_MEMLOCK_RANGE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MEMLOCK_RANGE,0x031069,-1,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_MEMORY_PROTECTION.S b/libc/sysv/consts/_POSIX_MEMORY_PROTECTION.S deleted file mode 100644 index 12a14fdbd..000000000 --- a/libc/sysv/consts/_POSIX_MEMORY_PROTECTION.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MEMORY_PROTECTION,0x031069,0x030db0,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_MESSAGE_PASSING.S b/libc/sysv/consts/_POSIX_MESSAGE_PASSING.S deleted file mode 100644 index d5d784672..000000000 --- a/libc/sysv/consts/_POSIX_MESSAGE_PASSING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MESSAGE_PASSING,0x031069,-1,0x030db0,-1,-1,0 diff --git a/libc/sysv/consts/_POSIX_MONOTONIC_CLOCK.S b/libc/sysv/consts/_POSIX_MONOTONIC_CLOCK.S deleted file mode 100644 index 06db4eb35..000000000 --- a/libc/sysv/consts/_POSIX_MONOTONIC_CLOCK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MONOTONIC_CLOCK,0,-1,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_MQ_OPEN_MAX.S b/libc/sysv/consts/_POSIX_MQ_OPEN_MAX.S deleted file mode 100644 index 0ea3ac38e..000000000 --- a/libc/sysv/consts/_POSIX_MQ_OPEN_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MQ_OPEN_MAX,8,8,8,0,0,0 diff --git a/libc/sysv/consts/_POSIX_MQ_PRIO_MAX.S b/libc/sysv/consts/_POSIX_MQ_PRIO_MAX.S deleted file mode 100644 index 36272de45..000000000 --- a/libc/sysv/consts/_POSIX_MQ_PRIO_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_MQ_PRIO_MAX,0x20,0x20,0x20,0,0,0 diff --git a/libc/sysv/consts/_POSIX_NAME_MAX.S b/libc/sysv/consts/_POSIX_NAME_MAX.S deleted file mode 100644 index a7a828bb7..000000000 --- a/libc/sysv/consts/_POSIX_NAME_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_NAME_MAX,14,14,14,14,14,14 diff --git a/libc/sysv/consts/_POSIX_NGROUPS_MAX.S b/libc/sysv/consts/_POSIX_NGROUPS_MAX.S deleted file mode 100644 index 7ba077af6..000000000 --- a/libc/sysv/consts/_POSIX_NGROUPS_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_NGROUPS_MAX,8,8,8,8,8,0 diff --git a/libc/sysv/consts/_POSIX_NO_TRUNC.S b/libc/sysv/consts/_POSIX_NO_TRUNC.S deleted file mode 100644 index 9971eb2d7..000000000 --- a/libc/sysv/consts/_POSIX_NO_TRUNC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_NO_TRUNC,1,0x030db0,1,1,1,0 diff --git a/libc/sysv/consts/_POSIX_OPEN_MAX.S b/libc/sysv/consts/_POSIX_OPEN_MAX.S deleted file mode 100644 index 6c9468640..000000000 --- a/libc/sysv/consts/_POSIX_OPEN_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_OPEN_MAX,20,20,20,20,20,20 diff --git a/libc/sysv/consts/_POSIX_PATH_MAX.S b/libc/sysv/consts/_POSIX_PATH_MAX.S deleted file mode 100644 index 909d3c2c7..000000000 --- a/libc/sysv/consts/_POSIX_PATH_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_PATH_MAX,255,255,255,255,255,255 diff --git a/libc/sysv/consts/_POSIX_PIPE_BUF.S b/libc/sysv/consts/_POSIX_PIPE_BUF.S deleted file mode 100644 index c831974fe..000000000 --- a/libc/sysv/consts/_POSIX_PIPE_BUF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_PIPE_BUF,0x0200,0x0200,0x0200,0x0200,0x0200,0 diff --git a/libc/sysv/consts/_POSIX_RAW_SOCKETS.S b/libc/sysv/consts/_POSIX_RAW_SOCKETS.S deleted file mode 100644 index 9f4fc94b1..000000000 --- a/libc/sysv/consts/_POSIX_RAW_SOCKETS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_RAW_SOCKETS,0x031069,-1,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_READER_WRITER_LOCKS.S b/libc/sysv/consts/_POSIX_READER_WRITER_LOCKS.S deleted file mode 100644 index a1a4cc1c7..000000000 --- a/libc/sysv/consts/_POSIX_READER_WRITER_LOCKS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_READER_WRITER_LOCKS,0x031069,0x030db0,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_REALTIME_SIGNALS.S b/libc/sysv/consts/_POSIX_REALTIME_SIGNALS.S deleted file mode 100644 index be894edb5..000000000 --- a/libc/sysv/consts/_POSIX_REALTIME_SIGNALS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_REALTIME_SIGNALS,0x031069,-1,0x030db0,-1,-1,0 diff --git a/libc/sysv/consts/_POSIX_REGEXP.S b/libc/sysv/consts/_POSIX_REGEXP.S deleted file mode 100644 index ce4e54768..000000000 --- a/libc/sysv/consts/_POSIX_REGEXP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_REGEXP,1,0x030db0,1,1,1,0 diff --git a/libc/sysv/consts/_POSIX_RE_DUP_MAX.S b/libc/sysv/consts/_POSIX_RE_DUP_MAX.S deleted file mode 100644 index bfb673a04..000000000 --- a/libc/sysv/consts/_POSIX_RE_DUP_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_RE_DUP_MAX,255,255,255,255,255,0 diff --git a/libc/sysv/consts/_POSIX_RTSIG_MAX.S b/libc/sysv/consts/_POSIX_RTSIG_MAX.S deleted file mode 100644 index 2241f715a..000000000 --- a/libc/sysv/consts/_POSIX_RTSIG_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_RTSIG_MAX,8,8,8,0,0,0 diff --git a/libc/sysv/consts/_POSIX_SAVED_IDS.S b/libc/sysv/consts/_POSIX_SAVED_IDS.S deleted file mode 100644 index 82fffc4ea..000000000 --- a/libc/sysv/consts/_POSIX_SAVED_IDS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SAVED_IDS,1,0x030db0,0,1,1,0 diff --git a/libc/sysv/consts/_POSIX_SEMAPHORES.S b/libc/sysv/consts/_POSIX_SEMAPHORES.S deleted file mode 100644 index de3e8eaad..000000000 --- a/libc/sysv/consts/_POSIX_SEMAPHORES.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SEMAPHORES,0x031069,-1,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_SEM_NSEMS_MAX.S b/libc/sysv/consts/_POSIX_SEM_NSEMS_MAX.S deleted file mode 100644 index e9effe5ee..000000000 --- a/libc/sysv/consts/_POSIX_SEM_NSEMS_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SEM_NSEMS_MAX,0x0100,0x0100,0x0100,0x0100,0x0100,0 diff --git a/libc/sysv/consts/_POSIX_SEM_VALUE_MAX.S b/libc/sysv/consts/_POSIX_SEM_VALUE_MAX.S deleted file mode 100644 index 763e10aff..000000000 --- a/libc/sysv/consts/_POSIX_SEM_VALUE_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SEM_VALUE_MAX,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0 diff --git a/libc/sysv/consts/_POSIX_SHARED_MEMORY_OBJECTS.S b/libc/sysv/consts/_POSIX_SHARED_MEMORY_OBJECTS.S deleted file mode 100644 index a775360c0..000000000 --- a/libc/sysv/consts/_POSIX_SHARED_MEMORY_OBJECTS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SHARED_MEMORY_OBJECTS,0x031069,-1,0x030db0,0x031069,0x031069,0 diff --git a/libc/sysv/consts/_POSIX_SHELL.S b/libc/sysv/consts/_POSIX_SHELL.S deleted file mode 100644 index ea364b705..000000000 --- a/libc/sysv/consts/_POSIX_SHELL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SHELL,1,0x030db0,1,1,1,0 diff --git a/libc/sysv/consts/_POSIX_SIGQUEUE_MAX.S b/libc/sysv/consts/_POSIX_SIGQUEUE_MAX.S deleted file mode 100644 index b6e88a5ee..000000000 --- a/libc/sysv/consts/_POSIX_SIGQUEUE_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SIGQUEUE_MAX,0x20,0x20,0x20,0,0,0 diff --git a/libc/sysv/consts/_POSIX_SPAWN.S b/libc/sysv/consts/_POSIX_SPAWN.S deleted file mode 100644 index 5cc922cef..000000000 --- a/libc/sysv/consts/_POSIX_SPAWN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SPAWN,0x031069,-1,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_SPIN_LOCKS.S b/libc/sysv/consts/_POSIX_SPIN_LOCKS.S deleted file mode 100644 index 3da50e838..000000000 --- a/libc/sysv/consts/_POSIX_SPIN_LOCKS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SPIN_LOCKS,0x031069,-1,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_SSIZE_MAX.S b/libc/sysv/consts/_POSIX_SSIZE_MAX.S deleted file mode 100644 index e06159aff..000000000 --- a/libc/sysv/consts/_POSIX_SSIZE_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SSIZE_MAX,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0 diff --git a/libc/sysv/consts/_POSIX_SS_REPL_MAX.S b/libc/sysv/consts/_POSIX_SS_REPL_MAX.S deleted file mode 100644 index 3776e47a7..000000000 --- a/libc/sysv/consts/_POSIX_SS_REPL_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SS_REPL_MAX,0,4,4,0,0,0 diff --git a/libc/sysv/consts/_POSIX_STREAM_MAX.S b/libc/sysv/consts/_POSIX_STREAM_MAX.S deleted file mode 100644 index 4067e637b..000000000 --- a/libc/sysv/consts/_POSIX_STREAM_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_STREAM_MAX,8,8,8,8,8,0 diff --git a/libc/sysv/consts/_POSIX_SYMLINK_MAX.S b/libc/sysv/consts/_POSIX_SYMLINK_MAX.S deleted file mode 100644 index ca36778c4..000000000 --- a/libc/sysv/consts/_POSIX_SYMLINK_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SYMLINK_MAX,255,255,255,255,255,0 diff --git a/libc/sysv/consts/_POSIX_SYMLOOP_MAX.S b/libc/sysv/consts/_POSIX_SYMLOOP_MAX.S deleted file mode 100644 index 981d87de7..000000000 --- a/libc/sysv/consts/_POSIX_SYMLOOP_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_SYMLOOP_MAX,8,8,8,8,8,0 diff --git a/libc/sysv/consts/_POSIX_THREADS.S b/libc/sysv/consts/_POSIX_THREADS.S deleted file mode 100644 index 8198becab..000000000 --- a/libc/sysv/consts/_POSIX_THREADS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREADS,0x031069,0x030db0,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKADDR.S b/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKADDR.S deleted file mode 100644 index fc4fc4400..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKADDR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_ATTR_STACKADDR,0x031069,0x030db0,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKSIZE.S b/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKSIZE.S deleted file mode 100644 index 7fec49e45..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKSIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_ATTR_STACKSIZE,0x031069,0x030db0,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_CPUTIME.S b/libc/sysv/consts/_POSIX_THREAD_CPUTIME.S deleted file mode 100644 index 1ceab7a7e..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_CPUTIME.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_CPUTIME,0,-1,0x030db0,0x031069,0x031069,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_DESTRUCTOR_ITERATIONS.S b/libc/sysv/consts/_POSIX_THREAD_DESTRUCTOR_ITERATIONS.S deleted file mode 100644 index cfb21f89a..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_DESTRUCTOR_ITERATIONS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_DESTRUCTOR_ITERATIONS,4,4,4,4,4,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_KEYS_MAX.S b/libc/sysv/consts/_POSIX_THREAD_KEYS_MAX.S deleted file mode 100644 index f63502d07..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_KEYS_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_KEYS_MAX,0x80,0x80,0x80,0x80,0x80,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_PRIORITY_SCHEDULING.S b/libc/sysv/consts/_POSIX_THREAD_PRIORITY_SCHEDULING.S deleted file mode 100644 index ce2a15df8..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_PRIORITY_SCHEDULING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_PRIORITY_SCHEDULING,0x031069,-1,0x030db0,-1,-1,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_PROCESS_SHARED.S b/libc/sysv/consts/_POSIX_THREAD_PROCESS_SHARED.S deleted file mode 100644 index f79252755..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_PROCESS_SHARED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_PROCESS_SHARED,0x031069,0x030db0,0x030db0,-1,-1,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_SAFE_FUNCTIONS.S b/libc/sysv/consts/_POSIX_THREAD_SAFE_FUNCTIONS.S deleted file mode 100644 index e1d5d06fe..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_SAFE_FUNCTIONS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_SAFE_FUNCTIONS,0x031069,0x030db0,-1,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_THREAD_THREADS_MAX.S b/libc/sysv/consts/_POSIX_THREAD_THREADS_MAX.S deleted file mode 100644 index 2fcdce6ed..000000000 --- a/libc/sysv/consts/_POSIX_THREAD_THREADS_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_THREAD_THREADS_MAX,0x40,0x40,0x40,4,4,0 diff --git a/libc/sysv/consts/_POSIX_TIMEOUTS.S b/libc/sysv/consts/_POSIX_TIMEOUTS.S deleted file mode 100644 index dddedfedd..000000000 --- a/libc/sysv/consts/_POSIX_TIMEOUTS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TIMEOUTS,0x031069,-1,0x030db0,0x030db0,0x030db0,0 diff --git a/libc/sysv/consts/_POSIX_TIMERS.S b/libc/sysv/consts/_POSIX_TIMERS.S deleted file mode 100644 index 7f4c8ebed..000000000 --- a/libc/sysv/consts/_POSIX_TIMERS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TIMERS,0x031069,-1,0x030db0,-1,-1,0 diff --git a/libc/sysv/consts/_POSIX_TIMER_MAX.S b/libc/sysv/consts/_POSIX_TIMER_MAX.S deleted file mode 100644 index d7d3b7111..000000000 --- a/libc/sysv/consts/_POSIX_TIMER_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TIMER_MAX,0x20,0x20,0x20,0,0,0 diff --git a/libc/sysv/consts/_POSIX_TRACE_EVENT_NAME_MAX.S b/libc/sysv/consts/_POSIX_TRACE_EVENT_NAME_MAX.S deleted file mode 100644 index 56c6f2efb..000000000 --- a/libc/sysv/consts/_POSIX_TRACE_EVENT_NAME_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TRACE_EVENT_NAME_MAX,0,30,30,0,0,0 diff --git a/libc/sysv/consts/_POSIX_TRACE_NAME_MAX.S b/libc/sysv/consts/_POSIX_TRACE_NAME_MAX.S deleted file mode 100644 index c576681b8..000000000 --- a/libc/sysv/consts/_POSIX_TRACE_NAME_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TRACE_NAME_MAX,0,8,8,0,0,0 diff --git a/libc/sysv/consts/_POSIX_TRACE_SYS_MAX.S b/libc/sysv/consts/_POSIX_TRACE_SYS_MAX.S deleted file mode 100644 index 6a3a96249..000000000 --- a/libc/sysv/consts/_POSIX_TRACE_SYS_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TRACE_SYS_MAX,0,8,8,0,0,0 diff --git a/libc/sysv/consts/_POSIX_TRACE_USER_EVENT_MAX.S b/libc/sysv/consts/_POSIX_TRACE_USER_EVENT_MAX.S deleted file mode 100644 index 3beba770f..000000000 --- a/libc/sysv/consts/_POSIX_TRACE_USER_EVENT_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TRACE_USER_EVENT_MAX,0,0x20,0x20,0,0,0 diff --git a/libc/sysv/consts/_POSIX_TTY_NAME_MAX.S b/libc/sysv/consts/_POSIX_TTY_NAME_MAX.S deleted file mode 100644 index 900f1b86e..000000000 --- a/libc/sysv/consts/_POSIX_TTY_NAME_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TTY_NAME_MAX,9,9,9,9,9,0 diff --git a/libc/sysv/consts/_POSIX_TZNAME_MAX.S b/libc/sysv/consts/_POSIX_TZNAME_MAX.S deleted file mode 100644 index 0ce6a6993..000000000 --- a/libc/sysv/consts/_POSIX_TZNAME_MAX.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_TZNAME_MAX,6,6,6,6,6,0 diff --git a/libc/sysv/consts/_POSIX_V6_LP64_OFF64.S b/libc/sysv/consts/_POSIX_V6_LP64_OFF64.S deleted file mode 100644 index 3a3c260f4..000000000 --- a/libc/sysv/consts/_POSIX_V6_LP64_OFF64.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_V6_LP64_OFF64,1,1,0,0,0,0 diff --git a/libc/sysv/consts/_POSIX_V7_LP64_OFF64.S b/libc/sysv/consts/_POSIX_V7_LP64_OFF64.S deleted file mode 100644 index 351dd64b4..000000000 --- a/libc/sysv/consts/_POSIX_V7_LP64_OFF64.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_V7_LP64_OFF64,1,1,0,0,0,0 diff --git a/libc/sysv/consts/_POSIX_VDISABLE.S b/libc/sysv/consts/_POSIX_VDISABLE.S deleted file mode 100644 index b12b30623..000000000 --- a/libc/sysv/consts/_POSIX_VDISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_VDISABLE,0,255,255,255,255,0 diff --git a/libc/sysv/consts/_POSIX_VERSION.S b/libc/sysv/consts/_POSIX_VERSION.S deleted file mode 100644 index 34fb98fd9..000000000 --- a/libc/sysv/consts/_POSIX_VERSION.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon posix,_POSIX_VERSION,0x031069,0x030db0,0x030db0,0x031069,0x031069,0 diff --git a/libc/sysv/consts/__NR_exit.S b/libc/sysv/consts/__NR_exit.S index aab333d47..de72e4a7c 100644 --- a/libc/sysv/consts/__NR_exit.S +++ b/libc/sysv/consts/__NR_exit.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon nr,__NR_exit,0x003c,0x2000001,0x0001,0x0001,0x001,0xfff +.syscon nr,__NR_exit,0x003c,0x2000169,0x01af,0x012e,0x136,0xfff diff --git a/libc/sysv/consts/__NR_sigprocmask.S b/libc/sysv/consts/__NR_sigprocmask.S index 5d2629fba..3884005ef 100644 --- a/libc/sysv/consts/__NR_sigprocmask.S +++ b/libc/sysv/consts/__NR_sigprocmask.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon nr,__NR_sigprocmask,0x000e,0x2000030,0x0154,0x0030,0x125,0xfff +.syscon nr,__NR_sigprocmask,0x000e,0x2000149,0x0154,0x0030,0x125,0xfff diff --git a/libc/sysv/consts/__NR_thr_new.S b/libc/sysv/consts/__NR_thr_new.S deleted file mode 100644 index f985797f5..000000000 --- a/libc/sysv/consts/__NR_thr_new.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon nr,__NR_thr_new,0xfff,0xfff,0x01c7,0xfff,0xfff,0xfff diff --git a/libc/sysv/consts/_posix.h b/libc/sysv/consts/_posix.h index b96c0f051..66f9062b7 100644 --- a/libc/sysv/consts/_posix.h +++ b/libc/sysv/consts/_posix.h @@ -1,168 +1,59 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX_H_ -#include "libc/runtime/symbolic.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -extern const long _POSIX_ADVISORY_INFO; -extern const long _POSIX_AIO_LISTIO_MAX; -extern const long _POSIX_AIO_MAX; -extern const long _POSIX_ARG_MAX; -extern const long _POSIX_ASYNCHRONOUS_IO; -extern const long _POSIX_BARRIERS; -extern const long _POSIX_CHILD_MAX; -extern const long _POSIX_CHOWN_RESTRICTED; -extern const long _POSIX_CLOCKRES_MIN; -extern const long _POSIX_CLOCK_SELECTION; -extern const long _POSIX_CPUTIME; -extern const long _POSIX_DELAYTIMER_MAX; -extern const long _POSIX_FSYNC; -extern const long _POSIX_HOST_NAME_MAX; -extern const long _POSIX_IPV6; -extern const long _POSIX_JOB_CONTROL; -extern const long _POSIX_LINK_MAX; -extern const long _POSIX_LOGIN_NAME_MAX; -extern const long _POSIX_MAPPED_FILES; -extern const long _POSIX_MAX_CANON; -extern const long _POSIX_MAX_INPUT; -extern const long _POSIX_MEMLOCK; -extern const long _POSIX_MEMLOCK_RANGE; -extern const long _POSIX_MEMORY_PROTECTION; -extern const long _POSIX_MESSAGE_PASSING; -extern const long _POSIX_MONOTONIC_CLOCK; -extern const long _POSIX_MQ_OPEN_MAX; -extern const long _POSIX_MQ_PRIO_MAX; -extern const long _POSIX_NAME_MAX; -extern const long _POSIX_NGROUPS_MAX; -extern const long _POSIX_NO_TRUNC; -extern const long _POSIX_OPEN_MAX; -extern const long _POSIX_PATH_MAX; -extern const long _POSIX_PIPE_BUF; -extern const long _POSIX_RAW_SOCKETS; -extern const long _POSIX_READER_WRITER_LOCKS; -extern const long _POSIX_REALTIME_SIGNALS; -extern const long _POSIX_REGEXP; -extern const long _POSIX_RE_DUP_MAX; -extern const long _POSIX_RTSIG_MAX; -extern const long _POSIX_SAVED_IDS; -extern const long _POSIX_SEMAPHORES; -extern const long _POSIX_SEM_NSEMS_MAX; -extern const long _POSIX_SEM_VALUE_MAX; -extern const long _POSIX_SHARED_MEMORY_OBJECTS; -extern const long _POSIX_SHELL; -extern const long _POSIX_SIGQUEUE_MAX; -extern const long _POSIX_SPAWN; -extern const long _POSIX_SPIN_LOCKS; -extern const long _POSIX_SSIZE_MAX; -extern const long _POSIX_SS_REPL_MAX; -extern const long _POSIX_STREAM_MAX; -extern const long _POSIX_SYMLINK_MAX; -extern const long _POSIX_SYMLOOP_MAX; -extern const long _POSIX_THREADS; -extern const long _POSIX_THREAD_ATTR_STACKADDR; -extern const long _POSIX_THREAD_ATTR_STACKSIZE; -extern const long _POSIX_THREAD_CPUTIME; -extern const long _POSIX_THREAD_DESTRUCTOR_ITERATIONS; -extern const long _POSIX_THREAD_KEYS_MAX; -extern const long _POSIX_THREAD_PRIORITY_SCHEDULING; -extern const long _POSIX_THREAD_PROCESS_SHARED; -extern const long _POSIX_THREAD_SAFE_FUNCTIONS; -extern const long _POSIX_THREAD_THREADS_MAX; -extern const long _POSIX_TIMEOUTS; -extern const long _POSIX_TIMERS; -extern const long _POSIX_TIMER_MAX; -extern const long _POSIX_TRACE_EVENT_NAME_MAX; -extern const long _POSIX_TRACE_NAME_MAX; -extern const long _POSIX_TRACE_SYS_MAX; -extern const long _POSIX_TRACE_USER_EVENT_MAX; -extern const long _POSIX_TTY_NAME_MAX; -extern const long _POSIX_TZNAME_MAX; -extern const long _POSIX_V6_LP64_OFF64; -extern const long _POSIX_V7_LP64_OFF64; -extern const long _POSIX_VDISABLE; -extern const long _POSIX_VERSION; +/* The Open Group Base Specifications Issue 7, 2018 edition */ +/* IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008) */ -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#define _POSIX_AIO_LISTIO_MAX 2 +#define _POSIX_AIO_MAX 1 +#define _POSIX_ARG_MAX 4096 +#define _POSIX_CHILD_MAX 25 +#define _POSIX_DELAYTIMER_MAX 32 +#define _POSIX_HOST_NAME_MAX 255 +#define _POSIX_LINK_MAX 8 +#define _POSIX_LOGIN_NAME_MAX 9 +#define _POSIX_MAX_CANON 255 +#define _POSIX_MAX_INPUT 255 +#define _POSIX_MQ_OPEN_MAX 8 +#define _POSIX_MQ_PRIO_MAX 32 +#define _POSIX_NAME_MAX 14 +#define _POSIX_NGROUPS_MAX 8 +#define _POSIX_OPEN_MAX 20 +#define _POSIX_PATH_MAX 256 +#define _POSIX_PIPE_BUF 512 +#define _POSIX_RE_DUP_MAX 255 +#define _POSIX_RTSIG_MAX 8 +#define _POSIX_SEM_NSEMS_MAX 256 +#define _POSIX_SEM_VALUE_MAX 32767 +#define _POSIX_SIGQUEUE_MAX 32 +#define _POSIX_SSIZE_MAX 32767 +#define _POSIX_SS_REPL_MAX 4 +#define _POSIX_STREAM_MAX 8 +#define _POSIX_SYMLINK_MAX 255 +#define _POSIX_SYMLOOP_MAX 8 +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 +#define _POSIX_THREAD_KEYS_MAX 128 +#define _POSIX_THREAD_THREADS_MAX 64 +#define _POSIX_TIMER_MAX 32 +#define _POSIX_TRACE_EVENT_NAME_MAX 30 +#define _POSIX_TRACE_NAME_MAX 8 +#define _POSIX_TRACE_SYS_MAX 8 +#define _POSIX_TRACE_USER_EVENT_MAX 32 +#define _POSIX_TTY_NAME_MAX 9 +#define _POSIX_TZNAME_MAX 6 -#define _POSIX_ADVISORY_INFO SYMBOLIC(_POSIX_ADVISORY_INFO) -#define _POSIX_AIO_LISTIO_MAX SYMBOLIC(_POSIX_AIO_LISTIO_MAX) -#define _POSIX_AIO_MAX SYMBOLIC(_POSIX_AIO_MAX) -#define _POSIX_ARG_MAX SYMBOLIC(_POSIX_ARG_MAX) -#define _POSIX_ASYNCHRONOUS_IO SYMBOLIC(_POSIX_ASYNCHRONOUS_IO) -#define _POSIX_BARRIERS SYMBOLIC(_POSIX_BARRIERS) -#define _POSIX_CHILD_MAX SYMBOLIC(_POSIX_CHILD_MAX) -#define _POSIX_CHOWN_RESTRICTED SYMBOLIC(_POSIX_CHOWN_RESTRICTED) -#define _POSIX_CLOCKRES_MIN SYMBOLIC(_POSIX_CLOCKRES_MIN) -#define _POSIX_CLOCK_SELECTION SYMBOLIC(_POSIX_CLOCK_SELECTION) -#define _POSIX_CPUTIME SYMBOLIC(_POSIX_CPUTIME) -#define _POSIX_DELAYTIMER_MAX SYMBOLIC(_POSIX_DELAYTIMER_MAX) -#define _POSIX_FSYNC SYMBOLIC(_POSIX_FSYNC) -#define _POSIX_HOST_NAME_MAX SYMBOLIC(_POSIX_HOST_NAME_MAX) -#define _POSIX_IPV6 SYMBOLIC(_POSIX_IPV6) -#define _POSIX_JOB_CONTROL SYMBOLIC(_POSIX_JOB_CONTROL) -#define _POSIX_LINK_MAX SYMBOLIC(_POSIX_LINK_MAX) -#define _POSIX_LOGIN_NAME_MAX SYMBOLIC(_POSIX_LOGIN_NAME_MAX) -#define _POSIX_MAPPED_FILES SYMBOLIC(_POSIX_MAPPED_FILES) -#define _POSIX_MAX_CANON SYMBOLIC(_POSIX_MAX_CANON) -#define _POSIX_MAX_INPUT SYMBOLIC(_POSIX_MAX_INPUT) -#define _POSIX_MEMLOCK SYMBOLIC(_POSIX_MEMLOCK) -#define _POSIX_MEMLOCK_RANGE SYMBOLIC(_POSIX_MEMLOCK_RANGE) -#define _POSIX_MEMORY_PROTECTION SYMBOLIC(_POSIX_MEMORY_PROTECTION) -#define _POSIX_MESSAGE_PASSING SYMBOLIC(_POSIX_MESSAGE_PASSING) -#define _POSIX_MONOTONIC_CLOCK SYMBOLIC(_POSIX_MONOTONIC_CLOCK) -#define _POSIX_MQ_OPEN_MAX SYMBOLIC(_POSIX_MQ_OPEN_MAX) -#define _POSIX_MQ_PRIO_MAX SYMBOLIC(_POSIX_MQ_PRIO_MAX) -#define _POSIX_NAME_MAX SYMBOLIC(_POSIX_NAME_MAX) -#define _POSIX_NGROUPS_MAX SYMBOLIC(_POSIX_NGROUPS_MAX) -#define _POSIX_NO_TRUNC SYMBOLIC(_POSIX_NO_TRUNC) -#define _POSIX_OPEN_MAX SYMBOLIC(_POSIX_OPEN_MAX) -#define _POSIX_PATH_MAX SYMBOLIC(_POSIX_PATH_MAX) -#define _POSIX_PIPE_BUF SYMBOLIC(_POSIX_PIPE_BUF) -#define _POSIX_RAW_SOCKETS SYMBOLIC(_POSIX_RAW_SOCKETS) -#define _POSIX_READER_WRITER_LOCKS SYMBOLIC(_POSIX_READER_WRITER_LOCKS) -#define _POSIX_REALTIME_SIGNALS SYMBOLIC(_POSIX_REALTIME_SIGNALS) -#define _POSIX_REGEXP SYMBOLIC(_POSIX_REGEXP) -#define _POSIX_RE_DUP_MAX SYMBOLIC(_POSIX_RE_DUP_MAX) -#define _POSIX_RTSIG_MAX SYMBOLIC(_POSIX_RTSIG_MAX) -#define _POSIX_SAVED_IDS SYMBOLIC(_POSIX_SAVED_IDS) -#define _POSIX_SEMAPHORES SYMBOLIC(_POSIX_SEMAPHORES) -#define _POSIX_SEM_NSEMS_MAX SYMBOLIC(_POSIX_SEM_NSEMS_MAX) -#define _POSIX_SEM_VALUE_MAX SYMBOLIC(_POSIX_SEM_VALUE_MAX) -#define _POSIX_SHARED_MEMORY_OBJECTS SYMBOLIC(_POSIX_SHARED_MEMORY_OBJECTS) -#define _POSIX_SHELL SYMBOLIC(_POSIX_SHELL) -#define _POSIX_SIGQUEUE_MAX SYMBOLIC(_POSIX_SIGQUEUE_MAX) -#define _POSIX_SPAWN SYMBOLIC(_POSIX_SPAWN) -#define _POSIX_SPIN_LOCKS SYMBOLIC(_POSIX_SPIN_LOCKS) -#define _POSIX_SSIZE_MAX SYMBOLIC(_POSIX_SSIZE_MAX) -#define _POSIX_SS_REPL_MAX SYMBOLIC(_POSIX_SS_REPL_MAX) -#define _POSIX_STREAM_MAX SYMBOLIC(_POSIX_STREAM_MAX) -#define _POSIX_SYMLINK_MAX SYMBOLIC(_POSIX_SYMLINK_MAX) -#define _POSIX_SYMLOOP_MAX SYMBOLIC(_POSIX_SYMLOOP_MAX) -#define _POSIX_THREADS SYMBOLIC(_POSIX_THREADS) -#define _POSIX_THREAD_ATTR_STACKADDR SYMBOLIC(_POSIX_THREAD_ATTR_STACKADDR) -#define _POSIX_THREAD_ATTR_STACKSIZE SYMBOLIC(_POSIX_THREAD_ATTR_STACKSIZE) -#define _POSIX_THREAD_CPUTIME SYMBOLIC(_POSIX_THREAD_CPUTIME) -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS \ - SYMBOLIC(_POSIX_THREAD_DESTRUCTOR_ITERATIONS) -#define _POSIX_THREAD_KEYS_MAX SYMBOLIC(_POSIX_THREAD_KEYS_MAX) -#define _POSIX_THREAD_PRIORITY_SCHEDULING \ - SYMBOLIC(_POSIX_THREAD_PRIORITY_SCHEDULING) -#define _POSIX_THREAD_PROCESS_SHARED SYMBOLIC(_POSIX_THREAD_PROCESS_SHARED) -#define _POSIX_THREAD_SAFE_FUNCTIONS SYMBOLIC(_POSIX_THREAD_SAFE_FUNCTIONS) -#define _POSIX_THREAD_THREADS_MAX SYMBOLIC(_POSIX_THREAD_THREADS_MAX) -#define _POSIX_TIMEOUTS SYMBOLIC(_POSIX_TIMEOUTS) -#define _POSIX_TIMERS SYMBOLIC(_POSIX_TIMERS) -#define _POSIX_TIMER_MAX SYMBOLIC(_POSIX_TIMER_MAX) -#define _POSIX_TRACE_EVENT_NAME_MAX SYMBOLIC(_POSIX_TRACE_EVENT_NAME_MAX) -#define _POSIX_TRACE_NAME_MAX SYMBOLIC(_POSIX_TRACE_NAME_MAX) -#define _POSIX_TRACE_SYS_MAX SYMBOLIC(_POSIX_TRACE_SYS_MAX) -#define _POSIX_TRACE_USER_EVENT_MAX SYMBOLIC(_POSIX_TRACE_USER_EVENT_MAX) -#define _POSIX_TTY_NAME_MAX SYMBOLIC(_POSIX_TTY_NAME_MAX) -#define _POSIX_TZNAME_MAX SYMBOLIC(_POSIX_TZNAME_MAX) -#define _POSIX_V6_LP64_OFF64 SYMBOLIC(_POSIX_V6_LP64_OFF64) -#define _POSIX_V7_LP64_OFF64 SYMBOLIC(_POSIX_V7_LP64_OFF64) -#define _POSIX_VDISABLE SYMBOLIC(_POSIX_VDISABLE) -#define _POSIX_VERSION SYMBOLIC(_POSIX_VERSION) +#define _POSIX2_BC_BASE_MAX 99 +#define _POSIX2_BC_DIM_MAX 2048 +#define _POSIX2_BC_SCALE_MAX 99 +#define _POSIX2_BC_STRING_MAX 1000 +#define _POSIX2_CHARCLASS_NAME_MAX 14 +#define _POSIX2_COLL_WEIGHTS_MAX 2 +#define _POSIX2_EXPR_NEST_MAX 32 +#define _POSIX2_LINE_MAX 2048 +#define _POSIX2_RE_DUP_MAX 255 + +#define _XOPEN_IOV_MAX 16 +#define _XOPEN_NAME_MAX 255 +#define _XOPEN_PATH_MAX 1024 #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX_H_ */ diff --git a/libc/sysv/consts/audit.h b/libc/sysv/consts/audit.h new file mode 100644 index 000000000..25051c10f --- /dev/null +++ b/libc/sysv/consts/audit.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_AUDIT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_AUDIT_H_ +#include "libc/elf/def.h" + +#define __AUDIT_ARCH_64BIT 0x80000000 +#define __AUDIT_ARCH_LE 0x40000000 +#define __AUDIT_ARCH_CONVENTION_MASK 0x30000000 +#define __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000 + +#define AUDIT_ARCH_X86_64 (EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) +#define AUDIT_ARCH_I386 (EM_386 | __AUDIT_ARCH_LE) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_AUDIT_H_ */ diff --git a/libc/sysv/consts/auxv.h b/libc/sysv/consts/auxv.h index 69bf377f9..fb18fb88c 100644 --- a/libc/sysv/consts/auxv.h +++ b/libc/sysv/consts/auxv.h @@ -31,6 +31,16 @@ extern const long AT_SECURE; extern const long AT_SYSINFO_EHDR; extern const long AT_UCACHEBSIZE; extern const long AT_UID; +extern const long AT_STACKBASE; +extern const long AT_EXECPATH; +extern const long AT_CANARY; +extern const long AT_CANARYLEN; +extern const long AT_NCPUS; +extern const long AT_PAGESIZES; +extern const long AT_PAGESIZESLEN; +extern const long AT_TIMEKEEP; +extern const long AT_STACKPROT; +extern const long AT_EHDRFLAGS; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ @@ -62,5 +72,15 @@ COSMOPOLITAN_C_END_ #define AT_SYSINFO_EHDR SYMBOLIC(AT_SYSINFO_EHDR) #define AT_UCACHEBSIZE SYMBOLIC(AT_UCACHEBSIZE) #define AT_UID SYMBOLIC(AT_UID) +#define AT_STACKBASE SYMBOLIC(AT_STACKBASE) +#define AT_EXECPATH SYMBOLIC(AT_EXECPATH) +#define AT_CANARY SYMBOLIC(AT_CANARY) +#define AT_CANARYLEN SYMBOLIC(AT_CANARYLEN) +#define AT_NCPUS SYMBOLIC(AT_NCPUS) +#define AT_PAGESIZES SYMBOLIC(AT_PAGESIZES) +#define AT_PAGESIZESLEN SYMBOLIC(AT_PAGESIZESLEN) +#define AT_TIMEKEEP SYMBOLIC(AT_TIMEKEEP) +#define AT_STACKPROT SYMBOLIC(AT_STACKPROT) +#define AT_EHDRFLAGS SYMBOLIC(AT_EHDRFLAGS) #endif /* COSMOPOLITAN_LIBC_CALLS_AUXV_H_ */ diff --git a/libc/sysv/consts/clone.h b/libc/sysv/consts/clone.h index dafde6612..bd8102970 100644 --- a/libc/sysv/consts/clone.h +++ b/libc/sysv/consts/clone.h @@ -1,9 +1,15 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_ +#include "libc/runtime/symbolic.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#define CLONE_VM 0x00000100 +extern const long CLONE_VM; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define CLONE_VM SYMBOLIC(CLONE_VM) #define CLONE_FS 0x00000200 #define CLONE_FILES 0x00000400 #define CLONE_SIGHAND 0x00000800 @@ -21,6 +27,4 @@ COSMOPOLITAN_C_START_ #define CLONE_CHILD_SETTID 0x01000000 #define CLONE_STOPPED 0x02000000 -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_ */ diff --git a/libc/sysv/consts/exit.h b/libc/sysv/consts/exit.h index b980539d0..70e67d83f 100644 --- a/libc/sysv/consts/exit.h +++ b/libc/sysv/consts/exit.h @@ -1,16 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_EXIT_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_EXIT_H_ -#include "libc/runtime/symbolic.h" -#define EXIT_FAILURE SYMBOLIC(EXIT_FAILURE) -#define EXIT_SUCCESS SYMBOLIC(EXIT_SUCCESS) +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -extern const long EXIT_FAILURE; -extern const long EXIT_SUCCESS; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_EXIT_H_ */ diff --git a/libc/sysv/consts/limits.h b/libc/sysv/consts/limits.h index 4a5476963..b01418b22 100644 --- a/libc/sysv/consts/limits.h +++ b/libc/sysv/consts/limits.h @@ -4,11 +4,19 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern const long PIPE_BUF; +extern const int PIPE_BUF; +extern const int _ARG_MAX; +extern const int _NAME_MAX; +extern const int _PATH_MAX; +extern const int _NSIG; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#define PIPE_BUF SYMBOLIC(PIPE_BUF) +#define PIPE_BUF SYMBOLIC(PIPE_BUF) +#define _ARG_MAX SYMBOLIC(_ARG_MAX) +#define _NAME_MAX SYMBOLIC(_NAME_MAX) +#define _PATH_MAX SYMBOLIC(_PATH_MAX) +#define _NSIG SYMBOLIC(_NSIG) #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LIMITS_H_ */ diff --git a/libc/sysv/consts/log.h b/libc/sysv/consts/log.h index 838bfd293..989473351 100644 --- a/libc/sysv/consts/log.h +++ b/libc/sysv/consts/log.h @@ -1,93 +1,45 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_ -#include "libc/runtime/symbolic.h" -#define LOG_ALERT SYMBOLIC(LOG_ALERT) -#define LOG_AUTH SYMBOLIC(LOG_AUTH) -#define LOG_CONS SYMBOLIC(LOG_CONS) -#define LOG_CRIT SYMBOLIC(LOG_CRIT) -#define LOG_CRON SYMBOLIC(LOG_CRON) -#define LOG_DAEMON SYMBOLIC(LOG_DAEMON) -#define LOG_DEBUG SYMBOLIC(LOG_DEBUG) -#define LOG_EMERG SYMBOLIC(LOG_EMERG) -#define LOG_ERR SYMBOLIC(LOG_ERR) -#define LOG_FACMASK SYMBOLIC(LOG_FACMASK) -#define LOG_INFO SYMBOLIC(LOG_INFO) -#define LOG_KERN SYMBOLIC(LOG_KERN) -#define LOG_LOCAL0 SYMBOLIC(LOG_LOCAL0) -#define LOG_LOCAL1 SYMBOLIC(LOG_LOCAL1) -#define LOG_LOCAL2 SYMBOLIC(LOG_LOCAL2) -#define LOG_LOCAL3 SYMBOLIC(LOG_LOCAL3) -#define LOG_LOCAL4 SYMBOLIC(LOG_LOCAL4) -#define LOG_LOCAL5 SYMBOLIC(LOG_LOCAL5) -#define LOG_LOCAL6 SYMBOLIC(LOG_LOCAL6) -#define LOG_LOCAL7 SYMBOLIC(LOG_LOCAL7) -#define LOG_LPR SYMBOLIC(LOG_LPR) -#define LOG_MAIL SYMBOLIC(LOG_MAIL) -#define LOG_NDELAY SYMBOLIC(LOG_NDELAY) -#define LOG_NEWS SYMBOLIC(LOG_NEWS) -#define LOG_NFACILITIES SYMBOLIC(LOG_NFACILITIES) -#define LOG_NOTICE SYMBOLIC(LOG_NOTICE) -#define LOG_NOWAIT SYMBOLIC(LOG_NOWAIT) -#define LOG_ODELAY SYMBOLIC(LOG_ODELAY) -#define LOG_PERROR SYMBOLIC(LOG_PERROR) -#define LOG_PID SYMBOLIC(LOG_PID) -#define LOG_PRIMASK SYMBOLIC(LOG_PRIMASK) -#define LOG_SELECT SYMBOLIC(LOG_SELECT) -#define LOG_SENSE SYMBOLIC(LOG_SENSE) -#define LOG_SYSLOG SYMBOLIC(LOG_SYSLOG) -#define LOG_USER SYMBOLIC(LOG_USER) -#define LOG_UUCP SYMBOLIC(LOG_UUCP) -#define LOG_WARNING SYMBOLIC(LOG_WARNING) +#define LOG_MASK(pri) (1 << (pri)) +#define LOG_UPTO(pri) ((1 << ((pri) + 1)) - 1) -/* - * arguments to setlogmask. - */ -#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */ -#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */ +#define LOG_EMERG 0 +#define LOG_KERN 0 +#define LOG_ALERT 1 +#define LOG_PID 1 +#define LOG_CONS 2 +#define LOG_CRIT 2 +#define LOG_ERR 3 +#define LOG_ODELAY 4 +#define LOG_WARNING 4 +#define LOG_NOTICE 5 +#define LOG_INFO 6 +#define LOG_DEBUG 7 +#define LOG_PRIMASK 7 +#define LOG_NDELAY 8 +#define LOG_USER 8 +#define LOG_MAIL 16 +#define LOG_NOWAIT 16 +#define LOG_DAEMON 24 +#define LOG_NFACILITIES 24 +#define LOG_AUTH 32 +#define LOG_PERROR 32 +#define LOG_SYSLOG 40 +#define LOG_LPR 48 +#define LOG_NEWS 56 +#define LOG_UUCP 64 +#define LOG_CRON 72 +#define LOG_SELECT 76 +#define LOG_SENSE 77 +#define LOG_LOCAL0 128 +#define LOG_LOCAL1 136 +#define LOG_LOCAL2 144 +#define LOG_LOCAL3 152 +#define LOG_LOCAL4 160 +#define LOG_LOCAL5 168 +#define LOG_LOCAL6 176 +#define LOG_LOCAL7 184 +#define LOG_FACMASK 0x03f8 - -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -extern const long LOG_ALERT; -extern const long LOG_AUTH; -extern const long LOG_CONS; -extern const long LOG_CRIT; -extern const long LOG_CRON; -extern const long LOG_DAEMON; -extern const long LOG_DEBUG; -extern const long LOG_EMERG; -extern const long LOG_ERR; -extern const long LOG_FACMASK; -extern const long LOG_INFO; -extern const long LOG_KERN; -extern const long LOG_LOCAL0; -extern const long LOG_LOCAL1; -extern const long LOG_LOCAL2; -extern const long LOG_LOCAL3; -extern const long LOG_LOCAL4; -extern const long LOG_LOCAL5; -extern const long LOG_LOCAL6; -extern const long LOG_LOCAL7; -extern const long LOG_LPR; -extern const long LOG_MAIL; -extern const long LOG_NDELAY; -extern const long LOG_NEWS; -extern const long LOG_NFACILITIES; -extern const long LOG_NOTICE; -extern const long LOG_NOWAIT; -extern const long LOG_ODELAY; -extern const long LOG_PERROR; -extern const long LOG_PID; -extern const long LOG_PRIMASK; -extern const long LOG_SELECT; -extern const long LOG_SENSE; -extern const long LOG_SYSLOG; -extern const long LOG_USER; -extern const long LOG_UUCP; -extern const long LOG_WARNING; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_ */ diff --git a/libc/sysv/consts/madv.h b/libc/sysv/consts/madv.h index 1c828ad15..d03b6053e 100644 --- a/libc/sysv/consts/madv.h +++ b/libc/sysv/consts/madv.h @@ -1,44 +1,45 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MADV_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_MADV_H_ #include "libc/runtime/symbolic.h" - -#define MADV_DODUMP SYMBOLIC(MADV_DODUMP) -#define MADV_DOFORK SYMBOLIC(MADV_DOFORK) -#define MADV_DONTDUMP SYMBOLIC(MADV_DONTDUMP) -#define MADV_DONTFORK SYMBOLIC(MADV_DONTFORK) -#define MADV_DONTNEED SYMBOLIC(MADV_DONTNEED) -#define MADV_FREE SYMBOLIC(MADV_FREE) -#define MADV_HUGEPAGE SYMBOLIC(MADV_HUGEPAGE) -#define MADV_HWPOISON SYMBOLIC(MADV_HWPOISON) -#define MADV_MERGEABLE SYMBOLIC(MADV_MERGEABLE) -#define MADV_NOHUGEPAGE SYMBOLIC(MADV_NOHUGEPAGE) -#define MADV_NORMAL SYMBOLIC(MADV_NORMAL) -#define MADV_RANDOM SYMBOLIC(MADV_RANDOM) -#define MADV_REMOVE SYMBOLIC(MADV_REMOVE) -#define MADV_SEQUENTIAL SYMBOLIC(MADV_SEQUENTIAL) -#define MADV_UNMERGEABLE SYMBOLIC(MADV_UNMERGEABLE) -#define MADV_WILLNEED SYMBOLIC(MADV_WILLNEED) - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern const long MADV_DODUMP; -extern const long MADV_DOFORK; -extern const long MADV_DONTDUMP; -extern const long MADV_DONTFORK; -extern const long MADV_DONTNEED; -extern const long MADV_FREE; -extern const long MADV_HUGEPAGE; -extern const long MADV_HWPOISON; -extern const long MADV_MERGEABLE; -extern const long MADV_NOHUGEPAGE; -extern const long MADV_NORMAL; -extern const long MADV_RANDOM; -extern const long MADV_REMOVE; -extern const long MADV_SEQUENTIAL; -extern const long MADV_UNMERGEABLE; -extern const long MADV_WILLNEED; +extern const unsigned MADV_DODUMP; +extern const unsigned MADV_DOFORK; +extern const unsigned MADV_DONTDUMP; +extern const unsigned MADV_DONTFORK; +extern const unsigned MADV_DONTNEED; +extern const unsigned MADV_FREE; +extern const unsigned MADV_HUGEPAGE; +extern const unsigned MADV_HWPOISON; +extern const unsigned MADV_MERGEABLE; +extern const unsigned MADV_NOHUGEPAGE; +extern const unsigned MADV_NORMAL; +extern const unsigned MADV_RANDOM; +extern const unsigned MADV_REMOVE; +extern const unsigned MADV_SEQUENTIAL; +extern const unsigned MADV_UNMERGEABLE; +extern const unsigned MADV_WILLNEED; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define MADV_NORMAL LITERALLY(0) +#define MADV_RANDOM LITERALLY(1) +#define MADV_SEQUENTIAL LITERALLY(2) +#define MADV_WILLNEED LITERALLY(3) + +#define MADV_DODUMP SYMBOLIC(MADV_DODUMP) +#define MADV_DOFORK SYMBOLIC(MADV_DOFORK) +#define MADV_DONTDUMP SYMBOLIC(MADV_DONTDUMP) +#define MADV_DONTFORK SYMBOLIC(MADV_DONTFORK) +#define MADV_DONTNEED SYMBOLIC(MADV_DONTNEED) +#define MADV_FREE SYMBOLIC(MADV_FREE) +#define MADV_HUGEPAGE SYMBOLIC(MADV_HUGEPAGE) +#define MADV_HWPOISON SYMBOLIC(MADV_HWPOISON) +#define MADV_MERGEABLE SYMBOLIC(MADV_MERGEABLE) +#define MADV_NOHUGEPAGE SYMBOLIC(MADV_NOHUGEPAGE) +#define MADV_REMOVE SYMBOLIC(MADV_REMOVE) +#define MADV_UNMERGEABLE SYMBOLIC(MADV_UNMERGEABLE) + #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MADV_H_ */ diff --git a/libc/sysv/consts/nr.h b/libc/sysv/consts/nr.h index 810a90746..00ed55a70 100644 --- a/libc/sysv/consts/nr.h +++ b/libc/sysv/consts/nr.h @@ -1,778 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_NR_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_NR_H_ #include "libc/runtime/symbolic.h" - -#define __NR_exit SYMBOLIC(__NR_exit) -#define __NR_exit_group SYMBOLIC(__NR_exit_group) -#define __NR_read SYMBOLIC(__NR_read) -#define __NR_write SYMBOLIC(__NR_write) -#define __NR_open SYMBOLIC(__NR_open) -#define __NR_close SYMBOLIC(__NR_close) -#define __NR_stat SYMBOLIC(__NR_stat) -#define __NR_fstat SYMBOLIC(__NR_fstat) -#define __NR_lstat SYMBOLIC(__NR_lstat) -#define __NR_poll SYMBOLIC(__NR_poll) -#define __NR_ppoll SYMBOLIC(__NR_ppoll) -#define __NR_lseek SYMBOLIC(__NR_lseek) -#define __NR_mmap SYMBOLIC(__NR_mmap) -#define __NR_msync SYMBOLIC(__NR_msync) -#define __NR_mprotect SYMBOLIC(__NR_mprotect) -#define __NR_munmap SYMBOLIC(__NR_munmap) -#define __NR_sigaction SYMBOLIC(__NR_sigaction) -#define __NR_sigprocmask SYMBOLIC(__NR_sigprocmask) -#define __NR_ioctl SYMBOLIC(__NR_ioctl) -#define __NR_pread SYMBOLIC(__NR_pread) -#define __NR_pwrite SYMBOLIC(__NR_pwrite) -#define __NR_readv SYMBOLIC(__NR_readv) -#define __NR_writev SYMBOLIC(__NR_writev) -#define __NR_access SYMBOLIC(__NR_access) -#define __NR_pipe SYMBOLIC(__NR_pipe) -#define __NR_select SYMBOLIC(__NR_select) -#define __NR_pselect SYMBOLIC(__NR_pselect) -#define __NR_pselect6 SYMBOLIC(__NR_pselect6) -#define __NR_sched_yield SYMBOLIC(__NR_sched_yield) -#define __NR_mremap SYMBOLIC(__NR_mremap) -#define __NR_mincore SYMBOLIC(__NR_mincore) -#define __NR_madvise SYMBOLIC(__NR_madvise) -#define __NR_shmget SYMBOLIC(__NR_shmget) -#define __NR_shmat SYMBOLIC(__NR_shmat) -#define __NR_shmctl SYMBOLIC(__NR_shmctl) -#define __NR_dup SYMBOLIC(__NR_dup) -#define __NR_dup2 SYMBOLIC(__NR_dup2) -#define __NR_pause SYMBOLIC(__NR_pause) -#define __NR_nanosleep SYMBOLIC(__NR_nanosleep) -#define __NR_getitimer SYMBOLIC(__NR_getitimer) -#define __NR_setitimer SYMBOLIC(__NR_setitimer) -#define __NR_alarm SYMBOLIC(__NR_alarm) -#define __NR_getpid SYMBOLIC(__NR_getpid) -#define __NR_sendfile SYMBOLIC(__NR_sendfile) -#define __NR_socket SYMBOLIC(__NR_socket) -#define __NR_connect SYMBOLIC(__NR_connect) -#define __NR_accept SYMBOLIC(__NR_accept) -#define __NR_sendto SYMBOLIC(__NR_sendto) -#define __NR_recvfrom SYMBOLIC(__NR_recvfrom) -#define __NR_sendmsg SYMBOLIC(__NR_sendmsg) -#define __NR_recvmsg SYMBOLIC(__NR_recvmsg) -#define __NR_shutdown SYMBOLIC(__NR_shutdown) -#define __NR_bind SYMBOLIC(__NR_bind) -#define __NR_listen SYMBOLIC(__NR_listen) -#define __NR_getsockname SYMBOLIC(__NR_getsockname) -#define __NR_getpeername SYMBOLIC(__NR_getpeername) -#define __NR_socketpair SYMBOLIC(__NR_socketpair) -#define __NR_setsockopt SYMBOLIC(__NR_setsockopt) -#define __NR_getsockopt SYMBOLIC(__NR_getsockopt) -#define __NR_fork SYMBOLIC(__NR_fork) -#define __NR_vfork SYMBOLIC(__NR_vfork) -#define __NR_posix_spawn SYMBOLIC(__NR_posix_spawn) -#define __NR_execve SYMBOLIC(__NR_execve) -#define __NR_wait4 SYMBOLIC(__NR_wait4) -#define __NR_kill SYMBOLIC(__NR_kill) -#define __NR_killpg SYMBOLIC(__NR_killpg) -#define __NR_clone SYMBOLIC(__NR_clone) -#define __NR_tkill SYMBOLIC(__NR_tkill) -#define __NR_futex SYMBOLIC(__NR_futex) -#define __NR_set_robust_list SYMBOLIC(__NR_set_robust_list) -#define __NR_get_robust_list SYMBOLIC(__NR_get_robust_list) -#define __NR_uname SYMBOLIC(__NR_uname) -#define __NR_semget SYMBOLIC(__NR_semget) -#define __NR_semop SYMBOLIC(__NR_semop) -#define __NR_semctl SYMBOLIC(__NR_semctl) -#define __NR_shmdt SYMBOLIC(__NR_shmdt) -#define __NR_msgget SYMBOLIC(__NR_msgget) -#define __NR_msgsnd SYMBOLIC(__NR_msgsnd) -#define __NR_msgrcv SYMBOLIC(__NR_msgrcv) -#define __NR_msgctl SYMBOLIC(__NR_msgctl) -#define __NR_fcntl SYMBOLIC(__NR_fcntl) -#define __NR_flock SYMBOLIC(__NR_flock) -#define __NR_fsync SYMBOLIC(__NR_fsync) -#define __NR_fdatasync SYMBOLIC(__NR_fdatasync) -#define __NR_truncate SYMBOLIC(__NR_truncate) -#define __NR_ftruncate SYMBOLIC(__NR_ftruncate) -#define __NR_getcwd SYMBOLIC(__NR_getcwd) -#define __NR_chdir SYMBOLIC(__NR_chdir) -#define __NR_fchdir SYMBOLIC(__NR_fchdir) -#define __NR_rename SYMBOLIC(__NR_rename) -#define __NR_mkdir SYMBOLIC(__NR_mkdir) -#define __NR_rmdir SYMBOLIC(__NR_rmdir) -#define __NR_creat SYMBOLIC(__NR_creat) -#define __NR_link SYMBOLIC(__NR_link) -#define __NR_unlink SYMBOLIC(__NR_unlink) -#define __NR_symlink SYMBOLIC(__NR_symlink) -#define __NR_readlink SYMBOLIC(__NR_readlink) -#define __NR_chmod SYMBOLIC(__NR_chmod) -#define __NR_fchmod SYMBOLIC(__NR_fchmod) -#define __NR_chown SYMBOLIC(__NR_chown) -#define __NR_fchown SYMBOLIC(__NR_fchown) -#define __NR_lchown SYMBOLIC(__NR_lchown) -#define __NR_umask SYMBOLIC(__NR_umask) -#define __NR_gettimeofday SYMBOLIC(__NR_gettimeofday) -#define __NR_getrlimit SYMBOLIC(__NR_getrlimit) -#define __NR_getrusage SYMBOLIC(__NR_getrusage) -#define __NR_sysinfo SYMBOLIC(__NR_sysinfo) -#define __NR_times SYMBOLIC(__NR_times) -#define __NR_ptrace SYMBOLIC(__NR_ptrace) -#define __NR_syslog SYMBOLIC(__NR_syslog) -#define __NR_getuid SYMBOLIC(__NR_getuid) -#define __NR_getgid SYMBOLIC(__NR_getgid) -#define __NR_getppid SYMBOLIC(__NR_getppid) -#define __NR_getpgrp SYMBOLIC(__NR_getpgrp) -#define __NR_setsid SYMBOLIC(__NR_setsid) -#define __NR_getsid SYMBOLIC(__NR_getsid) -#define __NR_getpgid SYMBOLIC(__NR_getpgid) -#define __NR_setpgid SYMBOLIC(__NR_setpgid) -#define __NR_geteuid SYMBOLIC(__NR_geteuid) -#define __NR_getegid SYMBOLIC(__NR_getegid) -#define __NR_getgroups SYMBOLIC(__NR_getgroups) -#define __NR_setgroups SYMBOLIC(__NR_setgroups) -#define __NR_setreuid SYMBOLIC(__NR_setreuid) -#define __NR_setregid SYMBOLIC(__NR_setregid) -#define __NR_setuid SYMBOLIC(__NR_setuid) -#define __NR_setgid SYMBOLIC(__NR_setgid) -#define __NR_setresuid SYMBOLIC(__NR_setresuid) -#define __NR_setresgid SYMBOLIC(__NR_setresgid) -#define __NR_getresuid SYMBOLIC(__NR_getresuid) -#define __NR_getresgid SYMBOLIC(__NR_getresgid) -#define __NR_sigpending SYMBOLIC(__NR_sigpending) -#define __NR_sigsuspend SYMBOLIC(__NR_sigsuspend) -#define __NR_sigaltstack SYMBOLIC(__NR_sigaltstack) -#define __NR_mknod SYMBOLIC(__NR_mknod) -#define __NR_mknodat SYMBOLIC(__NR_mknodat) -#define __NR_mkfifo SYMBOLIC(__NR_mkfifo) -#define __NR_mkfifoat SYMBOLIC(__NR_mkfifoat) -#define __NR_statfs SYMBOLIC(__NR_statfs) -#define __NR_fstatfs SYMBOLIC(__NR_fstatfs) -#define __NR_getpriority SYMBOLIC(__NR_getpriority) -#define __NR_setpriority SYMBOLIC(__NR_setpriority) -#define __NR_mlock SYMBOLIC(__NR_mlock) -#define __NR_munlock SYMBOLIC(__NR_munlock) -#define __NR_mlockall SYMBOLIC(__NR_mlockall) -#define __NR_munlockall SYMBOLIC(__NR_munlockall) -#define __NR_setrlimit SYMBOLIC(__NR_setrlimit) -#define __NR_chroot SYMBOLIC(__NR_chroot) -#define __NR_sync SYMBOLIC(__NR_sync) -#define __NR_acct SYMBOLIC(__NR_acct) -#define __NR_settimeofday SYMBOLIC(__NR_settimeofday) -#define __NR_mount SYMBOLIC(__NR_mount) -#define __NR_reboot SYMBOLIC(__NR_reboot) -#define __NR_quotactl SYMBOLIC(__NR_quotactl) -#define __NR_setfsuid SYMBOLIC(__NR_setfsuid) -#define __NR_setfsgid SYMBOLIC(__NR_setfsgid) -#define __NR_capget SYMBOLIC(__NR_capget) -#define __NR_capset SYMBOLIC(__NR_capset) -#define __NR_sigtimedwait SYMBOLIC(__NR_sigtimedwait) -#define __NR_rt_sigqueueinfo SYMBOLIC(__NR_rt_sigqueueinfo) -#define __NR_personality SYMBOLIC(__NR_personality) -#define __NR_ustat SYMBOLIC(__NR_ustat) -#define __NR_sysfs SYMBOLIC(__NR_sysfs) -#define __NR_sched_setparam SYMBOLIC(__NR_sched_setparam) -#define __NR_sched_getparam SYMBOLIC(__NR_sched_getparam) -#define __NR_sched_setscheduler SYMBOLIC(__NR_sched_setscheduler) -#define __NR_sched_getscheduler SYMBOLIC(__NR_sched_getscheduler) -#define __NR_sched_get_priority_max SYMBOLIC(__NR_sched_get_priority_max) -#define __NR_sched_get_priority_min SYMBOLIC(__NR_sched_get_priority_min) -#define __NR_sched_rr_get_interval SYMBOLIC(__NR_sched_rr_get_interval) -#define __NR_vhangup SYMBOLIC(__NR_vhangup) -#define __NR_modify_ldt SYMBOLIC(__NR_modify_ldt) -#define __NR_pivot_root SYMBOLIC(__NR_pivot_root) -#define __NR__sysctl SYMBOLIC(__NR__sysctl) -#define __NR_prctl SYMBOLIC(__NR_prctl) -#define __NR_arch_prctl SYMBOLIC(__NR_arch_prctl) -#define __NR_adjtimex SYMBOLIC(__NR_adjtimex) -#define __NR_umount2 SYMBOLIC(__NR_umount2) -#define __NR_swapon SYMBOLIC(__NR_swapon) -#define __NR_swapoff SYMBOLIC(__NR_swapoff) -#define __NR_sethostname SYMBOLIC(__NR_sethostname) -#define __NR_setdomainname SYMBOLIC(__NR_setdomainname) -#define __NR_iopl SYMBOLIC(__NR_iopl) -#define __NR_ioperm SYMBOLIC(__NR_ioperm) -#define __NR_init_module SYMBOLIC(__NR_init_module) -#define __NR_delete_module SYMBOLIC(__NR_delete_module) -#define __NR_gettid SYMBOLIC(__NR_gettid) -#define __NR_readahead SYMBOLIC(__NR_readahead) -#define __NR_setxattr SYMBOLIC(__NR_setxattr) -#define __NR_fsetxattr SYMBOLIC(__NR_fsetxattr) -#define __NR_getxattr SYMBOLIC(__NR_getxattr) -#define __NR_fgetxattr SYMBOLIC(__NR_fgetxattr) -#define __NR_listxattr SYMBOLIC(__NR_listxattr) -#define __NR_flistxattr SYMBOLIC(__NR_flistxattr) -#define __NR_removexattr SYMBOLIC(__NR_removexattr) -#define __NR_fremovexattr SYMBOLIC(__NR_fremovexattr) -#define __NR_lsetxattr SYMBOLIC(__NR_lsetxattr) -#define __NR_lgetxattr SYMBOLIC(__NR_lgetxattr) -#define __NR_llistxattr SYMBOLIC(__NR_llistxattr) -#define __NR_lremovexattr SYMBOLIC(__NR_lremovexattr) -#define __NR_sched_setaffinity SYMBOLIC(__NR_sched_setaffinity) -#define __NR_sched_getaffinity SYMBOLIC(__NR_sched_getaffinity) -#define __NR_cpuset_getaffinity SYMBOLIC(__NR_cpuset_getaffinity) -#define __NR_cpuset_setaffinity SYMBOLIC(__NR_cpuset_setaffinity) -#define __NR_io_setup SYMBOLIC(__NR_io_setup) -#define __NR_io_destroy SYMBOLIC(__NR_io_destroy) -#define __NR_io_getevents SYMBOLIC(__NR_io_getevents) -#define __NR_io_submit SYMBOLIC(__NR_io_submit) -#define __NR_io_cancel SYMBOLIC(__NR_io_cancel) -#define __NR_lookup_dcookie SYMBOLIC(__NR_lookup_dcookie) -#define __NR_epoll_create SYMBOLIC(__NR_epoll_create) -#define __NR_epoll_wait SYMBOLIC(__NR_epoll_wait) -#define __NR_epoll_ctl SYMBOLIC(__NR_epoll_ctl) -#define __NR_getdents SYMBOLIC(__NR_getdents) -#define __NR_set_tid_address SYMBOLIC(__NR_set_tid_address) -#define __NR_restart_syscall SYMBOLIC(__NR_restart_syscall) -#define __NR_semtimedop SYMBOLIC(__NR_semtimedop) -#define __NR_fadvise SYMBOLIC(__NR_fadvise) -#define __NR_timer_create SYMBOLIC(__NR_timer_create) -#define __NR_timer_settime SYMBOLIC(__NR_timer_settime) -#define __NR_timer_gettime SYMBOLIC(__NR_timer_gettime) -#define __NR_timer_getoverrun SYMBOLIC(__NR_timer_getoverrun) -#define __NR_timer_delete SYMBOLIC(__NR_timer_delete) -#define __NR_clock_settime SYMBOLIC(__NR_clock_settime) -#define __NR_clock_gettime SYMBOLIC(__NR_clock_gettime) -#define __NR_clock_getres SYMBOLIC(__NR_clock_getres) -#define __NR_clock_nanosleep SYMBOLIC(__NR_clock_nanosleep) -#define __NR_tgkill SYMBOLIC(__NR_tgkill) -#define __NR_mbind SYMBOLIC(__NR_mbind) -#define __NR_set_mempolicy SYMBOLIC(__NR_set_mempolicy) -#define __NR_get_mempolicy SYMBOLIC(__NR_get_mempolicy) -#define __NR_mq_open SYMBOLIC(__NR_mq_open) -#define __NR_mq_unlink SYMBOLIC(__NR_mq_unlink) -#define __NR_mq_timedsend SYMBOLIC(__NR_mq_timedsend) -#define __NR_mq_timedreceive SYMBOLIC(__NR_mq_timedreceive) -#define __NR_mq_notify SYMBOLIC(__NR_mq_notify) -#define __NR_mq_getsetattr SYMBOLIC(__NR_mq_getsetattr) -#define __NR_kexec_load SYMBOLIC(__NR_kexec_load) -#define __NR_waitid SYMBOLIC(__NR_waitid) -#define __NR_add_key SYMBOLIC(__NR_add_key) -#define __NR_request_key SYMBOLIC(__NR_request_key) -#define __NR_keyctl SYMBOLIC(__NR_keyctl) -#define __NR_ioprio_set SYMBOLIC(__NR_ioprio_set) -#define __NR_ioprio_get SYMBOLIC(__NR_ioprio_get) -#define __NR_inotify_init SYMBOLIC(__NR_inotify_init) -#define __NR_inotify_add_watch SYMBOLIC(__NR_inotify_add_watch) -#define __NR_inotify_rm_watch SYMBOLIC(__NR_inotify_rm_watch) -#define __NR_openat SYMBOLIC(__NR_openat) -#define __NR_mkdirat SYMBOLIC(__NR_mkdirat) -#define __NR_fchownat SYMBOLIC(__NR_fchownat) -#define __NR_utime SYMBOLIC(__NR_utime) -#define __NR_utimes SYMBOLIC(__NR_utimes) -#define __NR_futimesat SYMBOLIC(__NR_futimesat) -#define __NR_futimes SYMBOLIC(__NR_futimes) -#define __NR_futimens SYMBOLIC(__NR_futimens) -#define __NR_fstatat SYMBOLIC(__NR_fstatat) -#define __NR_unlinkat SYMBOLIC(__NR_unlinkat) -#define __NR_renameat SYMBOLIC(__NR_renameat) -#define __NR_linkat SYMBOLIC(__NR_linkat) -#define __NR_symlinkat SYMBOLIC(__NR_symlinkat) -#define __NR_readlinkat SYMBOLIC(__NR_readlinkat) -#define __NR_fchmodat SYMBOLIC(__NR_fchmodat) -#define __NR_faccessat SYMBOLIC(__NR_faccessat) -#define __NR_unshare SYMBOLIC(__NR_unshare) -#define __NR_splice SYMBOLIC(__NR_splice) -#define __NR_tee SYMBOLIC(__NR_tee) -#define __NR_sync_file_range SYMBOLIC(__NR_sync_file_range) -#define __NR_vmsplice SYMBOLIC(__NR_vmsplice) -#define __NR_migrate_pages SYMBOLIC(__NR_migrate_pages) -#define __NR_move_pages SYMBOLIC(__NR_move_pages) -#define __NR_preadv SYMBOLIC(__NR_preadv) -#define __NR_pwritev SYMBOLIC(__NR_pwritev) -#define __NR_utimensat SYMBOLIC(__NR_utimensat) -#define __NR_fallocate SYMBOLIC(__NR_fallocate) -#define __NR_posix_fallocate SYMBOLIC(__NR_posix_fallocate) -#define __NR_accept4 SYMBOLIC(__NR_accept4) -#define __NR_dup3 SYMBOLIC(__NR_dup3) -#define __NR_pipe2 SYMBOLIC(__NR_pipe2) -#define __NR_epoll_pwait SYMBOLIC(__NR_epoll_pwait) -#define __NR_epoll_create1 SYMBOLIC(__NR_epoll_create1) -#define __NR_perf_event_open SYMBOLIC(__NR_perf_event_open) -#define __NR_inotify_init1 SYMBOLIC(__NR_inotify_init1) -#define __NR_rt_tgsigqueueinfo SYMBOLIC(__NR_rt_tgsigqueueinfo) -#define __NR_signalfd SYMBOLIC(__NR_signalfd) -#define __NR_signalfd4 SYMBOLIC(__NR_signalfd4) -#define __NR_eventfd SYMBOLIC(__NR_eventfd) -#define __NR_eventfd2 SYMBOLIC(__NR_eventfd2) -#define __NR_timerfd_create SYMBOLIC(__NR_timerfd_create) -#define __NR_timerfd_settime SYMBOLIC(__NR_timerfd_settime) -#define __NR_timerfd_gettime SYMBOLIC(__NR_timerfd_gettime) -#define __NR_recvmmsg SYMBOLIC(__NR_recvmmsg) -#define __NR_fanotify_init SYMBOLIC(__NR_fanotify_init) -#define __NR_fanotify_mark SYMBOLIC(__NR_fanotify_mark) -#define __NR_prlimit SYMBOLIC(__NR_prlimit) -#define __NR_name_to_handle_at SYMBOLIC(__NR_name_to_handle_at) -#define __NR_open_by_handle_at SYMBOLIC(__NR_open_by_handle_at) -#define __NR_clock_adjtime SYMBOLIC(__NR_clock_adjtime) -#define __NR_syncfs SYMBOLIC(__NR_syncfs) -#define __NR_sendmmsg SYMBOLIC(__NR_sendmmsg) -#define __NR_setns SYMBOLIC(__NR_setns) -#define __NR_getcpu SYMBOLIC(__NR_getcpu) -#define __NR_process_vm_readv SYMBOLIC(__NR_process_vm_readv) -#define __NR_process_vm_writev SYMBOLIC(__NR_process_vm_writev) -#define __NR_kcmp SYMBOLIC(__NR_kcmp) -#define __NR_finit_module SYMBOLIC(__NR_finit_module) -#define __NR_sched_setattr SYMBOLIC(__NR_sched_setattr) -#define __NR_sched_getattr SYMBOLIC(__NR_sched_getattr) -#define __NR_renameat2 SYMBOLIC(__NR_renameat2) -#define __NR_seccomp SYMBOLIC(__NR_seccomp) -#define __NR_getrandom SYMBOLIC(__NR_getrandom) -#define __NR_memfd_create SYMBOLIC(__NR_memfd_create) -#define __NR_kexec_file_load SYMBOLIC(__NR_kexec_file_load) -#define __NR_bpf SYMBOLIC(__NR_bpf) -#define __NR_execveat SYMBOLIC(__NR_execveat) -#define __NR_userfaultfd SYMBOLIC(__NR_userfaultfd) -#define __NR_membarrier SYMBOLIC(__NR_membarrier) -#define __NR_mlock2 SYMBOLIC(__NR_mlock2) -#define __NR_copy_file_range SYMBOLIC(__NR_copy_file_range) -#define __NR_preadv2 SYMBOLIC(__NR_preadv2) -#define __NR_pwritev2 SYMBOLIC(__NR_pwritev2) -#define __NR_pkey_mprotect SYMBOLIC(__NR_pkey_mprotect) -#define __NR_pkey_alloc SYMBOLIC(__NR_pkey_alloc) -#define __NR_pkey_free SYMBOLIC(__NR_pkey_free) -#define __NR_statx SYMBOLIC(__NR_statx) -#define __NR_io_pgetevents SYMBOLIC(__NR_io_pgetevents) -#define __NR_rseq SYMBOLIC(__NR_rseq) -#define __NR_pidfd_send_signal SYMBOLIC(__NR_pidfd_send_signal) -#define __NR_io_uring_setup SYMBOLIC(__NR_io_uring_setup) -#define __NR_io_uring_enter SYMBOLIC(__NR_io_uring_enter) -#define __NR_io_uring_register SYMBOLIC(__NR_io_uring_register) -#define __NR_pledge SYMBOLIC(__NR_pledge) -#define __NR_msyscall SYMBOLIC(__NR_msyscall) -#define __NR_ktrace SYMBOLIC(__NR_ktrace) -#define __NR_kqueue SYMBOLIC(__NR_kqueue) -#define __NR_kevent SYMBOLIC(__NR_kevent) -#define __NR_revoke SYMBOLIC(__NR_revoke) -#define __NR_setlogin SYMBOLIC(__NR_setlogin) -#define __NR_getfh SYMBOLIC(__NR_getfh) -#define __NR_chflags SYMBOLIC(__NR_chflags) -#define __NR_getfsstat SYMBOLIC(__NR_getfsstat) -#define __NR_nfssvc SYMBOLIC(__NR_nfssvc) -#define __NR_adjtime SYMBOLIC(__NR_adjtime) -#define __NR_fchflags SYMBOLIC(__NR_fchflags) -#define __NR_seteuid SYMBOLIC(__NR_seteuid) -#define __NR_setegid SYMBOLIC(__NR_setegid) -#define __NR_fpathconf SYMBOLIC(__NR_fpathconf) -#define __NR_fhopen SYMBOLIC(__NR_fhopen) -#define __NR_unmount SYMBOLIC(__NR_unmount) -#define __NR_issetugid SYMBOLIC(__NR_issetugid) -#define __NR_minherit SYMBOLIC(__NR_minherit) -#define __NR_pathconf SYMBOLIC(__NR_pathconf) -#define __NR_sysctl SYMBOLIC(__NR_sysctl) -#define __NR_ntp_adjtime SYMBOLIC(__NR_ntp_adjtime) -#define __NR_ntp_gettime SYMBOLIC(__NR_ntp_gettime) -#define __NR_shm_unlink SYMBOLIC(__NR_shm_unlink) -#define __NR_shm_open SYMBOLIC(__NR_shm_open) -#define __NR_aio_read SYMBOLIC(__NR_aio_read) -#define __NR_aio_suspend SYMBOLIC(__NR_aio_suspend) -#define __NR_aio_cancel SYMBOLIC(__NR_aio_cancel) -#define __NR_aio_fsync SYMBOLIC(__NR_aio_fsync) -#define __NR_aio_error SYMBOLIC(__NR_aio_error) -#define __NR_aio_return SYMBOLIC(__NR_aio_return) -#define __NR_aio_write SYMBOLIC(__NR_aio_write) -#define __NR_aio_waitcomplete SYMBOLIC(__NR_aio_waitcomplete) -#define __NR_aio_suspend_nocancel SYMBOLIC(__NR_aio_suspend_nocancel) -#define __NR_aio_mlock SYMBOLIC(__NR_aio_mlock) -#define __NR_sigwait SYMBOLIC(__NR_sigwait) -#define __NR_undelete SYMBOLIC(__NR_undelete) -#define __NR_getlogin SYMBOLIC(__NR_getlogin) -#define __NR_getdtablesize SYMBOLIC(__NR_getdtablesize) -#define __NR_setauid SYMBOLIC(__NR_setauid) -#define __NR_audit SYMBOLIC(__NR_audit) -#define __NR_auditctl SYMBOLIC(__NR_auditctl) -#define __NR_getaudit_addr SYMBOLIC(__NR_getaudit_addr) -#define __NR_getdirentries SYMBOLIC(__NR_getdirentries) -#define __NR_lio_listio SYMBOLIC(__NR_lio_listio) -#define __NR_setaudit_addr SYMBOLIC(__NR_setaudit_addr) -#define __NR_getauid SYMBOLIC(__NR_getauid) -#define __NR_semsys SYMBOLIC(__NR_semsys) -#define __NR_auditon SYMBOLIC(__NR_auditon) -#define __NR_msgsys SYMBOLIC(__NR_msgsys) -#define __NR_shmsys SYMBOLIC(__NR_shmsys) -#define __NR_fhstat SYMBOLIC(__NR_fhstat) -#define __NR_chflagsat SYMBOLIC(__NR_chflagsat) -#define __NR_profil SYMBOLIC(__NR_profil) -#define __NR_fhstatfs SYMBOLIC(__NR_fhstatfs) -#define __NR_utrace SYMBOLIC(__NR_utrace) -#define __NR_closefrom SYMBOLIC(__NR_closefrom) -#define __NR_pthread_markcancel SYMBOLIC(__NR_pthread_markcancel) -#define __NR_pthread_kill SYMBOLIC(__NR_pthread_kill) -#define __NR_pthread_fchdir SYMBOLIC(__NR_pthread_fchdir) -#define __NR_pthread_sigmask SYMBOLIC(__NR_pthread_sigmask) -#define __NR_pthread_chdir SYMBOLIC(__NR_pthread_chdir) -#define __NR_pthread_canceled SYMBOLIC(__NR_pthread_canceled) -#define __NR_disable_threadsignal SYMBOLIC(__NR_disable_threadsignal) -#define __NR_abort_with_payload SYMBOLIC(__NR_abort_with_payload) -#define __NR_accept_nocancel SYMBOLIC(__NR_accept_nocancel) -#define __NR_access_extended SYMBOLIC(__NR_access_extended) -#define __NR_audit_session_join SYMBOLIC(__NR_audit_session_join) -#define __NR_audit_session_port SYMBOLIC(__NR_audit_session_port) -#define __NR_audit_session_self SYMBOLIC(__NR_audit_session_self) -#define __NR_bsdthread_create SYMBOLIC(__NR_bsdthread_create) -#define __NR_bsdthread_ctl SYMBOLIC(__NR_bsdthread_ctl) -#define __NR_bsdthread_register SYMBOLIC(__NR_bsdthread_register) -#define __NR_bsdthread_terminate SYMBOLIC(__NR_bsdthread_terminate) -#define __NR_change_fdguard_np SYMBOLIC(__NR_change_fdguard_np) -#define __NR_chmod_extended SYMBOLIC(__NR_chmod_extended) -#define __NR_clonefileat SYMBOLIC(__NR_clonefileat) -#define __NR_close_nocancel SYMBOLIC(__NR_close_nocancel) -#define __NR_coalition SYMBOLIC(__NR_coalition) -#define __NR_coalition_info SYMBOLIC(__NR_coalition_info) -#define __NR_connect_nocancel SYMBOLIC(__NR_connect_nocancel) -#define __NR_connectx SYMBOLIC(__NR_connectx) -#define __NR_copyfile SYMBOLIC(__NR_copyfile) -#define __NR_csops SYMBOLIC(__NR_csops) -#define __NR_csops_audittoken SYMBOLIC(__NR_csops_audittoken) -#define __NR_csrctl SYMBOLIC(__NR_csrctl) -#define __NR_delete SYMBOLIC(__NR_delete) -#define __NR_disconnectx SYMBOLIC(__NR_disconnectx) -#define __NR_exchangedata SYMBOLIC(__NR_exchangedata) -#define __NR_fchmod_extended SYMBOLIC(__NR_fchmod_extended) -#define __NR_fclonefileat SYMBOLIC(__NR_fclonefileat) -#define __NR_fcntl_nocancel SYMBOLIC(__NR_fcntl_nocancel) -#define __NR_ffsctl SYMBOLIC(__NR_ffsctl) -#define __NR_fgetattrlist SYMBOLIC(__NR_fgetattrlist) -#define __NR_fileport_makefd SYMBOLIC(__NR_fileport_makefd) -#define __NR_fileport_makeport SYMBOLIC(__NR_fileport_makeport) -#define __NR_fmount SYMBOLIC(__NR_fmount) -#define __NR_fs_snapshot SYMBOLIC(__NR_fs_snapshot) -#define __NR_fsctl SYMBOLIC(__NR_fsctl) -#define __NR_fsetattrlist SYMBOLIC(__NR_fsetattrlist) -#define __NR_fstat_extended SYMBOLIC(__NR_fstat_extended) -#define __NR_fsync_nocancel SYMBOLIC(__NR_fsync_nocancel) -#define __NR_getattrlist SYMBOLIC(__NR_getattrlist) -#define __NR_getattrlistat SYMBOLIC(__NR_getattrlistat) -#define __NR_getattrlistbulk SYMBOLIC(__NR_getattrlistbulk) -#define __NR_getdirentriesattr SYMBOLIC(__NR_getdirentriesattr) -#define __NR_gethostuuid SYMBOLIC(__NR_gethostuuid) -#define __NR_getsgroups SYMBOLIC(__NR_getsgroups) -#define __NR_getwgroups SYMBOLIC(__NR_getwgroups) -#define __NR_grab_pgo_data SYMBOLIC(__NR_grab_pgo_data) -#define __NR_guarded_close_np SYMBOLIC(__NR_guarded_close_np) -#define __NR_guarded_kqueue_np SYMBOLIC(__NR_guarded_kqueue_np) -#define __NR_guarded_open_np SYMBOLIC(__NR_guarded_open_np) -#define __NR_guarded_pwrite_np SYMBOLIC(__NR_guarded_pwrite_np) -#define __NR_guarded_write_np SYMBOLIC(__NR_guarded_write_np) -#define __NR_guarded_writev_np SYMBOLIC(__NR_guarded_writev_np) -#define __NR_identitysvc SYMBOLIC(__NR_identitysvc) -#define __NR_initgroups SYMBOLIC(__NR_initgroups) -#define __NR_iopolicysys SYMBOLIC(__NR_iopolicysys) -#define __NR_kas_info SYMBOLIC(__NR_kas_info) -#define __NR_kdebug_trace SYMBOLIC(__NR_kdebug_trace) -#define __NR_kdebug_trace_string SYMBOLIC(__NR_kdebug_trace_string) -#define __NR_kdebug_typefilter SYMBOLIC(__NR_kdebug_typefilter) -#define __NR_kevent_id SYMBOLIC(__NR_kevent_id) -#define __NR_kevent_qos SYMBOLIC(__NR_kevent_qos) -#define __NR_ledger SYMBOLIC(__NR_ledger) -#define __NR_lstat_extended SYMBOLIC(__NR_lstat_extended) -#define __NR_memorystatus_control SYMBOLIC(__NR_memorystatus_control) -#define __NR_memorystatus_get_level SYMBOLIC(__NR_memorystatus_get_level) -#define __NR_microstackshot SYMBOLIC(__NR_microstackshot) -#define __NR_mkdir_extended SYMBOLIC(__NR_mkdir_extended) -#define __NR_mkfifo_extended SYMBOLIC(__NR_mkfifo_extended) -#define __NR_modwatch SYMBOLIC(__NR_modwatch) -#define __NR_mremap_encrypted SYMBOLIC(__NR_mremap_encrypted) -#define __NR_msgrcv_nocancel SYMBOLIC(__NR_msgrcv_nocancel) -#define __NR_msgsnd_nocancel SYMBOLIC(__NR_msgsnd_nocancel) -#define __NR_msync_nocancel SYMBOLIC(__NR_msync_nocancel) -#define __NR_necp_client_action SYMBOLIC(__NR_necp_client_action) -#define __NR_necp_match_policy SYMBOLIC(__NR_necp_match_policy) -#define __NR_necp_open SYMBOLIC(__NR_necp_open) -#define __NR_necp_session_action SYMBOLIC(__NR_necp_session_action) -#define __NR_necp_session_open SYMBOLIC(__NR_necp_session_open) -#define __NR_net_qos_guideline SYMBOLIC(__NR_net_qos_guideline) -#define __NR_netagent_trigger SYMBOLIC(__NR_netagent_trigger) -#define __NR_nfsclnt SYMBOLIC(__NR_nfsclnt) -#define __NR_open_dprotected_np SYMBOLIC(__NR_open_dprotected_np) -#define __NR_open_extended SYMBOLIC(__NR_open_extended) -#define __NR_open_nocancel SYMBOLIC(__NR_open_nocancel) -#define __NR_openat_nocancel SYMBOLIC(__NR_openat_nocancel) -#define __NR_openbyid_np SYMBOLIC(__NR_openbyid_np) -#define __NR_os_fault_with_payload SYMBOLIC(__NR_os_fault_with_payload) -#define __NR_peeloff SYMBOLIC(__NR_peeloff) -#define __NR_persona SYMBOLIC(__NR_persona) -#define __NR_pid_hibernate SYMBOLIC(__NR_pid_hibernate) -#define __NR_pid_resume SYMBOLIC(__NR_pid_resume) -#define __NR_pid_shutdown_sockets SYMBOLIC(__NR_pid_shutdown_sockets) -#define __NR_pid_suspend SYMBOLIC(__NR_pid_suspend) -#define __NR_poll_nocancel SYMBOLIC(__NR_poll_nocancel) -#define __NR_pread_nocancel SYMBOLIC(__NR_pread_nocancel) -#define __NR_proc_info SYMBOLIC(__NR_proc_info) -#define __NR_proc_rlimit_control SYMBOLIC(__NR_proc_rlimit_control) -#define __NR_proc_trace_log SYMBOLIC(__NR_proc_trace_log) -#define __NR_proc_uuid_policy SYMBOLIC(__NR_proc_uuid_policy) -#define __NR_process_policy SYMBOLIC(__NR_process_policy) -#define __NR_pselect_nocancel SYMBOLIC(__NR_pselect_nocancel) -#define __NR_psynch_cvbroad SYMBOLIC(__NR_psynch_cvbroad) -#define __NR_psynch_cvclrprepost SYMBOLIC(__NR_psynch_cvclrprepost) -#define __NR_psynch_cvsignal SYMBOLIC(__NR_psynch_cvsignal) -#define __NR_psynch_mutexdrop SYMBOLIC(__NR_psynch_mutexdrop) -#define __NR_psynch_mutexwait SYMBOLIC(__NR_psynch_mutexwait) -#define __NR_psynch_rw_downgrade SYMBOLIC(__NR_psynch_rw_downgrade) -#define __NR_psynch_rw_longrdlock SYMBOLIC(__NR_psynch_rw_longrdlock) -#define __NR_psynch_rw_rdlock SYMBOLIC(__NR_psynch_rw_rdlock) -#define __NR_psynch_rw_unlock SYMBOLIC(__NR_psynch_rw_unlock) -#define __NR_psynch_rw_unlock2 SYMBOLIC(__NR_psynch_rw_unlock2) -#define __NR_psynch_rw_upgrade SYMBOLIC(__NR_psynch_rw_upgrade) -#define __NR_psynch_rw_wrlock SYMBOLIC(__NR_psynch_rw_wrlock) -#define __NR_psynch_rw_yieldwrlock SYMBOLIC(__NR_psynch_rw_yieldwrlock) -#define __NR_pwrite_nocancel SYMBOLIC(__NR_pwrite_nocancel) -#define __NR_read_nocancel SYMBOLIC(__NR_read_nocancel) -#define __NR_readv_nocancel SYMBOLIC(__NR_readv_nocancel) -#define __NR_recvfrom_nocancel SYMBOLIC(__NR_recvfrom_nocancel) -#define __NR_recvmsg_nocancel SYMBOLIC(__NR_recvmsg_nocancel) -#define __NR_recvmsg_x SYMBOLIC(__NR_recvmsg_x) -#define __NR_renameatx_np SYMBOLIC(__NR_renameatx_np) -#define __NR_searchfs SYMBOLIC(__NR_searchfs) -#define __NR_select_nocancel SYMBOLIC(__NR_select_nocancel) -#define __NR_sem_close SYMBOLIC(__NR_sem_close) -#define __NR_sem_open SYMBOLIC(__NR_sem_open) -#define __NR_sem_post SYMBOLIC(__NR_sem_post) -#define __NR_sem_trywait SYMBOLIC(__NR_sem_trywait) -#define __NR_sem_unlink SYMBOLIC(__NR_sem_unlink) -#define __NR_sem_wait SYMBOLIC(__NR_sem_wait) -#define __NR_sem_wait_nocancel SYMBOLIC(__NR_sem_wait_nocancel) -#define __NR_sendmsg_nocancel SYMBOLIC(__NR_sendmsg_nocancel) -#define __NR_sendmsg_x SYMBOLIC(__NR_sendmsg_x) -#define __NR_sendto_nocancel SYMBOLIC(__NR_sendto_nocancel) -#define __NR_setattrlist SYMBOLIC(__NR_setattrlist) -#define __NR_setattrlistat SYMBOLIC(__NR_setattrlistat) -#define __NR_setprivexec SYMBOLIC(__NR_setprivexec) -#define __NR_setsgroups SYMBOLIC(__NR_setsgroups) -#define __NR_settid SYMBOLIC(__NR_settid) -#define __NR_settid_with_pid SYMBOLIC(__NR_settid_with_pid) -#define __NR_setwgroups SYMBOLIC(__NR_setwgroups) -#define __NR_sfi_ctl SYMBOLIC(__NR_sfi_ctl) -#define __NR_sfi_pidctl SYMBOLIC(__NR_sfi_pidctl) -#define __NR_shared_region_check_np SYMBOLIC(__NR_shared_region_check_np) -#define __NR_sigsuspend_nocancel SYMBOLIC(__NR_sigsuspend_nocancel) -#define __NR_socket_delegate SYMBOLIC(__NR_socket_delegate) -#define __NR_stat_extended SYMBOLIC(__NR_stat_extended) -#define __NR_sysctlbyname SYMBOLIC(__NR_sysctlbyname) -#define __NR_system_override SYMBOLIC(__NR_system_override) -#define __NR_telemetry SYMBOLIC(__NR_telemetry) -#define __NR_terminate_with_payload SYMBOLIC(__NR_terminate_with_payload) -#define __NR_thread_selfcounts SYMBOLIC(__NR_thread_selfcounts) -#define __NR_thread_selfid SYMBOLIC(__NR_thread_selfid) -#define __NR_thread_selfusage SYMBOLIC(__NR_thread_selfusage) -#define __NR_ulock_wait SYMBOLIC(__NR_ulock_wait) -#define __NR_ulock_wake SYMBOLIC(__NR_ulock_wake) -#define __NR_umask_extended SYMBOLIC(__NR_umask_extended) -#define __NR_usrctl SYMBOLIC(__NR_usrctl) -#define __NR_vfs_purge SYMBOLIC(__NR_vfs_purge) -#define __NR_vm_pressure_monitor SYMBOLIC(__NR_vm_pressure_monitor) -#define __NR_wait4_nocancel SYMBOLIC(__NR_wait4_nocancel) -#define __NR_waitevent SYMBOLIC(__NR_waitevent) -#define __NR_waitid_nocancel SYMBOLIC(__NR_waitid_nocancel) -#define __NR_watchevent SYMBOLIC(__NR_watchevent) -#define __NR_work_interval_ctl SYMBOLIC(__NR_work_interval_ctl) -#define __NR_workq_kernreturn SYMBOLIC(__NR_workq_kernreturn) -#define __NR_workq_open SYMBOLIC(__NR_workq_open) -#define __NR_write_nocancel SYMBOLIC(__NR_write_nocancel) -#define __NR_writev_nocancel SYMBOLIC(__NR_writev_nocancel) -#define __NR_abort2 SYMBOLIC(__NR_abort2) -#define __NR_afs3_syscall SYMBOLIC(__NR_afs3_syscall) -#define __NR_bindat SYMBOLIC(__NR_bindat) -#define __NR_break SYMBOLIC(__NR_break) -#define __NR_cap_enter SYMBOLIC(__NR_cap_enter) -#define __NR_cap_fcntls_get SYMBOLIC(__NR_cap_fcntls_get) -#define __NR_cap_fcntls_limit SYMBOLIC(__NR_cap_fcntls_limit) -#define __NR_cap_getmode SYMBOLIC(__NR_cap_getmode) -#define __NR_cap_ioctls_get SYMBOLIC(__NR_cap_ioctls_get) -#define __NR_cap_ioctls_limit SYMBOLIC(__NR_cap_ioctls_limit) -#define __NR_cap_rights_limit SYMBOLIC(__NR_cap_rights_limit) -#define __NR_clock_getcpuclockid2 SYMBOLIC(__NR_clock_getcpuclockid2) -#define __NR_connectat SYMBOLIC(__NR_connectat) -#define __NR_cpuset SYMBOLIC(__NR_cpuset) -#define __NR_cpuset_getdomain SYMBOLIC(__NR_cpuset_getdomain) -#define __NR_cpuset_getid SYMBOLIC(__NR_cpuset_getid) -#define __NR_cpuset_setdomain SYMBOLIC(__NR_cpuset_setdomain) -#define __NR_cpuset_setid SYMBOLIC(__NR_cpuset_setid) -#define __NR_eaccess SYMBOLIC(__NR_eaccess) -#define __NR_extattr_delete_fd SYMBOLIC(__NR_extattr_delete_fd) -#define __NR_extattr_delete_file SYMBOLIC(__NR_extattr_delete_file) -#define __NR_extattr_delete_link SYMBOLIC(__NR_extattr_delete_link) -#define __NR_extattr_get_fd SYMBOLIC(__NR_extattr_get_fd) -#define __NR_extattr_get_file SYMBOLIC(__NR_extattr_get_file) -#define __NR_extattr_get_link SYMBOLIC(__NR_extattr_get_link) -#define __NR_extattr_list_fd SYMBOLIC(__NR_extattr_list_fd) -#define __NR_extattr_list_file SYMBOLIC(__NR_extattr_list_file) -#define __NR_extattr_list_link SYMBOLIC(__NR_extattr_list_link) -#define __NR_extattr_set_fd SYMBOLIC(__NR_extattr_set_fd) -#define __NR_extattr_set_file SYMBOLIC(__NR_extattr_set_file) -#define __NR_extattr_set_link SYMBOLIC(__NR_extattr_set_link) -#define __NR_extattrctl SYMBOLIC(__NR_extattrctl) -#define __NR_fexecve SYMBOLIC(__NR_fexecve) -#define __NR_ffclock_getcounter SYMBOLIC(__NR_ffclock_getcounter) -#define __NR_ffclock_getestimate SYMBOLIC(__NR_ffclock_getestimate) -#define __NR_ffclock_setestimate SYMBOLIC(__NR_ffclock_setestimate) -#define __NR_fhlink SYMBOLIC(__NR_fhlink) -#define __NR_fhlinkat SYMBOLIC(__NR_fhlinkat) -#define __NR_fhreadlink SYMBOLIC(__NR_fhreadlink) -#define __NR_getaudit SYMBOLIC(__NR_getaudit) -#define __NR_getcontext SYMBOLIC(__NR_getcontext) -#define __NR_getfhat SYMBOLIC(__NR_getfhat) -#define __NR_gethostid SYMBOLIC(__NR_gethostid) -#define __NR_getkerninfo SYMBOLIC(__NR_getkerninfo) -#define __NR_getloginclass SYMBOLIC(__NR_getloginclass) -#define __NR_getpagesize SYMBOLIC(__NR_getpagesize) -#define __NR_gssd_syscall SYMBOLIC(__NR_gssd_syscall) -#define __NR_jail SYMBOLIC(__NR_jail) -#define __NR_jail_attach SYMBOLIC(__NR_jail_attach) -#define __NR_jail_get SYMBOLIC(__NR_jail_get) -#define __NR_jail_remove SYMBOLIC(__NR_jail_remove) -#define __NR_jail_set SYMBOLIC(__NR_jail_set) -#define __NR_kenv SYMBOLIC(__NR_kenv) -#define __NR_kldfind SYMBOLIC(__NR_kldfind) -#define __NR_kldfirstmod SYMBOLIC(__NR_kldfirstmod) -#define __NR_kldload SYMBOLIC(__NR_kldload) -#define __NR_kldnext SYMBOLIC(__NR_kldnext) -#define __NR_kldstat SYMBOLIC(__NR_kldstat) -#define __NR_kldsym SYMBOLIC(__NR_kldsym) -#define __NR_kldunload SYMBOLIC(__NR_kldunload) -#define __NR_kldunloadf SYMBOLIC(__NR_kldunloadf) -#define __NR_kmq_notify SYMBOLIC(__NR_kmq_notify) -#define __NR_kmq_setattr SYMBOLIC(__NR_kmq_setattr) -#define __NR_kmq_timedreceive SYMBOLIC(__NR_kmq_timedreceive) -#define __NR_kmq_timedsend SYMBOLIC(__NR_kmq_timedsend) -#define __NR_kmq_unlink SYMBOLIC(__NR_kmq_unlink) -#define __NR_ksem_close SYMBOLIC(__NR_ksem_close) -#define __NR_ksem_destroy SYMBOLIC(__NR_ksem_destroy) -#define __NR_ksem_getvalue SYMBOLIC(__NR_ksem_getvalue) -#define __NR_ksem_init SYMBOLIC(__NR_ksem_init) -#define __NR_ksem_open SYMBOLIC(__NR_ksem_open) -#define __NR_ksem_post SYMBOLIC(__NR_ksem_post) -#define __NR_ksem_timedwait SYMBOLIC(__NR_ksem_timedwait) -#define __NR_ksem_trywait SYMBOLIC(__NR_ksem_trywait) -#define __NR_ksem_unlink SYMBOLIC(__NR_ksem_unlink) -#define __NR_ksem_wait SYMBOLIC(__NR_ksem_wait) -#define __NR_ktimer_create SYMBOLIC(__NR_ktimer_create) -#define __NR_ktimer_delete SYMBOLIC(__NR_ktimer_delete) -#define __NR_ktimer_getoverrun SYMBOLIC(__NR_ktimer_getoverrun) -#define __NR_ktimer_gettime SYMBOLIC(__NR_ktimer_gettime) -#define __NR_ktimer_settime SYMBOLIC(__NR_ktimer_settime) -#define __NR_lchflags SYMBOLIC(__NR_lchflags) -#define __NR_lchmod SYMBOLIC(__NR_lchmod) -#define __NR_lgetfh SYMBOLIC(__NR_lgetfh) -#define __NR_lpathconf SYMBOLIC(__NR_lpathconf) -#define __NR_lutimes SYMBOLIC(__NR_lutimes) -#define __NR_mac_syscall SYMBOLIC(__NR_mac_syscall) -#define __NR_modfind SYMBOLIC(__NR_modfind) -#define __NR_modfnext SYMBOLIC(__NR_modfnext) -#define __NR_modnext SYMBOLIC(__NR_modnext) -#define __NR_modstat SYMBOLIC(__NR_modstat) -#define __NR_nfstat SYMBOLIC(__NR_nfstat) -#define __NR_nlm_syscall SYMBOLIC(__NR_nlm_syscall) -#define __NR_nlstat SYMBOLIC(__NR_nlstat) -#define __NR_nmount SYMBOLIC(__NR_nmount) -#define __NR_nnpfs_syscall SYMBOLIC(__NR_nnpfs_syscall) -#define __NR_nstat SYMBOLIC(__NR_nstat) -#define __NR_pdfork SYMBOLIC(__NR_pdfork) -#define __NR_pdgetpid SYMBOLIC(__NR_pdgetpid) -#define __NR_pdkill SYMBOLIC(__NR_pdkill) -#define __NR_posix_openpt SYMBOLIC(__NR_posix_openpt) -#define __NR_procctl SYMBOLIC(__NR_procctl) -#define __NR_psynch_cvwait SYMBOLIC(__NR_psynch_cvwait) -#define __NR_quota SYMBOLIC(__NR_quota) -#define __NR_rctl_add_rule SYMBOLIC(__NR_rctl_add_rule) -#define __NR_rctl_get_limits SYMBOLIC(__NR_rctl_get_limits) -#define __NR_rctl_get_racct SYMBOLIC(__NR_rctl_get_racct) -#define __NR_rctl_get_rules SYMBOLIC(__NR_rctl_get_rules) -#define __NR_rctl_remove_rule SYMBOLIC(__NR_rctl_remove_rule) -#define __NR_recv SYMBOLIC(__NR_recv) -#define __NR_rfork SYMBOLIC(__NR_rfork) -#define __NR_rtprio SYMBOLIC(__NR_rtprio) -#define __NR_rtprio_thread SYMBOLIC(__NR_rtprio_thread) -#define __NR_send SYMBOLIC(__NR_send) -#define __NR_setaudit SYMBOLIC(__NR_setaudit) -#define __NR_setcontext SYMBOLIC(__NR_setcontext) -#define __NR_setfib SYMBOLIC(__NR_setfib) -#define __NR_sethostid SYMBOLIC(__NR_sethostid) -#define __NR_setloginclass SYMBOLIC(__NR_setloginclass) -#define __NR_sigblock SYMBOLIC(__NR_sigblock) -#define __NR_sigqueue SYMBOLIC(__NR_sigqueue) -#define __NR_sigsetmask SYMBOLIC(__NR_sigsetmask) -#define __NR_sigstack SYMBOLIC(__NR_sigstack) -#define __NR_sigvec SYMBOLIC(__NR_sigvec) -#define __NR_sigwaitinfo SYMBOLIC(__NR_sigwaitinfo) -#define __NR_sstk SYMBOLIC(__NR_sstk) -#define __NR_swapcontext SYMBOLIC(__NR_swapcontext) -#define __NR_thr_create SYMBOLIC(__NR_thr_create) -#define __NR_thr_exit SYMBOLIC(__NR_thr_exit) -#define __NR_thr_kill SYMBOLIC(__NR_thr_kill) -#define __NR_thr_kill2 SYMBOLIC(__NR_thr_kill2) -#define __NR_thr_new SYMBOLIC(__NR_thr_new) -#define __NR_thr_self SYMBOLIC(__NR_thr_self) -#define __NR_thr_set_name SYMBOLIC(__NR_thr_set_name) -#define __NR_thr_suspend SYMBOLIC(__NR_thr_suspend) -#define __NR_thr_wake SYMBOLIC(__NR_thr_wake) -#define __NR_uuidgen SYMBOLIC(__NR_uuidgen) -#define __NR_vadvise SYMBOLIC(__NR_vadvise) -#define __NR_wait SYMBOLIC(__NR_wait) -#define __NR_wait6 SYMBOLIC(__NR_wait6) -#define __NR_yield SYMBOLIC(__NR_yield) -#define __NR_tfork SYMBOLIC(__NR_tfork) -#define __NR_thrsleep SYMBOLIC(__NR_thrsleep) -#define __NR_thrwakeup SYMBOLIC(__NR_thrwakeup) -#define __NR_threxit SYMBOLIC(__NR_threxit) -#define __NR_thrsigdivert SYMBOLIC(__NR_thrsigdivert) -#define __NR_set_tcb SYMBOLIC(__NR_set_tcb) -#define __NR_get_tcb SYMBOLIC(__NR_get_tcb) -#define __NR_adjfreq SYMBOLIC(__NR_adjfreq) -#define __NR_getdtablecount SYMBOLIC(__NR_getdtablecount) -#define __NR_getlogin_r SYMBOLIC(__NR_getlogin_r) -#define __NR_getrtable SYMBOLIC(__NR_getrtable) -#define __NR_getthrid SYMBOLIC(__NR_getthrid) -#define __NR_kbind SYMBOLIC(__NR_kbind) -#define __NR_mquery SYMBOLIC(__NR_mquery) -#define __NR_obreak SYMBOLIC(__NR_obreak) -#define __NR_sendsyslog SYMBOLIC(__NR_sendsyslog) -#define __NR_setrtable SYMBOLIC(__NR_setrtable) -#define __NR_swapctl SYMBOLIC(__NR_swapctl) -#define __NR_thrkill SYMBOLIC(__NR_thrkill) -#define __NR_unveil SYMBOLIC(__NR_unveil) -#define __NR_mac_get_link SYMBOLIC(__NR_mac_get_link) -#define __NR_mac_set_link SYMBOLIC(__NR_mac_set_link) -#define __NR_mac_get_fd SYMBOLIC(__NR_mac_get_fd) -#define __NR_mac_get_file SYMBOLIC(__NR_mac_get_file) -#define __NR_mac_get_proc SYMBOLIC(__NR_mac_get_proc) -#define __NR_mac_set_fd SYMBOLIC(__NR_mac_set_fd) -#define __NR_mac_get_pid SYMBOLIC(__NR_mac_get_pid) -#define __NR_mac_set_proc SYMBOLIC(__NR_mac_set_proc) -#define __NR_mac_set_file SYMBOLIC(__NR_mac_set_file) -#define __NR_mac_execve SYMBOLIC(__NR_mac_execve) -#define __NR_acl_get_link SYMBOLIC(__NR_acl_get_link) -#define __NR_sigwait_nocancel SYMBOLIC(__NR_sigwait_nocancel) -#define __NR_cap_rights_get SYMBOLIC(__NR_cap_rights_get) -#define __NR_semwait_signal SYMBOLIC(__NR_semwait_signal) -#define __NR_acl_set_link SYMBOLIC(__NR_acl_set_link) -#define __NR_acl_set_fd SYMBOLIC(__NR_acl_set_fd) -#define __NR_old_semwait_signal SYMBOLIC(__NR_old_semwait_signal) -#define __NR_setugid SYMBOLIC(__NR_setugid) -#define __NR_acl_aclcheck_fd SYMBOLIC(__NR_acl_aclcheck_fd) -#define __NR_acl_get_fd SYMBOLIC(__NR_acl_get_fd) -#define __NR___sysctl SYMBOLIC(__NR___sysctl) -#define __NR_mac_getfsstat SYMBOLIC(__NR_mac_getfsstat) -#define __NR_mac_get_mount SYMBOLIC(__NR_mac_get_mount) -#define __NR_acl_delete_link SYMBOLIC(__NR_acl_delete_link) -#define __NR_mac_mount SYMBOLIC(__NR_mac_mount) -#define __NR_acl_get_file SYMBOLIC(__NR_acl_get_file) -#define __NR_acl_aclcheck_file SYMBOLIC(__NR_acl_aclcheck_file) -#define __NR_acl_delete_fd SYMBOLIC(__NR_acl_delete_fd) -#define __NR_acl_aclcheck_link SYMBOLIC(__NR_acl_aclcheck_link) -#define __NR___mac_syscall SYMBOLIC(__NR___mac_syscall) -#define __NR_acl_set_file SYMBOLIC(__NR_acl_set_file) -#define __NR_acl_delete_file SYMBOLIC(__NR_acl_delete_file) -#define __NR_syscall SYMBOLIC(__NR_syscall) -#define __NR__umtx_op SYMBOLIC(__NR__umtx_op) -#define __NR_semwait_signal_nocancel SYMBOLIC(__NR_semwait_signal_nocancel) -#define __NR_old_semwait_signal_nocancel \ - SYMBOLIC(__NR_old_semwait_signal_nocancel) -#define __NR_sctp_peeloff SYMBOLIC(__NR_sctp_peeloff) -#define __NR_sctp_generic_recvmsg SYMBOLIC(__NR_sctp_generic_recvmsg) -#define __NR_sctp_generic_sendmsg SYMBOLIC(__NR_sctp_generic_sendmsg) -#define __NR_sctp_generic_sendmsg_iov SYMBOLIC(__NR_sctp_generic_sendmsg_iov) -#define __NR_shared_region_map_and_slide_np \ - SYMBOLIC(__NR_shared_region_map_and_slide_np) -#define __NR_guarded_open_dprotected_np \ - SYMBOLIC(__NR_guarded_open_dprotected_np) -#define __NR_stack_snapshot_with_config \ - SYMBOLIC(__NR_stack_snapshot_with_config) - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -1469,7 +697,6 @@ extern const long __NR_thr_create; extern const long __NR_thr_exit; extern const long __NR_thr_kill; extern const long __NR_thr_kill2; -extern const long __NR_thr_new; extern const long __NR_thr_self; extern const long __NR_thr_set_name; extern const long __NR_thr_suspend; @@ -1545,4 +772,775 @@ extern const long __NR_stack_snapshot_with_config; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define __NR_exit SYMBOLIC(__NR_exit) +#define __NR_exit_group SYMBOLIC(__NR_exit_group) +#define __NR_read SYMBOLIC(__NR_read) +#define __NR_write SYMBOLIC(__NR_write) +#define __NR_open SYMBOLIC(__NR_open) +#define __NR_close SYMBOLIC(__NR_close) +#define __NR_stat SYMBOLIC(__NR_stat) +#define __NR_fstat SYMBOLIC(__NR_fstat) +#define __NR_lstat SYMBOLIC(__NR_lstat) +#define __NR_poll SYMBOLIC(__NR_poll) +#define __NR_ppoll SYMBOLIC(__NR_ppoll) +#define __NR_lseek SYMBOLIC(__NR_lseek) +#define __NR_mmap SYMBOLIC(__NR_mmap) +#define __NR_msync SYMBOLIC(__NR_msync) +#define __NR_mprotect SYMBOLIC(__NR_mprotect) +#define __NR_munmap SYMBOLIC(__NR_munmap) +#define __NR_sigaction SYMBOLIC(__NR_sigaction) +#define __NR_sigprocmask SYMBOLIC(__NR_sigprocmask) +#define __NR_ioctl SYMBOLIC(__NR_ioctl) +#define __NR_pread SYMBOLIC(__NR_pread) +#define __NR_pwrite SYMBOLIC(__NR_pwrite) +#define __NR_readv SYMBOLIC(__NR_readv) +#define __NR_writev SYMBOLIC(__NR_writev) +#define __NR_access SYMBOLIC(__NR_access) +#define __NR_pipe SYMBOLIC(__NR_pipe) +#define __NR_select SYMBOLIC(__NR_select) +#define __NR_pselect SYMBOLIC(__NR_pselect) +#define __NR_pselect6 SYMBOLIC(__NR_pselect6) +#define __NR_sched_yield SYMBOLIC(__NR_sched_yield) +#define __NR_mremap SYMBOLIC(__NR_mremap) +#define __NR_mincore SYMBOLIC(__NR_mincore) +#define __NR_madvise SYMBOLIC(__NR_madvise) +#define __NR_shmget SYMBOLIC(__NR_shmget) +#define __NR_shmat SYMBOLIC(__NR_shmat) +#define __NR_shmctl SYMBOLIC(__NR_shmctl) +#define __NR_dup SYMBOLIC(__NR_dup) +#define __NR_dup2 SYMBOLIC(__NR_dup2) +#define __NR_pause SYMBOLIC(__NR_pause) +#define __NR_nanosleep SYMBOLIC(__NR_nanosleep) +#define __NR_getitimer SYMBOLIC(__NR_getitimer) +#define __NR_setitimer SYMBOLIC(__NR_setitimer) +#define __NR_alarm SYMBOLIC(__NR_alarm) +#define __NR_getpid SYMBOLIC(__NR_getpid) +#define __NR_sendfile SYMBOLIC(__NR_sendfile) +#define __NR_socket SYMBOLIC(__NR_socket) +#define __NR_connect SYMBOLIC(__NR_connect) +#define __NR_accept SYMBOLIC(__NR_accept) +#define __NR_sendto SYMBOLIC(__NR_sendto) +#define __NR_recvfrom SYMBOLIC(__NR_recvfrom) +#define __NR_sendmsg SYMBOLIC(__NR_sendmsg) +#define __NR_recvmsg SYMBOLIC(__NR_recvmsg) +#define __NR_shutdown SYMBOLIC(__NR_shutdown) +#define __NR_bind SYMBOLIC(__NR_bind) +#define __NR_listen SYMBOLIC(__NR_listen) +#define __NR_getsockname SYMBOLIC(__NR_getsockname) +#define __NR_getpeername SYMBOLIC(__NR_getpeername) +#define __NR_socketpair SYMBOLIC(__NR_socketpair) +#define __NR_setsockopt SYMBOLIC(__NR_setsockopt) +#define __NR_getsockopt SYMBOLIC(__NR_getsockopt) +#define __NR_fork SYMBOLIC(__NR_fork) +#define __NR_vfork SYMBOLIC(__NR_vfork) +#define __NR_posix_spawn SYMBOLIC(__NR_posix_spawn) +#define __NR_execve LITERALLY(0x003b) +#define __NR_wait4 SYMBOLIC(__NR_wait4) +#define __NR_kill SYMBOLIC(__NR_kill) +#define __NR_killpg SYMBOLIC(__NR_killpg) +#define __NR_clone SYMBOLIC(__NR_clone) +#define __NR_tkill SYMBOLIC(__NR_tkill) +#define __NR_futex SYMBOLIC(__NR_futex) +#define __NR_set_robust_list SYMBOLIC(__NR_set_robust_list) +#define __NR_get_robust_list SYMBOLIC(__NR_get_robust_list) +#define __NR_uname SYMBOLIC(__NR_uname) +#define __NR_semget SYMBOLIC(__NR_semget) +#define __NR_semop SYMBOLIC(__NR_semop) +#define __NR_semctl SYMBOLIC(__NR_semctl) +#define __NR_shmdt SYMBOLIC(__NR_shmdt) +#define __NR_msgget SYMBOLIC(__NR_msgget) +#define __NR_msgsnd SYMBOLIC(__NR_msgsnd) +#define __NR_msgrcv SYMBOLIC(__NR_msgrcv) +#define __NR_msgctl SYMBOLIC(__NR_msgctl) +#define __NR_fcntl SYMBOLIC(__NR_fcntl) +#define __NR_flock SYMBOLIC(__NR_flock) +#define __NR_fsync SYMBOLIC(__NR_fsync) +#define __NR_fdatasync SYMBOLIC(__NR_fdatasync) +#define __NR_truncate SYMBOLIC(__NR_truncate) +#define __NR_ftruncate SYMBOLIC(__NR_ftruncate) +#define __NR_getcwd SYMBOLIC(__NR_getcwd) +#define __NR_chdir SYMBOLIC(__NR_chdir) +#define __NR_fchdir SYMBOLIC(__NR_fchdir) +#define __NR_rename SYMBOLIC(__NR_rename) +#define __NR_mkdir SYMBOLIC(__NR_mkdir) +#define __NR_rmdir SYMBOLIC(__NR_rmdir) +#define __NR_creat SYMBOLIC(__NR_creat) +#define __NR_link SYMBOLIC(__NR_link) +#define __NR_unlink SYMBOLIC(__NR_unlink) +#define __NR_symlink SYMBOLIC(__NR_symlink) +#define __NR_readlink SYMBOLIC(__NR_readlink) +#define __NR_chmod SYMBOLIC(__NR_chmod) +#define __NR_fchmod SYMBOLIC(__NR_fchmod) +#define __NR_chown SYMBOLIC(__NR_chown) +#define __NR_fchown SYMBOLIC(__NR_fchown) +#define __NR_lchown SYMBOLIC(__NR_lchown) +#define __NR_umask SYMBOLIC(__NR_umask) +#define __NR_gettimeofday SYMBOLIC(__NR_gettimeofday) +#define __NR_getrlimit SYMBOLIC(__NR_getrlimit) +#define __NR_getrusage SYMBOLIC(__NR_getrusage) +#define __NR_sysinfo SYMBOLIC(__NR_sysinfo) +#define __NR_times SYMBOLIC(__NR_times) +#define __NR_ptrace SYMBOLIC(__NR_ptrace) +#define __NR_syslog SYMBOLIC(__NR_syslog) +#define __NR_getuid SYMBOLIC(__NR_getuid) +#define __NR_getgid SYMBOLIC(__NR_getgid) +#define __NR_getppid SYMBOLIC(__NR_getppid) +#define __NR_getpgrp SYMBOLIC(__NR_getpgrp) +#define __NR_setsid SYMBOLIC(__NR_setsid) +#define __NR_getsid SYMBOLIC(__NR_getsid) +#define __NR_getpgid SYMBOLIC(__NR_getpgid) +#define __NR_setpgid SYMBOLIC(__NR_setpgid) +#define __NR_geteuid SYMBOLIC(__NR_geteuid) +#define __NR_getegid SYMBOLIC(__NR_getegid) +#define __NR_getgroups SYMBOLIC(__NR_getgroups) +#define __NR_setgroups SYMBOLIC(__NR_setgroups) +#define __NR_setreuid SYMBOLIC(__NR_setreuid) +#define __NR_setregid SYMBOLIC(__NR_setregid) +#define __NR_setuid SYMBOLIC(__NR_setuid) +#define __NR_setgid SYMBOLIC(__NR_setgid) +#define __NR_setresuid SYMBOLIC(__NR_setresuid) +#define __NR_setresgid SYMBOLIC(__NR_setresgid) +#define __NR_getresuid SYMBOLIC(__NR_getresuid) +#define __NR_getresgid SYMBOLIC(__NR_getresgid) +#define __NR_sigpending SYMBOLIC(__NR_sigpending) +#define __NR_sigsuspend SYMBOLIC(__NR_sigsuspend) +#define __NR_sigaltstack SYMBOLIC(__NR_sigaltstack) +#define __NR_mknod SYMBOLIC(__NR_mknod) +#define __NR_mknodat SYMBOLIC(__NR_mknodat) +#define __NR_mkfifo SYMBOLIC(__NR_mkfifo) +#define __NR_mkfifoat SYMBOLIC(__NR_mkfifoat) +#define __NR_statfs SYMBOLIC(__NR_statfs) +#define __NR_fstatfs SYMBOLIC(__NR_fstatfs) +#define __NR_getpriority SYMBOLIC(__NR_getpriority) +#define __NR_setpriority SYMBOLIC(__NR_setpriority) +#define __NR_mlock SYMBOLIC(__NR_mlock) +#define __NR_munlock SYMBOLIC(__NR_munlock) +#define __NR_mlockall SYMBOLIC(__NR_mlockall) +#define __NR_munlockall SYMBOLIC(__NR_munlockall) +#define __NR_setrlimit SYMBOLIC(__NR_setrlimit) +#define __NR_chroot SYMBOLIC(__NR_chroot) +#define __NR_sync SYMBOLIC(__NR_sync) +#define __NR_acct SYMBOLIC(__NR_acct) +#define __NR_settimeofday SYMBOLIC(__NR_settimeofday) +#define __NR_mount SYMBOLIC(__NR_mount) +#define __NR_reboot SYMBOLIC(__NR_reboot) +#define __NR_quotactl SYMBOLIC(__NR_quotactl) +#define __NR_setfsuid SYMBOLIC(__NR_setfsuid) +#define __NR_setfsgid SYMBOLIC(__NR_setfsgid) +#define __NR_capget SYMBOLIC(__NR_capget) +#define __NR_capset SYMBOLIC(__NR_capset) +#define __NR_sigtimedwait SYMBOLIC(__NR_sigtimedwait) +#define __NR_rt_sigqueueinfo SYMBOLIC(__NR_rt_sigqueueinfo) +#define __NR_personality SYMBOLIC(__NR_personality) +#define __NR_ustat SYMBOLIC(__NR_ustat) +#define __NR_sysfs SYMBOLIC(__NR_sysfs) +#define __NR_sched_setparam SYMBOLIC(__NR_sched_setparam) +#define __NR_sched_getparam SYMBOLIC(__NR_sched_getparam) +#define __NR_sched_setscheduler SYMBOLIC(__NR_sched_setscheduler) +#define __NR_sched_getscheduler SYMBOLIC(__NR_sched_getscheduler) +#define __NR_sched_get_priority_max SYMBOLIC(__NR_sched_get_priority_max) +#define __NR_sched_get_priority_min SYMBOLIC(__NR_sched_get_priority_min) +#define __NR_sched_rr_get_interval SYMBOLIC(__NR_sched_rr_get_interval) +#define __NR_vhangup SYMBOLIC(__NR_vhangup) +#define __NR_modify_ldt SYMBOLIC(__NR_modify_ldt) +#define __NR_pivot_root SYMBOLIC(__NR_pivot_root) +#define __NR__sysctl SYMBOLIC(__NR__sysctl) +#define __NR_prctl SYMBOLIC(__NR_prctl) +#define __NR_arch_prctl SYMBOLIC(__NR_arch_prctl) +#define __NR_adjtimex SYMBOLIC(__NR_adjtimex) +#define __NR_umount2 SYMBOLIC(__NR_umount2) +#define __NR_swapon SYMBOLIC(__NR_swapon) +#define __NR_swapoff SYMBOLIC(__NR_swapoff) +#define __NR_sethostname SYMBOLIC(__NR_sethostname) +#define __NR_setdomainname SYMBOLIC(__NR_setdomainname) +#define __NR_iopl SYMBOLIC(__NR_iopl) +#define __NR_ioperm SYMBOLIC(__NR_ioperm) +#define __NR_init_module SYMBOLIC(__NR_init_module) +#define __NR_delete_module SYMBOLIC(__NR_delete_module) +#define __NR_gettid SYMBOLIC(__NR_gettid) +#define __NR_readahead SYMBOLIC(__NR_readahead) +#define __NR_setxattr SYMBOLIC(__NR_setxattr) +#define __NR_fsetxattr SYMBOLIC(__NR_fsetxattr) +#define __NR_getxattr SYMBOLIC(__NR_getxattr) +#define __NR_fgetxattr SYMBOLIC(__NR_fgetxattr) +#define __NR_listxattr SYMBOLIC(__NR_listxattr) +#define __NR_flistxattr SYMBOLIC(__NR_flistxattr) +#define __NR_removexattr SYMBOLIC(__NR_removexattr) +#define __NR_fremovexattr SYMBOLIC(__NR_fremovexattr) +#define __NR_lsetxattr SYMBOLIC(__NR_lsetxattr) +#define __NR_lgetxattr SYMBOLIC(__NR_lgetxattr) +#define __NR_llistxattr SYMBOLIC(__NR_llistxattr) +#define __NR_lremovexattr SYMBOLIC(__NR_lremovexattr) +#define __NR_sched_setaffinity SYMBOLIC(__NR_sched_setaffinity) +#define __NR_sched_getaffinity SYMBOLIC(__NR_sched_getaffinity) +#define __NR_cpuset_getaffinity SYMBOLIC(__NR_cpuset_getaffinity) +#define __NR_cpuset_setaffinity SYMBOLIC(__NR_cpuset_setaffinity) +#define __NR_io_setup SYMBOLIC(__NR_io_setup) +#define __NR_io_destroy SYMBOLIC(__NR_io_destroy) +#define __NR_io_getevents SYMBOLIC(__NR_io_getevents) +#define __NR_io_submit SYMBOLIC(__NR_io_submit) +#define __NR_io_cancel SYMBOLIC(__NR_io_cancel) +#define __NR_lookup_dcookie SYMBOLIC(__NR_lookup_dcookie) +#define __NR_epoll_create SYMBOLIC(__NR_epoll_create) +#define __NR_epoll_wait SYMBOLIC(__NR_epoll_wait) +#define __NR_epoll_ctl SYMBOLIC(__NR_epoll_ctl) +#define __NR_getdents SYMBOLIC(__NR_getdents) +#define __NR_set_tid_address SYMBOLIC(__NR_set_tid_address) +#define __NR_restart_syscall SYMBOLIC(__NR_restart_syscall) +#define __NR_semtimedop SYMBOLIC(__NR_semtimedop) +#define __NR_fadvise SYMBOLIC(__NR_fadvise) +#define __NR_timer_create SYMBOLIC(__NR_timer_create) +#define __NR_timer_settime SYMBOLIC(__NR_timer_settime) +#define __NR_timer_gettime SYMBOLIC(__NR_timer_gettime) +#define __NR_timer_getoverrun SYMBOLIC(__NR_timer_getoverrun) +#define __NR_timer_delete SYMBOLIC(__NR_timer_delete) +#define __NR_clock_settime SYMBOLIC(__NR_clock_settime) +#define __NR_clock_gettime SYMBOLIC(__NR_clock_gettime) +#define __NR_clock_getres SYMBOLIC(__NR_clock_getres) +#define __NR_clock_nanosleep SYMBOLIC(__NR_clock_nanosleep) +#define __NR_tgkill SYMBOLIC(__NR_tgkill) +#define __NR_mbind SYMBOLIC(__NR_mbind) +#define __NR_set_mempolicy SYMBOLIC(__NR_set_mempolicy) +#define __NR_get_mempolicy SYMBOLIC(__NR_get_mempolicy) +#define __NR_mq_open SYMBOLIC(__NR_mq_open) +#define __NR_mq_unlink SYMBOLIC(__NR_mq_unlink) +#define __NR_mq_timedsend SYMBOLIC(__NR_mq_timedsend) +#define __NR_mq_timedreceive SYMBOLIC(__NR_mq_timedreceive) +#define __NR_mq_notify SYMBOLIC(__NR_mq_notify) +#define __NR_mq_getsetattr SYMBOLIC(__NR_mq_getsetattr) +#define __NR_kexec_load SYMBOLIC(__NR_kexec_load) +#define __NR_waitid SYMBOLIC(__NR_waitid) +#define __NR_add_key SYMBOLIC(__NR_add_key) +#define __NR_request_key SYMBOLIC(__NR_request_key) +#define __NR_keyctl SYMBOLIC(__NR_keyctl) +#define __NR_ioprio_set SYMBOLIC(__NR_ioprio_set) +#define __NR_ioprio_get SYMBOLIC(__NR_ioprio_get) +#define __NR_inotify_init SYMBOLIC(__NR_inotify_init) +#define __NR_inotify_add_watch SYMBOLIC(__NR_inotify_add_watch) +#define __NR_inotify_rm_watch SYMBOLIC(__NR_inotify_rm_watch) +#define __NR_openat SYMBOLIC(__NR_openat) +#define __NR_mkdirat SYMBOLIC(__NR_mkdirat) +#define __NR_fchownat SYMBOLIC(__NR_fchownat) +#define __NR_utime SYMBOLIC(__NR_utime) +#define __NR_utimes SYMBOLIC(__NR_utimes) +#define __NR_futimesat SYMBOLIC(__NR_futimesat) +#define __NR_futimes SYMBOLIC(__NR_futimes) +#define __NR_futimens SYMBOLIC(__NR_futimens) +#define __NR_fstatat SYMBOLIC(__NR_fstatat) +#define __NR_unlinkat SYMBOLIC(__NR_unlinkat) +#define __NR_renameat SYMBOLIC(__NR_renameat) +#define __NR_linkat SYMBOLIC(__NR_linkat) +#define __NR_symlinkat SYMBOLIC(__NR_symlinkat) +#define __NR_readlinkat SYMBOLIC(__NR_readlinkat) +#define __NR_fchmodat SYMBOLIC(__NR_fchmodat) +#define __NR_faccessat SYMBOLIC(__NR_faccessat) +#define __NR_unshare SYMBOLIC(__NR_unshare) +#define __NR_splice SYMBOLIC(__NR_splice) +#define __NR_tee SYMBOLIC(__NR_tee) +#define __NR_sync_file_range SYMBOLIC(__NR_sync_file_range) +#define __NR_vmsplice SYMBOLIC(__NR_vmsplice) +#define __NR_migrate_pages SYMBOLIC(__NR_migrate_pages) +#define __NR_move_pages SYMBOLIC(__NR_move_pages) +#define __NR_preadv SYMBOLIC(__NR_preadv) +#define __NR_pwritev SYMBOLIC(__NR_pwritev) +#define __NR_utimensat SYMBOLIC(__NR_utimensat) +#define __NR_fallocate SYMBOLIC(__NR_fallocate) +#define __NR_posix_fallocate SYMBOLIC(__NR_posix_fallocate) +#define __NR_accept4 SYMBOLIC(__NR_accept4) +#define __NR_dup3 SYMBOLIC(__NR_dup3) +#define __NR_pipe2 SYMBOLIC(__NR_pipe2) +#define __NR_epoll_pwait SYMBOLIC(__NR_epoll_pwait) +#define __NR_epoll_create1 SYMBOLIC(__NR_epoll_create1) +#define __NR_perf_event_open SYMBOLIC(__NR_perf_event_open) +#define __NR_inotify_init1 SYMBOLIC(__NR_inotify_init1) +#define __NR_rt_tgsigqueueinfo SYMBOLIC(__NR_rt_tgsigqueueinfo) +#define __NR_signalfd SYMBOLIC(__NR_signalfd) +#define __NR_signalfd4 SYMBOLIC(__NR_signalfd4) +#define __NR_eventfd SYMBOLIC(__NR_eventfd) +#define __NR_eventfd2 SYMBOLIC(__NR_eventfd2) +#define __NR_timerfd_create SYMBOLIC(__NR_timerfd_create) +#define __NR_timerfd_settime SYMBOLIC(__NR_timerfd_settime) +#define __NR_timerfd_gettime SYMBOLIC(__NR_timerfd_gettime) +#define __NR_recvmmsg SYMBOLIC(__NR_recvmmsg) +#define __NR_fanotify_init SYMBOLIC(__NR_fanotify_init) +#define __NR_fanotify_mark SYMBOLIC(__NR_fanotify_mark) +#define __NR_prlimit SYMBOLIC(__NR_prlimit) +#define __NR_name_to_handle_at SYMBOLIC(__NR_name_to_handle_at) +#define __NR_open_by_handle_at SYMBOLIC(__NR_open_by_handle_at) +#define __NR_clock_adjtime SYMBOLIC(__NR_clock_adjtime) +#define __NR_syncfs SYMBOLIC(__NR_syncfs) +#define __NR_sendmmsg SYMBOLIC(__NR_sendmmsg) +#define __NR_setns SYMBOLIC(__NR_setns) +#define __NR_getcpu SYMBOLIC(__NR_getcpu) +#define __NR_process_vm_readv SYMBOLIC(__NR_process_vm_readv) +#define __NR_process_vm_writev SYMBOLIC(__NR_process_vm_writev) +#define __NR_kcmp SYMBOLIC(__NR_kcmp) +#define __NR_finit_module SYMBOLIC(__NR_finit_module) +#define __NR_sched_setattr SYMBOLIC(__NR_sched_setattr) +#define __NR_sched_getattr SYMBOLIC(__NR_sched_getattr) +#define __NR_renameat2 SYMBOLIC(__NR_renameat2) +#define __NR_seccomp SYMBOLIC(__NR_seccomp) +#define __NR_getrandom SYMBOLIC(__NR_getrandom) +#define __NR_memfd_create SYMBOLIC(__NR_memfd_create) +#define __NR_kexec_file_load SYMBOLIC(__NR_kexec_file_load) +#define __NR_bpf SYMBOLIC(__NR_bpf) +#define __NR_execveat SYMBOLIC(__NR_execveat) +#define __NR_userfaultfd SYMBOLIC(__NR_userfaultfd) +#define __NR_membarrier SYMBOLIC(__NR_membarrier) +#define __NR_mlock2 SYMBOLIC(__NR_mlock2) +#define __NR_copy_file_range SYMBOLIC(__NR_copy_file_range) +#define __NR_preadv2 SYMBOLIC(__NR_preadv2) +#define __NR_pwritev2 SYMBOLIC(__NR_pwritev2) +#define __NR_pkey_mprotect SYMBOLIC(__NR_pkey_mprotect) +#define __NR_pkey_alloc SYMBOLIC(__NR_pkey_alloc) +#define __NR_pkey_free SYMBOLIC(__NR_pkey_free) +#define __NR_statx SYMBOLIC(__NR_statx) +#define __NR_io_pgetevents SYMBOLIC(__NR_io_pgetevents) +#define __NR_rseq SYMBOLIC(__NR_rseq) +#define __NR_pidfd_send_signal SYMBOLIC(__NR_pidfd_send_signal) +#define __NR_io_uring_setup SYMBOLIC(__NR_io_uring_setup) +#define __NR_io_uring_enter SYMBOLIC(__NR_io_uring_enter) +#define __NR_io_uring_register SYMBOLIC(__NR_io_uring_register) +#define __NR_pledge SYMBOLIC(__NR_pledge) +#define __NR_msyscall SYMBOLIC(__NR_msyscall) +#define __NR_ktrace SYMBOLIC(__NR_ktrace) +#define __NR_kqueue SYMBOLIC(__NR_kqueue) +#define __NR_kevent SYMBOLIC(__NR_kevent) +#define __NR_revoke SYMBOLIC(__NR_revoke) +#define __NR_setlogin SYMBOLIC(__NR_setlogin) +#define __NR_getfh SYMBOLIC(__NR_getfh) +#define __NR_chflags SYMBOLIC(__NR_chflags) +#define __NR_getfsstat SYMBOLIC(__NR_getfsstat) +#define __NR_nfssvc SYMBOLIC(__NR_nfssvc) +#define __NR_adjtime SYMBOLIC(__NR_adjtime) +#define __NR_fchflags SYMBOLIC(__NR_fchflags) +#define __NR_seteuid SYMBOLIC(__NR_seteuid) +#define __NR_setegid SYMBOLIC(__NR_setegid) +#define __NR_fpathconf SYMBOLIC(__NR_fpathconf) +#define __NR_fhopen SYMBOLIC(__NR_fhopen) +#define __NR_unmount SYMBOLIC(__NR_unmount) +#define __NR_issetugid SYMBOLIC(__NR_issetugid) +#define __NR_minherit SYMBOLIC(__NR_minherit) +#define __NR_pathconf SYMBOLIC(__NR_pathconf) +#define __NR_sysctl SYMBOLIC(__NR_sysctl) +#define __NR_ntp_adjtime SYMBOLIC(__NR_ntp_adjtime) +#define __NR_ntp_gettime SYMBOLIC(__NR_ntp_gettime) +#define __NR_shm_unlink SYMBOLIC(__NR_shm_unlink) +#define __NR_shm_open SYMBOLIC(__NR_shm_open) +#define __NR_aio_read SYMBOLIC(__NR_aio_read) +#define __NR_aio_suspend SYMBOLIC(__NR_aio_suspend) +#define __NR_aio_cancel SYMBOLIC(__NR_aio_cancel) +#define __NR_aio_fsync SYMBOLIC(__NR_aio_fsync) +#define __NR_aio_error SYMBOLIC(__NR_aio_error) +#define __NR_aio_return SYMBOLIC(__NR_aio_return) +#define __NR_aio_write SYMBOLIC(__NR_aio_write) +#define __NR_aio_waitcomplete SYMBOLIC(__NR_aio_waitcomplete) +#define __NR_aio_suspend_nocancel SYMBOLIC(__NR_aio_suspend_nocancel) +#define __NR_aio_mlock SYMBOLIC(__NR_aio_mlock) +#define __NR_sigwait SYMBOLIC(__NR_sigwait) +#define __NR_undelete SYMBOLIC(__NR_undelete) +#define __NR_getlogin SYMBOLIC(__NR_getlogin) +#define __NR_getdtablesize SYMBOLIC(__NR_getdtablesize) +#define __NR_setauid SYMBOLIC(__NR_setauid) +#define __NR_audit SYMBOLIC(__NR_audit) +#define __NR_auditctl SYMBOLIC(__NR_auditctl) +#define __NR_getaudit_addr SYMBOLIC(__NR_getaudit_addr) +#define __NR_getdirentries SYMBOLIC(__NR_getdirentries) +#define __NR_lio_listio SYMBOLIC(__NR_lio_listio) +#define __NR_setaudit_addr SYMBOLIC(__NR_setaudit_addr) +#define __NR_getauid SYMBOLIC(__NR_getauid) +#define __NR_semsys SYMBOLIC(__NR_semsys) +#define __NR_auditon SYMBOLIC(__NR_auditon) +#define __NR_msgsys SYMBOLIC(__NR_msgsys) +#define __NR_shmsys SYMBOLIC(__NR_shmsys) +#define __NR_fhstat SYMBOLIC(__NR_fhstat) +#define __NR_chflagsat SYMBOLIC(__NR_chflagsat) +#define __NR_profil SYMBOLIC(__NR_profil) +#define __NR_fhstatfs SYMBOLIC(__NR_fhstatfs) +#define __NR_utrace SYMBOLIC(__NR_utrace) +#define __NR_closefrom SYMBOLIC(__NR_closefrom) +#define __NR_pthread_markcancel SYMBOLIC(__NR_pthread_markcancel) +#define __NR_pthread_kill SYMBOLIC(__NR_pthread_kill) +#define __NR_pthread_fchdir SYMBOLIC(__NR_pthread_fchdir) +#define __NR_pthread_sigmask SYMBOLIC(__NR_pthread_sigmask) +#define __NR_pthread_chdir SYMBOLIC(__NR_pthread_chdir) +#define __NR_pthread_canceled SYMBOLIC(__NR_pthread_canceled) +#define __NR_disable_threadsignal SYMBOLIC(__NR_disable_threadsignal) +#define __NR_abort_with_payload SYMBOLIC(__NR_abort_with_payload) +#define __NR_accept_nocancel SYMBOLIC(__NR_accept_nocancel) +#define __NR_access_extended SYMBOLIC(__NR_access_extended) +#define __NR_audit_session_join SYMBOLIC(__NR_audit_session_join) +#define __NR_audit_session_port SYMBOLIC(__NR_audit_session_port) +#define __NR_audit_session_self SYMBOLIC(__NR_audit_session_self) +#define __NR_bsdthread_create SYMBOLIC(__NR_bsdthread_create) +#define __NR_bsdthread_ctl SYMBOLIC(__NR_bsdthread_ctl) +#define __NR_bsdthread_register SYMBOLIC(__NR_bsdthread_register) +#define __NR_bsdthread_terminate SYMBOLIC(__NR_bsdthread_terminate) +#define __NR_change_fdguard_np SYMBOLIC(__NR_change_fdguard_np) +#define __NR_chmod_extended SYMBOLIC(__NR_chmod_extended) +#define __NR_clonefileat SYMBOLIC(__NR_clonefileat) +#define __NR_close_nocancel SYMBOLIC(__NR_close_nocancel) +#define __NR_coalition SYMBOLIC(__NR_coalition) +#define __NR_coalition_info SYMBOLIC(__NR_coalition_info) +#define __NR_connect_nocancel SYMBOLIC(__NR_connect_nocancel) +#define __NR_connectx SYMBOLIC(__NR_connectx) +#define __NR_copyfile SYMBOLIC(__NR_copyfile) +#define __NR_csops SYMBOLIC(__NR_csops) +#define __NR_csops_audittoken SYMBOLIC(__NR_csops_audittoken) +#define __NR_csrctl SYMBOLIC(__NR_csrctl) +#define __NR_delete SYMBOLIC(__NR_delete) +#define __NR_disconnectx SYMBOLIC(__NR_disconnectx) +#define __NR_exchangedata SYMBOLIC(__NR_exchangedata) +#define __NR_fchmod_extended SYMBOLIC(__NR_fchmod_extended) +#define __NR_fclonefileat SYMBOLIC(__NR_fclonefileat) +#define __NR_fcntl_nocancel SYMBOLIC(__NR_fcntl_nocancel) +#define __NR_ffsctl SYMBOLIC(__NR_ffsctl) +#define __NR_fgetattrlist SYMBOLIC(__NR_fgetattrlist) +#define __NR_fileport_makefd SYMBOLIC(__NR_fileport_makefd) +#define __NR_fileport_makeport SYMBOLIC(__NR_fileport_makeport) +#define __NR_fmount SYMBOLIC(__NR_fmount) +#define __NR_fs_snapshot SYMBOLIC(__NR_fs_snapshot) +#define __NR_fsctl SYMBOLIC(__NR_fsctl) +#define __NR_fsetattrlist SYMBOLIC(__NR_fsetattrlist) +#define __NR_fstat_extended SYMBOLIC(__NR_fstat_extended) +#define __NR_fsync_nocancel SYMBOLIC(__NR_fsync_nocancel) +#define __NR_getattrlist SYMBOLIC(__NR_getattrlist) +#define __NR_getattrlistat SYMBOLIC(__NR_getattrlistat) +#define __NR_getattrlistbulk SYMBOLIC(__NR_getattrlistbulk) +#define __NR_getdirentriesattr SYMBOLIC(__NR_getdirentriesattr) +#define __NR_gethostuuid SYMBOLIC(__NR_gethostuuid) +#define __NR_getsgroups SYMBOLIC(__NR_getsgroups) +#define __NR_getwgroups SYMBOLIC(__NR_getwgroups) +#define __NR_grab_pgo_data SYMBOLIC(__NR_grab_pgo_data) +#define __NR_guarded_close_np SYMBOLIC(__NR_guarded_close_np) +#define __NR_guarded_kqueue_np SYMBOLIC(__NR_guarded_kqueue_np) +#define __NR_guarded_open_np SYMBOLIC(__NR_guarded_open_np) +#define __NR_guarded_pwrite_np SYMBOLIC(__NR_guarded_pwrite_np) +#define __NR_guarded_write_np SYMBOLIC(__NR_guarded_write_np) +#define __NR_guarded_writev_np SYMBOLIC(__NR_guarded_writev_np) +#define __NR_identitysvc SYMBOLIC(__NR_identitysvc) +#define __NR_initgroups SYMBOLIC(__NR_initgroups) +#define __NR_iopolicysys SYMBOLIC(__NR_iopolicysys) +#define __NR_kas_info SYMBOLIC(__NR_kas_info) +#define __NR_kdebug_trace SYMBOLIC(__NR_kdebug_trace) +#define __NR_kdebug_trace_string SYMBOLIC(__NR_kdebug_trace_string) +#define __NR_kdebug_typefilter SYMBOLIC(__NR_kdebug_typefilter) +#define __NR_kevent_id SYMBOLIC(__NR_kevent_id) +#define __NR_kevent_qos SYMBOLIC(__NR_kevent_qos) +#define __NR_ledger SYMBOLIC(__NR_ledger) +#define __NR_lstat_extended SYMBOLIC(__NR_lstat_extended) +#define __NR_memorystatus_control SYMBOLIC(__NR_memorystatus_control) +#define __NR_memorystatus_get_level SYMBOLIC(__NR_memorystatus_get_level) +#define __NR_microstackshot SYMBOLIC(__NR_microstackshot) +#define __NR_mkdir_extended SYMBOLIC(__NR_mkdir_extended) +#define __NR_mkfifo_extended SYMBOLIC(__NR_mkfifo_extended) +#define __NR_modwatch SYMBOLIC(__NR_modwatch) +#define __NR_mremap_encrypted SYMBOLIC(__NR_mremap_encrypted) +#define __NR_msgrcv_nocancel SYMBOLIC(__NR_msgrcv_nocancel) +#define __NR_msgsnd_nocancel SYMBOLIC(__NR_msgsnd_nocancel) +#define __NR_msync_nocancel SYMBOLIC(__NR_msync_nocancel) +#define __NR_necp_client_action SYMBOLIC(__NR_necp_client_action) +#define __NR_necp_match_policy SYMBOLIC(__NR_necp_match_policy) +#define __NR_necp_open SYMBOLIC(__NR_necp_open) +#define __NR_necp_session_action SYMBOLIC(__NR_necp_session_action) +#define __NR_necp_session_open SYMBOLIC(__NR_necp_session_open) +#define __NR_net_qos_guideline SYMBOLIC(__NR_net_qos_guideline) +#define __NR_netagent_trigger SYMBOLIC(__NR_netagent_trigger) +#define __NR_nfsclnt SYMBOLIC(__NR_nfsclnt) +#define __NR_open_dprotected_np SYMBOLIC(__NR_open_dprotected_np) +#define __NR_open_extended SYMBOLIC(__NR_open_extended) +#define __NR_open_nocancel SYMBOLIC(__NR_open_nocancel) +#define __NR_openat_nocancel SYMBOLIC(__NR_openat_nocancel) +#define __NR_openbyid_np SYMBOLIC(__NR_openbyid_np) +#define __NR_os_fault_with_payload SYMBOLIC(__NR_os_fault_with_payload) +#define __NR_peeloff SYMBOLIC(__NR_peeloff) +#define __NR_persona SYMBOLIC(__NR_persona) +#define __NR_pid_hibernate SYMBOLIC(__NR_pid_hibernate) +#define __NR_pid_resume SYMBOLIC(__NR_pid_resume) +#define __NR_pid_shutdown_sockets SYMBOLIC(__NR_pid_shutdown_sockets) +#define __NR_pid_suspend SYMBOLIC(__NR_pid_suspend) +#define __NR_poll_nocancel SYMBOLIC(__NR_poll_nocancel) +#define __NR_pread_nocancel SYMBOLIC(__NR_pread_nocancel) +#define __NR_proc_info SYMBOLIC(__NR_proc_info) +#define __NR_proc_rlimit_control SYMBOLIC(__NR_proc_rlimit_control) +#define __NR_proc_trace_log SYMBOLIC(__NR_proc_trace_log) +#define __NR_proc_uuid_policy SYMBOLIC(__NR_proc_uuid_policy) +#define __NR_process_policy SYMBOLIC(__NR_process_policy) +#define __NR_pselect_nocancel SYMBOLIC(__NR_pselect_nocancel) +#define __NR_psynch_cvbroad SYMBOLIC(__NR_psynch_cvbroad) +#define __NR_psynch_cvclrprepost SYMBOLIC(__NR_psynch_cvclrprepost) +#define __NR_psynch_cvsignal SYMBOLIC(__NR_psynch_cvsignal) +#define __NR_psynch_mutexdrop SYMBOLIC(__NR_psynch_mutexdrop) +#define __NR_psynch_mutexwait SYMBOLIC(__NR_psynch_mutexwait) +#define __NR_psynch_rw_downgrade SYMBOLIC(__NR_psynch_rw_downgrade) +#define __NR_psynch_rw_longrdlock SYMBOLIC(__NR_psynch_rw_longrdlock) +#define __NR_psynch_rw_rdlock SYMBOLIC(__NR_psynch_rw_rdlock) +#define __NR_psynch_rw_unlock SYMBOLIC(__NR_psynch_rw_unlock) +#define __NR_psynch_rw_unlock2 SYMBOLIC(__NR_psynch_rw_unlock2) +#define __NR_psynch_rw_upgrade SYMBOLIC(__NR_psynch_rw_upgrade) +#define __NR_psynch_rw_wrlock SYMBOLIC(__NR_psynch_rw_wrlock) +#define __NR_psynch_rw_yieldwrlock SYMBOLIC(__NR_psynch_rw_yieldwrlock) +#define __NR_pwrite_nocancel SYMBOLIC(__NR_pwrite_nocancel) +#define __NR_read_nocancel SYMBOLIC(__NR_read_nocancel) +#define __NR_readv_nocancel SYMBOLIC(__NR_readv_nocancel) +#define __NR_recvfrom_nocancel SYMBOLIC(__NR_recvfrom_nocancel) +#define __NR_recvmsg_nocancel SYMBOLIC(__NR_recvmsg_nocancel) +#define __NR_recvmsg_x SYMBOLIC(__NR_recvmsg_x) +#define __NR_renameatx_np SYMBOLIC(__NR_renameatx_np) +#define __NR_searchfs SYMBOLIC(__NR_searchfs) +#define __NR_select_nocancel SYMBOLIC(__NR_select_nocancel) +#define __NR_sem_close SYMBOLIC(__NR_sem_close) +#define __NR_sem_open SYMBOLIC(__NR_sem_open) +#define __NR_sem_post SYMBOLIC(__NR_sem_post) +#define __NR_sem_trywait SYMBOLIC(__NR_sem_trywait) +#define __NR_sem_unlink SYMBOLIC(__NR_sem_unlink) +#define __NR_sem_wait SYMBOLIC(__NR_sem_wait) +#define __NR_sem_wait_nocancel SYMBOLIC(__NR_sem_wait_nocancel) +#define __NR_sendmsg_nocancel SYMBOLIC(__NR_sendmsg_nocancel) +#define __NR_sendmsg_x SYMBOLIC(__NR_sendmsg_x) +#define __NR_sendto_nocancel SYMBOLIC(__NR_sendto_nocancel) +#define __NR_setattrlist SYMBOLIC(__NR_setattrlist) +#define __NR_setattrlistat SYMBOLIC(__NR_setattrlistat) +#define __NR_setprivexec SYMBOLIC(__NR_setprivexec) +#define __NR_setsgroups SYMBOLIC(__NR_setsgroups) +#define __NR_settid SYMBOLIC(__NR_settid) +#define __NR_settid_with_pid SYMBOLIC(__NR_settid_with_pid) +#define __NR_setwgroups SYMBOLIC(__NR_setwgroups) +#define __NR_sfi_ctl SYMBOLIC(__NR_sfi_ctl) +#define __NR_sfi_pidctl SYMBOLIC(__NR_sfi_pidctl) +#define __NR_shared_region_check_np SYMBOLIC(__NR_shared_region_check_np) +#define __NR_sigsuspend_nocancel SYMBOLIC(__NR_sigsuspend_nocancel) +#define __NR_socket_delegate SYMBOLIC(__NR_socket_delegate) +#define __NR_stat_extended SYMBOLIC(__NR_stat_extended) +#define __NR_sysctlbyname SYMBOLIC(__NR_sysctlbyname) +#define __NR_system_override SYMBOLIC(__NR_system_override) +#define __NR_telemetry SYMBOLIC(__NR_telemetry) +#define __NR_terminate_with_payload SYMBOLIC(__NR_terminate_with_payload) +#define __NR_thread_selfcounts SYMBOLIC(__NR_thread_selfcounts) +#define __NR_thread_selfid SYMBOLIC(__NR_thread_selfid) +#define __NR_thread_selfusage SYMBOLIC(__NR_thread_selfusage) +#define __NR_ulock_wait SYMBOLIC(__NR_ulock_wait) +#define __NR_ulock_wake SYMBOLIC(__NR_ulock_wake) +#define __NR_umask_extended SYMBOLIC(__NR_umask_extended) +#define __NR_usrctl SYMBOLIC(__NR_usrctl) +#define __NR_vfs_purge SYMBOLIC(__NR_vfs_purge) +#define __NR_vm_pressure_monitor SYMBOLIC(__NR_vm_pressure_monitor) +#define __NR_wait4_nocancel SYMBOLIC(__NR_wait4_nocancel) +#define __NR_waitevent SYMBOLIC(__NR_waitevent) +#define __NR_waitid_nocancel SYMBOLIC(__NR_waitid_nocancel) +#define __NR_watchevent SYMBOLIC(__NR_watchevent) +#define __NR_work_interval_ctl SYMBOLIC(__NR_work_interval_ctl) +#define __NR_workq_kernreturn SYMBOLIC(__NR_workq_kernreturn) +#define __NR_workq_open SYMBOLIC(__NR_workq_open) +#define __NR_write_nocancel SYMBOLIC(__NR_write_nocancel) +#define __NR_writev_nocancel SYMBOLIC(__NR_writev_nocancel) +#define __NR_abort2 SYMBOLIC(__NR_abort2) +#define __NR_afs3_syscall SYMBOLIC(__NR_afs3_syscall) +#define __NR_bindat SYMBOLIC(__NR_bindat) +#define __NR_break SYMBOLIC(__NR_break) +#define __NR_cap_enter SYMBOLIC(__NR_cap_enter) +#define __NR_cap_fcntls_get SYMBOLIC(__NR_cap_fcntls_get) +#define __NR_cap_fcntls_limit SYMBOLIC(__NR_cap_fcntls_limit) +#define __NR_cap_getmode SYMBOLIC(__NR_cap_getmode) +#define __NR_cap_ioctls_get SYMBOLIC(__NR_cap_ioctls_get) +#define __NR_cap_ioctls_limit SYMBOLIC(__NR_cap_ioctls_limit) +#define __NR_cap_rights_limit SYMBOLIC(__NR_cap_rights_limit) +#define __NR_clock_getcpuclockid2 SYMBOLIC(__NR_clock_getcpuclockid2) +#define __NR_connectat SYMBOLIC(__NR_connectat) +#define __NR_cpuset SYMBOLIC(__NR_cpuset) +#define __NR_cpuset_getdomain SYMBOLIC(__NR_cpuset_getdomain) +#define __NR_cpuset_getid SYMBOLIC(__NR_cpuset_getid) +#define __NR_cpuset_setdomain SYMBOLIC(__NR_cpuset_setdomain) +#define __NR_cpuset_setid SYMBOLIC(__NR_cpuset_setid) +#define __NR_eaccess SYMBOLIC(__NR_eaccess) +#define __NR_extattr_delete_fd SYMBOLIC(__NR_extattr_delete_fd) +#define __NR_extattr_delete_file SYMBOLIC(__NR_extattr_delete_file) +#define __NR_extattr_delete_link SYMBOLIC(__NR_extattr_delete_link) +#define __NR_extattr_get_fd SYMBOLIC(__NR_extattr_get_fd) +#define __NR_extattr_get_file SYMBOLIC(__NR_extattr_get_file) +#define __NR_extattr_get_link SYMBOLIC(__NR_extattr_get_link) +#define __NR_extattr_list_fd SYMBOLIC(__NR_extattr_list_fd) +#define __NR_extattr_list_file SYMBOLIC(__NR_extattr_list_file) +#define __NR_extattr_list_link SYMBOLIC(__NR_extattr_list_link) +#define __NR_extattr_set_fd SYMBOLIC(__NR_extattr_set_fd) +#define __NR_extattr_set_file SYMBOLIC(__NR_extattr_set_file) +#define __NR_extattr_set_link SYMBOLIC(__NR_extattr_set_link) +#define __NR_extattrctl SYMBOLIC(__NR_extattrctl) +#define __NR_fexecve SYMBOLIC(__NR_fexecve) +#define __NR_ffclock_getcounter SYMBOLIC(__NR_ffclock_getcounter) +#define __NR_ffclock_getestimate SYMBOLIC(__NR_ffclock_getestimate) +#define __NR_ffclock_setestimate SYMBOLIC(__NR_ffclock_setestimate) +#define __NR_fhlink SYMBOLIC(__NR_fhlink) +#define __NR_fhlinkat SYMBOLIC(__NR_fhlinkat) +#define __NR_fhreadlink SYMBOLIC(__NR_fhreadlink) +#define __NR_getaudit SYMBOLIC(__NR_getaudit) +#define __NR_getcontext SYMBOLIC(__NR_getcontext) +#define __NR_getfhat SYMBOLIC(__NR_getfhat) +#define __NR_gethostid SYMBOLIC(__NR_gethostid) +#define __NR_getkerninfo SYMBOLIC(__NR_getkerninfo) +#define __NR_getloginclass SYMBOLIC(__NR_getloginclass) +#define __NR_getpagesize SYMBOLIC(__NR_getpagesize) +#define __NR_gssd_syscall SYMBOLIC(__NR_gssd_syscall) +#define __NR_jail SYMBOLIC(__NR_jail) +#define __NR_jail_attach SYMBOLIC(__NR_jail_attach) +#define __NR_jail_get SYMBOLIC(__NR_jail_get) +#define __NR_jail_remove SYMBOLIC(__NR_jail_remove) +#define __NR_jail_set SYMBOLIC(__NR_jail_set) +#define __NR_kenv SYMBOLIC(__NR_kenv) +#define __NR_kldfind SYMBOLIC(__NR_kldfind) +#define __NR_kldfirstmod SYMBOLIC(__NR_kldfirstmod) +#define __NR_kldload SYMBOLIC(__NR_kldload) +#define __NR_kldnext SYMBOLIC(__NR_kldnext) +#define __NR_kldstat SYMBOLIC(__NR_kldstat) +#define __NR_kldsym SYMBOLIC(__NR_kldsym) +#define __NR_kldunload SYMBOLIC(__NR_kldunload) +#define __NR_kldunloadf SYMBOLIC(__NR_kldunloadf) +#define __NR_kmq_notify SYMBOLIC(__NR_kmq_notify) +#define __NR_kmq_setattr SYMBOLIC(__NR_kmq_setattr) +#define __NR_kmq_timedreceive SYMBOLIC(__NR_kmq_timedreceive) +#define __NR_kmq_timedsend SYMBOLIC(__NR_kmq_timedsend) +#define __NR_kmq_unlink SYMBOLIC(__NR_kmq_unlink) +#define __NR_ksem_close SYMBOLIC(__NR_ksem_close) +#define __NR_ksem_destroy SYMBOLIC(__NR_ksem_destroy) +#define __NR_ksem_getvalue SYMBOLIC(__NR_ksem_getvalue) +#define __NR_ksem_init SYMBOLIC(__NR_ksem_init) +#define __NR_ksem_open SYMBOLIC(__NR_ksem_open) +#define __NR_ksem_post SYMBOLIC(__NR_ksem_post) +#define __NR_ksem_timedwait SYMBOLIC(__NR_ksem_timedwait) +#define __NR_ksem_trywait SYMBOLIC(__NR_ksem_trywait) +#define __NR_ksem_unlink SYMBOLIC(__NR_ksem_unlink) +#define __NR_ksem_wait SYMBOLIC(__NR_ksem_wait) +#define __NR_ktimer_create SYMBOLIC(__NR_ktimer_create) +#define __NR_ktimer_delete SYMBOLIC(__NR_ktimer_delete) +#define __NR_ktimer_getoverrun SYMBOLIC(__NR_ktimer_getoverrun) +#define __NR_ktimer_gettime SYMBOLIC(__NR_ktimer_gettime) +#define __NR_ktimer_settime SYMBOLIC(__NR_ktimer_settime) +#define __NR_lchflags SYMBOLIC(__NR_lchflags) +#define __NR_lchmod SYMBOLIC(__NR_lchmod) +#define __NR_lgetfh SYMBOLIC(__NR_lgetfh) +#define __NR_lpathconf SYMBOLIC(__NR_lpathconf) +#define __NR_lutimes SYMBOLIC(__NR_lutimes) +#define __NR_mac_syscall SYMBOLIC(__NR_mac_syscall) +#define __NR_modfind SYMBOLIC(__NR_modfind) +#define __NR_modfnext SYMBOLIC(__NR_modfnext) +#define __NR_modnext SYMBOLIC(__NR_modnext) +#define __NR_modstat SYMBOLIC(__NR_modstat) +#define __NR_nfstat SYMBOLIC(__NR_nfstat) +#define __NR_nlm_syscall SYMBOLIC(__NR_nlm_syscall) +#define __NR_nlstat SYMBOLIC(__NR_nlstat) +#define __NR_nmount SYMBOLIC(__NR_nmount) +#define __NR_nnpfs_syscall SYMBOLIC(__NR_nnpfs_syscall) +#define __NR_nstat SYMBOLIC(__NR_nstat) +#define __NR_pdfork SYMBOLIC(__NR_pdfork) +#define __NR_pdgetpid SYMBOLIC(__NR_pdgetpid) +#define __NR_pdkill SYMBOLIC(__NR_pdkill) +#define __NR_posix_openpt SYMBOLIC(__NR_posix_openpt) +#define __NR_procctl SYMBOLIC(__NR_procctl) +#define __NR_psynch_cvwait SYMBOLIC(__NR_psynch_cvwait) +#define __NR_quota SYMBOLIC(__NR_quota) +#define __NR_rctl_add_rule SYMBOLIC(__NR_rctl_add_rule) +#define __NR_rctl_get_limits SYMBOLIC(__NR_rctl_get_limits) +#define __NR_rctl_get_racct SYMBOLIC(__NR_rctl_get_racct) +#define __NR_rctl_get_rules SYMBOLIC(__NR_rctl_get_rules) +#define __NR_rctl_remove_rule SYMBOLIC(__NR_rctl_remove_rule) +#define __NR_recv SYMBOLIC(__NR_recv) +#define __NR_rfork SYMBOLIC(__NR_rfork) +#define __NR_rtprio SYMBOLIC(__NR_rtprio) +#define __NR_rtprio_thread SYMBOLIC(__NR_rtprio_thread) +#define __NR_send SYMBOLIC(__NR_send) +#define __NR_setaudit SYMBOLIC(__NR_setaudit) +#define __NR_setcontext SYMBOLIC(__NR_setcontext) +#define __NR_setfib SYMBOLIC(__NR_setfib) +#define __NR_sethostid SYMBOLIC(__NR_sethostid) +#define __NR_setloginclass SYMBOLIC(__NR_setloginclass) +#define __NR_sigblock SYMBOLIC(__NR_sigblock) +#define __NR_sigqueue SYMBOLIC(__NR_sigqueue) +#define __NR_sigsetmask SYMBOLIC(__NR_sigsetmask) +#define __NR_sigstack SYMBOLIC(__NR_sigstack) +#define __NR_sigvec SYMBOLIC(__NR_sigvec) +#define __NR_sigwaitinfo SYMBOLIC(__NR_sigwaitinfo) +#define __NR_sstk SYMBOLIC(__NR_sstk) +#define __NR_swapcontext SYMBOLIC(__NR_swapcontext) +#define __NR_thr_create SYMBOLIC(__NR_thr_create) +#define __NR_thr_exit SYMBOLIC(__NR_thr_exit) +#define __NR_thr_kill SYMBOLIC(__NR_thr_kill) +#define __NR_thr_kill2 SYMBOLIC(__NR_thr_kill2) +#define __NR_thr_self SYMBOLIC(__NR_thr_self) +#define __NR_thr_set_name SYMBOLIC(__NR_thr_set_name) +#define __NR_thr_suspend SYMBOLIC(__NR_thr_suspend) +#define __NR_thr_wake SYMBOLIC(__NR_thr_wake) +#define __NR_uuidgen SYMBOLIC(__NR_uuidgen) +#define __NR_vadvise SYMBOLIC(__NR_vadvise) +#define __NR_wait SYMBOLIC(__NR_wait) +#define __NR_wait6 SYMBOLIC(__NR_wait6) +#define __NR_yield SYMBOLIC(__NR_yield) +#define __NR_tfork SYMBOLIC(__NR_tfork) +#define __NR_thrsleep SYMBOLIC(__NR_thrsleep) +#define __NR_thrwakeup SYMBOLIC(__NR_thrwakeup) +#define __NR_threxit SYMBOLIC(__NR_threxit) +#define __NR_thrsigdivert SYMBOLIC(__NR_thrsigdivert) +#define __NR_set_tcb SYMBOLIC(__NR_set_tcb) +#define __NR_get_tcb SYMBOLIC(__NR_get_tcb) +#define __NR_adjfreq SYMBOLIC(__NR_adjfreq) +#define __NR_getdtablecount SYMBOLIC(__NR_getdtablecount) +#define __NR_getlogin_r SYMBOLIC(__NR_getlogin_r) +#define __NR_getrtable SYMBOLIC(__NR_getrtable) +#define __NR_getthrid SYMBOLIC(__NR_getthrid) +#define __NR_kbind SYMBOLIC(__NR_kbind) +#define __NR_mquery SYMBOLIC(__NR_mquery) +#define __NR_obreak SYMBOLIC(__NR_obreak) +#define __NR_sendsyslog SYMBOLIC(__NR_sendsyslog) +#define __NR_setrtable SYMBOLIC(__NR_setrtable) +#define __NR_swapctl SYMBOLIC(__NR_swapctl) +#define __NR_thrkill SYMBOLIC(__NR_thrkill) +#define __NR_unveil SYMBOLIC(__NR_unveil) +#define __NR_mac_get_link SYMBOLIC(__NR_mac_get_link) +#define __NR_mac_set_link SYMBOLIC(__NR_mac_set_link) +#define __NR_mac_get_fd SYMBOLIC(__NR_mac_get_fd) +#define __NR_mac_get_file SYMBOLIC(__NR_mac_get_file) +#define __NR_mac_get_proc SYMBOLIC(__NR_mac_get_proc) +#define __NR_mac_set_fd SYMBOLIC(__NR_mac_set_fd) +#define __NR_mac_get_pid SYMBOLIC(__NR_mac_get_pid) +#define __NR_mac_set_proc SYMBOLIC(__NR_mac_set_proc) +#define __NR_mac_set_file SYMBOLIC(__NR_mac_set_file) +#define __NR_mac_execve SYMBOLIC(__NR_mac_execve) +#define __NR_acl_get_link SYMBOLIC(__NR_acl_get_link) +#define __NR_sigwait_nocancel SYMBOLIC(__NR_sigwait_nocancel) +#define __NR_cap_rights_get SYMBOLIC(__NR_cap_rights_get) +#define __NR_semwait_signal SYMBOLIC(__NR_semwait_signal) +#define __NR_acl_set_link SYMBOLIC(__NR_acl_set_link) +#define __NR_acl_set_fd SYMBOLIC(__NR_acl_set_fd) +#define __NR_old_semwait_signal SYMBOLIC(__NR_old_semwait_signal) +#define __NR_setugid SYMBOLIC(__NR_setugid) +#define __NR_acl_aclcheck_fd SYMBOLIC(__NR_acl_aclcheck_fd) +#define __NR_acl_get_fd SYMBOLIC(__NR_acl_get_fd) +#define __NR___sysctl SYMBOLIC(__NR___sysctl) +#define __NR_mac_getfsstat SYMBOLIC(__NR_mac_getfsstat) +#define __NR_mac_get_mount SYMBOLIC(__NR_mac_get_mount) +#define __NR_acl_delete_link SYMBOLIC(__NR_acl_delete_link) +#define __NR_mac_mount SYMBOLIC(__NR_mac_mount) +#define __NR_acl_get_file SYMBOLIC(__NR_acl_get_file) +#define __NR_acl_aclcheck_file SYMBOLIC(__NR_acl_aclcheck_file) +#define __NR_acl_delete_fd SYMBOLIC(__NR_acl_delete_fd) +#define __NR_acl_aclcheck_link SYMBOLIC(__NR_acl_aclcheck_link) +#define __NR___mac_syscall SYMBOLIC(__NR___mac_syscall) +#define __NR_acl_set_file SYMBOLIC(__NR_acl_set_file) +#define __NR_acl_delete_file SYMBOLIC(__NR_acl_delete_file) +#define __NR_syscall SYMBOLIC(__NR_syscall) +#define __NR__umtx_op SYMBOLIC(__NR__umtx_op) +#define __NR_semwait_signal_nocancel SYMBOLIC(__NR_semwait_signal_nocancel) +#define __NR_old_semwait_signal_nocancel \ + SYMBOLIC(__NR_old_semwait_signal_nocancel) +#define __NR_sctp_peeloff SYMBOLIC(__NR_sctp_peeloff) +#define __NR_sctp_generic_recvmsg SYMBOLIC(__NR_sctp_generic_recvmsg) +#define __NR_sctp_generic_sendmsg SYMBOLIC(__NR_sctp_generic_sendmsg) +#define __NR_sctp_generic_sendmsg_iov SYMBOLIC(__NR_sctp_generic_sendmsg_iov) +#define __NR_shared_region_map_and_slide_np \ + SYMBOLIC(__NR_shared_region_map_and_slide_np) +#define __NR_guarded_open_dprotected_np \ + SYMBOLIC(__NR_guarded_open_dprotected_np) +#define __NR_stack_snapshot_with_config \ + SYMBOLIC(__NR_stack_snapshot_with_config) + #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_NR_H_ */ diff --git a/libc/sysv/consts/nrlinux.h b/libc/sysv/consts/nrlinux.h new file mode 100644 index 000000000..59d6aa8e7 --- /dev/null +++ b/libc/sysv/consts/nrlinux.h @@ -0,0 +1,330 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_NRLINUX_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_NRLINUX_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define __NR_linux_exit 0x003c +#define __NR_linux_exit_group 0x00e7 +#define __NR_linux_read 0x0000 +#define __NR_linux_write 0x0001 +#define __NR_linux_open 0x0002 +#define __NR_linux_close 0x0003 +#define __NR_linux_stat 0x0004 +#define __NR_linux_fstat 0x0005 +#define __NR_linux_lstat 0x0006 +#define __NR_linux_poll 0x0007 +#define __NR_linux_ppoll 0x010f +#define __NR_linux_brk 0x000c +#define __NR_linux_sigreturn 0x000f +#define __NR_linux_lseek 0x0008 +#define __NR_linux_mmap 0x0009 +#define __NR_linux_msync 0x001a +#define __NR_linux_mprotect 0x000a +#define __NR_linux_munmap 0x000b +#define __NR_linux_sigaction 0x000d +#define __NR_linux_sigprocmask 0x000e +#define __NR_linux_ioctl 0x0010 +#define __NR_linux_pread 0x0011 +#define __NR_linux_pwrite 0x0012 +#define __NR_linux_readv 0x0013 +#define __NR_linux_writev 0x0014 +#define __NR_linux_access 0x0015 +#define __NR_linux_pipe 0x0016 +#define __NR_linux_select 0x0017 +#define __NR_linux_pselect6 0x010e +#define __NR_linux_sched_yield 0x0018 +#define __NR_linux_mremap 0x0019 +#define __NR_linux_mincore 0x001b +#define __NR_linux_madvise 0x001c +#define __NR_linux_shmget 0x001d +#define __NR_linux_shmat 0x001e +#define __NR_linux_shmctl 0x001f +#define __NR_linux_dup 0x0020 +#define __NR_linux_dup2 0x0021 +#define __NR_linux_pause 0x0022 +#define __NR_linux_nanosleep 0x0023 +#define __NR_linux_getitimer 0x0024 +#define __NR_linux_setitimer 0x0026 +#define __NR_linux_alarm 0x0025 +#define __NR_linux_getpid 0x0027 +#define __NR_linux_sendfile 0x0028 +#define __NR_linux_socket 0x0029 +#define __NR_linux_connect 0x002a +#define __NR_linux_accept 0x002b +#define __NR_linux_sendto 0x002c +#define __NR_linux_recvfrom 0x002d +#define __NR_linux_sendmsg 0x002e +#define __NR_linux_recvmsg 0x002f +#define __NR_linux_shutdown 0x0030 +#define __NR_linux_bind 0x0031 +#define __NR_linux_listen 0x0032 +#define __NR_linux_getsockname 0x0033 +#define __NR_linux_getpeername 0x0034 +#define __NR_linux_socketpair 0x0035 +#define __NR_linux_setsockopt 0x0036 +#define __NR_linux_getsockopt 0x0037 +#define __NR_linux_fork 0x0039 +#define __NR_linux_vfork 0x003a +#define __NR_linux_execve 0x003b +#define __NR_linux_wait4 0x003d +#define __NR_linux_kill 0x003e +#define __NR_linux_clone 0x0038 +#define __NR_linux_tkill 0x00c8 +#define __NR_linux_futex 0x00ca +#define __NR_linux_set_robust_list 0x0111 +#define __NR_linux_get_robust_list 0x0112 +#define __NR_linux_uname 0x003f +#define __NR_linux_semget 0x0040 +#define __NR_linux_semop 0x0041 +#define __NR_linux_semctl 0x0042 +#define __NR_linux_shmdt 0x0043 +#define __NR_linux_msgget 0x0044 +#define __NR_linux_msgsnd 0x0045 +#define __NR_linux_msgrcv 0x0046 +#define __NR_linux_msgctl 0x0047 +#define __NR_linux_fcntl 0x0048 +#define __NR_linux_flock 0x0049 +#define __NR_linux_fsync 0x004a +#define __NR_linux_fdatasync 0x004b +#define __NR_linux_truncate 0x004c +#define __NR_linux_ftruncate 0x004d +#define __NR_linux_getcwd 0x004f +#define __NR_linux_chdir 0x0050 +#define __NR_linux_fchdir 0x0051 +#define __NR_linux_rename 0x0052 +#define __NR_linux_mkdir 0x0053 +#define __NR_linux_rmdir 0x0054 +#define __NR_linux_creat 0x0055 +#define __NR_linux_link 0x0056 +#define __NR_linux_unlink 0x0057 +#define __NR_linux_symlink 0x0058 +#define __NR_linux_readlink 0x0059 +#define __NR_linux_chmod 0x005a +#define __NR_linux_fchmod 0x005b +#define __NR_linux_chown 0x005c +#define __NR_linux_fchown 0x005d +#define __NR_linux_lchown 0x005e +#define __NR_linux_umask 0x005f +#define __NR_linux_gettimeofday 0x0060 +#define __NR_linux_getrlimit 0x0061 +#define __NR_linux_getrusage 0x0062 +#define __NR_linux_sysinfo 0x0063 +#define __NR_linux_times 0x0064 +#define __NR_linux_ptrace 0x0065 +#define __NR_linux_syslog 0x0067 +#define __NR_linux_getuid 0x0066 +#define __NR_linux_getgid 0x0068 +#define __NR_linux_getppid 0x006e +#define __NR_linux_getpgrp 0x006f +#define __NR_linux_setsid 0x0070 +#define __NR_linux_getsid 0x007c +#define __NR_linux_getpgid 0x0079 +#define __NR_linux_setpgid 0x006d +#define __NR_linux_geteuid 0x006b +#define __NR_linux_getegid 0x006c +#define __NR_linux_getgroups 0x0073 +#define __NR_linux_setgroups 0x0074 +#define __NR_linux_setreuid 0x0071 +#define __NR_linux_setregid 0x0072 +#define __NR_linux_setuid 0x0069 +#define __NR_linux_setgid 0x006a +#define __NR_linux_setresuid 0x0075 +#define __NR_linux_setresgid 0x0077 +#define __NR_linux_getresuid 0x0076 +#define __NR_linux_getresgid 0x0078 +#define __NR_linux_sigpending 0x007f +#define __NR_linux_sigsuspend 0x0082 +#define __NR_linux_sigaltstack 0x0083 +#define __NR_linux_mknod 0x0085 +#define __NR_linux_mknodat 0x0103 +#define __NR_linux_statfs 0x0089 +#define __NR_linux_fstatfs 0x008a +#define __NR_linux_getpriority 0x008c +#define __NR_linux_setpriority 0x008d +#define __NR_linux_mlock 0x0095 +#define __NR_linux_munlock 0x0096 +#define __NR_linux_mlockall 0x0097 +#define __NR_linux_munlockall 0x0098 +#define __NR_linux_setrlimit 0x00a0 +#define __NR_linux_chroot 0x00a1 +#define __NR_linux_sync 0x00a2 +#define __NR_linux_acct 0x00a3 +#define __NR_linux_settimeofday 0x00a4 +#define __NR_linux_mount 0x00a5 +#define __NR_linux_reboot 0x00a9 +#define __NR_linux_quotactl 0x00b3 +#define __NR_linux_setfsuid 0x007a +#define __NR_linux_setfsgid 0x007b +#define __NR_linux_capget 0x007d +#define __NR_linux_capset 0x007e +#define __NR_linux_sigtimedwait 0x0080 +#define __NR_linux_rt_sigqueueinfo 0x0081 +#define __NR_linux_personality 0x0087 +#define __NR_linux_ustat 0x0088 +#define __NR_linux_sysfs 0x008b +#define __NR_linux_sched_setparam 0x008e +#define __NR_linux_sched_getparam 0x008f +#define __NR_linux_sched_setscheduler 0x0090 +#define __NR_linux_sched_getscheduler 0x0091 +#define __NR_linux_sched_get_priority_max 0x0092 +#define __NR_linux_sched_get_priority_min 0x0093 +#define __NR_linux_sched_rr_get_interval 0x0094 +#define __NR_linux_vhangup 0x0099 +#define __NR_linux_modify_ldt 0x009a +#define __NR_linux_pivot_root 0x009b +#define __NR_linux__sysctl 0x009c +#define __NR_linux_prctl 0x009d +#define __NR_linux_arch_prctl 0x009e +#define __NR_linux_adjtimex 0x009f +#define __NR_linux_umount2 0x00a6 +#define __NR_linux_swapon 0x00a7 +#define __NR_linux_swapoff 0x00a8 +#define __NR_linux_sethostname 0x00aa +#define __NR_linux_setdomainname 0x00ab +#define __NR_linux_iopl 0x00ac +#define __NR_linux_ioperm 0x00ad +#define __NR_linux_init_module 0x00af +#define __NR_linux_delete_module 0x00b0 +#define __NR_linux_gettid 0x00ba +#define __NR_linux_readahead 0x00bb +#define __NR_linux_setxattr 0x00bc +#define __NR_linux_fsetxattr 0x00be +#define __NR_linux_getxattr 0x00bf +#define __NR_linux_fgetxattr 0x00c1 +#define __NR_linux_listxattr 0x00c2 +#define __NR_linux_flistxattr 0x00c4 +#define __NR_linux_removexattr 0x00c5 +#define __NR_linux_fremovexattr 0x00c7 +#define __NR_linux_lsetxattr 0x00bd +#define __NR_linux_lgetxattr 0x00c0 +#define __NR_linux_llistxattr 0x00c3 +#define __NR_linux_lremovexattr 0x00c6 +#define __NR_linux_sched_setaffinity 0x00cb +#define __NR_linux_sched_getaffinity 0x00cc +#define __NR_linux_io_setup 0x00ce +#define __NR_linux_io_destroy 0x00cf +#define __NR_linux_io_getevents 0x00d0 +#define __NR_linux_io_submit 0x00d1 +#define __NR_linux_io_cancel 0x00d2 +#define __NR_linux_lookup_dcookie 0x00d4 +#define __NR_linux_epoll_create 0x00d5 +#define __NR_linux_epoll_wait 0x00e8 +#define __NR_linux_epoll_ctl 0x00e9 +#define __NR_linux_getdents 0x00d9 +#define __NR_linux_set_tid_address 0x00da +#define __NR_linux_restart_syscall 0x00db +#define __NR_linux_semtimedop 0x00dc +#define __NR_linux_fadvise 0x00dd +#define __NR_linux_timer_create 0x00de +#define __NR_linux_timer_settime 0x00df +#define __NR_linux_timer_gettime 0x00e0 +#define __NR_linux_timer_getoverrun 0x00e1 +#define __NR_linux_timer_delete 0x00e2 +#define __NR_linux_clock_settime 0x00e3 +#define __NR_linux_clock_gettime 0x00e4 +#define __NR_linux_clock_getres 0x00e5 +#define __NR_linux_clock_nanosleep 0x00e6 +#define __NR_linux_tgkill 0x00ea +#define __NR_linux_mbind 0x00ed +#define __NR_linux_set_mempolicy 0x00ee +#define __NR_linux_get_mempolicy 0x00ef +#define __NR_linux_mq_open 0x00f0 +#define __NR_linux_mq_unlink 0x00f1 +#define __NR_linux_mq_timedsend 0x00f2 +#define __NR_linux_mq_timedreceive 0x00f3 +#define __NR_linux_mq_notify 0x00f4 +#define __NR_linux_mq_getsetattr 0x00f5 +#define __NR_linux_kexec_load 0x00f6 +#define __NR_linux_waitid 0x00f7 +#define __NR_linux_add_key 0x00f8 +#define __NR_linux_request_key 0x00f9 +#define __NR_linux_keyctl 0x00fa +#define __NR_linux_ioprio_set 0x00fb +#define __NR_linux_ioprio_get 0x00fc +#define __NR_linux_inotify_init 0x00fd +#define __NR_linux_inotify_add_watch 0x00fe +#define __NR_linux_inotify_rm_watch 0x00ff +#define __NR_linux_openat 0x0101 +#define __NR_linux_mkdirat 0x0102 +#define __NR_linux_fchownat 0x0104 +#define __NR_linux_utime 0x0084 +#define __NR_linux_utimes 0x00eb +#define __NR_linux_futimesat 0x0105 +#define __NR_linux_fstatat 0x0106 +#define __NR_linux_unlinkat 0x0107 +#define __NR_linux_renameat 0x0108 +#define __NR_linux_linkat 0x0109 +#define __NR_linux_symlinkat 0x010a +#define __NR_linux_readlinkat 0x010b +#define __NR_linux_fchmodat 0x010c +#define __NR_linux_faccessat 0x010d +#define __NR_linux_unshare 0x0110 +#define __NR_linux_splice 0x0113 +#define __NR_linux_tee 0x0114 +#define __NR_linux_sync_file_range 0x0115 +#define __NR_linux_vmsplice 0x0116 +#define __NR_linux_migrate_pages 0x0100 +#define __NR_linux_move_pages 0x0117 +#define __NR_linux_preadv 0x0127 +#define __NR_linux_pwritev 0x0128 +#define __NR_linux_utimensat 0x0118 +#define __NR_linux_fallocate 0x011d +#define __NR_linux_accept4 0x0120 +#define __NR_linux_dup3 0x0124 +#define __NR_linux_pipe2 0x0125 +#define __NR_linux_epoll_pwait 0x0119 +#define __NR_linux_epoll_create1 0x0123 +#define __NR_linux_perf_event_open 0x012a +#define __NR_linux_inotify_init1 0x0126 +#define __NR_linux_rt_tgsigqueueinfo 0x0129 +#define __NR_linux_signalfd 0x011a +#define __NR_linux_signalfd4 0x0121 +#define __NR_linux_eventfd 0x011c +#define __NR_linux_eventfd2 0x0122 +#define __NR_linux_timerfd_create 0x011b +#define __NR_linux_timerfd_settime 0x011e +#define __NR_linux_timerfd_gettime 0x011f +#define __NR_linux_recvmmsg 0x012b +#define __NR_linux_fanotify_init 0x012c +#define __NR_linux_fanotify_mark 0x012d +#define __NR_linux_prlimit 0x012e +#define __NR_linux_name_to_handle_at 0x012f +#define __NR_linux_open_by_handle_at 0x0130 +#define __NR_linux_clock_adjtime 0x0131 +#define __NR_linux_syncfs 0x0132 +#define __NR_linux_sendmmsg 0x0133 +#define __NR_linux_setns 0x0134 +#define __NR_linux_getcpu 0x0135 +#define __NR_linux_process_vm_readv 0x0136 +#define __NR_linux_process_vm_writev 0x0137 +#define __NR_linux_kcmp 0x0138 +#define __NR_linux_finit_module 0x0139 +#define __NR_linux_sched_setattr 0x013a +#define __NR_linux_sched_getattr 0x013b +#define __NR_linux_renameat2 0x013c +#define __NR_linux_seccomp 0x013d +#define __NR_linux_getrandom 0x013e +#define __NR_linux_memfd_create 0x013f +#define __NR_linux_kexec_file_load 0x0140 +#define __NR_linux_bpf 0x0141 +#define __NR_linux_execveat 0x0142 +#define __NR_linux_userfaultfd 0x0143 +#define __NR_linux_membarrier 0x0144 +#define __NR_linux_mlock2 0x0145 +#define __NR_linux_copy_file_range 0x0146 +#define __NR_linux_preadv2 0x0147 +#define __NR_linux_pwritev2 0x0148 +#define __NR_linux_pkey_mprotect 0x0149 +#define __NR_linux_pkey_alloc 0x014a +#define __NR_linux_pkey_free 0x014b +#define __NR_linux_statx 0x014c +#define __NR_linux_io_pgetevents 0x014d +#define __NR_linux_rseq 0x014e +#define __NR_linux_pidfd_send_signal 0x01a8 +#define __NR_linux_io_uring_setup 0x01a9 +#define __NR_linux_io_uring_enter 0x01aa +#define __NR_linux_io_uring_register 0x01ab + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_NRLINUX_H_ */ diff --git a/libc/sysv/consts/o.h b/libc/sysv/consts/o.h index fb996275f..175209255 100644 --- a/libc/sysv/consts/o.h +++ b/libc/sysv/consts/o.h @@ -4,47 +4,54 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern const long O_ACCMODE; -extern const long O_APPEND; -extern const long O_ASYNC; -extern const long O_CLOEXEC; -extern const long O_CREAT; -extern const long O_DIRECT; -extern const long O_DIRECTORY; -extern const long O_DSYNC; -extern const long O_EXCL; -extern const long O_EXEC; -extern const long O_EXLOCK; -extern const long O_LARGEFILE; -extern const long O_NDELAY; -extern const long O_NOATIME; -extern const long O_NOCTTY; -extern const long O_NOFOLLOW; -extern const long O_NOFOLLOW_ANY; -extern const long O_NONBLOCK; -extern const long O_PATH; -extern const long O_RANDOM; -extern const long O_RDONLY; -extern const long O_RDWR; -extern const long O_RSYNC; -extern const long O_SEARCH; -extern const long O_SEQUENTIAL; -extern const long O_SHLOCK; -extern const long O_SPARSE; -extern const long O_SYNC; -extern const long O_TMPFILE; -extern const long O_TRUNC; -extern const long O_TTY_INIT; -extern const long O_VERIFY; -extern const long O_WRONLY; +extern const unsigned O_ACCMODE; +extern const unsigned O_APPEND; +extern const unsigned O_ASYNC; +extern const unsigned O_CLOEXEC; +extern const unsigned O_COMPRESSED; +extern const unsigned O_CREAT; +extern const unsigned O_DIRECT; +extern const unsigned O_DIRECTORY; +extern const unsigned O_DSYNC; +extern const unsigned O_EXCL; +extern const unsigned O_EXEC; +extern const unsigned O_EXLOCK; +extern const unsigned O_INDEXED; +extern const unsigned O_LARGEFILE; +extern const unsigned O_NDELAY; +extern const unsigned O_NOATIME; +extern const unsigned O_NOCTTY; +extern const unsigned O_NOFOLLOW; +extern const unsigned O_NOFOLLOW_ANY; +extern const unsigned O_NONBLOCK; +extern const unsigned O_PATH; +extern const unsigned O_RANDOM; +extern const unsigned O_RDONLY; +extern const unsigned O_RDWR; +extern const unsigned O_RSYNC; +extern const unsigned O_SEARCH; +extern const unsigned O_SEQUENTIAL; +extern const unsigned O_SHLOCK; +extern const unsigned O_SPARSE; +extern const unsigned O_SYNC; +extern const unsigned O_TMPFILE; +extern const unsigned O_TRUNC; +extern const unsigned O_TTY_INIT; +extern const unsigned O_VERIFY; +extern const unsigned O_WRONLY; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#define O_ACCMODE SYMBOLIC(O_ACCMODE) +#define O_RDONLY LITERALLY(0) +#define O_WRONLY LITERALLY(1) +#define O_RDWR LITERALLY(2) +#define O_ACCMODE LITERALLY(3) + #define O_APPEND SYMBOLIC(O_APPEND) #define O_ASYNC SYMBOLIC(O_ASYNC) #define O_CLOEXEC SYMBOLIC(O_CLOEXEC) +#define O_COMPRESSED SYMBOLIC(O_COMPRESSED) #define O_CREAT SYMBOLIC(O_CREAT) #define O_DIRECT SYMBOLIC(O_DIRECT) #define O_DIRECTORY SYMBOLIC(O_DIRECTORY) @@ -52,6 +59,7 @@ COSMOPOLITAN_C_END_ #define O_EXCL SYMBOLIC(O_EXCL) #define O_EXEC SYMBOLIC(O_EXEC) #define O_EXLOCK SYMBOLIC(O_EXLOCK) +#define O_INDEXED SYMBOLIC(O_INDEXED) #define O_LARGEFILE SYMBOLIC(O_LARGEFILE) #define O_NDELAY SYMBOLIC(O_NDELAY) #define O_NOATIME SYMBOLIC(O_NOATIME) @@ -61,8 +69,6 @@ COSMOPOLITAN_C_END_ #define O_NONBLOCK SYMBOLIC(O_NONBLOCK) #define O_PATH SYMBOLIC(O_PATH) #define O_RANDOM SYMBOLIC(O_RANDOM) -#define O_RDONLY SYMBOLIC(O_RDONLY) -#define O_RDWR SYMBOLIC(O_RDWR) #define O_RSYNC SYMBOLIC(O_RSYNC) #define O_SEARCH SYMBOLIC(O_SEARCH) #define O_SEQUENTIAL SYMBOLIC(O_SEQUENTIAL) @@ -73,6 +79,5 @@ COSMOPOLITAN_C_END_ #define O_TRUNC SYMBOLIC(O_TRUNC) #define O_TTY_INIT SYMBOLIC(O_TTY_INIT) #define O_VERIFY SYMBOLIC(O_VERIFY) -#define O_WRONLY SYMBOLIC(O_WRONLY) #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_O_H_ */ diff --git a/libc/sysv/consts/pr.h b/libc/sysv/consts/pr.h index 2e28b55ce..8fd8d471a 100644 --- a/libc/sysv/consts/pr.h +++ b/libc/sysv/consts/pr.h @@ -1,216 +1,102 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ -#include "libc/runtime/symbolic.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -extern const long PR_CAPBSET_DROP; -extern const long PR_CAPBSET_READ; -extern const long PR_CAP_AMBIENT; -extern const long PR_CAP_AMBIENT_CLEAR_ALL; -extern const long PR_CAP_AMBIENT_IS_SET; -extern const long PR_CAP_AMBIENT_LOWER; -extern const long PR_CAP_AMBIENT_RAISE; -extern const long PR_ENDIAN_BIG; -extern const long PR_ENDIAN_LITTLE; -extern const long PR_ENDIAN_PPC_LITTLE; -extern const long PR_FPEMU_NOPRINT; -extern const long PR_FPEMU_SIGFPE; -extern const long PR_FP_EXC_ASYNC; -extern const long PR_FP_EXC_DISABLED; -extern const long PR_FP_EXC_DIV; -extern const long PR_FP_EXC_INV; -extern const long PR_FP_EXC_NONRECOV; -extern const long PR_FP_EXC_OVF; -extern const long PR_FP_EXC_PRECISE; -extern const long PR_FP_EXC_RES; -extern const long PR_FP_EXC_SW_ENABLE; -extern const long PR_FP_EXC_UND; -extern const long PR_FP_MODE_FR; -extern const long PR_FP_MODE_FRE; -extern const long PR_GET_CHILD_SUBREAPER; -extern const long PR_GET_DUMPABLE; -extern const long PR_GET_ENDIAN; -extern const long PR_GET_FPEMU; -extern const long PR_GET_FPEXC; -extern const long PR_GET_FP_MODE; -extern const long PR_GET_KEEPCAPS; -extern const long PR_GET_NAME; -extern const long PR_GET_NO_NEW_PRIVS; -extern const long PR_GET_PDEATHSIG; -extern const long PR_GET_SECCOMP; -extern const long PR_GET_SECUREBITS; -extern const long PR_GET_SPECULATION_CTRL; -extern const long PR_GET_THP_DISABLE; -extern const long PR_GET_TID_ADDRESS; -extern const long PR_GET_TIMERSLACK; -extern const long PR_GET_TIMING; -extern const long PR_GET_TSC; -extern const long PR_GET_UNALIGN; -extern const long PR_MCE_KILL; -extern const long PR_MCE_KILL_CLEAR; -extern const long PR_MCE_KILL_DEFAULT; -extern const long PR_MCE_KILL_EARLY; -extern const long PR_MCE_KILL_GET; -extern const long PR_MCE_KILL_LATE; -extern const long PR_MCE_KILL_SET; -extern const long PR_MPX_DISABLE_MANAGEMENT; -extern const long PR_MPX_ENABLE_MANAGEMENT; -extern const long PR_SET_CHILD_SUBREAPER; -extern const long PR_SET_DUMPABLE; -extern const long PR_SET_ENDIAN; -extern const long PR_SET_FPEMU; -extern const long PR_SET_FPEXC; -extern const long PR_SET_FP_MODE; -extern const long PR_SET_KEEPCAPS; -extern const long PR_SET_MM; -extern const long PR_SET_MM_ARG_END; -extern const long PR_SET_MM_ARG_START; -extern const long PR_SET_MM_AUXV; -extern const long PR_SET_MM_BRK; -extern const long PR_SET_MM_END_CODE; -extern const long PR_SET_MM_END_DATA; -extern const long PR_SET_MM_ENV_END; -extern const long PR_SET_MM_ENV_START; -extern const long PR_SET_MM_EXE_FILE; -extern const long PR_SET_MM_MAP; -extern const long PR_SET_MM_MAP_SIZE; -extern const long PR_SET_MM_START_BRK; -extern const long PR_SET_MM_START_CODE; -extern const long PR_SET_MM_START_DATA; -extern const long PR_SET_MM_START_STACK; -extern const long PR_SET_NAME; -extern const long PR_SET_NO_NEW_PRIVS; -extern const long PR_SET_PDEATHSIG; -extern const long PR_SET_PTRACER; -extern const long PR_SET_PTRACER_ANY; -extern const long PR_SET_SECCOMP; -extern const long PR_SET_SECUREBITS; -extern const long PR_SET_SPECULATION_CTRL; -extern const long PR_SET_THP_DISABLE; -extern const long PR_SET_TIMERSLACK; -extern const long PR_SET_TIMING; -extern const long PR_SET_TSC; -extern const long PR_SET_UNALIGN; -extern const long PR_SPEC_DISABLE; -extern const long PR_SPEC_ENABLE; -extern const long PR_SPEC_FORCE_DISABLE; -extern const long PR_SPEC_NOT_AFFECTED; -extern const long PR_SPEC_PRCTL; -extern const long PR_SPEC_STORE_BYPASS; -extern const long PR_TASK_PERF_EVENTS_DISABLE; -extern const long PR_TASK_PERF_EVENTS_ENABLE; -extern const long PR_TIMING_STATISTICAL; -extern const long PR_TIMING_TIMESTAMP; -extern const long PR_TSC_ENABLE; -extern const long PR_TSC_SIGSEGV; -extern const long PR_UNALIGN_NOPRINT; -extern const long PR_UNALIGN_SIGBUS; +#define PR_GET_SECCOMP 21 +#define PR_SET_SECCOMP 22 +#define SECCOMP_MODE_DISABLED 0 +#define SECCOMP_MODE_STRICT 1 +#define SECCOMP_MODE_FILTER 2 -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#define PR_SET_NO_NEW_PRIVS 38 +#define PR_GET_NO_NEW_PRIVS 39 -#define PR_CAPBSET_DROP SYMBOLIC(PR_CAPBSET_DROP) -#define PR_CAPBSET_READ SYMBOLIC(PR_CAPBSET_READ) -#define PR_CAP_AMBIENT SYMBOLIC(PR_CAP_AMBIENT) -#define PR_CAP_AMBIENT_CLEAR_ALL SYMBOLIC(PR_CAP_AMBIENT_CLEAR_ALL) -#define PR_CAP_AMBIENT_IS_SET SYMBOLIC(PR_CAP_AMBIENT_IS_SET) -#define PR_CAP_AMBIENT_LOWER SYMBOLIC(PR_CAP_AMBIENT_LOWER) -#define PR_CAP_AMBIENT_RAISE SYMBOLIC(PR_CAP_AMBIENT_RAISE) -#define PR_ENDIAN_BIG SYMBOLIC(PR_ENDIAN_BIG) -#define PR_ENDIAN_LITTLE SYMBOLIC(PR_ENDIAN_LITTLE) -#define PR_ENDIAN_PPC_LITTLE SYMBOLIC(PR_ENDIAN_PPC_LITTLE) -#define PR_FPEMU_NOPRINT SYMBOLIC(PR_FPEMU_NOPRINT) -#define PR_FPEMU_SIGFPE SYMBOLIC(PR_FPEMU_SIGFPE) -#define PR_FP_EXC_ASYNC SYMBOLIC(PR_FP_EXC_ASYNC) -#define PR_FP_EXC_DISABLED SYMBOLIC(PR_FP_EXC_DISABLED) -#define PR_FP_EXC_DIV SYMBOLIC(PR_FP_EXC_DIV) -#define PR_FP_EXC_INV SYMBOLIC(PR_FP_EXC_INV) -#define PR_FP_EXC_NONRECOV SYMBOLIC(PR_FP_EXC_NONRECOV) -#define PR_FP_EXC_OVF SYMBOLIC(PR_FP_EXC_OVF) -#define PR_FP_EXC_PRECISE SYMBOLIC(PR_FP_EXC_PRECISE) -#define PR_FP_EXC_RES SYMBOLIC(PR_FP_EXC_RES) -#define PR_FP_EXC_SW_ENABLE SYMBOLIC(PR_FP_EXC_SW_ENABLE) -#define PR_FP_EXC_UND SYMBOLIC(PR_FP_EXC_UND) -#define PR_FP_MODE_FR SYMBOLIC(PR_FP_MODE_FR) -#define PR_FP_MODE_FRE SYMBOLIC(PR_FP_MODE_FRE) -#define PR_GET_CHILD_SUBREAPER SYMBOLIC(PR_GET_CHILD_SUBREAPER) -#define PR_GET_DUMPABLE SYMBOLIC(PR_GET_DUMPABLE) -#define PR_GET_ENDIAN SYMBOLIC(PR_GET_ENDIAN) -#define PR_GET_FPEMU SYMBOLIC(PR_GET_FPEMU) -#define PR_GET_FPEXC SYMBOLIC(PR_GET_FPEXC) -#define PR_GET_FP_MODE SYMBOLIC(PR_GET_FP_MODE) -#define PR_GET_KEEPCAPS SYMBOLIC(PR_GET_KEEPCAPS) -#define PR_GET_NAME SYMBOLIC(PR_GET_NAME) -#define PR_GET_NO_NEW_PRIVS SYMBOLIC(PR_GET_NO_NEW_PRIVS) -#define PR_GET_PDEATHSIG SYMBOLIC(PR_GET_PDEATHSIG) -#define PR_GET_SECCOMP SYMBOLIC(PR_GET_SECCOMP) -#define PR_GET_SECUREBITS SYMBOLIC(PR_GET_SECUREBITS) -#define PR_GET_SPECULATION_CTRL SYMBOLIC(PR_GET_SPECULATION_CTRL) -#define PR_GET_THP_DISABLE SYMBOLIC(PR_GET_THP_DISABLE) -#define PR_GET_TID_ADDRESS SYMBOLIC(PR_GET_TID_ADDRESS) -#define PR_GET_TIMERSLACK SYMBOLIC(PR_GET_TIMERSLACK) -#define PR_GET_TIMING SYMBOLIC(PR_GET_TIMING) -#define PR_GET_TSC SYMBOLIC(PR_GET_TSC) -#define PR_GET_UNALIGN SYMBOLIC(PR_GET_UNALIGN) -#define PR_MCE_KILL SYMBOLIC(PR_MCE_KILL) -#define PR_MCE_KILL_CLEAR SYMBOLIC(PR_MCE_KILL_CLEAR) -#define PR_MCE_KILL_DEFAULT SYMBOLIC(PR_MCE_KILL_DEFAULT) -#define PR_MCE_KILL_EARLY SYMBOLIC(PR_MCE_KILL_EARLY) -#define PR_MCE_KILL_GET SYMBOLIC(PR_MCE_KILL_GET) -#define PR_MCE_KILL_LATE SYMBOLIC(PR_MCE_KILL_LATE) -#define PR_MCE_KILL_SET SYMBOLIC(PR_MCE_KILL_SET) -#define PR_MPX_DISABLE_MANAGEMENT SYMBOLIC(PR_MPX_DISABLE_MANAGEMENT) -#define PR_MPX_ENABLE_MANAGEMENT SYMBOLIC(PR_MPX_ENABLE_MANAGEMENT) -#define PR_SET_CHILD_SUBREAPER SYMBOLIC(PR_SET_CHILD_SUBREAPER) -#define PR_SET_DUMPABLE SYMBOLIC(PR_SET_DUMPABLE) -#define PR_SET_ENDIAN SYMBOLIC(PR_SET_ENDIAN) -#define PR_SET_FPEMU SYMBOLIC(PR_SET_FPEMU) -#define PR_SET_FPEXC SYMBOLIC(PR_SET_FPEXC) -#define PR_SET_FP_MODE SYMBOLIC(PR_SET_FP_MODE) -#define PR_SET_KEEPCAPS SYMBOLIC(PR_SET_KEEPCAPS) -#define PR_SET_MM SYMBOLIC(PR_SET_MM) -#define PR_SET_MM_ARG_END SYMBOLIC(PR_SET_MM_ARG_END) -#define PR_SET_MM_ARG_START SYMBOLIC(PR_SET_MM_ARG_START) -#define PR_SET_MM_AUXV SYMBOLIC(PR_SET_MM_AUXV) -#define PR_SET_MM_BRK SYMBOLIC(PR_SET_MM_BRK) -#define PR_SET_MM_END_CODE SYMBOLIC(PR_SET_MM_END_CODE) -#define PR_SET_MM_END_DATA SYMBOLIC(PR_SET_MM_END_DATA) -#define PR_SET_MM_ENV_END SYMBOLIC(PR_SET_MM_ENV_END) -#define PR_SET_MM_ENV_START SYMBOLIC(PR_SET_MM_ENV_START) -#define PR_SET_MM_EXE_FILE SYMBOLIC(PR_SET_MM_EXE_FILE) -#define PR_SET_MM_MAP SYMBOLIC(PR_SET_MM_MAP) -#define PR_SET_MM_MAP_SIZE SYMBOLIC(PR_SET_MM_MAP_SIZE) -#define PR_SET_MM_START_BRK SYMBOLIC(PR_SET_MM_START_BRK) -#define PR_SET_MM_START_CODE SYMBOLIC(PR_SET_MM_START_CODE) -#define PR_SET_MM_START_DATA SYMBOLIC(PR_SET_MM_START_DATA) -#define PR_SET_MM_START_STACK SYMBOLIC(PR_SET_MM_START_STACK) -#define PR_SET_NAME SYMBOLIC(PR_SET_NAME) -#define PR_SET_NO_NEW_PRIVS SYMBOLIC(PR_SET_NO_NEW_PRIVS) -#define PR_SET_PDEATHSIG SYMBOLIC(PR_SET_PDEATHSIG) -#define PR_SET_PTRACER SYMBOLIC(PR_SET_PTRACER) -#define PR_SET_PTRACER_ANY SYMBOLIC(PR_SET_PTRACER_ANY) -#define PR_SET_SECCOMP SYMBOLIC(PR_SET_SECCOMP) -#define PR_SET_SECUREBITS SYMBOLIC(PR_SET_SECUREBITS) -#define PR_SET_SPECULATION_CTRL SYMBOLIC(PR_SET_SPECULATION_CTRL) -#define PR_SET_THP_DISABLE SYMBOLIC(PR_SET_THP_DISABLE) -#define PR_SET_TIMERSLACK SYMBOLIC(PR_SET_TIMERSLACK) -#define PR_SET_TIMING SYMBOLIC(PR_SET_TIMING) -#define PR_SET_TSC SYMBOLIC(PR_SET_TSC) -#define PR_SET_UNALIGN SYMBOLIC(PR_SET_UNALIGN) -#define PR_SPEC_DISABLE SYMBOLIC(PR_SPEC_DISABLE) -#define PR_SPEC_ENABLE SYMBOLIC(PR_SPEC_ENABLE) -#define PR_SPEC_FORCE_DISABLE SYMBOLIC(PR_SPEC_FORCE_DISABLE) -#define PR_SPEC_NOT_AFFECTED SYMBOLIC(PR_SPEC_NOT_AFFECTED) -#define PR_SPEC_PRCTL SYMBOLIC(PR_SPEC_PRCTL) -#define PR_SPEC_STORE_BYPASS SYMBOLIC(PR_SPEC_STORE_BYPASS) -#define PR_TASK_PERF_EVENTS_DISABLE SYMBOLIC(PR_TASK_PERF_EVENTS_DISABLE) -#define PR_TASK_PERF_EVENTS_ENABLE SYMBOLIC(PR_TASK_PERF_EVENTS_ENABLE) -#define PR_TIMING_STATISTICAL SYMBOLIC(PR_TIMING_STATISTICAL) -#define PR_TIMING_TIMESTAMP SYMBOLIC(PR_TIMING_TIMESTAMP) -#define PR_TSC_ENABLE SYMBOLIC(PR_TSC_ENABLE) -#define PR_TSC_SIGSEGV SYMBOLIC(PR_TSC_SIGSEGV) -#define PR_UNALIGN_NOPRINT SYMBOLIC(PR_UNALIGN_NOPRINT) -#define PR_UNALIGN_SIGBUS SYMBOLIC(PR_UNALIGN_SIGBUS) +#define PR_SET_NAME 15 +#define PR_GET_NAME 0x10 + +#define PR_GET_TSC 25 +#define PR_SET_TSC 26 +#define PR_TSC_ENABLE 1 +#define PR_TSC_SIGSEGV 2 + +#define PR_GET_FPEXC 11 +#define PR_SET_FPEXC 12 +#define PR_FP_EXC_SW_ENABLE 0x80 +#define PR_FP_EXC_DIV 0x010000 +#define PR_FP_EXC_OVF 0x020000 +#define PR_FP_EXC_UND 0x040000 +#define PR_FP_EXC_RES 0x080000 +#define PR_FP_EXC_INV 0x100000 +#define PR_FP_EXC_DISABLED 0 +#define PR_FP_EXC_NONRECOV 1 +#define PR_FP_EXC_ASYNC 2 +#define PR_FP_EXC_PRECISE 3 + +#define PR_MCE_KILL_CLEAR 0 +#define PR_MCE_KILL_LATE 0 +#define PR_SPEC_NOT_AFFECTED 0 +#define PR_SPEC_STORE_BYPASS 0 +#define PR_CAP_AMBIENT_IS_SET 1 +#define PR_FPEMU_NOPRINT 1 +#define PR_MCE_KILL_EARLY 1 +#define PR_MCE_KILL_SET 1 +#define PR_SET_MM_START_CODE 1 +#define PR_SET_PDEATHSIG 1 +#define PR_SPEC_PRCTL 1 +#define PR_CAP_AMBIENT_RAISE 2 +#define PR_FPEMU_SIGFPE 2 +#define PR_GET_PDEATHSIG 2 +#define PR_MCE_KILL_DEFAULT 2 +#define PR_SET_MM_END_CODE 2 +#define PR_SPEC_ENABLE 2 +#define PR_CAP_AMBIENT_LOWER 3 +#define PR_GET_DUMPABLE 3 +#define PR_SET_MM_START_DATA 3 +#define PR_CAP_AMBIENT_CLEAR_ALL 4 +#define PR_SET_DUMPABLE 4 +#define PR_SET_MM_END_DATA 4 +#define PR_SPEC_DISABLE 4 +#define PR_SET_MM_START_STACK 5 +#define PR_SET_MM_START_BRK 6 +#define PR_GET_KEEPCAPS 7 +#define PR_SET_MM_BRK 7 +#define PR_SET_KEEPCAPS 8 +#define PR_SET_MM_ARG_START 8 +#define PR_SPEC_FORCE_DISABLE 8 +#define PR_GET_FPEMU 9 +#define PR_SET_MM_ARG_END 9 +#define PR_SET_FPEMU 10 +#define PR_SET_MM_ENV_START 10 +#define PR_GET_FPEXC 11 +#define PR_SET_MM_ENV_END 11 +#define PR_SET_FPEXC 12 +#define PR_SET_MM_AUXV 12 +#define PR_SET_MM_EXE_FILE 13 +#define PR_SET_MM_MAP 14 +#define PR_SET_MM_MAP_SIZE 15 +#define PR_CAPBSET_READ 23 +#define PR_CAPBSET_DROP 24 +#define PR_GET_TSC 25 +#define PR_SET_TSC 26 +#define PR_GET_SECUREBITS 27 +#define PR_SET_SECUREBITS 28 +#define PR_SET_TIMERSLACK 29 +#define PR_GET_TIMERSLACK 30 +#define PR_TASK_PERF_EVENTS_DISABLE 31 +#define PR_TASK_PERF_EVENTS_ENABLE 0x20 +#define PR_MCE_KILL 33 +#define PR_MCE_KILL_GET 34 +#define PR_SET_MM 35 +#define PR_SET_CHILD_SUBREAPER 36 +#define PR_GET_CHILD_SUBREAPER 37 +#define PR_GET_TID_ADDRESS 40 +#define PR_SET_THP_DISABLE 41 +#define PR_GET_THP_DISABLE 42 +#define PR_MPX_ENABLE_MANAGEMENT 43 +#define PR_MPX_DISABLE_MANAGEMENT 44 +#define PR_CAP_AMBIENT 47 +#define PR_GET_SPECULATION_CTRL 52 +#define PR_SET_SPECULATION_CTRL 53 +#define PR_SET_PTRACER 0x59616d61 +#define PR_SET_PTRACER_ANY -1 #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ */ diff --git a/libc/sysv/consts/ptrace.h b/libc/sysv/consts/ptrace.h index 7f6fdd337..444bcb21b 100644 --- a/libc/sysv/consts/ptrace.h +++ b/libc/sysv/consts/ptrace.h @@ -43,6 +43,7 @@ extern const long PTRACE_O_TRACECLONE; extern const long PTRACE_O_TRACEEXEC; extern const long PTRACE_O_TRACEVFORKDONE; extern const long PTRACE_O_TRACEEXIT; +extern const long PTRACE_O_TRACESECCOMP; extern const long PTRACE_O_MASK; extern const long PTRACE_EVENT_FORK; extern const long PTRACE_EVENT_VFORK; @@ -50,6 +51,8 @@ extern const long PTRACE_EVENT_CLONE; extern const long PTRACE_EVENT_EXEC; extern const long PTRACE_EVENT_VFORK_DONE; extern const long PTRACE_EVENT_EXIT; +extern const long PTRACE_EVENT_STOP; +extern const long PTRACE_EVENT_SECCOMP; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ @@ -93,6 +96,7 @@ COSMOPOLITAN_C_END_ #define PTRACE_O_TRACEEXEC SYMBOLIC(PTRACE_O_TRACEEXEC) #define PTRACE_O_TRACEVFORKDONE SYMBOLIC(PTRACE_O_TRACEVFORKDONE) #define PTRACE_O_TRACEEXIT SYMBOLIC(PTRACE_O_TRACEEXIT) +#define PTRACE_O_TRACESECCOMP SYMBOLIC(PTRACE_O_TRACESECCOMP) #define PTRACE_O_MASK SYMBOLIC(PTRACE_O_MASK) #define PTRACE_EVENT_FORK SYMBOLIC(PTRACE_EVENT_FORK) #define PTRACE_EVENT_VFORK SYMBOLIC(PTRACE_EVENT_VFORK) @@ -100,5 +104,7 @@ COSMOPOLITAN_C_END_ #define PTRACE_EVENT_EXEC SYMBOLIC(PTRACE_EVENT_EXEC) #define PTRACE_EVENT_VFORK_DONE SYMBOLIC(PTRACE_EVENT_VFORK_DONE) #define PTRACE_EVENT_EXIT SYMBOLIC(PTRACE_EVENT_EXIT) +#define PTRACE_EVENT_STOP SYMBOLIC(PTRACE_EVENT_STOP) +#define PTRACE_EVENT_SECCOMP SYMBOLIC(PTRACE_EVENT_SECCOMP) #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PTRACE_H_ */ diff --git a/libc/sysv/consts/reboot.h b/libc/sysv/consts/reboot.h index f72bcadbc..ecd6c2c4b 100644 --- a/libc/sysv/consts/reboot.h +++ b/libc/sysv/consts/reboot.h @@ -4,17 +4,17 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern const uint32_t RB_AUTOBOOT; -extern const uint32_t RB_POWER_OFF; -extern const uint32_t RB_POWERDOWN; -extern const uint32_t RB_POWEROFF; -extern const uint32_t RB_HALT_SYSTEM; -extern const uint32_t RB_HALT; -extern const uint32_t RB_SW_SUSPEND; -extern const uint32_t RB_KEXEC; -extern const uint32_t RB_ENABLE_CAD; -extern const uint32_t RB_DISABLE_CAD; -extern const uint32_t RB_NOSYNC; +extern const int RB_AUTOBOOT; +extern const int RB_POWER_OFF; +extern const int RB_POWERDOWN; +extern const int RB_POWEROFF; +extern const int RB_HALT_SYSTEM; +extern const int RB_HALT; +extern const int RB_SW_SUSPEND; +extern const int RB_KEXEC; +extern const int RB_ENABLE_CAD; +extern const int RB_DISABLE_CAD; +extern const int RB_NOSYNC; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/sysv/consts/scsi.h b/libc/sysv/consts/scsi.h deleted file mode 100644 index af52020b0..000000000 --- a/libc/sysv/consts/scsi.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SCSI_H_ -#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SCSI_H_ -#include "libc/runtime/symbolic.h" - -#define SCSI_IOCTL_BENCHMARK_COMMAND SYMBOLIC(SCSI_IOCTL_BENCHMARK_COMMAND) -#define SCSI_IOCTL_DOORLOCK SYMBOLIC(SCSI_IOCTL_DOORLOCK) -#define SCSI_IOCTL_DOORUNLOCK SYMBOLIC(SCSI_IOCTL_DOORUNLOCK) -#define SCSI_IOCTL_GET_BUS_NUMBER SYMBOLIC(SCSI_IOCTL_GET_BUS_NUMBER) -#define SCSI_IOCTL_GET_IDLUN SYMBOLIC(SCSI_IOCTL_GET_IDLUN) -#define SCSI_IOCTL_PROBE_HOST SYMBOLIC(SCSI_IOCTL_PROBE_HOST) -#define SCSI_IOCTL_SEND_COMMAND SYMBOLIC(SCSI_IOCTL_SEND_COMMAND) -#define SCSI_IOCTL_START_UNIT SYMBOLIC(SCSI_IOCTL_START_UNIT) -#define SCSI_IOCTL_STOP_UNIT SYMBOLIC(SCSI_IOCTL_STOP_UNIT) -#define SCSI_IOCTL_SYNC SYMBOLIC(SCSI_IOCTL_SYNC) -#define SCSI_IOCTL_TAGGED_DISABLE SYMBOLIC(SCSI_IOCTL_TAGGED_DISABLE) -#define SCSI_IOCTL_TAGGED_ENABLE SYMBOLIC(SCSI_IOCTL_TAGGED_ENABLE) -#define SCSI_IOCTL_TEST_UNIT_READY SYMBOLIC(SCSI_IOCTL_TEST_UNIT_READY) - -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -extern const long SCSI_IOCTL_BENCHMARK_COMMAND; -extern const long SCSI_IOCTL_DOORLOCK; -extern const long SCSI_IOCTL_DOORUNLOCK; -extern const long SCSI_IOCTL_GET_BUS_NUMBER; -extern const long SCSI_IOCTL_GET_IDLUN; -extern const long SCSI_IOCTL_PROBE_HOST; -extern const long SCSI_IOCTL_SEND_COMMAND; -extern const long SCSI_IOCTL_START_UNIT; -extern const long SCSI_IOCTL_STOP_UNIT; -extern const long SCSI_IOCTL_SYNC; -extern const long SCSI_IOCTL_TAGGED_DISABLE; -extern const long SCSI_IOCTL_TAGGED_ENABLE; -extern const long SCSI_IOCTL_TEST_UNIT_READY; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SCSI_H_ */ diff --git a/libc/sysv/consts/sg.h b/libc/sysv/consts/sg.h deleted file mode 100644 index 24f7e6c35..000000000 --- a/libc/sysv/consts/sg.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SG_H_ -#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SG_H_ -#include "libc/runtime/symbolic.h" - -#define SG_BIG_BUFF SYMBOLIC(SG_BIG_BUFF) -#define SG_DEFAULT_RETRIES SYMBOLIC(SG_DEFAULT_RETRIES) -#define SG_DEFAULT_TIMEOUT SYMBOLIC(SG_DEFAULT_TIMEOUT) -#define SG_DEF_COMMAND_Q SYMBOLIC(SG_DEF_COMMAND_Q) -#define SG_DEF_FORCE_LOW_DMA SYMBOLIC(SG_DEF_FORCE_LOW_DMA) -#define SG_DEF_FORCE_PACK_ID SYMBOLIC(SG_DEF_FORCE_PACK_ID) -#define SG_DEF_KEEP_ORPHAN SYMBOLIC(SG_DEF_KEEP_ORPHAN) -#define SG_DEF_RESERVED_SIZE SYMBOLIC(SG_DEF_RESERVED_SIZE) -#define SG_DEF_UNDERRUN_FLAG SYMBOLIC(SG_DEF_UNDERRUN_FLAG) -#define SG_DXFER_FROM_DEV SYMBOLIC(SG_DXFER_FROM_DEV) -#define SG_DXFER_NONE SYMBOLIC(SG_DXFER_NONE) -#define SG_DXFER_TO_DEV SYMBOLIC(SG_DXFER_TO_DEV) -#define SG_DXFER_TO_FROM_DEV SYMBOLIC(SG_DXFER_TO_FROM_DEV) -#define SG_EMULATED_HOST SYMBOLIC(SG_EMULATED_HOST) -#define SG_FLAG_DIRECT_IO SYMBOLIC(SG_FLAG_DIRECT_IO) -#define SG_FLAG_LUN_INHIBIT SYMBOLIC(SG_FLAG_LUN_INHIBIT) -#define SG_FLAG_NO_DXFER SYMBOLIC(SG_FLAG_NO_DXFER) -#define SG_GET_COMMAND_Q SYMBOLIC(SG_GET_COMMAND_Q) -#define SG_GET_KEEP_ORPHAN SYMBOLIC(SG_GET_KEEP_ORPHAN) -#define SG_GET_LOW_DMA SYMBOLIC(SG_GET_LOW_DMA) -#define SG_GET_NUM_WAITING SYMBOLIC(SG_GET_NUM_WAITING) -#define SG_GET_PACK_ID SYMBOLIC(SG_GET_PACK_ID) -#define SG_GET_REQUEST_TABLE SYMBOLIC(SG_GET_REQUEST_TABLE) -#define SG_GET_RESERVED_SIZE SYMBOLIC(SG_GET_RESERVED_SIZE) -#define SG_GET_SCSI_ID SYMBOLIC(SG_GET_SCSI_ID) -#define SG_GET_SG_TABLESIZE SYMBOLIC(SG_GET_SG_TABLESIZE) -#define SG_GET_TIMEOUT SYMBOLIC(SG_GET_TIMEOUT) -#define SG_GET_TRANSFORM SYMBOLIC(SG_GET_TRANSFORM) -#define SG_GET_VERSION_NUM SYMBOLIC(SG_GET_VERSION_NUM) -#define SG_INFO_CHECK SYMBOLIC(SG_INFO_CHECK) -#define SG_INFO_DIRECT_IO SYMBOLIC(SG_INFO_DIRECT_IO) -#define SG_INFO_DIRECT_IO_MASK SYMBOLIC(SG_INFO_DIRECT_IO_MASK) -#define SG_INFO_INDIRECT_IO SYMBOLIC(SG_INFO_INDIRECT_IO) -#define SG_INFO_MIXED_IO SYMBOLIC(SG_INFO_MIXED_IO) -#define SG_INFO_OK SYMBOLIC(SG_INFO_OK) -#define SG_INFO_OK_MASK SYMBOLIC(SG_INFO_OK_MASK) -#define SG_IO SYMBOLIC(SG_IO) -#define SG_MAX_QUEUE SYMBOLIC(SG_MAX_QUEUE) -#define SG_MAX_SENSE SYMBOLIC(SG_MAX_SENSE) -#define SG_NEXT_CMD_LEN SYMBOLIC(SG_NEXT_CMD_LEN) -#define SG_SCATTER_SZ SYMBOLIC(SG_SCATTER_SZ) -#define SG_SCSI_RESET SYMBOLIC(SG_SCSI_RESET) -#define SG_SCSI_RESET_BUS SYMBOLIC(SG_SCSI_RESET_BUS) -#define SG_SCSI_RESET_DEVICE SYMBOLIC(SG_SCSI_RESET_DEVICE) -#define SG_SCSI_RESET_HOST SYMBOLIC(SG_SCSI_RESET_HOST) -#define SG_SCSI_RESET_NOTHING SYMBOLIC(SG_SCSI_RESET_NOTHING) -#define SG_SET_COMMAND_Q SYMBOLIC(SG_SET_COMMAND_Q) -#define SG_SET_DEBUG SYMBOLIC(SG_SET_DEBUG) -#define SG_SET_FORCE_LOW_DMA SYMBOLIC(SG_SET_FORCE_LOW_DMA) -#define SG_SET_FORCE_PACK_ID SYMBOLIC(SG_SET_FORCE_PACK_ID) -#define SG_SET_KEEP_ORPHAN SYMBOLIC(SG_SET_KEEP_ORPHAN) -#define SG_SET_RESERVED_SIZE SYMBOLIC(SG_SET_RESERVED_SIZE) -#define SG_SET_TIMEOUT SYMBOLIC(SG_SET_TIMEOUT) -#define SG_SET_TRANSFORM SYMBOLIC(SG_SET_TRANSFORM) - -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -extern const long SG_BIG_BUFF; -extern const long SG_DEFAULT_RETRIES; -extern const long SG_DEFAULT_TIMEOUT; -extern const long SG_DEF_COMMAND_Q; -extern const long SG_DEF_FORCE_LOW_DMA; -extern const long SG_DEF_FORCE_PACK_ID; -extern const long SG_DEF_KEEP_ORPHAN; -extern const long SG_DEF_RESERVED_SIZE; -extern const long SG_DEF_UNDERRUN_FLAG; -extern const long SG_DXFER_FROM_DEV; -extern const long SG_DXFER_NONE; -extern const long SG_DXFER_TO_DEV; -extern const long SG_DXFER_TO_FROM_DEV; -extern const long SG_EMULATED_HOST; -extern const long SG_FLAG_DIRECT_IO; -extern const long SG_FLAG_LUN_INHIBIT; -extern const long SG_FLAG_NO_DXFER; -extern const long SG_GET_COMMAND_Q; -extern const long SG_GET_KEEP_ORPHAN; -extern const long SG_GET_LOW_DMA; -extern const long SG_GET_NUM_WAITING; -extern const long SG_GET_PACK_ID; -extern const long SG_GET_REQUEST_TABLE; -extern const long SG_GET_RESERVED_SIZE; -extern const long SG_GET_SCSI_ID; -extern const long SG_GET_SG_TABLESIZE; -extern const long SG_GET_TIMEOUT; -extern const long SG_GET_TRANSFORM; -extern const long SG_GET_VERSION_NUM; -extern const long SG_INFO_CHECK; -extern const long SG_INFO_DIRECT_IO; -extern const long SG_INFO_DIRECT_IO_MASK; -extern const long SG_INFO_INDIRECT_IO; -extern const long SG_INFO_MIXED_IO; -extern const long SG_INFO_OK; -extern const long SG_INFO_OK_MASK; -extern const long SG_IO; -extern const long SG_MAX_QUEUE; -extern const long SG_MAX_SENSE; -extern const long SG_NEXT_CMD_LEN; -extern const long SG_SCATTER_SZ; -extern const long SG_SCSI_RESET; -extern const long SG_SCSI_RESET_BUS; -extern const long SG_SCSI_RESET_DEVICE; -extern const long SG_SCSI_RESET_HOST; -extern const long SG_SCSI_RESET_NOTHING; -extern const long SG_SET_COMMAND_Q; -extern const long SG_SET_DEBUG; -extern const long SG_SET_FORCE_LOW_DMA; -extern const long SG_SET_FORCE_PACK_ID; -extern const long SG_SET_KEEP_ORPHAN; -extern const long SG_SET_RESERVED_SIZE; -extern const long SG_SET_TIMEOUT; -extern const long SG_SET_TRANSFORM; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SG_H_ */ diff --git a/libc/sysv/consts/sicode.h b/libc/sysv/consts/sicode.h index 11922b88d..7b79cc44d 100644 --- a/libc/sysv/consts/sicode.h +++ b/libc/sysv/consts/sicode.h @@ -23,6 +23,7 @@ extern const long TRAP_BRKPT; extern const long TRAP_TRACE; extern const long SEGV_MAPERR; extern const long SEGV_ACCERR; +extern const long SEGV_PKUERR; extern const long FPE_INTDIV; extern const long FPE_INTOVF; extern const long FPE_FLTDIV; @@ -44,12 +45,15 @@ extern const long BUS_ADRERR; extern const long BUS_OBJERR; extern const long BUS_MCEERR_AR; extern const long BUS_MCEERR_AO; +extern const long BUS_OOMERR; extern const long POLL_IN; extern const long POLL_OUT; extern const long POLL_MSG; extern const long POLL_ERR; extern const long POLL_PRI; extern const long POLL_HUP; +extern const long SYS_SECCOMP; +extern const long SYS_USER_DISPATCH; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ @@ -78,28 +82,32 @@ COSMOPOLITAN_C_END_ #define POLL_PRI LITERALLY(5) #define POLL_HUP LITERALLY(6) -#define SI_USER SYMBOLIC(SI_USER) -#define SI_QUEUE SYMBOLIC(SI_QUEUE) -#define SI_TIMER SYMBOLIC(SI_TIMER) -#define SI_MESGQ SYMBOLIC(SI_MESGQ) -#define SI_ASYNCIO SYMBOLIC(SI_ASYNCIO) -#define SI_TKILL SYMBOLIC(SI_TKILL) -#define SI_ASYNCNL SYMBOLIC(SI_ASYNCNL) -#define SI_KERNEL SYMBOLIC(SI_KERNEL) -#define SI_NOINFO SYMBOLIC(SI_NOINFO) -#define FPE_INTDIV SYMBOLIC(FPE_INTDIV) -#define FPE_INTOVF SYMBOLIC(FPE_INTOVF) -#define FPE_FLTDIV SYMBOLIC(FPE_FLTDIV) -#define FPE_FLTOVF SYMBOLIC(FPE_FLTOVF) -#define FPE_FLTUND SYMBOLIC(FPE_FLTUND) -#define FPE_FLTRES SYMBOLIC(FPE_FLTRES) -#define FPE_FLTINV SYMBOLIC(FPE_FLTINV) -#define FPE_FLTSUB SYMBOLIC(FPE_FLTSUB) -#define ILL_ILLOPN SYMBOLIC(ILL_ILLOPN) -#define ILL_ILLADR SYMBOLIC(ILL_ILLADR) -#define ILL_ILLTRP SYMBOLIC(ILL_ILLTRP) -#define ILL_PRVOPC SYMBOLIC(ILL_PRVOPC) -#define BUS_MCEERR_AR SYMBOLIC(BUS_MCEERR_AR) -#define BUS_MCEERR_AO SYMBOLIC(BUS_MCEERR_AO) +#define SI_USER SYMBOLIC(SI_USER) +#define SI_QUEUE SYMBOLIC(SI_QUEUE) +#define SI_TIMER SYMBOLIC(SI_TIMER) +#define SI_MESGQ SYMBOLIC(SI_MESGQ) +#define SI_ASYNCIO SYMBOLIC(SI_ASYNCIO) +#define SI_TKILL SYMBOLIC(SI_TKILL) +#define SI_ASYNCNL SYMBOLIC(SI_ASYNCNL) +#define SI_KERNEL SYMBOLIC(SI_KERNEL) +#define SI_NOINFO SYMBOLIC(SI_NOINFO) +#define SEGV_PKUERR SYMBOLIC(SEGV_PKUERR) +#define FPE_INTDIV SYMBOLIC(FPE_INTDIV) +#define FPE_INTOVF SYMBOLIC(FPE_INTOVF) +#define FPE_FLTDIV SYMBOLIC(FPE_FLTDIV) +#define FPE_FLTOVF SYMBOLIC(FPE_FLTOVF) +#define FPE_FLTUND SYMBOLIC(FPE_FLTUND) +#define FPE_FLTRES SYMBOLIC(FPE_FLTRES) +#define FPE_FLTINV SYMBOLIC(FPE_FLTINV) +#define FPE_FLTSUB SYMBOLIC(FPE_FLTSUB) +#define ILL_ILLOPN SYMBOLIC(ILL_ILLOPN) +#define ILL_ILLADR SYMBOLIC(ILL_ILLADR) +#define ILL_ILLTRP SYMBOLIC(ILL_ILLTRP) +#define ILL_PRVOPC SYMBOLIC(ILL_PRVOPC) +#define BUS_OOMERR SYMBOLIC(BUS_OOMERR) +#define BUS_MCEERR_AR SYMBOLIC(BUS_MCEERR_AR) +#define BUS_MCEERR_AO SYMBOLIC(BUS_MCEERR_AO) +#define SYS_SECCOMP SYMBOLIC(SYS_SECCOMP) +#define SYS_USER_DISPATCH SYMBOLIC(SYS_USER_DISPATCH) #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SICODE_H_ */ diff --git a/libc/sysv/consts/sig.h b/libc/sysv/consts/sig.h index 4f9b3e746..aa62d648d 100644 --- a/libc/sysv/consts/sig.h +++ b/libc/sysv/consts/sig.h @@ -53,43 +53,44 @@ COSMOPOLITAN_C_END_ #define SIGABRT LITERALLY(6) #define SIGALRM LITERALLY(14) -#define SIGBUS SYMBOLIC(SIGBUS) -#define SIGCHLD SYMBOLIC(SIGCHLD) -#define SIGCONT SYMBOLIC(SIGCONT) -#define SIGEMT SYMBOLIC(SIGEMT) #define SIGFPE LITERALLY(8) #define SIGHUP LITERALLY(1) #define SIGILL LITERALLY(4) -#define SIGINFO SYMBOLIC(SIGINFO) #define SIGINT LITERALLY(2) -#define SIGIO SYMBOLIC(SIGIO) #define SIGIOT LITERALLY(6) #define SIGKILL LITERALLY(9) #define SIGPIPE LITERALLY(13) -#define SIGPOLL SYMBOLIC(SIGPOLL) #define SIGPROF LITERALLY(27) -#define SIGPWR SYMBOLIC(SIGPWR) #define SIGQUIT LITERALLY(3) -#define SIGRTMAX SYMBOLIC(SIGRTMAX) -#define SIGRTMIN SYMBOLIC(SIGRTMIN) #define SIGSEGV LITERALLY(11) -#define SIGSTKFLT SYMBOLIC(SIGSTKFLT) -#define SIGSTOP SYMBOLIC(SIGSTOP) -#define SIGSYS SYMBOLIC(SIGSYS) #define SIGTERM LITERALLY(15) #define SIGTRAP LITERALLY(5) -#define SIGTSTP SYMBOLIC(SIGTSTP) #define SIGTTIN LITERALLY(21) #define SIGTTOU LITERALLY(22) -#define SIGUNUSED SYMBOLIC(SIGUNUSED) -#define SIGURG SYMBOLIC(SIGURG) -#define SIGUSR1 SYMBOLIC(SIGUSR1) -#define SIGUSR2 SYMBOLIC(SIGUSR2) #define SIGVTALRM LITERALLY(26) #define SIGWINCH LITERALLY(28) #define SIGXCPU LITERALLY(24) #define SIGXFSZ LITERALLY(25) +#define SIGBUS SYMBOLIC(SIGBUS) +#define SIGCHLD SYMBOLIC(SIGCHLD) +#define SIGCONT SYMBOLIC(SIGCONT) +#define SIGEMT SYMBOLIC(SIGEMT) +#define SIGINFO SYMBOLIC(SIGINFO) +#define SIGIO SYMBOLIC(SIGIO) +#define SIGPOLL SYMBOLIC(SIGPOLL) +#define SIGPWR SYMBOLIC(SIGPWR) +#define SIGRTMAX SYMBOLIC(SIGRTMAX) +#define SIGRTMIN SYMBOLIC(SIGRTMIN) +#define SIGSTKFLT SYMBOLIC(SIGSTKFLT) +#define SIGSTOP SYMBOLIC(SIGSTOP) +#define SIGSYS SYMBOLIC(SIGSYS) +#define SIGTSTP SYMBOLIC(SIGTSTP) +#define SIGUNUSED SYMBOLIC(SIGUNUSED) +#define SIGURG SYMBOLIC(SIGURG) +#define SIGUSR1 SYMBOLIC(SIGUSR1) +#define SIGUSR2 SYMBOLIC(SIGUSR2) + #define SIG_ATOMIC_MIN SYMBOLIC(SIG_ATOMIC_MIN) #define SIG_BLOCK SYMBOLIC(SIG_BLOCK) #define SIG_SETMASK SYMBOLIC(SIG_SETMASK) diff --git a/libc/sysv/consts/so.h b/libc/sysv/consts/so.h index e3ec79d74..3c61cf7a0 100644 --- a/libc/sysv/consts/so.h +++ b/libc/sysv/consts/so.h @@ -1,69 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SO_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_SO_H_ #include "libc/runtime/symbolic.h" - -#define LOCAL_PEERCRED SYMBOLIC(LOCAL_PEERCRED) -#define SO_ACCEPTCONN SYMBOLIC(SO_ACCEPTCONN) -#define SO_ATTACH_BPF SYMBOLIC(SO_ATTACH_BPF) -#define SO_ATTACH_FILTER SYMBOLIC(SO_ATTACH_FILTER) -#define SO_ATTACH_REUSEPORT_CBPF SYMBOLIC(SO_ATTACH_REUSEPORT_CBPF) -#define SO_ATTACH_REUSEPORT_EBPF SYMBOLIC(SO_ATTACH_REUSEPORT_EBPF) -#define SO_BINDTODEVICE SYMBOLIC(SO_BINDTODEVICE) -#define SO_BPF_EXTENSIONS SYMBOLIC(SO_BPF_EXTENSIONS) -#define SO_BROADCAST SYMBOLIC(SO_BROADCAST) -#define SO_BSDCOMPAT SYMBOLIC(SO_BSDCOMPAT) -#define SO_BUSY_POLL SYMBOLIC(SO_BUSY_POLL) -#define SO_CNX_ADVICE SYMBOLIC(SO_CNX_ADVICE) -#define SO_DEBUG SYMBOLIC(SO_DEBUG) -#define SO_DETACH_BPF SYMBOLIC(SO_DETACH_BPF) -#define SO_DETACH_FILTER SYMBOLIC(SO_DETACH_FILTER) -#define SO_DOMAIN SYMBOLIC(SO_DOMAIN) -#define SO_DONTROUTE SYMBOLIC(SO_DONTROUTE) -#define SO_ERROR SYMBOLIC(SO_ERROR) -#define SO_EXCLUSIVEADDRUSE SYMBOLIC(SO_EXCLUSIVEADDRUSE) -#define SO_GET_FILTER SYMBOLIC(SO_GET_FILTER) -#define SO_INCOMING_CPU SYMBOLIC(SO_INCOMING_CPU) -#define SO_KEEPALIVE SYMBOLIC(SO_KEEPALIVE) -#define SO_LINGER SYMBOLIC(SO_LINGER) -#define SO_LOCK_FILTER SYMBOLIC(SO_LOCK_FILTER) -#define SO_MARK SYMBOLIC(SO_MARK) -#define SO_MAX_PACING_RATE SYMBOLIC(SO_MAX_PACING_RATE) -#define SO_NOFCS SYMBOLIC(SO_NOFCS) -#define SO_NO_CHECK SYMBOLIC(SO_NO_CHECK) -#define SO_OOBINLINE SYMBOLIC(SO_OOBINLINE) -#define SO_PASSCRED SYMBOLIC(SO_PASSCRED) -#define SO_PASSSEC SYMBOLIC(SO_PASSSEC) -#define SO_PEEK_OFF SYMBOLIC(SO_PEEK_OFF) -#define SO_PEERCRED SYMBOLIC(SO_PEERCRED) -#define SO_PEERNAME SYMBOLIC(SO_PEERNAME) -#define SO_PEERSEC SYMBOLIC(SO_PEERSEC) -#define SO_PRIORITY SYMBOLIC(SO_PRIORITY) -#define SO_PROTOCOL SYMBOLIC(SO_PROTOCOL) -#define SO_RCVBUF SYMBOLIC(SO_RCVBUF) -#define SO_RCVBUFFORCE SYMBOLIC(SO_RCVBUFFORCE) -#define SO_RCVLOWAT SYMBOLIC(SO_RCVLOWAT) -#define SO_RCVTIMEO SYMBOLIC(SO_RCVTIMEO) -#define SO_REUSEADDR SYMBOLIC(SO_REUSEADDR) -#define SO_REUSEPORT SYMBOLIC(SO_REUSEPORT) -#define SO_RXQ_OVFL SYMBOLIC(SO_RXQ_OVFL) -#define SO_SELECT_ERR_QUEUE SYMBOLIC(SO_SELECT_ERR_QUEUE) -#define SO_SETFIB SYMBOLIC(SO_SETFIB) -#define SO_SNDBUF SYMBOLIC(SO_SNDBUF) -#define SO_SNDBUFFORCE SYMBOLIC(SO_SNDBUFFORCE) -#define SO_SNDLOWAT SYMBOLIC(SO_SNDLOWAT) -#define SO_SNDTIMEO SYMBOLIC(SO_SNDTIMEO) -#define SO_TIMESTAMP SYMBOLIC(SO_TIMESTAMP) -#define SO_TIMESTAMPING SYMBOLIC(SO_TIMESTAMPING) -#define SO_TIMESTAMPNS SYMBOLIC(SO_TIMESTAMPNS) -#define SO_TYPE SYMBOLIC(SO_TYPE) -#define SO_USELOOPBACK SYMBOLIC(SO_USELOOPBACK) -#define SO_WIFI_STATUS SYMBOLIC(SO_WIFI_STATUS) - -#define SO_SECURITY_AUTHENTICATION SYMBOLIC(SO_SECURITY_AUTHENTICATION) -#define SO_SECURITY_ENCRYPTION_NETWORK SYMBOLIC(SO_SECURITY_ENCRYPTION_NETWORK) -#define SO_SECURITY_ENCRYPTION_TRANSPORT \ - SYMBOLIC(SO_SECURITY_ENCRYPTION_TRANSPORT) - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -129,4 +66,68 @@ extern const long SO_WIFI_STATUS; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define SO_DEBUG LITERALLY(1) + +#define LOCAL_PEERCRED SYMBOLIC(LOCAL_PEERCRED) +#define SO_ACCEPTCONN SYMBOLIC(SO_ACCEPTCONN) +#define SO_ATTACH_BPF SYMBOLIC(SO_ATTACH_BPF) +#define SO_ATTACH_FILTER SYMBOLIC(SO_ATTACH_FILTER) +#define SO_ATTACH_REUSEPORT_CBPF SYMBOLIC(SO_ATTACH_REUSEPORT_CBPF) +#define SO_ATTACH_REUSEPORT_EBPF SYMBOLIC(SO_ATTACH_REUSEPORT_EBPF) +#define SO_BINDTODEVICE SYMBOLIC(SO_BINDTODEVICE) +#define SO_BPF_EXTENSIONS SYMBOLIC(SO_BPF_EXTENSIONS) +#define SO_BROADCAST SYMBOLIC(SO_BROADCAST) +#define SO_BSDCOMPAT SYMBOLIC(SO_BSDCOMPAT) +#define SO_BUSY_POLL SYMBOLIC(SO_BUSY_POLL) +#define SO_CNX_ADVICE SYMBOLIC(SO_CNX_ADVICE) +#define SO_DETACH_BPF SYMBOLIC(SO_DETACH_BPF) +#define SO_DETACH_FILTER SYMBOLIC(SO_DETACH_FILTER) +#define SO_DOMAIN SYMBOLIC(SO_DOMAIN) +#define SO_DONTROUTE SYMBOLIC(SO_DONTROUTE) +#define SO_ERROR SYMBOLIC(SO_ERROR) +#define SO_EXCLUSIVEADDRUSE SYMBOLIC(SO_EXCLUSIVEADDRUSE) +#define SO_GET_FILTER SYMBOLIC(SO_GET_FILTER) +#define SO_INCOMING_CPU SYMBOLIC(SO_INCOMING_CPU) +#define SO_KEEPALIVE SYMBOLIC(SO_KEEPALIVE) +#define SO_LINGER SYMBOLIC(SO_LINGER) +#define SO_LOCK_FILTER SYMBOLIC(SO_LOCK_FILTER) +#define SO_MARK SYMBOLIC(SO_MARK) +#define SO_MAX_PACING_RATE SYMBOLIC(SO_MAX_PACING_RATE) +#define SO_NOFCS SYMBOLIC(SO_NOFCS) +#define SO_NO_CHECK SYMBOLIC(SO_NO_CHECK) +#define SO_OOBINLINE SYMBOLIC(SO_OOBINLINE) +#define SO_PASSCRED SYMBOLIC(SO_PASSCRED) +#define SO_PASSSEC SYMBOLIC(SO_PASSSEC) +#define SO_PEEK_OFF SYMBOLIC(SO_PEEK_OFF) +#define SO_PEERCRED SYMBOLIC(SO_PEERCRED) +#define SO_PEERNAME SYMBOLIC(SO_PEERNAME) +#define SO_PEERSEC SYMBOLIC(SO_PEERSEC) +#define SO_PRIORITY SYMBOLIC(SO_PRIORITY) +#define SO_PROTOCOL SYMBOLIC(SO_PROTOCOL) +#define SO_RCVBUF SYMBOLIC(SO_RCVBUF) +#define SO_RCVBUFFORCE SYMBOLIC(SO_RCVBUFFORCE) +#define SO_RCVLOWAT SYMBOLIC(SO_RCVLOWAT) +#define SO_RCVTIMEO SYMBOLIC(SO_RCVTIMEO) +#define SO_REUSEADDR SYMBOLIC(SO_REUSEADDR) +#define SO_REUSEPORT SYMBOLIC(SO_REUSEPORT) +#define SO_RXQ_OVFL SYMBOLIC(SO_RXQ_OVFL) +#define SO_SELECT_ERR_QUEUE SYMBOLIC(SO_SELECT_ERR_QUEUE) +#define SO_SETFIB SYMBOLIC(SO_SETFIB) +#define SO_SNDBUF SYMBOLIC(SO_SNDBUF) +#define SO_SNDBUFFORCE SYMBOLIC(SO_SNDBUFFORCE) +#define SO_SNDLOWAT SYMBOLIC(SO_SNDLOWAT) +#define SO_SNDTIMEO SYMBOLIC(SO_SNDTIMEO) +#define SO_TIMESTAMP SYMBOLIC(SO_TIMESTAMP) +#define SO_TIMESTAMPING SYMBOLIC(SO_TIMESTAMPING) +#define SO_TIMESTAMPNS SYMBOLIC(SO_TIMESTAMPNS) +#define SO_TYPE SYMBOLIC(SO_TYPE) +#define SO_USELOOPBACK SYMBOLIC(SO_USELOOPBACK) +#define SO_WIFI_STATUS SYMBOLIC(SO_WIFI_STATUS) + +#define SO_SECURITY_AUTHENTICATION SYMBOLIC(SO_SECURITY_AUTHENTICATION) +#define SO_SECURITY_ENCRYPTION_NETWORK SYMBOLIC(SO_SECURITY_ENCRYPTION_NETWORK) +#define SO_SECURITY_ENCRYPTION_TRANSPORT \ + SYMBOLIC(SO_SECURITY_ENCRYPTION_TRANSPORT) + #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SO_H_ */ diff --git a/libc/sysv/consts/sol.h b/libc/sysv/consts/sol.h index a24cb776b..f3a1d6f06 100644 --- a/libc/sysv/consts/sol.h +++ b/libc/sysv/consts/sol.h @@ -1,36 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ #include "libc/runtime/symbolic.h" - -#define SOL_AAL SYMBOLIC(SOL_AAL) -#define SOL_ALG SYMBOLIC(SOL_ALG) -#define SOL_ATM SYMBOLIC(SOL_ATM) -#define SOL_BLUETOOTH SYMBOLIC(SOL_BLUETOOTH) -#define SOL_CAIF SYMBOLIC(SOL_CAIF) -#define SOL_DCCP SYMBOLIC(SOL_DCCP) -#define SOL_DECNET SYMBOLIC(SOL_DECNET) -#define SOL_ICMPV6 SYMBOLIC(SOL_ICMPV6) -#define SOL_IP SYMBOLIC(SOL_IP) -#define SOL_IPV6 SYMBOLIC(SOL_IPV6) -#define SOL_IRDA SYMBOLIC(SOL_IRDA) -#define SOL_IUCV SYMBOLIC(SOL_IUCV) -#define SOL_KCM SYMBOLIC(SOL_KCM) -#define SOL_LLC SYMBOLIC(SOL_LLC) -#define SOL_NETBEUI SYMBOLIC(SOL_NETBEUI) -#define SOL_NETLINK SYMBOLIC(SOL_NETLINK) -#define SOL_NFC SYMBOLIC(SOL_NFC) -#define SOL_PACKET SYMBOLIC(SOL_PACKET) -#define SOL_PNPIPE SYMBOLIC(SOL_PNPIPE) -#define SOL_PPPOL2TP SYMBOLIC(SOL_PPPOL2TP) -#define SOL_RAW SYMBOLIC(SOL_RAW) -#define SOL_RDS SYMBOLIC(SOL_RDS) -#define SOL_RXRPC SYMBOLIC(SOL_RXRPC) -#define SOL_SOCKET SYMBOLIC(SOL_SOCKET) -#define SOL_TCP SYMBOLIC(SOL_TCP) -#define SOL_TIPC SYMBOLIC(SOL_TIPC) -#define SOL_UDP SYMBOLIC(SOL_UDP) -#define SOL_X25 SYMBOLIC(SOL_X25) - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -65,4 +35,35 @@ extern const long SOL_X25; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define SOL_IP LITERALLY(0) +#define SOL_TCP LITERALLY(6) +#define SOL_UDP LITERALLY(17) + +#define SOL_AAL SYMBOLIC(SOL_AAL) +#define SOL_ALG SYMBOLIC(SOL_ALG) +#define SOL_ATM SYMBOLIC(SOL_ATM) +#define SOL_BLUETOOTH SYMBOLIC(SOL_BLUETOOTH) +#define SOL_CAIF SYMBOLIC(SOL_CAIF) +#define SOL_DCCP SYMBOLIC(SOL_DCCP) +#define SOL_DECNET SYMBOLIC(SOL_DECNET) +#define SOL_ICMPV6 SYMBOLIC(SOL_ICMPV6) +#define SOL_IPV6 SYMBOLIC(SOL_IPV6) +#define SOL_IRDA SYMBOLIC(SOL_IRDA) +#define SOL_IUCV SYMBOLIC(SOL_IUCV) +#define SOL_KCM SYMBOLIC(SOL_KCM) +#define SOL_LLC SYMBOLIC(SOL_LLC) +#define SOL_NETBEUI SYMBOLIC(SOL_NETBEUI) +#define SOL_NETLINK SYMBOLIC(SOL_NETLINK) +#define SOL_NFC SYMBOLIC(SOL_NFC) +#define SOL_PACKET SYMBOLIC(SOL_PACKET) +#define SOL_PNPIPE SYMBOLIC(SOL_PNPIPE) +#define SOL_PPPOL2TP SYMBOLIC(SOL_PPPOL2TP) +#define SOL_RAW SYMBOLIC(SOL_RAW) +#define SOL_RDS SYMBOLIC(SOL_RDS) +#define SOL_RXRPC SYMBOLIC(SOL_RXRPC) +#define SOL_SOCKET SYMBOLIC(SOL_SOCKET) +#define SOL_TIPC SYMBOLIC(SOL_TIPC) +#define SOL_X25 SYMBOLIC(SOL_X25) + #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ */ diff --git a/libc/sysv/describeos.greg.c b/libc/sysv/describeos.greg.c new file mode 100644 index 000000000..1b0f37c6a --- /dev/null +++ b/libc/sysv/describeos.greg.c @@ -0,0 +1,37 @@ +/*-*- 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 "libc/dce.h" + +const char *__describe_os(void) { + if (IsLinux()) { + return "gnu/systemd"; + } else if (IsXnu()) { + return "xnu's not unix!"; + } else if (IsFreebsd()) { + return "free besiyata dishmaya"; + } else if (IsNetbsd()) { + return "net besiyata dishmaya"; + } else if (IsOpenbsd()) { + return "open besiyata dishmaya"; + } else if (IsWindows()) { + return "the new technology"; + } else { + return "wut"; + } +} diff --git a/libc/sysv/g_syscount.S b/libc/sysv/g_syscount.S index 65bf841a2..ff253c0cf 100644 --- a/libc/sysv/g_syscount.S +++ b/libc/sysv/g_syscount.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // RII System Five system call counter. // diff --git a/libc/sysv/restorert.S b/libc/sysv/restorert.S index 03f07377a..42a16d079 100644 --- a/libc/sysv/restorert.S +++ b/libc/sysv/restorert.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .privileged -.source __FILE__ // Linux Signal Trampoline (HOLY CODE) __restore_bt: diff --git a/libc/sysv/strace.greg.c b/libc/sysv/strace.greg.c new file mode 100644 index 000000000..cd75bfa5f --- /dev/null +++ b/libc/sysv/strace.greg.c @@ -0,0 +1,21 @@ +/*-*- 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/strace.internal.h" + +int __strace; diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index 0b1b75675..bbd647557 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -49,7 +49,7 @@ scall sys_msync 0x115100041204101a globl hidden scall sys_mprotect 0x04a04a04a204a00a globl hidden scall __sys_munmap 0x049049049204900b globl hidden scall sys_sigaction 0x15402e1a0202e00d globl hidden # rt_sigaction on Lunix; it's complicated on NetBSD -scall sys_sigprocmask 0x125030154203000e globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue +scall __sys_sigprocmask 0x125030154214900e globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue, a.k.a. pthread_sigmask scall sys_ioctl 0x0360360362036010 globl hidden scall sys_pread 0x0ad0ad1db2099011 globl hidden # a.k.a. pread64; netbsd+openbsd:pad scall sys_pwrite 0x0ae0ae1dc209a012 globl hidden # a.k.a. pwrite64; netbsd+openbsd:pad @@ -92,13 +92,13 @@ scall __sys_socketpair 0x0870870872087035 globl hidden scall sys_setsockopt 0x0690690692069036 globl hidden scall sys_getsockopt 0x0760760762076037 globl hidden scall sys_fork 0x0020020022002039 globl hidden # xnu needs eax&=~-edx bc eax always holds pid and edx is 0 for parent and 1 for child -#scall vfork 0x042042042204203a globl # this syscall is from the moon so we implement it by hand in libc/calls/hefty/vfork.S +#scall vfork 0x042042042204203a globl # this syscall is from the moon so we implement it by hand in libc/runtime/vfork.S scall sys_posix_spawn 0xfffffffff20f4fff globl hidden # good luck figuring out how xnu defines this scall __sys_execve 0x03b03b03b203b03b globl hidden scall __sys_wait4 0x1c100b007200703d globl hidden scall sys_kill 0x02507a025202503e globl hidden # kill(pid, sig, 1) b/c xnu scall sys_killpg 0xffffff092fffffff globl hidden -scall clone 0xfffffffffffff038 globl +scall sys_clone 0x11fffffffffff038 globl hidden scall tkill 0xfffffffffffff0c8 globl scall futex 0xfff053fffffff0ca globl scall set_robust_list 0xfffffffffffff111 globl @@ -134,7 +134,7 @@ scall sys_fchmod 0x07c07c07c207c05b globl hidden scall sys_chown 0x010010010201005c globl hidden # impl. w/ fchownat() @asyncsignalsafe scall sys_fchown 0x07b07b07b207b05d globl hidden # @asyncsignalsafe scall sys_lchown 0x1130fe0fe216c05e globl hidden # impl. w/ fchownat() -scall umask 0x03c03c03c203c05f globl +scall sys_umask 0x03c03c03c203c05f globl hidden scall sys_gettimeofday 0x1a20430742074060 globl hidden # xnu esi/edx=0 scall sys_getrlimit 0x0c20c20c220c2061 globl hidden scall __sys_getrusage 0x1bd0130752075062 globl hidden @@ -145,25 +145,25 @@ scall syslog 0xfffffffffffff067 globl scall sys_getuid 0x0180180182018066 globl hidden scall sys_getgid 0x02f02f02f202f068 globl hidden scall sys_getppid 0xfff027027202706e globl hidden # see sys_getpid()→edx for netbsd -scall getpgrp 0x051051051205106f globl +scall sys_getpgrp 0x051051051205106f globl hidden scall sys_setsid 0x0930930932093070 globl hidden scall sys_getsid 0x11e0ff136213607c globl hidden scall sys_getpgid 0x0cf0cf0cf2097079 globl hidden -scall setpgid 0x052052052205206d globl -scall geteuid 0xfff019019201906b globl -scall getegid 0xfff02b02b202b06c globl +scall sys_setpgid 0x052052052205206d globl hidden +scall sys_geteuid 0x019019019201906b globl hidden +scall sys_getegid 0x02b02b02b202b06c globl hidden scall getgroups 0x04f04f04f204f073 globl scall setgroups 0x0500500502050074 globl -scall setreuid 0x07e07e07e207e071 globl -scall setregid 0x07f07f07f207f072 globl -scall setuid 0x0170170172017069 globl -scall setgid 0x0b50b50b520b506a globl +scall sys_setreuid 0x07e07e07e207e071 globl hidden +scall sys_setregid 0x07f07f07f207f072 globl hidden +scall sys_setuid 0x0170170172017069 globl hidden +scall sys_setgid 0x0b50b50b520b506a globl hidden scall sys_setresuid 0xfff11a137ffff075 globl hidden # polyfilled for xnu scall sys_setresgid 0xfff11c138ffff077 globl hidden # polyfilled for xnu -scall getresuid 0xfff119168ffff076 globl # semantics aren't well-defined -scall getresgid 0xfff11b169ffff078 globl # semantics aren't well-defined -scall sigpending 0x124034034203407f globl # rt_sigpending on linux -scall sys_sigsuspend 0x12606f155206f082 globl hidden # openbsd:byvalue +scall sys_getresuid 0xfff119168ffff076 globl # semantics aren't well-defined +scall sys_getresgid 0xfff11b169ffff078 globl # semantics aren't well-defined +scall sigpending 0x124034034203407f globl # a.k.a. rt_sigpending on linux +scall sys_sigsuspend 0x12606f155206f082 globl hidden # a.k.a. rt_sigsuspend on Linux; openbsd:byvalue, sigsuspend_nocancel on XNU scall sys_sigaltstack 0x1191200352035083 globl hidden scall sys_mknod 0x1c200e00e200e085 globl hidden scall mknodat 0x1cc14022fffff103 globl # FreeBSD 12+ @@ -178,11 +178,11 @@ scall munlock 0x0cc0cc0cc20cc096 globl scall mlockall 0x0f210f1442144097 globl scall munlockall 0x0f31101452145098 globl scall sys_setrlimit 0x0c30c30c320c30a0 globl hidden -scall chroot 0x03d03d03d203d0a1 globl +scall sys_chroot 0x03d03d03d203d0a1 globl hidden scall sys_sync 0xfff02402420240a2 globl hidden scall acct 0x03303303320330a3 globl scall settimeofday 0x1a304407a207a0a4 globl -scall sys_mount 0x19a01501520a70a5 globl +scall sys_mount 0x19a01501520a70a5 globl hidden scall sys_unmount 0x016016016209f0a6 globl hidden # umount2() on linux scall umount2 0x016016016209f0a6 globl hidden # unmount() on bsd scall sys_reboot 0x0d003703720370a9 globl hidden # two arguments b/c netbsd/sparc lool @@ -192,8 +192,8 @@ scall setfsgid 0xfffffffffffff07b globl scall capget 0xfffffffffffff07d globl scall capset 0xfffffffffffff07e globl scall sigtimedwait 0xffffff159ffff080 globl -scall sys_sigqueue 0xffffff1c8fffffff globl -scall sys_sigqueueinfo 0x0f5ffffffffff081 globl # rt_sigqueueinfo on linux +scall sys_sigqueue 0xffffff1c8fffffff globl hidden +scall sys_sigqueueinfo 0x0f5ffffffffff081 globl hidden # a.k.a. rt_sigqueueinfo on linux scall personality 0xfffffffffffff087 globl scall ustat 0xfffffffffffff088 globl scall sysfs 0xfffffffffffff08b globl @@ -208,7 +208,7 @@ scall vhangup 0xfffffffffffff099 globl scall modify_ldt 0xfffffffffffff09a globl scall pivot_root 0xfffffffffffff09b globl scall _sysctl 0xfffffffffffff09c globl -scall prctl 0xfffffffffffff09d globl +#scall prctl 0xfffffffffffff09d globl # wrapped manually scall sys_arch_prctl 0xfff0a50a5ffff09e globl hidden # sysarch() on bsd scall adjtimex 0xfffffffffffff09f globl scall swapon 0xffffff05520550a7 globl @@ -243,10 +243,10 @@ scall io_getevents 0xfffffffffffff0d0 globl scall io_submit 0xfffffffffffff0d1 globl scall io_cancel 0xfffffffffffff0d2 globl scall lookup_dcookie 0xfffffffffffff0d4 globl -scall sys_epoll_create 0xfffffffffffff0d5 globl -scall sys_epoll_wait 0xfffffffffffff0e8 globl -scall sys_epoll_ctl 0xfffffffffffff0e9 globl -scall getdents 0x18606311020c40d9 globl hidden # four args b/c xnu, getdirentries on xnu, 32-bit on xnu/freebsd, getdents64 on linux, 64-bit on openbsd +scall sys_epoll_create 0xfffffffffffff0d5 globl hidden +scall sys_epoll_wait 0xfffffffffffff0e8 globl hidden +scall sys_epoll_ctl 0xfffffffffffff0e9 globl hidden +scall getdents 0x18606311020c40d9 globl hidden # four args b/c xnu, getdirentries on xnu, 32-bit on xnu/freebsd, a.k.a. getdents64 on linux, 64-bit on openbsd scall set_tid_address 0xfffffffffffff0da globl scall restart_syscall 0xfffffffffffff0db globl scall semtimedop 0xfffffffffffff0dc globl @@ -309,8 +309,8 @@ scall sys_vmsplice 0xfffffffffffff116 globl hidden scall migrate_pages 0xfffffffffffff100 globl # numa numa yay scall move_pages 0xfffffffffffff117 globl # NOTE: We view Red Hat versions as "epochs" for all distros. #──────────────────────RHEL 5.0 LIMIT──────────────────────── # ←┬─ last distro with gplv2 licensed compiler c. 2007 -scall sys_preadv 0x12110b121ffff127 globl hidden # ├─ last distro with system v shell script init -scall sys_pwritev 0x12210c122ffff128 globl hidden # ├─ rob landley unleashes busybox gpl lawsuits +scall sys_preadv 0x12110b121221c127 globl hidden # ├─ last distro with system v shell script init +scall sys_pwritev 0x12210c122221d128 globl hidden # ├─ rob landley unleashes busybox gpl lawsuits scall __sys_utimensat 0x1d3054223ffff118 globl hidden # ├─ python modules need this due to pep513 scall fallocate 0xfffffffffffff11d globl hidden # ├─ end of life 2020-11-30 (extended) scall posix_fallocate 0xffffff212fffffff globl hidden # └─ cosmopolitan supports rhel5+ @@ -318,7 +318,7 @@ scall __sys_accept4 0xfff05d21dffff120 globl hidden # Linux 2.6.28+ scall __sys_dup3 0x1c6066fffffff124 globl hidden # Linux 2.6.27+ scall __sys_pipe2 0x1c506521effff125 globl hidden # Linux 2.6.27+ scall epoll_pwait 0xfffffffffffff119 globl -scall sys_epoll_create1 0xfffffffffffff123 globl +scall sys_epoll_create1 0xfffffffffffff123 globl hidden scall perf_event_open 0xfffffffffffff12a globl scall inotify_init1 0xfffffffffffff126 globl scall rt_tgsigqueueinfo 0xfffffffffffff129 globl @@ -338,7 +338,7 @@ scall name_to_handle_at 0xfffffffffffff12f globl scall open_by_handle_at 0xfffffffffffff130 globl scall clock_adjtime 0xfffffffffffff131 globl scall syncfs 0xfffffffffffff132 globl -scall sendmmsg 0x1dcffffffffff133 globl +#scall sendmmsg 0x1dcffffffffff133 globl scall setns 0xfffffffffffff134 globl scall getcpu 0xfffffffffffff135 globl scall process_vm_readv 0xfffffffffffff136 globl @@ -349,7 +349,7 @@ scall finit_module 0xfffffffffffff139 globl scall sched_setattr 0xfffffffffffff13a globl # ├─ desktop replaced with tablet-first gui inspired by mac os x scall sched_getattr 0xfffffffffffff13b globl # ├─ karen sandler requires systemd init and boot for tablet gui scall renameat2 0xfffffffffffff13c globl # └─ debian founder ian murdock found strangled with vacuum cord -scall seccomp 0xfffffffffffff13d globl +#scall seccomp 0xfffffffffffff13d globl # wrapped manually scall sys_getrandom 0xfff00723321f413e globl hidden # Linux 3.17+ and getentropy() on XNU/OpenBSD, coming to NetBSD in 9.2 scall memfd_create 0xfffffffffffff13f globl # wut scall kexec_file_load 0xfffffffffffff140 globl @@ -373,7 +373,7 @@ scall io_uring_setup 0xfffffffffffff1a9 globl # └─ gnu founder richard sta scall io_uring_enter 0xfffffffffffff1aa globl scall io_uring_register 0xfffffffffffff1ab globl #────────────────────────RHEL CLOUD────────────────────────── # ←┬─ red hat terminates community release of enterprise linux circa 2020 -scall pledge 0xfff06cffffffffff globl # └─ online linux services ban the president of united states of america +scall sys_pledge 0xfff06cffffffffff globl # └─ online linux services ban the president of united states of america scall msyscall 0xfff025ffffffffff globl # The Fifth Bell System Interface, Community Edition @@ -724,7 +724,7 @@ scall rctl_get_limits 0xffffff20ffffffff globl scall rctl_get_racct 0xffffff20dfffffff globl scall rctl_get_rules 0xffffff20efffffff globl scall rctl_remove_rule 0xffffff211fffffff globl -scall recv 0xffffff066fffffff globl +#scall recv 0xffffff066fffffff globl scall rfork 0xffffff0fbfffffff globl scall rtprio 0xffffff0a6fffffff globl scall rtprio_thread 0xffffff1d2fffffff globl @@ -817,7 +817,6 @@ scall __acl_aclcheck_link 0xffffff1acfffffff globl scall __mac_syscall 0xfffffffff217dfff globl scall __acl_set_file 0xffffff15cfffffff globl scall __acl_delete_file 0xffffff15ffffffff globl -scall __syscall 0xfff0c6ffffffffff globl scall _umtx_op 0xffffff1c6fffffff globl scall __semwait_signal_nocancel 0xfffffffff21a7fff globl scall __old_semwait_signal_nocancel 0xfffffffff2173fff globl diff --git a/libc/sysv/systemfive.S b/libc/sysv/systemfive.S index f1ddd4f68..fd37a06f4 100644 --- a/libc/sysv/systemfive.S +++ b/libc/sysv/systemfive.S @@ -16,13 +16,13 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/strace.internal.h" #include "libc/dce.h" -#include "libc/sysv/consts/prot.h" -#include "libc/sysv/consts/nr.h" -#include "libc/sysv/consts/map.h" #include "libc/macros.internal.h" -#include "libc/sysv/consts/prot.h" #include "libc/nexgen32e/macros.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/nr.h" +#include "libc/sysv/consts/prot.h" /* ▄▄▄ ▄▄▄ ▀▓▓▒▄ @@ -102,6 +102,8 @@ __hostos: __systemfive: .quad 0 .endobj __systemfive,globl,hidden +__pid: .quad 0 + .endobj __pid,globl,hidden .previous .privileged @@ -196,27 +198,36 @@ systemfive_xnu: .init.start 300,_init_systemfive push %rbx push %rsi - mov (%rdi),%eax +// Detect the operating system. + mov (%rdi),%eax # __hostos +#if SupportsWindows() || SupportsXnu() || SupportsFreebsd() +// set by libc/ape.S for XNU +// set by libc/crt/crt.S for XNU/FreeBSD +// set by libc/nt/winmain.greg.c for New Technology + test %eax,%eax + jnz _init_systemfive_detected # os is already known +#endif #if SupportsOpenbsd() cmpq $0,(%r15) # OpenBSD has no auxv jnz 0f mov $OPENBSD,%al + jmp _init_systemfive_detected 0: #endif #if SupportsNetbsd() xor %ecx,%ecx -0: cmpq $2014,(%r15,%rcx,8) # NetBSD AT_EXECFN +0: cmpq $2014,(%r15,%rcx,8) # NetBSD's AT_EXECFN jne 1f mov $NETBSD,%al + jmp _init_systemfive_detected 1: cmpq $0,(%r15,%rcx,8) lea 2(%ecx),%ecx jnz 0b 2: #endif - test %eax,%eax - jnz 1f mov $LINUX,%al -1: stosq #→ __hostos +_init_systemfive_detected: + stosq #→ __hostos bsr %eax,%eax mov $_init_systemfive_jmptab,%ebx movzbl (%rbx,%rax),%eax @@ -304,15 +315,52 @@ _init_systemfive_magnums: jnz 3b xchg %rbx,%rax stosq +#ifdef SYSDEBUG + inc %r8d +#endif jmp 2b -5: pop %rdi +5: nop +#ifdef SYSDEBUG + push %rdi + push %rsi + push %r8 + call __describe_os + mov %rax,%rdx + pop %r8 + .weak __stracef + ezlea __stracef,ax + test %rax,%rax + jz 5f + ezlea .Llog,di + mov %r8d,%esi + call *%rax +5: pop %rsi + pop %rdi +#endif /* DEBUGSYS */ + pop %rdi pop %rsi pop %rbx // 𝑠𝑙𝑖𝑑𝑒 .endfn _init_systemfive_magnums +#if SupportsSystemv() +_init_systemfive_pid: + ezlea __hostos,cx + mov (%rcx),%al + mov (%rdi),%eax + testb $WINDOWS|METAL,(%rcx) + jnz 1f + mov __NR_getpid,%eax + syscall +1: stosq + .endfn _init_systemfive_pid +#endif #if SupportsSystemv() && !defined(TINY) -_init_systemfive_stack: # determinism ftw! -#if SupportsWindows() || SupportsMetal() + +// Create a stack with deterministic readable addresses. +// If ape_execve() already created us a stack that meets +// the requirements of STATIC_STACK_SIZE() then we skip. +_init_systemfive_stack: +#if SupportsWindows() || SupportsMetal() || SupportsOpenbsd() testb $WINDOWS|METAL,__hostos(%rip) jnz _init_systemfive_done #endif @@ -321,7 +369,7 @@ _init_systemfive_stack: # determinism ftw! mov __NR_mmap,%eax movabs $ape_stack_vaddr,%rdi mov $ape_stack_memsz,%esi - mov $PROT_READ|PROT_WRITE,%edx + mov $ape_stack_prot,%edx mov $MAP_PRIVATE|MAP_FIXED,%r10d or MAP_ANONYMOUS,%r10d or $-1,%r8d @@ -378,11 +426,13 @@ _init_systemfive_stack: # determinism ftw! // m.p[0].h 32 8 // m.p[0].prot 40 4 // m.p[0].flags 44 4 +// m.p[0].offset 48 8 +// m.p[0].size 56 8 .weak _mmi ezlea _mmi,cx test %rcx,%rcx - push %r9 # save the stack size jz 3f + push %r9 # save the stack size lea -1(%r11,%r9),%r9 # need incl. interval shr $16,%r11 # for the stack range shr $16,%r9 @@ -392,8 +442,9 @@ _init_systemfive_stack: # determinism ftw! orq $-1,32(%rcx) # _mmi.s[0].h mov %edx,40(%rcx) # _mmi.s[0].prot mov %r10d,44(%rcx) # _mmi.s[0].flags -3: pop %r9 # restore stack size - pop %rsi + pop %r9 # restore stack size + mov %r9,56(%rcx) # _mmi.s[0].size +3: pop %rsi pop %rdi leave // switch stacks @@ -498,6 +549,15 @@ syscon_windows:/* .globl syscon_windows #endif +#ifdef SYSDEBUG + .rodata.str1.1 +.Llog: .ascii STRACE_PROLOGUE + .ascii "bell system five system call support" + .asciz " %'u magnums loaded on %s\n" + .previous +#endif /* DEBUGSYS */ + + .weak ape_stack_prot .weak ape_stack_vaddr .weak ape_stack_memsz .weak ape_stack_align diff --git a/libc/sysv/sysv.mk b/libc/sysv/sysv.mk index 1b01db90e..42d389fc7 100644 --- a/libc/sysv/sysv.mk +++ b/libc/sysv/sysv.mk @@ -22,6 +22,7 @@ LIBC_SYSV_ARTIFACTS += LIBC_SYSV_A LIBC_SYSV_A = o/$(MODE)/libc/sysv/sysv.a LIBC_SYSV_A_HDRS = $(filter %.h,$(LIBC_SYSV_A_FILES)) LIBC_SYSV_A_INCS = $(filter %.inc,$(LIBC_SYSV_A_FILES)) +LIBC_SYSV_A_SRCS_C = $(filter %.c,$(LIBC_SYSV_A_FILES)) LIBC_SYSV_A_SRCS_A = $(filter %.s,$(LIBC_SYSV_A_FILES)) LIBC_SYSV_A_SRCS_S = $(filter %.S,$(LIBC_SYSV_A_FILES)) LIBC_SYSV_A_CHECKS = $(LIBC_SYSV_A).pkg @@ -36,15 +37,19 @@ LIBC_SYSV_A_FILES := \ libc/sysv/restorert.S \ libc/sysv/syscall.S \ libc/sysv/systemfive.S \ + libc/sysv/strace.greg.c \ + libc/sysv/describeos.greg.c \ $(wildcard libc/sysv/consts/*) \ $(wildcard libc/sysv/errfuns/*) LIBC_SYSV_A_SRCS = \ $(LIBC_SYSV_A_SRCS_A) \ + $(LIBC_SYSV_A_SRCS_C) \ $(LIBC_SYSV_A_SRCS_S) LIBC_SYSV_A_OBJS = \ $(LIBC_SYSV_A_SRCS_A:%.s=o/$(MODE)/%.o) \ + $(LIBC_SYSV_A_SRCS_C:%.c=o/$(MODE)/%.o) \ $(LIBC_SYSV_A_SRCS_S:%.S=o/$(MODE)/%.o) LIBC_SYSV_A_DEPS := \ diff --git a/libc/testlib/bench.S b/libc/testlib/bench.S index ddc286dd0..8aaca6710 100644 --- a/libc/testlib/bench.S +++ b/libc/testlib/bench.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" .yoink testlib_runallbenchmarks -.source __FILE__ // Decentralized section for benchmark registration. // @@ -30,6 +29,7 @@ .hidden __bench_start,__bench_end .byte 0 .align __SIZEOF_POINTER__ + .underrun __bench_start: .previous/* ... @@ -38,4 +38,5 @@ __bench_start: */.section .piro.relo.sort.bench.3,"aw",@nobits __bench_end: .quad 0 + .overrun .previous diff --git a/libc/testlib/benchrunner.c b/libc/testlib/benchrunner.c index f5051aba2..0b4c57937 100644 --- a/libc/testlib/benchrunner.c +++ b/libc/testlib/benchrunner.c @@ -55,8 +55,10 @@ void testlib_runallbenchmarks(void) { int e; e = errno; _peekall(); - mlockall(MCL_CURRENT); - nice(-1); + if (!IsWindows()) { + mlockall(MCL_CURRENT); + nice(-1); + } errno = e; __log_level = kLogWarn; testlib_runtestcases(__bench_start, __bench_end, testlib_benchwarmup); diff --git a/libc/testlib/blocktronics.S b/libc/testlib/blocktronics.S index 54247a16a..2bbf3ee6c 100644 --- a/libc/testlib/blocktronics.S +++ b/libc/testlib/blocktronics.S @@ -17,15 +17,15 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .rodata // Nontrivial NUL-terminated string test vector. - .align 1 + .underrun kBlocktronics: 0: .incbin "libc/testlib/blocktronics.txt" 1: .byte 0 .endobj kBlocktronics,globl + .overrun .align 8 kBlocktronicsSize: diff --git a/libc/testlib/combo.S b/libc/testlib/combo.S index 2e85aa9a5..c78adbd6b 100644 --- a/libc/testlib/combo.S +++ b/libc/testlib/combo.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Decentralized section for test combo registration. // @@ -29,6 +28,7 @@ .hidden __combo_start,__combo_end .byte 0 .align __SIZEOF_POINTER__ + .underrun __combo_start: .previous/* ... @@ -37,4 +37,5 @@ __combo_start: */.section .piro.relo.sort.combo.3,"aw",@nobits __combo_end: .quad 0 + .overrun .previous diff --git a/libc/testlib/ezbench.h b/libc/testlib/ezbench.h index 789e3e3fe..7f8714343 100644 --- a/libc/testlib/ezbench.h +++ b/libc/testlib/ezbench.h @@ -1,158 +1,171 @@ #ifndef COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_ #define COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_ #include "libc/macros.internal.h" +#include "libc/nexgen32e/bench.h" #include "libc/nexgen32e/x86feature.h" #include "libc/sysv/consts/clock.h" #include "libc/testlib/bench.h" #include "libc/testlib/testlib.h" #include "libc/time/time.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define EZBENCH_COUNT 128 +#define EZBENCH_TRIES 10 #define EZBENCH(INIT, EXPR) EZBENCH2(#EXPR, INIT, EXPR) -#define EZBENCH2(NAME, INIT, EXPR) \ - do { \ - int Core, Tries, Interrupts; \ - int64_t Speculative, MemoryStrict; \ - Tries = 0; \ - do { \ - __testlib_yield(); \ - Core = __testlib_getcore(); \ - Interrupts = __testlib_getinterrupts(); \ - INIT; \ - EXPR; \ - Speculative = BENCHLOOP(__startbench, __endbench, 128, ({ \ - INIT; \ - polluteregisters(); \ - }), \ - (EXPR)); \ - } while (++Tries < 10 && (__testlib_getcore() != Core && \ - __testlib_getinterrupts() > Interrupts)); \ - if (Tries == 10) __testlib_ezbenchwarn(" speculative"); \ - Tries = 0; \ - do { \ - __testlib_yield(); \ - Core = __testlib_getcore(); \ - Interrupts = __testlib_getinterrupts(); \ - INIT; \ - EXPR; \ - MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 32, ({ \ - INIT; \ - thrashcodecache(); \ - polluteregisters(); \ - }), \ - (EXPR)); \ - } while (++Tries < 10 && (__testlib_getcore() != Core && \ - __testlib_getinterrupts() > Interrupts)); \ - if (Tries == 10) __testlib_ezbenchwarn(" memory strict"); \ - __testlib_ezbenchreport( \ - NAME, MAX(0, Speculative - __testlib_ezbenchcontrol()), \ - MAX(0, MemoryStrict - __testlib_ezbenchcontrol())); \ +#define EZBENCH2(NAME, INIT, EXPR) \ + do { \ + int Core, Tries, Interrupts; \ + int64_t Speculative, MemoryStrict; \ + Tries = 0; \ + do { \ + __testlib_yield(); \ + Core = __testlib_getcore(); \ + Interrupts = __testlib_getinterrupts(); \ + INIT; \ + EXPR; \ + Speculative = BENCHLOOP(__startbench, __endbench, EZBENCH_COUNT, ({ \ + INIT; \ + __polluteregisters(); \ + }), \ + (EXPR)); \ + } while (++Tries < EZBENCH_TRIES && \ + (__testlib_getcore() != Core && \ + __testlib_getinterrupts() > Interrupts)); \ + if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" speculative"); \ + Tries = 0; \ + do { \ + __testlib_yield(); \ + Core = __testlib_getcore(); \ + Interrupts = __testlib_getinterrupts(); \ + INIT; \ + EXPR; \ + MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 32, ({ \ + INIT; \ + thrashcodecache(); \ + __polluteregisters(); \ + }), \ + (EXPR)); \ + } while (++Tries < EZBENCH_TRIES && \ + (__testlib_getcore() != Core && \ + __testlib_getinterrupts() > Interrupts)); \ + if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" memory strict"); \ + __testlib_ezbenchreport( \ + NAME, MAX(0, Speculative - __testlib_ezbenchcontrol()), \ + MAX(0, MemoryStrict - __testlib_ezbenchcontrol())); \ } while (0) -#define EZBENCH3(NAME, NUM, INIT, EXPR) \ - do { \ - int Core, Tries, Interrupts; \ - int64_t Speculative, MemoryStrict; \ - Tries = 0; \ - do { \ - __testlib_yield(); \ - Core = __testlib_getcore(); \ - Interrupts = __testlib_getinterrupts(); \ - INIT; \ - EXPR; \ - Speculative = BENCHLOOP(__startbench, __endbench, NUM, ({ \ - INIT; \ - polluteregisters(); \ - }), \ - (EXPR)); \ - } while (++Tries < 10 && (__testlib_getcore() != Core && \ - __testlib_getinterrupts() > Interrupts)); \ - if (Tries == 10) __testlib_ezbenchwarn(" speculative"); \ - Tries = 0; \ - do { \ - __testlib_yield(); \ - Core = __testlib_getcore(); \ - Interrupts = __testlib_getinterrupts(); \ - INIT; \ - EXPR; \ - MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, NUM, ({ \ - INIT; \ - thrashcodecache(); \ - polluteregisters(); \ - }), \ - (EXPR)); \ - } while (++Tries < 10 && (__testlib_getcore() != Core && \ - __testlib_getinterrupts() > Interrupts)); \ - if (Tries == 10) __testlib_ezbenchwarn(" memory strict"); \ - __testlib_ezbenchreport( \ - NAME, MAX(0, Speculative - __testlib_ezbenchcontrol()), \ - MAX(0, MemoryStrict - __testlib_ezbenchcontrol())); \ +#define EZBENCH3(NAME, NUM, INIT, EXPR) \ + do { \ + int Core, Tries, Interrupts; \ + int64_t Speculative, MemoryStrict; \ + Tries = 0; \ + do { \ + __testlib_yield(); \ + Core = __testlib_getcore(); \ + Interrupts = __testlib_getinterrupts(); \ + INIT; \ + EXPR; \ + Speculative = BENCHLOOP(__startbench, __endbench, NUM, ({ \ + INIT; \ + __polluteregisters(); \ + }), \ + (EXPR)); \ + } while (++Tries < EZBENCH_TRIES && \ + (__testlib_getcore() != Core && \ + __testlib_getinterrupts() > Interrupts)); \ + if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" speculative"); \ + Tries = 0; \ + do { \ + __testlib_yield(); \ + Core = __testlib_getcore(); \ + Interrupts = __testlib_getinterrupts(); \ + INIT; \ + EXPR; \ + MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, NUM, ({ \ + INIT; \ + thrashcodecache(); \ + __polluteregisters(); \ + }), \ + (EXPR)); \ + } while (++Tries < EZBENCH_TRIES && \ + (__testlib_getcore() != Core && \ + __testlib_getinterrupts() > Interrupts)); \ + if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" memory strict"); \ + __testlib_ezbenchreport( \ + NAME, MAX(0, Speculative - __testlib_ezbenchcontrol()), \ + MAX(0, MemoryStrict - __testlib_ezbenchcontrol())); \ } while (0) -#define EZBENCH_C(NAME, CONTROL, EXPR) \ - do { \ - int Core, Tries, Interrupts; \ - int64_t Control, Speculative, MemoryStrict; \ - Tries = 0; \ - do { \ - __testlib_yield(); \ - Core = __testlib_getcore(); \ - Interrupts = __testlib_getinterrupts(); \ - Control = BENCHLOOP(__startbench_m, __endbench_m, 128, ({ \ - thrashcodecache(); \ - polluteregisters(); \ - }), \ - (CONTROL)); \ - } while (++Tries < 10 && (__testlib_getcore() != Core && \ - __testlib_getinterrupts() > Interrupts)); \ - if (Tries == 10) __testlib_ezbenchwarn(" control"); \ - Tries = 0; \ - do { \ - __testlib_yield(); \ - Core = __testlib_getcore(); \ - Interrupts = __testlib_getinterrupts(); \ - EXPR; \ - Speculative = BENCHLOOP(__startbench, __endbench, 128, \ - polluteregisters(), (EXPR)); \ - } while (++Tries < 10 && (__testlib_getcore() != Core && \ - __testlib_getinterrupts() > Interrupts)); \ - if (Tries == 10) __testlib_ezbenchwarn(" speculative"); \ - Tries = 0; \ - do { \ - __testlib_yield(); \ - Core = __testlib_getcore(); \ - Interrupts = __testlib_getinterrupts(); \ - EXPR; \ - MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, ({ \ - thrashcodecache(); \ - polluteregisters(); \ - }), \ - (EXPR)); \ - } while (++Tries < 10 && (__testlib_getcore() != Core && \ - __testlib_getinterrupts() > Interrupts)); \ - if (Tries == 10) __testlib_ezbenchwarn(" memory strict"); \ - __testlib_ezbenchreport(NAME, MAX(0, Speculative - Control), \ - MAX(0, MemoryStrict - Control)); \ +#define EZBENCH_C(NAME, CONTROL, EXPR) \ + do { \ + int Core, Tries, Interrupts; \ + int64_t Control, Speculative, MemoryStrict; \ + Tries = 0; \ + do { \ + __testlib_yield(); \ + Core = __testlib_getcore(); \ + Interrupts = __testlib_getinterrupts(); \ + Control = BENCHLOOP(__startbench_m, __endbench_m, EZBENCH_COUNT, ({ \ + thrashcodecache(); \ + __polluteregisters(); \ + }), \ + (CONTROL)); \ + } while (++Tries < EZBENCH_TRIES && \ + (__testlib_getcore() != Core && \ + __testlib_getinterrupts() > Interrupts)); \ + if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" control"); \ + Tries = 0; \ + do { \ + __testlib_yield(); \ + Core = __testlib_getcore(); \ + Interrupts = __testlib_getinterrupts(); \ + EXPR; \ + Speculative = BENCHLOOP(__startbench, __endbench, EZBENCH_COUNT, \ + __polluteregisters(), (EXPR)); \ + } while (++Tries < EZBENCH_TRIES && \ + (__testlib_getcore() != Core && \ + __testlib_getinterrupts() > Interrupts)); \ + if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" speculative"); \ + Tries = 0; \ + do { \ + __testlib_yield(); \ + Core = __testlib_getcore(); \ + Interrupts = __testlib_getinterrupts(); \ + EXPR; \ + MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, ({ \ + thrashcodecache(); \ + __polluteregisters(); \ + }), \ + (EXPR)); \ + } while (++Tries < EZBENCH_TRIES && \ + (__testlib_getcore() != Core && \ + __testlib_getinterrupts() > Interrupts)); \ + if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" memory strict"); \ + __testlib_ezbenchreport(NAME, MAX(0, Speculative - Control), \ + MAX(0, MemoryStrict - Control)); \ } while (0) -#define EZBENCH_N(NAME, N, EXPR) \ - do { \ - int64_t Speculative, Toto; \ - int Core, Tries, Interrupts; \ - Tries = 0; \ - do { \ - __testlib_yield(); \ - Core = __testlib_getcore(); \ - Interrupts = __testlib_getinterrupts(); \ - EXPR; \ - Speculative = \ - BENCHLOOP(__startbench, __endbench, 32, polluteregisters(), (EXPR)); \ - } while (++Tries < 10 && (__testlib_getcore() != Core && \ - __testlib_getinterrupts() > Interrupts)); \ - if (Tries == 10) __testlib_ezbenchwarn(""); \ - __testlib_ezbenchreport_n( \ - NAME, 'n', N, MAX(0, Speculative - __testlib_ezbenchcontrol())); \ +#define EZBENCH_N(NAME, N, EXPR) \ + do { \ + int64_t Speculative, Toto; \ + int Core, Tries, Interrupts; \ + Tries = 0; \ + do { \ + __testlib_yield(); \ + Core = __testlib_getcore(); \ + Interrupts = __testlib_getinterrupts(); \ + EXPR; \ + Speculative = BENCHLOOP(__startbench, __endbench, 32, \ + __polluteregisters(), (EXPR)); \ + } while (++Tries < EZBENCH_TRIES && \ + (__testlib_getcore() != Core && \ + __testlib_getinterrupts() > Interrupts)); \ + if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(""); \ + __testlib_ezbenchreport_n( \ + NAME, 'n', N, MAX(0, Speculative - __testlib_ezbenchcontrol())); \ } while (0) #define EZBENCH_K(NAME, K, EXPR) \ @@ -163,14 +176,14 @@ __testlib_yield(); \ Core = __testlib_getcore(); \ EXPR; \ - Speculative = \ - BENCHLOOP(__startbench, __endbench, 128, donothing, (EXPR)); \ + Speculative = BENCHLOOP(__startbench, __endbench, EZBENCH_COUNT, \ + donothing, (EXPR)); \ } while (Core != __testlib_getcore()); \ __testlib_ezbenchreport_n( \ NAME, 'k', K, MAX(0, Speculative - __testlib_ezbenchcontrol())); \ } while (0) -void polluteregisters(void); +void __polluteregisters(void); void __testlib_yield(void); int __testlib_getcore(void); int64_t __testlib_getinterrupts(void); @@ -189,5 +202,7 @@ void __testlib_ezbenchreport_n(const char *, char, size_t, uint64_t); #define EZBENCH_N(NAME, N, EXPR) (void)0 #define EZBENCH_K(NAME, K, EXPR) (void)0 #endif + +COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_ */ diff --git a/libc/testlib/fixture.S b/libc/testlib/fixture.S index 143a2ee58..68ba56c38 100644 --- a/libc/testlib/fixture.S +++ b/libc/testlib/fixture.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Decentralized section for test fixture registration. // @@ -29,6 +28,7 @@ .hidden __fixture_start,__fixture_end .byte 0 .align __SIZEOF_POINTER__ + .underrun __fixture_start: .previous/* ... @@ -37,4 +37,5 @@ __fixture_start: */.section .piro.relo.sort.fixture.3,"aw",@nobits __fixture_end: .quad 0 + .overrun .previous diff --git a/libc/testlib/formatint.c b/libc/testlib/formatint.c index c3c5cda07..c9ce6c926 100644 --- a/libc/testlib/formatint.c +++ b/libc/testlib/formatint.c @@ -25,7 +25,7 @@ static size_t sbufi_; static char sbufs_[2][256]; -nodiscard testonly char *testlib_formatint(intptr_t x) { +dontdiscard testonly char *testlib_formatint(intptr_t x) { char *str = sbufi_ < ARRAYLEN(sbufs_) ? sbufs_[sbufi_++] : malloc(256); char *p = str; p += sprintf(p, "%ld\t(or %#lx", x, x); diff --git a/libc/testlib/formatrange.c b/libc/testlib/formatrange.c index 479bfa170..dd7e80b4c 100644 --- a/libc/testlib/formatrange.c +++ b/libc/testlib/formatrange.c @@ -19,6 +19,6 @@ #include "libc/testlib/testlib.h" #include "libc/x/x.h" -nodiscard testonly char *testlib_formatrange(intptr_t beg, intptr_t end) { +dontdiscard testonly char *testlib_formatrange(intptr_t beg, intptr_t end) { return xasprintf("[%#ld,%#ld]", beg, end); } diff --git a/libc/testlib/formatstr.c b/libc/testlib/formatstr.c index 5e9a24460..a4b9d533e 100644 --- a/libc/testlib/formatstr.c +++ b/libc/testlib/formatstr.c @@ -24,7 +24,7 @@ /** * Turns string into code. */ -nodiscard testonly char *testlib_formatstr(size_t cw, const void *s, int n) { +dontdiscard testonly char *testlib_formatstr(size_t cw, const void *s, int n) { if (s) { switch (cw) { case 1: diff --git a/libc/testlib/hyperion.S b/libc/testlib/hyperion.S index a28828c66..4e2b1c42e 100644 --- a/libc/testlib/hyperion.S +++ b/libc/testlib/hyperion.S @@ -17,15 +17,15 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .rodata // Nontrivial NUL-terminated string test vector. - .align 1 + .underrun kHyperion: 0: .incbin "libc/testlib/hyperion.txt" 1: .byte 0 .endobj kHyperion,globl + .overrun .align 8 kHyperionSize: diff --git a/libc/testlib/leaks.c b/libc/testlib/leaks.c deleted file mode 100644 index 78f51b2ed..000000000 --- a/libc/testlib/leaks.c +++ /dev/null @@ -1,106 +0,0 @@ -/*-*- 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/bits/bits.h" -#include "libc/intrin/asan.internal.h" -#include "libc/log/libfatal.internal.h" -#include "libc/runtime/internal.h" -#include "libc/runtime/memtrack.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/testlib/testlib.h" - -static bool once; -static bool hasleaks; - -static noasan void CheckLeak(void *x, void *y, size_t n, void *a) { - if (n) { - if (IsAsan()) { - if (__asan_get_heap_size(x)) { - hasleaks = true; - } - } else { - hasleaks = true; - } - } -} - -static noasan void OnMemory(void *x, void *y, size_t n, void *a) { - static int i; - if (n) { - if (++i < 20) { - __printf("%p %,d bytes", x, n); - if (IsAsan()) { - __asan_print_trace(x); - } - __printf("\n"); - } - if (i == 20) { - __printf("etc. etc.\n"); - } - } -} - -static noasan bool HasLeaks(void) { - malloc_inspect_all(CheckLeak, 0); - return hasleaks; -} - -/** - * Tests for memory leaks. - * - * This function needs to call __cxa_finalize(). Therefore any runtime - * services that depend on malloc() cannot be used, after calling this - * function. - */ -noasan void testlib_checkformemoryleaks(void) { - struct mallinfo mi; - if (!cmpxchg(&once, false, true)) { - __printf("testlib_checkformemoryleaks() may only be called once\n"); - exit(1); - } - __cxa_finalize(0); - if (!IsAsan()) { - /* TODO(jart): How can we make this work without ASAN? */ - return; - } - malloc_trim(0); - if (HasLeaks()) { - mi = mallinfo(); - __printf("\n" - "UNFREED MEMORY\n" - "%s\n" - "max allocated space %,*d\n" - "total allocated space %,*d\n" - "total free space %,*d\n" - "releasable space %,*d\n" - "mmaped space %,*d\n" - "non-mmapped space %,*d\n" - "\n", - __argv[0], 16l, mi.usmblks, 16l, mi.uordblks, 16l, mi.fordblks, - 16l, mi.hblkhd, 16l, mi.keepcost, 16l, mi.arena); - if (!IsAsan()) { - __printf("# NOTE: Use `make -j8 MODE=dbg` for malloc() backtraces\n"); - } - malloc_inspect_all(OnMemory, 0); - __printf("\n"); - PrintMemoryIntervals(2, &_mmi); - /* PrintSystemMappings(2); */ - /* PrintGarbage(); */ - _Exit(78); - } -} diff --git a/libc/testlib/moby.S b/libc/testlib/moby.S index c1120154e..62d04645e 100644 --- a/libc/testlib/moby.S +++ b/libc/testlib/moby.S @@ -20,11 +20,12 @@ .rodata // Nontrivial NUL-terminated string test vector. - .align 1 + .underrun kMoby: 0: .incbin "libc/testlib/moby.txt" 1: .byte 0 .endobj kMoby,globl + .overrun .align 8 kMobySize: diff --git a/libc/testlib/polluteregisters.S b/libc/testlib/polluteregisters.S index 7b8a1c1be..62971dc97 100644 --- a/libc/testlib/polluteregisters.S +++ b/libc/testlib/polluteregisters.S @@ -19,15 +19,15 @@ #include "libc/nexgen32e/x86feature.h" #include "libc/macros.internal.h" -polluteregisters: +__polluteregisters: .leafprologue xor %eax,%eax - mov %ecx,%ecx - mov %edx,%edx - mov %r8d,%r8d - mov %r9d,%r9d - mov %r10d,%r10d - mov %r11d,%r11d + xor %ecx,%ecx + xor %edx,%edx + xor %r8d,%r8d + xor %r9d,%r9d + xor %r10d,%r10d + xor %r11d,%r11d testb X86_HAVE(AVX)+kCpuids(%rip) jz .Lsse vpxor %xmm0,%xmm0,%xmm0 @@ -48,13 +48,13 @@ polluteregisters: xorps %xmm6,%xmm6 xorps %xmm7,%xmm7 .leafepilogue - .endfn polluteregisters,globl + .endfn __polluteregisters,globl .end // Fill registers with junk data to create false dependencies. // Which shall create the problem that happens w/o vzeroupper. // Or the Core Architecture errata regarding BSR/BSF w/ 64bit. -polluteregisters: +__polluteregisters: .leafprologue mov $-1,%rax mov %rax,%rcx @@ -92,4 +92,4 @@ polluteregisters: punpcklqdq %xmm0,%xmm6 punpcklqdq %xmm0,%xmm7 .leafepilogue - .endfn polluteregisters,globl + .endfn __polluteregisters,globl diff --git a/libc/testlib/quota.c b/libc/testlib/quota.c index a9ff4bcbe..815e7e994 100644 --- a/libc/testlib/quota.c +++ b/libc/testlib/quota.c @@ -20,6 +20,8 @@ #include "libc/calls/calls.h" #include "libc/calls/sigbits.h" #include "libc/errno.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/backtrace.internal.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" @@ -28,7 +30,7 @@ #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/testlib/testlib.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" +#include "third_party/dlmalloc/dlmalloc.h" static noasan relegated uint64_t CountMappedBytes(void) { size_t i; @@ -43,57 +45,49 @@ static noasan relegated uint64_t CountMappedBytes(void) { static relegated void DieBecauseOfQuota(int rc, const char *message) { int e = errno; char hostname[32]; - __stpcpy(hostname, "unknown"); + stpcpy(hostname, "unknown"); gethostname(hostname, sizeof(hostname)); - __printf("%s on %s pid %d\n", message, hostname, (long)__getpid()); + kprintf("%s on %s pid %d\n", message, hostname, (long)getpid()); PrintBacktraceUsingSymbols(2, 0, GetSymbolTable()); exit(rc); } static relegated void OnXcpu(int sig) { - __restore_tty(2); + __restore_tty(); DieBecauseOfQuota(23, "\n\nSIGXCPU: ran out of cpu"); } static relegated void OnXfsz(int sig) { - __restore_tty(2); + __restore_tty(); DieBecauseOfQuota(25, "\n\nSIGXFSZ: exceeded maximum file size"); } relegated void __oom_hook(size_t request) { int e; uint64_t toto, newlim; - struct MallocStats stats; - __restore_tty(2); + __restore_tty(); e = errno; toto = CountMappedBytes(); - stats = dlmalloc_stats(g_dlmalloc); - __printf("\n\nWE REQUIRE MORE VESPENE GAS"); - if (e != ENOMEM) __printf(" (%s)", strerror(e)); - __printf("\n" - "mmap last request = %d\n" - "mmapped system bytes = %d\n" - "malloc max system bytes = %d\n" - "malloc system bytes = %d\n" - "malloc in use bytes = %d\n" - "\n", - request, toto, stats.maxfp, stats.fp, stats.used); + kprintf("\n\nWE REQUIRE MORE VESPENE GAS"); + if (e != ENOMEM) kprintf(" (%s)", strerror(e)); if (IsRunningUnderMake()) { newlim = toto + request; newlim += newlim >> 1; newlim = roundup2pow(newlim); - __printf("FIX CODE OR TUNE QUOTA += -M%dm\n", newlim / (1024 * 1024)); + kprintf("FIX CODE OR TUNE QUOTA += -M%dm\n", newlim / (1024 * 1024)); } - __printf("\n"); + kprintf("\n"); PrintMemoryIntervals(2, &_mmi); - __printf("\nTHE STRAW THAT BROKE THE CAMEL'S BACK\n"); + kprintf("\nTHE STRAW THAT BROKE THE CAMEL'S BACK\n"); PrintBacktraceUsingSymbols(2, 0, GetSymbolTable()); PrintSystemMappings(2); exit(42); } static textstartup void InstallQuotaHandlers(void) { + int e; struct sigaction sa; + e = errno; sa.sa_flags = 0; sa.sa_handler = OnXcpu; sigemptyset(&sa.sa_mask); @@ -101,6 +95,7 @@ static textstartup void InstallQuotaHandlers(void) { sa.sa_handler = OnXfsz; sigaction(SIGXFSZ, &sa, 0); GetSymbolTable(); /* for effect in case we oom */ + errno = e; } const void *const testlib_quota_handlers[] initarray = { diff --git a/libc/testlib/runner.c b/libc/testlib/runner.c index e21ef413c..868a4e633 100644 --- a/libc/testlib/runner.c +++ b/libc/testlib/runner.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/intrin/kprintf.h" #include "libc/log/log.h" #include "libc/nexgen32e/nexgen32e.h" #include "libc/runtime/runtime.h" diff --git a/libc/testlib/showerror.c b/libc/testlib/showerror.c index 51897d05f..6427501d1 100644 --- a/libc/testlib/showerror.c +++ b/libc/testlib/showerror.c @@ -17,7 +17,9 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/safemacros.internal.h" +#include "libc/calls/calls.h" #include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" #include "libc/log/color.internal.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" @@ -34,18 +36,20 @@ testonly void testlib_showerror(const char *file, int line, const char *func, const char *method, const char *symbol, const char *code, char *v1, char *v2) { char *p; - /* TODO(jart): Pay off tech debt re duplication */ - __getpid(); /* make strace easier to read */ - __getpid(); - __printf("%serror%s%s:%s:%d%s: %s() in %s(%s)\n" - "\t%s\n" - "\t\tneed %s %s\n" - "\t\t got %s\n" - "\t%s%s\n" - "\t%s%s\n", - RED2, UNBOLD, BLUE1, file, (long)line, RESET, method, func, - g_fixturename, code, v1, symbol, v2, SUBTLE, strerror(errno), - program_executable_name, RESET); + char hostname[128]; + if (!IsWindows()) __getpid(); /* make strace easier to read */ + if (!IsWindows()) __getpid(); + __stpcpy(hostname, "unknown"); + gethostname(hostname, sizeof(hostname)); + kprintf("%serror%s%s:%s:%d%s: %s() in %s(%s) on %s\n" + "\t%s\n" + "\t\tneed %s %s\n" + "\t\t got %s\n" + "\t%s%s\n" + "\t%s%s\n", + RED2, UNBOLD, BLUE1, file, (long)line, RESET, method, func, + g_fixturename, hostname, code, v1, symbol, v2, SUBTLE, + strerror(errno), GetProgramExecutableName(), RESET); free_s(&v1); free_s(&v2); } @@ -56,35 +60,36 @@ testonly void testlib_showerror_(int line, const char *wantcode, char *FREED_got, const char *fmt, ...) { int e; va_list va; - char hostname[32]; + char hostname[128]; e = errno; - __getpid(); - __getpid(); - __printf("%serror%s:%s%s:%d%s: %s(%s)\n" - "\t%s(%s, %s)\n", - RED2, UNBOLD, BLUE1, testlib_showerror_file, line, RESET, - testlib_showerror_func, g_fixturename, testlib_showerror_macro, - wantcode, gotcode); + if (!IsWindows()) __getpid(); + if (!IsWindows()) __getpid(); + if (gethostname(hostname, sizeof(hostname))) { + __stpcpy(hostname, "unknown"); + } + kprintf("%serror%s:%s%s:%d%s: %s(%s) on %s\n" + "\t%s(%s, %s)\n", + RED2, UNBOLD, BLUE1, testlib_showerror_file, line, RESET, + testlib_showerror_func, g_fixturename, hostname, + testlib_showerror_macro, wantcode, gotcode); if (wantcode) { - __printf("\t\tneed %s %s\n" - "\t\t got %s\n", - FREED_want, testlib_showerror_symbol, FREED_got); + kprintf("\t\tneed %s %s\n" + "\t\t got %s\n", + FREED_want, testlib_showerror_symbol, FREED_got); } else { - __printf("\t\t→ %s%s\n", testlib_showerror_symbol, FREED_want); + kprintf("\t\t→ %s%s\n", testlib_showerror_symbol, FREED_want); } if (!isempty(fmt)) { - __printf("\t"); + kprintf("\t"); va_start(va, fmt); - __vprintf(fmt, va); + kvprintf(fmt, va); va_end(va); - __printf("\n"); + kprintf("\n"); } - __stpcpy(hostname, "unknown"); - gethostname(hostname, sizeof(hostname)); - __printf("\t%s%s%s\n" - "\t%s%s @ %s%s\n", - SUBTLE, strerror(e), RESET, SUBTLE, program_invocation_name, - hostname, RESET); + kprintf("\t%s%s%s\n" + "\t%s%s @ %s%s\n", + SUBTLE, strerror(e), RESET, SUBTLE, program_invocation_name, hostname, + RESET); free_s(&FREED_want); free_s(&FREED_got); ++g_testlib_failed; diff --git a/libc/testlib/testcase.S b/libc/testlib/testcase.S index e300155f0..b74bc0a90 100644 --- a/libc/testlib/testcase.S +++ b/libc/testlib/testcase.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Decentralized section for test testcase registration. // @@ -29,6 +28,7 @@ .hidden __testcase_start,__testcase_end .byte 0 .align __SIZEOF_POINTER__ + .underrun __testcase_start: .previous/* ... @@ -37,4 +37,5 @@ __testcase_start: */.section .piro.relo.sort.testcase.3,"aw",@nobits __testcase_end: .quad 0 + .overrun .previous diff --git a/libc/testlib/testlib.h b/libc/testlib/testlib.h index 6e3fb3263..f0252c9dc 100644 --- a/libc/testlib/testlib.h +++ b/libc/testlib/testlib.h @@ -114,11 +114,12 @@ void TearDownOnce(void); #define ASSERT_SYS(ERRNO, WANT, GOT, ...) \ do { \ - errno = 0; \ + int e = errno; \ __TEST_EQ(assert, __FILE__, __LINE__, __FUNCTION__, #WANT, #GOT, WANT, \ GOT, __VA_ARGS__); \ __TEST_EQ(assert, __FILE__, __LINE__, __FUNCTION__, #ERRNO, \ strerror(errno), ERRNO, errno, __VA_ARGS__); \ + errno = e; \ } while (0) #define ASSERT_BETWEEN(BEG, END, GOT) \ @@ -352,7 +353,6 @@ void thrashcodecache(void); void testlib_finish(void); void testlib_runalltests(void); void testlib_runallbenchmarks(void); -void testlib_checkformemoryleaks(void); void testlib_runtestcases(testfn_t *, testfn_t *, testfn_t); void testlib_runcombos(testfn_t *, testfn_t *, const struct TestFixture *, const struct TestFixture *); diff --git a/libc/testlib/testlib.mk b/libc/testlib/testlib.mk index fc2274f50..9f71f865d 100644 --- a/libc/testlib/testlib.mk +++ b/libc/testlib/testlib.mk @@ -59,7 +59,6 @@ LIBC_TESTLIB_A_SRCS_C = \ libc/testlib/comborunner.c \ libc/testlib/contains.c \ libc/testlib/endswith.c \ - libc/testlib/leaks.c \ libc/testlib/yield.c \ libc/testlib/ezbenchcontrol.c \ libc/testlib/ezbenchreport.c \ diff --git a/libc/testlib/testmain.c b/libc/testlib/testmain.c index 80c1463e3..05fbb3cd9 100644 --- a/libc/testlib/testmain.c +++ b/libc/testlib/testmain.c @@ -18,25 +18,40 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" #include "libc/bits/safemacros.internal.h" +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/sigset.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/check.h" +#include "libc/log/color.internal.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" +#include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/x86feature.h" #include "libc/runtime/internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" +#include "libc/runtime/sysconf.h" +#include "libc/sock/sock.h" #include "libc/stdio/stdio.h" #include "libc/sysv/consts/ex.h" #include "libc/sysv/consts/exit.h" +#include "libc/sysv/consts/f.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/poll.h" +#include "libc/sysv/consts/rlimit.h" #include "libc/sysv/consts/sig.h" #include "libc/testlib/testlib.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" +#include "third_party/dlmalloc/dlmalloc.h" #include "third_party/getopt/getopt.h" #define USAGE \ @@ -80,28 +95,77 @@ void GetOpts(int argc, char *argv[]) { } } +static void EmptySignalMask(void) { + sigset_t ss; + sigemptyset(&ss); + sigprocmask(SIG_SETMASK, &ss, 0); +} + +static void FixIrregularFds(void) { + int i; + struct pollfd pfds[64]; + for (i = 0; i < 3; ++i) { + if (fcntl(0, F_GETFL) == -1) { + CHECK_EQ(0, open("/dev/null", O_RDWR)); + } + } + for (i = 0; i < ARRAYLEN(pfds); ++i) { + pfds[i].fd = i + 3; + pfds[i].events = POLLIN; + } + if (poll(pfds, ARRAYLEN(pfds), 0) != -1) { + for (i = 0; i < ARRAYLEN(pfds); ++i) { + if (pfds[i].revents & POLLNVAL) continue; + CHECK_EQ(0, close(pfds[i].fd)); + } + } +} + +static void SetLimit(int resource, uint64_t soft, uint64_t hard) { + struct rlimit old; + struct rlimit lim = {soft, hard}; + if (resource == 127) return; + if (setrlimit(resource, &lim) == -1) { + if (!getrlimit(resource, &old)) { + lim.rlim_max = MIN(hard, old.rlim_max); + lim.rlim_cur = MIN(soft, lim.rlim_max); + setrlimit(resource, &lim); + } + } +} + /** * Generic test program main function. */ noasan int main(int argc, char *argv[]) { + unsigned cpus; const char *comdbg; __log_level = kLogInfo; GetOpts(argc, argv); + setenv("GDB", "", true); + + // normalize this process + FixIrregularFds(); + EmptySignalMask(); ShowCrashReports(); + + // now get down to business g_testlib_shoulddebugbreak = IsDebuggerPresent(false); - sys_getpid(); /* make strace easier to read */ + if (!IsWindows()) sys_getpid(); // make strace easier to read testlib_clearxmmregisters(); testlib_runalltests(); if (!g_testlib_failed && runbenchmarks_ && weaken(testlib_runallbenchmarks)) { weaken(testlib_runallbenchmarks)(); if (!g_testlib_failed) { - testlib_checkformemoryleaks(); + CheckForMemoryLeaks(); } if (!g_testlib_failed && IsRunningUnderMake()) { - return 254; /* compile.com considers this 0 and propagates output */ + return 254; // compile.com considers this 0 and propagates output } } else if (!g_testlib_failed) { - testlib_checkformemoryleaks(); + CheckForMemoryLeaks(); } + + // we're done! exit(min(255, g_testlib_failed)); } diff --git a/libc/testlib/testrunner.c b/libc/testlib/testrunner.c index 514d0b757..b9fdfbfda 100644 --- a/libc/testlib/testrunner.c +++ b/libc/testlib/testrunner.c @@ -16,26 +16,39 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/sigset.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/fmt.h" +#include "libc/fmt/itoa.h" +#include "libc/intrin/kprintf.h" #include "libc/log/check.h" -#include "libc/log/libfatal.internal.h" +#include "libc/log/internal.h" #include "libc/macros.internal.h" #include "libc/nt/process.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" +#include "libc/sock/sock.h" #include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/poll.h" +#include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" +#include "libc/sysv/consts/w.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" static int x; char g_testlib_olddir[PATH_MAX]; char g_testlib_tmpdir[PATH_MAX]; +struct sigaction wanthandlers[31]; void testlib_finish(void) { if (g_testlib_failed) { @@ -52,13 +65,12 @@ wontreturn void testlib_abort(void) { static void SetupTmpDir(void) { char *p = g_testlib_tmpdir; - p = __stpcpy(p, "o/tmp/"); - p = __stpcpy(p, program_invocation_short_name), *p++ = '.'; - p = __intcpy(p, __getpid()), *p++ = '.'; - p = __intcpy(p, x++); + p = stpcpy(p, "o/tmp/"); + p = stpcpy(p, program_invocation_short_name), *p++ = '.'; + p = FormatInt64(p, getpid()), *p++ = '.'; + p = FormatInt64(p, x++); p[0] = '\0'; CHECK_NE(-1, makedirs(g_testlib_tmpdir, 0755), "%s", g_testlib_tmpdir); - CHECK_EQ(1, isdirectory(g_testlib_tmpdir), "%s", g_testlib_tmpdir); CHECK_NOTNULL(realpath(g_testlib_tmpdir, g_testlib_tmpdir), "%`'s", g_testlib_tmpdir); CHECK_NE(-1, chdir(g_testlib_tmpdir), "%s", g_testlib_tmpdir); @@ -66,7 +78,93 @@ static void SetupTmpDir(void) { static void TearDownTmpDir(void) { CHECK_NE(-1, chdir(g_testlib_olddir)); - CHECK_NE(-1, rmrf(g_testlib_tmpdir)); + CHECK_NE(-1, rmrf(g_testlib_tmpdir), "%s", g_testlib_tmpdir); +} + +static void DoNothing(int sig) { + // function intentionally empty +} + +static void CopySignalHandlers(void) { +#if 0 + int i; + for (i = 0; i < ARRAYLEN(wanthandlers); ++i) { + if (i + 1 == SIGKILL || i + 1 == SIGSTOP) continue; + CHECK_EQ(0, sigaction(i + 1, 0, wanthandlers + i), "sig=%d", i + 1); + } +#endif +} + +static void CheckSignalHandler(int sig) { +#if 0 + int i; + struct sigaction sa = {0}; + assert(0 <= sig - 1 && sig - 1 < ARRAYLEN(wanthandlers)); + CHECK_EQ(0, sigaction(sig, 0, &sa)); + CHECK_EQ(0, memcmp(wanthandlers + sig - 1, &sa, sizeof(sa)), + "signal handler for %s was %p/%#x/%#x:%x " + "but should have been restored to %p/%#x/%#x:%x", + strsignal(sig), sa.sa_handler, sa.sa_flags, sa.sa_mask.__bits[0], + sa.sa_mask.__bits[1], wanthandlers[sig - 1].sa_handler, + wanthandlers[sig - 1].sa_flags, + wanthandlers[sig - 1].sa_mask.__bits[0], + wanthandlers[sig - 1].sa_mask.__bits[1]); +#endif +} + +static void CheckForSignalHandlers(void) { +#if 0 + CheckSignalHandler(SIGINT); + CheckSignalHandler(SIGQUIT); + CheckSignalHandler(SIGCHLD); + CheckSignalHandler(SIGFPE); + CheckSignalHandler(SIGILL); + CheckSignalHandler(SIGSEGV); + CheckSignalHandler(SIGTRAP); + CheckSignalHandler(SIGABRT); + CheckSignalHandler(SIGBUS); + CheckSignalHandler(SIGSYS); + CheckSignalHandler(SIGWINCH); +#endif +} + +static void CheckForFileDescriptors(void) { +#if 0 + // TODO: race condition on fd cleanup :'( + int i; + struct pollfd pfds[16]; + if (!weaken(open) && !weaken(socket)) return; + for (i = 0; i < ARRAYLEN(pfds); ++i) { + pfds[i].fd = i + 3; + pfds[i].events = POLLIN; + } + if (poll(pfds, ARRAYLEN(pfds), 0) > 0) { + for (i = 0; i < ARRAYLEN(pfds); ++i) { + if (pfds[i].revents & POLLNVAL) continue; + ++g_testlib_failed; + fprintf(stderr, "error: test failed to close() fd %d\n", pfds[i].fd); + } + } +#endif +} + +static void CheckForZombies(void) { +#if 0 + int e, pid; + sigset_t ss, oldss; + struct sigaction oldsa; + struct sigaction ignore = {.sa_handler = DoNothing}; + if (!weaken(fork)) return; + for (;;) { + if ((pid = wait(0)) == -1) { + CHECK_EQ(ECHILD, errno); + break; + } else { + ++g_testlib_failed; + fprintf(stderr, "error: test failed to reap zombies %d\n", pid); + } + } +#endif } /** @@ -90,6 +188,7 @@ testonly void testlib_runtestcases(testfn_t *start, testfn_t *end, * @see ape/ape.lds */ const testfn_t *fn; + CopySignalHandlers(); CHECK_NOTNULL(getcwd(g_testlib_olddir, sizeof(g_testlib_olddir))); if (weaken(testlib_enable_tmp_setup_teardown_once)) SetupTmpDir(); if (weaken(SetUpOnce)) weaken(SetUpOnce)(); @@ -98,13 +197,16 @@ testonly void testlib_runtestcases(testfn_t *start, testfn_t *end, if (weaken(SetUp)) weaken(SetUp)(); errno = 0; SetLastError(0); - sys_getpid(); + if (!IsWindows()) sys_getpid(); if (warmup) warmup(); testlib_clearxmmregisters(); (*fn)(); - sys_getpid(); + if (!IsWindows()) sys_getpid(); if (weaken(TearDown)) weaken(TearDown)(); if (weaken(testlib_enable_tmp_setup_teardown)) TearDownTmpDir(); + CheckForFileDescriptors(); + CheckForSignalHandlers(); + CheckForZombies(); } if (weaken(TearDownOnce)) weaken(TearDownOnce)(); if (weaken(testlib_enable_tmp_setup_teardown_once)) TearDownTmpDir(); diff --git a/libc/testlib/thrashcodecache.S b/libc/testlib/thrashcodecache.S index e917a7853..171db6cea 100644 --- a/libc/testlib/thrashcodecache.S +++ b/libc/testlib/thrashcodecache.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .testonly // Empties L1 instruction cache. diff --git a/libc/testlib/thunks/assert_eq.S b/libc/testlib/thunks/assert_eq.S index a9b36c4d4..0a20900ef 100644 --- a/libc/testlib/thunks/assert_eq.S +++ b/libc/testlib/thunks/assert_eq.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_assert_eq: diff --git a/libc/testlib/thunks/assert_false.S b/libc/testlib/thunks/assert_false.S index 76dc877de..f7bc2cd87 100644 --- a/libc/testlib/thunks/assert_false.S +++ b/libc/testlib/thunks/assert_false.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_assert_false: diff --git a/libc/testlib/thunks/assert_ne.S b/libc/testlib/thunks/assert_ne.S index 9181df215..850eca544 100644 --- a/libc/testlib/thunks/assert_ne.S +++ b/libc/testlib/thunks/assert_ne.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_assert_ne: diff --git a/libc/testlib/thunks/assert_true.S b/libc/testlib/thunks/assert_true.S index 0ca3685ea..4389957c5 100644 --- a/libc/testlib/thunks/assert_true.S +++ b/libc/testlib/thunks/assert_true.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_assert_true: diff --git a/libc/testlib/thunks/expect_eq.S b/libc/testlib/thunks/expect_eq.S index ef5c8ece0..b703f4bcd 100644 --- a/libc/testlib/thunks/expect_eq.S +++ b/libc/testlib/thunks/expect_eq.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_expect_eq: diff --git a/libc/testlib/thunks/expect_false.S b/libc/testlib/thunks/expect_false.S index afe059894..900f8bd1d 100644 --- a/libc/testlib/thunks/expect_false.S +++ b/libc/testlib/thunks/expect_false.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_expect_false: diff --git a/libc/testlib/thunks/expect_ne.S b/libc/testlib/thunks/expect_ne.S index ea191ebf7..55ba142de 100644 --- a/libc/testlib/thunks/expect_ne.S +++ b/libc/testlib/thunks/expect_ne.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_expect_ne: diff --git a/libc/testlib/thunks/expect_true.S b/libc/testlib/thunks/expect_true.S index 5366b5bec..3f2953b3d 100644 --- a/libc/testlib/thunks/expect_true.S +++ b/libc/testlib/thunks/expect_true.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_expect_true: diff --git a/libc/testlib/thunks/free.S b/libc/testlib/thunks/free.S index 9b2ae53c0..5af1a57e1 100644 --- a/libc/testlib/thunks/free.S +++ b/libc/testlib/thunks/free.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Delegates to free(). // diff --git a/libc/testlib/thunks/jump.S b/libc/testlib/thunks/jump.S index 76bba4729..5c23a9010 100644 --- a/libc/testlib/thunks/jump.S +++ b/libc/testlib/thunks/jump.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .text.unlikely testlib_showerror_jump: diff --git a/libc/thread/clone.c b/libc/thread/clone.c new file mode 100644 index 000000000..616f63712 --- /dev/null +++ b/libc/thread/clone.c @@ -0,0 +1,395 @@ +/*-*- 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/bits/asmflag.h" +#include "libc/bits/weaken.h" +#include "libc/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/ucontext-netbsd.internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/asan.internal.h" +#include "libc/intrin/spinlock.h" +#include "libc/intrin/tls.h" +#include "libc/intrin/winthread.internal.h" +#include "libc/mem/mem.h" +#include "libc/nexgen32e/nt2sysv.h" +#include "libc/nexgen32e/stackframe.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thread.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/clone.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" +#include "libc/thread/freebsd.internal.h" +#include "libc/thread/openbsd.internal.h" + +// TODO(jart): work in progress + +STATIC_YOINK("gettid"); // for kprintf() + +#define __NR_thr_new 455 +#define __NR_sys___tfork 8 +#define __NR_clone_linux 56 +#define __NR__lwp_create 309 +#define __NR_getcontext_netbsd 307 +#define __NR__lwp_setprivate 317 + +extern bool __threaded; + +static struct Cloner { + _Alignas(64) char lock; + _Alignas(64) int flags; + int64_t tid; + int (*func)(void *); + void *arg; + void *stack; + int *ctid; + int *ptid; +} __cloner; + +static textwindows uint32_t WinThreadMain(void *notused) { + int (*func)(void *); + void *arg, *stack; + struct WinThread *wt; + int exitcode, tid, flags, *ctid; + tid = __cloner.tid; + arg = __cloner.arg; + func = __cloner.func; + ctid = __cloner.ctid; + flags = __cloner.flags; + stack = __cloner.stack; + _spunlock(&__cloner.lock); + wt = calloc(1, sizeof(struct WinThread)); + wt->pid = tid; + TlsSetValue(__winthread, wt); + if (flags & CLONE_CHILD_SETTID) *ctid = tid; + asm volatile("mov\t%%rbp,%%rbx\n\t" + "mov\t%%rsp,%%r15\n\t" + "xor\t%%ebp,%%ebp\n\t" + "xchg\t%%rax,%%rsp\n\t" + "call\t*%2\n\t" + "mov\t%%rbx,%%rbp\n\t" + "mov\t%%r15,%%rsp" + : "=a"(exitcode) + : "0"(stack), "d"(func), "D"(arg) + : "rbx", "r15", "memory"); + if (flags & CLONE_CHILD_CLEARTID) *ctid = 0; + __releasefd(tid); + free(wt); + return exitcode; +} + +static textwindows int CloneWindows(int (*func)(void *), void *stk, + size_t stksz, int flags, void *arg, + int *ptid, void *tls, size_t tlssz, + int *ctid) { + int tid; + int64_t hand; + uint32_t wintid; + if ((tid = __reservefd(-1)) == -1) return -1; + _spinlock(&__cloner.lock); + __cloner.tid = tid; + __cloner.arg = arg; + __cloner.func = func; + __cloner.ctid = ctid; + __cloner.flags = flags; + __cloner.stack = (char *)stk + stksz; + if (!(hand = CreateThread(&kNtIsInheritable, 0, NT2SYSV(WinThreadMain), 0, 0, + &wintid))) { + _spunlock(&__cloner.lock); + return -1; + } + if (flags & CLONE_CHILD_SETTID) *ctid = tid; + if (flags & CLONE_PARENT_SETTID) *ptid = tid; + // XXX: this should be tracked in a separate data structure + g_fds.p[tid].kind = kFdProcess; + g_fds.p[tid].handle = hand; + g_fds.p[tid].flags = O_CLOEXEC; + g_fds.p[tid].zombie = false; + return tid; +} + +static dontinline wontreturn void BsdThreadMain(void *unused) { + void *arg; + int (*func)(void *); + int tid, flags, exitcode, *ctid; + tid = __cloner.tid; + arg = __cloner.arg; + func = __cloner.func; + ctid = __cloner.ctid; + flags = __cloner.flags; + _spunlock(&__cloner.lock); + if (flags & CLONE_CHILD_SETTID) *ctid = tid; + exitcode = func(arg); + if (flags & CLONE_CHILD_CLEARTID) *ctid = 0; + _Exit1(exitcode); +} + +static privileged noasan int CloneFreebsd(int (*func)(void *), void *stk, + size_t stksz, int flags, void *arg, + int *ptid, void *tls, size_t tlssz, + int *ctid) { + int ax; + bool failed; + int64_t tid; + struct thr_param params = {0}; + _spinlock(&__cloner.lock); + __cloner.arg = arg; + __cloner.func = func; + __cloner.ctid = ctid; + __cloner.flags = flags; + params.start_func = BsdThreadMain; + params.stack_base = stk; + params.stack_size = stksz; + params.tls_base = flags & CLONE_SETTLS ? tls : 0; + params.tls_size = flags & CLONE_SETTLS ? tlssz : 0; + params.child_tid = &__cloner.tid; + params.parent_tid = &tid; + asm volatile(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(failed), "=a"(ax) + : "1"(__NR_thr_new), "D"(¶ms), "S"(sizeof(params)) + : "rcx", "r11", "memory", "cc"); + if (!failed) { + if (flags & CLONE_PARENT_SETTID) *ptid = tid; + return tid; + } else { + errno = ax; + return -1; + } +} + +static privileged noasan int CloneOpenbsd(int (*func)(void *), char *stk, + size_t stksz, int flags, void *arg, + int *ptid, void *tls, size_t tlssz, + int *ctid) { + int ax; + bool failed; + struct __tfork params; + _spinlock(&__cloner.lock); + __cloner.arg = arg; + __cloner.func = func; + __cloner.ctid = ctid; + __cloner.flags = flags; + __cloner.tid = 0; + asm volatile("" ::: "memory"); + params.tf_tid = (int *)&__cloner.tid; + params.tf_tcb = flags & CLONE_SETTLS ? tls : 0; + params.tf_stack = stk + stksz; + asm volatile(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(failed), "=a"(ax) + : "1"(__NR_sys___tfork), "D"(¶ms), "S"(sizeof(params)) + : "rcx", "r11", "memory", "cc"); + if (!failed) { + if (!ax) { + // this is the child thread + // we probably can't access local variables anymore + asm volatile("" ::: "memory"); + BsdThreadMain(0); + unreachable; + } else { + if (flags & CLONE_PARENT_SETTID) *ptid = ax; + return ax; + } + } else { + errno = ax; + return -1; + } +} + +static privileged noasan int CloneNetbsd(int (*func)(void *), void *stk, + size_t stksz, int flags, void *arg, + int *ptid, void *tls, size_t tlssz, + int *ctid) { + int ax, tid; + bool failed; + intptr_t *stack; + struct ucontext_netbsd ctx; + asm volatile(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(failed), "=a"(ax) + : "1"(__NR_getcontext_netbsd), "D"(&ctx) + : "rcx", "r11", "memory", "cc"); + if (failed) { + errno = ax; + return -1; + } + stack = (void *)(((long)((char *)stk + stksz) & -16) - 8 * 3); + *(long *)stack = (long)_Exit1; + ctx.uc_link = 0; + ctx.uc_mcontext.rip = (intptr_t)func; + ctx.uc_mcontext.rdi = (intptr_t)arg; + ctx.uc_mcontext.rsp = (intptr_t)stack; + ctx.uc_mcontext.rbp = 0; + ctx.uc_flags |= _UC_STACK; + ctx.uc_stack.ss_sp = stk; + ctx.uc_stack.ss_size = stksz; + ctx.uc_stack.ss_flags = 0; + if (flags & CLONE_SETTLS) { + ctx.uc_flags |= _UC_TLSBASE; + ctx.uc_mcontext._mc_tlsbase = (intptr_t)tls; + } + asm volatile("" ::: "memory"); + asm volatile(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(failed), "=a"(ax) + : "1"(__NR__lwp_create), "D"(&ctx), "S"(flags), "d"(&tid) + : "rcx", "r11", "memory", "cc"); + if (failed) { + errno = ax; + return -1; + } + if (flags & CLONE_PARENT_SETTID) *ptid = ax; + if (flags & CLONE_CHILD_SETTID) *ctid = ax; + return tid; +} + +static privileged int CloneLinux(int (*func)(void *), void *stk, size_t stksz, + int flags, void *arg, int *ptid, void *tls, + size_t tlssz, int *ctid) { + int ax; + bool failed; + register int *r8 asm("r8") = tls; + register int (*r9)(void *) asm("r9") = func; + register int *r10 asm("r10") = ctid; + stk = (void *)(((long)((char *)stk + stksz) & -16) - 8); + *(long *)stk = (long)arg; + asm volatile("syscall" + : "=a"(ax) + : "0"(__NR_clone_linux), "D"(flags), "S"(stk), "d"(ptid), + "r"(r10), "r"(r8), "r"(r9) + : "rcx", "r11", "memory"); + if (ax > -4096u) { + errno = -ax; + return -1; + } + if (ax) return ax; + asm volatile("xor\t%%ebp,%%ebp\n\t" + "pop\t%%rdi\n\t" + "call\t%0\n\t" + "xchg\t%%eax,%%edi\n\t" + "jmp\t_Exit1" + : /* no outputs */ + : "r"(r9) + : "memory"); + unreachable; +} + +/** + * Creates thread. + * + * This function follows the same ABI convention as the Linux userspace + * libraries, with a few small changes. The varargs has been removed to + * help prevent broken code, and the stack size and tls size parameters + * are introduced for compatibility with FreeBSD. + * + * @param func is your callback function + * @param stk points to the bottom of a caller allocated stack, which + * must be null when fork() and vfork() equivalent flags are used + * @param stksz is the size of that stack in bytes which must be zero + * if the fork() or vfork() equivalent flags are used it's highly + * recommended that this value be GetStackSize(), or else kprintf + * and other runtime services providing memory safety can't do as + * good and quick of a job at that + * @param flags usually has one of + * - `SIGCHLD` will delegate to fork() + * - `CLONE_VFORK|CLONE_VM|SIGCHLD` means vfork() + * - `CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND` for threads + * as part high bytes, and the low order byte may optionally contain + * a signal e.g. SIGCHLD, to enable parent notification on terminate + * although the signal isn't supported on non-Linux and non-NetBSD + * at the moment; 'flags' may optionally bitwise or the following: + * - `CLONE_PARENT_SETTID` is needed for `ctid` should be set + * - `CLONE_CHILD_SETTID` is needed for `ptid` should be set + * - `CLONE_SETTLS` is needed to set `%fs` segment to `tls` + * @param arg will be passed to your callback + * @param ptid lets the parent receive the child thread id; + * this parameter is ignored if `CLONE_PARENT_SETTID` is not set + * @param tls may be used to set the thread local storage segment; + * this parameter is ignored if `CLONE_SETTLS` is not set + * @param tlssz is the size of tls in bytes + * @param ctid lets the child receive its thread id; + * this parameter is ignored if `CLONE_CHILD_SETTID` is not set + * @return tid on success and 0 to the child, otherwise -1 w/ errno + * @returnstwice + * @threadsafe + */ +privileged int clone(int (*func)(void *), void *stk, size_t stksz, int flags, + void *arg, int *ptid, void *tls, size_t tlssz, int *ctid) { + int rc; + __threaded = true; + if (IsAsan() && + (!__asan_is_valid(stk, stksz) || + ((flags & CLONE_SETTLS) && !__asan_is_valid(tls, tlssz)) || + ((flags & CLONE_SETTLS) && !__asan_is_valid(tls, sizeof(long))) || + ((flags & CLONE_PARENT_SETTID) && + !__asan_is_valid(ptid, sizeof(*ptid))) || + ((flags & CLONE_CHILD_SETTID) && + !__asan_is_valid(ctid, sizeof(*ctid))))) { + rc = efault(); + } else if (IsLinux()) { + rc = CloneLinux(func, stk, stksz, flags, arg, ptid, tls, tlssz, ctid); + } else if (IsNetbsd()) { + rc = CloneNetbsd(func, stk, stksz, flags, arg, ptid, tls, tlssz, ctid); + } + + // polyfill fork() and vfork() use case on platforms w/o clone + else if (flags == (CLONE_VFORK | CLONE_VM | SIGCHLD)) { + if (IsTiny()) { + rc = einval(); + } else if (!arg && !stksz) { + return vfork(); // don't log clone() + } else { + rc = einval(); + } + } else if (flags == SIGCHLD) { + if (IsTiny()) { + rc = eopnotsupp(); + } else if (!arg && !stksz) { + return fork(); // don't log clone() + } else { + rc = einval(); + } + } + + // we now assume we're creating a thread + // these platforms can't do signals the way linux does + else if ((flags & + ~(CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_SETTID)) != + (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)) { + rc = einval(); + } else if (IsFreebsd()) { + rc = CloneFreebsd(func, stk, stksz, flags, arg, ptid, tls, tlssz, ctid); + } else if (IsOpenbsd()) { + rc = CloneOpenbsd(func, stk, stksz, flags, arg, ptid, tls, tlssz, ctid); + } + + // These platforms can't do segment registers like linux does + else if (flags & CLONE_SETTLS) { + rc = einval(); + } else if (IsWindows()) { + rc = CloneWindows(func, stk, stksz, flags, arg, ptid, tls, tlssz, ctid); + } else { + rc = enosys(); + } + + STRACE("clone(%p, %p, %'zu, %#x, %p, %p, %p, %'zu, %p) → %d% m", func, stk, + stksz, flags, arg, ptid, tls, tlssz, ctid, rc); + return rc; +} diff --git a/libc/thread/exit.c b/libc/thread/exit.c index c2cf0c578..268514128 100644 --- a/libc/thread/exit.c +++ b/libc/thread/exit.c @@ -16,28 +16,31 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/sysv/consts/nr.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/lockxadd.h" +#include "libc/runtime/runtime.h" #include "libc/thread/descriptor.h" #include "libc/thread/exit.h" #include "libc/thread/self.h" +/** + * Exits cosmopolitan thread. + * + * @param rc is exit code + * @see _Exit1() for the raw system call + * @threadsafe + * @noreturn + */ wontreturn void cthread_exit(int rc) { - cthread_t td = cthread_self(); + cthread_t td; + STRACE("cthread_exit(%d)", rc); + td = cthread_self(); td->rc = rc; - size_t size = (intptr_t)(td->alloc.top) - (intptr_t)(td->alloc.bottom); - - int state; - asm volatile("lock xadd\t%1, %0\n\t" // mark thread as finished - "test\t%2, %b1\n\t" // test if thread was detached - "jz .L.cthread_exit.%=\n\t" // skip unmap if not detached - "syscall\n" // unmap thread - ".L.cthread_exit.%=:\n\t" - "mov\t%%rbx, %%rdi\n\t" // rc - "mov\t$60, %%rax\n\t" - "syscall" // thread exit - : "+m"(td->state), "=&r"(state) - : "I"(cthread_detached), "1"(cthread_finished), "a"(__NR_munmap), - "b"(rc), "D"(td->alloc.bottom), "S"(size) - : "rcx", "r11", "cc", "memory"); - unreachable; + _lockxadd(&td->state, cthread_finished); + if (~td->state & cthread_detached) { + sys_munmap(td->alloc.bottom, + (intptr_t)td->alloc.top - (intptr_t)td->alloc.bottom); + } + _Exit1(rc); } diff --git a/libc/thread/freebsd.internal.h b/libc/thread/freebsd.internal.h new file mode 100644 index 000000000..e92180099 --- /dev/null +++ b/libc/thread/freebsd.internal.h @@ -0,0 +1,47 @@ +#ifndef COSMOPOLITAN_LIBC_THREAD_FREEBSD_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_THREAD_FREEBSD_INTERNAL_H_ +#include "libc/bits/asmflag.h" +#include "libc/calls/struct/timespec.h" +#include "libc/errno.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * @fileoverview FreeBSD Threading + * + * @note even though FreeBSD uses a 64-bit type for thread IDs the + * maximum legal range is PID_MAX + 2 (100001) through INT_MAX + */ + +struct rtprio { + uint16_t type; /* scheduling class */ + uint16_t prio; +}; + +struct thr_param { + void (*start_func)(void *); + void *arg; + char *stack_base; + uint64_t stack_size; + char *tls_base; + uint64_t tls_size; + int64_t *child_tid; + int64_t *parent_tid; + int32_t flags; + struct rtprio *rtp; +}; + +static inline int thr_new(struct thr_param *param, int param_size) { + bool failed; + long ax, di, si; + asm volatile(CFLAG_ASM("syscall") + : CFLAG_CONSTRAINT(failed), "=a"(ax), "=D"(di), "=S"(si) + : "1"(455), "2"(param), "3"(param_size) + : "rcx", "rdx", "r8", "r9", "r10", "r11", "memory"); + if (failed) ax = -ax; + return ax; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_THREAD_FREEBSD_INTERNAL_H_ */ diff --git a/libc/thread/openbsd.internal.h b/libc/thread/openbsd.internal.h new file mode 100644 index 000000000..2c89f5d4f --- /dev/null +++ b/libc/thread/openbsd.internal.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_THREAD_OPENBSD_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_THREAD_OPENBSD_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct __tfork { + void *tf_tcb; + int32_t *tf_tid; + void *tf_stack; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_THREAD_OPENBSD_INTERNAL_H_ */ diff --git a/libc/thread/sem.c b/libc/thread/sem.c index 5d005cdb8..e1b5bfa81 100644 --- a/libc/thread/sem.c +++ b/libc/thread/sem.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/atomic.h" +#include "libc/intrin/atomic_load.h" #include "libc/thread/sem.h" #include "libc/thread/wait.h" #include "libc/thread/yield.h" @@ -26,7 +27,7 @@ static void pause(int attempt) { if (attempt < 16) { for (int i = 0; i < (1 << attempt); ++i) { - asm("pause"); + __builtin_ia32_pause(); } } else { cthread_yield(); @@ -37,6 +38,7 @@ int cthread_sem_init(cthread_sem_t* sem, int count) { sem->linux.count = count; return 0; } + int cthread_sem_destroy(cthread_sem_t* sem) { (void)sem; return 0; @@ -44,7 +46,7 @@ int cthread_sem_destroy(cthread_sem_t* sem) { int cthread_sem_signal(cthread_sem_t* sem) { uint64_t count; - asm volatile("lock xadd\t%1, %0" + asm volatile("lock xadd\t%1,%0" : "+m"(sem->linux.count), "=r"(count) : "1"(1) : "cc"); @@ -62,7 +64,7 @@ int cthread_sem_wait_futex(cthread_sem_t* sem, const struct timespec* timeout) { uint64_t count; // record current thread as waiter - asm volatile("lock xadd\t%1, %0" + asm volatile("lock xadd\t%1,%0" : "+m"(sem->linux.count), "=r"(count) : "1"((uint64_t)1 << CTHREAD_THREAD_VAL_BITS) : "cc"); @@ -77,7 +79,7 @@ int cthread_sem_wait_futex(cthread_sem_t* sem, const struct timespec* timeout) { return 0; } } - + // WARNING: an offset of 4 bytes would be required on little-endian archs void* wait_address = &sem->linux.count; cthread_memory_wait32(wait_address, count, timeout); @@ -91,16 +93,17 @@ int cthread_sem_wait_spin(cthread_sem_t* sem, uint64_t count, int spin, const struct timespec* timeout) { // spin on pause for (int attempt = 0; attempt < spin; ++attempt) { - //if ((count >> CTHREAD_THREAD_VAL_BITS) != 0) break; + // if ((count >> CTHREAD_THREAD_VAL_BITS) != 0) break; while ((uint32_t)count > 0) { - // spin is useful if multiple waiters can acquire the semaphore at the same time + // spin is useful if multiple waiters can acquire the semaphore at the + // same time if (atomic_compare_exchange_weak(&sem->linux.count, count, count - 1)) { return 0; } } pause(attempt); } - + return cthread_sem_wait_futex(sem, timeout); } @@ -110,11 +113,12 @@ int cthread_sem_wait(cthread_sem_t* sem, int spin, // uncontended while ((uint32_t)count > 0) { - // spin is useful if multiple waiters can acquire the semaphore at the same time + // spin is useful if multiple waiters can acquire the semaphore at the same + // time if (atomic_compare_exchange_weak(&sem->linux.count, count, count - 1)) { return 0; } } - + return cthread_sem_wait_spin(sem, count, spin, timeout); } diff --git a/libc/thread/thread.mk b/libc/thread/thread.mk index 137c3e001..ee0d6ddb1 100644 --- a/libc/thread/thread.mk +++ b/libc/thread/thread.mk @@ -28,6 +28,7 @@ LIBC_THREAD_A_DIRECTDEPS = \ LIBC_CALLS \ LIBC_INTRIN \ LIBC_BITS \ + LIBC_MEM \ LIBC_RUNTIME \ LIBC_SYSV \ LIBC_SYSV_CALLS \ @@ -36,7 +37,8 @@ LIBC_THREAD_A_DIRECTDEPS = \ LIBC_THREAD_A_DEPS := \ $(call uniq,$(foreach x,$(LIBC_THREAD_A_DIRECTDEPS),$($(x)))) -$(LIBC_THREAD_A): libc/thread/ \ +$(LIBC_THREAD_A): \ + libc/thread/ \ $(LIBC_THREAD_A).pkg \ $(LIBC_THREAD_A_OBJS) @@ -44,6 +46,10 @@ $(LIBC_THREAD_A).pkg: \ $(LIBC_THREAD_A_OBJS) \ $(foreach x,$(LIBC_THREAD_A_DIRECTDEPS),$($(x)_A).pkg) +o/$(MODE)/libc/thread/clone.o: \ + OVERRIDE_CFLAGS += \ + -mno-red-zone + LIBC_THREAD_LIBS = $(foreach x,$(LIBC_THREAD_ARTIFACTS),$($(x))) LIBC_THREAD_SRCS = $(foreach x,$(LIBC_THREAD_ARTIFACTS),$($(x)_SRCS)) LIBC_THREAD_HDRS = $(foreach x,$(LIBC_THREAD_ARTIFACTS),$($(x)_HDRS)) diff --git a/libc/thread/xnu.internal.h b/libc/thread/xnu.internal.h new file mode 100644 index 000000000..04b530704 --- /dev/null +++ b/libc/thread/xnu.internal.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_THREAD_XNU_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_THREAD_XNU_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * XNU thread system calls. + * @see darwin-libpthread/kern/kern_support.c + */ + +void *bsdthread_create(void *func, void *func_arg, void *stack, void *pthread, + uint32_t flags); +int bsdthread_terminate(void *stackaddr, size_t freesize, uint32_t port, + uint32_t sem); +int bsdthread_register(void *threadstart, void *wqthread, uint32_t flags, + void *stack_addr_hint, void *targetconc_ptr, + uint32_t dispatchqueue_offset, uint32_t tsd_offset); +int bsdthread_ctl(void *cmd, void *arg1, void *arg2, void *arg3); +uint64_t thread_selfid(void); +uint64_t thread_selfusage(void); +int thread_selfcounts(int type, void *buf, uint64_t nbytes); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_THREAD_XNU_INTERNAL_H_ */ diff --git a/libc/time/asctime.c b/libc/time/asctime.c index b17b44e6f..c076e59f1 100644 --- a/libc/time/asctime.c +++ b/libc/time/asctime.c @@ -1,31 +1,114 @@ -/*-*- 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 "libc/fmt/fmt.h" #include "libc/time/time.h" +#include "libc/time/tz.internal.h" +// clang-format off +/* asctime and asctime_r a la POSIX and ISO C, except pad years before 1000. */ -static char g_asctime_buf[64]; +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ -/** - * Converts date time to string. - * - * @return date time string in statically allocated buffer - * @see asctime_r for reentrant version - */ -char *asctime(const struct tm *date) { - return asctime_r(date, g_asctime_buf); +/* +** Avoid the temptation to punt entirely to strftime; +** the output of strftime is supposed to be locale specific +** whereas the output of asctime is supposed to be constant. +*/ + +/* +** Some systems only handle "%.2d"; others only handle "%02d"; +** "%02.2d" makes (most) everybody happy. +** At least some versions of gcc warn about the %02.2d; +** we conditionalize below to avoid the warning. +*/ +/* +** All years associated with 32-bit time_t values are exactly four digits long; +** some years associated with 64-bit time_t values are not. +** Vintage programs are coded for years that are always four digits long +** and may assume that the newline always lands in the same place. +** For years that are less than four digits, we pad the output with +** leading zeroes to get the newline in the traditional place. +** The -4 ensures that we get four characters of output even if +** we call a strftime variant that produces fewer characters for some years. +** The ISO C and POSIX standards prohibit padding the year, +** but many implementations pad anyway; most likely the standards are buggy. +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT "%s %s%3d %2.2d:%2.2d:%2.2d %-4s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT "%s %s%3d %02.2d:%02.2d:%02.2d %-4s\n" +#endif /* !defined __GNUC__ */ +/* +** For years that are more than four digits we put extra spaces before the year +** so that code trying to overwrite the newline won't end up overwriting +** a digit within a year and truncating the year (operating on the assumption +** that no output is better than wrong output). +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT_B "%s %s%3d %2.2d:%2.2d:%2.2d %s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT_B "%s %s%3d %02.2d:%02.2d:%02.2d %s\n" +#endif /* !defined __GNUC__ */ + +#define STD_ASCTIME_BUF_SIZE 26 +/* +** Big enough for something such as +** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n +** (two three-character abbreviations, five strings denoting integers, +** seven explicit spaces, two explicit colons, a newline, +** and a trailing NUL byte). +** The values above are for systems where an int is 32 bits and are provided +** as an example; the define below calculates the maximum for the system at +** hand. +*/ +#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1) + +static char buf_asctime[MAX_ASCTIME_BUF_SIZE]; + +char * +asctime_r(register const struct tm *timeptr, char *buf) +{ + register const char * wn; + register const char * mn; + char year[INT_STRLEN_MAXIMUM(int) + 2]; + char result[MAX_ASCTIME_BUF_SIZE]; + + if (timeptr == NULL) { + errno = EINVAL; + return strcpy(buf, "??? ??? ?? ??:??:?? ????\n"); + } + if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) + wn = "???"; + else wn = kWeekdayNameShort[timeptr->tm_wday]; + if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR) + mn = "???"; + else mn = kMonthNameShort[timeptr->tm_mon]; + /* + ** Use strftime's %Y to generate the year, to avoid overflow problems + ** when computing timeptr->tm_year + TM_YEAR_BASE. + ** Assume that strftime is unaffected by other out-of-range members + ** (e.g., timeptr->tm_mday) when processing "%Y". + */ + strftime(year, sizeof year, "%Y", timeptr); + /* + ** We avoid using snprintf since it's not available on all systems. + */ + (sprintf)(result, + ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B), + wn, mn, + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec, + year); + if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) + return strcpy(buf, result); + else { + errno = EOVERFLOW; + return NULL; + } +} + +char * +asctime(register const struct tm *timeptr) +{ + return asctime_r(timeptr, buf_asctime); } diff --git a/libc/time/asctime_r.c b/libc/time/asctime_r.c deleted file mode 100644 index fda926f26..000000000 --- a/libc/time/asctime_r.c +++ /dev/null @@ -1,40 +0,0 @@ -/*-*- 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 "libc/fmt/fmt.h" -#include "libc/time/struct/tm.h" -#include "libc/time/time.h" - -static unsigned clip(unsigned index, unsigned count) { - return index < count ? index : 0; -} - -/** - * Converts date time to string. - * - * @param buf needs to have 64 bytes - * @return pointer to buf - * @see asctime_r for reentrant version - */ -char *asctime_r(const struct tm *date, char buf[hasatleast 64]) { - (snprintf)(buf, 64, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", - kWeekdayNameShort[clip(date->tm_wday, 7)], - kMonthNameShort[clip(date->tm_mon, 12)], date->tm_mday, - date->tm_hour, date->tm_min, date->tm_sec, 1900 + date->tm_year); - return buf; -} diff --git a/libc/time/clockstonanos.internal.h b/libc/time/clockstonanos.internal.h new file mode 100644 index 000000000..c44f78cec --- /dev/null +++ b/libc/time/clockstonanos.internal.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_TIME_CLOCKSTONANOS_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_TIME_CLOCKSTONANOS_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +static inline uint64_t ClocksToNanos(uint64_t x, uint64_t y) { + // approximation of round(x*.323018) which is usually + // the ratio between inva rdtsc ticks and nanoseconds + uint128_t difference = x - y; + return (difference * 338709) >> 20; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TIME_CLOCKSTONANOS_INTERNAL_H_ */ diff --git a/libc/time/ctime.c b/libc/time/ctime.c index e0e34ebfb..feedb7676 100644 --- a/libc/time/ctime.c +++ b/libc/time/ctime.c @@ -1,21 +1,13 @@ -/*-*- 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 "libc/calls/weirdtypes.h" #include "libc/time/time.h" -char *ctime(const int64_t *timep) { return asctime(localtime(timep)); } +char *ctime(const time_t *timep) { + /* + ** Section 4.12.3.2 of X3.159-1989 requires that + ** The ctime function converts the calendar time pointed to by timer + ** to local time in the form of a string. It is equivalent to + ** asctime(localtime(timer)) + */ + struct tm *tmp = localtime(timep); + return tmp ? asctime(tmp) : NULL; +} diff --git a/libc/time/ctime_r.c b/libc/time/ctime_r.c index ddfd57b52..c830a081c 100644 --- a/libc/time/ctime_r.c +++ b/libc/time/ctime_r.c @@ -1,25 +1,9 @@ -/*-*- 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 "libc/calls/weirdtypes.h" #include "libc/time/struct/tm.h" #include "libc/time/time.h" -char *ctime_r(const int64_t *timep, char buf[hasatleast 64]) { - struct tm date[1]; - return asctime_r(localtime_r(timep, date), buf); +char *ctime_r(const time_t *timep, char *buf) { + struct tm mytm; + struct tm *tmp = localtime_r(timep, &mytm); + return tmp ? asctime_r(tmp, buf) : NULL; } diff --git a/libc/time/difftime.c b/libc/time/difftime.c index 435401775..00f1daa00 100644 --- a/libc/time/difftime.c +++ b/libc/time/difftime.c @@ -1,21 +1,61 @@ -/*-*- 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. │ +/*-*- mode:c; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/time/time.h" +#include "libc/time/tz.internal.h" +// clang-format off +/* Return the difference between two timestamps. */ -double difftime(int64_t x, int64_t y) { return x - y; } +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* Return -X as a double. Using this avoids casting to 'double'. */ +static inline double +dminus(double x) +{ + return -x; +} + +double +difftime(time_t time1, time_t time0) +{ + /* + ** If double is large enough, simply convert and subtract + ** (assuming that the larger type has more precision). + */ + if (sizeof(time_t) < sizeof(double)) { + double t1 = time1, t0 = time0; + return t1 - t0; + } + + /* + ** The difference of two unsigned values can't overflow + ** if the minuend is greater than or equal to the subtrahend. + */ + if (!TYPE_SIGNED(time_t)) + return time0 <= time1 ? time1 - time0 : dminus(time0 - time1); + + /* Use uintmax_t if wide enough. */ + if (sizeof(time_t) <= sizeof(uintmax_t)) { + uintmax_t t1 = time1, t0 = time0; + return time0 <= time1 ? t1 - t0 : dminus(t0 - t1); + } + + /* + ** Handle cases where both time1 and time0 have the same sign + ** (meaning that their difference cannot overflow). + */ + if ((time1 < 0) == (time0 < 0)) + return time1 - time0; + + /* + ** The values have opposite signs and uintmax_t is too narrow. + ** This suffers from double rounding; attempt to lessen that + ** by using long double temporaries. + */ + { + long double t1 = time1, t0 = time0; + return t1 - t0; + } +} diff --git a/libc/time/dsleep.c b/libc/time/dsleep.c index 33329400c..f7c5d094c 100644 --- a/libc/time/dsleep.c +++ b/libc/time/dsleep.c @@ -19,6 +19,8 @@ #include "libc/nexgen32e/nexgen32e.h" #include "libc/time/time.h" +// todo(jart): delete + /** * Sleeps w/ higher precision. */ diff --git a/libc/time/kmonthname.S b/libc/time/kmonthname.S index e37f267df..e9a4984d0 100644 --- a/libc/time/kmonthname.S +++ b/libc/time/kmonthname.S @@ -11,6 +11,7 @@ // extern const char kMonthName[12][10]; .section .rodata,"a",@progbits + .underrun kMonthName: .ascin "January",10 .ascin "February",10 @@ -25,4 +26,5 @@ kMonthName: .ascin "November",10 .ascin "December",10 .endobj kMonthName,globl + .overrun .previous diff --git a/libc/time/kmonthnameshort.S b/libc/time/kmonthnameshort.S index c616f15cb..4f1874086 100644 --- a/libc/time/kmonthnameshort.S +++ b/libc/time/kmonthnameshort.S @@ -16,6 +16,7 @@ // - Double-NUL Terminated String // - extern const char kMonthNameShort[]; .section .rodata,"a",@progbits + .underrun kMonthNameShort: .ascin "Jan",4 .ascin "Feb",4 @@ -31,4 +32,5 @@ kMonthNameShort: .ascin "Dec",4 .byte 0 .endobj kMonthNameShort,globl + .overrun .previous diff --git a/libc/time/kweekdayname.S b/libc/time/kweekdayname.S index 1cfc29250..0fa2d967c 100644 --- a/libc/time/kweekdayname.S +++ b/libc/time/kweekdayname.S @@ -11,6 +11,7 @@ // extern const char kWeekdayName[7][10]; .section .rodata,"a",@progbits + .underrun kWeekdayName: .ascin "Sunday",10 .ascin "Monday",10 @@ -20,4 +21,5 @@ kWeekdayName: .ascin "Friday",10 .ascin "Saturday",10 .endobj kWeekdayName,globl + .overrun .previous diff --git a/libc/time/kweekdaynameshort.S b/libc/time/kweekdaynameshort.S index a7b7677d4..14a37b1bd 100644 --- a/libc/time/kweekdaynameshort.S +++ b/libc/time/kweekdaynameshort.S @@ -16,6 +16,7 @@ // - Double-NUL Terminated String // - extern const char kWeekdayNameShort[]; .section .rodata,"a",@progbits + .underrun kWeekdayNameShort: .asciz "Sun" .asciz "Mon" @@ -26,4 +27,5 @@ kWeekdayNameShort: .asciz "Sat" .byte 0 .endobj kWeekdayNameShort,globl + .overrun .previous diff --git a/libc/time/localtime.c b/libc/time/localtime.c index 1ccad692b..4fcca25b2 100644 --- a/libc/time/localtime.c +++ b/libc/time/localtime.c @@ -1,39 +1,23 @@ /*-*- mode:c; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ │vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/initializer.internal.h" +#define LOCALTIME_IMPLEMENTATION #include "libc/calls/calls.h" -#include "libc/macros.internal.h" -#include "libc/math.h" -#include "libc/mem/mem.h" -#include "libc/nexgen32e/nexgen32e.h" -#include "libc/runtime/runtime.h" +#include "libc/intrin/spinlock.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" -#include "libc/time/struct/tm.h" #include "libc/time/time.h" +#include "libc/time/tz.internal.h" #include "libc/time/tzfile.internal.h" -#define ALL_STATE - -#define time_t int64_t -#define int_fast64_t int64_t -#define int_fast32_t int32_t -#define GRANDPARENTED "local time zone must be set" -#define AVGSECSPERYEAR 31556952L -#define SECSPERREPEAT \ - ((int_fast64_t)YEARSPERREPEAT * (int_fast64_t)AVGSECSPERYEAR) -#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ -#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ -#define TM_ZONE tm_zone -#define INITIALIZE(x) x = 0 - STATIC_YOINK("zip_uri_support"); STATIC_YOINK("usr/share/zoneinfo/"); +STATIC_YOINK("usr/share/zoneinfo/Anchorage"); STATIC_YOINK("usr/share/zoneinfo/Beijing"); STATIC_YOINK("usr/share/zoneinfo/Berlin"); STATIC_YOINK("usr/share/zoneinfo/Boulder"); STATIC_YOINK("usr/share/zoneinfo/Chicago"); +STATIC_YOINK("usr/share/zoneinfo/GMT"); STATIC_YOINK("usr/share/zoneinfo/GST"); STATIC_YOINK("usr/share/zoneinfo/Honolulu"); STATIC_YOINK("usr/share/zoneinfo/Israel"); @@ -41,25 +25,31 @@ STATIC_YOINK("usr/share/zoneinfo/Japan"); STATIC_YOINK("usr/share/zoneinfo/London"); STATIC_YOINK("usr/share/zoneinfo/Melbourne"); STATIC_YOINK("usr/share/zoneinfo/New_York"); -STATIC_YOINK("usr/share/zoneinfo/Singapore"); +STATIC_YOINK("usr/share/zoneinfo/UTC"); -/* clang-format off */ +// clang-format off +/* Convert timestamp from time_t to struct tm. */ /* ** This file is in the public domain, so clarified as of ** 1996-06-05 by Arthur David Olson. */ -/* #ifndef lint */ -/* #ifndef NOID */ -/* static char elsieid[] = "@(#)localtime.c 8.3"; */ -/* #endif /\* !defined NOID *\/ */ -/* #endif /\* !defined lint *\/ */ - /* ** Leap second handling from Bradley White. ** POSIX-style TZ environment variable handling from Guy Harris. */ +_Alignas(64) static char locallock; + +static int lock(void) { + _spinlock(&locallock); + return 0; +} + +static void unlock(void) { + _spunlock(&locallock); +} + #ifndef TZ_ABBR_MAX_LEN #define TZ_ABBR_MAX_LEN 16 #endif /* !defined TZ_ABBR_MAX_LEN */ @@ -97,36 +87,44 @@ STATIC_YOINK("usr/share/zoneinfo/Singapore"); #endif /* !defined WILDABBR */ static const char wildabbr[] = WILDABBR; -static char wildabbr2[sizeof(WILDABBR)]; -static const char gmt[] = "UTC"; +static const char gmt[] = "GMT"; /* ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. -** We default to US rules as of 1999-08-17. -** POSIX 1003.1 section 8.1.1 says that the default DST rules are -** implementation dependent; for historical reasons, US rules are a -** common default. +** Default to US rules as of 2017-05-07. +** POSIX does not specify the default DST rules; +** for historical reasons, US rules are a common default. */ #ifndef TZDEFRULESTRING -#define TZDEFRULESTRING ",M4.1.0,M10.5.0" -#endif /* !defined TZDEFDST */ +#define TZDEFRULESTRING ",M3.2.0,M11.1.0" +#endif struct ttinfo { /* time type information */ - long tt_gmtoff; /* UTC offset in seconds */ - int tt_isdst; /* used to set tm_isdst */ - int tt_abbrind; /* abbreviation list index */ - int tt_ttisstd; /* TRUE if transition is std time */ - int tt_ttisgmt; /* TRUE if transition is UTC */ + int_fast32_t tt_utoff; /* UT offset in seconds */ + bool tt_isdst; /* used to set tm_isdst */ + int tt_desigidx; /* abbreviation list index */ + bool tt_ttisstd; /* transition is std time */ + bool tt_ttisut; /* transition is UT */ }; struct lsinfo { /* leap second information */ time_t ls_trans; /* transition time */ - long ls_corr; /* correction to apply */ + int_fast32_t ls_corr; /* correction to apply */ }; +#define SMALLEST(a, b) (((a) < (b)) ? (a) : (b)) #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) +/* This abbreviation means local time is unspecified. */ +static char const UNSPEC[] = "-00"; + +/* How many extra bytes are needed at the end of struct state's chars array. + This needs to be at least 1 for null termination in case the input + data isn't properly terminated, and it also needs to be big enough + for ttunspecified to work without crashing. */ +enum { CHARS_EXTRA = BIGGEST(sizeof UNSPEC, 2) - 1 }; + #ifdef TZNAME_MAX #define MY_TZNAME_MAX TZNAME_MAX #endif /* defined TZNAME_MAX */ @@ -139,63 +137,46 @@ struct state { int timecnt; int typecnt; int charcnt; - int goback; - int goahead; + bool goback; + bool goahead; time_t ats[TZ_MAX_TIMES]; unsigned char types[TZ_MAX_TIMES]; struct ttinfo ttis[TZ_MAX_TYPES]; - char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), + char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + CHARS_EXTRA, + sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))]; struct lsinfo lsis[TZ_MAX_LEAPS]; + + /* The time type to use for early times or if no transitions. + It is always zero for recent tzdb releases. + It might be nonzero for data from tzdb 2018e or earlier. */ + int defaulttype; +}; + +enum r_type { + JULIAN_DAY, /* Jn = Julian day */ + DAY_OF_YEAR, /* n = day of year */ + MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */ }; struct rule { - int r_type; /* type of rule--see below */ + enum r_type r_type; /* type of rule */ int r_day; /* day number of rule */ int r_week; /* week number of rule */ int r_mon; /* month number of rule */ - int32_t r_time; /* transition time of rule */ + int_fast32_t r_time; /* transition time of rule */ }; -#define JULIAN_DAY 0 /* Jn - Julian day */ -#define DAY_OF_YEAR 1 /* n - day of year */ -#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ - -/* -** Prototypes for static functions. -*/ - -static int32_t detzcode(const char *); -static time_t detzcode64(const char *); -static int differ_by_repeat(time_t, time_t); -static const char * getzname(const char *); -static const char * getqzname(const char *, const int); -static const char * getnum(const char *, int *, int, int); -static const char * getsecs(const char *, int32_t *); -static const char * getoffset(const char *, int32_t *); -static const char * getrule(const char *, struct rule *); -static void gmtload(struct state *); -static struct tm * gmtsub(const time_t *, int32_t, struct tm *); -static struct tm * localsub(const time_t *, int32_t, struct tm *); -static int increment_overflow(int *, int); -static int leaps_thru_end_of(int); -static int normalize_overflow(int *, int *, int); -static void settzname(void); -static time_t time1(struct tm *, struct tm * (*)(const time_t *, - int32_t, struct tm *), - int32_t); -static time_t time2(struct tm *, struct tm *(*)(const time_t *, - int32_t, struct tm *), - int32_t, int *); -static time_t time2sub(struct tm *, struct tm *(*)(const time_t *, - int32_t, struct tm*), - int32_t, int *, int); -static struct tm * timesub(const time_t *, int32_t, - const struct state *, struct tm *); -static int tmcomp(const struct tm *, const struct tm *); -static time_t transtime(time_t, int, const struct rule *, int32_t); -static int tzload(const char *, struct state *, int); -static int tzparse(const char *, struct state *, int); +static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, + struct tm *); +static bool increment_overflow(int *, int); +static bool increment_overflow_time(time_t *, int_fast32_t); +static int_fast32_t leapcorr(struct state const *, time_t); +static bool normalize_overflow32(int_fast32_t *, int *, int); +static struct tm *localtime_timesub(time_t const *, int_fast32_t, + struct state const *, struct tm *); +static bool localtime_typesequiv(struct state const *, int, int); +static bool localtime_tzparse(char const *, struct state *, struct state *); #ifdef ALL_STATE static struct state * lclptr; @@ -215,18 +196,6 @@ static struct state gmtmem; static char lcl_TZname[TZ_STRLEN_MAX + 1]; static int lcl_is_set; -static int gmt_is_set; - -char * tzname[2] /* = { */ -/* wildabbr, */ -/* wildabbr */ -/* } */; - -INITIALIZER(400, _init_localtime, { - memcpy(wildabbr2, wildabbr, sizeof(WILDABBR)); - tzname[0] = wildabbr2; - tzname[1] = wildabbr2; -}) /* ** Section 4.12.3 of X3.159-1989 requires that @@ -238,87 +207,139 @@ INITIALIZER(400, _init_localtime, { static struct tm tm; -#ifdef USG_COMPAT -time_t timezone; +#if 2 <= HAVE_TZNAME + TZ_TIME_T +char * tzname[2] = { + (char *) wildabbr, + (char *) wildabbr +}; +#endif +#if 2 <= USG_COMPAT + TZ_TIME_T +long timezone; int daylight; -#endif /* defined USG_COMPAT */ +#endif +#if 2 <= ALTZONE + TZ_TIME_T +long altzone; +#endif -#ifdef ALTZONE -time_t altzone; -#endif /* defined ALTZONE */ +/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ +static void +init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx) +{ + s->tt_utoff = utoff; + s->tt_isdst = isdst; + s->tt_desigidx = desigidx; + s->tt_ttisstd = false; + s->tt_ttisut = false; +} -static int32_t -detzcode( - const char * const codep -) { - register int32_t result; +/* Return true if SP's time type I does not specify local time. */ +static bool +ttunspecified(struct state const *sp, int i) +{ + char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx]; + /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */ + return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0; +} + +static int_fast32_t +detzcode(const char *const codep) +{ + register int_fast32_t result; register int i; - result = (codep[0] & 0x80) ? ~0L : 0; - for (i = 0; i < 4; ++i) - result = ((unsigned)result << 8) | (codep[i] & 0xff); + int_fast32_t one = 1; + int_fast32_t halfmaxval = one << (32 - 2); + int_fast32_t maxval = halfmaxval - 1 + halfmaxval; + int_fast32_t minval = -1 - maxval; + + result = codep[0] & 0x7f; + for (i = 1; i < 4; ++i) + result = (result << 8) | (codep[i] & 0xff); + + if (codep[0] & 0x80) { + /* Do two's-complement negation even on non-two's-complement machines. + If the result would be minval - 1, return minval. */ + result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0; + result += minval; + } return result; } -static time_t -detzcode64( - const char * const codep -) { - register time_t result; - register int i; - result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0; - for (i = 0; i < 8; ++i) - result = result * 256 + (codep[i] & 0xff); +static int_fast64_t +detzcode64(const char *const codep) +{ + register int_fast64_t result; + register int i; + int_fast64_t one = 1; + int_fast64_t halfmaxval = one << (64 - 2); + int_fast64_t maxval = halfmaxval - 1 + halfmaxval; + int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval; + + result = codep[0] & 0x7f; + for (i = 1; i < 8; ++i) + result = (result << 8) | (codep[i] & 0xff); + + if (codep[0] & 0x80) { + /* Do two's-complement negation even on non-two's-complement machines. + If the result would be minval - 1, return minval. */ + result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0; + result += minval; + } return result; } +static void +update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp) +{ +#if HAVE_TZNAME + tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_desigidx]; +#endif + if (!ttisp->tt_isdst) + timezone = - ttisp->tt_utoff; +#if ALTZONE + if (ttisp->tt_isdst) + altzone = - ttisp->tt_utoff; +#endif +} + static void settzname(void) { - register struct state * sp; - register int i; - sp = lclptr; - tzname[0] = wildabbr2; - tzname[1] = wildabbr2; -#ifdef USG_COMPAT + register struct state * const sp = lclptr; + register int i; + +#if HAVE_TZNAME + tzname[0] = tzname[1] = (char *) (sp ? wildabbr : gmt); +#endif daylight = 0; timezone = 0; -#endif /* defined USG_COMPAT */ -#ifdef ALTZONE +#if ALTZONE altzone = 0; -#endif /* defined ALTZONE */ -#ifdef ALL_STATE +#endif if (sp == NULL) { - tzname[0] = tzname[1] = gmt; return; } -#endif /* defined ALL_STATE */ + /* + ** And to get the latest time zone abbreviations into tzname. . . + */ for (i = 0; i < sp->typecnt; ++i) { register const struct ttinfo * const ttisp = &sp->ttis[i]; - tzname[ttisp->tt_isdst] = - &sp->chars[ttisp->tt_abbrind]; -#ifdef USG_COMPAT - if (ttisp->tt_isdst) - daylight = 1; - if (i == 0 || !ttisp->tt_isdst) - timezone = -(ttisp->tt_gmtoff); -#endif /* defined USG_COMPAT */ -#ifdef ALTZONE - if (i == 0 || ttisp->tt_isdst) - altzone = -(ttisp->tt_gmtoff); -#endif /* defined ALTZONE */ + update_tzname_etc(sp, ttisp); } - /* - ** And to get the latest zone names into tzname. . . - */ for (i = 0; i < sp->timecnt; ++i) { register const struct ttinfo * const ttisp = &sp->ttis[ sp->types[i]]; - tzname[ttisp->tt_isdst] = - &sp->chars[ttisp->tt_abbrind]; + update_tzname_etc(sp, ttisp); + if (ttisp->tt_isdst) + daylight = 1; } +} + +static void +scrub_abbrs(struct state *sp) +{ + int i; /* - ** Finally, scrub the abbreviations. ** First, replace bogus characters. */ for (i = 0; i < sp->charcnt; ++i) @@ -329,330 +350,521 @@ settzname(void) */ for (i = 0; i < sp->typecnt; ++i) { register const struct ttinfo * const ttisp = &sp->ttis[i]; - register char * cp = &sp->chars[ttisp->tt_abbrind]; + char *cp = &sp->chars[ttisp->tt_desigidx]; + if (strlen(cp) > TZ_ABBR_MAX_LEN && strcmp(cp, GRANDPARENTED) != 0) *(cp + TZ_ABBR_MAX_LEN) = '\0'; } } -forceinline int -differ_by_repeat( - const time_t t1, - const time_t t0 -) { - if (TYPE_INTEGRAL(time_t) && - TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) - return 0; - return (t1 - t0) == SECSPERREPEAT; -} +/* Input buffer for data read from a compiled tz file. */ +union input_buffer { + /* The first part of the buffer, interpreted as a header. */ + struct tzhead tzhead; -forceinline int -cmpstr( - const char *l, - const char *r -) { - size_t i = 0; - while (l[i] == r[i] && r[i]) ++i; - return (l[i] & 0xff) - (r[i] & 0xff); -} + /* The entire buffer. */ + char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state) + + 4 * TZ_MAX_TIMES]; +}; +/* TZDIR with a trailing '/' rather than a trailing '\0'. */ +static char const tzdirslash[sizeof TZDIR] = TZDIR "/"; + +/* Local storage needed for 'tzloadbody'. */ +union local_storage { + /* The results of analyzing the file's contents after it is opened. */ + struct file_analysis { + /* The input buffer. */ + union input_buffer u; + + /* A temporary state used for parsing a TZ string in the file. */ + struct state st; + } u; + + /* The file name to be opened. */ + char fullname[BIGGEST(sizeof(struct file_analysis), + sizeof tzdirslash + 1024)]; +}; + +/* Load tz data from the file named NAME into *SP. Read extended + format if DOEXTEND. Use *LSP for temporary storage. Return 0 on + success, an errno value on failure. */ static int -typesequiv( - const struct state *sp, - int a, - int b -) { - int result; +localtime_tzloadbody(char const *name, struct state *sp, bool doextend, + union local_storage *lsp) +{ + register int i; + register int fid; + register int stored; + register ssize_t nread; + register bool doaccess; + register union input_buffer *up = &lsp->u.u; + register int tzheadsize = sizeof(struct tzhead); + + sp->goback = sp->goahead = false; + + if (! name) { + name = TZDEFAULT; + if (! name) + return EINVAL; + } + + if (name[0] == ':') + ++name; +#ifdef SUPPRESS_TZDIR + /* Do not prepend TZDIR. This is intended for specialized + applications only, due to its security implications. */ + doaccess = true; +#else + doaccess = name[0] == '/'; +#endif + if (!doaccess) { + char const *dot; + size_t namelen = strlen(name); + if (sizeof lsp->fullname - sizeof tzdirslash <= namelen) + return ENAMETOOLONG; + + /* Create a string "TZDIR/NAME". Using sprintf here + would pull in stdio (and would fail if the + resulting string length exceeded INT_MAX!). */ + memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash); + strcpy(lsp->fullname + sizeof tzdirslash, name); + + /* Set doaccess if NAME contains a ".." file name + component, as such a name could read a file outside + the TZDIR virtual subtree. */ + for (dot = name; (dot = strchr(dot, '.')); dot++) + if ((dot == name || dot[-1] == '/') && dot[1] == '.' + && (dot[2] == '/' || !dot[2])) { + doaccess = true; + break; + } + + name = lsp->fullname; + } + if (doaccess && access(name, R_OK) != 0) + return errno; + fid = open(name, O_RDONLY); + if (fid < 0) + return errno; + + nread = read(fid, up->buf, sizeof up->buf); + if (nread < tzheadsize) { + int err = nread < 0 ? errno : EINVAL; + close(fid); + return err; + } + if (close(fid) < 0) + return errno; + for (stored = 4; stored <= 8; stored *= 2) { + char version = up->tzhead.tzh_version[0]; + bool skip_datablock = stored == 4 && version; + int_fast32_t datablock_size; + int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); + int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); + int_fast64_t prevtr = -1; + int_fast32_t prevcorr = 0; + int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt); + int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt); + int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt); + int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt); + char const *p = up->buf + tzheadsize; + /* Although tzfile(5) currently requires typecnt to be nonzero, + support future formats that may allow zero typecnt + in files that have a TZ string and no transitions. */ + if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS + && 0 <= typecnt && typecnt < TZ_MAX_TYPES + && 0 <= timecnt && timecnt < TZ_MAX_TIMES + && 0 <= charcnt && charcnt < TZ_MAX_CHARS + && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES + && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES)) + return EINVAL; + datablock_size + = (timecnt * stored /* ats */ + + timecnt /* types */ + + typecnt * 6 /* ttinfos */ + + charcnt /* chars */ + + leapcnt * (stored + 4) /* lsinfos */ + + ttisstdcnt /* ttisstds */ + + ttisutcnt); /* ttisuts */ + if (nread < tzheadsize + datablock_size) + return EINVAL; + if (skip_datablock) + p += datablock_size; + else { + if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0) + && (ttisutcnt == typecnt || ttisutcnt == 0))) + return EINVAL; + + sp->leapcnt = leapcnt; + sp->timecnt = timecnt; + sp->typecnt = typecnt; + sp->charcnt = charcnt; + + /* Read transitions, discarding those out of time_t range. + But pretend the last transition before TIME_T_MIN + occurred at TIME_T_MIN. */ + timecnt = 0; + for (i = 0; i < sp->timecnt; ++i) { + int_fast64_t at + = stored == 4 ? detzcode(p) : detzcode64(p); + sp->types[i] = at <= TIME_T_MAX; + if (sp->types[i]) { + time_t attime + = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0) + ? TIME_T_MIN : at); + if (timecnt && attime <= sp->ats[timecnt - 1]) { + if (attime < sp->ats[timecnt - 1]) + return EINVAL; + sp->types[i - 1] = 0; + timecnt--; + } + sp->ats[timecnt++] = attime; + } + p += stored; + } + + timecnt = 0; + for (i = 0; i < sp->timecnt; ++i) { + unsigned char typ = *p++; + if (sp->typecnt <= typ) + return EINVAL; + if (sp->types[i]) + sp->types[timecnt++] = typ; + } + sp->timecnt = timecnt; + for (i = 0; i < sp->typecnt; ++i) { + register struct ttinfo * ttisp; + unsigned char isdst, desigidx; + + ttisp = &sp->ttis[i]; + ttisp->tt_utoff = detzcode(p); + p += 4; + isdst = *p++; + if (! (isdst < 2)) + return EINVAL; + ttisp->tt_isdst = isdst; + desigidx = *p++; + if (! (desigidx < sp->charcnt)) + return EINVAL; + ttisp->tt_desigidx = desigidx; + } + for (i = 0; i < sp->charcnt; ++i) + sp->chars[i] = *p++; + /* Ensure '\0'-terminated, and make it safe to call + ttunspecified later. */ + memset(&sp->chars[i], 0, CHARS_EXTRA); + + /* Read leap seconds, discarding those out of time_t range. */ + leapcnt = 0; + for (i = 0; i < sp->leapcnt; ++i) { + int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); + int_fast32_t corr = detzcode(p + stored); + p += stored + 4; + + /* Leap seconds cannot occur before the Epoch, + or out of order. */ + if (tr <= prevtr) + return EINVAL; + + /* To avoid other botches in this code, each leap second's + correction must differ from the previous one's by 1 + second or less, except that the first correction can be + any value; these requirements are more generous than + RFC 8536, to allow future RFC extensions. */ + if (! (i == 0 + || (prevcorr < corr + ? corr == prevcorr + 1 + : (corr == prevcorr + || corr == prevcorr - 1)))) + return EINVAL; + prevtr = tr; + prevcorr = corr; + + if (tr <= TIME_T_MAX) { + sp->lsis[leapcnt].ls_trans = tr; + sp->lsis[leapcnt].ls_corr = corr; + leapcnt++; + } + } + sp->leapcnt = leapcnt; + + for (i = 0; i < sp->typecnt; ++i) { + register struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisstdcnt == 0) + ttisp->tt_ttisstd = false; + else { + if (*p != true && *p != false) + return EINVAL; + ttisp->tt_ttisstd = *p++; + } + } + for (i = 0; i < sp->typecnt; ++i) { + register struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisutcnt == 0) + ttisp->tt_ttisut = false; + else { + if (*p != true && *p != false) + return EINVAL; + ttisp->tt_ttisut = *p++; + } + } + } + + nread -= p - up->buf; + memmove(up->buf, p, nread); + + /* If this is an old file, we're done. */ + if (!version) + break; + } + if (doextend && nread > 2 && + up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && + sp->typecnt + 2 <= TZ_MAX_TYPES) { + struct state *ts = &lsp->u.st; + + up->buf[nread - 1] = '\0'; + if (localtime_tzparse(&up->buf[1], ts, sp)) { + + /* Attempt to reuse existing abbreviations. + Without this, America/Anchorage would be right on + the edge after 2037 when TZ_MAX_CHARS is 50, as + sp->charcnt equals 40 (for LMT AST AWT APT AHST + AHDT YST AKDT AKST) and ts->charcnt equals 10 + (for AKST AKDT). Reusing means sp->charcnt can + stay 40 in this example. */ + int gotabbr = 0; + int charcnt = sp->charcnt; + for (i = 0; i < ts->typecnt; i++) { + char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; + int j; + for (j = 0; j < charcnt; j++) + if (strcmp(sp->chars + j, tsabbr) == 0) { + ts->ttis[i].tt_desigidx = j; + gotabbr++; + break; + } + if (! (j < charcnt)) { + int tsabbrlen = strlen(tsabbr); + if (j + tsabbrlen < TZ_MAX_CHARS) { + strcpy(sp->chars + j, tsabbr); + charcnt = j + tsabbrlen + 1; + ts->ttis[i].tt_desigidx = j; + gotabbr++; + } + } + } + if (gotabbr == ts->typecnt) { + sp->charcnt = charcnt; + + /* Ignore any trailing, no-op transitions generated + by zic as they don't help here and can run afoul + of bugs in zic 2016j or earlier. */ + while (1 < sp->timecnt + && (sp->types[sp->timecnt - 1] + == sp->types[sp->timecnt - 2])) + sp->timecnt--; + + for (i = 0; + i < ts->timecnt && sp->timecnt < TZ_MAX_TIMES; + i++) { + time_t t = ts->ats[i]; + if (increment_overflow_time(&t, leapcorr(sp, t)) + || (0 < sp->timecnt + && t <= sp->ats[sp->timecnt - 1])) + continue; + sp->ats[sp->timecnt] = t; + sp->types[sp->timecnt] = (sp->typecnt + + ts->types[i]); + sp->timecnt++; + } + for (i = 0; i < ts->typecnt; i++) + sp->ttis[sp->typecnt++] = ts->ttis[i]; + } + } + } + if (sp->typecnt == 0) + return EINVAL; + if (sp->timecnt > 1) { + if (sp->ats[0] <= TIME_T_MAX - SECSPERREPEAT) { + time_t repeatat = sp->ats[0] + SECSPERREPEAT; + int repeattype = sp->types[0]; + for (i = 1; i < sp->timecnt; ++i) + if (sp->ats[i] == repeatat + && localtime_typesequiv(sp, sp->types[i], repeattype)) { + sp->goback = true; + break; + } + } + if (TIME_T_MIN + SECSPERREPEAT <= sp->ats[sp->timecnt - 1]) { + time_t repeatat = sp->ats[sp->timecnt - 1] - SECSPERREPEAT; + int repeattype = sp->types[sp->timecnt - 1]; + for (i = sp->timecnt - 2; i >= 0; --i) + if (sp->ats[i] == repeatat + && localtime_typesequiv(sp, sp->types[i], repeattype)) { + sp->goahead = true; + break; + } + } + } + + /* Infer sp->defaulttype from the data. Although this default + type is always zero for data from recent tzdb releases, + things are trickier for data from tzdb 2018e or earlier. + + The first set of heuristics work around bugs in 32-bit data + generated by tzdb 2013c or earlier. The workaround is for + zones like Australia/Macquarie where timestamps before the + first transition have a time type that is not the earliest + standard-time type. See: + https://mm.icann.org/pipermail/tz/2013-May/019368.html */ + /* + ** If type 0 does not specify local time, or is unused in transitions, + ** it's the type to use for early times. + */ + for (i = 0; i < sp->timecnt; ++i) + if (sp->types[i] == 0) + break; + i = i < sp->timecnt && ! ttunspecified(sp, 0) ? -1 : 0; + /* + ** Absent the above, + ** if there are transition times + ** and the first transition is to a daylight time + ** find the standard type less than and closest to + ** the type of the first transition. + */ + if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) { + i = sp->types[0]; + while (--i >= 0) + if (!sp->ttis[i].tt_isdst) + break; + } + /* The next heuristics are for data generated by tzdb 2018e or + earlier, for zones like EST5EDT where the first transition + is to DST. */ + /* + ** If no result yet, find the first standard type. + ** If there is none, punt to type zero. + */ + if (i < 0) { + i = 0; + while (sp->ttis[i].tt_isdst) + if (++i >= sp->typecnt) { + i = 0; + break; + } + } + /* A simple 'sp->defaulttype = 0;' would suffice here if we + didn't have to worry about 2018e-or-earlier data. Even + simpler would be to remove the defaulttype member and just + use 0 in its place. */ + sp->defaulttype = i; + + return 0; +} + +/* Load tz data from the file named NAME into *SP. Read extended + format if DOEXTEND. Return 0 on success, an errno value on failure. */ +static int +localtime_tzload(char const *name, struct state *sp, bool doextend) +{ +#ifdef ALL_STATE + union local_storage *lsp = malloc(sizeof *lsp); + if (!lsp) { + return HAVE_MALLOC_ERRNO ? errno : ENOMEM; + } else { + int err = localtime_tzloadbody(name, sp, doextend, lsp); + free(lsp); + return err; + } +#else + int i; + volatile char *p; + volatile unsigned x; + union local_storage ls; /* 70+ kilobytes */ + p = (char *)&ls; + for (x = i = 0; i < sizeof(ls); i += 4096) { + x += p[i]; /* make sure tzdata doesn't smash the stack */ + } + return localtime_tzloadbody(name, sp, doextend, &ls); +#endif +} + +static bool +localtime_typesequiv(const struct state *sp, int a, int b) +{ + register bool result; + if (sp == NULL || - a < 0 || a >= sp->typecnt || - b < 0 || b >= sp->typecnt) - result = FALSE; + a < 0 || a >= sp->typecnt || + b < 0 || b >= sp->typecnt) + result = false; else { - const struct ttinfo * ap = &sp->ttis[a]; - const struct ttinfo * bp = &sp->ttis[b]; - result = ap->tt_gmtoff == bp->tt_gmtoff && - ap->tt_isdst == bp->tt_isdst && - ap->tt_ttisstd == bp->tt_ttisstd && - ap->tt_ttisgmt == bp->tt_ttisgmt && - cmpstr(&sp->chars[ap->tt_abbrind], - &sp->chars[bp->tt_abbrind]) == 0; + register const struct ttinfo * ap = &sp->ttis[a]; + register const struct ttinfo * bp = &sp->ttis[b]; + result = (ap->tt_utoff == bp->tt_utoff + && ap->tt_isdst == bp->tt_isdst + && ap->tt_ttisstd == bp->tt_ttisstd + && ap->tt_ttisut == bp->tt_ttisut + && (strcmp(&sp->chars[ap->tt_desigidx], + &sp->chars[bp->tt_desigidx]) + == 0)); } return result; } -static int -tzload( - const char * name, - struct state * const sp, - const int doextend -) { - register const char * p; - register int i; - register int fid; - register int stored; - register int nread; - union { - struct tzhead tzhead; - char buf[2 * sizeof(struct tzhead) + - 2 * sizeof *sp + - 4 * TZ_MAX_TIMES]; - } * up; - char fullname[PATH_MAX]; - - up = calloc(1, sizeof *up); - if (up == NULL) - return -1; - - sp->goback = sp->goahead = FALSE; - if (name != NULL /* && issetugid() != 0 */) { - if ((name[0] == ':' && (strchr(name, '/'))) || - name[0] == '/' || strchr(name, '.')) - name = NULL; - } - if (name == NULL && (name = TZDEFAULT) == NULL) - goto oops; - - if (name[0] == ':') - ++name; - if (name[0] != '/') { - if ((p = TZDIR) == NULL) - goto oops; - if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) - goto oops; - strlcpy(fullname, p, sizeof fullname); - strlcat(fullname, "/", sizeof fullname); - strlcat(fullname, name, sizeof fullname); - name = fullname; - } - if ((fid = open(name, O_RDONLY)) == -1) - goto oops; - - nread = read(fid, up->buf, sizeof up->buf); - if (close(fid) < 0 || nread <= 0) - goto oops; - for (stored = 4; stored <= 8; stored *= 2) { - int ttisstdcnt; - int ttisgmtcnt; - - ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt); - ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt); - sp->leapcnt = (int) detzcode(up->tzhead.tzh_leapcnt); - sp->timecnt = (int) detzcode(up->tzhead.tzh_timecnt); - sp->typecnt = (int) detzcode(up->tzhead.tzh_typecnt); - sp->charcnt = (int) detzcode(up->tzhead.tzh_charcnt); - p = up->tzhead.tzh_charcnt + sizeof up->tzhead.tzh_charcnt; - if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || - sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || - sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || - sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || - (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || - (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) - goto oops; - if (nread - (p - up->buf) < - sp->timecnt * stored + /* ats */ - sp->timecnt + /* types */ - sp->typecnt * 6 + /* ttinfos */ - sp->charcnt + /* chars */ - sp->leapcnt * (stored + 4) + /* lsinfos */ - ttisstdcnt + /* ttisstds */ - ttisgmtcnt) /* ttisgmts */ - goto oops; - for (i = 0; i < sp->timecnt; ++i) { - sp->ats[i] = (stored == 4) ? - detzcode(p) : detzcode64(p); - p += stored; - } - for (i = 0; i < sp->timecnt; ++i) { - sp->types[i] = (unsigned char) *p++; - if (sp->types[i] >= sp->typecnt) - goto oops; - } - for (i = 0; i < sp->typecnt; ++i) { - struct ttinfo * ttisp; - - ttisp = &sp->ttis[i]; - ttisp->tt_gmtoff = detzcode(p); - p += 4; - ttisp->tt_isdst = (unsigned char) *p++; - if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) - goto oops; - ttisp->tt_abbrind = (unsigned char) *p++; - if (ttisp->tt_abbrind < 0 || - ttisp->tt_abbrind > sp->charcnt) - goto oops; - } - for (i = 0; i < sp->charcnt; ++i) - sp->chars[i] = *p++; - sp->chars[i] = '\0'; /* ensure '\0' at end */ - for (i = 0; i < sp->leapcnt; ++i) { - struct lsinfo * lsisp; - - lsisp = &sp->lsis[i]; - lsisp->ls_trans = (stored == 4) ? - detzcode(p) : detzcode64(p); - p += stored; - lsisp->ls_corr = detzcode(p); - p += 4; - } - for (i = 0; i < sp->typecnt; ++i) { - struct ttinfo * ttisp; - - ttisp = &sp->ttis[i]; - if (ttisstdcnt == 0) - ttisp->tt_ttisstd = FALSE; - else { - ttisp->tt_ttisstd = *p++; - if (ttisp->tt_ttisstd != TRUE && - ttisp->tt_ttisstd != FALSE) - goto oops; - } - } - for (i = 0; i < sp->typecnt; ++i) { - struct ttinfo * ttisp; - - ttisp = &sp->ttis[i]; - if (ttisgmtcnt == 0) - ttisp->tt_ttisgmt = FALSE; - else { - ttisp->tt_ttisgmt = *p++; - if (ttisp->tt_ttisgmt != TRUE && - ttisp->tt_ttisgmt != FALSE) - goto oops; - } - } - /* - ** Out-of-sort ats should mean we're running on a - ** signed time_t system but using a data file with - ** unsigned values (or vice versa). - */ - for (i = 0; i < sp->timecnt - 2; ++i) - if (sp->ats[i] > sp->ats[i + 1]) { - ++i; - /* - ** Ignore the end (easy). - */ - sp->timecnt = i; - break; - } - /* - ** If this is an old file, we're done. - */ - if (up->tzhead.tzh_version[0] == '\0') - break; - nread -= p - up->buf; - for (i = 0; i < nread; ++i) - up->buf[i] = p[i]; - /* - ** If this is a narrow integer time_t system, we're done. - */ - if (stored >= sizeof(time_t)) - break; - } - if (doextend && nread > 2 && - up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && - sp->typecnt + 2 <= TZ_MAX_TYPES) { - struct state *ts; - int result; - ts = calloc(1, sizeof(struct state)); - if (!ts) abort(); - up->buf[nread - 1] = '\0'; - result = tzparse(&up->buf[1], ts, FALSE); - if (result == 0 && ts->typecnt == 2 && - sp->charcnt + ts->charcnt <= TZ_MAX_CHARS) { - for (i = 0; i < 2; ++i) - ts->ttis[i].tt_abbrind += - sp->charcnt; - for (i = 0; i < ts->charcnt; ++i) - sp->chars[sp->charcnt++] = - ts->chars[i]; - i = 0; - while (i < ts->timecnt && - ts->ats[i] <= - sp->ats[sp->timecnt - 1]) - ++i; - while (i < ts->timecnt && - sp->timecnt < TZ_MAX_TIMES) { - sp->ats[sp->timecnt] = - ts->ats[i]; - sp->types[sp->timecnt] = - sp->typecnt + - ts->types[i]; - ++sp->timecnt; - ++i; - } - sp->ttis[sp->typecnt++] = ts->ttis[0]; - sp->ttis[sp->typecnt++] = ts->ttis[1]; - } - free(ts); - } - if (sp->timecnt > 1) { - for (i = 1; i < sp->timecnt; ++i) { - if (typesequiv(sp, sp->types[i], sp->types[0]) && - differ_by_repeat(sp->ats[i], sp->ats[0])) { - sp->goback = TRUE; - break; - } - } - for (i = sp->timecnt - 2; i >= 0; --i) { - if (typesequiv(sp, sp->types[sp->timecnt - 1], - sp->types[i]) && - differ_by_repeat(sp->ats[sp->timecnt - 1], - sp->ats[i])) { - sp->goahead = TRUE; - break; - } - } - } - free(up); - return 0; -oops: - free(up); - return -1; -} - -static const unsigned char kMonthLengths[2][MONSPERYEAR] = { +static const int mon_lengths[2][MONSPERYEAR] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; -static const int kYearLengths[2] = { +static const int year_lengths[2] = { DAYSPERNYEAR, DAYSPERLYEAR }; +/* Is C an ASCII digit? */ +static inline bool +is_digit(char c) +{ + return '0' <= c && c <= '9'; +} + /* -** Given a pointer into a time zone string, scan until a character that is not -** a valid character in a zone name is found. Return a pointer to that -** character. +** Given a pointer into a timezone string, scan until a character that is not +** a valid character in a time zone abbreviation is found. +** Return a pointer to that character. */ -static const char * -getzname( - const char * strp -) { - char c; - while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' && - c != '+') { - ++strp; - } +static nosideeffect const char * +getzname(register const char *strp) +{ + register char c; + + while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && + c != '+') + ++strp; return strp; } /* -** Given a pointer into an extended time zone string, scan until the ending -** delimiter of the zone name is located. Return a pointer to the delimiter. +** Given a pointer into an extended timezone string, scan until the ending +** delimiter of the time zone abbreviation is located. +** Return a pointer to the delimiter. ** ** As with getzname above, the legal character set is actually quite ** restricted, with other characters producing undefined results. ** We don't do any checking here; checking is done later in common-case code. */ -static const char * -getqzname( - const char * strp, - const int delim -) { - register int c; +static nosideeffect const char * +getqzname(register const char *strp, const int delim) +{ + register int c; while ((c = *strp) != '\0' && c != delim) ++strp; @@ -660,23 +872,19 @@ getqzname( } /* -** Given a pointer into a time zone string, extract a number from that string. +** Given a pointer into a timezone string, extract a number from that string. ** Check that the number is within a specified range; if it is not, return ** NULL. ** Otherwise, return a pointer to the first character not part of the number. */ static const char * -getnum( - const char * strp, - int * const nump, - const int min, - const int max -) { - register char c; - register int num; +getnum(register const char *strp, int *const nump, const int min, const int max) +{ + register char c; + register int num; - if (strp == NULL || !isdigit(c = *strp)) + if (strp == NULL || !is_digit(c = *strp)) return NULL; num = 0; do { @@ -684,7 +892,7 @@ getnum( if (num > max) return NULL; /* illegal value */ c = *++strp; - } while (isdigit(c)); + } while (is_digit(c)); if (num < min) return NULL; /* illegal value */ *nump = num; @@ -692,7 +900,7 @@ getnum( } /* -** Given a pointer into a time zone string, extract a number of seconds, +** Given a pointer into a timezone string, extract a number of seconds, ** in hh[:mm[:ss]] form, from the string. ** If any error occurs, return NULL. ** Otherwise, return a pointer to the first character not part of the number @@ -700,21 +908,21 @@ getnum( */ static const char * -getsecs( - const char * strp, - int32_t * const secsp -) { - int num; +getsecs(register const char *strp, int_fast32_t *const secsp) +{ + int num; + int_fast32_t secsperhour = SECSPERHOUR; + /* - ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like + ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like ** "M10.4.6/26", which does not conform to Posix, ** but which specifies the equivalent of - ** ``02:00 on the first Sunday on or after 23 Oct''. + ** "02:00 on the first Sunday on or after 23 Oct". */ strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); if (strp == NULL) return NULL; - *secsp = num * (int32_t) SECSPERHOUR; + *secsp = num * secsperhour; if (*strp == ':') { ++strp; strp = getnum(strp, &num, 0, MINSPERHOUR - 1); @@ -723,7 +931,7 @@ getsecs( *secsp += num * SECSPERMIN; if (*strp == ':') { ++strp; - /* `SECSPERMIN' allows for leap seconds. */ + /* 'SECSPERMIN' allows for leap seconds. */ strp = getnum(strp, &num, 0, SECSPERMIN); if (strp == NULL) return NULL; @@ -734,20 +942,19 @@ getsecs( } /* -** Given a pointer into a time zone string, extract an offset, in +** Given a pointer into a timezone string, extract an offset, in ** [+-]hh[:mm[:ss]] form, from the string. ** If any error occurs, return NULL. ** Otherwise, return a pointer to the first character not part of the time. */ static const char * -getoffset( - const char * strp, - int32_t * const offsetp -) { - register int neg = 0; +getoffset(register const char *strp, int_fast32_t *const offsetp) +{ + register bool neg = false; + if (*strp == '-') { - neg = 1; + neg = true; ++strp; } else if (*strp == '+') ++strp; @@ -760,17 +967,15 @@ getoffset( } /* -** Given a pointer into a time zone string, extract a rule in the form +** Given a pointer into a timezone string, extract a rule in the form ** date[/time]. See POSIX section 8 for the format of "date" and "time". ** If a valid rule is not found, return NULL. ** Otherwise, return a pointer to the first character not part of the rule. */ static const char * -getrule( - const char * strp, - struct rule * const rulep -) { +getrule(const char *strp, register struct rule *const rulep) +{ if (*strp == 'J') { /* ** Julian day. @@ -795,7 +1000,7 @@ getrule( if (*strp++ != '.') return NULL; strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); - } else if (isdigit(*strp)) { + } else if (is_digit(*strp)) { /* ** Day of year. */ @@ -809,30 +1014,25 @@ getrule( ** Time specified. */ ++strp; - strp = getsecs(strp, &rulep->r_time); + strp = getoffset(strp, &rulep->r_time); } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ return strp; } /* -** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the -** year, a rule, and the offset from UTC at the time that rule takes effect, -** calculate the Epoch-relative time that rule takes effect. +** Given a year, a rule, and the offset from UT at the time that rule takes +** effect, calculate the year-relative time that rule takes effect. */ -static time_t -transtime( - const time_t janfirst, - const int year, - const struct rule * const rulep, - const int32_t offset -) { - register int leapyear; - register time_t value; - register int i; - int d, m1, yy0, yy1, yy2, dow; +static int_fast32_t +transtime(const int year, register const struct rule *const rulep, + const int_fast32_t offset) +{ + register bool leapyear; + register int_fast32_t value; + register int i; + int d, m1, yy0, yy1, yy2, dow; - INITIALIZE(value); leapyear = isleap(year); switch (rulep->r_type) { @@ -844,7 +1044,7 @@ transtime( ** add SECSPERDAY times the day number-1 to the time of ** January 1, midnight, to get the day. */ - value = janfirst + (rulep->r_day - 1) * SECSPERDAY; + value = (rulep->r_day - 1) * SECSPERDAY; if (leapyear && rulep->r_day >= 60) value += SECSPERDAY; break; @@ -855,16 +1055,13 @@ transtime( ** Just add SECSPERDAY times the day number to the time of ** January 1, midnight, to get the day. */ - value = janfirst + rulep->r_day * SECSPERDAY; + value = rulep->r_day * SECSPERDAY; break; case MONTH_NTH_DAY_OF_WEEK: /* ** Mm.n.d - nth "dth day" of month m. */ - value = janfirst; - for (i = 0; i < rulep->r_mon - 1; ++i) - value += kMonthLengths[leapyear][i] * SECSPERDAY; /* ** Use Zeller's Congruence to get day-of-week of first day of @@ -889,7 +1086,7 @@ transtime( d += DAYSPERWEEK; for (i = 1; i < rulep->r_week; ++i) { if (d + DAYSPERWEEK >= - kMonthLengths[leapyear][rulep->r_mon - 1]) + mon_lengths[leapyear][rulep->r_mon - 1]) break; d += DAYSPERWEEK; } @@ -897,15 +1094,19 @@ transtime( /* ** "d" is the day-of-month (zero-origin) of the day we want. */ - value += d * SECSPERDAY; + value = d * SECSPERDAY; + for (i = 0; i < rulep->r_mon - 1; ++i) + value += mon_lengths[leapyear][i] * SECSPERDAY; break; + + default: UNREACHABLE(); } /* - ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in - ** question. To get the Epoch-relative time of the specified local + ** "value" is the year-relative time of 00:00:00 UT on the day in + ** question. To get the year-relative time of the specified local ** time on that day, add the transition time and the current offset - ** from UTC. + ** from UT. */ return value + rulep->r_time + offset; } @@ -915,142 +1116,194 @@ transtime( ** appropriate. */ -static int -tzparse( - const char * name, - struct state * const sp, - const int lastditch -) { - const char * stdname; - const char * dstname; - size_t stdlen; - size_t dstlen; - int32_t stdoffset; - int32_t dstoffset; - register time_t * atp; - register unsigned char *typep; - register char * cp; - register int load_result; +static bool +localtime_tzparse(const char *name, struct state *sp, struct state *basep) +{ + const char * stdname; + const char * dstname; + size_t stdlen; + size_t dstlen; + size_t charcnt; + int_fast32_t stdoffset; + int_fast32_t dstoffset; + register char * cp; + register bool load_ok; + time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN; - INITIALIZE(dstname); stdname = name; - if (lastditch) { - stdlen = strlen(name); /* length of standard zone name */ - name += stdlen; - if (stdlen >= sizeof sp->chars) - stdlen = (sizeof sp->chars) - 1; - stdoffset = 0; + if (*name == '<') { + name++; + stdname = name; + name = getqzname(name, '>'); + if (*name != '>') + return false; + stdlen = name - stdname; + name++; } else { - if (*name == '<') { - name++; - stdname = name; - name = getqzname(name, '>'); - if (*name != '>') - return (-1); - stdlen = name - stdname; - name++; - } else { - name = getzname(name); - stdlen = name - stdname; - } - if (*name == '\0') - return -1; - name = getoffset(name, &stdoffset); - if (name == NULL) - return -1; + name = getzname(name); + stdlen = name - stdname; } - load_result = tzload(TZDEFRULES, sp, FALSE); - if (load_result != 0) - sp->leapcnt = 0; /* so, we're off a little */ - sp->timecnt = 0; + if (!stdlen) + return false; + name = getoffset(name, &stdoffset); + if (name == NULL) + return false; + charcnt = stdlen + 1; + if (sizeof sp->chars < charcnt) + return false; + if (basep) { + if (0 < basep->timecnt) + atlo = basep->ats[basep->timecnt - 1]; + load_ok = false; + sp->leapcnt = basep->leapcnt; + memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis); + } else { + load_ok = localtime_tzload(TZDEFRULES, sp, false) == 0; + if (!load_ok) + sp->leapcnt = 0; /* So, we're off a little. */ + } + if (0 < sp->leapcnt) + leaplo = sp->lsis[sp->leapcnt - 1].ls_trans; if (*name != '\0') { if (*name == '<') { dstname = ++name; name = getqzname(name, '>'); if (*name != '>') - return -1; + return false; dstlen = name - dstname; name++; } else { dstname = name; name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ + dstlen = name - dstname; /* length of DST abbr. */ } + if (!dstlen) + return false; + charcnt += dstlen + 1; + if (sizeof sp->chars < charcnt) + return false; if (*name != '\0' && *name != ',' && *name != ';') { name = getoffset(name, &dstoffset); if (name == NULL) - return -1; + return false; } else dstoffset = stdoffset - SECSPERHOUR; - if (*name == '\0' && load_result != 0) + if (*name == '\0' && !load_ok) name = TZDEFRULESTRING; if (*name == ',' || *name == ';') { struct rule start; struct rule end; register int year; - register time_t janfirst; - time_t starttime; - time_t endtime; + register int timecnt; + time_t janfirst; + int_fast32_t janoffset = 0; + int yearbeg, yearlim; ++name; if ((name = getrule(name, &start)) == NULL) - return -1; + return false; if (*name++ != ',') - return -1; + return false; if ((name = getrule(name, &end)) == NULL) - return -1; + return false; if (*name != '\0') - return -1; + return false; sp->typecnt = 2; /* standard time and DST */ /* ** Two transitions per year, from EPOCH_YEAR forward. */ - sp->ttis[0].tt_gmtoff = -dstoffset; - sp->ttis[0].tt_isdst = 1; - sp->ttis[0].tt_abbrind = stdlen + 1; - sp->ttis[1].tt_gmtoff = -stdoffset; - sp->ttis[1].tt_isdst = 0; - sp->ttis[1].tt_abbrind = 0; - atp = sp->ats; - typep = sp->types; + init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); + init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); + sp->defaulttype = 0; + timecnt = 0; janfirst = 0; - for (year = EPOCH_YEAR; - sp->timecnt + 2 <= TZ_MAX_TIMES; - ++year) { - time_t newfirst; + yearbeg = EPOCH_YEAR; - starttime = transtime(janfirst, year, &start, - stdoffset); - endtime = transtime(janfirst, year, &end, - dstoffset); - if (starttime > endtime) { - *atp++ = endtime; - *typep++ = 1; /* DST ends */ - *atp++ = starttime; - *typep++ = 0; /* DST begins */ - } else { - *atp++ = starttime; - *typep++ = 0; /* DST begins */ - *atp++ = endtime; - *typep++ = 1; /* DST ends */ - } - sp->timecnt += 2; - newfirst = janfirst; - newfirst += kYearLengths[isleap(year)] * - SECSPERDAY; - if (newfirst <= janfirst) - break; - janfirst = newfirst; + do { + int_fast32_t yearsecs + = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; + yearbeg--; + if (increment_overflow_time(&janfirst, -yearsecs)) { + janoffset = -yearsecs; + break; + } + } while (atlo < janfirst + && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); + + while (true) { + int_fast32_t yearsecs + = year_lengths[isleap(yearbeg)] * SECSPERDAY; + int yearbeg1 = yearbeg; + time_t janfirst1 = janfirst; + if (increment_overflow_time(&janfirst1, yearsecs) + || increment_overflow(&yearbeg1, 1) + || atlo <= janfirst1) + break; + yearbeg = yearbeg1; + janfirst = janfirst1; } + + yearlim = yearbeg; + if (increment_overflow(&yearlim, YEARSPERREPEAT + 1)) + yearlim = INT_MAX; + for (year = yearbeg; year < yearlim; year++) { + int_fast32_t + starttime = transtime(year, &start, stdoffset), + endtime = transtime(year, &end, dstoffset); + int_fast32_t + yearsecs = (year_lengths[isleap(year)] + * SECSPERDAY); + bool reversed = endtime < starttime; + if (reversed) { + int_fast32_t swap = starttime; + starttime = endtime; + endtime = swap; + } + if (reversed + || (starttime < endtime + && endtime - starttime < yearsecs)) { + if (TZ_MAX_TIMES - 2 < timecnt) + break; + sp->ats[timecnt] = janfirst; + if (! increment_overflow_time + (&sp->ats[timecnt], + janoffset + starttime) + && atlo <= sp->ats[timecnt]) + sp->types[timecnt++] = !reversed; + sp->ats[timecnt] = janfirst; + if (! increment_overflow_time + (&sp->ats[timecnt], + janoffset + endtime) + && atlo <= sp->ats[timecnt]) { + sp->types[timecnt++] = reversed; + } + } + if (endtime < leaplo) { + yearlim = year; + if (increment_overflow(&yearlim, + YEARSPERREPEAT + 1)) + yearlim = INT_MAX; + } + if (increment_overflow_time + (&janfirst, janoffset + yearsecs)) + break; + janoffset = 0; + } + sp->timecnt = timecnt; + if (! timecnt) { + sp->ttis[0] = sp->ttis[1]; + sp->typecnt = 1; /* Perpetual DST. */ + } else if (YEARSPERREPEAT < year - yearbeg) + sp->goback = sp->goahead = true; } else { - register int32_t theirstdoffset; - register int32_t theirdstoffset; - register int32_t theiroffset; - register int isdst; + register int_fast32_t theirstdoffset; + register int_fast32_t theirdstoffset; + register int_fast32_t theiroffset; + register bool isdst; register int i; register int j; if (*name != '\0') - return -1; + return false; /* ** Initial values of theirstdoffset and theirdstoffset. */ @@ -1059,7 +1312,7 @@ tzparse( j = sp->types[i]; if (!sp->ttis[j].tt_isdst) { theirstdoffset = - -sp->ttis[j].tt_gmtoff; + - sp->ttis[j].tt_utoff; break; } } @@ -1068,15 +1321,14 @@ tzparse( j = sp->types[i]; if (sp->ttis[j].tt_isdst) { theirdstoffset = - -sp->ttis[j].tt_gmtoff; + - sp->ttis[j].tt_utoff; break; } } /* ** Initially we're assumed to be in standard time. */ - isdst = FALSE; - theiroffset = theirstdoffset; + isdst = false; /* ** Now juggle transition times and types ** tracking offsets as you do. @@ -1084,16 +1336,17 @@ tzparse( for (i = 0; i < sp->timecnt; ++i) { j = sp->types[i]; sp->types[i] = sp->ttis[j].tt_isdst; - if (sp->ttis[j].tt_ttisgmt) { + if (sp->ttis[j].tt_ttisut) { /* No adjustment to transition time */ } else { /* - ** If summer time is in effect, and the - ** transition time was not specified as - ** standard time, add the summer time - ** offset to the transition time; - ** otherwise, add the standard time - ** offset to the transition time. + ** If daylight saving time is in + ** effect, and the transition time was + ** not specified as standard time, add + ** the daylight saving time offset to + ** the transition time; otherwise, add + ** the standard time offset to the + ** transition time. */ /* ** Transitions from DST to DDST @@ -1109,206 +1362,192 @@ tzparse( theirstdoffset; } } - theiroffset = -sp->ttis[j].tt_gmtoff; + theiroffset = -sp->ttis[j].tt_utoff; if (sp->ttis[j].tt_isdst) theirdstoffset = theiroffset; else theirstdoffset = theiroffset; } /* ** Finally, fill in ttis. - ** ttisstd and ttisgmt need not be handled. */ - sp->ttis[0].tt_gmtoff = -stdoffset; - sp->ttis[0].tt_isdst = FALSE; - sp->ttis[0].tt_abbrind = 0; - sp->ttis[1].tt_gmtoff = -dstoffset; - sp->ttis[1].tt_isdst = TRUE; - sp->ttis[1].tt_abbrind = stdlen + 1; + init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); + init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); sp->typecnt = 2; + sp->defaulttype = 0; } } else { dstlen = 0; sp->typecnt = 1; /* only standard time */ sp->timecnt = 0; - sp->ttis[0].tt_gmtoff = -stdoffset; - sp->ttis[0].tt_isdst = 0; - sp->ttis[0].tt_abbrind = 0; + init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); + sp->defaulttype = 0; } - sp->charcnt = stdlen + 1; - if (dstlen != 0) - sp->charcnt += dstlen + 1; - if ((size_t) sp->charcnt > sizeof sp->chars) - return -1; + sp->charcnt = charcnt; cp = sp->chars; - (void) strncpy(cp, stdname, stdlen); + memcpy(cp, stdname, stdlen); cp += stdlen; *cp++ = '\0'; if (dstlen != 0) { - (void) strncpy(cp, dstname, dstlen); + memcpy(cp, dstname, dstlen); *(cp + dstlen) = '\0'; } - return 0; + return true; } static void -gmtload( - struct state * const sp -) { - if (tzload(gmt, sp, TRUE) != 0) - (void) tzparse(gmt, sp, TRUE); +gmtload(struct state *const sp) +{ + if (localtime_tzload(gmt, sp, true) != 0) + localtime_tzparse("GMT0", sp, NULL); } -#ifndef STD_INSPIRED -/* -** A non-static declaration of tzsetwall in a system header file -** may cause a warning about this upcoming static declaration... -*/ -static -#endif /* !defined STD_INSPIRED */ -void -tzsetwall(void) +/* Initialize *SP to a value appropriate for the TZ setting NAME. + Return 0 on success, an errno value on failure. */ +static int +zoneinit(struct state *sp, char const *name) { - if (lcl_is_set < 0) - return; - lcl_is_set = -1; -#ifdef ALL_STATE - if (lclptr == NULL) { - if ((lclptr = malloc(sizeof(*lclptr)))) { - __cxa_atexit(free, lclptr, 0); - } else { - settzname(); /* all we can do */ - return; - } + if (name && ! name[0]) { + /* + ** User wants it fast rather than right. + */ + sp->leapcnt = 0; /* so, we're off a little */ + sp->timecnt = 0; + sp->typecnt = 0; + sp->charcnt = 0; + sp->goback = sp->goahead = false; + init_ttinfo(&sp->ttis[0], 0, false, 0); + strcpy(sp->chars, gmt); + sp->defaulttype = 0; + return 0; + } else { + int err = localtime_tzload(name, sp, true); + if (err != 0 && name && name[0] != ':' && + localtime_tzparse(name, sp, NULL)) + err = 0; + if (err == 0) + scrub_abbrs(sp); + return err; } +} + +static void +localtime_tzset_unlocked(void) +{ + char const *name = getenv("TZ"); + struct state *sp = lclptr; + int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; + if (lcl < 0 + ? lcl_is_set < 0 + : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) + return; +#ifdef ALL_STATE + if (! sp) + lclptr = sp = malloc(sizeof *lclptr); #endif /* defined ALL_STATE */ - if (tzload((char *) NULL, lclptr, TRUE) != 0) - gmtload(lclptr); + if (sp) { + if (zoneinit(sp, name) != 0) + zoneinit(sp, ""); + if (0 < lcl) + strcpy(lcl_TZname, name); + } settzname(); + lcl_is_set = lcl; } void tzset(void) { - register const char * name = NULL; - /* static char buf[PROP_VALUE_MAX]; */ - - name = getenv("TZ"); - - /* // try the "persist.sys.timezone" system property first */ - /* if (name == NULL && __system_property_get("persist.sys.timezone", buf) > 0) */ - /* name = buf; */ - - if (name == NULL) { - tzsetwall(); + if (lock() != 0) return; - } + localtime_tzset_unlocked(); + unlock(); +} - if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) +static void +localtime_gmtcheck(void) +{ + static bool gmt_is_set; + if (lock() != 0) return; - lcl_is_set = strlen(name) < sizeof lcl_TZname; - if (lcl_is_set) - (void) strcpy(lcl_TZname, name); - + if (! gmt_is_set) { #ifdef ALL_STATE - if (lclptr == NULL) { - if ((lclptr = malloc(sizeof(*lclptr)))) { - __cxa_atexit(free, lclptr, 0); - } else { - settzname(); /* all we can do */ - return; - } + gmtptr = malloc(sizeof *gmtptr); +#endif + if (gmtptr) + gmtload(gmtptr); + gmt_is_set = true; } -#endif /* defined ALL_STATE */ - if (*name == '\0') { - /* - ** User wants it fast rather than right. - */ - lclptr->leapcnt = 0; /* so, we're off a little */ - lclptr->timecnt = 0; - lclptr->typecnt = 0; - lclptr->ttis[0].tt_isdst = 0; - lclptr->ttis[0].tt_gmtoff = 0; - lclptr->ttis[0].tt_abbrind = 0; - (void) strcpy(lclptr->chars, gmt); - } else if (tzload(name, lclptr, TRUE) != 0) - if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) - (void) gmtload(lclptr); - settzname(); + unlock(); } /* ** The easy way to behave "as if no library function calls" localtime -** is to not call it--so we drop its guts into "localsub", which can be -** freely called. (And no, the PANS doesn't require the above behavior-- +** is to not call it, so we drop its guts into "localsub", which can be +** freely called. (And no, the PANS doesn't require the above behavior, ** but it *is* desirable.) ** -** The unused offset argument is for the benefit of mktime variants. +** If successful and SETNAME is nonzero, +** set the applicable parts of tzname, timezone and altzone; +** however, it's OK to omit this step if the timezone is POSIX-compatible, +** since in that case tzset should have already done this step correctly. +** SETNAME's type is int_fast32_t for compatibility with gmtsub, +** but it is actually a boolean and its value should be 0 or 1. */ /*ARGSUSED*/ static struct tm * -localsub( - const time_t * const timep, - const int32_t offset, - struct tm * const tmp -) { - register struct state * sp; +localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, + struct tm *const tmp) +{ register const struct ttinfo * ttisp; register int i; register struct tm * result; const time_t t = *timep; - sp = lclptr; -#ifdef ALL_STATE - if (sp == NULL) - return gmtsub(timep, offset, tmp); -#endif /* defined ALL_STATE */ + if (sp == NULL) { + /* Don't bother to set tzname etc.; tzset has already done it. */ + return gmtsub(gmtptr, timep, 0, tmp); + } if ((sp->goback && t < sp->ats[0]) || (sp->goahead && t > sp->ats[sp->timecnt - 1])) { - time_t newt = t; + time_t newt; register time_t seconds; - register time_t tcycles; - register int_fast64_t icycles; + register time_t years; if (t < sp->ats[0]) seconds = sp->ats[0] - t; else seconds = t - sp->ats[sp->timecnt - 1]; --seconds; - tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR; - ++tcycles; - icycles = tcycles; - if (tcycles - icycles >= 1 || icycles - tcycles >= 1) - return NULL; - seconds = icycles; - seconds *= YEARSPERREPEAT; - seconds *= AVGSECSPERYEAR; + + /* Beware integer overflow, as SECONDS might + be close to the maximum time_t. */ + years = seconds / SECSPERREPEAT * YEARSPERREPEAT; + seconds = years * AVGSECSPERYEAR; + years += YEARSPERREPEAT; if (t < sp->ats[0]) - newt += seconds; - else newt -= seconds; + newt = t + seconds + SECSPERREPEAT; + else + newt = t - seconds - SECSPERREPEAT; + if (newt < sp->ats[0] || newt > sp->ats[sp->timecnt - 1]) return NULL; /* "cannot happen" */ - result = localsub(&newt, offset, tmp); - if (result == tmp) { - register time_t newy; + result = localsub(sp, &newt, setname, tmp); + if (result) { + register int_fast64_t newy; - newy = tmp->tm_year; + newy = result->tm_year; if (t < sp->ats[0]) - newy -= icycles * YEARSPERREPEAT; - else newy += icycles * YEARSPERREPEAT; - tmp->tm_year = newy; - if (tmp->tm_year != newy) + newy -= years; + else newy += years; + if (! (INT_MIN <= newy && newy <= INT_MAX)) return NULL; + result->tm_year = newy; } return result; } if (sp->timecnt == 0 || t < sp->ats[0]) { - i = 0; - while (sp->ttis[i].tt_isdst) - if (++i >= sp->typecnt) { - i = 0; - break; - } + i = sp->defaulttype; } else { register int lo = 1; register int hi = sp->timecnt; @@ -1320,43 +1559,50 @@ localsub( hi = mid; else lo = mid + 1; } - i = (int) sp->types[lo - 1]; + i = sp->types[lo - 1]; } ttisp = &sp->ttis[i]; /* ** To get (wrong) behavior that's compatible with System V Release 2.0 ** you'd replace the statement below with - ** t += ttisp->tt_gmtoff; + ** t += ttisp->tt_utoff; ** timesub(&t, 0L, sp, tmp); */ - result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); - tmp->tm_isdst = ttisp->tt_isdst; - tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; -#ifdef TM_ZONE - tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; -#endif /* defined TM_ZONE */ + result = localtime_timesub(&t, ttisp->tt_utoff, sp, tmp); + if (result) { + result->tm_isdst = ttisp->tt_isdst; + result->tm_zone = (char *) &sp->chars[ttisp->tt_desigidx]; + if (setname) + update_tzname_etc(sp, ttisp); + } return result; } -struct tm * -localtime( - const time_t * const timep -) { - tzset(); - return localsub(timep, 0L, &tm); +static struct tm * +localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) +{ + int err = lock(); + if (err) { + errno = err; + return NULL; + } + if (setname || !lcl_is_set) + localtime_tzset_unlocked(); + tmp = localsub(lclptr, timep, setname, tmp); + unlock(); + return tmp; } -/* -** Re-entrant version of localtime. -*/ +struct tm * +localtime(const time_t *timep) +{ + return localtime_tzset(timep, &tm, true); +} struct tm * -localtime_r( - const time_t * const timep, - struct tm * tmp -) { - tzset(); - return localsub(timep, 0L, tmp); +localtime_r(const time_t *timep, struct tm *tmp) +{ + return localtime_tzset(timep, tmp, false); } /* @@ -1364,249 +1610,164 @@ localtime_r( */ static struct tm * -gmtsub( - const time_t * const timep, - const int32_t offset, - struct tm * const tmp -) { +gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset, + struct tm *tmp) +{ register struct tm * result; - if (!gmt_is_set) { - gmt_is_set = TRUE; -#ifdef ALL_STATE - if (!gmtptr) { - gmtptr = malloc(sizeof(*gmtptr)); - __cxa_atexit(free, gmtptr, 0); - } - if (gmtptr) -#endif /* defined ALL_STATE */ - gmtload(gmtptr); - } - result = timesub(timep, offset, gmtptr, tmp); -#ifdef TM_ZONE + + result = localtime_timesub(timep, offset, gmtptr, tmp); /* ** Could get fancy here and deliver something such as - ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero, + ** "+xx" or "-xx" if offset is non-zero, ** but this is no time for a treasure hunt. */ - if (offset != 0) - tmp->TM_ZONE = wildabbr; - else { -#ifdef ALL_STATE - if (gmtptr == NULL) - tmp->TM_ZONE = gmt; - else tmp->TM_ZONE = gmtptr->chars; -#endif /* defined ALL_STATE */ -#ifndef ALL_STATE - tmp->TM_ZONE = gmtptr->chars; -#endif /* State Farm */ - } -#endif /* defined TM_ZONE */ + tmp->tm_zone = ((char *) + (offset ? wildabbr : gmtptr ? gmtptr->chars : gmt)); return result; } -struct tm * -gmtime( - const time_t * const timep -) { - return gmtsub(timep, 0L, &tm); -} - /* * Re-entrant version of gmtime. */ struct tm * -gmtime_r( - const time_t * const timep, - struct tm * tmp -) { - return gmtsub(timep, 0L, tmp); +gmtime_r(const time_t *timep, struct tm *tmp) +{ + localtime_gmtcheck(); + return gmtsub(gmtptr, timep, 0, tmp); } -#ifdef STD_INSPIRED - struct tm * -offtime( - const time_t * const timep, - const int32_t offset -) { - return gmtsub(timep, offset, &tm); +gmtime(const time_t *timep) +{ + return gmtime_r(timep, &tm); } -#endif /* defined STD_INSPIRED */ - /* ** Return the number of leap years through the end of the given year ** where, to make the math easy, the answer for year zero is defined as zero. */ -pureconst optimizespeed static int -leaps_thru_end_of( - const int y -) { - return (y >= 0) ? (y / 4 - y / 100 + y / 400) : - -(leaps_thru_end_of(-(y + 1)) + 1); +static time_t +leaps_thru_end_of_nonneg(time_t y) +{ + return y / 4 - y / 100 + y / 400; +} + +static time_t +leaps_thru_end_of(time_t y) +{ + return (y < 0 + ? -1 - leaps_thru_end_of_nonneg(-1 - y) + : leaps_thru_end_of_nonneg(y)); } static struct tm * -timesub( - const time_t * const timep, - const int32_t offset, - const struct state * const sp, - struct tm * const tmp -) { - const struct lsinfo * lp; - time_t tdays; - int idays; /* unsigned would be so 2003 */ - long rem; /* ^wut */ - int y; - int leap; - long corr; - int hit; - int i; +localtime_timesub(const time_t *timep, int_fast32_t offset, + const struct state *sp, struct tm *tmp) +{ + register const struct lsinfo * lp; + register time_t tdays; + register const int * ip; + register int_fast32_t corr; + register int i; + int_fast32_t idays, rem, dayoff, dayrem; + time_t y; + + /* If less than SECSPERMIN, the number of seconds since the + most recent positive leap second; otherwise, do not add 1 + to localtime tm_sec because of leap seconds. */ + time_t secs_since_posleap = SECSPERMIN; corr = 0; - hit = 0; -#ifdef ALL_STATE i = (sp == NULL) ? 0 : sp->leapcnt; -#endif /* defined ALL_STATE */ -#ifndef ALL_STATE - i = sp->leapcnt; -#endif /* State Farm */ while (--i >= 0) { lp = &sp->lsis[i]; if (*timep >= lp->ls_trans) { - if (*timep == lp->ls_trans) { - hit = ((i == 0 && lp->ls_corr > 0) || - lp->ls_corr > sp->lsis[i - 1].ls_corr); - if (hit) - while (i > 0 && - sp->lsis[i].ls_trans == - sp->lsis[i - 1].ls_trans + 1 && - sp->lsis[i].ls_corr == - sp->lsis[i - 1].ls_corr + 1) { - ++hit; - --i; - } - } corr = lp->ls_corr; + if ((i == 0 ? 0 : lp[-1].ls_corr) < corr) + secs_since_posleap = *timep - lp->ls_trans; break; } } - y = EPOCH_YEAR; - tdays = *timep / SECSPERDAY; - rem = *timep - tdays * SECSPERDAY; - while (tdays < 0 || tdays >= kYearLengths[isleap(y)]) { - int newy; - register time_t tdelta; - register int idelta; - register int leapdays; - tdelta = tdays / DAYSPERLYEAR; - idelta = tdelta; - if (tdelta - idelta >= 1 || idelta - tdelta >= 1) - return NULL; - if (idelta == 0) - idelta = (tdays < 0) ? -1 : 1; - newy = y; - if (increment_overflow(&newy, idelta)) - return NULL; + /* Calculate the year, avoiding integer overflow even if + time_t is unsigned. */ + tdays = *timep / SECSPERDAY; + rem = *timep % SECSPERDAY; + rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; + dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; + rem %= SECSPERDAY; + /* y = (EPOCH_YEAR + + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), + sans overflow. But calculate against 1570 (EPOCH_YEAR - + YEARSPERREPEAT) instead of against 1970 so that things work + for localtime values before 1970 when time_t is unsigned. */ + dayrem = tdays % DAYSPERREPEAT; + dayrem += dayoff % DAYSPERREPEAT; + y = (EPOCH_YEAR - YEARSPERREPEAT + + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT + - ((dayrem % DAYSPERREPEAT) < 0) + + tdays / DAYSPERREPEAT) + * YEARSPERREPEAT)); + /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ + idays = tdays % DAYSPERREPEAT; + idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT; + idays %= DAYSPERREPEAT; + /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ + while (year_lengths[isleap(y)] <= idays) { + int tdelta = idays / DAYSPERLYEAR; + int_fast32_t ydelta = tdelta + !tdelta; + time_t newy = y + ydelta; + register int leapdays; leapdays = leaps_thru_end_of(newy - 1) - leaps_thru_end_of(y - 1); - tdays -= ((time_t) newy - y) * DAYSPERNYEAR; - tdays -= leapdays; + idays -= ydelta * DAYSPERNYEAR; + idays -= leapdays; y = newy; } - { - register long seconds; - seconds = tdays * SECSPERDAY + 0.5; - tdays = seconds / SECSPERDAY; - rem += seconds - tdays * SECSPERDAY; + if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { + int signed_y = y; + tmp->tm_year = signed_y - TM_YEAR_BASE; + } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) + && y - TM_YEAR_BASE <= INT_MAX) + tmp->tm_year = y - TM_YEAR_BASE; + else { + errno = EOVERFLOW; + return NULL; } - /* - ** Given the range, we can now fearlessly cast... - */ - idays = tdays; - rem += offset - corr; - while (rem < 0) { - rem += SECSPERDAY; - --idays; - } - while (rem >= SECSPERDAY) { - rem -= SECSPERDAY; - ++idays; - } - while (idays < 0) { - if (increment_overflow(&y, -1)) - return NULL; - idays += kYearLengths[isleap(y)]; - } - while (idays >= kYearLengths[isleap(y)]) { - idays -= kYearLengths[isleap(y)]; - if (increment_overflow(&y, 1)) - return NULL; - } - tmp->tm_year = y; - if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) - return NULL; tmp->tm_yday = idays; /* ** The "extra" mods below avoid overflow problems. */ - tmp->tm_wday = EPOCH_WDAY + - ((y - EPOCH_YEAR) % DAYSPERWEEK) * - (DAYSPERNYEAR % DAYSPERWEEK) + - leaps_thru_end_of(y - 1) - - leaps_thru_end_of(EPOCH_YEAR - 1) + - idays; + tmp->tm_wday = (TM_WDAY_BASE + + ((tmp->tm_year % DAYSPERWEEK) + * (DAYSPERNYEAR % DAYSPERWEEK)) + + leaps_thru_end_of(y - 1) + - leaps_thru_end_of(TM_YEAR_BASE - 1) + + idays); tmp->tm_wday %= DAYSPERWEEK; if (tmp->tm_wday < 0) tmp->tm_wday += DAYSPERWEEK; - tmp->tm_hour = (int) (rem / SECSPERHOUR); + tmp->tm_hour = rem / SECSPERHOUR; rem %= SECSPERHOUR; - tmp->tm_min = (int) (rem / SECSPERMIN); - /* - ** A positive leap second requires a special - ** representation. This uses "... ??:59:60" et seq. - */ - tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; - leap = isleap(y); - for (tmp->tm_mon = 0; - idays >= kMonthLengths[leap][tmp->tm_mon]; - ++(tmp->tm_mon)) { - idays -= kMonthLengths[leap][tmp->tm_mon]; - } - tmp->tm_mday = (int) (idays + 1); + tmp->tm_min = rem / SECSPERMIN; + tmp->tm_sec = rem % SECSPERMIN; + + /* Use "... ??:??:60" at the end of the localtime minute containing + the second just before the positive leap second. */ + tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; + + ip = mon_lengths[isleap(y)]; + for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) + idays -= ip[tmp->tm_mon]; + tmp->tm_mday = idays + 1; tmp->tm_isdst = 0; -#ifdef TM_GMTOFF - tmp->TM_GMTOFF = offset; -#endif /* defined TM_GMTOFF */ + tmp->tm_gmtoff = offset; return tmp; } -/* char * */ -/* ctime(timep) */ -/* const time_t * const timep; */ -/* { */ -/* /\* */ -/* ** Section 4.12.3.2 of X3.159-1989 requires that */ -/* ** The ctime function converts the calendar time pointed to by timer */ -/* ** to local time in the form of a string. It is equivalent to */ -/* ** asctime(localtime(timer)) */ -/* *\/ */ -/* return asctime(localtime(timep)); */ -/* } */ - -/* char * */ -/* ctime_r(timep, buf) */ -/* const time_t * const timep; */ -/* char * buf; */ -/* { */ -/* struct tm mytm; */ -/* return asctime_r(localtime_r(timep, &mytm), buf); */ -/* } */ - /* ** Adapted from code provided by Robert Elz, who writes: ** The "best" way to do mktime I think is based on an idea of Bob @@ -1621,31 +1782,77 @@ timesub( #endif /* !defined WRONG */ /* -** Simplified normalize logic courtesy Paul Eggert. +** Normalize logic courtesy Paul Eggert. */ -static inline int -increment_overflow( - int * number, - int delta -) { -#ifdef __GNUC__ - return __builtin_add_overflow(*number, delta, number); +static inline bool +increment_overflow(int *ip, int j) +{ +#if defined(__GNUC__) && __GNUC__ >= 6 + int i = *ip; + if (__builtin_add_overflow(i, j, &i)) return true; + *ip = i; + return false; #else - int number0; - number0 = *number; - *number += delta; - return (*number < number0) != (delta < 0); + register int const i = *ip; + /* + ** If i >= 0 there can only be overflow if i + j > INT_MAX + ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. + ** If i < 0 there can only be overflow if i + j < INT_MIN + ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. + */ + if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) + return true; + *ip += j; + return false; #endif } -static int -normalize_overflow( - int * const tensptr, - int * const unitsptr, - const int base -) { +static inline bool +increment_overflow32(int_fast32_t *const lp, int const m) +{ +#if defined(__GNUC__) && __GNUC__ >= 6 + int_fast32_t i = *lp; + if (__builtin_add_overflow(i, m, &i)) return true; + *lp = i; + return false; +#else + register int_fast32_t const l = *lp; + if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) + return true; + *lp += m; + return false; +#endif +} + +static inline bool +increment_overflow_time(time_t *tp, int_fast32_t j) +{ +#if defined(__GNUC__) && __GNUC__ >= 6 + time_t i = *tp; + if (__builtin_add_overflow(i, j, &i)) return true; + *tp = i; + return false; +#else + /* + ** This is like + ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', + ** except that it does the right thing even if *tp + j would overflow. + */ + if (! (j < 0 + ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) + : *tp <= TIME_T_MAX - j)) + return true; + *tp += j; + return false; +#endif +} + +static bool +normalize_overflow(int *const tensptr, int *const unitsptr, const int base) +{ register int tensdelta; + tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base); @@ -1653,14 +1860,27 @@ normalize_overflow( return increment_overflow(tensptr, tensdelta); } +static bool +normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base) +{ + register int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return increment_overflow32(tensptr, tensdelta); +} + static int -tmcomp( - const struct tm * const atmp, - const struct tm * const btmp -) { +tmcomp(register const struct tm *const atmp, + register const struct tm *const btmp) +{ register int result; - if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && - (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + + if (atmp->tm_year != btmp->tm_year) + return atmp->tm_year < btmp->tm_year ? -1 : 1; + if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && (result = (atmp->tm_min - btmp->tm_min)) == 0) @@ -1669,25 +1889,27 @@ tmcomp( } static time_t -time2sub( - struct tm * const tmp, - struct tm * (* const funcp)(const time_t*, int32_t, struct tm*), - const int32_t offset, - int * const okayp, - const int do_norm_secs -) { - register const struct state * sp; +localtime_time2sub( + struct tm *const tmp, + struct tm *(*funcp)(struct state const *, time_t const *, + int_fast32_t, struct tm *), + struct state const *sp, + const int_fast32_t offset, + bool *okayp, + bool do_norm_secs) +{ register int dir; register int i, j; register int saved_seconds; - register long li; + register int_fast32_t li; register time_t lo; register time_t hi; - int32_t y; + int_fast32_t y; time_t newt; time_t t; struct tm yourtm, mytm; - *okayp = FALSE; + + *okayp = false; yourtm = *tmp; if (do_norm_secs) { if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, @@ -1699,42 +1921,42 @@ time2sub( if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) return WRONG; y = yourtm.tm_year; - if (normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR)) + if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) return WRONG; /* ** Turn y into an actual year number for now. ** It is converted back to an offset from TM_YEAR_BASE later. */ - if (increment_overflow(&y, TM_YEAR_BASE)) + if (increment_overflow32(&y, TM_YEAR_BASE)) return WRONG; while (yourtm.tm_mday <= 0) { - if (increment_overflow(&y, -1)) + if (increment_overflow32(&y, -1)) return WRONG; li = y + (1 < yourtm.tm_mon); - yourtm.tm_mday += kYearLengths[isleap(li)]; + yourtm.tm_mday += year_lengths[isleap(li)]; } while (yourtm.tm_mday > DAYSPERLYEAR) { li = y + (1 < yourtm.tm_mon); - yourtm.tm_mday -= kYearLengths[isleap(li)]; - if (increment_overflow(&y, 1)) + yourtm.tm_mday -= year_lengths[isleap(li)]; + if (increment_overflow32(&y, 1)) return WRONG; } for ( ; ; ) { - i = kMonthLengths[isleap(y)][yourtm.tm_mon]; + i = mon_lengths[isleap(y)][yourtm.tm_mon]; if (yourtm.tm_mday <= i) break; yourtm.tm_mday -= i; if (++yourtm.tm_mon >= MONSPERYEAR) { yourtm.tm_mon = 0; - if (increment_overflow(&y, 1)) + if (increment_overflow32(&y, 1)) return WRONG; } } - if (increment_overflow(&y, -TM_YEAR_BASE)) + if (increment_overflow32(&y, -TM_YEAR_BASE)) + return WRONG; + if (! (INT_MIN <= y && y <= INT_MAX)) return WRONG; yourtm.tm_year = y; - if (yourtm.tm_year != y) - return WRONG; if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) saved_seconds = 0; else if (y + TM_YEAR_BASE < EPOCH_YEAR) { @@ -1757,27 +1979,15 @@ time2sub( /* ** Do a binary search (this works whatever time_t's type is). */ - if (!TYPE_SIGNED(time_t)) { - lo = 0; - hi = lo - 1; - } else if (!TYPE_INTEGRAL(time_t)) { - if (sizeof(time_t) > sizeof(float)) - hi = (time_t) DBL_MAX; - else hi = (time_t) FLT_MAX; - lo = -hi; - } else { - lo = 1; - for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) - lo *= 2; - hi = -(lo + 1); - } + lo = TIME_T_MIN; + hi = TIME_T_MAX; for ( ; ; ) { t = lo / 2 + hi / 2; if (t < lo) t = lo; else if (t > hi) t = hi; - if ((*funcp)(&t, offset, &mytm) == NULL) { + if (! funcp(sp, &t, offset, &mytm)) { /* ** Assume that t is too extreme to be represented in ** a struct tm; arrange things so that it is less @@ -1787,14 +1997,14 @@ time2sub( } else dir = tmcomp(&mytm, &yourtm); if (dir != 0) { if (t == lo) { - ++t; - if (t <= lo) + if (t == TIME_T_MAX) return WRONG; + ++t; ++lo; } else if (t == hi) { - --t; - if (t >= hi) + if (t == TIME_T_MIN) return WRONG; + --t; --hi; } if (lo > hi) @@ -1804,6 +2014,35 @@ time2sub( else lo = t; continue; } +#if defined TM_GMTOFF && ! UNINIT_TRAP + if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF + && (yourtm.TM_GMTOFF < 0 + ? (-SECSPERDAY <= yourtm.TM_GMTOFF + && (mytm.TM_GMTOFF <= + (SMALLEST(INT_FAST32_MAX, LONG_MAX) + + yourtm.TM_GMTOFF))) + : (yourtm.TM_GMTOFF <= SECSPERDAY + && ((BIGGEST(INT_FAST32_MIN, LONG_MIN) + + yourtm.TM_GMTOFF) + <= mytm.TM_GMTOFF)))) { + /* MYTM matches YOURTM except with the wrong UT offset. + YOURTM.TM_GMTOFF is plausible, so try it instead. + It's OK if YOURTM.TM_GMTOFF contains uninitialized data, + since the guess gets checked. */ + time_t altt = t; + int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF; + if (!increment_overflow_time(&altt, diff)) { + struct tm alttm; + if (funcp(sp, &altt, offset, &alttm) + && alttm.tm_isdst == mytm.tm_isdst + && alttm.TM_GMTOFF == yourtm.TM_GMTOFF + && tmcomp(&alttm, &yourtm) == 0) { + t = altt; + mytm = alttm; + } + } + } +#endif if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) break; /* @@ -1812,25 +2051,19 @@ time2sub( ** It's okay to guess wrong since the guess ** gets checked. */ - /* - ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. - */ - sp = (const struct state *) - (((void *) funcp == (void *) localsub) ? - lclptr : gmtptr); -#ifdef ALL_STATE if (sp == NULL) return WRONG; -#endif /* defined ALL_STATE */ for (i = sp->typecnt - 1; i >= 0; --i) { if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) continue; for (j = sp->typecnt - 1; j >= 0; --j) { if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) continue; - newt = t + sp->ttis[j].tt_gmtoff - - sp->ttis[i].tt_gmtoff; - if ((*funcp)(&newt, offset, &mytm) == NULL) + if (ttunspecified(sp, j)) + continue; + newt = (t + sp->ttis[j].tt_utoff + - sp->ttis[i].tt_utoff); + if (! funcp(sp, &newt, offset, &mytm)) continue; if (tmcomp(&mytm, &yourtm) != 0) continue; @@ -1850,57 +2083,64 @@ label: if ((newt < t) != (saved_seconds < 0)) return WRONG; t = newt; - if ((*funcp)(&t, offset, tmp)) - *okayp = TRUE; + if (funcp(sp, &t, offset, tmp)) + *okayp = true; return t; } static time_t -time2( - struct tm * const tmp, - struct tm * (* const funcp)(const time_t*, int32_t, struct tm*), - const int32_t offset, - int * const okayp -) { - time_t t; +localtime_time2( + struct tm * const tmp, + struct tm *(*funcp)(struct state const *, time_t const *, + int_fast32_t, struct tm *), + struct state const *sp, + const int_fast32_t offset, + bool *okayp) +{ + time_t t; + /* ** First try without normalization of seconds ** (in case tm_sec contains a value associated with a leap second). ** If that fails, try with normalization of seconds. */ - t = time2sub(tmp, funcp, offset, okayp, FALSE); - return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE); + t = localtime_time2sub(tmp, funcp, sp, offset, okayp, false); + return *okayp ? t : localtime_time2sub(tmp,funcp,sp,offset,okayp,true); } static time_t -time1( - struct tm * const tmp, - struct tm * (* const funcp)(const time_t *, int32_t, struct tm *), - const int32_t offset -) { +localtime_time1( + struct tm *const tmp, + struct tm *(*funcp)(struct state const *, time_t const *, + int_fast32_t, struct tm *), + struct state const *sp, + const int_fast32_t offset) +{ register time_t t; - register const struct state * sp; register int samei, otheri; register int sameind, otherind; register int i; register int nseen; - int seen[TZ_MAX_TYPES]; - int types[TZ_MAX_TYPES]; - int okay; + char seen[TZ_MAX_TYPES]; + unsigned char types[TZ_MAX_TYPES]; + bool okay; + + if (tmp == NULL) { + errno = EINVAL; + return WRONG; + } if (tmp->tm_isdst > 1) tmp->tm_isdst = 1; - t = time2(tmp, funcp, offset, &okay); -#ifdef PCTS - /* - ** PCTS code courtesy Grant Sullivan. - */ + t = localtime_time2(tmp, funcp, sp, offset, &okay); if (okay) return t; if (tmp->tm_isdst < 0) +#ifdef PCTS + /* + ** POSIX Conformance Test Suite code courtesy Grant Sullivan. + */ tmp->tm_isdst = 0; /* reset to std and try again */ -#endif /* defined PCTS */ -#ifndef PCTS - if (okay || tmp->tm_isdst < 0) +#else return t; #endif /* !defined PCTS */ /* @@ -1909,21 +2149,14 @@ time1( ** We try to divine the type they started from and adjust to the ** type they need. */ - /* - ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. - */ - sp = (const struct state *) (((void *) funcp == (void *) localsub) ? - lclptr : gmtptr); -#ifdef ALL_STATE if (sp == NULL) return WRONG; -#endif /* defined ALL_STATE */ for (i = 0; i < sp->typecnt; ++i) - seen[i] = FALSE; + seen[i] = false; nseen = 0; for (i = sp->timecnt - 1; i >= 0; --i) - if (!seen[sp->types[i]]) { - seen[sp->types[i]] = TRUE; + if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { + seen[sp->types[i]] = true; types[nseen++] = sp->types[i]; } for (sameind = 0; sameind < nseen; ++sameind) { @@ -1934,117 +2167,57 @@ time1( otheri = types[otherind]; if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) continue; - tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - - sp->ttis[samei].tt_gmtoff; + tmp->tm_sec += (sp->ttis[otheri].tt_utoff + - sp->ttis[samei].tt_utoff); tmp->tm_isdst = !tmp->tm_isdst; - t = time2(tmp, funcp, offset, &okay); + t = localtime_time2(tmp, funcp, sp, offset, &okay); if (okay) return t; - tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - - sp->ttis[samei].tt_gmtoff; + tmp->tm_sec -= (sp->ttis[otheri].tt_utoff + - sp->ttis[samei].tt_utoff); tmp->tm_isdst = !tmp->tm_isdst; } } return WRONG; } -time_t -mktime( - struct tm * const tmp -) { - tzset(); - return time1(tmp, localsub, 0L); +static time_t +mktime_tzname(struct state *sp, struct tm *tmp, bool setname) +{ + if (sp) + return localtime_time1(tmp, localsub, sp, setname); + else { + localtime_gmtcheck(); + return localtime_time1(tmp, gmtsub, gmtptr, 0); + } } time_t -timelocal( - struct tm * const tmp -) { - tmp->tm_isdst = -1; /* in case it wasn't initialized */ - return mktime(tmp); +mktime(struct tm *tmp) +{ + time_t t; + int err = lock(); + if (err) { + errno = err; + return -1; + } + localtime_tzset_unlocked(); + t = mktime_tzname(lclptr, tmp, true); + unlock(); + return t; } -time_t -timegm( - struct tm * const tmp -) { - tmp->tm_isdst = 0; - return time1(tmp, gmtsub, 0L); -} - -time_t -timeoff( - struct tm * const tmp, - const long offset -) { - tmp->tm_isdst = 0; - return time1(tmp, gmtsub, offset); -} - -/* -** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599 -** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which -** is not the case if we are accounting for leap seconds. -** So, we provide the following conversion routines for use -** when exchanging timestamps with POSIX conforming systems. -*/ - -static long -leapcorr( - time_t * timep -) { - register struct state * sp; - register struct lsinfo * lp; +static int_fast32_t +leapcorr(struct state const *sp, time_t t) +{ + register struct lsinfo const * lp; register int i; - sp = lclptr; i = sp->leapcnt; while (--i >= 0) { lp = &sp->lsis[i]; - if (*timep >= lp->ls_trans) + if (t >= lp->ls_trans) return lp->ls_corr; } return 0; } - -pureconst time_t -time2posix( - time_t t -) { - tzset(); - return t - leapcorr(&t); -} - -pureconst time_t -posix2time( - time_t t -) { - time_t x; - time_t y; - - tzset(); - /* - ** For a positive leap second hit, the result - ** is not unique. For a negative leap second - ** hit, the corresponding time doesn't exist, - ** so we return an adjacent second. - */ - x = t + leapcorr(&t); - y = x - leapcorr(&x); - if (y < t) { - do { - x++; - y = x - leapcorr(&x); - } while (y < t); - if (t != y) - return x - 1; - } else if (y > t) { - do { - --x; - y = x - leapcorr(&x); - } while (y > t); - if (t != y) - return x + 1; - } - return x; -} diff --git a/libc/time/strftime.c b/libc/time/strftime.c index 70082babd..8ab0ae2d1 100644 --- a/libc/time/strftime.c +++ b/libc/time/strftime.c @@ -1,5 +1,5 @@ -/*-*- 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│ +/*-*- mode:c; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright (c) 1989 The Regents of the University of California. │ │ All rights reserved. │ @@ -16,354 +16,545 @@ │ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED │ │ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/calls/calls.h" #include "libc/fmt/fmt.h" -#include "libc/fmt/itoa.h" -#include "libc/macros.internal.h" -#include "libc/nexgen32e/nexgen32e.h" -#include "libc/time/struct/tm.h" +#include "libc/inttypes.h" +#include "libc/stdio/stdio.h" #include "libc/time/time.h" -#include "libc/time/tzfile.internal.h" +#include "libc/time/tz.internal.h" +#include "libc/unicode/locale.h" +// clang-format off +// converts broken-down timestamp to string + +#define DIVISOR 100 asm(".ident\t\"\\n\\n\ strftime (BSD-3)\\n\ Copyright 1989 The Regents of the University of California\""); asm(".include \"libc/disclaimer.inc\""); -static char *strftime_add(char *p, const char *pe, const char *str) { - while (p < pe && (*p = *str++)) ++p; - return p; +/* +** Based on the UCB version with the copyright notice appearing above. +** +** This is ANSIish only when "multibyte character == plain character". +*/ + +struct lc_time_T { + const char * mon[MONSPERYEAR]; + const char * month[MONSPERYEAR]; + const char * wday[DAYSPERWEEK]; + const char * weekday[DAYSPERWEEK]; + const char * X_fmt; + const char * x_fmt; + const char * c_fmt; + const char * am; + const char * pm; + const char * date_fmt; +}; + +#define Locale (&C_time_locale) + +static const struct lc_time_T C_time_locale = { + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }, { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }, { + "Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat" + }, { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }, + + /* X_fmt */ + "%H:%M:%S", + + /* + ** x_fmt + ** C99 and later require this format. + ** Using just numbers (as here) makes Quakers happier; + ** it's also compatible with SVR4. + */ + "%m/%d/%y", + + /* + ** c_fmt + ** C99 and later require this format. + ** Previously this code used "%D %X", but we now conform to C99. + ** Note that + ** "%a %b %d %H:%M:%S %Y" + ** is used by Solaris 2.3. + */ + "%a %b %e %T %Y", + + /* am */ + "AM", + + /* pm */ + "PM", + + /* date_fmt */ + "%a %b %e %H:%M:%S %Z %Y" +}; + +enum warn { IN_NONE, IN_SOME, IN_THIS, IN_ALL }; + +#ifndef YEAR_2000_NAME +#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" +#endif /* !defined YEAR_2000_NAME */ + +static char * +strftime_add(const char *str, char *pt, const char *ptlim) +{ + while (pt < ptlim && (*pt = *str++) != '\0') + ++pt; + return pt; } -static char *strftime_conv(char *p, const char *pe, int n, const char *format) { - char buf[22]; - (snprintf)(buf, sizeof(buf), format, n); - return strftime_add(p, pe, buf); +static char * +strftime_conv(int n, const char *format, char *pt, const char *ptlim) +{ + char buf[INT_STRLEN_MAXIMUM(int) + 1]; + (sprintf)(buf, format, n); + return strftime_add(buf, pt, ptlim); } -static char *strftime_secs(char *p, const char *pe, const struct tm *t) { - char ibuf[21]; - struct tm tmp; - int64_t s; - tmp = *t; /* Make a copy, mktime(3) modifies the tm struct. */ - s = mktime(&tmp); - int64toarray_radix10(s, ibuf); - return strftime_add(p, pe, ibuf); +/* +** POSIX and the C Standard are unclear or inconsistent about +** what %C and %y do if the year is negative or exceeds 9999. +** Use the convention that %C concatenated with %y yields the +** same output as %Y, and that %Y contains at least 4 bytes, +** with more only if necessary. +*/ + +static char * +strftime_yconv( + int a, + int b, + bool convert_top, + bool convert_yy, + char *pt, + const char *ptlim) +{ + register int lead; + register int trail; + + trail = a % DIVISOR + b % DIVISOR; + lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (convert_top) { + if (lead == 0 && trail < 0) + pt = strftime_add("-0", pt, ptlim); + else pt = strftime_conv(lead, "%02d", pt, ptlim); + } + if (convert_yy) + pt = strftime_conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim); + return pt; } -static char *strftime_timefmt(char *p, const char *pe, const char *format, - const struct tm *t) { - int i; - long diff; - char const *sign; - /* size_t z1, z2, z3; */ - for (; *format; ++format) { - if (*format == '%') { - label: - switch (*++format) { - case '\0': - --format; - break; - case 'A': - p = strftime_add(p, pe, - (t->tm_wday < 0 || t->tm_wday > 6) - ? "?" - : kWeekdayName[t->tm_wday]); - continue; - case 'a': - p = strftime_add(p, pe, - (t->tm_wday < 0 || t->tm_wday > 6) - ? "?" - : kWeekdayNameShort[t->tm_wday]); - continue; - case 'B': - p = strftime_add( - p, pe, - (t->tm_mon < 0 || t->tm_mon > 11) ? "?" : kMonthName[t->tm_mon]); - continue; - case 'b': - case 'h': - p = strftime_add(p, pe, - (t->tm_mon < 0 || t->tm_mon > 11) - ? "?" - : kMonthNameShort[t->tm_mon]); - continue; - case 'c': - p = strftime_timefmt(p, pe, "%D %X", t); - continue; - case 'C': - /* - ** %C used to do a... - ** strftime_timefmt("%a %b %e %X %Y", t); - ** ...whereas now POSIX 1003.2 calls for - ** something completely different. - ** (ado, 5/24/93) - */ - p = strftime_conv(p, pe, div100int64(t->tm_year + TM_YEAR_BASE), - "%02d"); - continue; - case 'D': - p = strftime_timefmt(p, pe, "%m/%d/%y", t); - continue; - case 'x': - /* - ** Version 3.0 of strftime from Arnold Robbins - ** (arnold@skeeve.atl.ga.us) does the - ** equivalent of... - ** strftime_timefmt("%a %b %e %Y"); - ** ...for %x; since the X3J11 C language - ** standard calls for "date, using locale's - ** date format," anything goes. Using just - ** numbers (as here) makes Quakers happier. - ** Word from Paul Eggert (eggert@twinsun.com) - ** is that %Y-%m-%d is the ISO standard date - ** format, specified in ISO 2014 and later - ** ISO 8601:1988, with a summary available in - ** pub/doc/ISO/english/ISO8601.ps.Z on - ** ftp.uni-erlangen.de. - ** (ado, 5/30/93) - */ - p = strftime_timefmt(p, pe, "%m/%d/%y", t); - continue; - case 'd': - p = strftime_conv(p, pe, t->tm_mday, "%02d"); - continue; - case 'E': - case 'O': - /* - ** POSIX locale extensions, a la - ** Arnold Robbins' strftime version 3.0. - ** The sequences - ** %Ec %EC %Ex %Ey %EY - ** %Od %oe %OH %OI %Om %OM - ** %OS %Ou %OU %OV %Ow %OW %Oy - ** are supposed to provide alternate - ** representations. - ** (ado, 5/24/93) - */ - goto label; - case 'e': - p = strftime_conv(p, pe, t->tm_mday, "%2d"); - continue; - case 'H': - p = strftime_conv(p, pe, t->tm_hour, "%02d"); - continue; - case 'I': - p = strftime_conv(p, pe, (t->tm_hour % 12) ? (t->tm_hour % 12) : 12, - "%02d"); - continue; - case 'j': - p = strftime_conv(p, pe, t->tm_yday + 1, "%03d"); - continue; - case 'k': - /* - ** This used to be... - ** strftime_conv(t->tm_hour % 12 ? - ** t->tm_hour % 12 : 12, 2, ' '); - ** ...and has been changed to the below to - ** match SunOS 4.1.1 and Arnold Robbins' - ** strftime version 3.0. That is, "%k" and - ** "%l" have been swapped. - ** (ado, 5/24/93) - */ - p = strftime_conv(p, pe, t->tm_hour, "%2d"); - continue; +static char * +strftime_fmt(const char *format, const struct tm *t, char *pt, + const char *ptlim, enum warn *warnp) +{ + for ( ; *format; ++format) { + if (*format == '%') { +label: + switch (*++format) { + case '\0': + --format; + break; + case 'A': + pt = strftime_add( + (t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? + "?" : Locale->weekday[t->tm_wday], + pt, ptlim); + continue; + case 'a': + pt = strftime_add( + (t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? + "?" : Locale->wday[t->tm_wday], + pt, ptlim); + continue; + case 'B': + pt = strftime_add( + (t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? + "?" : Locale->month[t->tm_mon], + pt, ptlim); + continue; + case 'b': + case 'h': + pt = strftime_add( + (t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? + "?" : Locale->mon[t->tm_mon], + pt, ptlim); + continue; + case 'C': + /* + ** %C used to do a... + ** _fmt("%a %b %e %X %Y", t); + ** ...whereas now POSIX 1003.2 calls for + ** something completely different. + ** (ado, 1993-05-24) + */ + pt = strftime_yconv(t->tm_year, TM_YEAR_BASE, + true, false, pt, ptlim); + continue; + case 'c': + { + enum warn warn2 = IN_SOME; + + pt = strftime_fmt(Locale->c_fmt, t, pt, ptlim, &warn2); + if (warn2 == IN_ALL) + warn2 = IN_THIS; + if (warn2 > *warnp) + *warnp = warn2; + } + continue; + case 'D': + pt = strftime_fmt("%m/%d/%y", t, pt, ptlim, warnp); + continue; + case 'd': + pt = strftime_conv(t->tm_mday, "%02d", pt, ptlim); + continue; + case 'E': + case 'O': + /* + ** Locale modifiers of C99 and later. + ** The sequences + ** %Ec %EC %Ex %EX %Ey %EY + ** %Od %oe %OH %OI %Om %OM + ** %OS %Ou %OU %OV %Ow %OW %Oy + ** are supposed to provide alternative + ** representations. + */ + goto label; + case 'e': + pt = strftime_conv(t->tm_mday, "%2d", pt, ptlim); + continue; + case 'F': + pt = strftime_fmt("%Y-%m-%d", t, pt, ptlim, warnp); + continue; + case 'H': + pt = strftime_conv(t->tm_hour, "%02d", pt, ptlim); + continue; + case 'I': + pt = strftime_conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + "%02d", pt, ptlim); + continue; + case 'j': + pt = strftime_conv(t->tm_yday + 1, "%03d", pt, ptlim); + continue; + case 'k': + /* + ** This used to be... + ** _conv(t->tm_hour % 12 ? + ** t->tm_hour % 12 : 12, 2, ' '); + ** ...and has been changed to the below to + ** match SunOS 4.1.1 and Arnold Robbins' + ** strftime version 3.0. That is, "%k" and + ** "%l" have been swapped. + ** (ado, 1993-05-24) + */ + pt = strftime_conv(t->tm_hour, "%2d", + pt, ptlim); + continue; #ifdef KITCHEN_SINK - case 'K': - /* - ** After all this time, still unclaimed! - */ - p = strftime_add(p, pe, "kitchen sink"); - continue; + case 'K': + /* + ** After all this time, still unclaimed! + */ + pt = strftime_add("kitchen sink", pt, ptlim); + continue; #endif /* defined KITCHEN_SINK */ - case 'l': - /* - ** This used to be... - ** strftime_conv(t->tm_hour, 2, ' '); - ** ...and has been changed to the below to - ** match SunOS 4.1.1 and Arnold Robbin's - ** strftime version 3.0. That is, "%k" and - ** "%l" have been swapped. - ** (ado, 5/24/93) - */ - p = strftime_conv(p, pe, (t->tm_hour % 12) ? (t->tm_hour % 12) : 12, - "%2d"); - continue; - case 'M': - p = strftime_conv(p, pe, t->tm_min, "%02d"); - continue; - case 'm': - p = strftime_conv(p, pe, t->tm_mon + 1, "%02d"); - continue; - case 'n': - p = strftime_add(p, pe, "\n"); - continue; - case 'p': - p = strftime_add(p, pe, t->tm_hour >= 12 ? "PM" : "AM"); - continue; - case 'R': - p = strftime_timefmt(p, pe, "%H:%M", t); - continue; - case 'r': - p = strftime_timefmt(p, pe, "%I:%M:%S %p", t); - continue; - case 'S': - p = strftime_conv(p, pe, t->tm_sec, "%02d"); - continue; - case 's': - p = strftime_secs(p, pe, t); - continue; - case 'T': - case 'X': - p = strftime_timefmt(p, pe, "%H:%M:%S", t); - continue; - case 't': - p = strftime_add(p, pe, "\t"); - continue; - case 'U': - p = strftime_conv(p, pe, (t->tm_yday + 7 - t->tm_wday) / 7, "%02d"); - continue; - case 'u': - /* - ** From Arnold Robbins' strftime version 3.0: - ** "ISO 8601: Weekday as a decimal number - ** [1 (Monday) - 7]" - ** (ado, 5/24/93) - */ - p = strftime_conv(p, pe, (t->tm_wday == 0) ? 7 : t->tm_wday, "%d"); - continue; - case 'V': - /* - ** From Arnold Robbins' strftime version 3.0: - ** "the week number of the year (the first - ** Monday as the first day of week 1) as a - ** decimal number (01-53). The method for - ** determining the week number is as specified - ** by ISO 8601 (to wit: if the week containing - ** January 1 has four or more days in the new - ** year, then it is week 1, otherwise it is - ** week 53 of the previous year and the next - ** week is week 1)." - ** (ado, 5/24/93) - */ - /* - ** XXX--If January 1 falls on a Friday, - ** January 1-3 are part of week 53 of the - ** previous year. By analogy, if January - ** 1 falls on a Thursday, are December 29-31 - ** of the PREVIOUS year part of week 1??? - ** (ado 5/24/93) - ** - ** You are understood not to expect this. - */ - i = (t->tm_yday + 10 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7; - if (i == 0) { - /* - ** What day of the week does - ** January 1 fall on? - */ - i = t->tm_wday - (t->tm_yday - 1); - /* - ** Fri Jan 1: 53 - ** Sun Jan 1: 52 - ** Sat Jan 1: 53 if previous - ** year a leap - ** year, else 52 - */ - if (i == TM_FRIDAY) - i = 53; - else if (i == TM_SUNDAY) - i = 52; - else - i = isleap(t->tm_year + TM_YEAR_BASE) ? 53 : 52; -#ifdef XPG4_1994_04_09 - /* - ** As of 4/9/94, though, - ** XPG4 calls for 53 - ** unconditionally. - */ - i = 53; -#endif /* defined XPG4_1994_04_09 */ - } - p = strftime_conv(p, pe, i, "%02d"); - continue; - case 'v': - /* - ** From Arnold Robbins' strftime version 3.0: - ** "date as dd-bbb-YYYY" - ** (ado, 5/24/93) - */ - p = strftime_timefmt(p, pe, "%e-%b-%Y", t); - continue; - case 'W': - p = strftime_conv( - p, pe, (t->tm_yday + 7 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7, - "%02d"); - continue; - case 'w': - p = strftime_conv(p, pe, t->tm_wday, "%d"); - continue; - case 'y': - p = strftime_conv(p, pe, (t->tm_year + TM_YEAR_BASE) % 100, "%02d"); - continue; - case 'Y': - p = strftime_conv(p, pe, t->tm_year + TM_YEAR_BASE, "%04d"); - continue; - case 'Z': - if (t->tm_zone) { - p = strftime_add(p, pe, t->tm_zone); - } else { - if (t->tm_isdst == 0 || t->tm_isdst == 1) { - p = strftime_add(p, pe, tzname[t->tm_isdst]); - } else { - p = strftime_add(p, pe, "?"); - } - } - continue; - case 'z': - if (t->tm_isdst < 0) continue; -#ifdef TM_GMTOFF - diff = t->TM_GMTOFF; -#else /* !defined TM_GMTOFF */ - if (t->tm_isdst == 0) -#ifdef USG_COMPAT - diff = -timezone; -#else /* !defined USG_COMPAT */ - continue; -#endif /* !defined USG_COMPAT */ - else -#ifdef ALTZONE - diff = -altzone; -#else /* !defined ALTZONE */ - continue; -#endif /* !defined ALTZONE */ -#endif /* !defined TM_GMTOFF */ - if (diff < 0) { - sign = "-"; - diff = -diff; - } else { - sign = "+"; - } - p = strftime_add(p, pe, sign); - diff /= SECSPERMIN; - diff = (diff / MINSPERHOUR) * 100 + (diff % MINSPERHOUR); - p = strftime_conv(p, pe, diff, "%04d"); - continue; - case '%': - /* - * X311J/88-090 (4.12.3.5): if conversion char is - * undefined, behavior is undefined. Print out the - * character itself as printf(3) also does. - */ - default: - break; - } - } - if (p >= pe) break; - *p++ = *format; - } - return p; + case 'l': + /* + ** This used to be... + ** _conv(t->tm_hour, 2, ' '); + ** ...and has been changed to the below to + ** match SunOS 4.1.1 and Arnold Robbin's + ** strftime version 3.0. That is, "%k" and + ** "%l" have been swapped. + ** (ado, 1993-05-24) + */ + pt = strftime_conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + "%2d", pt, ptlim); + continue; + case 'M': + pt = strftime_conv(t->tm_min, "%02d", + pt, ptlim); + continue; + case 'm': + pt = strftime_conv(t->tm_mon + 1, "%02d", + pt, ptlim); + continue; + case 'n': + pt = strftime_add("\n", pt, ptlim); + continue; + case 'p': + pt = strftime_add( + (t->tm_hour >= (HOURSPERDAY / 2)) ? + Locale->pm : + Locale->am, + pt, ptlim); + continue; + case 'R': + pt = strftime_fmt("%H:%M", t, pt, ptlim, warnp); + continue; + case 'r': + pt = strftime_fmt("%I:%M:%S %p", t, pt, + ptlim, warnp); + continue; + case 'S': + pt = strftime_conv(t->tm_sec, "%02d", pt, + ptlim); + continue; + case 's': + { + struct tm tm; + char buf[INT_STRLEN_MAXIMUM( + time_t) + 1]; + time_t mkt; + + tm = *t; + tm.tm_yday = -1; + mkt = mktime(&tm); + if (mkt == (time_t) -1) { + /* Fail unless this -1 represents + a valid time. */ + struct tm tm_1; + if (!localtime_r(&mkt, &tm_1)) + return NULL; + if (!(tm.tm_year == tm_1.tm_year + && tm.tm_yday == tm_1.tm_yday + && tm.tm_hour == tm_1.tm_hour + && tm.tm_min == tm_1.tm_min + && tm.tm_sec == tm_1.tm_sec)) + return NULL; + } + if (TYPE_SIGNED(time_t)) { + intmax_t n = mkt; + (sprintf)(buf, "%"PRIdMAX, n); + } else { + uintmax_t n = mkt; + (sprintf)(buf, "%"PRIuMAX, n); + } + pt = strftime_add(buf, pt, ptlim); + } + continue; + case 'T': + pt = strftime_fmt("%H:%M:%S", t, pt, ptlim, warnp); + continue; + case 't': + pt = strftime_add("\t", pt, ptlim); + continue; + case 'U': + pt = strftime_conv((t->tm_yday + DAYSPERWEEK - + t->tm_wday) / DAYSPERWEEK, + "%02d", pt, ptlim); + continue; + case 'u': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "ISO 8601: Weekday as a decimal number + ** [1 (Monday) - 7]" + ** (ado, 1993-05-24) + */ + pt = strftime_conv((t->tm_wday == 0) ? + DAYSPERWEEK : t->tm_wday, + "%d", pt, ptlim); + continue; + case 'V': /* ISO 8601 week number */ + case 'G': /* ISO 8601 year (four digits) */ + case 'g': /* ISO 8601 year (two digits) */ +/* +** From Arnold Robbins' strftime version 3.0: "the week number of the +** year (the first Monday as the first day of week 1) as a decimal number +** (01-53)." +** (ado, 1993-05-24) +** +** From by Markus Kuhn: +** "Week 01 of a year is per definition the first week which has the +** Thursday in this year, which is equivalent to the week which contains +** the fourth day of January. In other words, the first week of a new year +** is the week which has the majority of its days in the new year. Week 01 +** might also contain days from the previous year and the week before week +** 01 of a year is the last week (52 or 53) of the previous year even if +** it contains days from the new year. A week starts with Monday (day 1) +** and ends with Sunday (day 7). For example, the first week of the year +** 1997 lasts from 1996-12-30 to 1997-01-05..." +** (ado, 1996-01-02) +*/ + { + int year; + int base; + int yday; + int wday; + int w; + + year = t->tm_year; + base = TM_YEAR_BASE; + yday = t->tm_yday; + wday = t->tm_wday; + for ( ; ; ) { + int len; + int bot; + int top; + + len = isleap_sum(year, base) ? + DAYSPERLYEAR : + DAYSPERNYEAR; + /* + ** What yday (-3 ... 3) does + ** the ISO year begin on? + */ + bot = ((yday + 11 - wday) % + DAYSPERWEEK) - 3; + /* + ** What yday does the NEXT + ** ISO year begin on? + */ + top = bot - + (len % DAYSPERWEEK); + if (top < -3) + top += DAYSPERWEEK; + top += len; + if (yday >= top) { + ++base; + w = 1; + break; + } + if (yday >= bot) { + w = 1 + ((yday - bot) / + DAYSPERWEEK); + break; + } + --base; + yday += isleap_sum(year, base) ? + DAYSPERLYEAR : + DAYSPERNYEAR; + } + if (*format == 'V') + pt = strftime_conv(w, "%02d", + pt, ptlim); + else if (*format == 'g') { + *warnp = IN_ALL; + pt = strftime_yconv(year, base, + false, true, + pt, ptlim); + } else pt = strftime_yconv(year, base, + true, true, + pt, ptlim); + } + continue; + case 'v': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "date as dd-bbb-YYYY" + ** (ado, 1993-05-24) + */ + pt = strftime_fmt("%e-%b-%Y", t, pt, ptlim, warnp); + continue; + case 'W': + pt = strftime_conv( + (t->tm_yday + DAYSPERWEEK - + (t->tm_wday ? + (t->tm_wday - 1) : + (DAYSPERWEEK - 1))) / DAYSPERWEEK, + "%02d", pt, ptlim); + continue; + case 'w': + pt = strftime_conv(t->tm_wday, "%d", pt, ptlim); + continue; + case 'X': + pt = strftime_fmt(Locale->X_fmt, t, pt, ptlim, warnp); + continue; + case 'x': + { + enum warn warn2 = IN_SOME; + + pt = strftime_fmt(Locale->x_fmt, t, pt, ptlim, &warn2); + if (warn2 == IN_ALL) + warn2 = IN_THIS; + if (warn2 > *warnp) + *warnp = warn2; + } + continue; + case 'y': + *warnp = IN_ALL; + pt = strftime_yconv(t->tm_year, TM_YEAR_BASE, + false, true, + pt, ptlim); + continue; + case 'Y': + pt = strftime_yconv(t->tm_year, TM_YEAR_BASE, + true, true, + pt, ptlim); + continue; + case 'Z': + pt = strftime_add(t->tm_zone, pt, ptlim); + /* + ** C99 and later say that %Z must be + ** replaced by the empty string if the + ** time zone abbreviation is not + ** determinable. + */ + continue; + case 'z': + { + long diff; + char const * sign; + bool negative; + + diff = t->tm_gmtoff; + negative = diff < 0; + if (diff == 0) { + negative = t->tm_zone[0] == '-'; + } + if (negative) { + sign = "-"; + diff = -diff; + } else sign = "+"; + pt = strftime_add(sign, pt, ptlim); + diff /= SECSPERMIN; + diff = (diff / MINSPERHOUR) * 100 + + (diff % MINSPERHOUR); + pt = strftime_conv(diff, "%04d", pt, ptlim); + } + continue; + case '+': + pt = strftime_fmt(Locale->date_fmt, t, pt, + ptlim, warnp); + continue; + case '%': + /* + ** X311J/88-090 (4.12.3.5): if conversion char is + ** undefined, behavior is undefined. Print out the + ** character itself as printf(3) also does. + */ + default: + break; + } + } + if (pt == ptlim) + break; + *pt++ = *format; + } + return pt; } /** @@ -379,14 +570,32 @@ static char *strftime_timefmt(char *p, const char *pe, const char *format, * * @return bytes copied excluding nul, or 0 on error */ -size_t strftime(char *s, size_t size, const char *f, const struct tm *t) { - char *p; - p = strftime_timefmt(s, s + size, f, t); - if (p < s + size) { - *p = '\0'; - return p - s; - } else { - s[size - 1] = '\0'; - return 0; - } +size_t +strftime(char *s, size_t maxsize, const char *format, const struct tm *t) +{ + char * p; + int saved_errno = errno; + enum warn warn = IN_NONE; + + tzset(); + p = strftime_fmt(format, t, s, s + maxsize, &warn); + if (!p) { + errno = EOVERFLOW; + return 0; + } + if (p == s + maxsize) { + errno = ERANGE; + return 0; + } + *p = '\0'; + errno = saved_errno; + return p - s; +} + +size_t +strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t, + locale_t locale) +{ + /* Just call strftime, as only the C locale is supported. */ + return strftime(s, maxsize, format, t); } diff --git a/libc/time/time.h b/libc/time/time.h index 17c05ebdc..510d19ba8 100644 --- a/libc/time/time.h +++ b/libc/time/time.h @@ -4,6 +4,7 @@ #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" #include "libc/time/struct/timezone.h" +#include "libc/time/struct/tm.h" #include "libc/time/struct/utimbuf.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -16,6 +17,8 @@ hidden extern const unsigned short kMonthYearDay[2][12]; extern char *tzname[2]; extern long CLOCKS_PER_SEC; +extern long timezone; +extern int daylight; int64_t clock(void); int64_t time(int64_t *); @@ -63,8 +66,9 @@ extern long double (*nowl)(void); long double ConvertTicksToNanos(uint64_t); void RefreshTime(void); -double difftime(int64_t, int64_t) nothrow pureconst; +double difftime(int64_t, int64_t) dontthrow pureconst; char *iso8601(char[hasatleast 20], struct tm *); +size_t wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/time/time.mk b/libc/time/time.mk index 412653371..da673d944 100644 --- a/libc/time/time.mk +++ b/libc/time/time.mk @@ -61,12 +61,15 @@ o/$(MODE)/libc/time/strftime.o: \ OVERRIDE_CFLAGS += \ -fno-jump-tables -o/$(MODE)/libc/time/localtime.o \ -o/$(MODE)/libc/time/strftime.o: \ +o/$(MODE)/libc/time/localtime.o: \ OVERRIDE_CFLAGS += \ -fdata-sections \ -ffunction-sections +o/$(MODE)/libc/time/localtime.o: \ + OVERRIDE_CPPFLAGS += \ + -DSTACK_FRAME_UNLIMITED + o/$(MODE)/libc/time/now.o: \ OVERRIDE_CFLAGS += \ -O3 diff --git a/libc/time/timezone.c b/libc/time/timezone.c new file mode 100644 index 000000000..80d45411c --- /dev/null +++ b/libc/time/timezone.c @@ -0,0 +1,23 @@ +/*-*- 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 2022 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/time/time.h" + +char *tzname[2]; +long timezone; +int daylight; diff --git a/libc/time/tz.internal.h b/libc/time/tz.internal.h new file mode 100644 index 000000000..8dd16b6da --- /dev/null +++ b/libc/time/tz.internal.h @@ -0,0 +1,544 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_TZ_PRIVATE_H_ +#define COSMOPOLITAN_THIRD_PARTY_TZ_PRIVATE_H_ +#include "libc/calls/calls.h" +#include "libc/calls/weirdtypes.h" +#include "libc/errno.h" +#include "libc/inttypes.h" +#include "libc/limits.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/ok.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/* clang-format off */ +/* Private header for tzdb code. */ + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** zdump has been made independent of the rest of the time +** conversion package to increase confidence in the verification it provides. +** You can use zdump to help in verifying other implementations. +** To do this, compile with -DUSE_LTZ=0 and link without the tz library. +*/ +#ifndef USE_LTZ +# define USE_LTZ 1 +#endif + +/* This string was in the Factory zone through version 2016f. */ +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + +/* +** Defaults for preprocessor symbols. +** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'. +*/ + +#ifndef HAVE_DECL_ASCTIME_R +#define HAVE_DECL_ASCTIME_R 1 +#endif + +#if !defined HAVE_GENERIC && defined __has_extension +# if __has_extension(c_generic_selections) +# define HAVE_GENERIC 1 +# else +# define HAVE_GENERIC 0 +# endif +#endif +/* _Generic is buggy in pre-4.9 GCC. */ +#if !defined HAVE_GENERIC && defined __GNUC__ +# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__)) +#endif +#ifndef HAVE_GENERIC +# define HAVE_GENERIC (201112 <= __STDC_VERSION__) +#endif + +#ifndef HAVE_GETTEXT +#define HAVE_GETTEXT 0 +#endif /* !defined HAVE_GETTEXT */ + +#ifndef HAVE_INCOMPATIBLE_CTIME_R +#define HAVE_INCOMPATIBLE_CTIME_R 0 +#endif + +#ifndef HAVE_LINK +#define HAVE_LINK 1 +#endif /* !defined HAVE_LINK */ + +#ifndef HAVE_MALLOC_ERRNO +#define HAVE_MALLOC_ERRNO 1 +#endif + +#ifndef HAVE_POSIX_DECLS +#define HAVE_POSIX_DECLS 1 +#endif + +#ifndef HAVE_STRTOLL +#define HAVE_STRTOLL 1 +#endif + +#ifndef HAVE_SYMLINK +#define HAVE_SYMLINK 1 +#endif /* !defined HAVE_SYMLINK */ + +#if HAVE_INCOMPATIBLE_CTIME_R +#define asctime_r _incompatible_asctime_r +#define ctime_r _incompatible_ctime_r +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +/* +** Nested includes +*/ + +/* Avoid clashes with NetBSD by renaming NetBSD's declarations. + If defining the 'timezone' variable, avoid a clash with FreeBSD's + 'timezone' function by renaming its declaration. */ +#define localtime_rz sys_localtime_rz +#define mktime_z sys_mktime_z +#define posix2time_z sys_posix2time_z +#define time2posix_z sys_time2posix_z +#if defined USG_COMPAT && USG_COMPAT == 2 +# define timezone sys_timezone +#endif +#define timezone_t sys_timezone_t +#define tzalloc sys_tzalloc +#define tzfree sys_tzfree +#undef localtime_rz +#undef mktime_z +#undef posix2time_z +#undef time2posix_z +#if defined USG_COMPAT && USG_COMPAT == 2 +# undef timezone +#endif +#undef timezone_t +#undef tzalloc +#undef tzfree + +#if HAVE_GETTEXT +#include +#endif /* HAVE_GETTEXT */ + +#ifndef HAVE_STRFTIME_L +# if _POSIX_VERSION < 200809 +# define HAVE_STRFTIME_L 0 +# else +# define HAVE_STRFTIME_L 1 +# endif +#endif + +#ifndef USG_COMPAT +# ifndef _XOPEN_VERSION +# define USG_COMPAT 0 +# else +# define USG_COMPAT 1 +# endif +#endif + +#ifndef HAVE_TZNAME +# if _POSIX_VERSION < 198808 && !USG_COMPAT +# define HAVE_TZNAME 0 +# else +# define HAVE_TZNAME 1 +# endif +#endif + +#ifndef ALTZONE +# if defined __sun || defined _M_XENIX +# define ALTZONE 1 +# else +# define ALTZONE 0 +# endif +#endif + +#ifndef R_OK +#define R_OK 4 +#endif /* !defined R_OK */ + +#if 3 <= __GNUC__ +# define ATTRIBUTE_FORMAT(spec) __attribute__((__format__ spec)) +#else +# define ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +/* +** Workarounds for compilers/systems. +*/ + +#ifndef EPOCH_LOCAL +# define EPOCH_LOCAL 0 +#endif +#ifndef EPOCH_OFFSET +# define EPOCH_OFFSET 0 +#endif + +/* +** Compile with -Dtime_tz=T to build the tz package with a private +** int64_t type equivalent to T rather than the system-supplied int64_t. +** This debugging feature can test unusual design decisions +** (e.g., int64_t wider than 'long', or unsigned int64_t) even on +** typical platforms. +*/ +#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0 +# define TZ_INT64_T 1 +#else +# define TZ_INT64_T 0 +#endif + +#if defined LOCALTIME_IMPLEMENTATION && TZ_INT64_T +static int64_t sys_time(int64_t *x) { return time(x); } +#endif + +#if TZ_INT64_T + +typedef time_tz tz_int64_t; + +# undef asctime +# define asctime tz_asctime +# undef asctime_r +# define asctime_r tz_asctime_r +# undef ctime +# define ctime tz_ctime +# undef ctime_r +# define ctime_r tz_ctime_r +# undef difftime +# define difftime tz_difftime +# undef gmtime +# define gmtime tz_gmtime +# undef gmtime_r +# define gmtime_r tz_gmtime_r +# undef localtime +# define localtime tz_localtime +# undef localtime_r +# define localtime_r tz_localtime_r +# undef localtime_rz +# define localtime_rz tz_localtime_rz +# undef mktime +# define mktime tz_mktime +# undef mktime_z +# define mktime_z tz_mktime_z +# undef offtime +# define offtime tz_offtime +# undef posix2time +# define posix2time tz_posix2time +# undef posix2time_z +# define posix2time_z tz_posix2time_z +# undef strftime +# define strftime tz_strftime +# undef time +# define time tz_time +# undef time2posix +# define time2posix tz_time2posix +# undef time2posix_z +# define time2posix_z tz_time2posix_z +# undef int64_t +# define int64_t tz_int64_t +# undef timegm +# define timegm tz_timegm +# undef timelocal +# define timelocal tz_timelocal +# undef timeoff +# define timeoff tz_timeoff +# undef tzalloc +# define tzalloc tz_tzalloc +# undef tzfree +# define tzfree tz_tzfree +# undef tzset +# define tzset tz_tzset +# if HAVE_STRFTIME_L +# undef strftime_l +# define strftime_l tz_strftime_l +# endif +# if HAVE_TZNAME +# undef tzname +# define tzname tz_tzname +# endif +# if USG_COMPAT +# undef daylight +# define daylight tz_daylight +# undef timezone +# define timezone tz_timezone +# endif +# if ALTZONE +# undef altzone +# define altzone tz_altzone +# endif + +char *asctime(struct tm const *); +char *asctime_r(struct tm const *restrict, char *restrict); +char *ctime(int64_t const *); +char *ctime_r(int64_t const *, char *); +double difftime(int64_t, int64_t) pureconst; +size_t strftime(char *restrict, size_t, char const *restrict, + struct tm const *restrict); +# if HAVE_STRFTIME_L +size_t strftime_l(char *restrict, size_t, char const *restrict, + struct tm const *restrict, locale_t); +# endif +struct tm *gmtime(int64_t const *); +struct tm *gmtime_r(int64_t const *restrict, struct tm *restrict); +struct tm *localtime(int64_t const *); +struct tm *localtime_r(int64_t const *restrict, struct tm *restrict); +int64_t mktime(struct tm *); +int64_t time(int64_t *); +void tzset(void); +#endif + +#if !HAVE_DECL_ASCTIME_R && !defined asctime_r +extern char *asctime_r(struct tm const *restrict, char *restrict); +#endif + +#ifndef HAVE_DECL_ENVIRON +# if defined environ || defined __USE_GNU +# define HAVE_DECL_ENVIRON 1 +# else +# define HAVE_DECL_ENVIRON 0 +# endif +#endif + +#if 2 <= HAVE_TZNAME + (TZ_INT64_T || !HAVE_POSIX_DECLS) +extern char *tzname[]; +#endif +#if 2 <= USG_COMPAT + (TZ_INT64_T || !HAVE_POSIX_DECLS) +extern long timezone; +extern int daylight; +#endif +#if 2 <= ALTZONE + (TZ_INT64_T || !HAVE_POSIX_DECLS) +extern long altzone; +#endif + +/* +** The STD_INSPIRED functions are similar, but most also need +** declarations if time_tz is defined. +*/ + +#ifdef STD_INSPIRED +# if TZ_INT64_T || !defined offtime +struct tm *offtime(int64_t const *, long); +# endif +# if TZ_INT64_T || !defined timegm +int64_t timegm(struct tm *); +# endif +# if TZ_INT64_T || !defined timelocal +int64_t timelocal(struct tm *); +# endif +# if TZ_INT64_T || !defined timeoff +int64_t timeoff(struct tm *, long); +# endif +# if TZ_INT64_T || !defined time2posix +int64_t time2posix(int64_t); +# endif +# if TZ_INT64_T || !defined posix2time +int64_t posix2time(int64_t); +# endif +#endif + +/* Infer TM_ZONE on systems where this information is known, but suppress + guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */ +#define TM_GMTOFF tm_gmtoff +#define TM_ZONE tm_zone + +/* +** Define functions that are ABI compatible with NetBSD but have +** better prototypes. NetBSD 6.1.4 defines a pointer type timezone_t +** and labors under the misconception that 'const timezone_t' is a +** pointer to a constant. This use of 'const' is ineffective, so it +** is not done here. What we call 'struct state' NetBSD calls +** 'struct __state', but this is a private name so it doesn't matter. +*/ +#if NETBSD_INSPIRED +typedef struct state *timezone_t; +struct tm *localtime_rz(timezone_t restrict, int64_t const *restrict, + struct tm *restrict); +int64_t mktime_z(timezone_t restrict, struct tm *restrict); +timezone_t tzalloc(char const *); +void tzfree(timezone_t); +# ifdef STD_INSPIRED +# if TZ_INT64_T || !defined posix2time_z +int64_t posix2time_z(timezone_t, int64_t) nosideeffect; +# endif +# if TZ_INT64_T || !defined time2posix_z +int64_t time2posix_z(timezone_t, int64_t) nosideeffect; +# endif +# endif +#endif + +/* +** Finally, some convenience items. +*/ + +#define TYPE_BIT(type) (sizeof(type) * CHAR_BIT) +#define TYPE_SIGNED(type) (((type) -1) < 0) +#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0) + +/* Max and min values of the integer type T, of which only the bottom + B bits are used, and where the highest-order used bit is considered + to be a sign bit if T is signed. */ +#define MAXVAL(t, b) \ + ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \ + - 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t))))) +#define MINVAL(t, b) \ + ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0)) + +/* The extreme time values, assuming no padding. */ +#define INT64_T_MIN_NO_PADDING MINVAL(int64_t, TYPE_BIT(int64_t)) +#define INT64_T_MAX_NO_PADDING MAXVAL(int64_t, TYPE_BIT(int64_t)) + +/* The extreme time values. These are macros, not constants, so that + any portability problems occur only when compiling .c files that use + the macros, which is safer for applications that need only zdump and zic. + This implementation assumes no padding if int64_t is signed and + either the compiler lacks support for _Generic or int64_t is not one + of the standard signed integer types. */ +#if HAVE_GENERIC +# define INT64_T_MIN \ + _Generic((int64_t) 0, \ + signed char: SCHAR_MIN, short: SHRT_MIN, \ + int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \ + default: INT64_T_MIN_NO_PADDING) +# define INT64_T_MAX \ + (TYPE_SIGNED(int64_t) \ + ? _Generic((int64_t) 0, \ + signed char: SCHAR_MAX, short: SHRT_MAX, \ + int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \ + default: INT64_T_MAX_NO_PADDING) \ + : (int64_t) -1) +#else +# define INT64_T_MIN INT64_T_MIN_NO_PADDING +# define INT64_T_MAX INT64_T_MAX_NO_PADDING +#endif + +/* +** 302 / 1000 is log10(2.0) rounded up. +** Subtract one for the sign bit if the type is signed; +** add one for integer division truncation; +** add one more for a minus sign if the type is signed. +*/ +#define INT_STRLEN_MAXIMUM(type) \ + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ + 1 + TYPE_SIGNED(type)) + +/* +** INITIALIZE(x) +*/ + +#define INITIALIZE(x) ((x) = 0) + +/* Whether memory access must strictly follow the C standard. + If 0, it's OK to read uninitialized storage so long as the value is + not relied upon. Defining it to 0 lets mktime access parts of + struct tm that might be uninitialized, as a heuristic when the + standard doesn't say what to return and when tm_gmtoff can help + mktime likely infer a better value. */ +#ifndef UNINIT_TRAP +# define UNINIT_TRAP 0 +#endif + +#ifdef DEBUG +# define UNREACHABLE() abort() +#elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) +# define UNREACHABLE() __builtin_unreachable() +#elif defined __has_builtin +# if __has_builtin(__builtin_unreachable) +# define UNREACHABLE() __builtin_unreachable() +# endif +#endif +#ifndef UNREACHABLE +# define UNREACHABLE() ((void) 0) +#endif + +/* +** For the benefit of GNU folk... +** '_(MSGID)' uses the current locale's message library string for MSGID. +** The default is to use gettext if available, and use MSGID otherwise. +*/ + +#if HAVE_GETTEXT +#define _(msgid) gettext(msgid) +#else /* !HAVE_GETTEXT */ +#define _(msgid) msgid +#endif /* !HAVE_GETTEXT */ + +#if !defined TZ_DOMAIN && defined HAVE_GETTEXT +# define TZ_DOMAIN "tz" +#endif + +#if HAVE_INCOMPATIBLE_CTIME_R +#undef asctime_r +#undef ctime_r +char *asctime_r(struct tm const *, char *); +char *ctime_r(int64_t const *, char *); +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +/* Handy macros that are independent of tzfile implementation. */ + +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 +#define DAYSPERWEEK 7 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY) +#define MONSPERYEAR 12 + +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#define DAYSPERREPEAT ((int_fast32_t) 400 * 365 + 100 - 4 + 1) +#define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY) +#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT) + +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_TUESDAY 2 +#define TM_WEDNESDAY 3 +#define TM_THURSDAY 4 +#define TM_FRIDAY 5 +#define TM_SATURDAY 6 + +#define TM_JANUARY 0 +#define TM_FEBRUARY 1 +#define TM_MARCH 2 +#define TM_APRIL 3 +#define TM_MAY 4 +#define TM_JUNE 5 +#define TM_JULY 6 +#define TM_AUGUST 7 +#define TM_SEPTEMBER 8 +#define TM_OCTOBER 9 +#define TM_NOVEMBER 10 +#define TM_DECEMBER 11 + +#define TM_YEAR_BASE 1900 +#define TM_WDAY_BASE TM_MONDAY + +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY TM_THURSDAY + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + +/* +** Since everything in isleap is modulo 400 (or a factor of 400), we know that +** isleap(y) == isleap(y % 400) +** and so +** isleap(a + b) == isleap((a + b) % 400) +** or +** isleap(a + b) == isleap(a % 400 + b % 400) +** This is true even if % means modulo rather than Fortran remainder +** (which is allowed by C89 but not by C99 or later). +** We use this to avoid addition overflow problems. +*/ + +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_TZ_PRIVATE_H_ */ diff --git a/libc/time/tzfile.internal.h b/libc/time/tzfile.internal.h index cc2aa6067..bfef13de0 100644 --- a/libc/time/tzfile.internal.h +++ b/libc/time/tzfile.internal.h @@ -1,46 +1,56 @@ #ifndef TZFILE_H #define TZFILE_H - -#define TM_ZONE tm_zone -#define TM_GMTOFF tm_gmtoff +/* clang-format off */ +/* Layout and location of TZif files. */ /* ** This file is in the public domain, so clarified as of ** 1996-06-05 by Arthur David Olson. */ +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + /* ** Information about time zone files. */ #ifndef TZDIR -#define TZDIR "/zip/usr/share/zoneinfo" -#endif +#define TZDIR "/zip/usr/share/zoneinfo" /* Time zone object file directory */ +#endif /* !defined TZDIR */ #ifndef TZDEFAULT -#define TZDEFAULT "GST" -#endif +#define TZDEFAULT "GST" +#endif /* !defined TZDEFAULT */ #ifndef TZDEFRULES -#define TZDEFRULES "New_York" -#endif +#define TZDEFRULES "New_York" +#endif /* !defined TZDEFRULES */ + + +/* See Internet RFC 8536 for more details about the following format. */ /* ** Each file begins with. . . */ -#define TZ_MAGIC "TZif" +#define TZ_MAGIC "TZif" struct tzhead { - char tzh_magic[4]; /* TZ_MAGIC */ - char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */ - char tzh_reserved[15]; /* reserved; must be zero */ - char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ - char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ - char tzh_leapcnt[4]; /* coded number of leap seconds */ - char tzh_timecnt[4]; /* coded number of transition times */ - char tzh_typecnt[4]; /* coded number of local time types */ - char tzh_charcnt[4]; /* coded number of abbr. chars */ + char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */ + char tzh_reserved[15]; /* reserved; must be zero */ + char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ + char tzh_leapcnt[4]; /* coded number of leap seconds */ + char tzh_timecnt[4]; /* coded number of transition times */ + char tzh_typecnt[4]; /* coded number of local time types */ + char tzh_charcnt[4]; /* coded number of abbr. chars */ }; /* @@ -58,14 +68,15 @@ struct tzhead { ** one (char [4]) total correction after above ** tzh_ttisstdcnt (char)s indexed by type; if 1, transition ** time is standard time, if 0, -** transition time is wall clock time -** if absent, transition times are -** assumed to be wall clock time -** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition -** time is UT, if 0, -** transition time is local time -** if absent, transition times are +** transition time is local (wall clock) +** time; if absent, transition times are ** assumed to be local time +** tzh_ttisutcnt (char)s indexed by type; if 1, transition +** time is UT, if 0, transition time is +** local time; if absent, transition +** times are assumed to be local time. +** When this is 1, the corresponding +** std/wall indicator must also be 1. */ /* @@ -91,73 +102,21 @@ struct tzhead { */ #ifndef TZ_MAX_TIMES -#define TZ_MAX_TIMES 1200 +#define TZ_MAX_TIMES 2000 #endif /* !defined TZ_MAX_TIMES */ #ifndef TZ_MAX_TYPES /* This must be at least 17 for Europe/Samara and Europe/Vilnius. */ -#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ +#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ #endif /* !defined TZ_MAX_TYPES */ #ifndef TZ_MAX_CHARS -#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ -/* (limited by what unsigned chars can hold) */ +#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ + /* (limited by what unsigned chars can hold) */ #endif /* !defined TZ_MAX_CHARS */ #ifndef TZ_MAX_LEAPS -#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ +#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ #endif /* !defined TZ_MAX_LEAPS */ -#define SECSPERMIN 60 -#define MINSPERHOUR 60 -#define HOURSPERDAY 24 -#define DAYSPERWEEK 7 -#define DAYSPERNYEAR 365 -#define DAYSPERLYEAR 366 -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) -#define SECSPERDAY ((int_fast32_t)SECSPERHOUR * HOURSPERDAY) -#define MONSPERYEAR 12 - -#define TM_SUNDAY 0 -#define TM_MONDAY 1 -#define TM_TUESDAY 2 -#define TM_WEDNESDAY 3 -#define TM_THURSDAY 4 -#define TM_FRIDAY 5 -#define TM_SATURDAY 6 - -#define TM_JANUARY 0 -#define TM_FEBRUARY 1 -#define TM_MARCH 2 -#define TM_APRIL 3 -#define TM_MAY 4 -#define TM_JUNE 5 -#define TM_JULY 6 -#define TM_AUGUST 7 -#define TM_SEPTEMBER 8 -#define TM_OCTOBER 9 -#define TM_NOVEMBER 10 -#define TM_DECEMBER 11 - -#define TM_YEAR_BASE 1900 - -#define EPOCH_YEAR 1970 -#define EPOCH_WDAY TM_THURSDAY - -#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) - -/* -** Since everything in isleap is modulo 400 (or a factor of 400), we know that -** isleap(y) == isleap(y % 400) -** and so -** isleap(a + b) == isleap((a + b) % 400) -** or -** isleap(a + b) == isleap(a % 400 + b % 400) -** This is true even if % means modulo rather than Fortran remainder -** (which is allowed by C89 but not C99). -** We use this to avoid addition overflow problems. -*/ - -#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) - #endif /* !defined TZFILE_H */ diff --git a/libc/tinymath/atanf.S b/libc/tinymath/atanf.S index e80e5ae3a..174916519 100644 --- a/libc/tinymath/atanf.S +++ b/libc/tinymath/atanf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns arc tangent of 𝑥. // diff --git a/libc/tinymath/c2rangr.S b/libc/tinymath/c2rangr.S index 1f779e7c9..253d77214 100644 --- a/libc/tinymath/c2rangr.S +++ b/libc/tinymath/c2rangr.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/runtime/pc.internal.h" #include "libc/macros.internal.h" -.source __FILE__ // Computes transcedental trigonometry op w/ reactive scaling. // diff --git a/libc/tinymath/cabs.S b/libc/tinymath/cabs.S index b41359a5e..856d87d3e 100644 --- a/libc/tinymath/cabs.S +++ b/libc/tinymath/cabs.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns absolute value of complex number. cabs: jmp hypot diff --git a/libc/tinymath/cabsf.S b/libc/tinymath/cabsf.S index 9489744f5..c2b1d7d6f 100644 --- a/libc/tinymath/cabsf.S +++ b/libc/tinymath/cabsf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ cabsf: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/cabsl.S b/libc/tinymath/cabsl.S index 0ea2da181..0217ef83e 100644 --- a/libc/tinymath/cabsl.S +++ b/libc/tinymath/cabsl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ cabsl: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/carg.S b/libc/tinymath/carg.S index 3d0f5ecc2..f1f98d59d 100644 --- a/libc/tinymath/carg.S +++ b/libc/tinymath/carg.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ carg: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/cargf.S b/libc/tinymath/cargf.S index 9c86b8d45..9117d0405 100644 --- a/libc/tinymath/cargf.S +++ b/libc/tinymath/cargf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ cargf: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/cargl.S b/libc/tinymath/cargl.S index a8fa5ec1b..9ee6703be 100644 --- a/libc/tinymath/cargl.S +++ b/libc/tinymath/cargl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ cargl: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/cbrt.S b/libc/tinymath/cbrt.S index dd5695ae8..fdbf1b941 100644 --- a/libc/tinymath/cbrt.S +++ b/libc/tinymath/cbrt.S @@ -24,4 +24,3 @@ // @return %xmm0 holds binary64 result cbrt: jmp __cbrt .endfn cbrt,globl - .source __FILE__ diff --git a/libc/tinymath/cbrtf.S b/libc/tinymath/cbrtf.S index 4c5b615ea..69ff82a43 100644 --- a/libc/tinymath/cbrtf.S +++ b/libc/tinymath/cbrtf.S @@ -30,4 +30,3 @@ cbrtf: pushq %rbp popq %rbp ret .endfn cbrtf,globl - .source __FILE__ diff --git a/libc/tinymath/cbrtl.S b/libc/tinymath/cbrtl.S index 96c4c57c7..da94d039f 100644 --- a/libc/tinymath/cbrtl.S +++ b/libc/tinymath/cbrtl.S @@ -34,4 +34,3 @@ cbrtl: pushq %rbp leave ret .endfn cbrtl,globl - .source __FILE__ diff --git a/libc/tinymath/cimag.S b/libc/tinymath/cimag.S index 7c4cd24b6..e6c77fd31 100644 --- a/libc/tinymath/cimag.S +++ b/libc/tinymath/cimag.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ cimag: .leafprologue .profilable diff --git a/libc/tinymath/cimagf.S b/libc/tinymath/cimagf.S index a4c962c4f..739d7b90a 100644 --- a/libc/tinymath/cimagf.S +++ b/libc/tinymath/cimagf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ cimagf: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/cimagl.S b/libc/tinymath/cimagl.S index 9c562c0a9..36e0b66ac 100644 --- a/libc/tinymath/cimagl.S +++ b/libc/tinymath/cimagl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ cimagl: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/complex.internal.h b/libc/tinymath/complex.internal.h new file mode 100644 index 000000000..40b2130f4 --- /dev/null +++ b/libc/tinymath/complex.internal.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_TINYMATH_COMPLEX_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_TINYMATH_COMPLEX_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +_Complex double __ldexp_cexp(_Complex double, int) hidden; +_Complex float __ldexp_cexpf(_Complex float, int) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TINYMATH_COMPLEX_INTERNAL_H_ */ diff --git a/libc/tinymath/conj.S b/libc/tinymath/conj.S index 6ae4fc03b..1c01913ac 100644 --- a/libc/tinymath/conj.S +++ b/libc/tinymath/conj.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ conj: .leafprologue .profilable diff --git a/libc/tinymath/conjf.S b/libc/tinymath/conjf.S index 7040cdced..b5fedbd95 100644 --- a/libc/tinymath/conjf.S +++ b/libc/tinymath/conjf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ conjf: .profilable sub $16,%rsp diff --git a/libc/tinymath/conjl.S b/libc/tinymath/conjl.S index 21aedc4b9..ca9353811 100644 --- a/libc/tinymath/conjl.S +++ b/libc/tinymath/conjl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ conjl: .profilable sub $24,%rsp diff --git a/libc/tinymath/cosdf.c b/libc/tinymath/cosdf.c new file mode 100644 index 000000000..fb18bfdd3 --- /dev/null +++ b/libc/tinymath/cosdf.c @@ -0,0 +1,71 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Musl Libc │ +│ Copyright © 2005-2020 Rich Felker, et al. │ +│ │ +│ 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. │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" + +asm(".ident\t\"\\n\\n\ +fdlibm (fdlibm license)\\n\ +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\""); +asm(".ident\t\"\\n\\n\ +Musl libc (MIT License)\\n\ +Copyright 2005-2014 Rich Felker, et. al.\""); +asm(".include \"libc/disclaimer.inc\""); +/* clang-format off */ + +/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */ +/* + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Debugged and optimized by Bruce D. Evans. + */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */ +static const double +C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ +C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ +C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ +C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ + +float __cosdf(double x) +{ + double_t r, w, z; + + /* Try to optimize for parallel evaluation as in __tandf.c. */ + z = x*x; + w = z*z; + r = C2+z*C3; + return ((1.0+z*C0) + w*C1) + (w*z)*r; +} diff --git a/libc/tinymath/cosf.S b/libc/tinymath/cosf.S index 2ef0679a7..8dacf7b85 100644 --- a/libc/tinymath/cosf.S +++ b/libc/tinymath/cosf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns cosine of 𝑥. // diff --git a/libc/tinymath/cosl.S b/libc/tinymath/cosl.S index e74490c54..4a5482e7f 100644 --- a/libc/tinymath/cosl.S +++ b/libc/tinymath/cosl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns cosine of 𝑥. // diff --git a/libc/tinymath/cprojf.S b/libc/tinymath/cprojf.S index c4e7b6dfc..30fb916c9 100644 --- a/libc/tinymath/cprojf.S +++ b/libc/tinymath/cprojf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ cprojf: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/cprojl.S b/libc/tinymath/cprojl.S index bafbfb81d..eeef0b6ef 100644 --- a/libc/tinymath/cprojl.S +++ b/libc/tinymath/cprojl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Projects into Rienmann sphere. // diff --git a/libc/tinymath/creal.S b/libc/tinymath/creal.S index b5c91c80b..2d9fa8259 100644 --- a/libc/tinymath/creal.S +++ b/libc/tinymath/creal.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ creal: ret .endfn creal,globl diff --git a/libc/tinymath/crealf.S b/libc/tinymath/crealf.S index db1688ffc..8cf46f57a 100644 --- a/libc/tinymath/crealf.S +++ b/libc/tinymath/crealf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ crealf: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/creall.S b/libc/tinymath/creall.S index 1628cdc73..a3eca9133 100644 --- a/libc/tinymath/creall.S +++ b/libc/tinymath/creall.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ creall: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/csqrt.c b/libc/tinymath/csqrt.c new file mode 100644 index 000000000..d182ec42b --- /dev/null +++ b/libc/tinymath/csqrt.c @@ -0,0 +1,139 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Musl Libc │ +│ Copyright © 2005-2014 Rich Felker, et al. │ +│ │ +│ 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. │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/complex.h" +#include "libc/math.h" +#include "libc/tinymath/complex.internal.h" + +asm(".ident\t\"\\n\\n\ +Musl libc (MIT License)\\n\ +Copyright 2005-2014 Rich Felker, et. al.\""); +asm(".include \"libc/disclaimer.inc\""); +/* clang-format off */ + +/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrt.c */ +/*- + * Copyright (c) 2007 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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. + */ + +/* + * gcc doesn't implement complex multiplication or division correctly, + * so we need to handle infinities specially. We turn on this pragma to + * notify conforming c99 compilers that the fast-but-incorrect code that + * gcc generates is acceptable, since the special cases have already been + * handled. + */ +// TODO(elimisteve): write test proving why we do / don't need it +// #pragma STDC CX_LIMITED_RANGE ON + +/* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */ +#define THRESH 0x1.a827999fcef32p+1022 + +/** + * Returns complex square root. + */ +complex double csqrt(complex double z) +{ + complex double result; + double a, b; + double t; + int scale; + + a = creal(z); + b = cimag(z); + + /* Handle special cases. */ + if (z == 0) + return CMPLX(0, b); + if (isinf(b)) + return CMPLX(INFINITY, b); + if (isnan(a)) { + t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ + return CMPLX(a, t); /* return NaN + NaN i */ + } + if (isinf(a)) { + /* + * csqrt(inf + NaN i) = inf + NaN i + * csqrt(inf + y i) = inf + 0 i + * csqrt(-inf + NaN i) = NaN +- inf i + * csqrt(-inf + y i) = 0 + inf i + */ + if (signbit(a)) + return CMPLX(fabs(b - b), copysign(a, b)); + else + return CMPLX(a, copysign(b - b, b)); + } + /* + * The remaining special case (b is NaN) is handled just fine by + * the normal code path below. + */ + + /* Scale to avoid overflow. */ + if (fabs(a) >= THRESH || fabs(b) >= THRESH) { + a *= 0.25; + b *= 0.25; + scale = 1; + } else { + scale = 0; + } + + /* Algorithm 312, CACM vol 10, Oct 1967. */ + if (a >= 0) { + t = sqrt((a + hypot(a, b)) * 0.5); + result = CMPLX(t, b / (2 * t)); + } else { + t = sqrt((-a + hypot(a, b)) * 0.5); + result = CMPLX(fabs(b) / (2 * t), copysign(t, b)); + } + + /* Rescale. */ + if (scale) + result *= 2; + return result; +} diff --git a/libc/tinymath/d2ld2.S b/libc/tinymath/d2ld2.S index c064587c5..ceafca877 100644 --- a/libc/tinymath/d2ld2.S +++ b/libc/tinymath/d2ld2.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Thunks double(*fn)(double,double) -> long double fn. // diff --git a/libc/tinymath/exp10f.S b/libc/tinymath/exp10f.S index bd32d10cd..468ea0641 100644 --- a/libc/tinymath/exp10f.S +++ b/libc/tinymath/exp10f.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns 10^x. // diff --git a/libc/tinymath/exp2f.S b/libc/tinymath/exp2f.S index f00bf06ff..487f83e12 100644 --- a/libc/tinymath/exp2f.S +++ b/libc/tinymath/exp2f.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns 2^𝑥. // diff --git a/libc/tinymath/expf.S b/libc/tinymath/expf.S index 14171a0f2..477c6b8fa 100644 --- a/libc/tinymath/expf.S +++ b/libc/tinymath/expf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns 𝑒^x. // diff --git a/libc/tinymath/expm1f.S b/libc/tinymath/expm1f.S index 92e5fe373..4b2c71a8e 100644 --- a/libc/tinymath/expm1f.S +++ b/libc/tinymath/expm1f.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns 𝑒^x-1. // diff --git a/libc/tinymath/f2ld2.S b/libc/tinymath/f2ld2.S index 1773da104..c3a93a49b 100644 --- a/libc/tinymath/f2ld2.S +++ b/libc/tinymath/f2ld2.S @@ -39,4 +39,3 @@ _f2ld2: push %rbp leave ret .endfn _f2ld2,globl,hidden - .source __FILE__ diff --git a/libc/tinymath/fabsf.S b/libc/tinymath/fabsf.S index 6ecad6976..9060da2a7 100644 --- a/libc/tinymath/fabsf.S +++ b/libc/tinymath/fabsf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns absolute value of 𝑥. // diff --git a/libc/tinymath/fmodf.S b/libc/tinymath/fmodf.S index 68464a307..94ba1a90f 100644 --- a/libc/tinymath/fmodf.S +++ b/libc/tinymath/fmodf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ fmodf: ezlea fmodl,ax jmp _f2ld2 diff --git a/libc/tinymath/gamma.c b/libc/tinymath/gamma.c index 62488c474..6da9b236c 100644 --- a/libc/tinymath/gamma.c +++ b/libc/tinymath/gamma.c @@ -322,6 +322,5 @@ double lgamma_r(double x, int *signgamp) */ double lgamma(double x) { - extern int __signgam; return lgamma_r(x, &__signgam); } diff --git a/libc/tinymath/ilogb.S b/libc/tinymath/ilogb.S index 44d3e2a77..f9fcb71b5 100644 --- a/libc/tinymath/ilogb.S +++ b/libc/tinymath/ilogb.S @@ -36,4 +36,3 @@ ilogb: push %rbp leave ret .endfn ilogb,globl - .source __FILE__ diff --git a/libc/tinymath/ilogbf.S b/libc/tinymath/ilogbf.S index 26b29fb1d..04557fc75 100644 --- a/libc/tinymath/ilogbf.S +++ b/libc/tinymath/ilogbf.S @@ -36,4 +36,3 @@ ilogbf: push %rbp leave ret .endfn ilogbf,globl - .source __FILE__ diff --git a/libc/tinymath/ilogbl.S b/libc/tinymath/ilogbl.S index 2d2763019..db5baaba8 100644 --- a/libc/tinymath/ilogbl.S +++ b/libc/tinymath/ilogbl.S @@ -35,4 +35,3 @@ ilogbl: push %rbp leave ret .endfn ilogbl,globl - .source __FILE__ diff --git a/libc/tinymath/kernel.internal.h b/libc/tinymath/kernel.internal.h index e968f32b4..ae09d989f 100644 --- a/libc/tinymath/kernel.internal.h +++ b/libc/tinymath/kernel.internal.h @@ -3,6 +3,11 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +extern int __signgam; + +float __cosdf(double); +float __sindf(double); +float __tandf(double, int); double __sin(double, double, int); double __tan(double, double, int); double __cos(double, double); diff --git a/libc/tinymath/ldexpf.S b/libc/tinymath/ldexpf.S index 7014b4122..485c5e3c7 100644 --- a/libc/tinymath/ldexpf.S +++ b/libc/tinymath/ldexpf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns 𝑥 × 2ʸ. // diff --git a/libc/tinymath/lgamma.c b/libc/tinymath/lgamma.c new file mode 100644 index 000000000..dbac09974 --- /dev/null +++ b/libc/tinymath/lgamma.c @@ -0,0 +1,24 @@ +/*-*- 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 2022 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/math.h" +#include "libc/tinymath/kernel.internal.h" + +double lgamma(double x) { + return lgamma_r(x, &__signgam); +} diff --git a/libc/tinymath/lgamma_r.c b/libc/tinymath/lgamma_r.c new file mode 100644 index 000000000..ac35db779 --- /dev/null +++ b/libc/tinymath/lgamma_r.c @@ -0,0 +1,321 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Musl Libc │ +│ Copyright © 2005-2020 Rich Felker, et al. │ +│ │ +│ 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. │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/tinymath/kernel.internal.h" + +asm(".ident\t\"\\n\\n\ +fdlibm (fdlibm license)\\n\ +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\""); +asm(".ident\t\"\\n\\n\ +Musl libc (MIT License)\\n\ +Copyright 2005-2014 Rich Felker, et. al.\""); +asm(".include \"libc/disclaimer.inc\""); +/* clang-format off */ + +/* origin: FreeBSD /usr/src/lib/msun/src/e_lgamma_r.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ +/* lgamma_r(x, signgamp) + * Reentrant version of the logarithm of the Gamma function + * with user provide pointer for the sign of Gamma(x). + * + * Method: + * 1. Argument Reduction for 0 < x <= 8 + * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may + * reduce x to a number in [1.5,2.5] by + * lgamma(1+s) = log(s) + lgamma(s) + * for example, + * lgamma(7.3) = log(6.3) + lgamma(6.3) + * = log(6.3*5.3) + lgamma(5.3) + * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) + * 2. Polynomial approximation of lgamma around its + * minimun ymin=1.461632144968362245 to maintain monotonicity. + * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use + * Let z = x-ymin; + * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) + * where + * poly(z) is a 14 degree polynomial. + * 2. Rational approximation in the primary interval [2,3] + * We use the following approximation: + * s = x-2.0; + * lgamma(x) = 0.5*s + s*P(s)/Q(s) + * with accuracy + * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71 + * Our algorithms are based on the following observation + * + * zeta(2)-1 2 zeta(3)-1 3 + * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... + * 2 3 + * + * where Euler = 0.5771... is the Euler constant, which is very + * close to 0.5. + * + * 3. For x>=8, we have + * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... + * (better formula: + * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) + * Let z = 1/x, then we approximation + * f(z) = lgamma(x) - (x-0.5)(log(x)-1) + * by + * 3 5 11 + * w = w0 + w1*z + w2*z + w3*z + ... + w6*z + * where + * |w - f(z)| < 2**-58.74 + * + * 4. For negative x, since (G is gamma function) + * -x*G(-x)*G(x) = pi/sin(pi*x), + * we have + * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) + * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 + * Hence, for x<0, signgam = sign(sin(pi*x)) and + * lgamma(x) = log(|Gamma(x)|) + * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); + * Note: one should avoid compute pi*(-x) directly in the + * computation of sin(pi*(-x)). + * + * 5. Special Cases + * lgamma(2+s) ~ s*(1-Euler) for tiny s + * lgamma(1) = lgamma(2) = 0 + * lgamma(x) ~ -log(|x|) for tiny x + * lgamma(0) = lgamma(neg.integer) = inf and raise divide-by-zero + * lgamma(inf) = inf + * lgamma(-inf) = inf (bug for bug compatible with C99!?) + * + */ + +static const double +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */ +a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */ +a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */ +a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */ +a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */ +a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */ +a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */ +a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */ +a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */ +a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */ +a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */ +a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */ +tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */ +tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */ +/* tt = -(tail of tf) */ +tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */ +t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */ +t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */ +t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */ +t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */ +t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */ +t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */ +t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */ +t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */ +t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */ +t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */ +t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */ +t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */ +t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */ +t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */ +t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */ +u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ +u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */ +u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */ +u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */ +u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */ +u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */ +v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */ +v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */ +v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */ +v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */ +v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */ +s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ +s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */ +s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */ +s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */ +s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */ +s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */ +s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */ +r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */ +r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */ +r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */ +r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */ +r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */ +r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */ +w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */ +w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */ +w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */ +w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */ +w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */ +w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */ +w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */ + +/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */ +static double sin_pi(double x) +{ + int n; + + /* spurious inexact if odd int */ + x = 2.0*(x*0.5 - floor(x*0.5)); /* x mod 2.0 */ + + n = (int)(x*4.0); + n = (n+1)/2; + x -= n*0.5f; + x *= pi; + + switch (n) { + default: /* case 4: */ + case 0: return __sin(x, 0.0, 0); + case 1: return __cos(x, 0.0); + case 2: return __sin(-x, 0.0, 0); + case 3: return -__cos(x, 0.0); + } +} + +/** + * Returns natural logarithm of absolute value of Gamma function. + */ +double lgamma_r(double x, int *signgamp) +{ + union {double f; uint64_t i;} u = {x}; + double_t t,y,z,nadj,p,p1,p2,p3,q,r,w; + uint32_t ix; + int sign,i; + + /* purge off +-inf, NaN, +-0, tiny and negative arguments */ + *signgamp = 1; + sign = u.i>>63; + ix = u.i>>32 & 0x7fffffff; + if (ix >= 0x7ff00000) + return x*x; + if (ix < (0x3ff-70)<<20) { /* |x|<2**-70, return -log(|x|) */ + if(sign) { + x = -x; + *signgamp = -1; + } + return -log(x); + } + if (sign) { + x = -x; + t = sin_pi(x); + if (t == 0.0) /* -integer */ + return 1.0/(x-x); + if (t > 0.0) + *signgamp = -1; + else + t = -t; + nadj = log(pi/(t*x)); + } + + /* purge off 1 and 2 */ + if ((ix == 0x3ff00000 || ix == 0x40000000) && (uint32_t)u.i == 0) + r = 0; + /* for x < 2.0 */ + else if (ix < 0x40000000) { + if (ix <= 0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */ + r = -log(x); + if (ix >= 0x3FE76944) { + y = 1.0 - x; + i = 0; + } else if (ix >= 0x3FCDA661) { + y = x - (tc-1.0); + i = 1; + } else { + y = x; + i = 2; + } + } else { + r = 0.0; + if (ix >= 0x3FFBB4C3) { /* [1.7316,2] */ + y = 2.0 - x; + i = 0; + } else if(ix >= 0x3FF3B4C4) { /* [1.23,1.73] */ + y = x - tc; + i = 1; + } else { + y = x - 1.0; + i = 2; + } + } + switch (i) { + case 0: + z = y*y; + p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); + p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); + p = y*p1+p2; + r += (p-0.5*y); + break; + case 1: + z = y*y; + w = z*y; + p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ + p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); + p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); + p = z*p1-(tt-w*(p2+y*p3)); + r += tf + p; + break; + case 2: + p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); + p2 = 1.0+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); + r += -0.5*y + p1/p2; + } + } else if (ix < 0x40200000) { /* x < 8.0 */ + i = (int)x; + y = x - (double)i; + p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); + q = 1.0+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); + r = 0.5*y+p/q; + z = 1.0; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch (i) { + case 7: z *= y + 6.0; /* FALLTHRU */ + case 6: z *= y + 5.0; /* FALLTHRU */ + case 5: z *= y + 4.0; /* FALLTHRU */ + case 4: z *= y + 3.0; /* FALLTHRU */ + case 3: z *= y + 2.0; /* FALLTHRU */ + r += log(z); + break; + } + } else if (ix < 0x43900000) { /* 8.0 <= x < 2**58 */ + t = log(x); + z = 1.0/x; + y = z*z; + w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); + r = (x-0.5)*(t-1.0)+w; + } else /* 2**58 <= x <= inf */ + r = x*(log(x)-1.0); + if (sign) + r = nadj - r; + return r; +} diff --git a/libc/tinymath/lgammaf.c b/libc/tinymath/lgammaf.c new file mode 100644 index 000000000..641d69769 --- /dev/null +++ b/libc/tinymath/lgammaf.c @@ -0,0 +1,24 @@ +/*-*- 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 2022 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/math.h" +#include "libc/tinymath/kernel.internal.h" + +float lgammaf(float x) { + return lgammaf_r(x, &__signgam); +} diff --git a/libc/tinymath/lgammaf_r.c b/libc/tinymath/lgammaf_r.c new file mode 100644 index 000000000..99f9b5ebf --- /dev/null +++ b/libc/tinymath/lgammaf_r.c @@ -0,0 +1,256 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Musl Libc │ +│ Copyright © 2005-2020 Rich Felker, et al. │ +│ │ +│ 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. │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/tinymath/kernel.internal.h" + +asm(".ident\t\"\\n\\n\ +fdlibm (fdlibm license)\\n\ +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\""); +asm(".ident\t\"\\n\\n\ +Musl libc (MIT License)\\n\ +Copyright 2005-2014 Rich Felker, et. al.\""); +asm(".include \"libc/disclaimer.inc\""); +/* clang-format off */ + +/* origin: FreeBSD /usr/src/lib/msun/src/e_lgammaf_r.c */ +/* + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +static const float +pi = 3.1415927410e+00, /* 0x40490fdb */ +a0 = 7.7215664089e-02, /* 0x3d9e233f */ +a1 = 3.2246702909e-01, /* 0x3ea51a66 */ +a2 = 6.7352302372e-02, /* 0x3d89f001 */ +a3 = 2.0580807701e-02, /* 0x3ca89915 */ +a4 = 7.3855509982e-03, /* 0x3bf2027e */ +a5 = 2.8905137442e-03, /* 0x3b3d6ec6 */ +a6 = 1.1927076848e-03, /* 0x3a9c54a1 */ +a7 = 5.1006977446e-04, /* 0x3a05b634 */ +a8 = 2.2086278477e-04, /* 0x39679767 */ +a9 = 1.0801156895e-04, /* 0x38e28445 */ +a10 = 2.5214456400e-05, /* 0x37d383a2 */ +a11 = 4.4864096708e-05, /* 0x383c2c75 */ +tc = 1.4616321325e+00, /* 0x3fbb16c3 */ +tf = -1.2148628384e-01, /* 0xbdf8cdcd */ +/* tt = -(tail of tf) */ +tt = 6.6971006518e-09, /* 0x31e61c52 */ +t0 = 4.8383611441e-01, /* 0x3ef7b95e */ +t1 = -1.4758771658e-01, /* 0xbe17213c */ +t2 = 6.4624942839e-02, /* 0x3d845a15 */ +t3 = -3.2788541168e-02, /* 0xbd064d47 */ +t4 = 1.7970675603e-02, /* 0x3c93373d */ +t5 = -1.0314224288e-02, /* 0xbc28fcfe */ +t6 = 6.1005386524e-03, /* 0x3bc7e707 */ +t7 = -3.6845202558e-03, /* 0xbb7177fe */ +t8 = 2.2596477065e-03, /* 0x3b141699 */ +t9 = -1.4034647029e-03, /* 0xbab7f476 */ +t10 = 8.8108185446e-04, /* 0x3a66f867 */ +t11 = -5.3859531181e-04, /* 0xba0d3085 */ +t12 = 3.1563205994e-04, /* 0x39a57b6b */ +t13 = -3.1275415677e-04, /* 0xb9a3f927 */ +t14 = 3.3552918467e-04, /* 0x39afe9f7 */ +u0 = -7.7215664089e-02, /* 0xbd9e233f */ +u1 = 6.3282704353e-01, /* 0x3f2200f4 */ +u2 = 1.4549225569e+00, /* 0x3fba3ae7 */ +u3 = 9.7771751881e-01, /* 0x3f7a4bb2 */ +u4 = 2.2896373272e-01, /* 0x3e6a7578 */ +u5 = 1.3381091878e-02, /* 0x3c5b3c5e */ +v1 = 2.4559779167e+00, /* 0x401d2ebe */ +v2 = 2.1284897327e+00, /* 0x4008392d */ +v3 = 7.6928514242e-01, /* 0x3f44efdf */ +v4 = 1.0422264785e-01, /* 0x3dd572af */ +v5 = 3.2170924824e-03, /* 0x3b52d5db */ +s0 = -7.7215664089e-02, /* 0xbd9e233f */ +s1 = 2.1498242021e-01, /* 0x3e5c245a */ +s2 = 3.2577878237e-01, /* 0x3ea6cc7a */ +s3 = 1.4635047317e-01, /* 0x3e15dce6 */ +s4 = 2.6642270386e-02, /* 0x3cda40e4 */ +s5 = 1.8402845599e-03, /* 0x3af135b4 */ +s6 = 3.1947532989e-05, /* 0x3805ff67 */ +r1 = 1.3920053244e+00, /* 0x3fb22d3b */ +r2 = 7.2193557024e-01, /* 0x3f38d0c5 */ +r3 = 1.7193385959e-01, /* 0x3e300f6e */ +r4 = 1.8645919859e-02, /* 0x3c98bf54 */ +r5 = 7.7794247773e-04, /* 0x3a4beed6 */ +r6 = 7.3266842264e-06, /* 0x36f5d7bd */ +w0 = 4.1893854737e-01, /* 0x3ed67f1d */ +w1 = 8.3333335817e-02, /* 0x3daaaaab */ +w2 = -2.7777778450e-03, /* 0xbb360b61 */ +w3 = 7.9365057172e-04, /* 0x3a500cfd */ +w4 = -5.9518753551e-04, /* 0xba1c065c */ +w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */ +w6 = -1.6309292987e-03; /* 0xbad5c4e8 */ + +/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */ +static float sin_pi(float x) +{ + double_t y; + int n; + + /* spurious inexact if odd int */ + x = 2*(x*0.5f - floorf(x*0.5f)); /* x mod 2.0 */ + + n = (int)(x*4); + n = (n+1)/2; + y = x - n*0.5f; + y *= 3.14159265358979323846; + switch (n) { + default: /* case 4: */ + case 0: return __sindf(y); + case 1: return __cosdf(y); + case 2: return __sindf(-y); + case 3: return -__cosdf(y); + } +} + +/** + * Returns natural logarithm of absolute value of Gamma function. + */ +float lgammaf_r(float x, int *signgamp) +{ + union {float f; uint32_t i;} u = {x}; + float t,y,z,nadj,p,p1,p2,p3,q,r,w; + uint32_t ix; + int i,sign; + + /* purge off +-inf, NaN, +-0, tiny and negative arguments */ + *signgamp = 1; + sign = u.i>>31; + ix = u.i & 0x7fffffff; + if (ix >= 0x7f800000) + return x*x; + if (ix < 0x35000000) { /* |x| < 2**-21, return -log(|x|) */ + if (sign) { + *signgamp = -1; + x = -x; + } + return -logf(x); + } + if (sign) { + x = -x; + t = sin_pi(x); + if (t == 0.0f) /* -integer */ + return 1.0f/(x-x); + if (t > 0.0f) + *signgamp = -1; + else + t = -t; + nadj = logf(pi/(t*x)); + } + + /* purge off 1 and 2 */ + if (ix == 0x3f800000 || ix == 0x40000000) + r = 0; + /* for x < 2.0 */ + else if (ix < 0x40000000) { + if (ix <= 0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */ + r = -logf(x); + if (ix >= 0x3f3b4a20) { + y = 1.0f - x; + i = 0; + } else if (ix >= 0x3e6d3308) { + y = x - (tc-1.0f); + i = 1; + } else { + y = x; + i = 2; + } + } else { + r = 0.0f; + if (ix >= 0x3fdda618) { /* [1.7316,2] */ + y = 2.0f - x; + i = 0; + } else if (ix >= 0x3F9da620) { /* [1.23,1.73] */ + y = x - tc; + i = 1; + } else { + y = x - 1.0f; + i = 2; + } + } + switch(i) { + case 0: + z = y*y; + p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); + p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); + p = y*p1+p2; + r += p - 0.5f*y; + break; + case 1: + z = y*y; + w = z*y; + p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ + p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); + p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); + p = z*p1-(tt-w*(p2+y*p3)); + r += (tf + p); + break; + case 2: + p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); + p2 = 1.0f+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); + r += -0.5f*y + p1/p2; + } + } else if (ix < 0x41000000) { /* x < 8.0 */ + i = (int)x; + y = x - (float)i; + p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); + q = 1.0f+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); + r = 0.5f*y+p/q; + z = 1.0f; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch (i) { + case 7: z *= y + 6.0f; /* FALLTHRU */ + case 6: z *= y + 5.0f; /* FALLTHRU */ + case 5: z *= y + 4.0f; /* FALLTHRU */ + case 4: z *= y + 3.0f; /* FALLTHRU */ + case 3: z *= y + 2.0f; /* FALLTHRU */ + r += logf(z); + break; + } + } else if (ix < 0x5c800000) { /* 8.0 <= x < 2**58 */ + t = logf(x); + z = 1.0f/x; + y = z*z; + w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); + r = (x-0.5f)*(t-1.0f)+w; + } else /* 2**58 <= x <= inf */ + r = x*(logf(x)-1.0f); + if (sign) + r = nadj - r; + return r; +} diff --git a/libc/tinymath/log10.S b/libc/tinymath/log10.S index 88e72971d..a8907b473 100644 --- a/libc/tinymath/log10.S +++ b/libc/tinymath/log10.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Calculates log₁₀𝑥. // diff --git a/libc/tinymath/log10f.S b/libc/tinymath/log10f.S index 70719015b..4ccf29a44 100644 --- a/libc/tinymath/log10f.S +++ b/libc/tinymath/log10f.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Calculates log₁₀𝑥. // diff --git a/libc/tinymath/log10l.S b/libc/tinymath/log10l.S index 644e899f6..75e1fa2fa 100644 --- a/libc/tinymath/log10l.S +++ b/libc/tinymath/log10l.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Calculates log₁₀𝑥. // diff --git a/libc/tinymath/log1pl.S b/libc/tinymath/log1pl.S index 29082fc69..4b2626dd4 100644 --- a/libc/tinymath/log1pl.S +++ b/libc/tinymath/log1pl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns log(𝟷+𝑥). // diff --git a/libc/tinymath/log2f.S b/libc/tinymath/log2f.S index 1c9527cb2..304d6de34 100644 --- a/libc/tinymath/log2f.S +++ b/libc/tinymath/log2f.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Calculates log₂𝑥. // diff --git a/libc/tinymath/logb.S b/libc/tinymath/logb.S index 9f85a250c..415bfc9bd 100644 --- a/libc/tinymath/logb.S +++ b/libc/tinymath/logb.S @@ -25,4 +25,3 @@ logb: ezlea logbl,ax jmp _d2ld2 .endfn logb,globl - .source __FILE__ diff --git a/libc/tinymath/logbf.S b/libc/tinymath/logbf.S index 333cb99ea..79fb34572 100644 --- a/libc/tinymath/logbf.S +++ b/libc/tinymath/logbf.S @@ -25,4 +25,3 @@ logbf: ezlea logbl,ax jmp _f2ld2 .endfn logbf,globl - .source __FILE__ diff --git a/libc/tinymath/logbl.S b/libc/tinymath/logbl.S index 9c78f30b2..1b61e4f77 100644 --- a/libc/tinymath/logbl.S +++ b/libc/tinymath/logbl.S @@ -31,4 +31,3 @@ logbl: push %rbp pop %rbp ret .endfn logbl,globl - .source __FILE__ diff --git a/libc/tinymath/logf.S b/libc/tinymath/logf.S index a3acff19c..7255a6b37 100644 --- a/libc/tinymath/logf.S +++ b/libc/tinymath/logf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns natural logarithm of 𝑥. // diff --git a/libc/tinymath/lrint.S b/libc/tinymath/lrint.S index f2423df3e..332b78b01 100644 --- a/libc/tinymath/lrint.S +++ b/libc/tinymath/lrint.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ lrint: cvtsd2siq %xmm0,%rax ret diff --git a/libc/tinymath/lrintf.S b/libc/tinymath/lrintf.S index ac7e9e5f8..b220eca3c 100644 --- a/libc/tinymath/lrintf.S +++ b/libc/tinymath/lrintf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ lrintf: cvtss2siq %xmm0,%rax ret diff --git a/libc/tinymath/lrintl.S b/libc/tinymath/lrintl.S index e874c7496..4dc5ef4b1 100644 --- a/libc/tinymath/lrintl.S +++ b/libc/tinymath/lrintl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ lrintl: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/lround.S b/libc/tinymath/lround.S index b93a81936..2f22bc9d3 100644 --- a/libc/tinymath/lround.S +++ b/libc/tinymath/lround.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Rounds to nearest integer, away from zero. // diff --git a/libc/tinymath/lroundf.S b/libc/tinymath/lroundf.S index 5e9dd3824..fbdb4f982 100644 --- a/libc/tinymath/lroundf.S +++ b/libc/tinymath/lroundf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Rounds to nearest integer, away from zero. // diff --git a/libc/tinymath/lroundl.S b/libc/tinymath/lroundl.S index c8dac6f1a..7c1794e86 100644 --- a/libc/tinymath/lroundl.S +++ b/libc/tinymath/lroundl.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/runtime/pc.internal.h" #include "libc/macros.internal.h" -.source __FILE__ lroundl: push %rbp diff --git a/libc/tinymath/nan.c b/libc/tinymath/nan.c new file mode 100644 index 000000000..a2bc5b0e1 --- /dev/null +++ b/libc/tinymath/nan.c @@ -0,0 +1,23 @@ +/*-*- 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 2022 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/math.h" + +double nan(const char *s) { + return NAN; +} diff --git a/libc/tinymath/nanf.c b/libc/tinymath/nanf.c new file mode 100644 index 000000000..d1023fb60 --- /dev/null +++ b/libc/tinymath/nanf.c @@ -0,0 +1,23 @@ +/*-*- 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 2022 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/math.h" + +float nanf(const char *s) { + return NAN; +} diff --git a/libc/tinymath/nanl.c b/libc/tinymath/nanl.c new file mode 100644 index 000000000..fb16dc09e --- /dev/null +++ b/libc/tinymath/nanl.c @@ -0,0 +1,23 @@ +/*-*- 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 2022 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/math.h" + +long double nanl(const char *s) { + return NAN; +} diff --git a/libc/tinymath/nearbyint.S b/libc/tinymath/nearbyint.S index e79ef582c..fe230585d 100644 --- a/libc/tinymath/nearbyint.S +++ b/libc/tinymath/nearbyint.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ nearbyint: .profilable diff --git a/libc/tinymath/nearbyintf.S b/libc/tinymath/nearbyintf.S index b56d9964a..8016b8011 100644 --- a/libc/tinymath/nearbyintf.S +++ b/libc/tinymath/nearbyintf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ nearbyintf: .profilable diff --git a/libc/tinymath/nearbyintl.S b/libc/tinymath/nearbyintl.S index 9c9307ddb..7b586448d 100644 --- a/libc/tinymath/nearbyintl.S +++ b/libc/tinymath/nearbyintl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ nearbyintl: .profilable diff --git a/libc/tinymath/remainder.S b/libc/tinymath/remainder.S index 3558e291a..098774ed7 100644 --- a/libc/tinymath/remainder.S +++ b/libc/tinymath/remainder.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // remainder(𝑥,𝑦) means (𝑥 rem 𝑦) w/ rint()-style rounding. // diff --git a/libc/tinymath/remainderf.S b/libc/tinymath/remainderf.S index 7427c6aea..9e6a90405 100644 --- a/libc/tinymath/remainderf.S +++ b/libc/tinymath/remainderf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ remainderf: ezlea remainderl,ax diff --git a/libc/tinymath/remainderl.S b/libc/tinymath/remainderl.S index bd14ae998..edf2c159e 100644 --- a/libc/tinymath/remainderl.S +++ b/libc/tinymath/remainderl.S @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/runtime/pc.internal.h" #include "libc/macros.internal.h" -.source __FILE__ remainderl: push %rbp diff --git a/libc/tinymath/rint.S b/libc/tinymath/rint.S index 07e5a4a3b..b3b8d3d4e 100644 --- a/libc/tinymath/rint.S +++ b/libc/tinymath/rint.S @@ -19,7 +19,6 @@ #include "libc/nexgen32e/x86feature.h" #include "libc/bits/smmintrin.internal.h" #include "libc/macros.internal.h" -.source __FILE__ // Rounds to nearest integer. // diff --git a/libc/tinymath/rintf.S b/libc/tinymath/rintf.S index 858e358c2..358ead1a3 100644 --- a/libc/tinymath/rintf.S +++ b/libc/tinymath/rintf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ rintf: .leafprologue .profilable diff --git a/libc/tinymath/rintl.S b/libc/tinymath/rintl.S index adc97bad7..1e67d7054 100644 --- a/libc/tinymath/rintl.S +++ b/libc/tinymath/rintl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Rounds to nearest integer. // diff --git a/libc/tinymath/round.S b/libc/tinymath/round.S index e47e79de6..cfdfd4648 100644 --- a/libc/tinymath/round.S +++ b/libc/tinymath/round.S @@ -19,7 +19,6 @@ #include "libc/macros.internal.h" #include "libc/bits/smmintrin.internal.h" #include "libc/nexgen32e/x86feature.h" -.source __FILE__ // Rounds to nearest integer, away from zero. // diff --git a/libc/tinymath/roundf.S b/libc/tinymath/roundf.S index b873d920b..a7e582e36 100644 --- a/libc/tinymath/roundf.S +++ b/libc/tinymath/roundf.S @@ -19,7 +19,6 @@ #include "libc/macros.internal.h" #include "libc/bits/smmintrin.internal.h" #include "libc/nexgen32e/x86feature.h" -.source __FILE__ // Rounds to nearest integer, away from zero. // diff --git a/libc/tinymath/roundl.S b/libc/tinymath/roundl.S index db45f9994..d04e1bd86 100644 --- a/libc/tinymath/roundl.S +++ b/libc/tinymath/roundl.S @@ -44,7 +44,6 @@ roundl: push %rbp 1: leave ret .endfn roundl,globl - .source __FILE__ .rodata.cst4 .Lhalf: .float .5 diff --git a/libc/tinymath/scalbf.S b/libc/tinymath/scalbf.S index b7acc2c48..3d797bebe 100644 --- a/libc/tinymath/scalbf.S +++ b/libc/tinymath/scalbf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns 𝑥 × 2ʸ. // diff --git a/libc/tinymath/scalbl.S b/libc/tinymath/scalbl.S index a0ae41ae5..263475c2a 100644 --- a/libc/tinymath/scalbl.S +++ b/libc/tinymath/scalbl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns 𝑥 × 2ʸ. // diff --git a/libc/tinymath/signbit.S b/libc/tinymath/signbit.S index a588c7ef6..3c9f63836 100644 --- a/libc/tinymath/signbit.S +++ b/libc/tinymath/signbit.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ signbit: .leafprologue diff --git a/libc/tinymath/signbitf.S b/libc/tinymath/signbitf.S index d9c96da57..df1ff15cc 100644 --- a/libc/tinymath/signbitf.S +++ b/libc/tinymath/signbitf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ signbitf: .leafprologue diff --git a/libc/tinymath/signbitl.S b/libc/tinymath/signbitl.S index 737f4d2c2..3e627ed52 100644 --- a/libc/tinymath/signbitl.S +++ b/libc/tinymath/signbitl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ signbitl: push %rbp diff --git a/libc/tinymath/significand.S b/libc/tinymath/significand.S index f49868c1a..324e32854 100644 --- a/libc/tinymath/significand.S +++ b/libc/tinymath/significand.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ significand: push %rbp diff --git a/libc/tinymath/significandf.S b/libc/tinymath/significandf.S index d539f557e..81e54c2de 100644 --- a/libc/tinymath/significandf.S +++ b/libc/tinymath/significandf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ significandf: push %rbp diff --git a/libc/tinymath/significandl.S b/libc/tinymath/significandl.S index a022ffaa2..e355f7fb2 100644 --- a/libc/tinymath/significandl.S +++ b/libc/tinymath/significandl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ significandl: push %rbp diff --git a/libc/tinymath/sindf.c b/libc/tinymath/sindf.c new file mode 100644 index 000000000..3ea45935f --- /dev/null +++ b/libc/tinymath/sindf.c @@ -0,0 +1,72 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Musl Libc │ +│ Copyright © 2005-2020 Rich Felker, et al. │ +│ │ +│ 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. │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" + +asm(".ident\t\"\\n\\n\ +fdlibm (fdlibm license)\\n\ +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\""); +asm(".ident\t\"\\n\\n\ +Musl libc (MIT License)\\n\ +Copyright 2005-2014 Rich Felker, et. al.\""); +asm(".include \"libc/disclaimer.inc\""); +/* clang-format off */ + +/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */ +/* + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Optimized by Bruce D. Evans. + */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */ +static const double +S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ +S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ +S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ +S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */ + +float __sindf(double x) +{ + double_t r, s, w, z; + + /* Try to optimize for parallel evaluation as in __tandf.c. */ + z = x*x; + w = z*z; + r = S3 + z*S4; + s = z*x; + return (x + s*(S1 + z*S2)) + s*w*r; +} diff --git a/libc/tinymath/sqrtl.S b/libc/tinymath/sqrtl.S index b8584b323..2b5c63634 100644 --- a/libc/tinymath/sqrtl.S +++ b/libc/tinymath/sqrtl.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns square root of 𝑥. // diff --git a/libc/tinymath/tandf.c b/libc/tinymath/tandf.c new file mode 100644 index 000000000..c6a7b06ba --- /dev/null +++ b/libc/tinymath/tandf.c @@ -0,0 +1,90 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Musl Libc │ +│ Copyright © 2005-2020 Rich Felker, et al. │ +│ │ +│ 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. │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" + +asm(".ident\t\"\\n\\n\ +fdlibm (fdlibm license)\\n\ +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\""); +asm(".ident\t\"\\n\\n\ +Musl libc (MIT License)\\n\ +Copyright 2005-2014 Rich Felker, et. al.\""); +asm(".include \"libc/disclaimer.inc\""); +/* clang-format off */ + +/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */ +/* + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Optimized by Bruce D. Evans. + */ +/* + * ==================================================== + * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */ +static const double T[] = { + 0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */ + 0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */ + 0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */ + 0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */ + 0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */ + 0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */ +}; + +float __tandf(double x, int odd) +{ + double_t z,r,w,s,t,u; + + z = x*x; + /* + * Split up the polynomial into small independent terms to give + * opportunities for parallel evaluation. The chosen splitting is + * micro-optimized for Athlons (XP, X64). It costs 2 multiplications + * relative to Horner's method on sequential machines. + * + * We add the small terms from lowest degree up for efficiency on + * non-sequential machines (the lowest degree terms tend to be ready + * earlier). Apart from this, we don't care about order of + * operations, and don't need to to care since we have precision to + * spare. However, the chosen splitting is good for accuracy too, + * and would give results as accurate as Horner's method if the + * small terms were added from highest degree down. + */ + r = T[4] + z*T[5]; + t = T[2] + z*T[3]; + w = z*z; + s = z*x; + u = T[0] + z*T[1]; + r = (x + s*u) + (s*w)*(t + w*r); + return odd ? -1.0/r : r; +} diff --git a/libc/tinymath/tanf.S b/libc/tinymath/tanf.S index 348e42b4a..faf026c2c 100644 --- a/libc/tinymath/tanf.S +++ b/libc/tinymath/tanf.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Returns tangent of 𝑥. // diff --git a/libc/type2str.h b/libc/type2str.h new file mode 100644 index 000000000..ad48948b3 --- /dev/null +++ b/libc/type2str.h @@ -0,0 +1,44 @@ +#ifndef COSMOPOLITAN_LIBC_TYPE2STR_H_ +#define COSMOPOLITAN_LIBC_TYPE2STR_H_ +#if __STDC_VERSION__ + 0 >= 201112 +/* clang-format off */ + +#define _TYPE2STR(X) \ + _Generic(X, \ + _Bool: "_Bool", \ + signed char: "signed char", \ + unsigned char: "unsigned char", \ + char: "char", \ + short: "short", \ + unsigned short: "unsigned short", \ + int: "int", \ + unsigned: "unsigned", \ + long: "long", \ + unsigned long: "unsigned long", \ + long long: "long long", \ + unsigned long long: "unsigned long long", \ + float: "float", \ + double: "double", \ + long double: "long double") + +#define _PRINTF_GENERIC(X, D, U) \ + _Generic(X, \ + _Bool: "hhh" U, \ + signed char: "hh" D, \ + unsigned char: "hh" U, \ + char: "hh" D, \ + short: "h" D, \ + unsigned short: "h" U, \ + int: D, \ + unsigned: U, \ + long: "l" D, \ + unsigned long: "l" U, \ + long long: "ll" D, \ + unsigned long long: "ll" U, \ + float: "f", \ + double: "f", \ + long double: "Lf") + +/* clang-format on */ +#endif /* C11 */ +#endif /* COSMOPOLITAN_LIBC_TYPE2STR_H_ */ diff --git a/libc/unicode/eastasianwidth.txt b/libc/unicode/eastasianwidth.txt index e04f70517..8e2a738fe 100644 --- a/libc/unicode/eastasianwidth.txt +++ b/libc/unicode/eastasianwidth.txt @@ -1,6 +1,6 @@ -# EastAsianWidth-14.0.0.txt -# Date: 2021-07-06, 09:58:53 GMT [KW, LI] -# © 2021 Unicode®, Inc. +# EastAsianWidth-15.0.0.txt +# Date: 2022-01-28, 13:07:15 GMT [KW, LI] +# © 2022 Unicode®, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see https://www.unicode.org/terms_of_use.html # @@ -534,6 +534,7 @@ 0CE2..0CE3;N # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL 0CE6..0CEF;N # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE 0CF1..0CF2;N # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA +0CF3;N # Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT 0D00..0D01;N # Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU 0D02..0D03;N # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA 0D04..0D0C;N # Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L @@ -595,7 +596,7 @@ 0EBD;N # Lo LAO SEMIVOWEL SIGN NYO 0EC0..0EC4;N # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI 0EC6;N # Lm LAO KO LA -0EC8..0ECD;N # Mn [6] LAO TONE MAI EK..LAO NIGGAHITA +0EC8..0ECE;N # Mn [7] LAO TONE MAI EK..LAO YAMAKKAN 0ED0..0ED9;N # Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE 0EDC..0EDF;N # Lo [4] LAO HO NO..LAO LETTER KHMU NYO 0F00;N # Lo TIBETAN SYLLABLE OM @@ -1946,6 +1947,7 @@ FFFD;A # So REPLACEMENT CHARACTER 10EAB..10EAC;N # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK 10EAD;N # Pd YEZIDI HYPHENATION MARK 10EB0..10EB1;N # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE +10EFD..10EFF;N # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA 10F00..10F1C;N # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F1D..10F26;N # No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF 10F27;N # Lo OLD SOGDIAN LIGATURE AYIN-DALETH @@ -2028,6 +2030,8 @@ FFFD;A # So REPLACEMENT CHARACTER 11236..11237;N # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA 11238..1123D;N # Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN 1123E;N # Mn KHOJKI SIGN SUKUN +1123F..11240;N # Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I +11241;N # Mn KHOJKI VOWEL SIGN VOCALIC R 11280..11286;N # Lo [7] MULTANI LETTER A..MULTANI LETTER GA 11288;N # Lo MULTANI LETTER GHA 1128A..1128D;N # Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA @@ -2190,6 +2194,7 @@ FFFD;A # So REPLACEMENT CHARACTER 11A9E..11AA2;N # Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2 11AB0..11ABF;N # Lo [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA 11AC0..11AF8;N # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL +11B00..11B09;N # Po [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU 11C00..11C08;N # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E;N # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C2F;N # Mc BHAIKSUKI VOWEL SIGN AA @@ -2235,6 +2240,19 @@ FFFD;A # So REPLACEMENT CHARACTER 11EF3..11EF4;N # Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U 11EF5..11EF6;N # Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O 11EF7..11EF8;N # Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION +11F00..11F01;N # Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA +11F02;N # Lo KAWI SIGN REPHA +11F03;N # Mc KAWI SIGN VISARGA +11F04..11F10;N # Lo [13] KAWI LETTER A..KAWI LETTER O +11F12..11F33;N # Lo [34] KAWI LETTER KA..KAWI LETTER JNYA +11F34..11F35;N # Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA +11F36..11F3A;N # Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R +11F3E..11F3F;N # Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI +11F40;N # Mn KAWI VOWEL SIGN EU +11F41;N # Mc KAWI SIGN KILLER +11F42;N # Mn KAWI CONJOINER +11F43..11F4F;N # Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL +11F50..11F59;N # Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE 11FB0;N # Lo LISU LETTER YHA 11FC0..11FD4;N # No [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH 11FD5..11FDC;N # So [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI @@ -2247,8 +2265,10 @@ FFFD;A # So REPLACEMENT CHARACTER 12480..12543;N # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU 12F90..12FF0;N # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 12FF1..12FF2;N # Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302 -13000..1342E;N # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 -13430..13438;N # Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT +13000..1342F;N # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D +13430..13440;N # Cf [17] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY +13441..13446;N # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN +13447..13455;N # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED 14400..14646;N # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 16800..16A38;N # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E;N # Lo [31] MRO LETTER TA..MRO LETTER TEK @@ -2293,7 +2313,9 @@ FFFD;A # So REPLACEMENT CHARACTER 1AFFD..1AFFE;W # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 1B000..1B0FF;W # Lo [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2 1B100..1B122;W # Lo [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU +1B132;W # Lo HIRAGANA LETTER SMALL KO 1B150..1B152;W # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO +1B155;W # Lo KATAKANA LETTER SMALL KO 1B164..1B167;W # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N 1B170..1B2FB;W # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB 1BC00..1BC6A;N # Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M @@ -2324,6 +2346,7 @@ FFFD;A # So REPLACEMENT CHARACTER 1D200..1D241;N # So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54 1D242..1D244;N # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME 1D245;N # So GREEK MUSICAL LEIMMA +1D2C0..1D2D3;N # No [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN 1D2E0..1D2F3;N # No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN 1D300..1D356;N # So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING 1D360..1D378;N # No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE @@ -2383,11 +2406,14 @@ FFFD;A # So REPLACEMENT CHARACTER 1DF00..1DF09;N # Ll [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK 1DF0A;N # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK 1DF0B..1DF1E;N # Ll [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL +1DF25..1DF2A;N # Ll [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK 1E000..1E006;N # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE 1E008..1E018;N # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU 1E01B..1E021;N # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI 1E023..1E024;N # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS 1E026..1E02A;N # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA +1E030..1E06D;N # Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE +1E08F;N # Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I 1E100..1E12C;N # Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W 1E130..1E136;N # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D 1E137..1E13D;N # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER @@ -2400,6 +2426,10 @@ FFFD;A # So REPLACEMENT CHARACTER 1E2EC..1E2EF;N # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E2F0..1E2F9;N # Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE 1E2FF;N # Sc WANCHO NGUN SIGN +1E4D0..1E4EA;N # Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL +1E4EB;N # Lm NAG MUNDARI SIGN OJOD +1E4EC..1E4EF;N # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH +1E4F0..1E4F9;N # Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE 1E7E0..1E7E6;N # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO 1E7E8..1E7EB;N # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE 1E7ED..1E7EE;N # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE @@ -2528,13 +2558,14 @@ FFFD;A # So REPLACEMENT CHARACTER 1F6D0..1F6D2;W # So [3] PLACE OF WORSHIP..SHOPPING TROLLEY 1F6D3..1F6D4;N # So [2] STUPA..PAGODA 1F6D5..1F6D7;W # So [3] HINDU TEMPLE..ELEVATOR -1F6DD..1F6DF;W # So [3] PLAYGROUND SLIDE..RING BUOY +1F6DC..1F6DF;W # So [4] WIRELESS..RING BUOY 1F6E0..1F6EA;N # So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE 1F6EB..1F6EC;W # So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING 1F6F0..1F6F3;N # So [4] SATELLITE..PASSENGER SHIP 1F6F4..1F6FC;W # So [9] SCOOTER..ROLLER SKATE -1F700..1F773;N # So [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE -1F780..1F7D8;N # So [89] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NEGATIVE CIRCLED SQUARE +1F700..1F776;N # So [119] ALCHEMICAL SYMBOL FOR QUINTESSENCE..LUNAR ECLIPSE +1F77B..1F77F;N # So [5] HAUMEA..ORCUS +1F780..1F7D9;N # So [90] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NINE POINTED WHITE STAR 1F7E0..1F7EB;W # So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE 1F7F0;W # So HEAVY EQUALS SIGN 1F800..1F80B;N # So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD @@ -2551,15 +2582,14 @@ FFFD;A # So REPLACEMENT CHARACTER 1F947..1F9FF;W # So [185] FIRST PLACE MEDAL..NAZAR AMULET 1FA00..1FA53;N # So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP 1FA60..1FA6D;N # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER -1FA70..1FA74;W # So [5] BALLET SHOES..THONG SANDAL -1FA78..1FA7C;W # So [5] DROP OF BLOOD..CRUTCH -1FA80..1FA86;W # So [7] YO-YO..NESTING DOLLS -1FA90..1FAAC;W # So [29] RINGED PLANET..HAMSA -1FAB0..1FABA;W # So [11] FLY..NEST WITH EGGS -1FAC0..1FAC5;W # So [6] ANATOMICAL HEART..PERSON WITH CROWN -1FAD0..1FAD9;W # So [10] BLUEBERRIES..JAR -1FAE0..1FAE7;W # So [8] MELTING FACE..BUBBLES -1FAF0..1FAF6;W # So [7] HAND WITH INDEX FINGER AND THUMB CROSSED..HEART HANDS +1FA70..1FA7C;W # So [13] BALLET SHOES..CRUTCH +1FA80..1FA88;W # So [9] YO-YO..FLUTE +1FA90..1FABD;W # So [46] RINGED PLANET..WING +1FABE;W # Cn +1FABF..1FAC5;W # So [7] GOOSE..PERSON WITH CROWN +1FACE..1FADB;W # So [14] MOOSE..PEA POD +1FAE0..1FAE8;W # So [9] MELTING FACE..SHAKING FACE +1FAF0..1FAF8;W # So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND 1FB00..1FB92;N # So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK 1FB94..1FBCA;N # So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON 1FBF0..1FBF9;N # Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE @@ -2577,7 +2607,9 @@ FFFD;A # So REPLACEMENT CHARACTER 2FA1E..2FA1F;W # Cn [2] .. 2FA20..2FFFD;W # Cn [1502] .. 30000..3134A;W # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A -3134B..3FFFD;W # Cn [60595] .. +3134B..3134F;W # Cn [5] .. +31350..323AF;W # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF +323B0..3FFFD;W # Cn [56398] .. E0001;N # Cf LANGUAGE TAG E0020..E007F;N # Cf [96] TAG SPACE..CANCEL TAG E0100..E01EF;A # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 diff --git a/libc/unicode/isdigit_l.c b/libc/unicode/isdigit_l.c new file mode 100644 index 000000000..ec1ec68e0 --- /dev/null +++ b/libc/unicode/isdigit_l.c @@ -0,0 +1,24 @@ +/*-*- 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 2022 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/str/str.h" +#include "libc/unicode/locale.h" + +int isdigit_l(int c, locale_t l) { + return iswdigit(c); +} diff --git a/libc/unicode/isxdigit_l.c b/libc/unicode/isxdigit_l.c new file mode 100644 index 000000000..b11f4bbc4 --- /dev/null +++ b/libc/unicode/isxdigit_l.c @@ -0,0 +1,24 @@ +/*-*- 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 2022 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/str/str.h" +#include "libc/unicode/locale.h" + +int isxdigit_l(int c, locale_t l) { + return iswxdigit(c); +} diff --git a/libc/unicode/locale.h b/libc/unicode/locale.h index d8f082fbb..81f1ee1ea 100644 --- a/libc/unicode/locale.h +++ b/libc/unicode/locale.h @@ -1,5 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_UNICODE_LOCALE_H_ #define COSMOPOLITAN_LIBC_UNICODE_LOCALE_H_ +#include "libc/fmt/conv.h" #define LC_CTYPE 0 #define LC_NUMERIC 1 @@ -19,7 +20,24 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +struct __locale_struct; +typedef struct __locale_struct *locale_t; + char *setlocale(int, const char *); +locale_t uselocale(locale_t); +locale_t newlocale(int, const char *, locale_t); +long long strtoll_l(const char *, char **, int, locale_t); +unsigned long long strtoull_l(const char *, char **, int, locale_t); +long long wcstoll_l(const wchar_t *, wchar_t **, int, locale_t); +unsigned long long wcstoull_l(const wchar_t *, wchar_t **, int, locale_t); +float strtof_l(const char *, char **, locale_t); +float wcstof_l(const wchar_t *, wchar_t **, locale_t); +double wcstod_l(const wchar_t *, wchar_t **, locale_t); +long double wcstold_l(const wchar_t *, wchar_t **, locale_t); +double strtod_l(const char *, char **, locale_t); +long double strtold_l(const char *, char **, locale_t); +int isxdigit_l(int, locale_t); +int isdigit_l(int, locale_t); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/unicode/unicode-properties.txt b/libc/unicode/unicode-properties.txt index bbd3eaea2..f208c7cfb 100644 --- a/libc/unicode/unicode-properties.txt +++ b/libc/unicode/unicode-properties.txt @@ -28,3 +28,10 @@ Cf = Other, format Cs = Other, surrogate Co = Other, private use Cn = Other, not assigned (including noncharacters) + +W Wide Naturally wide character, e.g. Hiragana. +Na Narrow Naturally narrow character, e.g. ISO Basic Latin alphabet. +F Fullwidth Wide variant with compatibility normalisation to naturally narrow character, e.g. fullwidth Latin script. +H Halfwidth Narrow variant with compatibility normalisation to naturally wide character, e.g. half-width kana. Includes U+20A9 (₩) as an exception. +A Ambiguous Characters included in East Asian DBCS codes but also in European SBCS codes, e.g. Greek alphabet. Duospaced behaviour can consequently vary. +N Neutral Characters which do not appear in East Asian DBCS codes, e.g. Devanagari. diff --git a/libc/unicode/unicodedata.txt b/libc/unicode/unicodedata.txt index b5abef7ed..6a2e57ff2 100644 --- a/libc/unicode/unicodedata.txt +++ b/libc/unicode/unicodedata.txt @@ -2975,6 +2975,7 @@ 0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; 0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +0CF3;KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT;Mc;0;L;;;;;N;;;;; 0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;; 0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; @@ -3339,6 +3340,7 @@ 0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;; 0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;; 0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;; +0ECE;LAO YAMAKKAN;Mn;0;NSM;;;;;N;;;;; 0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -19393,6 +19395,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10EAD;YEZIDI HYPHENATION MARK;Pd;0;R;;;;;N;;;;; 10EB0;YEZIDI LETTER LAM WITH DOT ABOVE;Lo;0;R;;;;;N;;;;; 10EB1;YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE;Lo;0;R;;;;;N;;;;; +10EFD;ARABIC SMALL LOW WORD SAKTA;Mn;220;NSM;;;;;N;;;;; +10EFE;ARABIC SMALL LOW WORD QASR;Mn;220;NSM;;;;;N;;;;; +10EFF;ARABIC SMALL LOW WORD MADDA;Mn;220;NSM;;;;;N;;;;; 10F00;OLD SOGDIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; 10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;; 10F02;OLD SOGDIAN LETTER BETH;Lo;0;R;;;;;N;;;;; @@ -20058,6 +20063,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1123C;KHOJKI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;; 1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 1123E;KHOJKI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;; +1123F;KHOJKI LETTER QA;Lo;0;L;;;;;N;;;;; +11240;KHOJKI LETTER SHORT I;Lo;0;L;;;;;N;;;;; +11241;KHOJKI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; 11280;MULTANI LETTER A;Lo;0;L;;;;;N;;;;; 11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;; 11282;MULTANI LETTER U;Lo;0;L;;;;;N;;;;; @@ -21256,6 +21264,16 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11AF6;PAU CIN HAU LOW-FALLING TONE LONG FINAL;Lo;0;L;;;;;N;;;;; 11AF7;PAU CIN HAU LOW-FALLING TONE FINAL;Lo;0;L;;;;;N;;;;; 11AF8;PAU CIN HAU GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;; +11B00;DEVANAGARI HEAD MARK;Po;0;L;;;;;N;;;;; +11B01;DEVANAGARI HEAD MARK WITH HEADSTROKE;Po;0;L;;;;;N;;;;; +11B02;DEVANAGARI SIGN BHALE;Po;0;L;;;;;N;;;;; +11B03;DEVANAGARI SIGN BHALE WITH HOOK;Po;0;L;;;;;N;;;;; +11B04;DEVANAGARI SIGN EXTENDED BHALE;Po;0;L;;;;;N;;;;; +11B05;DEVANAGARI SIGN EXTENDED BHALE WITH HOOK;Po;0;L;;;;;N;;;;; +11B06;DEVANAGARI SIGN WESTERN FIVE-LIKE BHALE;Po;0;L;;;;;N;;;;; +11B07;DEVANAGARI SIGN WESTERN NINE-LIKE BHALE;Po;0;L;;;;;N;;;;; +11B08;DEVANAGARI SIGN REVERSED NINE-LIKE BHALE;Po;0;L;;;;;N;;;;; +11B09;DEVANAGARI SIGN MINDU;Po;0;L;;;;;N;;;;; 11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;; 11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;; 11C02;BHAIKSUKI LETTER I;Lo;0;L;;;;;N;;;;; @@ -21584,6 +21602,92 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;; 11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;; 11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;; +11F00;KAWI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11F01;KAWI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11F02;KAWI SIGN REPHA;Lo;0;L;;;;;N;;;;; +11F03;KAWI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11F04;KAWI LETTER A;Lo;0;L;;;;;N;;;;; +11F05;KAWI LETTER AA;Lo;0;L;;;;;N;;;;; +11F06;KAWI LETTER I;Lo;0;L;;;;;N;;;;; +11F07;KAWI LETTER II;Lo;0;L;;;;;N;;;;; +11F08;KAWI LETTER U;Lo;0;L;;;;;N;;;;; +11F09;KAWI LETTER UU;Lo;0;L;;;;;N;;;;; +11F0A;KAWI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +11F0B;KAWI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +11F0C;KAWI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +11F0D;KAWI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +11F0E;KAWI LETTER E;Lo;0;L;;;;;N;;;;; +11F0F;KAWI LETTER AI;Lo;0;L;;;;;N;;;;; +11F10;KAWI LETTER O;Lo;0;L;;;;;N;;;;; +11F12;KAWI LETTER KA;Lo;0;L;;;;;N;;;;; +11F13;KAWI LETTER KHA;Lo;0;L;;;;;N;;;;; +11F14;KAWI LETTER GA;Lo;0;L;;;;;N;;;;; +11F15;KAWI LETTER GHA;Lo;0;L;;;;;N;;;;; +11F16;KAWI LETTER NGA;Lo;0;L;;;;;N;;;;; +11F17;KAWI LETTER CA;Lo;0;L;;;;;N;;;;; +11F18;KAWI LETTER CHA;Lo;0;L;;;;;N;;;;; +11F19;KAWI LETTER JA;Lo;0;L;;;;;N;;;;; +11F1A;KAWI LETTER JHA;Lo;0;L;;;;;N;;;;; +11F1B;KAWI LETTER NYA;Lo;0;L;;;;;N;;;;; +11F1C;KAWI LETTER TTA;Lo;0;L;;;;;N;;;;; +11F1D;KAWI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11F1E;KAWI LETTER DDA;Lo;0;L;;;;;N;;;;; +11F1F;KAWI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11F20;KAWI LETTER NNA;Lo;0;L;;;;;N;;;;; +11F21;KAWI LETTER TA;Lo;0;L;;;;;N;;;;; +11F22;KAWI LETTER THA;Lo;0;L;;;;;N;;;;; +11F23;KAWI LETTER DA;Lo;0;L;;;;;N;;;;; +11F24;KAWI LETTER DHA;Lo;0;L;;;;;N;;;;; +11F25;KAWI LETTER NA;Lo;0;L;;;;;N;;;;; +11F26;KAWI LETTER PA;Lo;0;L;;;;;N;;;;; +11F27;KAWI LETTER PHA;Lo;0;L;;;;;N;;;;; +11F28;KAWI LETTER BA;Lo;0;L;;;;;N;;;;; +11F29;KAWI LETTER BHA;Lo;0;L;;;;;N;;;;; +11F2A;KAWI LETTER MA;Lo;0;L;;;;;N;;;;; +11F2B;KAWI LETTER YA;Lo;0;L;;;;;N;;;;; +11F2C;KAWI LETTER RA;Lo;0;L;;;;;N;;;;; +11F2D;KAWI LETTER LA;Lo;0;L;;;;;N;;;;; +11F2E;KAWI LETTER WA;Lo;0;L;;;;;N;;;;; +11F2F;KAWI LETTER SHA;Lo;0;L;;;;;N;;;;; +11F30;KAWI LETTER SSA;Lo;0;L;;;;;N;;;;; +11F31;KAWI LETTER SA;Lo;0;L;;;;;N;;;;; +11F32;KAWI LETTER HA;Lo;0;L;;;;;N;;;;; +11F33;KAWI LETTER JNYA;Lo;0;L;;;;;N;;;;; +11F34;KAWI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11F35;KAWI VOWEL SIGN ALTERNATE AA;Mc;0;L;;;;;N;;;;; +11F36;KAWI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11F37;KAWI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +11F38;KAWI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11F39;KAWI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +11F3A;KAWI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11F3E;KAWI VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +11F3F;KAWI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +11F40;KAWI VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;; +11F41;KAWI SIGN KILLER;Mc;9;L;;;;;N;;;;; +11F42;KAWI CONJOINER;Mn;9;NSM;;;;;N;;;;; +11F43;KAWI DANDA;Po;0;L;;;;;N;;;;; +11F44;KAWI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +11F45;KAWI PUNCTUATION SECTION MARKER;Po;0;L;;;;;N;;;;; +11F46;KAWI PUNCTUATION ALTERNATE SECTION MARKER;Po;0;L;;;;;N;;;;; +11F47;KAWI PUNCTUATION FLOWER;Po;0;L;;;;;N;;;;; +11F48;KAWI PUNCTUATION SPACE FILLER;Po;0;L;;;;;N;;;;; +11F49;KAWI PUNCTUATION DOT;Po;0;L;;;;;N;;;;; +11F4A;KAWI PUNCTUATION DOUBLE DOT;Po;0;L;;;;;N;;;;; +11F4B;KAWI PUNCTUATION TRIPLE DOT;Po;0;L;;;;;N;;;;; +11F4C;KAWI PUNCTUATION CIRCLE;Po;0;L;;;;;N;;;;; +11F4D;KAWI PUNCTUATION FILLED CIRCLE;Po;0;L;;;;;N;;;;; +11F4E;KAWI PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;; +11F4F;KAWI PUNCTUATION CLOSING SPIRAL;Po;0;L;;;;;N;;;;; +11F50;KAWI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11F51;KAWI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11F52;KAWI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11F53;KAWI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11F54;KAWI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11F55;KAWI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11F56;KAWI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11F57;KAWI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11F58;KAWI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11F59;KAWI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 11FB0;LISU LETTER YHA;Lo;0;L;;;;;N;;;;; 11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;; 11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;; @@ -24040,6 +24144,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;; 1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;; 1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;; +1342F;EGYPTIAN HIEROGLYPH V011D;Lo;0;L;;;;;N;;;;; 13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;; 13431;EGYPTIAN HIEROGLYPH HORIZONTAL JOINER;Cf;0;L;;;;;N;;;;; 13432;EGYPTIAN HIEROGLYPH INSERT AT TOP START;Cf;0;L;;;;;N;;;;; @@ -24049,6 +24154,35 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;; 13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;; 13438;EGYPTIAN HIEROGLYPH END SEGMENT;Cf;0;L;;;;;N;;;;; +13439;EGYPTIAN HIEROGLYPH INSERT AT MIDDLE;Cf;0;L;;;;;N;;;;; +1343A;EGYPTIAN HIEROGLYPH INSERT AT TOP;Cf;0;L;;;;;N;;;;; +1343B;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM;Cf;0;L;;;;;N;;;;; +1343C;EGYPTIAN HIEROGLYPH BEGIN ENCLOSURE;Cf;0;L;;;;;N;;;;; +1343D;EGYPTIAN HIEROGLYPH END ENCLOSURE;Cf;0;L;;;;;N;;;;; +1343E;EGYPTIAN HIEROGLYPH BEGIN WALLED ENCLOSURE;Cf;0;L;;;;;N;;;;; +1343F;EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE;Cf;0;L;;;;;N;;;;; +13440;EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY;Cf;0;L;;;;;N;;;;; +13441;EGYPTIAN HIEROGLYPH FULL BLANK;Lo;0;L;;;;;N;;;;; +13442;EGYPTIAN HIEROGLYPH HALF BLANK;Lo;0;L;;;;;N;;;;; +13443;EGYPTIAN HIEROGLYPH LOST SIGN;Lo;0;L;;;;;N;;;;; +13444;EGYPTIAN HIEROGLYPH HALF LOST SIGN;Lo;0;L;;;;;N;;;;; +13445;EGYPTIAN HIEROGLYPH TALL LOST SIGN;Lo;0;L;;;;;N;;;;; +13446;EGYPTIAN HIEROGLYPH WIDE LOST SIGN;Lo;0;L;;;;;N;;;;; +13447;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START;Mn;0;NSM;;;;;N;;;;; +13448;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM START;Mn;0;NSM;;;;;N;;;;; +13449;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START;Mn;0;NSM;;;;;N;;;;; +1344A;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP END;Mn;0;NSM;;;;;N;;;;; +1344B;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP;Mn;0;NSM;;;;;N;;;;; +1344C;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM START AND TOP END;Mn;0;NSM;;;;;N;;;;; +1344D;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START AND TOP;Mn;0;NSM;;;;;N;;;;; +1344E;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM END;Mn;0;NSM;;;;;N;;;;; +1344F;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START AND BOTTOM END;Mn;0;NSM;;;;;N;;;;; +13450;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM;Mn;0;NSM;;;;;N;;;;; +13451;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START AND BOTTOM;Mn;0;NSM;;;;;N;;;;; +13452;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT END;Mn;0;NSM;;;;;N;;;;; +13453;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP AND END;Mn;0;NSM;;;;;N;;;;; +13454;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM AND END;Mn;0;NSM;;;;;N;;;;; +13455;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED;Mn;0;NSM;;;;;N;;;;; 14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; 14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; 14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; @@ -27289,9 +27423,11 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1B120;KATAKANA LETTER ARCHAIC YI;Lo;0;L;;;;;N;;;;; 1B121;KATAKANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;; 1B122;KATAKANA LETTER ARCHAIC WU;Lo;0;L;;;;;N;;;;; +1B132;HIRAGANA LETTER SMALL KO;Lo;0;L;;;;;N;;;;; 1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; 1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; 1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; +1B155;KATAKANA LETTER SMALL KO;Lo;0;L;;;;;N;;;;; 1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; 1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; 1B166;KATAKANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; @@ -28573,6 +28709,26 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;; 1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;; 1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;; +1D2C0;KAKTOVIK NUMERAL ZERO;No;0;ON;;;;0;N;;;;; +1D2C1;KAKTOVIK NUMERAL ONE;No;0;ON;;;;1;N;;;;; +1D2C2;KAKTOVIK NUMERAL TWO;No;0;ON;;;;2;N;;;;; +1D2C3;KAKTOVIK NUMERAL THREE;No;0;ON;;;;3;N;;;;; +1D2C4;KAKTOVIK NUMERAL FOUR;No;0;ON;;;;4;N;;;;; +1D2C5;KAKTOVIK NUMERAL FIVE;No;0;ON;;;;5;N;;;;; +1D2C6;KAKTOVIK NUMERAL SIX;No;0;ON;;;;6;N;;;;; +1D2C7;KAKTOVIK NUMERAL SEVEN;No;0;ON;;;;7;N;;;;; +1D2C8;KAKTOVIK NUMERAL EIGHT;No;0;ON;;;;8;N;;;;; +1D2C9;KAKTOVIK NUMERAL NINE;No;0;ON;;;;9;N;;;;; +1D2CA;KAKTOVIK NUMERAL TEN;No;0;ON;;;;10;N;;;;; +1D2CB;KAKTOVIK NUMERAL ELEVEN;No;0;ON;;;;11;N;;;;; +1D2CC;KAKTOVIK NUMERAL TWELVE;No;0;ON;;;;12;N;;;;; +1D2CD;KAKTOVIK NUMERAL THIRTEEN;No;0;ON;;;;13;N;;;;; +1D2CE;KAKTOVIK NUMERAL FOURTEEN;No;0;ON;;;;14;N;;;;; +1D2CF;KAKTOVIK NUMERAL FIFTEEN;No;0;ON;;;;15;N;;;;; +1D2D0;KAKTOVIK NUMERAL SIXTEEN;No;0;ON;;;;16;N;;;;; +1D2D1;KAKTOVIK NUMERAL SEVENTEEN;No;0;ON;;;;17;N;;;;; +1D2D2;KAKTOVIK NUMERAL EIGHTEEN;No;0;ON;;;;18;N;;;;; +1D2D3;KAKTOVIK NUMERAL NINETEEN;No;0;ON;;;;19;N;;;;; 1D2E0;MAYAN NUMERAL ZERO;No;0;L;;;;0;N;;;;; 1D2E1;MAYAN NUMERAL ONE;No;0;L;;;;1;N;;;;; 1D2E2;MAYAN NUMERAL TWO;No;0;L;;;;2;N;;;;; @@ -30404,6 +30560,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1DF1C;LATIN SMALL LETTER TESH DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; 1DF1D;LATIN SMALL LETTER C WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; 1DF1E;LATIN SMALL LETTER S WITH CURL;Ll;0;L;;;;;N;;;;; +1DF25;LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;; +1DF26;LATIN SMALL LETTER L WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;; +1DF27;LATIN SMALL LETTER N WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;; +1DF28;LATIN SMALL LETTER R WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;; +1DF29;LATIN SMALL LETTER S WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;; +1DF2A;LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;; 1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;; 1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;; 1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;; @@ -30442,6 +30604,69 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;; 1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;; 1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;; +1E030;MODIFIER LETTER CYRILLIC SMALL A;Lm;0;L; 0430;;;;N;;;;; +1E031;MODIFIER LETTER CYRILLIC SMALL BE;Lm;0;L; 0431;;;;N;;;;; +1E032;MODIFIER LETTER CYRILLIC SMALL VE;Lm;0;L; 0432;;;;N;;;;; +1E033;MODIFIER LETTER CYRILLIC SMALL GHE;Lm;0;L; 0433;;;;N;;;;; +1E034;MODIFIER LETTER CYRILLIC SMALL DE;Lm;0;L; 0434;;;;N;;;;; +1E035;MODIFIER LETTER CYRILLIC SMALL IE;Lm;0;L; 0435;;;;N;;;;; +1E036;MODIFIER LETTER CYRILLIC SMALL ZHE;Lm;0;L; 0436;;;;N;;;;; +1E037;MODIFIER LETTER CYRILLIC SMALL ZE;Lm;0;L; 0437;;;;N;;;;; +1E038;MODIFIER LETTER CYRILLIC SMALL I;Lm;0;L; 0438;;;;N;;;;; +1E039;MODIFIER LETTER CYRILLIC SMALL KA;Lm;0;L; 043A;;;;N;;;;; +1E03A;MODIFIER LETTER CYRILLIC SMALL EL;Lm;0;L; 043B;;;;N;;;;; +1E03B;MODIFIER LETTER CYRILLIC SMALL EM;Lm;0;L; 043C;;;;N;;;;; +1E03C;MODIFIER LETTER CYRILLIC SMALL O;Lm;0;L; 043E;;;;N;;;;; +1E03D;MODIFIER LETTER CYRILLIC SMALL PE;Lm;0;L; 043F;;;;N;;;;; +1E03E;MODIFIER LETTER CYRILLIC SMALL ER;Lm;0;L; 0440;;;;N;;;;; +1E03F;MODIFIER LETTER CYRILLIC SMALL ES;Lm;0;L; 0441;;;;N;;;;; +1E040;MODIFIER LETTER CYRILLIC SMALL TE;Lm;0;L; 0442;;;;N;;;;; +1E041;MODIFIER LETTER CYRILLIC SMALL U;Lm;0;L; 0443;;;;N;;;;; +1E042;MODIFIER LETTER CYRILLIC SMALL EF;Lm;0;L; 0444;;;;N;;;;; +1E043;MODIFIER LETTER CYRILLIC SMALL HA;Lm;0;L; 0445;;;;N;;;;; +1E044;MODIFIER LETTER CYRILLIC SMALL TSE;Lm;0;L; 0446;;;;N;;;;; +1E045;MODIFIER LETTER CYRILLIC SMALL CHE;Lm;0;L; 0447;;;;N;;;;; +1E046;MODIFIER LETTER CYRILLIC SMALL SHA;Lm;0;L; 0448;;;;N;;;;; +1E047;MODIFIER LETTER CYRILLIC SMALL YERU;Lm;0;L; 044B;;;;N;;;;; +1E048;MODIFIER LETTER CYRILLIC SMALL E;Lm;0;L; 044D;;;;N;;;;; +1E049;MODIFIER LETTER CYRILLIC SMALL YU;Lm;0;L; 044E;;;;N;;;;; +1E04A;MODIFIER LETTER CYRILLIC SMALL DZZE;Lm;0;L; A689;;;;N;;;;; +1E04B;MODIFIER LETTER CYRILLIC SMALL SCHWA;Lm;0;L; 04D9;;;;N;;;;; +1E04C;MODIFIER LETTER CYRILLIC SMALL BYELORUSSIAN-UKRAINIAN I;Lm;0;L; 0456;;;;N;;;;; +1E04D;MODIFIER LETTER CYRILLIC SMALL JE;Lm;0;L; 0458;;;;N;;;;; +1E04E;MODIFIER LETTER CYRILLIC SMALL BARRED O;Lm;0;L; 04D9;;;;N;;;;; +1E04F;MODIFIER LETTER CYRILLIC SMALL STRAIGHT U;Lm;0;L; 04AF;;;;N;;;;; +1E050;MODIFIER LETTER CYRILLIC SMALL PALOCHKA;Lm;0;L; 04CF;;;;N;;;;; +1E051;CYRILLIC SUBSCRIPT SMALL LETTER A;Lm;0;L; 0430;;;;N;;;;; +1E052;CYRILLIC SUBSCRIPT SMALL LETTER BE;Lm;0;L; 0431;;;;N;;;;; +1E053;CYRILLIC SUBSCRIPT SMALL LETTER VE;Lm;0;L; 0432;;;;N;;;;; +1E054;CYRILLIC SUBSCRIPT SMALL LETTER GHE;Lm;0;L; 0433;;;;N;;;;; +1E055;CYRILLIC SUBSCRIPT SMALL LETTER DE;Lm;0;L; 0434;;;;N;;;;; +1E056;CYRILLIC SUBSCRIPT SMALL LETTER IE;Lm;0;L; 0435;;;;N;;;;; +1E057;CYRILLIC SUBSCRIPT SMALL LETTER ZHE;Lm;0;L; 0436;;;;N;;;;; +1E058;CYRILLIC SUBSCRIPT SMALL LETTER ZE;Lm;0;L; 0437;;;;N;;;;; +1E059;CYRILLIC SUBSCRIPT SMALL LETTER I;Lm;0;L; 0438;;;;N;;;;; +1E05A;CYRILLIC SUBSCRIPT SMALL LETTER KA;Lm;0;L; 043A;;;;N;;;;; +1E05B;CYRILLIC SUBSCRIPT SMALL LETTER EL;Lm;0;L; 043B;;;;N;;;;; +1E05C;CYRILLIC SUBSCRIPT SMALL LETTER O;Lm;0;L; 043E;;;;N;;;;; +1E05D;CYRILLIC SUBSCRIPT SMALL LETTER PE;Lm;0;L; 043F;;;;N;;;;; +1E05E;CYRILLIC SUBSCRIPT SMALL LETTER ES;Lm;0;L; 0441;;;;N;;;;; +1E05F;CYRILLIC SUBSCRIPT SMALL LETTER U;Lm;0;L; 0443;;;;N;;;;; +1E060;CYRILLIC SUBSCRIPT SMALL LETTER EF;Lm;0;L; 0444;;;;N;;;;; +1E061;CYRILLIC SUBSCRIPT SMALL LETTER HA;Lm;0;L; 0445;;;;N;;;;; +1E062;CYRILLIC SUBSCRIPT SMALL LETTER TSE;Lm;0;L; 0446;;;;N;;;;; +1E063;CYRILLIC SUBSCRIPT SMALL LETTER CHE;Lm;0;L; 0447;;;;N;;;;; +1E064;CYRILLIC SUBSCRIPT SMALL LETTER SHA;Lm;0;L; 0448;;;;N;;;;; +1E065;CYRILLIC SUBSCRIPT SMALL LETTER HARD SIGN;Lm;0;L; 044A;;;;N;;;;; +1E066;CYRILLIC SUBSCRIPT SMALL LETTER YERU;Lm;0;L; 044B;;;;N;;;;; +1E067;CYRILLIC SUBSCRIPT SMALL LETTER GHE WITH UPTURN;Lm;0;L; 0491;;;;N;;;;; +1E068;CYRILLIC SUBSCRIPT SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Lm;0;L; 0456;;;;N;;;;; +1E069;CYRILLIC SUBSCRIPT SMALL LETTER DZE;Lm;0;L; 0455;;;;N;;;;; +1E06A;CYRILLIC SUBSCRIPT SMALL LETTER DZHE;Lm;0;L; 045F;;;;N;;;;; +1E06B;MODIFIER LETTER CYRILLIC SMALL ES WITH DESCENDER;Lm;0;L; 04AB;;;;N;;;;; +1E06C;MODIFIER LETTER CYRILLIC SMALL YERU WITH BACK YER;Lm;0;L; A651;;;;N;;;;; +1E06D;MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE;Lm;0;L; 04B1;;;;N;;;;; +1E08F;COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Mn;230;NSM;;;;;N;;;;; 1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;; 1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;; 1E102;NYIAKENG PUACHUE HMONG LETTER NTA;Lo;0;L;;;;;N;;;;; @@ -30603,6 +30828,48 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;; +1E4D0;NAG MUNDARI LETTER O;Lo;0;L;;;;;N;;;;; +1E4D1;NAG MUNDARI LETTER OP;Lo;0;L;;;;;N;;;;; +1E4D2;NAG MUNDARI LETTER OL;Lo;0;L;;;;;N;;;;; +1E4D3;NAG MUNDARI LETTER OY;Lo;0;L;;;;;N;;;;; +1E4D4;NAG MUNDARI LETTER ONG;Lo;0;L;;;;;N;;;;; +1E4D5;NAG MUNDARI LETTER A;Lo;0;L;;;;;N;;;;; +1E4D6;NAG MUNDARI LETTER AJ;Lo;0;L;;;;;N;;;;; +1E4D7;NAG MUNDARI LETTER AB;Lo;0;L;;;;;N;;;;; +1E4D8;NAG MUNDARI LETTER ANY;Lo;0;L;;;;;N;;;;; +1E4D9;NAG MUNDARI LETTER AH;Lo;0;L;;;;;N;;;;; +1E4DA;NAG MUNDARI LETTER I;Lo;0;L;;;;;N;;;;; +1E4DB;NAG MUNDARI LETTER IS;Lo;0;L;;;;;N;;;;; +1E4DC;NAG MUNDARI LETTER IDD;Lo;0;L;;;;;N;;;;; +1E4DD;NAG MUNDARI LETTER IT;Lo;0;L;;;;;N;;;;; +1E4DE;NAG MUNDARI LETTER IH;Lo;0;L;;;;;N;;;;; +1E4DF;NAG MUNDARI LETTER U;Lo;0;L;;;;;N;;;;; +1E4E0;NAG MUNDARI LETTER UC;Lo;0;L;;;;;N;;;;; +1E4E1;NAG MUNDARI LETTER UD;Lo;0;L;;;;;N;;;;; +1E4E2;NAG MUNDARI LETTER UK;Lo;0;L;;;;;N;;;;; +1E4E3;NAG MUNDARI LETTER UR;Lo;0;L;;;;;N;;;;; +1E4E4;NAG MUNDARI LETTER E;Lo;0;L;;;;;N;;;;; +1E4E5;NAG MUNDARI LETTER ENN;Lo;0;L;;;;;N;;;;; +1E4E6;NAG MUNDARI LETTER EG;Lo;0;L;;;;;N;;;;; +1E4E7;NAG MUNDARI LETTER EM;Lo;0;L;;;;;N;;;;; +1E4E8;NAG MUNDARI LETTER EN;Lo;0;L;;;;;N;;;;; +1E4E9;NAG MUNDARI LETTER ETT;Lo;0;L;;;;;N;;;;; +1E4EA;NAG MUNDARI LETTER ELL;Lo;0;L;;;;;N;;;;; +1E4EB;NAG MUNDARI SIGN OJOD;Lm;0;L;;;;;N;;;;; +1E4EC;NAG MUNDARI SIGN MUHOR;Mn;232;NSM;;;;;N;;;;; +1E4ED;NAG MUNDARI SIGN TOYOR;Mn;232;NSM;;;;;N;;;;; +1E4EE;NAG MUNDARI SIGN IKIR;Mn;220;NSM;;;;;N;;;;; +1E4EF;NAG MUNDARI SIGN SUTUH;Mn;230;NSM;;;;;N;;;;; +1E4F0;NAG MUNDARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1E4F1;NAG MUNDARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1E4F2;NAG MUNDARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1E4F3;NAG MUNDARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1E4F4;NAG MUNDARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1E4F5;NAG MUNDARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1E4F6;NAG MUNDARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1E4F7;NAG MUNDARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1E4F8;NAG MUNDARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1E4F9;NAG MUNDARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 1E7E0;ETHIOPIC SYLLABLE HHYA;Lo;0;L;;;;;N;;;;; 1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;; 1E7E2;ETHIOPIC SYLLABLE HHYI;Lo;0;L;;;;;N;;;;; @@ -32678,6 +32945,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;; 1F6D6;HUT;So;0;ON;;;;;N;;;;; 1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;; +1F6DC;WIRELESS;So;0;ON;;;;;N;;;;; 1F6DD;PLAYGROUND SLIDE;So;0;ON;;;;;N;;;;; 1F6DE;WHEEL;So;0;ON;;;;;N;;;;; 1F6DF;RING BUOY;So;0;ON;;;;;N;;;;; @@ -32823,6 +33091,14 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;; 1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;; 1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;So;0;ON;;;;;N;;;;; +1F774;LOT OF FORTUNE;So;0;ON;;;;;N;;;;; +1F775;OCCULTATION;So;0;ON;;;;;N;;;;; +1F776;LUNAR ECLIPSE;So;0;ON;;;;;N;;;;; +1F77B;HAUMEA;So;0;ON;;;;;N;;;;; +1F77C;MAKEMAKE;So;0;ON;;;;;N;;;;; +1F77D;GONGGONG;So;0;ON;;;;;N;;;;; +1F77E;QUAOAR;So;0;ON;;;;;N;;;;; +1F77F;ORCUS;So;0;ON;;;;;N;;;;; 1F780;BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; 1F781;BLACK UP-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; 1F782;BLACK RIGHT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; @@ -32912,6 +33188,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;; 1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;; 1F7D8;NEGATIVE CIRCLED SQUARE;So;0;ON;;;;;N;;;;; +1F7D9;NINE POINTED WHITE STAR;So;0;ON;;;;;N;;;;; 1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;; 1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;; 1F7E2;LARGE GREEN CIRCLE;So;0;ON;;;;;N;;;;; @@ -33434,6 +33711,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FA72;BRIEFS;So;0;ON;;;;;N;;;;; 1FA73;SHORTS;So;0;ON;;;;;N;;;;; 1FA74;THONG SANDAL;So;0;ON;;;;;N;;;;; +1FA75;LIGHT BLUE HEART;So;0;ON;;;;;N;;;;; +1FA76;GREY HEART;So;0;ON;;;;;N;;;;; +1FA77;PINK HEART;So;0;ON;;;;;N;;;;; 1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;; 1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;; 1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;; @@ -33446,6 +33726,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FA84;MAGIC WAND;So;0;ON;;;;;N;;;;; 1FA85;PINATA;So;0;ON;;;;;N;;;;; 1FA86;NESTING DOLLS;So;0;ON;;;;;N;;;;; +1FA87;MARACAS;So;0;ON;;;;;N;;;;; +1FA88;FLUTE;So;0;ON;;;;;N;;;;; 1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;; 1FA91;CHAIR;So;0;ON;;;;;N;;;;; 1FA92;RAZOR;So;0;ON;;;;;N;;;;; @@ -33475,6 +33757,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAAA;IDENTIFICATION CARD;So;0;ON;;;;;N;;;;; 1FAAB;LOW BATTERY;So;0;ON;;;;;N;;;;; 1FAAC;HAMSA;So;0;ON;;;;;N;;;;; +1FAAD;FOLDING HAND FAN;So;0;ON;;;;;N;;;;; +1FAAE;HAIR PICK;So;0;ON;;;;;N;;;;; +1FAAF;KHANDA;So;0;ON;;;;;N;;;;; 1FAB0;FLY;So;0;ON;;;;;N;;;;; 1FAB1;WORM;So;0;ON;;;;;N;;;;; 1FAB2;BEETLE;So;0;ON;;;;;N;;;;; @@ -33486,12 +33771,18 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAB8;CORAL;So;0;ON;;;;;N;;;;; 1FAB9;EMPTY NEST;So;0;ON;;;;;N;;;;; 1FABA;NEST WITH EGGS;So;0;ON;;;;;N;;;;; +1FABB;HYACINTH;So;0;ON;;;;;N;;;;; +1FABC;JELLYFISH;So;0;ON;;;;;N;;;;; +1FABD;WING;So;0;ON;;;;;N;;;;; +1FABF;GOOSE;So;0;ON;;;;;N;;;;; 1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;; 1FAC1;LUNGS;So;0;ON;;;;;N;;;;; 1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;; 1FAC3;PREGNANT MAN;So;0;ON;;;;;N;;;;; 1FAC4;PREGNANT PERSON;So;0;ON;;;;;N;;;;; 1FAC5;PERSON WITH CROWN;So;0;ON;;;;;N;;;;; +1FACE;MOOSE;So;0;ON;;;;;N;;;;; +1FACF;DONKEY;So;0;ON;;;;;N;;;;; 1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;; 1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;; 1FAD2;OLIVE;So;0;ON;;;;;N;;;;; @@ -33502,6 +33793,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAD7;POURING LIQUID;So;0;ON;;;;;N;;;;; 1FAD8;BEANS;So;0;ON;;;;;N;;;;; 1FAD9;JAR;So;0;ON;;;;;N;;;;; +1FADA;GINGER ROOT;So;0;ON;;;;;N;;;;; +1FADB;PEA POD;So;0;ON;;;;;N;;;;; 1FAE0;MELTING FACE;So;0;ON;;;;;N;;;;; 1FAE1;SALUTING FACE;So;0;ON;;;;;N;;;;; 1FAE2;FACE WITH OPEN EYES AND HAND OVER MOUTH;So;0;ON;;;;;N;;;;; @@ -33510,6 +33803,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAE5;DOTTED LINE FACE;So;0;ON;;;;;N;;;;; 1FAE6;BITING LIP;So;0;ON;;;;;N;;;;; 1FAE7;BUBBLES;So;0;ON;;;;;N;;;;; +1FAE8;SHAKING FACE;So;0;ON;;;;;N;;;;; 1FAF0;HAND WITH INDEX FINGER AND THUMB CROSSED;So;0;ON;;;;;N;;;;; 1FAF1;RIGHTWARDS HAND;So;0;ON;;;;;N;;;;; 1FAF2;LEFTWARDS HAND;So;0;ON;;;;;N;;;;; @@ -33517,6 +33811,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAF4;PALM UP HAND;So;0;ON;;;;;N;;;;; 1FAF5;INDEX POINTING AT THE VIEWER;So;0;ON;;;;;N;;;;; 1FAF6;HEART HANDS;So;0;ON;;;;;N;;;;; +1FAF7;LEFTWARDS PUSHING HAND;So;0;ON;;;;;N;;;;; +1FAF8;RIGHTWARDS PUSHING HAND;So;0;ON;;;;;N;;;;; 1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;; 1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;; 1FB02;BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;; @@ -34283,6 +34579,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;; 30000;;Lo;0;L;;;;;N;;;;; 3134A;;Lo;0;L;;;;;N;;;;; +31350;;Lo;0;L;;;;;N;;;;; +323AF;;Lo;0;L;;;;;N;;;;; E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;; E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;; E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;; diff --git a/libc/x/makedirs.c b/libc/x/makedirs.c index 05e3e0a9d..1d3fd2eb8 100644 --- a/libc/x/makedirs.c +++ b/libc/x/makedirs.c @@ -16,12 +16,36 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.internal.h" +#include "libc/bits/weaken.h" #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" #include "libc/errno.h" +#include "libc/log/log.h" #include "libc/mem/mem.h" #include "libc/str/str.h" #include "libc/x/x.h" +static int MakeDirs(const char *path, unsigned mode, int e) { + int rc; + char *dir; + if (mkdir(path, mode) != -1) { + errno = e; + return 0; + } + if (errno != ENOENT) return -1; + dir = xdirname(path); + if (strcmp(dir, path)) { + rc = MakeDirs(dir, mode, e); + } else { + rc = -1; + } + free(dir); + if (rc == -1) return -1; + errno = e; + return mkdir(path, mode); +} + /** * Recursively creates directory a.k.a. folder. * @@ -31,19 +55,5 @@ * @see mkdir() */ int makedirs(const char *path, unsigned mode) { - int e, rc; - char *dir; - e = errno; - if (mkdir(path, mode) != -1) return 0; - if (errno != ENOENT) return -1; - dir = xdirname(path); - if (strcmp(dir, path)) { - rc = makedirs(dir, mode); - } else { - rc = -1; - } - free(dir); - if (rc == -1) return -1; - errno = e; - return mkdir(path, mode); + return MakeDirs(path, mode, errno); } diff --git a/libc/x/x.h b/libc/x/x.h index 3166a0bb5..a904caa93 100644 --- a/libc/x/x.h +++ b/libc/x/x.h @@ -14,7 +14,7 @@ COSMOPOLITAN_C_START_ Standard Library veneers for folks not building embedded RTOS */ #define _XPNN paramsnonnull() -#define _XRET nothrow nocallback nodiscard returnsnonnull +#define _XRET dontthrow nocallback dontdiscard returnsnonnull #define _XMAL returnspointerwithnoaliases _XRET #define _XMALPG returnsaligned((PAGESIZE)) _XMAL @@ -38,7 +38,7 @@ char *xvasprintf(const char *, va_list) _XPNN _XMAL; char *xgetline(struct FILE *) _XPNN mallocesque; void *xmalloc(size_t) attributeallocsize((1)) _XMAL; void *xrealloc(void *, size_t) - attributeallocsize((2)) nothrow nocallback nodiscard; + attributeallocsize((2)) dontthrow nocallback dontdiscard; void *xcalloc(size_t, size_t) attributeallocsize((1, 2)) _XMAL; void *xvalloc(size_t) attributeallocsize((1)) _XMALPG; void *xmemalign(size_t, size_t) attributeallocalign((1)) @@ -52,13 +52,13 @@ char *xstrmul(const char *, size_t) paramsnonnull((1)) _XMAL; char *xinet_ntop(int, const void *) _XPNN _XMAL; void *xunbinga(size_t, const char16_t *) attributeallocalign((1)) _XMAL _XRET; void *xunbing(const char16_t *) _XMAL _XRET; -char16_t *utf8toutf16(const char *, size_t, size_t *) nodiscard; -char *utf16toutf8(const char16_t *, size_t, size_t *) nodiscard; -wchar_t *utf8toutf32(const char *, size_t, size_t *) nodiscard; -wchar_t *utf16to32(const char16_t *, size_t, size_t *) nodiscard; -char *xhomedir(void) nodiscard; -char *xstripext(const char *) nodiscard; -char *xstripexts(const char *) nodiscard; +char16_t *utf8toutf16(const char *, size_t, size_t *) dontdiscard; +char *utf16toutf8(const char16_t *, size_t, size_t *) dontdiscard; +wchar_t *utf8toutf32(const char *, size_t, size_t *) dontdiscard; +wchar_t *utf16to32(const char16_t *, size_t, size_t *) dontdiscard; +char *xhomedir(void) dontdiscard; +char *xstripext(const char *) dontdiscard; +char *xstripexts(const char *) dontdiscard; void *xload(bool *, void **, const void *, size_t, size_t); void *xloadzd(bool *, void **, const void *, size_t, size_t, size_t, size_t, uint32_t); @@ -88,7 +88,7 @@ char *xiso8601ts(struct timespec *) mallocesque; void *xslurp(const char *, size_t *) paramsnonnull((1)) returnspointerwithnoaliases - returnsaligned((PAGESIZE)) nodiscard; + returnsaligned((PAGESIZE)) dontdiscard; int xbarf(const char *, const void *, size_t); /*───────────────────────────────────────────────────────────────────────────│─╗ @@ -122,6 +122,11 @@ int xvspawn(void (*)(void *), void *, struct rusage *); #if defined(__GNUC__) && !defined(__STRICT_ANSI__) #define xasprintf(FMT, ...) (xasprintf)(PFLINK(FMT), ##__VA_ARGS__) #define xvasprintf(FMT, VA) (xvasprintf)(PFLINK(FMT), VA) +#define xsigaction(SIG, HANDLER, FLAGS, MASK, OLD) \ + ({ \ + __SIGACTION_YOINK(SIG); \ + xsigaction(SIG, HANDLER, FLAGS, MASK, OLD); \ + }) #endif COSMOPOLITAN_C_END_ diff --git a/libc/x/xbarf.c b/libc/x/xbarf.c index 0162a812a..9041dca8d 100644 --- a/libc/x/xbarf.c +++ b/libc/x/xbarf.c @@ -26,7 +26,7 @@ * Writes data to file. * * @param size can be -1 to strlen(data) - * @return if failed, -1 w/ errno + * @return 0 on success or -1 w/ errno * @note this is uninterruptible */ int xbarf(const char *path, const void *data, size_t size) { diff --git a/libc/x/xdirname.c b/libc/x/xdirname.c index 28c336ada..8b483c6e8 100644 --- a/libc/x/xdirname.c +++ b/libc/x/xdirname.c @@ -17,11 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/conv.h" +#include "libc/runtime/gc.internal.h" #include "libc/x/x.h" /** * Returns directory portion of path. */ char *xdirname(const char *path) { - return dirname(xstrdup(path)); + return xstrdup(dirname(gc(xstrdup(path)))); } diff --git a/libc/x/xgetline.c b/libc/x/xgetline.c index 56123ffef..d5a16e16a 100644 --- a/libc/x/xgetline.c +++ b/libc/x/xgetline.c @@ -23,10 +23,10 @@ /** * Reads line from stream. * - * @return allocated line that needs free() and usually chomp() too, + * @return allocated line that needs free() and usually _chomp() too, * or NULL on ferror() or feof() * @see getdelim() for a more difficult api - * @see chomp() + * @see _chomp() */ char *xgetline(FILE *f) { char *p; diff --git a/libc/x/xjoinpaths.c b/libc/x/xjoinpaths.c index be058d02e..b7b21021e 100644 --- a/libc/x/xjoinpaths.c +++ b/libc/x/xjoinpaths.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/safemacros.internal.h" +#include "libc/str/path.h" #include "libc/str/str.h" #include "libc/x/x.h" diff --git a/libc/x/xload.c b/libc/x/xload.c index 6219e2a8b..0dfc6cc2f 100644 --- a/libc/x/xload.c +++ b/libc/x/xload.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" +#include "libc/intrin/lockcmpxchg.h" #include "libc/log/check.h" #include "libc/runtime/runtime.h" #include "libc/x/x.h" @@ -58,7 +58,7 @@ void *xload(bool *o, void **t, const void *p, size_t n, size_t m) { zs.next_out = (void *)q; inflateInit2(&zs, -MAX_WBITS); inflate(&zs, Z_NO_FLUSH); - if (lockcmpxchg(t, 0, q)) { + if (_lockcmpxchg(t, 0, q)) { __cxa_atexit(free, q, 0); } else { free(q); diff --git a/libc/x/xloadzd.c b/libc/x/xloadzd.c index 5a04a0494..2444b3abf 100644 --- a/libc/x/xloadzd.c +++ b/libc/x/xloadzd.c @@ -17,8 +17,8 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" -#include "libc/bits/bits.h" #include "libc/fmt/leb128.h" +#include "libc/intrin/lockcmpxchg.h" #include "libc/nexgen32e/crc32.h" #include "libc/runtime/runtime.h" #include "libc/x/x.h" @@ -69,7 +69,7 @@ void *xloadzd(bool *o, void **t, const void *p, size_t n, size_t m, size_t c, } free(q); assert(crc32_z(0, r, c * z) == s); - if (lockcmpxchg(t, 0, r)) { + if (_lockcmpxchg(t, 0, r)) { __cxa_atexit(free, r, 0); } else { free(q); diff --git a/libc/x/xsigaction.c b/libc/x/xsigaction.c index de964a857..3a64fda0f 100644 --- a/libc/x/xsigaction.c +++ b/libc/x/xsigaction.c @@ -39,8 +39,8 @@ * @asyncsignalsafe * @vforksafe */ -int xsigaction(int sig, void *handler, uint64_t flags, uint64_t mask, - struct sigaction *old) { +int(xsigaction)(int sig, void *handler, uint64_t flags, uint64_t mask, + struct sigaction *old) { /* This API is superior to sigaction() because (1) it offers feature parity; (2) compiler emits 1/3rd as much binary code at call-site; and (3) it removes typing that just whines without added saftey. */ diff --git a/libc/x/xslurp.c b/libc/x/xslurp.c index a99bb093e..b3b137a60 100644 --- a/libc/x/xslurp.c +++ b/libc/x/xslurp.c @@ -32,22 +32,21 @@ */ void *xslurp(const char *path, size_t *opt_out_size) { int fd; - ssize_t rc; size_t i, got; char *res, *p; - struct stat st; + ssize_t rc, size; res = NULL; if ((fd = open(path, O_RDONLY)) != -1) { - if (fstat(fd, &st) != -1 && (res = valloc(st.st_size + 1))) { - if (st.st_size > 2 * 1024 * 1024) { - fadvise(fd, 0, st.st_size, MADV_SEQUENTIAL); + if ((size = getfiledescriptorsize(fd)) != -1 && (res = valloc(size + 1))) { + if (size > 2 * 1024 * 1024) { + fadvise(fd, 0, size, MADV_SEQUENTIAL); } - for (i = 0; i < st.st_size; i += got) { + for (i = 0; i < size; i += got) { TryAgain: - if ((rc = pread(fd, res + i, st.st_size - i, i)) != -1) { + if ((rc = pread(fd, res + i, size - i, i)) != -1) { if (!(got = rc)) { - if (fstat(fd, &st) == -1) { - abort(); + if (getfiledescriptorsize(fd) == -1) { + abort(); // TODO(jart): what is this } } } else if (errno == EINTR) { @@ -60,7 +59,7 @@ void *xslurp(const char *path, size_t *opt_out_size) { } if (res) { if (opt_out_size) { - *opt_out_size = st.st_size; + *opt_out_size = size; } res[i] = '\0'; } diff --git a/libc/zip.h b/libc/zip.h index 250438e0d..35477adf5 100644 --- a/libc/zip.h +++ b/libc/zip.h @@ -44,11 +44,10 @@ #define kZipCompressionNone 0 #define kZipCompressionDeflate 8 -#define kZipCdirHdrMagic 0x06054b50 /* PK♣♠ "PK\5\6" */ -#define kZipCdirHdrMinSize 22 -#define kZipCdirAlign kZipAlign -#define kZipCdirHdrLinkableSize \ - ROUNDUP(kZipCfileHdrMinSize + PATH_MAX, kZipCdirAlign) +#define kZipCdirHdrMagic 0x06054b50 /* PK♣♠ "PK\5\6" */ +#define kZipCdirHdrMinSize 22 +#define kZipCdirAlign kZipAlign +#define kZipCdirHdrLinkableSize 294 #define kZipCdir64HdrMagic 0x06064b50 /* PK♣♠ "PK\6\6" */ #define kZipCdir64HdrMinSize 56 @@ -200,7 +199,6 @@ uint64_t GetZipCfileCompressedSize(const uint8_t *); uint64_t GetZipCfileOffset(const uint8_t *); uint64_t GetZipLfileUncompressedSize(const uint8_t *); uint64_t GetZipLfileCompressedSize(const uint8_t *); -uint8_t *zipfindcentraldir(const uint8_t *, size_t); void GetZipCfileTimestamps(const uint8_t *, struct timespec *, struct timespec *, struct timespec *, int); diff --git a/libc/zipos/close.c b/libc/zipos/close.c index bffb0416c..98fb0b3c6 100644 --- a/libc/zipos/close.c +++ b/libc/zipos/close.c @@ -29,19 +29,17 @@ * @param fd is vetted by close() */ int __zipos_close(int fd) { + int rc; struct ZiposHandle *h; h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle; - ZTRACE("__zipos_close(%.*s)", - ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile), - ZIP_CFILE_NAME(__zipos_get()->map + h->cfile)); if (!IsWindows()) { - sys_close(fd); + rc = sys_close(fd); } else { - CloseHandle(h->handle); + rc = 0; /* no system file descriptor needed on nt */ } if (!__vforked) { free(h->freeme); free(h); } - return 0; + return rc; } diff --git a/libc/zipos/fcntl.c b/libc/zipos/fcntl.c index 1fd82e2aa..aa0d673cf 100644 --- a/libc/zipos/fcntl.c +++ b/libc/zipos/fcntl.c @@ -28,30 +28,23 @@ #define HANDLE ((struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle) int __zipos_fcntl(int fd, int cmd, uintptr_t arg) { + int rc; if (cmd == F_GETFD) { - ZTRACE("__zipos_fcntl(%.*s, %s)", - ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile), - ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), "F_GETFD"); if (g_fds.p[fd].flags & O_CLOEXEC) { - return FD_CLOEXEC; + rc = FD_CLOEXEC; } else { - return 0; + rc = 0; } } else if (cmd == F_SETFD) { - ZTRACE("__zipos_fcntl(%.*s, %s, 0x%x)", - ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile), - ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), "F_SETFD", arg); if (arg & FD_CLOEXEC) { g_fds.p[fd].flags |= O_CLOEXEC; - return FD_CLOEXEC; + rc = FD_CLOEXEC; } else { g_fds.p[fd].flags &= ~O_CLOEXEC; - return 0; + rc = 0; } } else { - ZTRACE("__zipos_fcntl(%.*s, %d, 0x%x) → EINVAL", - ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile), - ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), cmd, arg); - return einval(); + rc = einval(); } + return rc; } diff --git a/libc/zipos/fstat.c b/libc/zipos/fstat.c index c0c2a7085..059dec50e 100644 --- a/libc/zipos/fstat.c +++ b/libc/zipos/fstat.c @@ -29,13 +29,10 @@ */ int __zipos_fstat(const struct ZiposHandle *h, struct stat *st) { int rc; - if (!st) return efault(); - if (!(rc = __zipos_stat_impl(__zipos_get(), h->cfile, st))) { - ZTRACE("__zipos_fstat(%.*s) → %d", - ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile), - ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), st->st_size); - return 0; + if (st) { + rc = __zipos_stat_impl(__zipos_get(), h->cfile, st); } else { - return rc; + rc = efault(); } + return rc; } diff --git a/libc/zipos/get.c b/libc/zipos/get.c index 59bc282c6..93a067eeb 100644 --- a/libc/zipos/get.c +++ b/libc/zipos/get.c @@ -18,11 +18,15 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" +#include "libc/calls/internal.h" #include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/stat.h" +#include "libc/dce.h" #include "libc/errno.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/spinlock.h" #include "libc/limits.h" -#include "libc/log/libfatal.internal.h" #include "libc/macros.internal.h" #include "libc/mem/alloca.h" #include "libc/runtime/runtime.h" @@ -58,19 +62,28 @@ static void __zipos_munmap_unneeded(const uint8_t *base, const uint8_t *cdir, /** * Returns pointer to zip central directory of current executable. + * @asyncsignalsafe (TODO: verify this) + * @threadsafe */ struct Zipos *__zipos_get(void) { - static bool once; - static struct Zipos zipos; int fd; char *path; - size_t size; + ssize_t size; + static bool once; sigset_t neu, old; + struct Zipos *res; + const char *progpath; + static struct Zipos zipos; uint8_t *map, *base, *cdir; + _Alignas(64) static char lock; + _spinlock(&lock); if (!once) { sigfillset(&neu); - sigprocmask(SIG_BLOCK, &neu, &old); - if ((fd = open(program_executable_name, O_RDONLY)) != -1) { + if (!IsWindows()) { + sys_sigprocmask(SIG_BLOCK, &neu, &old); + } + progpath = GetProgramExecutableName(); + if ((fd = open(progpath, O_RDONLY)) != -1) { if ((size = getfiledescriptorsize(fd)) != SIZE_MAX && (map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) { if ((base = FindEmbeddedApe(map, size))) { @@ -82,21 +95,26 @@ struct Zipos *__zipos_get(void) { __zipos_munmap_unneeded(base, cdir, map); zipos.map = base; zipos.cdir = cdir; + STRACE("__zipos_get(%#s)", progpath); } else { munmap(map, size); - ZTRACE("__zipos_get(%s) → eocd not found", program_executable_name); + STRACE("__zipos_get(%#s) → eocd not found", progpath); } - } else { - ZTRACE("__zipos_get(%s) → stat/mmap %s", program_executable_name, - strerror(errno)); } close(fd); } else { - ZTRACE("__zipos_get(%s) → open %s", program_executable_name, - strerror(errno)); + STRACE("__zipos_get(%#s) → open failed %m", progpath); + } + if (!IsWindows()) { + sigprocmask(SIG_SETMASK, &old, 0); } once = true; - sigprocmask(SIG_SETMASK, &old, 0); } - return zipos.cdir ? &zipos : 0; + if (zipos.cdir) { + res = &zipos; + } else { + res = 0; + } + _spunlock(&lock); + return res; } diff --git a/libc/zipos/lseek.c b/libc/zipos/lseek.c index 87693b3aa..352dec699 100644 --- a/libc/zipos/lseek.c +++ b/libc/zipos/lseek.c @@ -30,26 +30,25 @@ * @asyncsignalsafe */ int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) { - int64_t i; + int64_t rc; switch (whence) { case SEEK_SET: - i = offset; + rc = offset; break; case SEEK_CUR: - i = h->pos + offset; + rc = h->pos + offset; break; case SEEK_END: - i = h->size - offset; + rc = h->size - offset; break; default: - return einval(); + rc = -1; + break; } - if (i < 0) { - return einval(); + if (rc >= 0) { + h->pos = rc; + } else { + rc = einval(); } - h->pos = i; - ZTRACE("__zipos_lseek(%.*s, %d)", - ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile), - ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), i); - return i; + return rc; } diff --git a/libc/zipos/notat.c b/libc/zipos/notat.c index ef7d7f505..4f45aa44b 100644 --- a/libc/zipos/notat.c +++ b/libc/zipos/notat.c @@ -25,7 +25,6 @@ int __zipos_notat(int dirfd, const char *path) { struct ZiposUri zipname; if (!path) return efault(); if (__isfdkind(dirfd, kFdZip) || __zipos_parseuri(path, &zipname) != -1) { - ZTRACE("__zipos_notat(%d, %s) → EINVAL", dirfd, path); return einval(); } return 0; diff --git a/libc/zipos/open.c b/libc/zipos/open.c index 4582be7ab..9e8fcf4d9 100644 --- a/libc/zipos/open.c +++ b/libc/zipos/open.c @@ -124,12 +124,13 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags, h->mem = NULL; } if (h->mem) { - if ((fd = dup(2)) != -1) { + if ((fd = IsWindows() ? __reservefd(-1) : dup(2)) != -1) { if (__ensurefds(fd) != -1) { h->handle = g_fds.p[fd].handle; g_fds.p[fd].kind = kFdZip; g_fds.p[fd].handle = (intptr_t)h; g_fds.p[fd].flags = flags | O_CLOEXEC; + g_fds.p[fd].mode = mode; return fd; } close(fd); @@ -147,22 +148,22 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags, * @note don't call open() from signal handlers */ int __zipos_open(const struct ZiposUri *name, unsigned flags, int mode) { - int fd; + int rc; ssize_t cf; sigset_t oldmask; struct Zipos *zipos; - if ((flags & O_ACCMODE) != O_RDONLY) return einval(); - if ((zipos = __zipos_get())) { - if ((cf = __zipos_find(zipos, name)) != -1) { - fd = __zipos_load(zipos, cf, flags, mode); - ZTRACE("__zipos_open(%.*s)", name->len, name->path); + if ((flags & O_ACCMODE) == O_RDONLY) { + if ((zipos = __zipos_get())) { + if ((cf = __zipos_find(zipos, name)) != -1) { + rc = __zipos_load(zipos, cf, flags, mode); + } else { + rc = enoent(); + } } else { - ZTRACE("__zipos_open(%.*s) enoent", name->len, name->path); - fd = enoent(); + rc = enoexec(); } } else { - fd = enoexec(); - ZTRACE("__zipos_open(%.*s) enoexec", name->len, name->path); + rc = einval(); } - return fd; + return rc; } diff --git a/libc/zipos/read.c b/libc/zipos/read.c index 47f7e18fe..2767dd10c 100644 --- a/libc/zipos/read.c +++ b/libc/zipos/read.c @@ -46,9 +46,5 @@ ssize_t __zipos_read(struct ZiposHandle *h, const struct iovec *iov, memcpy(iov[i].iov_base, h->mem + y, b); } if (opt_offset == -1) h->pos = y; - ZTRACE("__zipos_read(%.*s, cap=%d, off=%d) -> %d", - ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile), - ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), GetIovSize(iov, iovlen), - x, y - x); return y - x; } diff --git a/libc/zipos/stat-impl.c b/libc/zipos/stat-impl.c index 16b040828..a9d9558a3 100644 --- a/libc/zipos/stat-impl.c +++ b/libc/zipos/stat-impl.c @@ -28,12 +28,8 @@ int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) { size_t lf; if (zipos && st) { bzero(st, sizeof(*st)); - if (ZIP_CFILE_FILEATTRCOMPAT(zipos->map + cf) == kZipOsUnix) { - st->st_mode = ZIP_CFILE_EXTERNALATTRIBUTES(zipos->map + cf) >> 16; - } else { - st->st_mode = 0100644; - } lf = GetZipCfileOffset(zipos->map + cf); + st->st_mode = GetZipCfileMode(zipos->map + cf); st->st_size = GetZipLfileUncompressedSize(zipos->map + lf); st->st_blocks = roundup(GetZipLfileCompressedSize(zipos->map + lf), 512) / 512; diff --git a/libc/zipos/stat.c b/libc/zipos/stat.c index 6be580a8b..2bdffd684 100644 --- a/libc/zipos/stat.c +++ b/libc/zipos/stat.c @@ -28,18 +28,21 @@ * @asyncsignalsafe */ int __zipos_stat(const struct ZiposUri *name, struct stat *st) { + int rc; ssize_t cf; struct Zipos *zipos; - if (!st) return efault(); - if ((zipos = __zipos_get())) { - if ((cf = __zipos_find(zipos, name)) != -1) { - return __zipos_stat_impl(zipos, cf, st); + if (st) { + if ((zipos = __zipos_get())) { + if ((cf = __zipos_find(zipos, name)) != -1) { + rc = __zipos_stat_impl(zipos, cf, st); + } else { + rc = enoent(); + } } else { - ZTRACE("__zipos_stat(%.*s) -> enoent", name->len, name->path); - return enoent(); + rc = enoexec(); } } else { - ZTRACE("__zipos_stat(%.*s) → enoexec", name->len, name->path); - return enoexec(); + rc = efault(); } + return rc; } diff --git a/libc/zipos/zipos.internal.h b/libc/zipos/zipos.internal.h index 89c8c8f26..babe65247 100644 --- a/libc/zipos/zipos.internal.h +++ b/libc/zipos/zipos.internal.h @@ -1,16 +1,9 @@ #ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ #define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ #include "libc/calls/calls.h" -#include "libc/calls/sysdebug.internal.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#if DEBUGSYS -#define ZTRACE(FMT, ...) __printf("ZIP: " FMT "\n", ##__VA_ARGS__) -#else -#define ZTRACE(FMT, ...) (void)0 -#endif - struct stat; struct iovec; diff --git a/net/http/decodelatin1.c b/net/http/decodelatin1.c index a52ce8b95..04ec84bd7 100644 --- a/net/http/decodelatin1.c +++ b/net/http/decodelatin1.c @@ -39,7 +39,7 @@ char *DecodeLatin1(const char *p, size_t n, size_t *z) { if (n == -1) n = p ? strlen(p) : 0; if ((q = r = malloc(n * 2 + 1))) { for (i = 0; i < n;) { - memset(vz, 0, 16); /* 3x speedup for ASCII */ + bzero(vz, 16); /* 3x speedup for ASCII */ while (i + 16 < n) { memcpy(v1, p + i, 16); pcmpgtb(v2, v1, vz); diff --git a/net/http/encodelatin1.c b/net/http/encodelatin1.c index 924188c4e..abb15c433 100644 --- a/net/http/encodelatin1.c +++ b/net/http/encodelatin1.c @@ -40,7 +40,7 @@ char *EncodeLatin1(const char *p, size_t n, size_t *z, int f) { size_t i; char t[256]; char *r, *q; - memset(t, 0, sizeof(t)); + bzero(t, sizeof(t)); if (f & kControlC0) memset(t + 0x00, 1, 0x20 - 0x00), t[0x7F] = 1; if (f & kControlC1) memset(t + 0x80, 1, 0xA0 - 0x80); t['\t'] = t['\r'] = t['\n'] = t['\v'] = !!(f & kControlWs); diff --git a/net/http/foldheader.c b/net/http/foldheader.c new file mode 100644 index 000000000..ac930abf9 --- /dev/null +++ b/net/http/foldheader.c @@ -0,0 +1,46 @@ +/*-*- 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 2022 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/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "net/http/http.h" + +/** + * Collapses repeating headers onto a single line. + */ +char *FoldHeader(struct HttpMessage *msg, char *b, int h, size_t *z) { + char *p; + size_t i, n, m; + struct HttpHeader *x; + n = msg->headers[h].b - msg->headers[h].a; + if ((p = malloc(n))) { + memcpy(p, b + msg->headers[h].a, n); + for (i = 0; i < msg->xheaders.n; ++i) { + x = msg->xheaders.p + i; + if (GetHttpHeader(b + x->k.a, x->k.b - x->k.a) == h) { + m = x->v.b - x->v.a; + if (!(p = realloc(p, n + 2 + m))) abort(); + memcpy(mempcpy(p + n, ", ", 2), b + x->v.a, m); + n += 2 + m; + } + } + *z = n; + } + return p; +} diff --git a/net/http/hascontrolcodes.c b/net/http/hascontrolcodes.c index c7fba8f22..dd6c4e30d 100644 --- a/net/http/hascontrolcodes.c +++ b/net/http/hascontrolcodes.c @@ -34,7 +34,7 @@ ssize_t HasControlCodes(const char *p, size_t n, int f) { char t[256]; wint_t x, a, b; size_t i, j, m, g; - memset(t, 0, sizeof(t)); + bzero(t, sizeof(t)); if (f & kControlC0) memset(t + 0x00, 1, 0x20 - 0x00), t[0x7F] = 1; if (f & kControlC1) memset(t + 0x80, 1, 0xA0 - 0x80); t['\t'] = t['\r'] = t['\n'] = t['\v'] = !!(f & kControlWs); diff --git a/net/http/http.h b/net/http/http.h index e63e44089..d6bfc93d1 100644 --- a/net/http/http.h +++ b/net/http/http.h @@ -208,6 +208,7 @@ int ParseForwarded(const char *, size_t, uint32_t *, uint16_t *); bool IsMimeType(const char *, size_t, const char *); ssize_t Unchunk(struct HttpUnchunker *, char *, size_t, size_t *); const char *FindContentType(const char *, size_t); +char *FoldHeader(struct HttpMessage *, char *, int, size_t *); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/net/http/khttprepeatable.c b/net/http/khttprepeatable.c index 11360b35f..184823e70 100644 --- a/net/http/khttprepeatable.c +++ b/net/http/khttprepeatable.c @@ -77,6 +77,7 @@ const bool kHttpRepeatable[kHttpHeadersMax] = { [kHttpVia] = true, [kHttpWarning] = true, [kHttpWwwAuthenticate] = true, + [kHttpXForwardedFor] = true, [kHttpAccessControlAllowHeaders] = true, [kHttpAccessControlAllowMethods] = true, [kHttpAccessControlRequestHeaders] = true, diff --git a/net/http/parseforwarded.c b/net/http/parseforwarded.c index 4b25697eb..d5aa2b052 100644 --- a/net/http/parseforwarded.c +++ b/net/http/parseforwarded.c @@ -24,13 +24,13 @@ * * This header is used by reverse proxies. For example: * - * X-Forwarded-For: 203.0.113.42:31337 + * X-Forwarded-For: 203.0.110.2, 203.0.113.42:31337 * * The port is optional and will be set to zero if absent. * * @param s is input data * @param n if -1 implies strlen - * @param ip receives ip on success if not NULL + * @param ip receives last/right ip on success if not NULL * @param port receives port on success if not NULL * @return 0 on success or -1 on failure * @see RFC7239's poorly designed Forwarded header @@ -38,10 +38,15 @@ int ParseForwarded(const char *s, size_t n, uint32_t *ip, uint16_t *port) { int c, t; size_t i; + char *r; uint32_t x; if (n == -1) n = s ? strlen(s) : 0; if (n) { t = x = i = 0; + if ((r = strrchr(s, ','))) { + i = r - s; + if ((s[++i] & 255) == ' ') ++i; // skip optional space + } do { c = s[i++] & 255; if (isdigit(c)) { diff --git a/net/http/parsehttpmessage.c b/net/http/parsehttpmessage.c index f9babfebb..77afdf730 100644 --- a/net/http/parsehttpmessage.c +++ b/net/http/parsehttpmessage.c @@ -36,7 +36,7 @@ */ void InitHttpMessage(struct HttpMessage *r, int type) { assert(type == kHttpRequest || type == kHttpResponse); - memset(r, 0, sizeof(*r)); + bzero(r, sizeof(*r)); r->type = type; } diff --git a/net/http/parseurl.c b/net/http/parseurl.c index cf5a8c0a6..8bdc6ac1b 100644 --- a/net/http/parseurl.c +++ b/net/http/parseurl.c @@ -257,7 +257,7 @@ static char *ParseUrlImpl(const char *s, size_t n, struct Url *h, bool latin1) { u.isform = false; u.isopaque = false; u.islatin1 = latin1; - memset(h, 0, sizeof(*h)); + bzero(h, sizeof(*h)); if ((m = malloc(latin1 ? u.n * 2 : u.n))) { u.q = u.p = m; if (ParseScheme(&u, h)) ParseAuthority(&u, h); diff --git a/net/http/underlong.c b/net/http/underlong.c index 0d924dbfb..e6e1c959b 100644 --- a/net/http/underlong.c +++ b/net/http/underlong.c @@ -46,7 +46,7 @@ char *Underlong(const char *p, size_t n, size_t *z) { if (n == -1) n = p ? strlen(p) : 0; if ((q = r = malloc(n + 1))) { for (i = 0; i < n;) { - memset(vz, 0, 16); /* 50x speedup for ASCII */ + bzero(vz, 16); /* 50x speedup for ASCII */ while (i + 16 < n) { memcpy(v1, p + i, 16); pcmpgtb(v2, v1, vz); diff --git a/net/https/getsslcachefile.c b/net/https/getsslcachefile.c index 6023a471f..bbcffaf3c 100644 --- a/net/https/getsslcachefile.c +++ b/net/https/getsslcachefile.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/safemacros.internal.h" #include "libc/fmt/fmt.h" +#include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "net/https/sslcache.h" @@ -26,10 +27,10 @@ * @return pointer to static memory */ char *GetSslCacheFile(void) { - static char sslcachefile[PATH_MAX + 1]; + static char sslcachefile[PATH_MAX]; if (snprintf(sslcachefile, sizeof(sslcachefile), "%s/%s.sslcache", firstnonnull(getenv("TMPDIR"), "/tmp"), - getenv("USER")) <= PATH_MAX) { + getenv("USER")) < ARRAYLEN(sslcachefile)) { return sslcachefile; } else { return 0; diff --git a/net/https/getsslroots.c b/net/https/getsslroots.c index 267c12e20..7b5bc2fc2 100644 --- a/net/https/getsslroots.c +++ b/net/https/getsslroots.c @@ -32,26 +32,40 @@ STATIC_YOINK("ssl_root_support"); +static void FreeSslRoots(mbedtls_x509_crt *c) { + mbedtls_x509_crt_free(c); + free(c); +} + +/** + * Returns singleton of SSL roots stored in /zip/usr/share/ssl/root/... + */ mbedtls_x509_crt *GetSslRoots(void) { int fd; DIR *d; uint8_t *p; size_t n, m; struct dirent *e; - mbedtls_x509_crt *c; - char path[PATH_MAX + 1]; - c = calloc(1, sizeof(*c)); - m = stpcpy(path, "/zip/usr/share/ssl/root/") - path; - if ((d = opendir(path))) { - while ((e = readdir(d))) { - if (e->d_type != DT_REG) continue; - if (m + (n = strlen(e->d_name)) > PATH_MAX) continue; - memcpy(path + m, e->d_name, n + 1); - CHECK((p = xslurp(path, &n))); - CHECK_GE(mbedtls_x509_crt_parse(c, p, n + 1), 0, "%s", path); - free(p); + static bool once; + char path[PATH_MAX]; + static mbedtls_x509_crt *c; + if (!once) { + if ((c = calloc(1, sizeof(*c)))) { + m = stpcpy(path, "/zip/usr/share/ssl/root/") - path; + if ((d = opendir(path))) { + while ((e = readdir(d))) { + if (e->d_type != DT_REG) continue; + if (m + (n = strlen(e->d_name)) >= ARRAYLEN(path)) continue; + memcpy(path + m, e->d_name, n + 1); + CHECK((p = xslurp(path, &n))); + CHECK_GE(mbedtls_x509_crt_parse(c, p, n + 1), 0, "%s", path); + free(p); + } + closedir(d); + } + __cxa_atexit(FreeSslRoots, c, 0); } - closedir(d); + once = true; } return c; } diff --git a/net/https/https.h b/net/https/https.h index 98459e876..f83229875 100644 --- a/net/https/https.h +++ b/net/https/https.h @@ -29,7 +29,6 @@ void TlsDie(const char *, int) wontreturn; bool ChainCertificate(mbedtls_x509_crt *, mbedtls_x509_crt *); bool CertHasIp(const mbedtls_x509_crt *, uint32_t); bool CertHasHost(const mbedtls_x509_crt *, const void *, size_t); -bool CertHasCommonName(const mbedtls_x509_crt *, const void *, size_t); bool IsServerCert(const struct Cert *, mbedtls_pk_type_t); void TlsDebug(void *, int, const char *, int, const char *); diff --git a/net/https/logcertificate.c b/net/https/logcertificate.c index cf46521e4..ea306fe05 100644 --- a/net/https/logcertificate.c +++ b/net/https/logcertificate.c @@ -25,7 +25,7 @@ void LogCertificate(const char *msg, mbedtls_x509_crt *cert) { if (LOGGABLE(kLogDebug)) { if ((s = malloc((n = 15000)))) { if (mbedtls_x509_crt_info(s, n, " ", cert) > 0) { - DEBUGF("%s\n%s", msg, chomp(s)); + DEBUGF("%s\n%s", msg, _chomp(s)); } free(s); } diff --git a/net/https/sslcache.c b/net/https/sslcache.c index 0d48c8ae3..664f5f0ca 100644 --- a/net/https/sslcache.c +++ b/net/https/sslcache.c @@ -21,6 +21,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/errno.h" +#include "libc/intrin/lockcmpxchg.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/macros.internal.h" @@ -129,7 +130,7 @@ int UncacheSslSession(void *data, mbedtls_ssl_session *session) { ts = time(0); if (!(e->time <= ts && ts <= e->time + cache->lifetime)) { DEBUGF("%u sslcache expired", i); - lockcmpxchg(&e->tick, tick, 0); + _lockcmpxchg(&e->tick, tick, 0); return 1; } cert = 0; @@ -199,7 +200,7 @@ int CacheSslSession(void *data, const mbedtls_ssl_session *session) { e->time = time(0); tick = rdtsc(); asm volatile("" ::: "memory"); - if (tick && lockcmpxchg(&e->pid, pid, 0)) { + if (tick && _lockcmpxchg(&e->pid, pid, 0)) { DEBUGF("%u saved %s%s %`#.*s", i, mbedtls_ssl_get_ciphersuite_name(session->ciphersuite), session->compression ? " DEFLATE" : "", session->id_len, diff --git a/test/dsp/core/float2short_test.c b/test/dsp/core/float2short_test.c deleted file mode 100644 index 0d229565a..000000000 --- a/test/dsp/core/float2short_test.c +++ /dev/null @@ -1,83 +0,0 @@ -/*-*- 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/core.h" -#include "dsp/mpeg/mpeg.h" -#include "libc/log/check.h" -#include "libc/macros.internal.h" -#include "libc/rand/rand.h" -#include "libc/runtime/buffer.h" -#include "libc/testlib/ezbench.h" -#include "libc/testlib/testlib.h" - -short pcm[8][8]; -float binary32[8][8]; -struct GuardedBuffer b1, b2; - -TEST(float2short, test) { - binary32[0][0] = -0.5; - binary32[0][1] = 0.0; - binary32[0][2] = 0.5; - float2short(8, pcm, binary32); - EXPECT_EQ(-16384, pcm[0][0]); - EXPECT_EQ(0, pcm[0][1]); - EXPECT_EQ(16384, pcm[0][2]); -} - -TEST(float2short, testOverflow) { - binary32[0][0] = -1.1; - binary32[0][1] = -1.0; - binary32[0][2] = 1.0; - binary32[0][3] = 1.1; - float2short(8, pcm, binary32); - EXPECT_EQ(-32768, pcm[0][0]); - EXPECT_EQ(-32768, pcm[0][1]); - EXPECT_EQ(32767, pcm[0][2]); - EXPECT_EQ(32767, pcm[0][3]); -} - -void unclamped(size_t n, short pcm16[n][8], const float binary32[n][8]) { - size_t i, j; - for (i = 0; i < n; ++i) { - for (j = 0; j < 8; ++j) { - pcm16[i][j] = binary32[i][j] * 32768; - } - } -} - -plm_samples_t samps; - -void randomizeaudio(void) { - size_t i; - for (i = 0; i < ARRAYLEN(samps.interleaved); ++i) { - samps.interleaved[i] = randf(); - } -} - -void float2short_pure(void) { - float2short(ARRAYLEN(samps.interleaved) / 8, pcm, (void *)samps.interleaved); -} - -void float2short_unclamped(void) { - unclamped(ARRAYLEN(samps.interleaved) / 8, pcm, (void *)samps.interleaved); -} - -BENCH(float2short, audioframe) { - EZBENCH(randomizeaudio(), float2short_pure()); - EZBENCH(randomizeaudio(), float2short_unclamped()); -} diff --git a/test/libc/alg/critbit0_test.c b/test/libc/alg/critbit0_test.c index cf863c9ce..0ee2581c0 100644 --- a/test/libc/alg/critbit0_test.c +++ b/test/libc/alg/critbit0_test.c @@ -29,7 +29,7 @@ struct Bog { const char *p[]; }; -static testonly nodiscard struct Bog *NewBog(unsigned n) { +static testonly dontdiscard struct Bog *NewBog(unsigned n) { struct Bog *res = malloc(sizeof(struct Bog) + sizeof(const char *) * n); res->i = 0; res->n = n; diff --git a/test/libc/bits/popcnt_test.c b/test/libc/bits/popcnt_test.c index 707b86ac6..4a5043d50 100644 --- a/test/libc/bits/popcnt_test.c +++ b/test/libc/bits/popcnt_test.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/popcnt.h" #include "libc/testlib/ezbench.h" +#include "libc/testlib/hyperion.h" #include "libc/testlib/testlib.h" TEST(popcnt, test) { @@ -31,4 +32,5 @@ BENCH(popcnt, bench) { EXPROPRIATE(popcnt(VEIL("r", 0x5555555555555555)))); EZBENCH2("(popcnt)", donothing, EXPROPRIATE((popcnt)(VEIL("r", 0x5555555555555555)))); + EZBENCH_N("_countbits", kHyperionSize, _countbits(kHyperion, kHyperionSize)); } diff --git a/test/libc/calls/access_test.c b/test/libc/calls/access_test.c index e4832d01c..07587ab20 100644 --- a/test/libc/calls/access_test.c +++ b/test/libc/calls/access_test.c @@ -29,8 +29,21 @@ char testlib_enable_tmp_setup_teardown; -TEST(access, testNull_returnsEfault) { +TEST(access, efault) { ASSERT_SYS(EFAULT, -1, access(0, F_OK)); + if (IsWindows() && !IsAsan()) return; // not possible + ASSERT_SYS(EFAULT, -1, access((void *)77, F_OK)); +} + +TEST(access, enoent) { + ASSERT_SYS(ENOENT, -1, access("", F_OK)); + ASSERT_SYS(ENOENT, -1, access("doesnotexist", F_OK)); + ASSERT_SYS(ENOENT, -1, access("o/doesnotexist", F_OK)); +} + +TEST(access, enotdir) { + ASSERT_SYS(0, 0, touch("o", 0644)); + ASSERT_SYS(ENOTDIR, -1, access("o/doesnotexist", F_OK)); } TEST(access, test) { @@ -59,5 +72,5 @@ TEST(access, testRequestWriteOnReadOnly_returnsEaccess) { } TEST(access, runThisExecutable) { - ASSERT_SYS(0, 0, access(program_executable_name, R_OK | X_OK)); + ASSERT_SYS(0, 0, access(GetProgramExecutableName(), R_OK | X_OK)); } diff --git a/test/libc/calls/chdir_test.c b/test/libc/calls/chdir_test.c new file mode 100644 index 000000000..4fa925296 --- /dev/null +++ b/test/libc/calls/chdir_test.c @@ -0,0 +1,52 @@ +/*-*- 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 2022 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/errno.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/testlib.h" + +char testlib_enable_tmp_setup_teardown; + +TEST(chdir, efault) { + ASSERT_SYS(EFAULT, -1, chdir(0)); + if (IsWindows() && !IsAsan()) return; // not possible + ASSERT_SYS(EFAULT, -1, chdir((void *)77)); +} + +TEST(chdir, enoent) { + ASSERT_SYS(ENOENT, -1, chdir("")); + ASSERT_SYS(ENOENT, -1, chdir("doesnotexist")); + ASSERT_SYS(ENOENT, -1, chdir("o/doesnotexist")); +} + +TEST(chdir, enotdir) { + ASSERT_SYS(0, 0, touch("o", 0644)); + ASSERT_SYS(ENOTDIR, -1, chdir("o/doesnotexist")); +} + +TEST(chdir, test) { + ASSERT_SYS(0, 0, mkdir("o", 0755)); + ASSERT_SYS(0, 0, touch("o/file", 0644)); + ASSERT_SYS(0, 3, open("o/file", O_RDONLY)); + ASSERT_SYS(0, 0, close(3)); + ASSERT_SYS(0, 0, chdir("o")); + ASSERT_SYS(0, 3, open("file", O_RDONLY)); + ASSERT_SYS(0, 0, close(3)); + ASSERT_SYS(ENOENT, -1, open("o/file", O_RDONLY)); +} diff --git a/test/libc/calls/clock_gettime_test.c b/test/libc/calls/clock_gettime_test.c new file mode 100644 index 000000000..e67d61473 --- /dev/null +++ b/test/libc/calls/clock_gettime_test.c @@ -0,0 +1,29 @@ +/*-*- 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 2022 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/struct/timespec.h" +#include "libc/sysv/consts/clock.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +BENCH(clock_gettime, bench) { + struct timespec ts; + EZBENCH2("nowl", donothing, nowl()); + EZBENCH2("clock_gettime", donothing, clock_gettime(CLOCK_REALTIME, &ts)); +} diff --git a/test/libc/calls/commandv_test.c b/test/libc/calls/commandv_test.c index e4f6da7a7..955d41266 100644 --- a/test/libc/calls/commandv_test.c +++ b/test/libc/calls/commandv_test.c @@ -54,34 +54,34 @@ void TearDown(void) { TEST(commandv, testPathSearch) { EXPECT_NE(-1, touch("bin/sh", 0755)); - EXPECT_STREQ("bin/sh", commandv("sh", pathbuf)); + EXPECT_STREQ("bin/sh", commandv("sh", pathbuf, sizeof(pathbuf))); } TEST(commandv, testPathSearch_appendsComExtension) { EXPECT_NE(-1, touch("bin/sh.com", 0755)); - EXPECT_STREQ("bin/sh.com", commandv("sh", pathbuf)); + EXPECT_STREQ("bin/sh.com", commandv("sh", pathbuf, sizeof(pathbuf))); } TEST(commandv, testSlashes_wontSearchPath_butChecksAccess) { EXPECT_NE(-1, touch("home/sh", 0755)); i = g_syscount; - EXPECT_STREQ("home/sh", commandv("home/sh", pathbuf)); + EXPECT_STREQ("home/sh", commandv("home/sh", pathbuf, sizeof(pathbuf))); if (!IsWindows()) EXPECT_EQ(i + 1, g_syscount); } TEST(commandv, testSlashes_wontSearchPath_butStillAppendsComExtension) { EXPECT_NE(-1, touch("home/sh.com", 0755)); i = g_syscount; - EXPECT_STREQ("home/sh.com", commandv("home/sh", pathbuf)); + EXPECT_STREQ("home/sh.com", commandv("home/sh", pathbuf, sizeof(pathbuf))); if (!IsWindows()) EXPECT_EQ(i + 2, g_syscount); } TEST(commandv, testSameDir_doesntHappenByDefaultUnlessItsWindows) { EXPECT_NE(-1, touch("bog", 0755)); if (IsWindows()) { - EXPECT_STREQ("./bog", commandv("bog", pathbuf)); + EXPECT_STREQ("./bog", commandv("bog", pathbuf, sizeof(pathbuf))); } else { - EXPECT_EQ(NULL, commandv("bog", pathbuf)); + EXPECT_EQ(NULL, commandv("bog", pathbuf, sizeof(pathbuf))); } } @@ -89,9 +89,9 @@ TEST(commandv, testSameDir_willHappenWithColonBlank) { CHECK_NE(-1, setenv("PATH", "bin:", true)); EXPECT_NE(-1, touch("bog", 0755)); if (IsWindows()) { - EXPECT_STREQ("./bog", commandv("bog", pathbuf)); + EXPECT_STREQ("./bog", commandv("bog", pathbuf, sizeof(pathbuf))); } else { - EXPECT_STREQ("bog", commandv("bog", pathbuf)); + EXPECT_STREQ("bog", commandv("bog", pathbuf, sizeof(pathbuf))); } } @@ -99,8 +99,8 @@ TEST(commandv, testSameDir_willHappenWithColonBlank2) { CHECK_NE(-1, setenv("PATH", ":bin", true)); EXPECT_NE(-1, touch("bog", 0755)); if (IsWindows()) { - EXPECT_STREQ("./bog", commandv("bog", pathbuf)); + EXPECT_STREQ("./bog", commandv("bog", pathbuf, sizeof(pathbuf))); } else { - EXPECT_STREQ("bog", commandv("bog", pathbuf)); + EXPECT_STREQ("bog", commandv("bog", pathbuf, sizeof(pathbuf))); } } diff --git a/test/libc/calls/dup_test.c b/test/libc/calls/dup_test.c index 1f7ff126a..5c8734786 100644 --- a/test/libc/calls/dup_test.c +++ b/test/libc/calls/dup_test.c @@ -51,8 +51,8 @@ TEST(dup, clearsCloexecFlag) { ASSERT_NE(-1, (ws = xspawn(0))); if (ws == -2) { dup2(3, 0); - execv(program_executable_name, - (char *const[]){program_executable_name, "boop", 0}); + execv(GetProgramExecutableName(), + (char *const[]){GetProgramExecutableName(), "boop", 0}); _exit(127); } ASSERT_EQ(72, WEXITSTATUS(ws)); diff --git a/test/libc/calls/execve_test.c b/test/libc/calls/execve_test.c new file mode 100644 index 000000000..88cbd140f --- /dev/null +++ b/test/libc/calls/execve_test.c @@ -0,0 +1,73 @@ +/*-*- 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 2022 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/dce.h" +#include "libc/log/check.h" +#include "libc/runtime/runtime.h" +#include "libc/testlib/testlib.h" + +void SetUp(void) { + if (getenv("_SUBPROCESS")) { + if (!__argv[0]) { + exit(0); + } else { + exit(7); + } + } else if (getenv("_WEIRDENV")) { + for (char **e = environ; *e; ++e) { + if (!strcmp(*e, "WEIRD")) { + exit(0); + } + } + exit(7); + } +} + +TEST(execve, testWeirdAnsiC89emptyArgv) { + char *prog; + int pid, ws; + if (IsWindows()) return; + if (IsOpenbsd()) return; + prog = GetProgramExecutableName(); + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + execve(prog, (char *const[]){0}, (char *const[]){"_SUBPROCESS=1", 0}); + _Exit(127); + } + ASSERT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); +} + +TEST(execve, testWeirdEnvironmentVariable) { + char *prog; + int pid, ws; + if (IsWindows()) return; + if (IsOpenbsd()) return; + prog = GetProgramExecutableName(); + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + execve(prog, (char *const[]){prog, 0}, + (char *const[]){"_WEIRDENV=1", "WEIRD", 0}); + _Exit(127); + } + ASSERT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); +} diff --git a/test/libc/calls/fcntl_test.c b/test/libc/calls/fcntl_test.c index 5ebf46bdf..3c9ee8a41 100644 --- a/test/libc/calls/fcntl_test.c +++ b/test/libc/calls/fcntl_test.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/dce.h" #include "libc/fmt/fmt.h" #include "libc/log/check.h" #include "libc/macros.internal.h" @@ -40,9 +41,12 @@ TEST(fcntl_getfl, testRemembersAccessMode) { } TEST(fcntl_setfl, testChangeAppendStatus) { + if (IsWindows()) { + // no obivous way to do fcntl(fd, F_SETFL, O_APPEND) + return; + } int fd; char buf[8] = {0}; - if (IsWindows()) return; /* doesn't appear possible on windows */ ASSERT_NE(-1, (fd = open("foo", O_CREAT | O_RDWR, 0644))); EXPECT_EQ(3, write(fd, "foo", 3)); EXPECT_NE(-1, lseek(fd, 0, SEEK_SET)); diff --git a/test/libc/calls/fork_test.c b/test/libc/calls/fork_test.c deleted file mode 100644 index d70f93207..000000000 --- a/test/libc/calls/fork_test.c +++ /dev/null @@ -1,79 +0,0 @@ -/*-*- 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/macros.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/msync.h" -#include "libc/sysv/consts/prot.h" -#include "libc/testlib/testlib.h" - -TEST(fork, testPipes) { - int a, b; - int ws, pid; - int pipefds[2]; - ASSERT_NE(-1, pipe(pipefds)); - ASSERT_NE(-1, (pid = fork())); - if (!pid) { - a = 31337; - close(pipefds[0]); - write(pipefds[1], &a, sizeof(a)); - close(pipefds[1]); - _exit(0); - } - EXPECT_NE(-1, close(pipefds[1])); - EXPECT_EQ(sizeof(b), read(pipefds[0], &b, sizeof(b))); - EXPECT_NE(-1, close(pipefds[0])); - EXPECT_NE(-1, waitpid(pid, &ws, 0)); - EXPECT_EQ(31337, b); -} - -TEST(fork, testSharedMemory) { - int ws, pid; - int stackvar; - int *sharedvar; - int *privatevar; - EXPECT_NE(MAP_FAILED, - (sharedvar = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, -1, 0))); - EXPECT_NE(MAP_FAILED, - (privatevar = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); - stackvar = 1; - *sharedvar = 1; - *privatevar = 1; - EXPECT_NE(-1, (pid = fork())); - if (!pid) { - EXPECT_EQ(NULL, getenv("_FORK")); - ++stackvar; - ++*sharedvar; - ++*privatevar; - msync((void *)ROUNDDOWN((intptr_t)&stackvar, FRAMESIZE), FRAMESIZE, - MS_SYNC); - EXPECT_NE(-1, msync(privatevar, FRAMESIZE, MS_SYNC)); - EXPECT_NE(-1, msync(sharedvar, FRAMESIZE, MS_SYNC)); - _exit(0); - } - EXPECT_NE(-1, waitpid(pid, &ws, 0)); - EXPECT_EQ(1, stackvar); - EXPECT_EQ(2, *sharedvar); - EXPECT_EQ(1, *privatevar); - EXPECT_NE(-1, munmap(sharedvar, FRAMESIZE)); - EXPECT_NE(-1, munmap(privatevar, FRAMESIZE)); -} diff --git a/test/libc/calls/getcwd_test.c b/test/libc/calls/getcwd_test.c index e6adae3bd..022ca22b6 100644 --- a/test/libc/calls/getcwd_test.c +++ b/test/libc/calls/getcwd_test.c @@ -40,3 +40,10 @@ TEST(getcwd, testNullBuf_allocatesResult) { EXPECT_NE(-1, chdir("subdir")); EXPECT_STREQ("subdir", basename(gc(getcwd(0, 0)))); } + +TEST(getcwd, testWindows_addsFunnyPrefix) { + if (!IsWindows()) return; + char path[PATH_MAX]; + ASSERT_NE(0, getcwd(path, sizeof(path))); + EXPECT_STARTSWITH("//?/", path); +} diff --git a/test/libc/calls/mkdir_test.c b/test/libc/calls/mkdir_test.c index 997ac9742..e0037d558 100644 --- a/test/libc/calls/mkdir_test.c +++ b/test/libc/calls/mkdir_test.c @@ -17,9 +17,11 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/log/check.h" +#include "libc/mem/mem.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/o.h" #include "libc/testlib/testlib.h" @@ -27,6 +29,10 @@ char testlib_enable_tmp_setup_teardown; +void SetUp(void) { + errno = 0; +} + TEST(mkdir, testNothingExists_ENOENT) { EXPECT_EQ(-1, mkdir("yo/yo/yo", 0755)); EXPECT_EQ(ENOENT, errno); @@ -54,8 +60,17 @@ TEST(mkdir, testPathIsDirectory_EEXIST) { EXPECT_EQ(EEXIST, errno); } -TEST(makedirs, testEmptyString_ENOENT) { - EXPECT_EQ(-1, makedirs("", 0755)); +TEST(mkdir, enametoolong) { + int i; + size_t n = 2048; + char *d, *s = gc(calloc(1, n)); + for (i = 0; i < n - 1; ++i) s[i] = 'x'; + s[i] = 0; + EXPECT_SYS(ENAMETOOLONG, -1, mkdir(s, 0644)); +} + +TEST(makedirs, testEmptyString_EEXIST) { + EXPECT_EQ(-1, mkdir("", 0755)); EXPECT_EQ(ENOENT, errno); } @@ -68,3 +83,14 @@ TEST(mkdirat, testRelativePath_opensRelativeToDirFd) { EXPECT_EQ(-1, makedirs("", 0755)); EXPECT_NE(-1, close(dirfd)); } + +TEST(mkdir, longname) { + int i; + char *d, s[270] = {0}; + for (i = 0; i < sizeof(s) - 1; ++i) s[i] = 'x'; + s[i] = 0; + ASSERT_NE(NULL, (d = gc(getcwd(0, 0)))); + memcpy(s, d, strlen(d)); + s[strlen(d)] = '/'; + ASSERT_SYS(0, 0, mkdir(s, 0644)); +} diff --git a/test/libc/calls/mkntcmdline_test.c b/test/libc/calls/mkntcmdline_test.c index bd373fd76..db1b4afe8 100644 --- a/test/libc/calls/mkntcmdline_test.c +++ b/test/libc/calls/mkntcmdline_test.c @@ -23,9 +23,15 @@ #include "libc/str/str.h" #include "libc/testlib/testlib.h" -char16_t cmdline[ARG_MAX]; +char16_t cmdline[ARG_MAX / 2]; -TEST(mkntcmdline, emptyArgvList_isEmpty) { +TEST(mkntcmdline, emptyArgvList_cantBeEmptyOnWindows) { + char *argv[] = {NULL}; + EXPECT_NE(-1, mkntcmdline(cmdline, "foo", argv)); + EXPECT_STREQ(u"foo", cmdline); +} + +TEST(mkntcmdline, emptyArgvListWithProg_isEmpty) { char *argv[] = {NULL}; EXPECT_NE(-1, mkntcmdline(cmdline, argv[0], argv)); EXPECT_STREQ(u"", cmdline); @@ -76,11 +82,17 @@ TEST(mkntcmdline, fix) { char *argv1[] = { "C:/WINDOWS/system32/cmd.exe", "/C", - "more < \"C:\\Users\\jtunn\\AppData\\Local\\Temp\\tmplquaa_d6\"", + "more < \"C:\\Users\\jart\\AppData\\Local\\Temp\\tmplquaa_d6\"", NULL, }; EXPECT_NE(-1, mkntcmdline(cmdline, argv1[0], argv1)); EXPECT_STREQ(u"C:\\WINDOWS\\system32\\cmd.exe /C \"more < " - u"\\\"C:\\Users\\jtunn\\AppData\\Local\\Temp\\tmplquaa_d6\\\"\"", + u"\\\"C:\\Users\\jart\\AppData\\Local\\Temp\\tmplquaa_d6\\\"\"", cmdline); } + +TEST(mkntcmdline, testWut) { + char *argv[] = {"redbean.com", "--strace", NULL}; + EXPECT_NE(-1, mkntcmdline(cmdline, "C:\\Users\\jart\\redbean.com", argv)); + EXPECT_STREQ(u"C:\\Users\\jart\\redbean.com --strace", cmdline); +} diff --git a/test/libc/calls/mkntenvblock_test.c b/test/libc/calls/mkntenvblock_test.c index b441a08fa..3c7c4bac2 100644 --- a/test/libc/calls/mkntenvblock_test.c +++ b/test/libc/calls/mkntenvblock_test.c @@ -20,7 +20,7 @@ #include "libc/runtime/gc.internal.h" #include "libc/testlib/testlib.h" -char16_t envvars[ARG_MAX]; +char16_t envvars[ARG_MAX / 2]; TEST(mkntenvblock, emptyList_onlyOutputsDoubleNulStringTerminator) { char *envp[] = {NULL}; diff --git a/test/libc/calls/mprotect_test.c b/test/libc/calls/mprotect_test.c deleted file mode 100644 index 8cf332040..000000000 --- a/test/libc/calls/mprotect_test.c +++ /dev/null @@ -1,67 +0,0 @@ -/*-*- 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/struct/sigaction.h" -#include "libc/runtime/runtime.h" -#include "libc/sysv/consts/prot.h" -#include "libc/sysv/consts/sa.h" -#include "libc/testlib/testlib.h" - -jmp_buf jb; -bool gotsegv; -struct sigaction old[2]; - -void OnSigSegv(int sig) { - gotsegv = true; - longjmp(jb, 1); -} - -void SetUp(void) { - sigaction(SIGBUS, NULL, &old[0]); - sigaction(SIGSEGV, NULL, &old[1]); -} - -void TearDown(void) { - sigaction(SIGBUS, &old[0], NULL); - sigaction(SIGSEGV, &old[1], NULL); -} - -TEST(mprotect, test) { - char *p = gc(memalign(PAGESIZE, PAGESIZE)); - p[0] = 0; - ASSERT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); - p[0] = 1; - EXPECT_EQ(1, p[0]); -} - -TEST(mprotect, testSegfault) { - char *p; - struct sigaction ss = {.sa_handler = OnSigSegv, .sa_flags = SA_NODEFER}; - if (IsWindows()) return; /* TODO */ - p = gc(memalign(PAGESIZE, PAGESIZE)); - EXPECT_NE(-1, sigaction(SIGBUS, &ss, NULL)); - EXPECT_NE(-1, sigaction(SIGSEGV, &ss, NULL)); - if (!setjmp(jb)) p[0] = 1; - EXPECT_FALSE(gotsegv); - EXPECT_NE(-1, mprotect(p, sizeof(p), PROT_READ)); - if (!setjmp(jb)) p[0] = 2; - EXPECT_TRUE(gotsegv); - EXPECT_EQ(1, p[0]); - EXPECT_NE(-1, mprotect(p, sizeof(p), PROT_READ | PROT_WRITE)); -} diff --git a/test/libc/calls/open_test.c b/test/libc/calls/open_test.c new file mode 100644 index 000000000..ddfbae830 --- /dev/null +++ b/test/libc/calls/open_test.c @@ -0,0 +1,90 @@ +/*-*- 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 "libc/dce.h" +#include "libc/errno.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +char testlib_enable_tmp_setup_teardown; + +TEST(open, efault) { + ASSERT_SYS(EFAULT, -1, open(0, O_RDONLY)); + if (IsWindows() && !IsAsan()) return; // not possible + ASSERT_SYS(EFAULT, -1, open((void *)77, O_RDONLY)); +} + +TEST(open, enoent) { + ASSERT_SYS(ENOENT, -1, open("", O_RDONLY)); + ASSERT_SYS(ENOENT, -1, open("doesnotexist", O_RDONLY)); + ASSERT_SYS(ENOENT, -1, open("o/doesnotexist", O_RDONLY)); +} + +TEST(open, enotdir) { + ASSERT_SYS(0, 0, touch("o", 0644)); + ASSERT_SYS(ENOTDIR, -1, open("o/doesnotexist", O_RDONLY)); +} + +TEST(open, eexist) { + ASSERT_SYS(0, 0, touch("exists", 0644)); + ASSERT_SYS(EEXIST, -1, open("exists", O_WRONLY | O_CREAT | O_EXCL)); +} + +TEST(open, enametoolong) { + size_t n = 260; + char *s = gc(xcalloc(1, n + 1)); + memset(s, 'J', n); + ASSERT_SYS(ENAMETOOLONG, -1, creat(s, 0644)); +} + +TEST(open, testOpenExistingForWriteOnly_seeksToStart) { + char buf[8] = {0}; + ASSERT_SYS(0, 0, xbarf("hello.txt", "hello", -1)); + ASSERT_SYS(0, 3, open("hello.txt", O_WRONLY)); + EXPECT_SYS(0, 1, write(3, "H", 1)); + EXPECT_SYS(0, 0, close(3)); + ASSERT_SYS(0, 3, open("hello.txt", O_RDONLY)); + EXPECT_SYS(0, 5, read(3, buf, 7)); + EXPECT_STREQ("Hello", buf); + EXPECT_SYS(0, 0, close(3)); +} + +TEST(open, testOpenExistingForReadWrite_seeksToStart) { + char buf[8] = {0}; + ASSERT_SYS(0, 0, xbarf("hello.txt", "hello", -1)); + ASSERT_SYS(0, 3, open("hello.txt", O_RDWR)); + EXPECT_SYS(0, 1, write(3, "H", 1)); + EXPECT_SYS(0, 0, close(3)); + ASSERT_SYS(0, 3, open("hello.txt", O_RDONLY)); + EXPECT_SYS(0, 5, read(3, buf, 7)); + EXPECT_STREQ("Hello", buf); + EXPECT_SYS(0, 0, close(3)); +} + +TEST(open, testOpenExistingForAppendWriteOnly_seeksToEnd) { + char buf[8] = {0}; + ASSERT_SYS(0, 0, xbarf("hello.txt", "hell", -1)); + ASSERT_SYS(0, 3, open("hello.txt", O_WRONLY | O_APPEND)); + EXPECT_SYS(0, 1, write(3, "o", 1)); + EXPECT_SYS(0, 0, close(3)); + ASSERT_SYS(0, 3, open("hello.txt", O_RDONLY)); + EXPECT_SYS(0, 5, read(3, buf, 7)); + EXPECT_STREQ("hello", buf); + EXPECT_SYS(0, 0, close(3)); +} diff --git a/test/libc/calls/pipe_test.c b/test/libc/calls/pipe_test.c new file mode 100644 index 000000000..c88c5d0f2 --- /dev/null +++ b/test/libc/calls/pipe_test.c @@ -0,0 +1,75 @@ +/*-*- 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 2022 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/dce.h" +#include "libc/errno.h" +#include "libc/sysv/consts/rlimit.h" +#include "libc/testlib/testlib.h" + +int ws, pid, f[2]; +char buf[6] = {0}; +struct rlimit rlim = {0, 10}; + +TEST(pipe, efault) { + EXPECT_SYS(EFAULT, -1, pipe(0)); +} + +TEST(pipe, einval) { + EXPECT_SYS(EINVAL, -1, pipe2(f, -1)); +} + +TEST(pipe, ebadf) { + if (IsFreebsd()) return; // somehow succeeds + if (IsOpenbsd()) return; // somehow succeeds + EXPECT_SYS(0, 0, pipe(f)); + EXPECT_SYS(EBADF, -1, write(f[0], "h", 1)); + EXPECT_SYS(EBADF, -1, read(f[1], buf, 1)); + EXPECT_SYS(0, 0, close(f[0])); + EXPECT_SYS(0, 0, close(f[1])); +} + +TEST(pipe, emfile) { + if (IsWindows()) return; // TODO + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + ASSERT_EQ(0, setrlimit(RLIMIT_NOFILE, &rlim)); + ASSERT_SYS(EMFILE, -1, pipe(f)); + _exit(0); + } + EXPECT_NE(-1, waitpid(pid, &ws, 0)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); +} + +TEST(pipe, usesLowestFileNumbers) { + EXPECT_SYS(0, 0, pipe(f)); + EXPECT_SYS(0, 3, f[0]); + EXPECT_SYS(0, 4, f[1]); + EXPECT_SYS(0, 0, close(f[0])); + EXPECT_SYS(0, 0, close(f[1])); +} + +TEST(pipe, doesBuffering) { + EXPECT_SYS(0, 0, pipe(f)); + EXPECT_SYS(0, 5, write(f[1], "hello", 5)); + EXPECT_SYS(0, 5, read(f[0], buf, 5)); + EXPECT_STREQ("hello", buf); + EXPECT_SYS(0, 0, close(f[0])); + EXPECT_SYS(0, 0, close(f[1])); +} diff --git a/test/libc/calls/pread_test.c b/test/libc/calls/pread_test.c new file mode 100644 index 000000000..1f3ff5e34 --- /dev/null +++ b/test/libc/calls/pread_test.c @@ -0,0 +1,39 @@ +/*-*- 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 2022 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/sysv/consts/o.h" +#include "libc/testlib/testlib.h" + +char testlib_enable_tmp_setup_teardown; + +static int fd; +static char buf[8]; + +TEST(dog, testReadPastEof_returnsZero) { + EXPECT_NE(-1, (fd = open("a", O_RDWR | O_CREAT | O_TRUNC, 0644))); + EXPECT_EQ(0, pread(fd, buf, 8, 0)); + EXPECT_EQ(0, close(fd)); +} + +TEST(dog, testReadOverlapsEof_returnsShortNumber) { + EXPECT_NE(-1, (fd = open("b", O_RDWR | O_CREAT | O_TRUNC, 0644))); + EXPECT_EQ(4, pwrite(fd, buf, 4, 0)); + EXPECT_EQ(4, pread(fd, buf, 8, 0)); + EXPECT_EQ(0, close(fd)); +} diff --git a/test/libc/calls/printargs_test.c b/test/libc/calls/printargs_test.c new file mode 100644 index 000000000..25d0f6484 --- /dev/null +++ b/test/libc/calls/printargs_test.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 2022 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/runtime/internal.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +/** + * @fileoverview platform arguments tool + * + * This is intended to integrate with the Emacs keystroke `C-c C-s` + * which will remotely launch it on all the other operating systems and + * print the output. This way we can audit stuff. + */ + +TEST(printargs, test) { + __printargs("%r"); +} diff --git a/test/libc/calls/read_test.c b/test/libc/calls/read_test.c new file mode 100644 index 000000000..20db7ebb4 --- /dev/null +++ b/test/libc/calls/read_test.c @@ -0,0 +1,53 @@ +/*-*- 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/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/sock/internal.h" +#include "libc/sysv/consts/nr.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +static long Read(long fd, void *buf, unsigned long size) { + long ax, di, si, dx; + asm volatile("syscall" + : "=a"(ax), "=D"(di), "=S"(si), "=d"(dx) + : "0"(__NR_read), "1"(fd), "2"(buf), "3"(size) + : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"); + return ax; +} + +BENCH(read, bench) { + char buf[16]; + ASSERT_SYS(0, 3, open("/dev/zero", O_RDONLY)); + EZBENCH2("read", donothing, read(3, buf, 5)); + EZBENCH2("pread", donothing, pread(3, buf, 5, 0)); + EZBENCH2("readv₁", donothing, readv(3, &(struct iovec){buf, 5}, 1)); + EZBENCH2("readv₂", donothing, + readv(3, (struct iovec[]){{buf, 1}, {buf + 1, 4}}, 2)); + EZBENCH2("preadv₁", donothing, preadv(3, &(struct iovec){buf, 5}, 1, 0)); + EZBENCH2("preadv₂", donothing, + preadv(3, (struct iovec[]){{buf, 1}, {buf + 1, 4}}, 2, 0)); + EZBENCH2("sys_read", donothing, sys_read(3, buf, 5)); + EZBENCH2("sys_readv", donothing, sys_readv(3, &(struct iovec){buf, 5}, 1)); + EZBENCH2("Read", donothing, Read(3, buf, 5)); + EZBENCH2("Read", donothing, Read(3, buf, 5)); + ASSERT_SYS(0, 0, close(3)); +} diff --git a/test/libc/calls/readansi_test.c b/test/libc/calls/readansi_test.c index 4c4b10d60..12f4c6e41 100644 --- a/test/libc/calls/readansi_test.c +++ b/test/libc/calls/readansi_test.c @@ -52,6 +52,7 @@ TEST(readansi, test) { EXPECT_STREQ("\xc2\x9bM", b); EXPECT_EQ(0, readansi(fds[0], b, sizeof(b))); EXPECT_STREQ("", b); + close(fds[0]); ASSERT_NE(-1, wait(&ws)); ASSERT_TRUE(WIFEXITED(ws)); ASSERT_EQ(0, WEXITSTATUS(ws)); @@ -73,6 +74,7 @@ TEST(readansi, testOperatingSystemCommand) { EXPECT_STREQ(s, b); EXPECT_EQ(0, readansi(fds[0], b, sizeof(b))); EXPECT_STREQ("", b); + close(fds[0]); ASSERT_NE(-1, wait(&ws)); ASSERT_TRUE(WIFEXITED(ws)); ASSERT_EQ(0, WEXITSTATUS(ws)); diff --git a/test/libc/calls/readlinkat_test.c b/test/libc/calls/readlinkat_test.c index 5f9affb24..b178c07ee 100644 --- a/test/libc/calls/readlinkat_test.c +++ b/test/libc/calls/readlinkat_test.c @@ -31,6 +31,18 @@ char testlib_enable_tmp_setup_teardown; +TEST(readlink, enoent) { + char buf[32]; + ASSERT_SYS(ENOENT, -1, readlink("doesnotexist", buf, 32)); + ASSERT_SYS(ENOENT, -1, readlink("o/doesnotexist", buf, 32)); +} + +TEST(readlink, enotdir) { + char buf[32]; + ASSERT_SYS(0, 0, touch("o", 0644)); + ASSERT_SYS(ENOTDIR, -1, readlink("o/doesnotexist", buf, 32)); +} + TEST(readlinkat, test) { char buf[128], *p, *q; memset(buf, -1, sizeof(buf)); @@ -71,10 +83,8 @@ TEST(readlinkat, frootloop) { ASSERT_SYS(0, 0, symlink("froot", "froot")); ASSERT_SYS(ELOOP, -1, readlink("froot/loop", buf, sizeof(buf))); if (O_NOFOLLOW) { - ASSERT_SYS(IsFreebsd() ? EMLINK - : IsNetbsd() ? EFTYPE - : ELOOP, - -1, open("froot", O_RDONLY | O_NOFOLLOW)); + ASSERT_SYS(IsFreebsd() ? EMLINK : IsNetbsd() ? EFTYPE : ELOOP, -1, + open("froot", O_RDONLY | O_NOFOLLOW)); if (0 && O_PATH) { /* need rhel5 test */ ASSERT_NE(-1, (fd = open("froot", O_RDONLY | O_NOFOLLOW | O_PATH))); ASSERT_NE(-1, close(fd)); @@ -89,3 +99,11 @@ TEST(readlinkat, statReadsNameLength) { EXPECT_TRUE(S_ISLNK(st.st_mode)); EXPECT_EQ(5, st.st_size); } + +TEST(readlinkat, realpathReturnsLongPath) { + if (!IsWindows()) return; + struct stat st; + char buf[PATH_MAX]; + ASSERT_SYS(0, 0, touch("froot", 0644)); + ASSERT_STARTSWITH("//?/", realpath("froot", buf)); +} diff --git a/test/libc/calls/renameat_test.c b/test/libc/calls/renameat_test.c index 51c8ec228..658ee52ba 100644 --- a/test/libc/calls/renameat_test.c +++ b/test/libc/calls/renameat_test.c @@ -24,6 +24,20 @@ char testlib_enable_tmp_setup_teardown; +TEST(rename, enoent) { + EXPECT_SYS(ENOENT, -1, rename("foo", "")); + EXPECT_SYS(ENOENT, -1, rename("", "foo")); + EXPECT_SYS(ENOENT, -1, rename("foo", "o/bar")); + EXPECT_SYS(ENOENT, -1, rename("o/bar", "foo")); +} + +TEST(renameat, enotdir) { + EXPECT_SYS(0, 0, close(creat("yo", 0644))); + EXPECT_SYS(ENOTDIR, -1, rename("yo/there", "hrcue")); + // this test makes platforms crazy + // EXPECT_SYS(ENOTDIR, -1, rename("zoo", "yo/there")); +} + TEST(renameat, testNull_returnsEfault) { ASSERT_SYS(0, 0, close(creat("hello", 0644))); EXPECT_SYS(EFAULT, -1, renameat(AT_FDCWD, 0, AT_FDCWD, 0)); diff --git a/test/libc/calls/seccomp_test.c b/test/libc/calls/seccomp_test.c new file mode 100644 index 000000000..3fe4a74b8 --- /dev/null +++ b/test/libc/calls/seccomp_test.c @@ -0,0 +1,115 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/calls/struct/bpf.h" +#include "libc/calls/struct/filter.h" +#include "libc/calls/struct/iovec.h" +#include "libc/calls/struct/seccomp.h" +#include "libc/errno.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/audit.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/pr.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" +#include "tool/net/sandbox.h" + +void SetUp(void) { + if (!__is_linux_2_6_23()) { + exit(0); + } +} + +TEST(seccompStrictMode, evilProcess_getsKill9d) { + int ws, pid; + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + EXPECT_EQ(0, seccomp(SECCOMP_SET_MODE_STRICT, 0, 0)); + open("/etc/passwd", O_RDWR); + _Exit1(127); + } + EXPECT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFSIGNALED(ws)); + EXPECT_EQ(SIGKILL, WTERMSIG(ws)); +} + +TEST(seccompStrictMode, goodProcess_isAuthorized) { + int ws, pid; + int pfds[2]; + char buf[3] = {0}; + ASSERT_SYS(0, 0, pipe(pfds)); + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + EXPECT_EQ(0, seccomp(SECCOMP_SET_MODE_STRICT, 0, 0)); + write(pfds[1], "hi", 3); + _Exit1(0); + } + EXPECT_SYS(0, 0, close(pfds[1])); + EXPECT_SYS(0, 3, read(pfds[0], buf, 3)); + EXPECT_SYS(0, 0, close(pfds[0])); + EXPECT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); + EXPECT_STREQ("hi", buf); +} + +TEST(seccompFilter, isSoMuchBetter) { + char buf[3] = {0}; + int ws, pid, pfds[2]; + ASSERT_SYS(0, 0, pipe(pfds)); + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + struct sock_filter filter[] = { + _SECCOMP_MACHINE(AUDIT_ARCH_X86_64), // + _SECCOMP_LOAD_SYSCALL_NR(), // + _SECCOMP_ALLOW_SYSCALL(0x0013), // readv + _SECCOMP_ALLOW_SYSCALL(0x0014), // writev + _SECCOMP_ALLOW_SYSCALL(0x0000), // read + _SECCOMP_ALLOW_SYSCALL(0x0001), // write + _SECCOMP_ALLOW_SYSCALL(0x0003), // close + _SECCOMP_ALLOW_SYSCALL(0x000f), // rt_sigreturn + _SECCOMP_ALLOW_SYSCALL(0x00e7), // exit_group + _SECCOMP_ALLOW_SYSCALL(0x0009), // mmap + _SECCOMP_ALLOW_SYSCALL(0x0106), // newfstatat + _SECCOMP_ALLOW_SYSCALL(0x0008), // lseek + _SECCOMP_ALLOW_SYSCALL(0x000b), // munmap + _SECCOMP_ALLOW_SYSCALL(0x00e4), // clock_gettime + _SECCOMP_ALLOW_SYSCALL(0x003f), // uname + _SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM + }; + struct sock_fprog prog = { + .len = ARRAYLEN(filter), + .filter = filter, + }; + ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); + ASSERT_EQ(0, prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)); + ASSERT_SYS(0, 3, write(pfds[1], "hi", 3)); + ASSERT_SYS(EPERM, -1, open("/etc/passwd", O_RDONLY)); + _Exit(0); + } + EXPECT_SYS(0, 0, close(pfds[1])); + EXPECT_SYS(0, 3, read(pfds[0], buf, 3)); + EXPECT_SYS(0, 0, close(pfds[0])); + EXPECT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); + EXPECT_STREQ("hi", buf); +} diff --git a/test/libc/calls/setitimer_test.c b/test/libc/calls/setitimer_test.c new file mode 100644 index 000000000..d858c22c4 --- /dev/null +++ b/test/libc/calls/setitimer_test.c @@ -0,0 +1,57 @@ +/*-*- 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 2022 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/sigbits.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/struct/sigset.h" +#include "libc/calls/ucontext.h" +#include "libc/sysv/consts/itimer.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" +#include "libc/time/time.h" + +bool gotsig; + +void OnSigAlrm(int sig, siginfo_t *si, ucontext_t *ctx) { + EXPECT_EQ(SIGALRM, sig); + EXPECT_EQ(SIGALRM, si->si_signo); + gotsig = true; +} + +TEST(setitimer, testSingleShot) { + sigset_t block, oldmask; + struct sigaction oldalrm; + struct itimerval it = {{0, 0}, {0, 10000}}; + struct sigaction sa = {.sa_sigaction = OnSigAlrm, + .sa_flags = SA_RESETHAND | SA_SIGINFO}; + gotsig = false; + sigemptyset(&block); + sigaddset(&block, SIGALRM); + EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &block, &oldmask)); + ASSERT_EQ(0, sigaction(SIGALRM, &sa, &oldalrm)); + ASSERT_EQ(0, setitimer(ITIMER_REAL, &it, 0)); + sigdelset(&block, SIGALRM); + EXPECT_EQ(-1, sigsuspend(&block)); + EXPECT_EQ(0, sigprocmask(SIG_SETMASK, &oldmask, 0)); + EXPECT_EQ(0, sigaction(SIGUSR1, &oldalrm, 0)); + EXPECT_EQ(true, gotsig); +} diff --git a/test/libc/calls/setrlimit_test.c b/test/libc/calls/setrlimit_test.c index 78d3521e9..1fcf0e440 100644 --- a/test/libc/calls/setrlimit_test.c +++ b/test/libc/calls/setrlimit_test.c @@ -22,6 +22,7 @@ #include "libc/calls/sigbits.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/sigaction.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/log/check.h" @@ -42,7 +43,7 @@ #define MEM (64 * 1024 * 1024) -char tmpfile[PATH_MAX]; +static char tmpname[PATH_MAX]; void OnSigxcpu(int sig) { ASSERT_EQ(SIGXCPU, sig); @@ -50,7 +51,7 @@ void OnSigxcpu(int sig) { } void OnSigxfsz(int sig) { - unlink(tmpfile); + unlink(tmpname); ASSERT_EQ(SIGXFSZ, sig); _exit(0); } @@ -95,16 +96,16 @@ TEST(setrlimit, testFileSizeLimit) { ASSERT_EQ(0, getrlimit(RLIMIT_FSIZE, &rlim)); rlim.rlim_cur = 1024 * 1024; /* set soft limit to one megabyte */ ASSERT_EQ(0, setrlimit(RLIMIT_FSIZE, &rlim)); - snprintf(tmpfile, sizeof(tmpfile), "%s/%s.%d", + snprintf(tmpname, sizeof(tmpname), "%s/%s.%d", firstnonnull(getenv("TMPDIR"), "/tmp"), program_invocation_short_name, getpid()); - ASSERT_NE(-1, (fd = open(tmpfile, O_RDWR | O_CREAT | O_TRUNC))); + ASSERT_NE(-1, (fd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC))); rngset(junkdata, 512, rand64, -1); for (i = 0; i < 5 * 1024 * 1024 / 512; ++i) { ASSERT_EQ(512, write(fd, junkdata, 512)); } close(fd); - unlink(tmpfile); + unlink(tmpname); _exit(1); } EXPECT_TRUE(WIFEXITED(wstatus)); @@ -114,25 +115,30 @@ TEST(setrlimit, testFileSizeLimit) { } int SetKernelEnforcedMemoryLimit(size_t n) { - struct rlimit rlim = {n, n}; - if (IsWindows() || IsXnu()) return -1; - return setrlimit(!IsOpenbsd() ? RLIMIT_AS : RLIMIT_DATA, &rlim); + struct rlimit rlim; + getrlimit(RLIMIT_AS, &rlim); + rlim.rlim_cur = n; + return setrlimit(RLIMIT_AS, &rlim); } TEST(setrlimit, testMemoryLimit) { char *p; + bool gotsome; int i, wstatus; - if (IsAsan()) return; /* b/c we use sys_mmap */ - if (IsXnu()) return; /* doesn't work on darwin */ - if (IsWindows()) return; /* of course it doesn't work on windows */ + if (IsAsan()) return; /* b/c we use sys_mmap */ ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, SetKernelEnforcedMemoryLimit(MEM)); - for (i = 0; i < (MEM * 2) / PAGESIZE; ++i) { - p = sys_mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) - .addr; - if (p == MAP_FAILED) { + for (gotsome = i = 0; i < (MEM * 2) / PAGESIZE; ++i) { + p = mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0); + if (p != MAP_FAILED) { + gotsome = true; + } else { + if (!IsNetbsd()) { + // TODO(jart): what's going on with NetBSD? + ASSERT_TRUE(gotsome); + } ASSERT_EQ(ENOMEM, errno); _exit(0); } diff --git a/test/libc/calls/sigaction_test.c b/test/libc/calls/sigaction_test.c index 1d9d7c8e2..fe4983c30 100644 --- a/test/libc/calls/sigaction_test.c +++ b/test/libc/calls/sigaction_test.c @@ -39,37 +39,10 @@ void OnSigInt(int sig) { void SetUp(void) { gotsigint = false; - /* TODO(jart): Windows needs huge signal overhaul */ - if (IsWindows()) exit(0); } -TEST(sigaction, test) { - int pid, status; - sigset_t block, ignore, oldmask; - struct sigaction saint = {.sa_handler = OnSigInt}; - sigemptyset(&block); - sigaddset(&block, SIGINT); - EXPECT_NE(-1, sigprocmask(SIG_BLOCK, &block, &oldmask)); - sigfillset(&ignore); - sigdelset(&ignore, SIGINT); - EXPECT_NE(-1, sigaction(SIGINT, &saint, &oldsa)); - ASSERT_NE(-1, (pid = fork())); - if (!pid) { - EXPECT_NE(-1, kill(getppid(), SIGINT)); - EXPECT_EQ(-1, sigsuspend(&ignore)); - EXPECT_EQ(EINTR, errno); - EXPECT_TRUE(gotsigint); - _exit(0); - } - EXPECT_EQ(-1, sigsuspend(&ignore)); - EXPECT_NE(-1, kill(pid, SIGINT)); - EXPECT_NE(-1, waitpid(pid, &status, 0)); - EXPECT_EQ(1, WIFEXITED(status)); - EXPECT_EQ(0, WEXITSTATUS(status)); - EXPECT_EQ(0, WTERMSIG(status)); - EXPECT_NE(-1, sigprocmask(SIG_SETMASK, &oldmask, NULL)); - EXPECT_NE(-1, sigaction(SIGINT, &oldsa, NULL)); -} +//////////////////////////////////////////////////////////////////////////////// +// test raise() TEST(sigaction, raise) { struct sigaction saint = {.sa_handler = OnSigInt}; @@ -80,6 +53,58 @@ TEST(sigaction, raise) { EXPECT_NE(-1, sigaction(SIGINT, &oldsa, NULL)); } +//////////////////////////////////////////////////////////////////////////////// +// test kill() + +TEST(sigaction, testPingPongParentChildWithSigint) { + int pid, status; + sigset_t blockint, oldmask; + struct sigaction oldint; + struct sigaction ignoreint = {.sa_handler = SIG_IGN}; + struct sigaction catchint = {.sa_handler = OnSigInt}; + if (IsWindows()) { + // this works if it's run by itself on the command prompt. but it + // doesn't currently work if it's launched as a subprocess of some + // kind of runner. todo(fixme!) + return; + } + EXPECT_NE(-1, sigemptyset(&blockint)); + EXPECT_NE(-1, sigaddset(&blockint, SIGINT)); + EXPECT_NE(-1, sigprocmask(SIG_BLOCK, &blockint, &oldmask)); + EXPECT_NE(-1, sigaction(SIGINT, &catchint, &oldint)); + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + // ping + EXPECT_NE(-1, kill(getppid(), SIGINT)); + EXPECT_FALSE(gotsigint); + // pong + EXPECT_NE(-1, sigaction(SIGINT, &catchint, 0)); + EXPECT_EQ(-1, sigsuspend(0)); + EXPECT_EQ(EINTR, errno); + EXPECT_TRUE(gotsigint); + _exit(0); + } + // pong + EXPECT_FALSE(gotsigint); + EXPECT_NE(-1, sigaction(SIGINT, &catchint, 0)); + EXPECT_EQ(-1, sigsuspend(0)); + EXPECT_TRUE(gotsigint); + // ping + EXPECT_NE(-1, sigaction(SIGINT, &ignoreint, 0)); + EXPECT_NE(-1, kill(pid, SIGINT)); + // cleanup + EXPECT_NE(-1, wait4(pid, &status, 0, 0)); + EXPECT_EQ(1, WIFEXITED(status)); + EXPECT_EQ(0, WEXITSTATUS(status)); + EXPECT_EQ(0, WTERMSIG(status)); + EXPECT_NE(-1, sigaction(SIGINT, &oldint, 0)); + EXPECT_NE(-1, sigprocmask(SIG_BLOCK, &oldmask, 0)); +} + +//////////////////////////////////////////////////////////////////////////////// +// test int3 crash +// we expect this to be recoverable by default + volatile int trapeax; void OnTrap(int sig, struct siginfo *si, struct ucontext *ctx) { @@ -94,11 +119,19 @@ TEST(sigaction, debugBreak_handlerCanReadCpuState) { EXPECT_NE(-1, sigaction(SIGTRAP, &oldsa, NULL)); } -void OnFpe(int sig, struct siginfo *si, struct ucontext *ctx) { +//////////////////////////////////////////////////////////////////////////////// +// test fpu crash (unrecoverable) +// test signal handler can modify cpu registers (now it's recoverable!) + +void SkipOverFaultingInstruction(struct ucontext *ctx) { struct XedDecodedInst xedd; xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15); ctx->uc_mcontext.rip += xedd.length; +} + +void OnFpe(int sig, struct siginfo *si, struct ucontext *ctx) { + SkipOverFaultingInstruction(ctx); ctx->uc_mcontext.rax = 42; ctx->uc_mcontext.rdx = 0; } diff --git a/test/libc/calls/signal_test.c b/test/libc/calls/signal_test.c index 3c1330b09..7dc90e833 100644 --- a/test/libc/calls/signal_test.c +++ b/test/libc/calls/signal_test.c @@ -24,13 +24,12 @@ #include "libc/sysv/consts/sig.h" #include "libc/testlib/testlib.h" -testonly void OnCtrlC(int sig) { +testonly void OnUsr1(int sig) { _exit(0); } TEST(signal, test) { - if (IsWindows()) return; /* omg */ - ASSERT_NE(SIG_ERR, signal(SIGINT, OnCtrlC)); - ASSERT_NE(-1, raise(SIGINT)); + ASSERT_NE(SIG_ERR, signal(SIGUSR1, OnUsr1)); + ASSERT_NE(-1, raise(SIGUSR1)); __die(); } diff --git a/test/libc/calls/sigprocmask_test.c b/test/libc/calls/sigprocmask_test.c new file mode 100644 index 000000000..51836565e --- /dev/null +++ b/test/libc/calls/sigprocmask_test.c @@ -0,0 +1,77 @@ +/*-*- 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 2022 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/sigbits.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/struct/sigset.h" +#include "libc/calls/ucontext.h" +#include "libc/dce.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" + +volatile int n; + +void OnSig(int sig, siginfo_t *si, ucontext_t *ctx) { + ++n; +} + +TEST(sigprocmask, testMultipleBlockedDeliveries) { + int pid, ws; + sigset_t neu, old; + struct sigaction oldusr1, oldusr2; + struct sigaction sa = {.sa_sigaction = OnSig, .sa_flags = SA_SIGINFO}; + n = 0; + sigemptyset(&neu); + sigaddset(&neu, SIGUSR1); + sigaddset(&neu, SIGUSR2); + EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &neu, &old)); + ASSERT_EQ(0, sigaction(SIGUSR1, &sa, &oldusr1)); + ASSERT_EQ(0, sigaction(SIGUSR2, &sa, &oldusr2)); + ASSERT_EQ(0, raise(SIGUSR1)); + ASSERT_EQ(0, raise(SIGUSR2)); + EXPECT_EQ(0, n); + EXPECT_EQ(0, sigprocmask(SIG_SETMASK, &old, NULL)); + EXPECT_EQ(0, sigaction(SIGUSR1, &oldusr1, 0)); + EXPECT_EQ(0, sigaction(SIGUSR2, &oldusr2, 0)); + ASSERT_EQ(2, n); +} + +TEST(sigprocmask, testMultipleBlockedDeliveriesOfSameSignal) { + int pid, ws; + sigset_t neu, old; + struct sigaction oldusr2; + struct sigaction sa = {.sa_sigaction = OnSig, .sa_flags = SA_SIGINFO}; + n = 0; + sigemptyset(&neu); + sigaddset(&neu, SIGUSR2); + EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &neu, &old)); + ASSERT_EQ(0, sigaction(SIGUSR2, &sa, &oldusr2)); + ASSERT_EQ(0, raise(SIGUSR2)); + ASSERT_EQ(0, raise(SIGUSR2)); + EXPECT_EQ(0, n); + EXPECT_EQ(0, sigprocmask(SIG_SETMASK, &old, NULL)); + EXPECT_EQ(0, sigaction(SIGUSR2, &oldusr2, 0)); + if (IsFreebsd() || IsWindows()) { + EXPECT_EQ(2, n); + } else { + EXPECT_EQ(1, n); + } +} diff --git a/test/libc/calls/sigsuspend_test.c b/test/libc/calls/sigsuspend_test.c new file mode 100644 index 000000000..0772c8ef9 --- /dev/null +++ b/test/libc/calls/sigsuspend_test.c @@ -0,0 +1,115 @@ +/*-*- 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 2022 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/sigbits.h" +#include "libc/calls/struct/sigset.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +volatile bool gotsig1; +volatile bool gotsig2; +volatile bool finished; + +void OnSigQueuing(int sig, siginfo_t *si, ucontext_t *ctx) { + if (!finished) { + EXPECT_EQ(SIGUSR2, sig); + EXPECT_EQ(SIGUSR2, si->si_signo); + gotsig2 = true; + } else { + EXPECT_EQ(SIGUSR1, sig); + EXPECT_EQ(SIGUSR1, si->si_signo); + gotsig1 = true; + } +} + +TEST(sigsuspend, testSignalQueuingSelf) { + sigset_t neu, old, bits; + struct sigaction oldusr1, oldusr2; + struct sigaction sa = {.sa_sigaction = OnSigQueuing, .sa_flags = SA_SIGINFO}; + gotsig1 = false; + gotsig2 = false; + finished = false; + sigemptyset(&neu); + sigaddset(&neu, SIGUSR1); + sigaddset(&neu, SIGUSR2); + EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &neu, &old)); + ASSERT_EQ(0, sigaction(SIGUSR1, &sa, &oldusr1)); + ASSERT_EQ(0, sigaction(SIGUSR2, &sa, &oldusr2)); + raise(SIGUSR1); + raise(SIGUSR2); + sigdelset(&neu, SIGUSR2); + EXPECT_EQ(false, gotsig2); + memcpy(&bits, &neu, sizeof(bits)); + ASSERT_EQ(-1, sigsuspend(&neu)); // raises SIGUSR2 + EXPECT_EQ(0, memcmp(&bits, &neu, sizeof(bits))); // constness respected + EXPECT_EQ(EINTR, errno); + EXPECT_EQ(true, gotsig2); + EXPECT_EQ(false, gotsig1); + finished = true; + EXPECT_EQ(0, sigprocmask(SIG_SETMASK, &old, NULL)); // raises SIGUSR1 + EXPECT_EQ(true, gotsig1); + EXPECT_EQ(0, sigaction(SIGUSR1, &oldusr1, 0)); + EXPECT_EQ(0, sigaction(SIGUSR2, &oldusr2, 0)); +} + +TEST(sigsuspend, testSignalQueuingIpc) { + if (IsWindows()) { + // xxx: probably need a signal server to do this kind of signalling + return; + } + int pid, ws; + sigset_t neu, old, bits; + struct sigaction oldusr1, oldusr2; + struct sigaction sa = {.sa_sigaction = OnSigQueuing, .sa_flags = SA_SIGINFO}; + gotsig1 = false; + gotsig2 = false; + finished = false; + sigemptyset(&neu); + sigaddset(&neu, SIGUSR1); + sigaddset(&neu, SIGUSR2); + EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &neu, &old)); + ASSERT_EQ(0, sigaction(SIGUSR1, &sa, &oldusr1)); + ASSERT_EQ(0, sigaction(SIGUSR2, &sa, &oldusr2)); + pid = getpid(); + ASSERT_NE(-1, (ws = xspawn(0))); + if (ws == -2) { + kill(pid, SIGUSR1); + kill(pid, SIGUSR2); + _exit(0); + } + sigdelset(&neu, SIGUSR2); + EXPECT_EQ(false, gotsig2); + memcpy(&bits, &neu, sizeof(bits)); + ASSERT_EQ(-1, sigsuspend(&neu)); // raises SIGUSR2 + EXPECT_EQ(0, memcmp(&bits, &neu, sizeof(bits))); // constness respected + EXPECT_EQ(EINTR, errno); + EXPECT_EQ(true, gotsig2); + EXPECT_EQ(false, gotsig1); + finished = true; + EXPECT_EQ(0, sigprocmask(SIG_SETMASK, &old, NULL)); // raises SIGUSR1 + EXPECT_EQ(true, gotsig1); + EXPECT_EQ(0, sigaction(SIGUSR1, &oldusr1, 0)); + EXPECT_EQ(0, sigaction(SIGUSR2, &oldusr2, 0)); +} diff --git a/test/libc/calls/stat_test.c b/test/libc/calls/stat_test.c index c51f5f8ad..61526d11f 100644 --- a/test/libc/calls/stat_test.c +++ b/test/libc/calls/stat_test.c @@ -17,6 +17,8 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/metastat.internal.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" #include "libc/errno.h" @@ -24,6 +26,7 @@ #include "libc/runtime/gc.internal.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" +#include "libc/sysv/consts/at.h" #include "libc/sysv/consts/nr.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" @@ -43,6 +46,7 @@ TEST(stat_010, testEmptyFile_sizeIsZero) { TEST(stat, enoent) { ASSERT_SYS(ENOENT, -1, stat("hi", 0)); + ASSERT_SYS(ENOENT, -1, stat("o/doesnotexist", 0)); } TEST(stat, enotdir) { @@ -67,18 +71,34 @@ static long Stat(const char *path, struct stat *st) { return ax; } +static long Fstatat(const char *path, struct stat *st) { + long ax, di, si, dx; + register long r10 asm("r10") = 0; + asm volatile("syscall" + : "=a"(ax), "=D"(di), "=S"(si), "=d"(dx), "+r"(r10) + : "0"(__NR_fstatat), "1"(AT_FDCWD), "2"(path), "3"(st) + : "rcx", "r8", "r9", "r11", "memory", "cc"); + return ax; +} + BENCH(stat, bench) { struct stat st; + union metastat ms; EXPECT_SYS(0, 0, makedirs(".python/test", 0755)); + EZBENCH2("__stat2cosmo", donothing, __stat2cosmo(&st, &ms)); EXPECT_SYS(0, 0, touch(".python/test/" "tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt", 0644)); - if (!IsWindows()) { + if (!IsWindows() && !IsFreebsd()) { EZBENCH2("stat syscall", donothing, Stat(".python/test/" "tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt", &st)); + EZBENCH2("fstatat syscall", donothing, + Fstatat(".python/test/" + "tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt", + &st)); } EZBENCH2("stat() fs", donothing, stat(".python/test/" diff --git a/test/libc/calls/symlinkat_test.c b/test/libc/calls/symlinkat_test.c new file mode 100644 index 000000000..c8d06f68e --- /dev/null +++ b/test/libc/calls/symlinkat_test.c @@ -0,0 +1,62 @@ +/*-*- 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 2022 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/struct/stat.h" +#include "libc/fmt/fmt.h" +#include "libc/fmt/itoa.h" +#include "libc/rand/rand.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/at.h" +#include "libc/testlib/testlib.h" + +char testlib_enable_tmp_setup_teardown; +char p[2][PATH_MAX]; +struct stat st; + +TEST(symlink, enoent) { + ASSERT_SYS(ENOENT, -1, symlink("o/foo", "")); + ASSERT_SYS(ENOENT, -1, symlink("o/foo", "o/bar")); +} + +TEST(symlinkat, enotdir) { + ASSERT_SYS(0, 0, close(creat("yo", 0644))); + ASSERT_SYS(ENOTDIR, -1, symlink("hrcue", "yo/there")); +} + +TEST(symlinkat, test) { + sprintf(p[0], "%s.%d", program_invocation_short_name, rand()); + sprintf(p[1], "%s.%d", program_invocation_short_name, rand()); + + EXPECT_EQ(0, touch(p[0], 0644)); + EXPECT_EQ(0, symlink(p[0], p[1])); + + // check the normal file + EXPECT_FALSE(issymlink(p[0])); + EXPECT_EQ(0, lstat(p[0], &st)); + EXPECT_FALSE(S_ISLNK(st.st_mode)); + + // check the symlink file + EXPECT_TRUE(issymlink(p[1])); + EXPECT_EQ(0, lstat(p[1], &st)); + EXPECT_TRUE(S_ISLNK(st.st_mode)); + + // symlink isn't a symlink if we use it normally + EXPECT_EQ(0, stat(p[1], &st)); + EXPECT_FALSE(S_ISLNK(st.st_mode)); +} diff --git a/test/libc/calls/unlinkat_test.c b/test/libc/calls/unlinkat_test.c new file mode 100644 index 000000000..b744ce80b --- /dev/null +++ b/test/libc/calls/unlinkat_test.c @@ -0,0 +1,52 @@ +/*-*- 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 2022 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/dce.h" +#include "libc/sysv/consts/at.h" +#include "libc/testlib/testlib.h" + +char testlib_enable_tmp_setup_teardown; + +TEST(unlink, efault) { + ASSERT_SYS(EFAULT, -1, unlink(0)); + if (IsWindows() && !IsAsan()) return; // not possible + ASSERT_SYS(EFAULT, -1, unlink((void *)77)); +} + +TEST(unlink, enoent) { + ASSERT_SYS(ENOENT, -1, unlink("")); + ASSERT_SYS(ENOENT, -1, unlink("doesnotexist")); + ASSERT_SYS(ENOENT, -1, unlink("o/doesnotexist")); +} + +TEST(unlink, enotdir) { + ASSERT_SYS(0, 0, touch("o", 0644)); + ASSERT_SYS(ENOTDIR, -1, unlink("o/doesnotexist")); +} + +TEST(unlinkat, test) { + int i, fd; + EXPECT_EQ(0, touch("mytmp", 0644)); + EXPECT_EQ(0, unlinkat(AT_FDCWD, "mytmp", 0)); + for (i = 0; i < 8; ++i) { + EXPECT_NE(-1, (fd = creat("mytmp", 0644))); + EXPECT_EQ(0, close(fd)); + EXPECT_EQ(0, unlinkat(AT_FDCWD, "mytmp", 0)); + } +} diff --git a/test/libc/calls/write_test.c b/test/libc/calls/write_test.c index 476b349a8..39e068529 100644 --- a/test/libc/calls/write_test.c +++ b/test/libc/calls/write_test.c @@ -37,6 +37,7 @@ static long Write(long fd, const void *data, unsigned long size) { BENCH(write, bench) { ASSERT_SYS(0, 3, open("/dev/null", O_WRONLY)); EZBENCH2("write", donothing, write(3, "hello", 5)); + EZBENCH2("writev", donothing, writev(3, &(struct iovec){"hello", 5}, 1)); EZBENCH2("sys_write", donothing, sys_write(3, "hello", 5)); EZBENCH2("sys_writev", donothing, sys_writev(3, &(struct iovec){"hello", 5}, 1)); diff --git a/test/libc/fmt/atoi_test.c b/test/libc/fmt/atoi_test.c index 0b491c9dc..1b0fc92c3 100644 --- a/test/libc/fmt/atoi_test.c +++ b/test/libc/fmt/atoi_test.c @@ -23,6 +23,13 @@ #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" +void __on_arithmetic_overflow(void) { + // prevent -ftrapv crashes + // + // for some reason gcc generates trap code even when we're doing it + // manually with __builtin_mul_overflow() :'( +} + TEST(atoi, test) { EXPECT_EQ(0, atoi("")); EXPECT_EQ(0, atoi("-b")); @@ -306,24 +313,24 @@ TEST(strtoimax, testEndPtr) { ASSERT_EQ(1, e - p); } -TEST(strtoimax, testLimits) { +TEST(strtoi128, testLimits) { EXPECT_EQ( - ((uintmax_t)0xffffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff, - strtoimax("-1", NULL, 0)); + ((uint128_t)0xffffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff, + strtoi128("-1", NULL, 0)); EXPECT_EQ( - ((uintmax_t)0x7fffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff, - strtoimax("0x7fffffffffffffffffffffffffffffff", NULL, 0)); + ((uint128_t)0x7fffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff, + strtoi128("0x7fffffffffffffffffffffffffffffff", NULL, 0)); } -TEST(strtoimax, testOutsideLimit) { +TEST(strtoi128, testOutsideLimit) { errno = 0; EXPECT_EQ( - ((uintmax_t)0x7fffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff, - strtoimax("0x80000000000000000000000000000000", NULL, 0)); + ((uint128_t)0x7fffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff, + strtoi128("0x80000000000000000000000000000000", NULL, 0)); EXPECT_EQ(ERANGE, errno); errno = 0; - EXPECT_EQ(((uintmax_t)0x8000000000000000) << 64 | 0x0000000000000000, - strtoimax("-0x80000000000000000000000000000001", NULL, 0)); + EXPECT_EQ(((uint128_t)0x8000000000000000) << 64 | 0x0000000000000000, + strtoi128("-0x80000000000000000000000000000001", NULL, 0)); EXPECT_EQ(ERANGE, errno); } @@ -335,6 +342,7 @@ TEST(strtoul, neghex) { TEST(strtoumax, testZero) { EXPECT_EQ(UINTMAX_MIN, strtoumax("0", NULL, 0)); + EXPECT_EQ(UINT128_MIN, strtou128("0", NULL, 0)); } TEST(strtoumax, testDecimal) { EXPECT_EQ(123, strtoumax("123", NULL, 0)); @@ -353,16 +361,16 @@ TEST(strtoumax, testBinary) { EXPECT_EQ(42, strtoumax("0b101010", NULL, 2)); } -TEST(strtoumax, testMaximum) { - EXPECT_EQ(UINTMAX_MAX, - strtoumax("340282366920938463463374607431768211455", NULL, 0)); - EXPECT_EQ(UINTMAX_MAX, - strtoumax("0xffffffffffffffffffffffffffffffff", NULL, 0)); +TEST(strtou128, test128imum) { + EXPECT_EQ(UINT128_MAX, + strtou128("340282366920938463463374607431768211455", NULL, 0)); + EXPECT_EQ(UINT128_MAX, + strtou128("0xffffffffffffffffffffffffffffffff", NULL, 0)); } -TEST(strtoumax, testTwosBane) { - EXPECT_EQ(((uintmax_t)0x8000000000000000) << 64 | 0x0000000000000000, - strtoumax("0x80000000000000000000000000000000", NULL, 0)); +TEST(strtou128, testTwosBane) { + EXPECT_EQ(((uint128_t)0x8000000000000000) << 64 | 0x0000000000000000, + strtou128("0x80000000000000000000000000000000", NULL, 0)); } TEST(wcstol, test) { @@ -566,4 +574,12 @@ BENCH(atoi, bench) { EXPROPRIATE(wcstoimax(VEIL("r", L"100000000"), 0, 10))); EZBENCH2("wcstoumax 10⁸", donothing, EXPROPRIATE(wcstoimax(VEIL("r", L"100000000"), 0, 10))); + EZBENCH2("strtoi128 10⁸", donothing, + EXPROPRIATE(strtoi128(VEIL("r", "100000000"), 0, 10))); + EZBENCH2("strtou128 10⁸", donothing, + EXPROPRIATE(strtoi128(VEIL("r", "100000000"), 0, 10))); + EZBENCH2("wcstoi128 10⁸", donothing, + EXPROPRIATE(wcstoi128(VEIL("r", L"100000000"), 0, 10))); + EZBENCH2("wcstou128 10⁸", donothing, + EXPROPRIATE(wcstoi128(VEIL("r", L"100000000"), 0, 10))); } diff --git a/test/libc/fmt/basename_test.c b/test/libc/fmt/basename_test.c index be234e6d8..60eb8ae42 100644 --- a/test/libc/fmt/basename_test.c +++ b/test/libc/fmt/basename_test.c @@ -21,25 +21,33 @@ #include "libc/mem/mem.h" #include "libc/testlib/testlib.h" -TEST(basename, test) { - EXPECT_STREQ("", basename("")); - EXPECT_STREQ("/", basename("/")); - EXPECT_STREQ("hello", basename("hello")); - EXPECT_STREQ("there", basename("hello/there")); - EXPECT_STREQ("yo", basename("hello/there/yo")); +#define BASENAME(x) basename(gc(strdup(x))) + +TEST(basename, testRegularExamples) { + EXPECT_STREQ("lib", BASENAME("/usr/lib")); + EXPECT_STREQ("lib", BASENAME("usr/lib")); + EXPECT_STREQ("usr", BASENAME("/usr/")); + EXPECT_STREQ("usr", BASENAME("usr")); + EXPECT_STREQ("/", BASENAME("/")); + EXPECT_STREQ(".", BASENAME(".")); + EXPECT_STREQ("..", BASENAME("..")); +} + +TEST(basename, testIrregularExamples) { + EXPECT_STREQ(".", basename(0)); + EXPECT_STREQ(".", basename("")); } TEST(basename, testTrailingSlash_isIgnored) { - /* should be "foo" but basename() doesn't allocate memory */ - EXPECT_STREQ("foo/", basename("foo/")); - EXPECT_STREQ("foo//", basename("foo//")); + EXPECT_STREQ("foo", BASENAME("foo/")); + EXPECT_STREQ("foo", BASENAME("foo//")); } TEST(basename, testOnlySlashes_oneSlashOnlyVasily) { - EXPECT_STREQ("/", basename("///")); + EXPECT_STREQ("/", BASENAME("///")); } TEST(basename, testWindows_isGrantedRespect) { - EXPECT_STREQ("there", basename("hello\\there")); - EXPECT_STREQ("yo", basename("hello\\there\\yo")); + EXPECT_STREQ("there", BASENAME("hello\\there")); + EXPECT_STREQ("yo", BASENAME("hello\\there\\yo")); } diff --git a/test/libc/fmt/dirname_test.c b/test/libc/fmt/dirname_test.c index 02542b87e..42e089209 100644 --- a/test/libc/fmt/dirname_test.c +++ b/test/libc/fmt/dirname_test.c @@ -26,12 +26,11 @@ TEST(dirname, test) { EXPECT_STREQ("/usr/lib", dirname(gc(strdup("/usr/lib/foo.bar")))); EXPECT_STREQ("/usr", dirname(gc(strdup("/usr/lib")))); - EXPECT_STREQ("/usr", dirname(gc(strdup("/usr/lib")))); EXPECT_STREQ("usr", dirname(gc(strdup("usr/lib")))); EXPECT_STREQ("/", dirname(gc(strdup("/usr/")))); + EXPECT_STREQ(".", dirname(gc(strdup("usr")))); EXPECT_STREQ("/", dirname(gc(strdup("/")))); - EXPECT_STREQ(".", dirname(gc(strdup("hello")))); EXPECT_STREQ(".", dirname(gc(strdup(".")))); EXPECT_STREQ(".", dirname(gc(strdup("..")))); - EXPECT_STREQ("", dirname(gc(strdup("")))); + EXPECT_STREQ(".", dirname(gc(strdup("")))); } diff --git a/test/libc/fmt/formatbinary64_test.c b/test/libc/fmt/formatbinary64_test.c new file mode 100644 index 000000000..930a946d8 --- /dev/null +++ b/test/libc/fmt/formatbinary64_test.c @@ -0,0 +1,98 @@ +/*-*- 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 2022 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/fmt/fmt.h" +#include "libc/fmt/itoa.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +char buf[67]; + +void SetUp(void) { + memset(buf, 0x55, sizeof(buf)); +} + +TEST(FormatBinary64, test1) { + EXPECT_EQ(1, FormatBinary64(buf, 0, 2) - buf); + EXPECT_STREQ("0", buf); +} + +TEST(FormatBinary64, test2) { + EXPECT_EQ(1, FormatBinary64(buf, 0, 0) - buf); + EXPECT_STREQ("0", buf); + EXPECT_EQ(3, FormatBinary64(buf, 0, 1) - buf); + EXPECT_STREQ("0b0", buf); +} + +TEST(FormatBinary64, test3) { + EXPECT_EQ(3, FormatBinary64(buf, 1, 2) - buf); + EXPECT_STREQ("0b1", buf); +} + +TEST(FormatBinary64, test4) { + EXPECT_EQ(1, FormatBinary64(buf, 1, 0) - buf); + EXPECT_STREQ("1", buf); +} + +TEST(FormatBinary64, test5) { + EXPECT_EQ(66, FormatBinary64(buf, 01777777777777777777777UL, 2) - buf); + EXPECT_STREQ( + "0b1111111111111111111111111111111111111111111111111111111111111111", + buf); +} + +TEST(FormatBinary64, test6) { + EXPECT_EQ(64, FormatBinary64(buf, 01777777777777777777777UL, 0) - buf); + EXPECT_STREQ( + "1111111111111111111111111111111111111111111111111111111111111111", buf); +} + +TEST(FormatBinary64, test7) { + EXPECT_EQ(66, FormatBinary64(buf, 0xEBF2AA499B9028EAul, 2) - buf); + EXPECT_STREQ( + "0b1110101111110010101010100100100110011011100100000010100011101010", + buf); +} + +TEST(FormatBinary64, test8) { + EXPECT_EQ(66, FormatBinary64(buf, 0x00F2AA499B9028EAul, 2) - buf); + EXPECT_STREQ( + "0b0000000011110010101010100100100110011011100100000010100011101010", + buf); +} + +TEST(FormatBinary64, testScalesToWordSizes) { + EXPECT_EQ(8 + 2, FormatBinary64(buf, 13, 2) - buf); + EXPECT_STREQ("0b00001101", buf); + EXPECT_EQ(16 + 2, FormatBinary64(buf, 31337, 2) - buf); + EXPECT_STREQ("0b0111101001101001", buf); + EXPECT_EQ(32 + 2, FormatBinary64(buf, 65536, 2) - buf); + EXPECT_STREQ("0b00000000000000010000000000000000", buf); +} + +BENCH(FormatBinary64, bench) { + EZBENCH2("FormatUint64 tiny", donothing, FormatUint64(buf, 1)); + EZBENCH2("FormatOctal64 tiny", donothing, FormatOctal64(buf, 1, true)); + EZBENCH2("FormatBinary64 tiny", donothing, FormatBinary64(buf, 1, 2)); + EZBENCH2("FormatUint64 big", donothing, + FormatUint64(buf, 01777777777777777777777UL)); + EZBENCH2("FormatOctal64 big", donothing, + FormatOctal64(buf, 01777777777777777777777UL, true)); + EZBENCH2("FormatBinary64 big", donothing, + FormatBinary64(buf, 01777777777777777777777UL, 2)); +} diff --git a/test/libc/fmt/formatflex64_test.c b/test/libc/fmt/formatflex64_test.c new file mode 100644 index 000000000..974966272 --- /dev/null +++ b/test/libc/fmt/formatflex64_test.c @@ -0,0 +1,34 @@ +/*-*- 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 2022 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/fmt/fmt.h" +#include "libc/fmt/itoa.h" +#include "libc/testlib/testlib.h" + +char buf[25]; + +void SetUp(void) { + memset(buf, 0x55, sizeof(buf)); +} + +TEST(formatflex64, test) { + EXPECT_EQ(5, FormatFlex64(buf, 31337, 2) - buf); + EXPECT_STREQ("31337", buf); + EXPECT_EQ(10, FormatFlex64(buf, 0x80000000, 2) - buf); + EXPECT_STREQ("0x80000000", buf); +} diff --git a/test/libc/fmt/formathex64_test.c b/test/libc/fmt/formathex64_test.c new file mode 100644 index 000000000..9b41dda2f --- /dev/null +++ b/test/libc/fmt/formathex64_test.c @@ -0,0 +1,87 @@ +/*-*- 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 2022 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/fmt/fmt.h" +#include "libc/fmt/itoa.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +char buf[19]; + +void SetUp(void) { + memset(buf, 0x55, sizeof(buf)); +} + +TEST(FormatHex64, test1) { + EXPECT_EQ(1, FormatHex64(buf, 0, 2) - buf); + EXPECT_STREQ("0", buf); +} + +TEST(FormatHex64, test2) { + EXPECT_EQ(1, FormatHex64(buf, 0, 0) - buf); + EXPECT_STREQ("0", buf); + EXPECT_EQ(3, FormatHex64(buf, 0, 1) - buf); + EXPECT_STREQ("0x0", buf); +} + +TEST(FormatHex64, test3) { + EXPECT_EQ(4, FormatHex64(buf, 1, 2) - buf); + EXPECT_STREQ("0x01", buf); +} + +TEST(FormatHex64, test4) { + EXPECT_EQ(1, FormatHex64(buf, 1, 0) - buf); + EXPECT_STREQ("1", buf); +} + +TEST(FormatHex64, test5) { + EXPECT_EQ(18, FormatHex64(buf, 01777777777777777777777UL, 2) - buf); + EXPECT_STREQ("0xffffffffffffffff", buf); +} + +TEST(FormatHex64, test6) { + EXPECT_EQ(16, FormatHex64(buf, 01777777777777777777777UL, 0) - buf); + EXPECT_STREQ("ffffffffffffffff", buf); +} + +TEST(FormatHex64, test7) { + EXPECT_EQ(18, FormatHex64(buf, 0xEBF2AA499B9028EAul, 2) - buf); + EXPECT_STREQ("0xebf2aa499b9028ea", buf); +} + +TEST(FormatHex64, test8) { + EXPECT_EQ(18, FormatHex64(buf, 0x00F2AA499B9028EAul, 2) - buf); + EXPECT_STREQ("0x00f2aa499b9028ea", buf); +} + +TEST(FormatHex64, testScalesToWordSizes) { + EXPECT_EQ(2 + 2, FormatHex64(buf, 13, 2) - buf); + EXPECT_STREQ("0x0d", buf); + EXPECT_EQ(4 + 2, FormatHex64(buf, 31337, 2) - buf); + EXPECT_STREQ("0x7a69", buf); + EXPECT_EQ(8 + 2, FormatHex64(buf, 65536, 2) - buf); + EXPECT_STREQ("0x00010000", buf); +} + +BENCH(FormatHex64, bench) { + EZBENCH2("FormatUint64 tiny", donothing, FormatUint64(buf, 1)); + EZBENCH2("FormatOctal64 tiny", donothing, FormatOctal64(buf, 1, true)); + EZBENCH2("FormatHex64 tiny", donothing, FormatHex64(buf, 1, 2)); + EZBENCH2("FormatHex64 big", donothing, + FormatHex64(buf, 01777777777777777777777UL, 2)); +} diff --git a/test/libc/fmt/formatint64_test.c b/test/libc/fmt/formatint64_test.c new file mode 100644 index 000000000..533789f54 --- /dev/null +++ b/test/libc/fmt/formatint64_test.c @@ -0,0 +1,74 @@ +/*-*- 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 "libc/fmt/conv.h" +#include "libc/fmt/itoa.h" +#include "libc/limits.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +TEST(FormatInt64, test) { + char buf[21]; + EXPECT_EQ(1, FormatInt64(buf, 0) - buf); + EXPECT_STREQ("0", buf); + EXPECT_EQ(1, FormatInt64(buf, 1) - buf); + EXPECT_STREQ("1", buf); + EXPECT_EQ(2, FormatInt64(buf, -1) - buf); + EXPECT_STREQ("-1", buf); + EXPECT_EQ(19, FormatInt64(buf, INT64_MAX) - buf); + EXPECT_STREQ("9223372036854775807", buf); + EXPECT_EQ(20, FormatInt64(buf, INT64_MIN) - buf); + EXPECT_STREQ("-9223372036854775808", buf); +} + +TEST(FormatUint64, test) { + char buf[21]; + EXPECT_EQ(1, FormatUint64(buf, 0) - buf); + EXPECT_STREQ("0", buf); + EXPECT_EQ(4, FormatUint64(buf, 1024) - buf); + EXPECT_STREQ("1024", buf); + EXPECT_EQ(20, FormatUint64(buf, UINT64_MAX) - buf); + EXPECT_STREQ("18446744073709551615", buf); + EXPECT_EQ(19, FormatUint64(buf, INT64_MIN) - buf); + EXPECT_STREQ("9223372036854775808", buf); +} + +TEST(int128toarray_radix10, test) { + char buf[41]; + EXPECT_EQ(1, int128toarray_radix10(0, buf)); + EXPECT_STREQ("0", buf); + EXPECT_EQ(39, int128toarray_radix10(INT128_MAX, buf)); + EXPECT_STREQ("170141183460469231731687303715884105727", buf); + EXPECT_EQ(40, int128toarray_radix10(INT128_MIN, buf)); + EXPECT_STREQ("-170141183460469231731687303715884105728", buf); +} + +TEST(uint128toarray_radix10, test) { + char buf[40]; + EXPECT_EQ(1, uint128toarray_radix10(0, buf)); + EXPECT_STREQ("0", buf); + EXPECT_EQ(39, uint128toarray_radix10(UINT128_MAX, buf)); + EXPECT_STREQ("340282366920938463463374607431768211455", buf); + EXPECT_EQ(39, uint128toarray_radix10(INT128_MIN, buf)); + EXPECT_STREQ("170141183460469231731687303715884105728", buf); +} + +BENCH(itoa64radix10, bench) { + char b[21]; + EZBENCH2("itoa64radix10", donothing, FormatUint64(b, UINT64_MAX)); +} diff --git a/test/libc/fmt/formatint64thousands_test.c b/test/libc/fmt/formatint64thousands_test.c index c0158d2a8..ae338e41a 100644 --- a/test/libc/fmt/formatint64thousands_test.c +++ b/test/libc/fmt/formatint64thousands_test.c @@ -76,8 +76,6 @@ TEST(FormatInt64Thousands, testNegative) { BENCH(FormatInt64Thousands, bench) { char s[27]; - EZBENCH2("int64toarray_radix10(MAX)", donothing, - int64toarray_radix10(INT64_MAX, s)); EZBENCH2("FormatInt64Thousands(MAX)", donothing, FormatInt64Thousands(s, INT64_MAX)); EZBENCH2("FormatInt64Thousands(MIN)", donothing, diff --git a/test/libc/fmt/formatoctal32_test.c b/test/libc/fmt/formatoctal32_test.c new file mode 100644 index 000000000..ae808806e --- /dev/null +++ b/test/libc/fmt/formatoctal32_test.c @@ -0,0 +1,57 @@ +/*-*- 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 2022 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/fmt/itoa.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +char buf[13]; + +void SetUp(void) { + memset(buf, 0x55, sizeof(buf)); +} + +TEST(FormatOctal32, test1) { + EXPECT_EQ(1, FormatOctal32(buf, 0, true) - buf); + EXPECT_STREQ("0", buf); +} + +TEST(FormatOctal32, test2) { + EXPECT_EQ(1, FormatOctal32(buf, 0, false) - buf); + EXPECT_STREQ("0", buf); +} + +TEST(FormatOctal32, test3) { + EXPECT_EQ(2, FormatOctal32(buf, 1, true) - buf); + EXPECT_STREQ("01", buf); +} + +TEST(FormatOctal32, test4) { + EXPECT_EQ(1, FormatOctal32(buf, 1, false) - buf); + EXPECT_STREQ("1", buf); +} + +TEST(FormatOctal32, test5) { + EXPECT_EQ(12, FormatOctal32(buf, 037777777777, true) - buf); + EXPECT_STREQ("037777777777", buf); +} + +TEST(FormatOctal32, test6) { + EXPECT_EQ(11, FormatOctal32(buf, 037777777777, false) - buf); + EXPECT_STREQ("37777777777", buf); +} diff --git a/test/libc/fmt/formatoctal64_test.c b/test/libc/fmt/formatoctal64_test.c new file mode 100644 index 000000000..82e3b675d --- /dev/null +++ b/test/libc/fmt/formatoctal64_test.c @@ -0,0 +1,66 @@ +/*-*- 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 2022 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/fmt/itoa.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +char buf[24]; + +void SetUp(void) { + memset(buf, 0x55, sizeof(buf)); +} + +TEST(FormatOctal64, test1) { + EXPECT_EQ(1, FormatOctal64(buf, 0, true) - buf); + EXPECT_STREQ("0", buf); +} + +TEST(FormatOctal64, test2) { + EXPECT_EQ(1, FormatOctal64(buf, 0, false) - buf); + EXPECT_STREQ("0", buf); +} + +TEST(FormatOctal64, test3) { + EXPECT_EQ(2, FormatOctal64(buf, 1, true) - buf); + EXPECT_STREQ("01", buf); +} + +TEST(FormatOctal64, test4) { + EXPECT_EQ(1, FormatOctal64(buf, 1, false) - buf); + EXPECT_STREQ("1", buf); +} + +TEST(FormatOctal64, test5) { + EXPECT_EQ(23, FormatOctal64(buf, 01777777777777777777777UL, true) - buf); + EXPECT_STREQ("01777777777777777777777", buf); +} + +TEST(FormatOctal64, test6) { + EXPECT_EQ(22, FormatOctal64(buf, 01777777777777777777777UL, false) - buf); + EXPECT_STREQ("1777777777777777777777", buf); +} + +BENCH(FormatOctal64, bench) { + EZBENCH2("FormatUint64", donothing, + FormatUint64(buf, 01777777777777777777777UL)); + EZBENCH2("FormatOctal64", donothing, + FormatOctal64(buf, 01777777777777777777777UL, true)); + EZBENCH2("FormatOctal32", donothing, FormatOctal32(buf, 037777777777U, true)); +} diff --git a/test/libc/fmt/itoa64radix10_test.c b/test/libc/fmt/itoa64radix10_test.c deleted file mode 100644 index c9387aa0f..000000000 --- a/test/libc/fmt/itoa64radix10_test.c +++ /dev/null @@ -1,74 +0,0 @@ -/*-*- 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 "libc/fmt/conv.h" -#include "libc/fmt/itoa.h" -#include "libc/limits.h" -#include "libc/testlib/ezbench.h" -#include "libc/testlib/testlib.h" - -TEST(int64toarray_radix10, test) { - char buf[21]; - EXPECT_EQ(1, int64toarray_radix10(0, buf)); - EXPECT_STREQ("0", buf); - EXPECT_EQ(1, int64toarray_radix10(1, buf)); - EXPECT_STREQ("1", buf); - EXPECT_EQ(2, int64toarray_radix10(-1, buf)); - EXPECT_STREQ("-1", buf); - EXPECT_EQ(19, int64toarray_radix10(INT64_MAX, buf)); - EXPECT_STREQ("9223372036854775807", buf); - EXPECT_EQ(20, int64toarray_radix10(INT64_MIN, buf)); - EXPECT_STREQ("-9223372036854775808", buf); -} - -TEST(uint64toarray_radix10, test) { - char buf[21]; - EXPECT_EQ(1, uint64toarray_radix10(0, buf)); - EXPECT_STREQ("0", buf); - EXPECT_EQ(4, uint64toarray_radix10(1024, buf)); - EXPECT_STREQ("1024", buf); - EXPECT_EQ(20, uint64toarray_radix10(UINT64_MAX, buf)); - EXPECT_STREQ("18446744073709551615", buf); - EXPECT_EQ(19, uint64toarray_radix10(INT64_MIN, buf)); - EXPECT_STREQ("9223372036854775808", buf); -} - -TEST(int128toarray_radix10, test) { - char buf[41]; - EXPECT_EQ(1, int128toarray_radix10(0, buf)); - EXPECT_STREQ("0", buf); - EXPECT_EQ(39, int128toarray_radix10(INT128_MAX, buf)); - EXPECT_STREQ("170141183460469231731687303715884105727", buf); - EXPECT_EQ(40, int128toarray_radix10(INT128_MIN, buf)); - EXPECT_STREQ("-170141183460469231731687303715884105728", buf); -} - -TEST(uint128toarray_radix10, test) { - char buf[40]; - EXPECT_EQ(1, uint128toarray_radix10(0, buf)); - EXPECT_STREQ("0", buf); - EXPECT_EQ(39, uint128toarray_radix10(UINT128_MAX, buf)); - EXPECT_STREQ("340282366920938463463374607431768211455", buf); - EXPECT_EQ(39, uint128toarray_radix10(INT128_MIN, buf)); - EXPECT_STREQ("170141183460469231731687303715884105728", buf); -} - -BENCH(itoa64radix10, bench) { - char b[21]; - EZBENCH2("itoa64radix10", donothing, uint64toarray_radix10(UINT64_MAX, b)); -} diff --git a/test/libc/fmt/mapdoserrortoerrno_test.c b/test/libc/fmt/mapdoserrortoerrno_test.c deleted file mode 100644 index 9dd047fef..000000000 --- a/test/libc/fmt/mapdoserrortoerrno_test.c +++ /dev/null @@ -1,28 +0,0 @@ -/*-*- 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/errno.h" -#include "libc/nt/errors.h" -#include "libc/sock/internal.h" -#include "libc/sock/sock.h" -#include "libc/testlib/testlib.h" - -TEST(__dos2errno, test) { - EXPECT_EQ(EACCES, __dos2errno(kNtErrorSectorNotFound)); - EXPECT_EQ(EADDRNOTAVAIL, __dos2errno(kNtErrorInvalidNetname)); -} diff --git a/test/libc/fmt/palandprintf_test.c b/test/libc/fmt/palandprintf_test.c index fd2d24c4d..1e1e680d2 100644 --- a/test/libc/fmt/palandprintf_test.c +++ b/test/libc/fmt/palandprintf_test.c @@ -572,7 +572,7 @@ TEST(xasprintf, hugeNtoa) { ASSERT_STREQ( "0b1111111111111111111111111111111111111111111111111111111111111111111111" "1111111111111111111111111111111111111111111111111111111111", - gc(xasprintf("%#jb", UINT128_MAX))); + gc(xasprintf("%#jjb", UINT128_MAX))); } TEST(xasprintf, twosBane) { @@ -591,20 +591,19 @@ TEST(snprintf, testFixedWidthString_wontOverrunInput) { free(buf); } -/* TODO(jart): why is this weird in TINY mode? */ -/* TEST(snprintf, testFixedWidthStringIsNull_wontOverrunBuffer) { */ -/* int N = 3; */ -/* char *buf = malloc(N + 1); */ -/* EXPECT_EQ(3, snprintf(buf, N + 1, "%.*s", pushpop(N), pushpop(NULL))); */ -/* EXPECT_STREQ("(nu", buf); */ -/* EXPECT_EQ(3, snprintf(buf, N + 1, "%#.*s", pushpop(N), pushpop(NULL))); */ -/* EXPECT_STREQ("(nu", buf); */ -/* EXPECT_EQ(3, snprintf(buf, N + 1, "%`'.*s", pushpop(N), pushpop(NULL))); */ -/* EXPECT_STREQ("NUL", buf); */ -/* EXPECT_EQ(3, snprintf(buf, N + 1, "%`#.*s", pushpop(N), pushpop(NULL))); */ -/* EXPECT_STREQ("NUL", buf); */ -/* free(buf); */ -/* } */ +TEST(snprintf, testFixedWidthStringIsNull_wontOverrunBuffer) { + int N = 3; + char *buf = malloc(N + 1); + EXPECT_EQ(3, snprintf(buf, N + 1, "%.*s", pushpop(N), pushpop(NULL))); + EXPECT_STREQ("(nu", buf); + EXPECT_EQ(3, snprintf(buf, N + 1, "%#.*s", pushpop(N), pushpop(NULL))); + EXPECT_STREQ("(nu", buf); + EXPECT_EQ(3, snprintf(buf, N + 1, "%`'.*s", pushpop(N), pushpop(NULL))); + EXPECT_STREQ("NUL", buf); + EXPECT_EQ(3, snprintf(buf, N + 1, "%`#.*s", pushpop(N), pushpop(NULL))); + EXPECT_STREQ("NUL", buf); + free(buf); +} TEST(snprintf, twosBaneWithTypePromotion) { int16_t x = 0x8000; @@ -642,19 +641,15 @@ BENCH(palandprintf, bench) { EZBENCH2("%g M_PI", donothing, Format("%g", VEIL("x", M_PI))); EZBENCH2("%a M_PI", donothing, Format("%a", VEIL("x", M_PI))); EZBENCH2("%e M_PI", donothing, Format("%e", VEIL("x", M_PI))); + EZBENCH2("ULONG_MAX %lo", donothing, Format("%lo", VEIL("r", ULONG_MAX))); EZBENCH2("INT_MIN %x", donothing, Format("%x", VEIL("r", INT_MIN))); EZBENCH2("INT_MIN %d", donothing, Format("%d", VEIL("r", INT_MIN))); EZBENCH2("INT_MIN %,d", donothing, Format("%,d", VEIL("r", INT_MIN))); EZBENCH2("INT_MIN %ld", donothing, Format("%ld", (long)VEIL("r", INT_MIN))); - EZBENCH2("INT_MIN %jd", donothing, - Format("%jd", (intmax_t)VEIL("r", INT_MIN))); EZBENCH2("LONG_MIN %lx", donothing, Format("%lx", VEIL("r", LONG_MIN))); EZBENCH2("LONG_MIN %ld", donothing, Format("%ld", VEIL("r", LONG_MIN))); - EZBENCH2("LONG_MIN %jd", donothing, - Format("%jd", (intmax_t)VEIL("r", LONG_MIN))); - EZBENCH2("LONG_MIN %jx", donothing, - Format("%jx", (intmax_t)VEIL("r", LONG_MIN))); - EZBENCH2("int64toarray 23", donothing, int64toarray_radix10(23, buffer)); - EZBENCH2("int64toarray min", donothing, - int64toarray_radix10(INT_MIN, buffer)); + EZBENCH2("INT128_MIN %jjd", donothing, Format("%jjd", INT128_MIN)); + EZBENCH2("INT128_MIN %jjx", donothing, Format("%jjx", INT128_MIN)); + EZBENCH2("int64toarray 23", donothing, FormatInt64(buffer, 23)); + EZBENCH2("int64toarray min", donothing, FormatInt64(buffer, INT_MIN)); } diff --git a/test/libc/fmt/sscanf_test.c b/test/libc/fmt/sscanf_test.c index 763af0e4a..7705985d3 100644 --- a/test/libc/fmt/sscanf_test.c +++ b/test/libc/fmt/sscanf_test.c @@ -26,7 +26,7 @@ #define sscanf1(STR, FMT) \ ({ \ errno = 0; \ - intmax_t x = 0; \ + int128_t x = 0; \ EXPECT_EQ(1, sscanf(STR, FMT, &x)); \ x; \ }) @@ -50,11 +50,11 @@ TEST(sscanf, testHex) { EXPECT_EQ(0x123, sscanf1("123", "%x")); EXPECT_EQ(0x123, sscanf1("0x123", "%x")); EXPECT_EQ(0x123, sscanf1("0123", "%x")); - EXPECT_EQ(INTMAX_MAX, - sscanf1("170141183460469231731687303715884105727", "%jd")); - EXPECT_EQ(INTMAX_MIN, - sscanf1("-170141183460469231731687303715884105728", "%jd")); - EXPECT_EQ(UINTMAX_MAX, sscanf1("0xffffffffffffffffffffffffffffffff", "%jx")); + EXPECT_EQ(INT128_MAX, + sscanf1("170141183460469231731687303715884105727", "%jjd")); + EXPECT_EQ(INT128_MIN, + sscanf1("-170141183460469231731687303715884105728", "%jjd")); + EXPECT_EQ(UINT128_MAX, sscanf1("0xffffffffffffffffffffffffffffffff", "%jjx")); } TEST(sscanf, testOctal) { diff --git a/test/libc/fmt/strerror_r_test.c b/test/libc/fmt/strerror_r_test.c index 98e78a8d2..1f8552188 100644 --- a/test/libc/fmt/strerror_r_test.c +++ b/test/libc/fmt/strerror_r_test.c @@ -30,55 +30,25 @@ */ TEST(strerror, e2big) { - if (IsTiny()) { - EXPECT_STARTSWITH("E2BIG", strerror(E2BIG)); - } else { - EXPECT_STARTSWITH("E2BIG[Arg list too long]", strerror(E2BIG)); - } + EXPECT_STARTSWITH("E2BIG", strerror(E2BIG)); } TEST(strerror, enosys) { - if (IsTiny()) { - EXPECT_STARTSWITH("ENOSYS", strerror(ENOSYS)); - } else { - EXPECT_STARTSWITH("ENOSYS[Function not implemented]", strerror(ENOSYS)); - } + EXPECT_STARTSWITH("ENOSYS", strerror(ENOSYS)); } TEST(strerror, einval) { - if (IsTiny()) { - EXPECT_STARTSWITH("EINVAL", strerror(EINVAL)); - } else { - EXPECT_STARTSWITH("EINVAL[Invalid argument]", strerror(EINVAL)); - } + EXPECT_STARTSWITH("EINVAL", strerror(EINVAL)); } TEST(strerror, symbolizingTheseNumbersAsErrorsIsHeresyInUnixStyle) { - if (IsTiny()) { - EXPECT_STARTSWITH("EUNKNOWN", strerror(0)); - } else { - EXPECT_STARTSWITH("EUNKNOWN[No error information]", strerror(0)); - } - if (IsTiny()) { - EXPECT_STARTSWITH("EUNKNOWN", strerror(-1)); - } else { - EXPECT_STARTSWITH("EUNKNOWN[No error information]", strerror(-1)); - } + EXPECT_STARTSWITH("EUNKNOWN", strerror(0)); } TEST(strerror, enotconn_orLinkerIsntUsingLocaleC_orCodeIsOutOfSync) { - if (IsTiny()) { - EXPECT_STARTSWITH("ENOTCONN", strerror(ENOTCONN)); - } else { - EXPECT_STARTSWITH("ENOTCONN[Transport endpoint is not connected]", - strerror(ENOTCONN)); - } + EXPECT_STARTSWITH("ENOTCONN", strerror(ENOTCONN)); } TEST(strerror, exfull_orLinkerIsntUsingLocaleC_orCodeIsOutOfSync) { - if (IsTiny()) { - EXPECT_STARTSWITH("ETXTBSY", strerror(ETXTBSY)); - } else { - EXPECT_STARTSWITH("ETXTBSY[Text file busy]", strerror(ETXTBSY)); - } + EXPECT_STARTSWITH("ETXTBSY", strerror(ETXTBSY)); } diff --git a/test/libc/intrin/describeflags_test.c b/test/libc/intrin/describeflags_test.c new file mode 100644 index 000000000..f23a33b35 --- /dev/null +++ b/test/libc/intrin/describeflags_test.c @@ -0,0 +1,40 @@ +/*-*- 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 2022 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/intrin/describeflags.internal.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/testlib/testlib.h" + +static const struct DescribeFlags kFlags[] = { + {1, "hi"}, // + {2, "there"}, // +}; + +const char *DescribeIt(uint32_t x) { + static char s[64]; + return DescribeFlags(s, ARRAYLEN(s), kFlags, ARRAYLEN(kFlags), "x", x); +} + +TEST(describeflags, test) { + EXPECT_STREQ("0", DescribeIt(0)); + EXPECT_STREQ("xhi", DescribeIt(1)); + EXPECT_STREQ("xthere", DescribeIt(2)); + EXPECT_STREQ("xhi|xthere", DescribeIt(3)); + EXPECT_STREQ("xhi|xthere|0x14", DescribeIt(0x17)); +} diff --git a/test/libc/intrin/dos2errno_test.c b/test/libc/intrin/dos2errno_test.c new file mode 100644 index 000000000..391f900c4 --- /dev/null +++ b/test/libc/intrin/dos2errno_test.c @@ -0,0 +1,31 @@ +/*-*- 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/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/nt/errors.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +TEST(__dos2errno, test) { + EXPECT_EQ(0, __dos2errno(0)); + EXPECT_EQ(EACCES, __dos2errno(kNtErrorSectorNotFound)); + EXPECT_EQ(EADDRNOTAVAIL, __dos2errno(kNtErrorInvalidNetname)); +} diff --git a/test/libc/calls/getenv_test.c b/test/libc/intrin/getenv_test.c similarity index 92% rename from test/libc/calls/getenv_test.c rename to test/libc/intrin/getenv_test.c index 21642a97c..5ef0c98df 100644 --- a/test/libc/calls/getenv_test.c +++ b/test/libc/intrin/getenv_test.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/runtime/runtime.h" +#include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" TEST(getenv, test) { @@ -26,3 +27,8 @@ TEST(getenv, test) { unsetenv("X"); EXPECT_EQ(NULL, getenv("X")); } + +BENCH(getenv, bench) { + char *getenv_(const char *) asm("getenv"); + EZBENCH2("getenv(TZ)", donothing, getenv_("TZ")); +} diff --git a/test/libc/intrin/intrin_test.c b/test/libc/intrin/intrin_test.c index f659c17e8..9ef375a2a 100644 --- a/test/libc/intrin/intrin_test.c +++ b/test/libc/intrin/intrin_test.c @@ -1440,8 +1440,8 @@ TEST(pabsb, fuzz) { RngSet(x, sizeof(x)); pabsb(a, x); (pabsb)(b, x); - ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%`#.16s\n\t%`#.16s\n\t%`#.16s", i, x, - a, b); + ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%#.16hhs\n\t%#.16hhs\n\t%#.16hhs", i, + x, a, b); } } @@ -1947,25 +1947,26 @@ TEST(psradv, fuzz) { } } -TEST(psrldq, fuzz) { - int i, n; - uint8_t x[16], a[16], b[16]; - for (i = 0; i < 100; ++i) { - memset(a, -1, sizeof(a)); - memset(b, -1, sizeof(b)); - RngSet(x, sizeof(x)); - n = Rando() % 20; - psrldq(a, x, n); - (psrldq)(b, x, n); - ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%`#.16s\n\t%`#.16s\n\t%`#.16s", n, x, - a, b); - n = Rando() % 20; - psrldq(a, a, n); - (psrldq)(b, b, n); - ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%`#.16s\n\t%`#.16s\n\t%`#.16s", n, x, - a, b); - } -} +// // TODO(jart): Fix me. on low power cpus. +// TEST(psrldq, fuzz) { +// int i, n; +// uint8_t x[16], a[16], b[16]; +// for (i = 0; i < 100; ++i) { +// memset(a, -1, sizeof(a)); +// memset(b, -1, sizeof(b)); +// RngSet(x, sizeof(x)); +// n = Rando() % 20; +// psrldq(a, x, n); +// (psrldq)(b, x, n); +// ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%#.16hhs\n\t%#.16hhs\n\t%#.16hhs", +// n, x, a, b); +// n = Rando() % 20; +// psrldq(a, a, n); +// (psrldq)(b, b, n); +// ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%#.16hhs\n\t%#.16hhs\n\t%#.16hhs", +// n, x, a, b); +// } +// } TEST(pslldq, fuzz) { int i, n; @@ -1977,13 +1978,13 @@ TEST(pslldq, fuzz) { n = Rando() % 20; pslldq(a, x, n); (pslldq)(b, x, n); - ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%`#.16s\n\t%`#.16s\n\t%`#.16s", n, x, - a, b); + ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%#.16hhs\n\t%#.16hhs\n\t%#.16hhs", n, + x, a, b); n = Rando() % 20; pslldq(a, a, n); (pslldq)(b, b, n); - ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%`#.16s\n\t%`#.16s\n\t%`#.16s", n, x, - a, b); + ASSERT_EQ(0, memcmp(a, b, 16), "%d\n\t%#.16hhs\n\t%#.16hhs\n\t%#.16hhs", n, + x, a, b); } } diff --git a/test/libc/intrin/kprintf_test.c b/test/libc/intrin/kprintf_test.c new file mode 100644 index 000000000..071c15f5d --- /dev/null +++ b/test/libc/intrin/kprintf_test.c @@ -0,0 +1,412 @@ +/*-*- 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/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" +#include "libc/limits.h" +#include "libc/log/libfatal.internal.h" +#include "libc/macros.internal.h" +#include "libc/rand/rand.h" +#include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.internal.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +#define S(x) ((uintptr_t)(x)) + +/** + * returns random bytes that don't have exclamation mark + * since that would disable memory safety in the fuzzing + */ +static uint64_t Rando(void) { + uint64_t x; + do + x = lemur64(); + while (((x ^ READ64LE("!!!!!!!!")) - 0x0101010101010101) & + ~(x ^ READ64LE("!!!!!!!!")) & 0x8080808080808080); + return x; +} + +static const struct { + const char *want; + const char *fmt; + uintptr_t arg1; + uintptr_t arg2; +} V[] = { + {"!!WONTFMT", (const char *)31337, 123}, // + {"!!31337", "%s", 0x31337}, // + {"!!1", "%#s", 1}, // + {"!!feff800000031337", "%s", 0xfeff800000031337ull}, // + {"!!ffff800000031337", "%s", 0xffff800000031337ull}, // + {"123", "%d", 123}, // + {"2147483647", "%d", INT_MAX}, // + {"-2147483648", "%d", INT_MIN}, // + {"9223372036854775807", "%ld", LONG_MAX}, // + {"-9223372036854775808", "%ld", LONG_MIN}, // + {"9'223'372'036'854'775'807", "%'ld", LONG_MAX}, // + {"-9'223'372'036'854'775'808", "%'ld", LONG_MIN}, // + {"9,223,372,036,854,775,807", "%,ld", LONG_MAX}, // + {"-9,223,372,036,854,775,808", "%,ld", LONG_MIN}, // + {"9_223_372_036_854_775_807", "%_ld", LONG_MAX}, // + {"-9_223_372_036_854_775_808", "%_ld", LONG_MIN}, // + {"true", "%hhhd", 0xffff}, // + {"true", "%hhhd", 0xff00}, // + {"false", "%hhhd"}, // + {"fa", "%hhh.2d"}, // + {" 0x001337", "%#010.6x", 0x1337}, // + {"0x001337 ", "%#-010.6x", 0x1337}, // + {"0x1337 ", "%#-010.2x", 0x1337}, // + {" 0x1337", "%#010.2x", 0x1337}, // + {"0000001337", "%010d", 1337}, // + {"+000001337", "%+010d", 1337}, // + {" 001337", "%010.6d", 1337}, // + {" +001337", "%+010.6d", 1337}, // + {" 001337", "%010.6x", 0x1337}, // + {" 1337", "%010.2x", 0x1337}, // + {"1337 ", "%-010d", 1337}, // + {"001337 ", "%-010.6d", 1337}, // + {"+1337 ", "%+-010d", 1337}, // + {"+001337 ", "%+-010.6d", 1337}, // + {"001337 ", "%-010.6x", 0x1337}, // + {"1337 ", "%-010.2x", 0x1337}, // + {"000001'337", "%'010d", 1337}, // + {" 1337", "%*d", 10, 1337}, // + {"1337 ", "%*d", -10, 1337}, // + {"0", "%#x"}, // + {"0", "%#o"}, // + {"0", "%#b"}, // + {"0", "%#d"}, // + {"0", "%p"}, // + {"-1", "%p", S(MAP_FAILED)}, // + {"00000000", "%#.8x"}, // + {"00000000", "%#.8b"}, // + {"00000000", "%#.8o"}, // + {" 123", "%5d", 123}, // + {" -123", "%5d", -123}, // + {" 123", "%*d", 5, 123}, // + {" -123", "%*d", 5, -123}, // + {"123 ", "%-5d", 123}, // + {"-123 ", "%-5d", -123}, // + {" +123", "%+5d", 123}, // + {"00123", "%05d", 123}, // + {"-0123", "%05d", -123}, // + {" 0", "%5d"}, // + {" +0", "%+5d"}, // + {"00000", "%05d"}, // + {" deadbeef", "%20x", 0xdeadbeef}, // + {" 0xdeadbeef", "%20p", 0xdeadbeef}, // + {"101", "%b", 0b101}, // + {"123", "%x", 0x123}, // + {"deadbeef", "%x", 0xdeadbeef}, // + {"DEADBEEF", "%X", 0xdeadbeef}, // + {"0", "%hd", INT_MIN}, // + {"123", "%o", 0123}, // + {"+0", "%+d"}, // + {"+123", "%+d", 123}, // + {"-123", "%+d", -123}, // + {" 0", "% d"}, // + {" 123", "% d", 123}, // + {"-123", "% d", -123}, // + {"x", "%c", 'x'}, // + {"☺", "%hc", u'☺'}, // + {"☺", "%lc", L'☺'}, // + {"☺", "%C", L'☺'}, // + {"0x31337", "%p", 0x31337}, // + {"0xffff800000031337", "%p", 0xffff800000031337ull}, // + {"0xfeff800000031337", "%p", 0xfeff800000031337ull}, // + {"65535", "%hu", 0xffffffffu}, // + {"0", "%hu", 0x80000000u}, // + {"123", "%hd", 123}, // + {"32767", "%hd", SHRT_MAX}, // + {"-32768", "%hd", SHRT_MIN}, // + {"-1", "%hhd", 0xffff}, // + {"-128", "%hhd", 0xff80}, // + {"255", "%hhu", 0xffffffffu}, // + {"'x'", "%#c", 'x'}, // + {"u'☺'", "%#hc", u'☺'}, // + {"L'☺'", "%#lc", L'☺'}, // + {"L'☺'", "%#C", L'☺'}, // + {"L'\\''", "%#C", L'\''}, // + {"hello world\n", "%s", S("hello world\n")}, // + {"☺☻♥♦♣♠!\n", "%s", S("☺☻♥♦♣♠!\n")}, // + {"␁", "%s", S("\1")}, // + {"\1", "%.*s", 1, S("\1")}, // + {"\\001", "%'s", S("\1")}, // + {"\"\\001\"", "%#s", S("\1")}, // + {"", "%.*s", 0}, // + {"☺☻♥♦♣♠!", "%hhs", S("\1\2\3\4\5\6!")}, // + {"☺☻", "%.*hhs", 2, S("\1\2\3\4\5\6!")}, // + {"u\"☺☻\"", "%#.*hhs", 2, S("\1\2\3\4\5\6!")}, // + {"u\" ☻\"", "%#.*hhs", 2, S("\0\2\3\4\5\6!")}, // + {"", "% s", S("")}, // + {" a", "% s", S("a")}, // + {"", "% .*s", 0, S("a")}, // + {"", "% s"}, // + {"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷", "%hs", S(u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷")}, // + {"☺☻♥♦♣♠!", "%ls", S(L"☺☻♥♦♣♠!")}, // + {"HELLO", "%^s", S("hello")}, // + {"eeeeeee ", "%10s", S("eeeeeee")}, // + {"hello", "%.*s", 5, S("hello world")}, // + {"þell", "%.*s", 5, S("þello world")}, // + {"þello", "%.*hs", 5, S(u"þello world")}, // + {"þeeeeee ", "%10s", S("þeeeeee")}, // + {"☺☻♥♦♣♠! ", "%10s", S("☺☻♥♦♣♠!")}, // + {"☺☻♥♦♣♠ ", "%10hs", S(u"☺☻♥♦♣♠")}, // + {"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷 ", "%10hs", S(u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷")}, // + {"☺☻♥♦♣♠! ", "%10ls", S(L"☺☻♥♦♣♠!")}, // + {"\"xx\"", "%#s", S("xx")}, // + {"u\"☺☺\"", "%#hs", S(u"☺☺")}, // + {"L\"☺☺\"", "%#ls", S(L"☺☺")}, // + {"\"\\\\\\\"\\177\"", "%#s", S("\\\"\177")}, // + {"%%", "%%%%"}, // + {"%", "%.%"}, // + {"=", "%="}, // +}; + +TEST(ksnprintf, test) { + char b[48], g[48]; + size_t i, j, n, rc; + rngset(g, sizeof(g), 0, 0); + for (i = 0; i < ARRAYLEN(V); ++i) { + bzero(b, 48); + n = strlen(V[i].want); + rc = ksnprintf(b, 48, V[i].fmt, V[i].arg1, V[i].arg2); + EXPECT_EQ(n, rc, "ksnprintf(\"%s\", %#lx, %#lx) → %zu ≠ %zu", V[i].fmt, + V[i].arg1, V[i].arg2, rc, n); + EXPECT_STREQ(V[i].want, b); + memcpy(b, g, 48); + for (j = 0; j < 40; ++j) { + rc = ksnprintf(b, 0, V[i].fmt, V[i].arg1, V[i].arg2); + ASSERT_EQ(n, rc, "ksnprintf(b, %zu, \"%s\", %#lx, %#lx) → %zu ≠ %zu", j, + V[i].fmt, V[i].arg1, V[i].arg2, rc, n); + ASSERT_EQ(READ64LE(g + j), READ64LE(b + j), + "ksnprintf(b, %zu, \"%s\", %#lx, %#lx) → buffer overrun", j, + V[i].fmt, V[i].arg1, V[i].arg2); + } + } +} + +TEST(ksnprintf, testSymbols) { + char b[2][32]; + bool hassymbols; + hassymbols = GetSymbolTable(); + ksnprintf(b[0], 32, "%t", strlen); + if (hassymbols) { + ASSERT_STREQ("&strlen", b[0]); + } else { + ksnprintf(b[1], 32, "&%x", strlen); + ASSERT_STREQ(b[1], b[0]); + } +} + +TEST(ksnprintf, fuzzTheUnbreakable) { + int e; + size_t i; + uint64_t x; + char *f, b[32]; + _Alignas(PAGESIZE) static const char weasel[PAGESIZE]; + asm("mov\t%1,%0" : "=r"(f) : "g"(weasel)); + EXPECT_SYS(0, 0, mprotect(f, PAGESIZE, PROT_READ | PROT_WRITE)); + strcpy(f, "hello %s\n"); + EXPECT_EQ(12, ksnprintf(b, sizeof(b), f, "world")); + EXPECT_STREQ("hello world\n", b); + for (i = 0; i < 30000; ++i) { + x = Rando(); + memcpy(f, &x, sizeof(x)); + x = Rando(); + memcpy(f + 8, &x, sizeof(x)); + f[Rando() & 15] = '%'; + ksnprintf(b, sizeof(b), f, lemur64(), lemur64(), lemur64()); + } + EXPECT_SYS(0, 0, mprotect(f, PAGESIZE, PROT_READ)); +} + +TEST(kprintf, testFailure_wontClobberErrnoAndBypassesSystemCallSupport) { + int n; + ASSERT_EQ(0, errno); + EXPECT_SYS(0, 3, dup(2)); + EXPECT_SYS(0, 0, close(2)); + n = g_syscount; + kprintf("hello%n"); + EXPECT_EQ(n, g_syscount); + EXPECT_EQ(0, errno); + EXPECT_SYS(0, 2, dup2(3, 2)); + EXPECT_SYS(0, 0, close(3)); +} + +TEST(ksnprintf, testy) { + char b[32]; + EXPECT_EQ(3, ksnprintf(b, 32, "%#s", 1)); + EXPECT_STREQ("!!1", b); +} + +TEST(ksnprintf, testNonTextFmt_wontFormat) { + char b[32]; + char variable_format_string[16] = "%s"; + EXPECT_EQ(9, ksnprintf(b, 32, variable_format_string, NULL)); + EXPECT_STREQ("!!WONTFMT", b); +} + +TEST(ksnprintf, testMisalignedPointer_wontFormat) { + char b[32]; + const char16_t *s = u"hello"; + ksnprintf(b, 32, "%hs", (char *)s + 1); + EXPECT_STARTSWITH("!!", b); +} + +TEST(ksnprintf, testUnterminatedOverrun_truncatesAtPageBoundary) { + char *m; + char b[32]; + m = memset(mapanon(FRAMESIZE * 2), 1, FRAMESIZE); + EXPECT_SYS(0, 0, munmap(m + FRAMESIZE, FRAMESIZE)); + EXPECT_EQ(12, ksnprintf(b, 32, "%'s", m + FRAMESIZE - 3)); + EXPECT_STREQ("\\001\\001\\001", b); + EXPECT_SYS(0, 0, munmap(m, FRAMESIZE)); +} + +TEST(ksnprintf, testEmptyBuffer_determinesTrueLength) { + EXPECT_EQ(5, ksnprintf(0, 0, "hello")); +} + +TEST(ksnprintf, testFormatOnly_copiesString) { + char b[6]; + EXPECT_EQ(5, ksnprintf(b, 6, "hello")); + EXPECT_STREQ("hello", b); +} + +TEST(ksnprintf, testOneChar_justNulTerminates) { + char b[2] = {1, 2}; + EXPECT_EQ(3, ksnprintf(b, 1, "%d", 123)); + EXPECT_EQ(0, b[0]); + EXPECT_EQ(2, b[1]); +} + +TEST(kprintf, testStringUcs2) { + char b[32]; + EXPECT_EQ(21, ksnprintf(b, 32, "%hs", u"þ☺☻♥♦♣♠!")); + EXPECT_EQ(0xc3, b[0] & 255); + EXPECT_EQ(0xbe, b[1] & 255); + EXPECT_EQ(0xe2, b[2] & 255); + EXPECT_EQ(0x98, b[3] & 255); + EXPECT_EQ(0xba, b[4] & 255); + EXPECT_STREQ("þ☺☻♥♦♣♠!", b); +} + +TEST(kprintf, testTruncate_addsDotsAndReturnsTrueLength) { + char b[15]; + EXPECT_EQ(10, ksnprintf(b, 15, "%p", 0xdeadbeef)); + EXPECT_STREQ("0xdeadbeef", b); + EXPECT_EQ(10, ksnprintf(b, 10, "%p", 0xdeadbeef)); + EXPECT_STREQ("0xdead...", b); +} + +TEST(kprintf, testTruncate_preservesNewlineFromEndOfFormatString) { + char b[14]; + EXPECT_EQ(11, ksnprintf(b, 10, "%p\n", 0xdeadbeef)); + EXPECT_STREQ("0xdea...\n", b); +} + +TEST(ksnprintf, testTruncate_doesntBreakApartCharacters) { + char b[5]; + ASSERT_EQ(6, ksnprintf(b, 5, "☻☻")); + ASSERT_STREQ("....", b); +} + +TEST(ksnprintf, badUtf16) { + size_t i; + char b[16]; + static const struct { + const char *want; + const char *fmt; + char16_t arg[16]; + } V[] = { + {"� ", "%10hs", {0xd800}}, + {"� ", "%10hs", {0xdc00}}, + {"�� ", "%10hs", {0xd800, 0xd800}}, + {"�� ", "%10hs", {0xdc00, 0xdc00}}, + }; + for (i = 0; i < ARRAYLEN(V); ++i) { + EXPECT_EQ(strlen(V[i].want), ksnprintf(b, 16, V[i].fmt, V[i].arg)); + EXPECT_STREQ(V[i].want, b); + } +} + +TEST(ksnprintf, truncation) { + char buf[16] = {0}; + rngset(buf, sizeof(buf) - 1, lemur64, -1); + ksnprintf(0, 0, "%s", "xxxxx"); + rngset(buf, sizeof(buf) - 1, lemur64, -1); + ksnprintf(buf, 1, "%s", "xxxxx"); + EXPECT_STREQ("", buf); + rngset(buf, sizeof(buf) - 1, lemur64, -1); + ksnprintf(buf, 2, "%s", "xxxxx"); + EXPECT_STREQ(".", buf); + rngset(buf, sizeof(buf) - 1, lemur64, -1); + ksnprintf(buf, 3, "%s", "xxxxx"); + EXPECT_STREQ("..", buf); + rngset(buf, sizeof(buf) - 1, lemur64, -1); + ksnprintf(buf, 4, "%s", "xxxxx"); + EXPECT_STREQ("...", buf); + rngset(buf, sizeof(buf) - 1, lemur64, -1); + ksnprintf(buf, 5, "%s", "xxxxx"); + EXPECT_STREQ("x...", buf); + rngset(buf, sizeof(buf) - 1, lemur64, -1); + ksnprintf(buf, 6, "%s", "xxxxxxxxxxx"); + EXPECT_STREQ("xx...", buf); + rngset(buf, sizeof(buf) - 1, lemur64, -1); + ksnprintf(buf, 7, "%s", "xxxxxxxxx"); + EXPECT_STREQ("xxx...", buf); +} + +BENCH(printf, bench) { + char b[128]; + int snprintf_(char *, size_t, const char *, ...) asm("snprintf"); + EZBENCH2("ksnprintf fmt", donothing, ksnprintf(b, 128, ".")); + EZBENCH2("kusnprintf fmt", donothing, kusnprintf(b, 128, ".")); + EZBENCH2("snprintf fmt", donothing, snprintf_(b, 128, ".")); + EZBENCH2("kusnprintf str", donothing, + kusnprintf(b, 128, "%s\n", "hello world")); + EZBENCH2("snprintf str", donothing, + snprintf_(b, 128, "%s\n", "hello world")); + EZBENCH2("kusnprintf utf8", donothing, + kusnprintf(b, 128, "%s\n", "天地玄黄宇宙洪荒天地玄黄宇宙洪荒")); + EZBENCH2("snprintf utf8", donothing, + snprintf_(b, 128, "%s\n", "天地玄黄宇宙洪荒天地玄黄宇宙洪荒")); + EZBENCH2("kusnprintf chinese", donothing, + kusnprintf(b, 128, "%hs\n", u"天地玄黄宇宙洪荒")); + EZBENCH2("snprintf chinese", donothing, + snprintf_(b, 128, "%hs\n", u"天地玄黄宇宙洪荒")); + EZBENCH2("kusnprintf astral", donothing, + kusnprintf(b, 128, "%hs\n", u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷")); + EZBENCH2("snprintf astral", donothing, + snprintf_(b, 128, "%hs\n", u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷")); + EZBENCH2("kusnprintf octal", donothing, + kusnprintf(b, 128, "%#lo", ULONG_MAX)); + EZBENCH2("kusnprintf long", donothing, kusnprintf(b, 128, "%ld", LONG_MAX)); + EZBENCH2("snprintf long", donothing, snprintf_(b, 128, "%ld", LONG_MAX)); + EZBENCH2("kusnprintf thou", donothing, kusnprintf(b, 128, "%'ld", LONG_MAX)); + EZBENCH2("snprintf thou", donothing, snprintf_(b, 128, "%'ld", LONG_MAX)); +} diff --git a/test/libc/intrin/memcmp_test.c b/test/libc/intrin/memcmp_test.c index 5d923d126..1a5fbe143 100644 --- a/test/libc/intrin/memcmp_test.c +++ b/test/libc/intrin/memcmp_test.c @@ -121,17 +121,17 @@ BENCH(bcmp, bench) { EZBENCH_N("bcmp", 256, v = buncmp(a, b, 256)); a = gc(malloc(16 * 1024)); b = gc(malloc(16 * 1024)); - rngset(a, 16 * 1024, vigna, -1); + rngset(a, 16 * 1024, lemur64, -1); memcpy(b, a, 16 * 1024); EZBENCH_N("bcmp", 16384, v = buncmp(a, b, 16384)); a = gc(malloc(32 * 1024)); b = gc(malloc(32 * 1024)); - rngset(a, 32 * 1024, vigna, -1); + rngset(a, 32 * 1024, lemur64, -1); memcpy(b, a, 32 * 1024); EZBENCH_N("bcmp", 32768, v = buncmp(a, b, 32768)); a = gc(malloc(128 * 1024)); b = gc(malloc(128 * 1024)); - rngset(a, 128 * 1024, vigna, -1); + rngset(a, 128 * 1024, lemur64, -1); memcpy(b, a, 128 * 1024); EZBENCH_N("bcmp", 131072, v = buncmp(a, b, 131072)); } @@ -166,17 +166,17 @@ BENCH(memcmp, bench) { EZBENCH_N("memcmp", 256, v = funcmp(a, b, 256)); a = gc(malloc(16 * 1024)); b = gc(malloc(16 * 1024)); - rngset(a, 16 * 1024, vigna, -1); + rngset(a, 16 * 1024, lemur64, -1); memcpy(b, a, 16 * 1024); EZBENCH_N("memcmp", 16384, v = funcmp(a, b, 16384)); a = gc(malloc(32 * 1024)); b = gc(malloc(32 * 1024)); - rngset(a, 32 * 1024, vigna, -1); + rngset(a, 32 * 1024, lemur64, -1); memcpy(b, a, 32 * 1024); EZBENCH_N("memcmp", 32768, v = funcmp(a, b, 32768)); a = gc(malloc(128 * 1024)); b = gc(malloc(128 * 1024)); - rngset(a, 128 * 1024, vigna, -1); + rngset(a, 128 * 1024, lemur64, -1); memcpy(b, a, 128 * 1024); EZBENCH_N("memcmp", 131072, v = funcmp(a, b, 131072)); } @@ -211,17 +211,17 @@ BENCH(timingsafe_memcmp, bench) { EZBENCH_N("timingsafe_memcmp", 256, v = timingsafe_memcmp(a, b, 256)); a = gc(malloc(16 * 1024)); b = gc(malloc(16 * 1024)); - rngset(a, 16 * 1024, vigna, -1); + rngset(a, 16 * 1024, lemur64, -1); memcpy(b, a, 16 * 1024); EZBENCH_N("timingsafe_memcmp", 16384, v = timingsafe_memcmp(a, b, 16384)); a = gc(malloc(32 * 1024)); b = gc(malloc(32 * 1024)); - rngset(a, 32 * 1024, vigna, -1); + rngset(a, 32 * 1024, lemur64, -1); memcpy(b, a, 32 * 1024); EZBENCH_N("timingsafe_memcmp", 32768, v = timingsafe_memcmp(a, b, 32768)); a = gc(malloc(128 * 1024)); b = gc(malloc(128 * 1024)); - rngset(a, 128 * 1024, vigna, -1); + rngset(a, 128 * 1024, lemur64, -1); memcpy(b, a, 128 * 1024); EZBENCH_N("timingsafe_memcmp", 131072, v = timingsafe_memcmp(a, b, 131072)); } @@ -256,17 +256,17 @@ BENCH(timingsafe_bcmp, bench) { EZBENCH_N("timingsafe_bcmp", 256, v = timingsafe_bcmp(a, b, 256)); a = gc(malloc(16 * 1024)); b = gc(malloc(16 * 1024)); - rngset(a, 16 * 1024, vigna, -1); + rngset(a, 16 * 1024, lemur64, -1); memcpy(b, a, 16 * 1024); EZBENCH_N("timingsafe_bcmp", 16384, v = timingsafe_bcmp(a, b, 16384)); a = gc(malloc(32 * 1024)); b = gc(malloc(32 * 1024)); - rngset(a, 32 * 1024, vigna, -1); + rngset(a, 32 * 1024, lemur64, -1); memcpy(b, a, 32 * 1024); EZBENCH_N("timingsafe_bcmp", 32768, v = timingsafe_bcmp(a, b, 32768)); a = gc(malloc(128 * 1024)); b = gc(malloc(128 * 1024)); - rngset(a, 128 * 1024, vigna, -1); + rngset(a, 128 * 1024, lemur64, -1); memcpy(b, a, 128 * 1024); EZBENCH_N("timingsafe_bcmp", 131072, v = timingsafe_bcmp(a, b, 131072)); } @@ -301,17 +301,17 @@ BENCH(memcasecmp, bench) { EZBENCH_N("memcasecmp", 256, v = memcasecmp(a, b, 256)); a = gc(malloc(16 * 1024)); b = gc(malloc(16 * 1024)); - rngset(a, 16 * 1024, vigna, -1); + rngset(a, 16 * 1024, lemur64, -1); memcpy(b, a, 16 * 1024); EZBENCH_N("memcasecmp", 16384, v = memcasecmp(a, b, 16384)); a = gc(malloc(32 * 1024)); b = gc(malloc(32 * 1024)); - rngset(a, 32 * 1024, vigna, -1); + rngset(a, 32 * 1024, lemur64, -1); memcpy(b, a, 32 * 1024); EZBENCH_N("memcasecmp", 32768, v = memcasecmp(a, b, 32768)); a = gc(malloc(128 * 1024)); b = gc(malloc(128 * 1024)); - rngset(a, 128 * 1024, vigna, -1); + rngset(a, 128 * 1024, lemur64, -1); memcpy(b, a, 128 * 1024); EZBENCH_N("memcasecmp", 131072, v = memcasecmp(a, b, 131072)); } @@ -320,7 +320,7 @@ BENCH(timingsafe_memcmp, demonstration) { int bcmp_(const void *, const void *, size_t) asm("bcmp"); int memcmp_(const void *, const void *, size_t) asm("memcmp"); char a[256], b[256]; - rngset(a, 256, vigna, -1); + rngset(a, 256, lemur64, -1); memcpy(b, a, 256); ++a[0]; EZBENCH_N("bcmp ne", 256, bcmp_(a, b, 256)); diff --git a/test/libc/intrin/memset_test.c b/test/libc/intrin/memset_test.c index b1a3ee8b9..c5adfabe4 100644 --- a/test/libc/intrin/memset_test.c +++ b/test/libc/intrin/memset_test.c @@ -39,7 +39,7 @@ TEST(memset, hug) { b = gc(malloc(1025 * 2)); for (i = 0; i < 1025; ++i) { for (j = 0; j < 1025 - i; ++j) { - c = vigna(); + c = lemur64(); rngset(a, i + j, 0, 0); memcpy(b, a, i + j); ASSERT_EQ(a + i, golden(a + i, c, j)); diff --git a/test/libc/intrin/test.mk b/test/libc/intrin/test.mk index b8c23624a..c29c57784 100644 --- a/test/libc/intrin/test.mk +++ b/test/libc/intrin/test.mk @@ -24,7 +24,6 @@ TEST_LIBC_INTRIN_CHECKS = \ TEST_LIBC_INTRIN_DIRECTDEPS = \ LIBC_CALLS \ - LIBC_STDIO \ LIBC_FMT \ LIBC_INTRIN \ LIBC_LOG \ @@ -32,10 +31,13 @@ TEST_LIBC_INTRIN_DIRECTDEPS = \ LIBC_NEXGEN32E \ LIBC_RAND \ LIBC_RUNTIME \ + LIBC_STDIO \ LIBC_STR \ LIBC_STUBS \ + LIBC_SYSV \ LIBC_TESTLIB \ LIBC_TINYMATH \ + LIBC_UNICODE \ LIBC_X \ TOOL_VIZ_LIB diff --git a/test/libc/log/appendresourcereport_test.c b/test/libc/log/appendresourcereport_test.c new file mode 100644 index 000000000..a9d0d3873 --- /dev/null +++ b/test/libc/log/appendresourcereport_test.c @@ -0,0 +1,53 @@ +/*-*- 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 2022 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/log/log.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/rusage.h" +#include "libc/testlib/testlib.h" + +TEST(AppendResourceReport, testEmpty_doesNothing) { + char *b = 0; + struct rusage ru; + bzero(&ru, sizeof(ru)); + AppendResourceReport(&b, &ru, " / "); + EXPECT_EQ(NULL, b); +} + +TEST(AppendResourceReport, testMemory_balloons) { + char *b = 0; + struct rusage ru; + bzero(&ru, sizeof(ru)); + ru.ru_maxrss = 1; + AppendResourceReport(&b, &ru, ""); + EXPECT_STREQ("ballooned to 1kb in size", b); + free(b); +} + +#if 0 +TEST(AppendResourceReport, impure) { + char *b = 0; + struct rusage ru; + EXPECT_EQ(0, getrusage(RUSAGE_SELF, &ru)); + AppendResourceReport(&b, &ru, "\n"); + EXPECT_STREQ("ballooned to 1kb in size", b); + free(b); +} +#endif diff --git a/test/libc/log/backtrace_test.c b/test/libc/log/backtrace_test.c index e89bfbb12..e283d19cc 100644 --- a/test/libc/log/backtrace_test.c +++ b/test/libc/log/backtrace_test.c @@ -16,15 +16,18 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" #include "libc/mem/mem.h" #include "libc/runtime/gc.internal.h" +#include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" #include "libc/stdio/append.internal.h" @@ -84,11 +87,12 @@ char *StackOverrunCrash(int n) { char *MemoryLeakCrash(void) { char *p = strdup("doge"); - testlib_checkformemoryleaks(); + CheckForMemoryLeaks(); return p; } int NpeCrash(char *p) { + asm("nop"); // xxx: due to backtrace addr-1 thing return *p; } @@ -123,6 +127,9 @@ void SetUp(void) { exit((intptr_t)pMemoryLeakCrash()); case 7: exit(pNpeCrash(0)); + case 8: + __cxa_finalize(0); + exit(pNpeCrash(0)); default: printf("preventing fork recursion: %s\n", __argv[1]); exit(1); @@ -170,8 +177,8 @@ TEST(ShowCrashReports, testMemoryLeakCrash) { if (!pid) { dup2(fds[1], 1); dup2(fds[1], 2); - execv(program_executable_name, - (char *const[]){program_executable_name, "6", 0}); + execv(GetProgramExecutableName(), + (char *const[]){GetProgramExecutableName(), "6", 0}); _exit(127); } close(fds[1]); @@ -189,6 +196,7 @@ TEST(ShowCrashReports, testMemoryLeakCrash) { break; } } + close(fds[0]); ASSERT_NE(-1, wait(&ws)); EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(78, WEXITSTATUS(ws)); @@ -247,8 +255,8 @@ TEST(ShowCrashReports, testStackOverrunCrash) { if (!pid) { dup2(fds[1], 1); dup2(fds[1], 2); - execv(program_executable_name, - (char *const[]){program_executable_name, "5", 0}); + execv(GetProgramExecutableName(), + (char *const[]){GetProgramExecutableName(), "5", 0}); _exit(127); } close(fds[1]); @@ -266,6 +274,7 @@ TEST(ShowCrashReports, testStackOverrunCrash) { break; } } + close(fds[0]); ASSERT_NE(-1, wait(&ws)); EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(77, WEXITSTATUS(ws)); @@ -275,15 +284,20 @@ TEST(ShowCrashReports, testStackOverrunCrash) { gc(IndentLines(output, -1, 0, 4))); __die(); } - if (!strstr(output, "☺☻♥♦♣♠•◘○")) { - fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "stack overrun")) { - fprintf(stderr, "ERROR: crash report misclassified stack overrun\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); + if (strstr(output, "'int' index 10 into 'char [10]' out of bounds")) { + // ubsan nailed it + } else { + // asan nailed it + if (!strstr(output, "☺☻♥♦♣♠•◘○")) { + fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "stack overrun")) { + fprintf(stderr, "ERROR: crash report misclassified stack overrun\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } } free(output); } @@ -350,8 +364,8 @@ TEST(ShowCrashReports, testDivideByZero) { if (!pid) { dup2(fds[1], 1); dup2(fds[1], 2); - execv(program_executable_name, - (char *const[]){program_executable_name, "1", 0}); + execv(GetProgramExecutableName(), + (char *const[]){GetProgramExecutableName(), "1", 0}); _exit(127); } close(fds[1]); @@ -369,9 +383,10 @@ TEST(ShowCrashReports, testDivideByZero) { break; } } + close(fds[0]); ASSERT_NE(-1, wait(&ws)); EXPECT_TRUE(WIFEXITED(ws)); - EXPECT_EQ(128 + SIGFPE, WEXITSTATUS(ws)); + assert(128 + SIGFPE == WEXITSTATUS(ws) || 77 == WEXITSTATUS(ws)); /* NULL is stopgap until we can copy symbol tablces into binary */ #ifdef __FNO_OMIT_FRAME_POINTER__ if (!OutputHasSymbol(output, "FpuCrash")) { @@ -380,35 +395,53 @@ TEST(ShowCrashReports, testDivideByZero) { __die(); } #endif - if (!strstr(output, gc(xasprintf("%d", pid)))) { - fprintf(stderr, "ERROR: crash report didn't have pid\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "SIGFPE")) { - fprintf(stderr, "ERROR: crash report didn't have signal name\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "3.141")) { - fprintf(stderr, "ERROR: crash report didn't have fpu register\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "0f0e0d0c0b0a09080706050403020100")) { - fprintf(stderr, "ERROR: crash report didn't have sse register\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "3133731337")) { - fprintf(stderr, "ERROR: crash report didn't have general register\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); + if (strstr(output, "divrem overflow")) { + // UBSAN handled it + } else { + // ShowCrashReports() handled it + if (!strstr(output, gc(xasprintf("%d", pid)))) { + fprintf(stderr, "ERROR: crash report didn't have pid\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "SIGFPE")) { + fprintf(stderr, "ERROR: crash report didn't have signal name\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "3.141")) { + fprintf(stderr, "ERROR: crash report didn't have fpu register\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "0f0e0d0c0b0a09080706050403020100")) { + fprintf(stderr, "ERROR: crash report didn't have sse register\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "3133731337")) { + fprintf(stderr, "ERROR: crash report didn't have general register\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } } free(output); } // clang-format off +// +// test/libc/log/backtrace_test.c:59: ubsan error: 'int' index 10 into 'char [10]' out of bounds +// 0x000000000040a352: __die at libc/log/die.c:40 +// 0x0000000000489bc8: __ubsan_abort at libc/intrin/ubsan.c:196 +// 0x0000000000489e1c: __ubsan_handle_out_of_bounds at libc/intrin/ubsan.c:242 +// 0x0000000000423666: BssOverrunCrash at test/libc/log/backtrace_test.c:59 +// 0x0000000000423e0a: SetUp at test/libc/log/backtrace_test.c:115 +// 0x000000000049350b: testlib_runtestcases at libc/testlib/testrunner.c:98 +// 0x000000000048ab50: testlib_runalltests at libc/testlib/runner.c:37 +// 0x00000000004028d0: main at libc/testlib/testmain.c:94 +// 0x0000000000403977: cosmo at libc/runtime/cosmo.S:69 +// 0x00000000004021ae: _start at libc/crt/crt.S:78 +// // asan error: global redzone 1-byte store at 0x00000048cf2a shadow 0x0000800899e5 // x // ........................................OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO @@ -439,7 +472,9 @@ TEST(ShowCrashReports, testDivideByZero) { // 0x00000000004026db: main at libc/testlib/testmain.c:155 // 0x000000000040323f: cosmo at libc/runtime/cosmo.S:64 // 0x000000000040219b: _start at libc/crt/crt.S:67 +// // clang-format on + TEST(ShowCrashReports, testBssOverrunCrash) { if (!IsAsan()) return; size_t got; @@ -451,8 +486,8 @@ TEST(ShowCrashReports, testBssOverrunCrash) { if (!pid) { dup2(fds[1], 1); dup2(fds[1], 2); - execv(program_executable_name, - (char *const[]){program_executable_name, "2", 0}); + execv(GetProgramExecutableName(), + (char *const[]){GetProgramExecutableName(), "2", 0}); _exit(127); } close(fds[1]); @@ -470,6 +505,7 @@ TEST(ShowCrashReports, testBssOverrunCrash) { break; } } + close(fds[0]); ASSERT_NE(-1, wait(&ws)); EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(77, WEXITSTATUS(ws)); @@ -481,7 +517,8 @@ TEST(ShowCrashReports, testBssOverrunCrash) { __die(); } #endif - if (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone")) { + if (!strstr(output, "'int' index 10 into 'char [10]' out of bounds") && + (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone"))) { fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", gc(IndentLines(output, -1, 0, 4))); __die(); @@ -528,8 +565,8 @@ TEST(ShowCrashReports, testNpeCrash) { if (!pid) { dup2(fds[1], 1); dup2(fds[1], 2); - execv(program_executable_name, - (char *const[]){program_executable_name, "7", 0}); + execv(GetProgramExecutableName(), + (char *const[]){GetProgramExecutableName(), "7", 0}); _exit(127); } close(fds[1]); @@ -547,11 +584,12 @@ TEST(ShowCrashReports, testNpeCrash) { break; } } + close(fds[0]); ASSERT_NE(-1, wait(&ws)); EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(77, WEXITSTATUS(ws)); - /* NULL is stopgap until we can copy symbol tablces into binary */ - if (!strstr(output, "null pointer dereference")) { + /* NULL is stopgap until we can copy symbol tables into binary */ + if (!strstr(output, "null pointer")) { fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n", gc(IndentLines(output, -1, 0, 4))); __die(); @@ -563,10 +601,15 @@ TEST(ShowCrashReports, testNpeCrash) { __die(); } #endif - if (!strstr(output, "∅∅∅∅")) { - fprintf(stderr, "ERROR: crash report didn't have shadow diagram\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); + if (strstr(output, "null pointer access")) { + // ubsan nailed it + } else { + // asan nailed it + if (!strstr(output, "∅∅∅∅")) { + fprintf(stderr, "ERROR: crash report didn't have shadow diagram\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } } free(output); } @@ -582,8 +625,8 @@ TEST(ShowCrashReports, testDataOverrunCrash) { if (!pid) { dup2(fds[1], 1); dup2(fds[1], 2); - execv(program_executable_name, - (char *const[]){program_executable_name, "4", 0}); + execv(GetProgramExecutableName(), + (char *const[]){GetProgramExecutableName(), "4", 0}); _exit(127); } close(fds[1]); @@ -601,6 +644,7 @@ TEST(ShowCrashReports, testDataOverrunCrash) { break; } } + close(fds[0]); ASSERT_NE(-1, wait(&ws)); EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(77, WEXITSTATUS(ws)); @@ -612,10 +656,65 @@ TEST(ShowCrashReports, testDataOverrunCrash) { __die(); } #endif - if (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone")) { + if (!strstr(output, "'int' index 10 into 'char [10]' out of bounds") && + (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone"))) { fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", gc(IndentLines(output, -1, 0, 4))); __die(); } free(output); } + +TEST(ShowCrashReports, testNpeCrashAfterFinalize) { + /* + * this test makes sure we're not doing things like depending on + * environment variables after __cxa_finalize is called in cases + * where putenv() is used + */ + size_t got; + ssize_t rc; + int ws, pid, fds[2]; + char *output, buf[512]; + ASSERT_NE(-1, pipe2(fds, O_CLOEXEC)); + ASSERT_NE(-1, (pid = vfork())); + if (!pid) { + dup2(fds[1], 1); + dup2(fds[1], 2); + execv(GetProgramExecutableName(), + (char *const[]){GetProgramExecutableName(), "8", 0}); + _exit(127); + } + close(fds[1]); + output = 0; + appends(&output, ""); + for (;;) { + rc = read(fds[0], buf, sizeof(buf)); + if (rc == -1) { + ASSERT_EQ(EINTR, errno); + continue; + } + if ((got = rc)) { + appendd(&output, buf, got); + } else { + break; + } + } + close(fds[0]); + ASSERT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(IsAsan() ? 77 : 128 + SIGSEGV, WEXITSTATUS(ws)); + /* NULL is stopgap until we can copy symbol tables into binary */ + if (!strstr(output, IsAsan() ? "null pointer" : "Uncaught SIGSEGV (SEGV_")) { + fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } +#ifdef __FNO_OMIT_FRAME_POINTER__ + if (!OutputHasSymbol(output, "NpeCrash")) { + fprintf(stderr, "ERROR: crash report didn't have backtrace\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } +#endif + free(output); +} diff --git a/test/libc/mem/malloc_test.c b/test/libc/mem/malloc_test.c index b598989f9..767467b28 100644 --- a/test/libc/mem/malloc_test.c +++ b/test/libc/mem/malloc_test.c @@ -20,6 +20,8 @@ #include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" +#include "libc/dce.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/rand/rand.h" @@ -37,6 +39,11 @@ #define N 1024 #define M 20 +void SetUp(void) { + // TODO(jart): what is wrong? + if (IsWindows()) exit(0); +} + TEST(malloc, zeroMeansOne) { ASSERT_GE(malloc_usable_size(gc(malloc(0))), 1); } @@ -85,9 +92,9 @@ TEST(malloc, test) { if (fds[k] == -1) { ASSERT_NE(-1, (fds[k] = open(program_invocation_name, O_RDONLY))); ASSERT_NE(-1, fstat(fds[k], &st)); - ASSERT_NE(MAP_FAILED, - (maps[k] = mmap(NULL, (mapsizes[k] = st.st_size), PROT_READ, - MAP_SHARED, fds[k], 0))); + mapsizes[k] = st.st_size; + ASSERT_NE(MAP_FAILED, (maps[k] = mmap(NULL, mapsizes[k], PROT_READ, + MAP_SHARED, fds[k], 0))); } else { ASSERT_NE(-1, munmap(maps[k], mapsizes[k])); ASSERT_NE(-1, close(fds[k])); diff --git a/test/libc/mem/pledge_test.c b/test/libc/mem/pledge_test.c new file mode 100644 index 000000000..808141f41 --- /dev/null +++ b/test/libc/mem/pledge_test.c @@ -0,0 +1,62 @@ +/*-*- 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 2022 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/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/testlib.h" + +void SetUp(void) { + if (!__is_linux_2_6_23() && !IsOpenbsd()) { + exit(0); + } +} + +TEST(pledge, default_allowsExit) { + int ws, pid; + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + ASSERT_SYS(0, 0, pledge("", 0)); + _Exit(0); + } + EXPECT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); +} + +TEST(pledge, stdio_forbidsOpeningPasswd) { + int ws, pid; + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + ASSERT_SYS(0, 0, pledge("stdio", 0)); + ASSERT_SYS(EPERM, -1, open("/etc/passwd", O_RDWR)); + _Exit(0); + } + EXPECT_NE(-1, wait(&ws)); + if (IsLinux()) { + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); + } else { + EXPECT_TRUE(WIFSIGNALED(ws)); + EXPECT_EQ(SIGABRT, WTERMSIG(ws)); + } +} diff --git a/test/libc/mem/test.mk b/test/libc/mem/test.mk index 037d0de95..cdb4dc420 100644 --- a/test/libc/mem/test.mk +++ b/test/libc/mem/test.mk @@ -3,61 +3,69 @@ PKGS += TEST_LIBC_MEM -TEST_LIBC_MEM_SRCS := $(wildcard test/libc/mem/*.c) -TEST_LIBC_MEM_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_MEM_SRCS)) +TEST_LIBC_MEM_FILES := $(wildcard test/libc/mem/*) +TEST_LIBC_MEM_SRCS = $(TEST_LIBC_MEM_SRCS_C) $(TEST_LIBC_MEM_SRCS_CC) +TEST_LIBC_MEM_SRCS_C = $(filter %_test.c,$(TEST_LIBC_MEM_FILES)) +TEST_LIBC_MEM_SRCS_CC = $(filter %_test.cc,$(TEST_LIBC_MEM_FILES)) -TEST_LIBC_MEM_OBJS = \ - $(TEST_LIBC_MEM_SRCS:%.c=o/$(MODE)/%.o) +TEST_LIBC_MEM_OBJS = \ + $(TEST_LIBC_MEM_SRCS_C:%.c=o/$(MODE)/%.o) \ + $(TEST_LIBC_MEM_SRCS_CC:%.cc=o/$(MODE)/%.o) -TEST_LIBC_MEM_COMS = \ - $(TEST_LIBC_MEM_SRCS:%.c=o/$(MODE)/%.com) +TEST_LIBC_MEM_COMS = \ + $(TEST_LIBC_MEM_SRCS_C:%.c=o/$(MODE)/%.com) \ + $(TEST_LIBC_MEM_SRCS_CC:%.cc=o/$(MODE)/%.com) -TEST_LIBC_MEM_BINS = \ - $(TEST_LIBC_MEM_COMS) \ +TEST_LIBC_MEM_BINS = \ + $(TEST_LIBC_MEM_COMS) \ $(TEST_LIBC_MEM_COMS:%=%.dbg) -TEST_LIBC_MEM_TESTS = $(TEST_LIBC_MEM_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) +TEST_LIBC_MEM_TESTS = \ + $(TEST_LIBC_MEM_SRCS_C:%.c=o/$(MODE)/%.com.ok) \ + $(TEST_LIBC_MEM_SRCS_CC:%.cc=o/$(MODE)/%.com.ok) -TEST_LIBC_MEM_CHECKS = \ - $(TEST_LIBC_MEM_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) +TEST_LIBC_MEM_CHECKS = \ + $(TEST_LIBC_MEM_SRCS_C:%.c=o/$(MODE)/%.com.runs) \ + $(TEST_LIBC_MEM_SRCS_CC:%.cc=o/$(MODE)/%.com.runs) -TEST_LIBC_MEM_DIRECTDEPS = \ - LIBC_CALLS \ - LIBC_FMT \ - LIBC_INTRIN \ - LIBC_LOG \ - LIBC_MEM \ - LIBC_NEXGEN32E \ - LIBC_RAND \ - LIBC_RUNTIME \ - LIBC_STDIO \ - LIBC_STR \ - LIBC_STUBS \ - LIBC_SYSV \ - LIBC_TESTLIB \ - THIRD_PARTY_DLMALLOC +TEST_LIBC_MEM_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_INTRIN \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RAND \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + THIRD_PARTY_DLMALLOC \ + THIRD_PARTY_LIBCXX -TEST_LIBC_MEM_DEPS := \ +TEST_LIBC_MEM_DEPS := \ $(call uniq,$(foreach x,$(TEST_LIBC_MEM_DIRECTDEPS),$($(x)))) -o/$(MODE)/test/libc/mem/mem.pkg: \ - $(TEST_LIBC_MEM_OBJS) \ +o/$(MODE)/test/libc/mem/mem.pkg: \ + $(TEST_LIBC_MEM_OBJS) \ $(foreach x,$(TEST_LIBC_MEM_DIRECTDEPS),$($(x)_A).pkg) -o/$(MODE)/test/libc/mem/%.com.dbg: \ - $(TEST_LIBC_MEM_DEPS) \ - o/$(MODE)/test/libc/mem/%.o \ - o/$(MODE)/test/libc/mem/mem.pkg \ - $(LIBC_TESTMAIN) \ - $(CRT) \ +o/$(MODE)/test/libc/mem/%.com.dbg: \ + $(TEST_LIBC_MEM_DEPS) \ + o/$(MODE)/test/libc/mem/%.o \ + o/$(MODE)/test/libc/mem/mem.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ $(APE) @$(APELINK) -$(TEST_LIBC_MEM_OBJS): \ - DEFAULT_CCFLAGS += \ +$(TEST_LIBC_MEM_OBJS): \ + DEFAULT_CCFLAGS += \ -fno-builtin .PHONY: o/$(MODE)/test/libc/mem -o/$(MODE)/test/libc/mem: \ - $(TEST_LIBC_MEM_BINS) \ +o/$(MODE)/test/libc/mem: \ + $(TEST_LIBC_MEM_BINS) \ $(TEST_LIBC_MEM_CHECKS) diff --git a/test/libc/nexgen32e/gclongjmp_test.c b/test/libc/nexgen32e/gclongjmp_test.c index a39227ef2..e74f05d66 100644 --- a/test/libc/nexgen32e/gclongjmp_test.c +++ b/test/libc/nexgen32e/gclongjmp_test.c @@ -62,7 +62,7 @@ void (*Bp)(void(void)) = B; void (*Cp)(void) = C; TEST(gclongjmp, test) { - PrintGarbage(); + if (0) PrintGarbage(); if (!setjmp(jb)) { Ap(Cp, Bp); abort(); diff --git a/test/libc/nexgen32e/memeqmask_test.c b/test/libc/nexgen32e/memeqmask_test.c index ef43e7ca2..dfedfc68d 100644 --- a/test/libc/nexgen32e/memeqmask_test.c +++ b/test/libc/nexgen32e/memeqmask_test.c @@ -55,7 +55,7 @@ const char kM[] = "11111111100000000000100000000000" "01111111111111111111111111111110" "00000000000000000000000000000010"; -nodiscard char *binify(uint8_t *data, size_t size) { +dontdiscard char *binify(uint8_t *data, size_t size) { uint8_t b; size_t i, j; char *s, *p; diff --git a/test/libc/nexgen32e/memrchr16_test.c b/test/libc/nexgen32e/memrchr16_test.c new file mode 100644 index 000000000..c6bd7edb2 --- /dev/null +++ b/test/libc/nexgen32e/memrchr16_test.c @@ -0,0 +1,34 @@ +/*-*- 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/nexgen32e/nexgen32e.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +TEST(memrchr16, test) { + EXPECT_EQ(NULL, memrchr16(u"yo.hi.thereeuhcruhrceeuhcre", '-', 27)); + EXPECT_STREQ(u".there", memrchr16(u"yo.hi.there", '.', 11)); + EXPECT_STREQ(u".thereeuhcruhrceeuhcre", + memrchr16(u"yo.hi.thereeuhcruhrceeuhcre", '.', 27)); +} + +BENCH(memrchr16, bench) { + EZBENCH2("memrchr16", donothing, + EXPROPRIATE(memrchr16(u"yo.hi.there", '.', 11))); +} diff --git a/test/libc/rand/mt19937_test.c b/test/libc/rand/mt19937_test.c index 39a3343e0..f017b5a04 100644 --- a/test/libc/rand/mt19937_test.c +++ b/test/libc/rand/mt19937_test.c @@ -155,6 +155,8 @@ TEST(mt19937, test) { BENCH(mt19937, bench8) { volatile uint64_t x; + EZBENCH2("lemur64", donothing, x = lemur64()); + EZBENCH2("rand64", donothing, x = rand64()); EZBENCH2("vigna", donothing, x = vigna()); EZBENCH2("vigna_r", donothing, vigna_r(&x)); EZBENCH2("xorshift", donothing, x = xorshift()); diff --git a/test/libc/rand/rand64_test.c b/test/libc/rand/rand64_test.c new file mode 100644 index 000000000..50672b6cc --- /dev/null +++ b/test/libc/rand/rand64_test.c @@ -0,0 +1,111 @@ +/*-*- 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 2022 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/sigbits.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/sigset.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/spinlock.h" +#include "libc/macros.internal.h" +#include "libc/rand/rand.h" +#include "libc/runtime/stack.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/clone.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" + +#define THREADS 8 +#define ENTRIES 256 + +char locks[THREADS]; +volatile bool ready; +volatile uint64_t A[THREADS * ENTRIES]; + +void OnChld(int sig) { + // do nothing +} + +int Thrasher(void *arg) { + int i, id = (intptr_t)arg; + while (!ready) { + __builtin_ia32_pause(); + } + for (i = 0; i < ENTRIES; ++i) { + A[id * ENTRIES + i] = rand64(); + } + _spunlock(locks + id); + return 0; +} + +TEST(rand64, testLcg_doesntProduceIdenticalValues) { + int i, j; + bzero(A, sizeof(A)); + for (i = 0; i < ARRAYLEN(A); ++i) { + A[i] = rand64(); + } + for (i = 0; i < ARRAYLEN(A); ++i) { + EXPECT_NE(0, A[i], "i=%d", i); + for (j = 0; j < ARRAYLEN(A); ++j) { + if (i == j) continue; + EXPECT_NE(A[i], A[j], "i=%d j=%d", i, j); + } + } +} + +TEST(rand64, testThreadSafety_doesntProduceIdenticalValues) { + char *stack; + sigset_t ss, oldss; + int i, j, rc, ws, tid[THREADS]; + if (IsXnu()) return; + if (IsNetbsd()) return; // still flaky :'( + if (IsOpenbsd()) return; // still flaky :'( + struct sigaction oldsa; + struct sigaction sa = {.sa_handler = OnChld, .sa_flags = SA_RESTART}; + EXPECT_NE(-1, sigaction(SIGCHLD, &sa, &oldsa)); + bzero(A, sizeof(A)); + sigemptyset(&ss); + sigaddset(&ss, SIGCHLD); + EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &ss, &oldss)); + for (i = 0; i < THREADS; ++i) { + locks[i] = 1; + } + ready = false; + for (i = 0; i < THREADS; ++i) { + stack = gc(malloc(GetStackSize())); + tid[i] = clone(Thrasher, stack, GetStackSize(), + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(intptr_t)i, 0, 0, 0, 0); + ASSERT_NE(-1, tid[i]); + } + ready = true; + for (i = 0; i < THREADS; ++i) { + _spinlock(locks + i); + } + sigaction(SIGCHLD, &oldsa, 0); + sigprocmask(SIG_BLOCK, &oldss, 0); + for (i = 0; i < ARRAYLEN(A); ++i) { + EXPECT_NE(0, A[i], "i=%d", i); + for (j = 0; j < ARRAYLEN(A); ++j) { + if (i == j) continue; + EXPECT_NE(A[i], A[j], "i=%d j=%d", i, j); + } + } +} diff --git a/test/libc/rand/test.mk b/test/libc/rand/test.mk index 9af26f7f5..a26a99a32 100644 --- a/test/libc/rand/test.mk +++ b/test/libc/rand/test.mk @@ -30,6 +30,7 @@ TEST_LIBC_RAND_DIRECTDEPS = \ LIBC_STR \ LIBC_STUBS \ LIBC_CALLS \ + LIBC_THREAD \ LIBC_LOG \ LIBC_SYSV \ LIBC_TESTLIB \ diff --git a/test/libc/release/clang.sh b/test/libc/release/clang.sh deleted file mode 100755 index dee70c864..000000000 --- a/test/libc/release/clang.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ -#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ - -# TODO: someone who uses clang please mantain this - -# if CLANG=$(command -v clang); then -# mkdir -p o/$MODE/test/libc/release -# $CLANG \ -# -o o/$MODE/test/libc/release/smokeclang2.com.dbg \ -# -Os \ -# -Wall \ -# -Werror \ -# -static \ -# -fno-pie \ -# -nostdlib \ -# -nostdinc \ -# -fuse-ld=lld \ -# -mno-red-zone \ -# -Wl,-T,o/$MODE/ape/ape.lds \ -# -include o/cosmopolitan.h \ -# test/libc/release/smoke.c \ -# o/$MODE/libc/crt/crt.o \ -# o/$MODE/ape/ape.o \ -# o/$MODE/cosmopolitan.a || exit -# o/$MODE/test/libc/release/smokeclang2.com.dbg || exit -# fi diff --git a/test/libc/release/lld.sh b/test/libc/release/lld.sh deleted file mode 100755 index 7482ea3c3..000000000 --- a/test/libc/release/lld.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ -#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ - -# TODO: someone who uses clang please mantain this - -# if CLANG=$(command -v clang); then -# mkdir -p o/$MODE/test/libc/release -# $CLANG \ -# -o o/$MODE/test/libc/release/smokeclang.com.dbg \ -# -Os \ -# -Wall \ -# -Werror \ -# -static \ -# -fno-pie \ -# -nostdlib \ -# -nostdinc \ -# -fuse-ld=lld \ -# -mno-red-zone \ -# -Wl,-T,o/$MODE/ape/ape.lds \ -# -include o/cosmopolitan.h \ -# test/libc/release/smoke.c \ -# o/$MODE/libc/crt/crt.o \ -# o/$MODE/ape/ape.o \ -# o/$MODE/cosmopolitan.a || exit -# o/$MODE/test/libc/release/smokeclang.com.dbg || exit -# fi diff --git a/test/libc/release/smoke.c b/test/libc/release/smoke.c index 322fd4ace..2c7d3b4e9 100644 --- a/test/libc/release/smoke.c +++ b/test/libc/release/smoke.c @@ -2,7 +2,7 @@ int main(int argc, char *argv[]) { int rc; char *s; FILE *f; - showcrashreports(); + ShowCrashReports(); s = strdup(argv[0]); s[0] = 'Z'; f = fopen("/dev/null", "w"); diff --git a/test/libc/release/test.mk b/test/libc/release/test.mk index 118b6f7e9..ec61a09a3 100644 --- a/test/libc/release/test.mk +++ b/test/libc/release/test.mk @@ -8,8 +8,8 @@ o/$(MODE)/test/libc/release/cosmopolitan.zip: \ o/$(MODE)/ape/ape.o \ o/$(MODE)/ape/ape-no-modify-self.o \ o/$(MODE)/cosmopolitan.a \ - o/$(MODE)/third_party/infozip/zip.com - @$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -qj $@ o/cosmopolitan.h o/$(MODE)/ape/ape.lds o/$(MODE)/libc/crt/crt.o o/$(MODE)/ape/ape.o o/$(MODE)/ape/ape-no-modify-self.o o/$(MODE)/cosmopolitan.a + o/$(MODE)/third_party/zip/zip.com + @$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -qj $@ o/cosmopolitan.h o/$(MODE)/ape/ape.lds o/$(MODE)/libc/crt/crt.o o/$(MODE)/ape/ape.o o/$(MODE)/ape/ape-no-modify-self.o o/$(MODE)/cosmopolitan.a o/$(MODE)/test/libc/release/smoke.com: \ o/$(MODE)/test/libc/release/smoke.com.dbg @@ -116,26 +116,6 @@ o/$(MODE)/test/libc/release/smokeansi.com.dbg: \ o/$(MODE)/ape/ape.o \ o/$(MODE)/cosmopolitan.a -o/$(MODE)/test/libc/release/clang.ok: \ - test/libc/release/clang.sh \ - test/libc/release/smoke.c \ - o/cosmopolitan.h \ - o/$(MODE)/ape/ape.lds \ - o/$(MODE)/libc/crt/crt.o \ - o/$(MODE)/ape/ape.o \ - o/$(MODE)/cosmopolitan.a - @$(COMPILE) -ASHTEST -tT$@ $< - -o/$(MODE)/test/libc/release/lld.ok: \ - test/libc/release/lld.sh \ - test/libc/release/smoke.c \ - o/cosmopolitan.h \ - o/$(MODE)/ape/ape.lds \ - o/$(MODE)/libc/crt/crt.o \ - o/$(MODE)/ape/ape.o \ - o/$(MODE)/cosmopolitan.a - @$(COMPILE) -ASHTEST -tT$@ $< - o/$(MODE)/test/libc/release/metal.ok: \ test/libc/release/metal.sh \ o/$(MODE)/examples/hello.com \ @@ -158,7 +138,5 @@ o/$(MODE)/test/libc/release: \ o/$(MODE)/test/libc/release/smokecxx.com.runs \ o/$(MODE)/test/libc/release/smokeansi.com \ o/$(MODE)/test/libc/release/smokeansi.com.runs \ - o/$(MODE)/test/libc/release/clang.ok \ - o/$(MODE)/test/libc/release/lld.ok \ o/$(MODE)/test/libc/release/emulate.ok \ o/$(MODE)/test/libc/release/metal.ok diff --git a/test/libc/runtime/fork_test.c b/test/libc/runtime/fork_test.c new file mode 100644 index 000000000..688d4cd04 --- /dev/null +++ b/test/libc/runtime/fork_test.c @@ -0,0 +1,143 @@ +/*-*- 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/sigbits.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/dce.h" +#include "libc/log/check.h" +#include "libc/macros.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/msync.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +TEST(fork, testPipes) { + int a, b; + int ws, pid; + int pipefds[2]; + ASSERT_NE(-1, pipe(pipefds)); + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + a = 31337; + close(pipefds[0]); + write(pipefds[1], &a, sizeof(a)); + close(pipefds[1]); + _exit(0); + } + EXPECT_NE(-1, close(pipefds[1])); + EXPECT_EQ(sizeof(b), read(pipefds[0], &b, sizeof(b))); + EXPECT_NE(-1, close(pipefds[0])); + EXPECT_NE(-1, waitpid(pid, &ws, 0)); + EXPECT_EQ(31337, b); +} + +TEST(fork, testSharedMemory) { + int ws, pid; + int stackvar; + int *sharedvar; + int *privatevar; + EXPECT_NE(MAP_FAILED, + (sharedvar = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0))); + EXPECT_NE(MAP_FAILED, + (privatevar = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + stackvar = 1; + *sharedvar = 1; + *privatevar = 1; + EXPECT_NE(-1, (pid = fork())); + if (!pid) { + EXPECT_EQ(NULL, getenv("_FORK")); + ++stackvar; + ++*sharedvar; + ++*privatevar; + msync((void *)ROUNDDOWN((intptr_t)&stackvar, FRAMESIZE), FRAMESIZE, + MS_SYNC); + EXPECT_NE(-1, msync(privatevar, FRAMESIZE, MS_SYNC)); + EXPECT_NE(-1, msync(sharedvar, FRAMESIZE, MS_SYNC)); + _exit(0); + } + EXPECT_NE(-1, waitpid(pid, &ws, 0)); + EXPECT_EQ(1, stackvar); + EXPECT_EQ(2, *sharedvar); + EXPECT_EQ(1, *privatevar); + EXPECT_NE(-1, munmap(sharedvar, FRAMESIZE)); + EXPECT_NE(-1, munmap(privatevar, FRAMESIZE)); +} + +static volatile bool gotsigusr1; +static volatile bool gotsigusr2; + +static void OnSigusr1(int sig) { + gotsigusr1 = true; +} + +static void OnSigusr2(int sig) { + gotsigusr2 = true; +} + +TEST(fork, childToChild) { + if (IsWindows()) return; // :'( + sigset_t mask, oldmask; + int ws, parent, child1, child2; + gotsigusr1 = false; + gotsigusr2 = false; + parent = getpid(); + signal(SIGUSR1, OnSigusr1); + signal(SIGUSR2, OnSigusr2); + sigemptyset(&mask); + sigaddset(&mask, SIGUSR2); + sigprocmask(SIG_BLOCK, &mask, &oldmask); + ASSERT_NE(-1, (child1 = fork())); + if (!child1) { + kill(parent, SIGUSR2); + sigsuspend(0); + _Exit(!gotsigusr1); + } + sigdelset(&mask, SIGUSR2); + sigsuspend(&mask); + ASSERT_NE(-1, (child2 = fork())); + if (!child2) { + kill(child1, SIGUSR1); + _Exit(0); + } + ASSERT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); + ASSERT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); + sigprocmask(SIG_SETMASK, &oldmask, 0); +} + +void ForkInSerial(void) { + int pid, ws; + ASSERT_NE(-1, (pid = fork())); + if (!pid) _Exit(0); + ASSERT_NE(-1, waitpid(pid, &ws, 0)); + ASSERT_TRUE(WIFEXITED(ws)); + ASSERT_EQ(0, WEXITSTATUS(ws)); +} + +BENCH(fork, bench) { + EZBENCH2("fork", donothing, ForkInSerial()); +} diff --git a/test/libc/runtime/getdosargv_test.c b/test/libc/runtime/getdosargv_test.c index ccc7e20c0..83c1f247c 100644 --- a/test/libc/runtime/getdosargv_test.c +++ b/test/libc/runtime/getdosargv_test.c @@ -22,7 +22,7 @@ TEST(GetDosArgv, empty) { size_t max = 4; - size_t size = ARG_MAX; + size_t size = ARG_MAX / 2; char *buf = malloc(size * sizeof(char)); char **argv = malloc(max * sizeof(char *)); EXPECT_EQ(0, GetDosArgv(u"", buf, size, argv, max)); @@ -33,7 +33,7 @@ TEST(GetDosArgv, empty) { TEST(GetDosArgv, emptyish) { size_t max = 4; - size_t size = ARG_MAX; + size_t size = ARG_MAX / 2; char *buf = malloc(size * sizeof(char)); char **argv = malloc(max * sizeof(char *)); EXPECT_EQ(0, GetDosArgv(u" ", buf, size, argv, max)); @@ -44,7 +44,7 @@ TEST(GetDosArgv, emptyish) { TEST(GetDosArgv, basicUsage) { size_t max = 4; - size_t size = ARG_MAX; + size_t size = ARG_MAX / 2; char *buf = malloc(size * sizeof(char)); char **argv = malloc(max * sizeof(char *)); EXPECT_EQ(3, GetDosArgv(u"a\t \"b c\" d ", buf, size, argv, max)); @@ -58,7 +58,7 @@ TEST(GetDosArgv, basicUsage) { TEST(GetDosArgv, advancedUsage) { size_t max = 4; - size_t size = ARG_MAX; + size_t size = ARG_MAX / 2; char *buf = malloc(size * sizeof(char)); char **argv = malloc(max * sizeof(char *)); EXPECT_EQ(2, GetDosArgv(u"(╯°□°)╯︵ ┻━┻", buf, size, argv, max)); @@ -71,7 +71,7 @@ TEST(GetDosArgv, advancedUsage) { TEST(GetDosArgv, testAegeanGothicSupplementaryPlanes) { size_t max = 4; /* these symbols are almost as old as dos */ - size_t size = ARG_MAX; + size_t size = ARG_MAX / 2; char *buf = malloc(size * sizeof(char)); char **argv = malloc(max * sizeof(char *)); EXPECT_EQ(2, GetDosArgv(u"𐄷𐄸𐄹𐄺𐄻𐄼 𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷", buf, size, argv, max)); @@ -84,7 +84,7 @@ TEST(GetDosArgv, testAegeanGothicSupplementaryPlanes) { TEST(GetDosArgv, realWorldUsage) { size_t max = 512; - size_t size = ARG_MAX; + size_t size = ARG_MAX / 2; char *buf = malloc(size * sizeof(char)); char **argv = malloc(max * sizeof(char *)); EXPECT_EQ(5, GetDosArgv(u"C:\\Users\\jtunn\\printargs.com oh yes yes yes", @@ -145,7 +145,7 @@ TEST(GetDosArgv, quoteInMiddleOfArg_wontSplitArg) { TEST(GetDosArgv, waqQuoting1) { size_t max = 4; - size_t size = ARG_MAX; + size_t size = ARG_MAX / 2; char *buf = malloc(size * sizeof(char)); char **argv = malloc(max * sizeof(char *)); EXPECT_EQ(2, @@ -159,7 +159,7 @@ TEST(GetDosArgv, waqQuoting1) { TEST(GetDosArgv, waqQuoting2) { size_t max = 4; - size_t size = ARG_MAX; + size_t size = ARG_MAX / 2; char *buf = malloc(size * sizeof(char)); char **argv = malloc(max * sizeof(char *)); EXPECT_EQ(2, GetDosArgv(u"\"a\\\"b c\" d", buf, size, argv, max)); diff --git a/test/libc/runtime/memtrack_test.c b/test/libc/runtime/memtrack_test.c index a69fd6dbe..200ec8a2e 100644 --- a/test/libc/runtime/memtrack_test.c +++ b/test/libc/runtime/memtrack_test.c @@ -63,9 +63,9 @@ static void CheckMemoryIntervalsAreOk(const struct MemoryIntervals *mm) { static void RunTrackMemoryIntervalTest(const struct MemoryIntervals t[2], int x, int y, long h) { struct MemoryIntervals *mm; - mm = memcpy(malloc(sizeof(*t)), t, sizeof(*t)); + mm = memcpy(memalign(64, sizeof(*t)), t, sizeof(*t)); CheckMemoryIntervalsAreOk(mm); - CHECK_NE(-1, TrackMemoryInterval(mm, x, y, h, 0, 0)); + CHECK_NE(-1, TrackMemoryInterval(mm, x, y, h, 0, 0, 0, 0, 0, 0)); CheckMemoryIntervalsAreOk(mm); CheckMemoryIntervalsEqual(mm, t + 1); free(mm); @@ -75,7 +75,7 @@ static int RunReleaseMemoryIntervalsTest(const struct MemoryIntervals t[2], int x, int y) { int rc; struct MemoryIntervals *mm; - mm = memcpy(malloc(sizeof(*t)), t, sizeof(*t)); + mm = memcpy(memalign(64, sizeof(*t)), t, sizeof(*t)); CheckMemoryIntervalsAreOk(mm); if ((rc = ReleaseMemoryIntervals(mm, x, y, NULL)) != -1) { CheckMemoryIntervalsAreOk(mm); @@ -102,10 +102,10 @@ TEST(TrackMemoryInterval, TestFull) { mm = calloc(1, sizeof(struct MemoryIntervals)); for (i = 0; i < mm->n; ++i) { CheckMemoryIntervalsAreOk(mm); - CHECK_NE(-1, TrackMemoryInterval(mm, i, i, i, 0, 0)); + CHECK_NE(-1, TrackMemoryInterval(mm, i, i, i, 0, 0, 0, 0, 0, 0)); CheckMemoryIntervalsAreOk(mm); } - CHECK_EQ(-1, TrackMemoryInterval(mm, i, i, i, 0, 0)); + CHECK_EQ(-1, TrackMemoryInterval(mm, i, i, i, 0, 0, 0, 0, 0, 0)); CHECK_EQ(ENOMEM, errno); CheckMemoryIntervalsAreOk(mm); free(mm); diff --git a/test/libc/runtime/mmap_test.c b/test/libc/runtime/mmap_test.c index 045ce2b50..316517888 100644 --- a/test/libc/runtime/mmap_test.c +++ b/test/libc/runtime/mmap_test.c @@ -19,9 +19,14 @@ #include "libc/bits/bits.h" #include "libc/bits/xchg.internal.h" #include "libc/calls/calls.h" +#include "libc/dce.h" #include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" +#include "libc/linux/mmap.h" +#include "libc/linux/munmap.h" #include "libc/log/log.h" #include "libc/mem/mem.h" +#include "libc/rand/rand.h" #include "libc/runtime/gc.internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" @@ -31,6 +36,7 @@ #include "libc/sysv/consts/msync.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" +#include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" @@ -40,7 +46,7 @@ TEST(mmap, testMapFile) { int fd; char *p; char path[PATH_MAX]; - sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid()); + sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64()); ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); EXPECT_EQ(5, write(fd, "hello", 5)); EXPECT_NE(-1, fdatasync(fd)); @@ -54,7 +60,7 @@ TEST(mmap, testMapFile) { TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) { int fd; char *p, buf[16], path[PATH_MAX]; - sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid()); + sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64()); ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); EXPECT_EQ(5, write(fd, "hello", 5)); EXPECT_NE(-1, fdatasync(fd)); @@ -113,6 +119,7 @@ TEST(mmap, fileOffset) { EXPECT_NE(-1, ftruncate(fd, FRAMESIZE * 2)); EXPECT_NE(-1, pwrite(fd, "hello", 5, FRAMESIZE * 0)); EXPECT_NE(-1, pwrite(fd, "there", 5, FRAMESIZE * 1)); + EXPECT_NE(-1, fdatasync(fd)); ASSERT_NE(MAP_FAILED, (map = mmap(NULL, FRAMESIZE, PROT_READ, MAP_PRIVATE, fd, FRAMESIZE))); EXPECT_EQ(0, memcmp(map, "there", 5), "%#.*s", 5, map); @@ -122,8 +129,8 @@ TEST(mmap, fileOffset) { TEST(mmap, mapPrivate_writesDontChangeFile) { int fd; - char *map, buf[5]; - ASSERT_NE(-1, (fd = open("foo", O_CREAT | O_RDWR, 0644))); + char *map, buf[6]; + ASSERT_NE(-1, (fd = open("bar", O_CREAT | O_RDWR, 0644))); EXPECT_NE(-1, ftruncate(fd, FRAMESIZE)); EXPECT_NE(-1, pwrite(fd, "hello", 5, 0)); ASSERT_NE(MAP_FAILED, (map = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, @@ -131,7 +138,7 @@ TEST(mmap, mapPrivate_writesDontChangeFile) { memcpy(map, "there", 5); EXPECT_NE(-1, msync(map, FRAMESIZE, MS_SYNC)); EXPECT_NE(-1, munmap(map, FRAMESIZE)); - EXPECT_NE(-1, pread(fd, buf, 5, 0)); + EXPECT_NE(-1, pread(fd, buf, 6, 0)); EXPECT_EQ(0, memcmp(buf, "hello", 5), "%#.*s", 5, buf); EXPECT_NE(-1, close(fd)); } @@ -152,3 +159,183 @@ TEST(isheap, mallocOffset) { char *p = gc(malloc(131072)); ASSERT_TRUE(_isheap(p + 100000)); } + +//////////////////////////////////////////////////////////////////////////////// +// NON-SHARED READ-ONLY FILE MEMORY + +TEST(mmap, cow) { + int fd; + char *p; + char path[PATH_MAX]; + sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64()); + ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); + EXPECT_EQ(5, write(fd, "hello", 5)); + EXPECT_NE(-1, fdatasync(fd)); + EXPECT_NE(MAP_FAILED, + (p = mmap(NULL, 5, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))); + EXPECT_STREQN("hello", p, 5); + EXPECT_NE(-1, munmap(p, 5)); + EXPECT_NE(-1, close(fd)); + EXPECT_NE(-1, unlink(path)); +} + +//////////////////////////////////////////////////////////////////////////////// +// NON-SHARED READ-ONLY FILE MEMORY BETWEEN PROCESSES + +TEST(mmap, cowFileMapReadonlyFork) { + char *p; + int fd, pid, ws; + char path[PATH_MAX], lol[6]; + sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64()); + ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); + EXPECT_EQ(6, write(fd, "hello", 6)); + EXPECT_NE(-1, close(fd)); + ASSERT_NE(-1, (fd = open(path, O_RDONLY))); + EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ, MAP_PRIVATE, fd, 0))); + EXPECT_STREQN("hello", p, 5); + ASSERT_NE(-1, (ws = xspawn(0))); + if (ws == -2) { + ASSERT_STREQN("hello", p, 5); + _exit(0); + } + EXPECT_STREQN("hello", p, 5); + EXPECT_NE(-1, munmap(p, 6)); + EXPECT_NE(-1, close(fd)); + EXPECT_NE(-1, unlink(path)); +} + +//////////////////////////////////////////////////////////////////////////////// +// NON-SHARED READ/WRITE FILE MEMORY BETWEEN PROCESSES + +TEST(mmap, cowFileMapFork) { + char *p; + int fd, pid, ws; + char path[PATH_MAX], lol[6]; + sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64()); + ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); + EXPECT_EQ(6, write(fd, "parnt", 6)); + EXPECT_NE(-1, fdatasync(fd)); + EXPECT_NE(MAP_FAILED, + (p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))); + EXPECT_STREQN("parnt", p, 5); + ASSERT_NE(-1, (ws = xspawn(0))); + if (ws == -2) { + ASSERT_STREQN("parnt", p, 5); + strcpy(p, "child"); + ASSERT_STREQN("child", p, 5); + _exit(0); + } + EXPECT_STREQN("parnt", p, 5); // child changing memory did not change parent + EXPECT_EQ(6, pread(fd, lol, 6, 0)); + EXPECT_STREQN("parnt", lol, 5); // changing memory did not change file + EXPECT_NE(-1, munmap(p, 6)); + EXPECT_NE(-1, close(fd)); + EXPECT_NE(-1, unlink(path)); +} + +//////////////////////////////////////////////////////////////////////////////// +// SHARED ANONYMOUS MEMORY BETWEEN PROCESSES + +TEST(mmap, sharedAnonMapFork) { + char *p; + int pid, ws; + EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0))); + strcpy(p, "parnt"); + EXPECT_STREQN("parnt", p, 5); + ASSERT_NE(-1, (ws = xspawn(0))); + if (ws == -2) { + ASSERT_STREQN("parnt", p, 5); + strcpy(p, "child"); + ASSERT_STREQN("child", p, 5); + _exit(0); + } + EXPECT_STREQN("child", p, 5); // boom + EXPECT_NE(-1, munmap(p, 5)); +} + +//////////////////////////////////////////////////////////////////////////////// +// SHARED FILE MEMORY BETWEEN PROCESSES + +TEST(mmap, sharedFileMapFork) { + char *p; + int fd, pid, ws; + char path[PATH_MAX], lol[6]; + sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64()); + ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); + EXPECT_EQ(6, write(fd, "parnt", 6)); + EXPECT_NE(-1, fdatasync(fd)); + EXPECT_NE(MAP_FAILED, + (p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))); + EXPECT_STREQN("parnt", p, 5); + ASSERT_NE(-1, (ws = xspawn(0))); + if (ws == -2) { + ASSERT_STREQN("parnt", p, 5); + strcpy(p, "child"); + ASSERT_STREQN("child", p, 5); + ASSERT_NE(-1, msync(p, 6, MS_SYNC | MS_INVALIDATE)); + _exit(0); + } + EXPECT_STREQN("child", p, 5); // child changing memory changed parent memory + // XXX: RHEL5 has a weird issue where if we read the file into its own + // shared memory then corruption occurs! + EXPECT_EQ(6, pread(fd, lol, 6, 0)); + EXPECT_STREQN("child", lol, 5); // changing memory changed file + EXPECT_NE(-1, munmap(p, 6)); + EXPECT_NE(-1, close(fd)); + EXPECT_NE(-1, unlink(path)); +} + +//////////////////////////////////////////////////////////////////////////////// +// BENCHMARKS + +#define N (EZBENCH_COUNT * EZBENCH_TRIES) + +int count; +void *ptrs[N]; + +void BenchUnmap(void) { + int i; + for (i = 0; i < count; ++i) { + if (ptrs[i]) { + ASSERT_EQ(0, munmap(ptrs[i], FRAMESIZE)); + } + } +} + +void BenchMmapPrivate(void) { + void *p; + p = mmap(0, FRAMESIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, + -1, 0); + if (p == MAP_FAILED) abort(); + ptrs[count++] = p; +} + +BENCH(mmap, bench) { + EZBENCH2("mmap", donothing, BenchMmapPrivate()); + BenchUnmap(); +} + +void BenchUnmapLinux(void) { + int i; + for (i = 0; i < count; ++i) { + if (ptrs[i]) { + ASSERT_EQ(0, LinuxMunmap(ptrs[i], FRAMESIZE)); + } + } +} + +void BenchMmapPrivateLinux(void) { + void *p; + p = (void *)LinuxMmap(0, FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (p == MAP_FAILED) abort(); + ptrs[count++] = p; +} + +BENCH(mmap, benchLinux) { + void *p; + if (!IsLinux()) return; + EZBENCH2("mmap (linux)", donothing, BenchMmapPrivateLinux()); + BenchUnmapLinux(); +} diff --git a/test/libc/runtime/mprotect_test.c b/test/libc/runtime/mprotect_test.c new file mode 100644 index 000000000..d9f64e1a4 --- /dev/null +++ b/test/libc/runtime/mprotect_test.c @@ -0,0 +1,212 @@ +/*-*- 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/struct/sigaction.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/sa.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "third_party/xed/x86.h" + +volatile bool gotsegv; +volatile bool gotbusted; +struct sigaction old[2]; +char testlib_enable_tmp_setup_teardown; + +void SkipOverFaultingInstruction(struct ucontext *ctx) { + struct XedDecodedInst xedd; + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); + xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15); + ctx->uc_mcontext.rip += xedd.length; +} + +void OnSigSegv(int sig, struct siginfo *si, struct ucontext *ctx) { + gotsegv = true; + SkipOverFaultingInstruction(ctx); +} + +void OnSigBus(int sig, struct siginfo *si, struct ucontext *ctx) { + gotbusted = true; + SkipOverFaultingInstruction(ctx); +#if 0 + kprintf("SIGBUS%n"); + kprintf("si->si_signo = %G%n", si->si_signo); + kprintf("si->si_errno = %s (%d)%n", strerrno(si->si_errno), + si->si_errno); + kprintf("si->si_code = %s (%d)%n", GetSiCodeName(sig, si->si_code), + si->si_code); + kprintf("┌si->si_addr = %p%n", si->si_addr); + kprintf("┼─────────────────%n"); + kprintf("│si->si_pid = %d (note: getpid() is %d)%n", si->si_pid, getpid()); + kprintf("│si->si_uid = %d%n", si->si_uid); + kprintf("┼─────────────────%n"); + kprintf("│si->si_timerid = %d%n", si->si_timerid); + kprintf("└si->si_overrun = %d%n", si->si_overrun); + kprintf("si->si_value.sival_int = %d%n", si->si_value.sival_int); + kprintf("si->si_value.sival_ptr = %p%n", si->si_value.sival_ptr); + system(xasprintf("cat /proc/%d/map", getpid())); +#endif +} + +void SetUp(void) { + struct sigaction sabus = {.sa_sigaction = OnSigBus, + .sa_flags = SA_SIGINFO | SA_RESETHAND}; + struct sigaction sasegv = {.sa_sigaction = OnSigSegv, + .sa_flags = SA_SIGINFO | SA_RESETHAND}; + sigaction(SIGBUS, &sabus, old + 0); + sigaction(SIGSEGV, &sasegv, old + 1); + gotbusted = false; + gotsegv = false; +} + +void TearDown(void) { + sigaction(SIGBUS, old + 0, 0); + sigaction(SIGSEGV, old + 1, 0); +} + +TEST(mprotect, testOkMemory) { + char *p = gc(memalign(PAGESIZE, PAGESIZE)); + p[0] = 0; + ASSERT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); + p[0] = 1; + EXPECT_EQ(1, p[0]); + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); +} + +TEST(mprotect, testSegfault_writeToReadOnlyAnonymous) { + volatile char *p; + p = gc(memalign(PAGESIZE, PAGESIZE)); + EXPECT_FALSE(gotsegv); + p[0] = 1; + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ)); + missingno(p[0]); + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); + p[0] = 2; + EXPECT_TRUE(gotsegv | gotbusted); + EXPECT_EQ(1, p[0]); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); +} + +TEST(mprotect, testExecOnly_impliesReadFlag) { + volatile char *p; + p = gc(memalign(PAGESIZE, PAGESIZE)); + p[0] = 1; + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_EXEC)); + missingno(p[0]); + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); + p[0] = 2; + EXPECT_TRUE(gotsegv | gotbusted); + EXPECT_EQ(1, p[0]); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); +} + +TEST(mprotect, testProtNone_cantEvenRead) { + volatile char *p; + p = gc(memalign(PAGESIZE, PAGESIZE)); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_NONE)); + missingno(p[0]); + EXPECT_TRUE(gotsegv | gotbusted); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); +} + +static const char kRet31337[] = { + 0xb8, 0x69, 0x7a, 0x00, 0x00, // mov $31337,%eax + 0xc3, // ret +}; + +TEST(mprotect, testExecJit_actuallyWorks) { + int (*p)(void) = gc(memalign(PAGESIZE, PAGESIZE)); + memcpy(p, kRet31337, sizeof(kRet31337)); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_EXEC)); + EXPECT_EQ(31337, p()); + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); +} + +TEST(mprotect, testRwxMap_vonNeumannRules) { + if (IsOpenbsd()) return; // boo + int (*p)(void) = gc(memalign(PAGESIZE, PAGESIZE)); + memcpy(p, kRet31337, sizeof(kRet31337)); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE | PROT_EXEC)); + EXPECT_EQ(31337, p()); + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); + EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); +} + +TEST(mprotect, testExecuteFlatFileMapOpenedAsReadonly) { + int (*p)(void); + size_t n = sizeof(kRet31337); + ASSERT_SYS(0, 3, creat("return31337", 0755)); + ASSERT_SYS(0, n, write(3, kRet31337, n)); + ASSERT_SYS(0, 0, close(3)); + ASSERT_SYS(0, 3, open("return31337", O_RDONLY)); + EXPECT_NE(MAP_FAILED, + (p = mmap(NULL, n, PROT_READ | PROT_EXEC, MAP_PRIVATE, 3, 0))); + EXPECT_EQ(31337, p()); + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); + ASSERT_SYS(0, 0, close(3)); + ASSERT_SYS(0, 0, munmap(p, n)); +} + +TEST(mprotect, testFileMap_canChangeToExecWhileOpenInRdwrMode) { + int (*p)(void); + size_t n = sizeof(kRet31337); + ASSERT_SYS(0, 3, open("return31337", O_CREAT | O_TRUNC | O_RDWR, 0755)); + ASSERT_SYS(0, n, write(3, kRet31337, n)); + EXPECT_NE(MAP_FAILED, + (p = mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_PRIVATE, 3, 0))); + EXPECT_NE(-1, mprotect(p, n, PROT_READ | PROT_EXEC)); + EXPECT_EQ(31337, p()); + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); + ASSERT_SYS(0, 0, close(3)); + ASSERT_SYS(0, 0, munmap(p, n)); +} + +TEST(mprotect, testBadProt_failsEinval) { + volatile char *p = gc(memalign(PAGESIZE, PAGESIZE)); + EXPECT_EQ(-1, mprotect(p, 9999, -1)); + EXPECT_EQ(EINVAL, errno); +} + +TEST(mprotect, testZeroSize_doesNothing) { + volatile char *p = gc(memalign(PAGESIZE, PAGESIZE)); + EXPECT_NE(-1, mprotect(p, 0, PROT_READ)); + p[0] = 1; + EXPECT_FALSE(gotsegv); + EXPECT_FALSE(gotbusted); +} diff --git a/test/libc/runtime/mremap_test.c b/test/libc/runtime/mremap_test.c deleted file mode 100644 index 95425bd85..000000000 --- a/test/libc/runtime/mremap_test.c +++ /dev/null @@ -1,33 +0,0 @@ -/*-*- 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/mem/mem.h" -#include "libc/runtime/gc.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/testlib/testlib.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -TEST(mremap, testMalloc) { - int i; - char *a, *b, *c, *d; - ASSERT_NE(NULL, a = malloc(DEFAULT_MMAP_THRESHOLD)); - ASSERT_NE(NULL, b = mapanon(FRAMESIZE)); - ASSERT_NE(NULL, a = realloc(a, DEFAULT_MMAP_THRESHOLD * 2)); - munmap(b, FRAMESIZE); - free(a); -} diff --git a/test/libc/sock/inet_ntop_test.c b/test/libc/sock/inet_ntop_test.c index 261bbcd70..a98ab7671 100644 --- a/test/libc/sock/inet_ntop_test.c +++ b/test/libc/sock/inet_ntop_test.c @@ -41,17 +41,17 @@ TEST(inet_ntop, testBadFamily) { uint8_t localhost[4] = {127, 0, 0, 1}; ASSERT_EQ(NULL, inet_ntop(666, localhost, buf, sizeof(buf))); EXPECT_EQ(EAFNOSUPPORT, errno); - ASSERT_STREQ("", buf); + ASSERT_STREQ("hi", buf); } TEST(inet_ntop, testNoSpace) { char *buf = memcpy(malloc(16), "hi", 3); uint8_t localhost[4] = {127, 0, 0, 1}; - ASSERT_EQ(NULL, inet_ntop(AF_INET, localhost, buf, 0)); + EXPECT_EQ(NULL, inet_ntop(AF_INET, localhost, buf, 1)); EXPECT_EQ(ENOSPC, errno); ASSERT_STREQ("hi", buf); ASSERT_EQ(NULL, inet_ntop(AF_INET, localhost, buf, 7)); - ASSERT_STREQ("", buf); + ASSERT_STREQ("hi", buf); free(buf); } diff --git a/test/libc/sock/poll_test.c b/test/libc/sock/poll_test.c index da9b543f5..9a6271de1 100644 --- a/test/libc/sock/poll_test.c +++ b/test/libc/sock/poll_test.c @@ -16,26 +16,39 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/sigbits.h" +#include "libc/dce.h" +#include "libc/intrin/kprintf.h" #include "libc/log/libfatal.internal.h" +#include "libc/nexgen32e/rdtsc.h" +#include "libc/nexgen32e/rdtscp.h" +#include "libc/nt/synchronization.h" #include "libc/runtime/gc.internal.h" #include "libc/sock/sock.h" #include "libc/sysv/consts/af.h" #include "libc/sysv/consts/inaddr.h" #include "libc/sysv/consts/ipproto.h" #include "libc/sysv/consts/poll.h" +#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sock.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" +#include "third_party/chibicc/test/test.h" #include "tool/decode/lib/flagger.h" #include "tool/decode/lib/pollnames.h" -nodiscard char *FormatPollFd(struct pollfd p[2]) { +dontdiscard char *FormatPollFd(struct pollfd p[2]) { return xasprintf("fd:%d revents:%s\n" "fd:%d revents:%s\n", p[0].fd, gc(RecreateFlags(kPollNames, p[0].revents)), p[1].fd, gc(RecreateFlags(kPollNames, p[1].revents))); } +TEST(poll, allZero_doesNothing_exceptValidateAndCheckForSignals) { + EXPECT_SYS(0, 0, poll(0, 0, 0)); +} + TEST(poll, testNegativeOneFd_isIgnored) { ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); struct sockaddr_in addr = {AF_INET, 0, {htonl(INADDR_LOOPBACK)}}; @@ -48,3 +61,79 @@ TEST(poll, testNegativeOneFd_isIgnored) { gc(FormatPollFd(&fds[0]))); ASSERT_SYS(0, 0, close(3)); } + +TEST(poll, pipe_noInput) { + // we can't test stdin here since + // we can't assume it isn't /dev/null + // since nil is always pollin as eof + int pipefds[2]; + EXPECT_SYS(0, 0, pipe(pipefds)); + struct pollfd fds[] = {{pipefds[0], POLLIN}}; + EXPECT_SYS(0, 0, poll(fds, 1, 0)); + EXPECT_EQ(0, fds[0].revents); + EXPECT_SYS(0, 0, close(pipefds[0])); + EXPECT_SYS(0, 0, close(pipefds[1])); +} + +TEST(poll, pipe_hasInputFromSameProcess) { + char buf[2]; + int pipefds[2]; + EXPECT_SYS(0, 0, pipe(pipefds)); + struct pollfd fds[] = {{pipefds[0], POLLIN}}; + EXPECT_SYS(0, 2, write(pipefds[1], "hi", 2)); + EXPECT_SYS(0, 1, poll(fds, 1, 1000)); // flake nt! + EXPECT_EQ(POLLIN, fds[0].revents); + EXPECT_SYS(0, 2, read(pipefds[0], buf, 2)); + EXPECT_SYS(0, 0, poll(fds, 1, 0)); + EXPECT_SYS(0, 0, close(pipefds[0])); + EXPECT_SYS(0, 0, close(pipefds[1])); +} + +TEST(poll, pipe_hasInput) { + char buf[2]; + sigset_t chldmask, savemask; + int ws, pid, sync[2], pipefds[2]; + EXPECT_EQ(0, sigemptyset(&chldmask)); + EXPECT_EQ(0, sigaddset(&chldmask, SIGCHLD)); + EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &chldmask, &savemask)); + EXPECT_SYS(0, 0, pipe(pipefds)); + EXPECT_NE(-1, (pid = fork())); + if (!pid) { + EXPECT_SYS(0, 0, close(pipefds[0])); + EXPECT_SYS(0, 2, write(pipefds[1], "hi", 2)); + EXPECT_SYS(0, 2, write(pipefds[1], "hi", 2)); + EXPECT_SYS(0, 0, close(pipefds[1])); + _Exit(0); + } + EXPECT_SYS(0, 0, close(pipefds[1])); + EXPECT_SYS(0, 2, read(pipefds[0], buf, 2)); + struct pollfd fds[] = {{pipefds[0], POLLIN}}; + EXPECT_SYS(0, 1, poll(fds, 1, -1)); + EXPECT_EQ(POLLIN, fds[0].revents & POLLIN); + EXPECT_SYS(0, 2, read(pipefds[0], buf, 2)); + EXPECT_SYS(0, 0, close(pipefds[0])); + ASSERT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); + EXPECT_EQ(0, sigprocmask(SIG_SETMASK, &savemask, 0)); +} + +#if 0 +TEST(poll, emptyFds_becomesSleep) { + // timing tests w/o mocks are always the hardest + int64_t a, b, c, p, i = 0; + do { + if (++i == 5) { + kprintf("too much cpu churn%n"); + return; + } + p = TSC_AUX_CORE(rdpid()); + a = rdtsc(); + EXPECT_SYS(0, 0, poll(0, 0, 5)); + b = rdtsc(); + EXPECT_SYS(0, 0, poll(0, 0, 50)); + c = rdtsc(); + } while (TSC_AUX_CORE(rdpid()) != p); + EXPECT_LT((b - a) * 2, c - b); +} +#endif diff --git a/test/libc/sock/select_test.c b/test/libc/sock/select_test.c index 6e4721ee3..b46e657d3 100644 --- a/test/libc/sock/select_test.c +++ b/test/libc/sock/select_test.c @@ -16,17 +16,37 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" #include "libc/calls/struct/timeval.h" #include "libc/sock/select.h" #include "libc/sock/sock.h" #include "libc/testlib/testlib.h" #include "libc/time/time.h" -TEST(select, allZero) { - /* blocks indefinitely not worth supporting */ - /* EXPECT_SYS(0, 0, select(0, 0, 0, 0, 0)); */ +// TEST(select, allZero) { +// // todo: figure out how to test block until signal w/ select +// EXPECT_SYS(0, 0, select(0, 0, 0, 0, 0)); +// } + +TEST(select, pipe_hasInputFromSameProcess) { + fd_set rfds; + char buf[2]; + int pipefds[2]; + struct timeval tv = {.tv_usec = 100 * 1000}; + EXPECT_SYS(0, 0, pipe(pipefds)); + FD_ZERO(&rfds); + FD_SET(pipefds[0], &rfds); + EXPECT_SYS(0, 2, write(pipefds[1], "hi", 2)); + EXPECT_SYS(0, 1, select(pipefds[0] + 1, &rfds, 0, 0, &tv)); + EXPECT_TRUE(FD_ISSET(pipefds[0], &rfds)); + EXPECT_SYS(0, 2, read(pipefds[0], buf, 2)); + EXPECT_SYS(0, 0, select(pipefds[0] + 1, &rfds, 0, 0, &tv)); + EXPECT_TRUE(!FD_ISSET(pipefds[0], &rfds)); + EXPECT_SYS(0, 0, close(pipefds[0])); + EXPECT_SYS(0, 0, close(pipefds[1])); } +#if 0 // flaky TEST(select, testSleep) { int64_t e; long double n; @@ -35,9 +55,9 @@ TEST(select, testSleep) { EXPECT_SYS(0, 0, select(0, 0, 0, 0, &t)); e = (nowl() - n) * 1e6; EXPECT_GT(e, 1000); - if (!IsBsd()) { - /* maybe we should polyfill */ + if (IsLinux()) { EXPECT_EQ(0, t.tv_sec); EXPECT_EQ(0, t.tv_usec); } } +#endif diff --git a/test/libc/stdio/dirstream_test.c b/test/libc/stdio/dirstream_test.c index f8afc6f0e..5f2ce3641 100644 --- a/test/libc/stdio/dirstream_test.c +++ b/test/libc/stdio/dirstream_test.c @@ -18,24 +18,70 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/struct/dirent.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/rand/rand.h" #include "libc/runtime/gc.internal.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" +#include "libc/sysv/consts/dt.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" STATIC_YOINK("zip_uri_support"); STATIC_YOINK("usr/share/zoneinfo/New_York"); +char testlib_enable_tmp_setup_teardown; + +DIR *dir; +struct dirent *ent; + +void SetUp(void) { + dir = 0; + ent = 0; +} + +TEST(opendir, efault) { + ASSERT_SYS(EFAULT, NULL, opendir(0)); + if (!IsAsan()) return; // not possible + ASSERT_SYS(EFAULT, NULL, opendir((void *)77)); +} + +TEST(opendir, enoent) { + ASSERT_SYS(ENOENT, NULL, opendir("")); + ASSERT_SYS(ENOENT, NULL, opendir("o/foo")); +} + +TEST(opendir, enotdir) { + ASSERT_SYS(0, 0, close(creat("yo", 0644))); + ASSERT_SYS(ENOTDIR, NULL, opendir("yo/there")); +} + +TEST(dirstream, testDots) { + int hasdot = 0; + int hasdotdot = 0; + ASSERT_SYS(0, 0, close(creat("foo", 0644))); + ASSERT_NE(NULL, (dir = opendir("."))); + while ((ent = readdir(dir))) { + if (!strcmp(ent->d_name, ".")) { + ++hasdot; + EXPECT_EQ(DT_DIR, ent->d_type); + } + if (!strcmp(ent->d_name, "..")) { + ++hasdotdot; + EXPECT_EQ(DT_DIR, ent->d_type); + } + } + EXPECT_EQ(1, hasdot); + EXPECT_EQ(1, hasdotdot); + EXPECT_SYS(0, 0, closedir(dir)); +} + TEST(dirstream, test) { - DIR *dir; - struct dirent *ent; bool hasfoo = false; bool hasbar = false; char *dpath, *file1, *file2; - dpath = gc(xasprintf("%s%s%lu", kTmpPath, "dirstream", rand64())); + dpath = gc(xasprintf("%s.%d", "dirstream", rand())); file1 = gc(xasprintf("%s/%s", dpath, "foo")); file2 = gc(xasprintf("%s/%s", dpath, "bar")); EXPECT_NE(-1, mkdir(dpath, 0755)); @@ -43,8 +89,14 @@ TEST(dirstream, test) { EXPECT_NE(-1, touch(file2, 0644)); EXPECT_TRUE(NULL != (dir = opendir(dpath))); while ((ent = readdir(dir))) { - if (strcmp(ent->d_name, "foo")) hasfoo = true; - if (strcmp(ent->d_name, "bar")) hasbar = true; + if (!strcmp(ent->d_name, "foo")) { + EXPECT_EQ(DT_REG, ent->d_type); + hasfoo = true; + } + if (!strcmp(ent->d_name, "bar")) { + EXPECT_EQ(DT_REG, ent->d_type); + hasbar = true; + } } EXPECT_TRUE(hasfoo); EXPECT_TRUE(hasbar); @@ -56,25 +108,21 @@ TEST(dirstream, test) { TEST(dirstream, zipTest) { bool foundNewYork = false; - DIR *d; - struct dirent *e; const char *path = "/zip/usr/share/zoneinfo/"; ASSERT_NE(0, _gc(xiso8601ts(NULL))); - ASSERT_NE(NULL, (d = opendir(path))); - while ((e = readdir(d))) { - foundNewYork |= !strcmp(e->d_name, "New_York"); + ASSERT_NE(NULL, (dir = opendir(path))); + while ((ent = readdir(dir))) { + foundNewYork |= !strcmp(ent->d_name, "New_York"); } - closedir(d); + closedir(dir); EXPECT_TRUE(foundNewYork); } TEST(rewinddir, test) { - DIR *dir; - struct dirent *ent; bool hasfoo = false; bool hasbar = false; char *dpath, *file1, *file2; - dpath = gc(xasprintf("%s%s%lu", kTmpPath, "dirstream", rand64())); + dpath = gc(xasprintf("%s.%d", "dirstream", rand())); file1 = gc(xasprintf("%s/%s", dpath, "foo")); file2 = gc(xasprintf("%s/%s", dpath, "bar")); EXPECT_NE(-1, mkdir(dpath, 0755)); diff --git a/test/libc/stdio/fwrite_test.c b/test/libc/stdio/fwrite_test.c index 6bb2f6402..4d8005799 100644 --- a/test/libc/stdio/fwrite_test.c +++ b/test/libc/stdio/fwrite_test.c @@ -29,8 +29,6 @@ #include "libc/testlib/testlib.h" #include "libc/time/time.h" -/* TODO(jart): O_APPEND on Windows */ - #define PATH "hog" FILE *f; diff --git a/test/libc/stdio/getdelim_test.c b/test/libc/stdio/getdelim_test.c index 9f37d5cd1..60700469c 100644 --- a/test/libc/stdio/getdelim_test.c +++ b/test/libc/stdio/getdelim_test.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/bits/bits.h" +#include "libc/intrin/kprintf.h" #include "libc/log/libfatal.internal.h" #include "libc/mem/mem.h" #include "libc/runtime/symbols.internal.h" @@ -98,7 +99,6 @@ void ReadHyperionLines(void) { ASSERT_NE(NULL, (f = fopen("hyperion.txt", "r"))); int i = 0; for (;;) { - __printf("i=%d\n", i++); rc = getline(&line, &linesize, f); if (rc == -1) break; data = xrealloc(data, size + rc); diff --git a/test/libc/stdio/mkostempsm_test.c b/test/libc/stdio/mkostempsm_test.c index af911e000..f99e32a7e 100644 --- a/test/libc/stdio/mkostempsm_test.c +++ b/test/libc/stdio/mkostempsm_test.c @@ -45,7 +45,6 @@ static int MockOpen1(const char *file, int flags, ...) { } TEST(mkostempsm, test1) { - if (IsWindows()) return; /* TODO */ uint64_t rando = 1; char path[PATH_MAX] = "/tmp/mkostemps.XXXXXX"; EXPECT_EQ(123L, mkostempsmi(path, 0, 0, &rando, 0600, MockOpen1)); @@ -74,7 +73,6 @@ static int MockOpen2(const char *file, int flags, ...) { } TEST(mkostempsm, test2) { - if (IsWindows()) return; /* TODO */ uint64_t rando = 1; char path[PATH_MAX] = "/tmp/mkostemps.XXXXXX"; EXPECT_EQ(123, mkostempsmi(path, 0, 0, &rando, 0600, MockOpen2)); diff --git a/test/libc/stdio/spawn_test.c b/test/libc/stdio/spawn_test.c index c834a6a9c..75fd4ecb8 100644 --- a/test/libc/stdio/spawn_test.c +++ b/test/libc/stdio/spawn_test.c @@ -30,7 +30,7 @@ TEST(spawn, test) { int rc, ws, pid; - char *prog = (char *)getauxval(AT_EXECFN); + char *prog = GetProgramExecutableName(); char *args[] = {program_invocation_name, NULL}; char *envs[] = {"THE_DOGE=42", NULL}; if (atoi(nulltoempty(getenv("THE_DOGE"))) == 42) exit(42); diff --git a/test/libc/stdio/tmpfile_test.c b/test/libc/stdio/tmpfile_test.c index 5f9039fb0..841255de4 100644 --- a/test/libc/stdio/tmpfile_test.c +++ b/test/libc/stdio/tmpfile_test.c @@ -29,7 +29,7 @@ TEST(tmpfile, test) { FILE *f; mkdir("doge", 0755); setenv("TMPDIR", "doge", true); - f = tmpfile(); + ASSERT_NE(NULL, (f = tmpfile())); EXPECT_NE(-1, fputc('t', f)); EXPECT_NE(-1, fflush(f)); rewind(f); diff --git a/test/libc/stdio/vappendf_test.c b/test/libc/stdio/vappendf_test.c index d3475859c..8489e3e5e 100644 --- a/test/libc/stdio/vappendf_test.c +++ b/test/libc/stdio/vappendf_test.c @@ -17,10 +17,15 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" +#include "libc/intrin/kprintf.h" #include "libc/stdio/append.internal.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" +static void PrintMemory(void *p) { + kprintf("%#.*hhs%n", malloc_usable_size(p), p); +} + TEST(vappendf, test) { char *b = 0; ASSERT_NE(-1, appendf(&b, "hello ")); @@ -137,6 +142,7 @@ TEST(appendr, testExtend_zeroFills) { TEST(appendr, testAbsent_allocatesNul) { char *b = 0; ASSERT_NE(-1, appendr(&b, 0)); + ASSERT_BINEQ(u" ", b); EXPECT_EQ(0, appendz(b).i); ASSERT_BINEQ(u" ", b); free(b); @@ -157,6 +163,16 @@ TEST(appendd, testMemFail_doesntFreeExistingAllocation) { free(b); } +TEST(appendd, nontrivialAmountOfMemory) { + char *b = 0; + int i, n = 40000; + for (i = 0; i < n; ++i) { + ASSERT_EQ(2, appendd(&b, "hi", 2)); + } + EXPECT_EQ(40000 * 2, appendz(b).i); + free(b); +} + BENCH(vappendf, bench) { const char t[] = {0}; char *b = 0; diff --git a/test/libc/str/classifypath_test.c b/test/libc/str/classifypath_test.c new file mode 100644 index 000000000..174ae9172 --- /dev/null +++ b/test/libc/str/classifypath_test.c @@ -0,0 +1,121 @@ +/*-*- 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 2022 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/dce.h" +#include "libc/str/path.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(isabspath, testUniversal) { + ASSERT_TRUE(_isabspath("/home/jart/foo.txt")); +} + +TEST(isabspath, testDosPaths) { + if (!SupportsWindows()) return; + ASSERT_FALSE(_isabspath("C:")); + ASSERT_FALSE(_isabspath("C:foo.txt")); + ASSERT_TRUE(_isabspath("C:/")); + ASSERT_TRUE(_isabspath("C:/Users/jart/foo.txt")); + ASSERT_TRUE(_isabspath("C:\\Users\\jart\\foo.txt")); + ASSERT_TRUE(_isabspath("\\Users\\jart\\foo.txt")); +} + +TEST(isabspath, testWin32Paths) { + if (!SupportsWindows()) return; + ASSERT_TRUE(_isabspath("\\\\?\\C:\\..")); + ASSERT_TRUE(_isabspath("\\\\.\\C:\\Users\\jart\\foo.txt")); +} + +TEST(isabspath, testNtPaths) { + if (!SupportsWindows()) return; + ASSERT_TRUE(_isabspath("\\??\\C:\\Users\\jart\\foo.txt")); +} + +TEST(_classifypath, test) { + if (!SupportsWindows()) return; + EXPECT_EQ(0, _classifypath("")); + EXPECT_EQ(0, _classifypath("xyz")); + EXPECT_EQ(_PATH_DOS | _PATH_DEV, _classifypath("CON")); + EXPECT_EQ(_PATH_DOS | _PATH_DEV, _classifypath("NUL")); + EXPECT_EQ(0, _classifypath(":")); + EXPECT_EQ(_PATH_DOS, _classifypath("::")); + EXPECT_EQ(_PATH_DOS, _classifypath(":::")); + EXPECT_EQ(_PATH_DOS, _classifypath("::::")); + EXPECT_EQ(_PATH_ABS | _PATH_DOS, _classifypath("::\\")); + EXPECT_EQ(_PATH_ABS, _classifypath("\\")); + EXPECT_EQ(_PATH_ABS, _classifypath("\\:")); + EXPECT_EQ(_PATH_ABS, _classifypath("\\C:")); + EXPECT_EQ(_PATH_ABS, _classifypath("\\C:\\")); + EXPECT_EQ(_PATH_ABS, _classifypath("/")); + EXPECT_EQ(_PATH_ABS, _classifypath("/:")); + EXPECT_EQ(_PATH_ABS, _classifypath("/C:")); + EXPECT_EQ(_PATH_ABS, _classifypath("/C:/")); + EXPECT_EQ(0, _classifypath("C")); + EXPECT_EQ(_PATH_DOS, _classifypath("C:")); + EXPECT_EQ(_PATH_DOS, _classifypath("C:a")); + EXPECT_EQ(_PATH_DOS, _classifypath("C:a\\")); + EXPECT_EQ(_PATH_ABS | _PATH_DOS, _classifypath("C:\\")); + EXPECT_EQ(_PATH_ABS | _PATH_DOS, _classifypath("C:/")); + EXPECT_EQ(_PATH_ABS | _PATH_DOS, _classifypath("C:\\a")); + EXPECT_EQ(_PATH_ABS | _PATH_DOS, _classifypath("C:/a")); + EXPECT_EQ(_PATH_ABS | _PATH_DOS, _classifypath("C:\\\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\;")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\f\\b\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\f\\b")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\f\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\f")); + EXPECT_EQ(_PATH_ABS | _PATH_NT, _classifypath("\\??\\")); + EXPECT_EQ(_PATH_ABS | _PATH_NT, _classifypath("\\??\\UNC")); + EXPECT_EQ(_PATH_ABS | _PATH_NT, _classifypath("\\??\\UNC\\")); + EXPECT_EQ(_PATH_ABS, _classifypath("\\?")); + EXPECT_EQ(_PATH_ABS, _classifypath("\\?\\")); + EXPECT_EQ(_PATH_ABS, _classifypath("\\?\\UNC")); + EXPECT_EQ(_PATH_ABS, _classifypath("\\?\\UNC\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV, _classifypath("\\\\?\\UNC\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT, + _classifypath("\\\\?")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\??")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\??\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\\\??\\C:\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT, + _classifypath("\\\\.")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV, _classifypath("\\\\.\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV, _classifypath("\\\\.\\C:\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("\\/")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("/\\")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("//")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("///")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("//;")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT, + _classifypath("//?")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT, + _classifypath("/\\?")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT, + _classifypath("\\/?")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN, _classifypath("//??")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT, + _classifypath("//.")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT, + _classifypath("\\/.")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV | _PATH_ROOT, + _classifypath("/\\.")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV, _classifypath("//./")); + EXPECT_EQ(_PATH_ABS | _PATH_WIN | _PATH_DEV, _classifypath("//./C:/")); +} diff --git a/test/libc/str/str_test.c b/test/libc/str/str_test.c index a1bda4b46..57818969b 100644 --- a/test/libc/str/str_test.c +++ b/test/libc/str/str_test.c @@ -41,5 +41,9 @@ TEST(strclen, testAegeanNumberSupplementaryPlane) { } TEST(strlen16, testCoolKidNulTerminator) { - EXPECT_EQ(2, strlen16((const char16_t *)"\x00\xd8\x00\xdc\x00")); + union { + uint8_t s8[6]; + char16_t s16[3]; + } u = {.s8 = {0x00, 0xd8, 0x00, 0xdc, 0x00, 0x00}}; + EXPECT_EQ(2, strlen16(u.s16)); } diff --git a/test/libc/str/strsignal_test.c b/test/libc/str/strsignal_test.c new file mode 100644 index 000000000..39fc43897 --- /dev/null +++ b/test/libc/str/strsignal_test.c @@ -0,0 +1,33 @@ +/*-*- 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 2022 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/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(strsignal, test) { + EXPECT_STREQ("SIGUNKNOWN", strsignal(0)); + EXPECT_STREQ("SIGINT", strsignal(SIGINT)); + EXPECT_STREQ("SIGQUIT", strsignal(SIGQUIT)); + EXPECT_STREQ("SIGALRM", strsignal(SIGALRM)); + EXPECT_STREQ("SIGUSR1", strsignal(SIGUSR1)); + EXPECT_STREQ("SIGSTOP", strsignal(SIGSTOP)); + EXPECT_STREQ("SIG099", strsignal(99)); + EXPECT_STREQ("SIG100", strsignal(100)); + EXPECT_STREQ("SIGWUT", strsignal(-1)); + EXPECT_STREQ("SIGWUT", strsignal(9001)); +} diff --git a/test/libc/str/undeflate_test.c b/test/libc/str/undeflate_test.c index 93ddf2e50..2b2c0c9a1 100644 --- a/test/libc/str/undeflate_test.c +++ b/test/libc/str/undeflate_test.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/errno.h" +#include "libc/intrin/kprintf.h" #include "libc/log/check.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" @@ -38,6 +39,7 @@ #include "libc/testlib/testlib.h" #include "libc/x/x.h" #include "libc/zip.h" +#include "libc/zipos/zipos.internal.h" #include "third_party/zlib/zlib.h" STATIC_YOINK("zip_uri_support"); @@ -89,7 +91,7 @@ TEST(undeflate, testEmbeddedCompressedZipFile_theHardWay) { ASSERT_NE(-1, fstat(fd, &st)); ASSERT_NE(MAP_FAILED, (map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0))); - ASSERT_NE(NULL, (cd = zipfindcentraldir(map, st.st_size))); + ASSERT_NE(NULL, (cd = GetZipCdir(map, st.st_size))); ASSERT_GE(ZIP_CDIR_RECORDS(cd), 1); for (i = 0, cf = map + ZIP_CDIR_OFFSET(cd); i < ZIP_CDIR_RECORDS(cd); ++i, cf += ZIP_CFILE_HDRSIZE(cf)) { @@ -113,8 +115,6 @@ TEST(undeflate, testEmbeddedCompressedZipFile_theHardWay) { ASSERT_TRUE(found); } -#if 0 /* todo: don't rely on __zip_end */ - uint8_t *buf_; size_t bufsize_; uint8_t *data_; @@ -141,29 +141,20 @@ void Undeflate(void) { undeflate(buf_, uncompressedsize_, data_, compressedsize_, &ds_); } -static size_t GetLocalFile(const char *name) { - size_t i, cf, namesize; - namesize = strlen(name); - for (i = 0, cf = ZIP_CDIR_OFFSET(__zip_end); i < ZIP_CDIR_RECORDS(__zip_end); - ++i, cf += ZIP_CFILE_HDRSIZE(cf)) { - if (namesize == ZIP_CFILE_NAMESIZE(&_base[0] + cf) && - memcmp(name, ZIP_CFILE_NAME(&_base[0] + cf), namesize) == 0) { - return ZIP_CFILE_OFFSET(&_base[0] + cf); - } - } - abort(); -} - BENCH(undeflate, bench) { - size_t lf; - lf = GetLocalFile("libc/testlib/hyperion.txt"); - data_ = ZIP_LFILE_CONTENT(&_base[0] + lf); - compressedsize_ = ZIP_LFILE_COMPRESSEDSIZE(&_base[0] + lf); - uncompressedsize_ = ZIP_LFILE_UNCOMPRESSEDSIZE(&_base[0] + lf); + size_t cf, lf; + struct Zipos *zipos; + struct ZiposUri path; + zipos = __zipos_get(); + path.path = "libc/testlib/hyperion.txt"; + path.len = strlen(path.path); + cf = __zipos_find(zipos, &path); + lf = GetZipCfileOffset(zipos->map + cf); + data_ = ZIP_LFILE_CONTENT(zipos->map + lf); + compressedsize_ = ZIP_LFILE_COMPRESSEDSIZE(zipos->map + lf); + uncompressedsize_ = ZIP_LFILE_UNCOMPRESSEDSIZE(zipos->map + lf); bufsize_ = ROUNDUP(uncompressedsize_, FRAMESIZE / 2); buf_ = gc(malloc(bufsize_)); EZBENCH(donothing, Inflate()); EZBENCH(donothing, Undeflate()); } - -#endif diff --git a/test/libc/test.mk b/test/libc/test.mk index 7f7bbf676..02b30e514 100644 --- a/test/libc/test.mk +++ b/test/libc/test.mk @@ -18,6 +18,7 @@ o/$(MODE)/test/libc: \ o/$(MODE)/test/libc/sock \ o/$(MODE)/test/libc/stdio \ o/$(MODE)/test/libc/str \ + o/$(MODE)/test/libc/thread \ o/$(MODE)/test/libc/time \ o/$(MODE)/test/libc/tinymath \ o/$(MODE)/test/libc/unicode \ diff --git a/test/libc/runtime/clone_test.c b/test/libc/thread/clone_test.c similarity index 78% rename from test/libc/runtime/clone_test.c rename to test/libc/thread/clone_test.c index cd05e1956..e1d599b00 100644 --- a/test/libc/runtime/clone_test.c +++ b/test/libc/thread/clone_test.c @@ -16,33 +16,42 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/dce.h" -#include "libc/log/backtrace.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/gc.internal.h" -#include "libc/runtime/symbols.internal.h" +#include "libc/intrin/spinlock.h" #include "libc/sysv/consts/clone.h" #include "libc/testlib/testlib.h" -#include "libc/time/time.h" -volatile int x; +int x, thechilde; +_Alignas(64) volatile char lock; + +void SetUp(void) { + x = 0; + lock = 0; + thechilde = 0; +} int thread(void *arg) { - return (x = 42); + x = 42; + ASSERT_EQ(23, (intptr_t)arg); + thechilde = gettid(); + _spunlock(&lock); + return 0; } TEST(clone, test) { - if (!IsLinux() && !IsNetbsd() && !IsWindows()) return; + if (IsXnu()) return; + if (IsOpenbsd()) return; // still flaky :'( + int me, tid; char *stack; - long double t; - int tid, ptid, ctid, tls, ws; - t = nowl(); - stack = gc(malloc(FRAMESIZE)); - EXPECT_NE(-1, (tid = clone(thread, stack + FRAMESIZE, + me = gettid(); + _spinlock(&lock); + stack = _gc(valloc(STACKSIZE)); + ASSERT_NE(-1, (tid = clone(thread, stack, STACKSIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, - 0, &ptid, &tls, &ctid))); - while ((nowl() - t) < 1 && !x) asm("pause"); + (void *)23, 0, 0, 0, 0))); + _spinlock(&lock); ASSERT_EQ(42, x); + ASSERT_NE(me, tid); + ASSERT_EQ(tid, thechilde); } diff --git a/test/libc/thread/test.mk b/test/libc/thread/test.mk new file mode 100644 index 000000000..33a46bc08 --- /dev/null +++ b/test/libc/thread/test.mk @@ -0,0 +1,71 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_THREAD + +TEST_LIBC_THREAD_SRCS := $(wildcard test/libc/thread/*.c) +TEST_LIBC_THREAD_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_THREAD_SRCS)) + +TEST_LIBC_THREAD_OBJS = \ + $(TEST_LIBC_THREAD_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_THREAD_COMS = \ + $(TEST_LIBC_THREAD_SRCS:%.c=o/$(MODE)/%.com) + +TEST_LIBC_THREAD_BINS = \ + $(TEST_LIBC_THREAD_COMS) \ + $(TEST_LIBC_THREAD_COMS:%=%.dbg) + +TEST_LIBC_THREAD_TESTS = \ + $(TEST_LIBC_THREAD_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_THREAD_CHECKS = \ + $(TEST_LIBC_THREAD_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_THREAD_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_INTRIN \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_THREAD \ + LIBC_TESTLIB + +TEST_LIBC_THREAD_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_THREAD_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/thread/thread.pkg: \ + $(TEST_LIBC_THREAD_OBJS) \ + $(foreach x,$(TEST_LIBC_THREAD_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/thread/%.com.dbg: \ + $(TEST_LIBC_THREAD_DEPS) \ + o/$(MODE)/test/libc/thread/%.o \ + o/$(MODE)/test/libc/thread/thread.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_THREAD_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +o/$(MODE)/test/libc/thread/getenv_test.com.runs: \ + o/$(MODE)/test/libc/thread/getenv_test.com + @HELLO=THERE build/runit $@ $< + +o/$(MODE)/test/libc/thread/fun_test.o \ +o/$(MODE)/test/libc/thread/itsatrap_test.o: \ + OVERRIDE_CFLAGS += \ + -fno-sanitize=all \ + -ftrapv + +.PHONY: o/$(MODE)/test/libc/thread +o/$(MODE)/test/libc/thread: \ + $(TEST_LIBC_THREAD_BINS) \ + $(TEST_LIBC_THREAD_CHECKS) diff --git a/test/libc/time/dsleep_test.c b/test/libc/time/dsleep_test.c deleted file mode 100644 index ab0be4703..000000000 --- a/test/libc/time/dsleep_test.c +++ /dev/null @@ -1,47 +0,0 @@ -/*-*- 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 "libc/calls/calls.h" -#include "libc/calls/sigbits.h" -#include "libc/calls/struct/sigset.h" -#include "libc/log/log.h" -#include "libc/nexgen32e/nexgen32e.h" -#include "libc/sysv/consts/clock.h" -#include "libc/sysv/consts/sig.h" -#include "libc/testlib/testlib.h" -#include "libc/time/time.h" -#include "libc/x/x.h" - -TEST(fastdiv, test) { - long x = 123000000321; - EXPECT_EQ(123, div1000000000int64(x)); - EXPECT_EQ(321, rem1000000000int64(x)); -} - -TEST(dsleep, test) { - long double t1, t2; - sigset_t mask, oldmask; - sigfillset(&mask); - sigprocmask(SIG_BLOCK, &mask, &oldmask); - sched_yield(); - t1 = dtime(CLOCK_MONOTONIC); - dsleep(0.001L); - t2 = dtime(CLOCK_MONOTONIC); - sigprocmask(SIG_SETMASK, &oldmask, NULL); - ASSERT_LDBL_GT(t2 - t1, 0.0005L); -} diff --git a/test/libc/tinymath/asin_test.c b/test/libc/tinymath/asin_test.c index fe476a788..ed35e42ef 100644 --- a/test/libc/tinymath/asin_test.c +++ b/test/libc/tinymath/asin_test.c @@ -49,5 +49,5 @@ BENCH(asin, bench) { EZBENCH2("asin(-0)", donothing, asin(-0.)); EZBENCH2("asin(NAN)", donothing, asin(NAN)); EZBENCH2("asin(INFINITY)", donothing, asin(INFINITY)); - EZBENCH_C("asin", _real1(vigna()), asin(_real1(vigna()))); + EZBENCH_C("asin", _real1(lemur64()), asin(_real1(lemur64()))); } diff --git a/test/libc/tinymath/complex_test.c b/test/libc/tinymath/complex_test.c new file mode 100644 index 000000000..70e6f493e --- /dev/null +++ b/test/libc/tinymath/complex_test.c @@ -0,0 +1,34 @@ +/*-*- 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 2022 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/complex.h" +#include "libc/fmt/fmt.h" +#include "libc/testlib/testlib.h" + +TEST(complex, test) { + char buf[128]; + complex double z, z1; + sprintf(buf, "I = %.1f%+.1fi", creal(_Complex_I), cimag(_Complex_I)); + EXPECT_STREQ("I = 0.0+1.0i", buf); + z1 = _Complex_I * _Complex_I; // imaginary unit squared + sprintf(buf, "I * I = %.1f%+.1fi", creal(z1), cimag(z1)); + EXPECT_STREQ("I * I = -1.0+0.0i", buf); + z = 1.0 + 2.0 * _Complex_I; // usual way to form a complex number pre-C11 + sprintf(buf, "z = %.1f%+.1fi", creal(z), cimag(z)); + EXPECT_STREQ("z = 1.0+2.0i", buf); +} diff --git a/test/libc/tinymath/csqrt_test.c b/test/libc/tinymath/csqrt_test.c new file mode 100644 index 000000000..d585a1b08 --- /dev/null +++ b/test/libc/tinymath/csqrt_test.c @@ -0,0 +1,28 @@ +/*-*- 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 2022 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/complex.h" +#include "libc/fmt/fmt.h" +#include "libc/runtime/gc.internal.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(csqrt, test) { + complex double x = csqrt(-1); + EXPECT_STREQ("0 1", gc(xasprintf("%g %g", creal(x), cimag(x)))); +} diff --git a/test/libc/tinymath/strtod_test.c b/test/libc/tinymath/strtod_test.c index bd9c38388..e1fce65a8 100644 --- a/test/libc/tinymath/strtod_test.c +++ b/test/libc/tinymath/strtod_test.c @@ -33,28 +33,24 @@ void TearDown(void) { } TEST(strtod, testNearest) { - if (IsWindows()) return; fesetround(FE_TONEAREST); EXPECT_STREQ("-1.79769313486231e+308", gc(xasprintf("%.15g", strtod("-1.79769313486231e+308", NULL)))); } TEST(strtod, testDownward) { - if (IsWindows()) return; fesetround(FE_DOWNWARD); EXPECT_STREQ("-1.79769313486232e+308", gc(xasprintf("%.15g", strtod("-1.79769313486231e+308", NULL)))); } TEST(strtod, testUpward) { - if (IsWindows()) return; fesetround(FE_UPWARD); EXPECT_STREQ("-1.7976931348623e+308", gc(xasprintf("%.15g", strtod("-1.79769313486231e+308", NULL)))); } TEST(strtod, testTowardzero) { - if (IsWindows()) return; char *p; for (int i = 0; i < 9999; ++i) { fesetround(FE_TOWARDZERO); diff --git a/test/libc/x/filecmp_test.c b/test/libc/x/filecmp_test.c index fd1c94f41..578d262d9 100644 --- a/test/libc/x/filecmp_test.c +++ b/test/libc/x/filecmp_test.c @@ -26,6 +26,9 @@ #include "libc/testlib/testlib.h" #include "libc/x/x.h" +// TODO: This test flakes occasionally on Windows. +#if 0 + #define N (72 * 1024) char p[N]; @@ -59,3 +62,5 @@ BENCH(filecmp, bench) { EXPECT_EQ(0, xbarf("b", p, N)); EZBENCH2("filecmp", donothing, filecmp("a", "b")); } + +#endif diff --git a/test/libc/x/test.mk b/test/libc/x/test.mk index b5fa44aa6..025c759c0 100644 --- a/test/libc/x/test.mk +++ b/test/libc/x/test.mk @@ -32,6 +32,7 @@ TEST_LIBC_X_DIRECTDEPS = \ LIBC_STDIO \ LIBC_STR \ LIBC_RAND \ + LIBC_SOCK \ LIBC_STUBS \ LIBC_SYSV \ LIBC_TESTLIB \ diff --git a/test/libc/xed/lib.h b/test/libc/xed/lib.h index 97b0c80d2..a9d5ebe6f 100644 --- a/test/libc/xed/lib.h +++ b/test/libc/xed/lib.h @@ -6,7 +6,7 @@ COSMOPOLITAN_C_START_ int ild(const char16_t *codez); int ildreal(const char16_t *codez); int ildlegacy(const char16_t *codez); -uint8_t *unbingx86op(const char16_t *codez) nodiscard; +uint8_t *unbingx86op(const char16_t *codez) dontdiscard; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/test/libc/xed/x86ild_lib.c b/test/libc/xed/x86ild_lib.c index c94bc4976..1cd65857c 100644 --- a/test/libc/xed/x86ild_lib.c +++ b/test/libc/xed/x86ild_lib.c @@ -25,7 +25,7 @@ #include "test/libc/xed/lib.h" #include "third_party/xed/x86.h" -testonly nodiscard uint8_t *unbingx86op(const char16_t *codez) { +testonly dontdiscard uint8_t *unbingx86op(const char16_t *codez) { size_t len; len = strlen16(codez); return unbingbuf(xmalloc(ROUNDUP(len, 16)), len, codez, 0x90); @@ -35,8 +35,8 @@ testonly nodiscard uint8_t *unbingx86op(const char16_t *codez) { * Long mode instruction length decoder. */ testonly int ild(const char16_t *codez) { + int error; struct XedDecodedInst xedd; - enum XedError error; error = xed_instruction_length_decode( xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64), gc(unbingx86op(codez)), strlen16(codez) + 16); @@ -47,8 +47,8 @@ testonly int ild(const char16_t *codez) { * Real mode instruction length decoder. */ testonly int ildreal(const char16_t *codez) { + int error; struct XedDecodedInst xedd; - enum XedError error; error = xed_instruction_length_decode( xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_REAL), gc(unbingx86op(codez)), strlen16(codez) + 16); @@ -59,8 +59,8 @@ testonly int ildreal(const char16_t *codez) { * Legacy mode instruction length decoder. */ testonly int ildlegacy(const char16_t *codez) { + int error; struct XedDecodedInst xedd; - enum XedError error; error = xed_instruction_length_decode( xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LEGACY_32), gc(unbingx86op(codez)), strlen16(codez) + 16); diff --git a/test/net/http/parsehttpmessage_test.c b/test/net/http/parsehttpmessage_test.c index 893b953c5..bb2897e38 100644 --- a/test/net/http/parsehttpmessage_test.c +++ b/test/net/http/parsehttpmessage_test.c @@ -528,7 +528,7 @@ GET / HTTP/1.1\r\n\ X-In-Your-Way-A: a\r\n\ X-In-Your-Way-B: b\r\n\ X-In-Your-Way-C: b\r\n\ -Accept-Encoding: deflate\r\n\ +Accept-Encoding:deflate\r\n\ ACCEPT-ENCODING: gzip\r\n\ ACCEPT-encoding: bzip2\r\n\ \r\n"; diff --git a/test/tool/build/lib/bsu_test.c b/test/tool/build/lib/bsu_test.c index 8a7593bf3..1e4053527 100644 --- a/test/tool/build/lib/bsu_test.c +++ b/test/tool/build/lib/bsu_test.c @@ -199,6 +199,9 @@ void FixupUndefOpTestFlags(char w, int h, uint64_t x, uint64_t y, if (y != 0 && y != 1) { *flags = SetFlag(*flags, FLAGS_OF, GetFlag(goldenflags, FLAGS_OF)); } + if (y >= w) { + *flags = SetFlag(*flags, FLAGS_CF, GetFlag(goldenflags, FLAGS_CF)); + } } TEST(bsu, test) { diff --git a/test/tool/net/redbean_test.c b/test/tool/net/redbean_test.c index d91f65068..177ee4294 100644 --- a/test/tool/net/redbean_test.c +++ b/test/tool/net/redbean_test.c @@ -19,7 +19,6 @@ #include "libc/calls/calls.h" #include "libc/calls/sigbits.h" #include "libc/fmt/conv.h" -#include "libc/log/check.h" #include "libc/runtime/gc.internal.h" #include "libc/runtime/runtime.h" #include "libc/sock/goodsocket.internal.h" @@ -91,7 +90,7 @@ char *SendHttpRequest(const char *s) { bool Matches(const char *regex, const char *str) { bool r; regex_t re; - CHECK_EQ(REG_OK, regcomp(&re, regex, 0)); + EXPECT_EQ(REG_OK, regcomp(&re, regex, 0)); r = regexec(&re, str, 0, 0, 0) == REG_OK; regfree(&re); return r; @@ -103,15 +102,22 @@ TEST(redbean, testOptions) { int pid, pipefds[2]; sigset_t chldmask, savemask; sigaddset(&chldmask, SIGCHLD); - CHECK_NE(-1, sigprocmask(SIG_BLOCK, &chldmask, &savemask)); + EXPECT_NE(-1, sigprocmask(SIG_BLOCK, &chldmask, &savemask)); ASSERT_NE(-1, pipe(pipefds)); ASSERT_NE(-1, (pid = fork())); if (!pid) { + setpgrp(); + close(0); + open("/dev/null", O_RDWR); + close(1); + dup(0); + close(2); + open("log", O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, 0644); close(pipefds[0]); dup2(pipefds[1], 1); sigprocmask(SIG_SETMASK, &savemask, NULL); execv("bin/redbean.com", - (char *const[]){"bin/redbean.com", "-szp0", "-l127.0.0.1", 0}); + (char *const[]){"bin/redbean.com", "-vvszp0", "-l127.0.0.1", 0}); _exit(127); } EXPECT_NE(-1, close(pipefds[1])); @@ -126,9 +132,11 @@ TEST(redbean, testOptions) { "Content-Length: 0\r\n" "\r\n", gc(SendHttpRequest("OPTIONS * HTTP/1.1\n\n")))); + EXPECT_EQ(0, close(pipefds[0])); EXPECT_NE(-1, kill(pid, SIGTERM)); EXPECT_NE(-1, wait(0)); - CHECK_NE(-1, sigprocmask(SIG_SETMASK, &savemask, 0)); + EXPECT_NE(-1, sigprocmask(SIG_SETMASK, &savemask, 0)); + if (g_testlib_failed) fputs(gc(xslurp("log", 0)), stderr); } TEST(redbean, testPipeline) { @@ -137,15 +145,20 @@ TEST(redbean, testPipeline) { int pid, pipefds[2]; sigset_t chldmask, savemask; sigaddset(&chldmask, SIGCHLD); - CHECK_NE(-1, sigprocmask(SIG_BLOCK, &chldmask, &savemask)); + EXPECT_NE(-1, sigprocmask(SIG_BLOCK, &chldmask, &savemask)); ASSERT_NE(-1, pipe(pipefds)); ASSERT_NE(-1, (pid = fork())); if (!pid) { + setpgrp(); + close(0); + open("/dev/null", O_RDWR); + close(2); + open("log", O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, 0644); close(pipefds[0]); dup2(pipefds[1], 1); sigprocmask(SIG_SETMASK, &savemask, NULL); execv("bin/redbean.com", - (char *const[]){"bin/redbean.com", "-szp0", "-l127.0.0.1", 0}); + (char *const[]){"bin/redbean.com", "-vvszp0", "-l127.0.0.1", 0}); _exit(127); } EXPECT_NE(-1, close(pipefds[1])); @@ -169,7 +182,9 @@ TEST(redbean, testPipeline) { "\r\n", gc(SendHttpRequest("OPTIONS * HTTP/1.1\n\n" "OPTIONS * HTTP/1.1\n\n")))); + EXPECT_EQ(0, close(pipefds[0])); EXPECT_NE(-1, kill(pid, SIGTERM)); EXPECT_NE(-1, wait(0)); - CHECK_NE(-1, sigprocmask(SIG_SETMASK, &savemask, 0)); + EXPECT_NE(-1, sigprocmask(SIG_SETMASK, &savemask, 0)); + if (g_testlib_failed) fputs(gc(xslurp("log", 0)), stderr); } diff --git a/test/tool/plinko/algebra_test.lisp b/test/tool/plinko/algebra_test.lisp new file mode 100644 index 000000000..5f4c157c6 --- /dev/null +++ b/test/tool/plinko/algebra_test.lisp @@ -0,0 +1,99 @@ +#| plinko - a really fast lisp tarpit + | Copyright 2022 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. + |# + +(TEST '(A B C) (SUBST '(A B C) NIL)) +(TEST '(X B C) (SUBST '(A B C) '((A . X)))) +(TEST '(X B Z) (SUBST '(A B C) '((A . X) (C . Z)))) +(TEST '((X) B Z) (SUBST '((A) B C) '((A . X) (C . Z)))) + +(TEST '(ADD B C) (RIGHTEN '(ADD C B))) +(TEST '(ADD C (ADD A B)) (RIGHTEN '(ADD C (ADD A B)))) +(TEST '(ADD C (* A B)) (RIGHTEN '(ADD (* A B) C))) +(TEST '(ADD C (ADD A B)) (RIGHTEN '(ADD (ADD A B) C))) +(TEST '(ADD A (ADD B (ADD C D))) (RIGHTEN '(ADD (ADD (ADD D C) B) A))) + +(TEST 'DOG (SIMPTREE 'DOG '((* ((* A 0) 0))))) +(TEST '(NOT X) (SIMPTREE '(NOT X) '((* ((* A 0) 0))))) +(TEST '0 (SIMPTREE '(* Z 0) '((* ((* A 0) 0))))) +(TEST '0 (SIMPTREE '(* (* Z 0) (* Z 0)) + '((* ((* A 0) 0) + ((* A 0) 0))))) + +(TEST '(A) (PERMCOMM 'A)) +(TEST '((SUB A B)) (PERMCOMM '(SUB A B))) +(TEST '((ADD B A) (ADD A B)) (PERMCOMM '(ADD A B))) +(TEST '((ADD C (* A B)) (ADD (* A B) C) (ADD C (* B A)) (ADD (* B A) C)) (PERMCOMM '(ADD (* A B) C))) + +(TEST '0 (SIMPLIFY '(AND P (NOT P)))) +(TEST '0 (SIMPLIFY '(NOT (OR P (NOT P))))) +(TEST 'A (SIMPLIFY '(* (SQRT A) (SQRT A)))) +(TEST 'A (SIMPLIFY '(SQRT (POW 4 (LOGN A 2))))) +(TEST '(* (ABS A) (POW 2 (DIV 1 2))) (SIMPLIFY '(HYPOT A A))) +(TEST '1 (SIMPLIFY '(POW (SQR A) 0))) +(TEST '(POW A (* B C)) (SIMPLIFY '(POW (POW A B) C))) +(TEST '(POW A (ADD B C)) (SIMPLIFY '(* (POW A B) (POW A C)))) +(TEST 'B (SIMPLIFY '(LOGN (POW A B) A))) +(TEST '(DIV (LOG (DIV A B)) (LOG C)) (SIMPLIFY '(SUB (LOGN A C) (LOGN B C)))) +;; (TEST '(DIV (* P (LOG X)) (LOG A)) (SIMPLIFY '(LOGN (POW X P) A))) ;; LITTLE WEIRD +(TEST '(* B C) (SIMPLIFY '(LOGN (POW (POW A B) C) A))) +(TEST 'A (SIMPLIFY '(DIV A 1))) +(TEST '0 (SIMPLIFY '(DIV 0 A))) +(TEST ':DBZERO (SIMPLIFY '(DIV A 0))) +(TEST ':DBZERO (SIMPLIFY '(LOGN A 1))) +(TEST '(DIV A B) (SIMPLIFY '(DIV (SUB 0 A) (SUB 0 B)))) +(TEST '1 (SIMPLIFY '(DIV A A))) +(TEST '(DIV B C) (SIMPLIFY '(DIV (* A B) (* A C)))) +(TEST '(DIV A C) (SIMPLIFY '(* (DIV A B) (DIV B C)))) +(TEST '(DIV C B) (SIMPLIFY '(* (DIV A B) (DIV C A)))) +(TEST 'B (SIMPLIFY '(* (DIV B A) A))) +(TEST '(DIV (ADD A C) B) (SIMPLIFY '(ADD (DIV A B) (DIV C B)))) +(TEST '(DIV (SUB A C) B) (SIMPLIFY '(SUB (DIV A B) (DIV C B)))) +;; (TEST '(DIV (* A D) (* B C)) (SIMPLIFY '(DIV (DIV A B) (DIV C D)))) +(TEST '(DIV 1 A) (SIMPLIFY '(* (POW A (SUB B 1)) (POW A (SUB 0 B))))) +(TEST '(* C (POW A 2)) (SIMPLIFY '(* (ABS A) (* (ABS A) C)))) +(TEST '(OR B (NOT A)) (SIMPLIFY '(SUB (ADD (SUB 0 A) (AND A B)) 1))) +(TEST '(NOT (XOR A B)) (SIMPLIFY '(SUB (ADD (SUB (SUB 0 A) B) (* 2 (AND A B))) 1))) +(TEST '(ADD Z (SUB X Y)) (SIMPLIFY '(ADD (OR (SUB (AND X (NOT Y)) (AND (NOT X) Y)) Z) (AND (SUB (AND X (NOT Y)) (AND (NOT X) Y)) Z)))) +(TEST '(* (ADD A B) (SUB A B)) (SIMPLIFY '(SUB (SQR A) (SQR B)))) +(TEST '(* (ADD A B) (SUB A B)) (SIMPLIFY '(SUB (SUB (* A (ADD B A)) (* A B)) (POW B 2)))) +(TEST '(ADD X Y) (SIMPLIFY '(ADD (XOR X Y) (* (AND X Y) 2)))) + +(TEST (DERIV '(* X 1) 'X) '(ADD (* X 0) (* 1 1))) +(TEST (DERIV '(* X Y) 'X) '(ADD (* X 0) (* 1 Y))) +(TEST (DERIV '(* (* X Y) (ADD X 3)) 'X) '(ADD (* (* X Y) (ADD 1 0)) (* (ADD (* X 0) (* 1 Y)) (ADD X 3)))) +(TEST '(ADD (* (POW X 2) (* (LOG X) 0)) (* 2 (* (POW X (SUB 2 1)) 1))) (DERIV '(POW X 2) 'X)) + +(TEST '0 (DERIVATIVE '(* X 0) 'X)) +(TEST '1 (DERIVATIVE '(* X 1) 'X)) +(TEST 'Y (DERIVATIVE '(* X Y) 'X)) +(TEST '(* 2 X) (DERIVATIVE '(* X X) 'X)) +(TEST '(* 4 (POW X 3)) (DERIVATIVE '(* (* (* X X) X) X) 'X)) +(TEST '(* Y (ADD 3 (* 2 X))) (DERIVATIVE '(* (* X Y) (ADD X 3)) 'X)) +(TEST '(* 3 (POW X 2)) (DERIVATIVE '(POW X 3) 'X)) +(TEST '(* 4 (POW X 3)) (DERIVATIVE '(POW (* X X) 2) 'X)) +(TEST '(* Y (* 3 (POW X 2))) (DERIVATIVE '(* (* (* X Y) X) X) 'X)) +(TEST '(DIV 1 X) (DERIVATIVE '(LOG X) 'X)) +(TEST '(DIV Y X) (DERIVATIVE '(LOG (POW X Y)) 'X)) +(TEST '(COS X) (DERIVATIVE '(SIN X) 'X)) +(TEST '(* Y (COS (* X Y))) (DERIVATIVE '(SIN (* X Y)) 'X)) +(TEST '(SUB 0 (SIN X)) (DERIVATIVE '(COS X) 'X)) +(TEST '(SUB 0 (* Y (SIN (* X Y)))) (DERIVATIVE '(COS (* X Y)) 'X)) +(TEST '(DIV 1 (* 2 (POW X (DIV 1 2)))) (DERIVATIVE '(SQRT X) 'X)) +(TEST '(* Y (DIV X (ABS X))) (DERIVATIVE '(* Y (ABS X)) 'X)) +(TEST '1 (DERIVATIVE '(SUB X Y) 'X)) +(TEST '(SUB 0 1) (DERIVATIVE '(SUB X Y) 'Y)) +(TEST '(* Y (POW X (SUB Y 1))) (DERIVATIVE '(POW X Y) 'X)) diff --git a/test/tool/plinko/library_test.lisp b/test/tool/plinko/library_test.lisp new file mode 100644 index 000000000..0661f9b32 --- /dev/null +++ b/test/tool/plinko/library_test.lisp @@ -0,0 +1,222 @@ +#| plinko - a really fast lisp tarpit + | Copyright 2022 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. + |# + +(test nil (cmp 'a 'a)) +(test '(nil) (cmp 'a 'b)) +(test t (cmp 'b 'a)) +(test '(nil) (cmp 'a 'aa)) +(test t (cmp 'aa 'a)) +(test '(nil) (cmp 'a '(a))) +(test t (cmp '(a) 'a)) +(test nil (cmp '(a) '(a))) +(test '(nil) (cmp '(a) '(a b))) +(test nil (cmp '(a a) '(a a))) +(test '(nil) (cmp '(a a) '(a aa))) +(test '(nil) (cmp '(a a) '((a) a))) +(test '(nil) (cmp '(a a) '(a a b))) +(test 'hello ((macro (x) (cons (quote quote) (cons x))) hello)) +(test 'hello ((closure (macro (x) (cons (quote quote) (cons x)))) hello)) +(test '(quoth hello) ((macro (x) (cons (quote quote) (cons (cons (quote quoth) (cons x))))) hello)) +(test (quote (macro (x) (cons (quote quote) (cons x)))) (car (cdr (macro (x) (cons (quote quote) (cons x)))))) + +(test 'b ((closure (lambda () a) (a . b)))) +(test 'b (eval 'a '((a . b)))) + +(test nil (reverse)) +(test '(c b a) (reverse '(a b c))) + +(test '(a b c) + (akeys '((a x) + (b y) + (c z)))) + +(test '(x y z) + (avals '((a x) + (b y) + (c z)))) + +(test t (and)) +(test nil (and nil)) +(test t (and t)) +(test nil (and nil nil)) +(test nil (and t nil)) +(test nil (and nil t)) +(test t (and t t)) +(test 'a (and 'a)) +(test 'b (and 'a 'b)) +(test 'c (and 'a 'b 'c)) + +(test nil (or)) +(test nil (or nil)) +(test t (or t)) +(test nil (or nil nil)) +(test t (or t nil)) +(test t (or nil t)) +(test t (or t t)) +(test 'a (or 'a)) +(test 'a (or 'a 'b)) +(test 'a (or 'a 'b 'c)) + +(test t (not)) +(test t (not nil)) +(test nil (not t)) +(test '(eq x) (expand '(not x))) + +(test '(abc . def) + (let ((x 'abc) + (y 'def)) + (cons x y))) + +(test '((lambda (x y) + (cons x y)) + 'abc + 'def) + (expand '(let ((x 'abc) + (y 'def)) + (cons x y)))) + +(test '(abc def (abc . def)) + (let* ((x 'abc) + (y 'def) + (z (cons x y))) + (cons x (cons y (cons z))))) + +(test '((lambda (x) + ((lambda (y) + ((lambda (z) + (list x y z)) + (cons x y))) + 'def)) + 'abc) + (expand '(let* ((x 'abc) + (y 'def) + (z (cons x y))) + (list x y z)))) + +(test nil (last nil)) +(test 'a (last '(a))) +(test 'b (last '(a b))) +(test '(c) (last '(a b (c)))) + +(test nil (copy nil)) +(test t (copy t)) +(test '(a b) (copy '(a b))) +(test '(a . b) (copy '(a . b))) + +(test nil (assoc 'a ())) +(test nil (assoc 'd '((a b) (c d)))) +(test '(a b) (assoc 'a '((a b) (c d)))) +(test '(c d) (assoc 'c '((a b) (c d)))) +(test '((foo bar) d) (assoc '(foo bar) '((a b) ((foo bar) d)))) + +(test '(a) (addset 'a)) +(test '(a) (addset 'a '(a))) +(test '(b a) (addset 'b '(a))) +(test '(a b) (addset 'b '(a b))) + +(test '(a) (peel 'a)) +(test '(a) (peel 'a '(a))) +(test '(b a) (peel 'b '(a))) +(test '(b a b) (peel 'b '(a b))) + +(test nil (reverse (reverse-mapcar cons nil))) +(test '((a) (b) (c)) (reverse (reverse-mapcar cons '(a b c)))) +(test '(a b a) (reverse (reverse-mapcar car '((a . x) (b . y) (a . z))))) +(test '(a b a c) (reverse (reverse-mapcar car '((a . x) (b . y) (a . z) (c . z))))) +(test '((a . a) (b . b) (a . a)) (reverse (reverse-mapcar (lambda (x) (cons x x)) '(a b a)))) + +(test nil (mapcar cons nil)) +(test '((a) (b) (c)) (mapcar cons '(a b c))) +(test '(a b a) (mapcar car '((a . x) (b . y) (a . z)))) +(test '(a b a c) (mapcar car '((a . x) (b . y) (a . z) (c . z)))) +(test '((a . a) (b . b) (a . a)) (mapcar (lambda (x) (cons x x)) '(a b a))) + +(test nil (mapset cons nil)) +(test '((a) (b) (c)) (mapset cons '(a b c))) +(test '(a b) (mapset car '((a . x) (b . y) (a . z)))) +(test '((a . a) (b . b)) (mapset (lambda (x) (cons x x)) '(a b a))) + +(test 'a (reduce list '(a))) +(test '(((a b) c) d) (reduce list '(a b c d))) + +(test '(a b c d) (append '(a b) '(c d))) + +(test t (all ())) +(test nil (all '(a b nil d))) +(test 'd (all '(a b c d))) + +(test nil (any ())) +(test 'a (any '(a b nil d))) +(test 'b (any '(nil b c d))) +(test nil (any '(nil nil))) + +(test '((a . b) (c . d)) (pairwise '(a b c d))) +(test '((a . a) (b . b) (c . c)) (dolist (x '(a b c)) (cons x x))) +(test '((a . a) (b . b) (c . c)) (reverse (reverse-dolist (x '(a b c)) (cons x x)))) +(test '((a . a) (c . c)) (reverse (reverse-dolist (x '(a a c) peel) (cons x x)))) + +(test '((abs ((abs k) k)) + (log ((log 1) 0)) + (add ((add 1 2) 3) + ((add 1 3) 4) + ((add 1 4) 5)) + (sub ((sub 1 1) 0) + ((sub 2 1) 1) + ((sub 3 1) 2))) + (GroupBy (lambda (x) (caar x)) + '(((abs k) k) + ((log 1) 0) + ((add 1 2) 3) + ((add 1 3) 4) + ((add 1 4) 5) + ((sub 1 1) 0) + ((sub 2 1) 1) + ((sub 3 1) 2)))) + +(progn + (cond ((eq 'b (car (cdr '(a b c d))))) ((error '(cadr failed)))) + (cond ((eq 'c (car (cdr (cdr '(a b c d)))))) ((error '(caddr failed)))) + (cond ((eq 'c (car (cdr (car '(((a . b) . (c . d)))))))) ((error '(cadar failed)))) + (cond ((eq 'a (car (car '((a . b) . (c . d)))))) ((error '(caar failed)))) + (cond ((eq 'b (cdr (car '((a . b) . (c . d)))))) ((error '(cdar failed)))) + (cond ((eq 'c (car (cdr '((a . b) . (c . d)))))) ((error '(cadr failed)))) + (cond ((eq 'd (cdr (cdr '((a . b) . (c . d)))))) ((error '(cddr failed)))) + (cond ((eq 'a ((lambda ((x )) x) (cons 'a 'b)))) ((error '(lambda car failed)))) + (cond ((eq 'b ((lambda ((nil . x)) x) (cons 'a 'b)))) ((error '(lambda cdr failed)))) + (ignore)) + +(progn + (cond ((eq (quote a) + ((lambda (f) + (f f (quote ((a) b c)))) + (lambda (f a) + (cond ((atom a) a) + ((f f (car a)))))))) + ((error (quote (test failed)) + (quote (find first atom))))) + (ignore)) + +(progn + (cond ((equal (cons 'a 'b) + (((lambda (f) + (f (cons 'a 'b))) + (lambda (x) + (lambda () + x)))))) + ((error '(enclosed memory failed to propogate upward)))) + (ignore)) + diff --git a/test/tool/plinko/plinko_test.c b/test/tool/plinko/plinko_test.c new file mode 100644 index 000000000..4b95011b0 --- /dev/null +++ b/test/tool/plinko/plinko_test.c @@ -0,0 +1,126 @@ +/*-*- 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 2022 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/sigbits.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/errno.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/mem/io.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" + +STATIC_YOINK("zip_uri_support"); +STATIC_YOINK("plinko.com"); +STATIC_YOINK("library.lisp"); +STATIC_YOINK("library_test.lisp"); +STATIC_YOINK("binarytrees.lisp"); +STATIC_YOINK("algebra.lisp"); +STATIC_YOINK("algebra_test.lisp"); +STATIC_YOINK("infix.lisp"); +STATIC_YOINK("ok.lisp"); + +static const char *const kSauces[] = { + "/zip/library.lisp", // + "/zip/library_test.lisp", // + "/zip/binarytrees.lisp", // + "/zip/algebra.lisp", // + "/zip/algebra_test.lisp", // + "/zip/infix.lisp", // + "/zip/ok.lisp", // +}; + +char testlib_enable_tmp_setup_teardown_once; + +void SetUpOnce(void) { + int fdin, fdout; + ASSERT_NE(-1, mkdir("bin", 0755)); + ASSERT_NE(-1, (fdin = open("/zip/plinko.com", O_RDONLY))); + ASSERT_NE(-1, (fdout = creat("bin/plinko.com", 0755))); + ASSERT_NE(-1, _copyfd(fdin, fdout, -1)); + EXPECT_EQ(0, close(fdout)); + EXPECT_EQ(0, close(fdin)); +} + +TEST(plinko, worksOrPrintsNiceError) { + size_t n; + ssize_t rc, got; + char buf[1024], drain[64]; + sigset_t chldmask, savemask; + int i, pid, fdin, wstatus, pfds[2][2]; + struct sigaction ignore, saveint, savequit, savepipe; + bzero(buf, sizeof(buf)); + ignore.sa_flags = 0; + ignore.sa_handler = SIG_IGN; + EXPECT_EQ(0, sigemptyset(&ignore.sa_mask)); + EXPECT_EQ(0, sigaction(SIGINT, &ignore, &saveint)); + EXPECT_EQ(0, sigaction(SIGQUIT, &ignore, &savequit)); + EXPECT_EQ(0, sigaction(SIGPIPE, &ignore, &savepipe)); + EXPECT_EQ(0, sigemptyset(&chldmask)); + EXPECT_EQ(0, sigaddset(&chldmask, SIGCHLD)); + EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &chldmask, &savemask)); + ASSERT_NE(-1, pipe2(pfds[0], O_CLOEXEC)); + ASSERT_NE(-1, pipe2(pfds[1], O_CLOEXEC)); + ASSERT_NE(-1, (pid = vfork())); + if (!pid) { + close(0), dup(pfds[0][0]); + close(1), dup(pfds[1][1]); + close(2), dup(pfds[1][1]); + sigaction(SIGINT, &saveint, 0); + sigaction(SIGQUIT, &savequit, 0); + sigaction(SIGQUIT, &savepipe, 0); + sigprocmask(SIG_SETMASK, &savemask, 0); + execve("bin/plinko.com", (char *const[]){"bin/plinko.com", 0}, + (char *const[]){0}); + _exit(127); + } + EXPECT_NE(-1, close(pfds[0][0])); + EXPECT_NE(-1, close(pfds[1][1])); + for (i = 0; i < ARRAYLEN(kSauces); ++i) { + EXPECT_NE(-1, (fdin = open(kSauces[i], O_RDONLY))); + rc = _copyfd(fdin, pfds[0][1], -1); + if (rc == -1) EXPECT_EQ(EPIPE, errno); + EXPECT_NE(-1, close(fdin)); + } + EXPECT_NE(-1, close(pfds[0][1])); + EXPECT_NE(-1, (got = read(pfds[1][0], buf, sizeof(buf) - 1))); + EXPECT_NE(0, got); + while (read(pfds[1][0], drain, sizeof(drain)) > 0) donothing; + EXPECT_NE(-1, close(pfds[1][0])); + EXPECT_NE(-1, waitpid(pid, &wstatus, 0)); + EXPECT_TRUE(WIFEXITED(wstatus)); + if (!startswith(buf, "error: ")) { + EXPECT_STREQ("OKCOMPUTER\n", buf); + EXPECT_EQ(0, WEXITSTATUS(wstatus)); + } else { + EXPECT_EQ(1, WEXITSTATUS(wstatus)); + } + EXPECT_EQ(0, sigaction(SIGINT, &saveint, 0)); + EXPECT_EQ(0, sigaction(SIGQUIT, &savequit, 0)); + EXPECT_EQ(0, sigaction(SIGPIPE, &savepipe, 0)); + EXPECT_EQ(0, sigprocmask(SIG_SETMASK, &savemask, 0)); + if (g_testlib_failed) { + kprintf("note: got the following in pipe: %s%n", buf); + } +} diff --git a/test/tool/plinko/test.mk b/test/tool/plinko/test.mk new file mode 100644 index 000000000..c247d780a --- /dev/null +++ b/test/tool/plinko/test.mk @@ -0,0 +1,91 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_TOOL_PLINKO + +TEST_TOOL_PLINKO = $(TOOL_PLINKO_A_DEPS) $(TOOL_PLINKO_A) +TEST_TOOL_PLINKO_A = o/$(MODE)/test/tool/plinko/plinkolib.a +TEST_TOOL_PLINKO_FILES := $(wildcard test/tool/plinko/*) +TEST_TOOL_PLINKO_SRCS = $(filter %.c,$(TEST_TOOL_PLINKO_FILES)) +TEST_TOOL_PLINKO_SRCS_TEST = $(filter %_test.c,$(TEST_TOOL_PLINKO_SRCS)) +TEST_TOOL_PLINKO_HDRS = $(filter %.h,$(TEST_TOOL_PLINKO_FILES)) +TEST_TOOL_PLINKO_COMS = $(TEST_TOOL_PLINKO_OBJS:%.o=%.com) + +TEST_TOOL_PLINKO_OBJS = \ + $(TEST_TOOL_PLINKO_SRCS:%.c=o/$(MODE)/%.o) \ + o/$(MODE)/tool/plinko/plinko.com.zip.o \ + o/$(MODE)/tool/plinko/lib/library.lisp.zip.o \ + o/$(MODE)/tool/plinko/lib/binarytrees.lisp.zip.o \ + o/$(MODE)/tool/plinko/lib/algebra.lisp.zip.o \ + o/$(MODE)/tool/plinko/lib/infix.lisp.zip.o \ + o/$(MODE)/tool/plinko/lib/ok.lisp.zip.o \ + o/$(MODE)/test/tool/plinko/library_test.lisp.zip.o \ + o/$(MODE)/test/tool/plinko/algebra_test.lisp.zip.o + +TEST_TOOL_PLINKO_COMS = \ + $(TEST_TOOL_PLINKO_SRCS:%.c=o/$(MODE)/%.com) + +TEST_TOOL_PLINKO_BINS = \ + $(TEST_TOOL_PLINKO_COMS) \ + $(TEST_TOOL_PLINKO_COMS:%=%.dbg) + +TEST_TOOL_PLINKO_TESTS = \ + $(TEST_TOOL_PLINKO_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_TOOL_PLINKO_CHECKS = \ + $(TEST_TOOL_PLINKO_HDRS:%=o/$(MODE)/%.ok) \ + $(TEST_TOOL_PLINKO_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_TOOL_PLINKO_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_INTRIN \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_UNICODE \ + LIBC_X \ + LIBC_ZIPOS \ + THIRD_PARTY_COMPILER_RT \ + THIRD_PARTY_XED + +TEST_TOOL_PLINKO_DEPS := \ + $(call uniq,$(foreach x,$(TEST_TOOL_PLINKO_DIRECTDEPS),$($(x)))) + +$(TEST_TOOL_PLINKO_A): \ + test/tool/plinko/ \ + $(TEST_TOOL_PLINKO_A).pkg \ + $(TEST_TOOL_PLINKO_OBJS) + +$(TEST_TOOL_PLINKO_A).pkg: \ + $(TEST_TOOL_PLINKO_OBJS) \ + $(foreach x,$(TEST_TOOL_PLINKO_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/tool/plinko/%.com.dbg: \ + $(TEST_TOOL_PLINKO_DEPS) \ + $(TEST_TOOL_PLINKO_A) \ + o/$(MODE)/test/tool/plinko/%.o \ + $(TEST_TOOL_PLINKO_A).pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +o/$(MODE)/test/tool/plinko/plinko_test.com.runs: \ + QUOTA = -M100g + +o/$(MODE)/test/tool/plinko/algebra_test.lisp.zip.o \ +o/$(MODE)/test/tool/plinko/library_test.lisp.zip.o: \ + ZIPOBJ_FLAGS += \ + -B + +.PHONY: o/$(MODE)/test/tool/plinko +o/$(MODE)/test/tool/plinko: \ + $(TEST_TOOL_PLINKO_BINS) \ + $(TEST_TOOL_PLINKO_CHECKS) diff --git a/test/tool/test.mk b/test/tool/test.mk index fa224a841..4b5f57a02 100644 --- a/test/tool/test.mk +++ b/test/tool/test.mk @@ -4,5 +4,6 @@ .PHONY: o/$(MODE)/test/tool o/$(MODE)/test/tool: \ o/$(MODE)/test/tool/build \ + o/$(MODE)/test/tool/plinko \ o/$(MODE)/test/tool/net \ o/$(MODE)/test/tool/viz diff --git a/third_party/argon2/argon2.c b/third_party/argon2/argon2.c index 6fa853c39..8c876c7b5 100644 --- a/third_party/argon2/argon2.c +++ b/third_party/argon2/argon2.c @@ -1,28 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Argon2 reference source code package - reference C implementations │ +│ │ +│ Copyright 2015 │ +│ Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves │ +│ │ +│ You may use this work under the terms of a Creative Commons CC0 1.0 │ +│ License/Waiver or the Apache Public License 2.0, at your option. The │ +│ terms of these licenses can be found at: │ +│ │ +│ - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │ +│ - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/limits.h" #include "libc/mem/mem.h" #include "libc/str/str.h" #include "third_party/argon2/argon2.h" #include "third_party/argon2/core.h" #include "third_party/argon2/encoding.h" + +asm(".ident\t\"\\n\\n\ +argon2 (CC0 or Apache2)\\n\ +Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\ +Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\""); /* clang-format off */ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. +/** + * Function that gives the string representation of an argon2_type. + * @param type The argon2_type that we want the string for + * @param uppercase Whether the string should have the first letter uppercase + * @return NULL if invalid type, otherwise the string representation. */ - const char *argon2_type2string(argon2_type type, int uppercase) { switch (type) { case Argon2_d: @@ -32,10 +43,14 @@ const char *argon2_type2string(argon2_type type, int uppercase) { case Argon2_id: return uppercase ? "Argon2id" : "argon2id"; } - return NULL; } +/** + * Function that performs memory-hard hashing with certain degree of parallelism + * @param context Pointer to the Argon2 internal structure + * @return Error code if smth is wrong, ARGON2_OK otherwise + */ int argon2_ctx(argon2_context *context, argon2_type type) { /* 1. Validate all inputs */ int result = validate_inputs(context); @@ -131,9 +146,9 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, context.out = (uint8_t *)out; context.outlen = (uint32_t)hashlen; - context.pwd = CONST_CAST(uint8_t *)pwd; + context.pwd = (uint8_t *)(uintptr_t)pwd; context.pwdlen = (uint32_t)pwdlen; - context.salt = CONST_CAST(uint8_t *)salt; + context.salt = (uint8_t *)(uintptr_t)salt; context.saltlen = (uint32_t)saltlen; context.secret = NULL; context.secretlen = 0; @@ -176,6 +191,21 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, return ARGON2_OK; } +/** + * Hashes a password with Argon2i, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, const size_t pwdlen, const void *salt, @@ -187,6 +217,20 @@ int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, ARGON2_VERSION_NUMBER); } +/** + * Hashes a password with Argon2i, producing a raw hash at @hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash - updated by the function + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, const size_t pwdlen, const void *salt, @@ -251,9 +295,7 @@ int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, argon2_context ctx; uint8_t *desired_result = NULL; - int ret = ARGON2_OK; - size_t encoded_len; uint32_t max_field_len; @@ -312,6 +354,13 @@ fail: return ret; } +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) { return argon2_verify(encoded, pwd, pwdlen, Argon2_i); @@ -327,14 +376,39 @@ int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) { return argon2_verify(encoded, pwd, pwdlen, Argon2_id); } +/** + * Argon2d: Version of Argon2 that picks memory blocks depending + * on the password and salt. Only for side-channel-free + * environment!! + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ int argon2d_ctx(argon2_context *context) { return argon2_ctx(context, Argon2_d); } +/** + * Argon2i: Version of Argon2 that picks memory blocks + * independent on the password and salt. Good for side-channels, + * but worse w.r.t. tradeoff attacks if only one pass is used. + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ int argon2i_ctx(argon2_context *context) { return argon2_ctx(context, Argon2_i); } +/** + * Argon2id: Version of Argon2 where the first half-pass over memory is + * password-independent, the rest are password-dependent (on the password and + * salt). OK against side channels (they reduce to 1/2-pass Argon2i), and + * better with w.r.t. tradeoff attacks (similar to Argon2d). + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ int argon2id_ctx(argon2_context *context) { return argon2_ctx(context, Argon2_id); } @@ -353,18 +427,43 @@ int argon2_verify_ctx(argon2_context *context, const char *hash, return ARGON2_OK; } +/** + * Verify if a given password is correct for Argon2d hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ int argon2d_verify_ctx(argon2_context *context, const char *hash) { return argon2_verify_ctx(context, hash, Argon2_d); } +/** + * Verify if a given password is correct for Argon2i hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ int argon2i_verify_ctx(argon2_context *context, const char *hash) { return argon2_verify_ctx(context, hash, Argon2_i); } +/** + * Verify if a given password is correct for Argon2id hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ int argon2id_verify_ctx(argon2_context *context, const char *hash) { return argon2_verify_ctx(context, hash, Argon2_id); } +/** + * Get the associated error message for given error code + * @return The error message associated with the given error code + */ const char *argon2_error_message(int error_code) { switch (error_code) { case ARGON2_OK: @@ -444,6 +543,16 @@ const char *argon2_error_message(int error_code) { } } +/** + * Returns the encoded hash length for the given input parameters + * @param t_cost Number of iterations + * @param m_cost Memory usage in kibibytes + * @param parallelism Number of threads; used to compute lanes + * @param saltlen Salt size in bytes + * @param hashlen Hash size in bytes + * @param type The argon2_type that we want the encoded length for + * @return The encoded hash length in bytes + */ size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism, uint32_t saltlen, uint32_t hashlen, argon2_type type) { return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) + diff --git a/third_party/argon2/argon2.h b/third_party/argon2/argon2.h index 91d3093ba..c65efabce 100644 --- a/third_party/argon2/argon2.h +++ b/third_party/argon2/argon2.h @@ -1,22 +1,11 @@ -#ifndef ARGON2_H -#define ARGON2_H +#ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_ +#define COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_ #include "libc/literal.h" -COSMOPOLITAN_C_START_ -/* clang-format off */ #define ARGON2_NO_THREADS -/* Symbols visibility control */ -#ifdef A2_VISCTL -#define ARGON2_PUBLIC __attribute__((visibility("default"))) -#define ARGON2_LOCAL __attribute__ ((visibility ("hidden"))) -#elif defined(_MSC_VER) -#define ARGON2_PUBLIC __declspec(dllexport) -#define ARGON2_LOCAL -#else -#define ARGON2_PUBLIC -#define ARGON2_LOCAL -#endif +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ /* * Argon2 input parameter restrictions @@ -42,10 +31,10 @@ COSMOPOLITAN_C_START_ #define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) /* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */ -#define ARGON2_MAX_MEMORY_BITS \ - ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) -#define ARGON2_MAX_MEMORY \ - ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) +#define ARGON2_MAX_MEMORY_BITS \ + ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) +#define ARGON2_MAX_MEMORY \ + ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) /* Minimum and maximum number of passes */ #define ARGON2_MIN_TIME UINT32_C(1) @@ -68,9 +57,9 @@ COSMOPOLITAN_C_START_ #define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) /* Flags to determine which fields are securely wiped (default = no wipe). */ -#define ARGON2_DEFAULT_FLAGS UINT32_C(0) +#define ARGON2_DEFAULT_FLAGS UINT32_C(0) #define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) -#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) +#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) /* Global flag to determine if we are wiping internal memory buffers. This flag * is defined in core.c and defaults to 1 (wipe internal memory). */ @@ -78,71 +67,48 @@ extern int FLAG_clear_internal_memory; /* Error codes */ typedef enum Argon2_ErrorCodes { - ARGON2_OK = 0, - - ARGON2_OUTPUT_PTR_NULL = -1, - - ARGON2_OUTPUT_TOO_SHORT = -2, - ARGON2_OUTPUT_TOO_LONG = -3, - - ARGON2_PWD_TOO_SHORT = -4, - ARGON2_PWD_TOO_LONG = -5, - - ARGON2_SALT_TOO_SHORT = -6, - ARGON2_SALT_TOO_LONG = -7, - - ARGON2_AD_TOO_SHORT = -8, - ARGON2_AD_TOO_LONG = -9, - - ARGON2_SECRET_TOO_SHORT = -10, - ARGON2_SECRET_TOO_LONG = -11, - - ARGON2_TIME_TOO_SMALL = -12, - ARGON2_TIME_TOO_LARGE = -13, - - ARGON2_MEMORY_TOO_LITTLE = -14, - ARGON2_MEMORY_TOO_MUCH = -15, - - ARGON2_LANES_TOO_FEW = -16, - ARGON2_LANES_TOO_MANY = -17, - - ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ - ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ - ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ - ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ - - ARGON2_MEMORY_ALLOCATION_ERROR = -22, - - ARGON2_FREE_MEMORY_CBK_NULL = -23, - ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, - - ARGON2_INCORRECT_PARAMETER = -25, - ARGON2_INCORRECT_TYPE = -26, - - ARGON2_OUT_PTR_MISMATCH = -27, - - ARGON2_THREADS_TOO_FEW = -28, - ARGON2_THREADS_TOO_MANY = -29, - - ARGON2_MISSING_ARGS = -30, - - ARGON2_ENCODING_FAIL = -31, - - ARGON2_DECODING_FAIL = -32, - - ARGON2_THREAD_FAIL = -33, - - ARGON2_DECODING_LENGTH_FAIL = -34, - - ARGON2_VERIFY_MISMATCH = -35 + ARGON2_OK = 0, + ARGON2_OUTPUT_PTR_NULL = -1, + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, + ARGON2_SECRET_TOO_SHORT = -10, + ARGON2_SECRET_TOO_LONG = -11, + ARGON2_TIME_TOO_SMALL = -12, + ARGON2_TIME_TOO_LARGE = -13, + ARGON2_MEMORY_TOO_LITTLE = -14, + ARGON2_MEMORY_TOO_MUCH = -15, + ARGON2_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + ARGON2_MEMORY_ALLOCATION_ERROR = -22, + ARGON2_FREE_MEMORY_CBK_NULL = -23, + ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, + ARGON2_INCORRECT_PARAMETER = -25, + ARGON2_INCORRECT_TYPE = -26, + ARGON2_OUT_PTR_MISMATCH = -27, + ARGON2_THREADS_TOO_FEW = -28, + ARGON2_THREADS_TOO_MANY = -29, + ARGON2_MISSING_ARGS = -30, + ARGON2_ENCODING_FAIL = -31, + ARGON2_DECODING_FAIL = -32, + ARGON2_THREAD_FAIL = -33, + ARGON2_DECODING_LENGTH_FAIL = -34, + ARGON2_VERIFY_MISMATCH = -35 } argon2_error_codes; /* Memory allocator types --- for external allocation */ typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate); typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); -/* Argon2 external data structures */ - /* ***** * Context: structure to hold Argon2 inputs: @@ -169,32 +135,24 @@ typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) */ typedef struct Argon2_Context { - uint8_t *out; /* output array */ - uint32_t outlen; /* digest length */ - - uint8_t *pwd; /* password array */ - uint32_t pwdlen; /* password length */ - - uint8_t *salt; /* salt array */ - uint32_t saltlen; /* salt length */ - - uint8_t *secret; /* key array */ - uint32_t secretlen; /* key length */ - - uint8_t *ad; /* associated data array */ - uint32_t adlen; /* associated data length */ - - uint32_t t_cost; /* number of passes */ - uint32_t m_cost; /* amount of memory requested (KB) */ - uint32_t lanes; /* number of lanes */ - uint32_t threads; /* maximum number of threads */ - - uint32_t version; /* version number */ - - allocate_fptr allocate_cbk; /* pointer to memory allocator */ - deallocate_fptr free_cbk; /* pointer to memory deallocator */ - - uint32_t flags; /* array of bool options */ + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ + uint32_t version; /* version number */ + allocate_fptr allocate_cbk; /* pointer to memory allocator */ + deallocate_fptr free_cbk; /* pointer to memory deallocator */ + uint32_t flags; /* array of bool options */ } argon2_context; /* Argon2 primitive type */ @@ -206,209 +164,50 @@ typedef enum Argon2_type { /* Version of the algorithm */ typedef enum Argon2_version { - ARGON2_VERSION_10 = 0x10, - ARGON2_VERSION_13 = 0x13, - ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 + ARGON2_VERSION_10 = 0x10, + ARGON2_VERSION_13 = 0x13, + ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 } argon2_version; -/* - * Function that gives the string representation of an argon2_type. - * @param type The argon2_type that we want the string for - * @param uppercase Whether the string should have the first letter uppercase - * @return NULL if invalid type, otherwise the string representation. - */ -ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase); +int argon2i_hash_encoded(const uint32_t, const uint32_t, const uint32_t, + const void *, const size_t, const void *, const size_t, + const size_t, char *, const size_t); +int argon2i_hash_raw(const uint32_t, const uint32_t, const uint32_t, + const void *, const size_t, const void *, const size_t, + void *, const size_t); +int argon2d_hash_encoded(const uint32_t, const uint32_t, const uint32_t, + const void *, const size_t, const void *, const size_t, + const size_t, char *, const size_t); +int argon2d_hash_raw(const uint32_t, const uint32_t, const uint32_t, + const void *, const size_t, const void *, const size_t, + void *, const size_t); +int argon2id_hash_encoded(const uint32_t, const uint32_t, const uint32_t, + const void *, const size_t, const void *, + const size_t, const size_t, char *, const size_t); +int argon2id_hash_raw(const uint32_t, const uint32_t, const uint32_t, + const void *, const size_t, const void *, const size_t, + void *, const size_t); +int argon2_hash(const uint32_t, const uint32_t, const uint32_t, const void *, + const size_t, const void *, const size_t, void *, const size_t, + char *, const size_t, argon2_type, const uint32_t); -/* - * Function that performs memory-hard hashing with certain degree of parallelism - * @param context Pointer to the Argon2 internal structure - * @return Error code if smth is wrong, ARGON2_OK otherwise - */ -ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type); - -/** - * Hashes a password with Argon2i, producing an encoded hash - * @param t_cost Number of iterations - * @param m_cost Sets memory usage to m_cost kibibytes - * @param parallelism Number of threads and compute lanes - * @param pwd Pointer to password - * @param pwdlen Password size in bytes - * @param salt Pointer to salt - * @param saltlen Salt size in bytes - * @param hashlen Desired length of the hash in bytes - * @param encoded Buffer where to write the encoded hash - * @param encodedlen Size of the buffer (thus max size of the encoded hash) - * @pre Different parallelism levels will give different results - * @pre Returns ARGON2_OK if successful - */ -ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost, - const uint32_t m_cost, - const uint32_t parallelism, - const void *pwd, const size_t pwdlen, - const void *salt, const size_t saltlen, - const size_t hashlen, char *encoded, - const size_t encodedlen); - -/** - * Hashes a password with Argon2i, producing a raw hash at @hash - * @param t_cost Number of iterations - * @param m_cost Sets memory usage to m_cost kibibytes - * @param parallelism Number of threads and compute lanes - * @param pwd Pointer to password - * @param pwdlen Password size in bytes - * @param salt Pointer to salt - * @param saltlen Salt size in bytes - * @param hash Buffer where to write the raw hash - updated by the function - * @param hashlen Desired length of the hash in bytes - * @pre Different parallelism levels will give different results - * @pre Returns ARGON2_OK if successful - */ -ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, - const size_t hashlen); - -ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost, - const uint32_t m_cost, - const uint32_t parallelism, - const void *pwd, const size_t pwdlen, - const void *salt, const size_t saltlen, - const size_t hashlen, char *encoded, - const size_t encodedlen); - -ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, - const size_t hashlen); - -ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost, - const uint32_t m_cost, - const uint32_t parallelism, - const void *pwd, const size_t pwdlen, - const void *salt, const size_t saltlen, - const size_t hashlen, char *encoded, - const size_t encodedlen); - -ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost, - const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, - const size_t hashlen); - -/* generic function underlying the above ones */ -ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, - const size_t hashlen, char *encoded, - const size_t encodedlen, argon2_type type, - const uint32_t version); - -/** - * Verifies a password against an encoded string - * Encoded string is restricted as in validate_inputs() - * @param encoded String encoding parameters, salt, hash - * @param pwd Pointer to password - * @pre Returns ARGON2_OK if successful - */ -ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd, - const size_t pwdlen); - -ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd, - const size_t pwdlen); - -ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd, - const size_t pwdlen); - -/* generic function underlying the above ones */ -ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd, - const size_t pwdlen, argon2_type type); - -/** - * Argon2d: Version of Argon2 that picks memory blocks depending - * on the password and salt. Only for side-channel-free - * environment!! - ***** - * @param context Pointer to current Argon2 context - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2d_ctx(argon2_context *context); - -/** - * Argon2i: Version of Argon2 that picks memory blocks - * independent on the password and salt. Good for side-channels, - * but worse w.r.t. tradeoff attacks if only one pass is used. - ***** - * @param context Pointer to current Argon2 context - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2i_ctx(argon2_context *context); - -/** - * Argon2id: Version of Argon2 where the first half-pass over memory is - * password-independent, the rest are password-dependent (on the password and - * salt). OK against side channels (they reduce to 1/2-pass Argon2i), and - * better with w.r.t. tradeoff attacks (similar to Argon2d). - ***** - * @param context Pointer to current Argon2 context - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2id_ctx(argon2_context *context); - -/** - * Verify if a given password is correct for Argon2d hashing - * @param context Pointer to current Argon2 context - * @param hash The password hash to verify. The length of the hash is - * specified by the context outlen member - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash); - -/** - * Verify if a given password is correct for Argon2i hashing - * @param context Pointer to current Argon2 context - * @param hash The password hash to verify. The length of the hash is - * specified by the context outlen member - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash); - -/** - * Verify if a given password is correct for Argon2id hashing - * @param context Pointer to current Argon2 context - * @param hash The password hash to verify. The length of the hash is - * specified by the context outlen member - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context, - const char *hash); - -/* generic function underlying the above ones */ -ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash, - argon2_type type); - -/** - * Get the associated error message for given error code - * @return The error message associated with the given error code - */ -ARGON2_PUBLIC const char *argon2_error_message(int error_code); - -/** - * Returns the encoded hash length for the given input parameters - * @param t_cost Number of iterations - * @param m_cost Memory usage in kibibytes - * @param parallelism Number of threads; used to compute lanes - * @param saltlen Salt size in bytes - * @param hashlen Hash size in bytes - * @param type The argon2_type that we want the encoded length for - * @return The encoded hash length in bytes - */ -ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, - uint32_t parallelism, uint32_t saltlen, - uint32_t hashlen, argon2_type type); +const char *argon2_type2string(argon2_type, int); +int argon2_ctx(argon2_context *, argon2_type); +int argon2i_verify(const char *, const void *, const size_t); +int argon2d_verify(const char *, const void *, const size_t); +int argon2id_verify(const char *, const void *, const size_t); +int argon2_verify(const char *, const void *, const size_t, argon2_type); +int argon2d_ctx(argon2_context *); +int argon2i_ctx(argon2_context *); +int argon2id_ctx(argon2_context *); +int argon2d_verify_ctx(argon2_context *, const char *); +int argon2i_verify_ctx(argon2_context *, const char *); +int argon2id_verify_ctx(argon2_context *, const char *); +int argon2_verify_ctx(argon2_context *, const char *, argon2_type); +const char *argon2_error_message(int); +size_t argon2_encodedlen(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + argon2_type); COSMOPOLITAN_C_END_ -#endif +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_ */ diff --git a/third_party/argon2/argon2.mk b/third_party/argon2/argon2.mk index 03a805c74..9599effd0 100644 --- a/third_party/argon2/argon2.mk +++ b/third_party/argon2/argon2.mk @@ -42,6 +42,11 @@ $(THIRD_PARTY_ARGON2_A).pkg: \ $(THIRD_PARTY_ARGON2_A_OBJS) \ $(foreach x,$(THIRD_PARTY_ARGON2_A_DIRECTDEPS),$($(x)_A).pkg) +$(THIRD_PARTY_ARGON2_A_OBJS): \ + OVERRIDE_CFLAGS += \ + -ffunction-sections \ + -fdata-sections + THIRD_PARTY_ARGON2_LIBS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x))) THIRD_PARTY_ARGON2_SRCS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)_SRCS)) THIRD_PARTY_ARGON2_HDRS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)_HDRS)) diff --git a/third_party/argon2/blake2.h b/third_party/argon2/blake2.h index 50ea43dca..ca21dfae0 100644 --- a/third_party/argon2/blake2.h +++ b/third_party/argon2/blake2.h @@ -1,66 +1,52 @@ -#ifndef PORTABLE_BLAKE2_H -#define PORTABLE_BLAKE2_H +#ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_ +#define COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_ #include "third_party/argon2/argon2.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -/* clang-format off */ enum blake2b_constant { - BLAKE2B_BLOCKBYTES = 128, - BLAKE2B_OUTBYTES = 64, - BLAKE2B_KEYBYTES = 64, - BLAKE2B_SALTBYTES = 16, - BLAKE2B_PERSONALBYTES = 16 + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 }; -#pragma pack(push, 1) typedef struct __blake2b_param { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint64_t node_offset; /* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint8_t leaf_length[4]; /* 8 */ + uint8_t node_offset[8]; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ } blake2b_param; -#pragma pack(pop) typedef struct __blake2b_state { - uint64_t h[8]; - uint64_t t[2]; - uint64_t f[2]; - uint8_t buf[BLAKE2B_BLOCKBYTES]; - unsigned buflen; - unsigned outlen; - uint8_t last_node; + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + unsigned buflen; + unsigned outlen; + uint8_t last_node; } blake2b_state; -/* Ensure param structs have not been wrongly padded */ -/* Poor man's static_assert */ -enum { - blake2_size_check_0 = 1 / !!(CHAR_BIT == 8), - blake2_size_check_2 = - 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT) -}; - /* Streaming API */ -ARGON2_LOCAL int blake2b_init(blake2b_state *S, size_t outlen); -ARGON2_LOCAL int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, - size_t keylen); -ARGON2_LOCAL int blake2b_init_param(blake2b_state *S, const blake2b_param *P); -ARGON2_LOCAL int blake2b_update(blake2b_state *S, const void *in, size_t inlen); -ARGON2_LOCAL int blake2b_final(blake2b_state *S, void *out, size_t outlen); +int blake2b_init(blake2b_state *, size_t); +int blake2b_init_key(blake2b_state *, size_t, const void *, size_t); +int blake2b_init_param(blake2b_state *, const blake2b_param *); +int blake2b_update(blake2b_state *, const void *, size_t); +int blake2b_final(blake2b_state *, void *, size_t); /* Simple API */ -ARGON2_LOCAL int blake2b(void *out, size_t outlen, const void *in, size_t inlen, - const void *key, size_t keylen); - -/* Argon2 Team - Begin Code */ -ARGON2_LOCAL int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen); -/* Argon2 Team - End Code */ +int blake2b(void *, size_t, const void *, size_t, const void *, size_t); +int blake2b_long(void *, size_t, const void *, size_t); COSMOPOLITAN_C_END_ -#endif +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_ */ diff --git a/third_party/argon2/blake2b.c b/third_party/argon2/blake2b.c index 733833d60..5aad00f29 100644 --- a/third_party/argon2/blake2b.c +++ b/third_party/argon2/blake2b.c @@ -1,3 +1,20 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Argon2 reference source code package - reference C implementations │ +│ │ +│ Copyright 2015 │ +│ Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves │ +│ │ +│ You may use this work under the terms of a Creative Commons CC0 1.0 │ +│ License/Waiver or the Apache Public License 2.0, at your option. The │ +│ terms of these licenses can be found at: │ +│ │ +│ - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │ +│ - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" #include "libc/limits.h" #include "third_party/argon2/blake2-impl.h" @@ -5,30 +22,27 @@ #include "third_party/argon2/core.h" /* clang-format off */ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ +asm(".ident\t\"\\n\\n\ +argon2 (CC0 or Apache2)\\n\ +Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\ +Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\""); + +/* Ensure param structs have not been wrongly padded */ +/* Poor man's static_assert */ +enum { + blake2_size_check_0 = 1 / !!(CHAR_BIT == 8), + blake2_size_check_2 = + 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT) +}; static const uint64_t blake2b_IV[8] = { UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1), UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f), - UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)}; + UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179), +}; -static const unsigned int blake2b_sigma[12][16] = { +static const unsigned char blake2b_sigma[12][16] = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, @@ -55,7 +69,7 @@ static inline void blake2b_set_lastblock(blake2b_state *S) { } static inline void blake2b_increment_counter(blake2b_state *S, - uint64_t inc) { + uint64_t inc) { S->t[0] += inc; S->t[1] += (S->t[0] < inc); } @@ -105,8 +119,8 @@ int blake2b_init(blake2b_state *S, size_t outlen) { P.key_length = 0; P.fanout = 1; P.depth = 1; - P.leaf_length = 0; - P.node_offset = 0; + WRITE32LE(P.leaf_length, 0); + WRITE64LE(P.node_offset, 0); P.node_depth = 0; P.inner_length = 0; memset(P.reserved, 0, sizeof(P.reserved)); @@ -139,8 +153,8 @@ int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, P.key_length = (uint8_t)keylen; P.fanout = 1; P.depth = 1; - P.leaf_length = 0; - P.node_offset = 0; + WRITE32LE(P.leaf_length, 0); + WRITE64LE(P.node_offset, 0); P.node_depth = 0; P.inner_length = 0; memset(P.reserved, 0, sizeof(P.reserved)); @@ -387,4 +401,3 @@ fail: return ret; #undef TRY } -/* Argon2 Team - End Code */ diff --git a/third_party/argon2/core.c b/third_party/argon2/core.c index a69409306..8befb8ad2 100644 --- a/third_party/argon2/core.c +++ b/third_party/argon2/core.c @@ -1,27 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Argon2 reference source code package - reference C implementations │ +│ │ +│ Copyright 2015 │ +│ Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves │ +│ │ +│ You may use this work under the terms of a Creative Commons CC0 1.0 │ +│ License/Waiver or the Apache Public License 2.0, at your option. The │ +│ terms of these licenses can be found at: │ +│ │ +│ - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │ +│ - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/mem/mem.h" #include "third_party/argon2/blake2-impl.h" #include "third_party/argon2/blake2.h" #include "third_party/argon2/core.h" + +asm(".ident\t\"\\n\\n\ +argon2 (CC0 or Apache2)\\n\ +Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\ +Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\""); /* clang-format off */ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -/***************Instance and Position constructors**********/ +int FLAG_clear_internal_memory = 1; void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); @@ -52,34 +57,45 @@ static void store_block(void *output, const block *src) { } } -/***************Memory functions*****************/ - +/** + * Allocates memory to the given pointer, uses the appropriate allocator as + * specified in the context. Total allocated memory is num*size. + * @param context argon2_context which specifies the allocator + * @param memory pointer to the pointer to the memory + * @param size the size in bytes for each element to be allocated + * @param num the number of elements to be allocated + * @return ARGON2_OK if @memory is a valid pointer and memory is allocated + */ int allocate_memory(const argon2_context *context, uint8_t **memory, size_t num, size_t size) { size_t memory_size = num*size; if (memory == NULL) { return ARGON2_MEMORY_ALLOCATION_ERROR; } - /* 1. Check for multiplication overflow */ if (size != 0 && memory_size / size != num) { return ARGON2_MEMORY_ALLOCATION_ERROR; } - /* 2. Try to allocate with appropriate allocator */ if (context->allocate_cbk) { (context->allocate_cbk)(memory, memory_size); } else { *memory = malloc(memory_size); } - if (*memory == NULL) { return ARGON2_MEMORY_ALLOCATION_ERROR; } - return ARGON2_OK; } +/** + * Frees memory at the given pointer, uses the appropriate deallocator as + * specified in the context. Also cleans the memory using clear_internal_memory. + * @param context argon2_context which specifies the deallocator + * @param memory pointer to buffer to be freed + * @param size the size in bytes for each element to be deallocated + * @param num the number of elements to be deallocated + */ void free_memory(const argon2_context *context, uint8_t *memory, size_t num, size_t size) { size_t memory_size = num*size; @@ -91,14 +107,31 @@ void free_memory(const argon2_context *context, uint8_t *memory, } } -/* Memory clear flag defaults to true. */ -int FLAG_clear_internal_memory = 1; +/** + * Function that securely clears the memory if + * FLAG_clear_internal_memory is set. If the flag isn't set, this + * function does nothing. + * + * @param mem Pointer to the memory + * @param s Memory size in bytes + */ void clear_internal_memory(void *v, size_t n) { if (FLAG_clear_internal_memory && v) { explicit_bzero(v, n); } } +/** + * XORing the last block of each lane, hashing it, making the tag. + * Deallocates the memory. + * + * @param context current Argon2 context (use only the out parameters from it) + * @param instance Pointer to current instance of Argon2 + * @pre instance->state must point to necessary amount of memory + * @pre context->out must point to outlen bytes of memory + * @pre if context->free_cbk is not NULL, it should point to a function that + * deallocates memory + */ void finalize(const argon2_context *context, argon2_instance_t *instance) { if (context != NULL && instance != NULL) { block blockhash; @@ -129,6 +162,16 @@ void finalize(const argon2_context *context, argon2_instance_t *instance) { } } +/** + * Computes absolute position of reference block in the lane following a skewed + * distribution and using a pseudo-random value as input + * @param instance Pointer to the current instance + * @param position Pointer to the current position + * @param pseudo_rand 32-bit pseudo-random value used to determine the position + * @param same_lane Indicates if the block will be taken from the current lane. + * If so we can reference the current segment + * @pre All pointers must be valid + */ uint32_t index_alpha(const argon2_instance_t *instance, const argon2_position_t *position, uint32_t pseudo_rand, int same_lane) { @@ -309,6 +352,12 @@ fail: #endif /* ARGON2_NO_THREADS */ +/** + * Function that fills the entire memory t_cost times based on the first two + * blocks in each lane + * @param instance Pointer to the current instance + * @return ARGON2_OK if successful, @context->state + */ int fill_memory_blocks(argon2_instance_t *instance) { if (instance == NULL || instance->lanes == 0) { return ARGON2_INCORRECT_PARAMETER; @@ -321,6 +370,14 @@ int fill_memory_blocks(argon2_instance_t *instance) { #endif } +/** + * Function that validates all inputs against predefined restrictions + * and return an error code. + * + * @param context Pointer to current Argon2 context + * @return ARGON2_OK if everything is all right, otherwise one of error + * codes (all defined in argon.h) + */ int validate_inputs(const argon2_context *context) { if (NULL == context) { return ARGON2_INCORRECT_PARAMETER; @@ -448,6 +505,12 @@ int validate_inputs(const argon2_context *context) { return ARGON2_OK; } +/** + * Function creates first 2 blocks per lane + * @param instance Pointer to the current instance + * @param blockhash Pointer to the pre-hashing digest + * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values + */ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) { uint32_t l; /* Make the first and second block in each lane as G(H0||0||i) or @@ -471,6 +534,17 @@ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) { clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); } +/** + * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], + * clears password and secret if needed + * + * @param context Pointer to the Argon2 internal structure containing + * memory pointer, and parameters for time and space requirements + * @param blockhash Buffer for pre-hashing digest + * @param type Argon2 type + * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes + * allocated + */ void initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type) { blake2b_state BlakeHash; @@ -545,6 +619,17 @@ void initial_hash(uint8_t *blockhash, argon2_context *context, blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH); } +/** + * Function allocates memory, hashes the inputs with Blake, and creates + * first two blocks. Returns the pointer to the main memory with 2 + * blocks per lane initialized. + * + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param instance Current Argon2 instance + * @return Zero if successful, -1 if memory failed to allocate. @context->state + * will be modified if successful. + */ int initialize(argon2_instance_t *instance, argon2_context *context) { uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; int result = ARGON2_OK; diff --git a/third_party/argon2/core.h b/third_party/argon2/core.h index a34c0f94f..7cdfc54e6 100644 --- a/third_party/argon2/core.h +++ b/third_party/argon2/core.h @@ -1,229 +1,87 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef ARGON2_CORE_H -#define ARGON2_CORE_H -/* clang-format off */ - +#ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_ +#define COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_ #include "third_party/argon2/argon2.h" - -#define CONST_CAST(x) (x)(uintptr_t) - -/**********************Argon2 internal constants*******************************/ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ enum argon2_core_constants { - /* Memory block size in bytes */ - ARGON2_BLOCK_SIZE = 1024, - ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, - ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, - ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, - ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, - - /* Number of pseudo-random values generated by one call to Blake in Argon2i - to - generate reference block positions */ - ARGON2_ADDRESSES_IN_BLOCK = 128, - - /* Pre-hashing digest length and its extension*/ - ARGON2_PREHASH_DIGEST_LENGTH = 64, - ARGON2_PREHASH_SEED_LENGTH = 72 + /* Memory block size in bytes */ + ARGON2_BLOCK_SIZE = 1024, + ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, + ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, + ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, + ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, + /* Number of pseudo-random values generated by one call to Blake in + Argon2i to generate reference block positions */ + ARGON2_ADDRESSES_IN_BLOCK = 128, + /* Pre-hashing digest length and its extension*/ + ARGON2_PREHASH_DIGEST_LENGTH = 64, + ARGON2_PREHASH_SEED_LENGTH = 72 }; -/*************************Argon2 internal data types***********************/ - /* * Structure for the (1KB) memory block implemented as 128 64-bit words. * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no * bounds checking). */ -typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block; +typedef struct block_ { + uint64_t v[ARGON2_QWORDS_IN_BLOCK]; +} block; -/*****************Functions that work with the block******************/ - -/* Initialize each byte of the block with @in */ -void init_block_value(block *b, uint8_t in); - -/* Copy block @src to block @dst */ -void copy_block(block *dst, const block *src); - -/* XOR @src onto @dst bytewise */ -void xor_block(block *dst, const block *src); +void init_block_value(block *, uint8_t); +void copy_block(block *, const block *); +void xor_block(block *, const block *); /* - * Argon2 instance: memory pointer, number of passes, amount of memory, type, - * and derived values. - * Used to evaluate the number and location of blocks to construct in each - * thread + * Argon2 instance: memory pointer, number of passes, amount of memory, + * type, and derived values. Used to evaluate the number and location of + * blocks to construct in each thread. */ typedef struct Argon2_instance_t { - block *memory; /* Memory pointer */ - uint32_t version; - uint32_t passes; /* Number of passes */ - uint32_t memory_blocks; /* Number of blocks in memory */ - uint32_t segment_length; - uint32_t lane_length; - uint32_t lanes; - uint32_t threads; - argon2_type type; - int print_internals; /* whether to print the memory blocks */ - argon2_context *context_ptr; /* points back to original context */ + block *memory; /* Memory pointer */ + uint32_t version; + uint32_t passes; /* Number of passes */ + uint32_t memory_blocks; /* Number of blocks in memory */ + uint32_t segment_length; + uint32_t lane_length; + uint32_t lanes; + uint32_t threads; + argon2_type type; + int print_internals; /* whether to print the memory blocks */ + argon2_context *context_ptr; /* points back to original context */ } argon2_instance_t; /* - * Argon2 position: where we construct the block right now. Used to distribute - * work between threads. + * Argon2 position: where we construct the block right now. Used to + * distribute work between threads. */ typedef struct Argon2_position_t { - uint32_t pass; - uint32_t lane; - uint8_t slice; - uint32_t index; + uint32_t pass; + uint32_t lane; + uint8_t slice; + uint32_t index; } argon2_position_t; /*Struct that holds the inputs for thread handling FillSegment*/ typedef struct Argon2_thread_data { - argon2_instance_t *instance_ptr; - argon2_position_t pos; + argon2_instance_t *instance_ptr; + argon2_position_t pos; } argon2_thread_data; -/*************************Argon2 core functions********************************/ +/* argon2 core functions */ +int allocate_memory(const argon2_context *, uint8_t **, size_t, size_t); +void free_memory(const argon2_context *, uint8_t *, size_t, size_t); +void clear_internal_memory(void *, size_t); +uint32_t index_alpha(const argon2_instance_t *, const argon2_position_t *, + uint32_t, int); +int validate_inputs(const argon2_context *); +void initial_hash(uint8_t *, argon2_context *, argon2_type); +void fill_first_blocks(uint8_t *, const argon2_instance_t *); +int initialize(argon2_instance_t *, argon2_context *); +void finalize(const argon2_context *, argon2_instance_t *); +void fill_segment(const argon2_instance_t *, argon2_position_t); +int fill_memory_blocks(argon2_instance_t *); -/* Allocates memory to the given pointer, uses the appropriate allocator as - * specified in the context. Total allocated memory is num*size. - * @param context argon2_context which specifies the allocator - * @param memory pointer to the pointer to the memory - * @param size the size in bytes for each element to be allocated - * @param num the number of elements to be allocated - * @return ARGON2_OK if @memory is a valid pointer and memory is allocated - */ -int allocate_memory(const argon2_context *context, uint8_t **memory, - size_t num, size_t size); - -/* - * Frees memory at the given pointer, uses the appropriate deallocator as - * specified in the context. Also cleans the memory using clear_internal_memory. - * @param context argon2_context which specifies the deallocator - * @param memory pointer to buffer to be freed - * @param size the size in bytes for each element to be deallocated - * @param num the number of elements to be deallocated - */ -void free_memory(const argon2_context *context, uint8_t *memory, - size_t num, size_t size); - -/* Function that securely cleans the memory. This ignores any flags set - * regarding clearing memory. Usually one just calls clear_internal_memory. - * @param mem Pointer to the memory - * @param s Memory size in bytes - */ -void secure_wipe_memory(void *v, size_t n); - -/* Function that securely clears the memory if FLAG_clear_internal_memory is - * set. If the flag isn't set, this function does nothing. - * @param mem Pointer to the memory - * @param s Memory size in bytes - */ -void clear_internal_memory(void *v, size_t n); - -/* - * Computes absolute position of reference block in the lane following a skewed - * distribution and using a pseudo-random value as input - * @param instance Pointer to the current instance - * @param position Pointer to the current position - * @param pseudo_rand 32-bit pseudo-random value used to determine the position - * @param same_lane Indicates if the block will be taken from the current lane. - * If so we can reference the current segment - * @pre All pointers must be valid - */ -uint32_t index_alpha(const argon2_instance_t *instance, - const argon2_position_t *position, uint32_t pseudo_rand, - int same_lane); - -/* - * Function that validates all inputs against predefined restrictions and return - * an error code - * @param context Pointer to current Argon2 context - * @return ARGON2_OK if everything is all right, otherwise one of error codes - * (all defined in - */ -int validate_inputs(const argon2_context *context); - -/* - * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears - * password and secret if needed - * @param context Pointer to the Argon2 internal structure containing memory - * pointer, and parameters for time and space requirements. - * @param blockhash Buffer for pre-hashing digest - * @param type Argon2 type - * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes - * allocated - */ -void initial_hash(uint8_t *blockhash, argon2_context *context, - argon2_type type); - -/* - * Function creates first 2 blocks per lane - * @param instance Pointer to the current instance - * @param blockhash Pointer to the pre-hashing digest - * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values - */ -void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); - -/* - * Function allocates memory, hashes the inputs with Blake, and creates first - * two blocks. Returns the pointer to the main memory with 2 blocks per lane - * initialized - * @param context Pointer to the Argon2 internal structure containing memory - * pointer, and parameters for time and space requirements. - * @param instance Current Argon2 instance - * @return Zero if successful, -1 if memory failed to allocate. @context->state - * will be modified if successful. - */ -int initialize(argon2_instance_t *instance, argon2_context *context); - -/* - * XORing the last block of each lane, hashing it, making the tag. Deallocates - * the memory. - * @param context Pointer to current Argon2 context (use only the out parameters - * from it) - * @param instance Pointer to current instance of Argon2 - * @pre instance->state must point to necessary amount of memory - * @pre context->out must point to outlen bytes of memory - * @pre if context->free_cbk is not NULL, it should point to a function that - * deallocates memory - */ -void finalize(const argon2_context *context, argon2_instance_t *instance); - -/* - * Function that fills the segment using previous segments also from other - * threads - * @param context current context - * @param instance Pointer to the current instance - * @param position Current position - * @pre all block pointers must be valid - */ -void fill_segment(const argon2_instance_t *instance, - argon2_position_t position); - -/* - * Function that fills the entire memory t_cost times based on the first two - * blocks in each lane - * @param instance Pointer to the current instance - * @return ARGON2_OK if successful, @context->state - */ -int fill_memory_blocks(argon2_instance_t *instance); - -#endif +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_ */ diff --git a/third_party/argon2/encoding.c b/third_party/argon2/encoding.c index dad92075a..cd9bff6a4 100644 --- a/third_party/argon2/encoding.c +++ b/third_party/argon2/encoding.c @@ -1,26 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Argon2 reference source code package - reference C implementations │ +│ │ +│ Copyright 2015 │ +│ Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves │ +│ │ +│ You may use this work under the terms of a Creative Commons CC0 1.0 │ +│ License/Waiver or the Apache Public License 2.0, at your option. The │ +│ terms of these licenses can be found at: │ +│ │ +│ - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │ +│ - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/fmt.h" #include "libc/limits.h" #include "libc/str/str.h" #include "third_party/argon2/core.h" #include "third_party/argon2/encoding.h" -/* clang-format off */ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ +asm(".ident\t\"\\n\\n\ +argon2 (CC0 or Apache2)\\n\ +Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\ +Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\""); +/* clang-format off */ /* * Example code for a decoder and encoder of "hash strings", with Argon2 @@ -255,6 +260,18 @@ static const char *decode_decimal(const char *str, unsigned long *v) { * when it is fed into decode_string. */ +/** + * Decodes an Argon2 hash string into the provided structure 'ctx'. + * The only fields that must be set prior to this call are ctx.saltlen and + * ctx.outlen (which must be the maximal salt and out length values that are + * allowed), ctx.salt and ctx.out (which must be buffers of the specified + * length), and ctx.pwd and ctx.pwdlen which must hold a valid password. + * + * Invalid input string causes an error. On success, the ctx is valid and all + * fields have been initialized. + * + * @return value is ARGON2_OK on success, other ARGON2_ codes on error + */ int decode_string(argon2_context *ctx, const char *str, argon2_type type) { /* check for prefix */ @@ -370,6 +387,14 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) { #undef BIN } +/** + * Encodes an Argon2 hash string into the provided buffer. 'dst_len' + * contains the size, in characters, of the 'dst' buffer; if 'dst_len' + * is less than the number of required characters (including the + * terminating 0), then this function returns ARGON2_ENCODING_ERROR. + * + * @return on success, ARGON2_OK is returned + */ int encode_string(char *dst, size_t dst_len, argon2_context *ctx, argon2_type type) { #define SS(str) \ @@ -437,9 +462,9 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx, #undef SB } +/** Returns length of the encoded byte stream with length len */ size_t b64len(uint32_t len) { size_t olen = ((size_t)len / 3) << 2; - switch (len % 3) { case 2: olen++; @@ -448,10 +473,10 @@ size_t b64len(uint32_t len) { olen += 2; break; } - return olen; } +/** Returns length of the encoded number num */ size_t numlen(uint32_t num) { size_t len = 1; while (num >= 10) { diff --git a/third_party/argon2/encoding.h b/third_party/argon2/encoding.h index a1ad131a8..538d770f5 100644 --- a/third_party/argon2/encoding.h +++ b/third_party/argon2/encoding.h @@ -1,58 +1,18 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef ENCODING_H -#define ENCODING_H +#ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_H_ +#define COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_H_ #include "third_party/argon2/argon2.h" -/* clang-format off */ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ -#define ARGON2_MAX_DECODED_LANES UINT32_C(255) +#define ARGON2_MAX_DECODED_LANES UINT32_C(255) #define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8) -#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12) +#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12) -/* -* encode an Argon2 hash string into the provided buffer. 'dst_len' -* contains the size, in characters, of the 'dst' buffer; if 'dst_len' -* is less than the number of required characters (including the -* terminating 0), then this function returns ARGON2_ENCODING_ERROR. -* -* on success, ARGON2_OK is returned. -*/ -int encode_string(char *dst, size_t dst_len, argon2_context *ctx, - argon2_type type); +int encode_string(char *, size_t, argon2_context *, argon2_type); +int decode_string(argon2_context *, const char *, argon2_type); +size_t b64len(uint32_t); +size_t numlen(uint32_t); -/* -* Decodes an Argon2 hash string into the provided structure 'ctx'. -* The only fields that must be set prior to this call are ctx.saltlen and -* ctx.outlen (which must be the maximal salt and out length values that are -* allowed), ctx.salt and ctx.out (which must be buffers of the specified -* length), and ctx.pwd and ctx.pwdlen which must hold a valid password. -* -* Invalid input string causes an error. On success, the ctx is valid and all -* fields have been initialized. -* -* Returned value is ARGON2_OK on success, other ARGON2_ codes on error. -*/ -int decode_string(argon2_context *ctx, const char *str, argon2_type type); - -/* Returns the length of the encoded byte stream with length len */ -size_t b64len(uint32_t len); - -/* Returns the length of the encoded number num */ -size_t numlen(uint32_t num); - -#endif +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_H_ */ diff --git a/third_party/argon2/ref.c b/third_party/argon2/ref.c index 3599d6e5a..2ce1e832b 100644 --- a/third_party/argon2/ref.c +++ b/third_party/argon2/ref.c @@ -1,9 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Argon2 reference source code package - reference C implementations │ +│ │ +│ Copyright 2015 │ +│ Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves │ +│ │ +│ You may use this work under the terms of a Creative Commons CC0 1.0 │ +│ License/Waiver or the Apache Public License 2.0, at your option. The │ +│ terms of these licenses can be found at: │ +│ │ +│ - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │ +│ - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/log/libfatal.internal.h" #include "third_party/argon2/argon2.h" #include "third_party/argon2/blake2-impl.h" #include "third_party/argon2/blake2.h" #include "third_party/argon2/blamka-round-ref.h" #include "third_party/argon2/core.h" + +asm(".ident\t\"\\n\\n\ +argon2 (CC0 or Apache2)\\n\ +Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\ +Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\""); /* clang-format off */ /* @@ -85,6 +107,15 @@ static void next_addresses(block *address_block, block *input_block, fill_block(zero_block, address_block, address_block, 0); } +/** + * Function that fills the segment using previous segments also from + * other threads. + * + * @param context current context + * @param instance Pointer to the current instance + * @param position Current position + * @pre all block pointers must be valid + */ void fill_segment(const argon2_instance_t *instance, argon2_position_t position) { block *ref_block = NULL, *curr_block = NULL; diff --git a/third_party/chibicc/README.cosmo b/third_party/chibicc/README.cosmo index feca45a91..18bbd30fa 100644 --- a/third_party/chibicc/README.cosmo +++ b/third_party/chibicc/README.cosmo @@ -17,6 +17,7 @@ local enhancements - support __builtin_constant_p, __builtin_likely, etc. - support __builtin_isunordered, __builtin_islessgreater, etc. - support __builtin_ctz, __builtin_bswap, __builtin_popcount, etc. +- support __atomic_load, __sync_lock_test_and_set, __sync_lock_release, etc. - support __force_align_arg_pointer__, __no_caller_saved_registers__, etc. - support __constructor__, __section__, __cold__, -ffunction-sections, etc. - support building -x assembler-with-cpp a.k.a. .S files diff --git a/third_party/chibicc/as.c b/third_party/chibicc/as.c index 1e0382a6c..42883b804 100644 --- a/third_party/chibicc/as.c +++ b/third_party/chibicc/as.c @@ -1255,7 +1255,7 @@ static void EmitData(struct As *a, const void *p, uint128_t n) { struct Slice *s; s = &a->sections.p[a->section].binary; s->p = realloc(s->p, s->n + n); - memcpy(s->p + s->n, p, n); + if (n) memcpy(s->p + s->n, p, n); s->n += n; } @@ -1752,6 +1752,14 @@ static void OnSize(struct As *a, struct Slice s) { a->symbols.p[i].size = GetInt(a); } +static void OnEqu(struct As *a, struct Slice s) { + int i, j; + i = GetSymbol(a, a->things.p[a->i++].i); + ConsumeComma(a); + a->symbols.p[i].offset = GetInt(a); + a->symbols.p[i].section = SHN_ABS; +} + static void OnComm(struct As *a, struct Slice s) { int i; i = GetSymbol(a, a->things.p[a->i++].i); @@ -2132,12 +2140,24 @@ static void EmitRexOpModrm(struct As *a, long op, int reg, int modrm, int disp, EmitOpModrm(a, op, reg, modrm, disp, skew); } -static void OnLea(struct As *a, struct Slice s) { +static void OnLoad(struct As *a, struct Slice s, int op) { int modrm, reg, disp; modrm = ParseModrm(a, &disp); ConsumeComma(a); reg = GetRegisterReg(a); - EmitRexOpModrm(a, 0x8D, reg, modrm, disp, 0); + EmitRexOpModrm(a, op, reg, modrm, disp, 0); +} + +static void OnLea(struct As *a, struct Slice s) { + return OnLoad(a, s, 0x8D); +} + +static void OnLar(struct As *a, struct Slice s) { + return OnLoad(a, s, 0x0f02); +} + +static void OnLsl(struct As *a, struct Slice s) { + return OnLoad(a, s, 0x0f03); } static void OnMov(struct As *a, struct Slice s) { @@ -2428,6 +2448,14 @@ static void OpSseMov(struct As *a, int opWsdVsd, int opVsdWsd) { } } +static void OpMovntdq(struct As *a) { + int reg, modrm, disp; + reg = GetRegisterReg(a); + ConsumeComma(a); + modrm = ParseModrm(a, &disp); + EmitRexOpModrm(a, 0x660FE7, reg, modrm, disp, 0); +} + static void OpMovdqx(struct As *a, int op) { OpSseMov(a, op + 0x10, op); } @@ -2585,6 +2613,12 @@ static void OnPush(struct As *a, struct Slice s) { } } +static void OnRdpid(struct As *a, struct Slice s) { + int modrm, disp; + EmitVarword(a, 0xf30fc7); + EmitByte(a, 0370 | GetRegisterReg(a)); +} + static void OnPop(struct As *a, struct Slice s) { int modrm, disp; modrm = RemoveRexw(ParseModrm(a, &disp)); @@ -2893,6 +2927,7 @@ static void OnMinsd(struct As *a, struct Slice s) { OpSse(a, 0xF20F5D); } static void OnMinss(struct As *a, struct Slice s) { OpSse(a, 0xF30F5D); } static void OnMovmskpd(struct As *a, struct Slice s) { OpSse(a, 0x660F50); } static void OnMovmskps(struct As *a, struct Slice s) { OpSse(a, 0x0F50); } +static void OnMovntdq(struct As *a, struct Slice s) { OpMovntdq(a); } static void OnMovsb(struct As *a, struct Slice s) { EmitByte(a, 0xA4); } static void OnMovsl(struct As *a, struct Slice s) { EmitByte(a, 0xA5); } static void OnMovsq(struct As *a, struct Slice s) { EmitVarword(a, 0x48A5); } @@ -3010,6 +3045,8 @@ static void OnRcl(struct As *a, struct Slice s) { OpBsu(a, s, 2); } static void OnRcpps(struct As *a, struct Slice s) { OpSse(a, 0x0F53); } static void OnRcpss(struct As *a, struct Slice s) { OpSse(a, 0xF30F53); } static void OnRcr(struct As *a, struct Slice s) { OpBsu(a, s, 3); } +static void OnRdtsc(struct As *a, struct Slice s) { EmitVarword(a, 0x0f31); } +static void OnRdtscp(struct As *a, struct Slice s) { EmitVarword(a, 0x0f01f9); } static void OnRol(struct As *a, struct Slice s) { OpBsu(a, s, 0); } static void OnRor(struct As *a, struct Slice s) { OpBsu(a, s, 1); } static void OnRoundsd(struct As *a, struct Slice s) { OpSseIb(a, 0x660F3A0B); } @@ -3079,6 +3116,7 @@ static const struct Directive8 { {".comm", OnComm}, // {".data", OnData}, // {".double", OnDouble}, // + {".equ", OnEqu}, // {".err", OnErr}, // {".error", OnError}, // {".file", OnFile}, // @@ -3320,12 +3358,14 @@ static const struct Directive8 { {"jpo", OnJnp}, // {"js", OnJs}, // {"jz", OnJz}, // + {"lar", OnLar}, // {"lea", OnLea}, // {"leave", OnLeave}, // {"lodsb", OnLodsb}, // {"lodsl", OnLodsl}, // {"lodsq", OnLodsq}, // {"lodsw", OnLodsw}, // + {"lsl", OnLsl}, // {"maxpd", OnMaxpd}, // {"maxps", OnMaxps}, // {"maxsd", OnMaxsd}, // @@ -3498,6 +3538,9 @@ static const struct Directive8 { {"rcrl", OnRcr}, // {"rcrq", OnRcr}, // {"rcrw", OnRcr}, // + {"rdpid", OnRdpid}, // + {"rdtsc", OnRdtsc}, // + {"rdtscp", OnRdtscp}, // {"ret", OnRet}, // {"rol", OnRol}, // {"rolb", OnRol}, // @@ -3637,6 +3680,7 @@ static const struct Directive16 { {"cvttss2si", OnCvttss2si}, // {"cvttss2sil", OnCvttss2si}, // {"cvttss2siq", OnCvttss2si}, // + {"movntdq", OnMovntdq}, // {"pcmpistri", OnPcmpistri}, // {"pcmpistrm", OnPcmpistrm}, // {"phminposuw", OnPhminposuw}, // @@ -3910,8 +3954,10 @@ static void Objectify(struct As *a, int path) { Fail(a, "unsupported relocation type"); } } - memcpy(elfwriter_reserve(elf, a->sections.p[i].binary.n), - a->sections.p[i].binary.p, a->sections.p[i].binary.n); + if (a->sections.p[i].binary.n) { + memcpy(elfwriter_reserve(elf, a->sections.p[i].binary.n), + a->sections.p[i].binary.p, a->sections.p[i].binary.n); + } elfwriter_commit(elf, a->sections.p[i].binary.n); elfwriter_finishsection(elf); } diff --git a/third_party/chibicc/as.main.c b/third_party/chibicc/as.main.c index 6e61db41b..c20008130 100644 --- a/third_party/chibicc/as.main.c +++ b/third_party/chibicc/as.main.c @@ -19,7 +19,7 @@ #include "third_party/chibicc/chibicc.h" int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); Assembler(argc, argv); return 0; } diff --git a/third_party/chibicc/cast.c b/third_party/chibicc/cast.c index 0ddb90103..3ac289971 100644 --- a/third_party/chibicc/cast.c +++ b/third_party/chibicc/cast.c @@ -39,12 +39,12 @@ "\taddsd\t%xmm0,%xmm0\n" \ "2:" -#define u64f80 \ - PUSHPOPRAX("fildq\t(%rsp)\n" \ - "\ttest\t%rax,%rax\n" \ - "\tjns\t1f\n" \ - "\tmov\t$0x5f800000,(%rsp)\n" \ - "\tfadds\t(%rsp)\n" \ +#define u64f80 \ + PUSHPOPRAX("fildq\t(%rsp)\n" \ + "\ttest\t%rax,%rax\n" \ + "\tjns\t1f\n" \ + "\tmovq\t$0x5f800000,(%rsp)\n" \ + "\tfadds\t(%rsp)\n" \ "1:") #define i32i8 "movsbl\t%al,%eax" diff --git a/third_party/chibicc/chibicc.c b/third_party/chibicc/chibicc.c index 16e09c9a6..e1fff9230 100644 --- a/third_party/chibicc/chibicc.c +++ b/third_party/chibicc/chibicc.c @@ -685,6 +685,8 @@ static void OnCtrlC(int sig, siginfo_t *si, ucontext_t *ctx) { } int chibicc(int argc, char **argv) { + ShowCrashReports(); + atexit(chibicc_cleanup); sigaction(SIGINT, &(struct sigaction){.sa_sigaction = OnCtrlC}, NULL); for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-cc1")) { diff --git a/third_party/chibicc/chibicc.h b/third_party/chibicc/chibicc.h index 9d9d35232..75eb581af 100644 --- a/third_party/chibicc/chibicc.h +++ b/third_party/chibicc/chibicc.h @@ -345,7 +345,14 @@ typedef enum { ND_ASM, // "asm" ND_CAS, // Atomic compare-and-swap ND_EXCH, // Atomic exchange + ND_LOAD, // Atomic load + ND_TESTANDSET, // Atomic lock test and set + ND_RELEASE, // Atomic lock release + ND_FETCHADD, // Atomic fetch and add + ND_SUBFETCH, // Atomic sub and fetch ND_FPCLASSIFY, // floating point classify + ND_MOVNTDQ, // Intel MOVNTDQ + ND_PMOVMSKB, // Intel PMOVMSKB } NodeKind; struct Node { diff --git a/third_party/chibicc/chibicc.mk b/third_party/chibicc/chibicc.mk index 1605b20c6..ec387ba89 100644 --- a/third_party/chibicc/chibicc.mk +++ b/third_party/chibicc/chibicc.mk @@ -109,6 +109,16 @@ o/$(MODE)/third_party/chibicc/chibicc2.com.dbg: \ $(THIRD_PARTY_CHIBICC2_A).pkg @$(APELINK) +o/$(MODE)/third_party/chibicc/chibicc.com: \ + o/$(MODE)/third_party/chibicc/chibicc.com.dbg \ + o/$(MODE)/third_party/zip/zip.com \ + o/$(MODE)/tool/build/symtab.com + @$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@ + @$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \ + -o o/$(MODE)/third_party/chibicc/.chibicc/.symtab $< + @$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \ + o/$(MODE)/third_party/chibicc/.chibicc/.symtab + o/$(MODE)/third_party/chibicc/as.com.dbg: \ $(THIRD_PARTY_CHIBICC_A_DEPS) \ $(THIRD_PARTY_CHIBICC_A) \ @@ -124,6 +134,8 @@ o/$(MODE)/third_party/chibicc/chibicc.o: \ o/$(MODE)/third_party/chibicc/chibicc.chibicc.o: \ CHIBICC_FLAGS += $(THIRD_PARTY_CHIBICC_DEFINES) +o/$(MODE)/%.chibicc.o: %.s o/$(MODE)/third_party/chibicc/chibicc.com.dbg + @$(COMPILE) -ACHIBICC -T$@ $(CHIBICC) $(CHIBICC_FLAGS) -c -o $@ $< o/$(MODE)/%.chibicc.o: %.c o/$(MODE)/third_party/chibicc/chibicc.com.dbg @$(COMPILE) -ACHIBICC -T$@ $(CHIBICC) $(CHIBICC_FLAGS) -c -o $@ $< o/$(MODE)/%.chibicc2.o: %.c o/$(MODE)/third_party/chibicc/chibicc2.com.dbg diff --git a/third_party/chibicc/codegen.c b/third_party/chibicc/codegen.c index 298975e83..21727cf4b 100644 --- a/third_party/chibicc/codegen.c +++ b/third_party/chibicc/codegen.c @@ -192,9 +192,9 @@ void print_loc(int64_t file, int64_t line) { if (file != lastfile || line != lastline) { locbuf = malloc(2 + 4 + 1 + 20 + 1 + 20 + 1); p = stpcpy(locbuf, "\t.loc\t"); - p += int64toarray_radix10(file, p); + p = FormatInt64(p, file); *p++ = ' '; - int64toarray_radix10(line, p); + FormatInt64(p, line); emitlin(locbuf); free(locbuf); lastfile = file; @@ -262,6 +262,20 @@ static char *reg_ax(int sz) { UNREACHABLE(); } +static char *reg_di(int sz) { + switch (sz) { + case 1: + return "%dil"; + case 2: + return "%di"; + case 4: + return "%edi"; + case 8: + return "%rdi"; + } + UNREACHABLE(); +} + static const char *gotpcrel(void) { if (opt_pic) { return "@gotpcrel(%rip)"; @@ -904,6 +918,9 @@ static bool gen_builtin_funcall(Node *node, const char *name) { } else if (!strcmp(name, "trap")) { emitlin("\tint3"); return true; + } else if (!strcmp(name, "ia32_pause")) { + emitlin("\tpause"); + return true; } else if (!strcmp(name, "unreachable")) { emitlin("\tud2"); return true; @@ -1521,7 +1538,8 @@ void gen_expr(Node *node) { emitlin("\tmovzbl\t%cl,%eax"); return; } - case ND_EXCH: { + case ND_EXCH: + case ND_TESTANDSET: { gen_expr(node->lhs); push(); gen_expr(node->rhs); @@ -1529,6 +1547,43 @@ void gen_expr(Node *node) { println("\txchg\t%s,(%%rdi)", reg_ax(node->ty->size)); return; } + case ND_LOAD: { + gen_expr(node->rhs); + push(); + gen_expr(node->lhs); + println("\tmov\t(%%rax),%s", reg_ax(node->ty->size)); + pop("%rdi"); + println("\tmov\t%s,(%%rdi)", reg_ax(node->ty->size)); + return; + } + case ND_FETCHADD: { + gen_expr(node->lhs); + push(); + gen_expr(node->rhs); + pop("%rdi"); + println("\txadd\t%s,(%%rdi)", reg_ax(node->ty->size)); + return; + } + case ND_SUBFETCH: { + gen_expr(node->lhs); + push(); + gen_expr(node->rhs); + pop("%rdi"); + push(); + println("\tneg\t%s", reg_ax(node->ty->size)); + println("\txadd\t%s,(%%rdi)", reg_ax(node->ty->size)); + pop("%rdi"); + println("\tsub\t%s,%s", reg_di(node->ty->size), reg_ax(node->ty->size)); + return; + } + case ND_RELEASE: { + gen_expr(node->lhs); + push(); + pop("%rdi"); + println("\txor\t%%eax,%%eax"); + println("\tmov\t%s,(%%rdi)", reg_ax(node->ty->size)); + return; + } case ND_FPCLASSIFY: gen_fpclassify(node->fpc); return; @@ -1658,6 +1713,14 @@ void gen_expr(Node *node) { dx = "%edx"; } switch (node->kind) { + case ND_PMOVMSKB: + println("\tmovdqu\t(%%rax),%%xmm0"); + println("\tpmovmskb\t%%xmm0,%%rax"); + break; + case ND_MOVNTDQ: + println("\tmovdqu\t(%%rdi),%%xmm0"); + println("\tmovntdq\t%%xmm0,(%%rax)"); + break; case ND_ADD: if (node->lhs->ty->kind == TY_INT128) { emitlin("\tadd\t%rdi,%rax"); diff --git a/third_party/chibicc/kw.gperf b/third_party/chibicc/kw.gperf index 13482408c..0f1c7777b 100644 --- a/third_party/chibicc/kw.gperf +++ b/third_party/chibicc/kw.gperf @@ -81,7 +81,7 @@ __thread, KW__THREAD_LOCAL __typeof, KW_TYPEOF __builtin_add_overflow, KW___BUILTIN_ADD_OVERFLOW __builtin_assume_aligned, KW___BUILTIN_ASSUME_ALIGNED -__builtin_atomic_exchange, KW___BUILTIN_ATOMIC_EXCHANGE +__atomic_exchange, KW___ATOMIC_EXCHANGE __builtin_compare_and_swap, KW___BUILTIN_COMPARE_AND_SWAP __builtin_constant_p, KW___BUILTIN_CONSTANT_P __builtin_expect, KW___BUILTIN_EXPECT @@ -118,3 +118,10 @@ __builtin_types_compatible_p, KW___BUILTIN_TYPES_COMPATIBLE_P "||", KW_LOGOR "->", KW_ARROW ".", KW_DOT +__atomic_load, KW___ATOMIC_LOAD +__atomic_fetch_add, KW___ATOMIC_FETCH_ADD +__atomic_sub_fetch, KW___ATOMIC_SUB_FETCH +__sync_lock_test_and_set, KW___SYNC_LOCK_TEST_AND_SET +__sync_lock_release, KW___SYNC_LOCK_RELEASE +__builtin_ia32_movntdq, KW___BUILTIN_IA32_MOVNTDQ +__builtin_ia32_pmovmskb128, KW___BUILTIN_IA32_PMOVMSKB128 diff --git a/third_party/chibicc/kw.h b/third_party/chibicc/kw.h index 185d180e0..62d8194eb 100644 --- a/third_party/chibicc/kw.h +++ b/third_party/chibicc/kw.h @@ -68,7 +68,7 @@ #define KW___ASM__ 84 #define KW___BUILTIN_ADD_OVERFLOW 85 #define KW___BUILTIN_ASSUME_ALIGNED 86 -#define KW___BUILTIN_ATOMIC_EXCHANGE 87 +#define KW___ATOMIC_EXCHANGE 87 #define KW___BUILTIN_COMPARE_AND_SWAP 88 #define KW___BUILTIN_CONSTANT_P 89 #define KW___BUILTIN_EXPECT 90 @@ -105,6 +105,13 @@ #define KW_LOGOR 121 #define KW_ARROW 122 #define KW_DOT 123 +#define KW___ATOMIC_LOAD 124 +#define KW___SYNC_LOCK_TEST_AND_SET 125 +#define KW___SYNC_LOCK_RELEASE 126 +#define KW___BUILTIN_IA32_PMOVMSKB128 127 +#define KW___BUILTIN_IA32_MOVNTDQ 128 +#define KW___ATOMIC_FETCH_ADD 129 +#define KW___ATOMIC_SUB_FETCH 130 #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ diff --git a/third_party/chibicc/kw.inc b/third_party/chibicc/kw.inc index eeb8bc5c8..f570e2e53 100644 --- a/third_party/chibicc/kw.inc +++ b/third_party/chibicc/kw.inc @@ -1,7 +1,7 @@ /* ANSI-C code produced by gperf version 3.1 */ /* Command-line: gperf kw.gperf */ /* Computed positions: -k'1,4,11,14,$' */ -/* clang-format off */ +// clang-format off #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ @@ -37,51 +37,44 @@ #line 10 "kw.gperf" struct thatispacked KwSlot { char *name; unsigned char code; }; -#define TOTAL_KEYWORDS 109 +#define TOTAL_KEYWORDS 116 #define MIN_WORD_LENGTH 1 #define MAX_WORD_LENGTH 28 #define MIN_HASH_VALUE 1 -#define MAX_HASH_VALUE 211 -/* maximum key range = 211, duplicates = 0 */ +#define MAX_HASH_VALUE 201 +/* maximum key range = 201, duplicates = 0 */ -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int +static inline unsigned int hash (register const char *str, register size_t len) { static const unsigned char asso_values[] = { - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 105, 212, 212, 212, 212, 65, 212, - 100, 95, 90, 15, 212, 0, 80, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 5, 212, 212, 212, - 212, 212, 65, 212, 212, 212, 0, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 5, 212, 20, 50, 0, - 5, 15, 0, 25, 40, 90, 60, 0, 20, 15, - 85, 105, 0, 25, 55, 10, 0, 65, 5, 0, - 0, 10, 0, 30, 10, 25, 5, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212 + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 100, 202, 202, 202, 202, 65, 202, + 95, 90, 85, 15, 202, 0, 75, 202, 202, 202, + 0, 202, 202, 202, 202, 202, 10, 202, 202, 202, + 202, 202, 55, 202, 202, 202, 0, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 5, 202, 0, 50, 0, + 5, 15, 0, 40, 45, 115, 60, 5, 20, 15, + 90, 85, 0, 0, 55, 10, 0, 65, 5, 0, + 0, 10, 25, 70, 35, 30, 5, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202 }; register unsigned int hval = len; @@ -135,24 +128,23 @@ LookupKw (register const char *str, register size_t len) {"~", KW_TILDE}, #line 68 "kw.gperf" {"_Atomic", KW__ATOMIC}, -#line 81 "kw.gperf" - {"__typeof", KW_TYPEOF}, - {""}, + {""}, {""}, #line 78 "kw.gperf" {"__restrict", KW_RESTRICT}, #line 22 "kw.gperf" {"sizeof", KW_SIZEOF}, #line 75 "kw.gperf" {"__asm__", KW___ASM__}, - {""}, +#line 41 "kw.gperf" + {"asm", KW_ASM}, #line 15 "kw.gperf" {"case", KW_CASE}, #line 73 "kw.gperf" {"__VA_OPT__", KW___VA_OPT__}, #line 13 "kw.gperf" {"struct", KW_STRUCT}, -#line 118 "kw.gperf" - {"||", KW_LOGOR}, +#line 60 "kw.gperf" + {"strpbrk", KW_STRPBRK}, {""}, {""}, #line 31 "kw.gperf" {"short", KW_SHORT}, @@ -178,22 +170,19 @@ LookupKw (register const char *str, register size_t len) {"while", KW_WHILE}, #line 85 "kw.gperf" {"__builtin_compare_and_swap", KW___BUILTIN_COMPARE_AND_SWAP}, -#line 101 "kw.gperf" - {"__builtin_strpbrk", KW___BUILTIN_STRPBRK}, -#line 41 "kw.gperf" - {"asm", KW_ASM}, +#line 82 "kw.gperf" + {"__builtin_add_overflow", KW___BUILTIN_ADD_OVERFLOW}, +#line 81 "kw.gperf" + {"__typeof", KW_TYPEOF}, #line 55 "kw.gperf" {"line", KW_LINE}, #line 86 "kw.gperf" {"__builtin_constant_p", KW___BUILTIN_CONSTANT_P}, #line 74 "kw.gperf" {"__alignof__", KW___ALIGNOF__}, -#line 60 "kw.gperf" - {"strpbrk", KW_STRPBRK}, - {""}, -#line 47 "kw.gperf" - {"elif", KW_ELIF}, - {""}, {""}, +#line 101 "kw.gperf" + {"__builtin_strpbrk", KW___BUILTIN_STRPBRK}, + {""}, {""}, {""}, {""}, #line 103 "kw.gperf" {"__builtin_sub_overflow", KW___BUILTIN_SUB_OVERFLOW}, #line 72 "kw.gperf" @@ -202,8 +191,8 @@ LookupKw (register const char *str, register size_t len) {"__builtin_popcountl", KW___BUILTIN_POPCOUNTL}, #line 97 "kw.gperf" {"__builtin_popcountll", KW___BUILTIN_POPCOUNTLL}, -#line 108 "kw.gperf" - {"}", KW_RB}, +#line 56 "kw.gperf" + {"pragma", KW_PRAGMA}, #line 92 "kw.gperf" {"__builtin_mul_overflow", KW___BUILTIN_MUL_OVERFLOW}, #line 104 "kw.gperf" @@ -213,15 +202,16 @@ LookupKw (register const char *str, register size_t len) {"float", KW_FLOAT}, #line 87 "kw.gperf" {"__builtin_expect", KW___BUILTIN_EXPECT}, -#line 82 "kw.gperf" - {"__builtin_add_overflow", KW___BUILTIN_ADD_OVERFLOW}, +#line 119 "kw.gperf" + {"->", KW_ARROW}, #line 20 "kw.gperf" {"for", KW_FOR}, - {""}, +#line 47 "kw.gperf" + {"elif", KW_ELIF}, #line 91 "kw.gperf" {"__builtin_fpclassify", KW___BUILTIN_FPCLASSIFY}, -#line 107 "kw.gperf" - {"{", KW_LB}, +#line 108 "kw.gperf" + {"}", KW_RB}, #line 42 "kw.gperf" {"default", KW_DEFAULT}, {""}, @@ -229,21 +219,19 @@ LookupKw (register const char *str, register size_t len) {"__builtin_ffsl", KW___BUILTIN_FFSL}, #line 90 "kw.gperf" {"__builtin_ffsll", KW___BUILTIN_FFSLL}, -#line 56 "kw.gperf" - {"pragma", KW_PRAGMA}, -#line 119 "kw.gperf" - {"->", KW_ARROW}, - {""}, + {""}, {""}, {""}, #line 18 "kw.gperf" {"char", KW_CHAR}, #line 64 "kw.gperf" {"undef", KW_UNDEF}, #line 61 "kw.gperf" {"strstr", KW_STRSTR}, - {""}, +#line 118 "kw.gperf" + {"||", KW_LOGOR}, #line 67 "kw.gperf" {"_Alignof", KW__ALIGNOF}, - {""}, +#line 124 "kw.gperf" + {"__sync_lock_test_and_set", KW___SYNC_LOCK_TEST_AND_SET}, #line 49 "kw.gperf" {"error", KW_ERROR}, #line 58 "kw.gperf" @@ -261,19 +249,53 @@ LookupKw (register const char *str, register size_t len) {""}, #line 66 "kw.gperf" {"_Alignas", KW__ALIGNAS}, +#line 125 "kw.gperf" + {"__sync_lock_release", KW___SYNC_LOCK_RELEASE}, {""}, -#line 84 "kw.gperf" - {"__builtin_atomic_exchange", KW___BUILTIN_ATOMIC_EXCHANGE}, #line 39 "kw.gperf" {"define", KW_DEFINE}, {""}, #line 35 "kw.gperf" {"continue", KW_CONTINUE}, -#line 24 "kw.gperf" - {"long", KW_LONG}, +#line 43 "kw.gperf" + {"auto", KW_AUTO}, {""}, #line 99 "kw.gperf" {"__builtin_strchr", KW___BUILTIN_STRCHR}, +#line 21 "kw.gperf" + {"do", KW_DO}, + {""}, {""}, {""}, {""}, {""}, +#line 70 "kw.gperf" + {"_Generic", KW__GENERIC}, +#line 98 "kw.gperf" + {"__builtin_reg_class", KW___BUILTIN_REG_CLASS}, + {""}, +#line 102 "kw.gperf" + {"__builtin_strstr", KW___BUILTIN_STRSTR}, +#line 84 "kw.gperf" + {"__atomic_exchange", KW___ATOMIC_EXCHANGE}, +#line 45 "kw.gperf" + {"__attribute__", KW___ATTRIBUTE__}, +#line 83 "kw.gperf" + {"__builtin_assume_aligned", KW___BUILTIN_ASSUME_ALIGNED}, + {""}, +#line 32 "kw.gperf" + {"signed", KW_SIGNED}, + {""}, +#line 77 "kw.gperf" + {"__int128", KW___INT128}, +#line 24 "kw.gperf" + {"long", KW_LONG}, +#line 33 "kw.gperf" + {"break", KW_BREAK}, +#line 50 "kw.gperf" + {"extern", KW_EXTERN}, + {""}, +#line 76 "kw.gperf" + {"__inline", KW_INLINE}, +#line 46 "kw.gperf" + {"_Noreturn", KW__NORETURN}, + {""}, {""}, #line 12 "kw.gperf" {"if", KW_IF}, #line 54 "kw.gperf" @@ -281,37 +303,11 @@ LookupKw (register const char *str, register size_t len) {""}, #line 37 "kw.gperf" {"ifdef", KW_IFDEF}, - {""}, {""}, {""}, -#line 98 "kw.gperf" - {"__builtin_reg_class", KW___BUILTIN_REG_CLASS}, - {""}, -#line 102 "kw.gperf" - {"__builtin_strstr", KW___BUILTIN_STRSTR}, - {""}, -#line 45 "kw.gperf" - {"__attribute__", KW___ATTRIBUTE__}, - {""}, -#line 33 "kw.gperf" - {"break", KW_BREAK}, -#line 50 "kw.gperf" - {"extern", KW_EXTERN}, - {""}, -#line 80 "kw.gperf" - {"__thread", KW__THREAD_LOCAL}, -#line 46 "kw.gperf" - {"_Noreturn", KW__NORETURN}, - {""}, -#line 38 "kw.gperf" - {"ifndef", KW_IFNDEF}, -#line 21 "kw.gperf" - {"do", KW_DO}, - {""}, {""}, {""}, #line 59 "kw.gperf" {"strlen", KW_STRLEN}, -#line 52 "kw.gperf" - {"include_next", KW_INCLUDE_NEXT}, -#line 70 "kw.gperf" - {"_Generic", KW__GENERIC}, + {""}, +#line 94 "kw.gperf" + {"__builtin_offsetof", KW___BUILTIN_OFFSETOF}, #line 34 "kw.gperf" {"enum", KW_ENUM}, {""}, @@ -319,62 +315,70 @@ LookupKw (register const char *str, register size_t len) {"switch", KW_SWITCH}, #line 93 "kw.gperf" {"__builtin_neg_overflow", KW___BUILTIN_NEG_OVERFLOW}, -#line 77 "kw.gperf" - {"__int128", KW___INT128}, -#line 83 "kw.gperf" - {"__builtin_assume_aligned", KW___BUILTIN_ASSUME_ALIGNED}, - {""}, -#line 32 "kw.gperf" - {"signed", KW_SIGNED}, -#line 36 "kw.gperf" - {"include", KW_INCLUDE}, #line 57 "kw.gperf" {"restrict", KW_RESTRICT}, -#line 43 "kw.gperf" - {"auto", KW_AUTO}, +#line 51 "kw.gperf" + {"goto", KW_GOTO}, {""}, #line 111 "kw.gperf" {"&", KW_AMP}, #line 117 "kw.gperf" {"&&", KW_LOGAND}, -#line 76 "kw.gperf" - {"__inline", KW_INLINE}, -#line 51 "kw.gperf" - {"goto", KW_GOTO}, - {""}, {""}, {""}, +#line 80 "kw.gperf" + {"__thread", KW__THREAD_LOCAL}, + {""}, {""}, +#line 38 "kw.gperf" + {"ifndef", KW_IFNDEF}, + {""}, #line 23 "kw.gperf" {"unsigned", KW_UNSIGNED}, {""}, {""}, +#line 107 "kw.gperf" + {"{", KW_LB}, +#line 52 "kw.gperf" + {"include_next", KW_INCLUDE_NEXT}, + {""}, {""}, {""}, #line 100 "kw.gperf" {"__builtin_strlen", KW___BUILTIN_STRLEN}, - {""}, -#line 94 "kw.gperf" - {"__builtin_offsetof", KW___BUILTIN_OFFSETOF}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 126 "kw.gperf" + {"__builtin_ia32_movntdq", KW___BUILTIN_IA32_MOVNTDQ}, + {""}, {""}, {""}, +#line 120 "kw.gperf" + {".", KW_DOT}, +#line 36 "kw.gperf" + {"include", KW_INCLUDE}, +#line 122 "kw.gperf" + {"__atomic_fetch_add", KW___ATOMIC_FETCH_ADD}, + {""}, {""}, #line 14 "kw.gperf" {"return", KW_RETURN}, {""}, {""}, {""}, #line 26 "kw.gperf" {"union", KW_UNION}, - {""}, {""}, {""}, {""}, {""}, -#line 120 "kw.gperf" - {".", KW_DOT}, +#line 127 "kw.gperf" + {"__builtin_ia32_pmovmskb128", KW___BUILTIN_IA32_PMOVMSKB128}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 53 "kw.gperf" - {"inline", KW_INLINE}, - {""}, {""}, {""}, {""}, {""}, {""}, +#line 112 "kw.gperf" + {"*", KW_STAR}, + {""}, +#line 121 "kw.gperf" + {"__atomic_load", KW___ATOMIC_LOAD}, + {""}, {""}, {""}, {""}, #line 44 "kw.gperf" {"register", KW_REGISTER}, {""}, {""}, -#line 112 "kw.gperf" - {"*", KW_STAR}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, #line 106 "kw.gperf" {")", KW_RP}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, #line 105 "kw.gperf" {"(", KW_LP}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 53 "kw.gperf" + {"inline", KW_INLINE}, + {""}, +#line 123 "kw.gperf" + {"__atomic_sub_fetch", KW___ATOMIC_SUB_FETCH}, + {""}, {""}, #line 113 "kw.gperf" {"!", KW_EXCLAIM} }; diff --git a/third_party/chibicc/parse.c b/third_party/chibicc/parse.c index fb6407b4c..7945505e8 100644 --- a/third_party/chibicc/parse.c +++ b/third_party/chibicc/parse.c @@ -19,6 +19,7 @@ #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/log/libfatal.internal.h" +#include "libc/log/log.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/ffs.h" #include "libc/testlib/testlib.h" @@ -352,7 +353,10 @@ static Obj *new_string_literal(char *p, Type *ty) { } static char *get_ident(Token *tok) { - if (tok->kind != TK_IDENT) error_tok(tok, "expected an identifier"); + if (tok->kind != TK_IDENT) { + __die(); + error_tok(tok, "expected an identifier"); + } return strndup(tok->loc, tok->len); } @@ -555,7 +559,7 @@ static Token *thing_attributes(Token *tok, void *arg) { consume_attribute(&tok, tok, "warn_unused_result") || consume_attribute(&tok, tok, "flatten") || consume_attribute(&tok, tok, "leaf") || - consume_attribute(&tok, tok, "nothrow") || + consume_attribute(&tok, tok, "dontthrow") || consume_attribute(&tok, tok, "optnone") || consume_attribute(&tok, tok, "returns_twice") || consume_attribute(&tok, tok, "nodebug") || @@ -976,11 +980,12 @@ static Type *type_suffix(Token **rest, Token *tok, Type *ty) { return ty; } -// pointers = ("*" ("const" | "volatile" | "restrict")*)* +// pointers = ("*" ("const" | "volatile" | "restrict" | attribute)*)* static Type *pointers(Token **rest, Token *tok, Type *ty) { while (CONSUME(&tok, tok, "*")) { ty = pointer_to(ty); for (;;) { + tok = attribute_list(tok, ty, type_attributes); if (EQUAL(tok, "const")) { ty->is_const = true; tok = tok->next; @@ -1087,6 +1092,10 @@ static Type *enum_specifier(Token **rest, Token *tok) { int val = 0; while (!consume_end(rest, tok)) { if (i++ > 0) tok = skip(tok, ','); + if (tok->kind == TK_JAVADOWN) { + current_javadown = tok; + tok = tok->next; + } char *name = get_ident(tok); tok = tok->next; if (EQUAL(tok, "=")) val = const_expr(&tok, tok->next); @@ -1281,6 +1290,10 @@ static void array_designator(Token **rest, Token *tok, Type *ty, int *begin, static Member *struct_designator(Token **rest, Token *tok, Type *ty) { Token *start = tok; tok = skip(tok, '.'); + if (tok->kind == TK_JAVADOWN) { + current_javadown = tok; + tok = tok->next; + } if (tok->kind != TK_IDENT) error_tok(tok, "expected a field designator"); for (Member *mem = ty->members; mem; mem = mem->next) { // Anonymous struct member @@ -2774,6 +2787,10 @@ static void struct_members(Token **rest, Token *tok, Type *ty) { // Regular struct members while (!CONSUME(&tok, tok, ";")) { if (!first) tok = skip(tok, ','); + if (tok->kind == TK_JAVADOWN) { + current_javadown = tok; + tok = tok->next; + } first = false; Member *mem = calloc(1, sizeof(Member)); mem->ty = declarator(&tok, tok, basety); @@ -2832,6 +2849,10 @@ static Type *struct_union_decl(Token **rest, Token *tok) { ty->name = tag; tok = skip(tok, '{'); // Construct a struct object. + if (tok->kind == TK_JAVADOWN) { + current_javadown = tok; + tok = tok->next; + } struct_members(&tok, tok, ty); *rest = attribute_list(tok, ty, type_attributes); if (tag) { @@ -3218,12 +3239,93 @@ static Node *primary(Token **rest, Token *tok) { node->ty = node->cas_addr->ty->base; return node; } - if (kw == KW___BUILTIN_ATOMIC_EXCHANGE) { + if (kw == KW___ATOMIC_EXCHANGE) { Node *node = new_node(ND_EXCH, tok); tok = skip(tok->next, '('); node->lhs = assign(&tok, tok); + add_type(node->lhs); + node->ty = node->lhs->ty->base; tok = skip(tok, ','); node->rhs = assign(&tok, tok); + *rest = skip(tok, ')'); + return node; + } + if (kw == KW___ATOMIC_LOAD) { + Node *node = new_node(ND_LOAD, tok); + tok = skip(tok->next, '('); + node->lhs = assign(&tok, tok); + add_type(node->lhs); + node->ty = node->lhs->ty->base; + tok = skip(tok, ','); + node->rhs = assign(&tok, tok); + tok = skip(tok, ','); + const_expr(&tok, tok); + *rest = skip(tok, ')'); + return node; + } + if (kw == KW___ATOMIC_FETCH_ADD) { + Node *node = new_node(ND_FETCHADD, tok); + tok = skip(tok->next, '('); + node->lhs = assign(&tok, tok); + add_type(node->lhs); + node->ty = node->lhs->ty->base; + tok = skip(tok, ','); + node->rhs = assign(&tok, tok); + tok = skip(tok, ','); + const_expr(&tok, tok); + *rest = skip(tok, ')'); + return node; + } + if (kw == KW___ATOMIC_SUB_FETCH) { + Node *node = new_node(ND_SUBFETCH, tok); + tok = skip(tok->next, '('); + node->lhs = assign(&tok, tok); + add_type(node->lhs); + node->ty = node->lhs->ty->base; + tok = skip(tok, ','); + node->rhs = assign(&tok, tok); + tok = skip(tok, ','); + const_expr(&tok, tok); + *rest = skip(tok, ')'); + return node; + } + if (kw == KW___SYNC_LOCK_TEST_AND_SET) { + Node *node = new_node(ND_TESTANDSET, tok); + tok = skip(tok->next, '('); + node->lhs = assign(&tok, tok); + add_type(node->lhs); + node->ty = node->lhs->ty->base; + tok = skip(tok, ','); + node->rhs = assign(&tok, tok); + *rest = skip(tok, ')'); + return node; + } + if (kw == KW___SYNC_LOCK_RELEASE) { + Node *node = new_node(ND_RELEASE, tok); + tok = skip(tok->next, '('); + node->lhs = assign(&tok, tok); + add_type(node->lhs); + node->ty = node->lhs->ty->base; + *rest = skip(tok, ')'); + return node; + } + if (kw == KW___BUILTIN_IA32_MOVNTDQ) { + Node *node = new_node(ND_MOVNTDQ, tok); + tok = skip(tok->next, '('); + node->lhs = assign(&tok, tok); + add_type(node->lhs); + node->ty = node->lhs->ty->base; + tok = skip(tok, ','); + node->rhs = assign(&tok, tok); + add_type(node->rhs); + *rest = skip(tok, ')'); + return node; + } + if (kw == KW___BUILTIN_IA32_PMOVMSKB128) { + Node *node = new_node(ND_PMOVMSKB, tok); + tok = skip(tok->next, '('); + node->lhs = assign(&tok, tok); + add_type(node->lhs); node->ty = node->lhs->ty->base; *rest = skip(tok, ')'); return node; @@ -3428,7 +3530,9 @@ static Node *primary(Token **rest, Token *tok) { static Token *parse_typedef(Token *tok, Type *basety) { bool first = true; while (!CONSUME(&tok, tok, ";")) { - if (!first) tok = skip(tok, ','); + if (!first) { + tok = skip(tok, ','); + } first = false; Type *ty = declarator(&tok, tok, basety); if (!ty->name) error_tok(ty->name_pos, "typedef name omitted"); @@ -3566,11 +3670,18 @@ static Token *function(Token *tok, Type *basety, VarAttr *attr) { static Token *global_variable(Token *tok, Type *basety, VarAttr *attr) { bool first = true; + bool isjavadown = tok->kind == TK_JAVADOWN; while (!CONSUME(&tok, tok, ";")) { if (!first) tok = skip(tok, ','); first = false; Type *ty = declarator(&tok, tok, basety); - if (!ty->name) error_tok(ty->name_pos, "variable name omitted"); + if (!ty->name) { + if (isjavadown) { + return tok; + } else { + error_tok(ty->name_pos, "variable name omitted"); + } + } Obj *var = new_gvar(get_ident(ty->name), ty); if (!var->tok) var->tok = ty->name; var->javadown = current_javadown; @@ -3690,6 +3801,7 @@ void declare_builtin_functions(void) { Type *pchar = pointer_to(ty_char); builtin_alloca = declare1("alloca", pointer_to(ty_void), ty_int); declare0("trap", ty_int); + declare0("ia32_pause", ty_void); declare0("unreachable", ty_int); declare1("ctz", ty_int, ty_int); declare1("ctzl", ty_int, ty_long); diff --git a/third_party/chibicc/preprocess.c b/third_party/chibicc/preprocess.c index 8eda785ca..d71363dd6 100644 --- a/third_party/chibicc/preprocess.c +++ b/third_party/chibicc/preprocess.c @@ -284,7 +284,9 @@ static long eval_const_expr(Token **rest, Token *tok) { convert_pp_tokens(expr); Token *rest2; long val = const_expr(&rest2, expr); - if (rest2->kind != TK_EOF) error_tok(rest2, "extra token"); + if (rest2->kind != TK_EOF && rest2->kind != TK_JAVADOWN) { + error_tok(rest2, "extra token"); + } __arena_pop(); return val; } @@ -324,7 +326,12 @@ static MacroParam *read_macro_params(Token **rest, Token *tok, *rest = skip(tok->next, ')'); return head.next; } - if (tok->kind != TK_IDENT) error_tok(tok, "expected an identifier"); + if (tok->kind == TK_JAVADOWN) { + tok = tok->next; + } + if (tok->kind != TK_IDENT) { + error_tok(tok, "expected an identifier"); + } if (EQUAL(tok->next, "...")) { *va_args_name = strndup(tok->loc, tok->len); *rest = skip(tok->next->next, ')'); @@ -1045,12 +1052,16 @@ __UINT32_MAX__\000\ 0xffffffffu\000\ __INT64_MAX__\000\ 0x7fffffffffffffffl\000\ +__INTMAX_MAX__\000\ +0x7fffffffffffffffl\000\ __LONG_MAX__\000\ 0x7fffffffffffffffl\000\ __LONG_LONG_MAX__\000\ 0x7fffffffffffffffl\000\ __UINT64_MAX__\000\ 0xfffffffffffffffful\000\ +__UINTMAX_MAX__\000\ +0xfffffffffffffffful\000\ __SIZE_MAX__\000\ 0xfffffffffffffffful\000\ __INTPTR_MAX__\000\ @@ -1103,8 +1114,16 @@ __UINT32_TYPE__\000\ unsigned int\000\ __INT64_TYPE__\000\ long int\000\ +__INTMAX_TYPE__\000\ +long int\000\ __UINT64_TYPE__\000\ long unsigned int\000\ +__UINTMAX_TYPE__\000\ +long unsigned int\000\ +__INTMAX_TYPE__\000\ +long int\000\ +__UINTMAX_TYPE__\000\ +long unsigned int\000\ __INTPTR_TYPE__\000\ long int\000\ __UINTPTR_TYPE__\000\ @@ -1267,6 +1286,22 @@ __SSE2__\000\ 1\000\ __SSE2_MATH__\000\ 1\000\ +__ATOMIC_ACQUIRE\000\ +2\000\ +__ATOMIC_HLE_RELEASE\000\ +131072\000\ +__ATOMIC_HLE_ACQUIRE\000\ +65536\000\ +__ATOMIC_RELAXED\000\ +0\000\ +__ATOMIC_CONSUME\000\ +1\000\ +__ATOMIC_SEQ_CST\000\ +5\000\ +__ATOMIC_ACQ_REL\000\ +4\000\ +__ATOMIC_RELEASE\000\ +3\000\ \000"; do { val = name + strlen(name) + 1; diff --git a/third_party/chibicc/test/common.c b/third_party/chibicc/test/common.c index baada9266..f2b346b29 100644 --- a/third_party/chibicc/test/common.c +++ b/third_party/chibicc/test/common.c @@ -17,8 +17,8 @@ void Assert2(long expected, long actual, char *code, char *func, int line) { void Assert128(__int128 k, __int128 x, char *code, char *func, int line) { if (k != x) { - fprintf(stderr, "%s:%d: %s => want %jd but got %jd\n", func, line, code, k, - x); + fprintf(stderr, "%s:%d: %s => want %jjd but got %jjd\n", func, line, code, + k, x); exit(1); } } diff --git a/third_party/chibicc/test/int128_test.c b/third_party/chibicc/test/int128_test.c index 474b822c8..c84532252 100644 --- a/third_party/chibicc/test/int128_test.c +++ b/third_party/chibicc/test/int128_test.c @@ -38,8 +38,8 @@ __int128 sub128x6(int f, __int128 a, __int128 b, __int128 c, __int128 d, return f - a - b - c - d - e; } -void lotsOfArgs(const char *file, int line, const char *func, intmax_t beg, - intmax_t end, intmax_t got, const char *gotcode, bool isfatal) { +void lotsOfArgs(const char *file, int line, const char *func, int128_t beg, + int128_t end, int128_t got, const char *gotcode, bool isfatal) { } void testLang128(void) { @@ -8176,7 +8176,7 @@ void testNot128(void) { void testAbi(void) { ASSERT(0, ({ char buf[200]; - sprintf(buf, "%d %d %d %d %032jx %032jx", 1, 2, 3, 4, + sprintf(buf, "%d %d %d %d %032jjx %032jjx", 1, 2, 3, 4, I128(0x1ffffffff, 0x2ffffffff), I128(0x3eeeeeeee, 0x4eeeeeeee)); strcmp("1 2 3 4 00000001ffffffff00000002ffffffff " @@ -8185,7 +8185,7 @@ void testAbi(void) { })); ASSERT(0, ({ char buf[200]; - sprintf(buf, "%d %d %d %d %d %032jx %032jx", 1, 2, 3, 4, 5, + sprintf(buf, "%d %d %d %d %d %032jjx %032jjx", 1, 2, 3, 4, 5, I128(0x1ffffffff, 0x2ffffffff), I128(0x3eeeeeeee, 0x4eeeeeeee)); strcmp("1 2 3 4 5 00000001ffffffff00000002ffffffff " diff --git a/third_party/chibicc/test/msabi_test.c b/third_party/chibicc/test/msabi_test.c new file mode 100644 index 000000000..ef14721a0 --- /dev/null +++ b/third_party/chibicc/test/msabi_test.c @@ -0,0 +1,6 @@ +#include "third_party/chibicc/test/test.h" + +int (*__attribute__((__ms_abi__)) NtFoo)(int x, int y); + +int main() { +} diff --git a/third_party/chibicc/test/spinlock_test.c b/third_party/chibicc/test/spinlock_test.c new file mode 100644 index 000000000..5e50af42d --- /dev/null +++ b/third_party/chibicc/test/spinlock_test.c @@ -0,0 +1,26 @@ +#include "third_party/chibicc/test/test.h" + +#define SPINLOCK(lock) \ + do { \ + for (;;) { \ + typeof(*(lock)) x; \ + __atomic_load(lock, &x, __ATOMIC_RELAXED); \ + if (!x && !__sync_lock_test_and_set(lock, 1)) { \ + break; \ + } else { \ + __builtin_ia32_pause(); \ + } \ + } \ + } while (0) + +#define SPUNLOCK(lock) __sync_lock_release(lock) + +_Alignas(64) char lock; + +main() { + ASSERT(0, lock); + SPINLOCK(&lock); + ASSERT(1, lock); + SPUNLOCK(&lock); + ASSERT(0, lock); +} diff --git a/third_party/chibicc/test/test.mk b/third_party/chibicc/test/test.mk index 61824fda4..e42be50b0 100644 --- a/third_party/chibicc/test/test.mk +++ b/third_party/chibicc/test/test.mk @@ -39,6 +39,7 @@ THIRD_PARTY_CHIBICC_TEST_CHECKS = \ $(THIRD_PARTY_CHIBICC_TEST_HDRS:%=o/$(MODE)/%.ok) THIRD_PARTY_CHIBICC_TEST_DIRECTDEPS = \ + LIBC_CALLS \ LIBC_FMT \ LIBC_INTRIN \ LIBC_MEM \ diff --git a/third_party/chibicc/test/vector_test.c b/third_party/chibicc/test/vector_test.c index a09b88cda..ea8160bf1 100644 --- a/third_party/chibicc/test/vector_test.c +++ b/third_party/chibicc/test/vector_test.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "third_party/chibicc/test/test.h" +typedef char byte16 __attribute__((__vector_size__(16))); typedef float float4 __attribute__((__vector_size__(16))); typedef float float4a1 __attribute__((__vector_size__(16), __aligned__(1))); typedef float float4a16 __attribute__((__vector_size__(16), __aligned__(16))); @@ -39,18 +40,33 @@ int main(void) { ASSERT(1, _Alignof(double2a1)); ASSERT(16, _Alignof(double2a16)); - float4 v1; - float4 v2; - float x[4] = {1, 2, 3, 4}; - float y[4] = {1, 1, 1, 1}; - memcpy(&v1, x, 16); - memcpy(&v2, y, 16); - v1 = v1 + v2; - memcpy(x, &v1, 16); - ASSERT(2, x[0]); - /* ASSERT(3, x[1]); */ - /* ASSERT(4, x[2]); */ - /* ASSERT(5, x[3]); */ + { + float4 v1; + float4 v2; + float x[4] = {1, 2, 3, 4}; + float y[4] = {1, 1, 1, 1}; + memcpy(&v1, x, 16); + memcpy(&v2, y, 16); + v1 = v1 + v2; + memcpy(x, &v1, 16); + ASSERT(2, x[0]); + // TODO(jart): fix me + /* ASSERT(3, x[1]); */ + /* ASSERT(4, x[2]); */ + /* ASSERT(5, x[3]); */ + } + + { + byte16 v; + float x1[4] = {1, 2, 3, 4}; + float x2[4]; + memcpy(&v, x1, 16); + __builtin_ia32_movntdq(x1, &v); + memcpy(x2, &v, 16); + ASSERT(1, x2[0]); + // TODO(jart): fix me + /* ASSERT(2, x[1]); */ + } return 0; } diff --git a/third_party/chibicc/tokenize.c b/third_party/chibicc/tokenize.c index 3be9520bf..909d07911 100644 --- a/third_party/chibicc/tokenize.c +++ b/third_party/chibicc/tokenize.c @@ -97,6 +97,9 @@ bool consume(Token **rest, Token *tok, char *str, size_t n) { // Ensure that the current token is `op`. Token *skip(Token *tok, char op) { + while (tok->kind == TK_JAVADOWN) { + tok = tok->next; + } if (tok->len == 1 && *tok->loc == op) { return tok->next; } else { diff --git a/third_party/compiler_rt/int_types.h b/third_party/compiler_rt/int_types.h index dd6c73824..49a11354f 100644 --- a/third_party/compiler_rt/int_types.h +++ b/third_party/compiler_rt/int_types.h @@ -1,5 +1,4 @@ /* clang-format off */ -/* clang-format off */ /* ===-- int_lib.h - configuration header for compiler-rt -----------------=== * * The LLVM Compiler Infrastructure diff --git a/third_party/dlmalloc/COPYING b/third_party/dlmalloc/COPYING deleted file mode 100644 index 3ce09cea1..000000000 --- a/third_party/dlmalloc/COPYING +++ /dev/null @@ -1,10 +0,0 @@ -/ Since dlmalloc is public domain, we intend to keep it that way. To the -/ extent possible under law, Justine Tunney has waived all copyright and -/ related or neighboring rights to her /third_party/dlmalloc changes, as -/ it is written in the following disclaimers: -/ • unlicense.org -/ • creativecommons.org/publicdomain/zero/1.0/ - -.ident "\n -dlmalloc (Public Domain CC0) -Credit: Doug Lea " diff --git a/third_party/dlmalloc/README b/third_party/dlmalloc/README index 6c542bd1a..690efa141 100644 --- a/third_party/dlmalloc/README +++ b/third_party/dlmalloc/README @@ -1,10 +1,9 @@ - This is a version (aka dlmalloc) of malloc/free/realloc written by Doug Lea and released to the public domain, as explained at http://creativecommons.org/publicdomain/zero/1.0/ Send questions, comments, complaints, performance data, etc to dl@cs.oswego.edu - Version 2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea +* Version 2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea Note: There may be an updated version of this malloc obtainable at ftp://gee.cs.oswego.edu/pub/misc/malloc.c Check before installing! @@ -41,7 +40,9 @@ (e.g. 2.7.2) supporting these.) Alignment: 8 bytes (minimum) - Is set to 16 for NexGen32e. + This suffices for nearly all current machines and C compilers. + However, you can define MALLOC_ALIGNMENT to be wider than this + if necessary (up to 128bytes), at the expense of using more space. Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) 8 or 16 bytes (if 8byte sizes) @@ -98,7 +99,7 @@ If you don't like either of these options, you can define CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything else. And if if you are sure that your program using malloc has - no errors or vulnerabilities, you can define TRUSTWORTHY to 1, + no errors or vulnerabilities, you can define INSECURE to 1, which might (or might not) provide a small performance improvement. It is also possible to limit the maximum total allocatable @@ -182,6 +183,371 @@ For a longer but out of date high-level description, see http://gee.cs.oswego.edu/dl/html/malloc.html + ----------------------- Chunk representations ------------------------ + + (The following includes lightly edited explanations by Colin Plumb.) + + The malloc_chunk declaration below is misleading (but accurate and + necessary). It declares a "view" into memory allowing access to + necessary fields at known offsets from a given base. + + Chunks of memory are maintained using a `boundary tag' method as + originally described by Knuth. (See the paper by Paul Wilson + ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such + techniques.) Sizes of free chunks are stored both in the front of + each chunk and at the end. This makes consolidating fragmented + chunks into bigger chunks fast. The head fields also hold bits + representing whether chunks are free or in use. + + Here are some pictures to make it clearer. They are "exploded" to + show that the state of a chunk can be thought of as extending from + the high 31 bits of the head field of its header through the + prev_foot and PINUSE_BIT bit of the following chunk header. + + A chunk that's in use looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk (if P = 0) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 1| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + +- -+ + | | + +- -+ + | : + +- size - sizeof(size_t) available payload bytes -+ + : | + chunk-> +- -+ + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| + | Size of next chunk (may or may not be in use) | +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + And if it's free, it looks like this: + + chunk-> +- -+ + | User payload (must be in use, or we would have merged!) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 0| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Prev pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- size - sizeof(struct chunk) unused bytes -+ + : | + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| + | Size of next chunk (must be in use, or we would have merged)| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- User payload -+ + : | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |0| + +-+ + Note that since we always merge adjacent free chunks, the chunks + adjacent to a free chunk must be in use. + + Given a pointer to a chunk (which can be derived trivially from the + payload pointer) we can, in O(1) time, find out whether the adjacent + chunks are free, and if so, unlink them from the lists that they + are on and merge them with the current chunk. + + Chunks always begin on even word boundaries, so the mem portion + (which is returned to the user) is also on an even word boundary, and + thus at least double-word aligned. + + The P (PINUSE_BIT) bit, stored in the unused low-order bit of the + chunk size (which is always a multiple of two words), is an in-use + bit for the *previous* chunk. If that bit is *clear*, then the + word before the current chunk size contains the previous chunk + size, and can be used to find the front of the previous chunk. + The very first chunk allocated always has this bit set, preventing + access to non-existent (or non-owned) memory. If pinuse is set for + any given chunk, then you CANNOT determine the size of the + previous chunk, and might even get a memory addressing fault when + trying to do so. + + The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of + the chunk size redundantly records whether the current chunk is + inuse (unless the chunk is mmapped). This redundancy enables usage + checks within free and realloc, and reduces indirection when freeing + and consolidating chunks. + + Each freshly allocated chunk must have both cinuse and pinuse set. + That is, each allocated chunk borders either a previously allocated + and still in-use chunk, or the base of its memory arena. This is + ensured by making all allocations from the `lowest' part of any + found chunk. Further, no free chunk physically borders another one, + so each free chunk is known to be preceded and followed by either + inuse chunks or the ends of memory. + + Note that the `foot' of the current chunk is actually represented + as the prev_foot of the NEXT chunk. This makes it easier to + deal with alignments etc but can be very confusing when trying + to extend or adapt this code. + + The exceptions to all this are + + 1. The special chunk `top' is the top-most available chunk (i.e., + the one bordering the end of available memory). It is treated + specially. Top is never included in any bin, is used only if + no other chunk is available, and is released back to the + system if it is very large (see M_TRIM_THRESHOLD). In effect, + the top chunk is treated as larger (and thus less well + fitting) than any other available chunk. The top chunk + doesn't update its trailing size field since there is no next + contiguous chunk that would have to index off it. However, + space is still allocated for it (TOP_FOOT_SIZE) to enable + separation or merging when space is extended. + + 3. Chunks allocated via mmap, have both cinuse and pinuse bits + cleared in their head fields. Because they are allocated + one-by-one, each must carry its own prev_foot field, which is + also used to hold the offset this chunk has within its mmapped + region, which is needed to preserve alignment. Each mmapped + chunk is trailed by the first two fields of a fake next-chunk + for sake of usage checks. + + ---------------------- Overlaid data structures ----------------------- + + When chunks are not in use, they are treated as nodes of either + lists or trees. + + "Small" chunks are stored in circular doubly-linked lists, and look + like this: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space (may be 0 bytes long) . + . . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Larger chunks are kept in a form of bitwise digital trees (aka + tries) keyed on chunksizes. Because malloc_tree_chunks are only for + free chunks greater than 256 bytes, their size doesn't impose any + constraints on user chunk sizes. Each node looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to left child (child[0]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to right child (child[1]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to parent | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | bin index of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Each tree holding treenodes is a tree of unique chunk sizes. Chunks + of the same size are arranged in a circularly-linked list, with only + the oldest chunk (the next to be used, in our FIFO ordering) + actually in the tree. (Tree members are distinguished by a non-null + parent pointer.) If a chunk with the same size an an existing node + is inserted, it is linked off the existing node using pointers that + work in the same way as fd/bk pointers of small chunks. + + Each tree contains a power of 2 sized range of chunk sizes (the + smallest is 0x100 <= x < 0x180), which is is divided in half at each + tree level, with the chunks in the smaller half of the range (0x100 + <= x < 0x140 for the top nose) in the left subtree and the larger + half (0x140 <= x < 0x180) in the right subtree. This is, of course, + done by inspecting individual bits. + + Using these rules, each node's left subtree contains all smaller + sizes than its right subtree. However, the node at the root of each + subtree has no particular ordering relationship to either. (The + dividing line between the subtree sizes is based on trie relation.) + If we remove the last chunk of a given size from the interior of the + tree, we need to replace it with a leaf node. The tree ordering + rules permit a node to be replaced by any leaf below it. + + The smallest chunk in a tree (a common operation in a best-fit + allocator) can be found by walking a path to the leftmost leaf in + the tree. Unlike a usual binary tree, where we follow left child + pointers until we reach a null, here we follow the right child + pointer any time the left one is null, until we reach a leaf with + both child pointers null. The smallest chunk in the tree will be + somewhere along that path. + + The worst case number of steps to add, find, or remove a node is + bounded by the number of bits differentiating chunks within + bins. Under current bin calculations, this ranges from 6 up to 21 + (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case + is of course much better. + + ----------------------------- Segments -------------------------------- + + Each malloc space may include non-contiguous segments, held in a + list headed by an embedded malloc_segment record representing the + top-most space. Segments also include flags holding properties of + the space. Large chunks that are directly allocated by mmap are not + included in this list. They are instead independently created and + destroyed without otherwise keeping track of them. + + Segment management mainly comes into play for spaces allocated by + MMAP. Any call to MMAP might or might not return memory that is + adjacent to an existing segment. MORECORE normally contiguously + extends the current space, so this space is almost always adjacent, + which is simpler and faster to deal with. (This is why MORECORE is + used preferentially to MMAP when both are available -- see + sys_alloc.) When allocating using MMAP, we don't use any of the + hinting mechanisms (inconsistently) supported in various + implementations of unix mmap, or distinguish reserving from + committing memory. Instead, we just ask for space, and exploit + contiguity when we get it. It is probably possible to do + better than this on some systems, but no general scheme seems + to be significantly better. + + Management entails a simpler variant of the consolidation scheme + used for chunks to reduce fragmentation -- new adjacent memory is + normally prepended or appended to an existing segment. However, + there are limitations compared to chunk consolidation that mostly + reflect the fact that segment processing is relatively infrequent + (occurring only when getting memory from system) and that we + don't expect to have huge numbers of segments: + + * Segments are not indexed, so traversal requires linear scans. (It + would be possible to index these, but is not worth the extra + overhead and complexity for most programs on most platforms.) + * New segments are only appended to old ones when holding top-most + memory; if they cannot be prepended to others, they are held in + different segments. + + Except for the top-most segment of an mstate, each segment record + is kept at the tail of its segment. Segments are added by pushing + segment records onto the list headed by &mstate.seg for the + containing mstate. + + Segment flags control allocation/merge/deallocation policies: + * If EXTERN_BIT set, then we did not allocate this segment, + and so should not try to deallocate or merge with others. + (This currently holds only for the initial segment passed + into create_mspace_with_base.) + * If USE_MMAP_BIT set, the segment may be merged with + other surrounding mmapped segments and trimmed/de-allocated + using munmap. + * If neither bit is set, then the segment was obtained using + MORECORE so can be merged with surrounding MORECORE'd segments + and deallocated/trimmed using MORECORE with negative arguments. + + ---------------------------- malloc_state ----------------------------- + + A malloc_state holds all of the bookkeeping for a space. + The main fields are: + + Top + The topmost chunk of the currently active segment. Its size is + cached in topsize. The actual size of topmost space is + topsize+TOP_FOOT_SIZE, which includes space reserved for adding + fenceposts and segment records if necessary when getting more + space from the system. The size at which to autotrim top is + cached from mparams in trim_check, except that it is disabled if + an autotrim fails. + + Designated victim (dv) + This is the preferred chunk for servicing small requests that + don't have exact fits. It is normally the chunk split off most + recently to service another small request. Its size is cached in + dvsize. The link fields of this chunk are not maintained since it + is not kept in a bin. + + SmallBins + An array of bin headers for free chunks. These bins hold chunks + with sizes less than MIN_LARGE_SIZE bytes. Each bin contains + chunks of all the same size, spaced 8 bytes apart. To simplify + use in double-linked lists, each bin header acts as a malloc_chunk + pointing to the real first node, if it exists (else pointing to + itself). This avoids special-casing for headers. But to avoid + waste, we allocate only the fd/bk pointers of bins, and then use + repositioning tricks to treat these as the fields of a chunk. + + TreeBins + Treebins are pointers to the roots of trees holding a range of + sizes. There are 2 equally spaced treebins for each power of two + from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything + larger. + + Bin maps + There is one bit map for small bins ("smallmap") and one for + treebins ("treemap). Each bin sets its bit when non-empty, and + clears the bit when empty. Bit operations are then used to avoid + bin-by-bin searching -- nearly all "search" is done without ever + looking at bins that won't be selected. The bit maps + conservatively use 32 bits per map word, even if on 64bit system. + For a good description of some of the bit-based techniques used + here, see Henry S. Warren Jr's book "Hacker's Delight" (and + supplement at http://hackersdelight.org/). Many of these are + intended to reduce the branchiness of paths through malloc etc, as + well as to reduce the number of memory locations read or written. + + Segments + A list of segments headed by an embedded malloc_segment record + representing the initial space. + + Address check support + The least_addr field is the least address ever obtained from + MORECORE or MMAP. Attempted frees and reallocs of any address less + than this are trapped (unless INSECURE is defined). + + Magic tag + A cross-check field that should always hold same value as mparams.magic. + + Max allowed footprint + The maximum allowed bytes to allocate from system (zero means no limit) + + Flags + Bits recording whether to use MMAP, locks, or contiguous MORECORE + + Statistics + Each space keeps track of current and maximum system memory + obtained via MORECORE or MMAP. + + Trim support + Fields holding the amount of unused topmost memory that should trigger + trimming, and a counter to force periodic scanning to release unused + non-topmost segments. + + Locking + If USE_LOCKS is defined, the "mutex" lock is acquired and released + around every public call using this mspace. + + Extension support + A void* pointer and a size_t field that can be used to help implement + extensions to this malloc. + +//////////////////////////////////////////////////////////////////////////////// + * MSPACES If MSPACES is defined, then in addition to malloc, free, etc., this file also defines mspace_malloc, mspace_free, etc. These @@ -213,12 +579,12 @@ indicating its originating mspace, and frees are directed to their originating spaces. Normally, this requires use of locks. - ───────────────────────── Compile-time options ─────────────────────────── + ------------------------- Compile-time options --------------------------- Be careful in setting #define values for numerical constants of type size_t. On some systems, literal values are not automatically extended to size_t precision unless they are explicitly casted. You can also -use the symbolic values SIZE_MAX, SIZE_T_ONE, etc below. +use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. WIN32 default: defined if _WIN32 defined Defining WIN32 sets up defaults for MS environment and compilers. @@ -287,7 +653,7 @@ FOOTERS default: 0 information in the footers of allocated chunks. This adds space and time overhead. -TRUSTWORTHY default: 0 +INSECURE default: 0 If true, omit checks for usage errors and heap space overwrites. USE_DL_PREFIX default: NOT defined @@ -301,7 +667,7 @@ MALLOC_INSPECT_ALL default: NOT defined functions is otherwise restricted, you probably do not want to include them in secure implementations. -MALLOC_ABORT default: defined as abort() +ABORT default: defined as abort() Defines how to abort on failed checks. On most systems, a failed check cannot die with an "assert" or even print an informative message, because the underlying print routines in turn call malloc, @@ -389,6 +755,10 @@ HAVE_MMAP default: 1 (true) able to unmap memory that may have be allocated using multiple calls to MMAP, so long as they are adjacent. +HAVE_MREMAP default: 1 on linux, else 0 + If true realloc() uses mremap() to re-allocate large blocks and + extend or shrink allocation spaces. + MMAP_CLEARS default: 1 except on WINCE. True if mmap clears memory so calloc doesn't need to. This is true for standard unix mmap using /dev/zero and on WIN32 except for WINCE. @@ -408,6 +778,10 @@ malloc_getpagesize default: derive from system includes, or 4096. if WIN32, where page size is determined using getSystemInfo during initialization. +USE_DEV_RANDOM default: 0 (i.e., not used) + Causes malloc to use /dev/random to initialize secure magic seed for + stamping footers. Otherwise, the current time is used. + NO_MALLINFO default: 0 If defined, don't compile "mallinfo". This can be a simple way of dealing with mismatches between system declarations and @@ -466,7 +840,7 @@ DEFAULT_TRIM_THRESHOLD default: 2MB and released in ways that can reuse each other's storage, perhaps mixed with phases where there are no such chunks at all. The trim value must be greater than page size to have any useful effect. To - disable trimming completely, you can set to SIZE_MAX. Note that the trick + disable trimming completely, you can set to MAX_SIZE_T. Note that the trick some people use of mallocing a huge space and then freeing it at program startup, in an attempt to reserve system memory, doesn't have the intended effect under automatic trimming, since that memory @@ -494,7 +868,7 @@ DEFAULT_MMAP_THRESHOLD default: 256K nearly always outweigh disadvantages for "large" chunks, but the value of "large" may vary across systems. The default is an empirically derived value that works well in most systems. You can - disable mmap by setting to SIZE_MAX. + disable mmap by setting to MAX_SIZE_T. MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP The number of consolidated frees between checks to release @@ -507,13 +881,100 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP consolidation. The best value for this parameter is a compromise between slowing down frees with relatively costly checks that rarely trigger versus holding on to unused memory. To effectively - disable, set to SIZE_MAX. This may lead to a very slight speed + disable, set to MAX_SIZE_T. This may lead to a very slight speed improvement at the expense of carrying around more memory. -──────────────────────────────────────────────────────────────────────────────── + Guidelines for creating a custom version of MORECORE: + * For best performance, MORECORE should allocate in multiples of pagesize. + * MORECORE may allocate more memory than requested. (Or even less, + but this will usually result in a malloc failure.) + * MORECORE must not allocate memory when given argument zero, but + instead return one past the end address of memory from previous + nonzero call. + * For best performance, consecutive calls to MORECORE with positive + arguments should return increasing addresses, indicating that + space has been contiguously extended. + * Even though consecutive calls to MORECORE need not return contiguous + addresses, it must be OK for malloc'ed chunks to span multiple + regions in those cases where they do happen to be contiguous. + * MORECORE need not handle negative arguments -- it may instead + just return MFAIL when given negative arguments. + Negative arguments are always multiples of pagesize. MORECORE + must not misinterpret negative args as large positive unsigned + args. You can suppress all such calls from even occurring by defining + MORECORE_CANNOT_TRIM, + + As an example alternative MORECORE, here is a custom allocator + kindly contributed for pre-OSX macOS. It uses virtually but not + necessarily physically contiguous non-paged memory (locked in, + present and won't get swapped out). You can use it by uncommenting + this section, adding some #includes, and setting up the appropriate + defines above: + + #define MORECORE osMoreCore + + There is also a shutdown routine that should somehow be called for + cleanup upon program exit. + + #define MAX_POOL_ENTRIES 100 + #define MINIMUM_MORECORE_SIZE (64 * 1024U) + static int next_os_pool; + void *our_os_pools[MAX_POOL_ENTRIES]; + + void *osMoreCore(int size) + { + void *ptr = 0; + static void *sbrk_top = 0; + + if (size > 0) + { + if (size < MINIMUM_MORECORE_SIZE) + size = MINIMUM_MORECORE_SIZE; + if (CurrentExecutionLevel() == kTaskLevel) + ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); + if (ptr == 0) + { + return (void *) MFAIL; + } + // save ptrs so they can be freed during cleanup + our_os_pools[next_os_pool] = ptr; + next_os_pool++; + ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); + sbrk_top = (char *) ptr + size; + return ptr; + } + else if (size < 0) + { + // we don't currently support shrink behavior + return (void *) MFAIL; + } + else + { + return sbrk_top; + } + } + + // cleanup any allocated memory pools + // called as last thing before shutting down driver + + void osCleanupMem(void) + { + void **ptr; + + for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) + if (*ptr) + { + PoolDeallocate(*ptr); + *ptr = 0; + } + } + +*/ + + +/* ----------------------------------------------------------------------- History: - v2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea * fix bad comparison in dlposix_memalign * don't reuse adjusted asize in sys_alloc @@ -521,7 +982,7 @@ History: * reduce compiler warnings -- thanks to all who reported/suggested these v2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee) - * Always perform unlink checks unless TRUSTWORTHY + * Always perform unlink checks unless INSECURE * Add posix_memalign. * Improve realloc to expand in more cases; expose realloc_in_place. Thanks to Peter Buhr for the suggestion. @@ -728,94 +1189,3 @@ History: Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) * Based loosely on libg++-1.2X malloc. (It retains some of the overall structure of old version, but most details differ.) - -/* ──────────────────── Alternative MORECORE functions ─────────────────── */ - -/* - Guidelines for creating a custom version of MORECORE: - - * For best performance, MORECORE should allocate in multiples of pagesize. - * MORECORE may allocate more memory than requested. (Or even less, - but this will usually result in a malloc failure.) - * MORECORE must not allocate memory when given argument zero, but - instead return one past the end address of memory from previous - nonzero call. - * For best performance, consecutive calls to MORECORE with positive - arguments should return increasing addresses, indicating that - space has been contiguously extended. - * Even though consecutive calls to MORECORE need not return contiguous - addresses, it must be OK for malloc'ed chunks to span multiple - regions in those cases where they do happen to be contiguous. - * MORECORE need not handle negative arguments -- it may instead - just return MFAIL when given negative arguments. - Negative arguments are always multiples of pagesize. MORECORE - must not misinterpret negative args as large positive unsigned - args. You can suppress all such calls from even occurring by defining - MORECORE_CANNOT_TRIM, - - As an example alternative MORECORE, here is a custom allocator - kindly contributed for pre-OSX macOS. It uses virtually but not - necessarily physically contiguous non-paged memory (locked in, - present and won't get swapped out). You can use it by uncommenting - this section, adding some #includes, and setting up the appropriate - defines above: - - #define MORECORE osMoreCore - - There is also a shutdown routine that should somehow be called for - cleanup upon program exit. - - #define MAX_POOL_ENTRIES 100 - #define MINIMUM_MORECORE_SIZE (64 * 1024U) - static int next_os_pool; - void *our_os_pools[MAX_POOL_ENTRIES]; - - void *osMoreCore(int size) - { - void *ptr = 0; - static void *sbrk_top = 0; - - if (size > 0) - { - if (size < MINIMUM_MORECORE_SIZE) - size = MINIMUM_MORECORE_SIZE; - if (CurrentExecutionLevel() == kTaskLevel) - ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); - if (ptr == 0) - { - return (void *) MFAIL; - } - // save ptrs so they can be freed during cleanup - our_os_pools[next_os_pool] = ptr; - next_os_pool++; - ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); - sbrk_top = (char *) ptr + size; - return ptr; - } - else if (size < 0) - { - // we don't currently support shrink behavior - return (void *) MFAIL; - } - else - { - return sbrk_top; - } - } - - // cleanup any allocated memory pools - // called as last thing before shutting down driver - - void osCleanupMem(void) - { - void **ptr; - - for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) - if (*ptr) - { - PoolDeallocate(*ptr); - *ptr = 0; - } - } - -*/ diff --git a/third_party/dlmalloc/README.cosmo b/third_party/dlmalloc/README.cosmo index 95e599734..d364ed7b6 100644 --- a/third_party/dlmalloc/README.cosmo +++ b/third_party/dlmalloc/README.cosmo @@ -1,21 +1,13 @@ -ORIGIN +DESCRIPTION - http://gee.cs.oswego.edu/ + malloc-2.8.6 + written by Doug Lea + +LICENSE + + http://creativecommons.org/publicdomain/zero/1.0/ LOCAL CHANGES - Numerous local changes were made while vendoring Doug Lee's original - dlmalloc sources. Those changes basically boil down to: - - 1. Fewer #ifdefs - 2. More modules (so linker can do a better job) - 3. Delete code we don't need (cf. Knight Capital) - 4. Readability / stylistic consistency - - Since we haven't made any genuine improvements to Doug Lee's legendary - allocator, we feel this folder faithfully presents his intended work, in - harmony with Cosmopolitan conventions. - - The only deleted code we're sure has compelling merit is the mspace - functionality. If we ever need memory pools, they might be more - appropriately vendored under //third_party/dlmalloc_mspace. + - Introduce __oom_hook() + - Favor pause (rather than sched_yield) for spin locks diff --git a/third_party/dlmalloc/bulk_free.c b/third_party/dlmalloc/bulk_free.c deleted file mode 100644 index 54fa98926..000000000 --- a/third_party/dlmalloc/bulk_free.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * Frees and clears (sets to NULL) each non-null pointer in the given - * array. This is twice as fast as freeing them one-by-one. If footers - * are used, pointers that have been allocated in different mspaces are - * not freed or cleared, and the count of all such pointers is returned. - * For large arrays of pointers with poor locality, it may be worthwhile - * to sort this array before calling bulk_free. - */ -size_t dlbulk_free(void *array[], size_t nelem) { - void **a, **b, *mem, **fence; - struct MallocChunk *p, *next; - size_t psize, newsize, unfreed; - /* - * Try to free all pointers in the given array. Note: this could be - * made faster, by delaying consolidation, at the price of disabling - * some user integrity checks, We still optimize some consolidations - * by combining adjacent chunks before freeing, which will occur often - * if allocated with ialloc or the array is sorted. - */ - unfreed = 0; - if (!PREACTION(g_dlmalloc)) { - a; - fence = &(array[nelem]); - for (a = array; a != fence; ++a) { - mem = *a; - if (mem != 0) { - p = mem2chunk(AddressDeathAction(mem)); - psize = chunksize(p); -#if FOOTERS - if (get_mstate_for(p) != g_dlmalloc) { - ++unfreed; - continue; - } -#endif - check_inuse_chunk(g_dlmalloc, p); - *a = 0; - if (RTCHECK(ok_address(g_dlmalloc, p) && ok_inuse(p))) { - b = a + 1; /* try to merge with next chunk */ - next = next_chunk(p); - if (b != fence && *b == chunk2mem(next)) { - newsize = chunksize(next) + psize; - set_inuse(g_dlmalloc, p, newsize); - *b = chunk2mem(p); - } else - dlmalloc_dispose_chunk(g_dlmalloc, p, psize); - } else { - CORRUPTION_ERROR_ACTION(g_dlmalloc); - break; - } - } - } - if (should_trim(g_dlmalloc, g_dlmalloc->topsize)) { - dlmalloc_sys_trim(g_dlmalloc, 0); - } - POSTACTION(g_dlmalloc); - } - return unfreed; -} diff --git a/third_party/dlmalloc/dlcalloc.c b/third_party/dlmalloc/dlcalloc.c deleted file mode 100644 index ea84df994..000000000 --- a/third_party/dlmalloc/dlcalloc.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "libc/str/str.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -void *dlcalloc(size_t n_elements, size_t elem_size) { - void *mem; - size_t req; - if (__builtin_mul_overflow(n_elements, elem_size, &req)) req = -1; - mem = dlmalloc(req); - if (mem && calloc_must_clear(mem2chunk(mem))) { - bzero(mem, req); - } - return mem; -} diff --git a/third_party/dlmalloc/dlindependent_calloc.c b/third_party/dlmalloc/dlindependent_calloc.c deleted file mode 100644 index a847335b0..000000000 --- a/third_party/dlmalloc/dlindependent_calloc.c +++ /dev/null @@ -1,227 +0,0 @@ -#include "libc/mem/mem.h" -#include "libc/str/str.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/* - Common support for independent_X routines, handling - all of the combinations that can result. - The opts arg has: - bit 0 set if all elements are same size (using sizes[0]) - bit 1 set if elements should be zeroed -*/ -static void **ialloc(mstate m, size_t n_elements, size_t *sizes, int opts, - void *chunks[]) { - size_t element_size; /* chunksize of each element, if all same */ - size_t contents_size; /* total size of elements */ - size_t array_size; /* request size of pointer array */ - void *mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size; /* remaining bytes while splitting */ - void **marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - flag_t was_enabled; /* to disable mmap */ - size_t size; - size_t i; - - ensure_initialization(); - /* compute array length, if needed */ - if (chunks != 0) { - if (n_elements == 0) return chunks; /* nothing to do */ - marray = chunks; - array_size = 0; - } else { - /* if empty req, must still return chunk representing empty array */ - if (n_elements == 0) return (void **)dlmalloc(0); - marray = 0; - array_size = request2size(n_elements * (sizeof(void *))); - } - - /* compute total element size */ - if (opts & 0x1) { /* all-same-size */ - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } else { /* add up all the sizes */ - element_size = 0; - contents_size = 0; - for (i = 0; i != n_elements; ++i) contents_size += request2size(sizes[i]); - } - - size = contents_size + array_size; - - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - mem = dlmalloc(size - CHUNK_OVERHEAD); - if (was_enabled) enable_mmap(m); - if (mem == 0) return 0; - - if (PREACTION(m)) return 0; - p = mem2chunk(mem); - remainder_size = chunksize(p); - - assert(!is_mmapped(p)); - - if (opts & 0x2) { /* optionally clear the elements */ - bzero((size_t *)mem, remainder_size - SIZE_T_SIZE - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if (marray == 0) { - size_t array_chunk_size; - array_chunk = chunk_plus_offset(p, contents_size); - array_chunk_size = remainder_size - contents_size; - marray = AddressBirthAction((void **)(chunk2mem(array_chunk))); - set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); - remainder_size = contents_size; - } - - /* split out elements */ - for (i = 0;; ++i) { - marray[i] = AddressBirthAction(chunk2mem(p)); - if (i != n_elements - 1) { - if (element_size != 0) - size = element_size; - else - size = request2size(sizes[i]); - remainder_size -= size; - set_size_and_pinuse_of_inuse_chunk(m, p, size); - p = chunk_plus_offset(p, size); - } else { /* the final element absorbs any overallocation slop */ - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - break; - } - } - -#ifdef DEBUG - if (marray != chunks) { - /* final element must have exactly exhausted chunk */ - if (element_size != 0) { - assert(remainder_size == element_size); - } else { - assert(remainder_size == request2size(sizes[i])); - } - check_inuse_chunk(m, mem2chunk(marray)); - } - for (i = 0; i != n_elements; ++i) { - check_inuse_chunk(m, mem2chunk(marray[i])); - } -#endif /* IsModeDbg() */ - - POSTACTION(m); - return marray; -} - -/** - * independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - * - * independent_calloc is similar to calloc, but instead of returning a - * single cleared space, it returns an array of pointers to n_elements - * independent elements that can hold contents of size elem_size, each - * of which starts out cleared, and can be independently freed, - * realloc'ed etc. The elements are guaranteed to be adjacently - * allocated (this is not guaranteed to occur with multiple callocs or - * mallocs), which may also improve cache locality in some applications. - * - * The "chunks" argument is optional (i.e., may be null, which is - * probably the most typical usage). If it is null, the returned array - * is itself dynamically allocated and should also be freed when it is - * no longer needed. Otherwise, the chunks array must be of at least - * n_elements in length. It is filled in with the pointers to the - * chunks. - * - * In either case, independent_calloc returns this pointer array, or - * null if the allocation failed. * If n_elements is zero and "chunks" - * is null, it returns a chunk representing an array with zero elements - * (which should be freed if not wanted). - * - * Each element must be freed when it is no longer needed. This can be - * done all at once using bulk_free. - * - * independent_calloc simplifies and speeds up implementations of many - * kinds of pools. * It may also be useful when constructing large data - * structures that initially have a fixed number of fixed-sized nodes, - * but the number is not known at compile time, and some of the nodes - * may later need to be freed. For example: - * - * struct Node { int item; struct Node* next; }; - * struct Node* build_list() { - * struct Node **pool; - * int n = read_number_of_nodes_needed(); - * if (n <= 0) return 0; - * pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - * if (pool == 0) __die(); - * // organize into a linked list... - * struct Node* first = pool[0]; - * for (i = 0; i < n-1; ++i) - * pool[i]->next = pool[i+1]; - * free(pool); * // Can now free the array (or not, if it is needed later) - * return first; - * } - */ -void **dlindependent_calloc(size_t n_elements, size_t elem_size, - void *chunks[]) { - size_t sz = elem_size; /* serves as 1-element array */ - return ialloc(g_dlmalloc, n_elements, &sz, 3, chunks); -} - -/** - * independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - * - * independent_comalloc allocates, all at once, a set of n_elements - * chunks with sizes indicated in the "sizes" array. It returns an array - * of pointers to these elements, each of which can be independently - * freed, realloc'ed etc. The elements are guaranteed to be adjacently - * allocated (this is not guaranteed to occur with multiple callocs or - * mallocs), which may also improve cache locality in some applications. - * - * The "chunks" argument is optional (i.e., may be null). If it is null - * the returned array is itself dynamically allocated and should also - * be freed when it is no longer needed. Otherwise, the chunks array - * must be of at least n_elements in length. It is filled in with the - * pointers to the chunks. - * - * In either case, independent_comalloc returns this pointer array, or - * null if the allocation failed. If n_elements is zero and chunks is - * null, it returns a chunk representing an array with zero elements - * (which should be freed if not wanted). - * - * Each element must be freed when it is no longer needed. This can be - * done all at once using bulk_free. - * - * independent_comallac differs from independent_calloc in that each - * element may have a different size, and also that it does not - * automatically clear elements. - * - * independent_comalloc can be used to speed up allocation in cases - * where several structs or objects must always be allocated at the - * same time. For example: - * - * struct Head { ... } - * struct Foot { ... } - * void send_message(char* msg) { - * int msglen = strlen(msg); - * size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - * void* chunks[3]; - * if (independent_comalloc(3, sizes, chunks) == 0) __die(); - * struct Head* head = (struct Head*)(chunks[0]); - * char* body = (char*)(chunks[1]); - * struct Foot* foot = (struct Foot*)(chunks[2]); - * // ... - * } - * - * In general though, independent_comalloc is worth using only for - * larger values of n_elements. For small values, you probably won't - * detect enough difference from series of malloc calls to bother. - * - * Overuse of independent_comalloc can increase overall memory usage, - * since it cannot reuse existing noncontiguous small chunks that might - * be available for some of the elements. - */ -void **dlindependent_comalloc(size_t n_elements, size_t sizes[], - void *chunks[]) { - return ialloc(g_dlmalloc, n_elements, sizes, 0, chunks); -} diff --git a/third_party/dlmalloc/dlmalloc-debug.c b/third_party/dlmalloc/dlmalloc-debug.c deleted file mode 100644 index bd4209506..000000000 --- a/third_party/dlmalloc/dlmalloc-debug.c +++ /dev/null @@ -1,247 +0,0 @@ -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/* Check properties of any chunk, whether free, inuse, mmapped etc */ -forceinline void do_check_any_chunk(mstate m, mchunkptr p) { - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); -} - -/* Check properties of top chunk */ -void do_check_top_chunk(mstate m, mchunkptr p) { - msegmentptr sp = segment_holding(m, (char*)p); - size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ - assert(sp != 0); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(sz == m->topsize); - assert(sz > 0); - assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); - assert(pinuse(p)); - assert(!pinuse(chunk_plus_offset(p, sz))); -} - -/* Check properties of (inuse) mmapped chunks */ -void do_check_mmapped_chunk(mstate m, mchunkptr p) { - size_t sz = chunksize(p); - size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); - assert(is_mmapped(p)); - assert(use_mmap(m)); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(!is_small(sz)); - assert((len & (g_mparams.page_size - SIZE_T_ONE)) == 0); - assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); - assert(chunk_plus_offset(p, sz + SIZE_T_SIZE)->head == 0); -} - -/* Check properties of inuse chunks */ -void do_check_inuse_chunk(mstate m, mchunkptr p) { - do_check_any_chunk(m, p); - assert(is_inuse(p)); - assert(next_pinuse(p)); - /* If not pinuse and not mmapped, previous chunk has OK offset */ - assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); - if (is_mmapped(p)) do_check_mmapped_chunk(m, p); -} - -/* Check properties of free chunks */ -void do_check_free_chunk(mstate m, mchunkptr p) { - size_t sz = chunksize(p); - mchunkptr next = chunk_plus_offset(p, sz); - do_check_any_chunk(m, p); - assert(!is_inuse(p)); - assert(!next_pinuse(p)); - assert(!is_mmapped(p)); - if (p != m->dv && p != m->top) { - if (sz >= MIN_CHUNK_SIZE) { - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(is_aligned(chunk2mem(p))); - assert(next->prev_foot == sz); - assert(pinuse(p)); - assert(next == m->top || is_inuse(next)); - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } else /* markers are always of size SIZE_T_SIZE */ - assert(sz == SIZE_T_SIZE); - } -} - -/* Check properties of malloced chunks at the point they are malloced */ -void do_check_malloced_chunk(mstate m, void* mem, size_t s) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - size_t sz = p->head & ~INUSE_BITS; - do_check_inuse_chunk(m, p); - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(sz >= MIN_CHUNK_SIZE); - assert(sz >= s); - /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ - assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); - } -} - -/* Check a tree and its subtrees. */ -static void do_check_tree(mstate m, tchunkptr t) { - tchunkptr head = 0; - tchunkptr u = t; - bindex_t tindex = t->index; - size_t tsize = chunksize(t); - bindex_t idx; - compute_tree_index(tsize, idx); - assert(tindex == idx); - assert(tsize >= MIN_LARGE_SIZE); - assert(tsize >= minsize_for_tree_index(idx)); - assert((idx == NTREEBINS - 1) || (tsize < minsize_for_tree_index((idx + 1)))); - - do { /* traverse through chain of same-sized nodes */ - do_check_any_chunk(m, ((mchunkptr)u)); - assert(u->index == tindex); - assert(chunksize(u) == tsize); - assert(!is_inuse(u)); - assert(!next_pinuse(u)); - assert(u->fd->bk == u); - assert(u->bk->fd == u); - if (u->parent == 0) { - assert(u->child[0] == 0); - assert(u->child[1] == 0); - } else { - assert(head == 0); /* only one node on chain has parent */ - head = u; - assert(u->parent != u); - assert(u->parent->child[0] == u || u->parent->child[1] == u || - *((tbinptr*)(u->parent)) == u); - if (u->child[0] != 0) { - assert(u->child[0]->parent == u); - assert(u->child[0] != u); - do_check_tree(m, u->child[0]); - } - if (u->child[1] != 0) { - assert(u->child[1]->parent == u); - assert(u->child[1] != u); - do_check_tree(m, u->child[1]); - } - if (u->child[0] != 0 && u->child[1] != 0) { - assert(chunksize(u->child[0]) < chunksize(u->child[1])); - } - } - u = u->fd; - } while (u != t); - assert(head != 0); -} - -/* Check all the chunks in a treebin. */ -static void do_check_treebin(mstate m, bindex_t i) { - tbinptr* tb = treebin_at(m, i); - tchunkptr t = *tb; - int empty = (m->treemap & (1U << i)) == 0; - if (t == 0) assert(empty); - if (!empty) do_check_tree(m, t); -} - -/* Check all the chunks in a smallbin. */ -static void do_check_smallbin(mstate m, bindex_t i) { - sbinptr b = smallbin_at(m, i); - mchunkptr p = b->bk; - unsigned int empty = (m->smallmap & (1U << i)) == 0; - if (p == b) assert(empty); - if (!empty) { - for (; p != b; p = p->bk) { - size_t size = chunksize(p); - mchunkptr q; - /* each chunk claims to be free */ - do_check_free_chunk(m, p); - /* chunk belongs in bin */ - assert(small_index(size) == i); - assert(p->bk == b || chunksize(p->bk) == chunksize(p)); - /* chunk is followed by an inuse chunk */ - q = next_chunk(p); - if (q->head != FENCEPOST_HEAD) do_check_inuse_chunk(m, q); - } - } -} - -/* Find x in a bin. Used in other check functions. */ -static int bin_find(mstate m, mchunkptr x) { - size_t size = chunksize(x); - if (is_small(size)) { - bindex_t sidx = small_index(size); - sbinptr b = smallbin_at(m, sidx); - if (smallmap_is_marked(m, sidx)) { - mchunkptr p = b; - do { - if (p == x) return 1; - } while ((p = p->fd) != b); - } - } else { - bindex_t tidx; - compute_tree_index(size, tidx); - if (treemap_is_marked(m, tidx)) { - tchunkptr t = *treebin_at(m, tidx); - size_t sizebits = size << leftshift_for_tree_index(tidx); - while (t != 0 && chunksize(t) != size) { - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - sizebits <<= 1; - } - if (t != 0) { - tchunkptr u = t; - do { - if (u == (tchunkptr)x) return 1; - } while ((u = u->fd) != t); - } - } - } - return 0; -} - -/* Traverse each chunk and check it; return total */ -static size_t traverse_and_check(mstate m) { - size_t sum = 0; - if (is_initialized(m)) { - msegmentptr s = &m->seg; - sum += m->topsize + TOP_FOOT_SIZE; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - mchunkptr lastq = 0; - assert(pinuse(q)); - while (segment_holds(s, q) && q != m->top && q->head != FENCEPOST_HEAD) { - sum += chunksize(q); - if (is_inuse(q)) { - assert(!bin_find(m, q)); - do_check_inuse_chunk(m, q); - } else { - assert(q == m->dv || bin_find(m, q)); - assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ - do_check_free_chunk(m, q); - } - lastq = q; - q = next_chunk(q); - } - s = s->next; - } - } - return sum; -} - -/* Check all properties of MallocState. */ -void do_check_malloc_state(mstate m) { - bindex_t i; - size_t total; - /* check bins */ - for (i = 0; i < NSMALLBINS; ++i) do_check_smallbin(m, i); - for (i = 0; i < NTREEBINS; ++i) do_check_treebin(m, i); - if (m->dvsize != 0) { /* check dv chunk */ - do_check_any_chunk(m, m->dv); - assert(m->dvsize == chunksize(m->dv)); - assert(m->dvsize >= MIN_CHUNK_SIZE); - assert(bin_find(m, m->dv) == 0); - } - if (m->top != 0) { /* check top chunk */ - do_check_top_chunk(m, m->top); - /*assert(m->topsize == chunksize(m->top)); redundant */ - assert(m->topsize > 0); - assert(bin_find(m, m->top) == 0); - } - total = traverse_and_check(m); - assert(total <= m->footprint); - assert(m->footprint <= m->max_footprint); -} diff --git a/third_party/dlmalloc/dlmalloc.c b/third_party/dlmalloc/dlmalloc.c deleted file mode 100644 index c77830922..000000000 --- a/third_party/dlmalloc/dlmalloc.c +++ /dev/null @@ -1,959 +0,0 @@ -#include "libc/assert.h" -#include "libc/bits/initializer.internal.h" -#include "libc/bits/safemacros.internal.h" -#include "libc/bits/weaken.h" -#include "libc/calls/calls.h" -#include "libc/calls/internal.h" -#include "libc/calls/struct/sysinfo.h" -#include "libc/dce.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/asan.internal.h" -#include "libc/limits.h" -#include "libc/log/backtrace.internal.h" -#include "libc/log/libfatal.internal.h" -#include "libc/macros.internal.h" -#include "libc/mem/mem.h" -#include "libc/nt/systeminfo.h" -#include "libc/runtime/memtrack.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/fileno.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/prot.h" -#include "libc/sysv/errfuns.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -STATIC_YOINK("_init_dlmalloc"); - -#define OOM_WARNING "warning: running out of physical memory\n" -#define is_global(M) ((M) == g_dlmalloc) - -hidden struct MallocState g_dlmalloc[1]; -hidden struct MallocParams g_mparams; - -/** - * Acquires more system memory for dlmalloc. - * - * Each time dlmalloc needs 64kb, we ask for a 2mb page directory. The - * empty space could help with buffer overflow detection; mremap() has - * plenty of room to grow; and debuggability is greatly enhanced. This - * should have less page table overhead than in security blanket mode. - * Note that contiguous allocations are what Doug Lea recommends. - */ -static void *dlmalloc_requires_more_vespene_gas(size_t size) { - char *p; - if ((p = mapanon(size)) != MAP_FAILED) { - if (weaken(__asan_poison)) { - weaken(__asan_poison)((uintptr_t)p, size, kAsanHeapFree); - } - } - return p; -} - -/* ─────────────────────────── mspace management ─────────────────────────── */ - -/* Initialize top chunk and its size */ -static void dlmalloc_init_top(struct MallocState *m, mchunkptr p, - size_t psize) { - /* Ensure alignment */ - size_t offset = align_offset(chunk2mem(p)); - p = (mchunkptr)((char *)p + offset); - psize -= offset; - m->top = p; - m->topsize = psize; - p->head = psize | PINUSE_BIT; - /* set size of fake trailing chunk holding overhead space only once */ - chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; - m->trim_check = g_mparams.trim_threshold; /* reset on each update */ -} - -/* Initialize bins for a new mstate that is otherwise zeroed out */ -static void init_bins(struct MallocState *m) { - /* Establish circular links for smallbins */ - bindex_t i; - for (i = 0; i < NSMALLBINS; ++i) { - sbinptr bin = smallbin_at(m, i); - bin->fd = bin->bk = bin; - } -} - -/* Allocate chunk and prepend remainder with chunk in successor base. */ -static void *dlmalloc_prepend_alloc(struct MallocState *m, char *newbase, - char *oldbase, size_t nb) { - mchunkptr p = align_as_chunk(newbase); - mchunkptr oldfirst = align_as_chunk(oldbase); - size_t psize = (char *)oldfirst - (char *)p; - mchunkptr q = chunk_plus_offset(p, nb); - size_t qsize = psize - nb; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - assert((char *)oldfirst > (char *)q); - assert(pinuse(oldfirst)); - assert(qsize >= MIN_CHUNK_SIZE); - /* consolidate remainder with first chunk of old base */ - if (oldfirst == m->top) { - size_t tsize = m->topsize += qsize; - m->top = q; - q->head = tsize | PINUSE_BIT; - check_top_chunk(m, q); - } else if (oldfirst == m->dv) { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } else { - if (!is_inuse(oldfirst)) { - size_t nsize = chunksize(oldfirst); - unlink_chunk(m, oldfirst, nsize); - oldfirst = chunk_plus_offset(oldfirst, nsize); - qsize += nsize; - } - set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); - check_free_chunk(m, q); - } - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); -} - -/* Add a segment to hold a new noncontiguous region */ -static void dlmalloc_add_segment(struct MallocState *m, char *tbase, - size_t tsize, flag_t mmapped) { - /* Determine locations and sizes of segment, fenceposts, old top */ - char *old_top = (char *)m->top; - msegmentptr oldsp = segment_holding(m, old_top); - char *old_end = oldsp->base + oldsp->size; - size_t ssize = pad_request(sizeof(struct MallocSegment)); - char *rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - size_t offset = align_offset(chunk2mem(rawsp)); - char *asp = rawsp + offset; - char *csp = (asp < (old_top + MIN_CHUNK_SIZE)) ? old_top : asp; - mchunkptr sp = (mchunkptr)csp; - msegmentptr ss = (msegmentptr)(chunk2mem(sp)); - mchunkptr tnext = chunk_plus_offset(sp, ssize); - mchunkptr p = tnext; - int nfences = 0; - /* reset top to new space */ - dlmalloc_init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - /* Set up segment record */ - assert(is_aligned(ss)); - set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); - *ss = m->seg; /* Push current record */ - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmapped; - m->seg.next = ss; - /* Insert trailing fenceposts */ - for (;;) { - mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); - p->head = FENCEPOST_HEAD; - ++nfences; - if ((char *)(&(nextp->head)) < old_end) - p = nextp; - else - break; - } - assert(nfences >= 2); - /* Insert the rest of old top into a bin as an ordinary free chunk */ - if (csp != old_top) { - mchunkptr q = (mchunkptr)old_top; - size_t psize = csp - old_top; - mchunkptr tn = chunk_plus_offset(q, psize); - set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); - } - check_top_chunk(m, m->top); -} - -/* ─────────────────────────── system integration ─────────────────────────── */ - -/* Return true if segment contains a segment link */ -dontinline int has_segment_link(struct MallocState *m, msegmentptr ss) { - msegmentptr sp; - assert(m); - sp = &m->seg; - for (;;) { - if ((char *)sp >= ss->base && (char *)sp < ss->base + ss->size) return 1; - if ((sp = sp->next) == 0) return 0; - } -} - -/* - Directly mmapped chunks are set up with an offset to the start of - the mmapped region stored in the prev_foot field of the chunk. This - allows reconstruction of the required argument to MUNMAP when freed, - and also allows adjustment of the returned chunk to meet alignment - requirements (especially in memalign). -*/ - -/* For sys_alloc, enough padding to ensure can malloc request on success */ -#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) - -/* Malloc using mmap */ -static void *mmap_alloc(struct MallocState *m, size_t nb) { - size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - if (m->footprint_limit != 0) { - size_t fp = m->footprint + mmsize; - if (fp <= m->footprint || fp > m->footprint_limit) return 0; - } - if (mmsize > nb) { /* Check for wrap around 0 */ - char *mm = (char *)(dlmalloc_requires_more_vespene_gas(mmsize)); - if (mm != CMFAIL) { - size_t offset = align_offset(chunk2mem(mm)); - size_t psize = mmsize - offset - MMAP_FOOT_PAD; - mchunkptr p = (mchunkptr)(mm + offset); - p->prev_foot = offset; - p->head = psize; - mark_inuse_foot(m, p, psize); - chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(p, psize + SIZE_T_SIZE)->head = 0; - if (m->least_addr == 0 || mm < m->least_addr) m->least_addr = mm; - if ((m->footprint += mmsize) > m->max_footprint) - m->max_footprint = m->footprint; - assert(is_aligned(chunk2mem(p))); - check_mmapped_chunk(m, p); - return chunk2mem(p); - } - } - return 0; -} - -/** - * Gets memory from system. - */ -static void *dlmalloc_sys_alloc(struct MallocState *m, size_t nb) { - char *tbase = CMFAIL; - size_t tsize = 0; - flag_t mmap_flag = 0; - size_t asize; /* allocation size */ - - ensure_initialization(); - - /* Directly map large chunks, but only if already initialized */ - if (use_mmap(m) && nb >= g_mparams.mmap_threshold && m->topsize != 0) { - void *mem = mmap_alloc(m, nb); - if (mem != 0) return mem; - } - - asize = granularity_align(nb + SYS_ALLOC_PADDING); - if (asize <= nb) return 0; /* wraparound */ - if (m->footprint_limit != 0) { - size_t fp = m->footprint + asize; - if (fp <= m->footprint || fp > m->footprint_limit) return 0; - } - - if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ - char *mp = (char *)(dlmalloc_requires_more_vespene_gas(asize)); - if (mp != CMFAIL) { - tbase = mp; - tsize = asize; - mmap_flag = USE_MMAP_BIT; - } - } - - if (tbase != CMFAIL) { - if ((m->footprint += tsize) > m->max_footprint) - m->max_footprint = m->footprint; - - if (!is_initialized(m)) { /* first-time initialization */ - if (m->least_addr == 0 || tbase < m->least_addr) m->least_addr = tbase; - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmap_flag; - m->magic = g_mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - init_bins(m); - if (is_global(m)) { - dlmalloc_init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - } else { - /* Offset top by embedded MallocState */ - mchunkptr mn = next_chunk(mem2chunk(m)); - dlmalloc_init_top( - m, mn, (size_t)((tbase + tsize) - (char *)mn) - TOP_FOOT_SIZE); - } - } - - else { - /* Try to merge with an existing segment */ - msegmentptr sp = &m->seg; - /* Only consider most recent segment if traversal suppressed */ - while (sp != 0 && tbase != sp->base + sp->size) - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - if (sp != 0 && !is_extern_segment(sp) && - (sp->sflags & USE_MMAP_BIT) == mmap_flag && - segment_holds(sp, m->top)) { /* append */ - sp->size += tsize; - dlmalloc_init_top(m, m->top, m->topsize + tsize); - } else { - if (tbase < m->least_addr) m->least_addr = tbase; - sp = &m->seg; - while (sp != 0 && sp->base != tbase + tsize) - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - if (sp != 0 && !is_extern_segment(sp) && - (sp->sflags & USE_MMAP_BIT) == mmap_flag) { - char *oldbase = sp->base; - sp->base = tbase; - sp->size += tsize; - return dlmalloc_prepend_alloc(m, tbase, oldbase, nb); - } else - dlmalloc_add_segment(m, tbase, tsize, mmap_flag); - } - } - - if (nb < m->topsize) { /* Allocate from new or extended top space */ - size_t rsize = m->topsize -= nb; - mchunkptr p = m->top; - mchunkptr r = m->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - check_top_chunk(m, m->top); - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); - } - } - - enomem(); - return 0; -} - -/* Unmap and unlink any mmapped segments that don't contain used chunks */ -static size_t dlmalloc_release_unused_segments(struct MallocState *m) { - size_t released = 0; - int nsegs = 0; - msegmentptr pred = &m->seg; - msegmentptr sp = pred->next; - while (sp != 0) { - char *base = sp->base; - size_t size = sp->size; - msegmentptr next = sp->next; - ++nsegs; - if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { - mchunkptr p = align_as_chunk(base); - size_t psize = chunksize(p); - /* Can unmap if first chunk holds entire segment and not pinned */ - if (!is_inuse(p) && (char *)p + psize >= base + size - TOP_FOOT_SIZE) { - tchunkptr tp = (tchunkptr)p; - assert(segment_holds(sp, (char *)sp)); - if (p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } else { - unlink_large_chunk(m, tp); - } - if (munmap(base, size) == 0) { - released += size; - m->footprint -= size; - /* unlink obsoleted record */ - sp = pred; - sp->next = next; - } else { /* back out if cannot unmap */ - insert_large_chunk(m, tp, psize); - } - } - } - if (NO_SEGMENT_TRAVERSAL) { /* scan only first segment */ - break; - } - pred = sp; - sp = next; - } - /* Reset check counter */ - m->release_checks = (((size_t)nsegs > (size_t)MAX_RELEASE_CHECK_RATE) - ? (size_t)nsegs - : (size_t)MAX_RELEASE_CHECK_RATE); - return released; -} - -int dlmalloc_sys_trim(struct MallocState *m, size_t pad) { - size_t released = 0; - ensure_initialization(); - if (pad < MAX_REQUEST && is_initialized(m)) { - pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ - if (m->topsize > pad) { - /* Shrink top space in granularity-size units, keeping at least one */ - size_t unit = g_mparams.granularity; - size_t extra = - ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - SIZE_T_ONE) * unit; - msegmentptr sp = segment_holding(m, (char *)m->top); - if (!is_extern_segment(sp)) { - if (is_mmapped_segment(sp)) { - if (HAVE_MMAP && sp->size >= extra && - !has_segment_link(m, sp)) { /* can't shrink if pinned */ - size_t newsize = sp->size - extra; - (void)newsize; /* placate people compiling -Wunused-variable */ - /* Prefer mremap, fall back to munmap */ - if ((mremap(sp->base, sp->size, newsize, 0, 0) != MAP_FAILED) || - (munmap(sp->base + newsize, extra) == 0)) { - released = extra; - } - } - } - } - if (released != 0) { - sp->size -= released; - m->footprint -= released; - dlmalloc_init_top(m, m->top, m->topsize - released); - check_top_chunk(m, m->top); - } - } - /* Unmap any unused mmapped segments */ - if (HAVE_MMAP) released += dlmalloc_release_unused_segments(m); - /* On failure, disable autotrim to avoid repeated failed future calls */ - if (released == 0 && m->topsize > m->trim_check) m->trim_check = SIZE_MAX; - } - return (released != 0) ? 1 : 0; -} - -/* ──────────────────────────── setting mparams ────────────────────────── */ - -#if LOCK_AT_FORK -static void pre_fork(void) { - ACQUIRE_LOCK(&(g_dlmalloc)->mutex); -} -static void post_fork_parent(void) { - RELEASE_LOCK(&(g_dlmalloc)->mutex); -} -static void post_fork_child(void) { - INITIAL_LOCK(&(g_dlmalloc)->mutex); -} -#endif /* LOCK_AT_FORK */ - -/* ───────────────────────────── statistics ────────────────────────────── */ - -/* Consolidate and bin a chunk. Differs from exported versions - of free mainly in that the chunk need not be marked as inuse. -*/ -void dlmalloc_dispose_chunk(struct MallocState *m, mchunkptr p, size_t psize) { - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - mchunkptr prev; - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) { - psize += prevsize + MMAP_FOOT_PAD; - if (munmap((char *)p - prevsize, psize) == 0) m->footprint -= psize; - return; - } - prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */ - if (p != m->dv) { - unlink_chunk(m, p, prevsize); - } else if ((next->head & INUSE_BITS) == INUSE_BITS) { - m->dvsize = psize; - set_free_with_pinuse(p, psize, next); - return; - } - } else { - CORRUPTION_ERROR_ACTION(m); - return; - } - } - if (RTCHECK(ok_address(m, next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == m->top) { - size_t tsize = m->topsize += psize; - m->top = p; - p->head = tsize | PINUSE_BIT; - if (p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } - return; - } else if (next == m->dv) { - size_t dsize = m->dvsize += psize; - m->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - return; - } else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(m, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == m->dv) { - m->dvsize = psize; - return; - } - } - } else { - set_free_with_pinuse(p, psize, next); - } - insert_chunk(m, p, psize); - } else { - CORRUPTION_ERROR_ACTION(m); - } -} - -/* ──────────────────────────── malloc ─────────────────────────── */ - -/* allocate a small request from the best fitting chunk in a treebin */ -static void *tmalloc_small(struct MallocState *m, size_t nb) { - tchunkptr t, v; - size_t rsize; - bindex_t i; - binmap_t leastbit = least_bit(m->treemap); - compute_bit2idx(leastbit, i); - v = t = *treebin_at(m, i); - rsize = chunksize(t) - nb; - while ((t = leftmost_child(t)) != 0) { - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - } - if (RTCHECK(ok_address(m, v))) { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); - } - return chunk2mem(v); - } - } - CORRUPTION_ERROR_ACTION(m); - return 0; -} - -/* allocate a large request from the best fitting chunk in a treebin */ -static void *tmalloc_large(struct MallocState *m, size_t nb) { - tchunkptr v = 0; - size_t rsize = -nb; /* Unsigned negation */ - tchunkptr t; - bindex_t idx; - compute_tree_index(nb, idx); - if ((t = *treebin_at(m, idx)) != 0) { - /* Traverse tree for this bin looking for node with size == nb */ - size_t sizebits = nb << leftshift_for_tree_index(idx); - tchunkptr rst = 0; /* The deepest untaken right subtree */ - for (;;) { - tchunkptr rt; - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - v = t; - if ((rsize = trem) == 0) break; - } - rt = t->child[1]; - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - if (rt != 0 && rt != t) rst = rt; - if (t == 0) { - t = rst; /* set t to least subtree holding sizes > nb */ - break; - } - sizebits <<= 1; - } - } - if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ - binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; - if (leftbits != 0) { - bindex_t i; - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - t = *treebin_at(m, i); - } - } - while (t != 0) { /* find smallest of tree or subtree */ - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - t = leftmost_child(t); - } - /* If dv is a better fit, return 0 so malloc will use it */ - if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { - if (RTCHECK(ok_address(m, v))) { /* split */ - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); - } - return chunk2mem(v); - } - } - CORRUPTION_ERROR_ACTION(m); - } - return 0; -} - -void *dlmalloc_impl(size_t bytes, bool takeaction) { - /* - Basic algorithm: - If a small request (< 256 bytes minus per-chunk overhead): - 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) - 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. - 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. - 4. If it is big enough, use the top chunk. - 5. If available, get memory from system and use it - Otherwise, for a large request: - 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. - 2. If better fitting than any binned chunk, use the dv chunk. - 3. If it is big enough, use the top chunk. - 4. If request size >= mmap threshold, try to directly mmap this chunk. - 5. If available, get memory from system and use it - - The ugly goto's here ensure that postaction occurs along all paths. - */ - -#if USE_LOCKS - ensure_initialization(); /* initialize in sys_alloc if not using locks */ -#endif - - if (!PREACTION(g_dlmalloc)) { - void *mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = g_dlmalloc->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(g_dlmalloc, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(g_dlmalloc, b, p, idx); - set_inuse_and_pinuse(g_dlmalloc, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(g_dlmalloc, mem, nb); - goto postaction; - } - - else if (nb > g_dlmalloc->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(g_dlmalloc, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(g_dlmalloc, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(g_dlmalloc, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(g_dlmalloc, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(g_dlmalloc, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(g_dlmalloc, mem, nb); - goto postaction; - } - - else if (g_dlmalloc->treemap != 0 && - (mem = tmalloc_small(g_dlmalloc, nb)) != 0) { - check_malloced_chunk(g_dlmalloc, mem, nb); - goto postaction; - } - } - } else if (bytes >= MAX_REQUEST) { - nb = SIZE_MAX; /* Too big to allocate. Force failure (in sys alloc) */ - } else { - nb = pad_request(bytes); - if (g_dlmalloc->treemap != 0 && - (mem = tmalloc_large(g_dlmalloc, nb)) != 0) { - check_malloced_chunk(g_dlmalloc, mem, nb); - goto postaction; - } - } - - if (nb <= g_dlmalloc->dvsize) { - size_t rsize = g_dlmalloc->dvsize - nb; - mchunkptr p = g_dlmalloc->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = g_dlmalloc->dv = chunk_plus_offset(p, nb); - g_dlmalloc->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(g_dlmalloc, p, nb); - } else { /* exhaust dv */ - size_t dvs = g_dlmalloc->dvsize; - g_dlmalloc->dvsize = 0; - g_dlmalloc->dv = 0; - set_inuse_and_pinuse(g_dlmalloc, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(g_dlmalloc, mem, nb); - goto postaction; - } - - else if (nb < g_dlmalloc->topsize) { /* Split top */ - size_t rsize = g_dlmalloc->topsize -= nb; - mchunkptr p = g_dlmalloc->top; - mchunkptr r = g_dlmalloc->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(g_dlmalloc, p, nb); - mem = chunk2mem(p); - check_top_chunk(g_dlmalloc, g_dlmalloc->top); - check_malloced_chunk(g_dlmalloc, mem, nb); - goto postaction; - } - - mem = dlmalloc_sys_alloc(g_dlmalloc, nb); - - postaction: - POSTACTION(g_dlmalloc); - return takeaction ? AddressBirthAction(mem) : mem; - } - - return 0; -} - -void dlfree(void *mem) { - /* asan runtime depends on this function */ - /* - Consolidate freed chunks with preceeding or succeeding bordering - free chunks, if they exist, and then place in a bin. Intermixed - with special cases for top, dv, mmapped chunks, and usage errors. - */ - if (mem != 0) { - mem = AddressDeathAction(mem); - mchunkptr p = mem2chunk(mem); - -#if FOOTERS - struct MallocState *fm = get_mstate_for(p); - if (!ok_magic(fm)) { /* HELLO - * TRY #1: rm -rf o && make -j8 -O MODE=dbg - * TRY #2: gdb: p/x (long*)(p+(*(long*)(p-8)&~(1|2|3))) - * gdb: watch *0xDEADBEEF - */ - USAGE_ERROR_ACTION(fm, p); - return; - } -#else /* FOOTERS */ -#define fm g_dlmalloc -#endif /* FOOTERS */ - - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) { - psize += prevsize + MMAP_FOOT_PAD; - if (munmap((char *)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } else if ((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } else - goto erroraction; - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) { - dlmalloc_sys_trim(fm, 0); - } - goto postaction; - } else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } else { - set_free_with_pinuse(p, psize, next); - } - - if (is_small(psize)) { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } else { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) dlmalloc_release_unused_segments(fm); - } - goto postaction; - } - } - erroraction: - if (IsArenaFrame((intptr_t)p >> 16)) return; - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -#if !FOOTERS -#undef fm -#endif /* FOOTERS */ -} - -size_t dlmalloc_usable_size(const void *mem) { - /* asan runtime depends on this function */ - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (is_inuse(p)) return chunksize(p) - overhead_for(p); - } - return 0; -} - -textstartup void dlmalloc_init(void) { -#ifdef NEED_GLOBAL_LOCK_INIT - if (malloc_global_mutex_status <= 0) init_malloc_global_mutex(); -#endif - ACQUIRE_MALLOC_GLOBAL_LOCK(); - if (g_mparams.magic == 0) { - size_t magic; - size_t psize = PAGESIZE; - size_t gsize = DEFAULT_GRANULARITY; - /* Sanity-check configuration: - size_t must be unsigned and as wide as pointer type. - ints must be at least 4 bytes. - alignment must be at least 8. - Alignment, min chunk size, and page size must all be powers of 2. - */ - if ((sizeof(size_t) != sizeof(char *)) || (SIZE_MAX < MIN_CHUNK_SIZE) || - (sizeof(int) < 4) || (MALLOC_ALIGNMENT < (size_t)8U) || - ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT - SIZE_T_ONE)) != 0) || - ((MCHUNK_SIZE & (MCHUNK_SIZE - SIZE_T_ONE)) != 0) || - ((gsize & (gsize - SIZE_T_ONE)) != 0) || - ((psize & (psize - SIZE_T_ONE)) != 0)) - MALLOC_ABORT; - g_mparams.granularity = gsize; - g_mparams.page_size = psize; - g_mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; - g_mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; - g_mparams.default_mflags = - USE_LOCK_BIT | USE_MMAP_BIT | USE_NONCONTIGUOUS_BIT; - /* Set up lock for main malloc area */ - g_dlmalloc->mflags = g_mparams.default_mflags; - (void)INITIAL_LOCK(&g_dlmalloc->mutex); -#if LOCK_AT_FORK - pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child); -#endif - magic = kStartTsc; - magic |= (size_t)8U; /* ensure nonzero */ - magic &= ~(size_t)7U; /* improve chances of fault for bad values */ - /* Until memory modes commonly available, use volatile-write */ - (*(volatile size_t *)(&(g_mparams.magic))) = magic; - } - RELEASE_MALLOC_GLOBAL_LOCK(); -} - -void *dlmemalign_impl(struct MallocState *m, size_t al, size_t bytes) { - char *br, *pos, *mem = 0; - mchunkptr p, newp, remainder; - size_t nb, req, size, leadsize, newsize, remainder_size; - if (bytes < MAX_REQUEST - al) { - /* alignment is 32+ bytes rounded up to nearest two power */ - al = 2ul << bsrl(MAX(MIN_CHUNK_SIZE, al) - 1); - nb = request2size(bytes); - req = nb + al + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; - if ((mem = dlmalloc_impl(req, false))) { - p = mem2chunk(mem); - if (PREACTION(m)) return 0; - if ((((size_t)(mem)) & (al - 1))) { /* misaligned */ - /* - Find an aligned spot inside chunk. Since we need to give - back leading space in a chunk of at least MIN_CHUNK_SIZE, if - the first calculation places us at a spot with less than - MIN_CHUNK_SIZE leader, we can move to the next aligned spot. - We've allocated enough total room so that this is always - possible. - */ - br = (char *)mem2chunk(ROUNDUP((uintptr_t)mem, al)); - pos = (size_t)(br - (char *)(p)) >= MIN_CHUNK_SIZE ? br : br + al; - newp = (mchunkptr)pos; - leadsize = pos - (char *)(p); - newsize = chunksize(p) - leadsize; - if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ - newp->prev_foot = p->prev_foot + leadsize; - newp->head = newsize; - } else { /* Otherwise, give back leader, use the rest */ - set_inuse(m, newp, newsize); - set_inuse(m, p, leadsize); - dlmalloc_dispose_chunk(m, p, leadsize); - } - p = newp; - } - /* Give back spare room at the end */ - if (!is_mmapped(p)) { - size = chunksize(p); - if (size > nb + MIN_CHUNK_SIZE) { - remainder_size = size - nb; - remainder = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, remainder, remainder_size); - dlmalloc_dispose_chunk(m, remainder, remainder_size); - } - } - mem = chunk2mem(p); - assert(chunksize(p) >= nb); - assert(!((size_t)mem & (al - 1))); - check_inuse_chunk(m, p); - POSTACTION(m); - } - return AddressBirthAction(mem); - } else { - enomem(); - return 0; - } -} - -void *dlmalloc(size_t bytes) { - return dlmalloc_impl(bytes, true); -} - -void *dlmemalign(size_t alignment, size_t bytes) { - /* asan runtime depends on this function */ - if (alignment <= MALLOC_ALIGNMENT) { - return dlmalloc_impl(bytes, true); - } else { - return dlmemalign_impl(g_dlmalloc, alignment, bytes); - } -} diff --git a/third_party/dlmalloc/dlmalloc.greg.c b/third_party/dlmalloc/dlmalloc.greg.c new file mode 100644 index 000000000..6bc34ac80 --- /dev/null +++ b/third_party/dlmalloc/dlmalloc.greg.c @@ -0,0 +1,4387 @@ +#include "libc/nexgen32e/rdtsc.h" +#include "libc/dce.h" +#include "libc/assert.h" +#include "libc/rand/rand.h" +#include "libc/runtime/sysconf.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" +#include "libc/runtime/runtime.h" +#include "libc/errno.h" +#include "libc/errno.h" +#include "libc/stdio/stdio.h" +#include "libc/intrin/kprintf.h" +#include "third_party/dlmalloc/vespene.internal.h" +#include "libc/calls/calls.h" +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#include "libc/bits/weaken.h" +#include "libc/intrin/kprintf.h" +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" +// clang-format off + +#define FOOTERS 0 +#define MSPACES 0 + +#define HAVE_MMAP 1 +#define HAVE_MREMAP 0 +#define HAVE_MORECORE 0 +#define USE_LOCKS 1 +#define MORECORE_CONTIGUOUS 0 +#define MALLOC_INSPECT_ALL 1 + +#if IsTiny() +#define INSECURE 1 +#define PROCEED_ON_ERROR 1 +#define ABORT_ON_ASSERT_FAILURE 0 +#endif + +#if IsModeDbg() +#define DEBUG 1 +#endif + +#define LACKS_UNISTD_H +#define LACKS_FCNTL_H +#define LACKS_SYS_PARAM_H +#define LACKS_SYS_MMAN_H +#define LACKS_STRINGS_H +#define LACKS_STRING_H +#define LACKS_SYS_TYPES_H +#define LACKS_ERRNO_H +#define LACKS_STDLIB_H +#define LACKS_SCHED_H +#define LACKS_TIME_H + +/* Version identifier to allow people to support multiple versions */ +#ifndef DLMALLOC_VERSION +#define DLMALLOC_VERSION 20806 +#endif /* DLMALLOC_VERSION */ + +#ifndef DLMALLOC_EXPORT +#define DLMALLOC_EXPORT extern +#endif + +/* The maximum possible size_t value has all bits set */ +#define MAX_SIZE_T (~(size_t)0) + +#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */ +#define USE_LOCKS ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \ + (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0)) +#endif /* USE_LOCKS */ + +#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */ +#if ((defined(__GNUC__) && \ + ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \ + defined(__i386__) || defined(__x86_64__))) || \ + (defined(_MSC_VER) && _MSC_VER>=1310)) +#ifndef USE_SPIN_LOCKS +#define USE_SPIN_LOCKS 1 +#endif /* USE_SPIN_LOCKS */ +#elif USE_SPIN_LOCKS +#error "USE_SPIN_LOCKS defined without implementation" +#endif /* ... locks available... */ +#elif !defined(USE_SPIN_LOCKS) +#define USE_SPIN_LOCKS 0 +#endif /* USE_LOCKS */ + +#ifndef ONLY_MSPACES +#define ONLY_MSPACES 0 +#endif /* ONLY_MSPACES */ +#ifndef MSPACES +#if ONLY_MSPACES +#define MSPACES 1 +#else /* ONLY_MSPACES */ +#define MSPACES 0 +#endif /* ONLY_MSPACES */ +#endif /* MSPACES */ +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *))) +#endif /* MALLOC_ALIGNMENT */ +#ifndef FOOTERS +#define FOOTERS 0 +#endif /* FOOTERS */ +#ifndef ABORT +#define ABORT dlmalloc_abort() +#endif /* ABORT */ +#ifndef ABORT_ON_ASSERT_FAILURE +#define ABORT_ON_ASSERT_FAILURE 1 +#endif /* ABORT_ON_ASSERT_FAILURE */ +#ifndef PROCEED_ON_ERROR +#define PROCEED_ON_ERROR 0 +#endif /* PROCEED_ON_ERROR */ + +#ifndef INSECURE +#define INSECURE 0 +#endif /* INSECURE */ +#ifndef MALLOC_INSPECT_ALL +#define MALLOC_INSPECT_ALL 0 +#endif /* MALLOC_INSPECT_ALL */ +#ifndef HAVE_MMAP +#define HAVE_MMAP 1 +#endif /* HAVE_MMAP */ +#ifndef MMAP_CLEARS +#define MMAP_CLEARS 1 +#endif /* MMAP_CLEARS */ +#ifndef HAVE_MREMAP +#ifdef linux +#define HAVE_MREMAP 1 +#define _GNU_SOURCE /* Turns on mremap() definition */ +#else /* linux */ +#define HAVE_MREMAP 0 +#endif /* linux */ +#endif /* HAVE_MREMAP */ +#ifndef MALLOC_FAILURE_ACTION +#define MALLOC_FAILURE_ACTION errno = ENOMEM; +#endif /* MALLOC_FAILURE_ACTION */ +#ifndef HAVE_MORECORE +#if ONLY_MSPACES +#define HAVE_MORECORE 0 +#else /* ONLY_MSPACES */ +#define HAVE_MORECORE 1 +#endif /* ONLY_MSPACES */ +#endif /* HAVE_MORECORE */ +#if !HAVE_MORECORE +#define MORECORE_CONTIGUOUS 0 +#else /* !HAVE_MORECORE */ +#define MORECORE_DEFAULT sbrk +#ifndef MORECORE_CONTIGUOUS +#define MORECORE_CONTIGUOUS 1 +#endif /* MORECORE_CONTIGUOUS */ +#endif /* HAVE_MORECORE */ +#ifndef DEFAULT_GRANULARITY +#if (MORECORE_CONTIGUOUS || defined(WIN32)) +#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ +#else /* MORECORE_CONTIGUOUS */ +#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) +#endif /* MORECORE_CONTIGUOUS */ +#endif /* DEFAULT_GRANULARITY */ +#ifndef DEFAULT_TRIM_THRESHOLD +#ifndef MORECORE_CANNOT_TRIM +#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) +#else /* MORECORE_CANNOT_TRIM */ +#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T +#endif /* MORECORE_CANNOT_TRIM */ +#endif /* DEFAULT_TRIM_THRESHOLD */ +#ifndef DEFAULT_MMAP_THRESHOLD +#if HAVE_MMAP +#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) +#else /* HAVE_MMAP */ +#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T +#endif /* HAVE_MMAP */ +#endif /* DEFAULT_MMAP_THRESHOLD */ +#ifndef MAX_RELEASE_CHECK_RATE +#if HAVE_MMAP +#define MAX_RELEASE_CHECK_RATE 4095 +#else +#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T +#endif /* HAVE_MMAP */ +#endif /* MAX_RELEASE_CHECK_RATE */ +#ifndef USE_BUILTIN_FFS +#define USE_BUILTIN_FFS 0 +#endif /* USE_BUILTIN_FFS */ +#ifndef USE_DEV_RANDOM +#define USE_DEV_RANDOM 0 +#endif /* USE_DEV_RANDOM */ +#ifndef NO_MALLINFO +#define NO_MALLINFO 0 +#endif /* NO_MALLINFO */ +#ifndef MALLINFO_FIELD_TYPE +#define MALLINFO_FIELD_TYPE size_t +#endif /* MALLINFO_FIELD_TYPE */ +#ifndef NO_MALLOC_STATS +#define NO_MALLOC_STATS 0 +#endif /* NO_MALLOC_STATS */ +#ifndef NO_SEGMENT_TRAVERSAL +#define NO_SEGMENT_TRAVERSAL 0 +#endif /* NO_SEGMENT_TRAVERSAL */ + +/* + mallopt tuning options. SVID/XPG defines four standard parameter + numbers for mallopt, normally defined in malloc.h. None of these + are used in this malloc, so setting them has no effect. But this + malloc does support the following options. +*/ + +#define M_TRIM_THRESHOLD (-1) +#define M_GRANULARITY (-2) +#define M_MMAP_THRESHOLD (-3) + +/* ------------------------ Mallinfo declarations ------------------------ */ + +/* + Try to persuade compilers to inline. The most critical functions for + inlining are defined as macros, so these aren't used for them. +*/ + +#define FORCEINLINE forceinline +#define NOINLINE dontinline + +/* + ======================================================================== + To make a fully customizable malloc.h header file, cut everything + above this line, put into file malloc.h, edit to suit, and #include it + on the next line, as well as in programs that use this malloc. + ======================================================================== +*/ + +/* #include "malloc.h" */ + +/*------------------------------ internal #includes ---------------------- */ + +#ifdef _MSC_VER +#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ +#endif /* _MSC_VER */ +#if !NO_MALLOC_STATS +#endif /* NO_MALLOC_STATS */ +#ifndef LACKS_ERRNO_H +#include /* for MALLOC_FAILURE_ACTION */ +#endif /* LACKS_ERRNO_H */ +#ifdef DEBUG +#if ABORT_ON_ASSERT_FAILURE +#undef assert +#define assert(x) if(!(x)) ABORT +#else /* ABORT_ON_ASSERT_FAILURE */ +#include +#endif /* ABORT_ON_ASSERT_FAILURE */ +#else /* DEBUG */ +#ifndef assert +#define assert(x) +#endif +#define DEBUG 0 +#endif /* DEBUG */ +#if !defined(WIN32) && !defined(LACKS_TIME_H) +#include /* for magic initialization */ +#endif /* WIN32 */ +#ifndef LACKS_STDLIB_H +#include /* for abort() */ +#endif /* LACKS_STDLIB_H */ +#ifndef LACKS_STRING_H +#include /* for memset etc */ +#endif /* LACKS_STRING_H */ +#if USE_BUILTIN_FFS +#ifndef LACKS_STRINGS_H +#include /* for ffs */ +#endif /* LACKS_STRINGS_H */ +#endif /* USE_BUILTIN_FFS */ +#if HAVE_MMAP +#ifndef LACKS_SYS_MMAN_H +/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */ +#if (defined(linux) && !defined(__USE_GNU)) +#define __USE_GNU 1 +#include /* for mmap */ +#undef __USE_GNU +#else +#include /* for mmap */ +#endif /* linux */ +#endif /* LACKS_SYS_MMAN_H */ +#ifndef LACKS_FCNTL_H +#include +#endif /* LACKS_FCNTL_H */ +#endif /* HAVE_MMAP */ +#ifndef LACKS_UNISTD_H +#include /* for sbrk, sysconf */ +#else /* LACKS_UNISTD_H */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__COSMOPOLITAN__) +extern void* sbrk(ptrdiff_t); +#endif /* FreeBSD etc */ +#endif /* LACKS_UNISTD_H */ + +/* Declarations for locking */ +#if USE_LOCKS +#ifndef WIN32 +#if defined (__SVR4) && defined (__sun) /* solaris */ +#include +#elif !defined(LACKS_SCHED_H) +#include +#endif /* solaris or LACKS_SCHED_H */ +#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS +#include +#endif /* USE_RECURSIVE_LOCKS ... */ +#elif defined(_MSC_VER) +#ifndef _M_AMD64 +/* These are already defined on AMD64 builds */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp); +LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _M_AMD64 */ +#pragma intrinsic (_InterlockedCompareExchange) +#pragma intrinsic (_InterlockedExchange) +#define interlockedcompareexchange _InterlockedCompareExchange +#define interlockedexchange _InterlockedExchange +#elif defined(WIN32) && defined(__GNUC__) +#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b) +#define interlockedexchange __sync_lock_test_and_set +#endif /* Win32 */ +#else /* USE_LOCKS */ +#endif /* USE_LOCKS */ + +#ifndef LOCK_AT_FORK +#define LOCK_AT_FORK 0 +#endif + +/* Declarations for bit scanning on win32 */ +#if defined(_MSC_VER) && _MSC_VER>=1300 +#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +unsigned char _BitScanForward(unsigned long *index, unsigned long mask); +unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#define BitScanForward _BitScanForward +#define BitScanReverse _BitScanReverse +#pragma intrinsic(_BitScanForward) +#pragma intrinsic(_BitScanReverse) +#endif /* BitScanForward */ +#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */ + +#ifndef WIN32 +#ifndef malloc_getpagesize +# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ +# ifndef _SC_PAGE_SIZE +# define _SC_PAGE_SIZE _SC_PAGESIZE +# endif +# endif +# ifdef _SC_PAGE_SIZE +# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) +# else +# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) + extern size_t getpagesize(); +# define malloc_getpagesize getpagesize() +# else +# ifdef WIN32 /* use supplied emulation of getpagesize */ +# define malloc_getpagesize getpagesize() +# else +# ifndef LACKS_SYS_PARAM_H +# include +# endif +# ifdef EXEC_PAGESIZE +# define malloc_getpagesize EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define malloc_getpagesize NBPG +# else +# define malloc_getpagesize (NBPG * CLSIZE) +# endif +# else +# ifdef NBPC +# define malloc_getpagesize NBPC +# else +# ifdef PAGESIZE +# define malloc_getpagesize PAGESIZE +# else /* just guess */ +# define malloc_getpagesize ((size_t)4096U) +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif +#endif + +/* ------------------- size_t and alignment properties -------------------- */ + +/* The byte and bit size of a size_t */ +#define SIZE_T_SIZE (sizeof(size_t)) +#define SIZE_T_BITSIZE (sizeof(size_t) << 3) + +/* Some constants coerced to size_t */ +/* Annoying but necessary to avoid errors on some platforms */ +#define SIZE_T_ZERO ((size_t)0) +#define SIZE_T_ONE ((size_t)1) +#define SIZE_T_TWO ((size_t)2) +#define SIZE_T_FOUR ((size_t)4) +#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) +#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) +#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) +#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) + +/* The bit mask value corresponding to MALLOC_ALIGNMENT */ +#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) + +/* True if address a has acceptable alignment */ +#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) + +/* the number of bytes to offset an address to align it */ +#define align_offset(A)\ + ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ + ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) + +/* -------------------------- MMAP preliminaries ------------------------- */ + +/* + If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and + checks to fail so compiler optimizer can delete code rather than + using so many "#if"s. +*/ + + +/* MORECORE and MMAP must return MFAIL on failure */ +#define MFAIL ((void*)(MAX_SIZE_T)) +#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ + +#if HAVE_MMAP + +#ifndef WIN32 +#define MUNMAP_DEFAULT(a, s) munmap((a), (s)) +#define MMAP_PROT (PROT_READ|PROT_WRITE) +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +#define MAP_ANONYMOUS MAP_ANON +#endif /* MAP_ANON */ +#ifdef MAP_ANONYMOUS +#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) +#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) +#else /* MAP_ANONYMOUS */ +/* + Nearly all versions of mmap support MAP_ANONYMOUS, so the following + is unlikely to be needed, but is supplied just in case. +*/ +#define MMAP_FLAGS (MAP_PRIVATE) +static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ +#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ + (dev_zero_fd = open("/dev/zero", O_RDWR), \ + mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ + mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) +#endif /* MAP_ANONYMOUS */ + +#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) + +#else /* WIN32 */ + +/* Win32 MMAP via VirtualAlloc */ +FORCEINLINE void* win32mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); + return (ptr != 0)? ptr: MFAIL; +} + +/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ +FORCEINLINE void* win32direct_mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, + PAGE_READWRITE); + return (ptr != 0)? ptr: MFAIL; +} + +/* This function supports releasing coalesed segments */ +FORCEINLINE int win32munmap(void* ptr, size_t size) { + MEMORY_BASIC_INFORMATION minfo; + char* cptr = (char*)ptr; + while (size) { + if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) + return -1; + if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || + minfo.State != MEM_COMMIT || minfo.RegionSize > size) + return -1; + if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) + return -1; + cptr += minfo.RegionSize; + size -= minfo.RegionSize; + } + return 0; +} + +#define MMAP_DEFAULT(s) win32mmap(s) +#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) +#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) +#endif /* WIN32 */ +#endif /* HAVE_MMAP */ + +#if HAVE_MREMAP +#ifndef WIN32 +#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) +#endif /* WIN32 */ +#endif /* HAVE_MREMAP */ + +/** + * Define CALL_MORECORE + */ +#if HAVE_MORECORE + #ifdef MORECORE + #define CALL_MORECORE(S) MORECORE(S) + #else /* MORECORE */ + #define CALL_MORECORE(S) MORECORE_DEFAULT(S) + #endif /* MORECORE */ +#else /* HAVE_MORECORE */ + #define CALL_MORECORE(S) MFAIL +#endif /* HAVE_MORECORE */ + +/** + * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP + */ +#if HAVE_MMAP + #define USE_MMAP_BIT (SIZE_T_ONE) + + #ifdef MMAP + #define CALL_MMAP(s) MMAP(s) + #else /* MMAP */ + #define CALL_MMAP(s) MMAP_DEFAULT(s) + #endif /* MMAP */ + #ifdef MUNMAP + #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) + #else /* MUNMAP */ + #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) + #endif /* MUNMAP */ + #ifdef DIRECT_MMAP + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) + #else /* DIRECT_MMAP */ + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) + #endif /* DIRECT_MMAP */ +#else /* HAVE_MMAP */ + #define USE_MMAP_BIT (SIZE_T_ZERO) + + #define MMAP(s) MFAIL + #define MUNMAP(a, s) (-1) + #define DIRECT_MMAP(s) MFAIL + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) + #define CALL_MMAP(s) MMAP(s) + #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) +#endif /* HAVE_MMAP */ + +/** + * Define CALL_MREMAP + */ +#if HAVE_MMAP && HAVE_MREMAP + #ifdef MREMAP + #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) + #else /* MREMAP */ + #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) + #endif /* MREMAP */ +#else /* HAVE_MMAP && HAVE_MREMAP */ + #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL +#endif /* HAVE_MMAP && HAVE_MREMAP */ + +/* mstate bit set if continguous morecore disabled or failed */ +#define USE_NONCONTIGUOUS_BIT (4U) + +/* segment bit set in create_mspace_with_base */ +#define EXTERN_BIT (8U) + + +/* --------------------------- Lock preliminaries ------------------------ */ + +/* + When locks are defined, there is one global lock, plus + one per-mspace lock. + + The global lock_ensures that mparams.magic and other unique + mparams values are initialized only once. It also protects + sequences of calls to MORECORE. In many cases sys_alloc requires + two calls, that should not be interleaved with calls by other + threads. This does not protect against direct calls to MORECORE + by other threads not using this lock, so there is still code to + cope the best we can on interference. + + Per-mspace locks surround calls to malloc, free, etc. + By default, locks are simple non-reentrant mutexes. + + Because lock-protected regions generally have bounded times, it is + OK to use the supplied simple spinlocks. Spinlocks are likely to + improve performance for lightly contended applications, but worsen + performance under heavy contention. + + If USE_LOCKS is > 1, the definitions of lock routines here are + bypassed, in which case you will need to define the type MLOCK_T, + and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK + and TRY_LOCK. You must also declare a + static MLOCK_T malloc_global_mutex = { initialization values };. + +*/ + +#if !USE_LOCKS +#define USE_LOCK_BIT (0U) +#define INITIAL_LOCK(l) (0) +#define DESTROY_LOCK(l) (0) +#define ACQUIRE_MALLOC_GLOBAL_LOCK() +#define RELEASE_MALLOC_GLOBAL_LOCK() + +#else +#if USE_LOCKS > 1 +/* ----------------------- User-defined locks ------------------------ */ +/* Define your own lock implementation here */ +/* #define INITIAL_LOCK(lk) ... */ +/* #define DESTROY_LOCK(lk) ... */ +/* #define ACQUIRE_LOCK(lk) ... */ +/* #define RELEASE_LOCK(lk) ... */ +/* #define TRY_LOCK(lk) ... */ +/* static MLOCK_T malloc_global_mutex = ... */ + +#elif USE_SPIN_LOCKS + +/* First, define CAS_LOCK and CLEAR_LOCK on ints */ +/* Note CAS_LOCK defined to return 0 on success */ + +#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) +#define CAS_LOCK(sl) __sync_lock_test_and_set(sl, 1) +#define CLEAR_LOCK(sl) __sync_lock_release(sl) + +#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) +/* Custom spin locks for older gcc on x86 */ +FORCEINLINE int x86_cas_lock(int *sl) { + int ret; + int val = 1; + int cmp = 0; + __asm__ __volatile__ ("lock; cmpxchgl %1, %2" + : "=a" (ret) + : "r" (val), "m" (*(sl)), "0"(cmp) + : "memory", "cc"); + return ret; +} + +FORCEINLINE void x86_clear_lock(int* sl) { + assert(*sl != 0); + int prev = 0; + int ret; + __asm__ __volatile__ ("lock; xchgl %0, %1" + : "=r" (ret) + : "m" (*(sl)), "0"(prev) + : "memory"); +} + +#define CAS_LOCK(sl) x86_cas_lock(sl) +#define CLEAR_LOCK(sl) x86_clear_lock(sl) + +#else /* Win32 MSC */ +#define CAS_LOCK(sl) interlockedexchange(sl, (LONG)1) +#define CLEAR_LOCK(sl) interlockedexchange (sl, (LONG)0) + +#endif /* ... gcc spins locks ... */ + +#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0 +/* Plain spin locks use single word (embedded in malloc_states) */ +static dontinline int spin_acquire_lock(int *sl) { + while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) { + __builtin_ia32_pause(); + } + return 0; +} + +#define MLOCK_T int +#define TRY_LOCK(sl) !CAS_LOCK(sl) +#define RELEASE_LOCK(sl) CLEAR_LOCK(sl) +#define ACQUIRE_LOCK(sl) (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0) +#define INITIAL_LOCK(sl) (*sl = 0) +#define DESTROY_LOCK(sl) (0) +static MLOCK_T malloc_global_mutex = 0; + +#else /* USE_RECURSIVE_LOCKS */ +/* types for lock owners */ +#ifdef WIN32 +#define THREAD_ID_T DWORD +#define CURRENT_THREAD GetCurrentThreadId() +#define EQ_OWNER(X,Y) ((X) == (Y)) +#else +/* + Note: the following assume that pthread_t is a type that can be + initialized to (casted) zero. If this is not the case, you will need to + somehow redefine these or not use spin locks. +*/ +#define THREAD_ID_T pthread_t +#define CURRENT_THREAD pthread_self() +#define EQ_OWNER(X,Y) pthread_equal(X, Y) +#endif + +struct malloc_recursive_lock { + int sl; + unsigned int c; + THREAD_ID_T threadid; +}; + +#define MLOCK_T struct malloc_recursive_lock +static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0}; + +FORCEINLINE void recursive_release_lock(MLOCK_T *lk) { + assert(lk->sl != 0); + if (--lk->c == 0) { + CLEAR_LOCK(&lk->sl); + } +} + +FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) { + THREAD_ID_T mythreadid = CURRENT_THREAD; + for (;;) { + if (*((volatile int *)(&lk->sl)) == 0) { + if (!CAS_LOCK(&lk->sl)) { + lk->threadid = mythreadid; + lk->c = 1; + return 0; + } + } + else if (EQ_OWNER(lk->threadid, mythreadid)) { + ++lk->c; + return 0; + } + __builtin_ia32_pause(); + } +} + +FORCEINLINE int recursive_try_lock(MLOCK_T *lk) { + THREAD_ID_T mythreadid = CURRENT_THREAD; + if (*((volatile int *)(&lk->sl)) == 0) { + if (!CAS_LOCK(&lk->sl)) { + lk->threadid = mythreadid; + lk->c = 1; + return 1; + } + } + else if (EQ_OWNER(lk->threadid, mythreadid)) { + ++lk->c; + return 1; + } + return 0; +} + +#define RELEASE_LOCK(lk) recursive_release_lock(lk) +#define TRY_LOCK(lk) recursive_try_lock(lk) +#define ACQUIRE_LOCK(lk) recursive_acquire_lock(lk) +#define INITIAL_LOCK(lk) ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0) +#define DESTROY_LOCK(lk) (0) +#endif /* USE_RECURSIVE_LOCKS */ + +#elif defined(WIN32) /* Win32 critical sections */ +#define MLOCK_T CRITICAL_SECTION +#define ACQUIRE_LOCK(lk) (EnterCriticalSection(lk), 0) +#define RELEASE_LOCK(lk) LeaveCriticalSection(lk) +#define TRY_LOCK(lk) TryEnterCriticalSection(lk) +#define INITIAL_LOCK(lk) (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000)) +#define DESTROY_LOCK(lk) (DeleteCriticalSection(lk), 0) +#define NEED_GLOBAL_LOCK_INIT + +static MLOCK_T malloc_global_mutex; +static volatile LONG malloc_global_mutex_status; + +/* Use spin loop to initialize global lock */ +static void init_malloc_global_mutex() { + for (;;) { + long stat = malloc_global_mutex_status; + if (stat > 0) + return; + /* transition to < 0 while initializing, then to > 0) */ + if (stat == 0 && + interlockedcompareexchange(&malloc_global_mutex_status, (LONG)-1, (LONG)0) == 0) { + InitializeCriticalSection(&malloc_global_mutex); + interlockedexchange(&malloc_global_mutex_status, (LONG)1); + return; + } + SleepEx(0, FALSE); + } +} + +#else /* pthreads-based locks */ +#define MLOCK_T pthread_mutex_t +#define ACQUIRE_LOCK(lk) pthread_mutex_lock(lk) +#define RELEASE_LOCK(lk) pthread_mutex_unlock(lk) +#define TRY_LOCK(lk) (!pthread_mutex_trylock(lk)) +#define INITIAL_LOCK(lk) pthread_init_lock(lk) +#define DESTROY_LOCK(lk) pthread_mutex_destroy(lk) + +#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE) +/* Cope with old-style linux recursive lock initialization by adding */ +/* skipped internal declaration from pthread.h */ +extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr, + int __kind)); +#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y) +#endif /* USE_RECURSIVE_LOCKS ... */ + +static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int pthread_init_lock (MLOCK_T *lk) { + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr)) return 1; +#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1; +#endif + if (pthread_mutex_init(lk, &attr)) return 1; + if (pthread_mutexattr_destroy(&attr)) return 1; + return 0; +} + +#endif /* ... lock types ... */ + +/* Common code for all lock types */ +#define USE_LOCK_BIT (2U) + +#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK +#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); +#endif + +#ifndef RELEASE_MALLOC_GLOBAL_LOCK +#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); +#endif + +#endif /* USE_LOCKS */ + +struct malloc_chunk { + size_t prev_foot; /* Size of previous chunk (if free). */ + size_t head; /* Size and inuse bits. */ + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; +}; + +typedef struct malloc_chunk mchunk; +typedef struct malloc_chunk* mchunkptr; +typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ +typedef unsigned int bindex_t; /* Described below */ +typedef unsigned int binmap_t; /* Described below */ +typedef unsigned int flag_t; /* The type of various bit flag sets */ + +/* ------------------- Chunks sizes and alignments ----------------------- */ + +#define MCHUNK_SIZE (sizeof(mchunk)) + +#if FOOTERS +#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +#else /* FOOTERS */ +#define CHUNK_OVERHEAD (SIZE_T_SIZE) +#endif /* FOOTERS */ + +/* MMapped chunks need a second word of overhead ... */ +#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +/* ... and additional padding for fake next-chunk at foot */ +#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) + +/* The smallest size we can malloc is an aligned minimal chunk */ +#define MIN_CHUNK_SIZE\ + ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* conversion from malloc headers to user pointers, and back */ +#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) +#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) +/* chunk associated with aligned address A */ +#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) + +/* Bounds on request (not chunk) sizes. */ +#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) +#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) + +/* pad request bytes into a usable size */ +#define pad_request(req) \ + (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* pad request, checking for minimum (but not maximum) */ +#define request2size(req) \ + (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) + + +/* ------------------ Operations on head and foot fields ----------------- */ + +/* + The head field of a chunk is or'ed with PINUSE_BIT when previous + adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in + use, unless mmapped, in which case both bits are cleared. + + FLAG4_BIT is not used by this malloc, but might be useful in extensions. +*/ + +#define PINUSE_BIT (SIZE_T_ONE) +#define CINUSE_BIT (SIZE_T_TWO) +#define FLAG4_BIT (SIZE_T_FOUR) +#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) +#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT) + +/* Head value for fenceposts */ +#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) + +/* extraction of fields from head words */ +#define cinuse(p) ((p)->head & CINUSE_BIT) +#define pinuse(p) ((p)->head & PINUSE_BIT) +#define flag4inuse(p) ((p)->head & FLAG4_BIT) +#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) +#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) + +#define chunksize(p) ((p)->head & ~(FLAG_BITS)) + +#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) +#define set_flag4(p) ((p)->head |= FLAG4_BIT) +#define clear_flag4(p) ((p)->head &= ~FLAG4_BIT) + +/* Treat space at ptr +/- offset as a chunk */ +#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) +#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) + +/* Ptr to next or previous physical malloc_chunk. */ +#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS))) +#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) + +/* extract next chunk's pinuse bit */ +#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) + +/* Get/set size at footer */ +#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) +#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) + +/* Set size, pinuse bit, and foot */ +#define set_size_and_pinuse_of_free_chunk(p, s)\ + ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) + +/* Set size, pinuse bit, foot, and clear next pinuse */ +#define set_free_with_pinuse(p, s, n)\ + (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) + +/* Get the internal overhead associated with chunk p */ +#define overhead_for(p)\ + (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) + +/* Return true if malloced space is not necessarily cleared */ +#if MMAP_CLEARS +#define calloc_must_clear(p) (!is_mmapped(p)) +#else /* MMAP_CLEARS */ +#define calloc_must_clear(p) (1) +#endif /* MMAP_CLEARS */ + + +struct malloc_tree_chunk { + /* The first four fields must be compatible with malloc_chunk */ + size_t prev_foot; + size_t head; + struct malloc_tree_chunk* fd; + struct malloc_tree_chunk* bk; + + struct malloc_tree_chunk* child[2]; + struct malloc_tree_chunk* parent; + bindex_t index; +}; + +typedef struct malloc_tree_chunk tchunk; +typedef struct malloc_tree_chunk* tchunkptr; +typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ + +/* A little helper macro for trees */ +#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) + +struct malloc_segment { + char* base; /* base address */ + size_t size; /* allocated size */ + struct malloc_segment* next; /* ptr to next segment */ + flag_t sflags; /* mmap and extern flag */ +}; + +#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) +#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) + +typedef struct malloc_segment msegment; +typedef struct malloc_segment* msegmentptr; + +/* Bin types, widths and sizes */ +#define NSMALLBINS (32U) +#define NTREEBINS (32U) +#define SMALLBIN_SHIFT (3U) +#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) +#define TREEBIN_SHIFT (8U) +#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) +#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) +#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) + +struct malloc_state { + binmap_t smallmap; + binmap_t treemap; + size_t dvsize; + size_t topsize; + char* least_addr; + mchunkptr dv; + mchunkptr top; + size_t trim_check; + size_t release_checks; + size_t magic; + mchunkptr smallbins[(NSMALLBINS+1)*2]; + tbinptr treebins[NTREEBINS]; + size_t footprint; + size_t max_footprint; + size_t footprint_limit; /* zero means no limit */ + flag_t mflags; +#if USE_LOCKS + MLOCK_T mutex; /* locate lock among fields that rarely change */ +#endif /* USE_LOCKS */ + msegment seg; + void* extp; /* Unused but available for extensions */ + size_t exts; +}; + +typedef struct malloc_state* mstate; + +/* ------------- Global malloc_state and malloc_params ------------------- */ + +/* + malloc_params holds global properties, including those that can be + dynamically set using mallopt. There is a single instance, mparams, + initialized in init_mparams. Note that the non-zeroness of "magic" + also serves as an initialization flag. +*/ + +struct malloc_params { + size_t magic; + size_t page_size; + size_t granularity; + size_t mmap_threshold; + size_t trim_threshold; + flag_t default_mflags; +}; + +static struct malloc_params mparams; + +/* Ensure mparams initialized */ +#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams()) + +#if !ONLY_MSPACES + +/* The global malloc_state used for all non-"mspace" calls */ +static struct malloc_state _gm_; +#define gm (&_gm_) +#define is_global(M) ((M) == &_gm_) + +#endif /* !ONLY_MSPACES */ + +#define is_initialized(M) ((M)->top != 0) + +/* -------------------------- system alloc setup ------------------------- */ + +/* Operations on mflags */ + +#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) +#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) +#if USE_LOCKS +#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) +#else +#define disable_lock(M) +#endif + +#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) +#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) +#if HAVE_MMAP +#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) +#else +#define disable_mmap(M) +#endif + +#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) +#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) + +#define set_lock(M,L)\ + ((M)->mflags = (L)?\ + ((M)->mflags | USE_LOCK_BIT) :\ + ((M)->mflags & ~USE_LOCK_BIT)) + +/* page-align a size */ +#define page_align(S)\ + (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) + +/* granularity-align a size */ +#define granularity_align(S)\ + (((S) + (mparams.granularity - SIZE_T_ONE))\ + & ~(mparams.granularity - SIZE_T_ONE)) + + +/* For mmap, use granularity alignment on windows, else page-align */ +#if defined(WIN32) || defined(__COSMOPOLITAN__) +#define mmap_align(S) granularity_align(S) +#else +#define mmap_align(S) page_align(S) +#endif + +/* For sys_alloc, enough padding to ensure can malloc request on success */ +#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) + +#define is_page_aligned(S)\ + (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) +#define is_granularity_aligned(S)\ + (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) + +/* True if segment S holds address A */ +#define segment_holds(S, A)\ + ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) + +/* Return segment holding given address */ +static msegmentptr segment_holding(mstate m, char* addr) { + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= sp->base && addr < sp->base + sp->size) + return sp; + if ((sp = sp->next) == 0) + return 0; + } +} + +/* Return true if segment contains a segment link */ +static int has_segment_link(mstate m, msegmentptr ss) { + msegmentptr sp = &m->seg; + for (;;) { + if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) + return 1; + if ((sp = sp->next) == 0) + return 0; + } +} + +#ifndef MORECORE_CANNOT_TRIM +#define should_trim(M,s) ((s) > (M)->trim_check) +#else /* MORECORE_CANNOT_TRIM */ +#define should_trim(M,s) (0) +#endif /* MORECORE_CANNOT_TRIM */ + +/* + TOP_FOOT_SIZE is padding at the end of a segment, including space + that may be needed to place segment records and fenceposts when new + noncontiguous segments are added. +*/ +#define TOP_FOOT_SIZE\ + (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) + + +/* ------------------------------- Hooks -------------------------------- */ + +/* + PREACTION should be defined to return 0 on success, and nonzero on + failure. If you are not using locking, you can redefine these to do + anything you like. +*/ + +#if USE_LOCKS +#define PREACTION(M) ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) +#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } +#else /* USE_LOCKS */ + +#ifndef PREACTION +#define PREACTION(M) (0) +#endif /* PREACTION */ + +#ifndef POSTACTION +#define POSTACTION(M) +#endif /* POSTACTION */ + +#endif /* USE_LOCKS */ + +/* + CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. + USAGE_ERROR_ACTION is triggered on detected bad frees and + reallocs. The argument p is an address that might have triggered the + fault. It is ignored by the two predefined actions, but might be + useful in custom actions that try to help diagnose errors. +*/ + +#if PROCEED_ON_ERROR + +/* A count of the number of corruption errors causing resets */ +int malloc_corruption_error_count; + +/* default corruption action */ +static void reset_on_error(mstate m); + +#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) +#define USAGE_ERROR_ACTION(m, p) + +#else /* PROCEED_ON_ERROR */ + +#ifndef CORRUPTION_ERROR_ACTION +#define CORRUPTION_ERROR_ACTION(m) ABORT +#endif /* CORRUPTION_ERROR_ACTION */ + +#ifndef USAGE_ERROR_ACTION +#define USAGE_ERROR_ACTION(m,p) ABORT +#endif /* USAGE_ERROR_ACTION */ + +#endif /* PROCEED_ON_ERROR */ + + +/* -------------------------- Debugging setup ---------------------------- */ + +#if ! DEBUG + +#define check_free_chunk(M,P) +#define check_inuse_chunk(M,P) +#define check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) +#define check_malloc_state(M) +#define check_top_chunk(M,P) + +#else /* DEBUG */ +#define check_free_chunk(M,P) do_check_free_chunk(M,P) +#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) +#define check_top_chunk(M,P) do_check_top_chunk(M,P) +#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) +#define check_malloc_state(M) do_check_malloc_state(M) + +static void do_check_any_chunk(mstate m, mchunkptr p); +static void do_check_top_chunk(mstate m, mchunkptr p); +static void do_check_mmapped_chunk(mstate m, mchunkptr p); +static void do_check_inuse_chunk(mstate m, mchunkptr p); +static void do_check_free_chunk(mstate m, mchunkptr p); +static void do_check_malloced_chunk(mstate m, void* mem, size_t s); +static void do_check_tree(mstate m, tchunkptr t); +static void do_check_treebin(mstate m, bindex_t i); +static void do_check_smallbin(mstate m, bindex_t i); +static void do_check_malloc_state(mstate m); +static int bin_find(mstate m, mchunkptr x); +static size_t traverse_and_check(mstate m); +#endif /* DEBUG */ + +/* ---------------------------- Indexing Bins ---------------------------- */ + +#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) +#define small_index(s) (bindex_t)((s) >> SMALLBIN_SHIFT) +#define small_index2size(i) ((i) << SMALLBIN_SHIFT) +#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) + +/* addressing by index. See above about smallbin repositioning */ +#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) +#define treebin_at(M,i) (&((M)->treebins[i])) + +/* assign tree index for size S to variable I. Use x86 asm if possible */ +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define compute_tree_index(S, I)\ +{\ + unsigned int X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#elif defined (__INTEL_COMPILER) +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K = _bit_scan_reverse (X); \ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#elif defined(_MSC_VER) && _MSC_VER>=1300 +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K;\ + _BitScanReverse((DWORD *) &K, (DWORD) X);\ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#else /* GNUC */ +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int Y = (unsigned int)X;\ + unsigned int N = ((Y - 0x100) >> 16) & 8;\ + unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ + N += K;\ + N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ + K = 14 - N + ((Y <<= K) >> 15);\ + I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ + }\ +} +#endif /* GNUC */ + +/* Bit representing maximum resolved size in a treebin at i */ +#define bit_for_tree_index(i) \ + (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) + +/* Shift placing maximum resolved bit in a treebin at i as sign bit */ +#define leftshift_for_tree_index(i) \ + ((i == NTREEBINS-1)? 0 : \ + ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) + +/* The size of the smallest chunk held in bin with index i */ +#define minsize_for_tree_index(i) \ + ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ + (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) + + +/* ------------------------ Operations on bin maps ----------------------- */ + +/* bit corresponding to given index */ +#define idx2bit(i) ((binmap_t)(1) << (i)) + +/* Mark/Clear bits with given index */ +#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) +#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) +#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) + +#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) +#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) +#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) + +/* isolate the least set bit of a bitmap */ +#define least_bit(x) ((x) & -(x)) + +/* mask with all bits to left of least bit of x on */ +#define left_bits(x) ((x<<1) | -(x<<1)) + +/* mask with all bits to left of or equal to least bit of x on */ +#define same_or_left_bits(x) ((x) | -(x)) + +/* index corresponding to given bit. Use x86 asm if possible */ + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + J = __builtin_ctz(X); \ + I = (bindex_t)J;\ +} + +#elif defined (__INTEL_COMPILER) +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + J = _bit_scan_forward (X); \ + I = (bindex_t)J;\ +} + +#elif defined(_MSC_VER) && _MSC_VER>=1300 +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + _BitScanForward((DWORD *) &J, X);\ + I = (bindex_t)J;\ +} + +#elif USE_BUILTIN_FFS +#define compute_bit2idx(X, I) I = ffs(X)-1 + +#else +#define compute_bit2idx(X, I)\ +{\ + unsigned int Y = X - 1;\ + unsigned int K = Y >> (16-4) & 16;\ + unsigned int N = K; Y >>= K;\ + N += K = Y >> (8-3) & 8; Y >>= K;\ + N += K = Y >> (4-2) & 4; Y >>= K;\ + N += K = Y >> (2-1) & 2; Y >>= K;\ + N += K = Y >> (1-0) & 1; Y >>= K;\ + I = (bindex_t)(N + Y);\ +} +#endif /* GNUC */ + + +/* ----------------------- Runtime Check Support ------------------------- */ + +/* + For security, the main invariant is that malloc/free/etc never + writes to a static address other than malloc_state, unless static + malloc_state itself has been corrupted, which cannot occur via + malloc (because of these checks). In essence this means that we + believe all pointers, sizes, maps etc held in malloc_state, but + check all of those linked or offsetted from other embedded data + structures. These checks are interspersed with main code in a way + that tends to minimize their run-time cost. + + When FOOTERS is defined, in addition to range checking, we also + verify footer fields of inuse chunks, which can be used guarantee + that the mstate controlling malloc/free is intact. This is a + streamlined version of the approach described by William Robertson + et al in "Run-time Detection of Heap-based Overflows" LISA'03 + http://www.usenix.org/events/lisa03/tech/robertson.html The footer + of an inuse chunk holds the xor of its mstate and a random seed, + that is checked upon calls to free() and realloc(). This is + (probabalistically) unguessable from outside the program, but can be + computed by any code successfully malloc'ing any chunk, so does not + itself provide protection against code that has already broken + security through some other means. Unlike Robertson et al, we + always dynamically check addresses of all offset chunks (previous, + next, etc). This turns out to be cheaper than relying on hashes. +*/ + +#if !INSECURE +/* Check if address a is at least as high as any from MORECORE or MMAP */ +#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) +/* Check if address of next chunk n is higher than base chunk p */ +#define ok_next(p, n) ((char*)(p) < (char*)(n)) +/* Check if p has inuse status */ +#define ok_inuse(p) is_inuse(p) +/* Check if p has its pinuse bit on */ +#define ok_pinuse(p) pinuse(p) + +#else /* !INSECURE */ +#define ok_address(M, a) (1) +#define ok_next(b, n) (1) +#define ok_inuse(p) (1) +#define ok_pinuse(p) (1) +#endif /* !INSECURE */ + +#if (FOOTERS && !INSECURE) +/* Check if (alleged) mstate m has expected magic field */ +#define ok_magic(M) ((M)->magic == mparams.magic) +#else /* (FOOTERS && !INSECURE) */ +#define ok_magic(M) (1) +#endif /* (FOOTERS && !INSECURE) */ + +/* In gcc, use __builtin_expect to minimize impact of checks */ +#if !INSECURE +#if defined(__GNUC__) && __GNUC__ >= 3 +#define RTCHECK(e) __builtin_expect(e, 1) +#else /* GNUC */ +#define RTCHECK(e) (e) +#endif /* GNUC */ +#else /* !INSECURE */ +#define RTCHECK(e) (1) +#endif /* !INSECURE */ + +/* macros to set up inuse chunks with or without footers */ + +#if !FOOTERS + +#define mark_inuse_foot(M,p,s) + +/* Macros for setting head/foot of non-mmapped chunks */ + +/* Set cinuse bit and pinuse bit of next chunk */ +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set size, cinuse and pinuse bit of this chunk */ +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) + +#else /* FOOTERS */ + +/* Set foot of inuse chunk to be xor of mstate and seed */ +#define mark_inuse_foot(M,p,s)\ + (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) + +#define get_mstate_for(p)\ + ((mstate)(((mchunkptr)((char*)(p) +\ + (chunksize(p))))->prev_foot ^ mparams.magic)) + +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ + mark_inuse_foot(M,p,s)) + +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ + mark_inuse_foot(M,p,s)) + +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + mark_inuse_foot(M, p, s)) + +#endif /* !FOOTERS */ + +/* ---------------------------- setting mparams -------------------------- */ + +#if LOCK_AT_FORK +static void pre_fork(void) { ACQUIRE_LOCK(&(gm)->mutex); } +static void post_fork_parent(void) { RELEASE_LOCK(&(gm)->mutex); } +static void post_fork_child(void) { INITIAL_LOCK(&(gm)->mutex); } +#endif /* LOCK_AT_FORK */ + +/* Initialize mparams */ +static int init_mparams(void) { +#ifdef NEED_GLOBAL_LOCK_INIT + if (malloc_global_mutex_status <= 0) + init_malloc_global_mutex(); +#endif + + ACQUIRE_MALLOC_GLOBAL_LOCK(); + if (mparams.magic == 0) { + size_t magic; + size_t psize; + size_t gsize; + +#ifndef WIN32 + psize = malloc_getpagesize; + gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); +#else /* WIN32 */ + { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + psize = system_info.dwPageSize; + gsize = ((DEFAULT_GRANULARITY != 0)? + DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); + } +#endif /* WIN32 */ + + /* Sanity-check configuration: + size_t must be unsigned and as wide as pointer type. + ints must be at least 4 bytes. + alignment must be at least 8. + Alignment, min chunk size, and page size must all be powers of 2. + */ + if ((sizeof(size_t) != sizeof(char*)) || + (MAX_SIZE_T < MIN_CHUNK_SIZE) || + (sizeof(int) < 4) || + (MALLOC_ALIGNMENT < (size_t)8U) || + ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || + ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || + ((gsize & (gsize-SIZE_T_ONE)) != 0) || + ((psize & (psize-SIZE_T_ONE)) != 0)) + ABORT; + mparams.granularity = gsize; + mparams.page_size = psize; + mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; + mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; +#if MORECORE_CONTIGUOUS + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; +#else /* MORECORE_CONTIGUOUS */ + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; +#endif /* MORECORE_CONTIGUOUS */ + +#if !ONLY_MSPACES + /* Set up lock for main malloc area */ + gm->mflags = mparams.default_mflags; + (void)INITIAL_LOCK(&gm->mutex); +#endif +#if LOCK_AT_FORK + pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child); +#endif + + { +#if USE_DEV_RANDOM + int fd; + unsigned char buf[sizeof(size_t)]; + /* Try to use /dev/urandom, else fall back on using time */ + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && + read(fd, buf, sizeof(buf)) == sizeof(buf)) { + magic = *((size_t *) buf); + close(fd); + } + else +#endif /* USE_DEV_RANDOM */ + magic = (size_t)(rand64() ^ (size_t)0x55555555U); + magic |= (size_t)8U; /* ensure nonzero */ + magic &= ~(size_t)7U; /* improve chances of fault for bad values */ + /* Until memory modes commonly available, use volatile-write */ + (*(volatile size_t *)(&(mparams.magic))) = magic; + } + } + + RELEASE_MALLOC_GLOBAL_LOCK(); + return 1; +} + +/* support for mallopt */ +static int change_mparam(int param_number, int value) { + size_t val; + ensure_initialization(); + val = (value == -1)? MAX_SIZE_T : (size_t)value; + switch(param_number) { + case M_TRIM_THRESHOLD: + mparams.trim_threshold = val; + return 1; + case M_GRANULARITY: + if (val >= mparams.page_size && ((val & (val-1)) == 0)) { + mparams.granularity = val; + return 1; + } + else + return 0; + case M_MMAP_THRESHOLD: + mparams.mmap_threshold = val; + return 1; + default: + return 0; + } +} + +#if DEBUG +/* ------------------------- Debugging Support --------------------------- */ + +/* Check properties of any chunk, whether free, inuse, mmapped etc */ +static void do_check_any_chunk(mstate m, mchunkptr p) { + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); +} + +/* Check properties of top chunk */ +static void do_check_top_chunk(mstate m, mchunkptr p) { + msegmentptr sp = segment_holding(m, (char*)p); + size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ + assert(sp != 0); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(sz == m->topsize); + assert(sz > 0); + assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); + assert(pinuse(p)); + assert(!pinuse(chunk_plus_offset(p, sz))); +} + +/* Check properties of (inuse) mmapped chunks */ +static void do_check_mmapped_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); + assert(is_mmapped(p)); + assert(use_mmap(m)); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(!is_small(sz)); + assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); + assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); + assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); +} + +/* Check properties of inuse chunks */ +static void do_check_inuse_chunk(mstate m, mchunkptr p) { + do_check_any_chunk(m, p); + assert(is_inuse(p)); + assert(next_pinuse(p)); + /* If not pinuse and not mmapped, previous chunk has OK offset */ + assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); + if (is_mmapped(p)) + do_check_mmapped_chunk(m, p); +} + +/* Check properties of free chunks */ +static void do_check_free_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + mchunkptr next = chunk_plus_offset(p, sz); + do_check_any_chunk(m, p); + assert(!is_inuse(p)); + assert(!next_pinuse(p)); + assert (!is_mmapped(p)); + if (p != m->dv && p != m->top) { + if (sz >= MIN_CHUNK_SIZE) { + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(is_aligned(chunk2mem(p))); + assert(next->prev_foot == sz); + assert(pinuse(p)); + assert (next == m->top || is_inuse(next)); + assert(p->fd->bk == p); + assert(p->bk->fd == p); + } + else /* markers are always of size SIZE_T_SIZE */ + assert(sz == SIZE_T_SIZE); + } +} + +/* Check properties of malloced chunks at the point they are malloced */ +static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + size_t sz = p->head & ~INUSE_BITS; + do_check_inuse_chunk(m, p); + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(sz >= MIN_CHUNK_SIZE); + assert(sz >= s); + /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ + assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); + } +} + +/* Check a tree and its subtrees. */ +static void do_check_tree(mstate m, tchunkptr t) { + tchunkptr head = 0; + tchunkptr u = t; + bindex_t tindex = t->index; + size_t tsize = chunksize(t); + bindex_t idx; + compute_tree_index(tsize, idx); + assert(tindex == idx); + assert(tsize >= MIN_LARGE_SIZE); + assert(tsize >= minsize_for_tree_index(idx)); + assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); + + do { /* traverse through chain of same-sized nodes */ + do_check_any_chunk(m, ((mchunkptr)u)); + assert(u->index == tindex); + assert(chunksize(u) == tsize); + assert(!is_inuse(u)); + assert(!next_pinuse(u)); + assert(u->fd->bk == u); + assert(u->bk->fd == u); + if (u->parent == 0) { + assert(u->child[0] == 0); + assert(u->child[1] == 0); + } + else { + assert(head == 0); /* only one node on chain has parent */ + head = u; + assert(u->parent != u); + assert (u->parent->child[0] == u || + u->parent->child[1] == u || + *((tbinptr*)(u->parent)) == u); + if (u->child[0] != 0) { + assert(u->child[0]->parent == u); + assert(u->child[0] != u); + do_check_tree(m, u->child[0]); + } + if (u->child[1] != 0) { + assert(u->child[1]->parent == u); + assert(u->child[1] != u); + do_check_tree(m, u->child[1]); + } + if (u->child[0] != 0 && u->child[1] != 0) { + assert(chunksize(u->child[0]) < chunksize(u->child[1])); + } + } + u = u->fd; + } while (u != t); + assert(head != 0); +} + +/* Check all the chunks in a treebin. */ +static void do_check_treebin(mstate m, bindex_t i) { + tbinptr* tb = treebin_at(m, i); + tchunkptr t = *tb; + int empty = (m->treemap & (1U << i)) == 0; + if (t == 0) + assert(empty); + if (!empty) + do_check_tree(m, t); +} + +/* Check all the chunks in a smallbin. */ +static void do_check_smallbin(mstate m, bindex_t i) { + sbinptr b = smallbin_at(m, i); + mchunkptr p = b->bk; + unsigned int empty = (m->smallmap & (1U << i)) == 0; + if (p == b) + assert(empty); + if (!empty) { + for (; p != b; p = p->bk) { + size_t size = chunksize(p); + mchunkptr q; + /* each chunk claims to be free */ + do_check_free_chunk(m, p); + /* chunk belongs in bin */ + assert(small_index(size) == i); + assert(p->bk == b || chunksize(p->bk) == chunksize(p)); + /* chunk is followed by an inuse chunk */ + q = next_chunk(p); + if (q->head != FENCEPOST_HEAD) + do_check_inuse_chunk(m, q); + } + } +} + +/* Find x in a bin. Used in other check functions. */ +static int bin_find(mstate m, mchunkptr x) { + size_t size = chunksize(x); + if (is_small(size)) { + bindex_t sidx = small_index(size); + sbinptr b = smallbin_at(m, sidx); + if (smallmap_is_marked(m, sidx)) { + mchunkptr p = b; + do { + if (p == x) + return 1; + } while ((p = p->fd) != b); + } + } + else { + bindex_t tidx; + compute_tree_index(size, tidx); + if (treemap_is_marked(m, tidx)) { + tchunkptr t = *treebin_at(m, tidx); + size_t sizebits = size << leftshift_for_tree_index(tidx); + while (t != 0 && chunksize(t) != size) { + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + sizebits <<= 1; + } + if (t != 0) { + tchunkptr u = t; + do { + if (u == (tchunkptr)x) + return 1; + } while ((u = u->fd) != t); + } + } + } + return 0; +} + +/* Traverse each chunk and check it; return total */ +static size_t traverse_and_check(mstate m) { + size_t sum = 0; + if (is_initialized(m)) { + msegmentptr s = &m->seg; + sum += m->topsize + TOP_FOOT_SIZE; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + mchunkptr lastq = 0; + assert(pinuse(q)); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + sum += chunksize(q); + if (is_inuse(q)) { + assert(!bin_find(m, q)); + do_check_inuse_chunk(m, q); + } + else { + assert(q == m->dv || bin_find(m, q)); + assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ + do_check_free_chunk(m, q); + } + lastq = q; + q = next_chunk(q); + } + s = s->next; + } + } + return sum; +} + + +/* Check all properties of malloc_state. */ +static void do_check_malloc_state(mstate m) { + bindex_t i; + size_t total; + /* check bins */ + for (i = 0; i < NSMALLBINS; ++i) + do_check_smallbin(m, i); + for (i = 0; i < NTREEBINS; ++i) + do_check_treebin(m, i); + + if (m->dvsize != 0) { /* check dv chunk */ + do_check_any_chunk(m, m->dv); + assert(m->dvsize == chunksize(m->dv)); + assert(m->dvsize >= MIN_CHUNK_SIZE); + assert(bin_find(m, m->dv) == 0); + } + + if (m->top != 0) { /* check top chunk */ + do_check_top_chunk(m, m->top); + /*assert(m->topsize == chunksize(m->top)); redundant */ + assert(m->topsize > 0); + assert(bin_find(m, m->top) == 0); + } + + total = traverse_and_check(m); + assert(total <= m->footprint); + assert(m->footprint <= m->max_footprint); +} +#endif /* DEBUG */ + +/* ----------------------------- statistics ------------------------------ */ + +#if !NO_MALLINFO +static struct mallinfo internal_mallinfo(mstate m) { + struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + ensure_initialization(); + if (!PREACTION(m)) { + check_malloc_state(m); + if (is_initialized(m)) { + size_t nfree = SIZE_T_ONE; /* top always free */ + size_t mfree = m->topsize + TOP_FOOT_SIZE; + size_t sum = mfree; + msegmentptr s = &m->seg; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + size_t sz = chunksize(q); + sum += sz; + if (!is_inuse(q)) { + mfree += sz; + ++nfree; + } + q = next_chunk(q); + } + s = s->next; + } + + nm.arena = sum; + nm.ordblks = nfree; + nm.hblkhd = m->footprint - sum; + nm.usmblks = m->max_footprint; + nm.uordblks = m->footprint - mfree; + nm.fordblks = mfree; + nm.keepcost = m->topsize; + } + + POSTACTION(m); + } + return nm; +} +#endif /* !NO_MALLINFO */ + +#if !NO_MALLOC_STATS +static void internal_malloc_stats(mstate m) { + ensure_initialization(); + if (!PREACTION(m)) { + size_t maxfp = 0; + size_t fp = 0; + size_t used = 0; + check_malloc_state(m); + if (is_initialized(m)) { + msegmentptr s = &m->seg; + maxfp = m->max_footprint; + fp = m->footprint; + used = fp - (m->topsize + TOP_FOOT_SIZE); + + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + if (!is_inuse(q)) + used -= chunksize(q); + q = next_chunk(q); + } + s = s->next; + } + } + POSTACTION(m); /* drop lock */ + kprintf("max system bytes = %10lu\n", (unsigned long)(maxfp)); + kprintf("system bytes = %10lu\n", (unsigned long)(fp)); + kprintf("in use bytes = %10lu\n", (unsigned long)(used)); + } +} +#endif /* NO_MALLOC_STATS */ + +/* ----------------------- Operations on smallbins ----------------------- */ + +/* + Various forms of linking and unlinking are defined as macros. Even + the ones for trees, which are very long but have very short typical + paths. This is ugly but reduces reliance on inlining support of + compilers. +*/ + +/* Link a free chunk into a smallbin */ +#define insert_small_chunk(M, P, S) {\ + bindex_t I = small_index(S);\ + mchunkptr B = smallbin_at(M, I);\ + mchunkptr F = B;\ + assert(S >= MIN_CHUNK_SIZE);\ + if (!smallmap_is_marked(M, I))\ + mark_smallmap(M, I);\ + else if (RTCHECK(ok_address(M, B->fd)))\ + F = B->fd;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + B->fd = P;\ + F->bk = P;\ + P->fd = F;\ + P->bk = B;\ +} + +/* Unlink a chunk from a smallbin */ +#define unlink_small_chunk(M, P, S) {\ + mchunkptr F = P->fd;\ + mchunkptr B = P->bk;\ + bindex_t I = small_index(S);\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \ + if (B == F) {\ + clear_smallmap(M, I);\ + }\ + else if (RTCHECK(B == smallbin_at(M,I) ||\ + (ok_address(M, B) && B->fd == P))) {\ + F->bk = B;\ + B->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Unlink the first chunk from a smallbin */ +#define unlink_first_small_chunk(M, B, P, I) {\ + mchunkptr F = P->fd;\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (B == F) {\ + clear_smallmap(M, I);\ + }\ + else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\ + F->bk = B;\ + B->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Replace dv node, binning the old one */ +/* Used only when dvsize known to be small */ +#define replace_dv(M, P, S) {\ + size_t DVS = M->dvsize;\ + assert(is_small(DVS));\ + if (DVS != 0) {\ + mchunkptr DV = M->dv;\ + insert_small_chunk(M, DV, DVS);\ + }\ + M->dvsize = S;\ + M->dv = P;\ +} + +/* ------------------------- Operations on trees ------------------------- */ + +/* Insert chunk into tree */ +#define insert_large_chunk(M, X, S) {\ + tbinptr* H;\ + bindex_t I;\ + compute_tree_index(S, I);\ + H = treebin_at(M, I);\ + X->index = I;\ + X->child[0] = X->child[1] = 0;\ + if (!treemap_is_marked(M, I)) {\ + mark_treemap(M, I);\ + *H = X;\ + X->parent = (tchunkptr)H;\ + X->fd = X->bk = X;\ + }\ + else {\ + tchunkptr T = *H;\ + size_t K = S << leftshift_for_tree_index(I);\ + for (;;) {\ + if (chunksize(T) != S) {\ + tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ + K <<= 1;\ + if (*C != 0)\ + T = *C;\ + else if (RTCHECK(ok_address(M, C))) {\ + *C = X;\ + X->parent = T;\ + X->fd = X->bk = X;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + else {\ + tchunkptr F = T->fd;\ + if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ + T->fd = F->bk = X;\ + X->fd = F;\ + X->bk = T;\ + X->parent = 0;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + }\ + }\ +} + +/* + Unlink steps: + + 1. If x is a chained node, unlink it from its same-sized fd/bk links + and choose its bk node as its replacement. + 2. If x was the last node of its size, but not a leaf node, it must + be replaced with a leaf node (not merely one with an open left or + right), to make sure that lefts and rights of descendents + correspond properly to bit masks. We use the rightmost descendent + of x. We could use any other leaf, but this is easy to locate and + tends to counteract removal of leftmosts elsewhere, and so keeps + paths shorter than minimally guaranteed. This doesn't loop much + because on average a node in a tree is near the bottom. + 3. If x is the base of a chain (i.e., has parent links) relink + x's parent and children to x's replacement (or null if none). +*/ + +#define unlink_large_chunk(M, X) {\ + tchunkptr XP = X->parent;\ + tchunkptr R;\ + if (X->bk != X) {\ + tchunkptr F = X->fd;\ + R = X->bk;\ + if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\ + F->bk = R;\ + R->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else {\ + tchunkptr* RP;\ + if (((R = *(RP = &(X->child[1]))) != 0) ||\ + ((R = *(RP = &(X->child[0]))) != 0)) {\ + tchunkptr* CP;\ + while ((*(CP = &(R->child[1])) != 0) ||\ + (*(CP = &(R->child[0])) != 0)) {\ + R = *(RP = CP);\ + }\ + if (RTCHECK(ok_address(M, RP)))\ + *RP = 0;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + }\ + if (XP != 0) {\ + tbinptr* H = treebin_at(M, X->index);\ + if (X == *H) {\ + if ((*H = R) == 0) \ + clear_treemap(M, X->index);\ + }\ + else if (RTCHECK(ok_address(M, XP))) {\ + if (XP->child[0] == X) \ + XP->child[0] = R;\ + else \ + XP->child[1] = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + if (R != 0) {\ + if (RTCHECK(ok_address(M, R))) {\ + tchunkptr C0, C1;\ + R->parent = XP;\ + if ((C0 = X->child[0]) != 0) {\ + if (RTCHECK(ok_address(M, C0))) {\ + R->child[0] = C0;\ + C0->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + if ((C1 = X->child[1]) != 0) {\ + if (RTCHECK(ok_address(M, C1))) {\ + R->child[1] = C1;\ + C1->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ +} + +/* Relays to large vs small bin operations */ + +#define insert_chunk(M, P, S)\ + if (is_small(S)) insert_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } + +#define unlink_chunk(M, P, S)\ + if (is_small(S)) unlink_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } + + +/* Relays to internal calls to malloc/free from realloc, memalign etc */ + +#if ONLY_MSPACES +#define internal_malloc(m, b) mspace_malloc(m, b) +#define internal_free(m, mem) mspace_free(m,mem); +#else /* ONLY_MSPACES */ +#if MSPACES +#define internal_malloc(m, b)\ + ((m == gm)? dlmalloc(b) : mspace_malloc(m, b)) +#define internal_free(m, mem)\ + if (m == gm) dlfree(mem); else mspace_free(m,mem); +#else /* MSPACES */ +#define internal_malloc(m, b) dlmalloc(b) +#define internal_free(m, mem) dlfree(mem) +#endif /* MSPACES */ +#endif /* ONLY_MSPACES */ + +/* ----------------------- Direct-mmapping chunks ----------------------- */ + +/* + Directly mmapped chunks are set up with an offset to the start of + the mmapped region stored in the prev_foot field of the chunk. This + allows reconstruction of the required argument to MUNMAP when freed, + and also allows adjustment of the returned chunk to meet alignment + requirements (especially in memalign). +*/ + +/* Malloc using mmap */ +static void* mmap_alloc(mstate m, size_t nb) { + size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + if (m->footprint_limit != 0) { + size_t fp = m->footprint + mmsize; + if (fp <= m->footprint || fp > m->footprint_limit) + return 0; + } + if (mmsize > nb) { /* Check for wrap around 0 */ + char* mm = (char*)(dlmalloc_requires_more_vespene_gas(mmsize)); + if (mm != CMFAIL) { + size_t offset = align_offset(chunk2mem(mm)); + size_t psize = mmsize - offset - MMAP_FOOT_PAD; + mchunkptr p = (mchunkptr)(mm + offset); + p->prev_foot = offset; + p->head = psize; + mark_inuse_foot(m, p, psize); + chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; + + if (m->least_addr == 0 || mm < m->least_addr) + m->least_addr = mm; + if ((m->footprint += mmsize) > m->max_footprint) + m->max_footprint = m->footprint; + assert(is_aligned(chunk2mem(p))); + check_mmapped_chunk(m, p); + return chunk2mem(p); + } + } + return 0; +} + +/* Realloc using mmap */ +static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { + size_t oldsize = chunksize(oldp); + (void)flags; /* placate people compiling -Wunused */ + if (is_small(nb)) /* Can't shrink mmap regions below small size */ + return 0; + /* Keep old chunk if big enough but not too big */ + if (oldsize >= nb + SIZE_T_SIZE && + (oldsize - nb) <= (mparams.granularity << 1)) + return oldp; + else { + size_t offset = oldp->prev_foot; + size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; + size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + char* cp = (char*)CALL_MREMAP((char*)oldp - offset, + oldmmsize, newmmsize, flags); + if (cp != CMFAIL) { + mchunkptr newp = (mchunkptr)(cp + offset); + size_t psize = newmmsize - offset - MMAP_FOOT_PAD; + newp->head = psize; + mark_inuse_foot(m, newp, psize); + chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; + + if (cp < m->least_addr) + m->least_addr = cp; + if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) + m->max_footprint = m->footprint; + check_mmapped_chunk(m, newp); + return newp; + } + } + return 0; +} + + +/* -------------------------- mspace management -------------------------- */ + +/* Initialize top chunk and its size */ +static void init_top(mstate m, mchunkptr p, size_t psize) { + /* Ensure alignment */ + size_t offset = align_offset(chunk2mem(p)); + p = (mchunkptr)((char*)p + offset); + psize -= offset; + + m->top = p; + m->topsize = psize; + p->head = psize | PINUSE_BIT; + /* set size of fake trailing chunk holding overhead space only once */ + chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; + m->trim_check = mparams.trim_threshold; /* reset on each update */ +} + +/* Initialize bins for a new mstate that is otherwise zeroed out */ +static void init_bins(mstate m) { + /* Establish circular links for smallbins */ + bindex_t i; + for (i = 0; i < NSMALLBINS; ++i) { + sbinptr bin = smallbin_at(m,i); + bin->fd = bin->bk = bin; + } +} + +#if PROCEED_ON_ERROR + +/* default corruption action */ +static void reset_on_error(mstate m) { + int i; + ++malloc_corruption_error_count; + /* Reinitialize fields to forget about all memory */ + m->smallmap = m->treemap = 0; + m->dvsize = m->topsize = 0; + m->seg.base = 0; + m->seg.size = 0; + m->seg.next = 0; + m->top = m->dv = 0; + for (i = 0; i < NTREEBINS; ++i) + *treebin_at(m, i) = 0; + init_bins(m); +} +#endif /* PROCEED_ON_ERROR */ + +/* Allocate chunk and prepend remainder with chunk in successor base. */ +static void* prepend_alloc(mstate m, char* newbase, char* oldbase, + size_t nb) { + mchunkptr p = align_as_chunk(newbase); + mchunkptr oldfirst = align_as_chunk(oldbase); + size_t psize = (char*)oldfirst - (char*)p; + mchunkptr q = chunk_plus_offset(p, nb); + size_t qsize = psize - nb; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + + assert((char*)oldfirst > (char*)q); + assert(pinuse(oldfirst)); + assert(qsize >= MIN_CHUNK_SIZE); + + /* consolidate remainder with first chunk of old base */ + if (oldfirst == m->top) { + size_t tsize = m->topsize += qsize; + m->top = q; + q->head = tsize | PINUSE_BIT; + check_top_chunk(m, q); + } + else if (oldfirst == m->dv) { + size_t dsize = m->dvsize += qsize; + m->dv = q; + set_size_and_pinuse_of_free_chunk(q, dsize); + } + else { + if (!is_inuse(oldfirst)) { + size_t nsize = chunksize(oldfirst); + unlink_chunk(m, oldfirst, nsize); + oldfirst = chunk_plus_offset(oldfirst, nsize); + qsize += nsize; + } + set_free_with_pinuse(q, qsize, oldfirst); + insert_chunk(m, q, qsize); + check_free_chunk(m, q); + } + + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); +} + +/* Add a segment to hold a new noncontiguous region */ +static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { + /* Determine locations and sizes of segment, fenceposts, old top */ + char* old_top = (char*)m->top; + msegmentptr oldsp = segment_holding(m, old_top); + char* old_end = oldsp->base + oldsp->size; + size_t ssize = pad_request(sizeof(struct malloc_segment)); + char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + size_t offset = align_offset(chunk2mem(rawsp)); + char* asp = rawsp + offset; + char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; + mchunkptr sp = (mchunkptr)csp; + msegmentptr ss = (msegmentptr)(chunk2mem(sp)); + mchunkptr tnext = chunk_plus_offset(sp, ssize); + mchunkptr p = tnext; + int nfences = 0; + + /* reset top to new space */ + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + + /* Set up segment record */ + assert(is_aligned(ss)); + set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); + *ss = m->seg; /* Push current record */ + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmapped; + m->seg.next = ss; + + /* Insert trailing fenceposts */ + for (;;) { + mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); + p->head = FENCEPOST_HEAD; + ++nfences; + if ((char*)(&(nextp->head)) < old_end) + p = nextp; + else + break; + } + assert(nfences >= 2); + + /* Insert the rest of old top into a bin as an ordinary free chunk */ + if (csp != old_top) { + mchunkptr q = (mchunkptr)old_top; + size_t psize = csp - old_top; + mchunkptr tn = chunk_plus_offset(q, psize); + set_free_with_pinuse(q, psize, tn); + insert_chunk(m, q, psize); + } + + check_top_chunk(m, m->top); +} + +/* -------------------------- System allocation -------------------------- */ + +/* Get memory from system using MORECORE or MMAP */ +static void* sys_alloc(mstate m, size_t nb) { + char* tbase = CMFAIL; + size_t tsize = 0; + flag_t mmap_flag = 0; + size_t asize; /* allocation size */ + + ensure_initialization(); + + /* Directly map large chunks, but only if already initialized */ + if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) { + void* mem = mmap_alloc(m, nb); + if (mem != 0) + return mem; + } + + asize = granularity_align(nb + SYS_ALLOC_PADDING); + if (asize <= nb) + return 0; /* wraparound */ + if (m->footprint_limit != 0) { + size_t fp = m->footprint + asize; + if (fp <= m->footprint || fp > m->footprint_limit) + return 0; + } + + /* + Try getting memory in any of three ways (in most-preferred to + least-preferred order): + 1. A call to MORECORE that can normally contiguously extend memory. + (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or + or main space is mmapped or a previous contiguous call failed) + 2. A call to MMAP new space (disabled if not HAVE_MMAP). + Note that under the default settings, if MORECORE is unable to + fulfill a request, and HAVE_MMAP is true, then mmap is + used as a noncontiguous system allocator. This is a useful backup + strategy for systems with holes in address spaces -- in this case + sbrk cannot contiguously expand the heap, but mmap may be able to + find space. + 3. A call to MORECORE that cannot usually contiguously extend memory. + (disabled if not HAVE_MORECORE) + + In all cases, we need to request enough bytes from system to ensure + we can malloc nb bytes upon success, so pad with enough space for + top_foot, plus alignment-pad to make sure we don't lose bytes if + not on boundary, and round this up to a granularity unit. + */ + + if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { + char* br = CMFAIL; + size_t ssize = asize; /* sbrk call size */ + msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); + ACQUIRE_MALLOC_GLOBAL_LOCK(); + + if (ss == 0) { /* First time through or recovery */ + char* base = (char*)CALL_MORECORE(0); + if (base != CMFAIL) { + size_t fp; + /* Adjust to end on a page boundary */ + if (!is_page_aligned(base)) + ssize += (page_align((size_t)base) - (size_t)base); + fp = m->footprint + ssize; /* recheck limits */ + if (ssize > nb && ssize < HALF_MAX_SIZE_T && + (m->footprint_limit == 0 || + (fp > m->footprint && fp <= m->footprint_limit)) && + (br = (char*)(CALL_MORECORE(ssize))) == base) { + tbase = base; + tsize = ssize; + } + } + } + else { + /* Subtract out existing available top space from MORECORE request. */ + ssize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); + /* Use mem here only if it did continuously extend old space */ + if (ssize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(ssize))) == ss->base+ss->size) { + tbase = br; + tsize = ssize; + } + } + + if (tbase == CMFAIL) { /* Cope with partial failure */ + if (br != CMFAIL) { /* Try to use/extend the space we did get */ + if (ssize < HALF_MAX_SIZE_T && + ssize < nb + SYS_ALLOC_PADDING) { + size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - ssize); + if (esize < HALF_MAX_SIZE_T) { + char* end = (char*)CALL_MORECORE(esize); + if (end != CMFAIL) + ssize += esize; + else { /* Can't use; try to release */ + (void) CALL_MORECORE(-ssize); + br = CMFAIL; + } + } + } + } + if (br != CMFAIL) { /* Use the space we did get */ + tbase = br; + tsize = ssize; + } + else + disable_contiguous(m); /* Don't try contiguous path in the future */ + } + + RELEASE_MALLOC_GLOBAL_LOCK(); + } + + if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ + char* mp = (char*)(dlmalloc_requires_more_vespene_gas(asize)); + if (mp != CMFAIL) { + tbase = mp; + tsize = asize; + mmap_flag = USE_MMAP_BIT; + } + } + + if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ + if (asize < HALF_MAX_SIZE_T) { + char* br = CMFAIL; + char* end = CMFAIL; + ACQUIRE_MALLOC_GLOBAL_LOCK(); + br = (char*)(CALL_MORECORE(asize)); + end = (char*)(CALL_MORECORE(0)); + RELEASE_MALLOC_GLOBAL_LOCK(); + if (br != CMFAIL && end != CMFAIL && br < end) { + size_t ssize = end - br; + if (ssize > nb + TOP_FOOT_SIZE) { + tbase = br; + tsize = ssize; + } + } + } + } + + if (tbase != CMFAIL) { + + if ((m->footprint += tsize) > m->max_footprint) + m->max_footprint = m->footprint; + + if (!is_initialized(m)) { /* first-time initialization */ + if (m->least_addr == 0 || tbase < m->least_addr) + m->least_addr = tbase; + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmap_flag; + m->magic = mparams.magic; + m->release_checks = MAX_RELEASE_CHECK_RATE; + init_bins(m); +#if !ONLY_MSPACES + if (is_global(m)) + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + else +#endif + { + /* Offset top by embedded malloc_state */ + mchunkptr mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); + } + } + + else { + /* Try to merge with an existing segment */ + msegmentptr sp = &m->seg; + /* Only consider most recent segment if traversal suppressed */ + while (sp != 0 && tbase != sp->base + sp->size) + sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & USE_MMAP_BIT) == mmap_flag && + segment_holds(sp, m->top)) { /* append */ + sp->size += tsize; + init_top(m, m->top, m->topsize + tsize); + } + else { + if (tbase < m->least_addr) + m->least_addr = tbase; + sp = &m->seg; + while (sp != 0 && sp->base != tbase + tsize) + sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & USE_MMAP_BIT) == mmap_flag) { + char* oldbase = sp->base; + sp->base = tbase; + sp->size += tsize; + return prepend_alloc(m, tbase, oldbase, nb); + } + else + add_segment(m, tbase, tsize, mmap_flag); + } + } + + if (nb < m->topsize) { /* Allocate from new or extended top space */ + size_t rsize = m->topsize -= nb; + mchunkptr p = m->top; + mchunkptr r = m->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + check_top_chunk(m, m->top); + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); + } + } + + MALLOC_FAILURE_ACTION; + return 0; +} + +/* ----------------------- system deallocation -------------------------- */ + +/* Unmap and unlink any mmapped segments that don't contain used chunks */ +static size_t release_unused_segments(mstate m) { + size_t released = 0; + int nsegs = 0; + msegmentptr pred = &m->seg; + msegmentptr sp = pred->next; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + msegmentptr next = sp->next; + ++nsegs; + if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { + mchunkptr p = align_as_chunk(base); + size_t psize = chunksize(p); + /* Can unmap if first chunk holds entire segment and not pinned */ + if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { + tchunkptr tp = (tchunkptr)p; + assert(segment_holds(sp, (char*)sp)); + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } + else { + unlink_large_chunk(m, tp); + } + if (CALL_MUNMAP(base, size) == 0) { + released += size; + m->footprint -= size; + /* unlink obsoleted record */ + sp = pred; + sp->next = next; + } + else { /* back out if cannot unmap */ + insert_large_chunk(m, tp, psize); + } + } + } + if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ + break; + pred = sp; + sp = next; + } + /* Reset check counter */ + m->release_checks = (((size_t) nsegs > (size_t) MAX_RELEASE_CHECK_RATE)? + (size_t) nsegs : (size_t) MAX_RELEASE_CHECK_RATE); + return released; +} + +static int sys_trim(mstate m, size_t pad) { + size_t released = 0; + ensure_initialization(); + if (pad < MAX_REQUEST && is_initialized(m)) { + pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ + + if (m->topsize > pad) { + /* Shrink top space in granularity-size units, keeping at least one */ + size_t unit = mparams.granularity; + size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - + SIZE_T_ONE) * unit; + msegmentptr sp = segment_holding(m, (char*)m->top); + + if (!is_extern_segment(sp)) { + if (is_mmapped_segment(sp)) { + if (HAVE_MMAP && + sp->size >= extra && + !has_segment_link(m, sp)) { /* can't shrink if pinned */ + size_t newsize = sp->size - extra; + (void)newsize; /* placate people compiling -Wunused-variable */ + /* Prefer mremap, fall back to munmap */ + if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || + (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { + released = extra; + } + } + } + else if (HAVE_MORECORE) { + if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ + extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; + ACQUIRE_MALLOC_GLOBAL_LOCK(); + { + /* Make sure end of memory is where we last set it. */ + char* old_br = (char*)(CALL_MORECORE(0)); + if (old_br == sp->base + sp->size) { + char* rel_br = (char*)(CALL_MORECORE(-extra)); + char* new_br = (char*)(CALL_MORECORE(0)); + if (rel_br != CMFAIL && new_br < old_br) + released = old_br - new_br; + } + } + RELEASE_MALLOC_GLOBAL_LOCK(); + } + } + + if (released != 0) { + sp->size -= released; + m->footprint -= released; + init_top(m, m->top, m->topsize - released); + check_top_chunk(m, m->top); + } + } + + /* Unmap any unused mmapped segments */ + if (HAVE_MMAP) + released += release_unused_segments(m); + + /* On failure, disable autotrim to avoid repeated failed future calls */ + if (released == 0 && m->topsize > m->trim_check) + m->trim_check = MAX_SIZE_T; + } + + return (released != 0)? 1 : 0; +} + +/* Consolidate and bin a chunk. Differs from exported versions + of free mainly in that the chunk need not be marked as inuse. +*/ +static void dispose_chunk(mstate m, mchunkptr p, size_t psize) { + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + mchunkptr prev; + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + m->footprint -= psize; + return; + } + prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */ + if (p != m->dv) { + unlink_chunk(m, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + m->dvsize = psize; + set_free_with_pinuse(p, psize, next); + return; + } + } + else { + CORRUPTION_ERROR_ACTION(m); + return; + } + } + if (RTCHECK(ok_address(m, next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == m->top) { + size_t tsize = m->topsize += psize; + m->top = p; + p->head = tsize | PINUSE_BIT; + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } + return; + } + else if (next == m->dv) { + size_t dsize = m->dvsize += psize; + m->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + return; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(m, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == m->dv) { + m->dvsize = psize; + return; + } + } + } + else { + set_free_with_pinuse(p, psize, next); + } + insert_chunk(m, p, psize); + } + else { + CORRUPTION_ERROR_ACTION(m); + } +} + +/* ---------------------------- malloc --------------------------- */ + +/* allocate a large request from the best fitting chunk in a treebin */ +static void* tmalloc_large(mstate m, size_t nb) { + tchunkptr v = 0; + size_t rsize = -nb; /* Unsigned negation */ + tchunkptr t; + bindex_t idx; + compute_tree_index(nb, idx); + if ((t = *treebin_at(m, idx)) != 0) { + /* Traverse tree for this bin looking for node with size == nb */ + size_t sizebits = nb << leftshift_for_tree_index(idx); + tchunkptr rst = 0; /* The deepest untaken right subtree */ + for (;;) { + tchunkptr rt; + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + v = t; + if ((rsize = trem) == 0) + break; + } + rt = t->child[1]; + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + if (rt != 0 && rt != t) + rst = rt; + if (t == 0) { + t = rst; /* set t to least subtree holding sizes > nb */ + break; + } + sizebits <<= 1; + } + } + if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ + binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; + if (leftbits != 0) { + bindex_t i; + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + t = *treebin_at(m, i); + } + } + + while (t != 0) { /* find smallest of tree or subtree */ + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + t = leftmost_child(t); + } + + /* If dv is a better fit, return 0 so malloc will use it */ + if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { + if (RTCHECK(ok_address(m, v))) { /* split */ + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + insert_chunk(m, r, rsize); + } + return chunk2mem(v); + } + } + CORRUPTION_ERROR_ACTION(m); + } + return 0; +} + +/* allocate a small request from the best fitting chunk in a treebin */ +static void* tmalloc_small(mstate m, size_t nb) { + tchunkptr t, v; + size_t rsize; + bindex_t i; + binmap_t leastbit = least_bit(m->treemap); + compute_bit2idx(leastbit, i); + v = t = *treebin_at(m, i); + rsize = chunksize(t) - nb; + + while ((t = leftmost_child(t)) != 0) { + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + } + + if (RTCHECK(ok_address(m, v))) { + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(m, r, rsize); + } + return chunk2mem(v); + } + } + + CORRUPTION_ERROR_ACTION(m); + return 0; +} + +#if !ONLY_MSPACES + +void* dlmalloc(size_t bytes) { + /* + Basic algorithm: + If a small request (< 256 bytes minus per-chunk overhead): + 1. If one exists, use a remainderless chunk in associated smallbin. + (Remainderless means that there are too few excess bytes to + represent as a chunk.) + 2. If it is big enough, use the dv chunk, which is normally the + chunk adjacent to the one used for the most recent small request. + 3. If one exists, split the smallest available chunk in a bin, + saving remainder in dv. + 4. If it is big enough, use the top chunk. + 5. If available, get memory from system and use it + Otherwise, for a large request: + 1. Find the smallest available binned chunk that fits, and use it + if it is better fitting than dv chunk, splitting if necessary. + 2. If better fitting than any binned chunk, use the dv chunk. + 3. If it is big enough, use the top chunk. + 4. If request size >= mmap threshold, try to directly mmap this chunk. + 5. If available, get memory from system and use it + + The ugly goto's here ensure that postaction occurs along all paths. + */ + +#if USE_LOCKS + ensure_initialization(); /* initialize in sys_alloc if not using locks */ +#endif + + if (!PREACTION(gm)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = gm->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(gm, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(gm, b, p, idx); + set_inuse_and_pinuse(gm, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb > gm->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(gm, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(gm, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(gm, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(gm, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + + if (nb <= gm->dvsize) { + size_t rsize = gm->dvsize - nb; + mchunkptr p = gm->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = gm->dv = chunk_plus_offset(p, nb); + gm->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + } + else { /* exhaust dv */ + size_t dvs = gm->dvsize; + gm->dvsize = 0; + gm->dv = 0; + set_inuse_and_pinuse(gm, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb < gm->topsize) { /* Split top */ + size_t rsize = gm->topsize -= nb; + mchunkptr p = gm->top; + mchunkptr r = gm->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + mem = chunk2mem(p); + check_top_chunk(gm, gm->top); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + mem = sys_alloc(gm, nb); + POSTACTION(gm); + if (mem == MAP_FAILED && weaken(__oom_hook)) { + weaken(__oom_hook)(bytes); + } + return mem; + + postaction: + POSTACTION(gm); + return mem; + } + + return 0; +} + +/* ---------------------------- free --------------------------- */ + +void dlfree(void* mem) { + /* + Consolidate freed chunks with preceeding or succeeding bordering + free chunks, if they exist, and then place in a bin. Intermixed + with special cases for top, dv, mmapped chunks, and usage errors. + */ + + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } +#else /* FOOTERS */ +#define fm gm +#endif /* FOOTERS */ + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + + if (is_small(psize)) { + insert_small_chunk(fm, p, psize); + check_free_chunk(fm, p); + } + else { + tchunkptr tp = (tchunkptr)p; + insert_large_chunk(fm, tp, psize); + check_free_chunk(fm, p); + if (--fm->release_checks == 0) + release_unused_segments(fm); + } + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +#if !FOOTERS +#undef fm +#endif /* FOOTERS */ +} + +void* dlcalloc(size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = dlmalloc(req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + bzero(mem, req); + return mem; +} + +#endif /* !ONLY_MSPACES */ + +/* ------------ Internal support for realloc, memalign, etc -------------- */ + +/* Try to realloc; only in-place unless can_move true */ +static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb, + int can_move) { + mchunkptr newp = 0; + size_t oldsize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, oldsize); + if (RTCHECK(ok_address(m, p) && ok_inuse(p) && + ok_next(p, next) && ok_pinuse(next))) { + if (is_mmapped(p)) { + newp = mmap_resize(m, p, nb, can_move); + } + else if (oldsize >= nb) { /* already big enough */ + size_t rsize = oldsize - nb; + if (rsize >= MIN_CHUNK_SIZE) { /* split off remainder */ + mchunkptr r = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, r, rsize); + dispose_chunk(m, r, rsize); + } + newp = p; + } + else if (next == m->top) { /* extend into top */ + if (oldsize + m->topsize > nb) { + size_t newsize = oldsize + m->topsize; + size_t newtopsize = newsize - nb; + mchunkptr newtop = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + newtop->head = newtopsize |PINUSE_BIT; + m->top = newtop; + m->topsize = newtopsize; + newp = p; + } + } + else if (next == m->dv) { /* extend into dv */ + size_t dvs = m->dvsize; + if (oldsize + dvs >= nb) { + size_t dsize = oldsize + dvs - nb; + if (dsize >= MIN_CHUNK_SIZE) { + mchunkptr r = chunk_plus_offset(p, nb); + mchunkptr n = chunk_plus_offset(r, dsize); + set_inuse(m, p, nb); + set_size_and_pinuse_of_free_chunk(r, dsize); + clear_pinuse(n); + m->dvsize = dsize; + m->dv = r; + } + else { /* exhaust dv */ + size_t newsize = oldsize + dvs; + set_inuse(m, p, newsize); + m->dvsize = 0; + m->dv = 0; + } + newp = p; + } + } + else if (!cinuse(next)) { /* extend into next free chunk */ + size_t nextsize = chunksize(next); + if (oldsize + nextsize >= nb) { + size_t rsize = oldsize + nextsize - nb; + unlink_chunk(m, next, nextsize); + if (rsize < MIN_CHUNK_SIZE) { + size_t newsize = oldsize + nextsize; + set_inuse(m, p, newsize); + } + else { + mchunkptr r = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, r, rsize); + dispose_chunk(m, r, rsize); + } + newp = p; + } + } + } + else { + USAGE_ERROR_ACTION(m, chunk2mem(p)); + } + return newp; +} + +static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { + void* mem = 0; + if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ + alignment = MIN_CHUNK_SIZE; + if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ + size_t a = MALLOC_ALIGNMENT << 1; + while (a < alignment) a <<= 1; + alignment = a; + } + if (bytes >= MAX_REQUEST - alignment) { + if (m != 0) { /* Test isn't needed but avoids compiler warning */ + MALLOC_FAILURE_ACTION; + } + } + else { + size_t nb = request2size(bytes); + size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; + mem = internal_malloc(m, req); + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (PREACTION(m)) + return 0; + if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */ + /* + Find an aligned spot inside chunk. Since we need to give + back leading space in a chunk of at least MIN_CHUNK_SIZE, if + the first calculation places us at a spot with less than + MIN_CHUNK_SIZE leader, we can move to the next aligned spot. + We've allocated enough total room so that this is always + possible. + */ + char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment - + SIZE_T_ONE)) & + -alignment)); + char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? + br : br+alignment; + mchunkptr newp = (mchunkptr)pos; + size_t leadsize = pos - (char*)(p); + size_t newsize = chunksize(p) - leadsize; + + if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ + newp->prev_foot = p->prev_foot + leadsize; + newp->head = newsize; + } + else { /* Otherwise, give back leader, use the rest */ + set_inuse(m, newp, newsize); + set_inuse(m, p, leadsize); + dispose_chunk(m, p, leadsize); + } + p = newp; + } + + /* Give back spare room at the end */ + if (!is_mmapped(p)) { + size_t size = chunksize(p); + if (size > nb + MIN_CHUNK_SIZE) { + size_t remainder_size = size - nb; + mchunkptr remainder = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, remainder, remainder_size); + dispose_chunk(m, remainder, remainder_size); + } + } + + mem = chunk2mem(p); + assert (chunksize(p) >= nb); + assert(((size_t)mem & (alignment - 1)) == 0); + check_inuse_chunk(m, p); + POSTACTION(m); + } + } + return mem; +} + +/* + Common support for independent_X routines, handling + all of the combinations that can result. + The opts arg has: + bit 0 set if all elements are same size (using sizes[0]) + bit 1 set if elements should be zeroed +*/ +static void** ialloc(mstate m, + size_t n_elements, + size_t* sizes, + int opts, + void* chunks[]) { + + size_t element_size; /* chunksize of each element, if all same */ + size_t contents_size; /* total size of elements */ + size_t array_size; /* request size of pointer array */ + void* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + size_t remainder_size; /* remaining bytes while splitting */ + void** marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + flag_t was_enabled; /* to disable mmap */ + size_t size; + size_t i; + + ensure_initialization(); + /* compute array length, if needed */ + if (chunks != 0) { + if (n_elements == 0) + return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } + else { + /* if empty req, must still return chunk representing empty array */ + if (n_elements == 0) + return (void**)internal_malloc(m, 0); + marray = 0; + array_size = request2size(n_elements * (sizeof(void*))); + } + + /* compute total element size */ + if (opts & 0x1) { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } + else { /* add up all the sizes */ + element_size = 0; + contents_size = 0; + for (i = 0; i != n_elements; ++i) + contents_size += request2size(sizes[i]); + } + + size = contents_size + array_size; + + /* + Allocate the aggregate chunk. First disable direct-mmapping so + malloc won't use it, since we would not be able to later + free/realloc space internal to a segregated mmap region. + */ + was_enabled = use_mmap(m); + disable_mmap(m); + mem = internal_malloc(m, size - CHUNK_OVERHEAD); + if (was_enabled) + enable_mmap(m); + if (mem == 0) + return 0; + + if (PREACTION(m)) return 0; + p = mem2chunk(mem); + remainder_size = chunksize(p); + + assert(!is_mmapped(p)); + + if (opts & 0x2) { /* optionally clear the elements */ + bzero((size_t*)mem, remainder_size - SIZE_T_SIZE - array_size); + } + + /* If not provided, allocate the pointer array as final part of chunk */ + if (marray == 0) { + size_t array_chunk_size; + array_chunk = chunk_plus_offset(p, contents_size); + array_chunk_size = remainder_size - contents_size; + marray = (void**) (chunk2mem(array_chunk)); + set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); + remainder_size = contents_size; + } + + /* split out elements */ + for (i = 0; ; ++i) { + marray[i] = chunk2mem(p); + if (i != n_elements-1) { + if (element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_size_and_pinuse_of_inuse_chunk(m, p, size); + p = chunk_plus_offset(p, size); + } + else { /* the final element absorbs any overallocation slop */ + set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); + break; + } + } + +#if DEBUG + if (marray != chunks) { + /* final element must have exactly exhausted chunk */ + if (element_size != 0) { + assert(remainder_size == element_size); + } + else { + assert(remainder_size == request2size(sizes[i])); + } + check_inuse_chunk(m, mem2chunk(marray)); + } + for (i = 0; i != n_elements; ++i) + check_inuse_chunk(m, mem2chunk(marray[i])); + +#endif /* DEBUG */ + + POSTACTION(m); + return marray; +} + +/* Try to free all pointers in the given array. + Note: this could be made faster, by delaying consolidation, + at the price of disabling some user integrity checks, We + still optimize some consolidations by combining adjacent + chunks before freeing, which will occur often if allocated + with ialloc or the array is sorted. +*/ +static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) { + size_t unfreed = 0; + if (!PREACTION(m)) { + void** a; + void** fence = &(array[nelem]); + for (a = array; a != fence; ++a) { + void* mem = *a; + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + size_t psize = chunksize(p); +#if FOOTERS + if (get_mstate_for(p) != m) { + ++unfreed; + continue; + } +#endif + check_inuse_chunk(m, p); + *a = 0; + if (RTCHECK(ok_address(m, p) && ok_inuse(p))) { + void ** b = a + 1; /* try to merge with next chunk */ + mchunkptr next = next_chunk(p); + if (b != fence && *b == chunk2mem(next)) { + size_t newsize = chunksize(next) + psize; + set_inuse(m, p, newsize); + *b = chunk2mem(p); + } + else + dispose_chunk(m, p, psize); + } + else { + CORRUPTION_ERROR_ACTION(m); + break; + } + } + } + if (should_trim(m, m->topsize)) + sys_trim(m, 0); + POSTACTION(m); + } + return unfreed; +} + +/* Traversal */ +#if MALLOC_INSPECT_ALL +static void internal_inspect_all(mstate m, + void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg) { + if (is_initialized(m)) { + mchunkptr top = m->top; + msegmentptr s; + for (s = &m->seg; s != 0; s = s->next) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) { + mchunkptr next = next_chunk(q); + size_t sz = chunksize(q); + size_t used; + void* start; + if (is_inuse(q)) { + used = sz - CHUNK_OVERHEAD; /* must not be mmapped */ + start = chunk2mem(q); + } + else { + used = 0; + if (is_small(sz)) { /* offset by possible bookkeeping */ + start = (void*)((char*)q + sizeof(struct malloc_chunk)); + } + else { + start = (void*)((char*)q + sizeof(struct malloc_tree_chunk)); + } + } + if (start < (void*)next) /* skip if all space is bookkeeping */ + handler(start, next, used, arg); + if (q == top) + break; + q = next; + } + } + } +} +#endif /* MALLOC_INSPECT_ALL */ + +/* ------------------ Exported realloc, memalign, etc -------------------- */ + +#if !ONLY_MSPACES + +void* dlrealloc(void* oldmem, size_t bytes) { + void* mem = 0; + if (oldmem == 0) { + mem = dlmalloc(bytes); + } + else if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + } +#ifdef REALLOC_ZERO_BYTES_FREES + else if (bytes == 0) { + dlfree(oldmem); + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if ! FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); + POSTACTION(m); + if (newp != 0) { + check_inuse_chunk(m, newp); + mem = chunk2mem(newp); + } + else { + mem = internal_malloc(m, bytes); + if (mem != 0) { + size_t oc = chunksize(oldp) - overhead_for(oldp); + memcpy(mem, oldmem, (oc < bytes)? oc : bytes); + internal_free(m, oldmem); + } + } + } + } + return mem; +} + +void* dlrealloc_in_place(void* oldmem, size_t bytes) { + void* mem = 0; + if (oldmem != 0) { + if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + } + else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if ! FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); + POSTACTION(m); + if (newp == oldp) { + check_inuse_chunk(m, newp); + mem = oldmem; + } + } + } + } + return mem; +} + +void* dlmemalign(size_t alignment, size_t bytes) { + if (alignment <= MALLOC_ALIGNMENT) { + return dlmalloc(bytes); + } + return internal_memalign(gm, alignment, bytes); +} + +int dlposix_memalign(void** pp, size_t alignment, size_t bytes) { + void* mem = 0; + if (alignment == MALLOC_ALIGNMENT) + mem = dlmalloc(bytes); + else { + size_t d = alignment / sizeof(void*); + size_t r = alignment % sizeof(void*); + if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0) + return EINVAL; + else if (bytes <= MAX_REQUEST - alignment) { + if (alignment < MIN_CHUNK_SIZE) + alignment = MIN_CHUNK_SIZE; + mem = internal_memalign(gm, alignment, bytes); + } + } + if (!mem) { + return ENOMEM; + } else { + *pp = mem; + return 0; + } +} + +void* dlvalloc(size_t bytes) { + size_t pagesz; + ensure_initialization(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, bytes); +} + +void* dlpvalloc(size_t bytes) { + size_t pagesz; + ensure_initialization(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); +} + +void** dlindependent_calloc(size_t n_elements, size_t elem_size, + void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + return ialloc(gm, n_elements, &sz, 3, chunks); +} + +void** dlindependent_comalloc(size_t n_elements, size_t sizes[], + void* chunks[]) { + return ialloc(gm, n_elements, sizes, 0, chunks); +} + +size_t dlbulk_free(void* array[], size_t nelem) { + return internal_bulk_free(gm, array, nelem); +} + +#if MALLOC_INSPECT_ALL +void dlmalloc_inspect_all(void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg) { + ensure_initialization(); + if (!PREACTION(gm)) { + internal_inspect_all(gm, handler, arg); + POSTACTION(gm); + } +} +#endif /* MALLOC_INSPECT_ALL */ + +int dlmalloc_trim(size_t pad) { + int result = 0; + ensure_initialization(); + if (!PREACTION(gm)) { + result = sys_trim(gm, pad); + POSTACTION(gm); + } + return result; +} + +size_t dlmalloc_footprint(void) { + return gm->footprint; +} + +size_t dlmalloc_max_footprint(void) { + return gm->max_footprint; +} + +size_t dlmalloc_footprint_limit(void) { + size_t maf = gm->footprint_limit; + return maf == 0 ? MAX_SIZE_T : maf; +} + +size_t dlmalloc_set_footprint_limit(size_t bytes) { + size_t result; /* invert sense of 0 */ + if (bytes == 0) + result = granularity_align(1); /* Use minimal size */ + if (bytes == MAX_SIZE_T) + result = 0; /* disable */ + else + result = granularity_align(bytes); + return gm->footprint_limit = result; +} + +#if !NO_MALLINFO +struct mallinfo dlmallinfo(void) { + return internal_mallinfo(gm); +} +#endif /* NO_MALLINFO */ + +#if !NO_MALLOC_STATS +void dlmalloc_stats() { + internal_malloc_stats(gm); +} +#endif /* NO_MALLOC_STATS */ + +int dlmallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +size_t dlmalloc_usable_size(const void* mem) { + mchunkptr p; + size_t bytes; + if (mem) { + p = mem2chunk(mem); + if (is_inuse(p)) { + bytes = chunksize(p) - overhead_for(p); + } else { + bytes = 0; + } + } else { + bytes = 0; + } + return bytes; +} + +#endif /* !ONLY_MSPACES */ + +/* ----------------------------- user mspaces ---------------------------- */ + +#if MSPACES + +static mstate init_user_mstate(char* tbase, size_t tsize) { + size_t msize = pad_request(sizeof(struct malloc_state)); + mchunkptr mn; + mchunkptr msp = align_as_chunk(tbase); + mstate m = (mstate)(chunk2mem(msp)); + bzero(m, msize); + (void)INITIAL_LOCK(&m->mutex); + msp->head = (msize|INUSE_BITS); + m->seg.base = m->least_addr = tbase; + m->seg.size = m->footprint = m->max_footprint = tsize; + m->magic = mparams.magic; + m->release_checks = MAX_RELEASE_CHECK_RATE; + m->mflags = mparams.default_mflags; + m->extp = 0; + m->exts = 0; + disable_contiguous(m); + init_bins(m); + mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); + check_top_chunk(m, m->top); + return m; +} + +mspace create_mspace(size_t capacity, int locked) { + mstate m = 0; + size_t msize; + ensure_initialization(); + msize = pad_request(sizeof(struct malloc_state)); + if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + size_t rs = ((capacity == 0)? mparams.granularity : + (capacity + TOP_FOOT_SIZE + msize)); + size_t tsize = granularity_align(rs); + char* tbase = (char*)(dlmalloc_requires_more_vespene_gas(tsize)); + if (tbase != CMFAIL) { + m = init_user_mstate(tbase, tsize); + m->seg.sflags = USE_MMAP_BIT; + set_lock(m, locked); + } + } + return (mspace)m; +} + +mspace create_mspace_with_base(void* base, size_t capacity, int locked) { + mstate m = 0; + size_t msize; + ensure_initialization(); + msize = pad_request(sizeof(struct malloc_state)); + if (capacity > msize + TOP_FOOT_SIZE && + capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + m = init_user_mstate((char*)base, capacity); + m->seg.sflags = EXTERN_BIT; + set_lock(m, locked); + } + return (mspace)m; +} + +int mspace_track_large_chunks(mspace msp, int enable) { + int ret = 0; + mstate ms = (mstate)msp; + if (!PREACTION(ms)) { + if (!use_mmap(ms)) { + ret = 1; + } + if (!enable) { + enable_mmap(ms); + } else { + disable_mmap(ms); + } + POSTACTION(ms); + } + return ret; +} + +size_t destroy_mspace(mspace msp) { + size_t freed = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + msegmentptr sp = &ms->seg; + (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */ + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + flag_t flag = sp->sflags; + (void)base; /* placate people compiling -Wunused-variable */ + sp = sp->next; + if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) && + CALL_MUNMAP(base, size) == 0) + freed += size; + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return freed; +} + +/* + mspace versions of routines are near-clones of the global + versions. This is not so nice but better than the alternatives. +*/ + +void* mspace_malloc(mspace msp, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (!PREACTION(ms)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = ms->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(ms, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(ms, b, p, idx); + set_inuse_and_pinuse(ms, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb > ms->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(ms, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(ms, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(ms, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(ms, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + + if (nb <= ms->dvsize) { + size_t rsize = ms->dvsize - nb; + mchunkptr p = ms->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = ms->dv = chunk_plus_offset(p, nb); + ms->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + } + else { /* exhaust dv */ + size_t dvs = ms->dvsize; + ms->dvsize = 0; + ms->dv = 0; + set_inuse_and_pinuse(ms, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb < ms->topsize) { /* Split top */ + size_t rsize = ms->topsize -= nb; + mchunkptr p = ms->top; + mchunkptr r = ms->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + mem = chunk2mem(p); + check_top_chunk(ms, ms->top); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + mem = sys_alloc(ms, nb); + POSTACTION(ms); + if (mem == MAP_FAILED && weaken(__oom_hook)) { + weaken(__oom_hook)(bytes); + } + return mem; + + postaction: + POSTACTION(ms); + return mem; + } + + return 0; +} + +void mspace_free(mspace msp, void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); + (void)msp; /* placate people compiling -Wunused */ +#else /* FOOTERS */ + mstate fm = (mstate)msp; +#endif /* FOOTERS */ + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + + if (is_small(psize)) { + insert_small_chunk(fm, p, psize); + check_free_chunk(fm, p); + } + else { + tchunkptr tp = (tchunkptr)p; + insert_large_chunk(fm, tp, psize); + check_free_chunk(fm, p); + if (--fm->release_checks == 0) + release_unused_segments(fm); + } + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +} + +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = internal_malloc(ms, req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + bzero(mem, req); + return mem; +} + +void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { + void* mem = 0; + if (oldmem == 0) { + mem = mspace_malloc(msp, bytes); + } + else if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + } +#ifdef REALLOC_ZERO_BYTES_FREES + else if (bytes == 0) { + mspace_free(msp, oldmem); + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if ! FOOTERS + mstate m = (mstate)msp; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); + POSTACTION(m); + if (newp != 0) { + check_inuse_chunk(m, newp); + mem = chunk2mem(newp); + } + else { + mem = mspace_malloc(m, bytes); + if (mem != 0) { + size_t oc = chunksize(oldp) - overhead_for(oldp); + memcpy(mem, oldmem, (oc < bytes)? oc : bytes); + mspace_free(m, oldmem); + } + } + } + } + return mem; +} + +void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) { + void* mem = 0; + if (oldmem != 0) { + if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + } + else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if ! FOOTERS + mstate m = (mstate)msp; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + (void)msp; /* placate people compiling -Wunused */ + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); + POSTACTION(m); + if (newp == oldp) { + check_inuse_chunk(m, newp); + mem = oldmem; + } + } + } + } + return mem; +} + +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (alignment <= MALLOC_ALIGNMENT) + return mspace_malloc(msp, bytes); + return internal_memalign(ms, alignment, bytes); +} + +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, &sz, 3, chunks); +} + +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, sizes, 0, chunks); +} + +size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) { + return internal_bulk_free((mstate)msp, array, nelem); +} + +#if MALLOC_INSPECT_ALL +void mspace_inspect_all(mspace msp, + void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg) { + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (!PREACTION(ms)) { + internal_inspect_all(ms, handler, arg); + POSTACTION(ms); + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } +} +#endif /* MALLOC_INSPECT_ALL */ + +int mspace_trim(mspace msp, size_t pad) { + int result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (!PREACTION(ms)) { + result = sys_trim(ms, pad); + POSTACTION(ms); + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +#if !NO_MALLOC_STATS +void mspace_malloc_stats(mspace msp) { + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + internal_malloc_stats(ms); + } + else { + USAGE_ERROR_ACTION(ms,ms); + } +} +#endif /* NO_MALLOC_STATS */ + +size_t mspace_footprint(mspace msp) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->footprint; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +size_t mspace_max_footprint(mspace msp) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->max_footprint; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +size_t mspace_footprint_limit(mspace msp) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + size_t maf = ms->footprint_limit; + result = (maf == 0) ? MAX_SIZE_T : maf; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +size_t mspace_set_footprint_limit(mspace msp, size_t bytes) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (bytes == 0) + result = granularity_align(1); /* Use minimal size */ + if (bytes == MAX_SIZE_T) + result = 0; /* disable */ + else + result = granularity_align(bytes); + ms->footprint_limit = result; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +#if !NO_MALLINFO +struct mallinfo mspace_mallinfo(mspace msp) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + } + return internal_mallinfo(ms); +} +#endif /* NO_MALLINFO */ + +size_t mspace_usable_size(const void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (is_inuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; +} + +int mspace_mallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +#endif /* MSPACES */ diff --git a/third_party/dlmalloc/dlmalloc.h b/third_party/dlmalloc/dlmalloc.h new file mode 100644 index 000000000..6de3f7623 --- /dev/null +++ b/third_party/dlmalloc/dlmalloc.h @@ -0,0 +1,512 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_DLMALLOC_DLMALLOC_H_ +#define COSMOPOLITAN_THIRD_PARTY_DLMALLOC_DLMALLOC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/* + malloc(size_t n) + Returns a pointer to a newly allocated chunk of at least n bytes, or + null if no space is available, in which case errno is set to ENOMEM + on ANSI C systems. + + If n is zero, malloc returns a minimum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 32 bytes on 64bit + systems.) Note that size_t is an unsigned type, so calls with + arguments that would be negative if signed are interpreted as + requests for huge amounts of space, which will often fail. The + maximum supported value of n differs across systems, but is in all + cases less than the maximum representable value of a size_t. +*/ +void* dlmalloc(size_t); + +/* + free(void* p) + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. If p was not malloced or already + freed, free(p) will by default cuase the current program to abort. +*/ +void dlfree(void*); + +/* + calloc(size_t n_elements, size_t element_size); + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +void* dlcalloc(size_t, size_t); + +/* + realloc(void* p, size_t n) + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p in most cases when possible, otherwise it + employs the equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + if n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. realloc with a size + argument of zero (re)allocates a minimum-sized chunk. + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ +void* dlrealloc(void*, size_t); + +/* + realloc_in_place(void* p, size_t n) + Resizes the space allocated for p to size n, only if this can be + done without moving p (i.e., only if there is adjacent space + available if n is greater than p's current allocated size, or n is + less than or equal to p's size). This may be used instead of plain + realloc if an alternative allocation strategy is needed upon failure + to expand space; for example, reallocation of a buffer that must be + memory-aligned or cleared. You can use realloc_in_place to trigger + these alternatives only when needed. + + Returns p if successful; otherwise null. +*/ +void* dlrealloc_in_place(void*, size_t); + +/* + memalign(size_t alignment, size_t n); + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +void* dlmemalign(size_t, size_t); + +/* + int posix_memalign(void** pp, size_t alignment, size_t n); + Allocates a chunk of n bytes, aligned in accord with the alignment + argument. Differs from memalign only in that it (1) assigns the + allocated memory to *pp rather than returning it, (2) fails and + returns EINVAL if the alignment is not a power of two (3) fails and + returns ENOMEM if memory cannot be allocated. +*/ +int dlposix_memalign(void**, size_t, size_t); + +/* + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +void* dlvalloc(size_t); + +/* + mallopt(int parameter_number, int parameter_value) + Sets tunable parameters The format is to provide a + (parameter-number, parameter-value) pair. mallopt then sets the + corresponding parameter to the argument value if it can (i.e., so + long as the value is meaningful), and returns 1 if successful else + 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, + normally defined in malloc.h. None of these are use in this malloc, + so setting them has no effect. But this malloc also supports other + options in mallopt: + + Symbol param # default allowed param values + M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) + M_GRANULARITY -2 page size any power of 2 >= page size + M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) +*/ +int dlmallopt(int, int); + +/* + malloc_footprint(); + Returns the number of bytes obtained from the system. The total + number of bytes allocated by malloc, realloc etc., is less than this + value. Unlike mallinfo, this function returns only a precomputed + result, so can be called frequently to monitor memory consumption. + Even if locks are otherwise defined, this function does not use them, + so results might not be up to date. +*/ +size_t dlmalloc_footprint(void); + +/* + malloc_max_footprint(); + Returns the maximum number of bytes obtained from the system. This + value will be greater than current footprint if deallocated space + has been reclaimed by the system. The peak number of bytes allocated + by malloc, realloc etc., is less than this value. Unlike mallinfo, + this function returns only a precomputed result, so can be called + frequently to monitor memory consumption. Even if locks are + otherwise defined, this function does not use them, so results might + not be up to date. +*/ +size_t dlmalloc_max_footprint(void); + +/* + malloc_footprint_limit(); + Returns the number of bytes that the heap is allowed to obtain from + the system, returning the last value returned by + malloc_set_footprint_limit, or the maximum size_t value if + never set. The returned value reflects a permission. There is no + guarantee that this number of bytes can actually be obtained from + the system. +*/ +size_t dlmalloc_footprint_limit(void); + +/* + malloc_set_footprint_limit(); + Sets the maximum number of bytes to obtain from the system, causing + failure returns from malloc and related functions upon attempts to + exceed this value. The argument value may be subject to page + rounding to an enforceable limit; this actual value is returned. + Using an argument of the maximum possible size_t effectively + disables checks. If the argument is less than or equal to the + current malloc_footprint, then all future allocations that require + additional system memory will fail. However, invocation cannot + retroactively deallocate existing used memory. +*/ +size_t dlmalloc_set_footprint_limit(size_t bytes); + +/* + malloc_inspect_all(void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg); + Traverses the heap and calls the given handler for each managed + region, skipping all bytes that are (or may be) used for bookkeeping + purposes. Traversal does not include include chunks that have been + directly memory mapped. Each reported region begins at the start + address, and continues up to but not including the end address. The + first used_bytes of the region contain allocated data. If + used_bytes is zero, the region is unallocated. The handler is + invoked with the given callback argument. If locks are defined, they + are held during the entire traversal. It is a bad idea to invoke + other malloc functions from within the handler. + + For example, to count the number of in-use chunks with size greater + than 1000, you could write: + static int count = 0; + void count_chunks(void* start, void* end, size_t used, void* arg) { + if (used >= 1000) ++count; + } + then: + malloc_inspect_all(count_chunks, NULL); + + malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. +*/ +void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), + void* arg); + +/* + mallinfo() + Returns (by copy) a struct containing various summary statistics: + + arena: current total non-mmapped bytes allocated from system + ordblks: the number of free chunks + smblks: always zero. + hblks: current number of mmapped regions + hblkhd: total bytes held in mmapped regions + usmblks: the maximum total allocated space. This will be greater + than current total if trimming has occurred. + fsmblks: always zero + uordblks: current total allocated space (normal or mmapped) + fordblks: total free space + keepcost: the maximum number of bytes that could ideally be released + back to system via malloc_trim. ("ideally" means that + it ignores page restrictions etc.) + + Because these fields are ints, but internal bookkeeping may + be kept as longs, the reported values may wrap around zero and + thus be inaccurate. +*/ + +struct mallinfo dlmallinfo(void); + +/* + independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); + + independent_calloc is similar to calloc, but instead of returning a + single cleared space, it returns an array of pointers to n_elements + independent elements that can hold contents of size elem_size, each + of which starts out cleared, and can be independently freed, + realloc'ed etc. The elements are guaranteed to be adjacently + allocated (this is not guaranteed to occur with multiple callocs or + mallocs), which may also improve cache locality in some + applications. + + The "chunks" argument is optional (i.e., may be null, which is + probably the most typical usage). If it is null, the returned array + is itself dynamically allocated and should also be freed when it is + no longer needed. Otherwise, the chunks array must be of at least + n_elements in length. It is filled in with the pointers to the + chunks. + + In either case, independent_calloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and "chunks" + is null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be freed when it is no longer needed. This can be + done all at once using bulk_free. + + independent_calloc simplifies and speeds up implementations of many + kinds of pools. It may also be useful when constructing large data + structures that initially have a fixed number of fixed-sized nodes, + but the number is not known at compile time, and some of the nodes + may later need to be freed. For example: + + struct Node { int item; struct Node* next; }; + + struct Node* build_list() { + struct Node** pool; + int n = read_number_of_nodes_needed(); + if (n <= 0) return 0; + pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + if (pool == 0) die(); + // organize into a linked list... + struct Node* first = pool[0]; + for (i = 0; i < n-1; ++i) + pool[i]->next = pool[i+1]; + free(pool); // Can now free the array (or not, if it is needed later) + return first; + } +*/ +void** dlindependent_calloc(size_t, size_t, void**); + +/* + independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); + + independent_comalloc allocates, all at once, a set of n_elements + chunks with sizes indicated in the "sizes" array. It returns + an array of pointers to these elements, each of which can be + independently freed, realloc'ed etc. The elements are guaranteed to + be adjacently allocated (this is not guaranteed to occur with + multiple callocs or mallocs), which may also improve cache locality + in some applications. + + The "chunks" argument is optional (i.e., may be null). If it is null + the returned array is itself dynamically allocated and should also + be freed when it is no longer needed. Otherwise, the chunks array + must be of at least n_elements in length. It is filled in with the + pointers to the chunks. + + In either case, independent_comalloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and chunks is + null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be freed when it is no longer needed. This can be + done all at once using bulk_free. + + independent_comallac differs from independent_calloc in that each + element may have a different size, and also that it does not + automatically clear elements. + + independent_comalloc can be used to speed up allocation in cases + where several structs or objects must always be allocated at the + same time. For example: + + struct Head { ... } + struct Foot { ... } + + void send_message(char* msg) { + int msglen = strlen(msg); + size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + void* chunks[3]; + if (independent_comalloc(3, sizes, chunks) == 0) + die(); + struct Head* head = (struct Head*)(chunks[0]); + char* body = (char*)(chunks[1]); + struct Foot* foot = (struct Foot*)(chunks[2]); + // ... + } + + In general though, independent_comalloc is worth using only for + larger values of n_elements. For small values, you probably won't + detect enough difference from series of malloc calls to bother. + + Overuse of independent_comalloc can increase overall memory usage, + since it cannot reuse existing noncontiguous small chunks that + might be available for some of the elements. +*/ +void** dlindependent_comalloc(size_t, size_t*, void**); + +/* + bulk_free(void* array[], size_t n_elements) + Frees and clears (sets to null) each non-null pointer in the given + array. This is likely to be faster than freeing them one-by-one. + If footers are used, pointers that have been allocated in different + mspaces are not freed or cleared, and the count of all such pointers + is returned. For large arrays of pointers with poor locality, it + may be worthwhile to sort this array before calling bulk_free. +*/ +size_t dlbulk_free(void**, size_t n_elements); + +/* + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +void* dlpvalloc(size_t); + +/* + malloc_trim(size_t pad); + + If possible, gives memory back to the system (via negative arguments + to sbrk) if there is unused memory at the `high' end of the malloc + pool or in unused MMAP segments. You can call this after freeing + large blocks of memory to potentially reduce the system-level memory + requirements of a program. However, it cannot guarantee to reduce + memory. Under some allocation patterns, some large free blocks of + memory will be locked between two used chunks, so they cannot be + given back to the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, only + the minimum amount of memory to maintain internal data structures + will be left. Non-zero arguments can be supplied to maintain enough + trailing space to service future expected allocations without having + to re-obtain memory from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. +*/ +int dlmalloc_trim(size_t); + +/* + malloc_stats(); + Prints on stderr the amount of space obtained from the system (both + via sbrk and mmap), the maximum amount (which may be more than + current if malloc_trim and/or munmap got called), and the current + number of bytes allocated via malloc (or realloc, etc) but not yet + freed. Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead. Because it includes + alignment wastage as being in use, this figure may be greater than + zero even when no user-level chunks are allocated. + + The reported current and maximum system memory can be inaccurate if + a program makes other calls to system memory allocation functions + (normally sbrk) outside of malloc. + + malloc_stats prints only the most commonly interesting statistics. + More information can be obtained by calling mallinfo. + + malloc_stats is not compiled if NO_MALLOC_STATS is defined. +*/ +void dlmalloc_stats(void); + +/* + malloc_usable_size(void* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); +*/ +size_t dlmalloc_usable_size(const void*); + +/* + mspace is an opaque type representing an independent + region of space that supports mspace_malloc, etc. +*/ +typedef void* mspace; + +/* + create_mspace creates and returns a new independent space with the + given initial capacity, or, if 0, the default granularity size. It + returns null if there is no system memory available to create the + space. If argument locked is non-zero, the space uses a separate + lock to control access. The capacity of the space will grow + dynamically as needed to service mspace_malloc requests. You can + control the sizes of incremental increases of this space by + compiling with a different DEFAULT_GRANULARITY or dynamically + setting with mallopt(M_GRANULARITY, value). +*/ +mspace create_mspace(size_t capacity, int locked); + +/* + destroy_mspace destroys the given space, and attempts to return all + of its memory back to the system, returning the total number of + bytes freed. After destruction, the results of access to all memory + used by the space become undefined. +*/ +size_t destroy_mspace(mspace msp); + +/* + create_mspace_with_base uses the memory supplied as the initial base + of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this + space is used for bookkeeping, so the capacity must be at least this + large. (Otherwise 0 is returned.) When this initial space is + exhausted, additional memory will be obtained from the system. + Destroying this space will deallocate all additionally allocated + space (if possible) but not the initial base. +*/ +mspace create_mspace_with_base(void* base, size_t capacity, int locked); + +/* + mspace_track_large_chunks controls whether requests for large chunks + are allocated in their own untracked mmapped regions, separate from + others in this mspace. By default large chunks are not tracked, + which reduces fragmentation. However, such chunks are not + necessarily released to the system upon destroy_mspace. Enabling + tracking by setting to true may increase fragmentation, but avoids + leakage when relying on destroy_mspace to release all memory + allocated using this space. The function returns the previous + setting. +*/ +int mspace_track_large_chunks(mspace msp, int enable); + +/* + mspace_mallinfo behaves as mallinfo, but reports properties of + the given space. +*/ +struct mallinfo mspace_mallinfo(mspace msp); + +/* + An alias for mallopt. +*/ +int mspace_mallopt(int, int); + +/* + The following operate identically to their malloc counterparts + but operate only for the given mspace argument +*/ +void* mspace_malloc(mspace msp, size_t bytes); +void mspace_free(mspace msp, void* mem); +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); +void* mspace_realloc(mspace msp, void* mem, size_t newsize); +void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize); +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]); +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]); +size_t mspace_bulk_free(mspace msp, void**, size_t n_elements); +size_t mspace_usable_size(const void* mem); +void mspace_malloc_stats(mspace msp); +int mspace_trim(mspace msp, size_t pad); +size_t mspace_footprint(mspace msp); +size_t mspace_max_footprint(mspace msp); +size_t mspace_footprint_limit(mspace msp); +size_t mspace_set_footprint_limit(mspace msp, size_t bytes); +void mspace_inspect_all(mspace msp, + void (*handler)(void*, void*, size_t, void*), + void* arg); + +void dlmalloc_abort(void); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_DLMALLOC_DLMALLOC_H_ */ diff --git a/third_party/dlmalloc/dlmalloc.internal.h b/third_party/dlmalloc/dlmalloc.internal.h deleted file mode 100644 index 1c8bdd67a..000000000 --- a/third_party/dlmalloc/dlmalloc.internal.h +++ /dev/null @@ -1,1312 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_MEM_DLMALLOC_H_ -#define COSMOPOLITAN_LIBC_MEM_DLMALLOC_H_ -#ifndef __STRICT_ANSI__ -#include "libc/assert.h" -#include "libc/bits/bits.h" -#include "libc/bits/weaken.h" -#include "libc/calls/calls.h" -#include "libc/dce.h" -#include "libc/log/backtrace.internal.h" -#include "libc/nexgen32e/bsf.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/symbols.internal.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -#if 0 -/** - * @fileoverview Internal header for Doug Lea's malloc. -*/ -#endif - -#define DLMALLOC_VERSION 20806 -#define HAVE_MMAP 1 -#define MMAP_CLEARS 1 -#define MALLOC_ALIGNMENT 16 -#define NO_SEGMENT_TRAVERSAL 1 -#define MAX_RELEASE_CHECK_RATE 128 -#define MALLOC_ABORT abort() -#define FOOTERS !NoDebug() -#define MAX_REQUEST 0xfffffffffff -#define DEFAULT_GRANULARITY (64UL * 1024UL) -#define DEFAULT_TRIM_THRESHOLD (10UL * 1024UL * 1024UL) -#define DEFAULT_MMAP_THRESHOLD (256UL * 1024UL) -#define USE_LOCKS 0 -#define USE_SPIN_LOCKS 0 -#define LOCK_AT_FORK 0 -#define NSMALLBINS (32u) -#define NTREEBINS (32u) -#define SMALLBIN_SHIFT (3u) -#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) -#define TREEBIN_SHIFT (8u) -#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) -#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) -#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - -/* ─────────────────── size_t and alignment properties ──────────────────── */ - -#define MALLINFO_FIELD_TYPE size_t - -/* The byte and bit size of a size_t */ -#define SIZE_T_SIZE (sizeof(size_t)) -#define SIZE_T_BITSIZE (sizeof(size_t) << 3) - -/* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some platforms */ -#define SIZE_T_ZERO 0UL -#define SIZE_T_ONE 1UL -#define SIZE_T_TWO 2UL -#define SIZE_T_FOUR 4UL -#define TWO_SIZE_T_SIZES (SIZE_T_SIZE << 1) -#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE << 2) -#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES + TWO_SIZE_T_SIZES) -#define HALF_SIZE_MAX (__SIZE_MAX__ / 2U) - -/* The bit mask value corresponding to MALLOC_ALIGNMENT */ -#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) - -/* True if address a has acceptable alignment */ -#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) - -/* the number of bytes to offset an address to align it */ -#define align_offset(A) \ - ((((size_t)(A)&CHUNK_ALIGN_MASK) == 0) \ - ? 0 \ - : ((MALLOC_ALIGNMENT - ((size_t)(A)&CHUNK_ALIGN_MASK)) & \ - CHUNK_ALIGN_MASK)) - -/* ────────────────────────── MMAP preliminaries ───────────────────────── */ - -#define MFAIL MAP_FAILED -#define CMFAIL ((char *)MAP_FAILED) -#define MMAP_DEFAULT(s) dlmalloc_requires_more_vespene_gas(s) -#define MUNMAP_DEFAULT(a, s) munmap(a, s) -#define MMAP_PROT (PROT_READ | PROT_WRITE) -#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) -#define USE_MMAP_BIT (SIZE_T_ONE) -#define CALL_MMAP(s) MMAP_DEFAULT(s) -#define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) -#define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) -#define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) -#define USE_NONCONTIGUOUS_BIT (4U) -#define EXTERN_BIT (8U) - -/* ─────────────────────────── Lock preliminaries ──────────────────────── */ - -/* - When locks are defined, there is one global lock, plus - one per-mspace lock. - - The global lock_ensures that mparams.magic and other unique - mparams values are initialized only once. It also protects - sequences of calls to MORECORE. In many cases sys_alloc requires - two calls, that should not be interleaved with calls by other - threads. This does not protect against direct calls to MORECORE - by other threads not using this lock, so there is still code to - cope the best we can on interference. - - Per-mspace locks surround calls to malloc, free, etc. - By default, locks are simple non-reentrant mutexes. - - Because lock-protected regions generally have bounded times, it is - OK to use the supplied simple spinlocks. Spinlocks are likely to - improve performance for lightly contended applications, but worsen - performance under heavy contention. - - If USE_LOCKS is > 1, the definitions of lock routines here are - bypassed, in which case you will need to define the type MLOCK_T, - and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK - and TRY_LOCK. You must also declare a - static MLOCK_T malloc_global_mutex = { initialization values };. -*/ - -#define USE_LOCK_BIT (0U) -#define INITIAL_LOCK(l) (0) -#define DESTROY_LOCK(l) (0) -#define ACQUIRE_MALLOC_GLOBAL_LOCK() -#define RELEASE_MALLOC_GLOBAL_LOCK() - -/* ─────────────────────── Chunk representations ──────────────────────── */ - -/* - (The following includes lightly edited explanations by Colin Plumb.) - - The MallocChunk declaration below is misleading (but accurate and - necessary). It declares a "view" into memory allowing access to - necessary fields at known offsets from a given base. - - Chunks of memory are maintained using a `boundary tag' method as - originally described by Knuth. (See the paper by Paul Wilson - ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such - techniques.) Sizes of free chunks are stored both in the front of - each chunk and at the end. This makes consolidating fragmented - chunks into bigger chunks fast. The head fields also hold bits - representing whether chunks are free or in use. - - Here are some pictures to make it clearer. They are "exploded" to - show that the state of a chunk can be thought of as extending from - the high 31 bits of the head field of its header through the - prev_foot and PINUSE_BIT bit of the following chunk header. - - A chunk that's in use looks like: - - chunk→ ┌───────────────────────────────────────────────────────────────┐ - │ Size of previous chunk (if P = 0) │ - └─────────────────────────────────────────────────────────────┬─┤ - ┌─────────────────────────────────────────────────────────────┐ │P│ - │ Size of this chunk 1│ └─┘ - mem→ ├───────────────────────────────────────────────────────────────┐ - │ │ - ├─ ─┤ - │ │ - ├─ ─┤ - │ : - ├─ size - sizeof(size_t) available payload bytes ─┤ - : │ - chunk→ ├─ ─┤ - │ │ - └───────────────────────────────────────────────────────────────┤ - ┌─────────────────────────────────────────────────────────────┐ |1│ - │ Size of next chunk (may or may not be in use) │ ├─┘ - mem→ └───────────────────────────────────────────────────────────────┘ - - And if it's free, it looks like this: - - chunk→ ┌─ ─┐ - │ User payload (must be in use, or we would have merged!) │ - └───────────────────────────────────────────────────────────────┤ - ┌─────────────────────────────────────────────────────────────┐ │P│ - │ Size of this chunk 0│ │─┘ - mem→ ├───────────────────────────────────────────────────────────────┤ - │ Next pointer │ - ├───────────────────────────────────────────────────────────────┤ - │ Prev pointer │ - ├───────────────────────────────────────────────────────────────┤ - │ : - ├─ size - sizeof(struct chunk) unused bytes ─┤ - : │ - chunk→ ├───────────────────────────────────────────────────────────────┤ - │ Size of this chunk │ - └───────────────────────────────────────────────────────────────┤ - ┌───────────────────────────────────────────────────────────────│0│ - │ Size of next chunk (must be in use, or we would have merged)| │─┘ - mem→ ├───────────────────────────────────────────────────────────────┤ - │ : - ├─ User payload ─┤ - : │ - └───────────────────────────────────────────────────────────────┤ - │0│ - └─┘ - Note that since we always merge adjacent free chunks, the chunks - adjacent to a free chunk must be in use. - - Given a pointer to a chunk (which can be derived trivially from the - payload pointer) we can, in O(1) time, find out whether the adjacent - chunks are free, and if so, unlink them from the lists that they - are on and merge them with the current chunk. - - Chunks always begin on even word boundaries, so the mem portion - (which is returned to the user) is also on an even word boundary, and - thus at least double-word aligned. - - The P (PINUSE_BIT) bit, stored in the unused low-order bit of the - chunk size (which is always a multiple of two words), is an in-use - bit for the *previous* chunk. If that bit is *clear*, then the - word before the current chunk size contains the previous chunk - size, and can be used to find the front of the previous chunk. - The very first chunk allocated always has this bit set, preventing - access to non-existent (or non-owned) memory. If pinuse is set for - any given chunk, then you CANNOT determine the size of the - previous chunk, and might even get a memory addressing fault when - trying to do so. - - The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of - the chunk size redundantly records whether the current chunk is - inuse (unless the chunk is mmapped). This redundancy enables usage - checks within free and realloc, and reduces indirection when freeing - and consolidating chunks. - - Each freshly allocated chunk must have both cinuse and pinuse set. - That is, each allocated chunk borders either a previously allocated - and still in-use chunk, or the base of its memory arena. This is - ensured by making all allocations from the `lowest' part of any - found chunk. Further, no free chunk physically borders another one, - so each free chunk is known to be preceded and followed by either - inuse chunks or the ends of memory. - - Note that the `foot' of the current chunk is actually represented - as the prev_foot of the NEXT chunk. This makes it easier to - deal with alignments etc but can be very confusing when trying - to extend or adapt this code. - - The exceptions to all this are - - 1. The special chunk `top' is the top-most available chunk (i.e., - the one bordering the end of available memory). It is treated - specially. Top is never included in any bin, is used only if - no other chunk is available, and is released back to the - system if it is very large (see M_TRIM_THRESHOLD). In effect, - the top chunk is treated as larger (and thus less well - fitting) than any other available chunk. The top chunk - doesn't update its trailing size field since there is no next - contiguous chunk that would have to index off it. However, - space is still allocated for it (TOP_FOOT_SIZE) to enable - separation or merging when space is extended. - - 3. Chunks allocated via mmap, have both cinuse and pinuse bits - cleared in their head fields. Because they are allocated - one-by-one, each must carry its own prev_foot field, which is - also used to hold the offset this chunk has within its mmapped - region, which is needed to preserve alignment. Each mmapped - chunk is trailed by the first two fields of a fake next-chunk - for sake of usage checks. - -*/ - -struct MallocChunk { - size_t prev_foot; /* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct MallocChunk *fd; /* double links -- used only if free. */ - struct MallocChunk *bk; -}; - -typedef struct MallocChunk mchunk; -typedef struct MallocChunk *mchunkptr; -typedef struct MallocChunk *sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ -typedef unsigned int binmap_t; /* Described below */ -typedef unsigned int flag_t; /* The type of various bit flag sets */ - -/* ─────────────────── Chunks sizes and alignments ─────────────────────── */ - -#define MCHUNK_SIZE (sizeof(mchunk)) - -#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) - -/* MMapped chunks need a second word of overhead ... */ -#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -/* ... and additional padding for fake next-chunk at foot */ -#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) - -/* The smallest size we can malloc is an aligned minimal chunk */ -#define MIN_CHUNK_SIZE ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((void *)((char *)(p) + TWO_SIZE_T_SIZES)) -#define mem2chunk(mem) ((mchunkptr)((char *)(mem)-TWO_SIZE_T_SIZES)) -/* chunk associated with aligned address A */ -#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) - -/* Bounds on request (not chunk) sizes. */ -#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) - -/* pad request bytes into a usable size */ -#define pad_request(req) \ - (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* pad request, checking for minimum (but not maximum) */ -#define request2size(req) \ - (((req) < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(req)) - -/* ────────────────── Operations on head and foot fields ───────────────── */ - -/* - The head field of a chunk is or'ed with PINUSE_BIT when previous - adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in - use, unless mmapped, in which case both bits are cleared. - - FLAG4_BIT is not used by this malloc, but might be useful in extensions. -*/ - -#define PINUSE_BIT (SIZE_T_ONE) -#define CINUSE_BIT (SIZE_T_TWO) -#define FLAG4_BIT (SIZE_T_FOUR) -#define INUSE_BITS (PINUSE_BIT | CINUSE_BIT) -#define FLAG_BITS (PINUSE_BIT | CINUSE_BIT | FLAG4_BIT) - -/* Head value for fenceposts */ -#define FENCEPOST_HEAD (INUSE_BITS | SIZE_T_SIZE) - -/* extraction of fields from head words */ -#define cinuse(p) ((p)->head & CINUSE_BIT) -#define pinuse(p) ((p)->head & PINUSE_BIT) -#define flag4inuse(p) ((p)->head & FLAG4_BIT) -#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) -#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) - -#define chunksize(p) ((p)->head & ~(FLAG_BITS)) - -#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) -#define set_flag4(p) ((p)->head |= FLAG4_BIT) -#define clear_flag4(p) ((p)->head &= ~FLAG4_BIT) - -/* Treat space at ptr +/- offset as a chunk */ -#define chunk_plus_offset(p, s) ((mchunkptr)(((char *)(p)) + (s))) -#define chunk_minus_offset(p, s) ((mchunkptr)(((char *)(p)) - (s))) - -/* Ptr to next or previous physical MallocChunk. */ -#define next_chunk(p) ((mchunkptr)(((char *)(p)) + ((p)->head & ~FLAG_BITS))) -#define prev_chunk(p) ((mchunkptr)(((char *)(p)) - ((p)->prev_foot))) - -/* extract next chunk's pinuse bit */ -#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) - -/* Get/set size at footer */ -#define get_foot(p, s) (((mchunkptr)((char *)(p) + (s)))->prev_foot) -#define set_foot(p, s) (((mchunkptr)((char *)(p) + (s)))->prev_foot = (s)) - -/* Set size, pinuse bit, and foot */ -#define set_size_and_pinuse_of_free_chunk(p, s) \ - ((p)->head = (s | PINUSE_BIT), set_foot(p, s)) - -/* Set size, pinuse bit, foot, and clear next pinuse */ -#define set_free_with_pinuse(p, s, n) \ - (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) - -/* Get the internal overhead associated with chunk p */ -#define overhead_for(p) (is_mmapped(p) ? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) - -/* Return true if malloced space is not necessarily cleared */ - -#define calloc_must_clear(p) (!is_mmapped(p)) - -/* ────────────────────── Overlaid data structures ─────────────────────── */ - -/* - When chunks are not in use, they are treated as nodes of either - lists or trees. - - "Small" chunks are stored in circular doubly-linked lists, and look - like this: - - chunk→ ┌───────────────────────────────────────────────────────────────┐ - │ Size of previous chunk │ - ├───────────────────────────────────────────────────────────────┤ - `head:' │ Size of chunk, in bytes |P│ - mem→ ├───────────────────────────────────────────────────────────────┤ - │ Forward pointer to next chunk in list │ - ├───────────────────────────────────────────────────────────────┤ - │ Back pointer to previous chunk in list │ - ├───────────────────────────────────────────────────────────────┤ - . Unused space (may be 0 bytes long) . - . . - │ │ - nextchunk→ ├───────────────────────────────────────────────────────────────┤ - `foot:' │ Size of chunk, in bytes │ - └───────────────────────────────────────────────────────────────┘ - - Larger chunks are kept in a form of bitwise digital trees (aka - tries) keyed on chunksizes. Because MallocTreeChunks are only for - free chunks greater than 256 bytes, their size doesn't impose any - constraints on user chunk sizes. Each node looks like: - - chunk→ ┌───────────────────────────────────────────────────────────────┐ - │ Size of previous chunk │ - ├─────────────────────────────────────────────────────────────┬─┤ - `head:' │ Size of chunk, in bytes │P│ - mem→ ├─────────────────────────────────────────────────────────────┴─┤ - │ Forward pointer to next chunk of same size │ - ├───────────────────────────────────────────────────────────────┤ - │ Back pointer to previous chunk of same size │ - ├───────────────────────────────────────────────────────────────┤ - │ Pointer to left child (child[0]) │ - ├───────────────────────────────────────────────────────────────┤ - │ Pointer to right child (child[1]) │ - ├───────────────────────────────────────────────────────────────┤ - │ Pointer to parent │ - ├───────────────────────────────────────────────────────────────┤ - │ bin index of this chunk │ - ├───────────────────────────────────────────────────────────────┤ - │ Unused space . - . │ - nextchunk→ ├───────────────────────────────────────────────────────────────┤ - `foot:' │ Size of chunk, in bytes │ - └───────────────────────────────────────────────────────────────┘ - - Each tree holding treenodes is a tree of unique chunk sizes. Chunks - of the same size are arranged in a circularly-linked list, with only - the oldest chunk (the next to be used, in our FIFO ordering) - actually in the tree. (Tree members are distinguished by a non-null - parent pointer.) If a chunk with the same size an an existing node - is inserted, it is linked off the existing node using pointers that - work in the same way as fd/bk pointers of small chunks. - - Each tree contains a power of 2 sized range of chunk sizes (the - smallest is 0x100 <= x < 0x180), which is is divided in half at each - tree level, with the chunks in the smaller half of the range (0x100 - <= x < 0x140 for the top nose) in the left subtree and the larger - half (0x140 <= x < 0x180) in the right subtree. This is, of course, - done by inspecting individual bits. - - Using these rules, each node's left subtree contains all smaller - sizes than its right subtree. However, the node at the root of each - subtree has no particular ordering relationship to either. (The - dividing line between the subtree sizes is based on trie relation.) - If we remove the last chunk of a given size from the interior of the - tree, we need to replace it with a leaf node. The tree ordering - rules permit a node to be replaced by any leaf below it. - - The smallest chunk in a tree (a common operation in a best-fit - allocator) can be found by walking a path to the leftmost leaf in - the tree. Unlike a usual binary tree, where we follow left child - pointers until we reach a null, here we follow the right child - pointer any time the left one is null, until we reach a leaf with - both child pointers null. The smallest chunk in the tree will be - somewhere along that path. - - The worst case number of steps to add, find, or remove a node is - bounded by the number of bits differentiating chunks within - bins. Under current bin calculations, this ranges from 6 up to 21 - (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case - is of course much better. -*/ - -struct MallocTreeChunk { - /* The first four fields must be compatible with MallocChunk */ - size_t prev_foot; - size_t head; - struct MallocTreeChunk *fd; - struct MallocTreeChunk *bk; - struct MallocTreeChunk *child[2]; - struct MallocTreeChunk *parent; - bindex_t index; -}; - -typedef struct MallocTreeChunk tchunk; -typedef struct MallocTreeChunk *tchunkptr; -typedef struct MallocTreeChunk *tbinptr; /* The type of bins of trees */ - -/* A little helper macro for trees */ -#define leftmost_child(t) ((t)->child[0] != 0 ? (t)->child[0] : (t)->child[1]) - -/* ───────────────────────────── Segments ──────────────────────────────── */ - -/* - Each malloc space may include non-contiguous segments, held in a list - headed by an embedded MallocSegment record representing the top-most - space. Segments also include flags holding properties of the space. - Large chunks that are directly allocated by mmap are not included in - this list. They are instead independently created and destroyed - without otherwise keeping track of them. - - Segment management mainly comes into play for spaces allocated by - MMAP. Any call to MMAP might or might not return memory that is - adjacent to an existing segment. MORECORE normally contiguously - extends the current space, so this space is almost always adjacent, - which is simpler and faster to deal with. (This is why MORECORE is - used preferentially to MMAP when both are available -- see sys_alloc.) - When allocating using MMAP, we don't use any of the hinting mechanisms - (inconsistently) supported in various implementations of unix mmap, or - distinguish reserving from committing memory. Instead, we just ask for - space, and exploit contiguity when we get it. It is probably possible - to do better than this on some systems, but no general scheme seems to - be significantly better. - - Management entails a simpler variant of the consolidation scheme used - for chunks to reduce fragmentation -- new adjacent memory is normally - prepended or appended to an existing segment. However, there are - limitations compared to chunk consolidation that mostly reflect the - fact that segment processing is relatively infrequent (occurring only - when getting memory from system) and that we don't expect to have huge - numbers of segments: - - * Segments are not indexed, so traversal requires linear scans. (It - would be possible to index these, but is not worth the extra - overhead and complexity for most programs on most platforms.) - * New segments are only appended to old ones when holding top-most - memory; if they cannot be prepended to others, they are held in - different segments. - - Except for the top-most segment of an mstate, each segment record is - kept at the tail of its segment. Segments are added by pushing segment - records onto the list headed by &mstate.seg for the containing mstate. - - Segment flags control allocation/merge/deallocation policies: - * If EXTERN_BIT set, then we did not allocate this segment, - and so should not try to deallocate or merge with others. - (This currently holds only for the initial segment passed - into create_mspace_with_base.) - * If USE_MMAP_BIT set, the segment may be merged with - other surrounding mmapped segments and trimmed/de-allocated - using munmap. - * If neither bit is set, then the segment was obtained using - MORECORE so can be merged with surrounding MORECORE'd segments - and deallocated/trimmed using MORECORE with negative arguments. -*/ - -struct MallocSegment { - char *base; /* base address */ - size_t size; /* allocated size */ - struct MallocSegment *next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ -}; - -#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) -#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) - -typedef struct MallocSegment msegment; -typedef struct MallocSegment *msegmentptr; - -/* ──────────────────────────── MallocState ───────────────────────────── */ - -/* - A MallocState holds all of the bookkeeping for a space. - The main fields are: - - Top - The topmost chunk of the currently active segment. Its size is - cached in topsize. The actual size of topmost space is - topsize+TOP_FOOT_SIZE, which includes space reserved for adding - fenceposts and segment records if necessary when getting more - space from the system. The size at which to autotrim top is - cached from mparams in trim_check, except that it is disabled if - an autotrim fails. - - Designated victim (dv) - This is the preferred chunk for servicing small requests that - don't have exact fits. It is normally the chunk split off most - recently to service another small request. Its size is cached in - dvsize. The link fields of this chunk are not maintained since it - is not kept in a bin. - - SmallBins - An array of bin headers for free chunks. These bins hold chunks - with sizes less than MIN_LARGE_SIZE bytes. Each bin contains - chunks of all the same size, spaced 8 bytes apart. To simplify - use in double-linked lists, each bin header acts as a MallocChunk - pointing to the real first node, if it exists (else pointing to - itself). This avoids special-casing for headers. But to avoid - waste, we allocate only the fd/bk pointers of bins, and then use - repositioning tricks to treat these as the fields of a chunk. - - TreeBins - Treebins are pointers to the roots of trees holding a range of - sizes. There are 2 equally spaced treebins for each power of two - from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything - larger. - - Bin maps - There is one bit map for small bins ("smallmap") and one for - treebins ("treemap). Each bin sets its bit when non-empty, and - clears the bit when empty. Bit operations are then used to avoid - bin-by-bin searching -- nearly all "search" is done without ever - looking at bins that won't be selected. The bit maps - conservatively use 32 bits per map word, even if on 64bit system. - For a good description of some of the bit-based techniques used - here, see Henry S. Warren Jr's book "Hacker's Delight" (and - supplement at http://hackersdelight.org/). Many of these are - intended to reduce the branchiness of paths through malloc etc, as - well as to reduce the number of memory locations read or written. - - Segments - A list of segments headed by an embedded MallocSegment record - representing the initial space. - - Address check support - The least_addr field is the least address ever obtained from - MORECORE or MMAP. Attempted frees and reallocs of any address less - than this are trapped (unless INSECURE is defined). - - Magic tag - A cross-check field that should always hold same value as mparams.magic. - - Max allowed footprint - The maximum allowed bytes to allocate from system (zero means no limit) - - Flags - Bits recording whether to use MMAP, locks, or contiguous MORECORE - - Statistics - Each space keeps track of current and maximum system memory - obtained via MORECORE or MMAP. - - Trim support - Fields holding the amount of unused topmost memory that should trigger - trimming, and a counter to force periodic scanning to release unused - non-topmost segments. - - Locking - If USE_LOCKS is defined, the "mutex" lock is acquired and released - around every public call using this mspace. - - Extension support - A void* pointer and a size_t field that can be used to help implement - extensions to this malloc. -*/ - -struct MallocState { - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char *least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t release_checks; - size_t magic; - mchunkptr smallbins[(NSMALLBINS + 1) * 2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - size_t footprint_limit; /* zero means no limit */ - flag_t mflags; - msegment seg; - void *extp; /* Unused but available for extensions */ - size_t exts; -}; - -struct MallocStats { - size_t maxfp; - size_t fp; - size_t used; -}; - -typedef struct MallocState *mstate; - -extern struct MallocState g_dlmalloc[1]; - -/* ─────────────────────────────── Hooks ──────────────────────────────── */ - -/* -d = {} -lines = open("log").read().split('\n') -def bad(i): - while i < len(lines): - if lines[i].startswith(('BIRTH', 'DEATH')): - break - print(lines[i]) - i += 1 -for i, line in enumerate(lines): - i += 1 - x = line.split() - if len(x) != 2: continue - if x[0] == 'DEATH': - b = int(x[1], 16) - if b in d: - if d[b] < 0: - print("OH NO", i, d[b]) - else: - d[b] = -d[b] - else: - print("wut", i) - elif x[0] == 'BIRTH': - b = int(x[1], 16) - if b in d: - if d[b] > 0: - print("bad malloc", i, d[b]) - d[b] = i - else: - d[b] = i -for k,v in d.items(): - if v > 0: - print("unfreed", v) - bad(v) -*/ -#define MALLOC_TRACE 0 - -forceinline void *AddressBirthAction(void *p) { -#if MALLOC_TRACE - (dprintf)(2, "BIRTH %p\n", p); - if (weaken(ShowBacktrace)) { - weaken(ShowBacktrace)(2, 0); - } else if (weaken(PrintBacktraceUsingSymbols) && weaken(GetSymbolTable)) { - weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0), - weaken(GetSymbolTable)()); - } -#endif - return p; -} - -forceinline void *AddressDeathAction(void *p) { -#if MALLOC_TRACE - (dprintf)(2, "DEATH %p\n", p); - if (weaken(ShowBacktrace)) { - weaken(ShowBacktrace)(2, 0); - } else if (weaken(PrintBacktraceUsingSymbols) && weaken(GetSymbolTable)) { - weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0), - weaken(GetSymbolTable)()); - } -#endif - return p; -} - -/* - PREACTION should be defined to return 0 on success, and nonzero on - failure. If you are not using locking, you can redefine these to do - anything you like. -*/ - -#define PREACTION(M) (0) -#define POSTACTION(M) - -/* - CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. - USAGE_ERROR_ACTION is triggered on detected bad frees and - reallocs. The argument p is an address that might have triggered the - fault. It is ignored by the two predefined actions, but might be - useful in custom actions that try to help diagnose errors. -*/ - -#define CORRUPTION_ERROR_ACTION(m) MALLOC_ABORT -#define USAGE_ERROR_ACTION(m, p) MALLOC_ABORT - -/* True if segment S holds address A */ -#define segment_holds(S, A) \ - ((char *)(A) >= S->base && (char *)(A) < S->base + S->size) - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE \ - (align_offset(chunk2mem(0)) + pad_request(sizeof(struct MallocSegment)) + \ - MIN_CHUNK_SIZE) - -/* ───────────── Global MallocState and MallocParams ─────────────────── */ - -/* - MallocParams holds global properties, including those that can be - dynamically set using mallopt. There is a single instance, mparams, - initialized in init_mparams. Note that the non-zeroness of "magic" - also serves as an initialization flag. -*/ - -struct MallocParams { - size_t magic; - size_t page_size; - size_t granularity; - size_t mmap_threshold; - size_t trim_threshold; - flag_t default_mflags; -}; - -extern struct MallocParams g_mparams; - -#define ensure_initialization() \ - /* we use a constructor [jart] */ \ - assert(g_mparams.magic != 0) -/* (void)(g_mparams.magic != 0 || init_mparams()) */ - -#define is_initialized(M) ((M)->top != 0) -#define is_page_aligned(S) \ - (((size_t)(S) & (g_mparams.page_size - SIZE_T_ONE)) == 0) -#define is_granularity_aligned(S) \ - (((size_t)(S) & (g_mparams.granularity - SIZE_T_ONE)) == 0) - -/* ────────────────────────── system alloc setup ───────────────────────── */ - -/* Operations on mflags */ - -#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) -#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) -#if USE_LOCKS -#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) -#else -#define disable_lock(M) -#endif - -#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) -#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) -#if HAVE_MMAP -#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) -#else -#define disable_mmap(M) -#endif - -#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) -#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) - -#define set_lock(M, L) \ - ((M)->mflags = \ - (L) ? ((M)->mflags | USE_LOCK_BIT) : ((M)->mflags & ~USE_LOCK_BIT)) - -/* page-align a size */ -#define page_align(S) \ - (((S) + (g_mparams.page_size - SIZE_T_ONE)) & \ - ~(g_mparams.page_size - SIZE_T_ONE)) - -/* granularity-align a size */ -#define granularity_align(S) \ - (((S) + (g_mparams.granularity - SIZE_T_ONE)) & \ - ~(g_mparams.granularity - SIZE_T_ONE)) - -#define mmap_align(s) granularity_align((size_t)(s)) - -/* ──────────────────────── Operations on bin maps ─────────────────────── */ - -#define idx2bit(i) ((binmap_t)(1) << (i)) -#define mark_smallmap(M, i) ((M)->smallmap |= idx2bit(i)) -#define clear_smallmap(M, i) ((M)->smallmap &= ~idx2bit(i)) -#define smallmap_is_marked(M, i) ((M)->smallmap & idx2bit(i)) -#define mark_treemap(M, i) ((M)->treemap |= idx2bit(i)) -#define clear_treemap(M, i) ((M)->treemap &= ~idx2bit(i)) -#define treemap_is_marked(M, i) ((M)->treemap & idx2bit(i)) -#define least_bit(x) ((x) & -(x)) -#define left_bits(x) ((x << 1) | -(x << 1)) -#define same_or_left_bits(x) ((x) | -(x)) -#define compute_bit2idx(X, I) \ - { \ - unsigned int J; \ - J = bsf(X); \ - I = (bindex_t)J; \ - } - -/* ──────────────────────────── Indexing Bins ──────────────────────────── */ - -#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) -#define small_index(s) (bindex_t)((s) >> SMALLBIN_SHIFT) -#define small_index2size(i) ((i) << SMALLBIN_SHIFT) -#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) - -/* addressing by index. See above about smallbin repositioning */ -#define smallbin_at(M, i) ((sbinptr)((char *)&((M)->smallbins[(i) << 1]))) -#define treebin_at(M, i) (&((M)->treebins[i])) - -/* assign tree index for size S to variable I. */ -#define compute_tree_index(S, I) \ - { \ - unsigned int X = S >> TREEBIN_SHIFT; \ - if (X == 0) \ - I = 0; \ - else if (X > 0xFFFF) \ - I = NTREEBINS - 1; \ - else { \ - unsigned int K = \ - (unsigned)sizeof(X) * __CHAR_BIT__ - 1 - (unsigned)__builtin_clz(X); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ - } \ - } - -/* Bit representing maximum resolved size in a treebin at i */ -#define bit_for_tree_index(i) \ - (i == NTREEBINS - 1) ? (SIZE_T_BITSIZE - 1) : (((i) >> 1) + TREEBIN_SHIFT - 2) - -/* Shift placing maximum resolved bit in a treebin at i as sign bit */ -#define leftshift_for_tree_index(i) \ - ((i == NTREEBINS - 1) \ - ? 0 \ - : ((SIZE_T_BITSIZE - SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) - -/* The size of the smallest chunk held in bin with index i */ -#define minsize_for_tree_index(i) \ - ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ - (((size_t)((i)&SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) - -/* ─────────────────────── Runtime Check Support ───────────────────────── */ - -/* - For security, the main invariant is that malloc/free/etc never - writes to a static address other than MallocState, unless static - MallocState itself has been corrupted, which cannot occur via - malloc (because of these checks). In essence this means that we - believe all pointers, sizes, maps etc held in MallocState, but - check all of those linked or offsetted from other embedded data - structures. These checks are interspersed with main code in a way - that tends to minimize their run-time cost. - - When FOOTERS is defined, in addition to range checking, we also - verify footer fields of inuse chunks, which can be used guarantee - that the mstate controlling malloc/free is intact. This is a - streamlined version of the approach described by William Robertson - et al in "Run-time Detection of Heap-based Overflows" LISA'03 - http://www.usenix.org/events/lisa03/tech/robertson.html The footer - of an inuse chunk holds the xor of its mstate and a random seed, - that is checked upon calls to free() and realloc(). This is - (probabalistically) unguessable from outside the program, but can be - computed by any code successfully malloc'ing any chunk, so does not - itself provide protection against code that has already broken - security through some other means. Unlike Robertson et al, we - always dynamically check addresses of all offset chunks (previous, - next, etc). This turns out to be cheaper than relying on hashes. -*/ - -#if !IsTrustworthy() -/* Check if address a is at least as high as any from MORECORE or MMAP */ -#define ok_address(M, a) ((char *)(a) >= (M)->least_addr) -/* Check if address of next chunk n is higher than base chunk p */ -#define ok_next(p, n) ((char *)(p) < (char *)(n)) -/* Check if p has inuse status */ -#define ok_inuse(p) is_inuse(p) -/* Check if p has its pinuse bit on */ -#define ok_pinuse(p) pinuse(p) - -#else /* !IsTrustworthy() */ -#define ok_address(M, a) (1) -#define ok_next(b, n) (1) -#define ok_inuse(p) (1) -#define ok_pinuse(p) (1) -#endif /* !IsTrustworthy() */ - -#if (FOOTERS && !IsTrustworthy()) -/* Check if (alleged) mstate m has expected magic field */ -#define ok_magic(M) \ - ((uintptr_t)(M) <= 0x00007ffffffffffful && (M)->magic == g_mparams.magic) -#else /* (FOOTERS && !IsTrustworthy()) */ -#define ok_magic(M) (1) -#endif /* (FOOTERS && !IsTrustworthy()) */ - -/* In gcc, use __builtin_expect to minimize impact of checks */ -#if !IsTrustworthy() -#if defined(__GNUC__) && __GNUC__ >= 3 -#define RTCHECK(e) __builtin_expect(e, 1) -#else /* GNUC */ -#define RTCHECK(e) (e) -#endif /* GNUC */ -#else /* !IsTrustworthy() */ -#define RTCHECK(e) (1) -#endif /* !IsTrustworthy() */ - -/* macros to set up inuse chunks with or without footers */ - -#if !FOOTERS - -#define mark_inuse_foot(M, p, s) - -/* Macros for setting head/foot of non-mmapped chunks */ - -/* Set cinuse bit and pinuse bit of next chunk */ -#define set_inuse(M, p, s) \ - ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ - ((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ -#define set_inuse_and_pinuse(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - ((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set size, cinuse and pinuse bit of this chunk */ -#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT)) - -#else /* FOOTERS */ - -/* Set foot of inuse chunk to be xor of mstate and seed */ -#define mark_inuse_foot(M, p, s) \ - (((mchunkptr)((char *)(p) + (s)))->prev_foot = \ - ((size_t)(M) ^ g_mparams.magic)) - -#define get_mstate_for(p) \ - ((mstate)(((mchunkptr)((char *)(p) + (chunksize(p))))->prev_foot ^ \ - g_mparams.magic)) - -#define set_inuse(M, p, s) \ - ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ - (((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#define set_inuse_and_pinuse(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - (((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), mark_inuse_foot(M, p, s)) - -#endif /* !FOOTERS */ - -/* Return segment holding given address */ -forceinline msegmentptr segment_holding(mstate m, char *addr) { - msegmentptr sp = &m->seg; - for (;;) { - if (addr >= sp->base && addr < sp->base + sp->size) return sp; - if ((sp = sp->next) == 0) return 0; - } -} - -/* ─────────────────────── Operations on smallbins ─────────────────────── */ - -/* - Various forms of linking and unlinking are defined as macros. Even - the ones for trees, which are very long but have very short typical - paths. This is ugly but reduces reliance on inlining support of - compilers. -*/ - -/* Link a free chunk into a smallbin */ -#define insert_small_chunk(M, P, S) \ - { \ - bindex_t I = small_index(S); \ - mchunkptr B = smallbin_at(M, I); \ - mchunkptr F = B; \ - assert(S >= MIN_CHUNK_SIZE); \ - if (!smallmap_is_marked(M, I)) \ - mark_smallmap(M, I); \ - else if (RTCHECK(ok_address(M, B->fd))) \ - F = B->fd; \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - B->fd = P; \ - F->bk = P; \ - P->fd = F; \ - P->bk = B; \ - } - -/* Unlink a chunk from a smallbin */ -#define unlink_small_chunk(M, P, S) \ - { \ - mchunkptr F = P->fd; \ - mchunkptr B = P->bk; \ - bindex_t I = small_index(S); \ - assert(P != B); \ - assert(P != F); \ - assert(chunksize(P) == small_index2size(I)); \ - if (RTCHECK(F == smallbin_at(M, I) || (ok_address(M, F) && F->bk == P))) { \ - if (B == F) { \ - clear_smallmap(M, I); \ - } else if (RTCHECK(B == smallbin_at(M, I) || \ - (ok_address(M, B) && B->fd == P))) { \ - F->bk = B; \ - B->fd = F; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } - -/* Unlink the first chunk from a smallbin */ -#define unlink_first_small_chunk(M, B, P, I) \ - { \ - mchunkptr F = P->fd; \ - assert(P != B); \ - assert(P != F); \ - assert(chunksize(P) == small_index2size(I)); \ - if (B == F) { \ - clear_smallmap(M, I); \ - } else if (RTCHECK(ok_address(M, F) && F->bk == P)) { \ - F->bk = B; \ - B->fd = F; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } - -/* Replace dv node, binning the old one */ -/* Used only when dvsize known to be small */ -#define replace_dv(M, P, S) \ - { \ - size_t DVS = M->dvsize; \ - assert(is_small(DVS)); \ - if (DVS != 0) { \ - mchunkptr DV = M->dv; \ - insert_small_chunk(M, DV, DVS); \ - } \ - M->dvsize = S; \ - M->dv = P; \ - } - -/* ───────────────────────── Operations on trees ───────────────────────── */ - -/* Insert chunk into tree */ -#define insert_large_chunk(M, X, S) \ - { \ - tbinptr *H; \ - bindex_t I; \ - compute_tree_index(S, I); \ - H = treebin_at(M, I); \ - X->index = I; \ - X->child[0] = X->child[1] = 0; \ - if (!treemap_is_marked(M, I)) { \ - mark_treemap(M, I); \ - *H = X; \ - X->parent = (tchunkptr)H; \ - X->fd = X->bk = X; \ - } else { \ - tchunkptr T = *H; \ - size_t K = S << leftshift_for_tree_index(I); \ - for (;;) { \ - if (chunksize(T) != S) { \ - tchunkptr *C = \ - &(T->child[(K >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]); \ - K <<= 1; \ - if (*C != 0) \ - T = *C; \ - else if (RTCHECK(ok_address(M, C))) { \ - *C = X; \ - X->parent = T; \ - X->fd = X->bk = X; \ - break; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - break; \ - } \ - } else { \ - tchunkptr F = T->fd; \ - if (RTCHECK(ok_address(M, T) && ok_address(M, F))) { \ - T->fd = F->bk = X; \ - X->fd = F; \ - X->bk = T; \ - X->parent = 0; \ - break; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - break; \ - } \ - } \ - } \ - } \ - } - -/* - Unlink steps: - - 1. If x is a chained node, unlink it from its same-sized fd/bk links - and choose its bk node as its replacement. - 2. If x was the last node of its size, but not a leaf node, it must - be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent - of x. We could use any other leaf, but this is easy to locate and - tends to counteract removal of leftmosts elsewhere, and so keeps - paths shorter than minimally guaranteed. This doesn't loop much - because on average a node in a tree is near the bottom. - 3. If x is the base of a chain (i.e., has parent links) relink - x's parent and children to x's replacement (or null if none). -*/ - -#define unlink_large_chunk(M, X) \ - { \ - tchunkptr XP = X->parent; \ - tchunkptr R; \ - if (X->bk != X) { \ - tchunkptr F = X->fd; \ - R = X->bk; \ - if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) { \ - F->bk = R; \ - R->fd = F; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } else { \ - tchunkptr *RP; \ - if (((R = *(RP = &(X->child[1]))) != 0) || \ - ((R = *(RP = &(X->child[0]))) != 0)) { \ - tchunkptr *CP; \ - while ((*(CP = &(R->child[1])) != 0) || \ - (*(CP = &(R->child[0])) != 0)) { \ - R = *(RP = CP); \ - } \ - if (RTCHECK(ok_address(M, RP))) \ - *RP = 0; \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } \ - } \ - if (XP != 0) { \ - tbinptr *H = treebin_at(M, X->index); \ - if (X == *H) { \ - if ((*H = R) == 0) clear_treemap(M, X->index); \ - } else if (RTCHECK(ok_address(M, XP))) { \ - if (XP->child[0] == X) \ - XP->child[0] = R; \ - else \ - XP->child[1] = R; \ - } else \ - CORRUPTION_ERROR_ACTION(M); \ - if (R != 0) { \ - if (RTCHECK(ok_address(M, R))) { \ - tchunkptr C0, C1; \ - R->parent = XP; \ - if ((C0 = X->child[0]) != 0) { \ - if (RTCHECK(ok_address(M, C0))) { \ - R->child[0] = C0; \ - C0->parent = R; \ - } else \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - if ((C1 = X->child[1]) != 0) { \ - if (RTCHECK(ok_address(M, C1))) { \ - R->child[1] = C1; \ - C1->parent = R; \ - } else \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } else \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } \ - } - -/* Relays to large vs small bin operations */ -#define insert_chunk(M, P, S) \ - if (is_small(S)) insert_small_chunk(M, P, S) else { \ - tchunkptr TP = (tchunkptr)(P); \ - insert_large_chunk(M, TP, S); \ - } -#define unlink_chunk(M, P, S) \ - if (is_small(S)) unlink_small_chunk(M, P, S) else { \ - tchunkptr TP = (tchunkptr)(P); \ - unlink_large_chunk(M, TP); \ - } - -#ifndef MORECORE_CANNOT_TRIM -#define should_trim(M, s) ((s) > (M)->trim_check) -#else /* MORECORE_CANNOT_TRIM */ -#define should_trim(M, s) (0) -#endif /* MORECORE_CANNOT_TRIM */ - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE \ - (align_offset(chunk2mem(0)) + pad_request(sizeof(struct MallocSegment)) + \ - MIN_CHUNK_SIZE) - -/* ────────────────────────── Debugging setup ──────────────────────────── */ - -#ifdef DEBUG -#define check_free_chunk(M, P) do_check_free_chunk(M, P) -#define check_inuse_chunk(M, P) do_check_inuse_chunk(M, P) -#define check_top_chunk(M, P) do_check_top_chunk(M, P) -#define check_malloced_chunk(M, P, N) do_check_malloced_chunk(M, P, N) -#define check_mmapped_chunk(M, P) do_check_mmapped_chunk(M, P) -#define check_malloc_state(M) do_check_malloc_state(M) -#else -#define check_free_chunk(M, P) -#define check_inuse_chunk(M, P) -#define check_malloced_chunk(M, P, N) -#define check_mmapped_chunk(M, P) -#define check_malloc_state(M) -#define check_top_chunk(M, P) -#endif /* DEBUG */ - -void do_check_free_chunk(mstate, mchunkptr) hidden; -void do_check_inuse_chunk(mstate, mchunkptr) hidden; -void do_check_top_chunk(mstate, mchunkptr) hidden; -void do_check_malloced_chunk(mstate, void *, size_t) hidden; -void do_check_mmapped_chunk(mstate, mchunkptr) hidden; -void do_check_malloc_state(mstate) hidden; - -/* ─────────────────────────── prototypes ──────────────────────────────── */ - -void *dlmalloc(size_t) hidden attributeallocsize((1)) mallocesque; -void *dlcalloc(size_t, size_t) hidden attributeallocsize((1, 2)) mallocesque; -void dlfree(void *) nothrow nocallback hidden; -void *dlmemalign_impl(mstate, size_t, size_t) hidden; -void *dlrealloc(void *, size_t) hidden reallocesque; -void *dlrealloc_in_place(void *, size_t) hidden reallocesque; -void *dlmemalign(size_t, size_t) hidden attributeallocalign((1)) - attributeallocsize((2)) returnspointerwithnoaliases libcesque nodiscard; -int dlmalloc_trim(size_t) hidden; -size_t dlmalloc_usable_size(const void *) hidden; -void **dlindependent_calloc(size_t, size_t, void *[]) hidden; -void **dlindependent_comalloc(size_t, size_t[], void *[]) hidden; -struct MallocStats dlmalloc_stats(mstate) hidden; -int dlmalloc_sys_trim(mstate, size_t) hidden; -void dlmalloc_dispose_chunk(mstate, mchunkptr, size_t) hidden; -mchunkptr dlmalloc_try_realloc_chunk(mstate, mchunkptr, size_t, int) hidden; -size_t dlbulk_free(void *[], size_t) hidden; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* !ANSI */ -#endif /* COSMOPOLITAN_LIBC_MEM_DLMALLOC_H_ */ diff --git a/third_party/dlmalloc/dlmalloc.mk b/third_party/dlmalloc/dlmalloc.mk index 2e0d6662c..2c27169fa 100644 --- a/third_party/dlmalloc/dlmalloc.mk +++ b/third_party/dlmalloc/dlmalloc.mk @@ -31,9 +31,11 @@ THIRD_PARTY_DLMALLOC_A_DIRECTDEPS = \ LIBC_NEXGEN32E \ LIBC_RUNTIME \ LIBC_STR \ + LIBC_RAND \ LIBC_STUBS \ LIBC_SYSV \ - LIBC_SYSV_CALLS + LIBC_SYSV_CALLS \ + THIRD_PARTY_COMPILER_RT THIRD_PARTY_DLMALLOC_A_DEPS := \ $(call uniq,$(foreach x,$(THIRD_PARTY_DLMALLOC_A_DIRECTDEPS),$($(x)))) @@ -50,13 +52,9 @@ $(THIRD_PARTY_DLMALLOC_A).pkg: \ $(THIRD_PARTY_DLMALLOC_A_OBJS): \ OVERRIDE_CFLAGS += \ $(NO_MAGIC) \ - -fno-sanitize=address - -ifneq ($(MODE),dbg) -$(THIRD_PARTY_DLMALLOC_A_OBJS): \ - OVERRIDE_CFLAGS += \ - -DNDEBUG -endif + -ffreestanding \ + -ffunction-sections \ + -fdata-sections THIRD_PARTY_DLMALLOC_LIBS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x))) THIRD_PARTY_DLMALLOC_SRCS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x)_SRCS)) diff --git a/third_party/dlmalloc/dlmalloc_abort.greg.c b/third_party/dlmalloc/dlmalloc_abort.greg.c new file mode 100644 index 000000000..d2b2fd17a --- /dev/null +++ b/third_party/dlmalloc/dlmalloc_abort.greg.c @@ -0,0 +1,31 @@ +/*-*- 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 2022 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/bits/weaken.h" +#include "libc/calls/calls.h" +#include "libc/log/log.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" + +#define MESSAGE "dlmalloc_abort()\n" + +void dlmalloc_abort(void) { + write(2, MESSAGE, strlen(MESSAGE)); + if (weaken(__die)) weaken(__die)(); + _Exit(44); +} diff --git a/third_party/dlmalloc/dlmalloc_stats.c b/third_party/dlmalloc/dlmalloc_stats.c deleted file mode 100644 index 2923dac86..000000000 --- a/third_party/dlmalloc/dlmalloc_stats.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "libc/mem/mem.h" -#include "libc/str/str.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * Prints on stderr the amount of space obtained from the system (both - * via sbrk and mmap), the maximum amount (which may be more than - * current if malloc_trim and/or munmap got called), and the current - * number of bytes allocated via malloc (or realloc, etc) but not yet - * freed. Note that this is the number of bytes allocated, not the - * number requested. It will be larger than the number requested because - * of alignment and bookkeeping overhead. Because it includes alignment - * wastage as being in use, this figure may be greater than zero even - * when no user-level chunks are allocated. - * - * The reported current and maximum system memory can be inaccurate if a - * program makes other calls to system memory allocation functions - * (normally sbrk) outside of malloc. - * - * malloc_stats prints only the most commonly interesting statistics. - * More information can be obtained by calling mallinfo. - */ -struct MallocStats dlmalloc_stats(mstate m) { - struct MallocChunk *q; - struct MallocStats res; - bzero(&res, sizeof(res)); - ensure_initialization(); - if (!PREACTION(m)) { - check_malloc_state(m); - if (is_initialized(m)) { - msegmentptr s = &m->seg; - res.maxfp = m->max_footprint; - res.fp = m->footprint; - res.used = res.fp - (m->topsize + TOP_FOOT_SIZE); - while (s != 0) { - q = align_as_chunk(s->base); - while (segment_holds(s, q) && q != m->top && - q->head != FENCEPOST_HEAD) { - if (!is_inuse(q)) res.used -= chunksize(q); - q = next_chunk(q); - } - s = s->next; - } - } - POSTACTION(m); /* drop lock */ - } - return res; -} diff --git a/third_party/dlmalloc/dlmalloc_try_realloc_chunk.c b/third_party/dlmalloc/dlmalloc_try_realloc_chunk.c deleted file mode 100644 index 8ecfb94c5..000000000 --- a/third_party/dlmalloc/dlmalloc_try_realloc_chunk.c +++ /dev/null @@ -1,107 +0,0 @@ -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/* Realloc using mmap */ -mchunkptr dlmalloc_mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { - size_t oldsize = chunksize(oldp); - if (is_small(nb)) return 0; /* Can't shrink mmap regions below small size */ - /* Keep old chunk if big enough but not too big */ - if (oldsize >= nb + SIZE_T_SIZE && - (oldsize - nb) <= (g_mparams.granularity << 1)) { - return oldp; - } else { - size_t offset = oldp->prev_foot; - size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; - size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - char *cp = mremap((char *)oldp - offset, oldmmsize, newmmsize, flags, 0); - if (cp != CMFAIL) { - mchunkptr newp = (mchunkptr)(cp + offset); - size_t psize = newmmsize - offset - MMAP_FOOT_PAD; - newp->head = psize; - mark_inuse_foot(m, newp, psize); - chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(newp, psize + SIZE_T_SIZE)->head = 0; - if (cp < m->least_addr) m->least_addr = cp; - if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) { - m->max_footprint = m->footprint; - } - check_mmapped_chunk(m, newp); - return newp; - } - } - return 0; -} - -/* Try to realloc; only in-place unless can_move true */ -mchunkptr dlmalloc_try_realloc_chunk(mstate m, mchunkptr p, size_t nb, - int can_move) { - mchunkptr newp = 0; - size_t oldsize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, oldsize); - if (RTCHECK(ok_address(m, p) && ok_inuse(p) && ok_next(p, next) && - ok_pinuse(next))) { - if (!is_mmapped(p)) { - if (oldsize >= nb) { /* already big enough */ - size_t rsize = oldsize - nb; - if (rsize >= MIN_CHUNK_SIZE) { /* split off remainder */ - mchunkptr r = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, r, rsize); - dlmalloc_dispose_chunk(m, r, rsize); - } - newp = p; - } else if (next == m->top) { /* extend into top */ - if (oldsize + m->topsize > nb) { - size_t newsize = oldsize + m->topsize; - size_t newtopsize = newsize - nb; - mchunkptr newtop = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - newtop->head = newtopsize | PINUSE_BIT; - m->top = newtop; - m->topsize = newtopsize; - newp = p; - } - } else if (next == m->dv) { /* extend into dv */ - size_t dvs = m->dvsize; - if (oldsize + dvs >= nb) { - size_t dsize = oldsize + dvs - nb; - if (dsize >= MIN_CHUNK_SIZE) { - mchunkptr r = chunk_plus_offset(p, nb); - mchunkptr n = chunk_plus_offset(r, dsize); - set_inuse(m, p, nb); - set_size_and_pinuse_of_free_chunk(r, dsize); - clear_pinuse(n); - m->dvsize = dsize; - m->dv = r; - } else { /* exhaust dv */ - size_t newsize = oldsize + dvs; - set_inuse(m, p, newsize); - m->dvsize = 0; - m->dv = 0; - } - newp = p; - } - } else if (!cinuse(next)) { /* extend into next free chunk */ - size_t nextsize = chunksize(next); - if (oldsize + nextsize >= nb) { - size_t rsize = oldsize + nextsize - nb; - unlink_chunk(m, next, nextsize); - if (rsize < MIN_CHUNK_SIZE) { - size_t newsize = oldsize + nextsize; - set_inuse(m, p, newsize); - } else { - mchunkptr r = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, r, rsize); - dlmalloc_dispose_chunk(m, r, rsize); - } - newp = p; - } - } - } else { - newp = dlmalloc_mmap_resize(m, p, nb, can_move); - } - } else { - USAGE_ERROR_ACTION(m, chunk2mem(p)); - } - return newp; -} diff --git a/third_party/dlmalloc/dlrealloc.c b/third_party/dlmalloc/dlrealloc.c deleted file mode 100644 index 22f649fcf..000000000 --- a/third_party/dlmalloc/dlrealloc.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "libc/bits/likely.h" -#include "libc/str/str.h" -#include "libc/sysv/errfuns.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -void *dlrealloc(void *oldmem, size_t bytes) { - void *mem = 0; - size_t oc, nb; - struct MallocState *m; - struct MallocChunk *oldp, *newp; - if (oldmem) { - if (LIKELY(bytes < MAX_REQUEST)) { - if (bytes) { - nb = request2size(bytes); - oldp = mem2chunk(oldmem); -#if !FOOTERS - m = g_dlmalloc; -#else /* FOOTERS */ - m = get_mstate_for(oldp); - if (UNLIKELY(!ok_magic(m))) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - if (!PREACTION(m)) { - newp = dlmalloc_try_realloc_chunk(m, oldp, nb, 1); - POSTACTION(m); - if (newp) { - check_inuse_chunk(m, newp); - mem = chunk2mem(newp); - } else if ((mem = dlmalloc(bytes))) { - oc = chunksize(oldp) - overhead_for(oldp); - memcpy(mem, oldmem, (oc < bytes) ? oc : bytes); - dlfree(oldmem); - } - } - } else { - dlfree(oldmem); - } - } else { - enomem(); - } - } else { - mem = dlmalloc(bytes); - } - return mem; -} diff --git a/third_party/dlmalloc/dlrealloc_in_place.c b/third_party/dlmalloc/dlrealloc_in_place.c deleted file mode 100644 index ab9bbc9ba..000000000 --- a/third_party/dlmalloc/dlrealloc_in_place.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "libc/mem/mem.h" -#include "libc/sysv/errfuns.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -void *dlrealloc_in_place(void *oldmem, size_t bytes) { - void *mem = 0; - if (oldmem != 0) { - if (bytes >= MAX_REQUEST) { - enomem(); - } else { - size_t nb = request2size(bytes); - mchunkptr oldp = mem2chunk(oldmem); -#if !FOOTERS - mstate m = g_dlmalloc; -#else /* FOOTERS */ - mstate m = get_mstate_for(oldp); - if (!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - if (!PREACTION(m)) { - mchunkptr newp = dlmalloc_try_realloc_chunk(m, oldp, nb, 0); - POSTACTION(m); - if (newp == oldp) { - check_inuse_chunk(m, newp); - mem = oldmem; - } - } - } - } - return mem; -} diff --git a/third_party/dlmalloc/initdlmalloc.S b/third_party/dlmalloc/initdlmalloc.S deleted file mode 100644 index 5ef5a91f1..000000000 --- a/third_party/dlmalloc/initdlmalloc.S +++ /dev/null @@ -1,29 +0,0 @@ -/*-*- 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│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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 "libc/macros.internal.h" -.source __FILE__ - -// Sneak ahead ctor list b/c runtime weakly links malloc. - .init.start 800,_init_dlmalloc - push %rdi - push %rsi - call dlmalloc_init - pop %rsi - pop %rdi - .init.end 800,_init_dlmalloc,globl,hidden diff --git a/third_party/dlmalloc/mallinfo.c b/third_party/dlmalloc/mallinfo.c deleted file mode 100644 index b696a5055..000000000 --- a/third_party/dlmalloc/mallinfo.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * Returns (by copy) a struct containing various summary statistics: - * - * - arena: current total non-mmapped bytes allocated from system - * - * - ordblks: the number of free chunks - * - * - smblks: always zero. - * - * - hblks: current number of mmapped regions - * - * - hblkhd: total bytes held in mmapped regions - * - * - usmblks: the maximum total allocated space. This will be greater - * than current total if trimming has occurred. - * - * - fsmblks: always zero - * - * - uordblks: current total allocated space (normal or mmapped) - * - * - fordblks: total free space - * - * - keepcost: the maximum number of bytes that could ideally be - * released back to system via malloc_trim. ("ideally" means that it - * ignores page restrictions etc.) - * - * Because these fields are ints, but internal bookkeeping may - * be kept as longs, the reported values may wrap around zero and - * thus be inaccurate. - */ -struct mallinfo mallinfo(void) { - struct mallinfo nm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - ensure_initialization(); - if (!PREACTION(g_dlmalloc)) { - check_malloc_state(g_dlmalloc); - if (is_initialized(g_dlmalloc)) { - size_t nfree = SIZE_T_ONE; /* top always free */ - size_t mfree = g_dlmalloc->topsize + TOP_FOOT_SIZE; - size_t sum = mfree; - msegmentptr s = &g_dlmalloc->seg; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && q != g_dlmalloc->top && - q->head != FENCEPOST_HEAD) { - size_t sz = chunksize(q); - sum += sz; - if (!is_inuse(q)) { - mfree += sz; - ++nfree; - } - q = next_chunk(q); - } - s = s->next; - } - nm.arena = sum; - nm.ordblks = nfree; - nm.hblkhd = g_dlmalloc->footprint - sum; - nm.usmblks = g_dlmalloc->max_footprint; - nm.uordblks = g_dlmalloc->footprint - mfree; - nm.fordblks = mfree; - nm.keepcost = g_dlmalloc->topsize; - } - POSTACTION(g_dlmalloc); - } - return nm; -} diff --git a/third_party/dlmalloc/malloc_footprint.c b/third_party/dlmalloc/malloc_footprint.c deleted file mode 100644 index 818f8cc7e..000000000 --- a/third_party/dlmalloc/malloc_footprint.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * Returns the number of bytes obtained from the system. The total - * number of bytes allocated by malloc, realloc etc., is less than this - * value. Unlike mallinfo, this function returns only a precomputed - * result, so can be called frequently to monitor memory consumption. - * Even if locks are otherwise defined, this function does not use them, - * so results might not be up to date. - */ -size_t malloc_footprint(void) { - return g_dlmalloc->footprint; -} diff --git a/third_party/dlmalloc/malloc_footprint_limit.c b/third_party/dlmalloc/malloc_footprint_limit.c deleted file mode 100644 index 84cd9bc4e..000000000 --- a/third_party/dlmalloc/malloc_footprint_limit.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "libc/limits.h" -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * Returns the number of bytes that the heap is allowed to obtain from - * the system, returning the last value returned by - * malloc_set_footprint_limit, or the maximum size_t value if never set. - * The returned value reflects a permission. There is no guarantee that - * this number of bytes can actually be obtained from the system. - */ -size_t malloc_footprint_limit(void) { - size_t maf = g_dlmalloc->footprint_limit; - return maf == 0 ? SIZE_MAX : maf; -} diff --git a/third_party/dlmalloc/malloc_inspect_all.c b/third_party/dlmalloc/malloc_inspect_all.c deleted file mode 100644 index f1fa6e938..000000000 --- a/third_party/dlmalloc/malloc_inspect_all.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -static void internal_inspect_all(mstate m, - void (*handler)(void *start, void *end, - size_t used_bytes, - void *callback_arg), - void *arg) { - if (is_initialized(m)) { - mchunkptr top = m->top; - msegmentptr s; - for (s = &m->seg; s != 0; s = s->next) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) { - mchunkptr next = next_chunk(q); - size_t sz = chunksize(q); - size_t used; - void *start; - if (is_inuse(q)) { - used = sz - CHUNK_OVERHEAD; /* must not be mmapped */ - start = chunk2mem(q); - } else { - used = 0; - if (is_small(sz)) { /* offset by possible bookkeeping */ - start = (void *)((char *)q + sizeof(struct MallocChunk)); - } else { - start = (void *)((char *)q + sizeof(struct MallocTreeChunk)); - } - } - if (start < (void *)next) { /* skip if all space is bookkeeping */ - handler(start, next, used, arg); - } - if (q == top) break; - q = next; - } - } - } -} - -/** - * Traverses the heap and calls the given handler for each managed - * region, skipping all bytes that are (or may be) used for bookkeeping - * purposes. Traversal does not include include chunks that have been - * directly memory mapped. Each reported region begins at the start - * address, and continues up to but not including the end address. The - * first used_bytes of the region contain allocated data. If - * used_bytes is zero, the region is unallocated. The handler is - * invoked with the given callback argument. If locks are defined, they - * are held during the entire traversal. It is a bad idea to invoke - * other malloc functions from within the handler. - * - * For example, to count the number of in-use chunks with size greater - * than 1000, you could write: - * - * static int count = 0; - * void count_chunks(void* start, void* end, size_t used, void* arg) { - * if (used >= 1000) ++count; - * } - * - * then, - * - * malloc_inspect_all(count_chunks, NULL); - */ -void malloc_inspect_all(void (*handler)(void *start, void *end, - size_t used_bytes, void *callback_arg), - void *arg) { - ensure_initialization(); - if (!PREACTION(g_dlmalloc)) { - internal_inspect_all(g_dlmalloc, handler, arg); - POSTACTION(g_dlmalloc); - } -} diff --git a/third_party/dlmalloc/malloc_max_footprint.c b/third_party/dlmalloc/malloc_max_footprint.c deleted file mode 100644 index 301b2b989..000000000 --- a/third_party/dlmalloc/malloc_max_footprint.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * Returns the maximum number of bytes obtained from the system. This - * value will be greater than current footprint if deallocated space has - * been reclaimed by the system. The peak number of bytes allocated by - * malloc, realloc etc., is less than this value. Unlike mallinfo, this - * function returns only a precomputed result, so can be called - * frequently to monitor memory consumption. Even if locks are otherwise - * defined, this function does not use them, so results might not be up - * to date. - */ -size_t malloc_max_footprint(void) { - return g_dlmalloc->max_footprint; -} diff --git a/third_party/dlmalloc/malloc_set_footprint_limit.c b/third_party/dlmalloc/malloc_set_footprint_limit.c deleted file mode 100644 index 68d840421..000000000 --- a/third_party/dlmalloc/malloc_set_footprint_limit.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "libc/limits.h" -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * Sets the maximum number of bytes to obtain from the system, causing - * failure returns from malloc and related functions upon attempts to - * exceed this value. The argument value may be subject to page rounding - * to an enforceable limit; this actual value is returned. Using an - * argument of the maximum possible size_t effectively disables checks. - * If the argument is less than or equal to the current - * malloc_footprint, then all future allocations that require additional - * system memory will fail. However, invocation cannot retroactively - * deallocate existing used memory. - */ -size_t malloc_set_footprint_limit(size_t bytes) { - size_t result; /* invert sense of 0 */ - if (bytes == 0) result = granularity_align(1); /* Use minimal size */ - if (bytes == SIZE_MAX) { - result = 0; /* disable */ - } else { - result = granularity_align(bytes); - } - return g_dlmalloc->footprint_limit = result; -} diff --git a/third_party/dlmalloc/malloc_trim.c b/third_party/dlmalloc/malloc_trim.c deleted file mode 100644 index e6982a8a8..000000000 --- a/third_party/dlmalloc/malloc_trim.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * If possible, gives memory back to the system (via negative arguments - * to sbrk) if there is unused memory at the `high` end of the malloc - * pool or in unused MMAP segments. You can call this after freeing - * large blocks of memory to potentially reduce the system-level memory - * requirements of a program. However, it cannot guarantee to reduce - * memory. Under some allocation patterns, some large free blocks of - * memory will be locked between two used chunks, so they cannot be - * given back to the system. - * - * The `pad` argument to malloc_trim represents the amount of free - * trailing space to leave untrimmed. If this argument is zero, only the - * minimum amount of memory to maintain internal data structures will be - * left. Non-zero arguments can be supplied to maintain enough trailing - * space to service future expected allocations without having to - * re-obtain memory from the system. - * - * @return 1 if it actually released any memory, else 0 - */ -int dlmalloc_trim(size_t pad) { - /* asan runtime depends on this function */ - int result = 0; - ensure_initialization(); - if (!PREACTION(g_dlmalloc)) { - result = dlmalloc_sys_trim(g_dlmalloc, pad); - POSTACTION(g_dlmalloc); - } - return result; -} diff --git a/third_party/dlmalloc/mallopt.c b/third_party/dlmalloc/mallopt.c deleted file mode 100644 index a7ab0d604..000000000 --- a/third_party/dlmalloc/mallopt.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "libc/limits.h" -#include "libc/mem/mem.h" -#include "third_party/dlmalloc/dlmalloc.internal.h" - -/** - * Sets memory allocation parameter. - * - * The format is to provide a (parameter-number, parameter-value) pair. - * mallopt then sets the corresponding parameter to the argument value - * if it can (i.e., so long as the value is meaningful), and returns 1 - * if successful else 0. SVID/XPG/ANSI defines four standard param - * numbers for mallopt, normally defined in malloc.h. None of these are - * use in this malloc, so setting them has no effect. But this malloc - * also supports other options in mallopt: - * - * Symbol param # default allowed param values - * M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) - * M_GRANULARITY -2 page size any power of 2 >= page size - * M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) - */ -bool32 mallopt(int param_number, int value) { - size_t val; - ensure_initialization(); - val = (value == -1) ? SIZE_MAX : (size_t)value; - switch (param_number) { - case M_TRIM_THRESHOLD: - g_mparams.trim_threshold = val; - return true; - case M_GRANULARITY: - if (val >= g_mparams.page_size && ((val & (val - 1)) == 0)) { - g_mparams.granularity = val; - return true; - } else { - return false; - } - case M_MMAP_THRESHOLD: - g_mparams.mmap_threshold = val; - return true; - default: - return false; - } -} diff --git a/third_party/dlmalloc/vespene.greg.c b/third_party/dlmalloc/vespene.greg.c new file mode 100644 index 000000000..bbcbd0989 --- /dev/null +++ b/third_party/dlmalloc/vespene.greg.c @@ -0,0 +1,40 @@ +/*-*- 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 2022 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/bits/weaken.h" +#include "libc/calls/calls.h" +#include "libc/intrin/asan.internal.h" +#include "libc/intrin/asancodes.h" +#include "libc/intrin/kprintf.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +/** + * Acquires more system memory for dlmalloc. + */ +void *dlmalloc_requires_more_vespene_gas(size_t size) { + char *p; + if ((p = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0)) != MAP_FAILED) { + if (weaken(__asan_poison)) { + weaken(__asan_poison)((uintptr_t)p, size, kAsanHeapFree); + } + } + return p; +} diff --git a/third_party/dlmalloc/vespene.internal.h b/third_party/dlmalloc/vespene.internal.h new file mode 100644 index 000000000..6c4445999 --- /dev/null +++ b/third_party/dlmalloc/vespene.internal.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_DLMALLOC_VESPENE_INTERNAL_H_ +#define COSMOPOLITAN_THIRD_PARTY_DLMALLOC_VESPENE_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void *dlmalloc_requires_more_vespene_gas(size_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_DLMALLOC_VESPENE_INTERNAL_H_ */ diff --git a/third_party/gdtoa/gdtoa.h b/third_party/gdtoa/gdtoa.h index 42b9a9ac5..83d331dd8 100644 --- a/third_party/gdtoa/gdtoa.h +++ b/third_party/gdtoa/gdtoa.h @@ -92,6 +92,10 @@ int strtopxL(const char *, char **, void *); #define strtopxL(s, se, x) strtorxL(s, se, 1, x) #endif +float wcstof(const wchar_t *, wchar_t **); +double wcstod(const wchar_t *, wchar_t **); +long double wcstold(const wchar_t *, wchar_t **); + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_THIRD_PARTY_GDTOA_GDTOA_H_ */ diff --git a/third_party/gdtoa/strtod_l.c b/third_party/gdtoa/strtod_l.c new file mode 100644 index 000000000..346894004 --- /dev/null +++ b/third_party/gdtoa/strtod_l.c @@ -0,0 +1,24 @@ +/*-*- 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 2022 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/unicode/locale.h" +#include "third_party/gdtoa/gdtoa.h" + +double strtod_l(const char *s, char **endptr, locale_t l) { + return strtod(s, endptr); +} diff --git a/third_party/gdtoa/strtof.c b/third_party/gdtoa/strtof.c index 3fb2f2518..4017171b5 100644 --- a/third_party/gdtoa/strtof.c +++ b/third_party/gdtoa/strtof.c @@ -29,6 +29,7 @@ │ THIS SOFTWARE. │ │ │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "third_party/gdtoa/gdtoa.h" #include "third_party/gdtoa/gdtoa.internal.h" /* clang-format off */ diff --git a/third_party/gdtoa/strtof_l.c b/third_party/gdtoa/strtof_l.c new file mode 100644 index 000000000..e302df715 --- /dev/null +++ b/third_party/gdtoa/strtof_l.c @@ -0,0 +1,24 @@ +/*-*- 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 2022 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/unicode/locale.h" +#include "third_party/gdtoa/gdtoa.h" + +float strtof_l(const char *s, char **sp, locale_t l) { + return strtof(s, sp); +} diff --git a/third_party/gdtoa/wcstod.c b/third_party/gdtoa/wcstod.c new file mode 100644 index 000000000..41b1439e3 --- /dev/null +++ b/third_party/gdtoa/wcstod.c @@ -0,0 +1,27 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/fmt/conv.h" +#include "libc/runtime/runtime.h" +#include "libc/unicode/locale.h" + +double wcstod(const wchar_t *nptr, wchar_t **endptr) { + assert(!"not implemented"); + abort(); +} diff --git a/third_party/gdtoa/wcstof.c b/third_party/gdtoa/wcstof.c new file mode 100644 index 000000000..7b1ac07c6 --- /dev/null +++ b/third_party/gdtoa/wcstof.c @@ -0,0 +1,28 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/fmt/conv.h" +#include "libc/runtime/runtime.h" +#include "libc/unicode/locale.h" +#include "third_party/gdtoa/gdtoa.h" + +float wcstof(const wchar_t *nptr, wchar_t **endptr) { + assert(!"not implemented"); + abort(); +} diff --git a/third_party/gdtoa/wcstold.c b/third_party/gdtoa/wcstold.c new file mode 100644 index 000000000..b925100eb --- /dev/null +++ b/third_party/gdtoa/wcstold.c @@ -0,0 +1,28 @@ +/*-*- 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 2022 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/assert.h" +#include "libc/fmt/conv.h" +#include "libc/runtime/runtime.h" +#include "libc/unicode/locale.h" +#include "third_party/gdtoa/gdtoa.h" + +long double wcstold(const wchar_t *nptr, wchar_t **endptr) { + assert(!"not implemented"); + abort(); +} diff --git a/third_party/gdtoa/wcstold_l.c b/third_party/gdtoa/wcstold_l.c new file mode 100644 index 000000000..8b75c0d84 --- /dev/null +++ b/third_party/gdtoa/wcstold_l.c @@ -0,0 +1,25 @@ +/*-*- 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 2022 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/fmt/conv.h" +#include "libc/unicode/locale.h" +#include "third_party/gdtoa/gdtoa.h" + +long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, locale_t l) { + return wcstold(nptr, endptr); +} diff --git a/third_party/getopt/initgetopt.S b/third_party/getopt/initgetopt.S index 457c31ee5..ffc4f7f2b 100644 --- a/third_party/getopt/initgetopt.S +++ b/third_party/getopt/initgetopt.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ .init.start 201,_init_getopt push $1 diff --git a/third_party/infozip/infozip.mk b/third_party/infozip/infozip.mk deleted file mode 100644 index 12b59237d..000000000 --- a/third_party/infozip/infozip.mk +++ /dev/null @@ -1,148 +0,0 @@ -#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ -#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ - -PKGS += THIRD_PARTY_ZIP - -THIRD_PARTY_ZIP_FILES := \ - $(wildcard third_party/infozip/zip/*) \ - $(wildcard third_party/infozip/zip/unix/*) - -THIRD_PARTY_ZIP_SRCS = $(filter %.c,$(THIRD_PARTY_ZIP_FILES)) -THIRD_PARTY_ZIP_HDRS = $(filter %.h,$(THIRD_PARTY_ZIP_FILES)) -THIRD_PARTY_ZIP_INCS = $(filter %.inc,$(THIRD_PARTY_ZIP_FILES)) - -THIRD_PARTY_ZIP_COMS = \ - o/$(MODE)/third_party/infozip/zip.com \ - o/$(MODE)/third_party/infozip/zipsplit.com \ - o/$(MODE)/third_party/infozip/zipnote.com \ - o/$(MODE)/third_party/infozip/zipcloak.com - -THIRD_PARTY_ZIP_BINS = \ - $(THIRD_PARTY_ZIP_COMS) \ - $(THIRD_PARTY_ZIP_COMS:%=%.dbg) - -THIRD_PARTY_ZIP_OBJS = $(sort \ - $(THIRD_PARTY_ZIP_COM_OBJS) \ - $(THIRD_PARTY_ZIPCLOAK_OBJS) \ - $(THIRD_PARTY_ZIPNOTE_OBJS) \ - $(THIRD_PARTY_ZIPSPLIT_OBJS) \ - ) - -THIRD_PARTY_ZIP_UTIL_OBJS1 = \ - o/$(MODE)/third_party/infozip/zip/globals.o \ - o/$(MODE)/third_party/infozip/zip/unix/unix_.o \ - o/$(MODE)/third_party/infozip/zip/zipfile_.o \ - o/$(MODE)/third_party/infozip/zip/fileio_.o \ - o/$(MODE)/third_party/infozip/zip/util_.o - -THIRD_PARTY_ZIP_UTIL_OBJS2 = \ - o/$(MODE)/third_party/infozip/zip/crypt_.o \ - o/$(MODE)/third_party/infozip/zip/crc32_.o - -THIRD_PARTY_ZIP_UTIL_OBJS = \ - $(THIRD_PARTY_ZIP_UTIL_OBJS1) \ - $(THIRD_PARTY_ZIP_UTIL_OBJS2) - -THIRD_PARTY_ZIP_COM_OBJS = \ - o/$(MODE)/third_party/infozip/zip/zip.o \ - o/$(MODE)/third_party/infozip/zip/zipfile.o \ - o/$(MODE)/third_party/infozip/zip/zipup.o \ - o/$(MODE)/third_party/infozip/zip/fileio.o \ - o/$(MODE)/third_party/infozip/zip/util.o \ - o/$(MODE)/third_party/infozip/zip/globals.o \ - o/$(MODE)/third_party/infozip/zip/crypt.o \ - o/$(MODE)/third_party/infozip/zip/ttyio.o \ - o/$(MODE)/third_party/infozip/zip/unix/unix.o \ - o/$(MODE)/third_party/infozip/zip/crc32.o \ - o/$(MODE)/third_party/infozip/zip/zbz2err.o \ - o/$(MODE)/third_party/infozip/zip/deflate.o \ - o/$(MODE)/third_party/infozip/zip/trees.o - -THIRD_PARTY_ZIPSPLIT_OBJS = \ - o/$(MODE)/third_party/infozip/zip/zipsplit.o \ - $(THIRD_PARTY_ZIP_UTIL_OBJS1) - -THIRD_PARTY_ZIPNOTE_OBJS = \ - o/$(MODE)/third_party/infozip/zip/zipnote.o \ - $(THIRD_PARTY_ZIP_UTIL_OBJS1) - -THIRD_PARTY_ZIPCLOAK_OBJS = \ - o/$(MODE)/third_party/infozip/zip/zipcloak.o \ - o/$(MODE)/third_party/infozip/zip/ttyio.o \ - $(THIRD_PARTY_ZIP_UTIL_OBJS1) \ - $(THIRD_PARTY_ZIP_UTIL_OBJS2) - -THIRD_PARTY_ZIP_LARGE_OBJS = \ - o/$(MODE)/third_party/infozip/zip/zip.o \ - o/$(MODE)/third_party/infozip/zip/zipsplit.o \ - o/$(MODE)/third_party/infozip/zip/fileio.o \ - o/$(MODE)/third_party/infozip/zip/fileio_.o - -o/$(MODE)/third_party/infozip/zip/%_.o: \ - third_party/infozip/zip/%.c \ - o/$(MODE)/third_party/infozip/zip/%.o - @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) -DUTIL $< - -$(THIRD_PARTY_ZIP_OBJS): \ - OVERRIDE_CPPFLAGS += \ - -DUNIX \ - -DMMAP \ - -DUNICODE_SUPPORT \ - -DUSE_EF_UT_TIME \ - -DLARGE_FILE_SUPPORT \ - -DHAVE_DIRENT_H \ - -DHAVE_TERMIOS_H \ - -DNO_BZIP2_SUPPORT \ - -DZIP64_SUPPORT - -$(THIRD_PARTY_ZIP_LARGE_OBJS): \ - OVERRIDE_CPPFLAGS += \ - -DSTACK_FRAME_UNLIMITED - -THIRD_PARTY_ZIP_DIRECTDEPS = \ - LIBC_ERRNO \ - LIBC_LIMITS \ - LIBC_ALG \ - LIBC_FMT \ - LIBC_STR \ - LIBC_MEM \ - LIBC_LOG \ - LIBC_CALLS \ - LIBC_STDIO \ - LIBC_TIME \ - LIBC_UNICODE - -THIRD_PARTY_ZIP_DEPS := \ - $(call uniq,$(foreach x,$(THIRD_PARTY_ZIP_DIRECTDEPS),$($(x)))) - -o/$(MODE)/third_party/infozip/zip.com.dbg: \ - $(THIRD_PARTY_ZIP_DEPS) \ - $(THIRD_PARTY_ZIP_COM_OBJS) \ - $(CRT) \ - $(APE) - @$(APELINK) - -o/$(MODE)/third_party/infozip/zipsplit.com.dbg: \ - $(THIRD_PARTY_ZIP_DEPS) \ - $(THIRD_PARTY_ZIPSPLIT_OBJS) \ - $(CRT) \ - $(APE) - @$(APELINK) - -o/$(MODE)/third_party/infozip/zipnote.com.dbg: \ - $(THIRD_PARTY_ZIP_DEPS) \ - $(THIRD_PARTY_ZIPNOTE_OBJS) \ - $(CRT) \ - $(APE) - @$(APELINK) - -o/$(MODE)/third_party/infozip/zipcloak.com.dbg: \ - $(THIRD_PARTY_ZIP_DEPS) \ - $(THIRD_PARTY_ZIPCLOAK_OBJS) \ - $(CRT) \ - $(APE) - @$(APELINK) - -.PHONY: o/$(MODE)/third_party/infozip -o/$(MODE)/third_party/infozip: \ - $(THIRD_PARTY_ZIP_BINS) diff --git a/third_party/infozip/zip/BUGS b/third_party/infozip/zip/BUGS deleted file mode 100644 index 21a9013f6..000000000 --- a/third_party/infozip/zip/BUGS +++ /dev/null @@ -1,6 +0,0 @@ -- zip sometimes crashes on some versions of NetBSD (0.8, 0.9 and early - 0.9-current), FreeBSD (<= 1.1) and BSDI (< 1.1) . This is due to a - bug in stdio. - Upgrading the stdio package in /usr/src/lib/libc/stdio should - fix the problem. See *BSD mirrors in src/lib/libc/stdio - You must at least replace setvbuf.o in all the libc's with a newer version. diff --git a/third_party/infozip/zip/CHANGES b/third_party/infozip/zip/CHANGES deleted file mode 100644 index 751695f2c..000000000 --- a/third_party/infozip/zip/CHANGES +++ /dev/null @@ -1,3460 +0,0 @@ -------------------------- August 7th 1996 version 2.2a ------------------ - 1. QDOS port (Jonathan Hudson) - 2. win32 volumelabel handling (Paul) - 3. VM/CMS clean up (Greg Hartwig) - 4. leading "../" in internal filenames are allowed (Paul) - 5. System V packages support (John Bush) - 6. Fix handling of atx in zipup() (Onno, Greg) - 7. Fixed typo that caused zip -R to dump core (Onno) - 8. msdos/makefile.dj2: fix for command line too long when linking zip.exe - 9. win95 long filename support with djgpp v2 (Onno, Kimio Itoh) -------------------------- August 9th 1996 version 2.2b ------------------ - 1. windll: use wiz instead of wizip (Mike) - 2. use z->name NOT z->zname to open files (Onno, Mike) ------------------------- September 1st 1996 version 2.2c ------------------ - 1. windll: use fprintf instead of putc to send data to std{out,err} (Mike) - 2. os2: make borlandc version detection equal to unzip 5.30d (Kai Uwe) - 3. use #elif constructions for msdos,os2 and win32 compiler detection (Onno) - 4. fix for incorrect free in zip.c (Onno, Mike, Steve) - 5. BeBox port from Chris - 6. unix/{configure,Makefile} fixes for SCO Xenix 286 (Tom Schmidt) - 7. remove zilog entry from unix/Makefile (Onno) - 8. man page fixes (Tom Schmidt) - 9. SCO ODT {3,5} fixes (Bill Davidsen) ------------------------- October 8th 1996 version 2.2d ------------------ - 1. Fix bug in QDOS patch that broke zipsplit.c (Onno, Paul) - 2. Fix a couple of warnings from BorlandC (Mike) - 3. msdos/makefile.wat: Delete some more files when cleaning up (Paul) - 4. store msdos volumelabels without a dot in them (Paul) - 5. clean up of unix/{Makefile,configure,packaging} (Tom Schmidt) - 6. make QDOS port case independent (Jonathan Hudson) - 7. new amiga SASC makefile (Walter Haidinger) - 8. don't truncate filenames in win32's in2ex() (Paul) - 9. os2/makefile.os2 update for emx 0.9c (Kai Uwe) -10. password() function for QDOS (Jonathan) -11. fix the last(?) free() related bug (Mike) -12. win32: security descriptors operations (Scott Field) -13. win32: FILE_SHARE_DELETE is not defined in some win32 compilers (Onno) -14. win32: fix makefile.wat to include nt.c (Onno) ------------------------- January 17th 1997 version 2.2e ------------------ - 1. define USE_CASE_MAP in osdep.h for those ports that need it (Onno) - 2. define PROCNAME in osdep.h for those ports that need it (Onno) - 3. wild() prototype decl only if PROCNAME defined => delete MSVMS define (Onno) - 4. add DOS EMX makefile (E-Yen Tan) - 5. include a little earlier in qdos/qdos.c (Jonathan) - 6. add ttyio.o to OBJZ in qdos/Makefile.qdos (Jonathan) - 7. remove unused fprintebc define from zip.c (Onno) - 8. use the right password routine in ttyio.c for unzip (Mike) - 9. BeOS update from Chris -10. Fix for 'zip -r foo x:' (Paul) -11. Fix library bug on beos (Chris) -12. Fix calculating version number (kitoh_@mix.or.jp, Walter Haidinger) -13. IsWinNT always returned TRUE (Mike) -14. Windll update from Mike -15. Improved crc routines for x86 from Scott Field -16. Detect in unix/configure if we can use crc_i386.S (Onno) -17. Fix spurious internal logic error (Paul) -18. Fix to include directory names on the Acorn when needed (Sergio) -19. include zip.h in mvs.h (Onno, George Carr) -20. add workaround for AZTEC C compiler bug to revision.h (Paul, Walter) -21. MVS doesn't have rmdir (George Carr) -22. define and use USE_ZIPMAIN for WINDLL en VM_CMS (Onno) -23. Fixes from Greg Hartwig to make CMS standalone versions possible. -24. Move OS specific encryption stuff to the os specific directories (Christian) -25. Change password fetching interface in ttyio and crypt (Christian) -26. Update emx support for 0.9c (Christian) -27. Define WINDLL instead of MSWIN (Christian) -28. Extended time stamp extra field format support (Christian) -29. Support for rsxnt-emx 0.9c win32 compiler (Christian) -30. Use izshr017b (Christian) ------------------------- March 11th 1997 version 2.2f ------------------ - 1. Move makefile.emx, rsxwinnt.h and zip.def to win32 subdir (Kai Uwe) - 2. Add win32 target to makefile.os2 to allow cross compilation (Kai Uwe) - 3. Fix NTSD_EAS link time failures with win32 (Paul) - 4. Fix buffer freed too early in password verification code (Mike) - 5. Remove unix/zipgrep and man/zipgrep.1 (sanvila@ctv.es) - 6. Only use crc_i386.o when we're using an x86 (Onno, Mark) - 7. Remove carriage returns from amiga/crc_68.a (Paul) - 8. New windll from Mike - 9. Fix typo in os2/os2zip.c (Kai Uwe) -10. Don't use ctime (last file status change) for unix and qdos cross compile - (Greg) -11. added gccwin32 crosscompilation target (RSXNT) to os2/makefile.os2 (Kai Uwe) -12. fixed the OS/2 file attribute and time stamp generation for zipping - stdin ("-") (Kai Uwe) -13. fixed the atime and ctime stat fields for the OS/2 Watcom C library - (Kai Uwe) -14. added atime and ctime support for the UT extra field when generated under - OS/2, the atime and ctime values are only stored when zipping (Kai Uwe) -15. qdos patches from Jonathan Hudson mainly for extended time flag handling -16. amiga aztec compiler bug workaround (Paul) -17. fix -v output of zipcloak, zipnote and zipsplit (Paul) -18. new amiga/makefile.azt with targets for debug versions (Paul) ------------------------- March 31st 1997 version 2.2g ------------------ - 1. remove -I/usr/local/include from unix/Makefile (Chris) - 2. Update versinfolines in revision.h (Greg) - 3. change 1U to 0x1 to accomodate non ANSI compilers (Onno, Rodney Brown) - 4. win32zip.c: cast buffer parameter in memcompress() to char * (Mike) - 5. remove beos/zipgrep (Chris) - 6. correct the -e password verification check in zip.c (Christian) - 7. use ZCONST instead of const in the generic code. (Christian) - 8. fix mktime timezone correction when time is near to daylight/nodaylight - switch points. (Christian) - 9. correct dependencies in makefile.os2 (Christian) -10. use a more sensible default for iztime.ctime than "0" when system does not - not support creation time stamps. (Christian) -11. fix VMS_PK_EXTRA function interface declarations. (Christian) -12. implement atime/ctime support in win32. (Christian) -13. win32/win32.c: replacement getch() for Watcom. (Paul) -14. win32/makefile.wat: debug object files kept separate. (Paul) -15. msdos/makefile.wat: debug object files kept separate. (Paul) -16. Fix extended time defines for the acorn. (Sergio) -17. Define PROCNAME() in acorn/osdep.h (Sergio) -18. Ignore exit status of ${INSTALL_D} in unix/Makefile (Chris) -19. Add Metroworks and BEOS info to version() in several files (Chris) -20. Move defines for the password fetch to zip.h (Christian) -21. Support the obsolete version rsxnt 1.1 / emx 0.9b (Christian) -22. Remove obsolete "#define PROCNAME ..." from cmsmvs/cmsmvs.h (Christian) -23. Fix extended time defines for qdos (Jonathan Hudson) -24. Use watcom getch() from unz530q in win32/win32.c (Onno) -25. Don't install zipgrep via the unix package tools (John Bush) -26. use izshr021 (Onno) -27. Fix zipnote: use iname not zname in zipnote.c (Onno) -28. Create proginfo directory (Christian) ------------------------- May 5th 1997 version 2.2h -------------------- - 1. Fix vms/zipup.h: iztime --> iztimes (Onno, Mike Freeman) - 2. Remove windll/wizdll.def (Mike) - 3. Add a couple of external variable declaration to windll.h (Mike) - 4. Remove zipgrep from install in unix/Makefile (Onno) - 5. Make updating .zip files with extended time fields possible (Kai Uwe) - 6. Delete beos/Makefile.gcc, beos/Makefiles handles both compilers (Chris) - 7. Fixes for unused variables (Chris) - 8. Added very simplistic example how to load and call the windll (Mike) - 9. Updated windll documentation to note this example (Mike) -10. Removed an unused memeber of a structure in windll (Mike) -11. Add BUGS instead of infozip.who and algorith.doc with the packaging - tools (John Bush) -12. tailor.h: increment NUM_HOSTS to keep in sync with UnZip (Christian) -13. win32/osdep.h: remove NO_SECURE_TESTS define (Christian) -14. zip.h: add declaration for free_crc_table() (Christian) -15. windll: move everything that's not windows specific into api.* (Mike) -16. use iname when checking for directory names in zipfile.c (Sergio) -17. improved mktime.c with better error checking (Christian) -18. improved crc routines (Christian, Rodney Brown) -19. get the -z option working again (Onno, Brad Clarke) -20. define BROKEN_FSEEK and seekable() for those systems where fseek() - always returns 0 (== OK) (Onno, Jeffrey Altman) ------------------------- May 10th 1997 version 2.2i -------------------- - 1. win32's seekable should only check for FILE_TYPE_DISK (Onno, Jeffrey Altman) - 2. add (ulg) cast to zipbeg = ~0 in zipfile.c (Steve) - 3. seekable() *really* belongs in flush_block, keep it there (Onno) - 4. seekable() calls fseekable(FILE *) (Onno) - 5. define HAVE_FSEEKABLE if a port has their own fseekable (Onno) - 6. WatCom doesn't have _get_osfhandle, use _os_handle instead (Paul) - 7. upgrade to Mike's latest windll sources (Mike) - 8. add -P option so you can specify a password on the commandline (Onno) - 9. Get -@ working again (Onno) -10. emx+RSXNT doesn't know about _get_osfhandle() (Kai Uwe) -11. fix a couple of typos in the OS/2 makefiles (Kai Uwe) -12. fix initialization bug in windll code (Mike) -13. tweak deletedir for RISC OS (Sergio) -14. RISCOS doesn't know about fstat() (Sergio) -15. Remove acorn/acorn (Sergio) -16. Delete debugging statements from version_local() in msdos.c (Greg) -17. Fix huge bug in readzipfile() (Onno) ------------------------- May 18th 1997 version 2.2j -------------------- - 1. Add missing ';' after return ZE_PARMS in zip.c (Mike) - 2. Remove obsolete 'struct stat st' in zipfile.c (Onno) - 3. Get Amiga SFX handling working again (Paul) - 4. Get zip -A working again (Onno) - 5. Change an && to & in zipfile.c (Johnny) - 6. Fix handling of empty sfx archives (Onno, Mike) - 7. Remove experimental entries from the makefiles (Jean-loup) - 8. Add exit codes to the manual page (Onno) - 9. Remove lines from the help screen that contain lesser used options (Onno) ------------------------- June 8th 1997 version 2.2k -------------------- - 1. use zip -t ddmmyyyy for year 2000 stuff (Greg) - 2. zip -@ only handles ONE filename per line (Jean-loup) - 3. beos support for DR9 filesystem and symlinks (Chris) - 4. VB support for windll (Mike) ------------------------- June 10th 1997 version 2.2l ------------------- - 1. beos filetype support (Chris) - 2. fill the buffer in getnam() to get it working again (Onno) - 3. implement -x@filename and -i@filename (Onno) ------------------------- June 22nd 1997 version 2.2m ------------------- - 1. Add a ; after de nextarg label in main() (Onno, Erik Baatz) - 2. Initialize p to NULL in get_filters() (Onno, Frank Donahoe) - 3. Fix typo in first if statement in filetypes() (Johnny Lee) - 4. zip -A works again (Onno, Greg) - 5. don't free zipbuf for VMS and CMS_MVS in main() (Onno, Mike Freeman) - 6. fix make_zip.com, link_zip.com and vmsdefs.h for gcc 2.6.3 on VMS (Onno) - 7. clarify -g option in the man page (Jean-loup) ------------------------- July 6th 1997 version 2.2n ------------------- - 1. use local in readzipfile2() declaration (Onno, Mike Freeman) - 2. return values with windll in get_filters() (Mike) - 3. a couple of minor patches for BEOS (Chris) - 4. zip -g works again (Onno, Chris) - 5. Some more Visual Basic dll support (Mike) - 6. Fix stack overflow in readzipfile() for DOS (Onno, Michael Mauch) ------------------------- August 19th 1997 version 2.2o ------------------- - 1. beos README and Makefile tweaks from Chris. - 2. Syntax corrections for README and man/zip.1 (Frank Donahoe) - 3. Use name not iname when deleting directories in trash() (Christian) - 4. change several wkuvx1 to lists in e-mail addresses (Christian) - 5. default to PK style extra fields for VMS (Christian) - 6. use izshr023 (Christian) - 7. replace buggy time library functions (Walter Haidinger, Paul, Christian) - 8. in2ex() and stat() are needed also when UTIL isn't defined (Greg Hartwig) - 9. don't use type=record in fopen() for MVS and CMS (Greg Hartwig) -10. Change P and K literals to hex for EBCDIC systems (Greg Hartwig) -11. Add output path support for CMS and MVS (Greg Hartwig) -12. Add memtoasc and memtoebc for EBCDIC systems (Greg Hartwig) -13. Handle comments correctly to fix zipnote for CMS and MVS (Greg Hartwig) -14. Add -tt option (do not operate on files after date mmddyy) (Christian) -15. move alloc routines for DOS into the !UTIL block (Christian) -16. move UTIL blocks and version_local() functions to a more logical place - (Christian) -17. Handle -P, -R, -x@, -i@ and -tt for the VMS CLI (Christian) -18. Update VMS help file with the new options (Christian) -19. Use iname in MATCH, not zname (Jonathan Hudson) -20. windll: more Visual Basic support (Mike) -21. windll: more project makefiles (Mike) -22. windll: insert Zip in front of global variable names (Mike) ------------------------- August 25th 1997 version 2.2p ------------------- - 1. Remove unused flags from LFLAGS2 in unix/Makefile (Onno) - 2. SunOS make bug: change unix_.o rule in unix/Makefile (Onno, Mike Freeman) - 3. ZipIsWinNT() instead of IsWinNT() in zip.h (Mike) - 4. Fix -t and -tt behaviour for windll (Mike) - 5. Remove windll makefiles that are now elsewhere (Mike) - 6. BEOS: preserve file attributes associated with symbolic links (Chris) - 7. No need to use in2ex() for ziputils (Christian) - 8. Fix comment handling for EBCDIC systems (Christian) - 9. EBCDIC conversion for entry names read from zipfile in UTIL mode (Christian) -10. Fix "fatal" error messages on EBCDIC systems (Christian) -11. zipnote.c: Fix handling of entry name changes for EBCDIC systems (Christian) -12. removed a large part of "dead" code from ziputils version (Christian) -13. use z->iname in comparison functions for sorting (Christian) -14. new installation utils for the acorn (Sergio) -15. use LSSTAT in set_extra_field for unix and beos (Onno) -16. perror(z->zname) instead of perror("zip warning") (Onno, Geoff Pennington) -17. Amiga SFX should work again (Paul) -18. refer to zip22 in install.doc (Frank Donahoe) ------------------------- September 10th 1997 version 2.2q ------------------- - 1. Change .doc to .txt, these aren't MS-Word documents (John D. Mitchell) - 2. Change msdos$_(OBJ) to msdos_$(OBJ) (Kai Uwe) - 3. Fix a couple of amiga related glitches (Paul) - 4. Support for DOS packed .exe files in makefile.dj2 (Frank Donahoe) - 5. Change warning message for zip -A (Greg) ------------------------- September 29th 1997 version 2.2r ------------------- - 1. Fix make svr4package (Eric Baatz) - 2. Fix VMS warning (Mike Freeman, Christian) - 3. Clean up beos gcc port and beos README (Chris) --------------------------- October 6th 1997 version 2.2s -------------------- - 1. Change lpPrint to lpZipPrint for windll (Mike) - 2. Change lpPassword to lpZipPassword for windll (Mike) - 3. Amiga timezone fixes (Paul) - 4. WatCom C 11.0 makefile fixes (Paul) - 5. Tandem port from Dave Smith - 6. Corrections and updates for install.txt (Christian) - 7. Minor VMS README update (Christian) --------------------------- October 12th 1997 version 2.2t -------------------- - 1. qdos compiler bug workaround (Jonathan) - 2. prevent storing qdos specific filenames that exceed filesystem limits - (Jonathan) - 3. fix undelimited comment in fileio.c (Frank Donahoe) - 4. disable storing of symlinks in BEOS until OS support is available (Chris) - 5. Init hash_head to 0 in amiga/deflate.a (Paul) - 6. Upgrade to izshr025 (Christian) - 7. don't add ".zip" to ZIP name for TANDEM (Dave Smith) - 8. use zipup.h not tandem.h in zipup.c (Dave Smith) - 9. rename history to CHANGES (Onno) -10. rename install.txt to INSTALL (Onno) -11. rename zip.txt to ZIPMAN (Onno) -12. create WHATSNEW (Onno) --------------------------- October 15th 1997 version 2.2u -------------------- - 1. Use Info-ZIP instead of Info-Zip (Christian) - 2. Note recent filename changes in several files (Christian) - 3. Remove a couple of items from the TODO list (Christian, Onno) - 4. Add windll port, zip -t yyyymmdd and zip -R to WHATSNEW (Christian) - 5. VMS documentation cleanups and clarifications (Christian) - 6. dist entry in unix/Makefile (Onno) - 7. remove duplicate amiga/timezone.txt (Christian) - 8. rename ZIPMAN to MANUAL and update a couple of files regarding this (Onno) --------------------------- October 24th 1997 version 2.2v -------------------- - 1. izshr026: in WHERE wiz40 instead of wiz30 (Christian) - 2. izshr026: another couple of Info-ZIP spelling fixes (Christian) - 3. Remove zipgrep from the makefiles that still had it (Christian) - 4. Update makefiles to handle the MANUAL renaming change (Christian) - 5. Fix the last daylight savings bug on the Amiga (Paul) - 6. Fix the SCO Unix specialty detection in unix/configure (Onno, - bug reported by Bo Kullmar for Solaris 2.6 and with uname -X output - for SCO Unix from ken@apisys.com and dgsmith@vnet.ibm.com) - 7. Update WHERE and amiga/time_lib.c from unzip 5.32g (Greg) --------------------------- October 26th 1997 version 2.2w -------------------- - 1. Additional +Onolimit check in unix/configure (Onno, Peter Jones) - 2. Use ZIPERR macro instead of ziperr (Christian) - 3. initialize z->lflg for zip entries without extra field (Christian) - 4. "local (+ locextend)" vs. "central" header consistency check (Christian) - 5. Override local header values with central header values with -A - and differences between these headers (Christain) - 6. made "deltaoff" signed long; offset adjustment may be negative (Christian) - 7. fix a number of "wild" deallocation bugs (Christian) - 8. When zipping from a FAT drive (only 8.3 DOS names) under OS/2 or - WIN32, set z->vem to "OS_DOS | ". - Mark as "made by DOS PKZIP 2.0" only when dosify was requested. (Christian) - 9. DOS port should not store fake unix style external attributes. (Christian) -10. amiga/time_lib.c from izshr028 (Christian) --------------------------- October 31st 1997 version 2.2y -------------------- - 1. amiga/time_lib.c from izshr029 (Christian) - 2. Turbo C++ version code clarification (E-Yen Tan) - 3. Fix spelling in cmsvms/zipname.conven (Rodney Brown) - 4. Fix memset check in unix/configure for Unixware 2.1.1 (Rodney Brown) - 5. Forward declaration fixes for HP-UX bundled compiler (Rodney Brown) --------------------------- November 3rd 1997 version 2.2 -------------------- - 1. Update WHERE (Greg). --------------------------- January 4th 1998 version 2.21a ------------------- - 1. BSD friendly version of version_local() in unix/unix.c (Onno) - 2. No NT versions in DOS version_local() (Steve Salisbury) - 3. -t mmddyyyy instead of -t ddmmyyyy in WHATSNEW (Walter Haidinger) - 4. use generic fseekable() for rsxnt (Christian) - 5. Fix MSC 8.x warnings (Christian, Steve Salisbury) - 6. win32 Borland C++ makefile (E-Yen Tan) - 7. Tandem doesn't know about extensions like .zip,.arj, ... (Dave Smith) - 8. Use dosmatch for EMX and DJGPP too (Christian) - 9. dummy djgpp startup functions to remove command line globbing and - recognition of environment variables from djgpp.env (Christian) -10. include DJGPP_MINOR in DOS version_local() (Christian) -11. TC 2.0 doesn't have mktime() (Christian, mmp@earthling.net) -12. VMS: rename opendir() to zopendir() so avoiding name clash with - VMS 7.x POSIX libraries (Christian, Martin Zinser) -13. Add support for VMS DEC C V 5.6 features (Christian) -14. Use iname for comparison in check_dup (Christian Spieler, Christian Michel) -15. Fix access to uninitialized ioctx records in vms_get_attributes() - Christian, Robert Nielsen) -16. Parenthesis around MAX_MATCH>>1 in match.S (Greg) -17. Use strchr() not strrchr() for -i and -x to get -i@ and -x@ really - working (Onno, Kai Uwe) -18. add chmod statements to unix/Makefile (Quentin Barnes) -19. Windll: handle both -r and -R (Mike) -20. Windll: general error handler in main() via setjmp/longjmp (Mike) -21. Don't allow zip -i@x.lst foo.zip (Onno) -22. vms/link_zip.com: use .eqs. not .nes. when checking with f$search - for the zip AXP object library (David Dachtera) -23. rsxnt 1.3.1 fixes (E-Yen Tan) --------------------------- January 20th 1998 version 2.21b ------------------- - 1. Bigger PATH_MAX for win32's windll (Mike) - 2. Update windll.txt w.r.t. PATH_MAX (Mike) - 3. Amiga SAS/C fixes (Walter, Paul) - 4. zip -i@ and -x@ should *really* work now ...... (Onno) --------------------------- February 20th 1998 version 2.21c ------------------- - 1. make -f unix/Makefile qnx needs LN=ln in its options (Chris) - 2. Support Metroworks Codewarrior/x86 on BEOS (Chris) - 3. Add Norbert Pueschel to proginfo/infozip.who (Walter) - 4. Use big endian for Be types (Chris) - 5. zip -i and -x were broken by the -i@ fix last time around (Christian) - 6. win32 stat bandaid (Paul) - 7. acorn filetype and timestamp fixes (Sergio, D. Krumbholz) - 8. update to izshr30 (Christian) - 9. Support for NTSD in the RSXNT environment (Christian) -10. restructure readzipfile() (Christian) -11. Where needed define MATCH in osdep.h (Christian) -12. version_local() fixes for RSXNT (Christian) -13. New vmsmunch.c (Christian) --------------------------- March 15th 1998 version 2.3a ------------------- - 1. Fixes for the windll API (Mike) - 2. Use CPUTYPE in BorlandC Makefile for DOS (E-Yen Tan) - 3. BEOS: -rostr not available for the x86 compiler (Chris) - 4. preserve file attributes of a symlink on BEOS (Chris) - 5. New VM/CMS README.CMS and version_local() (Ian Gorman) - 6. INSTALL fixes from Takahiro Watanabe - 7. OS/390 port from Paul von Behren - 8. new api.h from Mike --------------------------- April 19th 1998 version 2.3b ------------------- - 1. Improve Tandem file I/O performance (Dave Smith) - 2. New VM/CMS README.CMS and version_local() (Ian Gorman) - 3. cygwin32 port from Cosmin Truta - 4. Workaround for tasm32 5.0 bug in win32/crc_i386.asm (Cosmin Truta) - 5. win32/match32.asm fixes for tasm 5.0 (Cosmin Truta) - 6. simplify OS/390 port (Christian) - 7. win32 timezone handling fixes (Christian) - 8. fix 40-bit time conversion on the acorn (Sergio and Christian) - 9. strip network part from UNC type filenames (Christian) -10. Makefile for OpenMVS (Ian Gorman) -11. Use the Watcom getch() for cygwin32 (Christian) -12. Borland C++ 5.x added to win32's version_local() (Cosmin Truta) -13. Borland C++ needs tzset() in win32 (Christian, Cosmin Truta) --------------------------- May 21st 1998 version 2.3c ------------------- - 1. Better error messages for -i and -x (Christian) - 2. Win32 stat() wrapper needs dos2unixtime (Christian,Paul,Mike) - 3. DJGPP: use _chmod to handle LFN attributes correctly (Michael Mauch) - 4. Fix Borlandc warnings (Mike) - 5. win32/makefile.bor fixes from Michael Mauch - 6. win32/makefile.{dj,emx} fixes from E-Yen Tan - 7. Use izshr031 (Christian) - 8. CMS: use RECFM=V LRECL=32760 by adding "byteseek" (Greg Hartwig) - 9. Check external name for trailing "/" (Greg Hartwig) -10. More specific info in CMS version_local() (Greg Hartwig) -11. Changed usage info to refer to "fm" rather than "path" on CMS (Greg Hartwig) -12. No more "extra data" messages when using the same OS (Greg Hartwig) -13. Rewritten README.CMS, one version for ZIP and UNZIP (Greg Hartwig) -14. DOS/OS2/WIN32/UNIX: ex2in() strips off "//host/share/" from UNC names (SPC) --------------------------- June 23rd 1998 version 2.3d ------------------- - 1. Fixed Win32's stat() bandaid handling of time stamps (SPC) - 2. General fix of file selections for DELETE and FRESHEN action (SPC) - 3. CMS_MVS: Use ASCII coding for TIME extra field ID (SPC) - 4. EBCDIC: Repaired bogus CMS_MVS fix in zipup.c; check the internal - name for trailing (ASCII) '/' to detect directory entries (SPC) - 5. Use explicit ASCII coding when comparing or setting chars in iname (SPC) - 6. Fixed win32/makefile.bor, win32/makefile.dj (support NTSD), - win32/makefile.emx (SPC) - 7. Replaced win32/makefile.cyg by win32/makefile.gcc, containing new - support for mingw32 GCC environment (SPC) - 8. Use izshr032 (SPC) - 9. Modified zipup.c to hold (un)compressed lengths in "ulg" variables, in - an attempt to support handling of huge (>2GByte) files. (SPC) -10. Removed some duplicate #defines from api.h, they are now in crypt.h (SPC) -11. Reenabled "extra data size" info messages in noisy mode for all systems - except RISCOS and CMS_MVS (SPC) -12. For EMX 0.9c, the runtime lib contains a working mktime(), use it (SPC) -13. Miscellanous cosmetic changes (SPC) -14. Move win32/makefile.emx to msdos (E-Yen Tan) -15. make api.h work with zcrypt2.8 (Mike) -16. define ydays differently in api.h to avoid linking problems (Mike) -17. New windll.txt (Mike) -18. win32 lcc patches (E-Yen Tan) -19. win32 lcc makefile (E-Yen Tan) -20. Multiple inclusion bug: no malloc.h when using lcc-win32 (E-Yen Tan) -21. New VB support files for windll (Mike Le Voi, Raymond King) -22. MacOS port by Dirk Haase --------------------------- August 1st 1998 version 2.3e ------------------- - 1. Generalized check for validy of TZ timezone setup info, similar to - UnZip; use it on AMIGA and MSDOS, as before. (SPC) - 2. Apply TZ validy check on OS/2 and enable creation of UT e.f. (SPC) - 3. BEOS: New Makefile, updates for README and Contents (Chris Herborth) - 4. beos/beos.c: declare some private functions as "local" (SPC) - 5. Include memcompress() code only for ports that make use of it, controlled - by preprocessor symbol ZP_NEED_MEMCOMPR (SPC) - 6. cmsmvs/README.CMS fix: Zip archive entries to be extracted into var-length - records CMS files should >>NOT<< contain binary data ... (SPC) - 7. crc32.c, crctab.c: the crc polynom table is ZCONST (SPC) - 8. trees.c: fixed a bug in the deflate algorithm that limited the compressed - size of an archive member to 512 MByte (SPC) - 9. deflate.c: Integrated the changes found in zlib that are neccessary to make - the deflate algorithm deterministic; modified msdos/match.asm to take - care of the "nice_match" global no longer being constant. (SPC) -10. deflate.c, trees.c, zipup.c: Reorganized and simplified deflate's - compressed output buffer handling. I/O and compression code are now - separated more cleanly. (SPC) -11. Killed bits.c by moving its contents into trees.c resp. zipup.c; - synchronized all Makefiles and Make procedures with this change. (SPC) -12. Integrated support for optionally replacement of deflate and crc32 by - public domain zlib code. (SPC) -13. Synchronize the different variants (UNIX/GNU C, OS/2, WIN32) of i386 - assembler replacement for deflate's longest_match() (SPC) -14. Moved the EMX+rsxnt Makefile.emx from msdos/ back into win32/ (SPC) -15. Restored a separate Makefile.emx for DOS; on DOS, some make programs may - have difficulties with recursive invokation (SPC) -16. Fixed the "include header mess" of the new MACOS port and removed the - "work-around hacks" caused by these bad MACOS .h-file includes (SPC) -17. Integrated Dirk Haase's beta4 (27-Jun-98) release of MacZIP (Dirk Haase) -18. Added support for MS Quick C in the MSDOS version_local() report (SPC) -19. Added WIN32 rsxnt targets linking against the emx crtl DLL to Makefile.emx - in os2/ and win32/ (SPC) -20. Fixed typo in os2/os2.c wild() function. (Kai Uwe Rommel) -21. Removed ChangeNameForFAT() from os2/os2.c in2ex() to fix problem with - long filename support. (Kai Uwe Rommel) -22. os2/os2zip.[ch]: correct type of DOS-style timestamp data is "ulg" (SPC) -23. vms/cmdline.c: Removed wrong ';' behind if condition (Johnny Lee) -24. VMS: Preliminary preparations in C code for supporting GNU C on OpenVMS - Alpha (Onno van der Linden, Christian Spieler) -25. VMS: Fixed check against adding zipfile to itself in fileio.c (SPC) -26. WIN32: Added lcc-Win32 variants of i386 assembler code for crc32() and - longest_match(). (SPC) -27. WIN32: Removed bogus type-cast in assignment to statb st_mode member (SPC) -28. zip.c: Fixed MACOS-related typo that broke "-@" command option (SPC) -29. zipup.c: Fixed messed-up expression for assignment to z->ver (SPC) -30. MACOS extra fields: check realloc return values (Onno, Johnny Lee) -31. Fix the PUTBYTE macro in trees.c: >= instead of < (Onno) --------------------------- September 6th 1998 version 2.3f ------------------- - 1. Add zp_tz_is_valid to globals.c (Onno, Frank Donahoe) - 2. Updated tandem files from Dave Smith - 3. Windll: allow comments to zip archive with VB (Mike) - 4. Windll: add support for -b and update the documentation (Mike) - 5. win32: use wbS for FOPW to handle large zip files better (Steve Miller) - 6. MVS fix: use fseek();clearerr() instead of rewind() (Onno, Lee Burton) - 7. Updated VB examples for windll (Mike) - 8. Tandem: use UTC timestamps and GID/UID in extra field (Dave Smith) - 9. Tandem: handle -o option (Dave Smith) -10. default for ZCONST is const in tailor.h, override in osdep.h (Onno) -11. additional Macintosh options in zip.c (Dirk Haase) -12. additional Macintosh options in zip.1 and MANUAL (Onno, Dirk Haase) -13. Integrate Beta 5 of the Macintosh Port (Dirk Haase) --------------------------- October 27th 1998 version 2.3g ------------------- - 1. zip_tz_is_valid should be zp_tz_is_valid (Kai Uwe) - 2. MVS native (not OE) beta fixes (Keith Owens) - 3. LynxOS support from Giuseppe Guerrini - 4. MVS already has stat() and fstat() so use 'em (Keith Owens) - 5. MVS fix in readzipfile() for new, unopened dataset without EOF marker - (Keith Owens) - 6. Remove 16-bit stuff from windll/windll.rc (Mike) - 7. Windll: Use hCurrentInst not hInst (Mike) - 8. In util.c compare strchr() return value with NULL (Onno, Frank Donahoe) - 9. unix/unix.c: initialize variable t in ex2in() (Onno, Frank Danahoe) -10. Remove windll/borland subdirectory (Mike) -11. Really fix extra field realloc() for BeOS and MacOS (Christian) -12. Fix the dj2 LFN related access violation bug (Christian, Joe Forster) -13. proginfo/3rdparty.bug: Added more info about other Zip clone's bugs. -14. The global copyright definitions in revision.h now depend on DEFCPYRT - (Christian). -15. tandem/macros: removed obsolete object file references (Christian) -16. fix memory leak with the "filter" patterns (Christian, Leah Kramer) -17. zip.c: completed the support for MacOS specific -N (Christian) -18. reorganized the Mac specific help screen code (Christian) -19. zipup.c: corrected the USE_ZLIB code to emit "stored" entries under - the same conditions as the "native deflate" code (Christian) -20. A couple of vars that will never be negative should be unsigned (Christian) --------------------------- November 18th 1998 version 2.3h ------------------- - 1. DJGPP: When compressing from stdin don't set binary mode if stdin is - a terminal (E-Yen Tan) - 2. Fix signed/unsigned comparisons in fileio.c, util.c and zipcloak.c - (Frank Donahoe) - 3. Move macgetch() prototype from macos/source/macos.c to macos/osdep.h - (Christian) - 4. _doserrno should have type int, not unsigned int (Christian) - 5. In zipfile.c init a file pointer with NULL to fix gcc warning (Christian) - 6. Upgrade to MacOS beta 7 (Dirk Haase) - 7. Move the #pragma statements from generic sources to cmsmvs.h (Christian) - 8. Support for QNX/Neutrino 2.0 (Chris) - 9. Default to -r in help screen add -R at the bottom (Chris) -10. Clean up Makefile for BeOS R4 on x86 (Chris) -11. Beos: If not storing symlinks store attributes of symlink target (Chris) -12. Use izshr037 (Christian) -13. Remove ZIPERR() macro from in {msdos,win32}/osdep.h (Christian) -14. win32/win32.c: Fix 1-day offset in non-64bit FileTime2utime() (Christian) -15. win32: enable 64-bit FileTime2utime() for MS VC++ >= 5.0 (Christian) -16. cygwin32 only has _P_WAIT (Thomas Klausner) -17. msname() should *really* ignore illegal characters (Thomas Klausner) -18. Fix a missing ')' in Opendir() from win32zip.c (Thomas Klausner) --------------------------- December 5th 1998 version 2.3i ------------------- - 1. Remove the #pragma statements that were forgotten the first time (Ian) - 2. Remove obsolete macos/source/CharMap.h (Steve Salisbury) - 3. isatty(fileno(zstdin)) in zipup.c should be isatty(zstdin) - (Onno, E-Yen Tan) - 4. several "shut up warnings from compiler" fixes (Christian) - 5. several cosmetic source changes (Christian) - 6. win32: make NTSD handling to be robust against alignment and structure - padding problems (Christian) - 7. Apply don't set binary mode when stdin is a terminal in zipup.c for - MSDOS and human68k (Christian) - 8. Upgrade to MacOS beta 8 (Dirk Haase) - 9. Add callback for WINDLL to handle user termination (Mike) -10. Fix typo in acornzip.c (Darren Salt) -11. acorn/sendbits.s: pass correct parameters to flush_outbuf() (Darren Salt) -12. Fixes for IBM C/C++ 3.6 where time_t is a double (Kai Uwe) -13. Fixes for IBM Visual Age C++ for win32 (Douglas Hendrix) -14. man/zip.1: some version numbers in the text were still "2.2" (Christian) -15. win32/makefile.emx: added a compilation variant that generates - standalone executables (Christian) -16. change __CYGWIN32__ into __CYGWIN__ and add compatiblity definition for - B19 and older (Cosmin Truta) -17. create uniform win32 getch() replacement (Christian) -18. put back in define of USE_EF_UT_TIME in tandem.h (Dave Smith) -19. put back in define of USE_CASE_MAP in tandem.h (Dave Smith) -20. updates to make/macros to allow the object to be licensed (Dave Smith) -21. updates to macros/doit to remove mktime.c (Dave Smith) -22. updates to tandem.c for in2ex/mapname/chmod amendments to match Unzip - (Dave Smith) -23. Use izshr039.zip (Christian) -24. Init filenotes to 0 for the amiga too (Onno) -25. get_filters(): remove one flag=0 statement to make -R work again (Onno) --------------------------- December 17th 1998 version 2.3j ------------------ - 1. FOPWT defines opening a temp file for writing (Ian) - 2. Remove handling of bits.c from a couple of tandem files (Christian) - 3. A couple of "shut up warnings from compiler" fixes (Christian) - 4. win32/osdep.h: removed duplicate "IZ_PACKED" definition (Christian) - 5. win32/zipup.h: remove invalid "elseif" preprocessor token (Christian) - 6. sync MacOS help screen with other ports (Christian) - 7. get_filters(): set flag to 0 when -R isn't used (Christian) - 8. "local extra != central extra" now has "info" status (Christian) - 9. use windll directory as "home" directory for builds (Mike) -10. CMS/MVS: define FOPWT (Ian) -11. Upgrade to MacOS beta 9 (Dirk Haase) --------------------------- January 17th 1999 version 2.3k ------------------ - 1. Change FOPW into FOPW_TMP (Christian) - 2. win32: #include uses paths relative to the parent directory (Christian) - 3. Use forward slashes as path separator in #include statements (Christian) - 4. windll: fix descriptions of f{In,Ex}cludeDate (Christian) - 5. win32/makefile.lcc: add some -I options to find files in the - right places (Christian) - 6. Supply default empty IZ_PACKED define (Christian) - 7. windll: Fix some typos, descriptions (Christian) - 8. windll project files: use relative paths, no specific root directory - (Christian) - 9. windll project files: remove link references to import libraries that - are not used by the zip library (Christian) -10. windll: fix potential infinite loop in a VB sample (Mike) -11. windll/windll.txt: remove "may not work with VB" statement (Mike) -12. Multibyte character set support from Yoshioka Tsuneo -13. Theos port from Jean-Michel Dubois -14. Tandem: added simple handling of Enscribe files by converting them into - text type files (Dave Smith) -15. Tandem Extra Field ("TA") containing Tandem File Attributes (Dave Smith) -16. Tandem history file showing background info to (UN)ZIP ports (Dave Smith) -17. create ZIP file on tandem with special file code (1001) (Dave Smith) -18. made tandem.c & tandem.h code completely the same as UNZIP (Dave Smith) -19. unix/configure: move +Onolimit and -Olimit into the machine specific - section (Onno, John Wiersba) --------------------------- February 21st 1999 version 2.3l ------------------ - 1. Fix qdos Makefile (Jonathan Hudson) - 2. fgets instead of gets in zipnote to fix linker warnings (Jonathan Hudson) - 3. Theos: remove _setargv.c and a reference in zip.c (Jean-Michel Dubois) - 4. Theos README (Jean-Michel Dubois) - 5. interchanged the fRecurse flag values for "-R" and "-r" (Christian) - 6. add "z" pr prefix to MBCS functions to avoid name clashes (Christian) - 7. Whenever the position of the increment operator does not matter, the - INCSTR variant is used, which has been mapped to the {PRE|POS}INCSTR - variant that is more efficient. (Christian) - 8. fixed the "-R" handling in fileio.c, filter() function (Christian) - 9. simplified some THEOS specific code additions (Christian) -10. changed the line break of the compiler version message in version_local() - for MSDOS and Win32 to take into account some verbose compilers (Christian) -11. removed the THEOS changes from ttyio.c. Instead, a THEOS specific - setup was added to ttyio.h (Christian) -12. sync vms/link_zip.com with the corresponding make_zip.com (Christian) -13. added compatibility settings for support of MBCS on Win32 with all tested - compilers to win32/osdep.h -14. added type-casts to isalpha() macro calls (Christian) -15. fixed win32's wild_match which was clobbered by the MBCS addition - (Christian) -16. finished up the "potential infinite loop" problems in the VB sample - that Mike started to repair (Christian) -17. in ziperr.h, AZTEK C might require the false comma that was removed - to satisfy THEOS C (Christian) -18. removed the bogus THEOS specific isdir check in zipup.c (Christian) -19. modified the code for line ending translation to be independent - of the local system's convention for '\n' and '\r'; this allowed - the removal of the THEOS specialities (Christian) -20. Tandem: -B option to zip Enscribe files with no record delimiters - (Dave Smith) -21. Tandem: attempt to catch Large Transfer mode failure (Dave Smith) -22. Theos: Fixed keyboard entry functions. (Jean-Michel Dubois) -23. Theos: workaround for the argument wild card expansion that is bugged - in the standard library. Managed by MAINWA_BUG flag. (Jean-Michel Dubois) -24. Theos: support for filenames and notes with accented characters. - (Jean-Michel Dubois) -25. Upgrade to MacOS final (Dirk Haase) --------------------------- March 31st 1999 version 2.3m ------------------- - 1. Theos: for relative paths to root directory cause open, fopen and stat - failure, workaround this. (Jean-Michel Dubois) - 2. Theos: when no path is indicated in a file or directory name and the - file or directory doesn't exist in the current directory it looks for - the file or directory in the root directory, workaround this. - (Jean-Michel Dubois) - 3. Corrected some typos and spelling error in macos/HISTORY.TXT; skipped - off invisible trailing whitespace (Christian) - 4. proginfo/extra.fld: added documentation for Tandem and Theos extra - field layout (Christian with Dave D Smith resp. Jean-Michel Dubois) - 5. qdos/Makefile.qdos: The build of ZipCloak requires inclusion of - the crctab object module; qfileio_.o compilation requires the -DUTIL - flag (Christian) - 6. win32: fix incorrect MB_CUR_MAX macro for mingw32 and lcc (Christian) - 7. theos/_fprintf.c, theos/_rename.c, theos/osdep.h: Some function - parameters require the "const" attribute to achieve compatibility - with ANSI C requirements (Christian) - 8. theos/theos.c: map Theos' (No)Hidden file attribute to MSDOS Hidden - bit in the MSDOS part of zipentry header's external attribute field; - 9. theos/stat.h: prevent multiple inclusions -10. Theos: Fixed wild card management for options other than adding - (Jean-Michel Dubois) -11. Theos: Removed modifications of const strings (Jean-Michel Dubois) -12. Split tandem.c up into separate zip/unzip parts (Dave Smith, Christian) -13. Move inclusion of OS specific zipup.h files to tailor.h (Onno) --------------------------- August 14th 1999 version 2.3n ------------------- - 1. Move inclusion of OS specific zipup.h files back to zipup.c (Onno) - 2. Remove getline() from zipnote.c and use gets() again (Onno) - 3. BeOS PowerPC R4.1 support (Chris) - 4. New DOIT and MACROS files for the tandem port (Dave Smith) - 5. Don't switch the console to binary mode (Michel de Ruiter) - 6. In some circumstances undosm could be freed twice (Mike) - 7. Also define const in tailor.h for ultrix (Onno, Foppa Uberti Massimo) - 8. Tandem: Change zopen in TANZIPC to allow opening of files with missing - alt keys (err 4) (Dave Smith) - 9. Tandem: Assume not DST if can't resolve time (no DST table available) - (Dave Smith) -10. WIN32: skip trailing dots and spaces in getnam (Onno, Dan Kegel) -11. Use ZE_NONE when nothing to freshen or update (Onno, Yuri Sidorenko) -12. Remove tabs from files that don't need them (Onno) -13. Remove tabs and spaces from the end of a text line (Onno) -14. Upgrade macos to 1.04b2 (Dirk) -15. Add -Q documentation to manual page (Jonathan Hudson) -16. Copy hiperspace files instead of renaming them (Keith Owens) -17. Disallow some more characters to appear in DOS filenames when using -k - (Onno, Thomas Klausner) -18. Document missing options and environment variables in the manual (Onno) -19. New acorn/GMakefile to compile with gcc on RISCOS (Darren Salt) -20. ISO 8601 date format support for -t and -tt (Rodney Brown) --------------------------- September 21st 1999 version 2.3o ------------------- - 1. Sync zip.h license with LICENSE (Onno) - 2. Add copyright notice to README, os2zip.c and os2.zip.h (Onno, Greg) - 3. Fix the ASM variable in acorn/GMakefile (Darren Salt) - 4. Add another requirement to acorn/ReadMe.GMakefile (Darren Salt) - 5. Fix unbalanced parenthesis in vms_get_attributes declaration in zip.h - and move it to vms/zipup.h (Onno, Mike Freeman) - 6. Make a couple of os2 files public domain (Kai Uwe) - 7. Change and rename disclaimer array in revision.h (Onno) - 8. Change copyright array in revision.h (Onno) - 9. macstuff.c copyright is the same as macstuff.h (Christian) -10. WHATSNEW: add ISO 8601 dates supported (Christian) -11. fileio.c - msname(): strip off leading dots, these are illegal for - MSDOS compatible names (Christian) -13. fileio.c - replace(): deactivate "dead" code for CMS_MVS (Christian) -14. man/zip.1: "-$" option is also used for WIN32 ports -15. msdos/msdos.c - version_local(): break the version line for - GNU compilers too (Christian) -16. tailor.h: added typecasts to MBCS macros, to suppress "type mismatch" - warnings (Christian) -17. util.c, zip.h, zipfile.c: ZCONSTify several pointers (Christian) -18. util.c - recmatch(), zip.c - version_info(): add compile time option - WILD_STOP_AT_DIR (Christian, Darren Salt) -19. util.c - envargs(): MBCS related fixes (Christian) -20. win32/lm32_lcc.asm: add TAB characters that are required by the lcc - assembler source parser (Christian) -21. zip.c: fix the "is a console" check (Christian) -22. zipnote.c: use getline() (Christian) -23. zipup.c: use zclose() in case of I/O errors (Christian) -24. zipup.c: use ZE_WRITE when a write error occurs (Christian) -25. win32/win32.c: HAVE_INT64 is used by mingw32 (Cosmin Truta) -26. update shared sources to match izshr041 (Christian) --------------------------- November 29th 1999 version 2.3 ------------------ - 1. Missing parenthesis in win32/win32.c (Steve Salisbury) - 2. Add Cosmin Truta to proginfo/infozip.who (Onno) - 3. Remove one parenthesis pair too many from vms_get_attributes() declaration - in vms/zipup.h (Mike Freeman) - 4. qdos .s are expected to start with a #, work around it (Jonathan Hudson) - 5. tandem: -B0 should be deflating not storing (Dave Smith) - 6. human68k updates from Shimazaki Ryo - 7. beos Makefile cleanup (Chris) - 8. workaround for fseek to negativate offset behaviour of the RISC OS - SharedCLibrary (Darren Salt) - 9. set file type for RISC OS in zipcloak.c (Darren Salt) -10. change tandem zgetch() to allow crypt version to work (Dave Smith) -11. fix a comment typo in acorn/riscos.c (Christian) -12. fileio.c: two type-cast to shut up noisy compilers (Christian) -13. human68k: fix missing case_flag argmument (Christian) -14. win32/win32.c: remove HAVE_INT64 completely (Christian) -15. zip.c: raise "cannot zip to console" error when stdout IS a tty (Christian) -16. zip.h: don't use dummy argument names in declarations (Christian) -17. Add missing semicolon in fileio.c (Shimazaki Ryo) -18. win32.c: IBMC compiler >= 3.50 have int64 (Kai Uwe) -19. Handle initialization error return value from MVS stat() in procname() - (Keith Owens) -20. Use RISC OS instead of RiscOS in the manual (Darren Salt) -21. Use # instead of ? as single character wildcard on RISC OS (Darren Salt) -22. New windll example.c (Mike) -23. Correct storage of 8-bit char filenames with RSXNT (Burkhard Hirzinger) -24. fix install in unix/Makefile (Santiago Vila, Onno) -25. Fix zip -L output (Santiago Vila, Onno) -26. Ignore unix special files (Jonathan O'Brien) -27. Upgrade to izshr042 (Onno) -28. Make copyright notice the same as in izshr042 (Onno) -29. Make copyright notice in zip.h the same as LICENSE (Christian) -30. Set tempzf to NULL _after_ it has been closed (Chris Kacher) -31. Change email address for Jonathan Hudson (Jonathan Hudson) -32. Remove win32/winzip.c.orig (Steve Salisbury) -33. Use 'Steve Salisbury' throughout the documentation (Steve Salisbury) -34. Change email address for Steve Salisbury (Steve Salisbury) -35. Change email address for Chris Herborth (Chris Herborth) -36. Use zip23 in INSTALL (Roger Cornelius) -37. Use zcrypt28 in INSTALL (Onno) -38. New acorn/srcrename (Darren Salt) -39. amiga/makefile.azt: make clean should remove some more items (Paul) -40. Change email address for Cosmin Truta (Cosmin Truta) --------------------------- February 11th 2001 version 2.4a ------------------ - 1. Identify newer Borland compilers (Brad Clarke) - 2. Detect Turbo C 2.01 which doesn't have mktime (Brian Lindholm) - 3. Fix the use of -@ together with -i -x (Christian) - 4. Update msdos/README.DOS to match reality (Christian) - 5. win32: use assembler crc32 code (Christian) - 6. windll: _CRTIMP is needed in several function declarations (Christian) - 7. back to zip 2.2 memcompress() behaviour (Kelly Anderson) - 8. new amiga time code based on nih public domain code (Paul Kienitz) - 9. Detect some more Borland C++ builder versions (Brad Clarke) -10. Fix OS/2's extended file attributes compression code (Christian, Kai Uwe) -11. Correct translation of EBCDIC passwords to ASCII (Christian) -12. Attempt at integrating novell patches from Roger Foss (Onno) -13. Use izshr043 (Christian) --------------------------- July 3rd 2001 version 2.4b ------------------ - 1. Fix OS/2's ACL compression code (Christian, Kai Uwe) - 2. Rename netware subdir to novell (Christian) - 3. Remove -dNETWARE -dDOS from novell Makefile (Christian) - 4. Remove defined(NETWARE) from the sources (Christian) - 5. printf is a macro in glibc 2.2, fix version_local function - (Christian, Matthew Wilcox) --------------------------- January 13th 2002 version 2.4c ------------------ - 1. Use klist_items when initilizating koff[] in tandem.c (Dave Smith) - 2. Only call NLMsignals() in zip.c when NLM is defined (Mike, Onno) - 3. include riscos.h instead of acorn/riscos.h in acorn/osdep.h (Andy Wingate) - 4. Use izshr044 (Christian) --------------------------- January 13th 2002 version 2.4d ------------------ - 1. Don't use mmap for stored entries (Christian) - 2. BIG_MEM and MMAP cannot be defined at the same time (Christian) - 3. Allow redirection of version screen to file (Christian) - 4. Fix for OS/2 output redirection bug (Christian, Kai Uwe) - 5. Acorn script for creating self extracting zips (Darren Salt) - 6. Update amiga makefiles to support revised timezone routines (Christian) - 7. Correct memcompress calculation for allocation size (Christian) - 8. Fix FORCE_METHOD debug option for level 1 and 2 (Christian) - 9. Whitespace cleanup in man/zip.1 (Christian) -10. Define IZ_IMP to specify compiler declaration prefixes (Christian) -11. make win32 and msdos version_local() "stdio-macro-safe" (Christian) -12. move tandem's zip specific zipopen to tanzip.c (Christian) -13. first parm is void * in external scope of vms_get_attributes() (Christian) -14. use right novell subdirectory in zipup.c (Christian) -15. update copyright for files modified in 2002 (Onno) --------------------------- January 19th 2002 version 2.4e ------------------ - 1. Add MacOS X to version_local() (Mark) - 2. unix/configure: Init LFLAGS1 to "", MacOS X doesn't like -s (Onno, Mark) - 3. rename errors array to ziperrors to avoid MacOS X library clash (Mark) - 4. Support for the upx executable packer in DOS makefiles (Christian) - 5. remove obsolete -m486 switch from dos djgpp makefile (Christian) - 6. When using DOS, force the use of msdos style external attributes when - updating zip entries created under another OS (Christian) - 7. os2/makefile.os2: fixed ASFLAGS for watcom16dos (Christian) - 8. Update copyright and ftp address in several files (Christian) - 9. The RISCOS port uses '.' as directory separator, not '/' (Christian) -10. win32/makefile.bor: more options to compile the asm CRC code (Christian) -11. win32: use registry to handle timezones with MS C rtl (Christian) -12. acorn: use recommended practice for calling the linker (Andy Wingate) -13. unix/configure: check if CPP works else use ${CC} -E (Onno, Mark) -14. update versioninfolines in revision.h to match reality (Onno) --------------------------- February 10th 2002 version 2.4f ------------------ - 1. vms: Zip -V is now able to handle file sizes up to 4Gb (Christian) - 2. vms: Include target environment detection for MMS/MMK (Christian) - 3. Change dummy message from zipcloak (Christian) - 4. acorn: add riscos specific -/ option (Darren) - 5. Update acorn's WILD_STOP_AT_DIR feature (Christian) - 6. acorn: Fix buffer allocation for -/ option (Christian, Darren) - 7. acorn: fix make clean (Andy Wingate) - 8. acorn: use tabs for GMakefile to make GNU make happy (Andy Wingate) - 9. tandem: use nskopen not zipopen (Dave Smith) -10. tandem: allow passing of CRYPT define (Dave Smith) -11. use izshr045 (Christian) --------------------------- April 1st 2002 version 2.4g ------------------ - 1. acorn: fix assembler and compiler options in makefile (Darren) - 2. use izshr046 (Christian) - 3. MVS: define isatty to 1 to fix screen output (Christian) - 4. tandem: encryption really works now (Dave Smith) - 5. win32: detect Borland C++ builder 6 (Brad Clarke) --------------------------- April 30th 2003 version 2.4h ------------------ - 1. tandem: fix temporary file contention (Dave Smith) - 2. cmsmvs: generate better filenames with -j (Owen Leibman) - 3. tandem: fix temporary file leftovers (Dave Smith) - 4. solaris: enable large file I/O to break 2G barrier (Rick Moakley, Onno) - -Note: Zip 2.4 was never released. That code was the start of the Zip 3.0 -effort below. Some changes and fixes also made it to the Zip 2.3x releases. - ----------------------- January 21st 2004 version 3.0a ---------------------- -Initial work on Zip 3.0 by Ed Gordon and Rainer Nausedat - 1. Changed some comments to update copyrights (Ed) - 2. Changed text in command line messages from zip 2.4 to zip 3.0 (Ed) - 3. Changes to many files for Zip64 wrapped in ifdef ZIP64_SUPPORT (Rainer) - 4. Attempt to fix buggy Win32 buffered 64-bit calls (Ed) - 5. Add functions to zipfile.c for Little-Endian memory writes (Rainer) - 6. Add functions to zipfile.c for writing Zip64 extra fields (Rainer) - 7. Major changes to putlocal, putcentral, and putend (Rainer) - 8. Fixing -F and -FF for Zip64 postponed (Ed and Rainer) - 9. Command line code replaced. Global table sets options, long options now - supported. Permutes so order of arguments can vary (Ed) -10. Fix bug where not allowed to use -@ with stdout but was with stdin. - Now can read filenames from stdin using -@ and output to stdout and - no longer am allowed to use -@ if reading from stdin (Ed) -11. Replace stat() with zstat(), fstat() with zfstat() and struct - stat with z_stat in Zip64 blocks. Put 64-bit file calls in ifdef - LARGE_FILE_SUPPORT blocks. Can implement Zip64 without > 4 GB - file support but for now need large files for Zip64 support (Ed) -12. Move port-specific code to osdep.h and win32.c (port specific) and - tailor.h (generic) and remove temporary os_io.c. As OF() is - not defined until after osdep.h includes in tailor.h function - prototypes for zfseeko, zftello, and zstat after that in tailor.h (Ed) -13. Settings of ZIP64_SUPPORT and LARGE_FILE_SUPPORT automatic based on - port and version of compiler. Defining NO_ZIP64_SUPPORT or - NO_LARGE_FILE_SUPPORT overrides this (Ed) -14. Bugs compiling scanzipf_fix(...) in zipfile.c and the fix functions could - use rewrite (Rainer and Ed) -15. Add prototype for zfopen for mapping to 64-bit fopen on ports using - inodes but not implemented (Ed) -16. More work on extended local headers and encypted archives (Rainer) -17. Fix DLL files so now compiles (Ed) -18. File size in dll limited to 32-bit in structure. A new DLL api is needed - to return 64-bit file sizes. Current api fixed to return max 32-bit if - more than that (Ed) -19. Add local header Zip64 support and local extra field. Fixed cast - to ulg missed previously that forced zstat to return value mod 4 GB in - zipup.c which kept local header code from seeing actual file size (Ed) -20. Add new option --force-zip64 to force use of zip64 fields. Could - be temporary (Ed) -21. Fix for VB added to api.c that just store the passed strings internally. - Should update api to optionally return file sizes as 64-bit in call back - and to accept RootDir and other strings in same call that zips (Ed) -22. Readme updated to describe new features and mention updated mail group - web links (Ed) -23. Minor bugs in output format found and fixed. Now can add - files > 4 GB to archive and unzip using major unzippers (Ed) -24. If zip used as filter (zip - -) and sizes exceed limits of extended - local header (data descriptor) then set max 32-bit values there. Major - unzippers ignore and use central directory values which are correct. Can - create Zip64 data descriptor using --force-zip64 option but seems no need - for it (Ed) -25. A few bugs in how headers are handled prevented zipping large numbers - of files. Fixed (Rainer) -26. A bit of an attempt to fix -F and -FF. Seems to work but not that - robust. More work needed (Ed) -27. After some cast and other fixes zip compiles on Linux Red Hat 9 using Unix - generic. Added automatic detection of fseeko64 and if detected - sets LARGE_FILE_SUPPORT and setting that sets ZIP64_SUPPORT. Works but - could not test large files on the small system (Ed) -28. Tried to fix bug that prevents zipnotes from compiling when ZIP64_SUPPORT - is set. Still broke. This crashes the Unix Makefile but after - zip is compiled (Ed) ----------------------- May 8th 2004 version 3.0b ---------------------- - 1. Update license headers on more files (Ed) - 2. Change many ZIP64_SUPPORT ifdefs to LARGE_FILE_SUPPORT where appropriate. - Now can test ports using three stages, compile with NO_LARGE_FILE_SUPPORT - (which disables ZIP64_SUPPORT) to test base code, compile with - NO_ZIP64_SUPPORT to test the 64-bit file calls (assuming port sets - LARGE_FILE_SUPPORT) but otherwise use the base code, and without either - to test Zip64 if enabled on port (Ed) - 3. Fix zipnotes bug by moving a ZIP64_SUPPORT block in zipfile.c (Ed) - 4. Add Large File Summit (LFS) code to Unix port to enable 64-bit calls. - Update configure to include test for all needed 64-bit file calls before - enabling LARGE_FILE_SUPPORT for unix port (Ed) - 5. Merge encryption code from zcrypt29 (files from unzip) into zip and - enable by default (Ed) - 6. New man pages for zipnote, zipsplit, and zipcloak (Greg, Ed) - 7. Add encryption notice to crypt.c comments and to version information - in zip.c (Greg, Ed) - 8. Add Russian OEM EBCDIC support when OEM_RUSS defined in ebcdic.h but - Dmitri reports that 0x2F not '/' so make recommended change in cutpath - call in zipfile.c used by -D option (Dmitri - Nov 10 2003 email) - 9. ToDo30 file added to list what's left to do in this release (Ed) -10. Change fopen to zfopen for large file code and map to fopen64 for - Unix (Ed) -11. ftello64 seems broken in zipup.c on Linux (kernel 2.4), returning - negatives past the 2 GB barrier, though ftello64 works in a test program. - Likely error in defines. For now skip ftello64 check for Unix with - LARGE_FILE_SUPPORT. -12. A few updates in Readme. Needs overhaul likely. Also verified mxserver - is gone and replaced with list addresses (Ed) -13. First iterations at updating WinDLL for Zip64 (Mike) -14. Decide to drop backward dll compatibility in favor of a cleaner - dll interface. Decide to add string interfaces for VB (Ed, Mike) -15. Add string interfaces to dll interface to bypass array limitations - imposed by VB and add -x and -i to interface (Mike) -16. Create new VB example using new Zip64 dll interface (Ed) -17. Add O_LARGEFILE define for zopen in unix/zipup.h to enable reading - large files in unix (Ed) -18. Combine ZpSetOptions and ZpArchive dll calls to allow removing all VB kluges - in api.c to work around VB garbage collecting passed strings (Mike) -19. Change new VBz64 example to use updated interface. All works without - kluges (Ed) ----------------------- August 15th 2004 version 3.0c ---------------------- - 1. Add date formats in -t and -tt date errors (Ed) - 2. Add -so to display all available options (Ed) - 3. Many fixes from Dan Nelson to fix some large file support problems and - add large file support to a few ports. Main change is rather than use - explicit 64-bit calls like fopen64 now set 64-bit environment and use - standard calls. Also add a define for 64-bit printf format used to - print 64-bit stats (Dan, Ed) - 4. Changes to Unix config based on suggestions from Dan Nelson. Check - if off_t is at least 64 bit (Dan, Ed) - 5. Add -- to get_option. Any arguments after -- on command line now - read as paths and not options (Ed) - 6. Add extended help (Ed) - 7. Change add_filter flag parameter from char to int as some compilers have - problems with char arguments (Ed) - 8. Changed filter() to do R and i separately so i has precedence over R (Ed) - 9. Split variable t in zip.c into t (off_t) and tf (ulg) (Ed) -10. Add quotes to zipname in check_zipfile for MSDOS to allow spaces in - archive path given to unzip to test ( , Ed) -11. Move zip.h include before ctype.h include in trees.c and zipup.c as - when ctype.h is first and using 64-bit environment at least on unix port - found it defines off_t as 4 bytes in those files as off_t is defined as - 8 bytes in other files and this changes the size of the zlist structure - which is not good (Ed) -12. Add default 64-bit file environment to tailor.h if LARGE_FILE_SUPPORT - is set but no port 64-bit file defines are set up earlier in the file. - Should allow other ports to set LARGE_FILE_SUPPORT on the compiler - command line to test if the standard defines work (Ed) -13. Adjust binary detection in trees.c by changing 20% binary (4 out of 5 - ascii) that used >> 2 to 2% (64 out of 65) using >> 6 instead. - trees.c (Ed) ----------------------- November 12th 2004 version 3.0d ---------------------- - 1. Add global variable for EncryptionPassword in VBz64 example and - some other password callback cleanup (Ed) - 2. Add -W option to turn on WILD_STOP_AT_DIR where wildcards will not - include directory boundaries in matches (Ed) - 3. Add -nw option "no wild" to completely disable wildcards in MATCH - function. Allows a list of files to be read in without worrying about - wildcards or escapes (Ed) - 4. Add -s option split-size but not implemented (Ed) - 5. Add -sp option split-pause but not implemented (Ed) - 6. Add changes for WiZ including moving Win32 64-bit wrappers into - win32i64.c to avoid naming conflict between libraries in WiZ (Mike, Ed) - 7. Some large file fixes in crypt.c (Ed) - 8. Add new error code ZE_UNSUP for unsupported compiler options. Add - check of size of zoff_t in zip.c when LARGE_FILE_SUPPORT enabled (Ed) - 9. Changed ZE_UNSUP to ZE_COMPERR to avoid conflict with unzip (Ed) -10. On VMS (sufficiently recent, non-VAX), DECC$ARGV_PARSE_STYLE is set - automatically to preserve case of the command line if the user has - SET PROCESS /PARSE = EXTEND. This obviates quoting upper-case - options, like -V, when enabled. VMS.C (Steven Schweda (SMS)) -11. On VMS, building with macro VMS_PRESERVE_CASE defined preserves case - of names in archive, instead of forcing lower-case (the former and - current default behavior). VMSZIP.C (SMS) -12. On VMS, in some of the simplest cases, ODS5 extended file name - escape characters ("^") are removed from names in archive. - VMSZIP.C (SMS) -13. On VMS, fixed a problem in some cases with mixed-case directory - names, where too much of the directory hierarchy was included in the - path names in the archive. VMSZIP.C (SMS) -14. On VMS, minor changes for large file support (long -> zoff_t). - VMSZIP.C (SMS) -15. On VMS, changed some structure declarations to typedefs, and - rearranged to simplify #if's and reduce potential name conflicts. - VMS.H, VMS_IM.C, VMS_PK.C (SMS) -16. On VMS, reformed -V (/VMS) processing. Added -VV (/VMS=ALL). - Removed some sign bits to accomodate files bigger than 2GB. - CMDLINE.C, VMS_IM.C, VMS_PK.C, ZIP.C, ZIP_CLI.CLD, ZIP_CLI.HELP, - ZIPUP.H (SMS) -17. Update command line options to support -VV as distinct option (Ed) -18. More VMS changes (SMS) -19. Add zoff_t format function (SMS) -20. On VMS, when -b was not used, temporary archive files were always - created in the current default directory, rather than in the archive - file destination directory. VMS now uses its own tempname() - function. FILEIO.C, VMS.C (SMS) -21. Remove using FNMAX for path size in a few places including filetime.c - to avoid exceeding limit (based on fixes from Greg and others) (Ed) -22. Add port atheos (Ruslan Nickolaev, Ed) -23. Bug fix adds different extra fields for local and central in VMS (SMS) -24. Now short options also take optional values as next argument (Ed) -25. Change -dd to control -v dots (SMS, Ed) -26. On VMS, a new open callback function senses (where supported) the - process RMS_DEFAULT values for file extend quantity (deq), - multi-block count (mbc), and multi-buffer count (mbf), and sets the - FAB/RAB parameters accordingly. The default deq is now much larger - than before (16384, was none), and the default mbc is now 127 - (up from 64), speeding creation of a large archive file. Explicitly - set RMS_DEFAULT values override built-in defaults. OSDEP.H, VMS.C - (SMS) -27. VMS CLI definitions and CLI help have been updated, and may be - approximately correct. CMDLINE.C, ZIP_CLI.CLD, ZIP_CLI.HELP (SMS) -28. The man file zip.1 updated and Makefile updated to generate manual - pages for zipcloak.1, zipnote.1, and zipsplit.1 (Ed) ----------------------- July 23rd 2005 version 3.0e ---------------------- - 1. Debian patch 004 - apply 2.4i configure changes from Onno to remove - need for -fno-builtin in unix/configure (Onno, Ed) - 2. Debian patch 005 for bug 279867 - fix bug that could crash on large paths - and create security problem. Apply patch changes from Greg (Greg, Ed) - 3. SourceForge patch 1074363 - add win32i64.c to win32/makefile.w32 (Ed) - 4. Add check when not ZIP64_SUPPORT in scanzipf_reg() in zipfile.c if - Zip64 archive being read (Ed) - 5. Renamed fzofft() used to format zoff_t values to zip_fzofft() to remove - conflict when combined with UnZip in WiZ (Mike) - 6. Add check in scanzipf_reg() in zipfile.c if Zip64 archive being read (Ed) - 7. Fixes for amiga/makefile.azt to define directory for object files (Paul) - 8. Define prototypes for local functions optionerr, get_shortopt and - get_longopt in fileio.c. Define err argument of optionerr as ZCONST (Paul) - 9. Add help_extended and DisplayRunningStats prototypes, fix other prototypes - in zip.c (Paul) -10. Split int kk off of k for argument types (Paul) -11. Aztec #endif quirk fix in zip.c for Amiga (Paul) -12. Add detection of binary in first buffer read from file in zipup.c to avoid - a -l or -ll translation on binary file. Not perfect but at least should - catch some binary files (Ed) -13. Remove check for >= 128 from binary check in zipup.c as <= 6 enough for - signed char (SMS, Ed) -14. SF Bug 1074368 - check for empty zip file in readzipfile() in zipfile.c - (Christian d'Heureuse, Ed) -15. Add error exit to prevent archive corruption when updating a large-file - archive with a small-file program. Add ZE_ZIP64 error. - ziperr.h, zipfile.c (SMS) -16. Change percent() in zipup.c to do rounding better, handle cases near limits - while rounding, and allow negative percent returns (SMS, Ed) -17. Add function ffile_size() in zipfile.c but in #if 0 block until determine - if works on all ports under all conditions. Currently only used for size - check for Zip64 archive detection if compiled without ZIP64_SUPPORT and - this check may already be handled in scanzipf_reg() and should be added to - scanzipf_fix() when that is updated (SMS, Ed) -18. Change >>1 to /2 in zipsplit.c to allow for negative percent returns (SMS) -19. Add type uzoff_t for unsigned zoff_t things. Should clean up some casting - (Ed) -20. Based on discussions with other development groups, when data descriptors - (extended local headers) are used, force to Zip64. This is compatible - with other unzips and does not require a change of the AppNote, but the - resulting archive requires Zip64 to read. Using standard data descriptors - would mean that the zip operation would fail if a Zip64 entry was - encountered. See zipfile.c (Ed) -21. Add define SPLIT_SUPPORT to enable splits. The command line options are - done and the globals are set up but nothing more. globals.c, zip.h, and - zip.c mainly (Ed) -22. Create spanning signature at beginning of archive when splitting enabled. - If reading a split archive skip the spanning signature unless creating a - split archive. zip.c, globals.c (Ed) -23. Start implementing split archives. Define two methods. split_method = 1 - updates local headers and is the most compatible but requires updating - previous splits. split_method = 2 uses data descriptors and should work - for streams and removable media but may not be as compatible with other - zip applications. (In part based on previous discussions with Rainer.) - Updated global variables to include bytes written to just the current - entry in the current split. zipfile.c (Ed) -24. Add note about output redirection to zip.1 (?, Ed) -25. Remove num < 0 check as num now unsigned. util.c (SMS, Ed) -26. Change lastchar to lastchr in fileio.c in places to avoid function by same - name (SMS, Ed) -27. Moved #endif /* !WINDLL */ in zip.c (Mike) -28. Account for vms directory version being ;1. vmszip.c (SMS) -29. Fix Zip64 check in scanzipf_reg to use the buffer. zipfile.c (Ed) -30. Default define size_t (for use by Steve's ffile_size() function). tailor.h (Ed) -31. Enable Steve's ffile_size() function and enable large file check. It - currently does not allow file sizes over 2 GB but the code is not supporting - it anyway without large file support. Should remove that part of the check - when the casts are fixed. zipfile.c (Ed) -32. Fixes for djgpp. Now compiles with djgpp 2 (Ed) -33. Add new VC6 projects for win32 and windll (Cosmin) -34. Convert some variables in zipsplit.c from ulg to zoff_t so compiles (Ed) -35. Add wildcards to extended help. zip.c (Ed) -36. For optional option value now '-' is same as missing value. fileio.c (Ed) -37. Remove extra free() from -dd option switch. zip.c (Ed) -38. Change write_unsigned_to_mem() to write_ulong_to_mem() and write_short_to_mem() - to write_ushort_to_mem(). zipfile.c (Ed) -39. Create new append to mem functions. zipfile.c (Ed) -40. Change zlist nam and ext from extent to ushort as that is what gets written. - zipfile.c (Ed) -41. Change GetSD to use ush instead of size_t. win32/win32zip.c (Ed) -42. Change PutLocal(), PutExtended(), PutCentral(), and PutEnd() to write to - memory and then write the block at once to the file. zipfile.c (Ed) -43. Change zcomlen from extent to ush, other extent conversions. zipfile.c, - globals.c, zip.h (Ed) -44. Add is_seekable() and global output_is_seekable. Do seekable check - when output file is opened. zipup.c, globals.c, zip.h, zip.c (Ed) -45. Do not increment files_so_far and bytes_so_far if file could not be read. - zip.c (Ed) -46. If force_zip64 set, only force compressed size in central directory to Zip64 - instead of all entries (csize, usize, off, disk) in Zip64 extra field. This - fixes inconsistent handling of disk numbers. zipfile.c (Ed) -47. Add end status if displaying running stats and not all files were read. - zip.c (Ed) -48. Change force_zip64 to zip64_archive in putend(). zipfile.c (Ed) -49. Enable the i686-optimized code by default. crc_i386.S, - win32/crc_i386.asm, win32/crc_i386.c (Cosmin) -50. Document and implement a new text detection scheme provided by Cosmin in - set_file_type(). Should be able to handle UTF-8 and some other character sets. - proginfo/txtvsbin.txt, trees.c (Cosmin, Johnny, Christian) -51. Update binary detection for -l and -ll to use Cosmin black list. zipup.c (Ed) -52. Change ZE_BIG to include read and write. ziperr.h (Ed) -53. If archive not seekable then use data descriptors. If ZIP64_SUPPORT always - create Zip64 data descriptors and add a Zip64 extra field to flag it is - a Zip64 data descriptor. This is klugy but should be compatible with other - unzips. See the note in zipfile.c for details. (Ed) -54. Use ush for comment length in putend(). Instead of extent use ush for - zcount and fcount same as in zip file. zip.h (Ed) -55. Update VB readme. windll/VB/readmeVB.txt (Ed) -56. Change (INSTALL) to (INSTALL_PROGRAM). unix/Makefile (, Ed) -57. During update the file and byte status counts were off. Fixed by not coun- - ting files copied from old to new as those are not in totals. zip.c (Ed) -58. Change from -b to -bx for nroff of manuals to text files. unix/Makefile (Ed) -59. Add cygwin to makefile. unix/Makefile (, Ed) -60. Fix bug where files to delete not added to list. zip.c (Ed) -61. Fix delete stats. zip.c (Ed) -62. Increment version of crypt to 2.10. Update default behavior notes. - crypt.c, crypt.h (Paul, Christian) -63. Format changes, add parentheses to zfseeko(), fix output bytes, add ifdef - blocks for ZIP10, fzofft formatting, casts. crypt.c (Christian) -64. Cast block_start to unsigned. deflate.c (Christian) -65. Let -R patterns match in subdirectories. Update filter() to use switch, - use global icount and Rcount, handle subdirectories, update icount and - RCount in filterlist_to_patterns(). fileio.c, zip.c, zip.h, globals.c - (Christian) -66. Enclose option -! and use_privileges under NTSD_EAS guard. globals.c, - zip.c, zip.h (Cosmin) -67. Updates to version, copyright, license. [I did not split the copyright - to 2 lines as it already takes up space on the help screen. Ed] - revision.h (Christian) -68. Add ZCONST to some read-only string pointer arguments in function - declarations. zipcloak.c, zipnote.c, zipsplit.c, zip.c, zip.h (Christian) -69. Fix byte counts on exit in zipcloak() and zipbare() to fix zipcloak bug - (Christian) -70. Modified zipnote.c to use WRBUFSIZ to handle line widths of at least 2047 - characters in write mode (Christian) -71. Change simple() and greedy() from zoff_t to uzoff_t. zipsplit.c (Christian) -72. Remove duplicate copyright notices. zipsplit.c (Christian) -73. Remove export notice from help page. Move notice to bottom of license - page. zipcloak.c (Ed) -74. File USexport.msg export history added. (Greg) -75. Added support for VMS ODS5 extended file names. (Eight-bit only, no - Unicode.) VMS name character "/" is mapped to Zip name character - "?". New command-line options -C[2|5][-] (/PRESERVE_CASE[=opts]) - control name case preservation and/or down-casing. globals.c, - zip.c, zip.h, vms/cmdline.c, vms/vms_im.c, vms/vms_pk.c, vms/vms.c, - vms/vmszip.c, vms/vms.h (SMS) -76. New VMS option -ww (/DOT_VERSION) stores version numbers as ".nnn" - instead of ";nnn" [changed from -Y to -ww (Ed)]. zip.c (SMS) -77. Changes to vms_open(). vms/vms_im.c, vms/vms_pk.c -78. Changes to vms_read(). vms/vms_pk.c (SMS) -79. Documentation updates. vms/vms_zip.rnh (SMS) -80. Minor updates. vms/zip_cli.help, vms/cmdline.c, vms/vms_zip.rnh (Ed) -81. Changes to vmsmunch(). vms/vmsmunch.c (SMS) -82. Do some updating of VMS options. vms/zip_cli.cld (SMS) -83. Moved the VMS-specific ziptyp() function from zipfile.c to vms/vms.c - to segregate better the RMS stuff. (SMS) -84. Put 64-bit calls in ZIP64_SUPPORT ifdef blocks, change some long parameters - for append to memory block functions to ulg, remove redundant includes, - add OFT protos to some functions with parameter types that get promoted - like ush to avoid warnings in VMS. zipfile.c (SMS) -85. Use zip_fzofft() to format number. zipsplit.c (SMS) -86. Add file_id.diz from Zip 2.31 (?, Ed) -87. Update install from Zip 2.31 (?, Ed) -88. Update license from Zip 2.31. License (?, Ed) -89. Update Readme.cr from Zip 2.31 (?, Ed) -90. Add 64-bit assembler for Win32 from Zip 2.31. win32/makefile.a64, - win32/readme.a64, win32/gvmat64.asm (?, Ed) -91. Update Readme (Ed) -92. Update headers. crctab.c, crc32.c, deflate.c, ebcdic.h, fileio.h (Ed) -93. Option for extra verbose VMS, change DIAG_FLAG from verbose to - (verbose >= 2). vms/vms.c (SMS) -94. Update copyright header. qdos/qdos.c (Christian, Ed) -95. Change exit(0) to exit(ZE_OK). qdos/qdos.c (Christian) -96. Change ulg to unsigned long. tailor.h (, Christian) -97. Default uzoff_t to unsigned long long if LARGE_FILE_SUPPORT manually - enabled for an otherwise unsupported port. tailor.h (Ed) -98. Update copyright header. tailor.h (Ed) -99. Change EXIT(0) to EXIT(ZE_LOGIC) for ziperr recursion. zip.c (Christian) -100. Change EXIT(0) to EXIT(ZE_OK) for successful returns. zip.c, - zipcloak.c (Christian) -101. Update license. zip.h (Christian) -102. Initialized mesg in zipcloak.c, zipnote.c, zipsplit.c to fix access - violation crashes. (Christian) -103. Added -q (Quiet mode) option to zipcloak, zipnote, zipsplit. (Christian) -104. Add proto of mb_clen(). fileio.c (Cosmin) -105. Synchronize ttyio.c and ttyio.h with the unzip-5.52 source. (Cosmin) -106. Control the POSIX emulation provided by some Unix-on-Windows compiler - distributions, such as Cygwin, via the FORCE_WIN32_OVER_UNIX macro. - tailor.h, win32/Makefile.gcc (Cosmin) -107. Remove getenv() declaration. util.c (Cosmin) -108. Fix definitions of zopen and zstdin. unix/zipup.h (Cosmin) -109. Enable binary file operations for DJGPP and Cygwin. unix/osdep.h (Cosmin) -110. Remove -DMSDOS from CFLAGS; use correct dependency in target crc_i386.obj. - win32/makefile.w32, win32/makenoas.w32 (Cosmin) -111. Update win32/makefile.bor and win32/makefile.gcc (Cosmin) -112. Put mktemp() declaration inside the NO_PROTO guard. tailor.h (Cosmin) -113. Use the right type (DWORD) for volSerNo, maxCompLen and fileSysFlags - in FSusesLocalTime(). win32/win32.c (Cosmin) -114. Set the "zip Debug" configuration as default. win32/vc6/zip.dsp (Cosmin) -115. Define ASM_CRC by default. win32/osdep.h (Cosmin) -116. Avoid using file names that are distinguished solely by letter case; - e.g. crc_i386.S and crc_i386.s. unix/Makefile (Cosmin) -117. Stylistic fix inside ex2in(). unix/unix.c (Cosmin) -118. Change zlist dsk from ush to ulg to support Zip64 and added casts in - zipfile.c to write ush. zip.h, zipfile.c (Christian, Ed) -119. Conditionally apply S_IFLNK to support DJGPP. unix/unix.c (Cosmin) -120. Change -dd [siz] (display dots, set optional dot size) to the options - -dd (turn dots on, use 10 MB default) and -ds siz (set dot size). - Found that using -dd with an optional value got confusing as detection - of an optional argument, when the next argument was not either an option - or the end of the line, was easy to overlook. Easier to avoid optional - values. zip.c (Ed) -121. Change text output of manual pages to zip.txt, zip.txt, zipcloak.txt, - zipnote.txt, zipsplit.txt. unix/Makefile (Christian, Ed) -122. Change comments using // to /* */ format. api.c, zip.c (Christian) -123. Add support for signals SIGABRT, SIGBREAK, SIGBUS, SIGILL, and SIGSEGV - to utilities. zipcloak.c, zipnote.c, zipsplit.c (Christian) -124. Update ToDo30.txt file (Ed) -125. Delete old Manual file (Ed) -126. Update WHERE from Zip 2.32 (Ed) -127. Change description of dot-size. zip.c (Ed) -128. Change VMS to use -ds to set dotsize. vms/cmdline.c (Ed) -129. Update manuals. man/zip.1, man/zipsplit.1, man/zipnote.1, - man/zipcloak.1 (Ed) -130. Detect i586, i686 and Cygwin in version_local(). unix/unix.c (Cosmin) -131. Add clean target. win32/makefile.w32, win32/makenoas.w32 (Cosmin) -132. Changed most 64-bit size/offset variable declarations (like zoff_t) - into "unsigned" type (like uzoff_t), for better backward compatibility - with non-ZIP64_SUPPORT setups where "ulg" was used for these variables. - deflate.c, fileio.c, globals.c, trees.c, vms/vms_pk.c, win32zip.c, - zip.c, zip.h, zipfile.c, zipup.c (Christian) -133. Add (ulg) cast to strstart in flush_block. deflate.c (Christian) -134. Updated Win32 LARGE_FILE_SUPPORT setup for Watcom and MinGW. - tailor.h, win32/osdep.h (Christian) -135. Add attempt count to tempname(). fileio.c (Christian) -136. Fixed size counter handling in debug code for Zip64. trees.c (Christian) -137. Moved cryptnote display text definition into revision.h, like was done - in Zip 2.31. zip.c, revision.h (Christian) -138. Add ZCONST. fileio.c (Christian) -139. Removed earlier change in trash() where ASCII-containing iname was - searched for native-coded '/' characters. [Added note but left as - changed 5/20/05 EG] zipfile.c (Christian) -140. Change zipup size error message to use zip_fzofft(). zipup.c (Christian) -141. Updated win32/makefile.wat to enable Zip64 support and use directory - for intermediate files. (Christian) -142. Change fcount and zcount from ulg to extent as extent is used internally, - but Zip64 standard supports up to ulg. Add note to zip.h. globals.c, - zip.h (Christian) -143. Define NO_W32TIMES_IZFIX in compile options when appropriate. Add - version information for USE_ZLIB compiler option. zip.c (Christian) -144. Add support for SIGABRT, SIGBREAK, SIGBUS, SIGILL, and SIGSEGV signals. - zip.c (Christian) -145. Add display-usize option to show uncompressed size. zip.c (Ed) -146. Add many descriptions to options table. zip.c (Ed) -147. Remove -R from help screen as on extended help screen. zip.c (Ed) -148. Add basics to extended help. zip.c (Ed) -149. Fix checks in scanzipf_reg() for empty file since cenbeg now unsigned. - Change buffer from t to b in small big check. Back up after small - zip big archive check. zipfile.c (Ed) -150. Change Zip64 not supported warning in scanzipf_reg(). zipfile.c (Ed) -151. Fix bug where local and central headers were not matching when compiled - with NO_LARGE_FILE_SUPPORT. Restored order of zlist structure elements - to match order of local header as scanzipf_reg() compares it as an - array of bytes to the local header. Gag. It needs fixing but at least - it works as intended now. zip.h, zipfile.c (Ed) -152. Minor fix from 10000 to 10 K for WriteNumString(). util.c (Ed) -153. Add overflow check to file_read(). zipup.c (SMS) -154. Add parameter p1 product specification. vms/collect_deps.com (SMS) -155. VMS changes. vms/descrip_mkdeps.mms (SMS) -156. Change zoff_t to uzoff_t and unsigned int to size_t. vms/vms_im.c, - vms/vms_pk.c (SMS) -157. Fix ; that was : at end of line. Fix DisplayNumString() prototype. - zip.h (Ed) -158. Get rid of leading blanks in DisplayNumString(). util.c (Ed) -159. Reset dot_count each file. zipup.c (Ed) -160. Minor changes to extended help. zip.c (Ed) -161. Move defines into DEFINED_ONCE block. api.h (Mike) -162. Add Still Remaining And Planned For Zip 3.0 section. WhatsNew (Ed) -163. Delete quotes around CHANGES. Readme (Ed) -164. Add -lf, open file at path and use for logging, -la, append to - existing logfile, and -li, include informational messages, options. - globals.c, zip.h, zip.c (Ed) -165. Update extended help to include logging. zip.c (Ed) -166. Add support for required short option value in form -o=value as optional - does. fileio.c (Ed) -167. If bytes_total is smaller than bytes_so_far for some reason then display - negative of bytes_to_go. This can happen if files grow in size after all - the sizes are initially added up. zip.c (Ed) -168. Use usize from filetime for adding to bytes_total when updating instead - of size in old entry. zip.c (Ed) -169. Change status counts files_so_far and bytes_so_far to include bad files - so the status counts end at the end but add bad_files_so_far and - bad_bytes_so_far to track bad files. After minor fixes it looks like - the counts remaining at the end are correct, even when some files are - not readable. Update bad file warnings. zip.c, zip.h, globals.c, - zipup.c (Ed) -170. Add uq for unsigned q in zipup(). Initialize z->len in case an error - later so have a valid size. zipup.c (Ed) -171. Check noisy in DisplayRunningStats() so logging is independent of it. - zip.c (Ed) -172. Add check in DOS for windows and if running DOS version on Windows warn - user. zip.c, msdos/msdos.c, msdos/osdep.h (Johnny) -173. Add errno.h for strerror(errno) call. zip.c, zipup.c (SMS) -174. Fix log problem if using -q option. zipup.c (Ed) -175. Change "Far char" to "char Far" as Far is a qualifier not for the char - type but the storage allocation of the array. fileio.c (Christian) -176. Update note on extent. globals.c (Christian, Ed) -177. Remove extra USE_ZLIB. zip.c (Christian) -178. Add note for the OEM_RUSS '/' bug. Need to look at later as it seems - the Russian bug remains unfixed. zipfile.c (Christian, Ed) -180. So byte counts always come out even, create good_bytes_so_far to - count bytes read in and convert bytes_so_far to use the counts - from the initial scan. If files change during the zip operation - good_bytes_so_far will change and not match bytes_so_far. - zip.h, globals.c, zip.c (Ed) -181. Changes to extended help. zip.c (Ed) -182. Update WhatsNew (Ed) -183. Update DLL resource copyright. windll.rc, windll.aps (Ed) -184. Add directory search improvements to Win32 (within recursion, reuse - attribs from directory lookup to avoid calling stat()). Add - getd_attribs(), procname_win32(). win32/win32zip.c (Johnny) -185. Cache result of IsFileSystemOldFAT() to avoid repetitive system calls - for identical information. win32/win32.c (Johnny) -186. Add optimization to dosmatch(): apply alternate shortcut code when the - pattern to match consists of one multichar wildcard ('*') followed - by a fixed string. util.c (Johnny) -187. Move DOS check_for_windows() checks to Help and Version and errors - only. Shorten message to one line. zip.c, msdos/msdos.c (Ed) -188. Define WIN32_OEM to enable oem ansi conversions for more than RSXNT. - Not yet fully implemented. win32/win32.c, win32zip.c, zip.c, - zipfile.c (Ed) -189. Directory search improvements for MSDOS. msdos/msdos.c (Johnny) -190. Add caching of directory information. If pattern is just *string no - need to recurse. win32/win32.c (Johnny) -191. If wild_stop_at_dir then do recurse to handle cases like a/b/*.txt. - win32/win32.c (Ed) -192. Additional improvements to directory search speedups, including - a) MSDOS port fixes for Turbo C++ compiler - b) In both Win32 and MSDOS, change getDirEntryAttr() into macro, - saving one function call overhead - e) Add explaining comment to optimized procname_{local} code - f) In util.c, move "*literal" pattern-matching optimization from - dosmatch() to recmatch(). Advantages: - - optimization used for all systems - - optimization applied to all occurences where a "*" is last wildcard - in pattern - - "dosmatch()" only preconditoning wrapper for matching workhorse - "recmatch()", it should not implement matching algorithms itself - - optimization not applied for WILD_STOP_AT_DIR option - g) >>>disabled<<< "*literal" optimization for all MBCS-aware environments, - because suspect that supplied optimization code is not MBCS-clean - (for details see the comment within the patch), so IS NOT USED for - win32 port! Can force activation of match optimization by specifying - conditional compilation symbol TEST_FOR_MBCS_CLEAN. - (Christian) -193. Add and move comments, implement changes for directory search improvements - in Zip 3.0 util.c (Ed) -194. In win32/win32.c, IsFileSystemOldFAT(), add declarations of static caching - variables where missing to fix win32 port compilation bug (Christian) -195. Correct changed arguments in RSXNT-only character set conversion - call. win32/win32zip.c (Christian) -196. Implement Directory Search improvements from Zip 2.32. win32/win32zip.c - (Johnny, Ed) -197. Debian Bug #312090 fix. Reworded man page to give multiple examples of - recursion, not just zip -r foo foo. man/zip.1 (Ed) -198. Change "-Aa -D_HPUX_SOURCE +e" to -Ae for HP. "HP-UX with the HP compiler - and on AIX 4.2.0. AIX 5.1 with gcc-3.4.3 (32-bit) and Darwin built fine - - though AIX 5.1 needed CC=gcc make -e ... to find gcc. According to the - HP-UX man page -Ae is equivalent to -Aa -D_HPUX_SOURCE +e it seems the - +e is needed and -Ae is more terse anyway." Expression generated before - was too long. unix/configure (Rodney Brown) -199. Add support for osf4.0f that does not have fseeko or ftello but has 64-bit - fseek and ftell though. tailor.h (Rodney) -200. Fix unsigned char to char in recmatch(), add casts for compares. util.c - (Ed) -201. Fix for alpha off_t long long. unix/osdep.h (Rodney) -202. Change shmatch() from uch to char and change parameters to recmatch(). - Change dosmatch(). util.c (SMS, Rodney, Ed) -203. Add local for DisplayRunningStats(). zip.c (Rodney, Ed) -204. Disable unused append_ubyte_to_mem(). Fix error messages in other append. - zipfile.c (Rodney, Ed) -205. Delete unused getDirEntryAttribs(). msdos/msdos.c (Christian) -206. Change warning when running msdos version on Windows. msdos/msdos.c (Ed) -207. Change recmatch() to support MBCS matching. util.c (Christian) -208. Update WhatsNew (Ed) -209. Update Readme (Ed) -210. Format Readme to fit in 80 character lines (SMS, Ed) -211. Rename install.vms to install_vms.txt. vms/install_vms.txt (SMS) -212. Add reference to vms/install_vms.txt in INSTALL (SMS) -213. Update INSTALL (Ed) -214. Remove ALT_NEXTBYTE and Building UnZip sections as no longer needed. - vms/notes.txt (SMS, Ed) -215. Add note to TODO (Ed) -216. Update Makefile message to suggest using generic. unix/Makefile (Ed) -217. Update text output of manual. zip.txt (Ed) -218. Update VMS section. INSTALL (SMS, Ed) -219. Minor changes in vms/install_vms.txt (SMS, Ed) -220. Update VMS install information. INSTALL, vms/install_vms.txt (SMS, Ed) -221. Do not use _stati64 under Cygwin. win32/osdep.h (Cosmin) -222. Add note to Makefile to use generic first. unix/Makefile (Ed) -223. Add Test option for VMS CLI. vms/cmdline.c (SMS, ?) -224. Add noconfirm to deletes, define symbol edit. vms/descrip.mms (SMS) -225. Changes to vms/install_vms.txt (SMS) -226. Add note on symbols to VMS. INSTALL (SMS) -227. Update license headers. vms/osdep.h, vms/vms.h, vms/vmsmunch.c, - vms/zipup.h, vms/vmszip.c, vms/vms.c, vms/vms_im.c, vms/vms_pk.c, - vms/command.c (Ed) -228. Add stsdef.h include for VMS and convert unzip test return to VMS - result for VMS. zip.c (SMS) -229. Add const to ziperr(). amiga/amiga.c (Paul) -230. Clean up makefile. amiga/makefile.azt (Paul) -231. Don't try Amiga large file support. amiga/osdep.h (Paul) -232. Add note on -V and -VV. vms/notes.txt (SMS) -233. Small update. vms/zip_cli.help (SMS) -234. Format Windows warning message. msdos/msdos.c (Christian) -235. Format changes. util.c (Christian) -236. Update VMS. INSTALL (SMS) -237. Add creation of intermediate object directories. msdos/makefile.wat - (Christian) -238. Add void * cast. msdos/msdos.c (Christian) -239. Add include for mktemp(). msdos/osdep.h (Christian) -240. Fix __RSXNT__ and WIN32_OEM define blocks. win32/win32.c (Christian) -241. Fix __RSXNT__ and WIN32_OEM define blocks. win32/win32zip.c (Christian) -242. Add != NULL to check. zip.c (Christian) -243. Fix WIN32_OEM. zipfile.c (Christian) ----------------------- October 11th 2005 version 3.0f01 ---------------------- -(the internal betas may be merged later) - 1. Add DSEG for Watcom data segment. msdos/makefile.wat (Christian) - 2. Add -zq and use assembler. os2/makefile.os2 (Christian) - 3. Update header. os2/match32.asm (Christian) - 4. Change len from int to unsigned int. os2/os2.c (Christian) - 5. In GetLongPathEA() limit tempbuf to CCHMAXPATH. os2/os2.c (Christian) - 6. Add DWATCOM_DSEG to use data segment. win32/makefile.wat (Christian) - 7. Update header and add DGROUP. win32/match32.asm (Christian) - 8. Add UNICODE_SUPPORT define. zip.h, zip.c (Ed) - 9. Add oname to f and z structs for the display name to use in messages. - Change z->zname to z->oname in messages. fileio.c, zip.c, win32zip.c, - zipup.c, zipfile.c, zip.h (Ed) -10. Move multi-byte defines to make global (they were needed with wide - characters but that was taken out and left them where they are). - fileio.c, zip.h -11. Add copy_args(), free_args(), and insert_arg() to create copy of argv - that can free() and to support inserting "@" in get_option for lists. - fileio.c, zip.h -12. Insert arg "@" after list if not followed by option. fileio.c -13. Add args variable and copy argv to args so can use insert_arg(). zip.c -14. Add MKS Korn Shell note. zip.c -15. Change cast of option in add_filter() calls from char to int. zip.c -16. Implement multi-byte version of Unicode support. To support Win32 NT - wide calls will require additional work not planned for this release. - Changes include (Ed): - - Add use_wide_to_mb_default flag. globals.c, zip.h - - Add compiler UNICODE_SUPPORT version information. zip.c - - Add uname to f and z structs for UTF-8 name. zip.c - - Moved some defines out of ZIP64 section. zipfile.c - - Add define UTF8_PATH_EF_TAG for Unicode Path extra field. Currently - the tag is 0x7075 which is 'u' 'p' for Unicode path and seems - free according to the AppNote. The extra field is - tag (2 bytes 'u' 'p') - size (2 bytes) - Unicode Path size (2 bytes) - unused (2 bytes set to 0) - unused (2 bytes set to 0) - Unicode path (variable) - The unused locations also serve as a check in case the tag is in - use already. - - Add add_Unicode_Path_local_extra_field() and - add_Unicode_Path_cen_extra_field() functions. zipfile.c - - Add read_Unicode_Path_entry() function. zipfile.c - - Set uname and oname in scanzipf_ref(). zipfile.c - - Add define wide_to_mb_default. Add zchar but not used. win32/osdep.h - - Add wide command line reading but don't use. win32/win32.c - - Add port functions for Unicode, including local_to_utf8_string(), - wide_to_escape_string() (for converting a wide character that can't be - converted to mb in the local character set to a reversable escape string), - escape_string_to_wide(), wide_to_local_string(), local_to_display_string() - (for creating the display version of name), utf8_to_local_string(), - local_to_wide_string(), wide_to_utf8_string() (NOT IMPLEMENTED), and - utf8_to_wide_string() (NOT IMPLEMENTED). win32/win32.c - - Implement attempt at escape function. Whenever a wide character can't - be mapped to the local character set, this function gets called. - Currently the wide character is converted to a string of hex digits. - If the wide can fit in 2 bytes then the form #1234 is used. If not, - the 4-byte form #L12345678 is used. - It compiles but needs the utf8 functions implemented. Also needs testing - in a multi-byte environment and only Windows is implemented so need to at - least do Unix. (Ed) -17. Update freeup() to include uname and oname. zip.c -18. Move define wide_to_mb_default so default for all is '_'. zip.h (Ed) -19. No changes needed to osdep.h and update unix/unix.c but not tested. (Ed) ----------------------- October 19th 2005 version 3.0f02 ---------------------- - 1. Remove null value check for split_size as get_option() already checks. - zip.c (Ed) - 2. Update f$search(). vms/descrip.mms (SMS) - 3. Save parse name before search and use that on failure. Change name parsing - in ziptyp() to solve a problem with search-list logical name device directory - specs. vms/vms.c (SMS) - 4. Compile in UNICODE_SUPPORT if have wchar_t and mbstowcs(). unix/configure (Ed) - 5. Move Unicode defines to zip.h and functions to fileio.c so generic. Create - a new OEM function for Windows. fileio.c, zip.h, tailor.h, win32/win32.c (Ed) - 6. Add UTF-8 functions. fileio.c (Paul) - 7. Convert Unicode functions to use zwchar defined as unsigned long for wide - char. fileio.c, zip.h (Ed) - 8. Add wchar_t check for Unix. unix/configure (Ed) - 9. Add default when zwchar (4 bytes) is too big for wchar_t (2 bytes). zip.h (Ed) -10. Allow for states for wide characters but surrogates not done. fileio.c (Ed) -11. Update WhatsNew (Ed) ----------------------- December 16th 2005 version 3.0f03 ---------------------- - 1. Fix broke encryption when ZIP64_SUPPORT enabled by accounting for need for - data description when encrypting. Data description is not required for - encryption (WinZip does not use one) but seems needed by Zip for some reason. - zipfile.c (Ed) - 2. Add function bfwrite() to do buffered fwrite(). Most output already is - written by zfwrite used by crypt.c which now calls bfwrite. All splitting - and new byte counts are done in bfwrite. fileio.c (Ed) - 3. Move some functions out of ZIP64_SUPPORT defines for use with UNICODE_SUPPORT. - zipfile.c, zip.h (Ed) - 4. Add is_ascii_string() and only create Unicode extra field if z->iname is - not ascii. zipfile.c, zip.h, fileio.c, (Ed) - 5. Add parameter rewrite to putlocal() to note when rewriting bytes so the bytes - rewritten are not counted in output totals. zipfile.c, zip.h (Ed) - 6. Handle VMS ... wildcard. util.c (SMS) - 7. Make tempzip file name global. zip.c, globals.c, zip.h (Ed) - 8. Add out_path global and -O path option to allow the output archive to have a - different name than the input archive, if there is one. This allows - updating a split archive, since output to the same split name would otherwise - be complicated and not user friendly. Use out_path for output. zip.h, - zip.c, globals.c (Ed) - 9. Many output functions that had output file y as parameter, such as zipup(), - zipcopy(), putlocal(), putcentral(), and putend(), now do not as y is - now global. This allows changing y as splits are created. zip.c (Ed) -10. Add function zipmessage() for writing messages like zipwarn() but are - informational. zip.c (Ed) -11. Minor changes to help. zip.c (Ed) -12. Add SPLIT_SUPPORT to version output. zip.c (Ed) -13. Add rename_split() to rename and set attributes for a split. zip.c (Ed) -14. Add set_filetype() to set attributes of split. zip.c (Ed) -15. Change variable a (holds attributes) to zipfile_attributes and make global. - zip.c, zip.h, globals.c (Ed) -16. Add key_needed flag for encryption and move setting key to after - command line processed. zip.c (SMS) -17. Initialize dot size using default only if dot_size not set. zip.c (Ed) -18. Change command line processing so that last -P or -e is used. zip.c - (Ed) -19. Fix broke writing of 4-byte spanning signature at the beginning of the archive - if splitting. zip.c (Ed) -20. Use bfcopy() instead of fcopy() to copy archive beginning. bfcopy() uses - global y. zip.c (Ed) -21. It looks like tempzf is no longer used. zip.c (Ed) -22. Account for SUNPRO_C and DECC_VER. Change SPARC to Sparc. unix/unix.c (SMS) -23. Remove GNUC. vms/cmdline.c (SMS) -24. Change case of system calls. vms/vms.c (SMS) -25. Add fix for VMS ... matching, but may change Zip to avoid ex2in() and in2ex() - for pattern matching in future. vms/vmszip.c (SMS) -26. Remove /NODIRNAMES and /DIRNAMES from VMS help. vms/zip_cli.help (SMS) -27. Define new globals zip64_eocd_disk, zip64_eocd_offset, current_local_tempname, - bytes_this_split, and bytes_this_entry for splits. globals.c, zip.h (Ed) -28. Add SUNPRO C and DEC C compile checks. unix/configure (SMS) -29. Add CFLAGS_NOOPT for removing optimization for configure. unix/Makefile (SMS) -30. Modify crypthead() to use bfwrite(). crypt.h, crypt.c (Ed) -31. Modify zfwrite() to use global output file. crypt.h, crypt.c (Ed) -32. Modify zfwrite() when no encryption to use bfwrite(). crypt.h (Ed) -33. Add bfcopy() to copy to y. fileio.c (Ed) -34. Add close_split() and bfwrite() for splits. fileio.c (Ed) -35. Add is_ascii_string() to check if UTF-8 extra field is needed. fileio.c (Ed) -36. Change Unicode escape of 2-byte wide from #1234 to #U1234. fileio.c (Ed) -37. Add read_Unicode_Path_entry() to read the UTF-8 path extra field. zipfile.c (Ed) -38. Latest Unicode Path extra field format is - 1 byte Version of Unicode Path Extra Field - 2 bytes Name Field Checksum - variable UTF-8 Version of Name -39. Use CRC-32 for Unicode Path Checksum and AND halves. zipfile.c (Paul) -40. Add Unicode Path Checksum check to make sure extra field applies to Name field - still. zipfile.c (Christian) -41. Move get_extra_field() out of Zip64 block and make available for splits. - zipfile.c (Ed) -42. Check in putlocal() using is_ascii_string() and don't create Unicode path - extra field if name is ASCII characters. zipfile.c (Ed) -43. If local header for split is on another disk and using split method 1, close - that split in putlocal() after rewrite local header. zipfile.c (Ed) -44. Fix data descriptor bug when encrypting where putextended() did not handle the - not Zip64 case, which mostly only happens now for encryption. zipfile.c (Ed) -45. Check for ASCII name using is_ascii_string() in putcentral() for Unicode path - extra field. zipfile.c (Ed) -46. Instead of single disk values, update putend() to use real split values for - current_disk, cd-start_disk, cd_entries_this_disk, cd_start_offset, - zip64_eocd_disk, zip64_eocd_offset, and current_disk and allow for - needing Zip64 if exceed standard max values for current_disk, cd_start_disk, - cd_entries_this_disk, total_cd_entries, and cd_start_offset. zipfile.c (Ed) -47. Use current_local_offset and current_local_disk for z->off and z->dsk in - zipup(). zipup.c (Ed) -48. Fix bug where force_zip64 was used to determine descriptor size but can have - Zip64 entry without force_zip64 so use zip64_entry. zipup.c (Ed) -49. Change the p - o != s compression size test for splits to bytes_this_entry - != (key ? s + 12 : s) and avoid ftell() in split. zipup.c (Ed) -50. If local header is on a previous split and split method 1 do the seek on that - split to update header. zipup.c (Ed) -51. For streaming, only force Zip64 if reading stdin and writing a non-seekable - device. In other cases can detect either the input file size and set Zip64 - if needed or seek in the output to update the local headers. zipup.c, - zipfile.c, zipup.c (Ed) -52. Allow creation of stored archives with descriptors for testing. Currently - they can't reliably be read but this is planned. zipup.c, zipfile.c, zip.c - (Ed) -53. Update help, adding in -e, -P, -s splitsize, -sp, and -sv options. zip.c (Ed) -54. Spelling fix in zipsplit man page. man/zipsplit.1, zipsplit.txt (Ed) -55. New option -sv and variable noisy_splits to enable verbose splitting. - Default is to quietly create splits, unless -sp set to pause between splits. - zip.h, zip.c, globals.c, fileio.c (Ed) ----------------------- December 23rd 2005 version 3.0f04 ---------------------- - 1. Move inlined text-vs-binary checks from file_read() into a separate, - new function named is_text_buf(). zipup.c, util.c, zip.h (Cosmin) - 2. Fix calls to putlocal to remove the removed dest parameter. crypt.c (Ed) - 3. Add get_split_path() to get the path for a split given the disk number. - fileio.c, zip.h (Ed) - 4. Change formatting of zipmessage() to remove tabbing and add formatting - to call to zipmessage(). fileio.c, zip.c (Ed) - 5. Initialize many variables such as y and tempzip. zip.c, fileio.c, - zipfile.c (Ed) - 6. Add loop to pause during split method 2 to allow changing disk or changing - the path for the next split. fileio.c (Ed) - 7. If after starting new split there is not enough room for the remaining buffer - for split method 1 display error and exit and for split method 2 we can - display a warning and user can replace disk or change path. fileio.c (Ed) - 8. Add list to store input file arguments using add_name() to add the name to - filelist_struc filelist and then process the names after the input archive - is read. zip.c (Ed) - 9. Fix infinite loop when opening a log file whose name contains multiple '/'. - zip.c (Cosmin) -10. Move split size message lower and only output if option sv sets - noisy splits. zip.c (Ed) -11. Set y to output file, remove output file from zipcopy(), putlocal(), - putcentral(), and putend(). zipsplit.c, zipnote.c, zipcloak.c (Ed) -12. Add code for not SPLIT_SUPPORT case. zipfile.c, zipup.c (Ed) -13. Prepend '-' to commands from target clean. - win32/makefile.w32, win32/makenoas.w32, win32/makefile.bor (Cosmin) -14. Must not call putenv() in iz_w32_prepareTZenv() under Cygwin. - win32/osdep.h (Cosmin) -15. Add browse info in Visual C++ 6 project. win32/vc6/zip*.dsp (Cosmin) ----------------------- December 27th 2005 version 3.0f05 ---------------------- - 1. Add proposed changes to License (Ed) - 2. Fix -l corruption bug by using memcpy() instead of wrongly changing the - buffer pointer. Fix was left out of last beta. zipup.c (Cosmin) - 3. Fix get_split_path() parameter. zip.h (SMS, Ed) - 4. Add -dg and display_globaldots to display dots globally for entire archive - instead of for each file. Is not affected by noisy flag. globals.c, - zip.h, zip.c, zipup.c, fileio.c (Ed) - 5. Make dot_count and dot_size uzoff_t, dot_count because with global dots - dot_count does not reset and with terabyte files the number of buffers - could exceed 2G, dot_size to allow use of ReadNumString() to read number. - zip.c, zip.h, globals.c (Ed) - 6. Add Deletion to help. zip.c (Ed) - 7. Fix delete date. zip.c (Ed) - 8. For streaming, need to assume Zip64 if writing a non-seekable device so - extra field for Zip64 is created if needed. zipup.c, zipfile.c, zipup.c (Ed) - 9. Add remove_local_extra_field() and remove_central_extra_field(). - zipfile.c (Ed) -10. Remove disabled copyright from license(). zip.c (Ed) -11. Clean up recent changes. zip.c, zipfile.c, fileio.c, zip.h, zipup.c (Ed) -12. Create scanzipf_regnew() for new file scan. zipfile.c (Ed) ----------------------- December 29th 2005 version 3.0f06 ---------------------- - 1. Change dot_size and dot_count from uzoff_t to zoff_t to allow use of - negative flag values. globals.c, zip.h (SMS, Ed) - 2. Remove file parameter to bfwrite() in putend(). zipfile.c (SMS, Ed) - 3. Add back code for not SPLIT_SUPPORT to putend(). zipfile.c (SMS, Ed) - 4. Change tag from ush to ulg in remove_local_extra_field() and - remove_central_extra_field() to avoid parameter problems. zipfile.c (Ed) - 5. Add allow_empty_archive to flag when want to create an empty archive. - globals.c, zip.h (Ed) - 6. Set allow_empty_archive when using -i and expecting an archive to be - created. This is in response to the 2/14/05 email. zip.c (Ed) - 7. Make before and after variables that hold the dates of files to - process or delete global so can use them in scanzipf_regnew(). zip.h, - zip.c, globals.c (Ed) - 8. Change scanzipf_regnew() to be based on scanzipf_fix() which seems closer. - Still have not coded the new regular zipfile reader. zipfile.c (Ed) - 9. For new reader first get add list and then read old archive and filter - as reading old entries. zip.c, zipfile.c (Ed) -10. Define USE_NEW_READ to turn on using new reader, which is being - created. This allows all to work while the new reader is being worked - on. zip.c, zipfile.c (Ed) ----------------------- January 9th 2006 version 3.0f07 ---------------------- - 1. Remove dest parameter from crypthead() and zipcopy(). crypt.c (SMS, Ed) - 2. Change -ds to handle dots for as small as every 32 KB. zip.c (Ed) - 3. Add ask_for_split_write_path() and ask_for_split_read_path() for - asking where to put the next write split and for locating the next - read split. zip.h, fileio.c (Ed) - 4. Add in_path to track where reading splits from. zip.h, globals.c, zip.c (Ed) - 5. Update copyright date on changed files to include 2006 (Ed) - 6. Replace stderr with mesg for most output messages. deflate.c, fileio.c, - trees.c, util.c, zip.c, zipcloak.c, zipfile.c, zipnote.c, zipsplit.c - 7. Add mesg_line_started to track if need new line on mesg output and update - zipmessage() and zipwarn() to use it. Set mesg_line_started to 1 when - newline not last character written to mesg and 0 when it is. deflate.c, - zip.h, zip.c, globals.c, zipup(), fileio.c (Ed) - 8. Include base_path as parameter for get_split_path(). fileio.c (Ed) - 9. Account for VMS version in split path. Add vms_file_version(). fileio.c, - zip.c, vms/vms.c, vms/vms.h (SMS) -10. Create crc16f() to create ANDed halves crc32 for Unicode using copy - of crc32() but may change to use main copy. zipfile.c, zip.h, - fileio.c (Ed) -11. Close in_path and out_path in finish() and ziperr(). zip.c (Ed) -12. Change perror() to strerror() and print to mesg in ziperr(). zip.c (Ed) -13. Add find_next_signature() to find the next signature when reading a - zip file. zipfile.c (Ed) -14. Add find_signature() to find a given signature from current point in - archive. zipfile.c (Ed) -15. Add at_signature() to check if at a given signature in archive. - zipfile.c (Ed) -16. Changes to scanzipf_regnew() but far from done. zipfile.c (Ed) -17. Changes to readzipfile() to close input archive file and allow new - zipfile reader to open and close files as goes through splits. - zipfile.c (Ed) -18. Change -s to default to MB and set minimum split size to 64k. - zip.c (Ed) -19. Add link to user32.lib for CharToOem(). makefile.w32, makenoas.w32 - (Cosmin) -20. Remove unused Z64_EFPos. globals.c (Ed) ----------------------- February 13th 2006 version 3.0f08 ---------------------- - 1. Move option checks before any work is done. zip.c (Ed) - 2. Update bfcopy() to handle reading splits and remove input file - parameter and use global in_file. fileio.c (Ed) - 3. Change ask_for_split_read_path() to allow user aborting. fileio.c (Ed) - 4. Change get_split_path() to use standard file extensions from most - recent AppNote of .z01, .z02, ..., .z99, .z100, .z101, ... fileio.c (Ed) - 5. Change is_ascii_string to use 0x7F for ASCII detection. fileio.c (Ed) - 6. Add copy_only global for when -O is used to change the format of an - archive without changing the contents. This allows for converting an - archive to a split archive for instance. The global copy_only is used - to output status information for copies when normally copied files - have no status messages. globals.c (Ed) - 7. Add in_file, split_path, total_disks, current_in_disk, and - current_in_offset as globals to track reading splits. zip.h, - globals.c (Ed) - 8. Update copyright date. revision.h (Ed) - 9. Close in_file if open in finish(). zip.c (Ed) -10. Add -O (big o) to extended help. zip.c (Ed) -11. Remove readzipfile() from zipstdout() and use main call later down. - zip.c (Ed) -12. Move archive reading and file scanning after command line checks. - zip.c (Ed) -13. If -O out_zip and so have_out is set then set copy_only and allow - copying instead of error message *Nothing to do*. zip.c (Ed) -14. If zipbeg is just 4 bytes and spanning then assume is spanning - signature and set zipbeg to 0 to ignore. zip.c (Ed) -15. Don't open initial write test as modify if have_out is set and so have - a separate output file. zip.c (Ed) -16. If zipbeg is 0 and nothing at beginning of archive to copy then don't - open input file until zipcopy() does. zip.c (Ed) -17. If stuff at beginning then copy and close input file. Should be able - to keep it open but easier to close it and let zipcopy() reopen it. - zip.c (Ed) -18. Add status message when copy_only set so something is displayed. - zip.c (Ed) -19. Instead of closing x at bottom close in_file. The variable x was used - inconsistently and it seemed easier to make in_file global instead. - Then again y remains the global output variable. zip.c (Ed) -20. Update copyright. zipnote.c, zipsplit.c, zipcloak.c (Ed) -21. Change adjust_zip_local_entry() to return 1 if the entry is Zip64 and - 0 if not. This is needed to know how large the extended local header - is later. zipfile.c (Ed) -22. Add read_Unicode_Path_local_entry() to read the local version of the - Unicode Path extra field. zipfile.c (Ed) -23. Handle disk in adjust_zip_central_entry(). zipfile.c (Ed) -24. Change USE_NEW_READ to SPLIT_SUPPORT as splits seems to be stable more - or less. zipfile.c (Ed) -25. Add is_signature() to compate signatures. zipfile.c (Ed) -26. Create scanzipf_fixnew(). It should look like scanzipf_regnew(). - zipfile.c (Ed) -27. Change scanzipf_regnew() to read the central directory and create zlist - and handle reading traditionally. Allows using central directory - information, in particular file sizes, in zipcopy() while reading - entries. Use global in_file instead of f for input file and set to NULL - when not a valid file so finish() only tries to close it if needed. - Check to make sure the End Of Central Directory record found is infact - the last one in case a stored archive is in the last 64 KB. Refuse - to update a split archive but recommend using -O instead. zipfile.c (Ed) -28. Change readable check in readzipfile() to require input archive to exist - if using -O out_archive. zipfile.c (Ed) -29. Change putlocal() to not create a Zip64 extra field unless needed and - on rewriting the local header to remove Zip64 extra field if was created - but not needed. Add check if assumed entry does not need Zip64 but does, - meaning probably the uncompressed size is less than 4 GB but the - compressed size is over 4 GB. zipfile.c (Ed) -30. Change zipcopy() to use the global in_file and y files and to open and - close read splits as needed. Checks the local header against the - central directory header to verify same file, which should be as using - the disk and offset values from the central directory. Update disk and - offset in central directory. zipfile.c (Ed) -31. Change out_path and out_len to base_path and base_len in - get_split_path(). fileio.c (SMS) -32. Update command line options for VMS to include verbose splitting. - vms/zip_cli.cmd, vms/cmdline.c (SMS) -33. Handle HP. unix/unix.c (SMS) -34. Add adler16() checksum function. util.c (Cosmin) -35. Use FILE_FLAG_BACKUP_SEMANTICS and a less demanding access mode - in CreateFile() when retrieving file attributes. Fixes a problem - when adding a directory entry from an NTFS or a CDFS partition - (i.e. one that stores timestamps using universal time), and the - directory timestamp is not the same daylight savings time setting. - The effect is an offset in the timestamp by one hour, if zip is - built using NT_TZBUG_WORKAROUND. The problem is not exposed, - however, if NO_W32TIMES_IZFIX is defined. win32/win32.c (Cosmin) ----------------------- March 19th 2006 version 3.0f09 ---------------------- - 1. Fix encryption problem where a large file with uncompressable data - can cause deflate to store bad data. See crypt.c for details. - Thanks to the nice people at WinZip for finding and providing the - details of this problem. crypt.c (Ed) - 2. Add note at top of Extended Help to refer to the Zip Manual. zip.c - (Ed) - 3. Update extended help for delete. zip.c (Ed) - 4. Change crypthead() to use buffer and bfwrite() which is split aware. - crypt.c (Ed) - 5. Create SPLIT_SUPPORT version of zipcloak() and zipbare() and read - local header rather than assume data using central header. crypt.c (Ed) - 6. Change zfwrite() to use global output file y. crypt.c (Ed) - 7. Remove in and out parameters from zipcloak() and zipbare() for - splits. crypt.h, zipcloak.c (Ed) - 8. Change get_split_path() to get_in_split_path() and get_out_split_path(). - zipfile.c, fileio.c, zip.h (Ed) - 9. Change crc32f() to crc32u(). fileio.c, zip.h (Ed) -10. Add encryption overwrite fix to copy_block() and remove from zfwrite(). - crypt.c, tree.c (Ed, Christian) -11. Add note on bug fix. WhatsNew (Ed) -12. Add copy_only mode. zip.c (Ed) -13. Make SPLIT_SUPPORT the default. zip.h (Ed) -14. Add set_filetype(), rename_split(), and zipmessage(). zipcloak.c, - zipnote.c, zipsplit.c (Ed) -15. Add long option support. zipcloak.c (Ed) -16. Set in_path. zipcloak.c, zipnote.c, zipsplit.c (Ed) -17. Use SPLIT_SUPPORT calls. zipcloak.c, zipnote.c, zipsplit.c (Ed) -18. Set current_disk, cd_start_disk, and cd_entries_this_disk for use - by putend() and bytes_this_split for putcentral(). zipsplit.c (Ed) -19. Include ctype.h for toupper(). zipfile.c (Ed) -20. Add readlocal() for utilities to read local header. zipfile.c (Ed) -21. Put Zip64 variables and code in ZIP64_SUPPORT ifdef in scanzipf_regnew(). - zipfile.c (Ed, SMS) -22. Use zip_fzofft() for converting offset. zipfile.c (Ed, SMS) -23. Add casts to many append to memory calls. zipfile.c (Ed) -24. Move handling of .zip split to get_in_split_path() and - get_out_split_path(). zipfile.c (Ed) -25. Handle fix = 3 case for ZipNote that renames entries in zipcopy(). - zipfile.c (Ed) -26. Restore clearing of extended local header bit when not encrypting. When - encrypting need to output extended local header using putextended() in - zipcopy(). zipfile.c (Ed) -27. Add notes on using file time for encrypting. zipup.c (Ed) -28. Remove extended local header bit separately for z->lflg (local flags) - and z->flg (central directory flags). These should be the same but - could be different. zipup.c (Ed) -29. Suppress command line globbing for MINGW. win32/win32.c (Christian) -30. Add EF UT time fix for delete. zip.c (Christian) ----------------------- April 28th 2006 version 3.0f10 ---------------------- - 1. Add note to extended help to escape [ as [[] or use -nw. zip.c (Ed) - 2. Remove local declaration of tempfile as now global. zipnote.c, - zipcloak.c (SMS) - 3. Add zip_fzofft() for outputting uzoff_t bin size c. zipsplit.c (SMS) - 4. Add only_archive_set and clear_archive_bits to do Window archive bit - selection and clearing. Add -AS option to require DOS Archive bit - be set and -AC to clear archive bits of included files. Add - ClearArchiveBit() to clear archive bits after archive created. - Only Win32. globals.c, zip.h, zip.c, win32zip.c, win32.c (Ed) - 5. Change procname_win32() and readd() to check archive bit. - win32/win32zip.c (Ed) - 6. Update copyright. win32/win32zip.h (Ed) - 7. Add mesg_line_started = 0 to stats to remove blank line when clearing - archive bits. zipup.c (Ed) - 8. Add zip_fzofft() to format split size. zipsplit.c (SMS) - 9. Update help for splits and archive bit and add note on escaping [. - zip.c (Ed) -10. Add -M option and bad_open_is_error to exit with error if any input - file unreadable. Also error if -M and would get "name not matched" - warning. zip.c (Ed) -11. Copy Zip 2.32 csharp example, though it is designed for zip32.dll and - not zip32z64.dll from Zip 3.0. Updated note. windll/csharp (Ed) -12. Change -M to -MM and define -mm to avoid accidental use of -m. - zip.c (Ed) -13. Define split_method -1 to not allow splitting, mainly used when reading - a split archive to stop automatic splitting of output with same - split size. Now -s=0 or -s- disables splitting. zip.h, globals.c, - zip.c (Ed) -14. Add fflush() after dots displayed. deflate.c, fileio.c, zipup.c (Ed) -15. Instead of assuming buffer size as 32 KB for dots, use WSIZE for - compressing and SBSZ for storing and calculate as dots are counted. - Now dot_count and dot_size are bytes instead of buffers. Add dots - to Delete and Archive modes. zip.c, zipup.c, deflate.c, fileio.c (Ed) -16. If reading a split archive and split size has not been given, get - size of first split read by zipcopy(), which should be the first - split, and set split size to that, making the output archive the same - split size as the input archive. Delay -sv split size message - if split size is 0 at first but then changed. zipfile.c (Ed) -17. Add proc_archive_name() for new archive mode to process names in old - archive only and skip looking on the file system. Easier than modifying - the various port codes. fileio.c (Ed) -18. Fix cd_start_offset bug. fileio.c (Ed) -19. Create new action ARCHIVE that looks for matches only in old archive - for Copy Mode. If no input paths and there is an output archive, - Copy Mode is assumed even without ARCHIVE. Old default Copy Mode - when no input files updated to work like -U mode and allow filters. - New global copy_only currently only used to control global dots. - zip.c, fileio.c, globals.c, zip.h (Ed) -20. Update help. Change extended help to more help. Update more help - to include internal modes delete and new Archive. Update help for - formatting options. Update help for wildcards. Remove streaming - examples from top basic section. Indent examples. Help for new - --out and Copy Mode. Add warnings that output using data descriptors - may not be compatible with some unzips. Update dots help and add - warning that dot size is approximate. Add help for new DOS archive - bit options. More help for -b and -MM. zip.c (Ed) -21. Add support for Unix FIFO (named pipe). Add set_extra_field() stat - name ending in '/' fix found in Zip 2.32. unix/unix.c (Ed) -22. Add check to not allow setting -U (internal copy) in similar cases to - -d (delete). zip.c (Ed) -23. Add counts for internal modes Delete and Archive. Byte counts for -db - remain uncompressed size for external modes, but internal modes Delete - and Archive now use compressed sizes as these copy that many bytes. - zip.c (Ed) -24. Add check for when ftell() wraps. zipup.c (Ed) -25. Add mesg_line_started = 0 to result percentage message. zipup.c (Ed) -26. Update contact information. unix/packaging/preinstall.in (SMS, Ed) -27. A few Zip64 fixes to set Zip64 correctly and fix disk and offset of - Zip64 End Of Central Directory. zipsplit.c (Ed) -28. Update comments for get_option(). fileio.c (Ed) -29. Update DLL version. windll/windll.rc (SMS, Ed) -30. New option -sf shows files that would be operated on. zip.c (Ed) ----------------------- May 5th 2006 version 3.0f11 ---------------------- - 1. Use C prototypes for Unicode functions. fileio.c (SMS) - 2. Change constant for mask in set_file_type from unsigned to signed. - trees.c (SMS) - 3. Use C prototypes for zip_fzofft() and zip_fuzofft() signed and - unsigned zoff_t formatting functions. util.c (SMS) - 4. Remove U from constants in Adler16 code. util.c, zip.h (SMS) - 5. Add spaces to VMS usage to avoid misinterpretation. zip.c (SMS) - 6. Add OF() to at_signature(). zipfile.c (SMS) - 7. Use zip_zofft() for entries error. zipfile.c (SMS) - 8. Remove U in constants in percent(). zipup.c (SMS) - 9. VMS command line updates. vms/cmdline.c, vms/descrip_deps.mms, - vms/vms_zip.rnh, zip_cli.cld, vms/zip_cli.help (SMS) -10. Update to VMS help. vms/zip_cli.help (Ed) -11. Check for memmove() and strerror(). Remove specific 64-bit support - for SunOS, as large file support now does. unix/configure (SMS) -12. Add emergency replacements for memmove() and strerror(). - unix/unix.c (SMS) -13. Remove old not SPLIT_SUPPORT code. globals.c, zipnote.c, fileio.c, - crypt.h, crypt.c, zipcloak.c, zip.h, zip.c, zipup.c, zipsplit.c, - zipfile.c (Ed) ----------------------- May 12th 2006 version 3.0f12 ---------------------- - 1. Add UNICODE_SUPPORT ifdef around uname in zipup(). zip.c (SMS) - 2. Change size from uzoff_t to zoff_t in zipcopy(). zipfile.c (SMS, Ed) - 3. Fix a bug where filetime() returns -1 for device but not handled in - byte counts. zip.c (Ed) - 4. Add check for UnZip version and exit if not 6.00 or later if - a Zip64 archive. Define popen() and pclose() in Win32 to native - _popen() and _pclose(). ziperr.h, zip.c, win32/osdep.h (Ed) - 5. Add -sb option to ring bell when pause to change disk. Use new - global split_bell. global.c, zip.h, zip.c, fileio.c (Ed) - 6. Enable crc32u() and use for Unicode extra field. fileio.c (Ed) - 7. Add -dv to display volume being written to. zip.c, zip.h, - globals.c (Ed) - 8. Update WhatsNew. WhatsNew (Ed) - 9. Help updates. zip.c (Ed) -10. Create option -X- (negated -X) to keep old extra fields and remove - -XX which is now -X. Make get_extra_field() global. Add - copy_nondup_extra_fields()to copy old extra fields not already - in new extra fields. zipup.c, zip.c, zipfile.c (Ed) -11. Use output name oname for -sf option to show files that would be - worked on. zip.c (Ed) -12. When updating or freshening old entries, read the old local header - with readlocal() to get local flags and extra fields. zip.c (Ed) -13. Add UNICODE_SUPPORT ifdefs around uname code. zip.c (SMS, Ed) -14. If WIN32_OEM set then on WIN32 store OEM name in archive. As read - DOS or WIN32 archives convert assumed OEM paths to ANSI. Remove old - WIN32_OEM code. Make oem_to_local_string() global for WIN32_OEM and - local_to_oem_string() global for WIN32_OEM and UNICODE_SUPPORT. - zip.h, zipfile.c, zipup.c, win32/win32.c, win32/win32zip.c (Ed) -15. Update error 8 to include wrong unzip. ziperr.h (Ed) -16. Change checksum for Unicode extra field to standard crc32 using - C version crc32u(). Add crctab.c. win32/vc6/zipnote.dsp, - win32/vc6/zipsplit.dsp, zipfile.c -17. Update readlocal() to handle multi-disk archives if not UTIL. - zipfile.c (Ed) -18. Convert size to signed zoff_t in zipcopy(). Update note. - zipfile.c (Ed) -19. Update Readme. Readme (Ed) -20. Add crctab.o to zipsplit and zipnote. unix/Makefile (Ed) -21. Proposed update to license. License (Ed) ----------------------- May 20th 2006 version 3.0f13 ---------------------- - 1. Reformat License file. License (Cosmin) - 2. Change %d to %lu for disk number and add cast. zip.c (Cosmin, Ed) - 3. Display Scanning files message after delay at start based on - suggestion from Greg. Currently the time is checked every 100 - entries processed. After 100 entries the start time is saved. - After 5 seconds or 100 entries after that, whichever takes - longer, the Scanning files message is displayed and every 2 seconds - or 100 entries, whichever takes longer, after that a dot is displayed. - fileio.c, zip.c, globals.c, zip.h (Greg, Ed) - 4. Add Unicode mismatch flag and option -UN. Default is now a Unicode - mismatch is an error. -UN=warn outputs warnings and continues, - -UN=ignore disables warnings, and -UN=no ignores the Unicode extra - fields. globals.c, zip.h, zipfile.c (Ed) - 5. Add options for VMS. vms/cmdline.c, vms/zip_cld.cld (SMS) - 6. Add casts to percent(). zipup.c (Ed) - 7. Minor changes to logfile formatting. zip.c (Ed) - 8. Update help. zip.c (Ed) - 9. Add -Z=compression-method option. zip.c (Ed) -10. Add sd: to -sd status messages. zip.c (Ed) -11. Instead of original argv[] use args[] for -sc show command line - to show final command line. zip.c (Ed) -12. Change argv[] to args[] for logfile. zip.c (Ed) -13. Put results of -sf show files in log file if open. zip.c (Ed) -14. Add Johnny's bzip2 patch but not tested. win32/makefile, zip.c, - zip.h, zipup.c (Johnny) -15. Minor tweeks to bzip2 to work with latest beta. zip.c, zipup.c (Ed) -16. Add -sf- to list files that would be included only in log file - and not on stdout as list can be long. Only list totals on stdout. - zip.c (Ed) -17. Create check_unzip_version(). Fix Unix check. Zip still creates - the temporary archive then does the check, and if it fails - the archive is deleted, even if the check fails because of the wrong - verion of UnZip. On Unix only 'unzip' the system version of UnZip - is checked, not './unzip' which would allow putting a local more - up to date version of UnZip in the current directory for the check. - There should be a way to override the system version of UnZip for - the -T test. zip.c (Ed) ----------------------- July 12th 2006 version 3.0f14 ---------------------- - 1. Change crypt version from 2.10 to 2.91 to match Zip 2.32 and avoid - confusion. crypt.h (Cosmin) - 2. Add abbrevmatch() to handle option values that can be abbreviated - like compression method. util.c, zip.h, zip.c (Ed) - 3. Change USE_BZIP2 to BZIP2_SUPPORT as USE_BZIP2 implies it replaces - deflation maybe. zip.c, zip.h, zipup.c (Ed) - 4. Update man page. man/zip.1, zip.txt (Ed) - 5. Add bzip2 to VMS. vms/build_zip.com, vms/bzlib.h, vms/cmdline.c, - vms/descrip.mms, vms/descrip_src.mms, vms/find_bzip2_lib.com, - vms/install_vms.txt, vms/zip_cli.cld (SMS) - 6. Remove zipfile parameter from bzfilecompress(). Add unsigned - cast for EOF in bzip2 code. Add bzip2 version information. - zipup.c, zip.c (SMS) - 7. Add bzip2 to Unix. unix/configure (SMS) - 8. Add and update bzip2 descriptions. INSTALL, README, WhatsNew, - bzip2/install.txt (SMS, Ed) - 9. Add vc6bz2 projects for compiling bzip2 code into zip (not the - best approach perhaps). win32/vc6/readmevc.txt, - win32/vc6bz2/readvcbz.txt, win32/vc6bz2/zip.dsp, win32/vc6bz2/zip.dsw, - win32/vc6bz2/zipcloak.dsp, win32/vc6bz2/zipnote.dsp, - win32/vc6bz2/zipsplit.dsp (Ed) -10. Add support for VC++ 2005 by disabling deprecation. win32/osdep.h - (Cosmin) -11. Update instructions for makefile. unix/Makefile (Ed) -12. Update todo list. todo30.txt (Ed) -13. Reduce #if 0 block to now allow extra data message. zipfile.c (Ed) -14. Add note that readlocal() reads local headers. zipfile.c (Ed) -15. Archive comment was not being read by new scanzipf_regew(). Added. - zipfile.c (Ed) -16. Handle reading and writing OEM comments. zipfile.c (Ed) -17. Update Zip64 data descriptor note. zipfile.c (Ed) -18. Format filetypes() check. zipup.c (Ed) -19. Update note to remember to force deflation for descriptors by - release. zipup.c (Ed) -20. In compression code using libraries, enable dots for noisy also. - zipup.c (Ed) -21. Update extended help to add more of the basic options and - compression method. zip.c (Ed) -22. Add additional lines bz_opt_ver2 and bz_opt_ver3 to bzip2 - version to give credit to bzip2. zip.c (Ed) -23. Add descriptions to version information for USE_EF_UT_TIME, - NTSD_EAS, WILD_STOP_AT_DIR, WIN32_OEM, LARGE_FILE_SUPPORT, - ZIP64_SUPPORT, and UNICODE_SUPPORT similar to how UnZip does. - zip.c (Ed) -24. Add note that crypt is modified in Zip 3. zip.c (Ed) -25. Use abbrevmatch() and update warnings for compression - method selection. zip.c (Ed) -26. Update config to handle either using IZ_BZIP2 to define - the location of the bzip2 files or the bzip2 directory. - unix/configure, zipup.c, zip.c (SMS, Ed) ----------------------- July 14th 2006 version 3.0f15 ---------------------- - 1. Change USE_BZIP2 to BZIP2_SUPPORT in VMS. vms/descrip_src.mms, - vms/build_zip.com (SMS) - 2. Add SYS$DISK:. vms/descrip.mms, vms/build_zip.com (SMS) - 3. Change vms/install.txt to [.vms]install.txt. bzip2/install.txt (SMS) - 4. Change VMS files to lower case. vms/mod_dep.com, vms/install_vms.txt, - vms/zip.opt, vms/hlp_lib_next.com, vms/notes.txt, vms/unixlib_gcc.h, - vms/unixio_gcc.h (SMS) - 5. Remove old VMS files. vms/descrip-old.mms (removed), - vms/link_zip.com (removed), vms/make_zip.com (removed), - vms/makefile.vms (removed) (SMS) ----------------------- July 24th 2006 version 3.0f16 ---------------------- - 1. Fix global dots so can set with dot size. deflate.c, fileio.c (Ed) - 2. Update License top line to refer only to license. License (Cosmin) - 3. Update License. License (Ed) - 4. Implement zero length UTF-8 path length as flag standard path is UTF-8 - and should use that. This allows Zip to use the standard path as - UTF-8 when the local character set is UTF-8. zipfile.c (Ed) - 5. Update WhatsNew. WhatsNew (Ed) - 6. Change case of bzip2/install.txt. INSTALL (Ed) - 7. Change MANUAL.txt to ZIP.txt and update ftp site. README (Ed) - 8. Update announcement. zip30f.ann (Ed) - 9. Now also check if OS has bzip2 library and can use that. - unix/configure, zip.c (Mark Adler, Ed) -10. Add fix from akt@m5.dion.ne.jp in Japan to recurse on doublebyte - characters without processing in recmatch(). This should not be needed - unless the rest of the code in there is broke for Japanese character - sets in some way. Need to test. util.c (Ed) -11. Add note for bzip2. zip.c (Ed) -12. Do not do seek wrap test if ftell() returns -1 as from a pipe. Add - output of last ftell() and current ftell() for zipfile too big seek - error. zipup.c (Ed) -13. Add version to the options table. Remove the check to display version - before the command line is processed. Add to option -v a check to - display the version if that is the only argument. Can still enable - verbose with piping by using zip -v - - format. zip.c (Ed) -14. Add abbrevmatch() for -UN option. zip.c (Ed) ----------------------- August 7th 2006 version 3.0f17 ---------------------- - 1. Change license modifications to retain intent of copyright holders, as - any major change in license conditions would require contacting all - copyright holders. LICENSE (Greg, Ed) - 2. Move debugging statement after zipstdout() where mesg is set to stderr. - Add mesg and fflush() to sd messages where needed so that messages go - to stderr when piping. zip.c (Ed) - 3. Update encryption comment. zipup.c (Ed) - 4. Do not use data descriptors for directories. zipup.c (Mark, Ed) - 5. Update Q & A to match license. README (Ed) - 6. Update WhatsNew. WHATSNEW (Ed) - 7. Add ifndef around version_info() for dll. zip.c (Ed) - 8. Add -TT (--unzip-path) to allow setting the unzip command to use with - -T to test the archive. zip.c (Ed) - 9. Add -DF (--difference-archive) which requires --out and turns off - copying unchanged entries to the new archive creating an archive with - just the changes and additions since the original archive was created. - zip.c, globals.c, zip.h (Ed) -10. Update help. zip.c (Ed) ----------------------- September 7th 2006 version 3.0f18 ---------------------- - 1. Split -t and -tt options and remove limitation that only one can be - used to allow setting a date range. zip.c, WhatsNew (Ed) - 2. Minor changes in comments. zipfile.c (Ed) - 3. Add entries for format of Unicode Path and Unicode Comment extra fields. - proginfo/extrafld.txt (Ed) - 4. Change note at top of infozip.who, but needs to be updated with all new - contributors. proginfo/infozip.who (Ed) - 5. Note Zip 3 and UnZip 6 now support Zip64. proginfo/ziplimit.txt (Ed) - 6. Add note on Unicode. README (Ed) - 7. Update WHATSNEW. WHATSNEW (Ed) - 8. Update help. zip.c (Ed) - 9. Add {} support to -TT option, allowing insertion of temp archive path - into the command string to -TT similar to Unix find does. zip.c (Ed) -10. Start changes for -F fix option. Add checks when reading input archive - and skip bad central directory entries and bad local entries. Currently - -F requires the central directory to be intact (except for bad CD entries - that will be skipped) and local entries and data to be where the - central directory say they are. This allows all recovered entries to - be complete with all central directory information. Calculate CRC of - input entry and compare to CRC from central directory. Allow skipping - split disks the user may not have. Store state of output archive - before each local entry and data are read, allowing seeking back and - restoring state to skip bad entries. fileio.c, global.c, zipfile.c, - zip.h (Ed) -11. Started changes for fixfix. fileio.c (Ed) -12. Update help on -t and -tt. zip.c (Ed) -13. Add note on Unicode support, but may change if add handling of names - with characters not supported in current character set. README (Ed) -14. Combined ToDo30.txt and ToDo but more to be done. TODO (Ed) -15. Update ToDo list. ToDo30.txt (Ed) -16. Add -F and -FF to help. zip.c (Ed) -17. Run fix mode in copy mode, as it is copying from one archive to - another, and use those checks. zip.c (Ed) -18. Add Try -F and Try -FF warnings in places. zipfile.c (Ed) -19. Allow reading version 4.6 (bzip2) archives. zipfile.c (Ed) -20. Add Unicode Path and Unicode Comment extra field descriptions. - proginfo/extrafld.txt (Ed) -21. First attempt at updating the Who file. proginfo/infozip.who (Ed) -22. Add note to top of ziplimit.txt. proginfo/ziplimit.txt (Ed) -23. Add possible fix for paths returned by the Win32 directory scan with - '?' in the name. These are characters in the Unicode name stored on - disk but not represented in the multi-byte character set used by zip - for the scan. In this case, return the short name in 8.3 format so - directory scan can continue. Could put the Unicode name in the Unicode - extra field, but not done. Add warning when long name is replaced - by short name. Not fully tested. win32/win32zip.c, zip.h, zip.c, - fileio.c (Ed) -24. If archive name and -sf are the only parameters, list archive contents. - zip.c (Ed) ----------------------- September 8th 2006 version 3.0f19 ---------------------- - 1. Fix error message. zipfile.c (SMS, Ed) - 2. Put crc32() in ifndef UTIL as only needed for fix. fileio.c (SMS, Ed) ----------------------- November 3rd 2006 version 3.0f20 ----------------------- - 1. Fix comment. vms/vmszip.c (SMS) - 2. Include oem_to_local_string() if UNICODE_SUPPORT. win32/win32.c, - zip.h (Ed) - 3. Modify procname_win32() to flag a path not supported by the local - character set so can get Unicode for it. Check Unicode names. - win32/win32zip.c (Ed) - 4. Add matching of escaped Unicode names to proc_archive_name() that - reads entries from an archive. Add sorted zlist zusort. - globals.c, fileio.c, zip.h, zipfile.c (Ed) - 5. Add support for non-local character set names and paths for WIN32, - getting and storing the UTF-8 path when needed. Use 8.3 name - when normal name has characters not supported in current local - character set. Note when short name used. zip.c, fileio.c (Ed) - 6. Add support for fix = 2 which reads local headers first to - bfcopy(). fileio.c, zip.h (Ed) - 7. Allow selection of .zip split in ask_for_split_read_path() when - reading a split archive that has no end records giving the total - split count. fileio.c (Ed) - 8. Add zoff_t casts to dot counts. fileio.c (Ed) - 9. Comment changes for Unicode. fileio.c (Ed) -10. Call wide_to_local_string() separately in utf8_to_local_string() - to free up temp value. fileio.c (Ed) -11. Support new AppNote bit 11 for forcing UTF-8, but needs finishing. - globals.c (Ed) -12. Add to zlist struct zuname for the escaped version of the UTF-8 - name in uname and add ouname for the display version of zuname. - zip.c, zip.h, zipfile.c (Ed) -13. Add zipmessage_nl() that can output to the screen and to the log - file like zipmessage(), but can write lines without a newline. - zip.c, zip.h, zipcloak.c, zipnote.c, zipsplit.c (Ed) -14. Update help for -FF and Unicode. zip.c (Ed) -15. Change > to >= for byte message check to avoid -0 (negative zero). - zip.c (Ed) -16. Add -su show unicode option which adds escaped unicode paths to - -sf. Also uses show_files = 3. zip.c (Ed) -17. Update comments for -UN and -X. zip.c (Ed) -18. Add support for new AppNote bit 11 that says standard path and - comment have UTF-8 when -UN=f is used. zip.c (Ed) -19. Fix zipfile name message by replacing value with zipfile. - zip.c (Ed) -20. Add new code for -FF, which processes archives by trying to read - the EOCDR to get split count, then starting with the local - entries. This option does not use the standard code but does - everything itself. Add scanzipf_fixnew(), which tries to read - the EOCDR, then the local entries, then the central directory. - zip.c, zipfile.c (Ed) -21. Update note for ZIP64_CENTRAL_DIR_TAIL_SIZE. zipfile.c (Ed) -22. Put read_Unicode_Path_entry() and read_Unicode_Path_local_entry() - into UNICODE_SUPPORT ifdef. zipfile.c (Ed) -23. Add zuqcmp() and zubcmp() to support Unicode sorted list of - paths. zipfile.c (Ed) -24. Update zsearch() to also search unicode paths. zipfile.c (Ed) -25. Split out iname in read_Unicode_Path_entry() for debugging. - Should put it back. Update Unicode mismatch warning. - zipfile.c (Ed) -26. Update Unicode in readlocal(). zipfile.c (Ed) -27. Add more Unicode support to scanzipf_regnew(). zipfile.c (Ed) -28. Add support for fix = 2 to zipcopy(). Add checks and warnings, - but allow scan to continue when can. Use local data to fill - in central directory fields in case no central directory entry - for local entry. zipfile.c (Ed) -29. Add get_win32_utf8path() to get UTF-8 from Windows if can. - zipfile.c (Ed) ----------------------- November 7th 2006 version 3.0f21 ----------------------- - 1. Add crude data descriptor support to -FF in bfcopy() that should be - updated by release. fileio.c (Ed) - 2. Change %d to %s and use zip_fzofft() to format zoff_t byte count. - zipfile.c (SMS, Ed) - 3. Call local_to_oem_string() for only WIN32 in zipcopy(). zipfile.c - (SMS, Ed) ----------------------- November 29th 2006 version 3.0f22 ----------------------- - 1. Change ' to " in extended help. zip.c (Ed) - 2. Change -dv disk number display to indisk>outdisk. zip.c (Ed) - 3. Finish -FF fix option. Move detailed output to require -v. zip.c (Ed) - 4. Add note to help to use -v with -FF to see details. zip.c (Ed) - 5. Add -sU option to view only Unicode names when exist. zip.c (Ed) - 6. Change default dot size in verbose from every buffer to 10 MB. zip.c (Ed) - 7. Exit if --out and in path same as out path. zip.c (Ed) - 8. Remove verbose information when fixing archive. zip.c (Ed) - 9. Initialize in disk to 0, but still problem with disk number of first entry - for each disk lagging by 1. zip.c (Ed) -10. Consistently use ZE error codes for exit from ask_for_split_read_path. - zipfile.c, zip.c (Ed) -11. Seek back when fix finds bad entries. Also skip last entry of split - if next split is missing. Should check if entry completed. zip.c (Ed) -12. Add messages to -sd for writing the central directory, replacing the old - zip file, and setting file type. zip.c (Ed) -13. Don't set file type on stdout. zip.c (Ed) -14. Increase errbuf from FNMAX + 81 to FNMAX + 4081. zip.h (Ed) -15. Add skip_this_disk, des_good, des_crc, des_csize, and des_usize globals - for -FF and reading data descriptors. Change note on display_volume. - Add global skip_current_disk. zip.h, globals.c (Ed) -16. BFWRITE_HEADER define now also does data descriptor. zip.h (Ed) -17. Skip zipoddities() if fix. Maybe can later add back. zipfile.c (Ed) -18. Update fix messages. zipfile.c (Ed) -19. Allow user to end archive early using ZE_EOF. zipfile.c, fileio.c (Ed) -20. Only show split numbers and offsets for -FF if verbose. zipfile.c (Ed) -21. Handle spanning signature at top of split archive. zipfile.c (Ed) -22. Only close in_file if open. zipfile.c (Ed) -23. Add note if no .zip and only splits suggest use -FF. zipfile.c (Ed) -24. In putlocal() and putcentral() only convert to OEM if z->vem == 20. - zipfile.c (Ed) -25. Do not OEM convert archive comment as PKWare says this should - be ASCII. zipfile.c (Ed) -26. Fix swap of siz and len and LOCSIZ and LOCLEN. zipfile.c (Ed) -27. Call read_Unicode_Path_local_entry() before OEM conversion so Unicode - checksum checks iname before conversion. zipfile.c (Ed) -28. Only check if local and central crc match if not stream entry. - zipfile.c (Ed) -29. Keep data descriptors if fix == 2, but need to look at this. - zipfile.c (Ed) -30. Fix bug adding up header bytes in n by adding 4 for signature. - zipfile.c (Ed) -31. If fix == 2 use local crc for central, otherwise use central crc - for local. zipfile.c (Ed) -32. In zipcopy(), check data descriptor and skip if not correct one. - zipfile.c (Ed) -33. Add SH, LG, and LLG macros from zipfile.c to allow reading the data in - the data descriptor. fileio.c (Ed) -34. In bfcopy(), read and check the data descriptor if n == -2. If - run out of bytes before find descriptor, return error. fileio.c (Ed) -35. In ask_for_split_read_path(), increase buf to SPLIT_MAX_PATH + 100, - fix bug by adding "- 1", set split_dir = "" if current directory, - and update prompts to add skip and end choices. Add skip and end - choices. fileio.c (Ed) -36. Increase buffer for fgets to SPLIT_MAXPATH. fileio.c (Ed) -37. Update WhatsNew. WhatsNew (Ed) ----------------------- December 10th 2006 version 3.0f23 ----------------------- - 1. Handle additional ODS5 issues by upper casing many symbols and file names. - vms/build_zip.com, vms/collect_deps.com, vms/descrip.mms, - vms/descrip_mkdeps.mms, vms/descrip_src.mms, vms/find_bzip2_lib.com (SMS) - 2. Update VMS Find Help Library code. vms/hlp_lib_next.com (SMS) - 3. Instead of tempname use temp_name as parameter to avoid function - tempname(). zipsplit.c, zipnote.c, zipcloak.c, zip.c (Ed) - 4. If fixing archive with -FF and no EOCDR to get disk count, see if top of - archive has spanning signature or local header and guess if it is - single-disk archive, then ask user to confirm. zipfile.c (Ed) - 5. For Unix where NO_MKSTEMP is not defined, replace mktemp() with mkstemp() - that avoids a race condition. zip.c, zipcloak.c, zipnote.c, fileio.c (Ed) - 6. Eliminate mkstemp() warning by using mkstemp() instead of mktemp() for - Unix. Only for UNIX and if NO_MKSTEMP is not defined. Many OS do not - have mkstemp(). zipcloak.c, zipnote.c, zip.c, fileio.c (Ed) - 7. If UNICODE_SUPPORT and UNIX then try to switch to UTF-8 locale to allow - displaying of Unicode, otherwise just get escapes. This results in some - characters displaying as whitespace if needed fonts, such as East Asian, - are not installed. zip.c (Ed) - 8. If new global unicode_escape_all is set, then escape all non-ASCII - characters when converting Unicode file path. This allows viewing paths - as escapes on Unix that would otherwise be white space. If not set, any - characters that map to the current locale are returned as is. Can only - display if either supported as base by the OS or fonts installed. Set - using -UN=escape option. zip.c, fileio.c, zip.h, globals.c (Ed) - 9. Update extended help for Unicode. zip.c (Ed) -10. All variables used by Win32 in global.c should now be initialized at - start so dll is initialized each call. zip.c (Ed) ----------------------- January 1st 2007 version 3.0f24 ----------------------- - 1. Fix a problem when building with (old, obsolete) IM attribute encoding - combined with bzip2 support. vms/descrip_src.mms (SMS) - 2. Update WHATSNEW. WhatsNew (Ed) - 3. Update README. ReadMe (Ed) - 4. Remove in_crc code. Too involved to implement but may look at later. - fileio.c, globals.c, zip.c (Ed) - 5. Use 0x50 and 0x4b for 'P' and 'K' in signatures to handle EBCDIC case. - zipfile.c, fileio.c (Ed) - 6. Implement new -FS file sync option that deletes entries missing on the - file system from an archive being updated. globals.c, zip.c (?, Ed) - 7. Update help. zip.h, zip.c (Ed) - 8. Include scanning files dots when update small but new file scan long. - zip.c (Ed) - 9. Ask if single-file archive when using -FF and can't tell. zipfile.c (Ed) -10. Display message when entry would be truncated. zipfile.c (Ed) -11. Check for VMS_IM_EXTRA. Update bzip2 support for VMS. Change - destination directory if large-file enabled. vms/build_zip.com, - vms/descrip_src.mms (SMS) -12. Change parameters for VMS bzip2 search. vms/find_bzip2_lib.com (SMS) ----------------------- January 12th 2007 version 3.0f25 ----------------------- - 1. Incorporate faster crc32.c including the Rodney Brown changes (originally - implemented in the zlib project) from UnZip, which includes the - IZ_CRC_BE_OPTIMIZ and IZ_CRC_LE_OPTIMIZ optimizations when those symbols - are defined. These modifications include: - - enlarge unrolling of loops to do 16 bytes per turn - - use offsets to access each item - - add support for "unfolded tables" optimization variant - crc32.c (Christian) - 2. As the crc32.c module now includes crc table generation, remove crctab.c. - crctab.c (remove) (Christian) - 3. Update crc i386 assembler code from UnZip (details see above). - win32/crc_lcc.asm, win32/crc_i386.asm, win32/crc_i386.c, crc_i386.S - (Christian) - 4. Guard against redefinition of symbols @CodeSize and @DataSize in memory - model setup section to work around Open Watcom (version 1.6) wasm - assembler problem. msdos/crc_i86.asm (Christian) - 5. Change type of keys[] array for new crc, add IZ_CRC_BE_OPTIMIZ, and - use new crypt crc table. Use header buffer instead of buf for header. - crypt.c, crypt.h (Christian) - 6. Update version and remove crc table. crypt.h (Christian) - 7. Add crc32.h, change sprintf() format for disk number from d to lu as - can go over 16-bit, remove crc32u(). fileio.c (Christian) - 8. Update to use new crc. msdos/makefile.bor, msdos/makefile.dj1, - msdos/makefile.dj2, msdos/makefile.emx, msdos/makefile.msc, - msdos/makefile.tc, msdos/makefile.wat, unix/Makefile, - vms/build_zip.com, vms/descrip_deps.mms, vms/descrip_src.mms, - vms/osdep.h, win32/makefile.bor, win32/makefile.dj, win32/makefile.emx, - win32/makefile.gcc, win32/makefile.ibm, win32/makefile.lcc, - win32/makefile.w10, win32/makefile.w32, win32/makefile.wat, - win32/makenoas.w32, win32/vc6/zip.dsp, - win32/vc6/zipcloak.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp, - win32/vc6bz2/zip.dsp, win32/vc6bz2/zipcloak.dsp, win32/vc6bz2/zipnote.dsp, - win32/vc6bz2/zipsplit.dsp, windll/visualc/dll/zip32.dsp, - windll/visualc/dll/zip32.mak, windll/visualc/lib/zip32.dsp, - win32/visualc/lib/zip32.mak (Christian) - 9. Include crc32.h. Make variable uname local in proc_archive_name(). - Remove unused num and new_base_path. Change %02d to %02l2 for - disk number in print format. Remove crc32u() as now use crc32(). - Add parentheses around conditions in loops. Use 0 instead of NULL - for zwchar. fileio.c (Christian) -10. Add z_uint4 defines from crypt.c to tailor.h. Move uch, ush, and ulg - typedefs before tailor.h include which needs them. tailor.h, zip.h (SMS) -11. Include crc32.h. change add_name() to return not int but long - since number of command line arguments can exceed 16 bits. Cast - variable option to (int) for subtraction. Change 0x400 to 0x400L. - Add braces to show_files print block. zip.c (Christian) -12. Add warning if use -F or -FF without --out. Change defined(NO_MKSTEMP) - to !defined(NO_MKSTEMP). zip.c (Ed) -13. Define EC64LOC and EC64REC for size of Zip64 EOCD Locator and Zip64 - EOCD Record. Add extern for crc_32_tab. Move crc32() to crc32.h. - zip.h (Christian) -14. Add crc.h. zipcloak.c (Christian) -15. Include crc32.h. Comment out scanzipf_reg() and scanzipf_fix() as - no longer used, which are left in for now for comparison. Cast - blocksize to extent for malloc(). Instead of 0x10000 malloc 0xFFFF for - extra field block so fits in 16 bits. Instead of crc32u() use crc32(). - Only do lflg != flg check for fix == 2. Add comments to various #endif. - Indent comment. Comment out copy_sig() which is not used. Reduce size - of SCAN_BUFSIZE to EC64REC for MEMORY16. Use ENDHEAD for EOCDR size. - Change %u to %lu in print formats for disk count. Use EC64LOC for size - of Zip64 EOCD Locator. Use EC64REC for size of Zip64 EOCD Record. - Add streaming and was_zip64 to ZIP64_SUPPORT. Remove lflg != flg check - in zipcopy(). zipfile.c (Christian) -16. Add note that z-flg & ~0xf check will fail if new bit 12 for UTF-8 paths - and comments is set. Update -FF warning. zipfile.c (Ed) -17. Include crc32.h. Modify tempzn update. Fix comment. Set - z->lflg = z->flg after deflate as deflate may have set bits in z->flg - [Ed, Christian]. Include BZIP2_SUPPORT block in !UTIL block. zipup.c - (Christian) -18. Changes to use crc32.c. acorn/gmakefile, acorn/makefile, amiga/lmkfile, - amiga/makefile.azt, amiga/smakefile, aosvs/make.cli, atari/makefile, - atheos/makefile, beos/makefile, cmsmvs/cczip.exec, cmsmvs/mvs.mki, - cmsmvs/zip.makefile, cmsmvs/zipmvsc.job, cmsmvs/zipvmc.exec, - human68k/makefile, human68k/makefile.gcc, novell/makefile, novell/zip.lnk, - os2/makefile.os2, qdos/makefile.qdos, qdos/makefile.qlzip, tandem/history, - tandem/macros, tandem/tandem.h, theos/makefile, tops20/make.mic, - unix/configure, unix/makefile, win32/makefile.a64 (Christian) -19. Add note to use BZ_NO_STDIO. bzip2/install.txt (Ed) -20. Remove crctab. cmsmvs/zipvmc.exec (Ed) -21. Update comment. macos/source/pathname.c (Christian) -22. Start of manual update. Zip.1 (Ed) -23. Changes to use crc32.c. vms/descrip.mms, vms/descrip_deps.mms, - vms/descrip_mkdeps.mms, vms/descrip_src.mms, vms/vms.c (SMS) ----------------------- January 17th 2007 version 3.0f26 ----------------------- - 1. Add note for UnZip. crypt.c (Christian) - 2. Change current_disk and disk_number from int to ulg. Change num from int - to unsigned int. [Even though a 16-bit system likely won't see more than - 64k disks, it probably should be ulg - Ed] Remove unused mbsize. Change - match from long to int as the number of possible options should always fit - in that. fileio.c, globals.c (Christian) - 3. Use -Gt to force some data into separate data segments so all data fits. - msdos/makefile.msc (Christian) - 4. Move some copyright constants to far to save near space. - revision.h (Christian) - 5. Change u for character from int to unsigned int. util.c (Christian) - 6. Move include of crc32.h from vms/vms.c to vms/vms_pk.c. vms/vms.c, - vms/vms_pk.c (Christian) - 7. Update crci386_.o. win32/makefile.gcc (Christian) - 8. Use NOASM=1 to disable assembler and clear variables when do not. - win32/makefile.w32 (Christian) - 9. Remove unused totalslashes and returnslashes from get_win32_utf8path(). - win32/win32zip.c (Christian) -10. Remove local versions of tempzip and tempzf. - zip.c (Christian) -11. Make options[] far. Change cd_start_disk from int to ulg. Cast -1 to - (ulg) for cd_start_disk. Put here = zftello() in DEBUG defines. - zip.h, zip.c (Christian) -12. Change length of zipfile comment parameter from ush to extent. Change - disk numbers from int to ulg in close_split(), ask_for_split_read_path(), - ask_for_split_write_path(), get_in_split_path(), find_in_split_path(), - get_out_split_path(). Add Far to longopt and name strings in - option_struct. zip.h (Christian) -13. Add far to options[]. zipcloak.c (Christian, Ed) -14. Define write_string_to_mem() only for UNICODE_SUPPORT. Change ulg to - extent for append to mem memory offset and blocksize parameters. Make - at_signature() local. Cast usValue to char. Remove unused oname in - read_Unicode_Path_local_entry(). Remove local definitions of zip64_entry - as Zip is always processing one entry at a time and this is a global - flag for the current entry. Make find_next_signature() and - find_signature() local. Add ZCONST to signature parameter. Make - is_signature() and at_signature() local. Change m, result of fread(), - from int to extent. Reduce SCAN_BUFSIZE from 0x40000 to the size of the - largest header being read. As find_next_signature() is used to scan for - the next signature and that reads a byte at a time, the scan buf is only - used to read in the found headers. Since we skip the extra parts of the - Zip64 EOCDR, all headers are a fixed size. Remove unused variables from - scanzipf_fixnew(). Use ENDCOM for end comment offset. Instead of 64 KB - seek back 128 KB to find EOCDR. Use ENDOFF and ENDTOT for offsets in - EOCDR. Remove tabs. Merge versions of putend(). Update Amiga SFX. - Remove unused offset in zipcopy(). Make size local in zipcopy(). - zipfile.c (Christian) -15. Update putend() comment. zipfile.c (Ed) -16. Add far to options[]. zipnote.c, zipsplit.c (Christian) -17. Add NO_ASM versions of Win32 zipnote, zipsplit, and zipcloak projects. - Add crc32.h and crc32.c to zipsplit and zipnote projects. - win32/vc6/zipsplit.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipcloak.dsp (Ed) -18. Add NO_ASM versions of Win32 bzip2 zipnote, zipsplit, and Zipcloak - projects. Add crc32.h and crc32.c. win32/vc6bz2/zipsplit.dsp, - win32/vc6bz2/zipnote.dsp, win32/vc6bz2/zipcloak.dsp (Ed) -19. Update Win32 dll and lib projects and make files. - windll/visualc/lib/zip32.dsp, windll/visualc/lib/zip32.mak, - windll/visualc/dll/zip32.dsp, windll/visualc/dll/zip32.mak (Ed) -20. Remove space in front of #ifdef and other conditionals that slipped in. - zipfile.c, zipup.c (SMS) -21. Updates for bzip2. vms/bzlib.h, vms/install_vms.txt (SMS) -22. Updates. vms/notes.txt (SMS) -23. Update copyrights. crc32.c, deflate.c, globals.c, revision.h, ziperr.h, - trees.c, win32/nt.c, win32/win32.c, win32/win32i64.c, win32/win32zip.h, - win32/zipup.h (Ed) -24. Update WhatsNew. WHATSNEW (Ed) ----------------------- February 4th 2007 version 3.0f27 ----------------------- - 1. Fix array sizes and loop lengths in wide_to_escape_string(). fileio.c - (Johnny, Ed) - 2. Fix escape_string_to_wide() to handle hex strings, then comment out as - not used. zip.h, fileio.c (Ed) - 3. Use ZIPERRORS() macro instead of ziperrors[] array. zip.c, zipcloak.c, - zipnote.c, zipsplit.c (SMS) - 4. Add VMS-compatible "severity" values, add new ZE_SEV_PERR define to - set when perror() needs to be called, add ZIPERRORS() macro, change - PERR() to use ZE_SEV_PERR, change ziperrors[] to new structure array - to hold error strings, add new VMS facility names and severity codes - assigned by HP to ziperrors[] array, and add new official - VMS_MSG_IDENT. ziperr.h (SMS) - 5. Change ZE_SEV defines to ZE_S to save space and reformat ziperrors[]. - ziperr.h (Ed) - 6. Update install.txt to include generic Unix case. bzip2/install.txt (Ed) - 7. Add creation of message file and add NOMSG message. vms/build_zip.com, - vms/descrip.mms, vms/install_vms.txt (SMS) - 8. Update notes.txt to add changes to program exit status values and changes - to messages. vms/notes.txt (SMS) - 9. Include crc32.h, include ssdef.h, instead of FAB_OR_NAM use FAB_OR_NAML, - add status code summary note detailing old versus new error codes, and if - CTL_FAC_IZ_ZIP is 0x7FFF and OLD_STATUS is defined use old VMS error codes. - vms/vms.c (SMS) -10. Change FAB_OR_NAM to FAB_OR_NAML and remove NAME_DNA, NAME_DNS, NAME_FNA, - and NAME_FNS. vms/vms.h (SMS) -11. Change FAB_OR_NAM to FAB_OR_NAML. vms/vms_im.c, vms/vms_pk.c, - vms/vmszip.c (SMS) -12. Fix compile warning on VC 2005. win32/makefile.w32 (Johnny) -13. Update readmevb.txt and readvb64.txt. windll/vb/readmevb.txt, - windll/vbz64/readvb64.txt (Ed) -14. Change tch from int to ulg in utf8_from_ucs4_char(). Move comments to keep - line lengths to 80 characters. fileio.c (Christian) -15. Update comment for total_cd_entries. global.c, zip.c, zip.h (Christian) -16. Comment out unused Adler-16 code. util.c, zip.h (Christian) -17. Add InterlockedExchangePointer() macro if not defined. Update Initialize() - to use macro. nt.c (Christian) -18. Move zip64 eocd disk and offset variables next to input archive variables. - zip.c (Ed) -19. Remove zipbegset from scanzipf_fixnew() as offsets are ignored when this - is fixing archives. Add comment to cd_total_entries. Remove local - cd_start_disk and cd_start_offset as these are already global. Use - ZIP_UWORD16_MAX when disk number exceeds this to flag use of Zip64. - zipfile.c (Christian) -20. Some comment changes. zipfile.c (Ed) -21. Fix indentation in places. zipsplit.c (Christian) -22. Remove unused variable zfile. zipup.c (Christian) -23. Update manual. zip.1, zip.txt, zipsplit.txt (Ed) ----------------------- February 22nd 2007 version 3.0f28 ---------------------- - 1. Update notes. vms/notes.txt (SMS) - 2. Add stream_lf.fdl to specify carriage control. vms/stream_lf.fdl (SMS) - 3. Update License to also refer to www.info-zip.org and to hopefully provide - an example of misrepresentative use. LICENSE (Ed) - 4. Update Readme. README (Ed) - 5. Update WhatsNew. WHATSNEW (Ed) - 6. Change output archive cd_start_disk and cd_start_offset to input archive - local in_cd_start_disk and in_cd_start_offset in scanzipf_fixnew() and - scanzipf_regnew() to avoid mixing in and out. zipfile.c (Ed) - 7. Update copyright. Remove crc32.h include. vms/vms.c (Christian) - 8. Changes for new crc32. Remove CRC32. Add CRCA_0 and CRCAUO. Add - compiling of crc_i386.S. win32/makefile.emx. (Christian) - 9. Add handlers for better RSXNT and Windows OEM conversions. Add detailed - comments on conversions. win32/osdef.h (Christian) -10. Define CP_UTF8. win32/rsxntwin.h (Christian) -11. Define WIN32_LEAN_AND_MEAN to reduce size of Windows includes. - win32/win32.c, win32/win32zip.c, zip.c (Christian) -12. Use only standard FAT attributes if OEM. win32/win32zip.c (Christian) -13. Add use of INTERN_TO_OEM() and related OEM changes. Add console comment. - zip.c (Christian) -14. Change severity from char to int. Update macros. ziperror.h. (Christian) -15. Update Visual Basic project to clarify some of the code. - windll/vbz64/vbzip.vbp, windll/vbz64/vbzipbas.bas, - windll/vbz64/vbzipfrm.frm (Ed) -16. Update copyright. api.c (Ed) -17. Update format for duplicate entry warning. fileio.c (Ed) -18. Instead of ifdef __RSXNT__ use ifdef WIN32. Define WIN32_LEAN_AND_MEAN. - Use WIN32_CRT_OEM. Change OEM check from vem == 20 to vem & 0xff00 == 0 - and instead of local_to_oem_string() use _INTERN_OEM(). Remove unused - first_CD in scanzipf_fixnew(). Instead of oem_to_local_string() use - Ext_ASCII_TO_Native(). Instead of local_to_oem_string() use - INTERN_TO_OEM(). zipfile.c (Christian) -19. Replace escape from zipsplit man page with '. zipsplit.txt (Christian) -20. Instead of using 20 every time, account for dosify when setting vem. - Update FAT comment. zipup.c (Christian) ------------------------- March 3rd 2007 version 3.0f29 ------------------------- - 1. Remove crctab.c. vms/build_zip.com (SMS) - 2. Add LFLAGS_ARCH. vms/descrip.mms (SMS) - 3. Remove redundant includes descrip.h, rms.h, and atrdef.h. - vms/vmsmunch.c (SMS) - 4. Remove includes descrip.h and rms.h. vms/vmszip.c (SMS) - 5. Only define NO_UNISTD_H if __VAX defined or __CRTL_VER is - less than 70301000, allowing support of the new symbolic - links in VMS. Also use unlink instead of delete if version - above 70000000. vms/osdep.h (SMS) - 6. Formatting changes. vms/notes.txt, vms/install_vms.txt (Christian) - 7. Remove spaces before tabs. win32/makefile.emx (Christian) - 8. Formatting change. win32/osdep.h (Christian) - 9. If -y on VMS open the link not the target file. vms/vms_im.c (SMS) -10. If -y on VMS search for the link, not the target file. vms/vms_pk.c (SMS) -11. Change default for Unicode path mismatch from error to warning, so - processing will continue. zip.c, globals.c (Ed) ------------------------- March 12th 2007 version 3.0f30 ------------------------ - 1. Add bzip2 support for the reduced no stdio bzip2 library for VMS and Unix. - Use libbz2_ns_.olb for VMS bzip2 library which is compiled from the VMS - version of bzip2 with the BZ_NO_STDIO flag set. This flag removes most - standard bzip2 stdio support and enables using a callback routine for - errors. zbz2err.c, unix/Makefile, vms/build_zip.com, vms/descrip.mms, - vms/descrip_deps.mms, vms/descrip_src.mms (SMS) - 2. Add zbz2err.c to Win32 vc6bz2 project for support of BZ_NO_STDIO for bzip2. - Modify zbz2err.c to handle different ports. zbz2err.c (Ed) - 3. Update license. zip.h (Ed) - 4. Update copyright. zip.c, zipfile.c, zipup.c, zbz2err.c, revision.h (Ed) - 5. Fix bug where directories got set to ver 4.6 in local headers instead of - ver 1.0 when using bzip2. zipfile.c, zipup.c (Ed) - 6. Minor updates to INSTALL. INSTALL (Ed) - 7. Minor updates to README. README (Ed) - 8. Add BZ_NO_STDIO to vc6bz2 projects. Error routine seems to work. - win32/vc6bz2 (Ed) - 9. Set bit FAB$M_BIO (.fab$v_bio) in the FAB when using sys$open() on a - symlink. vms/vms_im.c (SMS) -10. Change sys$disk to SYS$DISK. vms/build_zip.com (SMS) -11. Update extended help. zip.c (Ed) -12. Update bzip2 install. bzip2/install.txt (Ed) ------------------------- March 19th 2007 version 3.0f31 ------------------------ - 1. Define bz2_olb as LIBBZ2_NS.OLB. Change LIBBZ2.OLB to bz2_olb. Use - ZZBZ2ERR.C error callback for bzip2. vms/build_zip.com (SMS) - 2. Change NO_SYMLINK to NO_SYMLINKS to be consistent with UnZip. tailor.h, - acorn/osdep.h, macos/osdep.h, tops20/osdep.h, vms/osdep.h (SMS) - 3. Minor note changes. Add section on Symbolic Links. vms/notes.txt (SMS) - 4. Update copyright. globals.c (Ed) - 5. Update License with official copy. LICENSE (Greg, Ed) - 6. Update Readme. README (Ed) - 7. Add support for NO_BZIP2_SUPPORT. tailor.h (Ed) - 8. Add common compiler flags to Install. INSTALL (Ed) - 9. Remove SPLIT_FILE define. zip.c (Ed) -10. Minor updates to extended help. zip.c (Ed) -11. Modify Makefile to also build bzip2 library if found. Split $MAKE - ("make -f unix/Makefile") into $MAKE and $MAKEF, leaving $MAKE as defined by - Make and defining $MAKEF to "-f unix/Makefile". Add clean_bzip2 target. - unix/Makefile (SMS) -12. Modify configure to handle compiling bzip2. unix/configure (SMS) -13. Remove linking bzip2 with utilities. Other changes. unix/Makefile (Ed) -14. Change bzip2 wrong library errors to warnings. Put back OS bzip2 library - check. Only compile bzip2 if in bzip2 directory. unix/configure (Ed) -15. More modifications to Makefile and configure to only allow compiling in - the bzip2 directory. unix/Makefile, unix/configure (Ed) ------------------------- March 27th 2007 version 3.0f32 ------------------------ - 1. Modify configure and Makefile to only allow compiling bzip2 in the Zip bzip2 - source directory. unix/Makefile, unix/configure (SMS, Ed) - 2. Update bzip2 installation instructions. bzip2/install.txt (SMS, Ed) - 3. Remove need for BZIP2_USEBZIP2DIR define by using an appropiate include dir - specification (-I ../../bzip2) when needed. zip.c, win32/vc6bz2/zip.dsp, - unix/configure (SMS, Ed, Christian) - 4. Update VC6 readme. win32/readmeVC.txt (Christian, Ed) - 5. Add crc32.h to VC projects. Add assembler group to zipcloak, zipnote, and - zipsplit projects. Add BZ_NO_STDIO to all configurations with bzip2 so - reduced bzip2 code is used. win32/vc6/zip.dsp, win32/vc6/zipcloak.dsp, - win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp (Christian) - 6. Update VC6bz2 readme. win32/readVCBZ.txt (Christian, Ed) - 7. Modify bzip2 VC6 workspace to use standard zipcloak, zipnote, and zipsplit - projects as they don't need bzip2. win32/vc6bz2/zip.dsw (Christian) - 8. Fix zlib flag problem by properly setting and clearing deflInit flag to - initialize and release resources. zipup.c (Bill Brinzer, Christian) - 9. Update copyright. crypt.h, api.c, tailor.h, fileio.c, ziperr.h, - zipsplit.c, zipnote.c, zipcloak.c, util.c (Ed) ------------------------- April 25th 2007 version 3.0f33 ------------------------ - 1. Fix -dd display_dots option for VMS. Fix adding value for -ds to command - line. Fix /NAMES = AS_IS for older header files. cmdline.c (SMS) - 2. Add Win32 wide scan support. In fileio.c add Win32 wide functions lastw(), - msnamew(), newnamew(), wchar_to_wide_string(), is_ascii_stringw(), - wchar_to_local_string(), and wchar_to_utf8_string(). In globals.c - add no_win32_wide that is true if the wide versions of calls like - GetFileAttributesW() do not work as on Win9x without the Unicode kit. - In tailor.h define zwstat for stats that use wchar_t strings and - defines SSTATW and LSSTATW. In util.c add isshexpw() and recmatchw() - and dosmatchw() for matching using wchar_t strings. In win32.c add - FSusesLocalTimeW(), IsFileSystemOldFATW(), GetFileModeW(), GetLongPathEAW(), - and zstat_zipwin32w(). In win32zip.c add zdirscanw structure, - GetDirAttribsW(), zDIRSCANW, readdw(), wild_recursew(), procname_win32w(), - OpenDirScanW(), GetNextDirEntryW(), CloseDirScanW(), procnamew(), - local_to_wchar_string(), wchar_to_utf8_string(), in wild() code to - check if W versions are supported and send zip down byte or wide path, - ex2inw(), in2exw(), and filetimew(). In zipup.h define zwopen to use - wide paths. In zipup.c if supported use filetimew() and zwopen(). - In zip.h add namew, inamew, and znamew to zlist and flist. In zip.c - remove duplicate initialization of use_wide_to_mb_default, force_zip64, - zip64_entry, and zip64_archive. Use filetimew() if UNICODE_SUPPORT and - using wide paths for directory scan. Remove old 8.3 path Unicode fix as - now use wide paths and get all where the 8.3 kluge missed paths where - characters in path needed multiple code pages. Changes to bit 11 Unicode - but still not ready. fileio.c, globals.c, tailor.h, util.c, zipup.h, - win32/win32.c, win32/win32zip.c, win32/win32.h, zipup.c, zip.c (Ed) - 3. Update copyright. Don't define UNICODE_SUPPORT if already defined. - Define MATCHW and zstat_zipwin32w(). win32/osdep.h (Ed) ------------------------- April 29th 2007 version 3.0f34 ------------------------ - 1. Add temporary option -sC to test Unicode file creation enabled with - UNICODE_TEST define. zip.c, fileio.c (Ed) - 2. On Unix display control characters as ^X as UnZip. (SMS) fileio.c - 3. Update extended help. zip.c (Ed) - 4. Fix bugs in Unicode changes. zip.c, fileio.c (SMS, Ed) - 5. Add NAMES AS_IS support. Handle root dir [000000]. zip.h, - vms/install_vms.txt, vms/vmszip.c, vms/vmsmunch.c (SMS) - 6. Add global zipfile_exists to handle missing zipfile errors better. zip.h, - globals.c, zip.c (Ed) - 7. Add functions utf8_to_escape_string(), wide_to_escape_string(), - local_to_escape_string(), utf8_to_wchar_string(), and - rename wide_to_escape_string() to wide_char_to_escape_string(). fileio.c, - win32/win32zip.c, zip.h (Ed) - 9. Free f->inamew in fexpel(). Use zuname for matching. fileio.c (Ed) -10. Fix memory bug by setting z->namew, z->inamew, and z->znamew to NULL. - Set f->namew, f->inamew, and f->znamew to NULL for new file in newname(). - Free wide_string in local_to_utf8(). Other Unicode fixes. Add namew, - inamew, and znamew to freeup(). fileio.c, win32/win32zip.c, zip.h (Ed) -11. Move wchar functions only used by Windows to win32zip.c. fileio.c, - zip.h (Ed) -12. Fix spelling in manual. zip.1 (SMS, Ed) -13. Add zuebcmp() for Unicode. zipfile.c -14. Open files to read using wide name as input path. zipup.c (Ed) -15. Update help. zip.c (Ed) -16. Change -TT long option from --unzip-path to --unzip-command. zip.c (Ed) -17. Update Manual to include section on Unicode, add -TT option, make some - changes to Unicode in other sections, update copyright at bottom, and - some small changes to wording and examples. man/zip.1, zip.txt (Ed) -18. Put #ifdef WIN32 around WIN32 blocks. zipfile.c (Ed) -------------------------- May 14th 2007 version 3.0f35 ------------------------- - 1. Update VMS to include new options. vms/cmdline.c, vms/zip_cli.cld (SMS) - 2. Update VMS help. vms/vms_zip.rnh (SMS) - 3. Minor updates to VMS help. vms/vms_zip.rnh (Ed) - 4. Create global filter_match_case that defaults to 1 (case-sensitive). zip.c - zip.h, globals.c (Ed) - 5. Add option -fc to fold case for case-insensitive matching in filter(). - Currently enabled only for WIN32. zip.c, win32/osdep.h (Ed) - 6. Change (action == DELETE || action == FRESHEN) to filter_match_case in - PROCNAME() define. I just couldn't figure out what was going on here and - why the case flag was controlled by this. zip.c (Ed) - 7. Update WhatsNew. WHATSNEW (Ed) -------------------------- May 17th 2007 version 3.0f36 ------------------------- - 1. Touch date on generated file. vms/ZIP_MSG.MSG (SMS, Ed) - 2. Update Betas readme to include Release Candidates. Betas_Readme.txt (Ed) - 3. Update Zip 3.0f announcement. zip30f.ann (Ed) - 4. Minor updates to VMS help. vms/cvthelp.tpu, vms/vms_zip.rnh (SMS) - 5. Major changes to VMS CLI help. vms/zip_cli.help (SMS, Ed) - 6. Update license. revision.h (Ed) -------------------------- May 21st 2007 version 3.0f37 ------------------------- - 1. Rename -fc (fold case) to -ic (ignore case) which may be more intuitive. - zip.c (Ed) - 2. VMS CLI updates for new options. vms/cmdline.c, vms/vms_zip.rnh, - vms/zip_cli.cld, vms/zip_cli.help (SMS) - 3. Updates to support Watcom C, mingw, djgppv2 and msc-16-bit, including - supporting wide stat and compare calls and work-around for problem with - "no symlink support" detection. tailor.h, util.c, zip.c, win32/osdep.h, - win32/win32.c, win32/win32/zipup.h (Christian) -------------------------- May 29th 2007 version 3.0f38 ------------------------- - 1. Update description. file_id.diz (Ed) - 2. Handle better when not splitting and run out of disk space. Also, for split - method 1 (automatically write all splits to same place) exit if run out of - space instead of filling available space with near empty splits. For split - method 2 require splits to be at least 64K bytes (the minimum split size). - fileio.c (Ed) - 3. Add line break in ziperr() if message line has been started. zip.c (Ed) - 4. In ziperr() don't close output handle y if same as current_local_file handle - and just closed that. zip.c (Ed) - 5. Change default definition of PROCNAME() to handle new filter_match_case flag - and restore backward compatibility. zip.c (Christian, Ed) - 6. Add note detailing definition of PROCNAME(). zip.c (Ed) - 7. Remove nonlocalpath parameter from procname_win32() and procname_win32w() - and variables nonlocal_path and nonlocal_name as this is not used now that - unicode is implemented in WIN32 using the wide calls. - 8. Enable ignore case option for VMS. zip.c (SMS) - 9. Update -v and other updates in manual. man/zip.1 (Christian, Ed) -10. Updates for Watcom C and Win32 symlinks. win32/osdep.h (Christian) -11. Fix historic problem with VAX seeking. zipfile.c (SMS) -12. Add NAM_M_EXP_DEV. Add determination if device is in file specification. - If device name in file specification do ODS2 and ODS5 down-casing. - Define explicite_dev(). vms/vms.h, vms/vmszip.c (SMS) -------------------------- June 4th 2007 version 3.0f39 ------------------------- - 1. Update osdep.h to use new filter_match_case flag. vms/osdep.h (SMS) - 2. Fix unterminated string bug and trim extra allocated space in - local_to_display_string(). fileio.c (Ed) - 3. Updated extended help for -u and -ic options. zip.c (Ed) - 4. Update Manual. man/zip.1, zip.txt (Ed) -------------------------- June 15th 2007 version 3.0f40 ------------------------- - 1. Update Unicode Path and Unicode Comment descriptions based on suggestions - from WinZip. proginfo/extrafld.txt (Steve Gross, Ed) - 2. Update descriptions for Add, Update, and Freshen in the manual. man/zip.1 - (Christian) - 3. Update default definition of PROCNAME() to use filter_case_match flag to - turn off case matching in filter(). zip.c (Christian) - 4. Update WhatsNew. WHATSNEW (Ed) - 5. Update announcement. zip30f.ann (Ed) - 6. Update manual. man/zip.1, zip.txt (Ed) -------------------------- July 7th 2007 version 3.0f41 ------------------------- - 1. Use File Name as Unicode path if UTF-8 flag is set in header. zip.c, - globals.c, zipfile.c, zip.h (Ed) - 2. Update ToDo. TODO (Ed) - 3. Update WhatsNew. WHATSNEW (Ed) - 4. Update ReadMe. README (Ed) - 5. Fix problems with incompatible stat types on Win32. fileio.c, tailor.h, - zip.h, win32/win32.c, win32/win32zip.c, win32/osdep.h (Ed) - 6. Define NO_STREAMING_STORE to turn off storing while streaming. - INSTALL, zipup.c (Ed) - 7. Define UNICODE_ALLOW_FORCE to enable -UN=force option which is now - disabled and would need work. globals.c, zip.h (Ed) - 8. Add global using_utf8 to flag when OS current character set is UTF-8. - If an existing entry has the UTF-8 flag set the flag is kept. If a new - entry needs Unicode and on a UTF-8 system assume the strings are UTF-8 - and set the UTF-8 flag. globals.c, zip.h (Ed) - 9. Update Unicode extra field descriptions. proginfo/extrafld.txt (Ed) -10. Add include directory so can find bzip2 header file when using bzip2 - directory. unix/configure (Ed) -11. Fix wide character wild(), wild_recursew() and OpenDirScanW() for Win32 so - work like the regular versions. win32/win32zip.c (Ed) -12. Update Unicode in manual. Update -W description in manual zip.1 -13. Flush logfile writing. zip.c (Ed) -14. Update extended help for -UN option. Update help for Update to note it - updates files where the OS has a later date. Chance -UN=Exit to -UN=Quit - so can abbreviate to first letter. zip.c (Ed) -15. Fix a bug in readzipfile() when zip used in pipe. Other pipe fixes. zip.c, - zipfile.c (Ed) ------------------------- August 10th 2007 version 3.0f42 ----------------------- - 1. Update error message for -DF. zip.c (Ed) - 2. Add bzipped message to write to log file. zipup.c (Ed) - 3. Update bzip2 install instructions. bzip2/install.txt (Ed) - 4. Move local.h include to tailor.h to fix compiler multiple define. tailor.h, - zip.c (SMS) - 5. Add additional C compiler checks for GNU and HP. unix/configure (SMS) - 6. Fix to build libbz2.a. unix/Makefile (SMS) - 7. Update copyright. acorn/osdep.h, macos/osdep.h, tops20/osdep.h, - vms/vmszip.c, vms/vmsmunch.c, vms/vms_pk.c, vms/vms_im.c, vms/vms.h, - vms/vms.c, vms/osdep.h, win32/rsxntwin.h, win32/osdep.h, win32/nt.c (Ed) - 8. Change zfeeko(file, 0, SEEK_SET) to rewind(file) in ffile_size() so - EOF is always reset. This was creating problems in WIN32 when - NO_ZIP64_SUPPORT was set but LARGE_FILE_SUPPORT was set. zipfile.c (Ed) - 9. Update compile -v descriptions for LARGE_FILE_SUPPORT and ZIP64_SUPPORT to - be more specific as to what each does. zip.c (Ed) -10. Fix bug that added the local header size to the next entry compressed size - giving a wrong compressed size error if splitting and the split occurs when - writing a local header. fileio.c (Ed) -11. Remove UNICODE_TEST define from VC 6 projects. win32/vc6/zip.dsp, - win32/vc6/zipcloak.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp (Ed) -12. Update extended help. zip.c (Ed) -13. Only output -FF central directory messages in verbose mode. zipfile.c (Ed) -14. Add note about possible bug when copying entries from a split archive. - WHATSNEW (Ed) ------------------------- August 11th 2007 version 3.0f43 ----------------------- - 1. Display locale inside check to avoid NULL locale. zip.c (SMS, Ed) - 2. Add include wchar.h to tailor.h. tailor.h (SMS) ------------------------- August 21st 2007 version 3.0f44 ----------------------- - 1. Remove verbose messages when setting locale as verbose flag is not set yet. - zip.c (SMS, Ed) - 2. Change reading splits message "abort archive" to "abort archive - quit" and - change selection letter from a to q so q quits consistently. For quit, - don't confirm as more annoying than helpful. fileio.c (Ed) - 3. In bfwrite() handle case where a split ends at the end of one entry and - trying to write the next local header forces opening next split. This - caused copying entries from one archive to another to fail if this came up. - Also handle case where a new split is needed while writing central directory - entries. Now close last split and update pointers to point to the new - split. fileio.c (Ed) - 4. Update use of mesg_line_started and add new logfile_line_started to account - for line ends in logfile. fflush() output. zip.c, zip.h, globals.c (Ed) - 5. Move setting split size if input archive is split and split_size not set - to after archive is read. zipfile.c, zip.c (Ed) - 6. Update Manual to describe Unicode as implemented and note that old splits - are not automatically excluded. man/zip.1, zip.txt (Ed) - 7. Update WhatsNew to remove note that creating and copying split archives - is broke as it seems fully working now. WHATSNEW (Ed) - 8. Update announcement. zip30f.ann (Ed) ------------------------- August 31st 2007 version 3.0f45 ----------------------- - 1. Unicode fix for VMS. tailor.h (SMS) - 2. Add member current to zlist structure to flag when an archive entry is - current with the matching OS file using file time and size. This is used by - File Sync to copy current entries from archive. zip.h, zip.c (Ed) - 3. Comment out zip info verbose extra data message as this message does not - seem to add much. zipfile.c (Ed) - 4. Add local and central directory Version Needed To Extract to mismatch - warning. Update warning text. zipfile.c (Ed) - 5. Add function BlankRunningStats() to output blanks for the running stats - part of the line to use when displaying stats for entries not on the mark - list so all output lines up. zip.c - 6. Add -FS to extended help as new mode. zip.c (Ed) - 7. Update description of -FF to remove Assume Worst. zip.c (Ed) - 8. Add all_current flag that is set if all entries in archive are current and - skip updating archive if -FS and all entries are current. zip.c (Ed) - 9. Change argv[] to args[] for "try: zip" error message as message depends on - new argument order in args where options are now at beginning. zip.c (Ed) -10. For File Sync, copy entries to new archive if file time and size are the - same. If verbose, output ok when copying current entries, otherwise no - message when current_entry. Set all_current to 0 if an entry not marked or - a file not on OS as need to avoid the All Current message in these cases to - catch only deletions. zip.c (Ed) -11. Initialize variables excluding zipstate and setjmp() if USE_ZIPMAIN defined - to fix bug when recall zipmain(). zip.c (Ed) -12. Update Manual. zip.1, zip.txt (Ed) -13. Update WhatsNew. WHATSNEW (Ed) -14. Update announcement. zip30f.ann (Ed) ------------------------ September 5th 2007 version 3.0f46 ---------------------- - 1. Move write of local header after when GPB11 UTF-8 bit set in putlocal(). - zipfile.c (Ed) - 2. Change to uppercase for compatibility. vms/install_vms.txt (SMS) - 3. Set cenbeg and bytes_this_split to fix grow. Check if grow split archive. - zipfile.c, zip.c (Ed) ------------------------ September 14th 2007 version 3.0f47 -------------------- - 1. Include address for new Info-ZIP forum. Add note on 16-bit OS support. - Add note about text file line ends. README (Ed) - 2. Update WhatsNew to include latest on Unicode. Add section on plans for - Zip 3.1. WHATSNEW (Ed) - 3. Minor change in note for Unicode in extended help. zip.c (Ed) - 4. Modify definitions of Unicode extra fields based on discussions with PKWare - and WinZip. proginfo/extrafld.txt (Ed) - 5. Add note on UTF-8 flag. INSTALL (Ed) - 6. Minor updates to ToDo list. Needs more work. TODO (Ed) - 7. Update announcement. zip30f.ann (Ed) - 8. Change definition of IZ_OUR_BZIP2_DIR to be compatible with Configure and - to work with HP-UX. unix/Makefile (SMS) ------------------------- September 24th 2007 version 3.0f --------------------- - 1. Update extended help Unicode description. zip.c (Ed) - 2. Update Readme. README (Ed) - 3. Fix case of define identifying IA64. vms/vms.c (SMS) - 4. Update announcement date. zip30f.ann (Ed) - 5. Update Unicode extra field definitions based on changes proposed for - AppNote. extrafld.txt (Ed) ------------------------- October 17th 2007 version 3.0g01 --------------------- - 1. Can get stuck on open Unix FIFO so default to skip and add option -FI to - enable reading FIFO. Add global allow_fifo. zip.c, zip.h, globals.c - (Willus 0, Ed) - 2. As problems with MinGW with wide-character paths, disable wide-character - Unicode support. zip.c, unix/unix.c (Willus 0, Ed) - 3. Update manual installs to include zipcloak.1, zipnote.1, and zipsplit.1 - pages. unix/Makefile (Ed) - 4. Update Solaris packages. unix/Packaging/pkginfo.in, - unix/Packaging/postinstall, unix/Packaging/preinstall.in, - unix/Packaging/prototype (SMS) ------------------------- October 30th 2007 version 3.0g02 --------------------- - 1. Fix bug in get_in_split_path() where look for .zip split when attempting - to open archives without a .zip extension, even when a single file archive - like jar file. fileio.c (Gabriele (balducci@units.it), Ed) - 2. Fix bug where temp file got created in current working directory on Unix - by giving entire archive path to mkstemp() as template. fileio.c, zip.c - (Willus, Ed) - 3. Use 64-bit output functions for bits_sent. trees.c (SMS) - 4. Add -FF to fixfix -sd messages to make different from identical main - messages. zip.c (SMS, Ed) - 5. If quiet do not ask for splits and all splits must be in same location. - zipfile.c (Ed) - 6. Clean up making zip manuals. unix/Makefile (Ed, SMS) - 7. Add clean_exe to make. unix/Makefile (SMS) - 8. Update to VMS Notes, including adding details on symlinks, -V, and UTC - dates times. vms/notes.txt (SMS) - 9. Fix bug in wild() when calling wile_recursew() where qw should be - pointing inside pw. win32/win32zip.c (Willus, Ed) -10. Fix bug where is_ascii_string() fails when passed a NULL string. This - may fix problem where the CentOS mbstowcs() function is returning -1 when - trying to convert a file name with a bad character (0xe6), causing - local_to_wide_string() and then local_to_utf8_string() to return NULL, so - f->uname gets NULL and so is_ascii_string() fails with SIGSEGV. fileio.c - (Willus, Ed) ------------------------- October 31st 2007 version 3.0g03 --------------------- - 1. Add handling of -b temp directory when opening splits in bfwrite() using - mkstemp(). fileio.c (SMS, Ed) ------------------------- November 3rd 2007 version 3.0g04 --------------------- - 1. Move show_files to global so can avoid split warning for -sf. zip.c, - globals.c, zip.h, zipfile.c (Ed) - 2. Account for -b tempath when opening temp file. zip.c, zipnote.c, - zipcloak.c (SMS, Ed) ------------------------- November 4th 2007 version 3.0g05 --------------------- - 1. Minor fixes to fdopen calls. zipcloak.c, zipnote.c (SMS, Ed) ------------------------- November 4th 2007 version 3.0g06 --------------------- - 1. Add negation to -db, -dc, -dd, -dg, -du, -dv display options. zip.c (Ed) - 2. Put back UNICODE_SUPPORT no_win32_wide code left out in previous fix. - win32/win32zip.c (Willus, Ed) ------------------------- November 21st 2007 version 3.0g07 --------------------- - 1. Fix bug preventing newline in some cases in zipmessage(). zip.c (Ed) - 2. Update Unicode help. zip.c (Ed) - 3. Update -sd messages. zip.c (Ed) - 4. Add filetimew() for Unicode case. zip.c (Ed) - 5. Add ClearArchiveBitW() for Win32 wide. zip.c, zip.h, win32/win32.c (Ed) - 6. Only ask for .zip split if path ends in .znn or .znnn where n 0 to 9. This - allows -FF to work on .exe sfx files without adding .zip. zipfile.c (Ed) - 7. Fix bug where only backed up 20 bytes to find Z64 EOCD Locator. Now back - up 24 bytes to include size of Z64 EOCD Locator signature. This prevented - reading and updating archives greater than 4 GB. zipfile.c (Ed) - 8. If -FF on Win32 initialize wide strings namew, inamew, and znamew to NULL. - zipfile.c (Ed) - 9. Add #include to support towupper(). tailor.h (SMS) ------------------------- December 4th 2007 version 3.0g08 --------------------- - 1. Update dot_size comment. globals.c (Ed) - 2. Update Compression in extended help. zip.c (Ed) - 3. Add extended help on self extractor -A and -J. zip.c (Ed) - 4. Update VMS SYMLINK version information. zip.c (SMS) - 5. Remove not final from Unicode version information as final now. zip.c (Ed) - 6. Remove apparently not needed WINDLL variable retcode. zip.c (Ed) - 7. Fix -A to calculate sfx offset and adjust offsets as it should. zip.c (Ed) - 8. Split -F and -FF used with -A warning to separate warnings. zip.c (Ed) - 9. Add adjusting to can't to that to split archive error. zip.c (Ed) -10. Fix bug for -A that tries to open split by asking for disk 0 instead of - disk 1. Add adjust_offset and cd_total_size variables. Calculate - sfx offset by determining offset of start of central directory. Archives - larger than 4 GB are not supported as sfx archives but these don't seem - to work anyway. Add adjust_offset to Zip64 EOCDR offset and central - directory offsets. zip.c, zipfile.c (Ed) -11. Comment out here debug variable in find_next_signature(). zipfile.c (Ed) -12. Change %2x to %02x as format for parts of a signature in error messages. - zipfile.c (SMS) -13. Add warning adjusting split archives not yet supported. zipfile.c (Ed) -14. Add period to central directory comment. zipfile.c (Ed) -15. Update readme for vb Zip64 project. windll/vbz64/readvb64.txt (Ed) -16. Update comments of VB for Zip64 example. Add SplitSize to VB Zip64 - example. windll/vbz64/vbzipbas.bas, windll/vbz64/vbzipfrm.frm (Ed) -17. Add SourceForge to comment noting where can get the source code. - windll/vbz64/vbzipfrm.frm (Ed) -18. Update WhatsNew. WHATSNEW (Ed) ------------------------- December 12th 2007 version 3.0g09 -------------------- - 1. A few minor changes to extended help. zip.c (Ed) - 2. Uppercase beginning of most -sd messages. zip.c (Ed) - 3. Add spaces between options in some error messages. zip.c (Ed) - 4. Update comments in scanzipf_regnew(). zipfile.c (Ed) - 5. Update scanzipf_regnew() to figure out sfx offset. (Ed) - 6. Uppercase VMS RUNOFF file as apparently needed. VMS_ZIP.RNH (SMS) - 7. Add comments to zipmessage(). zip.c (Ed) - 8. Update extended help and option descriptions. zip.c (Ed) ------------------------- December 20th 2007 version 3.0g10 -------------------- - 1. Fix -F to include -A adjustment check. zipfile.c (Ed) - 2. Change -FF message when find EOCDR. zipfile.c (Ed) - 3. For -FF, reset first CD entry flag in_central_directory when a local entry - is found after CD entries so that another CD entry forces sorting of all - local entries to that point. This allows files with multiple archives in - them to be processed. zipfile.c (Ed) - 4. Add message when a local entry is found after a central directory. - zipfile.c (Ed) - 5. Remove word offset from disk offset location messages. zipfile.c (Ed) - 6. Make Adjust offset message more descriptive. zipfile.c (SMS, Ed) - 7. In scanzipf_regnew(), if adjustment to offsets, add it to - in_cd_start_offset. zipfile.c (Ed) - 8. Allocate cextra only if localz->ext not 0 in zipcopy(). zipfile.c (Ed) ------------------------- December 28th 2007 version 3.0g11 -------------------- - 1. Include definitions of zip64_eocdr_start and z64eocdl_offset in - ZIP64_SUPPORT ifdef block. Add comments for End Of CD Record (EOCDR). - Update comments for adjust offset detection. zipfile.c (Ed) - 2. Change ((uzoff_t)1 << 32) to 0xFFFFFFFF. zipfile.c (SMS, Ed) - 3. Leave off local header detection as not useful when searching for start - of central directory to get adjust offset. Looks like all expected cases - are now covered as long as archive is intact. zipfile.c (Ed) - 4. Update some warning messages. Simplify adjust offset information message. - zipfile.c (Ed) - 5. Add braces to unicode_mismatch if block. zipfile.c (Christian) - 6. Add (void *) cast in InterlockedExchangePointer() mutex calls to fix - compile warnings in MinGW (GCC 3.4.4). win32/nt.c (Christian) - 7. Remove unused nonlocalpath variable. win32/win32zip.c (Christian) - 8. Update betas readme file. betas_readme.txt (Ed) - 9. Partial update to Who list of contributors. proginfo/infozip.who (Ed) -10. Update ReadMe. Create Announcement. README, zip30g.ann (Ed) -11. Update WhatsNew. WHATSNEW (Ed) ------------------------- January 7th 2008 version 3.0g12 -------------------- - 1. Convert Scanning files message to use standard zipmessage_nl() so line - ends are generated when needed. fileio.c (Ed) - 2. Add line ends in DisplayRunningStats() if a display line has been - started. zip.c (Ed) - 3. For the command line listed at the top of the log file, add double - quotes around any arguments that have spaces in them. - zip.c (Ed) - 4. Instead of stdout use standard mesg output stream for show files. - Output new line for show files for display and log file if there was - output on the current line. zip.c (Ed) - 5. Comment out new line output code after zipup() and replace with - call to zipmessage_nl("", 1) to output new line if needed. - zip.c (Ed) - 6. In GetFileMode() and GetFileModeW() when get attributes fails - instead of fprintf(mesg, ...) use zipwarn() so error goes in - log file and new lines are displayed when needed. win32/win32.c (Ed) - 7. In GetSD(), change cbytes from long to ulg. Check cbytes (the - compressed size of the security descriptor) and issue warning if - the compressed security descriptor is greater than 0x7FFF (32k) - as the entire header this extra field is in needs to fit in the - 64k header. Should be a check on the running size of the header - so the actual space remaining is tracked. Maybe in Zip 3.1. If - cbytes OK cast to ush and store. win32/win32zip.c (Ed) - 8. Use zipmessage_nl() for bytes security message so new lines are - handled and message goes in log file. win32/win32zip.c (Ed) - 9. Add new option -RE to enable [list] (regex) matching in DOS and - WIN32 but disable [list] matching otherwise. Default behavior - is restored if ALLOW_REGEX is defined. globals.c, util.c, - zip.h, zip.c (Ed) ------------------------- January 20th 2008 version 3.0g13 -------------------- - 1. Update copyrights to 2008. zip.c, zipcloak.c, zipfile.c, zipnote.c, - zipsplit.c, zipup.c, README (Ed) - 2. Update Who. proginfo/infozip.who (Ed) ------------------------- January 30th 2008 version 3.0g14 -------------------- - 1. Update copyrights. fileio.c, globals.c, revision.h, util.c, zip.h, - win32/win32.c, win32/win32zip.c (Ed) - 2. Updates. README, proginfo/infozip.who (Ed) - 3. Update announcement and WhatsNew. zip30g.ann, WHATSNEW (Ed) - 4. Add ALLOW_REGEX to INSTALL define list. INSTALL (Ed) - 5. Change -sd message. zip.c (Ed) - 6. For bzip2 check for binary and set binary/text flag. Handle -l and -ll - line end conversions for bzip2. zipup.c (Ed) ------------------------- February 3rd 2008 version 3.0g -------------------- - 1. Change && to || to fix logic bug in show files. zip.c (Johnny) - 2. Add CLEAN and CLEAN_ALL VMS targets. vms/descrip_mkdeps.mms (SMS) ------------------------ February 22nd 2008 version 3.0h01 -------------------- - 1. Update some echo statements to use CFLAGS_OPT. Add GNUC check. - unix/configure (SMS) - 2. Only store UID and GID if 16 bit. unix/unix.c (Ed) ------------------------ March 21st 2008 version 3.0h02 -------------------- - 1. Change long Unicode escapes from 8 characters to 6 characters based on - change in UnZip 6.0. fileio.c (Ed) - 2. Put zuebcmp() declaration in #if 0 block as definition already is. This - function would be used to allow Unicode escapes on the command line - without using the -UN=escape option, but the utility of this is still - being determined. zipfile.c (SMS, Ed) - 3. Remove declaration for unused bz_deflate_init(). zipup.c (SMS, Ed) - 4. Add release announcement file, anticipating the long-awaited release. - zip30.ann (Ed) - 5. Update WhatsNew. WHATSNEW (Ed) ------------------------ March 24th 2008 version 3.0h03 -------------------- - 1. Update Unix configure script to better test for modern HP-UX compiler. - unix/configure (SMS) - 2. Updated Beta Readme. betas_readme.txt (Ed) - 3. Update Install. INSTALL (Ed) - 4. Update ReadMe. README (Ed) - 5. Small change to main help screen. zip.c (Ed) - 6. Small update to top of ToDo list. Actual updating of items still - needs to be done. TODO (Ed) ------------------------ April 2nd 2008 version 3.0h04 -------------------- - 1. Update copyright. crc32.h (Christian) - 2. Remove zip.h include. crc32.h (Christian) - 3. Add local prototypes for Unicode functions. Add cast for split size - check. Make many Unicode functions local. #if 0 out currently unused - utf8_chars(). Fix memory leak in wide_to_local_string() by adding - free() for buffer on error return. Fix memory leak in copy_args() on - error return by adding free-args(). Add ZCONST to arg in - insert_arg(). Shorten some lines to less than 80 characters. Add - free() to get_longopt() to fix memory leak. fileio.c (Christian) - 4. Create Win32 versions of wide_to_local_string() and - local_to_wide_string() so can use Win32 conversion functions. - fileio.c, win32/win32.c (Christian) - 5. Update comments for get_option(). fileio.c (Ed) - 6. Update encryption code readme. README.cr (Ed) - 7. Add prototype for recmatchw(). util.c (Christian) - 8. Change count_args() from static to local. util.c (Christian) - 9. Change ifdefs for includes for prototypes for version_info(), - zipstdout(), and check_zipfile() for WINDLL and MACOS and add - check_unzip_version(). zip.c (Christian) -10. Change ifndef NO_SYMLINKS to ifdef S_IFLNK for determining compiler - information. zip.c (Christian) -11. Change UTF-8 locale from en_GB.UTF-8 to .UTF-8. zip.c (Christian) -12. Change cast of -1 for dot_size from uzoff_t to zoff_t. - zip.c (Christian) -13. Change prototype for set_filetype to include parameter char *. - Change prototype of has_win32_wide to include parameter void. - zip.h (Christian) -14. Add prototypes for find_next_signature(), find_signature(), - and is_signature(). Change duplicate prototype scanzipf_regnew() - to missing prototype scanzipf_fixnew(). Change comment for Adler-16 - checksum to CRC-32 checksum as that is being used at that point in - the code. Move multiple uname assignments to common assignment. - Add inameLocal for WIN32_OEM and use define for inameLocal if not - to save memory allocation when not not using WIN32_OEM. Also - change _INTERN_OEM(str1) to INTERN_TO_OEM(src, dst) for OEM - conversion. Format comment for vem to fit in 80 character lines. - zipfile.c (Christian) -15. Change variable a from buffer to a pointer and add abf as the - buffer for zgetline() to handle NULL case. zipnote.c (Christian) -16. Change comments to zipentry comments and zipfile comment in - messages. zipnote.c (Ed) -17. Use uidgid_16bit as flag variable instead of uid_size. Modify - size check that prevents saving Unix UIDs and GIDs in the old - Unix extra field if they are not 16 bits. Change memory - allocation based on uidgid_16bit. Delete unused code for memory - copy for extra field. unix/unix.c (Christian, Ed) -18. Change compiler flag from -zp8 to -Zp8 for LCC Win32. - win32/makefile.lcc (Christian) -19. Add ifndef debug. Add bzip2 support. Add additional compiler - flags. win32/makenoas.w32 (Christian) ------------------------ April 10th 2008 version 3.0h05 -------------------- - 1. Fix bug found by forum poster where Zip stops recursing down a tree - when option -AS is set and a directory without the Windows archive - bit is reached. Now Zip continues down the tree to include files with - the bit set. win32/win32zip.c (forum poster, Ed) - 2. Update comments. win32/osdep.h (Ed) - 3. Update VMS notes to better organize and add information about file - name case. Additional small updates. vms/notes.txt (SMS) - 4. Fix bugs from previous changes to unix. unix/unix.c (SMS, Christian, - Ed) - 5. Add unix IBM support. unix/unix.c (SMS) - 6. Update INSTALL to account for new distribution structure and other - changes. INSTALL (SMS, Ed) - 7. Update bzip2 install readme. bzip2/install.txt (SMS, Ed) - 8. Fix bug noted in forum where -@ and -x generated a "nothing to - select from error" by also checking filelist variable populated by - -@ for entries. zip.c (forum poster, Ed) ------------------------ April 20th 2008 version 3.0h06 -------------------- - 1. Start announcement for Zip 3.0h public beta. zip30h.ann (Ed) - 2. Update beta readme. betas_readme.txt (Ed) - 3. Update case of README.CR. INSTALL (Ed) - 4. Change -W to -ws for option to stop wildcards from scanning directory - boundaries in path. This frees up -W for later use, maybe as extendted - option introducer. zip.c, man/zip.1 (Ed) - 5. Updated date in announcement to May 4th. zip30.ann (Ed) - 6. Added announcement for public beta Zip 3.0h. zip30h.ann (Ed) - 7. Fix large file support for MinGW by checking for compiler environments - before the check for (generic) gcc. zipup.c, win32/osdep.h - (Will, Christian) - 8. Fix large file support for bzip2. Additionally, the "dot printout" - code has also been adapted for LARGE_FILE support. zipup.c - (Will, Christian) - 9. Add comments to top of configure. unix/configure (Ed) -10. Move comment and comment out value size check for UID/GID extra field. - unix/unix.c (Ed) -11. Change case of file ToDo to TODO for consistency and to work with Unix - package. TODO (SMS, Ed) ------------------------ April 26th 2008 version 3.0h07 -------------------- - 1. For -AS, which for Windows only includes files with the archive bit - set, exclude directory entries (by setting -D) as some directories may - not have any files with the archive bit set and so the directory would - be empty. zip.c (Ed) - 2. Fix UID/GID size detection to use byte sizes and remove data fit test. - unix/unix.c (Ed) - 3. Update announcement. zip30h.ann (Ed) - 4. Add new unix extra field with tag 'ux' that stores UIDs/GIDs of 1 to 4 - bytes (8 to 32 bits). unix/unix.c (Ed) - 5. Update VB readme. windll/vbz64/readVB64.txt (Ed) - 6. For Unicode escaped output also show escape for ASCII 7-bit if - isprintable() is false. fileio.c (Ed) - 7. Use locale "en_US.UTF-8" for Unix. zip.c (Ed) - 8. Also show escaped Unicode for new files in found list. zip.c (Ed) - 9. Update manual. man/zip.1, zip.txt (Ed) ------------------------- May 4th 2008 version 3.0h08 ----------------------- - 1. Handle when a bad Unicode string in archive forces - utf8_to_wide_string() to return a NULL string. Give warning if UTF-8 - in existing archive is bad. Put WIN32 wide local header initializations - in UNICODE_SUPPORT block. fileio.c, zipfile.c (Ed) - 2. Leave out Unicode escape code if not Unicode enabled. zip.c (Ed) - 3. Enable oem_to_local_string() and local_to_oem_string() for WIN32 - even if no Unicode. zip.h, win32/win32.c (Christian, Ed) - 4. Update comment about encryption code. zipcloak.c (Ed) - 4. Update zipmessage_nl() and zipmessage() from zip.c. zipcloak.c, - zipnote.c, zipsplit.c (Ed) - 5. Add Mac OS X library check. unix/configure (SMS) - 6. Add 16-bit UID/GID check. unix/configure (Christian, Ed) - 7. Format echo and comment statements a bit. unix/configure (Ed) - 8. Only compile in old 16-bit UID/GID code if new define UIDGID_NOT_16BIT - from unix configure script is not defined. unix/unix.c (Christian) - 9. A couple changes to updated 16-bit UID/GID code. Add 64-bit - UID/GID support to new Unix extra field. unix/unix.c (Ed) -10. Remove redundant "license" from options table. zipcloak.c (Ed) -11. Remove old unix build files. unix/configure-orig, unix/Makefile-orig - (Christian) -12. Add -O (--output-file) option to ZipCloak. Fix bug by setting - out_path. zipcloak.c (Ed) ------------------------- May 8th 2008 version 3.0h09 ----------------------- - 1. Update copyright. Add check for NO_UNICODE_SUPPORT. tailor.h (Ed) - 2. Fix bug where Unicode General Purpose Bit Flag 11 should force keeping - the old name field but it was being overwritten by the escaped name - in the central directory header. Fixed some ZIPERR() calls in - putcentral() that referred to putlocal(). zipfile.c (Ed) - 3. Add comment about OCRCU8 and OCRCTB. unix/configure (Ed) - 4. Change line in instructions to note that manuals should be made after - Zip is made. Change OCRTB to OCRCTB. Add $(OCRCTB) to rule for - zipcloak$E so crc32_.o is linked in. Add comment for NO_UNICODE_SUPPORT - flag. unix/makefile (Ed) - 5. Update WhatsNew. Add additional items to the Zip 3.1 list. Add note - about Zip 2.4. WHATSNEW (Ed) - 6. Update Zip 3.0h announcement. zip30h.ann (Ed) - 7. Update manual pages. man/zip.1, man/zipsplit.1, man/zipnote.1, - man/zipcloak.1 (Ed) - 8. Add noted for UTF-8 locale. zip.c (Ed) - 9. Set UTF-8 locale for Unix in utilities if UNICODE_SUPPORT enabled - so can display and process paths in archives correctly. zipsplit.c, - zipcloak.c, zipnote.c (Ed) ------------------------- May 12th 2008 version 3.0h10 ---------------------- - 1. Add use of new Unix UID/GID extra field and of old Unix 16-bit UID/GID - extra field when system uses 16-bit UIDs/GIDs to version information. - zip.c (SMS, Ed) - 2. Add Unicode Path and Unicode Comment extra fields to extra fields list. - Update new Unix extra field revision date. proginfo/extrafld.txt (Ed) - 3. Add Mac hardware platform to version information. unix/unix.c (SMS) ------------------------- May 19th 2008 version 3.0h11 ---------------------- - 1. Initialize f->namew when streaming stdin to fix bug. fileio.c (Ed) - 2. Change force_zip64 to start as -1 as unset, then use 1 for forcing use - of Zip64 and 0 for disabling use of Zip64. Add negation of -fz to - prevent use of Zip64 during streaming from stdin to a non-seekable - output where data descriptors will be used, which allows creating - archives with the old stream format but will fail if a large file is - streamed. Default is still to force Zip64 data descriptors when - streaming, which covers all cases but requires a Zip64 compatible - unzip. zip.c, globals.c, zipfile.c (Ed) - 3. Handle case of bad Unicode in archive. zipfile.c (Ed) ------------------------- May 22nd 2008 version 3.0h12 ---------------------- - 1. Fix bug introduced last beta that prevented streaming large files. Use - separate error message depending on if -fz- was used. zipfile.c (Ed) - 2. Change non existent to nonexistent. unix/configure (SMS) - 3. Don't output blank line when zipmessage_nl() gets passed an empty - string. This removes blank lines for skipped entries when -FS used. - zip.c (Ed) ------------------------- May 27th 2008 version 3.0h13 ---------------------- - 1. Change UNICODE_ALLOW_FORCE to UNICODE_SUPPORT, -UN=force to -UN=UTF8, - and unicode_force to utf8_force. This option now standard with Unicode - support and forces Zip to save UTF-8 paths and comments, when not ASCII, - as if UTF-8 were the native character set. globals.c, zip.c, zip.h (Ed) - 2. Add note to Todo that it's out of date. TODO (Ed) - 3. Update WhatsNew. WHATSNEW (Ed) - 4. Update Unicode help in extended help. zip.c (Ed) - 5. Update announcements. zip30h.ann, zip30.ann (Ed) - 6. Fix bug with -UN=UTF8. zip.c, zipfile.c (Ed) - 7. Update Zip manual. man/zip.1, zip.txt (Ed) - 8. Attempt an update to zip limits document. proginfo/ziplimit.txt (Ed) - 9. Update README regarding forum postings. README (Ed) -10. Remove duplicate initialization lines for found and fnxt. zip.c (SMS) ------------------------- May 28th 2008 version 3.0h14 ---------------------- - 1. Remove >= 0 check from wide character check as value is unsigned. - fileio.c (SMS) - 2. In putlocal(), move nam and use_uname to UNICODE_SUPPORT block. If - no UNICODE_SUPPORT use z->nam instead of nam. zipfile.c (SMS, Ed) - 3. Update announcement date for beta. zip30h.ann (Ed) ------------------------- May 31st 2008 version 3.0h ------------------------ - 1. In putlocal() if using UTF-8 bit then also set UTF-8 bit in z->lflg so - is set in local header for streaming. zipfile.c (Ed) - 2. Update announcement date for beta. zip30h.ann (Ed) - 3. Rename lib and dll projects to zip32z64 and update project files so - project name is same as lib and dll libraries. Export make files. - windll/visualc/dll/zip32z64.dsp, windll/visualc/dll/zip32z64.dsw, - windll/visualc/dll/zip32z64.mak, windll/visualc/libzip32z64.dsp, - windll/visualc/libzip32z64.dsw, windll/visualc/libzip32z64.mak (Ed) ------------------------- June 7th 2008 version 3.0i01 ---------------------- - 1. Update Mac ReadMe to note Mac OS X uses Unix port. macos/readme.1st (Ed) - 2. Change UNIX to Unix in manual. Update dates in manual and add note - about Mac OS X. Change switch to switches. zip.1 (SMS, Ed) - 3. Add version information under Windows by adding a version resource. - win32/vc6/zip.dsp, win32/vc6bz2/zip.dsp, win32/zip.rc (Ed) ------------------------- June 15th 2008 version 3.0i02 ---------------------- - 1. Update Install instructions. INSTALL (Ed) - 2. Update ReadMe. README (Ed) - 3. Update ToDo list. TODO (Ed) - 4. Update WhatsNew. WHATSNEW (Ed) - 5. Add note to WHERE. WHERE (Ed) - 6. Update announcement. zip30.ann (Ed) - 7. Review man pages and update Zip man page. Compile text files from man - pages. man/zip.1, zip.txt, zipnote.txt, zipsplit.txt, zipcloak.txt (Ed) - 8. Update extended help. zip.c (Ed) ------------------------- June 17th 2008 version 3.0i03 ---------------------- - 1. Fix bug where UTF-8 flag was not being set when using_utf8 was set as - result of UTF-8 being current character set. zipfile.c (Ed) - 2. Update man page globbing description. man/zip.1, zip.txt (SMS, Ed) - 3. Update web address to bzip2 package for VMS. vms/install_vms.txt (SMS) ------------------------- June 21st 2008 version 3.0i04 ---------------------- - 1. Update comments. zbz2err.c (Christian) - 2. Put use_uname in UNICODE_SUPPORT block. zipfile.c (Christian) - 3. Increase st to 0x1400. msdos/makefile.msc (Christian) - 4. Update copyright and put @CodeSize and @DataSize into ifndef blocks for - Huge, Large, Compact, Medium, and Small. msdos/match.asm (Christian) - 5. Add check to disable symbolic links. msdos/osdep.h (Christian) - 6. Put Mac OS X compiler check into if Mac OS X block to avoid problems on - some other Unix ports with the check. unix/configure (SMS) - 7. Move set_extra_field() to fix compile problem. unix/unix.c (SMS) - 8. Update USEBZIP2 to USEBZ2 and -DUSE_BZIP2 to -DBZIP2_SUPPORT. Drop - -DMSDOS compile flag. win32/makefile.w32 (Christian) - 9. Change BZIP2_SUPPORT to USEBZ2. win32/makenoas.w32 (Christian) ------------------------- June 23rd 2008 version 3.0i05 ---------------------- - 1. Update and unify resources. Remove any MFC dependencies from the resource - files zip.rc and windll.rc. win32/zip.rc and windll/windll.rc now read - the version info from revision.h. windll.rc internal flags modified to - "32-bit dll". zip.rc internal flags liberated from "winnt 32-bit" - to "generic 32-bit windows". Win32 zip.exe also supported on Win9x - (32-bit). Update makefiles for Borland, MSC, GCC(mingw32), Watcom - to support inclusion of zip.rc version resources into zip.exe binary. - revision.h, msdos/osdep.h, win32/makefile.bor, win32/makefile.gcc, - win32/makefile.w10, win32/makefile.w32, win32/makefile.wat, - win32/makenoas.w32, win32/zip.rc, windll/windll.rc (Christian) - 2. Remove unused files. win32/resource.h, windll/resource.h, - windll/windll.aps, windll/zipver.h, windll/visualc/dll/zip32z64.mak, - windll/visualc/lib/zip32z64.mak (Christian) - 3. Update VMS. vms/descrip_deps.mms (SMS) ------------------------- June 26th 2008 version 3.0i06 ---------------------- - 1. Update Install and Readme in preparation for release. Update WhatsNew. - INSTALL, README, WHATSNEW (Ed) - 2. Update announcement. zip30.ann (Ed) - 3. Update original Visual Basic project comments and documentation. - windll/vb/readmevb.txt, windll/vb/vbzip.vbp, windll/vb/vbzip.vbw, - windll/vb/vbzipbas.bas, windll/vb/vbzipfrm.frm (Ed) - 4. Add bzip2 version of djgpp 2.x makefile thanks to Robert. Assumes a - standard djgpp installation. msdos/makebz2.dj2 (Robert Riebisch, Ed) ------------------------- June 27th 2008 version 3.0i07 ---------------------- - 1. Add DJGPP to bzip2 install instructions. bzip2/install.txt, - msdos/makebz2.dj2 (Robert, Ed) -------------------------- July 5th 2008 version 3.0 ------------------------- - 1. Add -sd to extended help. zip.c (Will, Ed) - 2. Fix memory bug when rebuilding Zip64 central directory extra field which - can crash MinGW and other ports when processing large files. zipfile.c - (Will) - 3. Fix -v bug preventing display of version information when options in - environment variables. zip.c (Ed) - 4. Update WhatsNew. WHATSNEW (Ed) - 5. Update announcement. zip30.ann (Ed) diff --git a/third_party/infozip/zip/README b/third_party/infozip/zip/README deleted file mode 100644 index a55942576..000000000 --- a/third_party/infozip/zip/README +++ /dev/null @@ -1,234 +0,0 @@ -Zip 3.0 is the first Zip update adding large file support. For now Zip 2.3x -remains available and supported, but users should switch to this new release. - -Testing for Zip 3.0 has focused mainly on Unix, VMS, Max OS X, and Win32, -and some other ports may not be fully supported yet. If you find your -favorite port is broke, send us the details or, better, send bug fixes. It's -possible that support for some older ports may be dropped in the future. - - - -Copyright (c) 1990-2008 Info-ZIP. All rights reserved. - -See the accompanying file LICENSE (the contents of which are also included -in unzip.h, zip.h and wiz.h) for terms of use. If, for some reason, all -of these files are missing, the Info-ZIP license also may be found at: -ftp://ftp.info-zip.org/pub/infozip/license.html and -http://www.info-zip.org/pub/infozip/license.html. - - -Zip 3.0 is a compression and file packaging utility. It is compatible with -PKZIP 2.04g (Phil Katz ZIP) for MSDOS systems. There is a companion to zip -called unzip (of course) which you should be able to find in the same place -you got zip. See the file 'WHERE' for details on ftp sites and mail -servers. - -So far zip has been ported to a wide array of Unix and other mainframes, -minis, and micros including VMS, OS/2, Minix, MSDOS, Windows, Atari, Amiga, -BeOS and VM/CMS. Although highly compatible with PKware's PKZIP and PKUNZIP -utilities of MSDOS fame, our primary objective has been one of portability -and other-than-MSDOS functionality. Features not found in the PKWare version -include creation of zip files in a pipe or on a device; VMS, BeOS and OS/2 -extended file attributes; conversion from Unix to MSDOS text file format; and, -of course, the ability to run on most of your favorite operating systems. And -it's free. - -See the file zip30.ann for a summary of new features in Zip 3.0 and WhatsNew -for the detailed list of new features and changes since Zip 2.32. The file -CHANGES details all day-to-day changes during development. - -Notes: - -Multi-volume support. This version does not support multi-volume spanned -archives as in pkzip 2.04g, and there is no intention at this point to support -spanned archives, but Zip 3.0 supports split archives. A split archive is an -archive split into a set of files, each file a piece of the archive and each -file using an extension, such as .z02 as in the file name archive.z02, that -provides the order of the splits. In contrast, a spanned archive is the -original multi-floppy archive supported by pkzip 2.0g where the split order -is contained in the volume labels. The contents of split and spanned archives -are mostly identical and there is a simple procedure to convert between the -formats. Many current unzips now support split archives. - -Zip64 support. This version supports Zip64 archives as described in the -PKWare AppNote. These archives use additional fields to support archives -greater than 2 GB and files in archives over the 2 GB previous limit (4 GB -on some ports). The Zip64 format also allows more than 64k entries in an -archive. Support by the OS for files larger than 4 GB is needed for Zip to -create and read large files and archives. On Unix, Win32, and some other -ports, large file and Zip64 support is automatically checked for and -compiled in if available. Use of Zip64 by Zip is automatic and to maximize -backward compatibility the Zip64 fields will only be used if needed. A -Zip64 archive requires a pkzip 4.5 compatible unzip, such as UnZip 6.0. - -Unicode support. This version has initial Unicode support. This allows -paths and names of files in other character sets to be accurately recreated -on OS that have sufficient character set support. On Win32, if wide -character calls are supported (not Win 9x unless Unicode support has been -added) all files (including paths with illegal characters in the current -character set) should now be readable by zip. Unicode support is provided -using a new set of UTF-8 path and comment extra fields and a new UTF-8 bit -for flagging when the current character set is already UTF-8. Zip 3.0 -maintains backward compatibility with older archives and is mostly compliant -with the new Unicode additions in the latest PKWare AppNote. The exception -is UTF-8 comments, which are not supported if UTF-8 is not the native -character set, but should be fully implemented in Zip 3.1. - -16-bit OS support. Though Zip 3.0 is designed to support the latest zip -standards and modern OS, some effort has been made to maintain support -for older and smaller systems. If you find Zip 3.0 does not fit on or -otherwise does not work well on a particular OS, send in the details and -we might be able to help. - -Compression methods. In addition to the standard store and deflate methods, -Zip now can use the bzip2 compression format using the bzip2 library. Though -bzip2 compression generally takes longer, in many cases using bzip2 results -in much better compression. However, many unzips may not yet support -bzip2 compressed entries in archives, so test your unzip first before using -bzip2 compression. - -Installation. Please read the file INSTALL for information on how to compile -and install zip, zipsplit, zipcloak, and zipnote and please read the manual -pages ZIP.txt, ZIPSPLIT.txt, ZIPCLOAK.txt, and ZIPNOTE.txt for information on -how to use them. Also, if you are using MSDOS or Windows, note that text -files in the distribution are generally in Unix line end format (LF only) -and Windows and DOS users will need to either convert the files as needed to -DOS line ends (CR LF) or extract the distribution contents using unzip -a. - -Utilities. At this point zipsplit, zipcloak, and zipnote should work with -large files, but they currently do not handle split archives. A work around -is to use zip to convert a split archive to a single file archive and then use -the utilities on that archive. - -Encryption. This version supports standard zip encryption. Until recently -the encryption code was distributed separately because of the US export -regulations but now is part of the main distribution. See crypt.c for -details. Decryption can be made with unzip 5.0p1 or later, or with zipcloak. - -Bug reports. All bug reports or patches should go to zip-bugs via the web -site contact form at http://www.info-zip.org/zip-bug.html (we have discontinued -the old email address zip-bugs@lists.wku.edu because of too much spam lately) -and suggestions for new features can be submitted there also (although we don't -promise to use all of them). We also are on SourceForge at -http://sourceforge.net/projects/infozip/ and now automatically get Bug Reports -and Feature Requests submitted there. In addition, a new Info-ZIP discussion -forum is available as well. See below. Though bug reports can be posted there, -we don't have automatic monitoring of all postings set up yet so you may want -to use the web form or SoureForge for a quicker response. A good approach may -be to post the details on the forum so others can benefit from the posting, -then use the web reply form to let us know you did that if you don't get a -reply in a reasonable time. - -Ports. If you're considering a port, please check in with zip-bugs FIRST, -since the code is constantly being updated behind the scenes. We'll -arrange to give you access to the latest source. - -Discussion group. If you'd like to keep up to date with our Zip (and companion -UnZip utility) development, join the ranks of BETA testers, add your own -thoughts and contributions, etc., check out the new discussion forum. This is -the latest offering, after the various Info-ZIP mailing-lists on -mxserver@lists.wku.edu (courtesy of Hunter Goatley) were no longer available -and the temporary QuickTopic discussion group for Info-ZIP issues at -http://www.quicktopic.com/27/H/V6ZQZ54uKNL died a horrible death due to large -amounts of spam. The new discussion forum is now available at -http://www.info-zip.org/board/board.pl (thanks again to Hunter Goatley) and -can be used to discuss issues, request features, and is one place new betas -and releases are announced. It also is a place to post bug reports, and -patches can be submitted as attachments. However, we don't yet get -automatic notification of all postings there so try one of the other methods -if you don't get a response. You can also post Bug Reports and Feature -Requests at Source Forge. However, the web site contact form remains -available if you would rather not post on the public forums. - -Frequently asked questions on zip and unzip: - -Q. When unzipping I get an error message about "compression method 8". - -A. This is standard deflate, which has been around for awhile. Please - get a current version of unzip. See the file 'WHERE' for details. - - -Q. How about "compression method 12"? - -A. Compression method 12 is bzip2 and requires a relatively modern unzip. - Please get the latest version of unzip. - - -Q. I can't extract this zip file that I just downloaded. I get - "zipfile is part of multi-disk archive" or some other message. - -A. Please make sure that you made the transfer in binary mode. Check - in particular that your copy has exactly the same size as the original. - Note that the above message also may actually mean you have only part - of a multi-part archive. Also note that UnZip 5.x does not and UnZip 6.0 - probably won't have multi-disk (split) archive support. A work around - is to use Zip 3.0 to convert the split archive to a single-file archive - then use UnZip on that archive. As a last result, if there's something - readable in what you have, zip -FF should be able to recover it. - - -Q. When running unzip, I get a message about "End-of-central-directory - signature not found". - -A. This usually means that your zip archive is damaged, or that you - have an uncompressed file with the same name in the same directory. - In the first case, it makes more sense to contact the person you - obtained the zip file from rather than the Info-ZIP software - developers, and to make sure that your copy is strictly identical to - the original. In the second case, use "unzip zipfile.zip" instead - of "unzip zipfile", to let unzip know which file is the zip archive - you want to extract. - - -Q. Why doesn't zip do just like PKZIP does? - -A. Zip is not a PKZIP clone and is not intended to be one. In some - cases we feel PKZIP does not do the right thing (e.g., not - including pathnames by default); in some cases the operating system - itself is responsible (e.g., under Unix it is the shell which - expands wildcards, not zip). Info-ZIP's and PKWARE's zipfiles - are interchangeable, not the programs. - - For example, if you are used to the following PKZIP command: - pkzip -rP foo *.c - you must use instead on Unix: - zip -R foo "*.c" - (the quotes are needed to let the shell know that it should - not expand the *.c argument but instead pass it on to the program, - but are not needed on ports that do not expand file paths like - MSDOS) - - -Q. Can I distribute zip and unzip sources and/or executables? - -A. You may redistribute the latest official distributions without any - modification, without even asking us for permission. You can charge - for the cost of the media (CDROM, diskettes, etc...) and a small copying - fee. If you want to distribute modified versions please contact us at - www.Info-ZIP.org first. You must not distribute beta versions. - The latest official distributions are always on ftp.Info-ZIP.org in - directory /pub/infozip and subdirectories and at SourceForge. - - -Q. Can I use the executables of zip and unzip to distribute my software? - -A. Yes, so long as it is made clear in the product documentation that - zip or unzip are not being sold, that the source code is freely - available, and that there are no extra or hidden charges resulting - from its use by or inclusion with the commercial product. See the - Info-ZIP license for more. Here is an example of a suitable notice: - - NOTE: is packaged on this CD using Info-ZIP's compression - utility. The installation program uses UnZip to read zip files from - the CD. Info-ZIP's software (Zip, UnZip and related utilities) is - freely distributed under the Info-ZIP license and can be obtained as - source code or executables from various anonymous-ftp sites, - including ftp://ftp.info-zip.org/pub/infozip. - - -Q. Can I use the source code of zip and unzip in my commercial application? - -A. Yes, as long as the conditions in the Info-ZIP license are met. We - recommend you include in your product documentation an acknowledgment - and note that the original compression sources are available at - www.Info-ZIP.org. If you have special requirements contact us. diff --git a/third_party/infozip/zip/README.CR b/third_party/infozip/zip/README.CR deleted file mode 100644 index c777d19f2..000000000 --- a/third_party/infozip/zip/README.CR +++ /dev/null @@ -1,119 +0,0 @@ -_____________________________________________________________________________ - - This is Info-ZIP's README.CR for zcrypt29.zip, last updated 27 March 2008. -_____________________________________________________________________________ - - -The files described below contain the encryption/decryption code for Zip 2.31, -UnZip 5.52, and WiZ 5.02 (and later). These files are included in the main -source distributions for all of these now, but the encryption patch is still -available for earlier versions of these. This file both describes the history -of the encryption package and notes the current conditions for use. Check -the comments at the top of crypt.c and crypt.h for additional information. - -As of version 2.9, this encryption source code is copyrighted by Info-ZIP; -see the enclosed LICENSE file for details. Older versions remain in the pub- -lic domain. Zcrypt was originally written in Europe and, as of April 2000, -can be freely distributed from the US as well as other countries. - -(The ability to export from the US is new and is due to a change in the Bureau -of Export Administration's regulations, as published in Volume 65, Number -10, of the Federal Register [14 January 2000]. Info-ZIP filed the required -notification via e-mail on 9 April 2000; see the USexport.msg file in this -archive. However, as of June 2002, it can now be freely distributed in both -source and object forms from any country, including the USA under License -Exception TSU of the U.S. Export Administration Regulations (section 740.13(e)) -of 6 June 2002.) - - LIKE ANYTHING ELSE THAT IS FREE, ZIP, UNZIP AND THEIR ASSOCIATED - UTILITIES ARE PROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, - EITHER EXPRESSED OR IMPLIED. IN NO EVENT WILL THE AUTHORS BE LIABLE - FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE. - -The encryption code is a direct transcription of the algorithm from -Roger Schlafly, described by Phil Katz in the file appnote.txt. This -file is distributed with the PKZIP program (even in the version without -encryption capabilities). Note that the encryption will probably resist -attacks by amateurs if the password is well chosen and long enough (at -least 8 characters) but it will probably not resist attacks by experts. -Paul Kocher has made available information concerning a known-plaintext -attack for the PKWARE encryption scheme; see http://www.cryptography.com/ -for details.) Short passwords consisting of lowercase letters only can be -recovered in a few hours on any workstation. But for casual cryptography -designed to keep your mother from reading your mail, it's OK. - -For more serious encryption, check into PGP (Pretty Good Privacy), a -public-key-based encryption system available from various Internet sites. -PGP has Zip and UnZip built into it. The most recent version at the time -this was originally written was 6.5, although older versions were still -widespread. At the time of this writing there are now GPG, PGP Universal -2.0, and various others based on OpenPGP. - -We are looking at adding AES strong encryption to future versions of Zip and -UnZip. - -Zip 2.3x and UnZip 5.5x and later are compatible with PKZIP 2.04g. (Thanks -to Phil Katz for accepting our suggested minor changes to the zipfile format.) - -IMPORTANT NOTE: - - Zip archives produced by Zip 2.0 or later must not be *updated* by - Zip 1.1 or PKZIP 1.10 or PKZIP 1.93a, if they contain encrypted members - or if they have been produced in a pipe or on a non-seekable device. - The old versions of Zip or PKZIP would destroy the zip structure. The - old versions can list the contents of the zipfile but cannot extract - it anyway (because of the new compression algorithm). If you do not - use encryption and compress regular disk files, you need not worry about - this problem. - - -Contents that were distributed and now are part of the main source files: - - file what it is - ---- ---------- - README.CR this file - LICENSE Info-ZIP license (terms of reuse and redistribution) - USexport.msg export notice sent to US Bureau of Export Administration - WHERE where Zip/UnZip/WiZ and related utilities can be found - crypt.c code for encryption and decryption - crypt.h code for encryption and decryption - file_id.diz description file for some BBSes - -Most all of the files are in Unix (LF only) format. On MSDOS systems, you -can use the -a option of UnZip to convert the source files to CRLF -format. This is only necessary if you wish to edit the files -- they -will compile as is with Microsoft C and Turbo/Borland C++ 1.0 or -later. However, you will have to convert the files (using "unzip -a") -to the CRLF format to compile with the older Turbo C 1.0 or 2.0. You -should be able to find Zip and UnZip in the same place you found this -(see ftp://ftp.info-zip.org/pub/infozip/Info-ZIP.html or the file -"WHERE" for details). - -Current releases all have encryption built in. To update previous versions -using the zcrypt sources: - - (1) Get the main sources (e.g., Zip 2.3) and unpack into a working - directory, as usual. - - (2) Overwrite the dummy crypt.c and crypt.h from the main sources with - the versions from this package. If you want to overwrite directly - out of the zcrypt29 archive, do not use UnZip's freshen/updating - option; the dummy files may be newer than the real sources in - zcrypt29. ("unzip -o zcrypt29 -d /your/working/dir" will do the - Right Thing in most cases, although it may overwrite a newer WHERE - file under some circumstances.) - - (3) Read the main INSTALL document and compile normally! No makefile - changes are necessary on account of the zcrypt sources. You can - check that the version you just compiled has encryption or decryption - support enabled by typing "zip -v" or "unzip -v" and verifying that - the last "special compilation option" says encryption or decryption - is included. - -Encryption enables new "-e" and "-P password" options in Zip, and a new -"-P password" option in UnZip--see the normal Zip and UnZip documentation -for details. (Note that passing a plaintext password on the command line -is potentially much more insecure than being prompted for it interactively, -which is the default for UnZip and for Zip with "-e". Also note that the -interactive method allows UnZip to deal with archives that use different -passwords for different files.) diff --git a/third_party/infozip/zip/TODO b/third_party/infozip/zip/TODO deleted file mode 100644 index 8d517328a..000000000 --- a/third_party/infozip/zip/TODO +++ /dev/null @@ -1,142 +0,0 @@ -Todo list (last updated 12 June 2008). - -Features for next official version: - -- Extended attributes for Windows, Linux, and Mac OS X. -- Win32 ACL rewrite to use backup api to create new and more useful extra - field (need unzip support) (Kai). -- Allow -d@ to read in a list of names to delete (11/17/2005). -- AES encryption (3/19/05). - -Features that may make the next release: - -- Allow reading in list of files using @filename. -- When -R, -x, or -i pattern ends in a directory add / to the end - (11/5/2004 Nehal). -- Decide if -R, -i and -x should use external rather than internal patterns. - Also, change pattern matching to not do ex2in() and then in2ex() if - appropriate. (12/26/2005 SMS) -- Though Unicode paths have been implemented and tested, Unicode comments - are not yet supported (except for comments on UTF-8 native systems which - are supported). -- Verbose mode -v may still need work. - -- Add C# example for Zip 3.0 (need to be converted to new DLLs) - original - C# example added with note. -- Path Prefix maybe, so entries added to an archive can have a directory - path string prepended to each path so can zip multiple drives and avoid - name conflicts (4/17/2006). -- UNC paths like \\server\path (4/26/2005). -- Support for other languages maybe. - -- Add About page option similar to -h2 and -v but lists Info-ZIP - information (could be -sa) (4/29/2006). -- Update utilities ZipSplit, ZipNote, and ZipCloak to handle split archives. -- Update ziperr and finish if needed. -- Review memory allocation and fill in memory leaks if any. -- Enhance -FF to fix common problems such as archives ftp in text mode - and fixing checksums so entries can be extracted if that makes - sense (6/17/2007). -- Add \ to / conversion in zipsplit to fix problem in - 1/29/2004 email. -- Encryption bug with small stored file (12/27/2005) (fixed?). - -- When updating large archives with few entries being - updated maybe display something in large periods of - quiet (1/23/2006). -- Windows OEM comments (5/17/2006). -- Example of using MVS zip and unzip (3/30/2004) (Need one). -- UTF-8 comments need to be implemented (6/17/2007) -- Maybe convert ../ in archive (5/20/2006). -- Per so many buffers dll callback (12/23/2005 Ale). -- Allow rename stdin "-" to something else (12/27/2005 gregor). -- Check for possible buffer overrun weaknesses while reading zip files. -- Do Active Template Library (ATL) (4/27/2005). -- Flush Win16 support - to be determined (Mike). -- Way to convert file names on input, converting foo.c to dir/foo_bar.c - for instance (4/8/2004, 3/12/2004). -- French WiZ (not a Zip thing actually but dependent on zip and unzip). -- Then there is that wierd ^D being converted to \000 error reported - in 6/21/2003 email when Zip is outputted into a pipe on Windows ports. - -Old list: - -Main features still missing for next official version (last updated 2/11/2001): - -- what about the binary/text detection ? (seems done) -- -b and -t options in help screen (covered in -h2) -- findfirst/findnext and after that LSSTAT (performance!!) -- use IS_EXEC from djgpp stat.h -- use install in unix/Makefile instead of mkdir -p, look at install sh script. -- #elif for those ports that can handle it. -- what about zopen vs. fopen ? -- Add zcreate or zfcreate for win32. -- Assembler stuff in match.S (subexpressions) -- zipping huge files (> 2G, unsigned 32bit) (done) -- Testsuite for zip and unzip (John D. Mitchell) -- make a version.c or version.h that includes all the compiler names -- run utils with dmalloc(). -- what to do with zip -F and zip -FF (readzipfile2()) ? (done?) -- profiling of the code -- multi disk zip files (could be done) -- zipfile modification tool (Greg) -- Implement -- option (Thomas Klauser, wiz@danbala.tuwien.ac.at) (could be done) -- don't add files with "Archive bit" or add files with "Archive bit" - (uwe.becher@metronet.de) (could be done with -AS and -AC) -- 32 bit file attributes -- generate output without having to seek at all (this seems to be stream output) -- remove contractions from zip error messages, make them clearer (Steve) -- display "[text]" for ascii files when not quiet (no -q) (Timo Salmi) -- does zipnote accept names with version number? -- for a WORM, zip should create temp file only when updating; new archives - should be created directly. -- APPNOTE.TXT specifies "4) The entries in the central directory may - not necessarily be in the same order that files appear in the zipfile" - but readzipfile() relies on same order. (new read does not, and now - the read for -FF searches for central directory matches rather than - rely on the order) -- on Mac, MPW C 3.3.1 requires #if (a || b) ["#if a || b" taken as "#if a"] -- on Unix, let -S be "include non-regular files without reading from them" - (as pkzip on Unix). This requires unzip support. -- zip -l should do ebcdic->ascii translation on CMS and MVS -- zip as subroutine (zdig/241) (some work done on this) -- accept k and M in zipsplit -- store / (part of file name) as ! in OS/2 (problem only with -E ?) -- in addition to -l (LF to CR LF) and -ll (CR LF to LF) add -lc - (LF to CR LF but CR LF remains unchanged) - -Known bugs: - -- On VMS, zip fails reading some files with "byte record too large for - user's buffer". You must use the "-V" option for such files. - (many changes to VMS so may be fixed) - -- on MSDOS, zip386.exe does not like "zip -bc: foo ..." - -- on MSDOS, zip386.exe is sometimes much slower than zip.exe. This is - probably a problem with DJGPP (to be investigated). - -- on NT with C shell, zip should not do file name expansion again. - -- zip zipfile ... ignores existing zipfile if name does not have an extension - (except for the -A option, generally used on self-extracting files). - (archives should probably have extensions. Things like archive.jar work) - -- For an sfx file without extension, "zip -A sfx" works but "zip sfx -A" - doesn't. (because options were required first, but now both OK) - -- When storing files in a zipfile (-0), zip marks all of them as binary. - -- On VMS, some indexed files are not restored correctly after zip -V and unzip. - (This is now known to be a problem of UnZip. The workaround for Zip 2.2 - and newer is to use PK-style VMS extra fields; this is now the default. - NOTE that UnZip 5.32 has been fixed [971019]!) (many VMS changes so - this may be fixed) - -- zip and unzip should use the same pattern matching rules, particularly - on MSDOS and OS/2. On OS/2, "zip foo *.*" should also match files - without extension. - Partially DONE (OS/2 "*.*" matches "*".) - -- there should be a way to avoid updating archive members (only addition - of new files allowed) diff --git a/third_party/infozip/zip/USexport.msg b/third_party/infozip/zip/USexport.msg deleted file mode 100644 index 068aa9f3f..000000000 --- a/third_party/infozip/zip/USexport.msg +++ /dev/null @@ -1,75 +0,0 @@ -From roelofs (at) sonic.net Tue Jun 17 08:26:55 2003 -Date: Tue, 17 Jun 2003 08:26:50 -0700 -Message-Id: <200306171526.h5HFQoaw014091 (at) bolt.sonic.net> -From: Greg Roelofs -Reply-To: Greg Roelofs -To: crypt (at) bis.doc.gov, enc (at) ncsc.mil, web_site (at) bis.doc.gov -Subject: TSU NOTIFICATION - Encryption (Info-ZIP zcrypt.zip) -Cc: newt (at) pobox.com, zip-bugs (at) lists.wku.edu - - - SUBMISSION TYPE: TSU - SUBMITTED BY: Greg Roelofs - SUBMITTED FOR: the Info-ZIP group (an informal, Internet-based - collection of software developers with the contact - address given in next item) - POINT OF CONTACT: Zip-Bugs (at) lists.wku.edu - PHONE and/or FAX: n/a - MANUFACTURER: n/a - PRODUCT NAME/MODEL #: zcrypt - ECCN: 5D002 - - NOTIFICATION: - - ftp://ftp.info-zip.org/pub/infozip/src/zcrypt.zip - - -FURTHER COMMENTS: - -(1) This notice is being sent in order to ensure that we may legally - take advantage of the 6 June 2002 amendment to 740.13 regarding - "corresponding object code." The encryption code in question is - unchanged since our original notification of 9 April 2000, appended - below and also reproduced within the above zcrypt.zip archive. - (Indeed, there has been no change to the core encryption/decryption - code in well over five years.) - -(2) The (larger) source archives for Zip, UnZip, MacZip, WiZ, and - potentially other packages, currently available in the same ftp - directory given above, also contain (or may contain) copies of - the same zcrypt source code. - -(3) ftp.info-zip.org currently points to a site in Germany, so techni- - cally it is not involved in "US export" in any direct way. However, - we encourage other sites to "mirror" our software, and some of these - mirror sites may be US-based (and therefore involved in reexport of - the code in question). In addition, some Info-ZIP members reside in - the US, and www.info-zip.org currently points to a site in Kentucky. - - -ORIGINAL NOTIFICATION: - -From roelofs (at) sonic.net Sun Apr 9 15:11:45 2000 -Date: Sun, 9 Apr 2000 15:11:27 -0700 -Message-Id: <200004092211.PAA20023 (at) sonic.net> -From: Greg Roelofs -To: crypt (at) bxa.doc.gov -Subject: notice of export of unrestricted encryption source code -Cc: newt (at) pobox.com, zip-bugs (at) lists.wku.edu - -The Info-ZIP group, an informal, Internet-based collection of software -developers with contact address Zip-Bugs (at) lists.wku.edu, hereby notifies -the US Bureau of Export Administration (BXA) of the posting of freely -available encryption source code on the Internet under License Exception -TSU, to commence later today at this location: - - ftp://ftp.info-zip.org/pub/infozip/src/zcrypt.zip - -This notification is in accordance with section 740.13(e) of the amended -Export Administration Regulations, as published in the 14 January 2000 -issue of the Federal Register. - --- -Greg Roelofs newt (at) pobox.com http://pobox.com/~newt/ -Newtware, PNG Group, Info-ZIP, Philips Research, ... - diff --git a/third_party/infozip/zip/WHATSNEW b/third_party/infozip/zip/WHATSNEW deleted file mode 100644 index 9e8d52bca..000000000 --- a/third_party/infozip/zip/WHATSNEW +++ /dev/null @@ -1,333 +0,0 @@ -What's New - -Last updated 1 July 2008 - -This file is the full list of new features and major changes for Zip 3.0 -by beta release. See the announcement file zip30.ann for a quick summary -of all features and changes in Zip 3.0. Also see the file README for -release information, INSTALL for installation procedures, and the manual -pages zip.txt, zipsplit.txt, zipcloak.txt, and zipnote.txt for how to use -the new features. The file CHANGES has all the day-to-day changes made -during development. - - -Below are some of the more significant items on the list for Zip 3.1 -(see ToDo for a more complete list): - -- AES encryption. -- Extended attributes for Windows, Linux, and Mac OS X. -- Support -d@ for deleting list of files. -- Decide if -R, -i and -x should use external rather than internal patterns. -- Though Unicode paths have been implemented and tested, Unicode comments - are not yet supported (except for comments on UTF-8 native systems which - are supported). -- Verbose mode -v may still need work. -- When pattern is directory add end / automatically. -- Add C# example for Zip 3.0 (need to be converted to new DLLs) - original - C# example added with note. -- Path Prefix maybe, so entries added to an archive can have a directory - path string prepended to each path. -- UNC path support maybe. -- Support for other languages maybe. -- Send in your suggestions. -- ... - - -MAJOR CHANGES BY BETA VERSION ------------------------------ - -New things in Zip 3.0 since Zip 3.0h: - -- Unicode fixes. -- Test and fix various ports as needed. -- Update Win32 resource to support more Windows ports. -- Add djgpp 2.x makefile that includes bzip2. -- Add Win32 version resource to Win32 executable. -- Bug fixes. -- Documentation updates. -- Package for release. - - -New things in Zip 3.0h - -- Allow -@ and -x to work together. -- Unicode code cleanup. -- Allow forcing use of UTF-8 storage in standard path and comment. -- Update symbolic link checks. -- Add support for storing 32-bit UIDs/GIDs using new extra field. - Backward compatible support for the old 16-bit UID/GID extra field - remains if Zip is compiled on an OS that has 16-bit UID/GID - storage. -- Update VMS notes. -- Directory scan using -AS (include only files with Windows archive - bit set) now ignores archive bit on directories to include all files - with archive bit set in all directories. Also, to avoid empty - directories being created, -AS now does not store directory - entries. -- Add Unix IBM support. -- Change -W to -ws to free -W for later use. -- Fix large file support for MinGW. -- Fix large file support for bzip2. -- Fix compile error in ZipCloak when UNICODE_SUPPORT is not enabled. -- Fix Unicode bug in ZipCloak involving Unicode paths. -- Long Unicode escapes changed from #Lxxxxxxxx to #Lxxxxxx to shorten - paths with escaped Unicode. -- Bug fixes. - - -New things in Zip 3.0g - -- Add split support to VB project for Zip64. -- Disable reading of Unix FIFOs unless new -FI option used to avoid an - archiving operation stopping when it hits an active unfed FIFO. -- The "[list]" wildcard expression (regular expression matching of any - character or range of characters in list) is now disabled on DOS and - Windows as it has caused confusion when filenames have [ and ] in - them. The new -RE option reenables it. -- Add negation to many display options such as -dc and -db. -- Allow -FF to read and fix archives having local entries that appear - after central directory entries. -- Bug fixes. - - -New things in Zip 3.0f - -- bzip2 - The bzip2 compression method looks supported for at least - Windows, Unix, and VMS using the bzip2 library. A new option, -Z cm, - selects the compression method. - -- Split archives - Can now use -s to create a split archive. The - default is to update split files as the archive is being written, - which requires all splits to remain open until the archive is done. - This should be no problem when writing the archive to a hard drive, - for example, and this approach creates archives that should be - supported by all unzips that support splits. Adding the -sp option - enables split pause mode that instead writes splits that do not - need updating and pauses Zip after each split. This allows splits - to be written directly to removable media, however -sp archives - may not be as universally compatible. - -- Unicode support - Zip now stores Unicode paths that should be more - portable across character sets and languages. The unzip must have - Unicode support enabled or the Unicode paths are ignored. If - reading an archive with Unicode paths, unsupported characters are - replaced by #Uxxxx and #Lxxxxxxxx escapes in the file name. Option - -UN controls how Unicode is handled. Also, on systems where the - current character set is UTF-8, preliminary support for the new - General Purpose Bit Flag, bit 11, UTF-8 flag, that indicates UTF-8 - is stored in the path and comment fields is implemented for paths. -- Unicode on Win32 - On WIN32 systems that support the wide character - calls (mainly NT and later systems using NTFS), when UNICODE SUPPORT - is enabled Zip will now do directory scans using Unicode and convert - the Unicode paths to the local character set for storage in the standard - path field and store UTF-8 in the Unicode extra field. This allows - directory scans to complete successfully regardless of the character - set the path is in. On Win9x systems wide character scans are not - generally supported and Zip automatically uses a local character scan - instead. - -- Keep extra fields option - The default operation has been, and continues - to be, to read then strip old extra fields when reading entries from an - existing archive and then recreate the extra fields that Zip knows about. - Extra fields specific to each operating system get added by default also. - The new option -X- (negated -X) keeps any old extra fields, copying - them to the updated archive unchanged (unless Zip has updated them). - The unnegated -X still strips most all extra fields except Zip64, - Unicode, and UT time. - -- License - minor updates to the license. - -- Windows OEM - When compiled with WIN32_OEM (the default for WIN32), - Zip on WIN32 now stores OEM paths, which should be more compatible - with other zips and should fix some character set problems. -- Windows Archive Bit support - On Windows can now use new -AS - (include if archive bit set) option to select files with the DOS - archive bit set and use new -AC (clear archive bits) option to clear - the archive bits on files after the archive has been created. - But -DF is probably better. - -- Difference mode - A new option -DF (--dif) creates an output archive - that includes only files changed or new since the input archive was - created. Can use to create incremental backups. -- File Sync - The new option -FS enables File Sync, a new mode that - synchronizes the entries in an archive with the files on the file - system, adding updating, and deleting entries as needed. This - should create the same results as creating a new archive, but - since existing entries are copied, may be much faster. - -- Copy Mode - A new --out option allows creating a new archive with a - different name than the input archive, leaving the input archive - unchanged. This allows updating split archives. It also allows - for a new copy mode to select entries in one archive and copy them - directly to a new archive. -- Empty archives - Now an empty archive is created when -i or -i@ is used - and the file patterns given do not match anything. This has been - requested to support scripts. - -- Global dots - A new -dg option now displays progress dots as -dd does, - but instead of displaying them for each file, the dots track the total - bytes read for the archive. The -dg option also works when -q is used - to disable most output, which allows for something like zip -qdgds 100m - to be used to not display specific files but display a dot every 100 MB - as a global status. -- Date range - Can now use -t and -tt to set a date range -- Fix options - Option -F redone and can recover files from an archive - with a mostly complete central directory more reliably, but no longer - can handle truncated archives. Option -FF redone and now can salvage - files from slightly more damaged archives, including truncated archives. - In some ways -F is less powerful but more stable than it was and -FF will - be needed where -F in Zip 2.32 was enough. One big change is -F and -FF - both now support split archives. -- Console writing - Updates to how messages are written to the console have - been made including more consistent handling of line breaks. -- Show Files options - Option -sf lists the files that would be operated - on. This option can be used alone to list the files in an archive. - Also see options -su and -sU for showing Unicode paths. -- UnZip Check - Now check that UnZip 6.00 or later is being used for - unzip if testing a Zip64 archive. A new option -TT can be used to set - the unzip to use with the -T check. Currently UnZip does not support - split archives so split archives can't be tested by UnZip. -- Streaming - Directories are now handled better when streaming. -- Case matching - Normally all matching against archive entries is case - sensitive, so *.BAR will not match or find foo.bar in an archive - when deleting, copying, or freshening entries (deleting and copying - only on VMS). New option -ic (--ignore-case) enables case insensitive - matching. Currently -ic is only implemented on WIN32 and VMS. - -- Delete date bug fixed - Bug when using -d to delete files while - using -t or -tt to select the files based on date is fixed -- Large file encryption bug fixed - Fix for bug that very rarely - results in bad data being stored when deflating and encrypting - uncompressable data and resulting in CRC errors when extracting, - but the chance of error increases with file size (thanks to - WinZip for finding this bug). See CHANGES for details. - - -New things in Zip 3.0e - -- Bugs described in Debian patches 004 (unix configure script update) and - 005 (large path bug) fixed -- Various fixes -- Add optional running stats and also end stats if not all files could - be read -- Options -l and -ll now do quick binary check on first buffer and skip - formatting if first buffer has binary - still check at end to note - if formatting was done on file that was later determined to be binary, - but now potential file corruption is generally avoided -- Main binary check now uses new algorithm that should also treat UTF-8 and - other similar encodings as text, allowing proper line end translation - for UTF-8 files -- When output is not updatable by seeking back and Zip64 is enabled, output - is forced to Zip64 to avoid possible later need for Zip64 when not enabled -- More work on splits, but still not usable -- Fixes for djgpp -- Add log file capability to save all errors and optionally messages -- Add code to test for a Zip64 archive when compiled without Zip64 support -- New VC6 projects for Win32 and WinDLL -- Updates to extended help -- Changes to force-zip64 option -- ZE_BIG error now given also for files too big to read or write -- Fix file delete bug -- Update license -- Update export documentation -- Add VMS extended filename support -- Add directory traversal improvements, some for Win32 ports and some for - all ports, that can result in a 10 times increase in speed in some cases - - -New things in Zip 3.0d - -- Some large file crypt fixes -- Some updates to support WiZ -- On VMS, changed -V (/VMS) processing to truncate file at EOF, allowing - greater compatability with non-VMS systems. New -VV (/VMS=ALL) option - saves all allocated blocks in a file. (Previously, -V did neither.) -- On VMS, pushed 2GB file size limit with -V out to 4GB -- On VMS (recent, non-VAX), with SET PROCESS /PARSE = EXTEND, - command-line case is preserved. This obviates quoting upper-case - options, like -V, when enabled -- On VMS, fixed problems with mixed-case directory names. Also changed - to keep ODS5 extended file name escape characters ("^") out of the - archived names in simple cases -- Changes to the display dots -- Option -W should now force wildcard matching to not cross directory - separators. For example, a/b*r/d will match a/bar/d but not a/ba/r/d -- Option -nw should turn off all wildcard matching so foo[bar] is matched - literally and [bar] is not considered a regular expression -- Atheos port -- Debugging of Unix and VMS large file ports. Most features may work now - on these ports for large files. Still need to fix 2 GB to 4 GB when not - compiled with large file support -- On VMS, added an open callback function which (where supported) senses - the process RMS_DEFAULT values for file extend quantity (deq) - multi-block count (mbc), and multi-buffer count (mbf), and sets the - FAB/RAB parameters accordingly. The default deq is now much larger - than before (16384 blocks, was none), and the default mbc is now 127 - (up from 64), speeding creation of a large archive file. The "-v" - option shows some of the activity. On old VMS versions, RMS_DEFAULT - sensing (GETJPI) fails (silently, without "-v"), and no changes will - be made. Even there, (DCL) SET RMS /EXTEND = can help - performance. RMS_DEFAULT values override built-in default values. - - -New things in Zip 3.0c - -- Converted to using 64-bit file environment instead of transitional functions - like fseeko64 for ports that support it -- Added "--" argument to read all following arguments as paths -- Second help page added -- Binary detection adjusted from 20% binary is binary to 2% -- When -R and -i used together now -i has precedence over -R -- Archive names with spaces can now be tested on MSDOS and Win32 - - -New things in Zip 3.0b - -- Fixed ifdefs so can test base code by compiling with NO_LARGE_FILE_SUPPORT, then - compiling with NO_ZIP64_SUPPORT to test 64-bit file calls (if port enables) but - otherwise use base code, and compiling normally to enable Zip64 code -- Unix Zip64 fixes - should now be able to create and read large files -- WinDLL changes to support Zip64. Zip 3.0 dll named Zip32z64.dll -- New VB example to show use of Zip32z64.dll -- New options -sc (show final command line and exit) and -sd (show each - step zip is doing, a little different than verbose which is still there) added - to help debug but both or at least -sd might go away in the release -- Some minor posted bugs fixed (see Changes) - - -New things in Zip 3.0a - -- Initial Zip64 support allowing large files and large numbers of files -- New command line processor -- Other changes, see file Changes - - -Note: Zip 2.4 was never released. That code was the start of the Zip 3.0 -effort above. - - -New things in Zip 2.3 - -- IBM OS/390 port (Unix like, but EBCDIC) by Paul von Behren -- Apple Macintosh (MACOS) port by Dirk Haase -- Theos port by Jean-Michel Dubois -- Multibyte characterset support by Yoshioka Tsuneo -- Support for ISO 8601 date format with -t and -tt options -- Info-ZIP license - - -New things in Zip 2.2 - -- BEOS port by Chris Herborth -- QDOS port by Jonathan Hudson -- TANDEM port by Dave Smith -- WINDLL port (16-bit Win 3.x and 32-bit WinNT/Win95) by Mike White -- SYSV packages support by John Bush -- zip -P SeCrEt encrypts entries in the zip file with password SeCrEt - (WARNING: THIS IS INSECURE, use at your own risk) -- zip -R recurses into subdirectories of current dir like "PKZIP -rP" -- zip -x@exclude.lst excludes files specified in the file exclude.lst -- zip -i@include.lst includes files specified in the file include.lst -- zip -@ only handles one filename per line, but supports whitespace in names -- zip -t mmddyyyy, 4 digit year number for uniqueness of years beyond 2000 -- zip -tt mmddyyyy only includes files before a specified date diff --git a/third_party/infozip/zip/WHERE b/third_party/infozip/zip/WHERE deleted file mode 100644 index 94a0d55c6..000000000 --- a/third_party/infozip/zip/WHERE +++ /dev/null @@ -1,261 +0,0 @@ -__________________________________________________________________________ - - This is the Info-ZIP file ``WHERE,'' last updated on 1 March 2005. -__________________________________________________________________________ - - This file is out of date. We plan to update the structure of the ftp - site shortly and should be updating this file as soon as that's done. - - The latest version of this file can be found online at: - - ftp://ftp.info-zip.org/pub/infozip/doc/WHERE - - Note that some ftp sites may not yet have the latest versions of Zip - and UnZip when you read this. The latest versions always appear in - ftp://ftp.info-zip.org/pub/infozip/ (and subdirectories thereof) first, - except for encryption binaries, which always appear in - ftp://ftp.icce.rug.nl/infozip/ (and subdirectories) first. - - IF YOU FIND AN ERROR: please let us know! We don't have time to - check each and every site personally (or even collectively), so any - number of the sites listed below may have moved or disappeared en- - tirely. E-mail to Zip-Bugs@lists.wku.edu and we'll update this file. -__________________________________________________________________________ - - -Info-ZIP's home WWW site is listed on Yahoo and is at: - - ftp://ftp.info-zip.org/pub/infozip/Info-ZIP.html (master version) - http://ftp.info-zip.org/pub/infozip/ (master version) - http://www.info-zip.org/ - -Note that the old sites at http://www.cdrom.com/pub/infozip/ and -http://www.freesoftware.com/pub/infozip are PERMANENTLY BROKEN. They -cannot be updated or removed, apparently. - -The Zip and UnZip pages have links to most known mirror sites carrying our -source and/or binary distributions, and they generally are more up-to-date -and have better information than what you are reading: - - ftp://ftp.info-zip.org/pub/infozip/Zip.html - ftp://ftp.info-zip.org/pub/infozip/UnZip.html - -The related zlib package by Info-ZIP's Jean-loup Gailly and Mark Adler is at: - - http://www.zlib.net/ - -Source-code archives for Info-ZIP's portable Zip, UnZip, and related -utilities: - - zip231.zip Zip 2.31 (deflation; includes zipnote/zipsplit/zipcloak) - zip231.tar.Z ditto, compress'd tar format - - zip11.zip Zip 1.1 (shrinking, implosion; compatible w. PKUNZIP 1.1) - zip11.tar.Z ditto, compress'd tar format - - unzip552.zip UnZip 5.52 (all methods[*]; unzip/funzip/unzipsfx/zipgrep) - unzip552.tar.gz ditto, gzip'd tar format - unzip552.tar.Z ditto, compress'd tar format - - unred552.zip UnZip 5.52 add-on, contains copyrighted unreduce support - - zcrypt29.zip encryption support for Zip 2.3[**] - zcrypt10.zip encryption support for Zip 1.1 - - MacZip106src.zip contains all the GUI stuff and the project files to build - the MacZip main-app. To build MacZip successfully, both - the Zip 2.31 and UnZip 5.52 sources are required, too. - - wiz502.zip WiZ 5.02, Windows 9x/NT GUI front-end for Info-ZIP DLLs - wiz502+dlls.zip WiZ 5.02, Windows 9x/NT GUI front-end plus DLL sources - -[*] Unreducing is disabled by default, but is available as add-on. - As of July 2004, Unisys's LZW patent was expired worldwide, and - unshrinking is turned on by default since the release of UnZip 5.52. - See UnZip's INSTALL file for details. - -[**] As of January 2000, US export regulations were amended to allow export - of free encryption source code from the US. As of June 2002, these - regulations were further relaxed to allow export of encryption binaries - associated with free encryption source code. The Zip 2.31, UnZip 5.52 - and Wiz 5.02 archives now include full crypto source code. As of the - Zip 2.31 release, all official binaries include encryption support; the - former "zcr" archives ceased to exist. - (Note that restrictions may still exist in other countries, of course.) - -Executables archives (and related files) for Info-ZIP's software; not all -of these will be immediately available due to lack of access to appropriate -systems on the part of Info-ZIP members. - - zip231x.zip MSDOS executables and docs - zip231x1.zip OS/2 1.x (16-bit) executables and docs - zip231x2.zip OS/2 2/3/4.x (32-bit) executables and docs - zip231xA.zip Amiga executables and docs - zip231xB.zip BeOS executables and docs - zip231xC.zip VM/CMS executable and docs - zip231xK.zip Tandem NSK executables and docs - zip231xM.xmit MVS classic executable - zip231xM-docs.zip MVS classic port, docs only - zip231dN.zip WinNT/Win9x (Intel) DLL, header files, docs - zip231xN.zip WinNT/Win9x (Intel) executables and docs - zip231xN-axp.zip WinNT (Alpha AXP) executables and docs - zip231xN-mip.zip WinNT (MIPS R4000) executables and docs - zip231xN-ppc.zip WinNT (PowerPC) executables and docs - zip231xO.zip IBM OS/390 Open Edition binaries and docs - zip231xQ.zip SMS/QDOS executables and docs - zip231xR.zip Acorn RISC OS executables and docs - zip231xT.zip Atari TOS executables and docs - zip231-vms-axp-obj.zip - VMS (Alpha AXP) object libs, link procedure and docs - zip231-vms-axp-exe.zip - VMS (Alpha AXP) executables for VMS 6.1 or later and docs - zip231-vms-vax-decc-obj.zip - VMS (VAX) object libs (new DEC C), link procedure and docs - zip231-vms-vax-decc-exe.zip - VMS (VAX) executables (DEC C) for VMS 6.1 or later; docs - zip231-vms-vax-vaxc-obj.zip - VMS (VAX) object libs (old VAX C), link procedure and docs - zip231x.hqx Macintosh BinHex'd executables and docs - - unz552x.exe MSDOS self-extracting executable (16-bit unzip, ..., docs) - unz552x3.exe MSDOS self-extracting executable (16-, 32-bit unzip, docs) - unz552x1.exe OS/2 1.x (16-bit) self-extracting executables and docs - unz552x2.exe OS/2 2/3/4.x (32-bit) self-extracting executables and docs - unz552d2.zip OS/2 2/3/4.x (32-bit) DLL, header file, demo exe and docs - unz552xA.ami Amiga self-extracting executables and docs - unz552xA.lha Amiga executables and docs, LHa archive - unz552xB.sfx BeOS self-extracting executables and docs - unz552xB.tar.gz BeOS executables and docs, gzip'd tar archive - unz552xC.mod VM/CMS executable module in "packed" format - unz552xC-docs.zip VM/CMS docs, only - unz552xF.zip FlexOS executable and docs - unz552xK.zip Tandem NSK executable and docs - unz552xM.xmit MVS classic executable - unz552xM-docs.zip MVS classic port, docs only - unz552dN.zip NT4/W2K/XP/2K3/W9x (32-bit Intel) DLL, header files, docs - unz552xN.exe NT/2K/XP/2K3/W9x self-extracting i386 executables and docs - unz552xN-axp.exe WinNT (Alpha AXP) self-extracting executables and docs - unz552xN-mip.exe WinNT (MIPS R4000) self-extracting executables and docs - unz552xN-ppc.exe WinNT (PowerPC) self-extracting executables and docs - unz552xQ.sfx SMS/QDOS self-extracting executables and docs - unz552xO.tar.Z IBM OS/390 Open edition (Unix-like), exes and docs - unz552xR.exe Acorn RISC OS self-extracting executables and docs - unz552xR.spk Acorn RISC OS Spark'd executables and docs - unz552xT.tos Atari TOS self-extracting executables and docs - unz552x-vms-axp-obj.bck VMS backup saveset, - contains UnZip (Alpha) obj libs, link procedure, docs - unz552x-vms-axp-obj.exe VMS (Alpha AXP) SFX archive (statically linked), - contains UnZip (Alpha) obj libs, link procedure, docs - unz552x-vms-axp-exe.exe VMS (Alpha AXP) SFX archive (dynamically linked), - contains UnZip (Alpha AXP, DEC C) executables and docs, - smaller than object archive, but requires VMS 6.1 - unz552x-vms-vax-decc-obj.bck VMS backup saveset, - contains UnZip (new DEC C) obj libs, link procedure, docs - unz552x-vms-vax-decc-obj.exe VMS (VAX) SFX archive (statically linked), - contains UnZip (new DEC C) obj libs, link procedure, docs - unz552x-vms-vax-decc-exe.exe VMS (VAX) SFX archive (dynamically linked), - contains UnZip (new DEC C) executables and docs, - smaller than object archive, but requires VMS 6.1 - unz552x-vms-vax-vaxc-obj.bck VMS backup saveset, - contains UnZip (old VAX C) obj libs, link procedure, docs - unz552x-vms-vax-vaxc-obj.exe VMS (VAX) SFX archive (statically linked), - contains UnZip (old VAX C) obj libs, link procedure, docs - unz552x.hqx Macintosh BinHex'd executables and docs for unzip - (unz552x.tar.{Z,gz} Unix exes/docs for Solaris 2.x, SCO Unix, Linux, etc., - depending on directory/location; generally only provided - in cases where the OS does *not* ship with a bundled C - compiler) - - MacZip106nc.hqx Macintosh combined Zip&UnZip application with GUI, - executables and docs (no encryption) - MacZip106c.hqx Macintosh combined Zip&UnZip application with GUI, - executables and docs (with encryption) - - wiz502xN.exe WiZ 5.02 32-bit (Win9x/NT/2K/XP/2K3) app+docs (self-extr.) - - UnzpHist.zip complete changes-history of UnZip and its precursors - ZipHist.zip complete changes-history of Zip - -ftp/web sites for the US-exportable sources and executables: - - NOTE: Look for the Info-ZIP file names given above (not PKWARE or third- - party stuff) in the following locations. Some sites like to use slightly - different names, such as zip-2.31.tar.gz instead of zip231.tar.Z. - - ftp://ftp.info-zip.org/pub/infozip/ [THE INFO-ZIP HOME SITE] - ftp://sunsite.doc.ic.ac.uk/packages/zip/ [MIRRORS THE INFO-ZIP HOME SITE] - ftp://unix.hensa.ac.uk/mirrors/uunet/pub/archiving/zip/ - - ftp://ftp.cmdl.noaa.gov/aerosol/doc/archiver/{all,dos,os2,mac,vax_alpha}/ - ftp://garbo.uwasa.fi/pc/arcers/ [AND OTHER GARBO MIRRORS] - ftp://garbo.uwasa.fi/unix/arcers/ [AND OTHER GARBO MIRRORS] - ftp://ftp.elf.stuba.sk/pub/pc/pack/ [AND OTHER STUBA MIRRORS] - ftp://ftp-os2.cdrom.com/pub/os2/archiver/ - ftp://ftp-os2.nmsu.edu/os2/archiver/ - ftp://ftp.informatik.tu-muenchen.de/pub/comp/os/os2/archiver/ - ftp://sumex-aim.stanford.edu/info-mac/cmp/ - ftp://ftp.wustl.edu/pub/aminet/util/arc/ [AND OTHER AMINET MIRRORS] - ftp://atari.archive.umich.edu/pub/Archivers/ [AND OTHER UMICH MIRRORS] - http://www.umich.edu/~archive/atari/Archivers/ - ftp://jake.educom.com.au/pub/infozip/acorn/ [Acorn RISC OS] - http://www.sitec.net/maczip/ [MacZip port] - -ftp/web sites for the encryption and decryption sources and/or executables: - - Outside the US: - ftp://ftp.info-zip.org/pub/infozip/ [THE INFO-ZIP HOME SITE] - ftp://ftp.icce.rug.nl/infozip/ [THE INFO-ZIP ENCRYPTION HOME SITE] - ftp://ftp.elf.stuba.sk/pub/pc/pack/ - ftp://garbo.uwasa.fi/pc/arcers/ - ftp://ftp.inria.fr/system/arch-compr/ - ftp://ftp.leo.org/pub/comp/os/os2/leo/archiver/ - (mail server at ftp-mailer@ftp.leo.org) - - ftp://ftp.win.tue.nl/pub/compression/zip/ - ftp://ftp.uni-erlangen.de/pub/pc/msdos/arc-utils/zip/ - - -The primary distribution site for the MacZip port can be found at: - - http://www.sitec.net/maczip/ - -ftp sites for VMS-format Zip and UnZip packages (sources, object files and -executables, no encryption/decryption--see also "Mail servers" section below): - - ftp.spc.edu [192.107.46.27] and ftp.wku.edu: - - [.MACRO32]AAAREADME.TXT - [.MACRO32.SAVESETS]UNZIP.BCK or UNZIP.ZIP (if already have older version) - [.MACRO32.SAVESETS]ZIP.ZIP - -To find other ftp/web sites: - - The "archie" ftp database utility can be used to find an ftp site near - you (although the command-line versions always seem to find old ver- - sions...the `FTPsearch' server at http://ftpsearch.ntnu.no/ftpsearch - --formerly `Archie 95'--is quite up-to-date, however). Or check a stan- - dard WWW search engine like AltaVista (http://www.altavista.digital.com/) - or Yahoo (http://www.yahoo.com/). If you don't know how to use these, - DON'T ASK US--read the web sites' help pages or check the Usenet groups - news.announce.newusers or news.answers or some such, or ask your system - administrator. - -Mail servers: - - To get the encryption sources by e-mail, send the following commands - to ftp-mailer@informatik.tu-muenchen.de: - - get /pub/comp/os/os2/archiver/zcrypt29.zip - quit - - To get the VMS Zip/UnZip package by e-mail, send the following - commands in the body of a mail message to fileserv@wku.edu (the - "HELP" command is also accepted): - - SEND FILESERV_TOOLS - SEND UNZIP - SEND ZIP - - To get Atari executables by e-mail, send a message to - atari@atari.archive.umich.edu for information about the mail server. -__________________________________________________________________________ diff --git a/third_party/infozip/zip/timezone.c b/third_party/infozip/zip/timezone.c deleted file mode 100644 index 54966dc98..000000000 --- a/third_party/infozip/zip/timezone.c +++ /dev/null @@ -1,816 +0,0 @@ -/* clang-format off */ -/* - timezone.c - Zip 3 - - Copyright (c) 1990-2004 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2003-May-08 or later - (the contents of which are also included in zip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html -*/ -/* Replacement time library functions, based on platform independent public - * domain timezone code from ftp://elsie.nci.nih.gov/pub, with mktime and - * mkgmtime from our own mktime.c in Zip. - * - * Contains: tzset() - * __tzset() - * gmtime() - * localtime() - * mktime() - * mkgmtime() - * GetPlatformLocalTimezone() [different versions] - */ - -/* HISTORY/CHANGES - * 17 Jun 00, Paul Kienitz, added the PD-based tzset(), localtime(), and so on - * to amiga/filedate.c, replacing GNU-based functions which had - * replaced time_lib.c, both having been rejected for licensing - * reasons. Support for timezone files and leap seconds was removed. - * - * 23 Aug 00, Paul Kienitz, split into separate timezone.c file, made platform - * independent, copied in mktime() and mkgmtime() from Zip, renamed - * locale_TZ as GetPlatformLocalTimezone(), for use as a generic - * hook by other platforms. - */ - -#ifndef __timezone_c -#define __timezone_c - - -#include "third_party/infozip/zip/zip.h" -#include "third_party/infozip/zip/timezone.h" -#include "libc/str/str.h" -#include "libc/errno.h" - -#ifdef IZTZ_DEFINESTDGLOBALS -long timezone = 0; -int daylight = 0; -char *tzname[2]; -#endif - -#ifndef IZTZ_GETLOCALETZINFO -# define IZTZ_GETLOCALETZINFO(ptzstruct, pgenrulefunct) (FALSE) -#endif - -int real_timezone_is_set = FALSE; /* set by tzset() */ - - -#define TZDEFRULESTRING ",M4.1.0,M10.5.0" -#define TZDEFAULT "EST5EDT" - -#define SECSPERMIN 60 -#define MINSPERHOUR 60 -#define HOURSPERDAY 24 -#define DAYSPERWEEK 7 -#define DAYSPERNYEAR 365 -#define DAYSPERLYEAR 366 -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) -#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) -#define MONSPERYEAR 12 - -#define EPOCH_WDAY 4 /* Jan 1, 1970 was thursday */ -#define EPOCH_YEAR 1970 -#define TM_YEAR_BASE 1900 -#define FIRST_GOOD_YEAR ((time_t) -1 < (time_t) 1 ? EPOCH_YEAR-68 : EPOCH_YEAR) -#define LAST_GOOD_YEAR (EPOCH_YEAR + ((time_t) -1 < (time_t) 1 ? 67 : 135)) - -#define YDAYS(month, year) yr_days[leap(year)][month] - -/* Nonzero if `y' is a leap year, else zero. */ -#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0) - -/* Number of leap years from EPOCH_YEAR to `y' (not including `y' itself). */ -#define _P4 ((EPOCH_YEAR / 4) * 4 + 1) -#define _P100 ((EPOCH_YEAR / 100) * 100 + 1) -#define _P400 ((EPOCH_YEAR / 400) * 400 + 1) -#define nleap(y) (((y) - _P4) / 4 - ((y) - _P100) / 100 + ((y) - _P400) / 400) - -/* Length of month `m' (0 .. 11) */ -#define monthlen(m, y) (yr_days[0][(m)+1] - yr_days[0][m] + \ - ((m) == 1 && leap(y))) - -/* internal module-level constants */ -#ifndef IZ_MKTIME_ONLY -static ZCONST char gmt[] = "GMT"; -static ZCONST int mon_lengths[2][MONSPERYEAR] = { - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; -#endif /* !IZ_MKTIME_ONLY */ -static ZCONST int yr_days[2][MONSPERYEAR+1] = { - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } -}; -#ifndef IZ_MKTIME_ONLY -static ZCONST int year_lengths[2] = { - DAYSPERNYEAR, DAYSPERLYEAR -}; - -/* internal variables */ -static struct state statism; - - -/* prototypes of static functions */ -static time_t transtime OF((ZCONST time_t janfirst, ZCONST int year, - ZCONST struct rule * ZCONST rulep, - ZCONST long offset)); -static void generate_transitions OF((register struct state * ZCONST sp, - ZCONST struct rule * ZCONST start, - ZCONST struct rule * ZCONST end)); -static ZCONST char *getzname OF((ZCONST char *strp)); -static ZCONST char *getnum OF((ZCONST char *strp, int * ZCONST nump, - ZCONST int min, ZCONST int max)); -static ZCONST char *getsecs OF((ZCONST char *strp, long * ZCONST secsp)); -static ZCONST char *getoffset OF((ZCONST char *strp, long * ZCONST offsetp)); -static ZCONST char *getrule OF((ZCONST char *strp, struct rule * ZCONST rulep)); -static int Parse_TZ OF((ZCONST char *name, register struct state * ZCONST sp)); - - -static time_t transtime(janfirst, year, rulep, offset) - ZCONST time_t janfirst; - ZCONST int year; - ZCONST struct rule * ZCONST rulep; - ZCONST long offset; -{ - register int leapyear; - register time_t value; - register int i; - int d, m1, yy0, yy1, yy2, dow; - - value = 0; - leapyear = leap(year); - switch (rulep->r_type) { - - case JULIAN_DAY: - /* - ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap - ** years. - ** In non-leap years, or if the day number is 59 or less, just - ** add SECSPERDAY times the day number-1 to the time of - ** January 1, midnight, to get the day. - */ - value = janfirst + (rulep->r_day - 1) * SECSPERDAY; - if (leapyear && rulep->r_day >= 60) - value += SECSPERDAY; - break; - - case DAY_OF_YEAR: - /* - ** n - day of year. - ** Just add SECSPERDAY times the day number to the time of - ** January 1, midnight, to get the day. - */ - value = janfirst + rulep->r_day * SECSPERDAY; - break; - - case MONTH_NTH_DAY_OF_WEEK: - /* - ** Mm.n.d - nth "dth day" of month m. - */ - value = janfirst; -/* - for (i = 0; i < rulep->r_mon - 1; ++i) - value += mon_lengths[leapyear][i] * SECSPERDAY; -*/ - value += yr_days[leapyear][rulep->r_mon - 1] * SECSPERDAY; - - /* - ** Use Zeller's Congruence to get day-of-week of first day of - ** month. - */ - m1 = (rulep->r_mon + 9) % 12 + 1; - yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; - yy1 = yy0 / 100; - yy2 = yy0 % 100; - dow = ((26 * m1 - 2) / 10 + - 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; - if (dow < 0) - dow += DAYSPERWEEK; - - /* - ** "dow" is the day-of-week of the first day of the month. Get - ** the day-of-month (zero-origin) of the first "dow" day of the - ** month. - */ - d = rulep->r_day - dow; - if (d < 0) - d += DAYSPERWEEK; - for (i = 1; i < rulep->r_week; ++i) { - if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1]) - break; - d += DAYSPERWEEK; - } - - /* - ** "d" is the day-of-month (zero-origin) of the day we want. - */ - value += d * SECSPERDAY; - break; - } - - /* - ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in - ** question. To get the Epoch-relative time of the specified local - ** time on that day, add the transition time and the current offset - ** from UTC. - */ - return value + rulep->r_time + offset; -} - -static void generate_transitions(sp, start, end) - register struct state * ZCONST sp; - ZCONST struct rule * ZCONST start; - ZCONST struct rule * ZCONST end; -{ - register int year; - register time_t janfirst; - time_t starttime; - time_t endtime; - long stdoffset = -sp->ttis[0].tt_gmtoff; - long dstoffset = -sp->ttis[1].tt_gmtoff; - register time_t * atp; - register unsigned char * typep; - - /* - ** Two transitions per year, from EPOCH_YEAR to LAST_GOOD_YEAR. - */ - sp->timecnt = 2 * (LAST_GOOD_YEAR - EPOCH_YEAR + 1); - atp = sp->ats; - typep = sp->types; - janfirst = 0; - for (year = EPOCH_YEAR; year <= LAST_GOOD_YEAR; ++year) { - starttime = transtime(janfirst, year, start, stdoffset); - endtime = transtime(janfirst, year, end, dstoffset); - if (starttime > endtime) { - *atp++ = endtime; - *typep++ = 0; /* DST ends */ - *atp++ = starttime; - *typep++ = 1; /* DST begins */ - } else { - *atp++ = starttime; - *typep++ = 1; /* DST begins */ - *atp++ = endtime; - *typep++ = 0; /* DST ends */ - } - janfirst += year_lengths[leap(year)] * SECSPERDAY; - } -} - -static ZCONST char *getzname(strp) - ZCONST char *strp; -{ - register char c; - - while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' && - c != '+') - ++strp; - return strp; -} - -static ZCONST char *getnum(strp, nump, min, max) - ZCONST char *strp; - int * ZCONST nump; - ZCONST int min; - ZCONST int max; -{ - register char c; - register int num; - - if (strp == NULL || !isdigit(c = *strp)) - return NULL; - num = 0; - do { - num = num * 10 + (c - '0'); - if (num > max) - return NULL; /* illegal value */ - c = *++strp; - } while (isdigit(c)); - if (num < min) - return NULL; /* illegal value */ - *nump = num; - return strp; -} - -static ZCONST char *getsecs(strp, secsp) - ZCONST char *strp; - long * ZCONST secsp; -{ - int num; - - /* - ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like - ** "M10.4.6/26", which does not conform to Posix, - ** but which specifies the equivalent of - ** ``02:00 on the first Sunday on or after 23 Oct''. - */ - strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); - if (strp == NULL) - return NULL; - *secsp = num * (long) SECSPERHOUR; - if (*strp == ':') { - ++strp; - strp = getnum(strp, &num, 0, MINSPERHOUR - 1); - if (strp == NULL) - return NULL; - *secsp += num * SECSPERMIN; - if (*strp == ':') { - ++strp; - /* `SECSPERMIN' allows for leap seconds. */ - strp = getnum(strp, &num, 0, SECSPERMIN); - if (strp == NULL) - return NULL; - *secsp += num; - } - } - return strp; -} - -static ZCONST char *getoffset(strp, offsetp) - ZCONST char *strp; - long * ZCONST offsetp; -{ - register int neg = 0; - - if (*strp == '-') { - neg = 1; - ++strp; - } else if (*strp == '+') - ++strp; - strp = getsecs(strp, offsetp); - if (strp == NULL) - return NULL; /* illegal time */ - if (neg) - *offsetp = -*offsetp; - return strp; -} - -static ZCONST char *getrule(strp, rulep) - ZCONST char *strp; - struct rule * ZCONST rulep; -{ - if (*strp == 'J') { - /* - ** Julian day. - */ - rulep->r_type = JULIAN_DAY; - ++strp; - strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); - } else if (*strp == 'M') { - /* - ** Month, week, day. - */ - rulep->r_type = MONTH_NTH_DAY_OF_WEEK; - ++strp; - strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); - if (strp == NULL) - return NULL; - if (*strp++ != '.') - return NULL; - strp = getnum(strp, &rulep->r_week, 1, 5); - if (strp == NULL) - return NULL; - if (*strp++ != '.') - return NULL; - strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); - } else if (isdigit(*strp)) { - /* - ** Day of year. - */ - rulep->r_type = DAY_OF_YEAR; - strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); - } else return NULL; /* invalid format */ - if (strp == NULL) - return NULL; - if (*strp == '/') { - /* - ** Time specified. - */ - ++strp; - strp = getsecs(strp, &rulep->r_time); - } else - rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ - return strp; -} - -static int Parse_TZ(name, sp) - ZCONST char *name; - register struct state * ZCONST sp; -{ - ZCONST char * stdname; - ZCONST char * dstname; - size_t stdlen; - size_t dstlen; - long stdoffset; - long dstoffset; - register char * cp; - - dstname = NULL; - stdname = name; - name = getzname(name); - stdlen = name - stdname; - if (stdlen < 3) - return -1; - if (*name == '\0') - return -1; - name = getoffset(name, &stdoffset); - if (name == NULL) - return -1; - if (*name != '\0') { - dstname = name; - name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ - if (dstlen < 3) - return -1; - if (*name != '\0' && *name != ',' && *name != ';') { - name = getoffset(name, &dstoffset); - if (name == NULL) - return -1; - } else - dstoffset = stdoffset - SECSPERHOUR; - if (*name == '\0') - name = TZDEFRULESTRING; - if (*name == ',' || *name == ';') { - struct rule start; - struct rule end; - - ++name; - if ((name = getrule(name, &start)) == NULL) - return -1; - if (*name++ != ',') - return -1; - if ((name = getrule(name, &end)) == NULL) - return -1; - if (*name != '\0') - return -1; - sp->typecnt = 2; /* standard time and DST */ - sp->ttis[0].tt_gmtoff = -stdoffset; - sp->ttis[0].tt_isdst = 0; - sp->ttis[0].tt_abbrind = 0; - sp->ttis[1].tt_gmtoff = -dstoffset; - sp->ttis[1].tt_isdst = 1; - sp->ttis[1].tt_abbrind = stdlen + 1; - generate_transitions(sp, &start, &end); - } - } else { - dstlen = 0; - sp->typecnt = 1; /* only standard time */ - sp->timecnt = 0; - sp->ttis[0].tt_gmtoff = -stdoffset; - sp->ttis[0].tt_isdst = 0; - sp->ttis[0].tt_abbrind = 0; - } - sp->charcnt = stdlen + 1; - if (dstlen != 0) - sp->charcnt += dstlen + 1; - if ((size_t) sp->charcnt > sizeof(sp->chars)) - return -1; - cp = sp->chars; - (void) strncpy(cp, stdname, stdlen); - cp += stdlen; - *cp++ = '\0'; - if (dstlen != 0) { - (void) strncpy(cp, dstname, dstlen); - *(cp + dstlen) = '\0'; - } - return 0; -} - -void tzset() -{ - char *TZstring; - int dstfirst; - static char *old_TZstring = NULL; - - TZstring = getenv("TZ"); /* read TZ envvar */ - if (old_TZstring && TZstring && !strcmp(old_TZstring, TZstring)) - /* do not repeatedly parse an unchanged TZ specification */ - return; - if ((TZstring && TZstring[0] && Parse_TZ(TZstring, &statism) == 0) - || IZTZ_GETLOCALETZINFO(&statism, generate_transitions) - || Parse_TZ(gmt, &statism) == 0) { - daylight = statism.typecnt > 1; - dstfirst = daylight && statism.ttis[0].tt_isdst && !statism.ttis[1].tt_isdst; - timezone = -statism.ttis[dstfirst].tt_gmtoff; - tzname[0] = statism.chars + statism.ttis[dstfirst].tt_abbrind; - tzname[1] = statism.chars + statism.ttis[!dstfirst].tt_abbrind; - real_timezone_is_set = TRUE; - if (TZstring) { - if (old_TZstring) - old_TZstring = realloc(old_TZstring, strlen(TZstring) + 1); - else - old_TZstring = malloc(strlen(TZstring) + 1); - if (old_TZstring) - strcpy(old_TZstring, TZstring); - } - } else { - timezone = 0; /* default is GMT0 which means no offsets */ - daylight = 0; /* from local system time */ - real_timezone_is_set = FALSE; - if (old_TZstring) { - free(old_TZstring); - old_TZstring = NULL; - } - } -#ifdef IZTZ_SETLOCALTZINFO - /* Some SAS/C library functions, e.g. stat(), call library */ - /* __tzset() themselves. So envvar TZ *must* exist in order to */ - /* to get the right offset from GMT. XXX TRY HARD to fix this! */ - set_TZ(timezone, daylight); -#endif /* IZTZ_SETLOCALTZINFO */ -} - -/* XXX Does this also help SAS/C library work? */ -void __tzset() -{ - if (!real_timezone_is_set) tzset(); -} - -static struct tm _tmbuf; - -struct tm *gmtime(when) - ZCONST time_t *when; -{ - long days = *when / SECSPERDAY; - long secs = *when % SECSPERDAY; - int isleap; - - memset(&_tmbuf, 0, sizeof(_tmbuf)); /* get any nonstandard fields */ - _tmbuf.tm_wday = (days + EPOCH_WDAY) % 7; - _tmbuf.tm_year = EPOCH_YEAR - TM_YEAR_BASE; - isleap = leap(_tmbuf.tm_year + TM_YEAR_BASE); - while (days >= year_lengths[isleap]) { - days -= year_lengths[isleap]; - _tmbuf.tm_year++; - isleap = leap(_tmbuf.tm_year + TM_YEAR_BASE); - } - _tmbuf.tm_mon = 0; - _tmbuf.tm_yday = days; - while (days >= mon_lengths[isleap][_tmbuf.tm_mon]) - days -= mon_lengths[isleap][_tmbuf.tm_mon++]; - _tmbuf.tm_mday = days + 1; - _tmbuf.tm_isdst = 0; - _tmbuf.tm_sec = secs % SECSPERMIN; - _tmbuf.tm_min = (secs / SECSPERMIN) % SECSPERMIN; - _tmbuf.tm_hour = secs / SECSPERHOUR; - return &_tmbuf; -} - -struct tm *localtime(when) - ZCONST time_t *when; -{ - time_t localwhen = *when; - int timetype; - struct tm *ret; - - __tzset(); - if (statism.timecnt == 0 || localwhen < statism.ats[0]) - timetype = statism.ttis[0].tt_isdst && statism.typecnt > 1 && - !statism.ttis[1].tt_isdst; - else { - for (timetype = 1; timetype < statism.timecnt; ++timetype) - if (localwhen < statism.ats[timetype]) - break; - timetype = statism.types[timetype - 1]; - } - localwhen += statism.ttis[timetype].tt_gmtoff; - ret = gmtime(&localwhen); - ret->tm_isdst = statism.ttis[timetype].tt_isdst; - return ret; -} - -#ifdef NEED__ISINDST -int _isindst(tb) - struct tm *tb; -{ - time_t localt; /* time_t equivalent of given tm struct */ - time_t univt; /* assumed UTC value of given time */ - long tzoffset_adj; /* timezone-adjustment `remainder' */ - int bailout_cnt; /* counter of tries for tz correction */ - int timetype; - - __tzset(); - - /* when DST is unsupported in current timezone, DST is always off */ - if (statism.typecnt <= 1) return FALSE; - - localt = mkgmtime(tb); - if (localt == (time_t)-1) - /* specified time is out-of-range, default to FALSE */ - return FALSE; - - univt = localt - statism.ttis[0].tt_gmtoff; - bailout_cnt = 3; - do { - if (statism.timecnt == 0 || univt < statism.ats[0]) - timetype = statism.ttis[0].tt_isdst && statism.typecnt > 1 && - !statism.ttis[1].tt_isdst; - else { - for (timetype = 1; timetype < statism.timecnt; ++timetype) - if (univt < statism.ats[timetype]) - break; - timetype = statism.types[timetype - 1]; - } - if ((tzoffset_adj = localt - univt - statism.ttis[timetype].tt_gmtoff) - == 0L) - break; - univt += tzoffset_adj; - } while (--bailout_cnt > 0); - - /* return TRUE when DST is active at given time */ - return (statism.ttis[timetype].tt_isdst); -} -#endif /* NEED__ISINDST */ -#endif /* !IZ_MKTIME_ONLY */ - -/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT - of the local time and date in the exploded time structure `tm', - adjust out of range fields in `tm' and set `tm->tm_yday', `tm->tm_wday'. - If `tm->tm_isdst < 0' was passed to mktime(), the correct setting of - tm_isdst is determined and returned. Otherwise, mktime() assumes this - field as valid; its information is used when converting local time - to UTC. - Return -1 if time in `tm' cannot be represented as time_t value. */ - -time_t mktime(tm) - struct tm *tm; -{ - struct tm *ltm; /* Local time. */ - time_t loctime; /* The time_t value of local time. */ - time_t then; /* The time to return. */ - long tzoffset_adj; /* timezone-adjustment `remainder' */ - int bailout_cnt; /* counter of tries for tz correction */ - int save_isdst; /* Copy of the tm->isdst input value */ - - save_isdst = tm->tm_isdst; - loctime = mkgmtime(tm); - if (loctime == -1) { - tm->tm_isdst = save_isdst; - return (time_t)-1; - } - - /* Correct for the timezone and any daylight savings time. - The correction is verified and repeated when not correct, to - take into account the rare case that a change to or from daylight - savings time occurs between when it is the time in `tm' locally - and when it is that time in Greenwich. After the second correction, - the "timezone & daylight" offset should be correct in all cases. To - be sure, we allow a third try, but then the loop is stopped. */ - bailout_cnt = 3; - then = loctime; - do { - ltm = localtime(&then); - if (ltm == (struct tm *)NULL || - (tzoffset_adj = loctime - mkgmtime(ltm)) == 0L) - break; - then += tzoffset_adj; - } while (--bailout_cnt > 0); - - if (ltm == (struct tm *)NULL || tzoffset_adj != 0L) { - /* Signal failure if timezone adjustment did not converge. */ - tm->tm_isdst = save_isdst; - return (time_t)-1; - } - - if (save_isdst >= 0) { - if (ltm->tm_isdst && !save_isdst) - { - if (then + 3600 < then) - then = (time_t)-1; - else - then += 3600; - } - else if (!ltm->tm_isdst && save_isdst) - { - if (then - 3600 > then) - then = (time_t)-1; - else - then -= 3600; - } - ltm->tm_isdst = save_isdst; - } - - if (tm != ltm) /* `tm' may already point to localtime's internal storage */ - *tm = *ltm; - - return then; -} - - -#ifndef NO_TIME_T_MAX - /* Provide default values for the upper limit of the time_t range. - These are the result of the decomposition into a `struct tm' for - the time value 0xFFFFFFFEL ( = (time_t)-2 ). - Note: `(time_t)-1' is reserved for "invalid time"! */ -# ifndef TM_YEAR_MAX -# define TM_YEAR_MAX 2106 -# endif -# ifndef TM_MON_MAX -# define TM_MON_MAX 1 /* February */ -# endif -# ifndef TM_MDAY_MAX -# define TM_MDAY_MAX 7 -# endif -# ifndef TM_HOUR_MAX -# define TM_HOUR_MAX 6 -# endif -# ifndef TM_MIN_MAX -# define TM_MIN_MAX 28 -# endif -# ifndef TM_SEC_MAX -# define TM_SEC_MAX 14 -# endif -#endif /* NO_TIME_T_MAX */ - -/* Adjusts out-of-range values for `tm' field `tm_member'. */ -#define ADJUST_TM(tm_member, tm_carry, modulus) \ - if ((tm_member) < 0) { \ - tm_carry -= (1 - ((tm_member)+1) / (modulus)); \ - tm_member = (modulus-1) + (((tm_member)+1) % (modulus)); \ - } else if ((tm_member) >= (modulus)) { \ - tm_carry += (tm_member) / (modulus); \ - tm_member = (tm_member) % (modulus); \ - } - -/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT - of the Greenwich Mean time and date in the exploded time structure `tm'. - This function does always put back normalized values into the `tm' struct, - parameter, including the calculated numbers for `tm->tm_yday', - `tm->tm_wday', and `tm->tm_isdst'. - Returns -1 if the time in the `tm' parameter cannot be represented - as valid `time_t' number. */ - -time_t mkgmtime(tm) - struct tm *tm; -{ - int years, months, days, hours, minutes, seconds; - - years = tm->tm_year + TM_YEAR_BASE; /* year - 1900 -> year */ - months = tm->tm_mon; /* 0..11 */ - days = tm->tm_mday - 1; /* 1..31 -> 0..30 */ - hours = tm->tm_hour; /* 0..23 */ - minutes = tm->tm_min; /* 0..59 */ - seconds = tm->tm_sec; /* 0..61 in ANSI C. */ - - ADJUST_TM(seconds, minutes, 60) - ADJUST_TM(minutes, hours, 60) - ADJUST_TM(hours, days, 24) - ADJUST_TM(months, years, 12) - if (days < 0) - do { - if (--months < 0) { - --years; - months = 11; - } - days += monthlen(months, years); - } while (days < 0); - else - while (days >= monthlen(months, years)) { - days -= monthlen(months, years); - if (++months >= 12) { - ++years; - months = 0; - } - } - - /* Restore adjusted values in tm structure */ - tm->tm_year = years - TM_YEAR_BASE; - tm->tm_mon = months; - tm->tm_mday = days + 1; - tm->tm_hour = hours; - tm->tm_min = minutes; - tm->tm_sec = seconds; - - /* Set `days' to the number of days into the year. */ - days += YDAYS(months, years); - tm->tm_yday = days; - - /* Now calculate `days' to the number of days since Jan 1, 1970. */ - days = (unsigned)days + 365 * (unsigned)(years - EPOCH_YEAR) + - (unsigned)(nleap (years)); - tm->tm_wday = ((unsigned)days + EPOCH_WDAY) % 7; - tm->tm_isdst = 0; - - if (years < EPOCH_YEAR) - return (time_t)-1; - -#if (defined(TM_YEAR_MAX) && defined(TM_MON_MAX) && defined(TM_MDAY_MAX)) -#if (defined(TM_HOUR_MAX) && defined(TM_MIN_MAX) && defined(TM_SEC_MAX)) - if (years > TM_YEAR_MAX || - (years == TM_YEAR_MAX && - (tm->tm_yday > (YDAYS(TM_MON_MAX, TM_YEAR_MAX) + (TM_MDAY_MAX - 1)) || - (tm->tm_yday == (YDAYS(TM_MON_MAX, TM_YEAR_MAX) + (TM_MDAY_MAX - 1)) && - (hours > TM_HOUR_MAX || - (hours == TM_HOUR_MAX && - (minutes > TM_MIN_MAX || - (minutes == TM_MIN_MAX && seconds > TM_SEC_MAX) ))))))) - return (time_t)-1; -#endif -#endif - - return (time_t)(SECSPERDAY * (unsigned long)(unsigned)days + - SECSPERHOUR * (unsigned long)hours + - (unsigned long)(SECSPERMIN * minutes + seconds)); -} - -#endif /* __timezone_c */ diff --git a/third_party/infozip/zip/ttyio.h b/third_party/infozip/zip/ttyio.h deleted file mode 100644 index 4a397292b..000000000 --- a/third_party/infozip/zip/ttyio.h +++ /dev/null @@ -1,230 +0,0 @@ -/* clang-format off */ -/* - ttyio.h - Zip 3 - - Copyright (c) 1990-2005 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2005-Feb-10 or later - (the contents of which are also included in zip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html -*/ -/* - ttyio.h - */ - -#ifndef __ttyio_h /* don't include more than once */ -#define __ttyio_h - -#ifndef __crypt_h -# include "third_party/infozip/zip/crypt.h" /* ensure that encryption header file has been seen */ -#endif - -#if (CRYPT || (defined(UNZIP) && !defined(FUNZIP))) -/* - * Non-echo keyboard/console input support is needed and enabled. - */ - -#ifndef __G /* UnZip only, for now (DLL stuff) */ -# define __G -# define __G__ -# define __GDEF -# define __GPRO void -# define __GPRO__ -#endif - -#ifndef ZCONST /* UnZip only (until have configure script like Zip) */ -# define ZCONST const -#endif - -#if (defined(MSDOS) || defined(OS2) || defined(WIN32)) -# ifndef DOS_OS2_W32 -# define DOS_OS2_W32 -# endif -#endif - -#if (defined(DOS_OS2_W32) || defined(__human68k__)) -# ifndef DOS_H68_OS2_W32 -# define DOS_H68_OS2_W32 -# endif -#endif - -#if (defined(DOS_OS2_W32) || defined(FLEXOS)) -# ifndef DOS_FLX_OS2_W32 -# define DOS_FLX_OS2_W32 -# endif -#endif - -#if (defined(DOS_H68_OS2_W32) || defined(FLEXOS)) -# ifndef DOS_FLX_H68_OS2_W32 -# define DOS_FLX_H68_OS2_W32 -# endif -#endif - -#if (defined(__ATHEOS__) || defined(__BEOS__) || defined(UNIX)) -# ifndef ATH_BEO_UNX -# define ATH_BEO_UNX -# endif -#endif - -#if (defined(VM_CMS) || defined(MVS)) -# ifndef CMS_MVS -# define CMS_MVS -# endif -#endif - - -/* Function prototypes */ - -/* The following systems supply a `non-echo' character input function "getch()" - * (or an alias) and do not need the echoff() / echon() function pair. - */ -#ifdef AMIGA -# define echoff(f) -# define echon() -# define getch() Agetch() -# define HAVE_WORKING_GETCH -#endif /* AMIGA */ - -#ifdef ATARI -# define echoff(f) -# define echon() -# include -# define getch() (Cnecin() & 0x000000ff) -# define HAVE_WORKING_GETCH -#endif - -#ifdef MACOS -# define echoff(f) -# define echon() -# define getch() macgetch() -# define HAVE_WORKING_GETCH -#endif - -#ifdef NLM -# define echoff(f) -# define echon() -# define HAVE_WORKING_GETCH -#endif - -#ifdef QDOS -# define echoff(f) -# define echon() -# define HAVE_WORKING_GETCH -#endif - -#ifdef RISCOS -# define echoff(f) -# define echon() -# define getch() SWI_OS_ReadC() -# define HAVE_WORKING_GETCH -#endif - -#ifdef DOS_H68_OS2_W32 -# define echoff(f) -# define echon() -# ifdef WIN32 -# ifndef getch -# define getch() getch_win32() -# endif -# else /* !WIN32 */ -# ifdef __EMX__ -# ifndef getch -# define getch() _read_kbd(0, 1, 0) -# endif -# else /* !__EMX__ */ -# ifdef __GO32__ -# include -# define getch() getkey() -# else /* !__GO32__ */ -# include -# endif /* ?__GO32__ */ -# endif /* ?__EMX__ */ -# endif /* ?WIN32 */ -# define HAVE_WORKING_GETCH -#endif /* DOS_H68_OS2_W32 */ - -#ifdef FLEXOS -# define echoff(f) -# define echon() -# define getch() getchar() /* not correct, but may not be on a console */ -# define HAVE_WORKING_GETCH -#endif - -/* For VM/CMS and MVS, we do not (yet) have any support to switch terminal - * input echo on and off. The following "fake" definitions allow inclusion - * of crypt support and UnZip's "pause prompting" features, but without - * any echo suppression. - */ -#ifdef CMS_MVS -# define echoff(f) -# define echon() -#endif - -#ifdef TANDEM -# define echoff(f) -# define echon() -# define getch() zgetch() /* defined in TANDEMC */ -# define HAVE_WORKING_GETCH -#endif - -/* The THEOS C runtime library supplies the function conmask() to toggle - * terminal input echo on (conmask("e")) and off (conmask("n")). But, - * since THEOS C RTL also contains a working non-echo getch() function, - * the echo toggles are not needed. - */ -#ifdef THEOS -# define echoff(f) -# define echon() -# define HAVE_WORKING_GETCH -#endif - -/* VMS has a single echo() function in ttyio.c to toggle terminal - * input echo on and off. - */ -#ifdef VMS -# define echoff(f) echo(0) -# define echon() echo(1) -# define getch() tt_getch() -# define FGETCH(f) tt_getch() - int echo OF((int)); - int tt_getch OF((void)); -#endif - -/* For all other systems, ttyio.c supplies the two functions Echoff() and - * Echon() for suppressing and (re)enabling console input echo. - */ -#ifndef echoff -# define echoff(f) Echoff(__G__ f) -# define echon() Echon(__G) - void Echoff OF((__GPRO__ int f)); - void Echon OF((__GPRO)); -#endif - -/* this stuff is used by MORE and also now by the ctrl-S code; fileio.c only */ -#if (defined(UNZIP) && !defined(FUNZIP)) -# ifdef HAVE_WORKING_GETCH -# define FGETCH(f) getch() -# endif -# ifndef FGETCH - /* default for all systems where no getch()-like function is available */ - int zgetch OF((__GPRO__ int f)); -# define FGETCH(f) zgetch(__G__ f) -# endif -#endif /* UNZIP && !FUNZIP */ - -#if (CRYPT && !defined(WINDLL)) - char *getp OF((__GPRO__ ZCONST char *m, char *p, int n)); -#endif - -#else /* !(CRYPT || (UNZIP && !FUNZIP)) */ - -/* - * No need for non-echo keyboard/console input; provide dummy definitions. - */ -#define echoff(f) -#define echon() - -#endif /* ?(CRYPT || (UNZIP && !FUNZIP)) */ - -#endif /* !__ttyio_h */ diff --git a/third_party/libcxx/.clang-format b/third_party/libcxx/.clang-format new file mode 100644 index 000000000..dd596813f --- /dev/null +++ b/third_party/libcxx/.clang-format @@ -0,0 +1,13 @@ +BasedOnStyle: LLVM + +--- +Language: Cpp +Standard: Cpp03 + +AlwaysBreakTemplateDeclarations: true +PointerAlignment: Left + +# Disable formatting options which may break tests. +SortIncludes: false +ReflowComments: false +--- diff --git a/third_party/libcxx/CREDITS.TXT b/third_party/libcxx/CREDITS.TXT new file mode 100644 index 000000000..46a06c6ea --- /dev/null +++ b/third_party/libcxx/CREDITS.TXT @@ -0,0 +1,150 @@ +This file is a partial list of people who have contributed to the LLVM/libc++ +project. If you have contributed a patch or made some other contribution to +LLVM/libc++, please submit a patch to this file to add yourself, and it will be +done! + +The list is sorted by surname and formatted to allow easy grepping and +beautification by scripts. The fields are: name (N), email (E), web-address +(W), PGP key ID and fingerprint (P), description (D), and snail-mail address +(S). + +N: Saleem Abdulrasool +E: compnerd@compnerd.org +D: Minor patches and Linux fixes. + +N: Dan Albert +E: danalbert@google.com +D: Android support and test runner improvements. + +N: Dimitry Andric +E: dimitry@andric.com +D: Visibility fixes, minor FreeBSD portability patches. + +N: Holger Arnold +E: holgerar@gmail.com +D: Minor fix. + +N: Ruben Van Boxem +E: vanboxem dot ruben at gmail dot com +D: Initial Windows patches. + +N: David Chisnall +E: theraven at theravensnest dot org +D: FreeBSD and Solaris ports, libcxxrt support, some atomics work. + +N: Marshall Clow +E: mclow.lists@gmail.com +E: marshall@idio.com +D: C++14 support, patches and bug fixes. + +N: Jonathan B Coe +E: jbcoe@me.com +D: Implementation of propagate_const. + +N: Glen Joseph Fernandes +E: glenjofe@gmail.com +D: Implementation of to_address. + +N: Eric Fiselier +E: eric@efcs.ca +D: LFTS support, patches and bug fixes. + +N: Bill Fisher +E: william.w.fisher@gmail.com +D: Regex bug fixes. + +N: Matthew Dempsky +E: matthew@dempsky.org +D: Minor patches and bug fixes. + +N: Google Inc. +D: Copyright owner and contributor of the CityHash algorithm + +N: Howard Hinnant +E: hhinnant@apple.com +D: Architect and primary author of libc++ + +N: Hyeon-bin Jeong +E: tuhertz@gmail.com +D: Minor patches and bug fixes. + +N: Argyrios Kyrtzidis +E: kyrtzidis@apple.com +D: Bug fixes. + +N: Bruce Mitchener, Jr. +E: bruce.mitchener@gmail.com +D: Emscripten-related changes. + +N: Michel Morin +E: mimomorin@gmail.com +D: Minor patches to is_convertible. + +N: Andrew Morrow +E: andrew.c.morrow@gmail.com +D: Minor patches and Linux fixes. + +N: Michael Park +E: mcypark@gmail.com +D: Implementation of . + +N: Arvid Picciani +E: aep at exys dot org +D: Minor patches and musl port. + +N: Bjorn Reese +E: breese@users.sourceforge.net +D: Initial regex prototype + +N: Nico Rieck +E: nico.rieck@gmail.com +D: Windows fixes + +N: Jon Roelofs +E: jroelofS@jroelofs.com +D: Remote testing, Newlib port, baremetal/single-threaded support. + +N: Jonathan Sauer +D: Minor patches, mostly related to constexpr + +N: Craig Silverstein +E: csilvers@google.com +D: Implemented Cityhash as the string hash function on 64-bit machines + +N: Richard Smith +D: Minor patches. + +N: Joerg Sonnenberger +E: joerg@NetBSD.org +D: NetBSD port. + +N: Stephan Tolksdorf +E: st@quanttec.com +D: Minor fix + +N: Michael van der Westhuizen +E: r1mikey at gmail dot com + +N: Larisse Voufo +D: Minor patches. + +N: Klaas de Vries +E: klaas at klaasgaaf dot nl +D: Minor bug fix. + +N: Zhang Xiongpang +E: zhangxiongpang@gmail.com +D: Minor patches and bug fixes. + +N: Xing Xue +E: xingxue@ca.ibm.com +D: AIX port + +N: Zhihao Yuan +E: lichray@gmail.com +D: Standard compatibility fixes. + +N: Jeffrey Yasskin +E: jyasskin@gmail.com +E: jyasskin@google.com +D: Linux fixes. diff --git a/third_party/libcxx/LICENSE.TXT b/third_party/libcxx/LICENSE.TXT new file mode 100644 index 000000000..e159d2834 --- /dev/null +++ b/third_party/libcxx/LICENSE.TXT @@ -0,0 +1,311 @@ +============================================================================== +The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: +============================================================================== + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. + +============================================================================== +Software from third parties included in the LLVM Project: +============================================================================== +The LLVM Project contains third party software which is under different license +terms. All such code will be identified clearly using at least one of two +mechanisms: +1) It will be in a separate directory tree with its own `LICENSE.txt` or + `LICENSE` file at the top containing the specific license and restrictions + which apply to that software, or +2) It will contain specific license and restriction terms at the top of every + file. + +============================================================================== +Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): +============================================================================== + +The libc++ library is dual licensed under both the University of Illinois +"BSD-Like" license and the MIT license. As a user of this code you may choose +to use it under either license. As a contributor, you agree to allow your code +to be used under both. + +Full text of the relevant licenses is included below. + +============================================================================== + +University of Illinois/NCSA +Open Source License + +Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT + +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +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: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +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 +CONTRIBUTORS 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 WITH THE +SOFTWARE. + +============================================================================== + +Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT + +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. diff --git a/third_party/libcxx/README.cosmo b/third_party/libcxx/README.cosmo new file mode 100644 index 000000000..1b62899d4 --- /dev/null +++ b/third_party/libcxx/README.cosmo @@ -0,0 +1,6 @@ +Upstream origin + + git@github.com:llvm-mirror/libcxx.git + commit 78d6a7767ed57b50122a161b91f59f19c9bd0d19 + Author: Zoe Carver + Date: Tue Oct 22 15:16:49 2019 +0000 diff --git a/third_party/libcxx/__bit_reference b/third_party/libcxx/__bit_reference new file mode 100644 index 000000000..5533a2208 --- /dev/null +++ b/third_party/libcxx/__bit_reference @@ -0,0 +1,1280 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_REFERENCE +#define _LIBCPP___BIT_REFERENCE + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/bit" +#include "third_party/libcxx/algorithm" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class __bit_iterator; +template class __bit_const_reference; + +template +struct __has_storage_type +{ + static const bool value = false; +}; + +template ::value> +class __bit_reference +{ + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__storage_pointer __storage_pointer; + + __storage_pointer __seg_; + __storage_type __mask_; + + friend typename _Cp::__self; + + friend class __bit_const_reference<_Cp>; + friend class __bit_iterator<_Cp, false>; +public: + _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT + {return static_cast(*__seg_ & __mask_);} + _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT + {return !static_cast(*this);} + + _LIBCPP_INLINE_VISIBILITY + __bit_reference& operator=(bool __x) _NOEXCEPT + { + if (__x) + *__seg_ |= __mask_; + else + *__seg_ &= ~__mask_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT + {return operator=(static_cast(__x));} + + _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;} + _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT + {return __bit_iterator<_Cp, false>(__seg_, static_cast(__libcpp_ctz(__mask_)));} +private: + _LIBCPP_INLINE_VISIBILITY + __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + : __seg_(__s), __mask_(__m) {} +}; + +template +class __bit_reference<_Cp, false> +{ +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +class __bit_const_reference +{ + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__const_storage_pointer __storage_pointer; + + __storage_pointer __seg_; + __storage_type __mask_; + + friend typename _Cp::__self; + friend class __bit_iterator<_Cp, true>; +public: + _LIBCPP_INLINE_VISIBILITY + __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT + : __seg_(__x.__seg_), __mask_(__x.__mask_) {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT + {return static_cast(*__seg_ & __mask_);} + + _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT + {return __bit_iterator<_Cp, true>(__seg_, static_cast(__libcpp_ctz(__mask_)));} +private: + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR + __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + : __seg_(__s), __mask_(__m) {} + + __bit_const_reference& operator=(const __bit_const_reference& __x); +}; + +// find + +template +__bit_iterator<_Cp, _IsConst> +__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + static const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + if (__n == __dn) + return __first + __n; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + if (*__first.__seg_) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(*__first.__seg_))); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + } + return _It(__first.__seg_, static_cast(__n)); +} + +template +__bit_iterator<_Cp, _IsConst> +__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = ~*__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + if (__n == __dn) + return __first + __n; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + { + __storage_type __b = ~*__first.__seg_; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + } + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = ~*__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); + } + return _It(__first.__seg_, static_cast(__n)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, _IsConst> +find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) +{ + if (static_cast(__value_)) + return __find_bool_true(__first, static_cast(__last - __first)); + return __find_bool_false(__first, static_cast(__last - __first)); +} + +// count + +template +typename __bit_iterator<_Cp, _IsConst>::difference_type +__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + typedef typename _It::difference_type difference_type; + const int __bits_per_word = _It::__bits_per_word; + difference_type __r = 0; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __r = _VSTD::__libcpp_popcount(*__first.__seg_ & __m); + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + __r += _VSTD::__libcpp_popcount(*__first.__seg_); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __r += _VSTD::__libcpp_popcount(*__first.__seg_ & __m); + } + return __r; +} + +template +typename __bit_iterator<_Cp, _IsConst>::difference_type +__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + typedef typename _It::difference_type difference_type; + const int __bits_per_word = _It::__bits_per_word; + difference_type __r = 0; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __r = _VSTD::__libcpp_popcount(~*__first.__seg_ & __m); + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + __r += _VSTD::__libcpp_popcount(~*__first.__seg_); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __r += _VSTD::__libcpp_popcount(~*__first.__seg_ & __m); + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __bit_iterator<_Cp, _IsConst>::difference_type +count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) +{ + if (static_cast(__value_)) + return __count_bool_true(__first, static_cast(__last - __first)); + return __count_bool_false(__first, static_cast(__last - __first)); +} + +// fill_n + +template +void +__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, false> _It; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + *__first.__seg_ &= ~__m; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + __storage_type __nw = __n / __bits_per_word; + _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type)); + __n -= __nw * __bits_per_word; + // do last partial word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__first.__seg_ &= ~__m; + } +} + +template +void +__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, false> _It; + typedef typename _It::__storage_type __storage_type; + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + *__first.__seg_ |= __m; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + __storage_type __nw = __n / __bits_per_word; + _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type)); + __n -= __nw * __bits_per_word; + // do last partial word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__first.__seg_ |= __m; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_) +{ + if (__n > 0) + { + if (__value_) + __fill_n_true(__first, __n); + else + __fill_n_false(__first, __n); + } +} + +// fill + +template +inline _LIBCPP_INLINE_VISIBILITY +void +fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_) +{ + _VSTD::fill_n(__first, static_cast(__last - __first), __value_); +} + +// copy + +template +__bit_iterator<_Cp, false> +__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + __storage_type __b = *__first.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + __storage_type __nw = __n / __bits_per_word; + _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), + _VSTD::__to_raw_pointer(__first.__seg_), + __nw * sizeof(__storage_type)); + __n -= __nw * __bits_per_word; + __result.__seg_ += __nw; + // do last word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(__n); + } + } + return __result; +} + +template +__bit_iterator<_Cp, false> +__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + static const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __first.__ctz_) + *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); + else + *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); + __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); + __result.__ctz_ = static_cast(__dn); + } + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __m = ~__storage_type(0) << __result.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) + { + __storage_type __b = *__first.__seg_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << __result.__ctz_; + ++__result.__seg_; + *__result.__seg_ &= __m; + *__result.__seg_ |= __b >> __clz_r; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + __storage_type __dn = _VSTD::min(__n, static_cast(__clz_r)); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << __result.__ctz_; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> __dn; + __result.__ctz_ = static_cast(__n); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + if (__first.__ctz_ == __result.__ctz_) + return __copy_aligned(__first, __last, __result); + return __copy_unaligned(__first, __last, __result); +} + +// copy_backward + +template +__bit_iterator<_Cp, false> +__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__last.__ctz_ != 0) + { + difference_type __dn = _VSTD::min(static_cast(__last.__ctz_), __n); + __n -= __dn; + unsigned __clz = __bits_per_word - __last.__ctz_; + __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); + __storage_type __b = *__last.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + // __last.__ctz_ = 0 + } + // __last.__ctz_ == 0 || __n == 0 + // __result.__ctz_ == 0 || __n == 0 + // do middle words + __storage_type __nw = __n / __bits_per_word; + __result.__seg_ -= __nw; + __last.__seg_ -= __nw; + _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), + _VSTD::__to_raw_pointer(__last.__seg_), + __nw * sizeof(__storage_type)); + __n -= __nw * __bits_per_word; + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); + __storage_type __b = *--__last.__seg_ & __m; + *--__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); + } + } + return __result; +} + +template +__bit_iterator<_Cp, false> +__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__last.__ctz_ != 0) + { + difference_type __dn = _VSTD::min(static_cast(__last.__ctz_), __n); + __n -= __dn; + unsigned __clz_l = __bits_per_word - __last.__ctz_; + __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); + __storage_type __b = *__last.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min(__dn, static_cast(__result.__ctz_)); + if (__ddn > 0) + { + __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __last.__ctz_) + *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); + else + *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); + __result.__ctz_ = static_cast(((-__ddn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + } + if (__dn > 0) + { + // __result.__ctz_ == 0 + --__result.__seg_; + __result.__ctz_ = static_cast(-__dn & (__bits_per_word - 1)); + __m = ~__storage_type(0) << __result.__ctz_; + *__result.__seg_ &= ~__m; + __last.__ctz_ -= __dn + __ddn; + *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); + } + // __last.__ctz_ = 0 + } + // __last.__ctz_ == 0 || __n == 0 + // __result.__ctz_ != 0 || __n == 0 + // do middle words + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __m = ~__storage_type(0) >> __clz_r; + for (; __n >= __bits_per_word; __n -= __bits_per_word) + { + __storage_type __b = *--__last.__seg_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> __clz_r; + *--__result.__seg_ &= __m; + *__result.__seg_ |= __b << __result.__ctz_; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) << (__bits_per_word - __n); + __storage_type __b = *--__last.__seg_ & __m; + __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __dn = _VSTD::min(__n, static_cast(__result.__ctz_)); + __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); + __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + // __result.__ctz_ == 0 + --__result.__seg_; + __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); + __m = ~__storage_type(0) << __result.__ctz_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + if (__last.__ctz_ == __result.__ctz_) + return __copy_backward_aligned(__first, __last, __result); + return __copy_backward_unaligned(__first, __last, __result); +} + +// move + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + return _VSTD::copy(__first, __last, __result); +} + +// move_backward + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + return _VSTD::copy_backward(__first, __last, __result); +} + +// swap_ranges + +template +__bit_iterator<__C2, false> +__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, + __bit_iterator<__C2, false> __result) +{ + typedef __bit_iterator<__C1, false> _I1; + typedef typename _I1::difference_type difference_type; + typedef typename _I1::__storage_type __storage_type; + const int __bits_per_word = _I1::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1; + *__first.__seg_ |= __b2; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) + swap(*__first.__seg_, *__result.__seg_); + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1; + *__first.__seg_ |= __b2; + __result.__ctz_ = static_cast(__n); + } + } + return __result; +} + +template +__bit_iterator<__C2, false> +__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, + __bit_iterator<__C2, false> __result) +{ + typedef __bit_iterator<__C1, false> _I1; + typedef typename _I1::difference_type difference_type; + typedef typename _I1::__storage_type __storage_type; + const int __bits_per_word = _I1::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __first.__ctz_) + { + unsigned __s = __result.__ctz_ - __first.__ctz_; + *__result.__seg_ |= __b1 << __s; + *__first.__seg_ |= __b2 >> __s; + } + else + { + unsigned __s = __first.__ctz_ - __result.__ctz_; + *__result.__seg_ |= __b1 >> __s; + *__first.__seg_ |= __b2 << __s; + } + __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + unsigned __s = __first.__ctz_ + __ddn; + *__result.__seg_ |= __b1 >> __s; + *__first.__seg_ |= __b2 << __s; + __result.__ctz_ = static_cast(__dn); + } + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + __storage_type __m = ~__storage_type(0) << __result.__ctz_; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) + { + __storage_type __b1 = *__first.__seg_; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 << __result.__ctz_; + *__first.__seg_ = __b2 >> __result.__ctz_; + ++__result.__seg_; + __b2 = *__result.__seg_ & ~__m; + *__result.__seg_ &= __m; + *__result.__seg_ |= __b1 >> __clz_r; + *__first.__seg_ |= __b2 << __clz_r; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 << __result.__ctz_; + *__first.__seg_ |= __b2 >> __result.__ctz_; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 >> __dn; + *__first.__seg_ |= __b2 << __dn; + __result.__ctz_ = static_cast(__n); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<__C2, false> +swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, + __bit_iterator<__C2, false> __first2) +{ + if (__first1.__ctz_ == __first2.__ctz_) + return __swap_ranges_aligned(__first1, __last1, __first2); + return __swap_ranges_unaligned(__first1, __last1, __first2); +} + +// rotate + +template +struct __bit_array +{ + typedef typename _Cp::difference_type difference_type; + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__storage_pointer __storage_pointer; + typedef typename _Cp::iterator iterator; + static const unsigned __bits_per_word = _Cp::__bits_per_word; + static const unsigned _Np = 4; + + difference_type __size_; + __storage_type __word_[_Np]; + + _LIBCPP_INLINE_VISIBILITY static difference_type capacity() + {return static_cast(_Np * __bits_per_word);} + _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {} + _LIBCPP_INLINE_VISIBILITY iterator begin() + { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); + } + _LIBCPP_INLINE_VISIBILITY iterator end() + { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, + static_cast(__size_ % __bits_per_word)); + } +}; + +template +__bit_iterator<_Cp, false> +rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) +{ + typedef __bit_iterator<_Cp, false> _I1; + typedef typename _I1::difference_type difference_type; + difference_type __d1 = __middle - __first; + difference_type __d2 = __last - __middle; + _I1 __r = __first + __d2; + while (__d1 != 0 && __d2 != 0) + { + if (__d1 <= __d2) + { + if (__d1 <= __bit_array<_Cp>::capacity()) + { + __bit_array<_Cp> __b(__d1); + _VSTD::copy(__first, __middle, __b.begin()); + _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first)); + break; + } + else + { + __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle); + __first = __middle; + __middle = __mp; + __d2 -= __d1; + } + } + else + { + if (__d2 <= __bit_array<_Cp>::capacity()) + { + __bit_array<_Cp> __b(__d2); + _VSTD::copy(__middle, __last, __b.begin()); + _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last)); + break; + } + else + { + __bit_iterator<_Cp, false> __mp = __first + __d2; + _VSTD::swap_ranges(__first, __mp, __middle); + __first = __mp; + __d1 -= __d2; + } + } + } + return __r; +} + +// equal + +template +bool +__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, + __bit_iterator<_Cp, _IC2> __first2) +{ + typedef __bit_iterator<_Cp, _IC1> _It; + typedef typename _It::difference_type difference_type; + typedef typename _It::__storage_type __storage_type; + static const int __bits_per_word = _It::__bits_per_word; + difference_type __n = __last1 - __first1; + if (__n > 0) + { + // do first word + if (__first1.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first1.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first1.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __first2.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + if (__first2.__ctz_ > __first1.__ctz_) + { + if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) + return false; + } + else + { + if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) + return false; + } + __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; + __first2.__ctz_ = static_cast((__ddn + __first2.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) + return false; + __first2.__ctz_ = static_cast(__dn); + } + ++__first1.__seg_; + // __first1.__ctz_ = 0; + } + // __first1.__ctz_ == 0; + // do middle words + unsigned __clz_r = __bits_per_word - __first2.__ctz_; + __storage_type __m = ~__storage_type(0) << __first2.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) + { + __storage_type __b = *__first1.__seg_; + if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) + return false; + ++__first2.__seg_; + if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) + return false; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first1.__seg_ & __m; + __storage_type __dn = _VSTD::min(__n, static_cast(__clz_r)); + __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) + return false; + __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; + __first2.__ctz_ = static_cast((__dn + __first2.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + if ((*__first2.__seg_ & __m) != (__b >> __dn)) + return false; + } + } + } + return true; +} + +template +bool +__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, + __bit_iterator<_Cp, _IC2> __first2) +{ + typedef __bit_iterator<_Cp, _IC1> _It; + typedef typename _It::difference_type difference_type; + typedef typename _It::__storage_type __storage_type; + static const int __bits_per_word = _It::__bits_per_word; + difference_type __n = __last1 - __first1; + if (__n > 0) + { + // do first word + if (__first1.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first1.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) + return false; + ++__first2.__seg_; + ++__first1.__seg_; + // __first1.__ctz_ = 0; + // __first2.__ctz_ = 0; + } + // __first1.__ctz_ == 0; + // __first2.__ctz_ == 0; + // do middle words + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) + if (*__first2.__seg_ != *__first1.__seg_) + return false; + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) + return false; + } + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) +{ + if (__first1.__ctz_ == __first2.__ctz_) + return __equal_aligned(__first1, __last1, __first2); + return __equal_unaligned(__first1, __last1, __first2); +} + +template +class __bit_iterator +{ +public: + typedef typename _Cp::difference_type difference_type; + typedef bool value_type; + typedef __bit_iterator pointer; + typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference; + typedef random_access_iterator_tag iterator_category; + +private: + typedef typename _Cp::__storage_type __storage_type; + typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer, + typename _Cp::__storage_pointer>::type __storage_pointer; + static const unsigned __bits_per_word = _Cp::__bits_per_word; + + __storage_pointer __seg_; + unsigned __ctz_; + +public: + _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __seg_(nullptr), __ctz_(0) +#endif + {} + + _LIBCPP_INLINE_VISIBILITY + __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT + : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + + _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT + {return reference(__seg_, __storage_type(1) << __ctz_);} + + _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++() + { + if (__ctz_ != __bits_per_word-1) + ++__ctz_; + else + { + __ctz_ = 0; + ++__seg_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int) + { + __bit_iterator __tmp = *this; + ++(*this); + return __tmp; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--() + { + if (__ctz_ != 0) + --__ctz_; + else + { + __ctz_ = __bits_per_word - 1; + --__seg_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int) + { + __bit_iterator __tmp = *this; + --(*this); + return __tmp; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n) + { + if (__n >= 0) + __seg_ += (__n + __ctz_) / __bits_per_word; + else + __seg_ += static_cast(__n - __bits_per_word + __ctz_ + 1) + / static_cast(__bits_per_word); + __n &= (__bits_per_word - 1); + __ctz_ = static_cast((__n + __ctz_) % __bits_per_word); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n) + { + return *this += -__n; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const + { + __bit_iterator __t(*this); + __t += __n; + return __t; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const + { + __bit_iterator __t(*this); + __t -= __n; + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;} + + _LIBCPP_INLINE_VISIBILITY + friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) + {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;} + + _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);} + + _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) + {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;} + + _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__x == __y);} + + _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) + {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);} + + _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) + {return __y < __x;} + + _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__y < __x);} + + _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__x < __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT + : __seg_(__s), __ctz_(__ctz) {} + + friend typename _Cp::__self; + + friend class __bit_reference<_Cp>; + friend class __bit_const_reference<_Cp>; + friend class __bit_iterator<_Cp, true>; + template friend struct __bit_array; + template friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + template friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + template friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, + __bit_iterator<_Dp, false>, + __bit_iterator<_Dp, false>); + template friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template friend bool equal(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, + typename _Dp::size_type); + template friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, + typename _Dp::size_type); + template friend typename __bit_iterator<_Dp, _IC>::difference_type + __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + template friend typename __bit_iterator<_Dp, _IC>::difference_type + __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); +}; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_REFERENCE diff --git a/third_party/libcxx/__bsd_locale_fallbacks.h b/third_party/libcxx/__bsd_locale_fallbacks.h new file mode 100644 index 000000000..b285bc49c --- /dev/null +++ b/third_party/libcxx/__bsd_locale_fallbacks.h @@ -0,0 +1,137 @@ +// -*- C++ -*- +//===---------------------- __bsd_locale_fallbacks.h ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// The BSDs have lots of *_l functions. This file provides reimplementations +// of those functions for non-BSD platforms. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H +#define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H + +#include "third_party/libcxx/stdlib.h" +#include "libc/mem/fmt.h" +#include "third_party/libcxx/memory" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY decltype(MB_CUR_MAX) + __libcpp_mb_cur_max_l(locale_t __l) { + __libcpp_locale_guard __current(__l); + return MB_CUR_MAX; +} + +inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_btowc_l(int __c, + locale_t __l) { + __libcpp_locale_guard __current(__l); + return btowc(__c); +} + +inline _LIBCPP_INLINE_VISIBILITY int __libcpp_wctob_l(wint_t __c, + locale_t __l) { + __libcpp_locale_guard __current(__l); + return wctob(__c); +} + +inline _LIBCPP_INLINE_VISIBILITY size_t +__libcpp_wcsnrtombs_l(char* __dest, const wchar_t** __src, size_t __nwc, + size_t __len, mbstate_t* __ps, locale_t __l) { + __libcpp_locale_guard __current(__l); + return wcsnrtombs(__dest, __src, __nwc, __len, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_wcrtomb_l(char* __s, + wchar_t __wc, + mbstate_t* __ps, + locale_t __l) { + __libcpp_locale_guard __current(__l); + return wcrtomb(__s, __wc, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY size_t +__libcpp_mbsnrtowcs_l(wchar_t* __dest, const char** __src, size_t __nms, + size_t __len, mbstate_t* __ps, locale_t __l) { + __libcpp_locale_guard __current(__l); + return mbsnrtowcs(__dest, __src, __nms, __len, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbrtowc_l(wchar_t* __pwc, + const char* __s, + size_t __n, + mbstate_t* __ps, + locale_t __l) { + __libcpp_locale_guard __current(__l); + return mbrtowc(__pwc, __s, __n, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY int __libcpp_mbtowc_l(wchar_t* __pwc, + const char* __pmb, + size_t __max, + locale_t __l) { + __libcpp_locale_guard __current(__l); + return mbtowc(__pwc, __pmb, __max); +} + +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbrlen_l(const char* __s, + size_t __n, + mbstate_t* __ps, + locale_t __l) { + __libcpp_locale_guard __current(__l); + return mbrlen(__s, __n, __ps); +} + +inline _LIBCPP_INLINE_VISIBILITY lconv* __libcpp_localeconv_l(locale_t __l) { + __libcpp_locale_guard __current(__l); + return localeconv(); +} + +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbsrtowcs_l(wchar_t* __dest, + const char** __src, + size_t __len, + mbstate_t* __ps, + locale_t __l) { + __libcpp_locale_guard __current(__l); + return mbsrtowcs(__dest, __src, __len, __ps); +} + +inline int __libcpp_snprintf_l(char* __s, size_t __n, locale_t __l, + const char* __format, ...) { + va_list __va; + va_start(__va, __format); + __libcpp_locale_guard __current(__l); + int __res = vsnprintf(__s, __n, __format, __va); + va_end(__va); + return __res; +} + +inline int __libcpp_asprintf_l(char** __s, locale_t __l, const char* __format, + ...) { + va_list __va; + va_start(__va, __format); + __libcpp_locale_guard __current(__l); + int __res = vasprintf(__s, __format, __va); + va_end(__va); + return __res; +} + +inline int __libcpp_sscanf_l(const char* __s, locale_t __l, + const char* __format, ...) { + va_list __va; + va_start(__va, __format); + __libcpp_locale_guard __current(__l); + int __res = vsscanf(__s, __format, __va); + va_end(__va); + return __res; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H diff --git a/third_party/libcxx/__config b/third_party/libcxx/__config new file mode 100644 index 000000000..aa17fbccb --- /dev/null +++ b/third_party/libcxx/__config @@ -0,0 +1,1490 @@ +// -*- C++ -*- +//===--------------------------- __config ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CONFIG +#define _LIBCPP_CONFIG + +#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#define _LIBCPP_HAS_NO_THREADS +#define _LIBCPP_ABI_UNSTABLE +// #define _LIBCPP_NO_EXCEPTIONS + +#if defined(_MSC_VER) && !defined(__clang__) +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# endif +#endif + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +#ifdef __cplusplus + +#ifdef __GNUC__ +# define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__) +// The _GNUC_VER_NEW macro better represents the new GCC versioning scheme +// introduced in GCC 5.0. +# define _GNUC_VER_NEW (_GNUC_VER * 10 + __GNUC_PATCHLEVEL__) +#else +# define _GNUC_VER 0 +# define _GNUC_VER_NEW 0 +#endif + +#define _LIBCPP_VERSION 10000 + +#ifndef _LIBCPP_ABI_VERSION +# define _LIBCPP_ABI_VERSION 1 +#endif + +#ifndef __STDC_HOSTED__ +# define _LIBCPP_FREESTANDING +#endif + +#ifndef _LIBCPP_STD_VER +# if __cplusplus <= 201103L +# define _LIBCPP_STD_VER 11 +# elif __cplusplus <= 201402L +# define _LIBCPP_STD_VER 14 +# elif __cplusplus <= 201703L +# define _LIBCPP_STD_VER 17 +# else +# define _LIBCPP_STD_VER 18 // current year, or date of c++2a ratification +# endif +#endif // _LIBCPP_STD_VER + +#if defined(__ELF__) +# define _LIBCPP_OBJECT_FORMAT_ELF 1 +#elif defined(__MACH__) +# define _LIBCPP_OBJECT_FORMAT_MACHO 1 +#elif defined(_WIN32) +# define _LIBCPP_OBJECT_FORMAT_COFF 1 +#elif defined(__wasm__) +# define _LIBCPP_OBJECT_FORMAT_WASM 1 +#else +# error Unknown object file format +#endif + +#if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2 +// Change short string representation so that string data starts at offset 0, +// improving its alignment in some cases. +# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +// Fix deque iterator type in order to support incomplete types. +# define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE +// Fix undefined behavior in how std::list stores its linked nodes. +# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB +// Fix undefined behavior in how __tree stores its end and parent nodes. +# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB +// Fix undefined behavior in how __hash_table stores its pointer types. +# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB +# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB +# define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE +// Don't use a nullptr_t simulation type in C++03 instead using C++11 nullptr +// provided under the alternate keyword __nullptr, which changes the mangling +// of nullptr_t. This option is ABI incompatible with GCC in C++03 mode. +# define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR +// Define the `pointer_safety` enum as a C++11 strongly typed enumeration +// instead of as a class simulating an enum. If this option is enabled +// `pointer_safety` and `get_pointer_safety()` will no longer be available +// in C++03. +# define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE +// Define a key function for `bad_function_call` in the library, to centralize +// its vtable and typeinfo to libc++ rather than having all other libraries +// using that class define their own copies. +# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION +// Enable optimized version of __do_get_(un)signed which avoids redundant copies. +# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET +// Use the smallest possible integer type to represent the index of the variant. +// Previously libc++ used "unsigned int" exclusively. +# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION +// Unstable attempt to provide a more optimized std::function +# define _LIBCPP_ABI_OPTIMIZED_FUNCTION +// All the regex constants must be distinct and nonzero. +# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO +#elif _LIBCPP_ABI_VERSION == 1 +# if !defined(_LIBCPP_OBJECT_FORMAT_COFF) +// Enable compiling copies of now inline methods into the dylib to support +// applications compiled against older libraries. This is unnecessary with +// COFF dllexport semantics, since dllexport forces a non-inline definition +// of inline functions to be emitted anyway. Our own non-inline copy would +// conflict with the dllexport-emitted copy, so we disable it. +// [jart] no thanks +//# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS +# endif +// Feature macros for disabling pre ABI v1 features. All of these options +// are deprecated. +# if defined(__FreeBSD__) +# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR +# endif +#endif + +#ifdef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR +#error "_LIBCPP_TRIVIAL_PAIR_COPY_CTOR" is no longer supported. \ + use _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR instead +#endif + +#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y +#define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) + +#ifndef _LIBCPP_ABI_NAMESPACE +# define _LIBCPP_ABI_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION) +#endif + +#if __cplusplus < 201103L +#define _LIBCPP_CXX03_LANG +#endif + +#ifndef __has_attribute +#define __has_attribute(__x) 0 +#endif + +#ifndef __has_builtin +#define __has_builtin(__x) 0 +#endif + +#ifndef __has_extension +#define __has_extension(__x) 0 +#endif + +#ifndef __has_feature +#define __has_feature(__x) 0 +#endif + +#ifndef __has_cpp_attribute +#define __has_cpp_attribute(__x) 0 +#endif + +// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by +// the compiler and '1' otherwise. +#ifndef __is_identifier +#define __is_identifier(__x) 1 +#endif + +#ifndef __has_declspec_attribute +#define __has_declspec_attribute(__x) 0 +#endif + +#define __has_keyword(__x) !(__is_identifier(__x)) + +#ifndef __has_include +#define __has_include(...) 0 +#endif + +#if defined(__clang__) +# define _LIBCPP_COMPILER_CLANG +# ifndef __apple_build_version__ +# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) +# endif +#elif defined(__GNUC__) +# define _LIBCPP_COMPILER_GCC +#elif defined(_MSC_VER) +# define _LIBCPP_COMPILER_MSVC +#elif defined(__IBMCPP__) +# define _LIBCPP_COMPILER_IBM +#endif + +#if defined(_LIBCPP_COMPILER_GCC) && __cplusplus < 201103L +#error "libc++ does not support using GCC with C++03. Please enable C++11" +#endif + +// FIXME: ABI detection should be done via compiler builtin macros. This +// is just a placeholder until Clang implements such macros. For now assume +// that Windows compilers pretending to be MSVC++ target the Microsoft ABI, +// and allow the user to explicitly specify the ABI to handle cases where this +// heuristic falls short. +#if defined(_LIBCPP_ABI_FORCE_ITANIUM) && defined(_LIBCPP_ABI_FORCE_MICROSOFT) +# error "Only one of _LIBCPP_ABI_FORCE_ITANIUM and _LIBCPP_ABI_FORCE_MICROSOFT can be defined" +#elif defined(_LIBCPP_ABI_FORCE_ITANIUM) +# define _LIBCPP_ABI_ITANIUM +#elif defined(_LIBCPP_ABI_FORCE_MICROSOFT) +# define _LIBCPP_ABI_MICROSOFT +#else +# if defined(_WIN32) && defined(_MSC_VER) +# define _LIBCPP_ABI_MICROSOFT +# else +# define _LIBCPP_ABI_ITANIUM +# endif +#endif + +#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) +# define _LIBCPP_ABI_VCRUNTIME +#endif + +// Need to detect which libc we're using if we're on Linux. +#if defined(__linux__) +# include "libc/isystem/features.h" +# if defined(__GLIBC_PREREQ) +# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) +# else +# define _LIBCPP_GLIBC_PREREQ(a, b) 0 +# endif // defined(__GLIBC_PREREQ) +#endif // defined(__linux__) + +#ifdef __LITTLE_ENDIAN__ +# if __LITTLE_ENDIAN__ +# define _LIBCPP_LITTLE_ENDIAN +# endif // __LITTLE_ENDIAN__ +#endif // __LITTLE_ENDIAN__ + +#ifdef __BIG_ENDIAN__ +# if __BIG_ENDIAN__ +# define _LIBCPP_BIG_ENDIAN +# endif // __BIG_ENDIAN__ +#endif // __BIG_ENDIAN__ + +#ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define _LIBCPP_LITTLE_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define _LIBCPP_BIG_ENDIAN +# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#endif // __BYTE_ORDER__ + +#ifdef __FreeBSD__ +# include "third_party/libcxx/sys/endian.h" +# include "third_party/libcxx/osreldate.h" +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# ifndef __LONG_LONG_SUPPORTED +# define _LIBCPP_HAS_NO_LONG_LONG +# endif // __LONG_LONG_SUPPORTED +#endif // __FreeBSD__ + +#ifdef __NetBSD__ +# include "third_party/libcxx/sys/endian.h" +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_HAS_QUICK_EXIT +#endif // __NetBSD__ + +#if defined(_WIN32) +# define _LIBCPP_WIN32API +# define _LIBCPP_LITTLE_ENDIAN +# define _LIBCPP_SHORT_WCHAR 1 +// Both MinGW and native MSVC provide a "MSVC"-like environment +# define _LIBCPP_MSVCRT_LIKE +// If mingw not explicitly detected, assume using MS C runtime only if +// a MS compatibility version is specified. +# if defined(_MSC_VER) && !defined(__MINGW32__) +# define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library +# endif +# if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_ARM) || defined(__arm__)) +# define _LIBCPP_HAS_BITSCAN64 +# endif +# define _LIBCPP_HAS_OPEN_WITH_WCHAR +# if defined(_LIBCPP_MSVCRT) +# define _LIBCPP_HAS_QUICK_EXIT +# endif + +// Some CRT APIs are unavailable to store apps +# if defined(WINAPI_FAMILY) +# include "third_party/libcxx/winapifamily.h" +# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && \ + (!defined(WINAPI_PARTITION_SYSTEM) || \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_SYSTEM)) +# define _LIBCPP_WINDOWS_STORE_APP +# endif +# endif +#endif // defined(_WIN32) + +#ifdef __sun__ +# include "third_party/libcxx/sys/isa_defs.h" +# ifdef _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else +# define _LIBCPP_BIG_ENDIAN +# endif +#endif // __sun__ + +#if defined(__CloudABI__) + // Certain architectures provide arc4random(). Prefer using + // arc4random() over /dev/{u,}random to make it possible to obtain + // random data even when using sandboxing mechanisms such as chroots, + // Capsicum, etc. +# define _LIBCPP_USING_ARC4_RANDOM +#elif defined(__Fuchsia__) || defined(__wasi__) || defined(__COSMOPOLITAN__) +# define _LIBCPP_USING_GETENTROPY +#elif defined(__native_client__) + // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, + // including accesses to the special files under /dev. C++11's + // std::random_device is instead exposed through a NaCl syscall. +# define _LIBCPP_USING_NACL_RANDOM +#elif defined(_LIBCPP_WIN32API) +# define _LIBCPP_USING_WIN32_RANDOM +#else +# define _LIBCPP_USING_DEV_RANDOM +#endif + +#if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) +# include "libc/isystem/endian.h" +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# elif __BYTE_ORDER == __BIG_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# else // __BYTE_ORDER == __BIG_ENDIAN +# error unable to determine endian +# endif +#endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) + +#if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) +#else +# define _LIBCPP_NO_CFI +#endif + +#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L +# if defined(__FreeBSD__) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_C11_FEATURES +# elif defined(__Fuchsia__) || defined(__wasi__) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_TIMESPEC_GET +# define _LIBCPP_HAS_C11_FEATURES +# elif defined(__linux__) +# if !defined(_LIBCPP_HAS_MUSL_LIBC) +# if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__) +# define _LIBCPP_HAS_QUICK_EXIT +# endif +# if _LIBCPP_GLIBC_PREREQ(2, 17) +# define _LIBCPP_HAS_C11_FEATURES +# define _LIBCPP_HAS_TIMESPEC_GET +# endif +# else // defined(_LIBCPP_HAS_MUSL_LIBC) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_TIMESPEC_GET +# define _LIBCPP_HAS_C11_FEATURES +# endif +# endif // __linux__ +#endif + +#ifndef _LIBCPP_CXX03_LANG +# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp) +#elif defined(_LIBCPP_COMPILER_CLANG) +# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp) +#else +// This definition is potentially buggy, but it's only taken with GCC in C++03, +// which we barely support anyway. See llvm.org/PR39713 +# define _LIBCPP_ALIGNOF(_Tp) __alignof(_Tp) +#endif + +#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp) + +#if defined(_LIBCPP_COMPILER_CLANG) + +// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for +// _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT left here for backward compatibility. +#if (defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \ + (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)) || \ + defined(_LIBCPP_ALTERNATE_STRING_LAYOUT) +#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +#endif + +#if __has_feature(cxx_alignas) +# define _ALIGNAS_TYPE(x) alignas(x) +# define _ALIGNAS(x) alignas(x) +#else +# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) +# define _ALIGNAS(x) __attribute__((__aligned__(x))) +#endif + +#if __cplusplus < 201103L +typedef __char16_t char16_t; +typedef __char32_t char32_t; +#endif + +#if !(__has_feature(cxx_exceptions)) && !defined(_LIBCPP_NO_EXCEPTIONS) +#define _LIBCPP_NO_EXCEPTIONS +#endif + +#if !(__has_feature(cxx_rtti)) && !defined(_LIBCPP_NO_RTTI) +#define _LIBCPP_NO_RTTI +#endif + +#if !(__has_feature(cxx_strong_enums)) +#define _LIBCPP_HAS_NO_STRONG_ENUMS +#endif + +#if __has_feature(cxx_attributes) +# define _LIBCPP_NORETURN [[noreturn]] +#else +# define _LIBCPP_NORETURN __attribute__ ((__noreturn__)) +#endif + +#if !(__has_feature(cxx_lambdas)) +#define _LIBCPP_HAS_NO_LAMBDAS +#endif + +#if !(__has_feature(cxx_nullptr)) +# if (__has_extension(cxx_nullptr) || __has_keyword(__nullptr)) && defined(_LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR) +# define nullptr __nullptr +# else +# define _LIBCPP_HAS_NO_NULLPTR +# endif +#endif + +#if !(__has_feature(cxx_rvalue_references)) +#define _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif + +#if !(__has_feature(cxx_auto_type)) +#define _LIBCPP_HAS_NO_AUTO_TYPE +#endif + +#if !(__has_feature(cxx_variadic_templates)) +#define _LIBCPP_HAS_NO_VARIADICS +#endif + +// Objective-C++ features (opt-in) +#if __has_feature(objc_arc) +#define _LIBCPP_HAS_OBJC_ARC +#endif + +#if __has_feature(objc_arc_weak) +#define _LIBCPP_HAS_OBJC_ARC_WEAK +#endif + +#if !(__has_feature(cxx_relaxed_constexpr)) +#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR +#endif + +#if !(__has_feature(cxx_variable_templates)) +#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +#endif + +#if !(__has_feature(cxx_noexcept)) +#define _LIBCPP_HAS_NO_NOEXCEPT +#endif + +#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer) +#define _LIBCPP_HAS_NO_ASAN +#endif + +// Allow for build-time disabling of unsigned integer sanitization +#if !defined(_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK) && __has_attribute(no_sanitize) +#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) +#endif + +#if __has_builtin(__builtin_launder) +#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER +#endif + +#if !__is_identifier(__has_unique_object_representations) +#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS +#endif + +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) + +// Literal operators ""d and ""y are supported starting with LLVM Clang 8 and AppleClang 10.0.1 +#if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 800) || \ + (defined(__apple_build_version__) && __apple_build_version__ < 10010000) +#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS +#endif + +#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ + +#elif defined(_LIBCPP_COMPILER_GCC) + +#define _ALIGNAS(x) __attribute__((__aligned__(x))) +#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) + +#define _LIBCPP_NORETURN __attribute__((noreturn)) + +#if !__EXCEPTIONS && !defined(_LIBCPP_NO_EXCEPTIONS) +#define _LIBCPP_NO_EXCEPTIONS +#endif + +// Determine if GCC supports relaxed constexpr +#if !defined(__cpp_constexpr) || __cpp_constexpr < 201304L +#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR +#endif + +// GCC 5 supports variable templates +#if !defined(__cpp_variable_templates) || __cpp_variable_templates < 201304L +#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +#endif + +#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__) +#define _LIBCPP_HAS_NO_ASAN +#endif + +#if _GNUC_VER >= 700 +#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER +#endif + +#if _GNUC_VER >= 700 +#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS +#endif + +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) + +#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ + +#elif defined(_LIBCPP_COMPILER_MSVC) + +#define _LIBCPP_TOSTRING2(x) #x +#define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) +#define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x)) + +#if _MSC_VER < 1900 +#error "MSVC versions prior to Visual Studio 2015 are not supported" +#endif + +#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR +#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +#define __alignof__ __alignof +#define _LIBCPP_NORETURN __declspec(noreturn) +#define _ALIGNAS(x) __declspec(align(x)) +#define _ALIGNAS_TYPE(x) alignas(x) + +#define _LIBCPP_WEAK + +#define _LIBCPP_HAS_NO_ASAN + +#define _LIBCPP_ALWAYS_INLINE __forceinline + +#define _LIBCPP_HAS_NO_VECTOR_EXTENSION + +#define _LIBCPP_DISABLE_EXTENSION_WARNING + +#elif defined(_LIBCPP_COMPILER_IBM) + +#define _ALIGNAS(x) __attribute__((__aligned__(x))) +#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) +#define _ATTRIBUTE(x) __attribute__((x)) +#define _LIBCPP_NORETURN __attribute__((noreturn)) + +#define _LIBCPP_HAS_NO_UNICODE_CHARS +#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES + +#if defined(_AIX) +#define __MULTILOCALE_API +#endif + +#define _LIBCPP_HAS_NO_ASAN + +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) + +#define _LIBCPP_HAS_NO_VECTOR_EXTENSION + +#define _LIBCPP_DISABLE_EXTENSION_WARNING + +#endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM] + +#if defined(_LIBCPP_OBJECT_FORMAT_COFF) + +#ifdef _DLL +# define _LIBCPP_CRT_FUNC __declspec(dllimport) +#else +# define _LIBCPP_CRT_FUNC +#endif + +#if defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_DLL_VIS +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_EXPORTED_FROM_ABI +#elif defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_DLL_VIS __declspec(dllexport) +# if defined(__MINGW32__) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# else +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS +# endif +# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport) +#else +# define _LIBCPP_DLL_VIS __declspec(dllimport) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport) +#endif + +#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS +#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS +#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS +#define _LIBCPP_HIDDEN +#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS +#define _LIBCPP_TEMPLATE_VIS +#define _LIBCPP_ENUM_VIS + +#endif // defined(_LIBCPP_OBJECT_FORMAT_COFF) + +#ifndef _LIBCPP_HIDDEN +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden"))) +# else +# define _LIBCPP_HIDDEN +# endif +#endif + +#ifndef _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +// The inline should be removed once PR32114 is resolved +# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN +# else +# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS +# endif +#endif + +#ifndef _LIBCPP_FUNC_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default"))) +# else +# define _LIBCPP_FUNC_VIS +# endif +#endif + +#ifndef _LIBCPP_TYPE_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default"))) +# else +# define _LIBCPP_TYPE_VIS +# endif +#endif + +#ifndef _LIBCPP_TEMPLATE_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# if __has_attribute(__type_visibility__) +# define _LIBCPP_TEMPLATE_VIS __attribute__ ((__type_visibility__("default"))) +# else +# define _LIBCPP_TEMPLATE_VIS __attribute__ ((__visibility__("default"))) +# endif +# else +# define _LIBCPP_TEMPLATE_VIS +# endif +#endif + +#ifndef _LIBCPP_EXPORTED_FROM_ABI +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default"))) +# else +# define _LIBCPP_EXPORTED_FROM_ABI +# endif +#endif + +#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS +#define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_FUNC_VIS +#endif + +#ifndef _LIBCPP_EXCEPTION_ABI +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default"))) +# else +# define _LIBCPP_EXCEPTION_ABI +# endif +#endif + +#ifndef _LIBCPP_ENUM_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__) +# define _LIBCPP_ENUM_VIS __attribute__ ((__type_visibility__("default"))) +# else +# define _LIBCPP_ENUM_VIS +# endif +#endif + +#ifndef _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __attribute__ ((__visibility__("default"))) +# else +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# endif +#endif + +#ifndef _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +#define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +#endif + +#if __has_attribute(internal_linkage) +# define _LIBCPP_INTERNAL_LINKAGE __attribute__ ((internal_linkage)) +#else +# define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE +#endif + +#if __has_attribute(exclude_from_explicit_instantiation) +# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__ ((__exclude_from_explicit_instantiation__)) +#else + // Try to approximate the effect of exclude_from_explicit_instantiation + // (which is that entities are not assumed to be provided by explicit + // template instantiations in the dylib) by always inlining those entities. +# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE +#endif + +#ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU +# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT +# define _LIBCPP_HIDE_FROM_ABI_PER_TU 0 +# else +# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1 +# endif +#endif + +#ifndef _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT +# ifdef _LIBCPP_OBJECT_FORMAT_COFF // Windows binaries can't merge typeinfos. +# define _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT 0 +#else +// TODO: This isn't strictly correct on ELF platforms due to llvm.org/PR37398 +// And we should consider defaulting to OFF. +# define _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT 1 +#endif +#endif + +#ifndef _LIBCPP_HIDE_FROM_ABI +# if _LIBCPP_HIDE_FROM_ABI_PER_TU +# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE +# else +# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION +# endif +#endif + +#ifdef _LIBCPP_BUILDING_LIBRARY +# if _LIBCPP_ABI_VERSION > 1 +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI +# else +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 +# endif +#else +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI +#endif + +// Just so we can migrate to the new macros gradually. +#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI + +// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect. +#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE { +#define _LIBCPP_END_NAMESPACE_STD } } +#define _VSTD std::_LIBCPP_ABI_NAMESPACE +_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 17 +#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem { +#else +#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem { +#endif + +#define _LIBCPP_END_NAMESPACE_FILESYSTEM \ + _LIBCPP_END_NAMESPACE_STD } } + +#define _VSTD_FS _VSTD::__fs::filesystem + +#ifndef _LIBCPP_PREFERRED_OVERLOAD +# if __has_attribute(__enable_if__) +# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, ""))) +# endif +#endif + +#ifndef _LIBCPP_HAS_NO_NOEXCEPT +# define _NOEXCEPT noexcept +# define _NOEXCEPT_(x) noexcept(x) +#else +# define _NOEXCEPT throw() +# define _NOEXCEPT_(x) +#endif + +#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS +typedef unsigned short char16_t; +typedef unsigned int char32_t; +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + +#ifndef __SIZEOF_INT128__ +#define _LIBCPP_HAS_NO_INT128 +#endif + +#ifdef _LIBCPP_CXX03_LANG +# define static_assert(...) _Static_assert(__VA_ARGS__) +# define decltype(...) __decltype(__VA_ARGS__) +#endif // _LIBCPP_CXX03_LANG + +#ifdef _LIBCPP_CXX03_LANG +# define _LIBCPP_CONSTEXPR +#else +# define _LIBCPP_CONSTEXPR constexpr +#endif + +#ifdef _LIBCPP_CXX03_LANG +# define _LIBCPP_DEFAULT {} +#else +# define _LIBCPP_DEFAULT = default; +#endif + +#ifdef _LIBCPP_CXX03_LANG +# define _LIBCPP_EQUAL_DELETE +#else +# define _LIBCPP_EQUAL_DELETE = delete +#endif + +#ifdef __GNUC__ +# define _LIBCPP_NOALIAS __attribute__((__malloc__)) +#else +# define _LIBCPP_NOALIAS +#endif + +#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) || \ + (!defined(_LIBCPP_CXX03_LANG) && defined(__GNUC__)) // All supported GCC versions +# define _LIBCPP_EXPLICIT explicit +#else +# define _LIBCPP_EXPLICIT +#endif + +#if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete) +#define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE +#endif + +#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS +# define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx +# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \ + __lx __v_; \ + _LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \ + _LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \ + _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} \ + }; +#else // _LIBCPP_HAS_NO_STRONG_ENUMS +# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x +# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) +#endif // _LIBCPP_HAS_NO_STRONG_ENUMS + +#ifdef _LIBCPP_DEBUG +# if _LIBCPP_DEBUG == 0 +# define _LIBCPP_DEBUG_LEVEL 1 +# elif _LIBCPP_DEBUG == 1 +# define _LIBCPP_DEBUG_LEVEL 2 +# else +# error Supported values for _LIBCPP_DEBUG are 0 and 1 +# endif +# if !defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_EXTERN_TEMPLATE(...) +# endif +#endif + +#ifdef _LIBCPP_DISABLE_EXTERN_TEMPLATE +#define _LIBCPP_EXTERN_TEMPLATE(...) +#define _LIBCPP_EXTERN_TEMPLATE2(...) +#endif + +#ifndef _LIBCPP_EXTERN_TEMPLATE +#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; +#endif + +#ifndef _LIBCPP_EXTERN_TEMPLATE2 +#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__; +#endif + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || \ + defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__) +#define _LIBCPP_LOCALE__L_EXTENSIONS 1 +#endif + +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +// Most unix variants have catopen. These are the specific ones that don't. +# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__COSMOPOLITAN__) +# define _LIBCPP_HAS_CATOPEN 1 +# endif +#endif + +#ifdef __FreeBSD__ +#define _DECLARE_C99_LDBL_MATH 1 +#endif + +// If we are getting operator new from the MSVC CRT, then allocation overloads +// for align_val_t were added in 19.12, aka VS 2017 version 15.3. +#if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912 +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +#elif defined(_LIBCPP_ABI_VCRUNTIME) && !defined(__cpp_aligned_new) + // We're deferring to Microsoft's STL to provide aligned new et al. We don't + // have it unless the language feature test macro is defined. +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +#endif + +#if defined(__APPLE__) +# if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ + defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) +# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# endif +#endif // defined(__APPLE__) + +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \ + (defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \ + (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)) +# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#endif + +#if defined(__APPLE__) || defined(__FreeBSD__) +#define _LIBCPP_HAS_DEFAULTRUNELOCALE +#endif + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) +#define _LIBCPP_WCTYPE_IS_MASK +#endif + +#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t) +#define _LIBCPP_NO_HAS_CHAR8_T +#endif + +// Deprecation macros. +// +// Deprecations warnings are always enabled, except when users explicitly opt-out +// by defining _LIBCPP_DISABLE_DEPRECATION_WARNINGS. +#if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) +# if __has_attribute(deprecated) +# define _LIBCPP_DEPRECATED __attribute__ ((deprecated)) +# elif _LIBCPP_STD_VER > 11 +# define _LIBCPP_DEPRECATED [[deprecated]] +# else +# define _LIBCPP_DEPRECATED +# endif +#else +# define _LIBCPP_DEPRECATED +#endif + +#if !defined(_LIBCPP_CXX03_LANG) +# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED +#else +# define _LIBCPP_DEPRECATED_IN_CXX11 +#endif + +#if _LIBCPP_STD_VER >= 14 +# define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED +#else +# define _LIBCPP_DEPRECATED_IN_CXX14 +#endif + +#if _LIBCPP_STD_VER >= 17 +# define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED +#else +# define _LIBCPP_DEPRECATED_IN_CXX17 +#endif + +// Macros to enter and leave a state where deprecation warnings are suppressed. +#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) && \ + (defined(_LIBCPP_COMPILER_CLANG) || defined(_LIBCPP_COMPILER_GCC)) +# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") +# define _LIBCPP_SUPPRESS_DEPRECATED_POP \ + _Pragma("GCC diagnostic pop") +#endif +#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) +# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH +# define _LIBCPP_SUPPRESS_DEPRECATED_POP +#endif + +#if _LIBCPP_STD_VER <= 11 +# define _LIBCPP_EXPLICIT_AFTER_CXX11 +#else +# define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit +#endif + +#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +# define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr +#else +# define _LIBCPP_CONSTEXPR_AFTER_CXX11 +#endif + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +# define _LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr +#else +# define _LIBCPP_CONSTEXPR_AFTER_CXX14 +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +# define _LIBCPP_CONSTEXPR_AFTER_CXX17 constexpr +#else +# define _LIBCPP_CONSTEXPR_AFTER_CXX17 +#endif + +// The _LIBCPP_NODISCARD_ATTRIBUTE should only be used to define other +// NODISCARD macros to the correct attribute. +#if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC) +# define _LIBCPP_NODISCARD_ATTRIBUTE [[nodiscard]] +#elif defined(_LIBCPP_COMPILER_CLANG) && !defined(_LIBCPP_CXX03_LANG) +# define _LIBCPP_NODISCARD_ATTRIBUTE [[clang::warn_unused_result]] +#else +// We can't use GCC's [[gnu::warn_unused_result]] and +// __attribute__((warn_unused_result)), because GCC does not silence them via +// (void) cast. +# define _LIBCPP_NODISCARD_ATTRIBUTE +#endif + +// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not +// specified as such as an extension. +#if defined(_LIBCPP_ENABLE_NODISCARD) && !defined(_LIBCPP_DISABLE_NODISCARD_EXT) +# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD_ATTRIBUTE +#else +# define _LIBCPP_NODISCARD_EXT +#endif + +#if !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) && \ + (_LIBCPP_STD_VER > 17 || defined(_LIBCPP_ENABLE_NODISCARD)) +# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD_ATTRIBUTE +#else +# define _LIBCPP_NODISCARD_AFTER_CXX17 +#endif + +#if _LIBCPP_STD_VER > 14 && defined(__cpp_inline_variables) && (__cpp_inline_variables >= 201606L) +# define _LIBCPP_INLINE_VAR inline +#else +# define _LIBCPP_INLINE_VAR +#endif + +#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES +# define _LIBCPP_EXPLICIT_MOVE(x) _VSTD::move(x) +#else +# define _LIBCPP_EXPLICIT_MOVE(x) (x) +#endif + +#ifndef _LIBCPP_CONSTEXPR_IF_NODEBUG +#if defined(_LIBCPP_DEBUG) || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#define _LIBCPP_CONSTEXPR_IF_NODEBUG +#else +#define _LIBCPP_CONSTEXPR_IF_NODEBUG constexpr +#endif +#endif + +#if __has_attribute(no_destroy) +# define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__)) +#else +# define _LIBCPP_NO_DESTROY +#endif + +#ifndef _LIBCPP_HAS_NO_ASAN +extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container( + const void *, const void *, const void *, const void *); +#endif + +// Try to find out if RTTI is disabled. +// g++ and cl.exe have RTTI on by default and define a macro when it is. +// g++ only defines the macro in 4.3.2 and onwards. +#if !defined(_LIBCPP_NO_RTTI) +# if defined(__GNUC__) && \ + ((__GNUC__ >= 5) || \ + (__GNUC__ == 4 && (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && \ + !defined(__GXX_RTTI) +# define _LIBCPP_NO_RTTI +# elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI) +# define _LIBCPP_NO_RTTI +# endif +#endif + +#ifndef _LIBCPP_WEAK +#define _LIBCPP_WEAK __attribute__((__weak__)) +#endif + +// Thread API +#if !defined(_LIBCPP_HAS_NO_THREADS) && \ + !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \ + !defined(_LIBCPP_HAS_THREAD_API_WIN32) && \ + !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +# if defined(__FreeBSD__) || \ + defined(__Fuchsia__) || \ + defined(__wasi__) || \ + defined(__NetBSD__) || \ + defined(__linux__) || \ + defined(__GNU__) || \ + defined(__APPLE__) || \ + defined(__CloudABI__) || \ + defined(__sun__) || \ + (defined(__MINGW32__) && __has_include()) +# define _LIBCPP_HAS_THREAD_API_PTHREAD +# elif defined(_LIBCPP_WIN32API) +# define _LIBCPP_HAS_THREAD_API_WIN32 +# else +# error "No thread API" +# endif // _LIBCPP_HAS_THREAD_API +#endif // _LIBCPP_HAS_NO_THREADS + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +#if defined(__ANDROID__) && __ANDROID_API__ >= 30 +#define _LIBCPP_HAS_COND_CLOCKWAIT +#elif defined(_LIBCPP_GLIBC_PREREQ) +#if _LIBCPP_GLIBC_PREREQ(2, 30) +#define _LIBCPP_HAS_COND_CLOCKWAIT +#endif +#endif +#endif + +#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +#error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \ + _LIBCPP_HAS_NO_THREADS is not defined. +#endif + +#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +#error _LIBCPP_HAS_THREAD_API_EXTERNAL may not be defined when \ + _LIBCPP_HAS_NO_THREADS is defined. +#endif + +#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS) +#error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ + _LIBCPP_HAS_NO_THREADS is defined. +#endif + +#if defined(__STDCPP_THREADS__) && defined(_LIBCPP_HAS_NO_THREADS) +#error _LIBCPP_HAS_NO_THREADS cannot be set when __STDCPP_THREADS__ is set. +#endif + +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(__STDCPP_THREADS__) +#define __STDCPP_THREADS__ 1 +#endif + +// The glibc and Bionic implementation of pthreads implements +// pthread_mutex_destroy as nop for regular mutexes. Additionally, Win32 +// mutexes have no destroy mechanism. +// +// This optimization can't be performed on Apple platforms, where +// pthread_mutex_destroy can allow the kernel to release resources. +// See https://llvm.org/D64298 for details. +// +// TODO(EricWF): Enable this optimization on Bionic after speaking to their +// respective stakeholders. +#if (defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && defined(__GLIBC__)) \ + || defined(_LIBCPP_HAS_THREAD_API_WIN32) +# define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION +#endif + +// Destroying a condvar is a nop on Windows. +// +// This optimization can't be performed on Apple platforms, where +// pthread_cond_destroy can allow the kernel to release resources. +// See https://llvm.org/D64298 for details. +// +// TODO(EricWF): This is potentially true for some pthread implementations +// as well. +#if defined(_LIBCPP_HAS_THREAD_API_WIN32) +# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION +#endif + +// Systems that use capability-based security (FreeBSD with Capsicum, +// Nuxi CloudABI) may only provide local filesystem access (using *at()). +// Functions like open(), rename(), unlink() and stat() should not be +// used, as they attempt to access the global filesystem namespace. +#ifdef __CloudABI__ +#define _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +#endif + +// CloudABI is intended for running networked services. Processes do not +// have standard input and output channels. +#ifdef __CloudABI__ +#define _LIBCPP_HAS_NO_STDIN +#define _LIBCPP_HAS_NO_STDOUT +#endif + +// Some systems do not provide gets() in their C library, for security reasons. +#ifndef _LIBCPP_C_HAS_NO_GETS +# if defined(_LIBCPP_MSVCRT) || \ + (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) +# define _LIBCPP_C_HAS_NO_GETS +# endif +#endif + +#if defined(__BIONIC__) || defined(__CloudABI__) || \ + defined(__Fuchsia__) || defined(__wasi__) || \ + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__COSMOPOLITAN__) +#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE +#endif + +// Thread-unsafe functions such as strtok() and localtime() +// are not available. +#ifdef __CloudABI__ +#define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS +#endif + +#if __has_feature(cxx_atomic) || __has_extension(c_atomic) || __has_keyword(_Atomic) +# define _LIBCPP_HAS_C_ATOMIC_IMP +#elif defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_HAS_GCC_ATOMIC_IMP +#endif + +#if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && \ + !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \ + !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP)) \ + || defined(_LIBCPP_HAS_NO_THREADS) +# define _LIBCPP_HAS_NO_ATOMIC_HEADER +#else +# ifndef _LIBCPP_ATOMIC_FLAG_TYPE +# define _LIBCPP_ATOMIC_FLAG_TYPE bool +# endif +# ifdef _LIBCPP_FREESTANDING +# define _LIBCPP_ATOMIC_ONLY_USE_BUILTINS +# endif +#endif + +#ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +#endif + +#if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) +# if defined(__clang__) && __has_attribute(acquire_capability) +// Work around the attribute handling in clang. When both __declspec and +// __attribute__ are present, the processing goes awry preventing the definition +// of the types. +# if !defined(_LIBCPP_OBJECT_FORMAT_COFF) +# define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +# endif +# endif +#endif + +#if __has_attribute(require_constant_initialization) +# define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__)) +#else +# define _LIBCPP_SAFE_STATIC +#endif + +#if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700 +#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF +#endif + +#if !__has_builtin(__builtin_is_constant_evaluated) && _GNUC_VER < 900 +#define _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED +#endif + +#if !defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) +# if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) +# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS +# endif +#endif + +#if __has_attribute(diagnose_if) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS) +# define _LIBCPP_DIAGNOSE_WARNING(...) \ + __attribute__((diagnose_if(__VA_ARGS__, "warning"))) +# define _LIBCPP_DIAGNOSE_ERROR(...) \ + __attribute__((diagnose_if(__VA_ARGS__, "error"))) +#else +# define _LIBCPP_DIAGNOSE_WARNING(...) +# define _LIBCPP_DIAGNOSE_ERROR(...) +#endif + +// Use a function like macro to imply that it must be followed by a semicolon +#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough) +# define _LIBCPP_FALLTHROUGH() [[fallthrough]] +#elif __has_cpp_attribute(clang::fallthrough) +# define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]] +#elif __has_attribute(fallthough) || _GNUC_VER >= 700 +# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) +#else +# define _LIBCPP_FALLTHROUGH() ((void)0) +#endif + +#if __has_attribute(__nodebug__) +#define _LIBCPP_NODEBUG __attribute__((__nodebug__)) +#else +#define _LIBCPP_NODEBUG +#endif + +#ifndef _LIBCPP_NODEBUG_TYPE +#if __has_attribute(__nodebug__) && \ + (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 900) +#define _LIBCPP_NODEBUG_TYPE __attribute__((nodebug)) +#else +#define _LIBCPP_NODEBUG_TYPE +#endif +#endif // !defined(_LIBCPP_NODEBUG_TYPE) + +#if defined(_LIBCPP_ABI_MICROSOFT) && \ + (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases)) +# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases) +#else +# define _LIBCPP_DECLSPEC_EMPTY_BASES +#endif + +#if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) +#define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR +#define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS +#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE +#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS +#endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES + +#if !defined(__cpp_deduction_guides) || __cpp_deduction_guides < 201611 +#define _LIBCPP_HAS_NO_DEDUCTION_GUIDES +#endif + +#if !__has_keyword(__is_aggregate) && (_GNUC_VER_NEW < 7001) +#define _LIBCPP_HAS_NO_IS_AGGREGATE +#endif + +#if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L +#define _LIBCPP_HAS_NO_COROUTINES +#endif + +// FIXME: Correct this macro when either (A) a feature test macro for the +// spaceship operator is provided, or (B) a compiler provides a complete +// implementation. +#define _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + +// Decide whether to use availability macros. +#if !defined(_LIBCPP_BUILDING_LIBRARY) && \ + !defined(_LIBCPP_DISABLE_AVAILABILITY) && \ + __has_feature(attribute_availability_with_strict) && \ + __has_feature(attribute_availability_in_templates) && \ + __has_extension(pragma_clang_attribute_external_declaration) +# ifdef __APPLE__ +# define _LIBCPP_USE_AVAILABILITY_APPLE +# endif +#endif + +// Define availability macros. +#if defined(_LIBCPP_USE_AVAILABILITY_APPLE) +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ + __attribute__((availability(macosx,strict,introduced=10.14))) \ + __attribute__((availability(ios,strict,introduced=12.0))) \ + __attribute__((availability(tvos,strict,introduced=12.0))) \ + __attribute__((availability(watchos,strict,introduced=5.0))) +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \ + _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ + _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ + __attribute__((availability(ios,strict,introduced=6.0))) +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_FILESYSTEM \ + __attribute__((availability(macosx,strict,introduced=10.15))) \ + __attribute__((availability(ios,strict,introduced=13.0))) \ + __attribute__((availability(tvos,strict,introduced=13.0))) \ + __attribute__((availability(watchos,strict,introduced=6.0))) +# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \ + _Pragma("clang attribute push(__attribute__((availability(macosx,strict,introduced=10.15))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))") +# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") +#else +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR +# define _LIBCPP_AVAILABILITY_FILESYSTEM +# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP +#endif + +// Define availability that depends on _LIBCPP_NO_EXCEPTIONS. +#ifdef _LIBCPP_NO_EXCEPTIONS +# define _LIBCPP_AVAILABILITY_FUTURE +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS +#else +# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +#endif + +// The stream API was dropped and re-added in the dylib shipped on macOS +// and iOS. We can only assume the dylib to provide these definitions for +// macosx >= 10.9 and ios >= 7.0. Otherwise, the definitions are available +// from the headers, but not from the dylib. Explicit instantiation +// declarations for streams exist conditionally to this; if we provide +// an explicit instantiation declaration and we try to deploy to a dylib +// that does not provide those symbols, we'll get a load-time error. +#if !defined(_LIBCPP_BUILDING_LIBRARY) && \ + ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1090) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)) +# define _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB +#endif + +#if defined(_LIBCPP_COMPILER_IBM) +#define _LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO +#endif + +#if defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO) +# define _LIBCPP_PUSH_MACROS +# define _LIBCPP_POP_MACROS +#else + // Don't warn about macro conflicts when we can restore them at the + // end of the header. +# ifndef _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS +# define _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS +# endif +# if defined(_LIBCPP_COMPILER_MSVC) +# define _LIBCPP_PUSH_MACROS \ + __pragma(push_macro("min")) \ + __pragma(push_macro("max")) +# define _LIBCPP_POP_MACROS \ + __pragma(pop_macro("min")) \ + __pragma(pop_macro("max")) +# else +# define _LIBCPP_PUSH_MACROS \ + _Pragma("push_macro(\"min\")") \ + _Pragma("push_macro(\"max\")") +# define _LIBCPP_POP_MACROS \ + _Pragma("pop_macro(\"min\")") \ + _Pragma("pop_macro(\"max\")") +# endif +#endif // defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO) + +#ifndef _LIBCPP_NO_AUTO_LINK +# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) +# if defined(_DLL) +# pragma comment(lib, "c++.lib") +# else +# pragma comment(lib, "libc++.lib") +# endif +# endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) +#endif // _LIBCPP_NO_AUTO_LINK + +#define _LIBCPP_UNUSED_VAR(x) ((void)(x)) + +// Configures the fopen close-on-exec mode character, if any. This string will +// be appended to any mode string used by fstream for fopen/fdopen. +// +// Not all platforms support this, but it helps avoid fd-leaks on platforms that +// do. +#if defined(__BIONIC__) +# define _LIBCPP_FOPEN_CLOEXEC_MODE "e" +#else +# define _LIBCPP_FOPEN_CLOEXEC_MODE +#endif + +#endif // __cplusplus + +#endif // _LIBCPP_CONFIG diff --git a/third_party/libcxx/__debug b/third_party/libcxx/__debug new file mode 100644 index 000000000..478560a27 --- /dev/null +++ b/third_party/libcxx/__debug @@ -0,0 +1,279 @@ +// -*- C++ -*- +//===--------------------------- __debug ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_DEBUG_H +#define _LIBCPP_DEBUG_H + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/iosfwd" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if defined(_LIBCPP_HAS_NO_NULLPTR) +# include "third_party/libcxx/cstddef" +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) +# include "third_party/libcxx/cstdlib" +# include "third_party/libcxx/cstdio" +# include "third_party/libcxx/cstddef" +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_ASSERT) +# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : \ + _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 2 +#ifndef _LIBCPP_DEBUG_ASSERT +#define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) +#endif +#define _LIBCPP_DEBUG_MODE(...) __VA_ARGS__ +#endif + +#ifndef _LIBCPP_ASSERT +# define _LIBCPP_ASSERT(x, m) ((void)0) +#endif +#ifndef _LIBCPP_DEBUG_ASSERT +# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) +#endif +#ifndef _LIBCPP_DEBUG_MODE +#define _LIBCPP_DEBUG_MODE(...) ((void)0) +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __libcpp_debug_info() + : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m) + : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {} + + _LIBCPP_FUNC_VIS std::string what() const; + + const char* __file_; + int __line_; + const char* __pred_; + const char* __msg_; +}; + +/// __libcpp_debug_function_type - The type of the assertion failure handler. +typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&); + +/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT +/// fails. +extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function; + +/// __libcpp_abort_debug_function - A debug handler that aborts when called. +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS +void __libcpp_abort_debug_function(__libcpp_debug_info const&); + +/// __libcpp_set_debug_function - Set the debug handler to the specified +/// function. +_LIBCPP_FUNC_VIS +bool __libcpp_set_debug_function(__libcpp_debug_function_type __func); + +#if _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) + +struct _LIBCPP_TYPE_VIS __c_node; + +struct _LIBCPP_TYPE_VIS __i_node +{ + void* __i_; + __i_node* __next_; + __c_node* __c_; + +#ifndef _LIBCPP_CXX03_LANG + __i_node(const __i_node&) = delete; + __i_node& operator=(const __i_node&) = delete; +#else +private: + __i_node(const __i_node&); + __i_node& operator=(const __i_node&); +public: +#endif + _LIBCPP_INLINE_VISIBILITY + __i_node(void* __i, __i_node* __next, __c_node* __c) + : __i_(__i), __next_(__next), __c_(__c) {} + ~__i_node(); +}; + +struct _LIBCPP_TYPE_VIS __c_node +{ + void* __c_; + __c_node* __next_; + __i_node** beg_; + __i_node** end_; + __i_node** cap_; + +#ifndef _LIBCPP_CXX03_LANG + __c_node(const __c_node&) = delete; + __c_node& operator=(const __c_node&) = delete; +#else +private: + __c_node(const __c_node&); + __c_node& operator=(const __c_node&); +public: +#endif + _LIBCPP_INLINE_VISIBILITY + __c_node(void* __c, __c_node* __next) + : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} + virtual ~__c_node(); + + virtual bool __dereferenceable(const void*) const = 0; + virtual bool __decrementable(const void*) const = 0; + virtual bool __addable(const void*, ptrdiff_t) const = 0; + virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; + + void __add(__i_node* __i); + _LIBCPP_HIDDEN void __remove(__i_node* __i); +}; + +template +struct _C_node + : public __c_node +{ + _C_node(void* __c, __c_node* __n) + : __c_node(__c, __n) {} + + virtual bool __dereferenceable(const void*) const; + virtual bool __decrementable(const void*) const; + virtual bool __addable(const void*, ptrdiff_t) const; + virtual bool __subscriptable(const void*, ptrdiff_t) const; +}; + +template +inline bool +_C_node<_Cont>::__dereferenceable(const void* __i) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__dereferenceable(__j); +} + +template +inline bool +_C_node<_Cont>::__decrementable(const void* __i) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__decrementable(__j); +} + +template +inline bool +_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__addable(__j, __n); +} + +template +inline bool +_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__subscriptable(__j, __n); +} + +class _LIBCPP_TYPE_VIS __libcpp_db +{ + __c_node** __cbeg_; + __c_node** __cend_; + size_t __csz_; + __i_node** __ibeg_; + __i_node** __iend_; + size_t __isz_; + + __libcpp_db(); +public: +#ifndef _LIBCPP_CXX03_LANG + __libcpp_db(const __libcpp_db&) = delete; + __libcpp_db& operator=(const __libcpp_db&) = delete; +#else +private: + __libcpp_db(const __libcpp_db&); + __libcpp_db& operator=(const __libcpp_db&); +public: +#endif + ~__libcpp_db(); + + class __db_c_iterator; + class __db_c_const_iterator; + class __db_i_iterator; + class __db_i_const_iterator; + + __db_c_const_iterator __c_end() const; + __db_i_const_iterator __i_end() const; + + typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*); + + template + _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) { + return ::new(__mem) _C_node<_Cont>(__c, __next); + } + + template + _LIBCPP_INLINE_VISIBILITY + void __insert_c(_Cont* __c) + { + __insert_c(static_cast(__c), &__create_C_node<_Cont>); + } + + void __insert_i(void* __i); + void __insert_c(void* __c, _InsertConstruct* __fn); + void __erase_c(void* __c); + + void __insert_ic(void* __i, const void* __c); + void __iterator_copy(void* __i, const void* __i0); + void __erase_i(void* __i); + + void* __find_c_from_i(void* __i) const; + void __invalidate_all(void* __c); + __c_node* __find_c_and_lock(void* __c) const; + __c_node* __find_c(void* __c) const; + void unlock() const; + + void swap(void* __c1, void* __c2); + + + bool __dereferenceable(const void* __i) const; + bool __decrementable(const void* __i) const; + bool __addable(const void* __i, ptrdiff_t __n) const; + bool __subscriptable(const void* __i, ptrdiff_t __n) const; + bool __less_than_comparable(const void* __i, const void* __j) const; +private: + _LIBCPP_HIDDEN + __i_node* __insert_iterator(void* __i); + _LIBCPP_HIDDEN + __i_node* __find_iterator(const void* __i) const; + + friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); +}; + +_LIBCPP_FUNC_VIS __libcpp_db* __get_db(); +_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); + + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_DEBUG_H + diff --git a/third_party/libcxx/__errc b/third_party/libcxx/__errc new file mode 100644 index 000000000..dd573c823 --- /dev/null +++ b/third_party/libcxx/__errc @@ -0,0 +1,217 @@ +// -*- C++ -*- +//===---------------------------- __errc ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ERRC +#define _LIBCPP___ERRC + +/* + system_error synopsis + +namespace std +{ + +enum class errc +{ + address_family_not_supported, // EAFNOSUPPORT + address_in_use, // EADDRINUSE + address_not_available, // EADDRNOTAVAIL + already_connected, // EISCONN + argument_list_too_long, // E2BIG + argument_out_of_domain, // EDOM + bad_address, // EFAULT + bad_file_descriptor, // EBADF + bad_message, // EBADMSG + broken_pipe, // EPIPE + connection_aborted, // ECONNABORTED + connection_already_in_progress, // EALREADY + connection_refused, // ECONNREFUSED + connection_reset, // ECONNRESET + cross_device_link, // EXDEV + destination_address_required, // EDESTADDRREQ + device_or_resource_busy, // EBUSY + directory_not_empty, // ENOTEMPTY + executable_format_error, // ENOEXEC + file_exists, // EEXIST + file_too_large, // EFBIG + filename_too_long, // ENAMETOOLONG + function_not_supported, // ENOSYS + host_unreachable, // EHOSTUNREACH + identifier_removed, // EIDRM + illegal_byte_sequence, // EILSEQ + inappropriate_io_control_operation, // ENOTTY + interrupted, // EINTR + invalid_argument, // EINVAL + invalid_seek, // ESPIPE + io_error, // EIO + is_a_directory, // EISDIR + message_size, // EMSGSIZE + network_down, // ENETDOWN + network_reset, // ENETRESET + network_unreachable, // ENETUNREACH + no_buffer_space, // ENOBUFS + no_child_process, // ECHILD + no_link, // ENOLINK + no_lock_available, // ENOLCK + no_message_available, // ENODATA + no_message, // ENOMSG + no_protocol_option, // ENOPROTOOPT + no_space_on_device, // ENOSPC + no_stream_resources, // ENOSR + no_such_device_or_address, // ENXIO + no_such_device, // ENODEV + no_such_file_or_directory, // ENOENT + no_such_process, // ESRCH + not_a_directory, // ENOTDIR + not_a_socket, // ENOTSOCK + not_a_stream, // ENOSTR + not_connected, // ENOTCONN + not_enough_memory, // ENOMEM + not_supported, // ENOTSUP + operation_canceled, // ECANCELED + operation_in_progress, // EINPROGRESS + operation_not_permitted, // EPERM + operation_not_supported, // EOPNOTSUPP + operation_would_block, // EWOULDBLOCK + owner_dead, // EOWNERDEAD + permission_denied, // EACCES + protocol_error, // EPROTO + protocol_not_supported, // EPROTONOSUPPORT + read_only_file_system, // EROFS + resource_deadlock_would_occur, // EDEADLK + resource_unavailable_try_again, // EAGAIN + result_out_of_range, // ERANGE + state_not_recoverable, // ENOTRECOVERABLE + stream_timeout, // ETIME + text_file_busy, // ETXTBSY + timed_out, // ETIMEDOUT + too_many_files_open_in_system, // ENFILE + too_many_files_open, // EMFILE + too_many_links, // EMLINK + too_many_symbolic_link_levels, // ELOOP + value_too_large, // EOVERFLOW + wrong_protocol_type // EPROTOTYPE +}; + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/cerrno" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Some error codes are not present on all platforms, so we provide equivalents +// for them: + +//enum class errc +_LIBCPP_DECLARE_STRONG_ENUM(errc) +{ + address_family_not_supported, + address_in_use, + address_not_available, + already_connected, + argument_list_too_long, + argument_out_of_domain, + bad_address, + bad_file_descriptor, + bad_message, + broken_pipe, + connection_aborted, + connection_already_in_progress, + connection_refused, + connection_reset, + cross_device_link, + destination_address_required, + device_or_resource_busy, + directory_not_empty, + executable_format_error, + file_exists, + file_too_large, + filename_too_long, + function_not_supported, + host_unreachable, + identifier_removed, + illegal_byte_sequence, + inappropriate_io_control_operation, + interrupted, + invalid_argument, + invalid_seek, + io_error, + is_a_directory, + message_size, + network_down, + network_reset, + network_unreachable, + no_buffer_space, + no_child_process, + no_link, + no_lock_available, +#ifdef ENODATA + no_message_available, +#else + no_message_available, +#endif + no_message, + no_protocol_option, + no_space_on_device, +#ifdef ENOSR + no_stream_resources, +#else + no_stream_resources, +#endif + no_such_device_or_address, + no_such_device, + no_such_file_or_directory, + no_such_process, + not_a_directory, + not_a_socket, +#ifdef ENOSTR + not_a_stream, +#else + not_a_stream, +#endif + not_connected, + not_enough_memory, + not_supported, + operation_canceled, + operation_in_progress, + operation_not_permitted, + operation_not_supported, + operation_would_block, + owner_dead, + permission_denied, + protocol_error, + protocol_not_supported, + read_only_file_system, + resource_deadlock_would_occur, + resource_unavailable_try_again, + result_out_of_range, + state_not_recoverable, +#ifdef ETIME + stream_timeout, +#else + stream_timeout, +#endif + text_file_busy, + timed_out, + too_many_files_open_in_system, + too_many_files_open, + too_many_links, + too_many_symbolic_link_levels, + value_too_large, + wrong_protocol_type +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ERRC diff --git a/third_party/libcxx/__functional_base b/third_party/libcxx/__functional_base new file mode 100644 index 000000000..cb7ddda5c --- /dev/null +++ b/third_party/libcxx/__functional_base @@ -0,0 +1,652 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FUNCTIONAL_BASE +#define _LIBCPP_FUNCTIONAL_BASE + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/type_traits" +#include "third_party/libcxx/typeinfo" +#include "third_party/libcxx/exception" +#include "third_party/libcxx/new" +#include "third_party/libcxx/utility" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS binary_function +{ + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; +}; + +template +struct __has_result_type +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::result_type* = 0); +public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x < __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS less +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +// __weak_result_type + +template +struct __derives_from_unary_function +{ +private: + struct __two {char __lx; char __lxx;}; + static __two __test(...); + template + static unary_function<_Ap, _Rp> + __test(const volatile unary_function<_Ap, _Rp>*); +public: + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; +}; + +template +struct __derives_from_binary_function +{ +private: + struct __two {char __lx; char __lxx;}; + static __two __test(...); + template + static binary_function<_A1, _A2, _Rp> + __test(const volatile binary_function<_A1, _A2, _Rp>*); +public: + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; +}; + +template ::value> +struct __maybe_derive_from_unary_function // bool is true + : public __derives_from_unary_function<_Tp>::type +{ +}; + +template +struct __maybe_derive_from_unary_function<_Tp, false> +{ +}; + +template ::value> +struct __maybe_derive_from_binary_function // bool is true + : public __derives_from_binary_function<_Tp>::type +{ +}; + +template +struct __maybe_derive_from_binary_function<_Tp, false> +{ +}; + +template ::value> +struct __weak_result_type_imp // bool is true + : public __maybe_derive_from_unary_function<_Tp>, + public __maybe_derive_from_binary_function<_Tp> +{ + typedef _LIBCPP_NODEBUG_TYPE typename _Tp::result_type result_type; +}; + +template +struct __weak_result_type_imp<_Tp, false> + : public __maybe_derive_from_unary_function<_Tp>, + public __maybe_derive_from_binary_function<_Tp> +{ +}; + +template +struct __weak_result_type + : public __weak_result_type_imp<_Tp> +{ +}; + +// 0 argument case + +template +struct __weak_result_type<_Rp ()> +{ + typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (&)()> +{ + typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (*)()> +{ + typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; +}; + +// 1 argument case + +template +struct __weak_result_type<_Rp (_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (&)(_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (*)(_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)()> + : public unary_function<_Cp*, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() const> + : public unary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() volatile> + : public unary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() const volatile> + : public unary_function +{ +}; + +// 2 argument case + +template +struct __weak_result_type<_Rp (_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (*)(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (&)(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1)> + : public binary_function<_Cp*, _A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) const> + : public binary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> + : public binary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> + : public binary_function +{ +}; + + +#ifndef _LIBCPP_CXX03_LANG +// 3 or more arguments + +template +struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> +{ + typedef _Rp result_type; +}; + +template +struct __invoke_return +{ + typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type; +}; + +#else // defined(_LIBCPP_CXX03_LANG) + +#include "third_party/libcxx/__functional_base_03" + +#endif // !defined(_LIBCPP_CXX03_LANG) + + +template +struct __invoke_void_return_wrapper +{ +#ifndef _LIBCPP_CXX03_LANG + template + static _Ret __call(_Args&&... __args) { + return __invoke(_VSTD::forward<_Args>(__args)...); + } +#else + template + static _Ret __call(_Fn __f) { + return __invoke(__f); + } + + template + static _Ret __call(_Fn __f, _A0& __a0) { + return __invoke(__f, __a0); + } + + template + static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { + return __invoke(__f, __a0, __a1); + } + + template + static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ + return __invoke(__f, __a0, __a1, __a2); + } +#endif +}; + +template <> +struct __invoke_void_return_wrapper +{ +#ifndef _LIBCPP_CXX03_LANG + template + static void __call(_Args&&... __args) { + __invoke(_VSTD::forward<_Args>(__args)...); + } +#else + template + static void __call(_Fn __f) { + __invoke(__f); + } + + template + static void __call(_Fn __f, _A0& __a0) { + __invoke(__f, __a0); + } + + template + static void __call(_Fn __f, _A0& __a0, _A1& __a1) { + __invoke(__f, __a0, __a1); + } + + template + static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { + __invoke(__f, __a0, __a1, __a2); + } +#endif +}; + +template +class _LIBCPP_TEMPLATE_VIS reference_wrapper + : public __weak_result_type<_Tp> +{ +public: + // types + typedef _Tp type; +private: + type* __f_; + +public: + // construct/copy/destroy + _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT + : __f_(_VSTD::addressof(__f)) {} +#ifndef _LIBCPP_CXX03_LANG + private: reference_wrapper(type&&); public: // = delete; // do not bind to temps +#endif + + // access + _LIBCPP_INLINE_VISIBILITY operator type& () const _NOEXCEPT {return *__f_;} + _LIBCPP_INLINE_VISIBILITY type& get() const _NOEXCEPT {return *__f_;} + +#ifndef _LIBCPP_CXX03_LANG + // invoke + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_of::type + operator() (_ArgTypes&&... __args) const { + return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); + } +#else + + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return::type + operator() () const { + return __invoke(get()); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0& __a0) const { + return __invoke(get(), __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0 const& __a0) const { + return __invoke(get(), __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1& __a1) const { + return __invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1& __a1) const { + return __invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1 const& __a1) const { + return __invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1 const& __a1) const { + return __invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } +#endif // _LIBCPP_CXX03_LANG +}; + + +template +inline _LIBCPP_INLINE_VISIBILITY +reference_wrapper<_Tp> +ref(_Tp& __t) _NOEXCEPT +{ + return reference_wrapper<_Tp>(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reference_wrapper<_Tp> +ref(reference_wrapper<_Tp> __t) _NOEXCEPT +{ + return ref(__t.get()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reference_wrapper +cref(const _Tp& __t) _NOEXCEPT +{ + return reference_wrapper(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reference_wrapper +cref(reference_wrapper<_Tp> __t) _NOEXCEPT +{ + return cref(__t.get()); +} + +#ifndef _LIBCPP_CXX03_LANG +template void ref(const _Tp&&) = delete; +template void cref(const _Tp&&) = delete; +#endif + +#if _LIBCPP_STD_VER > 11 +template +struct __is_transparent : false_type {}; + +template +struct __is_transparent<_Tp, _Up, + typename __void_t::type> + : true_type {}; +#endif + +// allocator_arg_t + +struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; }; + +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) +extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; +#else +/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); +#endif + +// uses_allocator + +template +struct __has_allocator_type +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::allocator_type* = 0); +public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + +template ::value> +struct __uses_allocator + : public integral_constant::value> +{ +}; + +template +struct __uses_allocator<_Tp, _Alloc, false> + : public false_type +{ +}; + +template +struct _LIBCPP_TEMPLATE_VIS uses_allocator + : public __uses_allocator<_Tp, _Alloc> +{ +}; + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_INLINE_VAR constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; +#endif + +#ifndef _LIBCPP_CXX03_LANG + +// allocator construction + +template +struct __uses_alloc_ctor_imp +{ + typedef _LIBCPP_NODEBUG_TYPE typename __uncvref<_Alloc>::type _RawAlloc; + static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value; + static const bool __ic = + is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; + static const int value = __ua ? 2 - __ic : 0; +}; + +template +struct __uses_alloc_ctor + : integral_constant::value> + {}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &, _Args &&... __args ) +{ + new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); +} + +// FIXME: This should have a version which takes a non-const alloc. +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) +{ + new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); +} + +// FIXME: This should have a version which takes a non-const alloc. +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) +{ + new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_FUNCTIONAL_BASE diff --git a/third_party/libcxx/__functional_base_03 b/third_party/libcxx/__functional_base_03 new file mode 100644 index 000000000..e6dac90c8 --- /dev/null +++ b/third_party/libcxx/__functional_base_03 @@ -0,0 +1,223 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FUNCTIONAL_BASE_03 +#define _LIBCPP_FUNCTIONAL_BASE_03 + +// manual variadic expansion for + +// __invoke + +template +struct __enable_invoke_imp; + +template +struct __enable_invoke_imp<_Ret, _T1, true, true> { + typedef _Ret _Bullet1; + typedef _Bullet1 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1, true, false> { + typedef _Ret _Bullet2; + typedef _Bullet2 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1, false, true> { + typedef typename add_lvalue_reference< + typename __apply_cv<_T1, _Ret>::type + >::type _Bullet3; + typedef _Bullet3 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1, false, false> { + typedef typename add_lvalue_reference< + typename __apply_cv()), _Ret>::type + >::type _Bullet4; + typedef _Bullet4 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1*, false, false> { + typedef typename add_lvalue_reference< + typename __apply_cv<_T1, _Ret>::type + >::type _Bullet4; + typedef _Bullet4 type; +}; + +template , + class _Ret = typename _Traits::_ReturnType, + class _Class = typename _Traits::_ClassType> +struct __enable_invoke : __enable_invoke_imp< + _Ret, _T1, + is_member_function_pointer<_Fn>::value, + is_base_of<_Class, typename remove_reference<_T1>::type>::value> +{ +}; + +__nat __invoke(__any, ...); + +// first bullet + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1) { + return (__t1.*__f)(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1, _A0& __a0) { + return (__t1.*__f)(__a0); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { + return (__t1.*__f)(__a0, __a1); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { + return (__t1.*__f)(__a0, __a1, __a2); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1) { + return ((*__t1).*__f)(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1, _A0& __a0) { + return ((*__t1).*__f)(__a0); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { + return ((*__t1).*__f)(__a0, __a1); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { + return ((*__t1).*__f)(__a0, __a1, __a2); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet3 +__invoke(_Fn __f, _T1& __t1) { + return __t1.*__f; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet4 +__invoke(_Fn __f, _T1& __t1) { + return (*__t1).*__f; +} + +// fifth bullet + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(_VSTD::declval<_Fp&>()()) +__invoke(_Fp& __f) +{ + return __f(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) +__invoke(_Fp& __f, _A0& __a0) +{ + return __f(__a0); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>())) +__invoke(_Fp& __f, _A0& __a0, _A1& __a1) +{ + return __f(__a0, __a1); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>())) +__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) +{ + return __f(__a0, __a1, __a2); +} + +template >::value> +struct __invoke_return +{ + typedef typename __weak_result_type<_Fp>::result_type type; +}; + +template +struct __invoke_return<_Fp, false> +{ + typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; +}; + +template +struct __invoke_return0 +{ + typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; +}; + +template +struct __invoke_return0<_Rp _Tp::*, _A0> +{ + typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; +}; + +template +struct __invoke_return1 +{ + typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), + _VSTD::declval<_A1&>())) type; +}; + +template +struct __invoke_return1<_Rp _Class::*, _A0, _A1> { + typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; +}; + +template +struct __invoke_return2 +{ + typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), + _VSTD::declval<_A1&>(), + _VSTD::declval<_A2&>())) type; +}; + +template +struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> { + typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type; +}; +#endif // _LIBCPP_FUNCTIONAL_BASE_03 diff --git a/third_party/libcxx/__hash_table b/third_party/libcxx/__hash_table new file mode 100644 index 000000000..16595fab1 --- /dev/null +++ b/third_party/libcxx/__hash_table @@ -0,0 +1,2913 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP__HASH_TABLE +#define _LIBCPP__HASH_TABLE + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/initializer_list" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/iterator" +#include "third_party/libcxx/algorithm" +#include "third_party/libcxx/cmath" +#include "third_party/libcxx/utility" +#include "third_party/libcxx/type_traits" + +#include "third_party/libcxx/__debug" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __hash_value_type; + +#ifndef _LIBCPP_CXX03_LANG +template +struct __is_hash_value_type_imp : false_type {}; + +template +struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value>> : true_type {}; + +template +struct __is_hash_value_type : false_type {}; + +template +struct __is_hash_value_type<_One> : __is_hash_value_type_imp::type> {}; +#endif + +_LIBCPP_FUNC_VIS +size_t __next_prime(size_t __n); + +template +struct __hash_node_base +{ + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef __hash_node_base __first_node; + typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer; + typedef _NodePtr __node_pointer; + +#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) + typedef __node_base_pointer __next_pointer; +#else + typedef typename conditional< + is_pointer<__node_pointer>::value, + __node_base_pointer, + __node_pointer>::type __next_pointer; +#endif + + __next_pointer __next_; + + _LIBCPP_INLINE_VISIBILITY + __next_pointer __ptr() _NOEXCEPT { + return static_cast<__next_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(*this)); + } + + _LIBCPP_INLINE_VISIBILITY + __node_pointer __upcast() _NOEXCEPT { + return static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(*this)); + } + + _LIBCPP_INLINE_VISIBILITY + size_t __hash() const _NOEXCEPT { + return static_cast<__node_type const&>(*this).__hash_; + } + + _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} +}; + +template +struct __hash_node + : public __hash_node_base + < + typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type + > +{ + typedef _Tp __node_value_type; + + size_t __hash_; + __node_value_type __value_; +}; + +inline _LIBCPP_INLINE_VISIBILITY +bool +__is_hash_power2(size_t __bc) +{ + return __bc > 2 && !(__bc & (__bc - 1)); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t +__constrain_hash(size_t __h, size_t __bc) +{ + return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : + (__h < __bc ? __h : __h % __bc); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t +__next_hash_pow2(size_t __n) +{ + return __n < 2 ? __n : (size_t(1) << (std::numeric_limits::digits - __libcpp_clz(__n-1))); +} + + +template class __hash_table; + +template class _LIBCPP_TEMPLATE_VIS __hash_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; +template class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; + +template +struct __hash_key_value_types { + static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, ""); + typedef _Tp key_type; + typedef _Tp __node_value_type; + typedef _Tp __container_value_type; + static const bool __is_map = false; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(_Tp const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& __get_value(__node_value_type const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n); + } +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __container_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v); + } +#endif +}; + +template +struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __hash_value_type<_Key, _Tp> __node_value_type; + typedef pair __container_value_type; + typedef __container_value_type __map_value_type; + static const bool __is_map = true; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(__container_value_type const& __v) { + return __v.first; + } + + template + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t.__get_value(); + } + + template + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n.__get_value()); + } +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static pair __move(__node_value_type& __v) { + return __v.__move(); + } +#endif + +}; + +template , + bool = _KVTypes::__is_map> +struct __hash_map_pointer_types {}; + +template +struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { + typedef typename _KVTypes::__map_value_type _Mv; + typedef typename __rebind_pointer<_AllocPtr, _Mv>::type + __map_value_type_pointer; + typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type + __const_map_value_type_pointer; +}; + +template ::element_type> +struct __hash_node_types; + +template +struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > + : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> + +{ + typedef __hash_key_value_types<_Tp> __base; + +public: + typedef ptrdiff_t difference_type; + typedef size_t size_type; + + typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; + + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_pointer; + + typedef __hash_node_base<__node_pointer> __node_base_type; + typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type + __node_base_pointer; + + typedef typename __node_base_type::__next_pointer __next_pointer; + + typedef _Tp __node_value_type; + typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type + __node_value_type_pointer; + typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type + __const_node_value_type_pointer; + +private: + static_assert(!is_const<__node_type>::value, + "_NodePtr should never be a pointer to const"); + static_assert((is_same::element_type, void>::value), + "_VoidPtr does not point to unqualified void type"); + static_assert((is_same::type, + _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); +}; + +template +struct __hash_node_types_from_iterator; +template +struct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template +struct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template +struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template +struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; + + +template +struct __make_hash_node_types { + typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; + typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr; + typedef __hash_node_types<_NodePtr> type; +}; + +template +class _LIBCPP_TEMPLATE_VIS __hash_iterator +{ + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + + __next_pointer __node_; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { + _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_iterator(const __hash_iterator& __i) + : __node_(__i.__node_) + { + __get_db()->__iterator_copy(this, &__i); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator& operator=(const __hash_iterator& __i) + { + if (this != &__i) + { + __get_db()->__iterator_copy(this, &__i); + __node_ = __i.__node_; + } + return *this; + } +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); + return __node_->__upcast()->__value_; + } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container iterator"); + __node_ = __node_->__next_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator operator++(int) + { + __hash_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) + {return !(__x == __y);} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT + : __node_(__node) + { + __get_db()->__insert_ic(this, __c); + } +#else + _LIBCPP_INLINE_VISIBILITY + __hash_iterator(__next_pointer __node) _NOEXCEPT + : __node_(__node) + {} +#endif + template friend class __hash_table; + template friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; + template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; + template friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; +}; + +template +class _LIBCPP_TEMPLATE_VIS __hash_const_iterator +{ + static_assert(!is_const::element_type>::value, ""); + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + + __next_pointer __node_; + +public: + typedef __hash_iterator<_NodePtr> __non_const_iterator; + + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + + + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { + _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT + : __node_(__x.__node_) + { + _LIBCPP_DEBUG_MODE(__get_db()->__iterator_copy(this, &__x)); + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(const __hash_const_iterator& __i) + : __node_(__i.__node_) + { + __get_db()->__iterator_copy(this, &__i); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_const_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator& operator=(const __hash_const_iterator& __i) + { + if (this != &__i) + { + __get_db()->__iterator_copy(this, &__i); + __node_ = __i.__node_; + } + return *this; + } +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_iterator"); + return __node_->__upcast()->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container const_iterator"); + __node_ = __node_->__next_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator operator++(int) + { + __hash_const_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) + {return !(__x == __y);} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT + : __node_(__node) + { + __get_db()->__insert_ic(this, __c); + } +#else + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(__next_pointer __node) _NOEXCEPT + : __node_(__node) + {} +#endif + template friend class __hash_table; + template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; + template friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; +}; + +template +class _LIBCPP_TEMPLATE_VIS __hash_local_iterator +{ + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + + __next_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { + _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator(const __hash_local_iterator& __i) + : __node_(__i.__node_), + __bucket_(__i.__bucket_), + __bucket_count_(__i.__bucket_count_) + { + __get_db()->__iterator_copy(this, &__i); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_local_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator& operator=(const __hash_local_iterator& __i) + { + if (this != &__i) + { + __get_db()->__iterator_copy(this, &__i); + __node_ = __i.__node_; + __bucket_ = __i.__bucket_; + __bucket_count_ = __i.__bucket_count_; + } + return *this; + } +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + return __node_->__upcast()->__value_; + } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container local_iterator"); + __node_ = __node_->__next_; + if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator operator++(int) + { + __hash_local_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) + {return !(__x == __y);} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator(__next_pointer __node, size_t __bucket, + size_t __bucket_count, const void* __c) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + __get_db()->__insert_ic(this, __c); + if (__node_ != nullptr) + __node_ = __node_->__next_; + } +#else + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator(__next_pointer __node, size_t __bucket, + size_t __bucket_count) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + if (__node_ != nullptr) + __node_ = __node_->__next_; + } +#endif + template friend class __hash_table; + template friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; + template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; +}; + +template +class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator +{ + typedef __hash_node_types<_ConstNodePtr> _NodeTypes; + typedef _ConstNodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + + __next_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; + + typedef pointer_traits<__node_pointer> __pointer_traits; + typedef typename __pointer_traits::element_type __node; + typedef typename remove_const<__node>::type __non_const_node; + typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type + __non_const_node_pointer; +public: + typedef __hash_local_iterator<__non_const_node_pointer> + __non_const_iterator; + + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + + + _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { + _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT + : __node_(__x.__node_), + __bucket_(__x.__bucket_), + __bucket_count_(__x.__bucket_count_) + { + _LIBCPP_DEBUG_MODE(__get_db()->__iterator_copy(this, &__x)); + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(const __hash_const_local_iterator& __i) + : __node_(__i.__node_), + __bucket_(__i.__bucket_), + __bucket_count_(__i.__bucket_count_) + { + __get_db()->__iterator_copy(this, &__i); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_const_local_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) + { + if (this != &__i) + { + __get_db()->__iterator_copy(this, &__i); + __node_ = __i.__node_; + __bucket_ = __i.__bucket_; + __bucket_count_ = __i.__bucket_count_; + } + return *this; + } +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); + return __node_->__upcast()->__value_; + } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container const_local_iterator"); + __node_ = __node_->__next_; + if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator operator++(int) + { + __hash_const_local_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) + {return !(__x == __y);} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(__next_pointer __node, size_t __bucket, + size_t __bucket_count, const void* __c) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + __get_db()->__insert_ic(this, __c); + if (__node_ != nullptr) + __node_ = __node_->__next_; + } +#else + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(__next_pointer __node, size_t __bucket, + size_t __bucket_count) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + if (__node_ != nullptr) + __node_ = __node_->__next_; + } +#endif + template friend class __hash_table; + template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; +}; + +template +class __bucket_list_deallocator +{ + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::size_type size_type; + + __compressed_pair __data_; +public: + typedef typename __alloc_traits::pointer pointer; + + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator() + _NOEXCEPT_(is_nothrow_default_constructible::value) + : __data_(0) {} + + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator(const allocator_type& __a, size_type __size) + _NOEXCEPT_(is_nothrow_copy_constructible::value) + : __data_(__size, __a) {} + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator(__bucket_list_deallocator&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : __data_(_VSTD::move(__x.__data_)) + { + __x.size() = 0; + } +#endif + + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __data_.first();} + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __data_.first();} + + _LIBCPP_INLINE_VISIBILITY + allocator_type& __alloc() _NOEXCEPT {return __data_.second();} + _LIBCPP_INLINE_VISIBILITY + const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + __alloc_traits::deallocate(__alloc(), __p, size()); + } +}; + +template class __hash_map_node_destructor; + +template +class __hash_node_destructor +{ + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + +public: + typedef typename __alloc_traits::pointer pointer; +private: + typedef __hash_node_types _NodeTypes; + + allocator_type& __na_; + + __hash_node_destructor& operator=(const __hash_node_destructor&); + +public: + bool __value_constructed; + + _LIBCPP_INLINE_VISIBILITY + explicit __hash_node_destructor(allocator_type& __na, + bool __constructed = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__constructed) + {} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + if (__value_constructed) + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } + + template friend class __hash_map_node_destructor; +}; + +#if _LIBCPP_STD_VER > 14 +template +struct __generic_container_node_destructor; + +template +struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> + : __hash_node_destructor<_Alloc> +{ + using __hash_node_destructor<_Alloc>::__hash_node_destructor; +}; +#endif + +template +struct __enforce_unordered_container_requirements { +#ifndef _LIBCPP_CXX03_LANG + static_assert(__check_hash_requirements<_Key, _Hash>::value, + "the specified hash does not meet the Hash requirements"); + static_assert(is_copy_constructible<_Equal>::value, + "the specified comparator is required to be copy constructible"); +#endif + typedef int type; +}; + +template +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, + "the specified comparator type does not provide a viable const call operator") + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, + "the specified hash functor does not provide a viable const call operator") +#endif +typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type +__diagnose_unordered_container_requirements(int); + +// This dummy overload is used so that the compiler won't emit a spurious +// "no matching function for call to __diagnose_unordered_xxx" diagnostic +// when the overload above causes a hard error. +template +int __diagnose_unordered_container_requirements(void*); + +template +class __hash_table +{ +public: + typedef _Tp value_type; + typedef _Hash hasher; + typedef _Equal key_equal; + typedef _Alloc allocator_type; + +private: + typedef allocator_traits __alloc_traits; + typedef typename + __make_hash_node_types::type + _NodeTypes; +public: + + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + typedef typename _NodeTypes::key_type key_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; +#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE + typedef typename __alloc_traits::size_type size_type; +#else + typedef typename _NodeTypes::size_type size_type; +#endif + typedef typename _NodeTypes::difference_type difference_type; +public: + // Create __node + + typedef typename _NodeTypes::__node_type __node; + typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + typedef typename _NodeTypes::__void_pointer __void_pointer; + typedef typename _NodeTypes::__node_pointer __node_pointer; + typedef typename _NodeTypes::__node_pointer __node_const_pointer; + typedef typename _NodeTypes::__node_base_type __first_node; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; + +private: + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type + __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + +private: + + typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator; + typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; + typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; + typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; + typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; + + // --- Member data begin --- + __bucket_list __bucket_list_; + __compressed_pair<__first_node, __node_allocator> __p1_; + __compressed_pair __p2_; + __compressed_pair __p3_; + // --- Member data end --- + + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __p2_.first();} +public: + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __p2_.first();} + + _LIBCPP_INLINE_VISIBILITY + hasher& hash_function() _NOEXCEPT {return __p2_.second();} + _LIBCPP_INLINE_VISIBILITY + const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} + + _LIBCPP_INLINE_VISIBILITY + float& max_load_factor() _NOEXCEPT {return __p3_.first();} + _LIBCPP_INLINE_VISIBILITY + float max_load_factor() const _NOEXCEPT {return __p3_.first();} + + _LIBCPP_INLINE_VISIBILITY + key_equal& key_eq() _NOEXCEPT {return __p3_.second();} + _LIBCPP_INLINE_VISIBILITY + const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} + + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __node_alloc() const _NOEXCEPT + {return __p1_.second();} + +public: + typedef __hash_iterator<__node_pointer> iterator; + typedef __hash_const_iterator<__node_pointer> const_iterator; + typedef __hash_local_iterator<__node_pointer> local_iterator; + typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; + + _LIBCPP_INLINE_VISIBILITY + __hash_table() + _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value && + is_nothrow_default_constructible<__first_node>::value && + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value); + _LIBCPP_INLINE_VISIBILITY + __hash_table(const hasher& __hf, const key_equal& __eql); + __hash_table(const hasher& __hf, const key_equal& __eql, + const allocator_type& __a); + explicit __hash_table(const allocator_type& __a); + __hash_table(const __hash_table& __u); + __hash_table(const __hash_table& __u, const allocator_type& __a); +#ifndef _LIBCPP_CXX03_LANG + __hash_table(__hash_table&& __u) + _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value && + is_nothrow_move_constructible<__first_node>::value && + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value); + __hash_table(__hash_table&& __u, const allocator_type& __a); +#endif // _LIBCPP_CXX03_LANG + ~__hash_table(); + + __hash_table& operator=(const __hash_table& __u); +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + __hash_table& operator=(__hash_table&& __u) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); +#endif + template + void __assign_unique(_InputIterator __first, _InputIterator __last); + template + void __assign_multi(_InputIterator __first, _InputIterator __last); + + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT + { + return std::min( + __node_traits::max_size(__node_alloc()), + numeric_limits::max() + ); + } + +private: + _LIBCPP_INLINE_VISIBILITY + __next_pointer __node_insert_multi_prepare(size_t __cp_hash, + value_type& __cp_val); + _LIBCPP_INLINE_VISIBILITY + void __node_insert_multi_perform(__node_pointer __cp, + __next_pointer __pn) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + __next_pointer __node_insert_unique_prepare(size_t __nd_hash, + value_type& __nd_val); + _LIBCPP_INLINE_VISIBILITY + void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; + +public: + _LIBCPP_INLINE_VISIBILITY + pair __node_insert_unique(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY + iterator __node_insert_multi(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY + iterator __node_insert_multi(const_iterator __p, + __node_pointer __nd); + +#ifndef _LIBCPP_CXX03_LANG + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique_key_args(_Key const& __k, _Args&&... __args); + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique_impl(_Args&&... __args); + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, + pair + >::type __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_multi(_Args&&... __args); + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + + _LIBCPP_INLINE_VISIBILITY + pair + __insert_unique(__container_value_type&& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); + } + + template ::value + >::type> + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique(_Pp&& __x) { + return __emplace_unique(_VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(_Pp&& __x) { + return __emplace_multi(_VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, _Pp&& __x) { + return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); + } + +#else // !defined(_LIBCPP_CXX03_LANG) + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique_key_args(_Key const&, _Args& __args); + + iterator __insert_multi(const __container_value_type& __x); + iterator __insert_multi(const_iterator __p, const __container_value_type& __x); +#endif + + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique(const __container_value_type& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); + } + +#if _LIBCPP_STD_VER > 14 + template + _LIBCPP_INLINE_VISIBILITY + _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_unique(const_iterator __hint, + _NodeHandle&& __nh); + template + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_unique(_Table& __source); + + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(_NodeHandle&& __nh); + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); + template + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_multi(_Table& __source); + + template + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(key_type const& __key); + template + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(const_iterator __it); +#endif + + void clear() _NOEXCEPT; + void rehash(size_type __n); + _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) + {rehash(static_cast(ceil(__n / max_load_factor())));} + + _LIBCPP_INLINE_VISIBILITY + size_type bucket_count() const _NOEXCEPT + { + return __bucket_list_.get_deleter().size(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT; + + template + _LIBCPP_INLINE_VISIBILITY + size_type bucket(const _Key& __k) const + { + _LIBCPP_ASSERT(bucket_count() > 0, + "unordered container::bucket(key) called when bucket_count() == 0"); + return __constrain_hash(hash_function()(__k), bucket_count()); + } + + template + iterator find(const _Key& __x); + template + const_iterator find(const _Key& __x) const; + + typedef __hash_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + + iterator erase(const_iterator __p); + iterator erase(const_iterator __first, const_iterator __last); + template + size_type __erase_unique(const _Key& __k); + template + size_type __erase_multi(const _Key& __k); + __node_holder remove(const_iterator __p) _NOEXCEPT; + + template + _LIBCPP_INLINE_VISIBILITY + size_type __count_unique(const _Key& __k) const; + template + size_type __count_multi(const _Key& __k) const; + + template + pair + __equal_range_unique(const _Key& __k); + template + pair + __equal_range_unique(const _Key& __k) const; + + template + pair + __equal_range_multi(const _Key& __k); + template + pair + __equal_range_multi(const _Key& __k) const; + + void swap(__hash_table& __u) +#if _LIBCPP_STD_VER <= 11 + _NOEXCEPT_( + __is_nothrow_swappable::value && __is_nothrow_swappable::value + && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value + || __is_nothrow_swappable<__pointer_allocator>::value) + && (!__node_traits::propagate_on_container_swap::value + || __is_nothrow_swappable<__node_allocator>::value) + ); +#else + _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value); +#endif + + _LIBCPP_INLINE_VISIBILITY + size_type max_bucket_count() const _NOEXCEPT + {return max_size(); } + size_type bucket_size(size_type __n) const; + _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT + { + size_type __bc = bucket_count(); + return __bc != 0 ? (float)size() / __bc : 0.f; + } + _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT + { + _LIBCPP_ASSERT(__mlf > 0, + "unordered container::max_load_factor(lf) called with lf <= 0"); + max_load_factor() = _VSTD::max(__mlf, load_factor()); + } + + _LIBCPP_INLINE_VISIBILITY + local_iterator + begin(size_type __n) + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::begin(n) called with n >= bucket_count()"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); +#else + return local_iterator(__bucket_list_[__n], __n, bucket_count()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + local_iterator + end(size_type __n) + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::end(n) called with n >= bucket_count()"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return local_iterator(nullptr, __n, bucket_count(), this); +#else + return local_iterator(nullptr, __n, bucket_count()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + const_local_iterator + cbegin(size_type __n) const + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::cbegin(n) called with n >= bucket_count()"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); +#else + return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + const_local_iterator + cend(size_type __n) const + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::cend(n) called with n >= bucket_count()"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_local_iterator(nullptr, __n, bucket_count(), this); +#else + return const_local_iterator(nullptr, __n, bucket_count()); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + bool __dereferenceable(const const_iterator* __i) const; + bool __decrementable(const const_iterator* __i) const; + bool __addable(const const_iterator* __i, ptrdiff_t __n) const; + bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + +private: + void __rehash(size_type __n); + +#ifndef _LIBCPP_CXX03_LANG + template + __node_holder __construct_node(_Args&& ...__args); + + template + __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); +#else // _LIBCPP_CXX03_LANG + __node_holder __construct_node(const __container_value_type& __v); + __node_holder __construct_node_hash(size_t __hash, const __container_value_type& __v); +#endif + + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __hash_table& __u) + {__copy_assign_alloc(__u, integral_constant());} + void __copy_assign_alloc(const __hash_table& __u, true_type); + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __hash_table&, false_type) {} + +#ifndef _LIBCPP_CXX03_LANG + void __move_assign(__hash_table& __u, false_type); + void __move_assign(__hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table& __u) + _NOEXCEPT_( + !__node_traits::propagate_on_container_move_assignment::value || + (is_nothrow_move_assignable<__pointer_allocator>::value && + is_nothrow_move_assignable<__node_allocator>::value)) + {__move_assign_alloc(__u, integral_constant());} + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__pointer_allocator>::value && + is_nothrow_move_assignable<__node_allocator>::value) + { + __bucket_list_.get_deleter().__alloc() = + _VSTD::move(__u.__bucket_list_.get_deleter().__alloc()); + __node_alloc() = _VSTD::move(__u.__node_alloc()); + } + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} +#endif // _LIBCPP_CXX03_LANG + + void __deallocate_node(__next_pointer __np) _NOEXCEPT; + __next_pointer __detach() _NOEXCEPT; + + template friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; +}; + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() + _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value && + is_nothrow_default_constructible<__first_node>::value && + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value) + : __p2_(0), + __p3_(1.0f) +{ +} + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, + const key_equal& __eql) + : __bucket_list_(nullptr, __bucket_list_deleter()), + __p1_(), + __p2_(0, __hf), + __p3_(1.0f, __eql) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, + const key_equal& __eql, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__second_tag(), __node_allocator(__a)), + __p2_(0, __hf), + __p3_(1.0f, __eql) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__second_tag(), __node_allocator(__a)), + __p2_(0), + __p3_(1.0f) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) + : __bucket_list_(nullptr, + __bucket_list_deleter(allocator_traits<__pointer_allocator>:: + select_on_container_copy_construction( + __u.__bucket_list_.get_deleter().__alloc()), 0)), + __p1_(__second_tag(), allocator_traits<__node_allocator>:: + select_on_container_copy_construction(__u.__node_alloc())), + __p2_(0, __u.hash_function()), + __p3_(__u.__p3_) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__second_tag(), __node_allocator(__a)), + __p2_(0, __u.hash_function()), + __p3_(__u.__p3_) +{ +} + +#ifndef _LIBCPP_CXX03_LANG + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) + _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value && + is_nothrow_move_constructible<__first_node>::value && + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value) + : __bucket_list_(_VSTD::move(__u.__bucket_list_)), + __p1_(_VSTD::move(__u.__p1_)), + __p2_(_VSTD::move(__u.__p2_)), + __p3_(_VSTD::move(__u.__p3_)) +{ + if (size() > 0) + { + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__second_tag(), __node_allocator(__a)), + __p2_(0, _VSTD::move(__u.hash_function())), + __p3_(_VSTD::move(__u.__p3_)) +{ + if (__a == allocator_type(__u.__node_alloc())) + { + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + if (__u.size() > 0) + { + __p1_.first().__next_ = __u.__p1_.first().__next_; + __u.__p1_.first().__next_ = nullptr; + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); + size() = __u.size(); + __u.size() = 0; + } + } +} + +#endif // _LIBCPP_CXX03_LANG + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() +{ +#if defined(_LIBCPP_CXX03_LANG) + static_assert((is_copy_constructible::value), + "Predicate must be copy-constructible."); + static_assert((is_copy_constructible::value), + "Hasher must be copy-constructible."); +#endif + + __deallocate_node(__p1_.first().__next_); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__erase_c(this); +#endif +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc( + const __hash_table& __u, true_type) +{ + if (__node_alloc() != __u.__node_alloc()) + { + clear(); + __bucket_list_.reset(); + __bucket_list_.get_deleter().size() = 0; + } + __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); + __node_alloc() = __u.__node_alloc(); +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>& +__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) +{ + if (this != &__u) + { + __copy_assign_alloc(__u); + hash_function() = __u.hash_function(); + key_eq() = __u.key_eq(); + max_load_factor() = __u.max_load_factor(); + __assign_multi(__u.begin(), __u.end()); + } + return *this; +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) + _NOEXCEPT +{ + __node_allocator& __na = __node_alloc(); + while (__np != nullptr) + { + __next_pointer __next = __np->__next_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__node_ == __np) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + __node_pointer __real_np = __np->__upcast(); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); + __node_traits::deallocate(__na, __real_np, 1); + __np = __next; + } +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT +{ + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + __next_pointer __cache = __p1_.first().__next_; + __p1_.first().__next_ = nullptr; + return __cache; +} + +#ifndef _LIBCPP_CXX03_LANG + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( + __hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) +{ + clear(); + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + __move_assign_alloc(__u); + size() = __u.size(); + hash_function() = _VSTD::move(__u.hash_function()); + max_load_factor() = __u.max_load_factor(); + key_eq() = _VSTD::move(__u.key_eq()); + __p1_.first().__next_ = __u.__p1_.first().__next_; + if (size() > 0) + { + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->swap(this, &__u); +#endif +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( + __hash_table& __u, false_type) +{ + if (__node_alloc() == __u.__node_alloc()) + __move_assign(__u, true_type()); + else + { + hash_function() = _VSTD::move(__u.hash_function()); + key_eq() = _VSTD::move(__u.key_eq()); + max_load_factor() = __u.max_load_factor(); + if (bucket_count() != 0) + { + __next_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + const_iterator __i = __u.begin(); + while (__cache != nullptr && __u.size() != 0) + { + __cache->__upcast()->__value_ = + _VSTD::move(__u.remove(__i++)->__value_); + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate_node(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate_node(__cache); + } + const_iterator __i = __u.begin(); + while (__u.size() != 0) + { + __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); + __node_insert_multi(__h.get()); + __h.release(); + } + } +} + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>& +__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) +{ + __move_assign(__u, integral_constant()); + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +template +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, + _InputIterator __last) +{ + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value), + "__assign_unique may only be called with the containers value type"); + + if (bucket_count() != 0) + { + __next_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __cache != nullptr && __first != __last; ++__first) + { + __cache->__upcast()->__value_ = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_unique(__cache->__upcast()); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate_node(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate_node(__cache); + } + for (; __first != __last; ++__first) + __insert_unique(*__first); +} + +template +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, + _InputIterator __last) +{ + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value || + is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); + if (bucket_count() != 0) + { + __next_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __cache != nullptr && __first != __last; ++__first) + { + __cache->__upcast()->__value_ = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate_node(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate_node(__cache); + } + for (; __first != __last; ++__first) + __insert_multi(_NodeTypes::__get_value(*__first)); +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__p1_.first().__next_, this); +#else + return iterator(__p1_.first().__next_); +#endif +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(nullptr, this); +#else + return iterator(nullptr); +#endif +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(__p1_.first().__next_, this); +#else + return const_iterator(__p1_.first().__next_); +#endif +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(nullptr, this); +#else + return const_iterator(nullptr); +#endif +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT +{ + if (size() > 0) + { + __deallocate_node(__p1_.first().__next_); + __p1_.first().__next_ = nullptr; + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + } +} + + +// Prepare the container for an insertion of the value __value with the hash +// __hash. This does a lookup into the container to see if __value is already +// present, and performs a rehash if necessary. Returns a pointer to the +// existing element if it exists, otherwise nullptr. +// +// Note that this function does forward exceptions if key_eq() throws, and never +// mutates __value or actually inserts into the map. +template +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( + size_t __hash, value_type& __value) +{ + size_type __bc = bucket_count(); + + if (__bc != 0) + { + size_t __chash = __constrain_hash(__hash, __bc); + __next_pointer __ndptr = __bucket_list_[__chash]; + if (__ndptr != nullptr) + { + for (__ndptr = __ndptr->__next_; __ndptr != nullptr && + __constrain_hash(__ndptr->__hash(), __bc) == __chash; + __ndptr = __ndptr->__next_) + { + if (key_eq()(__ndptr->__upcast()->__value_, __value)) + return __ndptr; + } + } + } + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + } + return nullptr; +} + +// Insert the node __nd into the container by pushing it into the right bucket, +// and updating size(). Assumes that __nd->__hash is up-to-date, and that +// rehashing has already occurred and that no element with the same key exists +// in the map. +template +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( + __node_pointer __nd) _NOEXCEPT +{ + size_type __bc = bucket_count(); + size_t __chash = __constrain_hash(__nd->__hash(), __bc); + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) + { + __pn =__p1_.first().__ptr(); + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__nd->__next_ != nullptr) + __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); + } + else + { + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + } + ++size(); +} + +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) +{ + __nd->__hash_ = hash_function()(__nd->__value_); + __next_pointer __existing_node = + __node_insert_unique_prepare(__nd->__hash(), __nd->__value_); + + // Insert the node, unless it already exists in the container. + bool __inserted = false; + if (__existing_node == nullptr) + { + __node_insert_unique_perform(__nd); + __existing_node = __nd->__ptr(); + __inserted = true; + } +#if _LIBCPP_DEBUG_LEVEL >= 2 + return pair(iterator(__existing_node, this), __inserted); +#else + return pair(iterator(__existing_node), __inserted); +#endif +} + +// Prepare the container for an insertion of the value __cp_val with the hash +// __cp_hash. This does a lookup into the container to see if __cp_value is +// already present, and performs a rehash if necessary. Returns a pointer to the +// last occurance of __cp_val in the map. +// +// Note that this function does forward exceptions if key_eq() throws, and never +// mutates __value or actually inserts into the map. +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( + size_t __cp_hash, value_type& __cp_val) +{ + size_type __bc = bucket_count(); + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = __constrain_hash(__cp_hash, __bc); + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn != nullptr) + { + for (bool __found = false; __pn->__next_ != nullptr && + __constrain_hash(__pn->__next_->__hash(), __bc) == __chash; + __pn = __pn->__next_) + { + // __found key_eq() action + // false false loop + // true true loop + // false true set __found to true + // true false break + if (__found != (__pn->__next_->__hash() == __cp_hash && + key_eq()(__pn->__next_->__upcast()->__value_, __cp_val))) + { + if (!__found) + __found = true; + else + break; + } + } + } + return __pn; +} + +// Insert the node __cp into the container after __pn (which is the last node in +// the bucket that compares equal to __cp). Rehashing, and checking for +// uniqueness has already been performed (in __node_insert_multi_prepare), so +// all we need to do is update the bucket and size(). Assumes that __cp->__hash +// is up-to-date. +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( + __node_pointer __cp, __next_pointer __pn) _NOEXCEPT +{ + size_type __bc = bucket_count(); + size_t __chash = __constrain_hash(__cp->__hash_, __bc); + if (__pn == nullptr) + { + __pn =__p1_.first().__ptr(); + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__cp->__next_ != nullptr) + __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)] + = __cp->__ptr(); + } + else + { + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + if (__cp->__next_ != nullptr) + { + size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __cp->__ptr(); + } + } + ++size(); +} + + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) +{ + __cp->__hash_ = hash_function()(__cp->__value_); + __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); + __node_insert_multi_perform(__cp, __pn); + +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__cp->__ptr(), this); +#else + return iterator(__cp->__ptr()); +#endif +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( + const_iterator __p, __node_pointer __cp) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); +#endif + if (__p != end() && key_eq()(*__p, __cp->__value_)) + { + __next_pointer __np = __p.__node_; + __cp->__hash_ = __np->__hash(); + size_type __bc = bucket_count(); + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = __constrain_hash(__cp->__hash_, __bc); + __next_pointer __pp = __bucket_list_[__chash]; + while (__pp->__next_ != __np) + __pp = __pp->__next_; + __cp->__next_ = __np; + __pp->__next_ = static_cast<__next_pointer>(__cp); + ++size(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(static_cast<__next_pointer>(__cp), this); +#else + return iterator(static_cast<__next_pointer>(__cp)); +#endif + } + return __node_insert_multi(__cp); +} + + + +#ifndef _LIBCPP_CXX03_LANG +template +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) +#else +template +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args& __args) +#endif +{ + + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + bool __inserted = false; + __next_pointer __nd; + size_t __chash; + if (__bc != 0) + { + __chash = __constrain_hash(__hash, __bc); + __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) + { + if (key_eq()(__nd->__upcast()->__value_, __k)) + goto __done; + } + } + } + { +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node_hash(__hash, __args); +#endif + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + __chash = __constrain_hash(__hash, __bc); + } + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) + { + __pn = __p1_.first().__ptr(); + __h->__next_ = __pn->__next_; + __pn->__next_ = __h.get()->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__h->__next_ != nullptr) + __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)] + = __h.get()->__ptr(); + } + else + { + __h->__next_ = __pn->__next_; + __pn->__next_ = static_cast<__next_pointer>(__h.get()); + } + __nd = static_cast<__next_pointer>(__h.release()); + // increment size + ++size(); + __inserted = true; + } +__done: +#if _LIBCPP_DEBUG_LEVEL >= 2 + return pair(iterator(__nd, this), __inserted); +#else + return pair(iterator(__nd), __inserted); +#endif +} + +#ifndef _LIBCPP_CXX03_LANG + +template +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + pair __r = __node_insert_unique(__h.get()); + if (__r.second) + __h.release(); + return __r; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__h.get()); + __h.release(); + return __r; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( + const_iterator __p, _Args&&... __args) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); +#endif + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__p, __h.get()); + __h.release(); + return __r; +} + +#else // _LIBCPP_CXX03_LANG + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const __container_value_type& __x) +{ + __node_holder __h = __construct_node(__x); + iterator __r = __node_insert_multi(__h.get()); + __h.release(); + return __r; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, + const __container_value_type& __x) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container::insert(const_iterator, lvalue) called with an iterator not" + " referring to this unordered container"); +#endif + __node_holder __h = __construct_node(__x); + iterator __r = __node_insert_multi(__p, __h.get()); + __h.release(); + return __r; +} + +#endif // _LIBCPP_CXX03_LANG + +#if _LIBCPP_STD_VER > 14 +template +template +_LIBCPP_INLINE_VISIBILITY +_InsertReturnType +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( + _NodeHandle&& __nh) +{ + if (__nh.empty()) + return _InsertReturnType{end(), false, _NodeHandle()}; + pair __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release_ptr(); + return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)}; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( + const_iterator, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + pair __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release_ptr(); + return __result.first; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( + key_type const& __key) +{ + iterator __i = find(__key); + if (__i == end()) + return _NodeHandle(); + return __node_handle_extract<_NodeHandle>(__i); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( + const_iterator __p) +{ + allocator_type __alloc(__node_alloc()); + return _NodeHandle(remove(__p).release(), __alloc); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique( + _Table& __source) +{ + static_assert(is_same<__node, typename _Table::__node>::value, ""); + + for (typename _Table::iterator __it = __source.begin(); + __it != __source.end();) + { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __hash = hash_function()(__src_ptr->__value_); + __next_pointer __existing_node = + __node_insert_unique_prepare(__hash, __src_ptr->__value_); + auto __prev_iter = __it++; + if (__existing_node == nullptr) + { + (void)__source.remove(__prev_iter).release(); + __src_ptr->__hash_ = __hash; + __node_insert_unique_perform(__src_ptr); + } + } +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( + _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__nh.__ptr_); + __nh.__release_ptr(); + return __result; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( + const_iterator __hint, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__hint, __nh.__ptr_); + __nh.__release_ptr(); + return __result; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( + _Table& __source) +{ + static_assert(is_same::value, ""); + + for (typename _Table::iterator __it = __source.begin(); + __it != __source.end();) + { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __src_hash = hash_function()(__src_ptr->__value_); + __next_pointer __pn = + __node_insert_multi_prepare(__src_hash, __src_ptr->__value_); + (void)__source.remove(__it++).release(); + __src_ptr->__hash_ = __src_hash; + __node_insert_multi_perform(__src_ptr, __pn); + } +} +#endif // _LIBCPP_STD_VER > 14 + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n) +_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +{ + if (__n == 1) + __n = 2; + else if (__n & (__n - 1)) + __n = __next_prime(__n); + size_type __bc = bucket_count(); + if (__n > __bc) + __rehash(__n); + else if (__n < __bc) + { + __n = _VSTD::max + ( + __n, + __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) : + __next_prime(size_t(ceil(float(size()) / max_load_factor()))) + ); + if (__n < __bc) + __rehash(__n); + } +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__invalidate_all(this); +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); + __bucket_list_.reset(__nbc > 0 ? + __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); + __bucket_list_.get_deleter().size() = __nbc; + if (__nbc > 0) + { + for (size_type __i = 0; __i < __nbc; ++__i) + __bucket_list_[__i] = nullptr; + __next_pointer __pp = __p1_.first().__ptr(); + __next_pointer __cp = __pp->__next_; + if (__cp != nullptr) + { + size_type __chash = __constrain_hash(__cp->__hash(), __nbc); + __bucket_list_[__chash] = __pp; + size_type __phash = __chash; + for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr; + __cp = __pp->__next_) + { + __chash = __constrain_hash(__cp->__hash(), __nbc); + if (__chash == __phash) + __pp = __cp; + else + { + if (__bucket_list_[__chash] == nullptr) + { + __bucket_list_[__chash] = __pp; + __pp = __cp; + __phash = __chash; + } + else + { + __next_pointer __np = __cp; + for (; __np->__next_ != nullptr && + key_eq()(__cp->__upcast()->__value_, + __np->__next_->__upcast()->__value_); + __np = __np->__next_) + ; + __pp->__next_ = __np->__next_; + __np->__next_ = __bucket_list_[__chash]->__next_; + __bucket_list_[__chash]->__next_ = __cp; + + } + } + } + } + } +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) +{ + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) + { + size_t __chash = __constrain_hash(__hash, __bc); + __next_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + (__nd->__hash() == __hash + || __constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) + { + if ((__nd->__hash() == __hash) + && key_eq()(__nd->__upcast()->__value_, __k)) +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__nd, this); +#else + return iterator(__nd); +#endif + } + } + } + return end(); +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const +{ + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) + { + size_t __chash = __constrain_hash(__hash, __bc); + __next_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + (__hash == __nd->__hash() + || __constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) + { + if ((__nd->__hash() == __hash) + && key_eq()(__nd->__upcast()->__value_, __k)) +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(__nd, this); +#else + return const_iterator(__nd); +#endif + } + } + + } + return end(); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) +{ + static_assert(!__is_hash_value_type<_Args...>::value, + "Construct cannot be called with a hash value type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = hash_function()(__h->__value_); + __h->__next_ = nullptr; + return __h; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( + size_t __hash, _First&& __f, _Rest&& ...__rest) +{ + static_assert(!__is_hash_value_type<_First, _Rest...>::value, + "Construct cannot be called with a hash value type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), + _VSTD::forward<_First>(__f), + _VSTD::forward<_Rest>(__rest)...); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = __hash; + __h->__next_ = nullptr; + return __h; +} + +#else // _LIBCPP_CXX03_LANG + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const __container_value_type& __v) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = hash_function()(__h->__value_); + __h->__next_ = nullptr; + return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, + const __container_value_type& __v) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = __hash; + __h->__next_ = nullptr; + return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 +} + +#endif // _LIBCPP_CXX03_LANG + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) +{ + __next_pointer __np = __p.__node_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container erase(iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_ASSERT(__p != end(), + "unordered container erase(iterator) called with a non-dereferenceable iterator"); + iterator __r(__np, this); +#else + iterator __r(__np); +#endif + ++__r; + remove(__p); + return __r; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, + const_iterator __last) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, + "unodered container::erase(iterator, iterator) called with an iterator not" + " referring to this unodered container"); + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, + "unodered container::erase(iterator, iterator) called with an iterator not" + " referring to this unodered container"); +#endif + for (const_iterator __p = __first; __first != __last; __p = __first) + { + ++__first; + erase(__p); + } + __next_pointer __np = __last.__node_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator (__np, this); +#else + return iterator (__np); +#endif +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) +{ + iterator __i = find(__k); + if (__i == end()) + return 0; + erase(__i); + return 1; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) +{ + size_type __r = 0; + iterator __i = find(__k); + if (__i != end()) + { + iterator __e = end(); + do + { + erase(__i++); + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT +{ + // current node + __next_pointer __cn = __p.__node_; + size_type __bc = bucket_count(); + size_t __chash = __constrain_hash(__cn->__hash(), __bc); + // find previous node + __next_pointer __pn = __bucket_list_[__chash]; + for (; __pn->__next_ != __cn; __pn = __pn->__next_) + ; + // Fix up __bucket_list_ + // if __pn is not in same bucket (before begin is not in same bucket) && + // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) + if (__pn == __p1_.first().__ptr() + || __constrain_hash(__pn->__hash(), __bc) != __chash) + { + if (__cn->__next_ == nullptr + || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash) + __bucket_list_[__chash] = nullptr; + } + // if __cn->__next_ is not in same bucket (nullptr is in same bucket) + if (__cn->__next_ != nullptr) + { + size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __pn; + } + // remove __cn + __pn->__next_ = __cn->__next_; + __cn->__next_ = nullptr; + --size(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) + { + --__dp; + iterator* __i = static_cast((*__dp)->__i_); + if (__i->__node_ == __cn) + { + (*__dp)->__c_ = nullptr; + if (--__c->end_ != __dp) + memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); +} + +template +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const +{ + return static_cast(find(__k) != end()); +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const +{ + size_type __r = 0; + const_iterator __i = find(__k); + if (__i != end()) + { + const_iterator __e = end(); + do + { + ++__i; + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; +} + +template +template +pair::iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( + const _Key& __k) +{ + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); +} + +template +template +pair::const_iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( + const _Key& __k) const +{ + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); +} + +template +template +pair::iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( + const _Key& __k) +{ + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) + { + iterator __e = end(); + do + { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); +} + +template +template +pair::const_iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( + const _Key& __k) const +{ + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) + { + const_iterator __e = end(); + do + { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) +#if _LIBCPP_STD_VER <= 11 + _NOEXCEPT_( + __is_nothrow_swappable::value && __is_nothrow_swappable::value + && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value + || __is_nothrow_swappable<__pointer_allocator>::value) + && (!__node_traits::propagate_on_container_swap::value + || __is_nothrow_swappable<__node_allocator>::value) + ) +#else + _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value) +#endif +{ + _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value || + this->__node_alloc() == __u.__node_alloc(), + "list::swap: Either propagate_on_container_swap must be true" + " or the allocators must compare equal"); + { + __node_pointer_pointer __npp = __bucket_list_.release(); + __bucket_list_.reset(__u.__bucket_list_.release()); + __u.__bucket_list_.reset(__npp); + } + _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); + __swap_allocator(__bucket_list_.get_deleter().__alloc(), + __u.__bucket_list_.get_deleter().__alloc()); + __swap_allocator(__node_alloc(), __u.__node_alloc()); + _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); + __p2_.swap(__u.__p2_); + __p3_.swap(__u.__p3_); + if (size() > 0) + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); + if (__u.size() > 0) + __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = + __u.__p1_.first().__ptr(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->swap(this, &__u); +#endif +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const +{ + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::bucket_size(n) called with n >= bucket_count()"); + __next_pointer __np = __bucket_list_[__n]; + size_type __bc = bucket_count(); + size_type __r = 0; + if (__np != nullptr) + { + for (__np = __np->__next_; __np != nullptr && + __constrain_hash(__np->__hash(), __bc) == __n; + __np = __np->__next_, ++__r) + ; + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, + __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +#if _LIBCPP_DEBUG_LEVEL >= 2 + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const +{ + return __i->__node_ != nullptr; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const +{ + return false; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const +{ + return false; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const +{ + return false; +} + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP__HASH_TABLE diff --git a/third_party/libcxx/__locale b/third_party/libcxx/__locale new file mode 100644 index 000000000..7e2d0c88a --- /dev/null +++ b/third_party/libcxx/__locale @@ -0,0 +1,1553 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LOCALE +#define _LIBCPP___LOCALE + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/string" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/utility" +#include "third_party/libcxx/mutex" +#include "third_party/libcxx/cstdint" +#include "third_party/libcxx/cctype" +#include "third_party/libcxx/locale.h" +#if defined(_LIBCPP_MSVCRT_LIKE) +# include "third_party/libcxx/cstring" +# include "third_party/libcxx/support/win32/locale_win32.h" +#elif defined(_AIX) +# include "third_party/libcxx/support/ibm/xlocale.h" +#elif defined(__ANDROID__) +# include "third_party/libcxx/support/android/locale_bionic.h" +#elif defined(__sun__) +# include "third_party/libcxx/xlocale.h" +# include "third_party/libcxx/support/solaris/xlocale.h" +#elif defined(_NEWLIB_VERSION) +# include "third_party/libcxx/support/newlib/xlocale.h" +#elif (defined(__APPLE__) || defined(__FreeBSD__) \ + || defined(__EMSCRIPTEN__) || defined(__IBMCPP__)) +# include "third_party/libcxx/xlocale.h" +#elif defined(__Fuchsia__) +# include "third_party/libcxx/support/fuchsia/xlocale.h" +#elif defined(__wasi__) +// WASI libc uses musl's locales support. +# include "third_party/libcxx/support/musl/xlocale.h" +#elif defined(_LIBCPP_HAS_MUSL_LIBC) +# include "third_party/libcxx/support/musl/xlocale.h" +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS) +struct __libcpp_locale_guard { + _LIBCPP_INLINE_VISIBILITY + __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {} + + _LIBCPP_INLINE_VISIBILITY + ~__libcpp_locale_guard() { + if (__old_loc_) + uselocale(__old_loc_); + } + + locale_t __old_loc_; +private: + __libcpp_locale_guard(__libcpp_locale_guard const&); + __libcpp_locale_guard& operator=(__libcpp_locale_guard const&); +}; +#elif defined(_LIBCPP_MSVCRT_LIKE) +struct __libcpp_locale_guard { + __libcpp_locale_guard(locale_t __l) : + __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) { + // Setting the locale can be expensive even when the locale given is + // already the current locale, so do an explicit check to see if the + // current locale is already the one we want. + const char* __lc = __setlocale(nullptr); + // If every category is the same, the locale string will simply be the + // locale name, otherwise it will be a semicolon-separated string listing + // each category. In the second case, we know at least one category won't + // be what we want, so we only have to check the first case. + if (strcmp(__l.__get_locale(), __lc) != 0) { + __locale_all = _strdup(__lc); + if (__locale_all == nullptr) + __throw_bad_alloc(); + __setlocale(__l.__get_locale()); + } + } + ~__libcpp_locale_guard() { + // The CRT documentation doesn't explicitly say, but setlocale() does the + // right thing when given a semicolon-separated list of locale settings + // for the different categories in the same format as returned by + // setlocale(LC_ALL, nullptr). + if (__locale_all != nullptr) { + __setlocale(__locale_all); + free(__locale_all); + } + _configthreadlocale(__status); + } + static const char* __setlocale(const char* __locale) { + const char* __new_locale = setlocale(LC_ALL, __locale); + if (__new_locale == nullptr) + __throw_bad_alloc(); + return __new_locale; + } + int __status; + char* __locale_all = nullptr; +}; +#endif + + +class _LIBCPP_TYPE_VIS locale; + +template +_LIBCPP_INLINE_VISIBILITY +bool +has_facet(const locale&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +const _Facet& +use_facet(const locale&); + +class _LIBCPP_TYPE_VIS locale +{ +public: + // types: + class _LIBCPP_TYPE_VIS facet; + class _LIBCPP_TYPE_VIS id; + + typedef int category; + _LIBCPP_AVAILABILITY_LOCALE_CATEGORY + static const category // values assigned here are for exposition only + none = 0, + collate = LC_COLLATE_MASK, + ctype = LC_CTYPE_MASK, + monetary = LC_MONETARY_MASK, + numeric = LC_NUMERIC_MASK, + time = LC_TIME_MASK, + messages = LC_MESSAGES_MASK, + all = collate | ctype | monetary | numeric | time | messages; + + // construct/copy/destroy: + locale() _NOEXCEPT; + locale(const locale&) _NOEXCEPT; + explicit locale(const char*); + explicit locale(const string&); + locale(const locale&, const char*, category); + locale(const locale&, const string&, category); + template + _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*); + locale(const locale&, const locale&, category); + + ~locale(); + + const locale& operator=(const locale&) _NOEXCEPT; + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + locale combine(const locale&) const; + + // locale operations: + string name() const; + bool operator==(const locale&) const; + bool operator!=(const locale& __y) const {return !(*this == __y);} + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + bool operator()(const basic_string<_CharT, _Traits, _Allocator>&, + const basic_string<_CharT, _Traits, _Allocator>&) const; + + // global locale objects: + static locale global(const locale&); + static const locale& classic(); + +private: + class __imp; + __imp* __locale_; + + void __install_ctor(const locale&, facet*, long); + static locale& __global(); + bool has_facet(id&) const; + const facet* use_facet(id&) const; + + template friend bool has_facet(const locale&) _NOEXCEPT; + template friend const _Facet& use_facet(const locale&); +}; + +class _LIBCPP_TYPE_VIS locale::facet + : public __shared_count +{ +protected: + _LIBCPP_INLINE_VISIBILITY + explicit facet(size_t __refs = 0) + : __shared_count(static_cast(__refs)-1) {} + + virtual ~facet(); + +// facet(const facet&) = delete; // effectively done in __shared_count +// void operator=(const facet&) = delete; +private: + virtual void __on_zero_shared() _NOEXCEPT; +}; + +class _LIBCPP_TYPE_VIS locale::id +{ + once_flag __flag_; + int32_t __id_; + + static int32_t __next_id; +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {} +private: + void __init(); + void operator=(const id&); // = delete; + id(const id&); // = delete; +public: // only needed for tests + long __get(); + + friend class locale; + friend class locale::__imp; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +locale::locale(const locale& __other, _Facet* __f) +{ + __install_ctor(__other, __f, __f ? __f->id.__get() : 0); +} + +template +locale +locale::combine(const locale& __other) const +{ + if (!_VSTD::has_facet<_Facet>(__other)) + __throw_runtime_error("locale::combine: locale missing facet"); + + return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +has_facet(const locale& __l) _NOEXCEPT +{ + return __l.has_facet(_Facet::id); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +const _Facet& +use_facet(const locale& __l) +{ + return static_cast(*__l.use_facet(_Facet::id)); +} + +// template class collate; + +template +class _LIBCPP_TEMPLATE_VIS collate + : public locale::facet +{ +public: + typedef _CharT char_type; + typedef basic_string string_type; + + _LIBCPP_INLINE_VISIBILITY + explicit collate(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_INLINE_VISIBILITY + int compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const + { + return do_compare(__lo1, __hi1, __lo2, __hi2); + } + + // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work + // around a dllimport bug that expects an external instantiation. + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_ALWAYS_INLINE + string_type transform(const char_type* __lo, const char_type* __hi) const + { + return do_transform(__lo, __hi); + } + + _LIBCPP_INLINE_VISIBILITY + long hash(const char_type* __lo, const char_type* __hi) const + { + return do_hash(__lo, __hi); + } + + static locale::id id; + +protected: + ~collate(); + virtual int do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const; + virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const + {return string_type(__lo, __hi);} + virtual long do_hash(const char_type* __lo, const char_type* __hi) const; +}; + +template locale::id collate<_CharT>::id; + +template +collate<_CharT>::~collate() +{ +} + +template +int +collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const +{ + for (; __lo2 != __hi2; ++__lo1, ++__lo2) + { + if (__lo1 == __hi1 || *__lo1 < *__lo2) + return -1; + if (*__lo2 < *__lo1) + return 1; + } + return __lo1 != __hi1; +} + +template +long +collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const +{ + size_t __h = 0; + const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8; + const size_t __mask = size_t(0xF) << (__sr + 4); + for(const char_type* __p = __lo; __p != __hi; ++__p) + { + __h = (__h << 4) + static_cast(*__p); + size_t __g = __h & __mask; + __h ^= __g | (__g >> __sr); + } + return static_cast(__h); +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate) + +// template class collate_byname; + +template class _LIBCPP_TEMPLATE_VIS collate_byname; + +template <> +class _LIBCPP_TYPE_VIS collate_byname + : public collate +{ + locale_t __l; +public: + typedef char char_type; + typedef basic_string string_type; + + explicit collate_byname(const char* __n, size_t __refs = 0); + explicit collate_byname(const string& __n, size_t __refs = 0); + +protected: + ~collate_byname(); + virtual int do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const; + virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const; +}; + +template <> +class _LIBCPP_TYPE_VIS collate_byname + : public collate +{ + locale_t __l; +public: + typedef wchar_t char_type; + typedef basic_string string_type; + + explicit collate_byname(const char* __n, size_t __refs = 0); + explicit collate_byname(const string& __n, size_t __refs = 0); + +protected: + ~collate_byname(); + + virtual int do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const; + virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const; +}; + +template +bool +locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, + const basic_string<_CharT, _Traits, _Allocator>& __y) const +{ + return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare( + __x.data(), __x.data() + __x.size(), + __y.data(), __y.data() + __y.size()) < 0; +} + +// template class ctype + +class _LIBCPP_TYPE_VIS ctype_base +{ +public: +#if defined(__GLIBC__) + typedef unsigned short mask; + static const mask space = _ISspace; + static const mask print = _ISprint; + static const mask cntrl = _IScntrl; + static const mask upper = _ISupper; + static const mask lower = _ISlower; + static const mask alpha = _ISalpha; + static const mask digit = _ISdigit; + static const mask punct = _ISpunct; + static const mask xdigit = _ISxdigit; + static const mask blank = _ISblank; +#if defined(__mips__) + static const mask __regex_word = static_cast(_ISbit(15)); +#else + static const mask __regex_word = 0x80; +#endif +#elif defined(_LIBCPP_MSVCRT_LIKE) + typedef unsigned short mask; + static const mask space = _SPACE; + static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT; + static const mask cntrl = _CONTROL; + static const mask upper = _UPPER; + static const mask lower = _LOWER; + static const mask alpha = _ALPHA; + static const mask digit = _DIGIT; + static const mask punct = _PUNCT; + static const mask xdigit = _HEX; + static const mask blank = _BLANK; + static const mask __regex_word = 0x80; +# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) +# ifdef __APPLE__ + typedef __uint32_t mask; +# elif defined(__FreeBSD__) + typedef unsigned long mask; +# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__) + typedef unsigned short mask; +# endif + static const mask space = _CTYPE_S; + static const mask print = _CTYPE_R; + static const mask cntrl = _CTYPE_C; + static const mask upper = _CTYPE_U; + static const mask lower = _CTYPE_L; + static const mask alpha = _CTYPE_A; + static const mask digit = _CTYPE_D; + static const mask punct = _CTYPE_P; + static const mask xdigit = _CTYPE_X; + +# if defined(__NetBSD__) + static const mask blank = _CTYPE_BL; + // NetBSD defines classes up to 0x2000 + // see sys/ctype_bits.h, _CTYPE_Q + static const mask __regex_word = 0x8000; +# else + static const mask blank = _CTYPE_B; + static const mask __regex_word = 0x80; +# endif +#elif defined(__sun__) || defined(_AIX) + typedef unsigned int mask; + static const mask space = _ISSPACE; + static const mask print = _ISPRINT; + static const mask cntrl = _ISCNTRL; + static const mask upper = _ISUPPER; + static const mask lower = _ISLOWER; + static const mask alpha = _ISALPHA; + static const mask digit = _ISDIGIT; + static const mask punct = _ISPUNCT; + static const mask xdigit = _ISXDIGIT; + static const mask blank = _ISBLANK; + static const mask __regex_word = 0x80; +#elif defined(_NEWLIB_VERSION) + // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. + typedef char mask; + static const mask space = _S; + static const mask print = _P | _U | _L | _N | _B; + static const mask cntrl = _C; + static const mask upper = _U; + static const mask lower = _L; + static const mask alpha = _U | _L; + static const mask digit = _N; + static const mask punct = _P; + static const mask xdigit = _X | _N; + static const mask blank = _B; + static const mask __regex_word = 0x80; +# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT +# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA +# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT +#else + typedef unsigned long mask; + static const mask space = 1<<0; + static const mask print = 1<<1; + static const mask cntrl = 1<<2; + static const mask upper = 1<<3; + static const mask lower = 1<<4; + static const mask alpha = 1<<5; + static const mask digit = 1<<6; + static const mask punct = 1<<7; + static const mask xdigit = 1<<8; + static const mask blank = 1<<9; + static const mask __regex_word = 1<<10; +#endif + static const mask alnum = alpha | digit; + static const mask graph = alnum | punct; + + _LIBCPP_INLINE_VISIBILITY ctype_base() {} +}; + +template class _LIBCPP_TEMPLATE_VIS ctype; + +template <> +class _LIBCPP_TYPE_VIS ctype + : public locale::facet, + public ctype_base +{ +public: + typedef wchar_t char_type; + + _LIBCPP_INLINE_VISIBILITY + explicit ctype(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_INLINE_VISIBILITY + bool is(mask __m, char_type __c) const + { + return do_is(__m, __c); + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const + { + return do_is(__low, __high, __vec); + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const + { + return do_scan_is(__m, __low, __high); + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const + { + return do_scan_not(__m, __low, __high); + } + + _LIBCPP_INLINE_VISIBILITY + char_type toupper(char_type __c) const + { + return do_toupper(__c); + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* toupper(char_type* __low, const char_type* __high) const + { + return do_toupper(__low, __high); + } + + _LIBCPP_INLINE_VISIBILITY + char_type tolower(char_type __c) const + { + return do_tolower(__c); + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* tolower(char_type* __low, const char_type* __high) const + { + return do_tolower(__low, __high); + } + + _LIBCPP_INLINE_VISIBILITY + char_type widen(char __c) const + { + return do_widen(__c); + } + + _LIBCPP_INLINE_VISIBILITY + const char* widen(const char* __low, const char* __high, char_type* __to) const + { + return do_widen(__low, __high, __to); + } + + _LIBCPP_INLINE_VISIBILITY + char narrow(char_type __c, char __dfault) const + { + return do_narrow(__c, __dfault); + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const + { + return do_narrow(__low, __high, __dfault, __to); + } + + static locale::id id; + +protected: + ~ctype(); + virtual bool do_is(mask __m, char_type __c) const; + virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; + virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; + virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; + virtual char_type do_toupper(char_type) const; + virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; + virtual char_type do_tolower(char_type) const; + virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; + virtual char_type do_widen(char) const; + virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; + virtual char do_narrow(char_type, char __dfault) const; + virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; +}; + +template <> +class _LIBCPP_TYPE_VIS ctype + : public locale::facet, public ctype_base +{ + const mask* __tab_; + bool __del_; +public: + typedef char char_type; + + explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0); + + _LIBCPP_INLINE_VISIBILITY + bool is(mask __m, char_type __c) const + { + return isascii(__c) ? (__tab_[static_cast(__c)] & __m) !=0 : false; + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const + { + for (; __low != __high; ++__low, ++__vec) + *__vec = isascii(*__low) ? __tab_[static_cast(*__low)] : 0; + return __low; + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const + { + for (; __low != __high; ++__low) + if (isascii(*__low) && (__tab_[static_cast(*__low)] & __m)) + break; + return __low; + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const + { + for (; __low != __high; ++__low) + if (!(isascii(*__low) && (__tab_[static_cast(*__low)] & __m))) + break; + return __low; + } + + _LIBCPP_INLINE_VISIBILITY + char_type toupper(char_type __c) const + { + return do_toupper(__c); + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* toupper(char_type* __low, const char_type* __high) const + { + return do_toupper(__low, __high); + } + + _LIBCPP_INLINE_VISIBILITY + char_type tolower(char_type __c) const + { + return do_tolower(__c); + } + + _LIBCPP_INLINE_VISIBILITY + const char_type* tolower(char_type* __low, const char_type* __high) const + { + return do_tolower(__low, __high); + } + + _LIBCPP_INLINE_VISIBILITY + char_type widen(char __c) const + { + return do_widen(__c); + } + + _LIBCPP_INLINE_VISIBILITY + const char* widen(const char* __low, const char* __high, char_type* __to) const + { + return do_widen(__low, __high, __to); + } + + _LIBCPP_INLINE_VISIBILITY + char narrow(char_type __c, char __dfault) const + { + return do_narrow(__c, __dfault); + } + + _LIBCPP_INLINE_VISIBILITY + const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const + { + return do_narrow(__low, __high, __dfault, __to); + } + + static locale::id id; + +#ifdef _CACHED_RUNES + static const size_t table_size = _CACHED_RUNES; +#else + static const size_t table_size = 256; // FIXME: Don't hardcode this. +#endif + _LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;} + static const mask* classic_table() _NOEXCEPT; +#if defined(__GLIBC__) || defined(__EMSCRIPTEN__) + static const int* __classic_upper_table() _NOEXCEPT; + static const int* __classic_lower_table() _NOEXCEPT; +#endif +#if defined(__NetBSD__) + static const short* __classic_upper_table() _NOEXCEPT; + static const short* __classic_lower_table() _NOEXCEPT; +#endif + +protected: + ~ctype(); + virtual char_type do_toupper(char_type __c) const; + virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; + virtual char_type do_tolower(char_type __c) const; + virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; + virtual char_type do_widen(char __c) const; + virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const; + virtual char do_narrow(char_type __c, char __dfault) const; + virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const; +}; + +// template class ctype_byname; + +template class _LIBCPP_TEMPLATE_VIS ctype_byname; + +template <> +class _LIBCPP_TYPE_VIS ctype_byname + : public ctype +{ + locale_t __l; + +public: + explicit ctype_byname(const char*, size_t = 0); + explicit ctype_byname(const string&, size_t = 0); + +protected: + ~ctype_byname(); + virtual char_type do_toupper(char_type) const; + virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; + virtual char_type do_tolower(char_type) const; + virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; +}; + +template <> +class _LIBCPP_TYPE_VIS ctype_byname + : public ctype +{ + locale_t __l; + +public: + explicit ctype_byname(const char*, size_t = 0); + explicit ctype_byname(const string&, size_t = 0); + +protected: + ~ctype_byname(); + virtual bool do_is(mask __m, char_type __c) const; + virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; + virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; + virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; + virtual char_type do_toupper(char_type) const; + virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; + virtual char_type do_tolower(char_type) const; + virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; + virtual char_type do_widen(char) const; + virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; + virtual char do_narrow(char_type, char __dfault) const; + virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isspace(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::space, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isprint(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::print, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +iscntrl(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::cntrl, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isupper(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::upper, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +islower(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::lower, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isalpha(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::alpha, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isdigit(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::digit, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +ispunct(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::punct, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isxdigit(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::xdigit, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isalnum(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::alnum, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isgraph(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::graph, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_CharT +toupper(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).toupper(__c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_CharT +tolower(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).tolower(__c); +} + +// codecvt_base + +class _LIBCPP_TYPE_VIS codecvt_base +{ +public: + _LIBCPP_INLINE_VISIBILITY codecvt_base() {} + enum result {ok, partial, error, noconv}; +}; + +// template class codecvt; + +template class _LIBCPP_TEMPLATE_VIS codecvt; + +// template <> class codecvt + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ +public: + typedef char intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_INLINE_VISIBILITY + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_INLINE_VISIBILITY + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_INLINE_VISIBILITY + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_INLINE_VISIBILITY + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(const char*, size_t __refs = 0) + : locale::facet(__refs) {} + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +// template <> class codecvt + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ + locale_t __l; +public: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + explicit codecvt(size_t __refs = 0); + + _LIBCPP_INLINE_VISIBILITY + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_INLINE_VISIBILITY + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_INLINE_VISIBILITY + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_INLINE_VISIBILITY + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + explicit codecvt(const char*, size_t __refs = 0); + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +// template <> class codecvt + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ +public: + typedef char16_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_INLINE_VISIBILITY + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_INLINE_VISIBILITY + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_INLINE_VISIBILITY + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_INLINE_VISIBILITY + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(const char*, size_t __refs = 0) + : locale::facet(__refs) {} + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +// template <> class codecvt + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ +public: + typedef char32_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_INLINE_VISIBILITY + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_INLINE_VISIBILITY + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_INLINE_VISIBILITY + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_INLINE_VISIBILITY + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(const char*, size_t __refs = 0) + : locale::facet(__refs) {} + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +// template class codecvt_byname + +template +class _LIBCPP_TEMPLATE_VIS codecvt_byname + : public codecvt<_InternT, _ExternT, _StateT> +{ +public: + _LIBCPP_INLINE_VISIBILITY + explicit codecvt_byname(const char* __nm, size_t __refs = 0) + : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {} + _LIBCPP_INLINE_VISIBILITY + explicit codecvt_byname(const string& __nm, size_t __refs = 0) + : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {} +protected: + ~codecvt_byname(); +}; + +template +codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() +{ +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) + +template +struct __narrow_to_utf8 +{ + template + _OutputIterator + operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const; +}; + +template <> +struct __narrow_to_utf8<8> +{ + template + _LIBCPP_INLINE_VISIBILITY + _OutputIterator + operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const + { + for (; __wb < __we; ++__wb, ++__s) + *__s = *__wb; + return __s; + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16> + : public codecvt +{ + _LIBCPP_INLINE_VISIBILITY + __narrow_to_utf8() : codecvt(1) {} + + _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); + + template + _LIBCPP_INLINE_VISIBILITY + _OutputIterator + operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const + { + result __r = ok; + mbstate_t __mb; + while (__wb < __we && __r != error) + { + const int __sz = 32; + char __buf[__sz]; + char* __bn; + const char16_t* __wn = (const char16_t*)__wb; + __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __wn == (const char16_t*)__wb) + __throw_runtime_error("locale not supported"); + for (const char* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = *__p; + __wb = (const _CharT*)__wn; + } + return __s; + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32> + : public codecvt +{ + _LIBCPP_INLINE_VISIBILITY + __narrow_to_utf8() : codecvt(1) {} + + _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); + + template + _LIBCPP_INLINE_VISIBILITY + _OutputIterator + operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const + { + result __r = ok; + mbstate_t __mb; + while (__wb < __we && __r != error) + { + const int __sz = 32; + char __buf[__sz]; + char* __bn; + const char32_t* __wn = (const char32_t*)__wb; + __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __wn == (const char32_t*)__wb) + __throw_runtime_error("locale not supported"); + for (const char* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = *__p; + __wb = (const _CharT*)__wn; + } + return __s; + } +}; + +template +struct __widen_from_utf8 +{ + template + _OutputIterator + operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; +}; + +template <> +struct __widen_from_utf8<8> +{ + template + _LIBCPP_INLINE_VISIBILITY + _OutputIterator + operator()(_OutputIterator __s, const char* __nb, const char* __ne) const + { + for (; __nb < __ne; ++__nb, ++__s) + *__s = *__nb; + return __s; + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16> + : public codecvt +{ + _LIBCPP_INLINE_VISIBILITY + __widen_from_utf8() : codecvt(1) {} + + _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); + + template + _LIBCPP_INLINE_VISIBILITY + _OutputIterator + operator()(_OutputIterator __s, const char* __nb, const char* __ne) const + { + result __r = ok; + mbstate_t __mb; + while (__nb < __ne && __r != error) + { + const int __sz = 32; + char16_t __buf[__sz]; + char16_t* __bn; + const char* __nn = __nb; + __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __nn == __nb) + __throw_runtime_error("locale not supported"); + for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = (wchar_t)*__p; + __nb = __nn; + } + return __s; + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32> + : public codecvt +{ + _LIBCPP_INLINE_VISIBILITY + __widen_from_utf8() : codecvt(1) {} + + _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); + + template + _LIBCPP_INLINE_VISIBILITY + _OutputIterator + operator()(_OutputIterator __s, const char* __nb, const char* __ne) const + { + result __r = ok; + mbstate_t __mb; + while (__nb < __ne && __r != error) + { + const int __sz = 32; + char32_t __buf[__sz]; + char32_t* __bn; + const char* __nn = __nb; + __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __nn == __nb) + __throw_runtime_error("locale not supported"); + for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = (wchar_t)*__p; + __nb = __nn; + } + return __s; + } +}; + +// template class numpunct + +template class _LIBCPP_TEMPLATE_VIS numpunct; + +template <> +class _LIBCPP_TYPE_VIS numpunct + : public locale::facet +{ +public: + typedef char char_type; + typedef basic_string string_type; + + explicit numpunct(size_t __refs = 0); + + _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} + _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} + _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} + _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} + _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} + + static locale::id id; + +protected: + ~numpunct(); + virtual char_type do_decimal_point() const; + virtual char_type do_thousands_sep() const; + virtual string do_grouping() const; + virtual string_type do_truename() const; + virtual string_type do_falsename() const; + + char_type __decimal_point_; + char_type __thousands_sep_; + string __grouping_; +}; + +template <> +class _LIBCPP_TYPE_VIS numpunct + : public locale::facet +{ +public: + typedef wchar_t char_type; + typedef basic_string string_type; + + explicit numpunct(size_t __refs = 0); + + _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} + _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} + _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} + _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} + _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} + + static locale::id id; + +protected: + ~numpunct(); + virtual char_type do_decimal_point() const; + virtual char_type do_thousands_sep() const; + virtual string do_grouping() const; + virtual string_type do_truename() const; + virtual string_type do_falsename() const; + + char_type __decimal_point_; + char_type __thousands_sep_; + string __grouping_; +}; + +// template class numpunct_byname + +template class _LIBCPP_TEMPLATE_VIS numpunct_byname; + +template <> +class _LIBCPP_TYPE_VIS numpunct_byname +: public numpunct +{ +public: + typedef char char_type; + typedef basic_string string_type; + + explicit numpunct_byname(const char* __nm, size_t __refs = 0); + explicit numpunct_byname(const string& __nm, size_t __refs = 0); + +protected: + ~numpunct_byname(); + +private: + void __init(const char*); +}; + +template <> +class _LIBCPP_TYPE_VIS numpunct_byname +: public numpunct +{ +public: + typedef wchar_t char_type; + typedef basic_string string_type; + + explicit numpunct_byname(const char* __nm, size_t __refs = 0); + explicit numpunct_byname(const string& __nm, size_t __refs = 0); + +protected: + ~numpunct_byname(); + +private: + void __init(const char*); +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LOCALE diff --git a/third_party/libcxx/__mutex_base b/third_party/libcxx/__mutex_base new file mode 100644 index 000000000..62ff1e4c2 --- /dev/null +++ b/third_party/libcxx/__mutex_base @@ -0,0 +1,541 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MUTEX_BASE +#define _LIBCPP___MUTEX_BASE + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/chrono" +#include "third_party/libcxx/system_error" +#include "third_party/libcxx/__threading_support" + +#include "libc/isystem/time.h" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_HAS_NO_THREADS + +#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION +# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x)) +# else +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) +# endif +#endif // _LIBCPP_THREAD_SAFETY_ANNOTATION + + +class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex +{ + __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; + +public: + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR mutex() = default; + + mutex(const mutex&) = delete; + mutex& operator=(const mutex&) = delete; + +#if defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION) + ~mutex() = default; +#else + ~mutex() _NOEXCEPT; +#endif + + void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); + bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); + void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); + + typedef __libcpp_mutex_t* native_handle_type; + _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} +}; + +static_assert(is_nothrow_default_constructible::value, + "the default constructor for std::mutex must be nothrow"); + +struct _LIBCPP_TYPE_VIS defer_lock_t { explicit defer_lock_t() = default; }; +struct _LIBCPP_TYPE_VIS try_to_lock_t { explicit try_to_lock_t() = default; }; +struct _LIBCPP_TYPE_VIS adopt_lock_t { explicit adopt_lock_t() = default; }; + +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) + +extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock; +extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock; +extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock; + +#else + +/* _LIBCPP_INLINE_VAR */ constexpr defer_lock_t defer_lock = defer_lock_t(); +/* _LIBCPP_INLINE_VAR */ constexpr try_to_lock_t try_to_lock = try_to_lock_t(); +/* _LIBCPP_INLINE_VAR */ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); + +#endif + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) +lock_guard +{ +public: + typedef _Mutex mutex_type; + +private: + mutex_type& __m_; +public: + + _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY + explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) + : __m_(__m) {__m_.lock();} + + _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY + lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) + : __m_(__m) {} + _LIBCPP_INLINE_VISIBILITY + ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();} + +private: + lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE; + lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE; +}; + +template +class _LIBCPP_TEMPLATE_VIS unique_lock +{ +public: + typedef _Mutex mutex_type; + +private: + mutex_type* __m_; + bool __owns_; + +public: + _LIBCPP_INLINE_VISIBILITY + unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} + _LIBCPP_INLINE_VISIBILITY + explicit unique_lock(mutex_type& __m) + : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();} + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT + : __m_(_VSTD::addressof(__m)), __owns_(false) {} + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, try_to_lock_t) + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {} + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, adopt_lock_t) + : __m_(_VSTD::addressof(__m)), __owns_(true) {} + template + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {} + template + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {} + _LIBCPP_INLINE_VISIBILITY + ~unique_lock() + { + if (__owns_) + __m_->unlock(); + } + +private: + unique_lock(unique_lock const&); // = delete; + unique_lock& operator=(unique_lock const&); // = delete; + +public: +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + unique_lock(unique_lock&& __u) _NOEXCEPT + : __m_(__u.__m_), __owns_(__u.__owns_) + {__u.__m_ = nullptr; __u.__owns_ = false;} + _LIBCPP_INLINE_VISIBILITY + unique_lock& operator=(unique_lock&& __u) _NOEXCEPT + { + if (__owns_) + __m_->unlock(); + __m_ = __u.__m_; + __owns_ = __u.__owns_; + __u.__m_ = nullptr; + __u.__owns_ = false; + return *this; + } + +#endif // _LIBCPP_CXX03_LANG + + void lock(); + bool try_lock(); + + template + bool try_lock_for(const chrono::duration<_Rep, _Period>& __d); + template + bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); + + void unlock(); + + _LIBCPP_INLINE_VISIBILITY + void swap(unique_lock& __u) _NOEXCEPT + { + _VSTD::swap(__m_, __u.__m_); + _VSTD::swap(__owns_, __u.__owns_); + } + _LIBCPP_INLINE_VISIBILITY + mutex_type* release() _NOEXCEPT + { + mutex_type* __m = __m_; + __m_ = nullptr; + __owns_ = false; + return __m; + } + + _LIBCPP_INLINE_VISIBILITY + bool owns_lock() const _NOEXCEPT {return __owns_;} + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_EXPLICIT + operator bool () const _NOEXCEPT {return __owns_;} + _LIBCPP_INLINE_VISIBILITY + mutex_type* mutex() const _NOEXCEPT {return __m_;} +}; + +template +void +unique_lock<_Mutex>::lock() +{ + if (__m_ == nullptr) + __throw_system_error(EPERM, "unique_lock::lock: references null mutex"); + if (__owns_) + __throw_system_error(EDEADLK, "unique_lock::lock: already locked"); + __m_->lock(); + __owns_ = true; +} + +template +bool +unique_lock<_Mutex>::try_lock() +{ + if (__m_ == nullptr) + __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex"); + if (__owns_) + __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked"); + __owns_ = __m_->try_lock(); + return __owns_; +} + +template +template +bool +unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) +{ + if (__m_ == nullptr) + __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex"); + if (__owns_) + __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked"); + __owns_ = __m_->try_lock_for(__d); + return __owns_; +} + +template +template +bool +unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) +{ + if (__m_ == nullptr) + __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex"); + if (__owns_) + __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked"); + __owns_ = __m_->try_lock_until(__t); + return __owns_; +} + +template +void +unique_lock<_Mutex>::unlock() +{ + if (!__owns_) + __throw_system_error(EPERM, "unique_lock::unlock: not locked"); + __m_->unlock(); + __owns_ = false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT + {__x.swap(__y);} + +//enum class cv_status +_LIBCPP_DECLARE_STRONG_ENUM(cv_status) +{ + no_timeout, + timeout +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) + +class _LIBCPP_TYPE_VIS condition_variable +{ + __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER; +public: + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default; + +#ifdef _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION + ~condition_variable() = default; +#else + ~condition_variable(); +#endif + + condition_variable(const condition_variable&) = delete; + condition_variable& operator=(const condition_variable&) = delete; + + void notify_one() _NOEXCEPT; + void notify_all() _NOEXCEPT; + + void wait(unique_lock& __lk) _NOEXCEPT; + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + void wait(unique_lock& __lk, _Predicate __pred); + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + cv_status + wait_until(unique_lock& __lk, + const chrono::time_point<_Clock, _Duration>& __t); + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + bool + wait_until(unique_lock& __lk, + const chrono::time_point<_Clock, _Duration>& __t, + _Predicate __pred); + + template + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + cv_status + wait_for(unique_lock& __lk, + const chrono::duration<_Rep, _Period>& __d); + + template + bool + _LIBCPP_INLINE_VISIBILITY + wait_for(unique_lock& __lk, + const chrono::duration<_Rep, _Period>& __d, + _Predicate __pred); + + typedef __libcpp_condvar_t* native_handle_type; + _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;} + +private: + void __do_timed_wait(unique_lock& __lk, + chrono::time_point) _NOEXCEPT; +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) + void __do_timed_wait(unique_lock& __lk, + chrono::time_point) _NOEXCEPT; +#endif + template + void __do_timed_wait(unique_lock& __lk, + chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT; +}; +#endif // !_LIBCPP_HAS_NO_THREADS + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_floating_point<_Rep>::value, + chrono::nanoseconds +>::type +__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) +{ + using namespace chrono; + using __ratio = ratio_divide<_Period, nano>; + using __ns_rep = nanoseconds::rep; + _Rep __result_float = __d.count() * __ratio::num / __ratio::den; + + _Rep __result_max = numeric_limits<__ns_rep>::max(); + if (__result_float >= __result_max) { + return nanoseconds::max(); + } + + _Rep __result_min = numeric_limits<__ns_rep>::min(); + if (__result_float <= __result_min) { + return nanoseconds::min(); + } + + return nanoseconds(static_cast<__ns_rep>(__result_float)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + !is_floating_point<_Rep>::value, + chrono::nanoseconds +>::type +__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) +{ + using namespace chrono; + if (__d.count() == 0) { + return nanoseconds(0); + } + + using __ratio = ratio_divide<_Period, nano>; + using __ns_rep = nanoseconds::rep; + __ns_rep __result_max = std::numeric_limits<__ns_rep>::max(); + if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) { + return nanoseconds::max(); + } + + __ns_rep __result_min = std::numeric_limits<__ns_rep>::min(); + if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) { + return nanoseconds::min(); + } + + __ns_rep __result = __d.count() * __ratio::num / __ratio::den; + if (__result == 0) { + return nanoseconds(1); + } + + return nanoseconds(__result); +} + +#ifndef _LIBCPP_HAS_NO_THREADS +template +void +condition_variable::wait(unique_lock& __lk, _Predicate __pred) +{ + while (!__pred()) + wait(__lk); +} + +template +cv_status +condition_variable::wait_until(unique_lock& __lk, + const chrono::time_point<_Clock, _Duration>& __t) +{ + using namespace chrono; + using __clock_tp_ns = time_point<_Clock, nanoseconds>; + + typename _Clock::time_point __now = _Clock::now(); + if (__t <= __now) + return cv_status::timeout; + + __clock_tp_ns __t_ns = __clock_tp_ns(__safe_nanosecond_cast(__t.time_since_epoch())); + + __do_timed_wait(__lk, __t_ns); + return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout; +} + +template +bool +condition_variable::wait_until(unique_lock& __lk, + const chrono::time_point<_Clock, _Duration>& __t, + _Predicate __pred) +{ + while (!__pred()) + { + if (wait_until(__lk, __t) == cv_status::timeout) + return __pred(); + } + return true; +} + +template +cv_status +condition_variable::wait_for(unique_lock& __lk, + const chrono::duration<_Rep, _Period>& __d) +{ + using namespace chrono; + if (__d <= __d.zero()) + return cv_status::timeout; + using __ns_rep = nanoseconds::rep; + steady_clock::time_point __c_now = steady_clock::now(); + +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) + using __clock_tp_ns = time_point; + __ns_rep __now_count_ns = __safe_nanosecond_cast(__c_now.time_since_epoch()).count(); +#else + using __clock_tp_ns = time_point; + __ns_rep __now_count_ns = __safe_nanosecond_cast(system_clock::now().time_since_epoch()).count(); +#endif + + __ns_rep __d_ns_count = __safe_nanosecond_cast(__d).count(); + + if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) { + __do_timed_wait(__lk, __clock_tp_ns::max()); + } else { + __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count))); + } + + return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : + cv_status::timeout; +} + +template +inline +bool +condition_variable::wait_for(unique_lock& __lk, + const chrono::duration<_Rep, _Period>& __d, + _Predicate __pred) +{ + return wait_until(__lk, chrono::steady_clock::now() + __d, + _VSTD::move(__pred)); +} + +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) +inline +void +condition_variable::__do_timed_wait(unique_lock& __lk, + chrono::time_point __tp) _NOEXCEPT +{ + using namespace chrono; + if (!__lk.owns_lock()) + __throw_system_error(EPERM, + "condition_variable::timed wait: mutex not locked"); + nanoseconds __d = __tp.time_since_epoch(); + timespec __ts; + seconds __s = duration_cast(__d); + using __ts_sec = decltype(__ts.tv_sec); + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = (__d - __s).count(); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = giga::num - 1; + } + int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts); + if (__ec != 0 && __ec != ETIMEDOUT) + __throw_system_error(__ec, "condition_variable timed_wait failed"); +} +#endif // _LIBCPP_HAS_COND_CLOCKWAIT + +template +inline +void +condition_variable::__do_timed_wait(unique_lock& __lk, + chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT +{ + wait_for(__lk, __tp - _Clock::now()); +} + +#endif // !_LIBCPP_HAS_NO_THREADS + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___MUTEX_BASE diff --git a/third_party/libcxx/__node_handle b/third_party/libcxx/__node_handle new file mode 100644 index 000000000..e61c1f321 --- /dev/null +++ b/third_party/libcxx/__node_handle @@ -0,0 +1,208 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NODE_HANDLE +#define _LIBCPP___NODE_HANDLE + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/optional" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +// Specialized in __tree & __hash_table for their _NodeType. +template +struct __generic_container_node_destructor; + +template class _MapOrSetSpecifics> +class _LIBCPP_TEMPLATE_VIS __basic_node_handle + : public _MapOrSetSpecifics< + _NodeType, + __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>> +{ + template + friend class __tree; + template + friend class __hash_table; + friend struct _MapOrSetSpecifics< + _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>; + + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_pointer::type + __node_pointer_type; + +public: + typedef _Alloc allocator_type; + +private: + __node_pointer_type __ptr_ = nullptr; + optional __alloc_; + + _LIBCPP_INLINE_VISIBILITY + void __release_ptr() + { + __ptr_ = nullptr; + __alloc_ = _VSTD::nullopt; + } + + _LIBCPP_INLINE_VISIBILITY + void __destroy_node_pointer() + { + if (__ptr_ != nullptr) + { + typedef typename __allocator_traits_rebind< + allocator_type, _NodeType>::type __node_alloc_type; + __node_alloc_type __alloc(*__alloc_); + __generic_container_node_destructor<_NodeType, __node_alloc_type>( + __alloc, true)(__ptr_); + __ptr_ = nullptr; + } + } + + _LIBCPP_INLINE_VISIBILITY + __basic_node_handle(__node_pointer_type __ptr, + allocator_type const& __alloc) + : __ptr_(__ptr), __alloc_(__alloc) + { + } + +public: + _LIBCPP_INLINE_VISIBILITY + __basic_node_handle() = default; + + _LIBCPP_INLINE_VISIBILITY + __basic_node_handle(__basic_node_handle&& __other) noexcept + : __ptr_(__other.__ptr_), + __alloc_(_VSTD::move(__other.__alloc_)) + { + __other.__ptr_ = nullptr; + __other.__alloc_ = _VSTD::nullopt; + } + + _LIBCPP_INLINE_VISIBILITY + __basic_node_handle& operator=(__basic_node_handle&& __other) + { + _LIBCPP_ASSERT( + __alloc_ == _VSTD::nullopt || + __alloc_traits::propagate_on_container_move_assignment::value || + __alloc_ == __other.__alloc_, + "node_type with incompatible allocator passed to " + "node_type::operator=(node_type&&)"); + + __destroy_node_pointer(); + __ptr_ = __other.__ptr_; + + if (__alloc_traits::propagate_on_container_move_assignment::value || + __alloc_ == _VSTD::nullopt) + __alloc_ = _VSTD::move(__other.__alloc_); + + __other.__ptr_ = nullptr; + __other.__alloc_ = _VSTD::nullopt; + + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const { return *__alloc_; } + + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const { return __ptr_ != nullptr; } + + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + bool empty() const { return __ptr_ == nullptr; } + + _LIBCPP_INLINE_VISIBILITY + void swap(__basic_node_handle& __other) noexcept( + __alloc_traits::propagate_on_container_swap::value || + __alloc_traits::is_always_equal::value) + { + using _VSTD::swap; + swap(__ptr_, __other.__ptr_); + if (__alloc_traits::propagate_on_container_swap::value || + __alloc_ == _VSTD::nullopt || __other.__alloc_ == _VSTD::nullopt) + swap(__alloc_, __other.__alloc_); + } + + _LIBCPP_INLINE_VISIBILITY + friend void swap(__basic_node_handle& __a, __basic_node_handle& __b) + noexcept(noexcept(__a.swap(__b))) { __a.swap(__b); } + + _LIBCPP_INLINE_VISIBILITY + ~__basic_node_handle() + { + __destroy_node_pointer(); + } +}; + +template +struct __set_node_handle_specifics +{ + typedef typename _NodeType::__node_value_type value_type; + + _LIBCPP_INLINE_VISIBILITY + value_type& value() const + { + return static_cast<_Derived const*>(this)->__ptr_->__value_; + } +}; + +template +struct __map_node_handle_specifics +{ + typedef typename _NodeType::__node_value_type::key_type key_type; + typedef typename _NodeType::__node_value_type::mapped_type mapped_type; + + _LIBCPP_INLINE_VISIBILITY + key_type& key() const + { + return static_cast<_Derived const*>(this)-> + __ptr_->__value_.__ref().first; + } + + _LIBCPP_INLINE_VISIBILITY + mapped_type& mapped() const + { + return static_cast<_Derived const*>(this)-> + __ptr_->__value_.__ref().second; + } +}; + +template +using __set_node_handle = + __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>; + +template +using __map_node_handle = + __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>; + +template +struct _LIBCPP_TEMPLATE_VIS __insert_return_type +{ + _Iterator position; + bool inserted; + _NodeType node; +}; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + +#endif diff --git a/third_party/libcxx/__nullptr b/third_party/libcxx/__nullptr new file mode 100644 index 000000000..dc84745d2 --- /dev/null +++ b/third_party/libcxx/__nullptr @@ -0,0 +1,61 @@ +// -*- C++ -*- +//===--------------------------- __nullptr --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_NULLPTR +#define _LIBCPP_NULLPTR + +#include "third_party/libcxx/__config" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_NULLPTR + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_TEMPLATE_VIS nullptr_t +{ + void* __lx; + + struct __nat {int __for_bool_;}; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;} + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + operator _Tp* () const {return 0;} + + template + _LIBCPP_INLINE_VISIBILITY + operator _Tp _Up::* () const {return 0;} + + friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;} + friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;} +}; + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);} + +#define nullptr _VSTD::__get_nullptr_t() + +_LIBCPP_END_NAMESPACE_STD + +#else // _LIBCPP_HAS_NO_NULLPTR + +namespace std +{ + typedef decltype(nullptr) nullptr_t; +} + +#endif // _LIBCPP_HAS_NO_NULLPTR + +#endif // _LIBCPP_NULLPTR diff --git a/third_party/libcxx/__split_buffer b/third_party/libcxx/__split_buffer new file mode 100644 index 000000000..86ea79d37 --- /dev/null +++ b/third_party/libcxx/__split_buffer @@ -0,0 +1,644 @@ +// -*- C++ -*- +#ifndef _LIBCPP_SPLIT_BUFFER +#define _LIBCPP_SPLIT_BUFFER + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/type_traits" +#include "third_party/libcxx/algorithm" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __split_buffer_common +{ +protected: + void __throw_length_error() const; + void __throw_out_of_range() const; +}; + +template > +struct __split_buffer + : private __split_buffer_common +{ +private: + __split_buffer(const __split_buffer&); + __split_buffer& operator=(const __split_buffer&); +public: + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename remove_reference::type __alloc_rr; + typedef allocator_traits<__alloc_rr> __alloc_traits; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef pointer iterator; + typedef const_pointer const_iterator; + + pointer __first_; + pointer __begin_; + pointer __end_; + __compressed_pair __end_cap_; + + typedef typename add_lvalue_reference::type __alloc_ref; + typedef typename add_lvalue_reference::type __alloc_const_ref; + + _LIBCPP_INLINE_VISIBILITY __alloc_rr& __alloc() _NOEXCEPT {return __end_cap_.second();} + _LIBCPP_INLINE_VISIBILITY const __alloc_rr& __alloc() const _NOEXCEPT {return __end_cap_.second();} + _LIBCPP_INLINE_VISIBILITY pointer& __end_cap() _NOEXCEPT {return __end_cap_.first();} + _LIBCPP_INLINE_VISIBILITY const pointer& __end_cap() const _NOEXCEPT {return __end_cap_.first();} + + _LIBCPP_INLINE_VISIBILITY + __split_buffer() + _NOEXCEPT_(is_nothrow_default_constructible::value); + _LIBCPP_INLINE_VISIBILITY + explicit __split_buffer(__alloc_rr& __a); + _LIBCPP_INLINE_VISIBILITY + explicit __split_buffer(const __alloc_rr& __a); + __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a); + ~__split_buffer(); + +#ifndef _LIBCPP_CXX03_LANG + __split_buffer(__split_buffer&& __c) + _NOEXCEPT_(is_nothrow_move_constructible::value); + __split_buffer(__split_buffer&& __c, const __alloc_rr& __a); + __split_buffer& operator=(__split_buffer&& __c) + _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) || + !__alloc_traits::propagate_on_container_move_assignment::value); +#endif // _LIBCPP_CXX03_LANG + + _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __begin_;} + _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;} + _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __end_;} + _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __end_;} + + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT + {__destruct_at_end(__begin_);} + _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast(__end_ - __begin_);} + _LIBCPP_INLINE_VISIBILITY bool empty() const {return __end_ == __begin_;} + _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast(__end_cap() - __first_);} + _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast(__begin_ - __first_);} + _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast(__end_cap() - __end_);} + + _LIBCPP_INLINE_VISIBILITY reference front() {return *__begin_;} + _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;} + _LIBCPP_INLINE_VISIBILITY reference back() {return *(__end_ - 1);} + _LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(__end_ - 1);} + + void reserve(size_type __n); + void shrink_to_fit() _NOEXCEPT; + void push_front(const_reference __x); + _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x); +#ifndef _LIBCPP_CXX03_LANG + void push_front(value_type&& __x); + void push_back(value_type&& __x); + template + void emplace_back(_Args&&... __args); +#endif // !defined(_LIBCPP_CXX03_LANG) + + _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);} + _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);} + + void __construct_at_end(size_type __n); + void __construct_at_end(size_type __n, const_reference __x); + template + typename enable_if + < + __is_input_iterator<_InputIter>::value && + !__is_forward_iterator<_InputIter>::value, + void + >::type + __construct_at_end(_InputIter __first, _InputIter __last); + template + typename enable_if + < + __is_forward_iterator<_ForwardIterator>::value, + void + >::type + __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); + + _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin) + {__destruct_at_begin(__new_begin, is_trivially_destructible());} + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_begin(pointer __new_begin, false_type); + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_begin(pointer __new_begin, true_type); + + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(pointer __new_last) _NOEXCEPT + {__destruct_at_end(__new_last, false_type());} + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT; + + void swap(__split_buffer& __x) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| + __is_nothrow_swappable<__alloc_rr>::value); + + bool __invariants() const; + +private: + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__split_buffer& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) + { + __alloc() = _VSTD::move(__c.__alloc()); + } + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT + {} + + struct _ConstructTransaction { + explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT + : __pos_(*__p), __end_(*__p + __n), __dest_(__p) { + } + ~_ConstructTransaction() { + *__dest_ = __pos_; + } + pointer __pos_; + const pointer __end_; + private: + pointer *__dest_; + }; +}; + +template +bool +__split_buffer<_Tp, _Allocator>::__invariants() const +{ + if (__first_ == nullptr) + { + if (__begin_ != nullptr) + return false; + if (__end_ != nullptr) + return false; + if (__end_cap() != nullptr) + return false; + } + else + { + if (__begin_ < __first_) + return false; + if (__end_ < __begin_) + return false; + if (__end_cap() < __end_) + return false; + } + return true; +} + +// Default constructs __n objects starting at __end_ +// throws if construction throws +// Precondition: __n > 0 +// Precondition: size() + __n <= capacity() +// Postcondition: size() == size() + __n +template +void +__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) +{ + _ConstructTransaction __tx(&this->__end_, __n); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { + __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(__tx.__pos_)); + } +} + +// Copy constructs __n objects starting at __end_ from __x +// throws if construction throws +// Precondition: __n > 0 +// Precondition: size() + __n <= capacity() +// Postcondition: size() == old size() + __n +// Postcondition: [i] == __x for all i in [size() - __n, __n) +template +void +__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) +{ + _ConstructTransaction __tx(&this->__end_, __n); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { + __alloc_traits::construct(this->__alloc(), + _VSTD::__to_raw_pointer(__tx.__pos_), __x); + } +} + +template +template +typename enable_if +< + __is_input_iterator<_InputIter>::value && + !__is_forward_iterator<_InputIter>::value, + void +>::type +__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) +{ + __alloc_rr& __a = this->__alloc(); + for (; __first != __last; ++__first) + { + if (__end_ == __end_cap()) + { + size_type __old_cap = __end_cap() - __first_; + size_type __new_cap = _VSTD::max(2 * __old_cap, 8); + __split_buffer __buf(__new_cap, 0, __a); + for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_) + __alloc_traits::construct(__buf.__alloc(), + _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p)); + swap(__buf); + } + __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); + ++this->__end_; + } +} + +template +template +typename enable_if +< + __is_forward_iterator<_ForwardIterator>::value, + void +>::type +__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) +{ + _ConstructTransaction __tx(&this->__end_, std::distance(__first, __last)); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, ++__first) { + __alloc_traits::construct(this->__alloc(), + _VSTD::__to_raw_pointer(__tx.__pos_), *__first); + } +} + +template +inline +void +__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) +{ + while (__begin_ != __new_begin) + __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++)); +} + +template +inline +void +__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type) +{ + __begin_ = __new_begin; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT +{ + while (__new_last != __end_) + __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT +{ + __end_ = __new_last; +} + +template +__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a) + : __end_cap_(nullptr, __a) +{ + __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr; + __begin_ = __end_ = __first_ + __start; + __end_cap() = __first_ + __cap; +} + +template +inline +__split_buffer<_Tp, _Allocator>::__split_buffer() + _NOEXCEPT_(is_nothrow_default_constructible::value) + : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr) +{ +} + +template +inline +__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a) + : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) +{ +} + +template +inline +__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a) + : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) +{ +} + +template +__split_buffer<_Tp, _Allocator>::~__split_buffer() +{ + clear(); + if (__first_) + __alloc_traits::deallocate(__alloc(), __first_, capacity()); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : __first_(_VSTD::move(__c.__first_)), + __begin_(_VSTD::move(__c.__begin_)), + __end_(_VSTD::move(__c.__end_)), + __end_cap_(_VSTD::move(__c.__end_cap_)) +{ + __c.__first_ = nullptr; + __c.__begin_ = nullptr; + __c.__end_ = nullptr; + __c.__end_cap() = nullptr; +} + +template +__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a) + : __end_cap_(__second_tag(), __a) +{ + if (__a == __c.__alloc()) + { + __first_ = __c.__first_; + __begin_ = __c.__begin_; + __end_ = __c.__end_; + __end_cap() = __c.__end_cap(); + __c.__first_ = nullptr; + __c.__begin_ = nullptr; + __c.__end_ = nullptr; + __c.__end_cap() = nullptr; + } + else + { + size_type __cap = __c.size(); + __first_ = __alloc_traits::allocate(__alloc(), __cap); + __begin_ = __end_ = __first_; + __end_cap() = __first_ + __cap; + typedef move_iterator _Ip; + __construct_at_end(_Ip(__c.begin()), _Ip(__c.end())); + } +} + +template +__split_buffer<_Tp, _Allocator>& +__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c) + _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) || + !__alloc_traits::propagate_on_container_move_assignment::value) +{ + clear(); + shrink_to_fit(); + __first_ = __c.__first_; + __begin_ = __c.__begin_; + __end_ = __c.__end_; + __end_cap() = __c.__end_cap(); + __move_assign_alloc(__c, + integral_constant()); + __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr; + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +template +void +__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| + __is_nothrow_swappable<__alloc_rr>::value) +{ + _VSTD::swap(__first_, __x.__first_); + _VSTD::swap(__begin_, __x.__begin_); + _VSTD::swap(__end_, __x.__end_); + _VSTD::swap(__end_cap(), __x.__end_cap()); + __swap_allocator(__alloc(), __x.__alloc()); +} + +template +void +__split_buffer<_Tp, _Allocator>::reserve(size_type __n) +{ + if (__n < capacity()) + { + __split_buffer __t(__n, 0, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } +} + +template +void +__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT +{ + if (capacity() > size()) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + __split_buffer __t(size(), 0, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + __t.__end_ = __t.__begin_ + (__end_ - __begin_); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +void +__split_buffer<_Tp, _Allocator>::push_front(const_reference __x) +{ + if (__begin_ == __first_) + { + if (__end_ < __end_cap()) + { + difference_type __d = __end_cap() - __end_; + __d = (__d + 1) / 2; + __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); + __end_ += __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, (__c + 3) / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x); + --__begin_; +} + +#ifndef _LIBCPP_CXX03_LANG + +template +void +__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x) +{ + if (__begin_ == __first_) + { + if (__end_ < __end_cap()) + { + difference_type __d = __end_cap() - __end_; + __d = (__d + 1) / 2; + __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); + __end_ += __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, (__c + 3) / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), + _VSTD::move(__x)); + --__begin_; +} + +#endif // _LIBCPP_CXX03_LANG + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__split_buffer<_Tp, _Allocator>::push_back(const_reference __x) +{ + if (__end_ == __end_cap()) + { + if (__begin_ > __first_) + { + difference_type __d = __begin_ - __first_; + __d = (__d + 1) / 2; + __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); + __begin_ -= __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, __c / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x); + ++__end_; +} + +#ifndef _LIBCPP_CXX03_LANG + +template +void +__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x) +{ + if (__end_ == __end_cap()) + { + if (__begin_ > __first_) + { + difference_type __d = __begin_ - __first_; + __d = (__d + 1) / 2; + __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); + __begin_ -= __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, __c / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), + _VSTD::move(__x)); + ++__end_; +} + +template +template +void +__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) +{ + if (__end_ == __end_cap()) + { + if (__begin_ > __first_) + { + difference_type __d = __begin_ - __first_; + __d = (__d + 1) / 2; + __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); + __begin_ -= __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, __c / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), + _VSTD::forward<_Args>(__args)...); + ++__end_; +} + +#endif // _LIBCPP_CXX03_LANG + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_SPLIT_BUFFER diff --git a/third_party/libcxx/__string b/third_party/libcxx/__string new file mode 100644 index 000000000..e13398084 --- /dev/null +++ b/third_party/libcxx/__string @@ -0,0 +1,985 @@ +// -*- C++ -*- +//===-------------------------- __string ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___STRING +#define _LIBCPP___STRING + +/* + string synopsis + +namespace std +{ + +template +struct char_traits +{ + typedef charT char_type; + typedef ... int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static constexpr void assign(char_type& c1, const char_type& c2) noexcept; + static constexpr bool eq(char_type c1, char_type c2) noexcept; + static constexpr bool lt(char_type c1, char_type c2) noexcept; + + static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); + static constexpr size_t length(const char_type* s); + static constexpr const char_type* + find(const char_type* s, size_t n, const char_type& a); + static char_type* move(char_type* s1, const char_type* s2, size_t n); + static char_type* copy(char_type* s1, const char_type* s2, size_t n); + static char_type* assign(char_type* s, size_t n, char_type a); + + static constexpr int_type not_eof(int_type c) noexcept; + static constexpr char_type to_char_type(int_type c) noexcept; + static constexpr int_type to_int_type(char_type c) noexcept; + static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; + static constexpr int_type eof() noexcept; +}; + +template <> struct char_traits; +template <> struct char_traits; +template <> struct char_traits; // c++20 + +} // std + +*/ + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/algorithm" // for search and min +#include "third_party/libcxx/cstdio" // For EOF. +#include "third_party/libcxx/memory" // for __murmur2_or_cityhash + +#include "third_party/libcxx/__debug" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +// char_traits + +template +struct _LIBCPP_TEMPLATE_VIS char_traits +{ + typedef _CharT char_type; + typedef int int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14 + assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + static _LIBCPP_CONSTEXPR_AFTER_CXX14 + int compare(const char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + size_t length(const char_type* __s); + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + const char_type* find(const char_type* __s, size_t __n, const char_type& __a); + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY + static char_type* assign(char_type* __s, size_t __n, char_type __a); + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(EOF);} +}; + +template +_LIBCPP_CONSTEXPR_AFTER_CXX14 int +char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n) +{ + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +} + +template +inline +_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t +char_traits<_CharT>::length(const char_type* __s) +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +template +inline +_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT* +char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a) +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +template +_CharT* +char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) +{ + char_type* __r = __s1; + if (__s1 < __s2) + { + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + } + else if (__s2 < __s1) + { + __s1 += __n; + __s2 += __n; + for (; __n; --__n) + assign(*--__s1, *--__s2); + } + return __r; +} + +template +inline +_CharT* +char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) +{ + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + char_type* __r = __s1; + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + return __r; +} + +template +inline +_CharT* +char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) +{ + char_type* __r = __s; + for (; __n; --__n, ++__s) + assign(*__s, __a); + return __r; +} + +// char_traits + +template <> +struct _LIBCPP_TEMPLATE_VIS char_traits +{ + typedef char char_type; + typedef int int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static inline _LIBCPP_CONSTEXPR_AFTER_CXX14 + void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return (unsigned char)__c1 < (unsigned char)__c2;} + + static _LIBCPP_CONSTEXPR_AFTER_CXX14 + int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14 + length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);} + static _LIBCPP_CONSTEXPR_AFTER_CXX14 + const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} + static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } + static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type((unsigned char)__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(EOF);} +}; + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +int +char_traits::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + if (__n == 0) + return 0; +#if __has_feature(cxx_constexpr_string_builtins) + return __builtin_memcmp(__s1, __s2, __n); +#elif _LIBCPP_STD_VER <= 14 + return memcmp(__s1, __s2, __n); +#else + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +#endif +} + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +const char* +char_traits::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + if (__n == 0) + return nullptr; +#if __has_feature(cxx_constexpr_string_builtins) + return __builtin_char_memchr(__s, to_int_type(__a), __n); +#elif _LIBCPP_STD_VER <= 14 + return (const char_type*) memchr(__s, to_int_type(__a), __n); +#else + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return nullptr; +#endif +} + + +// char_traits + +template <> +struct _LIBCPP_TEMPLATE_VIS char_traits +{ + typedef wchar_t char_type; + typedef wint_t int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static inline _LIBCPP_CONSTEXPR_AFTER_CXX14 + void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + static _LIBCPP_CONSTEXPR_AFTER_CXX14 + int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + static _LIBCPP_CONSTEXPR_AFTER_CXX14 + size_t length(const char_type* __s) _NOEXCEPT; + static _LIBCPP_CONSTEXPR_AFTER_CXX14 + const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);} + static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n); + } + static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);} + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(WEOF);} +}; + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +int +char_traits::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + if (__n == 0) + return 0; +#if __has_feature(cxx_constexpr_string_builtins) + return __builtin_wmemcmp(__s1, __s2, __n); +#elif _LIBCPP_STD_VER <= 14 + return wmemcmp(__s1, __s2, __n); +#else + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +#endif +} + + +template +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT { +#if _LIBCPP_DEBUG_LEVEL >= 1 + return __s ? _Traits::length(__s) : (_VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, "p == nullptr", "null pointer pass to non-null argument of char_traits<...>::length")), 0); +#else + return _Traits::length(__s); +#endif +} + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +size_t +char_traits::length(const char_type* __s) _NOEXCEPT +{ +#if __has_feature(cxx_constexpr_string_builtins) + return __builtin_wcslen(__s); +#elif _LIBCPP_STD_VER <= 14 + return wcslen(__s); +#else + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +#endif +} + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +const wchar_t* +char_traits::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + if (__n == 0) + return nullptr; +#if __has_feature(cxx_constexpr_string_builtins) + return __builtin_wmemchr(__s, __a, __n); +#elif _LIBCPP_STD_VER <= 14 + return wmemchr(__s, __a, __n); +#else + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return nullptr; +#endif +} + + +#ifndef _LIBCPP_NO_HAS_CHAR8_T + +template <> +struct _LIBCPP_TEMPLATE_VIS char_traits +{ + typedef char8_t char_type; + typedef unsigned int int_type; + typedef streamoff off_type; + typedef u8streampos pos_type; + typedef mbstate_t state_type; + + static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept + {__c1 = __c2;} + static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept + {return __c1 == __c2;} + static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept + {return __c1 < __c2;} + + static constexpr + int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + + static constexpr + size_t length(const char_type* __s) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY static constexpr + const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} + + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } + + static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} + + static inline constexpr int_type not_eof(int_type __c) noexcept + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline constexpr char_type to_char_type(int_type __c) noexcept + {return char_type(__c);} + static inline constexpr int_type to_int_type(char_type __c) noexcept + {return int_type(__c);} + static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept + {return __c1 == __c2;} + static inline constexpr int_type eof() noexcept + {return int_type(EOF);} +}; + +// TODO use '__builtin_strlen' if it ever supports char8_t ?? +inline constexpr +size_t +char_traits::length(const char_type* __s) _NOEXCEPT +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +inline constexpr +int +char_traits::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ +#if __has_feature(cxx_constexpr_string_builtins) + return __builtin_memcmp(__s1, __s2, __n); +#else + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +#endif +} + +// TODO use '__builtin_char_memchr' if it ever supports char8_t ?? +inline constexpr +const char8_t* +char_traits::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +#endif // #_LIBCPP_NO_HAS_CHAR8_T + +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + +template <> +struct _LIBCPP_TEMPLATE_VIS char_traits +{ + typedef char16_t char_type; + typedef uint_least16_t int_type; + typedef streamoff off_type; + typedef u16streampos pos_type; + typedef mbstate_t state_type; + + static inline _LIBCPP_CONSTEXPR_AFTER_CXX14 + void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + size_t length(const char_type* __s) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT; + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(0xFFFF);} +}; + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +int +char_traits::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +} + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +size_t +char_traits::length(const char_type* __s) _NOEXCEPT +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +const char16_t* +char_traits::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +inline +char16_t* +char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + char_type* __r = __s1; + if (__s1 < __s2) + { + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + } + else if (__s2 < __s1) + { + __s1 += __n; + __s2 += __n; + for (; __n; --__n) + assign(*--__s1, *--__s2); + } + return __r; +} + +inline +char16_t* +char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + char_type* __r = __s1; + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + return __r; +} + +inline +char16_t* +char_traits::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT +{ + char_type* __r = __s; + for (; __n; --__n, ++__s) + assign(*__s, __a); + return __r; +} + +template <> +struct _LIBCPP_TEMPLATE_VIS char_traits +{ + typedef char32_t char_type; + typedef uint_least32_t int_type; + typedef streamoff off_type; + typedef u32streampos pos_type; + typedef mbstate_t state_type; + + static inline _LIBCPP_CONSTEXPR_AFTER_CXX14 + void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + size_t length(const char_type* __s) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT; + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(0xFFFFFFFF);} +}; + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +int +char_traits::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +} + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +size_t +char_traits::length(const char_type* __s) _NOEXCEPT +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +const char32_t* +char_traits::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +inline +char32_t* +char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + char_type* __r = __s1; + if (__s1 < __s2) + { + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + } + else if (__s2 < __s1) + { + __s1 += __n; + __s2 += __n; + for (; __n; --__n) + assign(*--__s1, *--__s2); + } + return __r; +} + +inline +char32_t* +char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + char_type* __r = __s1; + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + return __r; +} + +inline +char32_t* +char_traits::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT +{ + char_type* __r = __s; + for (; __n; --__n, ++__s) + assign(*__s, __a); + return __r; +} + +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + +// helper fns for basic_string and string_view + +// __str_find +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find(const _CharT *__p, _SizeT __sz, + _CharT __c, _SizeT __pos) _NOEXCEPT +{ + if (__pos >= __sz) + return __npos; + const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c); + if (__r == 0) + return __npos; + return static_cast<_SizeT>(__r - __p); +} + +template +inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT * +__search_substring(const _CharT *__first1, const _CharT *__last1, + const _CharT *__first2, const _CharT *__last2) { + // Take advantage of knowing source and pattern lengths. + // Stop short when source is smaller than pattern. + const ptrdiff_t __len2 = __last2 - __first2; + if (__len2 == 0) + return __first1; + + ptrdiff_t __len1 = __last1 - __first1; + if (__len1 < __len2) + return __last1; + + // First element of __first2 is loop invariant. + _CharT __f2 = *__first2; + while (true) { + __len1 = __last1 - __first1; + // Check whether __first1 still has at least __len2 bytes. + if (__len1 < __len2) + return __last1; + + // Find __f2 the first byte matching in __first1. + __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2); + if (__first1 == 0) + return __last1; + + // It is faster to compare from the first byte of __first1 even if we + // already know that it matches the first byte of __first2: this is because + // __first2 is most likely aligned, as it is user's "pattern" string, and + // __first1 + 1 is most likely not aligned, as the match is in the middle of + // the string. + if (_Traits::compare(__first1, __first2, __len2) == 0) + return __first1; + + ++__first1; + } +} + +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + if (__pos > __sz) + return __npos; + + if (__n == 0) // There is nothing to search, just return __pos. + return __pos; + + const _CharT *__r = __search_substring<_CharT, _Traits>( + __p + __pos, __p + __sz, __s, __s + __n); + + if (__r == __p + __sz) + return __npos; + return static_cast<_SizeT>(__r - __p); +} + + +// __str_rfind + +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_rfind(const _CharT *__p, _SizeT __sz, + _CharT __c, _SizeT __pos) _NOEXCEPT +{ + if (__sz < 1) + return __npos; + if (__pos < __sz) + ++__pos; + else + __pos = __sz; + for (const _CharT* __ps = __p + __pos; __ps != __p;) + { + if (_Traits::eq(*--__ps, __c)) + return static_cast<_SizeT>(__ps - __p); + } + return __npos; +} + +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_rfind(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + __pos = _VSTD::min(__pos, __sz); + if (__n < __sz - __pos) + __pos += __n; + else + __pos = __sz; + const _CharT* __r = _VSTD::__find_end( + __p, __p + __pos, __s, __s + __n, _Traits::eq, + random_access_iterator_tag(), random_access_iterator_tag()); + if (__n > 0 && __r == __p + __pos) + return __npos; + return static_cast<_SizeT>(__r - __p); +} + +// __str_find_first_of +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_first_of(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + if (__pos >= __sz || __n == 0) + return __npos; + const _CharT* __r = _VSTD::__find_first_of_ce + (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq ); + if (__r == __p + __sz) + return __npos; + return static_cast<_SizeT>(__r - __p); +} + + +// __str_find_last_of +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_last_of(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT + { + if (__n != 0) + { + if (__pos < __sz) + ++__pos; + else + __pos = __sz; + for (const _CharT* __ps = __p + __pos; __ps != __p;) + { + const _CharT* __r = _Traits::find(__s, __n, *--__ps); + if (__r) + return static_cast<_SizeT>(__ps - __p); + } + } + return __npos; +} + + +// __str_find_first_not_of +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_first_not_of(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + if (__pos < __sz) + { + const _CharT* __pe = __p + __sz; + for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) + if (_Traits::find(__s, __n, *__ps) == 0) + return static_cast<_SizeT>(__ps - __p); + } + return __npos; +} + + +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_first_not_of(const _CharT *__p, _SizeT __sz, + _CharT __c, _SizeT __pos) _NOEXCEPT +{ + if (__pos < __sz) + { + const _CharT* __pe = __p + __sz; + for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) + if (!_Traits::eq(*__ps, __c)) + return static_cast<_SizeT>(__ps - __p); + } + return __npos; +} + + +// __str_find_last_not_of +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_last_not_of(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + if (__pos < __sz) + ++__pos; + else + __pos = __sz; + for (const _CharT* __ps = __p + __pos; __ps != __p;) + if (_Traits::find(__s, __n, *--__ps) == 0) + return static_cast<_SizeT>(__ps - __p); + return __npos; +} + + +template +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_last_not_of(const _CharT *__p, _SizeT __sz, + _CharT __c, _SizeT __pos) _NOEXCEPT +{ + if (__pos < __sz) + ++__pos; + else + __pos = __sz; + for (const _CharT* __ps = __p + __pos; __ps != __p;) + if (!_Traits::eq(*--__ps, __c)) + return static_cast<_SizeT>(__ps - __p); + return __npos; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +size_t __do_string_hash(_Ptr __p, _Ptr __e) +{ + typedef typename iterator_traits<_Ptr>::value_type value_type; + return __murmur2_or_cityhash()(__p, (__e-__p)*sizeof(value_type)); +} + +template > +struct __quoted_output_proxy +{ + _Iter __first; + _Iter __last; + _CharT __delim; + _CharT __escape; + + __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e) + : __first(__f), __last(__l), __delim(__d), __escape(__e) {} + // This would be a nice place for a string_ref +}; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___STRING diff --git a/third_party/libcxx/__threading_support b/third_party/libcxx/__threading_support new file mode 100644 index 000000000..9247e06f0 --- /dev/null +++ b/third_party/libcxx/__threading_support @@ -0,0 +1,490 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_THREADING_SUPPORT +#define _LIBCPP_THREADING_SUPPORT + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/chrono" +#include "third_party/libcxx/iosfwd" +#include "third_party/libcxx/errno.h" + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +# include "third_party/libcxx/__external_threading" +#elif !defined(_LIBCPP_HAS_NO_THREADS) + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# include "third_party/libcxx/pthread.h" +# include "third_party/libcxx/sched.h" +#endif + +#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ + defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \ + defined(_LIBCPP_HAS_THREAD_API_WIN32) +#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS +#else +#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY +#endif + +#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis) +#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) +#else +#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +#endif + +typedef ::timespec __libcpp_timespec_t; +#endif // !defined(_LIBCPP_HAS_NO_THREADS) + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_THREADS) + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +// Mutex +typedef pthread_mutex_t __libcpp_mutex_t; +#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +typedef pthread_mutex_t __libcpp_recursive_mutex_t; + +// Condition Variable +typedef pthread_cond_t __libcpp_condvar_t; +#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER + +// Execute once +typedef pthread_once_t __libcpp_exec_once_flag; +#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT + +// Thread id +typedef pthread_t __libcpp_thread_id; + +// Thread +#define _LIBCPP_NULL_THREAD 0U + +typedef pthread_t __libcpp_thread_t; + +// Thread Local Storage +typedef pthread_key_t __libcpp_tls_key; + +#define _LIBCPP_TLS_DESTRUCTOR_CC +#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +// Mutex +typedef void* __libcpp_mutex_t; +#define _LIBCPP_MUTEX_INITIALIZER 0 + +#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) +typedef void* __libcpp_recursive_mutex_t[6]; +#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) +typedef void* __libcpp_recursive_mutex_t[5]; +#else +# error Unsupported architecture +#endif + +// Condition Variable +typedef void* __libcpp_condvar_t; +#define _LIBCPP_CONDVAR_INITIALIZER 0 + +// Execute Once +typedef void* __libcpp_exec_once_flag; +#define _LIBCPP_EXEC_ONCE_INITIALIZER 0 + +// Thread ID +typedef long __libcpp_thread_id; + +// Thread +#define _LIBCPP_NULL_THREAD 0U + +typedef void* __libcpp_thread_t; + +// Thread Local Storage +typedef long __libcpp_tls_key; + +#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall +#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) + +#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +// Mutex +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); + +_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); + +_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); + +_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); + +_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +int __libcpp_mutex_lock(__libcpp_mutex_t *__m); + +_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); + +_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +int __libcpp_mutex_unlock(__libcpp_mutex_t *__m); + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_mutex_destroy(__libcpp_mutex_t *__m); + +// Condition variable +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_condvar_signal(__libcpp_condvar_t* __cv); + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); + +_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); + +_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS +int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, + __libcpp_timespec_t *__ts); + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); + +// Execute once +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_execute_once(__libcpp_exec_once_flag *flag, + void (*init_routine)()); + +// Thread id +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); + +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); + +// Thread +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_thread_isnull(const __libcpp_thread_t *__t); + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), + void *__arg); + +_LIBCPP_THREAD_ABI_VISIBILITY +__libcpp_thread_id __libcpp_thread_get_current_id(); + +_LIBCPP_THREAD_ABI_VISIBILITY +__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_thread_join(__libcpp_thread_t *__t); + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_thread_detach(__libcpp_thread_t *__t); + +_LIBCPP_THREAD_ABI_VISIBILITY +void __libcpp_thread_yield(); + +_LIBCPP_THREAD_ABI_VISIBILITY +void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); + +// Thread local storage +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_tls_create(__libcpp_tls_key* __key, + void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); + +_LIBCPP_THREAD_ABI_VISIBILITY +void *__libcpp_tls_get(__libcpp_tls_key __key); + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); + +#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) + +#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ + defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \ + defined(_LIBCPP_HAS_THREAD_API_PTHREAD) + +int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) +{ + pthread_mutexattr_t attr; + int __ec = pthread_mutexattr_init(&attr); + if (__ec) + return __ec; + __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + if (__ec) { + pthread_mutexattr_destroy(&attr); + return __ec; + } + __ec = pthread_mutex_init(__m, &attr); + if (__ec) { + pthread_mutexattr_destroy(&attr); + return __ec; + } + __ec = pthread_mutexattr_destroy(&attr); + if (__ec) { + pthread_mutex_destroy(__m); + return __ec; + } + return 0; +} + +int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) +{ + return pthread_mutex_lock(__m); +} + +bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) +{ + return pthread_mutex_trylock(__m) == 0; +} + +int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) +{ + return pthread_mutex_unlock(__m); +} + +int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) +{ + return pthread_mutex_destroy(__m); +} + +int __libcpp_mutex_lock(__libcpp_mutex_t *__m) +{ + return pthread_mutex_lock(__m); +} + +bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) +{ + return pthread_mutex_trylock(__m) == 0; +} + +int __libcpp_mutex_unlock(__libcpp_mutex_t *__m) +{ + return pthread_mutex_unlock(__m); +} + +int __libcpp_mutex_destroy(__libcpp_mutex_t *__m) +{ + return pthread_mutex_destroy(__m); +} + +// Condition Variable +int __libcpp_condvar_signal(__libcpp_condvar_t *__cv) +{ + return pthread_cond_signal(__cv); +} + +int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) +{ + return pthread_cond_broadcast(__cv); +} + +int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) +{ + return pthread_cond_wait(__cv, __m); +} + +int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, + __libcpp_timespec_t *__ts) +{ + return pthread_cond_timedwait(__cv, __m, __ts); +} + +int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) +{ + return pthread_cond_destroy(__cv); +} + +// Execute once +int __libcpp_execute_once(__libcpp_exec_once_flag *flag, + void (*init_routine)()) { + return pthread_once(flag, init_routine); +} + +// Thread id +// Returns non-zero if the thread ids are equal, otherwise 0 +bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) +{ + return pthread_equal(t1, t2) != 0; +} + +// Returns non-zero if t1 < t2, otherwise 0 +bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) +{ + return t1 < t2; +} + +// Thread +bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { + return *__t == 0; +} + +int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), + void *__arg) +{ + return pthread_create(__t, 0, __func, __arg); +} + +__libcpp_thread_id __libcpp_thread_get_current_id() +{ + return pthread_self(); +} + +__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) +{ + return *__t; +} + +int __libcpp_thread_join(__libcpp_thread_t *__t) +{ + return pthread_join(*__t, 0); +} + +int __libcpp_thread_detach(__libcpp_thread_t *__t) +{ + return pthread_detach(*__t); +} + +void __libcpp_thread_yield() +{ + sched_yield(); +} + +void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast(__ns); + __libcpp_timespec_t __ts; + typedef decltype(__ts.tv_sec) ts_sec; + _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast(__s.count()); + __ts.tv_nsec = static_cast((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); +} + +// Thread local storage +int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) +{ + return pthread_key_create(__key, __at_exit); +} + +void *__libcpp_tls_get(__libcpp_tls_key __key) +{ + return pthread_getspecific(__key); +} + +int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) +{ + return pthread_setspecific(__key, __p); +} + +#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL + +class _LIBCPP_TYPE_VIS thread; +class _LIBCPP_TYPE_VIS __thread_id; + +namespace this_thread +{ + +_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; + +} // this_thread + +template<> struct hash<__thread_id>; + +class _LIBCPP_TEMPLATE_VIS __thread_id +{ + // FIXME: pthread_t is a pointer on Darwin but a long on Linux. + // NULL is the no-thread value on Darwin. Someone needs to check + // on other platforms. We assume 0 works everywhere for now. + __libcpp_thread_id __id_; + +public: + _LIBCPP_INLINE_VISIBILITY + __thread_id() _NOEXCEPT : __id_(0) {} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT + { // don't pass id==0 to underlying routines + if (__x.__id_ == 0) return __y.__id_ == 0; + if (__y.__id_ == 0) return false; + return __libcpp_thread_id_equal(__x.__id_, __y.__id_); + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT + {return !(__x == __y);} + friend _LIBCPP_INLINE_VISIBILITY + bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT + { // id==0 is always less than any other thread_id + if (__x.__id_ == 0) return __y.__id_ != 0; + if (__y.__id_ == 0) return false; + return __libcpp_thread_id_less(__x.__id_, __y.__id_); + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT + {return !(__y < __x);} + friend _LIBCPP_INLINE_VISIBILITY + bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT + {return __y < __x ;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT + {return !(__x < __y);} + + _LIBCPP_INLINE_VISIBILITY + void __reset() { __id_ = 0; } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); + +private: + _LIBCPP_INLINE_VISIBILITY + __thread_id(__libcpp_thread_id __id) : __id_(__id) {} + + friend __thread_id this_thread::get_id() _NOEXCEPT; + friend class _LIBCPP_TYPE_VIS thread; + friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; +}; + +namespace this_thread +{ + +inline _LIBCPP_INLINE_VISIBILITY +__thread_id +get_id() _NOEXCEPT +{ + return __libcpp_thread_get_current_id(); +} + +} // this_thread + +#endif // !_LIBCPP_HAS_NO_THREADS + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_THREADING_SUPPORT diff --git a/third_party/libcxx/__tree b/third_party/libcxx/__tree new file mode 100644 index 000000000..458fd9bae --- /dev/null +++ b/third_party/libcxx/__tree @@ -0,0 +1,2843 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TREE +#define _LIBCPP___TREE + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/iterator" +#include "third_party/libcxx/memory" +#include "third_party/libcxx/stdexcept" +#include "third_party/libcxx/algorithm" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include "third_party/libcxx/__undef_macros" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if defined(__GNUC__) && !defined(__clang__) // gcc.gnu.org/PR37804 +template class _LIBCPP_TEMPLATE_VIS map; +template class _LIBCPP_TEMPLATE_VIS multimap; +template class _LIBCPP_TEMPLATE_VIS set; +template class _LIBCPP_TEMPLATE_VIS multiset; +#endif + +template class __tree; +template + class _LIBCPP_TEMPLATE_VIS __tree_iterator; +template + class _LIBCPP_TEMPLATE_VIS __tree_const_iterator; + +template class __tree_end_node; +template class __tree_node_base; +template class __tree_node; + +template +struct __value_type; + +template class __map_node_destructor; +template class _LIBCPP_TEMPLATE_VIS __map_iterator; +template class _LIBCPP_TEMPLATE_VIS __map_const_iterator; + +/* + +_NodePtr algorithms + +The algorithms taking _NodePtr are red black tree algorithms. Those +algorithms taking a parameter named __root should assume that __root +points to a proper red black tree (unless otherwise specified). + +Each algorithm herein assumes that __root->__parent_ points to a non-null +structure which has a member __left_ which points back to __root. No other +member is read or written to at __root->__parent_. + +__root->__parent_ will be referred to below (in comments only) as end_node. +end_node->__left_ is an externably accessible lvalue for __root, and can be +changed by node insertion and removal (without explicit reference to end_node). + +All nodes (with the exception of end_node), even the node referred to as +__root, have a non-null __parent_ field. + +*/ + +// Returns: true if __x is a left child of its parent, else false +// Precondition: __x != nullptr. +template +inline _LIBCPP_INLINE_VISIBILITY +bool +__tree_is_left_child(_NodePtr __x) _NOEXCEPT +{ + return __x == __x->__parent_->__left_; +} + +// Determines if the subtree rooted at __x is a proper red black subtree. If +// __x is a proper subtree, returns the black height (null counts as 1). If +// __x is an improper subtree, returns 0. +template +unsigned +__tree_sub_invariant(_NodePtr __x) +{ + if (__x == nullptr) + return 1; + // parent consistency checked by caller + // check __x->__left_ consistency + if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x) + return 0; + // check __x->__right_ consistency + if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x) + return 0; + // check __x->__left_ != __x->__right_ unless both are nullptr + if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr) + return 0; + // If this is red, neither child can be red + if (!__x->__is_black_) + { + if (__x->__left_ && !__x->__left_->__is_black_) + return 0; + if (__x->__right_ && !__x->__right_->__is_black_) + return 0; + } + unsigned __h = __tree_sub_invariant(__x->__left_); + if (__h == 0) + return 0; // invalid left subtree + if (__h != __tree_sub_invariant(__x->__right_)) + return 0; // invalid or different height right subtree + return __h + __x->__is_black_; // return black height of this node +} + +// Determines if the red black tree rooted at __root is a proper red black tree. +// __root == nullptr is a proper tree. Returns true is __root is a proper +// red black tree, else returns false. +template +bool +__tree_invariant(_NodePtr __root) +{ + if (__root == nullptr) + return true; + // check __x->__parent_ consistency + if (__root->__parent_ == nullptr) + return false; + if (!__tree_is_left_child(__root)) + return false; + // root must be black + if (!__root->__is_black_) + return false; + // do normal node checks + return __tree_sub_invariant(__root) != 0; +} + +// Returns: pointer to the left-most node under __x. +// Precondition: __x != nullptr. +template +inline _LIBCPP_INLINE_VISIBILITY +_NodePtr +__tree_min(_NodePtr __x) _NOEXCEPT +{ + while (__x->__left_ != nullptr) + __x = __x->__left_; + return __x; +} + +// Returns: pointer to the right-most node under __x. +// Precondition: __x != nullptr. +template +inline _LIBCPP_INLINE_VISIBILITY +_NodePtr +__tree_max(_NodePtr __x) _NOEXCEPT +{ + while (__x->__right_ != nullptr) + __x = __x->__right_; + return __x; +} + +// Returns: pointer to the next in-order node after __x. +// Precondition: __x != nullptr. +template +_NodePtr +__tree_next(_NodePtr __x) _NOEXCEPT +{ + if (__x->__right_ != nullptr) + return __tree_min(__x->__right_); + while (!__tree_is_left_child(__x)) + __x = __x->__parent_unsafe(); + return __x->__parent_unsafe(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_EndNodePtr +__tree_next_iter(_NodePtr __x) _NOEXCEPT +{ + if (__x->__right_ != nullptr) + return static_cast<_EndNodePtr>(__tree_min(__x->__right_)); + while (!__tree_is_left_child(__x)) + __x = __x->__parent_unsafe(); + return static_cast<_EndNodePtr>(__x->__parent_); +} + +// Returns: pointer to the previous in-order node before __x. +// Precondition: __x != nullptr. +// Note: __x may be the end node. +template +inline _LIBCPP_INLINE_VISIBILITY +_NodePtr +__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT +{ + if (__x->__left_ != nullptr) + return __tree_max(__x->__left_); + _NodePtr __xx = static_cast<_NodePtr>(__x); + while (__tree_is_left_child(__xx)) + __xx = __xx->__parent_unsafe(); + return __xx->__parent_unsafe(); +} + +// Returns: pointer to a node which has no children +// Precondition: __x != nullptr. +template +_NodePtr +__tree_leaf(_NodePtr __x) _NOEXCEPT +{ + while (true) + { + if (__x->__left_ != nullptr) + { + __x = __x->__left_; + continue; + } + if (__x->__right_ != nullptr) + { + __x = __x->__right_; + continue; + } + break; + } + return __x; +} + +// Effects: Makes __x->__right_ the subtree root with __x as its left child +// while preserving in-order order. +// Precondition: __x->__right_ != nullptr +template +void +__tree_left_rotate(_NodePtr __x) _NOEXCEPT +{ + _NodePtr __y = __x->__right_; + __x->__right_ = __y->__left_; + if (__x->__right_ != nullptr) + __x->__right_->__set_parent(__x); + __y->__parent_ = __x->__parent_; + if (__tree_is_left_child(__x)) + __x->__parent_->__left_ = __y; + else + __x->__parent_unsafe()->__right_ = __y; + __y->__left_ = __x; + __x->__set_parent(__y); +} + +// Effects: Makes __x->__left_ the subtree root with __x as its right child +// while preserving in-order order. +// Precondition: __x->__left_ != nullptr +template +void +__tree_right_rotate(_NodePtr __x) _NOEXCEPT +{ + _NodePtr __y = __x->__left_; + __x->__left_ = __y->__right_; + if (__x->__left_ != nullptr) + __x->__left_->__set_parent(__x); + __y->__parent_ = __x->__parent_; + if (__tree_is_left_child(__x)) + __x->__parent_->__left_ = __y; + else + __x->__parent_unsafe()->__right_ = __y; + __y->__right_ = __x; + __x->__set_parent(__y); +} + +// Effects: Rebalances __root after attaching __x to a leaf. +// Precondition: __root != nulptr && __x != nullptr. +// __x has no children. +// __x == __root or == a direct or indirect child of __root. +// If __x were to be unlinked from __root (setting __root to +// nullptr if __root == __x), __tree_invariant(__root) == true. +// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_ +// may be different than the value passed in as __root. +template +void +__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT +{ + __x->__is_black_ = __x == __root; + while (__x != __root && !__x->__parent_unsafe()->__is_black_) + { + // __x->__parent_ != __root because __x->__parent_->__is_black == false + if (__tree_is_left_child(__x->__parent_unsafe())) + { + _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_; + if (__y != nullptr && !__y->__is_black_) + { + __x = __x->__parent_unsafe(); + __x->__is_black_ = true; + __x = __x->__parent_unsafe(); + __x->__is_black_ = __x == __root; + __y->__is_black_ = true; + } + else + { + if (!__tree_is_left_child(__x)) + { + __x = __x->__parent_unsafe(); + __tree_left_rotate(__x); + } + __x = __x->__parent_unsafe(); + __x->__is_black_ = true; + __x = __x->__parent_unsafe(); + __x->__is_black_ = false; + __tree_right_rotate(__x); + break; + } + } + else + { + _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_; + if (__y != nullptr && !__y->__is_black_) + { + __x = __x->__parent_unsafe(); + __x->__is_black_ = true; + __x = __x->__parent_unsafe(); + __x->__is_black_ = __x == __root; + __y->__is_black_ = true; + } + else + { + if (__tree_is_left_child(__x)) + { + __x = __x->__parent_unsafe(); + __tree_right_rotate(__x); + } + __x = __x->__parent_unsafe(); + __x->__is_black_ = true; + __x = __x->__parent_unsafe(); + __x->__is_black_ = false; + __tree_left_rotate(__x); + break; + } + } + } +} + +// Precondition: __root != nullptr && __z != nullptr. +// __tree_invariant(__root) == true. +// __z == __root or == a direct or indirect child of __root. +// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed. +// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_ +// nor any of its children refer to __z. end_node->__left_ +// may be different than the value passed in as __root. +template +void +__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT +{ + // __z will be removed from the tree. Client still needs to destruct/deallocate it + // __y is either __z, or if __z has two children, __tree_next(__z). + // __y will have at most one child. + // __y will be the initial hole in the tree (make the hole at a leaf) + _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ? + __z : __tree_next(__z); + // __x is __y's possibly null single child + _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_; + // __w is __x's possibly null uncle (will become __x's sibling) + _NodePtr __w = nullptr; + // link __x to __y's parent, and find __w + if (__x != nullptr) + __x->__parent_ = __y->__parent_; + if (__tree_is_left_child(__y)) + { + __y->__parent_->__left_ = __x; + if (__y != __root) + __w = __y->__parent_unsafe()->__right_; + else + __root = __x; // __w == nullptr + } + else + { + __y->__parent_unsafe()->__right_ = __x; + // __y can't be root if it is a right child + __w = __y->__parent_->__left_; + } + bool __removed_black = __y->__is_black_; + // If we didn't remove __z, do so now by splicing in __y for __z, + // but copy __z's color. This does not impact __x or __w. + if (__y != __z) + { + // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr + __y->__parent_ = __z->__parent_; + if (__tree_is_left_child(__z)) + __y->__parent_->__left_ = __y; + else + __y->__parent_unsafe()->__right_ = __y; + __y->__left_ = __z->__left_; + __y->__left_->__set_parent(__y); + __y->__right_ = __z->__right_; + if (__y->__right_ != nullptr) + __y->__right_->__set_parent(__y); + __y->__is_black_ = __z->__is_black_; + if (__root == __z) + __root = __y; + } + // There is no need to rebalance if we removed a red, or if we removed + // the last node. + if (__removed_black && __root != nullptr) + { + // Rebalance: + // __x has an implicit black color (transferred from the removed __y) + // associated with it, no matter what its color is. + // If __x is __root (in which case it can't be null), it is supposed + // to be black anyway, and if it is doubly black, then the double + // can just be ignored. + // If __x is red (in which case it can't be null), then it can absorb + // the implicit black just by setting its color to black. + // Since __y was black and only had one child (which __x points to), __x + // is either red with no children, else null, otherwise __y would have + // different black heights under left and right pointers. + // if (__x == __root || __x != nullptr && !__x->__is_black_) + if (__x != nullptr) + __x->__is_black_ = true; + else + { + // Else __x isn't root, and is "doubly black", even though it may + // be null. __w can not be null here, else the parent would + // see a black height >= 2 on the __x side and a black height + // of 1 on the __w side (__w must be a non-null black or a red + // with a non-null black child). + while (true) + { + if (!__tree_is_left_child(__w)) // if x is left child + { + if (!__w->__is_black_) + { + __w->__is_black_ = true; + __w->__parent_unsafe()->__is_black_ = false; + __tree_left_rotate(__w->__parent_unsafe()); + // __x is still valid + // reset __root only if necessary + if (__root == __w->__left_) + __root = __w; + // reset sibling, and it still can't be null + __w = __w->__left_->__right_; + } + // __w->__is_black_ is now true, __w may have null children + if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && + (__w->__right_ == nullptr || __w->__right_->__is_black_)) + { + __w->__is_black_ = false; + __x = __w->__parent_unsafe(); + // __x can no longer be null + if (__x == __root || !__x->__is_black_) + { + __x->__is_black_ = true; + break; + } + // reset sibling, and it still can't be null + __w = __tree_is_left_child(__x) ? + __x->__parent_unsafe()->__right_ : + __x->__parent_->__left_; + // continue; + } + else // __w has a red child + { + if (__w->__right_ == nullptr || __w->__right_->__is_black_) + { + // __w left child is non-null and red + __w->__left_->__is_black_ = true; + __w->__is_black_ = false; + __tree_right_rotate(__w); + // __w is known not to be root, so root hasn't changed + // reset sibling, and it still can't be null + __w = __w->__parent_unsafe(); + } + // __w has a right red child, left child may be null + __w->__is_black_ = __w->__parent_unsafe()->__is_black_; + __w->__parent_unsafe()->__is_black_ = true; + __w->__right_->__is_black_ = true; + __tree_left_rotate(__w->__parent_unsafe()); + break; + } + } + else + { + if (!__w->__is_black_) + { + __w->__is_black_ = true; + __w->__parent_unsafe()->__is_black_ = false; + __tree_right_rotate(__w->__parent_unsafe()); + // __x is still valid + // reset __root only if necessary + if (__root == __w->__right_) + __root = __w; + // reset sibling, and it still can't be null + __w = __w->__right_->__left_; + } + // __w->__is_black_ is now true, __w may have null children + if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && + (__w->__right_ == nullptr || __w->__right_->__is_black_)) + { + __w->__is_black_ = false; + __x = __w->__parent_unsafe(); + // __x can no longer be null + if (!__x->__is_black_ || __x == __root) + { + __x->__is_black_ = true; + break; + } + // reset sibling, and it still can't be null + __w = __tree_is_left_child(__x) ? + __x->__parent_unsafe()->__right_ : + __x->__parent_->__left_; + // continue; + } + else // __w has a red child + { + if (__w->__left_ == nullptr || __w->__left_->__is_black_) + { + // __w right child is non-null and red + __w->__right_->__is_black_ = true; + __w->__is_black_ = false; + __tree_left_rotate(__w); + // __w is known not to be root, so root hasn't changed + // reset sibling, and it still can't be null + __w = __w->__parent_unsafe(); + } + // __w has a left red child, right child may be null + __w->__is_black_ = __w->__parent_unsafe()->__is_black_; + __w->__parent_unsafe()->__is_black_ = true; + __w->__left_->__is_black_ = true; + __tree_right_rotate(__w->__parent_unsafe()); + break; + } + } + } + } + } +} + +// node traits + + +#ifndef _LIBCPP_CXX03_LANG +template +struct __is_tree_value_type_imp : false_type {}; + +template +struct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {}; + +template +struct __is_tree_value_type : false_type {}; + +template +struct __is_tree_value_type<_One> : __is_tree_value_type_imp::type> {}; +#endif + +template +struct __tree_key_value_types { + typedef _Tp key_type; + typedef _Tp __node_value_type; + typedef _Tp __container_value_type; + static const bool __is_map = false; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(_Tp const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& __get_value(__node_value_type const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n); + } +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __container_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v); + } +#endif +}; + +template +struct __tree_key_value_types<__value_type<_Key, _Tp> > { + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __value_type<_Key, _Tp> __node_value_type; + typedef pair __container_value_type; + typedef __container_value_type __map_value_type; + static const bool __is_map = true; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& + __get_key(__node_value_type const& __t) { + return __t.__get_value().first; + } + + template + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + key_type const&>::type + __get_key(_Up& __t) { + return __t.first; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& + __get_value(__node_value_type const& __t) { + return __t.__get_value(); + } + + template + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n.__get_value()); + } + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static pair __move(__node_value_type& __v) { + return __v.__move(); + } +#endif +}; + +template +struct __tree_node_base_types { + typedef _VoidPtr __void_pointer; + + typedef __tree_node_base<__void_pointer> __node_base_type; + typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type + __node_base_pointer; + + typedef __tree_end_node<__node_base_pointer> __end_node_type; + typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type + __end_node_pointer; +#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) + typedef __end_node_pointer __parent_pointer; +#else + typedef typename conditional< + is_pointer<__end_node_pointer>::value, + __end_node_pointer, + __node_base_pointer>::type __parent_pointer; +#endif + +private: + static_assert((is_same::element_type, void>::value), + "_VoidPtr does not point to unqualified void type"); +}; + +template , + bool = _KVTypes::__is_map> +struct __tree_map_pointer_types {}; + +template +struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { + typedef typename _KVTypes::__map_value_type _Mv; + typedef typename __rebind_pointer<_AllocPtr, _Mv>::type + __map_value_type_pointer; + typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type + __const_map_value_type_pointer; +}; + +template ::element_type> +struct __tree_node_types; + +template +struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> > + : public __tree_node_base_types<_VoidPtr>, + __tree_key_value_types<_Tp>, + __tree_map_pointer_types<_Tp, _VoidPtr> +{ + typedef __tree_node_base_types<_VoidPtr> __base; + typedef __tree_key_value_types<_Tp> __key_base; + typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base; +public: + + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_pointer; + + typedef _Tp __node_value_type; + typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type + __node_value_type_pointer; + typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type + __const_node_value_type_pointer; +#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) + typedef typename __base::__end_node_pointer __iter_pointer; +#else + typedef typename conditional< + is_pointer<__node_pointer>::value, + typename __base::__end_node_pointer, + __node_pointer>::type __iter_pointer; +#endif +private: + static_assert(!is_const<__node_type>::value, + "_NodePtr should never be a pointer to const"); + static_assert((is_same::type, + _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); +}; + +template +struct __make_tree_node_types { + typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type + _NodePtr; + typedef __tree_node_types<_NodePtr> type; +}; + +// node + +template +class __tree_end_node +{ +public: + typedef _Pointer pointer; + pointer __left_; + + _LIBCPP_INLINE_VISIBILITY + __tree_end_node() _NOEXCEPT : __left_() {} +}; + +template +class __tree_node_base + : public __tree_node_base_types<_VoidPtr>::__end_node_type +{ + typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes; + +public: + typedef typename _NodeBaseTypes::__node_base_pointer pointer; + typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer; + + pointer __right_; + __parent_pointer __parent_; + bool __is_black_; + + _LIBCPP_INLINE_VISIBILITY + pointer __parent_unsafe() const { return static_cast(__parent_);} + + _LIBCPP_INLINE_VISIBILITY + void __set_parent(pointer __p) { + __parent_ = static_cast<__parent_pointer>(__p); + } + +private: + ~__tree_node_base() _LIBCPP_EQUAL_DELETE; + __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; + __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; +}; + +template +class __tree_node + : public __tree_node_base<_VoidPtr> +{ +public: + typedef _Tp __node_value_type; + + __node_value_type __value_; + +private: + ~__tree_node() _LIBCPP_EQUAL_DELETE; + __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE; + __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE; +}; + + +template +class __tree_node_destructor +{ + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + +public: + typedef typename __alloc_traits::pointer pointer; +private: + typedef __tree_node_types _NodeTypes; + allocator_type& __na_; + + __tree_node_destructor& operator=(const __tree_node_destructor&); + +public: + bool __value_constructed; + + _LIBCPP_INLINE_VISIBILITY + explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__val) + {} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + if (__value_constructed) + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } + + template friend class __map_node_destructor; +}; + +#if _LIBCPP_STD_VER > 14 +template +struct __generic_container_node_destructor; +template +struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc> + : __tree_node_destructor<_Alloc> +{ + using __tree_node_destructor<_Alloc>::__tree_node_destructor; +}; +#endif + +template +class _LIBCPP_TEMPLATE_VIS __tree_iterator +{ + typedef __tree_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; + typedef pointer_traits<__node_pointer> __pointer_traits; + + __iter_pointer __ptr_; + +public: + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _DiffType difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; + + _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __ptr_(nullptr) +#endif + {} + + _LIBCPP_INLINE_VISIBILITY reference operator*() const + {return __get_np()->__value_;} + _LIBCPP_INLINE_VISIBILITY pointer operator->() const + {return pointer_traits::pointer_to(__get_np()->__value_);} + + _LIBCPP_INLINE_VISIBILITY + __tree_iterator& operator++() { + __ptr_ = static_cast<__iter_pointer>( + __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __tree_iterator operator++(int) + {__tree_iterator __t(*this); ++(*this); return __t;} + + _LIBCPP_INLINE_VISIBILITY + __tree_iterator& operator--() { + __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( + static_cast<__end_node_pointer>(__ptr_))); + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __tree_iterator operator--(int) + {__tree_iterator __t(*this); --(*this); return __t;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y) + {return !(__x == __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } + template friend class __tree; + template friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator; + template friend class _LIBCPP_TEMPLATE_VIS __map_iterator; + template friend class _LIBCPP_TEMPLATE_VIS map; + template friend class _LIBCPP_TEMPLATE_VIS multimap; + template friend class _LIBCPP_TEMPLATE_VIS set; + template friend class _LIBCPP_TEMPLATE_VIS multiset; +}; + +template +class _LIBCPP_TEMPLATE_VIS __tree_const_iterator +{ + typedef __tree_node_types<_NodePtr> _NodeTypes; + typedef typename _NodeTypes::__node_pointer __node_pointer; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; + typedef pointer_traits<__node_pointer> __pointer_traits; + + __iter_pointer __ptr_; + +public: + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _DiffType difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + + _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __ptr_(nullptr) +#endif + {} + +private: + typedef __tree_iterator + __non_const_iterator; +public: + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT + : __ptr_(__p.__ptr_) {} + + _LIBCPP_INLINE_VISIBILITY reference operator*() const + {return __get_np()->__value_;} + _LIBCPP_INLINE_VISIBILITY pointer operator->() const + {return pointer_traits::pointer_to(__get_np()->__value_);} + + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator& operator++() { + __ptr_ = static_cast<__iter_pointer>( + __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator operator++(int) + {__tree_const_iterator __t(*this); ++(*this); return __t;} + + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator& operator--() { + __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( + static_cast<__end_node_pointer>(__ptr_))); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator operator--(int) + {__tree_const_iterator __t(*this); --(*this); return __t;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) + {return !(__x == __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT + : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT + : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } + + template friend class __tree; + template friend class _LIBCPP_TEMPLATE_VIS map; + template friend class _LIBCPP_TEMPLATE_VIS multimap; + template friend class _LIBCPP_TEMPLATE_VIS set; + template friend class _LIBCPP_TEMPLATE_VIS multiset; + template friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator; + +}; + +template +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value, + "the specified comparator type does not provide a viable const call operator") +#endif +int __diagnose_non_const_comparator(); + +template +class __tree +{ +public: + typedef _Tp value_type; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + +private: + typedef allocator_traits __alloc_traits; + typedef typename __make_tree_node_types::type + _NodeTypes; + typedef typename _NodeTypes::key_type key_type; +public: + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + +public: + typedef typename _NodeTypes::__void_pointer __void_pointer; + + typedef typename _NodeTypes::__node_type __node; + typedef typename _NodeTypes::__node_pointer __node_pointer; + + typedef typename _NodeTypes::__node_base_type __node_base; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + + typedef typename _NodeTypes::__end_node_type __end_node_t; + typedef typename _NodeTypes::__end_node_pointer __end_node_ptr; + + typedef typename _NodeTypes::__parent_pointer __parent_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; + + typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + +private: + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type + __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + +private: + __iter_pointer __begin_node_; + __compressed_pair<__end_node_t, __node_allocator> __pair1_; + __compressed_pair __pair3_; + +public: + _LIBCPP_INLINE_VISIBILITY + __iter_pointer __end_node() _NOEXCEPT + { + return static_cast<__iter_pointer>( + pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) + ); + } + _LIBCPP_INLINE_VISIBILITY + __iter_pointer __end_node() const _NOEXCEPT + { + return static_cast<__iter_pointer>( + pointer_traits<__end_node_ptr>::pointer_to( + const_cast<__end_node_t&>(__pair1_.first()) + ) + ); + } + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();} +private: + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __node_alloc() const _NOEXCEPT + {return __pair1_.second();} + _LIBCPP_INLINE_VISIBILITY + __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} + _LIBCPP_INLINE_VISIBILITY + const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} +public: + _LIBCPP_INLINE_VISIBILITY + allocator_type __alloc() const _NOEXCEPT + {return allocator_type(__node_alloc());} +private: + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __pair3_.first();} +public: + _LIBCPP_INLINE_VISIBILITY + const size_type& size() const _NOEXCEPT {return __pair3_.first();} + _LIBCPP_INLINE_VISIBILITY + value_compare& value_comp() _NOEXCEPT {return __pair3_.second();} + _LIBCPP_INLINE_VISIBILITY + const value_compare& value_comp() const _NOEXCEPT + {return __pair3_.second();} +public: + + _LIBCPP_INLINE_VISIBILITY + __node_pointer __root() const _NOEXCEPT + {return static_cast<__node_pointer>(__end_node()->__left_);} + + __node_base_pointer* __root_ptr() const _NOEXCEPT { + return _VSTD::addressof(__end_node()->__left_); + } + + typedef __tree_iterator iterator; + typedef __tree_const_iterator const_iterator; + + explicit __tree(const value_compare& __comp) + _NOEXCEPT_( + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_copy_constructible::value); + explicit __tree(const allocator_type& __a); + __tree(const value_compare& __comp, const allocator_type& __a); + __tree(const __tree& __t); + __tree& operator=(const __tree& __t); + template + void __assign_unique(_ForwardIterator __first, _ForwardIterator __last); + template + void __assign_multi(_InputIterator __first, _InputIterator __last); +#ifndef _LIBCPP_CXX03_LANG + __tree(__tree&& __t) + _NOEXCEPT_( + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value); + __tree(__tree&& __t, const allocator_type& __a); + __tree& operator=(__tree&& __t) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable<__node_allocator>::value); +#endif // _LIBCPP_CXX03_LANG + + ~__tree(); + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT {return iterator(__begin_node());} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT {return iterator(__end_node());} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());} + + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT + {return std::min( + __node_traits::max_size(__node_alloc()), + numeric_limits::max());} + + void clear() _NOEXCEPT; + + void swap(__tree& __t) +#if _LIBCPP_STD_VER <= 11 + _NOEXCEPT_( + __is_nothrow_swappable::value + && (!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) + ); +#else + _NOEXCEPT_(__is_nothrow_swappable::value); +#endif + +#ifndef _LIBCPP_CXX03_LANG + template + pair + __emplace_unique_key_args(_Key const&, _Args&&... __args); + template + iterator + __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); + + template + pair __emplace_unique_impl(_Args&&... __args); + + template + iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); + + template + iterator __emplace_multi(_Args&&... __args); + + template + iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, + pair + >::type __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) { + return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, + iterator + >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) { + return __emplace_hint_unique_key_args(__p, __f, + _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { + return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { + return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)); + } + +#else + template + _LIBCPP_INLINE_VISIBILITY + pair __emplace_unique_key_args(_Key const&, _Args& __args); + template + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&); +#endif + + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique(const __container_value_type& __v) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, const __container_value_type& __v) { + return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v); + } + +#ifdef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const __container_value_type& __v); + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, const __container_value_type& __v); +#else + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique(__container_value_type&& __v) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, __container_value_type&& __v) { + return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)); + } + + template ::type, + __container_value_type + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique(_Vp&& __v) { + return __emplace_unique(_VSTD::forward<_Vp>(__v)); + } + + template ::type, + __container_value_type + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, _Vp&& __v) { + return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(__container_value_type&& __v) { + return __emplace_multi(_VSTD::move(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, __container_value_type&& __v) { + return __emplace_hint_multi(__p, _VSTD::move(__v)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(_Vp&& __v) { + return __emplace_multi(_VSTD::forward<_Vp>(__v)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, _Vp&& __v) { + return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v)); + } + +#endif // !_LIBCPP_CXX03_LANG + + _LIBCPP_INLINE_VISIBILITY + pair __node_assign_unique(const __container_value_type& __v, __node_pointer __dest); + + _LIBCPP_INLINE_VISIBILITY + iterator __node_insert_multi(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY + iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); + + + _LIBCPP_INLINE_VISIBILITY iterator + __remove_node_pointer(__node_pointer) _NOEXCEPT; + +#if _LIBCPP_STD_VER > 14 + template + _LIBCPP_INLINE_VISIBILITY + _InsertReturnType __node_handle_insert_unique(_NodeHandle&&); + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&); + template + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_unique(_Tree& __source); + + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(_NodeHandle&&); + template + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&); + template + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_multi(_Tree& __source); + + + template + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(key_type const&); + template + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(const_iterator); +#endif + + iterator erase(const_iterator __p); + iterator erase(const_iterator __f, const_iterator __l); + template + size_type __erase_unique(const _Key& __k); + template + size_type __erase_multi(const _Key& __k); + + void __insert_node_at(__parent_pointer __parent, + __node_base_pointer& __child, + __node_base_pointer __new_node) _NOEXCEPT; + + template + iterator find(const _Key& __v); + template + const_iterator find(const _Key& __v) const; + + template + size_type __count_unique(const _Key& __k) const; + template + size_type __count_multi(const _Key& __k) const; + + template + _LIBCPP_INLINE_VISIBILITY + iterator lower_bound(const _Key& __v) + {return __lower_bound(__v, __root(), __end_node());} + template + iterator __lower_bound(const _Key& __v, + __node_pointer __root, + __iter_pointer __result); + template + _LIBCPP_INLINE_VISIBILITY + const_iterator lower_bound(const _Key& __v) const + {return __lower_bound(__v, __root(), __end_node());} + template + const_iterator __lower_bound(const _Key& __v, + __node_pointer __root, + __iter_pointer __result) const; + template + _LIBCPP_INLINE_VISIBILITY + iterator upper_bound(const _Key& __v) + {return __upper_bound(__v, __root(), __end_node());} + template + iterator __upper_bound(const _Key& __v, + __node_pointer __root, + __iter_pointer __result); + template + _LIBCPP_INLINE_VISIBILITY + const_iterator upper_bound(const _Key& __v) const + {return __upper_bound(__v, __root(), __end_node());} + template + const_iterator __upper_bound(const _Key& __v, + __node_pointer __root, + __iter_pointer __result) const; + template + pair + __equal_range_unique(const _Key& __k); + template + pair + __equal_range_unique(const _Key& __k) const; + + template + pair + __equal_range_multi(const _Key& __k); + template + pair + __equal_range_multi(const _Key& __k) const; + + typedef __tree_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + + __node_holder remove(const_iterator __p) _NOEXCEPT; +private: + __node_base_pointer& + __find_leaf_low(__parent_pointer& __parent, const key_type& __v); + __node_base_pointer& + __find_leaf_high(__parent_pointer& __parent, const key_type& __v); + __node_base_pointer& + __find_leaf(const_iterator __hint, + __parent_pointer& __parent, const key_type& __v); + // FIXME: Make this function const qualified. Unfortunetly doing so + // breaks existing code which uses non-const callable comparators. + template + __node_base_pointer& + __find_equal(__parent_pointer& __parent, const _Key& __v); + template + _LIBCPP_INLINE_VISIBILITY __node_base_pointer& + __find_equal(__parent_pointer& __parent, const _Key& __v) const { + return const_cast<__tree*>(this)->__find_equal(__parent, __v); + } + template + __node_base_pointer& + __find_equal(const_iterator __hint, __parent_pointer& __parent, + __node_base_pointer& __dummy, + const _Key& __v); + +#ifndef _LIBCPP_CXX03_LANG + template + __node_holder __construct_node(_Args&& ...__args); +#else + __node_holder __construct_node(const __container_value_type& __v); +#endif + + void destroy(__node_pointer __nd) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __tree& __t) + {__copy_assign_alloc(__t, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __tree& __t, true_type) + { + if (__node_alloc() != __t.__node_alloc()) + clear(); + __node_alloc() = __t.__node_alloc(); + } + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __tree&, false_type) {} + + void __move_assign(__tree& __t, false_type); + void __move_assign(__tree& __t, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value && + is_nothrow_move_assignable<__node_allocator>::value); + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__tree& __t) + _NOEXCEPT_( + !__node_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable<__node_allocator>::value) + {__move_assign_alloc(__t, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__tree& __t, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) + {__node_alloc() = _VSTD::move(__t.__node_alloc());} + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {} + + struct _DetachedTreeCache { + _LIBCPP_INLINE_VISIBILITY + explicit _DetachedTreeCache(__tree *__t) _NOEXCEPT : __t_(__t), + __cache_root_(__detach_from_tree(__t)) { + __advance(); + } + + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get() const _NOEXCEPT { + return __cache_elem_; + } + + _LIBCPP_INLINE_VISIBILITY + void __advance() _NOEXCEPT { + __cache_elem_ = __cache_root_; + if (__cache_root_) { + __cache_root_ = __detach_next(__cache_root_); + } + } + + _LIBCPP_INLINE_VISIBILITY + ~_DetachedTreeCache() { + __t_->destroy(__cache_elem_); + if (__cache_root_) { + while (__cache_root_->__parent_ != nullptr) + __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_); + __t_->destroy(__cache_root_); + } + } + + _DetachedTreeCache(_DetachedTreeCache const&) = delete; + _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete; + + private: + _LIBCPP_INLINE_VISIBILITY + static __node_pointer __detach_from_tree(__tree *__t) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static __node_pointer __detach_next(__node_pointer) _NOEXCEPT; + + __tree *__t_; + __node_pointer __cache_root_; + __node_pointer __cache_elem_; + }; + + + template friend class _LIBCPP_TEMPLATE_VIS map; + template friend class _LIBCPP_TEMPLATE_VIS multimap; +}; + +template +__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) + _NOEXCEPT_( + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_copy_constructible::value) + : __pair3_(0, __comp) +{ + __begin_node() = __end_node(); +} + +template +__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) + : __begin_node_(__iter_pointer()), + __pair1_(__second_tag(), __node_allocator(__a)), + __pair3_(0) +{ + __begin_node() = __end_node(); +} + +template +__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, + const allocator_type& __a) + : __begin_node_(__iter_pointer()), + __pair1_(__second_tag(), __node_allocator(__a)), + __pair3_(0, __comp) +{ + __begin_node() = __end_node(); +} + +// Precondition: size() != 0 +template +typename __tree<_Tp, _Compare, _Allocator>::__node_pointer +__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree *__t) _NOEXCEPT +{ + __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node()); + __t->__begin_node() = __t->__end_node(); + __t->__end_node()->__left_->__parent_ = nullptr; + __t->__end_node()->__left_ = nullptr; + __t->size() = 0; + // __cache->__left_ == nullptr + if (__cache->__right_ != nullptr) + __cache = static_cast<__node_pointer>(__cache->__right_); + // __cache->__left_ == nullptr + // __cache->__right_ == nullptr + return __cache; +} + +// Precondition: __cache != nullptr +// __cache->left_ == nullptr +// __cache->right_ == nullptr +// This is no longer a red-black tree +template +typename __tree<_Tp, _Compare, _Allocator>::__node_pointer +__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT +{ + if (__cache->__parent_ == nullptr) + return nullptr; + if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) + { + __cache->__parent_->__left_ = nullptr; + __cache = static_cast<__node_pointer>(__cache->__parent_); + if (__cache->__right_ == nullptr) + return __cache; + return static_cast<__node_pointer>(__tree_leaf(__cache->__right_)); + } + // __cache is right child + __cache->__parent_unsafe()->__right_ = nullptr; + __cache = static_cast<__node_pointer>(__cache->__parent_); + if (__cache->__left_ == nullptr) + return __cache; + return static_cast<__node_pointer>(__tree_leaf(__cache->__left_)); +} + +template +__tree<_Tp, _Compare, _Allocator>& +__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) +{ + if (this != &__t) + { + value_comp() = __t.value_comp(); + __copy_assign_alloc(__t); + __assign_multi(__t.begin(), __t.end()); + } + return *this; +} + +template +template +void +__tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last) +{ + typedef iterator_traits<_ForwardIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value), + "__assign_unique may only be called with the containers value type"); + static_assert(__is_forward_iterator<_ForwardIterator>::value, + "__assign_unique requires a forward iterator"); + if (size() != 0) + { + _DetachedTreeCache __cache(this); + for (; __cache.__get() != nullptr && __first != __last; ++__first) { + if (__node_assign_unique(*__first, __cache.__get()).second) + __cache.__advance(); + } + } + for (; __first != __last; ++__first) + __insert_unique(*__first); +} + +template +template +void +__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) +{ + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value || + is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); + if (size() != 0) + { + _DetachedTreeCache __cache(this); + for (; __cache.__get() && __first != __last; ++__first) { + __cache.__get()->__value_ = *__first; + __node_insert_multi(__cache.__get()); + __cache.__advance(); + } + } + for (; __first != __last; ++__first) + __insert_multi(_NodeTypes::__get_value(*__first)); +} + +template +__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) + : __begin_node_(__iter_pointer()), + __pair1_(__second_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())), + __pair3_(0, __t.value_comp()) +{ + __begin_node() = __end_node(); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) + _NOEXCEPT_( + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value) + : __begin_node_(_VSTD::move(__t.__begin_node_)), + __pair1_(_VSTD::move(__t.__pair1_)), + __pair3_(_VSTD::move(__t.__pair3_)) +{ + if (size() == 0) + __begin_node() = __end_node(); + else + { + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); + __t.__begin_node() = __t.__end_node(); + __t.__end_node()->__left_ = nullptr; + __t.size() = 0; + } +} + +template +__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a) + : __pair1_(__second_tag(), __node_allocator(__a)), + __pair3_(0, _VSTD::move(__t.value_comp())) +{ + if (__a == __t.__alloc()) + { + if (__t.size() == 0) + __begin_node() = __end_node(); + else + { + __begin_node() = __t.__begin_node(); + __end_node()->__left_ = __t.__end_node()->__left_; + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); + size() = __t.size(); + __t.__begin_node() = __t.__end_node(); + __t.__end_node()->__left_ = nullptr; + __t.size() = 0; + } + } + else + { + __begin_node() = __end_node(); + } +} + +template +void +__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value && + is_nothrow_move_assignable<__node_allocator>::value) +{ + destroy(static_cast<__node_pointer>(__end_node()->__left_)); + __begin_node_ = __t.__begin_node_; + __pair1_.first() = __t.__pair1_.first(); + __move_assign_alloc(__t); + __pair3_ = _VSTD::move(__t.__pair3_); + if (size() == 0) + __begin_node() = __end_node(); + else + { + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); + __t.__begin_node() = __t.__end_node(); + __t.__end_node()->__left_ = nullptr; + __t.size() = 0; + } +} + +template +void +__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) +{ + if (__node_alloc() == __t.__node_alloc()) + __move_assign(__t, true_type()); + else + { + value_comp() = _VSTD::move(__t.value_comp()); + const_iterator __e = end(); + if (size() != 0) + { + _DetachedTreeCache __cache(this); + while (__cache.__get() != nullptr && __t.size() != 0) { + __cache.__get()->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_); + __node_insert_multi(__cache.__get()); + __cache.__advance(); + } + } + while (__t.size() != 0) + __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_)); + } +} + +template +__tree<_Tp, _Compare, _Allocator>& +__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable<__node_allocator>::value) + +{ + __move_assign(__t, integral_constant()); + return *this; +} + +#endif // _LIBCPP_CXX03_LANG + +template +__tree<_Tp, _Compare, _Allocator>::~__tree() +{ + static_assert((is_copy_constructible::value), + "Comparator must be copy-constructible."); + destroy(__root()); +} + +template +void +__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT +{ + if (__nd != nullptr) + { + destroy(static_cast<__node_pointer>(__nd->__left_)); + destroy(static_cast<__node_pointer>(__nd->__right_)); + __node_allocator& __na = __node_alloc(); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_)); + __node_traits::deallocate(__na, __nd, 1); + } +} + +template +void +__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) +#if _LIBCPP_STD_VER <= 11 + _NOEXCEPT_( + __is_nothrow_swappable::value + && (!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) + ) +#else + _NOEXCEPT_(__is_nothrow_swappable::value) +#endif +{ + using _VSTD::swap; + swap(__begin_node_, __t.__begin_node_); + swap(__pair1_.first(), __t.__pair1_.first()); + __swap_allocator(__node_alloc(), __t.__node_alloc()); + __pair3_.swap(__t.__pair3_); + if (size() == 0) + __begin_node() = __end_node(); + else + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); + if (__t.size() == 0) + __t.__begin_node() = __t.__end_node(); + else + __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node()); +} + +template +void +__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT +{ + destroy(__root()); + size() = 0; + __begin_node() = __end_node(); + __end_node()->__left_ = nullptr; +} + +// Find lower_bound place to insert +// Set __parent to parent of null leaf +// Return reference to null leaf +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent, + const key_type& __v) +{ + __node_pointer __nd = __root(); + if (__nd != nullptr) + { + while (true) + { + if (value_comp()(__nd->__value_, __v)) + { + if (__nd->__right_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__right_); + else + { + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; + } + } + else + { + if (__nd->__left_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__left_); + else + { + __parent = static_cast<__parent_pointer>(__nd); + return __parent->__left_; + } + } + } + } + __parent = static_cast<__parent_pointer>(__end_node()); + return __parent->__left_; +} + +// Find upper_bound place to insert +// Set __parent to parent of null leaf +// Return reference to null leaf +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent, + const key_type& __v) +{ + __node_pointer __nd = __root(); + if (__nd != nullptr) + { + while (true) + { + if (value_comp()(__v, __nd->__value_)) + { + if (__nd->__left_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__left_); + else + { + __parent = static_cast<__parent_pointer>(__nd); + return __parent->__left_; + } + } + else + { + if (__nd->__right_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__right_); + else + { + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; + } + } + } + } + __parent = static_cast<__parent_pointer>(__end_node()); + return __parent->__left_; +} + +// Find leaf place to insert closest to __hint +// First check prior to __hint. +// Next check after __hint. +// Next do O(log N) search. +// Set __parent to parent of null leaf +// Return reference to null leaf +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, + __parent_pointer& __parent, + const key_type& __v) +{ + if (__hint == end() || !value_comp()(*__hint, __v)) // check before + { + // __v <= *__hint + const_iterator __prior = __hint; + if (__prior == begin() || !value_comp()(__v, *--__prior)) + { + // *prev(__hint) <= __v <= *__hint + if (__hint.__ptr_->__left_ == nullptr) + { + __parent = static_cast<__parent_pointer>(__hint.__ptr_); + return __parent->__left_; + } + else + { + __parent = static_cast<__parent_pointer>(__prior.__ptr_); + return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; + } + } + // __v < *prev(__hint) + return __find_leaf_high(__parent, __v); + } + // else __v > *__hint + return __find_leaf_low(__parent, __v); +} + +// Find place to insert if __v doesn't exist +// Set __parent to parent of null leaf +// Return reference to null leaf +// If __v exists, set parent to node of __v and return reference to node of __v +template +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent, + const _Key& __v) +{ + __node_pointer __nd = __root(); + __node_base_pointer* __nd_ptr = __root_ptr(); + if (__nd != nullptr) + { + while (true) + { + if (value_comp()(__v, __nd->__value_)) + { + if (__nd->__left_ != nullptr) { + __nd_ptr = _VSTD::addressof(__nd->__left_); + __nd = static_cast<__node_pointer>(__nd->__left_); + } else { + __parent = static_cast<__parent_pointer>(__nd); + return __parent->__left_; + } + } + else if (value_comp()(__nd->__value_, __v)) + { + if (__nd->__right_ != nullptr) { + __nd_ptr = _VSTD::addressof(__nd->__right_); + __nd = static_cast<__node_pointer>(__nd->__right_); + } else { + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; + } + } + else + { + __parent = static_cast<__parent_pointer>(__nd); + return *__nd_ptr; + } + } + } + __parent = static_cast<__parent_pointer>(__end_node()); + return __parent->__left_; +} + +// Find place to insert if __v doesn't exist +// First check prior to __hint. +// Next check after __hint. +// Next do O(log N) search. +// Set __parent to parent of null leaf +// Return reference to null leaf +// If __v exists, set parent to node of __v and return reference to node of __v +template +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, + __parent_pointer& __parent, + __node_base_pointer& __dummy, + const _Key& __v) +{ + if (__hint == end() || value_comp()(__v, *__hint)) // check before + { + // __v < *__hint + const_iterator __prior = __hint; + if (__prior == begin() || value_comp()(*--__prior, __v)) + { + // *prev(__hint) < __v < *__hint + if (__hint.__ptr_->__left_ == nullptr) + { + __parent = static_cast<__parent_pointer>(__hint.__ptr_); + return __parent->__left_; + } + else + { + __parent = static_cast<__parent_pointer>(__prior.__ptr_); + return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; + } + } + // __v <= *prev(__hint) + return __find_equal(__parent, __v); + } + else if (value_comp()(*__hint, __v)) // check after + { + // *__hint < __v + const_iterator __next = _VSTD::next(__hint); + if (__next == end() || value_comp()(__v, *__next)) + { + // *__hint < __v < *_VSTD::next(__hint) + if (__hint.__get_np()->__right_ == nullptr) + { + __parent = static_cast<__parent_pointer>(__hint.__ptr_); + return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_; + } + else + { + __parent = static_cast<__parent_pointer>(__next.__ptr_); + return __parent->__left_; + } + } + // *next(__hint) <= __v + return __find_equal(__parent, __v); + } + // else __v == *__hint + __parent = static_cast<__parent_pointer>(__hint.__ptr_); + __dummy = static_cast<__node_base_pointer>(__hint.__ptr_); + return __dummy; +} + +template +void __tree<_Tp, _Compare, _Allocator>::__insert_node_at( + __parent_pointer __parent, __node_base_pointer& __child, + __node_base_pointer __new_node) _NOEXCEPT +{ + __new_node->__left_ = nullptr; + __new_node->__right_ = nullptr; + __new_node->__parent_ = __parent; + // __new_node->__is_black_ is initialized in __tree_balance_after_insert + __child = __new_node; + if (__begin_node()->__left_ != nullptr) + __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_); + __tree_balance_after_insert(__end_node()->__left_, __child); + ++size(); +} + +#ifndef _LIBCPP_CXX03_LANG +template +template +pair::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) +#else +template +template +pair::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args) +#endif +{ + __parent_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, __k); + __node_pointer __r = static_cast<__node_pointer>(__child); + bool __inserted = false; + if (__child == nullptr) + { +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node(__args); +#endif + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + __inserted = true; + } + return pair(iterator(__r), __inserted); +} + + +#ifndef _LIBCPP_CXX03_LANG +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( + const_iterator __p, _Key const& __k, _Args&&... __args) +#else +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( + const_iterator __p, _Key const& __k, _Args& __args) +#endif +{ + __parent_pointer __parent; + __node_base_pointer __dummy; + __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node(__args); +#endif + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + } + return iterator(__r); +} + + +#ifndef _LIBCPP_CXX03_LANG + +template +template +typename __tree<_Tp, _Compare, _Allocator>::__node_holder +__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args) +{ + static_assert(!__is_tree_value_type<_Args...>::value, + "Cannot construct from __value_type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); + __h.get_deleter().__value_constructed = true; + return __h; +} + + +template +template +pair::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + __parent_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, __h->__value_); + __node_pointer __r = static_cast<__node_pointer>(__child); + bool __inserted = false; + if (__child == nullptr) + { + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + __inserted = true; + } + return pair(iterator(__r), __inserted); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + __parent_pointer __parent; + __node_base_pointer __dummy; + __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + } + return iterator(__r); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_)); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(static_cast<__node_pointer>(__h.release())); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, + _Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_)); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(static_cast<__node_pointer>(__h.release())); +} + + +#else // _LIBCPP_CXX03_LANG + +template +typename __tree<_Tp, _Compare, _Allocator>::__node_holder +__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); + __h.get_deleter().__value_constructed = true; + return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 +} + +#endif // _LIBCPP_CXX03_LANG + +#ifdef _LIBCPP_CXX03_LANG +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v) +{ + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v)); + __node_holder __h = __construct_node(__v); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(__h.release()); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v) +{ + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v)); + __node_holder __h = __construct_node(__v); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(__h.release()); +} +#endif + +template +pair::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_type& __v, __node_pointer __nd) +{ + __parent_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, _NodeTypes::__get_key(__v)); + __node_pointer __r = static_cast<__node_pointer>(__child); + bool __inserted = false; + if (__child == nullptr) + { + __nd->__value_ = __v; + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); + __r = __nd; + __inserted = true; + } + return pair(iterator(__r), __inserted); +} + + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) +{ + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_)); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); + return iterator(__nd); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, + __node_pointer __nd) +{ + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_)); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); + return iterator(__nd); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT +{ + iterator __r(__ptr); + ++__r; + if (__begin_node() == __ptr) + __begin_node() = __r.__ptr_; + --size(); + __tree_remove(__end_node()->__left_, + static_cast<__node_base_pointer>(__ptr)); + return __r; +} + +#if _LIBCPP_STD_VER > 14 +template +template +_LIBCPP_INLINE_VISIBILITY +_InsertReturnType +__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique( + _NodeHandle&& __nh) +{ + if (__nh.empty()) + return _InsertReturnType{end(), false, _NodeHandle()}; + + __node_pointer __ptr = __nh.__ptr_; + __parent_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, + __ptr->__value_); + if (__child != nullptr) + return _InsertReturnType{ + iterator(static_cast<__node_pointer>(__child)), + false, _VSTD::move(__nh)}; + + __insert_node_at(__parent, __child, + static_cast<__node_base_pointer>(__ptr)); + __nh.__release_ptr(); + return _InsertReturnType{iterator(__ptr), true, _NodeHandle()}; +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique( + const_iterator __hint, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + + __node_pointer __ptr = __nh.__ptr_; + __parent_pointer __parent; + __node_base_pointer __dummy; + __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, + __ptr->__value_); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { + __insert_node_at(__parent, __child, + static_cast<__node_base_pointer>(__ptr)); + __r = __ptr; + __nh.__release_ptr(); + } + return iterator(__r); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) +{ + iterator __it = find(__key); + if (__it == end()) + return _NodeHandle(); + return __node_handle_extract<_NodeHandle>(__it); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) +{ + __node_pointer __np = __p.__get_np(); + __remove_node_pointer(__np); + return _NodeHandle(__np, __alloc()); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +void +__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source) +{ + static_assert(is_same::value, ""); + + for (typename _Tree::iterator __i = __source.begin(); + __i != __source.end();) + { + __node_pointer __src_ptr = __i.__get_np(); + __parent_pointer __parent; + __node_base_pointer& __child = + __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_)); + ++__i; + if (__child != nullptr) + continue; + __source.__remove_node_pointer(__src_ptr); + __insert_node_at(__parent, __child, + static_cast<__node_base_pointer>(__src_ptr)); + } +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + __node_pointer __ptr = __nh.__ptr_; + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high( + __parent, _NodeTypes::__get_key(__ptr->__value_)); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); + __nh.__release_ptr(); + return iterator(__ptr); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi( + const_iterator __hint, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + + __node_pointer __ptr = __nh.__ptr_; + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__hint, __parent, + _NodeTypes::__get_key(__ptr->__value_)); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); + __nh.__release_ptr(); + return iterator(__ptr); +} + +template +template +_LIBCPP_INLINE_VISIBILITY +void +__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) +{ + static_assert(is_same::value, ""); + + for (typename _Tree::iterator __i = __source.begin(); + __i != __source.end();) + { + __node_pointer __src_ptr = __i.__get_np(); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high( + __parent, _NodeTypes::__get_key(__src_ptr->__value_)); + ++__i; + __source.__remove_node_pointer(__src_ptr); + __insert_node_at(__parent, __child, + static_cast<__node_base_pointer>(__src_ptr)); + } +} + +#endif // _LIBCPP_STD_VER > 14 + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) +{ + __node_pointer __np = __p.__get_np(); + iterator __r = __remove_node_pointer(__np); + __node_allocator& __na = __node_alloc(); + __node_traits::destroy(__na, _NodeTypes::__get_ptr( + const_cast<__node_value_type&>(*__p))); + __node_traits::deallocate(__na, __np, 1); + return __r; +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l) +{ + while (__f != __l) + __f = erase(__f); + return iterator(__l.__ptr_); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::size_type +__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) +{ + iterator __i = find(__k); + if (__i == end()) + return 0; + erase(__i); + return 1; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::size_type +__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) +{ + pair __p = __equal_range_multi(__k); + size_type __r = 0; + for (; __p.first != __p.second; ++__r) + __p.first = erase(__p.first); + return __r; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) +{ + iterator __p = __lower_bound(__v, __root(), __end_node()); + if (__p != end() && !value_comp()(__v, *__p)) + return __p; + return end(); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::const_iterator +__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const +{ + const_iterator __p = __lower_bound(__v, __root(), __end_node()); + if (__p != end() && !value_comp()(__v, *__p)) + return __p; + return end(); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::size_type +__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const +{ + __node_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __rt = static_cast<__node_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_pointer>(__rt->__right_); + else + return 1; + } + return 0; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::size_type +__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const +{ + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_pointer>(__rt->__right_); + else + return _VSTD::distance( + __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), + __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result) + ); + } + return 0; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, + __node_pointer __root, + __iter_pointer __result) +{ + while (__root != nullptr) + { + if (!value_comp()(__root->__value_, __v)) + { + __result = static_cast<__iter_pointer>(__root); + __root = static_cast<__node_pointer>(__root->__left_); + } + else + __root = static_cast<__node_pointer>(__root->__right_); + } + return iterator(__result); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::const_iterator +__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, + __node_pointer __root, + __iter_pointer __result) const +{ + while (__root != nullptr) + { + if (!value_comp()(__root->__value_, __v)) + { + __result = static_cast<__iter_pointer>(__root); + __root = static_cast<__node_pointer>(__root->__left_); + } + else + __root = static_cast<__node_pointer>(__root->__right_); + } + return const_iterator(__result); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, + __node_pointer __root, + __iter_pointer __result) +{ + while (__root != nullptr) + { + if (value_comp()(__v, __root->__value_)) + { + __result = static_cast<__iter_pointer>(__root); + __root = static_cast<__node_pointer>(__root->__left_); + } + else + __root = static_cast<__node_pointer>(__root->__right_); + } + return iterator(__result); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::const_iterator +__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, + __node_pointer __root, + __iter_pointer __result) const +{ + while (__root != nullptr) + { + if (value_comp()(__v, __root->__value_)) + { + __result = static_cast<__iter_pointer>(__root); + __root = static_cast<__node_pointer>(__root->__left_); + } + else + __root = static_cast<__node_pointer>(__root->__right_); + } + return const_iterator(__result); +} + +template +template +pair::iterator, + typename __tree<_Tp, _Compare, _Allocator>::iterator> +__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) +{ + typedef pair _Pp; + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_pointer>(__rt->__right_); + else + return _Pp(iterator(__rt), + iterator( + __rt->__right_ != nullptr ? + static_cast<__iter_pointer>(__tree_min(__rt->__right_)) + : __result)); + } + return _Pp(iterator(__result), iterator(__result)); +} + +template +template +pair::const_iterator, + typename __tree<_Tp, _Compare, _Allocator>::const_iterator> +__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const +{ + typedef pair _Pp; + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_pointer>(__rt->__right_); + else + return _Pp(const_iterator(__rt), + const_iterator( + __rt->__right_ != nullptr ? + static_cast<__iter_pointer>(__tree_min(__rt->__right_)) + : __result)); + } + return _Pp(const_iterator(__result), const_iterator(__result)); +} + +template +template +pair::iterator, + typename __tree<_Tp, _Compare, _Allocator>::iterator> +__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) +{ + typedef pair _Pp; + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_pointer>(__rt->__right_); + else + return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), + __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); + } + return _Pp(iterator(__result), iterator(__result)); +} + +template +template +pair::const_iterator, + typename __tree<_Tp, _Compare, _Allocator>::const_iterator> +__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const +{ + typedef pair _Pp; + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_pointer>(__rt->__right_); + else + return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), + __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); + } + return _Pp(const_iterator(__result), const_iterator(__result)); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::__node_holder +__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT +{ + __node_pointer __np = __p.__get_np(); + if (__begin_node() == __p.__ptr_) + { + if (__np->__right_ != nullptr) + __begin_node() = static_cast<__iter_pointer>(__np->__right_); + else + __begin_node() = static_cast<__iter_pointer>(__np->__parent_); + } + --size(); + __tree_remove(__end_node()->__left_, + static_cast<__node_base_pointer>(__np)); + return __node_holder(__np, _Dp(__node_alloc(), true)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__tree<_Tp, _Compare, _Allocator>& __x, + __tree<_Tp, _Compare, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TREE diff --git a/third_party/libcxx/__tuple b/third_party/libcxx/__tuple new file mode 100644 index 000000000..fd4c68fec --- /dev/null +++ b/third_party/libcxx/__tuple @@ -0,0 +1,551 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TUPLE +#define _LIBCPP___TUPLE + +#include "third_party/libcxx/__config" +#include "third_party/libcxx/cstddef" +#include "third_party/libcxx/type_traits" + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template struct _LIBCPP_TEMPLATE_VIS tuple_size; + +#if !defined(_LIBCPP_CXX03_LANG) +template +using __enable_if_tuple_size_imp = _Tp; + +template +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< + const _Tp, + typename enable_if::value>::type, + integral_constant)>>> + : public integral_constant::value> {}; + +template +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< + volatile _Tp, + typename enable_if::value>::type, + integral_constant)>>> + : public integral_constant::value> {}; + +template +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< + const volatile _Tp, + integral_constant)>>> + : public integral_constant::value> {}; + +#else +template struct _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; +template struct _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; +template struct _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; +#endif + +template struct _LIBCPP_TEMPLATE_VIS tuple_element; + +template +struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp> +{ + typedef _LIBCPP_NODEBUG_TYPE typename add_const::type>::type type; +}; + +template +struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp> +{ + typedef _LIBCPP_NODEBUG_TYPE typename add_volatile::type>::type type; +}; + +template +struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> +{ + typedef _LIBCPP_NODEBUG_TYPE typename add_cv::type>::type type; +}; + +template struct __tuple_like : false_type {}; + +template struct __tuple_like : public __tuple_like<_Tp> {}; +template struct __tuple_like : public __tuple_like<_Tp> {}; +template struct __tuple_like : public __tuple_like<_Tp> {}; + +// tuple specializations + +#ifndef _LIBCPP_CXX03_LANG + +template struct __tuple_indices {}; + +template +struct __integer_sequence { + template