Browse Source

Make more improvements

This change includes many bug fixes, for the NT polyfills, strings,
memory, boot, and math libraries which were discovered by adding more
tools for recreational programming, such as PC emulation. Lemon has also
been vendored because it works so well at parsing languages.
main
Justine Tunney 1 year ago
parent
commit
23d333c090
  1. 3
      Makefile
  2. 27
      ape/ape.S
  3. 2
      build/config.mk
  4. 35
      build/definitions.mk
  5. 177
      build/realify.sed
  6. 23
      build/realify.sh
  7. 1
      build/rules.mk
  8. 45
      examples/kilo.c
  9. 95
      examples/lstime.c
  10. 6
      libc/bits/bits.h
  11. 4
      libc/bits/roundup.c
  12. 1
      libc/calls/calls.h
  13. 0
      libc/calls/clock.c
  14. 0
      libc/calls/clock_gettime.c
  15. 2
      libc/calls/close-nt.c
  16. 0
      libc/calls/dtime.c
  17. 8
      libc/calls/dup-nt.c
  18. 2
      libc/calls/fcntl-nt.c
  19. 7
      libc/calls/fprot2nt.c
  20. 1
      libc/calls/getrlimit.c
  21. 0
      libc/calls/gettimeofday-nt.c
  22. 0
      libc/calls/gettimeofday-sysv.S
  23. 0
      libc/calls/gettimeofday.c
  24. 2
      libc/calls/growfds.c
  25. 3
      libc/calls/hefty/hefty.mk
  26. 59
      libc/calls/internal.h
  27. 4
      libc/calls/ioctl-default.c
  28. 6
      libc/calls/isfdkind.c
  29. 24
      libc/calls/isfdopen.c
  30. 1
      libc/calls/ktmppath.S
  31. 0
      libc/calls/nanosleep.c
  32. 0
      libc/calls/now.c
  33. 6
      libc/calls/open-nt.c
  34. 2
      libc/calls/prot2nt.greg.c
  35. 6
      libc/calls/removefd.c
  36. 0
      libc/calls/time.c
  37. 0
      libc/calls/utime.c
  38. 3
      libc/calls/utimensat-nt.c
  39. 0
      libc/calls/utimensat-sysv.c
  40. 0
      libc/calls/utimensat-xnu.c
  41. 0
      libc/calls/utimensat.c
  42. 0
      libc/calls/utimes.c
  43. 5
      libc/conv/conv.mk
  44. 11
      libc/conv/itoa.h
  45. 14
      libc/conv/itoa128radix10.greg.c
  46. 14
      libc/conv/itoa64radix10.greg.c
  47. 2
      libc/integral/normalize.inc
  48. 11
      libc/log/backtrace3.c
  49. 72
      libc/log/cancolor.c
  50. 2
      libc/nexgen32e/cescapec.S
  51. 13
      libc/nexgen32e/memcpy.S
  52. 28
      libc/nexgen32e/vidya.h
  53. 2
      libc/nt/master.sh
  54. 19
      libc/nt/thunk/console.inc
  55. 9
      libc/nt/thunk/files.inc
  56. 22
      libc/runtime/directmap.c
  57. 15
      libc/runtime/executive.S
  58. 8
      libc/runtime/ezmap.c
  59. 36
      libc/runtime/getstack.c
  60. 4
      libc/runtime/memtrack.h
  61. 6
      libc/runtime/mmap.c
  62. 18
      libc/runtime/msync-nt.c
  63. 1
      libc/runtime/runtime.h
  64. 2
      libc/runtime/runtime.mk
  65. 48
      libc/runtime/setstack.S
  66. 94
      libc/runtime/winmain.greg.c
  67. 4
      libc/stdio/favail.c
  68. 14
      libc/stdio/fputs.c
  69. 1
      libc/stdio/stdio.mk
  70. 9
      libc/str/chomp.c
  71. 2
      libc/str/chomp16.c
  72. 18
      libc/str/str.h
  73. 3
      libc/str/strcspn.c
  74. 4
      libc/str/strstr.c
  75. 2
      libc/str/wchomp.c
  76. 48
      libc/sysv/consts.sh
  77. 2
      libc/sysv/consts/PROT_GROWSDOWN.s
  78. 2
      libc/sysv/consts/RUSAGE_CHILDREN.s
  79. 2
      libc/sysv/consts/RUSAGE_SELF.s
  80. 2
      libc/sysv/consts/RUSAGE_THREAD.s
  81. 2
      libc/sysv/consts/WCONTINUED.s
  82. 2
      libc/sysv/consts/WEXITED.s
  83. 2
      libc/sysv/consts/WNOHANG.s
  84. 2
      libc/sysv/consts/WNOWAIT.s
  85. 2
      libc/sysv/consts/WSTOPPED.s
  86. 2
      libc/sysv/consts/WUNTRACED.s
  87. 8
      libc/sysv/consts/map.h
  88. 6
      libc/sysv/consts/w.h
  89. 4
      libc/time/xiso8601.c
  90. 2
      libc/tinymath/atan2.S
  91. 25
      libc/unicode/kcombiningchars.S
  92. 2
      libc/x/unbingbuf.c
  93. 5
      libc/x/x.h
  94. 2
      libc/x/x.mk
  95. 2
      libc/x/xaescape.c
  96. 65
      libc/x/xbarf.c
  97. 2
      libc/x/xcalloc.c
  98. 28
      libc/x/xdie.c
  99. 37
      libc/x/xjoinpaths.c
  100. 2
      libc/x/xmalloc.c

3
Makefile

@ -139,6 +139,7 @@ include dsp/tty/tty.mk # ├──online
include libc/dns/dns.mk # │
include libc/crypto/crypto.mk # │
include net/http/http.mk #─┘
include third_party/lemon/lemon.mk
include third_party/linenoise/linenoise.mk
include third_party/editline/editline.mk
include third_party/duktape/duktape.mk
@ -157,6 +158,8 @@ include tool/build/lib/buildlib.mk
include tool/build/emucrt/emucrt.mk
include tool/build/emubin/emubin.mk
include tool/build/build.mk
include tool/calc/calc.mk
include tool/tags/tags.mk
include tool/decode/lib/decodelib.mk
include tool/decode/decode.mk
include tool/hash/hash.mk

27
ape/ape.S

@ -1051,7 +1051,6 @@ realmodeloader:
mov %sp,%bp
call rlinit
call sinit4
mov $VIDYA_MODE,%di
call vinit
mov %es,XLM(VIDEO_POSITION_FAR_POINTER)
mov %ax,XLM(VIDEO_POSITION_FAR_POINTER)+2
@ -1291,32 +1290,16 @@ sputc: push %ax
ret
.endfn sputc,globl
/ Asks BIOS to initialize MDA/CGA display w/o cursor/blinking.
/ Asks BIOS to initialize Monochrome Display Adapter.
/
/ @param dil video mode
/ @return es:ax start of video page
/ @mode real
vinit: push %bp
mov %sp,%bp
push %bx
bbmov VIDYA_ADDR_CGA>>4,%ax,%ah,%al
mov %ax,%es
mov %di,%ax
cmp $VIDYA_MODE_CGA,%al
je 1f
xor %ch,%ch # aka movesdi VIDYA_ADDR_MDA
1: xor %di,%di
bbmov VIDYA_SET_MODE,%ax,%ah,%al
int $VIDYA_SERVICE
bbmov VIDYA_SET_CURSOR,,%ah,%al
bbmov VIDYA_SET_CURSOR_NONE,,%ch,%cl # since we don't support it
int $VIDYA_SERVICE
bbmov VIDYA_SET_BLINKING,,%ah,%al # cargo culting (ega?)
bbmov VIDYA_SET_BLINKING_NONE,,%bh,%bl
vinit: push $7
pop %ax
int $VIDYA_SERVICE
bbmov VIDYA_ADDR_MDA>>4,%ax,%ah,%al
mov %ax,%es
xor %ax,%ax
pop %bx
pop %bp
ret
.endfn vinit,globl

2
build/config.mk

@ -18,7 +18,7 @@ CONFIG_CCFLAGS += \
-Og
TARGET_ARCH ?= \
-march=k8-sse3
-msse3
RAGELFLAGS ?= -G2

35
build/definitions.mk

@ -155,8 +155,7 @@ MATHEMATICAL = \
DEFAULT_CPPFLAGS = \
-DIMAGE_BASE_VIRTUAL=$(IMAGE_BASE_VIRTUAL) \
-nostdinc \
-iquote . \
-include libc/integral/normalize.inc
-iquote .
DEFAULT_CFLAGS = \
-std=gnu2x
@ -217,7 +216,8 @@ cpp.flags = \
$(DEFAULT_CPPFLAGS) \
$(CONFIG_CPPFLAGS) \
$(CPPFLAGS) \
$(OVERRIDE_CPPFLAGS)
$(OVERRIDE_CPPFLAGS) \
-include libc/integral/normalize.inc
copt.flags = \
$(TARGET_ARCH) \
@ -317,18 +317,20 @@ OBJECTIFY.c99.c = $(CC) $(OBJECTIFY.c.flags) -std=c99 -Wextra -Werror -pedantic-
OBJECTIFY.c11.c = $(CC) $(OBJECTIFY.c.flags) -std=c11 -Wextra -Werror -pedantic-errors -c
OBJECTIFY.c2x.c = $(CC) $(OBJECTIFY.c.flags) -std=c2x -Wextra -Werror -pedantic-errors -c
# No-Clobber ABI (clobbers nothing, except rax and flags)
#
# This ABI is intended for core library functions that're frequently
# called by just about everything, e.g. memcpy, malloc, etc. By offering
# this guarantee, callers can optionally call these functions via asm(),
# which reduces register allocator pressure at call sites.
#
# This makes unrelated caller code faster, but the NCABI functions
# themselves a tiny bit slower. That's OK, since modern NexGen-32e CPUs
# seem to have one fifth of their execution engines devoted to pushing
# and popping, probably so legacy IA-32 code keeps going fast; so we use
# it to our advantage.
OBJECTIFY.real.c = \
$(GCC) \
$(OBJECTIFY.c.flags) \
-wrapper build/realify.sh \
-ffixed-r8 \
-ffixed-r9 \
-ffixed-r10 \
-ffixed-r11 \
-ffixed-r12 \
-ffixed-r13 \
-ffixed-r14 \
-ffixed-r15 \
-c
OBJECTIFY.ncabi.c = \
$(GCC) \
$(OBJECTIFY.c.flags) \
@ -350,9 +352,6 @@ OBJECTIFY.ncabi.c = \
-c \
-xc
# Initializer ABI
#
# Doesn't clobber RDI and RSI.
OBJECTIFY.initabi.c = \
$(GCC) \
$(OBJECTIFY.c.flags) \

177
build/realify.sed

@ -0,0 +1,177 @@
#-*-mode:sed;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: et ft=sed ts=8 tw=8 fenc=utf-8 :vi─────────────────┘
#
# SYNOPSIS
#
# sed -i -f build/realify.sed foo.s
#
# OVERVIEW
#
# This converts ints and longs to shorts while preserving System V ABI
# x86_64 compatibility. This works better than gcc -m16 because we can
# avoid the ASZ and OSZ prefixes in most cases while also avoiding the
# legacy 32-bit calling conventions.
# remove comments
s/[ \t][ \t]*#.*//
# preserve hardcoded stack offsets
s/leave\(q\|\)/leavew ; add $6,%sp/
s/call\(q\|\)\t/sub $6,%sp ; callw /
s/ret\(q\|\)/retw\t$6/
s/pushq\t\(.*\)/sub $6,%sp ; push \1/
s/popq\t\(.*\)/pop \1 ; add $6,%sp/
# can be used instead if
# 1. functions have 6 args or fewer
# 2. long double parameters forceinline
#s/leave\(q\|\)/leavew/
#s/call\(q\|\)/callw/
#s/ret\(q\|\)/retw/
#s/popq\t%rbp/pop\t%bp/
#s/pushq\t%rbp/push\t%bp/
#s/pushq\t\(.*\)/sub $6,%sp ; push \1/
#s/popq\t\(.*\)/pop \1 ; add $6,%sp/
# 32-bitify
s/rax/eax/g
s/rbx/ebx/g
s/rcx/ecx/g
s/rdx/edx/g
s/rbp/ebp/g
s/rdi/edi/g
s/rsi/esi/g
s/rsp/esp/g
# unextension
s/movswl/mov/
s/movzwl/mov/
s/movslq/mov/
s/movzlq/mov/
# unsuffix
s/^\(\t\(fild\|fist\|fistp\|fiadd\|fisub\|fisubr\|fimul\|fidiv\|fidivr\|ficom\)\)q\t/\1\t/
s/^\(\t\(mov\|add\|adc\|cmp\|test\|lea\|sbb\|mul\|imul\|div\|idiv\|in\|out\|xor\|sub\|and\|or\|rol\|ror\|rcl\|rcr\|shl\|shr\|sal\|sar\|inc\|dec\|not\|neg\)\)l\t/\1w\t/
s/^\(\t[a-z]*\)q\t/\1w\t/
# remove fluff
s/mov\t%eax,%eax//
s/mov\t%ebx,%ebx//
s/mov\t%ecx,%ecx//
s/mov\t%edx,%edx//
s/mov\t%ebp,%ebp//
s/mov\t%edi,%edi//
s/mov\t%esi,%esi//
s/mov\t%esp,%esp//
# make pic absolute
s/(%rip)//
# legal real mode modrm
s/(%ebx)/(%bx)/
s/(%edi)/(%di)/
s/(%esi)/(%si)/
s/(%ebp)/(%bp)/
s/(%ebx,%esi\(,1\|\))/(%bx,%si)/
s/(%ebx,%edi\(,1\|\))/(%bx,%di)/
s/(%ebp,%esi\(,1\|\))/(%bp,%si)/
s/(%ebp,%edi\(,1\|\))/(%bp,%di)/
# we need the asz prefix
s/(%eax,%eax/(%EAX,%EAX/
s/(%eax,%ebp/(%EAX,%EBP/
s/(%eax,%ebx/(%EAX,%EBX/
s/(%eax,%ecx/(%EAX,%ECX/
s/(%eax,%edi/(%EAX,%EDI/
s/(%eax,%edx/(%EAX,%EDX/
s/(%eax,%esi/(%EAX,%ESI/
s/(%eax,%esp/(%EAX,%ESP/
s/(%ebp,%eax/(%EBP,%EAX/
s/(%ebp,%ebp/(%EBP,%EBP/
s/(%ebp,%ebx/(%EBP,%EBX/
s/(%ebp,%ecx/(%EBP,%ECX/
s/(%ebp,%edi/(%EBP,%EDI/
s/(%ebp,%edx/(%EBP,%EDX/
s/(%ebp,%esi/(%EBP,%ESI/
s/(%ebp,%esp/(%EBP,%ESP/
s/(%ebx,%eax/(%EBX,%EAX/
s/(%ebx,%ebp/(%EBX,%EBP/
s/(%ebx,%ebx/(%EBX,%EBX/
s/(%ebx,%ecx/(%EBX,%ECX/
s/(%ebx,%edi/(%EBX,%EDI/
s/(%ebx,%edx/(%EBX,%EDX/
s/(%ebx,%esi/(%EBX,%ESI/
s/(%ebx,%esp/(%EBX,%ESP/
s/(%ecx,%eax/(%ECX,%EAX/
s/(%ecx,%ebp/(%ECX,%EBP/
s/(%ecx,%ebx/(%ECX,%EBX/
s/(%ecx,%ecx/(%ECX,%ECX/
s/(%ecx,%edi/(%ECX,%EDI/
s/(%ecx,%edx/(%ECX,%EDX/
s/(%ecx,%esi/(%ECX,%ESI/
s/(%ecx,%esp/(%ECX,%ESP/
s/(%edi,%eax/(%EDI,%EAX/
s/(%edi,%ebp/(%EDI,%EBP/
s/(%edi,%ebx/(%EDI,%EBX/
s/(%edi,%ecx/(%EDI,%ECX/
s/(%edi,%edi/(%EDI,%EDI/
s/(%edi,%edx/(%EDI,%EDX/
s/(%edi,%esi/(%EDI,%ESI/
s/(%edi,%esp/(%EDI,%ESP/
s/(%edx,%eax/(%EDX,%EAX/
s/(%edx,%ebp/(%EDX,%EBP/
s/(%edx,%ebx/(%EDX,%EBX/
s/(%edx,%ecx/(%EDX,%ECX/
s/(%edx,%edi/(%EDX,%EDI/
s/(%edx,%edx/(%EDX,%EDX/
s/(%edx,%esi/(%EDX,%ESI/
s/(%edx,%esp/(%EDX,%ESP/
s/(%esi,%eax/(%ESI,%EAX/
s/(%esi,%ebp/(%ESI,%EBP/
s/(%esi,%ebx/(%ESI,%EBX/
s/(%esi,%ecx/(%ESI,%ECX/
s/(%esi,%edi/(%ESI,%EDI/
s/(%esi,%edx/(%ESI,%EDX/
s/(%esi,%esi/(%ESI,%ESI/
s/(%esi,%esp/(%ESI,%ESP/
s/(%esp,%eax/(%ESP,%EAX/
s/(%esp,%ebp/(%ESP,%EBP/
s/(%esp,%ebx/(%ESP,%EBX/
s/(%esp,%ecx/(%ESP,%ECX/
s/(%esp,%edi/(%ESP,%EDI/
s/(%esp,%edx/(%ESP,%EDX/
s/(%esp,%esi/(%ESP,%ESI/
s/(%esp,%esp/(%ESP,%ESP/
s/(,%eax/(,%EAX/
s/(,%ebx/(,%EBX/
s/(,%ecx/(,%ECX/
s/(,%edx/(,%EDX/
s/(,%esi/(,%ESI/
s/(,%edi/(,%EDI/
s/(,%ebp/(,%EBP/
s/(,%esp/(,%ESP/
s/(%eax)/(%EAX)/
s/(%ecx)/(%ECX)/
s/(%edx)/(%EDX)/
s/(%esp)/(%ESP)/
# 16bitify
s/eax/ax/g
s/ebx/bx/g
s/ecx/cx/g
s/edx/dx/g
s/ebp/bp/g
s/edi/di/g
s/esi/si/g
s/esp/sp/g
# sigh :\
# impossible to avoid rex byte access with naive substitution
# best workaround is avoid uint8_t* and try using uint16_t* more
#s/dil/bl/g
#s/sil/bh/g
#s/spl/bl/g
#s/bpl/bh/g
# nope
s/cltq//

23
build/realify.sh

@ -0,0 +1,23 @@
#!/bin/sh
#
# SYNOPSIS
#
# gcc -g0 -Os -wrapper build/realify.sh -ffixed-r{8,9,1{0,1,2,4,5}}
#
# OVERVIEW
#
# Reconfigures x86_64 compiler to emit 16-bit PC boot code.
if [ "${1##*/}" = as ]; then
for x; do
if [ "${x##*.}" = s ]; then
{
printf "\t.code16gcc"
sed -f build/realify.sed "$x"
} >"$x".tmp
mv -f "$x".tmp "$x"
fi
done
fi
exec "$@"

1
build/rules.mk

@ -72,6 +72,7 @@ o/$(MODE)/%.c11.o: %.c11.c; @ACTION=OBJECTIFY.c11 build/compile $(OBJECTIFY.c11.
o/$(MODE)/%.c2x.o: %.c2x.c; @ACTION=OBJECTIFY.c2x build/compile $(OBJECTIFY.c2x.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.initabi.o: %.initabi.c; @ACTION=OBJECTIFY.init build/compile $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ncabi.o: %.ncabi.c; @ACTION=OBJECTIFY.nc build/compile $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $<
o/tiny/%.real.o: %.real.c; @ACTION=OBJECTIFY.real build/compile $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.runs: o/$(MODE)/%; @ACTION=CHECK.runs TARGET=$< build/runcom $< $(TESTARGS) && touch $@
o/$(MODE)/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
o/$(MODE)/%.zip.o: %; @build/zipobj $(OUTPUT_OPTION) $<

45
examples/kilo.c

@ -243,21 +243,19 @@ fatal:
int editorReadKey(int64_t fd) {
int nread;
char c, seq[3];
while ((nread = read(fd, &c, 1)) == 0) {
}
if (nread == -1) exit(1);
if ((nread = read(fd, &c, 1)) == -1) exit(1);
while (1) {
switch (c) {
case CTRL('J'): /* newline */
return CTRL('M');
case CTRL('['): /* escape sequence */
case CTRL('V'):
return PAGE_DOWN;
case '\e': /* escape sequence */
/* If this is just an ESC, we'll timeout here. */
if (read(fd, seq, 1) == 0) return CTRL('[');
if (read(fd, seq + 1, 1) == 0) return CTRL('[');
/* ESC [ sequences. */
if (seq[0] == '[') {
if (read(fd, seq + 1, 1) == 0) return CTRL('[');
if (seq[1] >= '0' && seq[1] <= '9') {
/* Extended escape, read additional byte. */
if (read(fd, seq + 2, 1) == 0) return CTRL('[');
@ -296,10 +294,11 @@ int editorReadKey(int64_t fd) {
return END_KEY;
}
}
}
/* ESC O sequences. */
else if (seq[0] == 'O') {
} else if (seq[0] == 'v') {
return PAGE_UP;
} else if (seq[0] == 'O') {
if (read(fd, seq + 1, 1) == 0) return CTRL('[');
/* ESC O sequences. */
switch (seq[1]) {
case 'H':
return HOME_KEY;
@ -586,8 +585,9 @@ void editorUpdateRow(erow *row) {
/* Create a version of the row we can directly print on the screen,
* respecting tabs, substituting non printable characters with '?'. */
free(row->render);
for (j = 0; j < row->size; j++)
for (j = 0; j < row->size; j++) {
if (row->chars[j] == CTRL('I')) tabs++;
}
row->render = malloc(row->size + tabs * 8 + nonprint * 9 + 1);
idx = 0;
@ -1200,9 +1200,10 @@ void editorMoveCursor(int key) {
void editorProcessKeypress(int64_t fd) {
/* When the file is modified, requires Ctrl-q to be pressed N times
* before actually quitting. */
int c, times;
static int quit_times;
int c = editorReadKey(fd);
c = editorReadKey(fd);
switch (c) {
case CTRL('M'): /* Enter */
editorInsertNewline();
@ -1271,6 +1272,13 @@ void editorProcessKeypress(int64_t fd) {
break;
}
case CTRL('L'):
times = E.screenrows / 2;
while (times--) editorMoveCursor(c == PAGE_UP ? ARROW_UP : ARROW_DOWN);
times = E.screenrows / 2;
while (times--) editorMoveCursor(c == PAGE_UP ? ARROW_DOWN : ARROW_UP);
break;
case PAGE_UP:
case PAGE_DOWN:
if (c == PAGE_UP && E.cy != 0) {
@ -1278,10 +1286,10 @@ void editorProcessKeypress(int64_t fd) {
} else if (c == PAGE_DOWN && E.cy != E.screenrows - 1) {
E.cy = E.screenrows - 1;
}
{
int times = E.screenrows;
while (times--) editorMoveCursor(c == PAGE_UP ? ARROW_UP : ARROW_DOWN);
}
times = E.screenrows;
while (times--) editorMoveCursor(c == PAGE_UP ? ARROW_UP : ARROW_DOWN);
times = E.screenrows / 2;
while (times--) editorMoveCursor(c == PAGE_UP ? ARROW_DOWN : ARROW_UP);
break;
case HOME_KEY:
@ -1316,9 +1324,6 @@ void editorProcessKeypress(int64_t fd) {
editorMoveCursor(c);
break;
case CTRL('L'): /* ctrl+l, clear screen */
/* Just refresht the line as side effect. */
break;
case CTRL('['):
/* Nothing to do for ESC in this mode. */
break;

95
examples/lstime.c

@ -0,0 +1,95 @@
#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/alg/alg.h"
#include "libc/alg/arraylist2.h"
#include "libc/bits/safemacros.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/dirent.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/struct/timespec.h"
#include "libc/log/check.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/dt.h"
#include "libc/x/x.h"
struct stat st;
struct Files {
size_t i, n;
struct File {
struct timespec mt;
char *path;
} * p;
} g_files;
int CompareFiles(struct File *a, struct File *b) {
if (a->mt.tv_sec > b->mt.tv_sec) return 1;
if (a->mt.tv_sec < b->mt.tv_sec) return -1;
if (a->mt.tv_nsec > b->mt.tv_nsec) return 1;
if (a->mt.tv_nsec < b->mt.tv_nsec) return -1;
return strcmp(a->path, b->path);
}
void WalkPaths(const char *dirpath) {
DIR *d;
char *path;
struct File f;
struct dirent *e;
CHECK((d = opendir(dirpath)));
while ((e = readdir(d))) {
if (strcmp(e->d_name, ".") == 0) continue;
if (strcmp(e->d_name, "..") == 0) continue;
path = xjoinpaths(dirpath, e->d_name);
if (strcmp(e->d_name, "o") == 0) continue;
if (strcmp(e->d_name, ".git") == 0) continue;
if (e->d_type == DT_DIR) {
WalkPaths(gc(path));
} else {
CHECK_NE(-1, lstat(path, &st), "%s", path);
f.mt = st.st_mtim;
f.path = path;
APPEND(&g_files.p, &g_files.i, &g_files.n, &f);
}
}
closedir(d);
}
void SortPaths(void) {
qsort(g_files.p, g_files.i, sizeof(*g_files.p), (void *)CompareFiles);
}
void PrintPaths(void) {
long i;
char *ts;
for (i = 0; i < g_files.i; ++i) {
ts = xiso8601(&g_files.p[i].mt);
printf("%s %s\n", ts, g_files.p[i].path);
free(ts);
}
}
void FreePaths(void) {
long i;
for (i = 0; i < g_files.i; ++i) free(g_files.p[i].path);
g_files.i = 0;
}
void LsTime(void) {
WalkPaths(".");
SortPaths();
PrintPaths();
FreePaths();
}
int main(int argc, char *argv[]) {
LsTime();
return 0;
}

6
libc/bits/bits.h

@ -45,9 +45,9 @@ unsigned long hamming(unsigned long, unsigned long) pureconst;
#define ROL(w, k) ((w) << (k) | CheckUnsigned(w) >> (sizeof(w) * 8 - (k)))
#define SAR(w, k) (((w) & ~(~0u >> (k))) | ((w) >> ((k) & (sizeof(w) * 8 - 1))))
#define bitreverse8(X) (kReverseBits[(X)&0xff])
#define bitreverse16(X) \
((uint16_t)kReverseBits[(X)&0xff] << 010 | \
#define bitreverse8(X) (kReverseBits[(uint8_t)(X)])
#define bitreverse16(X) \
((uint16_t)kReverseBits[(uint8_t)(X)] << 010 | \
kReverseBits[((uint16_t)(X) >> 010) & 0xff])
#define READ16LE(S) \

4
libc/bits/roundup.c

@ -19,4 +19,6 @@
*/
#include "libc/macros.h"
long(roundup)(long w, long k) { return ROUNDUP(w, k); }
long(roundup)(long w, long k) {
return ROUNDUP(w, k);
}

1
libc/calls/calls.h

@ -84,7 +84,6 @@ char *get_current_dir_name(void) nodiscard;
char *getcwd(char *, size_t);
char *realpath(const char *, char *);
char *replaceuser(const char *) nodiscard;
char *slurp(const char *, size_t *) nodiscard;
char *ttyname(int);
char *commandv(const char *, char[hasatleast PATH_MAX]);
int access(const char *, int) nothrow;

0
libc/time/clock.c → libc/calls/clock.c

0
libc/time/clock_gettime.c → libc/calls/clock_gettime.c

2
libc/calls/close-nt.c

@ -24,7 +24,7 @@
textwindows int close$nt(int fd) {
bool32 ok;
if (isfdindex(fd)) {
if (isfdopen(fd)) {
if (g_fds.p[fd].kind == kFdFile) {
/*
* Like Linux, closing a file on Windows doesn't guarantee it's

0
libc/time/dtime.c → libc/calls/dtime.c

8
libc/calls/dup-nt.c

@ -34,13 +34,13 @@ textwindows int dup$nt(int oldfd, int newfd, int flags) {
if (newfd == -1) {
if ((newfd = createfd()) == -1) return -1;
} else if (isfdindex(newfd)) {
close(newfd);
} else if (isfdlegal(newfd)) {
if (g_fds.p[newfd].kind != kFdEmpty) {
close(newfd);
}
} else {
do {
if (growfds() == -1) return -1;
} while (newfd >= g_fds.n);
} else {
return ebadf();
}
if (DuplicateHandle(GetCurrentProcess(), g_fds.p[oldfd].handle,
GetCurrentProcess(), &g_fds.p[newfd].handle, 0,

2
libc/calls/fcntl-nt.c

@ -24,7 +24,7 @@
#include "libc/sysv/errfuns.h"
textwindows int fcntl$nt(int fd, int cmd, unsigned arg) {
if (!isfdindex(fd)) return ebadf();
if (!isfdkind(fd, kFdFile)) return ebadf();
switch (cmd) {
case F_GETFD:
return GetHandleInformation(g_fds.p[fd].handle, &arg) ? (arg ^ FD_CLOEXEC)

7
libc/calls/fprot2nt.c

@ -33,7 +33,10 @@ uint32_t fprot2nt(int prot, int flags) {
return (HAS(prot, PROT_READ) ? kNtFileMapRead : 0) |
(HAS(prot, PROT_WRITE) ? kNtFileMapWrite : 0) |
(HAS(prot, PROT_EXEC) ? kNtFileMapExecute : 0) |
(HAS(flags, MAP_PRIVATE) ? kNtFileMapCopy : 0) |
(HAS(flags, kNtSecLargePages) ? kNtFileMapLargePages : 0) |
(HAS(flags, kNtSecReserve) ? kNtFileMapReserve : 0);
(HAS(flags, kNtSecReserve) ? kNtFileMapReserve : 0) |
((HAS(flags, MAP_PRIVATE) && HAS(prot, PROT_READ) &&
HAS(prot, PROT_WRITE))
? kNtFileMapCopy
: 0);
}

1
libc/calls/getrlimit.c

@ -31,7 +31,6 @@
* @see libc/sysv/consts.sh
*/
int getrlimit(int resource, struct rlimit *rlim) {
/* TODO(jart): Windows */
if (resource == -1) return einval();
return getrlimit$sysv(resource, rlim);
}

0
libc/time/gettimeofday-nt.c → libc/calls/gettimeofday-nt.c

0
libc/time/gettimeofday-sysv.S → libc/calls/gettimeofday-sysv.S

0
libc/time/gettimeofday.c → libc/calls/gettimeofday.c

2
libc/calls/growfds.c

@ -28,7 +28,7 @@ int growfds(void) {
struct Fd *p;
if (weaken(realloc)) {
if ((p = weaken(realloc)(g_fds.p != g_fds.__init_p ? g_fds.p : NULL,
(n = ((i = g_fds.n) * 2)) * sizeof(*p)))) {
(n = (i = g_fds.n) << 1) * sizeof(*p)))) {
do {
p[i++].kind = kFdEmpty;
} while (i < n);

3
libc/calls/hefty/hefty.mk

@ -46,8 +46,7 @@ LIBC_CALLS_HEFTY_A_DIRECTDEPS = \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_TIME
LIBC_SYSV_CALLS
LIBC_CALLS_HEFTY_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x))))

59
libc/calls/internal.h

@ -1,22 +1,3 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#ifndef COSMOPOLITAN_LIBC_CALLS_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_INTERNAL_H_
#ifndef __STRICT_ANSI__
@ -54,15 +35,8 @@ struct IoctlPtmGet {
char workername[16];
};
/**
* List of open handles on Windows NT.
*
* The array is indexed by the sysv-style file descriptor numbers that
* we assign. It's needed to make file descriptors only require 32bits
* and helps us abstract peculiarities like close() vs. closesocket().
*/
struct Fds {
size_t f; // length
size_t f; // arbitrary free slot start search index
size_t n; // capacity
struct Fd {
int64_t handle;
@ -82,34 +56,27 @@ struct Fds {
extern const struct Fd kEmptyFd;
hidden extern int g_sighandrvas[NSIG];
hidden extern struct Fds g_fds;
hidden extern struct NtSystemInfo g_ntsysteminfo;
hidden extern struct NtStartupInfo g_ntstartupinfo;
hidden extern const struct NtSecurityAttributes kNtIsInheritable;
extern int g_sighandrvas[NSIG] hidden;
extern struct Fds g_fds hidden;
extern struct NtSystemInfo g_ntsysteminfo hidden;
extern struct NtStartupInfo g_ntstartupinfo hidden;
extern const struct NtSecurityAttributes kNtIsInheritable hidden;
forceinline bool isfdlegal(int fd) {
if (!IsTrustworthy()) {
return (0 <= fd && fd <= INT_MAX);
} else {
return fd;
}
}
ssize_t createfd(void) hidden;
int growfds(void) hidden;
void removefd(int) hidden;
enum FdKind fdkind(int) hidden nosideeffect;
bool isfdopen(int) hidden nosideeffect;
bool isfdkind(int, enum FdKind) hidden nosideeffect;
forceinline bool isfdindex(int fd) {
if (!IsTrustworthy()) {
return (0 <= fd && fd < g_fds.n);
} else {
return fd;
return true;
}
}
ssize_t createfd(void) hidden;
int growfds(void) hidden;
void removefd(int) hidden;
enum FdKind fdkind(int) hidden nosideeffect;
bool isfdkind(int, enum FdKind) hidden nosideeffect;
forceinline size_t clampio(size_t size) {
if (!IsTrustworthy()) {
return MIN(size, 0x7ffff000);

4
libc/calls/ioctl-default.c

@ -29,8 +29,8 @@ int ioctl$default(int fd, uint64_t request, void *memory) {
int64_t handle;
if (!IsWindows()) {
return ioctl$sysv(fd, request, memory);
} else if (isfdindex(fd)) {
if (isfdkind(fd, kFdSocket)) {
} else if (isfdopen(fd)) {
if (g_fds.p[fd].kind == kFdSocket) {
handle = g_fds.p[fd].handle;
if ((rc = weaken(__ioctlsocket$nt)(handle, request, memory)) != -1) {
return rc;

6
libc/calls/isfdkind.c

@ -20,9 +20,5 @@
#include "libc/calls/internal.h"
bool isfdkind(int fd, enum FdKind kind) {
if (isfdindex(fd)) {
return g_fds.p[fd].kind == kind;
} else {
return false;
}
return isfdindex(fd) && g_fds.p[fd].kind == kind;
}

24
libc/calls/isfdopen.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
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/calls/internal.h"
bool isfdopen(int fd) {
return isfdindex(fd) && g_fds.p[fd].kind != kFdEmpty;
}

1
libc/calls/ktmppath.S

@ -39,5 +39,4 @@ kTmpPath:
ezlea GetTempPathA$flunk,ax
call __getntsyspath
.init.end 300,_init_kTmpPath
.source __FILE__

0
libc/time/nanosleep.c → libc/calls/nanosleep.c

0
libc/time/now.c → libc/calls/now.c

6
libc/calls/open-nt.c

@ -22,6 +22,7 @@
#include "libc/calls/ntmagicpaths.h"
#include "libc/nexgen32e/tinystrcmp.h"
#include "libc/nt/createfile.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/nt/enum/filetype.h"
#include "libc/nt/enum/fsctl.h"
#include "libc/nt/errors.h"
@ -38,7 +39,10 @@ static textwindows int64_t open$nt$impl(const char *file, uint32_t flags,
char16_t file16[PATH_MAX];
if (mkntpath2(file, flags, file16) == -1) return -1;
if ((handle = CreateFile(
file16, (flags & 0xf000000f),
file16,
(flags & 0xf000000f) | (/* this is needed if we mmap(rwx+cow)
nt is choosy about open() access */
kNtGenericExecute | kNtFileGenericWrite),
(flags & O_EXCL)
? kNtFileShareExclusive
: kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete,

2
libc/calls/prot2nt.greg.c

@ -37,7 +37,7 @@ privileged uint32_t prot2nt(int prot, int flags) {
: HAS(prot, PROT_READ | PROT_WRITE)
? (HAS(flags, MAP_SHARED) || HAS(flags, MAP_ANONYMOUS))
? kNtPageReadwrite
: kNtPageWritecopy
: kNtPageReadwrite /* kNtPageWritecopy */
: HAS(prot, PROT_READ | PROT_EXEC)
? kNtPageExecuteRead
: HAS(prot, PROT_EXEC)

6
libc/calls/removefd.c

@ -17,12 +17,12 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/bits/safemacros.h"
#include "libc/calls/internal.h"
#include "libc/macros.h"
void removefd(int fd) {
if (isfdindex(fd)) {
if (isfdopen(fd)) {
g_fds.p[fd].kind = kFdEmpty;
g_fds.f = min(g_fds.f, fd);
g_fds.f = MIN(g_fds.f, fd);
}
}

0
libc/time/time.c → libc/calls/time.c

0
libc/time/utime.c → libc/calls/utime.c

3
libc/time/utimensat-nt.c → libc/calls/utimensat-nt.c

@ -50,9 +50,6 @@ textwindows int utimensat$nt(int dirfd, const char *path,
} else {
return einval();
}
} else if (isfdindex(dirfd)) {
fh = g_fds.p[dirfd].handle;
closeme = false;
} else {
return ebadf();
}

0
libc/time/utimensat-sysv.c → libc/calls/utimensat-sysv.c

0
libc/time/utimensat-xnu.c → libc/calls/utimensat-xnu.c

0
libc/time/utimensat.c → libc/calls/utimensat.c

0
libc/time/utimes.c → libc/calls/utimes.c

5
libc/conv/conv.mk

@ -61,6 +61,11 @@ o/$(MODE)/libc/conv/filetimetotimeval.o: \
OVERRIDE_CFLAGS += \
-O3
o/$(MODE)/libc/conv/itoa64radix10.greg.o \
o/$(MODE)/libc/conv/itoa128radix10.greg.o: \
OVERRIDE_CFLAGS += \
-fwrapv
$(LIBC_CONV_A_OBJS): \
OVERRIDE_CFLAGS += \
$(NO_MAGIC)

11
libc/conv/itoa.h

@ -16,17 +16,10 @@ COSMOPOLITAN_C_START_
- uint128toarray_radix10(0x31337, a) l: 93 (27ns) m: 141 (41ns)
- int128toarray_radix10(0x31337, a) l: 96 (28ns) m: 173 (51ns)
SLOWEST + GENERAL
- int64toarray(0x31337, a, 10) l: 218 (64ns) m: 262 (77ns)
- uint64toarray(0x31337, a, 10) l: 565 (166ns) m: 260 (76ns)
*/
size_t int64toarray_radix10(int64_t, char *);
size_t uint64toarray_radix10(uint64_t, char *);
size_t int64toarray(int64_t, char *, int);
size_t uint64toarray(uint64_t, char *, int);
size_t int64toarray_radix10(int64_t, char[hasatleast 21]);
size_t uint64toarray_radix10(uint64_t, char[hasatleast 21]);
size_t uint64toarray_radix16(uint64_t, char[hasatleast 17]);
size_t uint64toarray_fixed16(uint64_t, char[hasatleast 17], uint8_t);

14
libc/conv/itoa128radix10.greg.c

@ -48,15 +48,7 @@ noinline size_t uint128toarray_radix10(uint128_t i, char *a) {
* @return bytes written w/o nul
*/
size_t int128toarray_radix10(int128_t i, char *a) {
if (i < 0) {
if (i != INT128_MIN) {
*a++ = '-';
return 1 + uint128toarray_radix10(-i, a);
} else {
memcpy(a, "-170141183460469231731687303715884105728", 41);
return 40;
}
} else {
return uint128toarray_radix10(i, a);
}
if (i >= 0) return uint128toarray_radix10(i, a);
*a++ = '-';
return 1 + uint128toarray_radix10(-i, a);
}

14
libc/conv/itoa64radix10.greg.c

@ -45,15 +45,7 @@ noinline size_t uint64toarray_radix10(uint64_t i, char *a) {
* @return bytes written w/o nul
*/
size_t int64toarray_radix10(int64_t i, char *a) {
if (i < 0) {
if (i != INT64_MIN) {
*a++ = '-';
return 1 + uint64toarray_radix10(-i, a);
} else {
memcpy(a, "-9223372036854775808", 21);
return 20;
}
} else {
return uint64toarray_radix10(i, a);
}
if (i >= 0) return uint64toarray_radix10(i, a);
*a++ = '-';
return 1 + uint64toarray_radix10(-i, a);
}

2
libc/integral/normalize.inc

@ -66,7 +66,7 @@
#endif
#define BIGPAGESIZE 0x200000
#define STACKSIZE 0x20000
#define STACKSIZE 0x80000 /* todo: zlib's fault? */
#define FRAMESIZE 0x10000 /* 8086 */
#define PAGESIZE 0x1000 /* i386+ */
#define BUFSIZ 0x1000 /* best stdio default */

11
libc/log/backtrace3.c

@ -31,6 +31,16 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
/**
* Prints stack frames with symbols.
*
* PrintBacktraceUsingSymbols(stdout, 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
*/
int PrintBacktraceUsingSymbols(FILE *f, const struct StackFrame *bp,
struct SymbolTable *st) {
size_t gi;
@ -41,6 +51,7 @@ int PrintBacktraceUsingSymbols(FILE *f, const struct StackFrame *bp,
const struct Symbol *symbol;
const struct StackFrame *frame;
if (!st) return -1;
if (!bp) bp = __builtin_frame_address(0);
garbage = weaken(g_garbage);
gi = garbage ? garbage->i : 0;
for (frame = bp; frame; frame = frame->next) {

72
libc/log/cancolor.c

@ -33,27 +33,6 @@
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
static struct CanColor {
bool once;
bool result;
struct OldNtConsole {
unsigned codepage;
unsigned mode;
int64_t handle;
} oldin, oldout;
} g_cancolor;
static textwindows void restorecmdexe(void) {
if (g_cancolor.oldin.handle) {
SetConsoleCP(g_cancolor.oldin.codepage);
SetConsoleMode(g_cancolor.oldin.handle, g_cancolor.oldin.mode);
}
if (g_cancolor.oldout.handle) {
SetConsoleOutputCP(g_cancolor.oldout.codepage);
SetConsoleMode(g_cancolor.oldout.handle, g_cancolor.oldout.mode);
}
}
/**
* Returns true if ANSI terminal colors are appropriate.
*
@ -75,47 +54,20 @@ static textwindows void restorecmdexe(void) {
* It's that easy fam.
*/
bool cancolor(void) {
int64_t handle;
static bool once;
static bool result;
const char *term;
if (g_cancolor.once) return g_cancolor.result;
g_cancolor.once = true;
if (IsWindows()) {
if ((int)weakaddr("v_ntsubsystem") == kNtImageSubsystemWindowsCui &&
NtGetVersion() >= kNtVersionWindows10) {
atexit(restorecmdexe);
if (GetFileType((handle = g_fds.p[STDIN_FILENO].handle)) ==
kNtFileTypeChar) {
g_cancolor.result = true;
g_cancolor.oldin.handle = handle;
g_cancolor.oldin.codepage = GetConsoleCP();
SetConsoleCP(kNtCpUtf8);
GetConsoleMode(handle, &g_cancolor.oldin.mode);
SetConsoleMode(handle, g_cancolor.oldin.mode | kNtEnableProcessedInput |
kNtEnableVirtualTerminalInput);
}
if (GetFileType((handle = g_fds.p[STDOUT_FILENO].handle)) ==
kNtFileTypeChar ||
GetFileType((handle = g_fds.p[STDERR_FILENO].handle)) ==
kNtFileTypeChar) {
g_cancolor.result = true;
g_cancolor.oldout.handle = handle;
g_cancolor.oldout.codepage = GetConsoleOutputCP();
SetConsoleOutputCP(kNtCpUtf8);
GetConsoleMode(handle, &g_cancolor.oldout.mode);
SetConsoleMode(handle, g_cancolor.oldout.mode |
kNtEnableProcessedOutput |
kNtEnableVirtualTerminalProcessing);
if (!once) {
if (!result) {
if ((term = getenv("TERM"))) {
/* anything but emacs basically */
result = strcmp(term, "dumb") != 0;
} else {
/* TODO(jart): Why does Mac bash login shell exec nuke TERM? */
result = IsXnu();
}
}
once = true;
}
if (!g_cancolor.result) {
if ((term = getenv("TERM"))) {
/* anything but emacs basically */
g_cancolor.result = strcmp(term, "dumb") != 0;
} else {
/* TODO(jart): Why does Mac bash login shell exec nuke TERM? */
g_cancolor.result = IsXnu();
}
}
return g_cancolor.result;
return result;
}

2
libc/nexgen32e/cescapec.S

@ -40,7 +40,7 @@ cescapec:
ret
.LHT: mov $'t,%ah
ret
.LLF: or $'n<<010|'\\<<020|'\n<<030,%eax
.LLF: mov $'n,%ah
ret
.LVT: mov $'v,%ah
ret

13
libc/nexgen32e/memcpy.S

@ -100,10 +100,15 @@ MemCpy: .leafprologue
mov %ecx,(%rdi)
mov %ebx,-4(%rdi,%rdx)
jmp 1b
.L3: mov 2(%rsi),%cl
mov %cl,2(%rdi)
.L2: mov 1(%rsi),%cl
mov %cl,1(%rdi)
.L3: push %rbx
mov (%rsi),%cx
mov -2(%rsi,%rdx),%bx
mov %cx,(%rdi)
mov %bx,-2(%rdi,%rdx)
jmp 1b
.L2: mov (%rsi),%cx
mov %cx,(%rdi)
jmp .L0
.L1: mov (%rsi),%cl
mov %cl,(%rdi)
jmp .L0

28
libc/nexgen32e/vidya.h

@ -48,20 +48,20 @@
* @mode long,legacy,real
*/
#define VIDYA_ROWS 25
#define VIDYA_COLUMNS 80
#define VIDYA_SIZE (VIDYA_ROWS * VIDYA_COLUMNS * 2)
#define VIDYA_MODE_MDA 7
#define VIDYA_MODE_CGA 3
#define VIDYA_ADDR_MDA 0xb0000
#define VIDYA_ADDR_CGA 0xb8000
#define VIDYA_ATTR_NORMAL 0x07 /* cozy default for both mda and cga */
#define VIDYA_REWIND ~0x7fff /* derived from mode addr min. lzcnt */
#define VIDYA_SERVICE 0x10
#define VIDYA_SET_MODE 0
#define VIDYA_SET_CURSOR 0x0100
#define VIDYA_SET_CURSOR_NONE 0x2000
#define VIDYA_SET_BLINKING 0x1003
#define VIDYA_ROWS 25
#define VIDYA_COLUMNS 80
#define VIDYA_SIZE (VIDYA_ROWS * VIDYA_COLUMNS * 2)
#define VIDYA_MODE_MDA 7
#define VIDYA_MODE_CGA 3
#define VIDYA_ADDR_MDA 0xb0000
#define VIDYA_ADDR_CGA 0xb8000
#define VIDYA_ATTR_NORMAL 0x07 /* cozy default for both mda and cga */
#define VIDYA_REWIND ~0x7fff /* derived from mode addr min. lzcnt */
#define VIDYA_SERVICE 0x10
#define VIDYA_SET_MODE 0x0003
#define VIDYA_SET_CURSOR 0x0100
#define VIDYA_SET_CURSOR_NONE 0x2000
#define VIDYA_SET_BLINKING 0x1003
#define VIDYA_SET_BLINKING_NONE 0x0000
#if !(__ASSEMBLER__ + __LINKER__ + 0)

2
libc/nt/master.sh

@ -5478,7 +5478,7 @@ imp 'RtlSetDaclSecurityDescriptor' RtlSetDaclSecurityDescriptor ntdll 138
imp 'RtlSetDynamicTimeZoneInformation' RtlSetDynamicTimeZoneInformation ntdll 1386
imp 'RtlSetEnvironmentStrings' RtlSetEnvironmentStrings ntdll 1387
imp 'RtlSetEnvironmentVar' RtlSetEnvironmentVar ntdll 1388
imp 'RtlSetEnvironmentVariable' RtlSetEnvironmentVariable ntdll 1389
imp 'RtlSetEnvironmentVariable' RtlSetEnvironmentVariable ntdll 1389
imp 'RtlSetExtendedFeaturesMask' RtlSetExtendedFeaturesMask ntdll 1390
imp 'RtlSetGroupSecurityDescriptor' RtlSetGroupSecurityDescriptor ntdll 1391
imp 'RtlSetHeapInformation' RtlSetHeapInformation ntdll 1392

19
libc/nt/thunk/console.inc

@ -1,11 +1,20 @@
#define GetConsoleMode(...) __imp_GetConsoleMode(__VA_ARGS__)
#define SetConsoleCP(...) __imp_SetConsoleCP(__VA_ARGS__)
#define SetConsoleCtrlHandler(...) __imp_SetConsoleCtrlHandler(__VA_ARGS__)
#define SetConsoleMode(...) __imp_SetConsoleMode(__VA_ARGS__)
#define SetConsoleOutputCP(...) __imp_SetConsoleOutputCP(__VA_ARGS__)
extern typeof(GetConsoleMode) *const __imp_GetConsoleMode __msabi;
#define SetConsoleCP(...) __imp_SetConsoleCP(__VA_ARGS__)
extern typeof(SetConsoleCP) *const __imp_SetConsoleCP __msabi;
#define GetConsoleCP(...) __imp_GetConsoleCP(__VA_ARGS__)
extern typeof(GetConsoleCP) *const __imp_GetConsoleCP __msabi;
#define SetConsoleCtrlHandler(...) __imp_SetConsoleCtrlHandler(__VA_ARGS__)
extern typeof(SetConsoleCtrlHandler) *const __imp_SetConsoleCtrlHandler __msabi;
#define SetConsoleMode(...) __imp_SetConsoleMode(__VA_ARGS__)
extern typeof(SetConsoleMode) *const __imp_SetConsoleMode __msabi;
#define SetConsoleOutputCP(...) __imp_SetConsoleOutputCP(__VA_ARGS__)
extern typeof(SetConsoleOutputCP) *const __imp_SetConsoleOutputCP __msabi;
#define GetConsoleOutputCP(...) __imp_GetConsoleOutputCP(__VA_ARGS__)
extern typeof(GetConsoleOutputCP) *const __imp_GetConsoleOutputCP __msabi;

9
libc/nt/thunk/files.inc

@ -1,5 +1,8 @@
#define CopyFile(...) __imp_CopyFileW(__VA_ARGS__)
#define FlushFileBuffers(...) __imp_FlushFileBuffers(__VA_ARGS__)
#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;

22
libc/runtime/directmap.c

@ -18,6 +18,7 @@
02110-1301 USA
*/
#include "libc/calls/internal.h"
#include "libc/macros.h"
#include "libc/nt/memory.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/directmap.h"
@ -25,14 +26,21 @@
static textwindows struct DirectMap DirectMapNt(void *addr, size_t size,
unsigned prot, unsigned flags,
int fd, int64_t off) {
int64_t handle;
struct DirectMap res;
if ((res.maphandle = CreateFileMappingNuma(
fd != -1 ? g_fds.p[fd].handle : kNtInvalidHandleValue,
&kNtIsInheritable, prot2nt(prot, flags), size >> 32, size, NULL,
kNtNumaNoPreferredNode))) {
if (!(res.addr = MapViewOfFileExNuma(res.maphandle, fprot2nt(prot, flags),
off >> 32, off, size, addr,
kNtNumaNoPreferredNode))) {
uint32_t protect, access;
if (fd != -1) {
handle = g_fds.p[fd].handle;
} else {
handle = kNtInvalidHandleValue;
}
protect = prot2nt(prot, flags);
access = fprot2nt(prot, flags);
if ((res.maphandle =
CreateFileMappingNuma(handle, &kNtIsInheritable, protect, size >> 32,
size, NULL, kNtNumaNoPreferredNode))) {
if (!(res.addr = MapViewOfFileExNuma(res.maphandle, access, off >> 32, off,
size, addr, kNtNumaNoPreferredNode))) {
CloseHandle(res.maphandle);
res.maphandle = kNtInvalidHandleValue;
res.addr = (void *)(intptr_t)winerr();

15
libc/runtime/executive.S

@ -20,6 +20,8 @@
#include "libc/dce.h"
#include "libc/macros.h"
#include "libc/notice.inc"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/map.h"
#include "libc/dce.h"
.text.startup
.source __FILE__
@ -40,12 +42,15 @@ _executive:
mov %rdx,%r14