Browse Source

Get binaries closer to running without an o/s

blinkenlights now does a pretty good job emulating what happens when
binaries boot from BIOS into long mode. So it's been much easier to
debug the bare metal process and wrinkle out many issues.
main
Justine Tunney 2 years ago
parent
commit
2d80bbc802
  1. 341
      ape/ape.S
  2. 2
      ape/config.h
  3. 12
      ape/lib/getpagetableentry.c
  4. 2
      ape/lib/kbiosdataarea.S
  5. 38
      ape/lib/mapimage.c
  6. 5
      ape/lib/pageunmap.c
  7. 5
      ape/lib/pc.h
  8. 26
      examples/hidecursor.c
  9. 2
      examples/package/build.mk
  10. 2
      libc/calls/hefty/spawnve-sysv.c
  11. 1
      libc/calls/kntwindowsdirectory.S
  12. 3
      libc/crt/crt.S
  13. 1
      libc/log/asan.c
  14. 10
      libc/macros.inc
  15. 16
      libc/nexgen32e/rdtscp.h
  16. 68
      libc/nexgen32e/uart.h
  17. 7
      libc/stdio/serialstdio.c
  18. 92
      libc/stdio/system.c
  19. 7
      libc/sysv/systemfive.S
  20. 6
      test/dsp/core/getintegercoefficients_test.c
  21. 1
      third_party/duktape/duktape.mk
  22. 136
      tool/build/blinkenlights.c
  23. 1
      tool/build/build.mk
  24. 30
      tool/build/emubin/emubin.mk
  25. 460
      tool/build/emubin/lisp.c
  26. 2
      tool/build/emubin/spiral.c
  27. 6
      tool/build/lib/argv.c
  28. 19
      tool/build/lib/buffer.c
  29. 4
      tool/build/lib/buffer.h
  30. 3
      tool/build/lib/buildlib.mk
  31. 21
      tool/build/lib/cpuid.c
  32. 3
      tool/build/lib/dis.c
  33. 20
      tool/build/lib/disarg.c
  34. 1
      tool/build/lib/diself.c
  35. 189
      tool/build/lib/disspec.c
  36. 36
      tool/build/lib/ioports.c
  37. 39
      tool/build/lib/loader.c
  38. 281
      tool/build/lib/machine.c
  39. 9
      tool/build/lib/machine.h
  40. 10
      tool/build/lib/memory.c
  41. 2
      tool/build/lib/memory.h
  42. 57
      tool/build/lib/op101.c
  43. 4
      tool/build/lib/pml4tfmt.c
  44. 4
      tool/build/lib/reset.c
  45. 16
      tool/build/lib/stack.c
  46. 1
      tool/build/lib/stack.h
  47. 12
      tool/build/lib/syscall.c
  48. 18
      tool/build/lib/time.c
  49. 1
      tool/build/lib/time.h
  50. 2
      tool/emacs/cosmo-c-constants.el

341
ape/ape.S

@ -45,8 +45,11 @@ @@ -45,8 +45,11 @@
#include "libc/nexgen32e/vidya.h"
#include "libc/nt/pedef.h"
#include "libc/nexgen32e/vidya.h"
#include "libc/dce.h"
#include "libc/sysv/consts/prot.h"
#define USE_SYMBOL_HACK 0
.source "NOTICE"
.source "ape/ape.S"
.source "ape/ape.lds"
@ -179,6 +182,10 @@ stub: mov $0x40,%dl # *literally* dos @@ -179,6 +182,10 @@ stub: mov $0x40,%dl # *literally* dos
/ @noreturn
.code16
pc: cld
#if USE_SYMBOL_HACK
.byte 0x0f,0x1f,0207 # nop rdi binbase
.short (0x7c00-IMAGE_BASE_VIRTUAL)/512
#endif
mov $REAL_STACK_FRAME>>4,%di # we need a stack
xor %cx,%cx
rlstack %di,%cx
@ -197,6 +204,10 @@ pc: cld @@ -197,6 +204,10 @@ pc: cld
xor %di,%di
rep
movsb %ds:(%si),%es:(%di)
#if USE_SYMBOL_HACK
.byte 0x0f,0x1f,0207 # nop rdi binbase
.short (IMAGE_BASE_REAL-0x7c00)/512
#endif
ljmp $0,$REAL(1f) # longjmp()
1: mov $-512,%cx # memcpy() [relocate this frame]
rep
@ -932,9 +943,6 @@ ape.str: @@ -932,9 +943,6 @@ ape.str:
.Lstr.long:
.asciz "nolong"
.endobj .Lstr.long
.Lstr.hello:
.asciz "hello\n"
.endobj .Lstr.hello
.endobj ape.str
/ Serial Line Configuration (8250 UART 16550)
@ -964,7 +972,7 @@ sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/ @@ -964,7 +972,7 @@ sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/
.align 8
gdt: .short 2f-1f # table byte length
.long REAL(1f),0 # table address
.align 8
.zero 2
1:
/ G:granularity (1 limit *= 0x1000)
/ D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
@ -1047,13 +1055,8 @@ ape.grub.entry: @@ -1047,13 +1055,8 @@ ape.grub.entry:
nop
nop
realmodeloader:
push %bp
mov %sp,%bp
call rlinit
call sinit4
call vinit
mov %es,XLM(VIDEO_POSITION_FAR_POINTER)
mov %ax,XLM(VIDEO_POSITION_FAR_POINTER)+2
mov $REAL(.Lstr.ape),%di
call rvputs
.optfn _start16
@ -1062,38 +1065,29 @@ realmodeloader: @@ -1062,38 +1065,29 @@ realmodeloader:
.endfn realmodeloader,globl,hidden
.section .sort.text.real.init.1,"ax",@progbits
.type rrinit,@function
rlinit: push %bp
mov %sp,%bp
.previous/*
.type rlinit,@function
rlinit: .previous/*
...
decentralized function
...
*/.section .sort.text.real.init.3,"ax",@progbits
pop %bp
ret
.previous
/ Initializes present PC serial lines.
sinit4: push %bp
mov %sp,%bp
movw $4,%cx
movw $kBiosDataAreaXlm+COM1,%si
0: lodsb
mov %al,%dl
lodsb
mov %al,%dh
test %dx,%dx
sinit4: mov $4,%cx
mov $kBiosDataAreaXlm+COM1,%si
0: lodsw
test %ax,%ax
jz 1f
push %cx
push %si
mov %dx,%di
movw $REAL(sconf),%si
xchg %ax,%di
mov $REAL(sconf),%si
call sinit
pop %si
pop %cx
1: loop 0b
pop %bp
ret
.endfn sinit4,global,hidden
@ -1103,9 +1097,7 @@ sinit4: push %bp @@ -1103,9 +1097,7 @@ sinit4: push %bp
/ @param char (*{es:,e,r}si)[4] register initial values
/ @mode long,legacy,real
/ @see www.lammertbies.nl/comm/info/serial-uart.html
sinit: push %bp
mov %sp,%bp
mov %di,%dx
sinit: mov %di,%dx
test %dx,%dx
jz 2f
push %dx
@ -1123,8 +1115,7 @@ sinit: push %bp @@ -1123,8 +1115,7 @@ sinit: push %bp
add $1,%dx
sub $1,%cx
jns 1b
2: pop %bp
ret
2: ret
.endfn sinit,global,hidden
/ Abnormally exits program.
@ -1132,9 +1123,7 @@ sinit: push %bp @@ -1132,9 +1123,7 @@ sinit: push %bp
/ @param di message
/ @mode real
/ @noreturn
rldie: push %bp
mov %sp,%bp
call rlpute
rldie: call rlpute
call rloff
.endfn rldie,globl,hidden
@ -1142,9 +1131,7 @@ rldie: push %bp @@ -1142,9 +1131,7 @@ rldie: push %bp
/
/ @mode real
/ @noreturn
rloff: push %bp
mov %sp,%bp
mov $kBiosDataAreaXlm+COM1,%di
rloff: mov $kBiosDataAreaXlm+COM1,%di
mov $4,%si
call sflush
call apmoff
@ -1154,9 +1141,7 @@ rloff: push %bp @@ -1154,9 +1141,7 @@ rloff: push %bp
/
/ @param di message
/ @mode real
rlpute: push %bp
mov %sp,%bp
mov kBiosDataAreaXlm+METAL_STDERR(%bx),%si
rlpute: mov kBiosDataAreaXlm+METAL_STDERR(%bx),%si
test %si,%si
jnz 1f
mov kBiosDataAreaXlm+METAL_STDOUT,%si
@ -1176,8 +1161,7 @@ rlpute: push %bp @@ -1176,8 +1161,7 @@ rlpute: push %bp
pop %si
call rlput2
jmp 1b
2: pop %bp
ret
2: ret
.endfn rlpute,globl,hidden
/ Prints string to both video and serial.
@ -1185,9 +1169,7 @@ rlpute: push %bp @@ -1185,9 +1169,7 @@ rlpute: push %bp
/ @param di NUL-terminated string
/ @param si serial port
/ @mode real
rlput2: push %bp
mov %sp,%bp
push %di
rlput2: push %di
push %si
call rvputs
pop %si
@ -1195,33 +1177,42 @@ rlput2: push %bp @@ -1195,33 +1177,42 @@ rlput2: push %bp
test %si,%si
jz 1f
call sputs
1: pop %bp
ret
1: ret
.endfn rlput2,globl,hidden
/ Video put string.
/
/ @param di is the string
/ @mode real
rvputs: push %bp
mov %sp,%bp
mov %di,%si
les XLM(VIDEO_POSITION_FAR_POINTER),%di
call vputs
mov %es,XLM(VIDEO_POSITION_FAR_POINTER)
mov %ax,XLM(VIDEO_POSITION_FAR_POINTER)+2
pop %bp
ret
rvputs: mov %di,%si
0: lodsb
test %al,%al
je 1f
call rvputc
jmp 0b
1: ret
.endfn rvputs,globl,hidden
/ Video put char.
/
/ @param al is the char
/ @mode real
rvputc: push %bx # don't clobber bp,bx,di,si,cx
push %bp # original ibm pc scroll up bug
mov $7,%bx # normal mda/cga style page zero
mov $0x0e,%ah # teletype output al cp437
int $0x10 # vidya service
pop %bp # preserves al
pop %bx
ret
.endfn rvputc
/ Writes string to serial line.
/
/ @param di NUL-terminated string
/ @param si serial port
/ @mode long,legacy,real
sputs: push %bp
mov %sp,%bp
push %bx
sputs: push %bx
mov %di,%bx
1: xchg %bx,%si
lodsb
@ -1234,7 +1225,6 @@ sputs: push %bp @@ -1234,7 +1225,6 @@ sputs: push %bp
pop %si
jmp 1b
2: pop %bx
pop %bp
ret
.endfn sputs,globl
@ -1290,137 +1280,11 @@ sputc: push %ax @@ -1290,137 +1280,11 @@ sputc: push %ax
ret
.endfn sputc,globl
/ Asks BIOS to initialize Monochrome Display Adapter.
/
/ @return es:ax start of video page
/ @mode real
vinit: push $7
pop %ax
int $VIDYA_SERVICE
bbmov VIDYA_ADDR_MDA>>4,%ax,%ah,%al
mov %ax,%es
xor %ax,%ax
ret
.endfn vinit,globl
/ Prints byte to display w/ teletype emulation.
/
/ @param es:di screen position
/ @param sil byte
/ @return es:ax new screen position
/ @mode long,legacy,real
vputc: push %bp
mov %sp,%bp
sub $16,%sp # goal is to turn sil into a buffer
xchg %si,%ax # modrm sooo different in real mode
mov %di,%cx
mov %sp,%si
mov %sp,%di
stosb
mov %cx,%di
pushpop 1,%dx
jmp 23f
/ Prints string to display w/ teletype emulation.
/
/ @param es:di screen position
/ @param si NUL-terminated string
/ @return es:ax new screen position
/ @mode long,legacy,real
vputs: push %si # inlined strlen
1: lodsb
test %al,%al
jnz 1b
mov %si,%dx
pop %si
sub %si,%dx
/ fallthrough
/ Prints data to display w/ teletype emulation.
/
/ @param es:di screen position
/ @param si data address
/ @param dx data size in bytes
/ @return es:ax new screen position
/ @mode long,legacy,real
vtput: push %bp
mov %sp,%bp
23: push %bx
mov %dx,%cx
mov %di,%dx
bband VIDYA_REWIND,%dh,%dl
bbadd VIDYA_SIZE,%dh,%dl
bbmov VIDYA_COLUMNS*2-2,%bx,%bh,%bl
0: cmp %dx,%di
je 6f
ja 3f
lodsb # todo: utf8 cp437
cmp $'\n,%al
je 4f
cmp $'\r,%al
je 5f
1: stosb
mov $VIDYA_ATTR_NORMAL,%al # todo: ansi color
stosb
2: loop 0b
3: mov %di,%ax
pop %bx
pop %bp
ret
4: add %bx,%di # line feed
jmp 2b
5: mov %di,%ax # carriage return
push %dx
xor %dx,%dx
idiv %bx # todo: division is deprecated
sub %dx,%di
pop %dx
jmp 2b
6: push %ax
push %cx
push %dx
push %si
mov %bx,%si
rlcall vscroll
mov %ax,%di
pop %si
pop %dx
pop %cx
pop %ax
jmp 2b
.endfn vtput,globl
.endfn vputs,globl
.endfn vputc,globl
/ Scrolls up content in display page.
/
/ @param es:di cursor address (bytes after aren't moved)
/ @param si byte difference, e.g. VIDYA_COLUMNS*2
/ @return es:ax new cursor address (which is es:di-si)
/ @mode long,legacy,real
vscroll:not %dx
mov %di,%cx
bband VIDYA_REWIND,%ch,%cl
xchg %cx,%di # di is now page addr, i.e. top-left
sub %si,%cx # cx is now future cursor address
push %cx
sub %di,%cx # cx is now memcpy size
mov %di,%si
add %cx,%si
mov $0,%ax
movpp %ds,%es
rep movsb
pop %ax
ret
.endfn vscroll,globl
/ Shuts down personal computer.
/
/ @mode real
/ @noreturn
apmoff: push %bp
mov %sp,%bp
mov $0x5300,%ax # apm installation check
apmoff: mov $0x5300,%ax # apm installation check
xor %bx,%bx # for the apm bios itself
int $APM_SERVICE
jc 1f
@ -1485,8 +1349,6 @@ apmoff: push %bp @@ -1485,8 +1349,6 @@ apmoff: push %bp
long mode is long */
longmodeloader:
push %bp
mov %sp,%bp
call lcheck
call a20
mov $XLM(E820),%di
@ -1495,15 +1357,13 @@ longmodeloader: @@ -1495,15 +1357,13 @@ longmodeloader:
jc 9f
call unreal
call hiload
call golong
jmp golong
9: mov $REAL(.Lstr.e820),%ax
call rldie
.endfn longmodeloader,globl,hidden
/ Long Mode Hardware Check
lcheck: push %bp
mov %sp,%bp
pushf # check for i8086 / i8088 / i80186
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
@ -1534,8 +1394,7 @@ lcheck: push %bp @@ -1534,8 +1394,7 @@ lcheck: push %bp
cmp %edi,%edx
jne 10f
xor %ax,%ax
1: pop %bp
ret
1: ret
9: mov $REAL(.Lstr.oldskool),%ax
jmp 20f
10: mov $REAL(.Lstr.long),%ax
@ -1587,9 +1446,7 @@ e820: push %bp @@ -1587,9 +1446,7 @@ e820: push %bp
/ Unreal Mode.
/ Makes 4gb of real memory accessible via %fs segment.
unreal: push %bp
mov %sp,%bp
cli
unreal: cli
lgdt REAL(gdt)
mov %cr0,%eax
or $CR0_PE,%al
@ -1599,16 +1456,13 @@ unreal: push %bp @@ -1599,16 +1456,13 @@ unreal: push %bp
mov %cx,%fs
and $~CR0_PE,%al
mov %eax,%cr0
ljmpl $0,$REAL(1f)
ljmp $0,$REAL(1f)
1: sti
pop %bp
ret
.endfn unreal
/ Loads remainder of executable off disk.
hiload: push %bp
mov %sp,%bp
push %bx
hiload: push %bx
mov $IMAGE_BASE_REAL,%esi # relocate, again
mov $IMAGE_BASE_PHYSICAL,%ebx
mov $v_ape_realsectors,%ecx
@ -1647,7 +1501,6 @@ hiload: push %bp @@ -1647,7 +1501,6 @@ hiload: push %bp
pop %cx
jmp 0b
9: pop %bx
pop %bp
ret
.endfn hiload
@ -1724,18 +1577,16 @@ a20: cli @@ -1724,18 +1577,16 @@ a20: cli
/ stack segment base. This function only defines enough tables
/ to get us started.
#define TIP REAL_STACK_FRAME
pinit: push %bp
mov %sp,%bp
push %ds
pinit: push %ds
mov $(TIP-0x4000)>>4,%ax
mov %ax,%ds
movl $TIP-0x2000+PAGE_V+PAGE_RW,%ds:0x3000 # PML4TPDPT
movl $TIP-0x3000+PAGE_V+PAGE_RW,%ds:0x2000 # PDPTPDT
movl $TIP-0x4000+PAGE_V+PAGE_RW,%ds:0x1000 # PDTPD
movl $TIP-0x2000+PAGE_V+PAGE_RW,0x3000 # PML4TPDPT
movl $TIP-0x3000+PAGE_V+PAGE_RW,0x2000 # PDPTPDT
movl $TIP-0x4000+PAGE_V+PAGE_RW,0x1000 # PDTPD
mov $0x100000/0x1000,%cx # PD512kb
mov $PAGE_V+PAGE_RW,%eax
xor %si,%si
0: mov %eax,%ds:(%si)
0: mov %eax,(%si)
add $0x1000,%eax
add $8,%si
loop 0b
@ -1743,7 +1594,6 @@ pinit: push %bp @@ -1743,7 +1594,6 @@ pinit: push %bp
movl $TIP-0x4000,XLM(PAGE_TABLE_STACK_POINTER) # STACKXLM
mov $TIP-0x1000,%eax # PML4TCR3
mov %eax,%cr3
pop %bp
ret
.endfn pinit,globl,hidden
@ -1765,44 +1615,47 @@ golong: cli @@ -1765,44 +1615,47 @@ golong: cli
or $CR0_PE|CR0_PG|CR0_MP,%eax
and $~CR0_EM,%eax
mov %eax,%cr0
ljmp $GDT_LONG_CODE,$REAL(1f)
.code64
1: mov $GDT_LONG_DATA,%eax
mov %ax,%ds
mov %ax,%fs
mov %ax,%gs
xor %edx,%edx
jmp long
ljmp $GDT_LONG_CODE,$REAL(long)
.endfn golong
/ Long mode is long.
/
/ @noreturn
long: .frame0
xor %edi,%edi
call pageunmap
mov $e820map_xlm,%edi
call smapsort
mov $e820map_xlm,%edi
mov $g_pml4t,%esi
mov $g_ptsp_xlm,%edx
call flattenhighmemory
mov $REAL(.Lstr.hello),%edi
mov kBiosDataAreaXlm+METAL_STDOUT,%esi
call sputs
mov $kBiosDataAreaXlm+METAL_STDOUT,%edi
mov $4,%esi
call sflush
jmp triplf
lea triplf(%rip),%rdx
call _start
jmp triplf
.code64
long: push $GDT_LONG_DATA
pop %rax
mov %eax,%ds
mov %eax,%ss
mov %eax,%es
mov %eax,%fs
mov %eax,%gs
xor %ebp,%ebp
mov $REAL_STACK_FRAME+FRAMESIZE,%esp
call __map_image
mov $_metal,%eax
jmp *%rax
.endfn long
/ Long mode in virtual address space.
/ @noreturn
_metal:
#if USE_SYMBOL_HACK
.byte 0x0f,0x1f,0207 # nop rdi binbase
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
#endif
xor %eax,%eax # clear bss
mov $.Lape.bss.vaddr,%edi
mov $.Lape.bss.memsz,%ecx
rep stosb
movb $METAL,hostos(%rip)
push $0 # auxv
push $0
push $0 # envp
push $0 # auxv
push $0 # argc
xor %edi,%edi
jmp _start
.endfn _metal
/ Avoid linker script variables appearing as code in objdump.
.macro .ldsvar name:req
.type \name,@object

2
ape/config.h

@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
#define METAL_STDOUT COM1
#endif
#ifndef METAL_STDERR
#define METAL_STDERR COM2 /* will fallback to stdout if COM2 not present */
#define METAL_STDERR COM1
#endif
/**

12
ape/lib/getpagetableentry.c

@ -24,14 +24,16 @@ textreal static uint64_t pushpagetable(uint64_t *ptsp) { @@ -24,14 +24,16 @@ textreal static uint64_t pushpagetable(uint64_t *ptsp) {
return (*ptsp -= PAGESIZE) | PAGE_V | PAGE_RW;
}
textreal uint64_t *getpagetableentry(uint64_t vaddr, unsigned depth,
textreal uint64_t *getpagetableentry(int64_t vaddr, unsigned depth,
struct PageTable *pml4t, uint64_t *ptsp) {
uint64_t *entry;
unsigned char shift;
assert(depth <= 3);
assert(*ptsp % PAGESIZE == 0);
assert((intptr_t)pml4t % PAGESIZE == 0);
unsigned char shift = 39;
assert(!(*ptsp & 0xfff));
assert(!((uintptr_t)pml4t & 0xfff));
shift = 39;
for (;;) {
uint64_t *entry = &pml4t->p[(vaddr >> shift) & 511];
entry = &pml4t->p[(vaddr >> shift) & 511];
if (!depth--) return entry;
shift -= 9;
if (!*entry) *entry = pushpagetable(ptsp);

2
ape/lib/kbiosdataarea.S

@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
.size kBiosDataAreaXlm,XLM_BIOS_DATA_AREA_SIZE
kBiosDataAreaXlm = XLM(BIOS_DATA_AREA)
.section .sort.real.init.2.kBiosDataArea,"ax",@progbits
.section .sort.text.real.init.2.kBiosDataArea,"ax",@progbits
movpp %ds,%es # copy bios data to valid page
mov $PC_BIOS_DATA_AREA,%si
mov $XLM(BIOS_DATA_AREA),%di

38
ape/lib/mapimage.c

@ -0,0 +1,38 @@ @@ -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
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 "ape/lib/pc.h"
#include "ape/relocations.h"
#include "libc/runtime/runtime.h"
textreal static void __map_segment(uint64_t k, uint64_t a, uint64_t b) {
uint64_t *e;
for (; a < b; a += 0x1000) {
e = getpagetableentry(IMAGE_BASE_VIRTUAL + a, 3, &g_pml4t, &g_ptsp_xlm);
*e = (IMAGE_BASE_PHYSICAL + a) | k;
}
}
textreal void __map_image(void) {
pageunmap(0);
__map_segment(PAGE_V | PAGE_U, 0, (uintptr_t)_etext - IMAGE_BASE_VIRTUAL);
__map_segment(PAGE_V | PAGE_U | PAGE_RW | PAGE_XD,
(uintptr_t)_etext - IMAGE_BASE_VIRTUAL,
(uintptr_t)_end - IMAGE_BASE_VIRTUAL);
}

5
ape/lib/pageunmap.c

@ -20,8 +20,9 @@ @@ -20,8 +20,9 @@
#include "ape/lib/pc.h"
#include "libc/bits/bits.h"
textreal void pageunmap(uint64_t vaddr) {
uint64_t *entry = getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm);
textreal void pageunmap(int64_t vaddr) {
uint64_t *entry;
entry = getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm);
*entry &= ~PAGE_V;
invlpg(vaddr);
}

5
ape/lib/pc.h

@ -157,6 +157,7 @@ @@ -157,6 +157,7 @@
#define PAGE_1GB /* */ 0b110000000
#define PAGE_TA 0b11111111111111111111111111111111111111000000000000
#define PAGE_PA2 0b11111111111111111111111111111000000000000000000000
#define PAGE_XD 0x8000000000000000
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#include "ape/config.h"
@ -213,9 +214,9 @@ extern uint64_t g_ptsp_xlm; @@ -213,9 +214,9 @@ extern uint64_t g_ptsp_xlm;
void bootdr(char drive) noreturn;
void smapsort(struct SmapEntry *);
uint64_t *getpagetableentry(uint64_t, unsigned, struct PageTable *, uint64_t *);
uint64_t *getpagetableentry(int64_t, unsigned, struct PageTable *, uint64_t *);
void flattenhighmemory(struct SmapEntry *, struct PageTable *, uint64_t *);
void pageunmap(uint64_t);
void pageunmap(int64_t);
forceinline unsigned long eflags(void) {
unsigned long res;

26
examples/hidecursor.c

@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
#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/nt/console.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/consolecursorinfo.h"
#include "libc/nt/synchronization.h"
int main(int argc, char *argv[]) {
struct NtConsoleCursorInfo ntcursor;
SleepEx(1000, false);
GetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
ntcursor.bVisible = false;
SetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
SleepEx(1000, false);
ntcursor.bVisible = true;
SetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
SleepEx(1000, false);
return 0;
}

2
examples/package/build.mk

@ -27,7 +27,7 @@ EXAMPLES_PACKAGE_FILES := $(wildcard examples/package/*) @@ -27,7 +27,7 @@ EXAMPLES_PACKAGE_FILES := $(wildcard examples/package/*)
# Defines sets of files without needing further iops.
EXAMPLES_PACKAGE_SRCS = $(filter %.c,$(EXAMPLES_PACKAGE_FILES))
EXAMPLES_PACKAGE_HDRS = $(filter %.h,$(EXAMPLES_PACKAGE_FILES))
EXAMPLES_PACKAGE_COMS = $(EXAMPLES_PACKAGE_OBJS:%.o=%.com)
EXAMPLES_PACKAGE_COMS = $(EXAMPLES_PACKAGE_SRCS:%.c=o/$(MODE)/%.com)
EXAMPLES_PACKAGE_BINS = \
$(EXAMPLES_PACKAGE_COMS) \
$(EXAMPLES_PACKAGE_COMS:%=%.dbg)

2
libc/calls/hefty/spawnve-sysv.c

@ -84,7 +84,7 @@ int spawnve$sysv(unsigned flags, int stdiofds[3], const char *program, @@ -84,7 +84,7 @@ int spawnve$sysv(unsigned flags, int stdiofds[3], const char *program,
}
if (pid != -1) {
if ((pid = fork$sysv()) == 0) {
if ((pid = vfork()) == 0) {
if (flags & SPAWN_DETACH) {
if (setsid() == -1) abort();
if ((rc = fork$sysv()) == -1) abort();

1
libc/calls/kntwindowsdirectory.S

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/dce.h"
#include "libc/macros.h"
.source __FILE__

3
libc/crt/crt.S

@ -40,7 +40,8 @@ _start: test %rdi,%rdi @@ -40,7 +40,8 @@ _start: test %rdi,%rdi
lea 24(%rsp,%rbx,8),%rdx # envp
.frame0
/ bofram 9f
.weak idata.iat,idata.iatend
.weak idata.iat
.weak idata.iatend
ezlea missingno,ax # make win32 imps noop
ezlea idata.iat,di
ezlea idata.iatend,cx

1
libc/log/asan.c

@ -140,6 +140,7 @@ static const char *__asan_describe_access_poison(int c) { @@ -140,6 +140,7 @@ static const char *__asan_describe_access_poison(int c) {
case kAsanUnscoped:
return "unscoped";
default:
DebugBreak();
return "poisoned";
}
}

10
libc/macros.inc

@ -186,11 +186,6 @@ @@ -186,11 +186,6 @@
.endif
.endm
/ Custom emulator instruction for bottom stack frame.
.macro bofram endfunc:req
.byte 0x0f,0x1f,0x45,\endfunc-. # nopl disp8(%rbp)
.endm
/ Overrides LOOP instruction.
/ With its mop-Fusion Mexican equivalent.
/ Thus avoiding 3x legacy pipeline slowdown.
@ -330,3 +325,8 @@ _init_\name: @@ -330,3 +325,8 @@ _init_\name:
call *\symbol(%rip)
add $32,%rsp
.endm
/ Custom emulator instruction for bottom stack frame.
.macro bofram endfunc:req
.byte 0x0f,0x1f,0105,\endfunc-. # nopl disp8(%rbp)
.endm

16
libc/nexgen32e/rdtscp.h

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_RDTSCP_H_
#define COSMOPOLITAN_LIBC_NEXGEN32E_RDTSCP_H_
#include "libc/bits/bits.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -32,17 +33,26 @@ COSMOPOLITAN_C_START_ @@ -32,17 +33,26 @@ COSMOPOLITAN_C_START_
*/
#define rdpid() \
({ \
bool Ok; \
long Msr; \
Ok = false; \
if (X86_HAVE(RDPID)) { \
asm volatile("rdpid\t%0" : "=r"(Msr) : /* no inputs */ : "memory"); \
Ok = true; \
} else if (IsLinux()) { \
asm volatile("lsl\t%1,%0" : "=r"(Msr) : "r"(0x7b) : "memory"); \
} else if (X86_HAVE(RDTSCP)) { \
asm volatile(ZFLAG_ASM("lsl\t%2,%1") \
: ZFLAG_CONSTRAINT(Ok), "=r"(Msr) \
: "r"(0x7b) \
: "memory"); \
} \
if (!Ok && X86_HAVE(RDTSCP)) { \
asm volatile("rdtscp" \
: "=c"(Msr) \
: /* no inputs */ \
: "eax", "edx", "memory"); \
} else { \
Ok = true; \
} \
if (!Ok) { \
Msr = -1; \
} \
Msr; \

68
libc/nexgen32e/uart.h

@ -1,38 +1,3 @@ @@ -1,38 +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
αcτµαlly pδrταblε εxεcµταblε § telecommunications
*/
#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_UART_H_
#define COSMOPOLITAN_LIBC_NEXGEN32E_UART_H_
@ -53,22 +18,23 @@ @@ -53,22 +18,23 @@
* @see www.lammertbies.nl/comm/info/serial-uart.html
*/
#define COM1 0x0 /* offset in pc bios data area with port number (0x400) */
#define COM2 0x2
#define COM3 0x4
#define COM4 0x6
#define IRQ3 0x0b /* com2 interrupt number (irq3) */
#define IRQ4 0x0c /* com1 interrupt number (irq4) */
#define UART_DLAB (1 << 7) /* serial line conf mode bit */
#define UART_DLL 0 /* divisor latch register */
#define UART_DLM 1 /* divisor latch register */
#define UART_IIR 2 /* interrupt identification register */
#define UART_LCR 3 /* line control register */
#define UART_LSR 5 /* line status register */
#define UART_TTYDA (1 << 0) /* data available (rx ready) */
#define UART_TTYOE (1 << 1) /* overrun error */
#define UART_TTYPE (1 << 2) /* parity error */
#define UART_TTYFE (1 << 3) /* framing error */
#define COM1 0x0 /* offset in pc bios data area with port number (0x400) */
#define COM2 0x2
#define COM3 0x4
#define COM4 0x6
#define IRQ3 0x0b /* com2 interrupt number (irq3) */
#define IRQ4 0x0c /* com1 interrupt number (irq4) */
#define UART_DLAB (1 << 7) /* serial line conf mode bit */
#define UART_DLL 0 /* divisor latch register */
#define UART_DLM 1 /* divisor latch register */
#define UART_IIR 2 /* interrupt identification register */
#define UART_LCR 3 /* line control register */
#define UART_MCR 4 /* modem control register */
#define UART_LSR 5 /* line status register */
#define UART_TTYDA (1 << 0) /* data available (rx ready) */
#define UART_TTYOE (1 << 1) /* overrun error */
#define UART_TTYPE (1 << 2) /* parity error */
#define UART_TTYFE (1 << 3) /* framing error */
#define UART_TTYBSR (1 << 4) /* break signal received */
#define UART_TTYTXR (1 << 5) /* serial thr empty (tx ready) */
#define UART_TTYIDL (1 << 6) /* serial thr empty and line idle */

7
libc/stdio/serialstdio.c

@ -23,12 +23,12 @@ @@ -23,12 +23,12 @@
#include "libc/stdio/stdio.h"
static void fin(FILE *f) {
f->buf[f->end] = inb(f->fd);
f->buf[f->end] = inb(0x3F8);
f->end = (f->end + 1) & (f->size - 1);
}
static void fout(FILE *f) {
outb(f->fd, f->buf[f->beg]);
outb(0x3F8, f->buf[f->beg]);
f->beg = (f->beg + 1) & (f->size - 1);
}
@ -36,7 +36,7 @@ static int serialstdio(FILE *f, unsigned char status, void action(FILE *)) { @@ -36,7 +36,7 @@ static int serialstdio(FILE *f, unsigned char status, void action(FILE *)) {
int block = 1;
unsigned tally = 0;
while (f->end != f->beg) {
if (!(inb(f->fd + UART_LSR) & status)) {
if (!(inb(0x3F8 + UART_LSR) & status)) {
if (!block) break;
asm("pause");
} else {
@ -50,6 +50,7 @@ static int serialstdio(FILE *f, unsigned char status, void action(FILE *)) { @@ -50,6 +50,7 @@ static int serialstdio(FILE *f, unsigned char status, void action(FILE *)) {
int fsreadbuf(FILE *f) {
return serialstdio(f, UART_TTYDA, fin);
}
int fswritebuf(FILE *f) {
return serialstdio(f, UART_TTYTXR, fout);
}

92
libc/stdio/system.c

@ -19,54 +19,52 @@ @@ -19,54 +19,52 @@
*/
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/hefty/ntspawn.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/mem/mem.h"
#include "libc/nt/accounting.h"
#include "libc/nt/enum/startf.h"
#include "libc/nt/enum/status.h"
#include "libc/nt/files.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/startupinfo.h"
#include "libc/nt/struct/processinformation.h"
#include "libc/nt/synchronization.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/errfuns.h"
#include "libc/x/x.h"
#define SHELL_BIN "/bin/sh"
#define SHELL_ARG "-c"
#define CMD_C "CMD /C "
static int system$sysv(const char *cmdline) {
int rc, n, wstatus;
struct mem {
char shell[sizeof(SHELL_BIN)];
char arg[sizeof(SHELL_ARG)];
char *args[4];
char cmdline[];
} * mem;
if (cmdline != NULL) {
int pid = fork$sysv();
if (pid == 0) {
struct mem {
char shell[sizeof(SHELL_BIN)];
char arg[sizeof(SHELL_ARG)];
char *args[4];
char cmdline[];
} *mem = malloc(sizeof(struct mem) + (strlen(cmdline) + 1));
if (!mem) return enomem();
strcpy(mem->shell, SHELL_BIN);
strcpy(mem->arg, SHELL_ARG);
mem->args[0] = mem->shell;
mem->args[1] = mem->arg;
mem->args[2] = mem->cmdline;
mem->args[3] = NULL;
strcpy(mem->cmdline, cmdline);
execve$sysv(mem->shell, mem->args, environ);
abort();
mem = malloc(sizeof(struct mem) + (strlen(cmdline) + 1));
if (!mem) return enomem();
strcpy(mem->shell, SHELL_BIN);
strcpy(mem->arg, SHELL_ARG);
mem->args[0] = mem->shell;
mem->args[1] = mem->arg;
mem->args[2] = mem->cmdline;
mem->args[3] = NULL;
strcpy(mem->cmdline, cmdline);
if ((rc = vfork()) != -1) {
if (rc == 0) {
execve$sysv(mem->shell, mem->args, environ);
abort();
}
if ((rc = wait4$sysv(rc, &wstatus, 0, NULL)) != -1) {
rc = wstatus;
}
}
int rc;
int wstatus;
if ((rc = wait4$sysv(pid, &wstatus, 0, NULL)) != -1) rc = wstatus;
free(mem);
return rc;
} else {
return fileexists(SHELL_BIN);
@ -74,27 +72,32 @@ static int system$sysv(const char *cmdline) { @@ -74,27 +72,32 @@ static int system$sysv(const char *cmdline) {
}
static textwindows noinline int system$nt(const char *cmdline) {
char *mem;
int rc, status;
uint32_t dwExitCode;
struct NtStartupInfo startinfo;
struct NtProcessInformation *info;
uint16_t *cmdline16, *quotedcmdline16;
unsigned len, dosquotemultiplier, cmdline16bytes, quotedcmdline16bytes;
if (cmdline != NULL) {
int rc = -1;
unsigned dosquotemultiplier = 2;
unsigned len = strlen(cmdline);
unsigned cmdline16bytes = (len + 1) * sizeof(uint16_t);
unsigned quotedcmdline16bytes =
rc = -1;
dosquotemultiplier = 2;
len = strlen(cmdline);
cmdline16bytes = (len + 1) * sizeof(uint16_t);
quotedcmdline16bytes =
strlen(CMD_C) * sizeof(uint16_t) + cmdline16bytes * dosquotemultiplier;
void *mem = malloc(sizeof(struct NtProcessInformation) + cmdline16bytes +
quotedcmdline16bytes);
if (mem == NULL) return enomem();
struct NtProcessInformation *info = mem;
uint16_t *cmdline16 =
(uint16_t *)((char *)mem + sizeof(struct NtProcessInformation));
uint16_t *quotedcmdline16 =
(uint16_t *)((char *)mem + sizeof(struct NtProcessInformation) +
cmdline16bytes);
if (!(mem = malloc(sizeof(struct NtProcessInformation) + cmdline16bytes +
quotedcmdline16bytes))) {
return enomem();
}
info = (struct NtProcessInformation *)mem;
cmdline16 = (uint16_t *)(mem + sizeof(struct NtProcessInformation));
quotedcmdline16 = (uint16_t *)(mem + sizeof(struct NtProcessInformation) +
cmdline16bytes);
strcpyzbw(cmdline16, cmdline);
strcpyzbw(quotedcmdline16, CMD_C);
if (escapedos(quotedcmdline16 + strlen(CMD_C), len * dosquotemultiplier,
cmdline16, len)) {
struct NtStartupInfo startinfo;
memset(&startinfo, 0, sizeof(startinfo));
startinfo.cb = sizeof(struct NtStartupInfo);
startinfo.dwFlags = kNtStartfUsestdhandles;
@ -112,8 +115,7 @@ static textwindows noinline int system$nt(const char *cmdline) { @@ -112,8 +115,7 @@ static textwindows noinline int system$nt(const char *cmdline) {
/* lpCurrentDirectory */ NULL,
/* lpStartupInfo */ &startinfo,
/* lpProcessInformation */ info)) {
uint32_t dwExitCode = kNtStillActive;
int status;
dwExitCode = kNtStillActive;
do {
WaitForSingleObject(info->hProcess, 0xffffffff);
} while ((status = GetExitCodeProcess(info->hProcess, &dwExitCode)) &&
@ -130,7 +132,7 @@ static textwindows noinline int system$nt(const char *cmdline) { @@ -130,7 +132,7 @@ static textwindows noinline int system$nt(const char *cmdline) {
} else {
rc = einval();
}
free(mem), mem = NULL;
free(mem);
return rc;
} else {
/* how could cmd.exe not exist? */

7
libc/sysv/systemfive.S

@ -166,6 +166,8 @@ systemfive.xnu: @@ -166,6 +166,8 @@ systemfive.xnu:
.init.start 300,_init_systemfive
push %rbx
push %rsi
testb $METAL,(%rdi) # @see ape/ape.S
jnz systemfive.init.metal
testb $XNU,(%rdi) # @see libc/crt/crt.S
jnz systemfive.init.xnu
testb $FREEBSD,(%rdi) # @see libc/crt/crt.S
@ -181,6 +183,11 @@ systemfive.init.linux: @@ -181,6 +183,11 @@ systemfive.init.linux:
push $LINUX
ezlea syscon.linux,si
jmp systemfive.init.os
systemfive.init.metal:
pushb systemfive.linux-.Lanchorpoint
push $METAL
ezlea syscon.linux,si
jmp systemfive.init.os
systemfive.init.windows:
pushb systemfive.enosys-.Lanchorpoint
push $WINDOWS

6
test/dsp/core/getintegercoefficients_test.c

@ -41,11 +41,11 @@ TEST(GetIntegerCoefficients, testBt601Vectors) { @@ -41,11 +41,11 @@ TEST(GetIntegerCoefficients, testBt601Vectors) {
16,
235,
{.299, .587, .114, 1, 1, 1},
{612, 1202, IsTiny() ? 233 : 234, 2048, 2048, 2048}},
{612, 1202, NoDebug() ? 233 : 234,