Browse Source

Make minor improvements

- Work towards simplifying ape.S startup process
- Rewrote ar because it took minutes to build cosmopolitan.a
main
Justine Tunney 12 months ago
parent
commit
aea89fe832
  1. 166
      ape/ape.S
  2. 3
      ape/ape.lds
  3. 2
      ape/config.h
  4. 3
      ape/lib/mapimage.c
  5. 55
      build/archive
  6. BIN
      build/bootstrap/ar.com
  7. 4
      build/definitions.mk
  8. 2
      examples/printmysymbols.c
  9. 30
      libc/bits/bits.h
  10. 19
      libc/calls/calls.h
  11. 4
      libc/calls/calls.mk
  12. 53
      libc/calls/getdomainname.c
  13. 58
      libc/calls/gethostname.c
  14. 2
      libc/calls/getntsyspath.S
  15. 2
      libc/calls/internal.h
  16. 3
      libc/calls/renameat.c
  17. 54
      libc/calls/sync-nt.c
  18. 21
      libc/calls/sync.c
  19. 1
      libc/conv/itoa.h
  20. 35
      libc/conv/itoa64radix8.c
  21. 13
      libc/elf/elf.h
  22. 2
      libc/elf/getelfstringtable.c
  23. 2
      libc/elf/getelfsymboltable.c
  24. 2
      libc/elf/iself64binary.c
  25. 1
      libc/elf/struct/sym.h
  26. 2
      libc/fmt/strerror_r.c
  27. 6
      libc/log/oncrash.c
  28. 4
      libc/macros.inc
  29. 2
      libc/nexgen32e/crc32init.S
  30. 2
      libc/nexgen32e/imapxlatab.S
  31. 4
      libc/nexgen32e/kbase36.S
  32. 2
      libc/nexgen32e/ktolower.S
  33. 2
      libc/nexgen32e/ktoupper.S
  34. 2
      libc/nexgen32e/memjmpinit.S
  35. 2
      libc/nexgen32e/rldecode.S
  36. 10
      libc/nt/KernelBase/GetComputerNameExW.s
  37. 16
      libc/nt/enum/computernameformat.h
  38. 2
      libc/nt/master.sh
  39. 2
      libc/nt/memory.h
  40. 2
      libc/nt/nt.mk
  41. 3
      libc/nt/systeminfo.h
  42. 4
      libc/runtime/directmap.c
  43. 15
      libc/runtime/executive.S
  44. 1
      libc/runtime/internal.h
  45. 2
      libc/runtime/mapelfread.c
  46. 4
      libc/runtime/msync.c
  47. 4
      libc/runtime/opensymboltable.c
  48. 1
      libc/runtime/runtime.h
  49. 4
      libc/runtime/setstack.S
  50. 30
      libc/runtime/winmain.greg.c
  51. 91
      libc/str/str.h
  52. 2
      libc/str/strcspn.c
  53. 23
      libc/str/strcspn16.c
  54. 23
      libc/str/wcscspn.c
  55. 2
      libc/sysv/calls/gethostname.s
  56. 2
      libc/sysv/calls/sync-sysv.s
  57. 2
      libc/sysv/calls/sync.s
  58. 6
      libc/sysv/syscalls.sh
  59. 255
      tool/build/ar.c
  60. 84
      tool/build/blinkenlights.c
  61. 55
      tool/build/dropcache.c
  62. 4
      tool/build/lib/diself.c
  63. 4
      tool/build/lib/disspec.c
  64. 2
      tool/build/lib/elfwriter.c
  65. 34
      tool/build/lib/loader.c
  66. 66
      tool/build/package.c
  67. 1
      tool/build/zipobj.c
  68. 146
      tool/decode/ar.c
  69. 24
      tool/decode/elf.c
  70. 2
      tool/decode/lib/pollnames.S

166
ape/ape.S

@ -175,7 +175,7 @@ stub: mov $0x40,%dl # *literally* dos
built the last forty years these routines also canonicalize the
cpu and program state, as it is written in the System V ABI. */
/ Initializes program and jumps to long mode loader.
/ Initializes program and jumps to real mode loader.
/
/ @param dl drive number (use 0x40 to skip bios disk load)
/ @mode real
@ -188,62 +188,46 @@ pc: cld
#endif
mov $REAL_STACK_FRAME>>4,%di # we need a stack
xor %cx,%cx
mov %cx,%es
rlstack %di,%cx
movpp %cs,%ax # memcpy() [relocate this page]
push %cs # memcpy() [relocate this page]
pop %ds
call 1f
1: pop %si
sub $RVA(1b),%si
mov $4,%cl
1: shr %si
loop 1b
mov $512,%cx
mov $IMAGE_BASE_REAL>>4,%di
mov %si,%ds
mov %di,%es
xor %si,%si
mov $IMAGE_BASE_REAL>>4,%ax
push %ax # save real base
push %ax
pop %es
xor %di,%di
rep
movsb %ds:(%si),%es:(%di)
mov $512,%cx
rep movsb
#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
movsb %ds:(%si),%es:(%di)
xor %bp,%bp
mov %bp,%ds # %ds and %cs are now zero
call 1f # setup frame pointers
1: push %bp
mov %sp,%bp
mov $XLM_SIZE,%cx # memset() [clear real bss]
1: mov %cx,%ds # %ds and %cs are now zero
mov $XLM_SIZE,%cx # memset to clear real bss
mov $XLM_BASE_REAL>>4,%ax
mov %ax,%es
xor %ax,%ax
xor %di,%di
rep
stosb %al,%es:(%di)
rep stosb
cmp $0x40,%dl # statfs() [disk geometry]
je 6f
call dsknfo
mov $IMAGE_BASE_REAL>>4,%ax
mov %ax,%es
mov $v_ape_realsectors,%di # total sectors to read
xor %dh,%dh # current head state
xor %cx,%cx # current cylinder state
3: mov %di,%ax
call pcread
mov %es,%si
4: add $512>>4,%si
pop %es # restore real base
mov $1,%al # current sector
xor %cx,%cx # current cylinder
xor %dh,%dh # current head
mov $v_ape_realsectors,%di # total sectors
3: call pcread
dec %di
jz 6f
dec %ax
jnz 4b
mov %si,%es
jmp 3b
6: mov %cx,XLM(LOADSTATE)+0
mov %dx,XLM(LOADSTATE)+2
jnz 3b
6: mov %ax,XLM(LOADSTATE)+0
mov %cx,XLM(LOADSTATE)+2
mov %dx,XLM(LOADSTATE)+4
ljmp $0,$REAL(realmodeloader)
.endfn pc,globl,hidden
@ -334,66 +318,40 @@ dsknfo: push %bx
jmp 1b
.endfn dsknfo
/ Reads disk sectors via BIOS.
/ Reads disk sector via BIOS.
/
/ Each call to this function performs a single read. It has a
/ special ABI, where its parameters are preserved, and rolled
/ forward accordingly across calls. BIOS requirements on read
/ parameter validity are abstracted. If the requested size is
/ too large for one read, then it's tuned down appropriately.
/
/ Please note that dskinfo() must be called beforehand.
/
/ @param ax number sectors to read
/ @param al sector number
/ @param es destination memory address >> 4
/ @param cx cylinder number
/ @param dh head number
/ @param dl drive number
/ @return number of sectors actually read
pcread: push %bx
xor %bx,%bx
mov XLM(DRIVE_LAST_SECTOR),%bl
cmp %ax,%bx # ax = min(ax, pertrack)
ja 1f
mov %bx,%ax
1: push %cx # how many sectors until 64k
push %ax # boundary reads can't cross
mov $0x1000,%bx # canonicalizing the segment
mov %es,%ax # register is not sufficient
sub %ax,%bx
and $0x0fff,%bx
mov $5,%cx
0: shr %bx
loop 0b
pop %ax
pop %cx
test %bx,%bx # %es 64k-aligned edge case
jz 1f
cmp %ax,%bx # ax = min(ax, remain64k)
ja 1f
mov %bx,%ax
1: push %ax # setup int-13-2() params
pcread: push %ax
push %cx
xchg %cl,%ch
ror %cl
ror %cl
or $1,%cl # one cylinder at a time
or %al,%cl
xor %bx,%bx # es:bx is destination addr
mov $0x02,%ah # read disk sectors ordinal
mov $1,%al # read only one disk sector
mov $2,%ah # read disk sectors ordinal
int $0x13
pop %cx
pop %bx
pop %ax
jc 9f
mov $0,%ah
cmp %ax,%bx
jl 9f
mov %es,%si
add $512>>4,%si
mov %si,%es
inc %al
cmp XLM(DRIVE_LAST_SECTOR),%al
jbe 2f
mov $1,%al
inc %cx
cmp XLM(DRIVE_LAST_CYLINDER),%cx
jle 2f
jbe 2f
xor %cx,%cx
inc %dh
2: pop %bx
ret
2: ret
9: push %ax
xor %ax,%ax # try disk reset on error
int $0x13
@ -824,11 +782,11 @@ ape.pe: .ascin "PE",4
.long 0 # Checksum
.short v_ntsubsystem # Subsystem: 0=Neutral,2=GUI,3=Console
.short .LDLLEXE # DllCharacteristics
.quad 0x0000000000100000 # StackReserve
.quad 0x0000000000100000 # StackCommit
.quad 0x0000000000000000 # HeapReserve
.quad 0x0000000000000000 # HeapCommit
.long 0x00000000 # LoaderFlags
.quad 0x0000000000080000 # StackReserve
.quad 0x0000000000080000 # StackCommit
.quad 0 # HeapReserve
.quad 0 # HeapCommit
.long 0 # LoaderFlags
.long 16 # NumberOfDirectoryEntries
.long 0,0 # ExportsDirectory
.long RVA(idata.idt) # ImportsDirectory
@ -857,10 +815,10 @@ ape.pe: .ascin "PE",4
.stub .Lape.text.rva,long # Relative Virtual Address
.stub .Lape.text.filesz,long # Physical Size
.stub .Lape.text.offset,long # Physical Offset
.long 0x00000000 # Relocation Table Offset
.long 0x00000000 # Line Number Table Offset
.short 0x0000 # Relocation Count
.short 0x0000 # Line Number Count
.long 0 # Relocation Table Offset
.long 0 # Line Number Table Offset
.short 0 # Relocation Count
.short 0 # Line Number Count
.long .LPETEXT # Flags
.previous
@ -870,10 +828,10 @@ ape.pe: .ascin "PE",4
.stub .Lape.ram.rva,long # Relative Virtual Address
.stub .Lape.ram.filesz,long # Physical Size
.stub .Lape.ram.offset,long # Physical Offset
.long 0x00000000 # Relocation Table Offset
.long 0x00000000 # Line Number Table Offset
.short 0x0000 # Relocation Count
.short 0x0000 # Line Number Count
.long 0 # Relocation Table Offset
.long 0 # Line Number Table Offset
.short 0 # Relocation Count
.short 0 # Line Number Count
.long .LPEDATA # Flags
.previous
@ -1246,7 +1204,8 @@ sflush: mov %si,%cx
mov $UART_TTYIDL,%ah
1: in %dx,%al
and %ah,%al
rep nop # todo(jart): interrupts are better
rep
nop
jz 1b
loop 0b
2: ret
@ -1269,7 +1228,8 @@ sputc: push %ax
1: in %dx,%al
and %ah,%al
jnz 2f
rep nop # todo(jart): interrupts are better
rep
nop
jmp 1b
2: mov %di,%ax
mov %si,%dx
@ -1356,7 +1316,7 @@ longmodeloader:
call e820
jc 9f
call unreal
call hiload
/ call hiload
jmp golong
9: mov $REAL(.Lstr.e820),%ax
call rldie
@ -1478,8 +1438,9 @@ hiload: push %bx
mov $v_ape_highsectors,%di # then copy rest off disk
mov $REAL_SCRATCH_AREA>>4,%ax # to real memory buffer
mov %ax,%es
mov XLM(LOADSTATE)+0,%cx
mov XLM(LOADSTATE)+2,%dx
mov XLM(LOADSTATE)+0,%ax
mov XLM(LOADSTATE)+2,%cx
mov XLM(LOADSTATE)+4,%dx
0: test %di,%di
jz 9f
mov %di,%ax
@ -1590,6 +1551,7 @@ pinit: push %ds
add $0x1000,%eax
add $8,%si
loop 0b
movb $0,0 # unmap null
pop %ds
movl $TIP-0x4000,XLM(PAGE_TABLE_STACK_POINTER) # STACKXLM
mov $TIP-0x1000,%eax # PML4TCR3
@ -1631,13 +1593,13 @@ long: push $GDT_LONG_DATA
xor %ebp,%ebp
mov $REAL_STACK_FRAME+FRAMESIZE,%esp
call __map_image
ezlea _metal,ax
ezlea metal,ax
jmp *%rax
.endfn long
/ Long mode in virtual address space.
/ @noreturn
_metal:
metal:
#if USE_SYMBOL_HACK
.byte 0x0f,0x1f,0207 # nop rdi binbase
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
@ -1658,7 +1620,7 @@ _metal:
push $0 # argc
xor %edi,%edi
jmp _start
.endfn _metal
.endfn metal
/ Avoid linker script variables appearing as code in objdump.
.macro .ldsvar name:req

3
ape/ape.lds

@ -537,7 +537,8 @@ HIDDEN(.Lape.bss.align = .Lape.data.align);
/* Program Loader Auto-Tune */
HIDDEN(v_ape_realsectors =
MIN(REAL_SCRATCH_AREA - IMAGE_BASE_REAL,
ROUNDUP(RVA(_edata), 512)) / 512);
ROUNDUP(RVA(_edata), 4096)) / 512);
HIDDEN(v_ape_realpages = v_ape_realsectors / (4096 / 512));
HIDDEN(v_ape_highsectors =
(ROUNDUP(RVA(_edata), 512) / 512) - v_ape_realsectors);

2
ape/config.h

@ -126,7 +126,7 @@
#define XLM_BADIDT 0x2230
#define XLM_BADIDT_SIZE 6
#define XLM_LOADSTATE 0x2240
#define XLM_LOADSTATE_SIZE 4
#define XLM_LOADSTATE_SIZE 6
#define XLM_SIZE ROUNDUP(XLM_LOADSTATE + XLM_LOADSTATE_SIZE, 0x1000)
#define IMAGE_BASE_REAL (XLM_BASE_REAL + XLM_SIZE)

3
ape/lib/mapimage.c

@ -25,12 +25,11 @@ 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;
*e = (IMAGE_BASE_REAL + 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,

55
build/archive

@ -4,57 +4,28 @@
#
# OVERVIEW
#
# GNU Archiver Veneer
# Cosmopolitan Archiver
#
# DESCRIPTION
#
# This script wraps normal archive commands that're transparently
# passed-through. It adds value too, by addressing difficulties
# that would normally cause a developer to need `make clean`.
# This goes 100x faster than ar and ranlib.
#
# EXAMPLE
#
# build/archive ar rcsD library.a foo.o ...
# build/archive rcsD library.a foo.o ...
if [ ! -d o/third_party/gcc ]; then
third_party/gcc/unbundle.sh
fi
export LC_ALL=C
RM=${RM:-$(command -v rm) -f} || exit
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
AR=$1
ARFLAGS=$2
OUT=$3
shift 3
# remove directory arguments (having .a targets depend on dirs is what
# lets them be invalidated by deleted files)
FIRST=1
for x; do
if [ $FIRST -eq 1 ]; then
set --
FIRST=0
fi
if [ -d "$x" ]; then
if [ -f "$OUT" ] && [ "$x" -nt "$OUT" ]; then
$RM "$OUT"
fi
continue
fi
if [ "$x" != "${x%.o}" ]; then
set -- "$@" "$x"
fi
done
set -- "$AR" "$ARFLAGS" "$OUT" "$@"
printf %s\\n "$*" >"$OUT.cmd"
OUTDIR="${OUT%/*}"
if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then
$MKDIR "$OUTDIR" || exit 2
# if [ -x "o/$MODE/tool/build/ar.com" ]; then
# set -- "o/$MODE/tool/build/ar.com" "$@"
# else
if [ ! -x o/build/bootstrap/ar.com ]; then
mkdir -p o/build/bootstrap &&
cp -f build/bootstrap/ar.com o/build/bootstrap/ar.com.$$ &&
mv -f o/build/bootstrap/ar.com.$$ o/build/bootstrap/ar.com || exit
fi
set -- o/build/bootstrap/ar.com "$@"
# fi
OUT=$3
printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2
# if [ "$SILENT" = "0" ]; then

BIN
build/bootstrap/ar.com

4
build/definitions.mk

@ -65,7 +65,7 @@ CC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
CXX = o/third_party/gcc/bin/x86_64-linux-musl-g++
CXXFILT = o/third_party/gcc/bin/x86_64-linux-musl-c++filt
LD = o/third_party/gcc/bin/x86_64-linux-musl-ld.bfd
AR = o/third_party/gcc/bin/x86_64-linux-musl-ar
AR = build/archive
NM = o/third_party/gcc/bin/x86_64-linux-musl-nm
GCC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
STRIP = o/third_party/gcc/bin/x86_64-linux-musl-strip
@ -295,7 +295,7 @@ PREPROCESS.lds = $(CC) $(PREPROCESS.lds.flags)
LINK = build/link $(LD) $(LINK.flags)
ELF = o/libc/elf/elf.lds
ELFLINK = ACTION=LINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION)
ARCHIVE = build/archive $(AR) $(ARFLAGS)
ARCHIVE = $(AR) $(ARFLAGS)
LINKARGS = $(patsubst %.lds,-T %.lds,$(call uniqr,$(LD.libs) $(filter-out %.pkg,$^)))
LOLSAN = build/lolsan -b $(IMAGE_BASE_VIRTUAL)

2
examples/printmysymbols.c

@ -23,7 +23,7 @@ int main(int argc, char *argv[]) {
(tab = OpenSymbolTable(filename))) {
for (unsigned i = 0; i < tab->count; ++i) {
printf("%p %s\n", tab->addr_base + tab->symbols[i].addr_rva,
getelfstring(tab->elf, tab->elfsize, tab->name_base,
GetElfString(tab->elf, tab->elfsize, tab->name_base,
tab->symbols[i].name_rva));
}
} else {

30
libc/bits/bits.h

@ -148,6 +148,36 @@ unsigned long hamming(unsigned long, unsigned long) pureconst;
Ple[7] = (uint8_t)(Vle >> 070); \
} while (0)
#define WRITE16BE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint16_t Vle = (V); \
Ple[1] = (uint8_t)(Vle >> 000); \
Ple[0] = (uint8_t)(Vle >> 010); \
} while (0)
#define WRITE32BE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint32_t Vle = (V); \
Ple[3] = (uint8_t)(Vle >> 000); \
Ple[2] = (uint8_t)(Vle >> 010); \
Ple[1] = (uint8_t)(Vle >> 020); \
Ple[0] = (uint8_t)(Vle >> 030); \
} while (0)
#define WRITE64BE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint64_t Vle = (V); \
Ple[7] = (uint8_t)(Vle >> 000); \
Ple[6] = (uint8_t)(Vle >> 010); \
Ple[5] = (uint8_t)(Vle >> 020); \
Ple[4] = (uint8_t)(Vle >> 030); \
Ple[3] = (uint8_t)(Vle >> 040); \
Ple[2] = (uint8_t)(Vle >> 050); \
Ple[1] = (uint8_t)(Vle >> 060); \
Ple[0] = (uint8_t)(Vle >> 070); \
} while (0)
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § bits » some assembly required
*/

19
libc/calls/calls.h

@ -79,12 +79,12 @@ bool isexecutable(const char *);
bool isregularfile(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 *getcwd(char *, size_t);
char *realpath(const char *, char *);
char *replaceuser(const char *) nodiscard;
char *ttyname(int);
char *commandv(const char *, char[hasatleast PATH_MAX]);
int access(const char *, int) nothrow;
int arch_prctl();
int chdir(const char *);
@ -120,6 +120,8 @@ int fstat(int, struct stat *);
int fstatat(int, const char *, struct stat *, uint32_t);
int fsync(int);
int ftruncate(int, int64_t);
int getdomainname(char *, size_t);
int gethostname(char *, size_t);
int getppid(void);
int getpriority(int, unsigned);
int getrlimit(int, struct rlimit *);
@ -161,18 +163,18 @@ int rmdir(const char *);
int sched_getaffinity(int, uint64_t, void *);
int sched_setaffinity(int, uint64_t, const void *);
int sched_yield(void);
int setegid(uint32_t);
int seteuid(uint32_t);
int setgid(uint32_t);
int setpgid(int, int);
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 setreuid(uint32_t, uint32_t);
int setrlimit(int, const struct rlimit *);
int setsid(void);
int setuid(uint32_t);
int setgid(uint32_t);
int seteuid(uint32_t);
int setegid(uint32_t);
int setreuid(uint32_t, uint32_t);
int setregid(uint32_t, uint32_t);
int setresuid(uint32_t, uint32_t, uint32_t);
int setresgid(uint32_t, uint32_t, uint32_t);
int sigaction(int, const struct sigaction *, struct sigaction *);
int sigignore(int);
int sigprocmask(int, const struct sigset *, struct sigset *);
@ -200,6 +202,7 @@ int64_t preadv(int, struct iovec *, int, int64_t);
int64_t pwrite(int, const void *, size_t, int64_t);
int64_t pwritev(int, const struct iovec *, int, int64_t);
int64_t syscall();
void sync(void);
long telldir(DIR *);
int getpid(void);
long times(struct tms *);

4
libc/calls/calls.mk

@ -16,10 +16,10 @@ LIBC_CALLS_ARTIFACTS += LIBC_CALLS_A
LIBC_CALLS = $(LIBC_CALLS_A_DEPS) $(LIBC_CALLS_A)
LIBC_CALLS_A = o/$(MODE)/libc/calls/syscalls.a
LIBC_CALLS_A_FILES := \
$(wildcard libc/calls/*) \
$(wildcard libc/calls/typedef/*) \
$(wildcard libc/calls/thunks/*) \
$(wildcard libc/calls/struct/*) \
$(wildcard libc/calls/*)
$(wildcard libc/calls/struct/*)
LIBC_CALLS_A_HDRS = $(filter %.h,$(LIBC_CALLS_A_FILES))
LIBC_CALLS_A_SRCS_S = $(filter %.S,$(LIBC_CALLS_A_FILES))
LIBC_CALLS_A_SRCS_C = $(filter %.c,$(LIBC_CALLS_A_FILES))

53
libc/calls/getdomainname.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
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/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/utsname.h"
#include "libc/dce.h"
#include "libc/macros.h"
#include "libc/nt/enum/computernameformat.h"
#include "libc/nt/errors.h"
#include "libc/nt/runtime.h"
#include "libc/nt/systeminfo.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
int getdomainname(char *name, size_t len) {
uint32_t nSize;
char16_t name16[256];
struct utsname u;
if (len < 1) return einval();
if (!name) return efault();
if (!IsWindows()) {
if (uname(&u) == -1) return -1;
if (!memccpy(name, u.domainname[0] ? u.domainname : u.nodename, '\0',
len)) {
name[len - 1] = '\0';
}
return 0;
} else {
nSize = ARRAYLEN(name16);
if (!GetComputerNameEx(kNtComputerNameDnsFullyQualified, name16, &nSize)) {
return winerr();
}
tprecode16to8(name, MIN(MIN(ARRAYLEN(name16), nSize + 1), len), name16);
return 0;
}
}

58
libc/calls/gethostname.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 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/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/utsname.h"
#include "libc/dce.h"
#include "libc/macros.h"
#include "libc/nt/enum/computernameformat.h"
#include "libc/nt/errors.h"
#include "libc/nt/runtime.h"
#include "libc/nt/systeminfo.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
/**
* Returns name of host system, e.g.
*
* pheidippides.domain.example
* ^^^^^^^^^^^^
*/
int gethostname(char *name, size_t len) {
uint32_t nSize;
char16_t name16[256];
struct utsname u;
if (len < 1) return einval();
if (!name) return efault();
if (!IsWindows()) {
if (uname(&u) == -1) return -1;
if (!memccpy(name, u.nodename, '\0', len)) {
name[len - 1] = '\0';
}
return 0;
} else {
nSize = ARRAYLEN(name16);
if (!GetComputerNameEx(kNtComputerNameDnsHostname, name16, &nSize)) {
return winerr();
}
tprecode16to8(name, MIN(MIN(ARRAYLEN(name16), nSize + 1), len), name16);
return 0;
}
}

2
libc/calls/getntsyspath.S

@ -49,7 +49,7 @@ __getntsyspath:
cmpb $'\\,-1(%rdi)
jne 2f
movb $'/,-1(%rdi)
2: loop 1b
2: .loop 1b
leave
ret
.endfn __getntsyspath,globl,hidden

2
libc/calls/internal.h

@ -161,6 +161,7 @@ i32 sigaction$sysv(i32, const void *, void *, i64) hidden;
i32 sigprocmask$sysv(i32, const sigset *, sigset *, u64) hidden;
i32 sigsuspend$sysv(const sigset *, u64) hidden;
i32 symlinkat$sysv(const char *, i32, const char *) hidden;
i32 sync$sysv(void) hidden;
i32 sync_file_range$sysv(i32, i64, i64, u32) hidden;
i32 sysinfo$sysv(struct sysinfo *) hidden;
i32 truncate$sysv(const char *, u64) hidden;
@ -239,6 +240,7 @@ int rename$nt(const char *, const char *) hidden;
int rmdir$nt(const char *) hidden;
int sched_yield$nt(void) hidden;
int stat$nt(const char *, struct stat *) hidden;
int sync$nt(void) hidden;
int symlink$nt(const char *, const char *) hidden;
int sysinfo$nt(struct sysinfo *) hidden;
int truncate$nt(const char *, u64) hidden;

3
libc/calls/renameat.c

@ -21,6 +21,9 @@
#include "libc/calls/internal.h"
#include "libc/sysv/consts/at.h"
/**
* Renames files relative to directories.
*/
int renameat(int olddirfd, const char *oldpath, int newdirfd,
const char *newpath) {
unsigned mode;

54
libc/calls/sync-nt.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
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/calls.h"
#include "libc/calls/internal.h"
#include "libc/nt/createfile.h"
#include "libc/nt/files.h"
#include "libc/nt/runtime.h"
#include "libc/sysv/consts/ok.h"
/**
* Flushes all open file handles and, if possible, all disk drives.
*/
int sync$nt(void) {
unsigned i;
int64_t volume;
uint32_t drives;
char16_t path[] = u"\\\\.\\C:";
for (i = 0; i < g_fds.n; ++i) {
if (g_fds.p[i].kind == kFdFile) {
FlushFileBuffers(g_fds.p[i].handle);
}
}
for (drives = GetLogicalDrives(), i = 0; i <= 'Z' - 'A'; ++i) {
if (!(drives & (1 << i))) continue;
path[4] = 'A' + i;
if (ntaccesscheck(path, R_OK | W_OK) != -1) {
if ((volume = CreateFile(
path, kNtFileReadAttributes,
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, 0,
kNtOpenExisting, 0, 0)) != -1) {
FlushFileBuffers(volume);
CloseHandle(volume);
}
}
}
return 0;
}

21
libc/runtime/getstack.c → libc/calls/sync.c

@ -18,19 +18,16 @@
02110-1301 USA
*/
#include "libc/calls/calls.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
/**
* Allocates deterministic stack for process.
* @see _executive()
* Flushes file system changes to disk to the greatest extent possible.
*/
void *_getstack(void) {
char *p;
p = mmap((char *)0x700000000000 /* IMAGE_BASE_VIRTUAL */ - STACKSIZE,
STACKSIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED) abort();
return p + STACKSIZE;
void sync(void) {
if (!IsWindows()) {
sync$sysv();
} else {
sync$nt();
}
}

1
libc/conv/itoa.h

@ -22,6 +22,7 @@ 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);
size_t uint64toarray_radix8(uint64_t, char[hasatleast 24]);
#ifndef __STRICT_ANSI__
size_t int128toarray_radix10(int128_t, char *);

35
libc/elf/getelfsectionbyaddress.c → libc/conv/itoa64radix8.c

@ -17,21 +17,24 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/elf/def.h"
#include "libc/elf/elf.h"
#include "libc/alg/reverse.h"
#include "libc/conv/conv.h"
#include "libc/conv/itoa.h"
#include "libc/limits.h"
Elf64_Shdr *getelfsectionbyaddress(const Elf64_Ehdr *elf, size_t mapsize,
void *addr) {
Elf64_Half i;
Elf64_Shdr *shdr;
if (elf) {
for (i = elf->e_shnum; i > 0; --i) {
shdr = getelfsectionheaderaddress(elf, mapsize, i - 1);
if ((intptr_t)addr >= shdr->sh_addr &&
(intptr_t)addr < shdr->sh_addr + shdr->sh_size) {
return shdr;
}
}
}
return NULL;
/**
* Converts unsigned 64-bit integer to octal string.
* @param a needs at least 24 bytes
* @return bytes written w/o nul
*/
noinline size_t uint64toarray_radix8(uint64_t i, char a[hasatleast 24]) {
size_t j;
j = 0;
do {
a[j++] = i % 8 + '0';
i /= 8;
} while (i > 0);
a[j] = '\0';
reverse(a, j);
return j;
}

13
libc/elf/elf.h

@ -20,10 +20,9 @@ COSMOPOLITAN_C_START_
struct MappedFile;
Elf64_Ehdr *mapelfread(const char *, struct MappedFile *);
char *getelfstringtable(const Elf64_Ehdr *, size_t);
Elf64_Sym *getelfsymboltable(const Elf64_Ehdr *, size_t, Elf64_Xword *);
Elf64_Shdr *getelfsectionbyaddress(const Elf64_Ehdr *, size_t, void *);
bool iself64binary(const Elf64_Ehdr *, size_t);
char *GetElfStringTable(const Elf64_Ehdr *, size_t);
Elf64_Sym *GetElfSymbolTable(const Elf64_Ehdr *, size_t, Elf64_Xword *);
bool IsElf64Binary(const Elf64_Ehdr *, size_t);
forceinline void checkelfaddress(const Elf64_Ehdr *elf, size_t mapsize,
intptr_t addr, size_t addrsize) {
@ -94,7 +93,7 @@ static inline void getelfvirtualaddressrange(const Elf64_Ehdr *elf,
if (out_end) *out_end = end;
}
static inline char *getelfstring(const Elf64_Ehdr *elf, size_t mapsize,
static inline char *GetElfString(const Elf64_Ehdr *elf, size_t mapsize,
const char *strtab, Elf64_Word rva) {
intptr_t addr = (intptr_t)strtab + rva;
#if !(TRUSTWORTHY + ELF_TRUSTWORTHY + 0)
@ -105,10 +104,10 @@ static inline char *getelfstring(const Elf64_Ehdr *elf, size_t mapsize,
return (char *)addr;
}
static inline const char *getelfsectionname(const Elf64_Ehdr *elf,
static inline const char *GetElfSectionName(const Elf64_Ehdr *elf,
size_t mapsize, Elf64_Shdr *shdr) {
if (!elf || !shdr) return NULL;
return getelfstring(elf, mapsize, getelfsectionnamestringtable(elf, mapsize),
return GetElfString(elf, mapsize, getelfsectionnamestringtable(elf, mapsize),
shdr->sh_name);
}

2
libc/elf/getelfstringtable.c

@ -20,7 +20,7 @@
#include "libc/elf/def.h"
#include "libc/elf/elf.h"
char *getelfstringtable(const Elf64_Ehdr *elf, size_t mapsize) {
char *GetElfStringTable(const Elf64_Ehdr *elf, size_t mapsize) {
Elf64_Half i;
Elf64_Shdr *shdr;
for (i = elf->e_shnum; i > 0; --i) {

2
libc/elf/getelfsymboltable.c

@ -20,7 +20,7 @@
#include "libc/elf/def.h"
#include "libc/elf/elf.h"
Elf64_Sym *getelfsymboltable(const Elf64_Ehdr *elf, size_t mapsize,
Elf64_Sym *GetElfSymbolTable(const Elf64_Ehdr *elf, size_t mapsize,
Elf64_Xword *out_count) {
Elf64_Half i;
Elf64_Shdr *shdr;

2
libc/elf/iself64binary.c

@ -19,7 +19,7 @@
*/
#include "libc/elf/elf.h"
bool iself64binary(const Elf64_Ehdr *elf, size_t mapsize) {
bool IsElf64Binary(const Elf64_Ehdr *elf, size_t mapsize) {
if (mapsize < sizeof(Elf64_Ehdr)) return false;
if (memcmp(elf->e_ident, ELFMAG, 4)) return false;
return (elf->e_ident[EI_CLASS] == ELFCLASSNONE ||

1
libc/elf/struct/sym.h

@ -10,6 +10,7 @@ typedef struct Elf64_Sym {
uint8_t st_info;
/* STV_{DEFAULT,INTERNAL,HIDDEN,PROTECTED} */
uint8_t st_other;
/* SHN_UNDEF, <section index>, SHN_ABS, SHN_COMMON, etc. */
Elf64_Section st_shndx;
Elf64_Addr st_value;
Elf64_Xword st_size;

2
libc/fmt/strerror_r.c

@ -63,7 +63,7 @@ int strerror_r(int err, char *buf, size_t size) {
if (FormatMessage(
kNtFormatMessageFromSystem | kNtFormatMessageIgnoreInserts, NULL,
err, 0, buf16, ARRAYLEN(buf16) - 1, 0) > 0) {
chomp(buf16);
chomp16(buf16);
} else {
buf16[0] = u'\0';
}

6
libc/log/oncrash.c

@ -152,6 +152,7 @@ relegated static void ShowMemoryMappings(int outfd) {
relegated static void ShowCrashReport(int err, int fd, int sig,
ucontext_t *ctx) {
int i;
struct utsname names;
(dprintf)(fd, VEIL("r", "\r\n%serror%s: Uncaught SIG%s\r\n %s\r\n %s\r\n"),
RED2, RESET, TinyStrSignal(sig), getauxval(AT_EXECFN),
@ -167,6 +168,11 @@ relegated static void ShowCrashReport(int err, int fd, int sig,
}
write(fd, "\r\n", 2);
ShowMemoryMappings(fd);
write(fd, "\r\n", 2);
for (i = 0; i < g_argc; ++i) {
write(fd, g_argv[i], strlen(g_argv[i]));
write(fd, "\r\n", 2);
}
}
relegated static void RestoreDefaultCrashSignalHandlers(void) {

4
libc/macros.inc

@ -186,10 +186,10 @@
.endif
.endm
/ Overrides LOOP instruction.
/ LOOP Instruction Replacement.
/ With its mop-Fusion Mexican equivalent.
/ Thus avoiding 3x legacy pipeline slowdown.
.macro loop label:req
.macro .loop label:req
.byte 0x83,0xe9,0x01 # sub $1,%ecx
jnz \label
.endm

2
libc/nexgen32e/crc32init.S

@ -59,7 +59,7 @@ crc32init:
pand %xmm0,%xmm3
pxor %xmm4,%xmm3
movdqa %xmm3,%xmm4
loop 2b
.loop 2b
movdqu %xmm3,(%rdi)
add $16,%rdi
paddd %xmm2,%xmm1

2
libc/nexgen32e/imapxlatab.S

@ -35,7 +35,7 @@ imapxlatab:
.align 8
1: stosq
add %rdx,%rax
loop 1b
.loop 1b
.leafepilogue
.endfn imapxlatab,globl,hidden
.source __FILE__

4
libc/nexgen32e/kbase36.S

@ -35,13 +35,13 @@ kBase36:.zero 256
pushpop 10,%rcx
0: inc %eax
stosb
loop 0b
.loop 0b
add $'A-1-'9,%rdi
pushpop 'Z+1-'A,%rcx
0: inc %eax
mov %al,0x20(%rdi)
stosb
loop 0b
.loop 0b
add $255-'Z,%rdi
.init.end 300,_init_kBase36
.source __FILE__

2
libc/nexgen32e/ktolower.S

@ -51,7 +51,7 @@ kToLower16:
mov $256,%ecx
0: lodsb
stosw
loop 0b
.loop 0b
pop %rsi
.init.end 300,_init_kToLower

2
libc/nexgen32e/ktoupper.S

@ -30,6 +30,6 @@ kToUpper:
call imapxlatab
pushpop 'z-'a,%rcx
0: subb $0x20,(%r8,%rcx)
loop 0b
.loop 0b
.init.end 300,_init_kToUpper
.source __FILE__

2
libc/nexgen32e/memjmpinit.S

@ -36,7 +36,7 @@ memjmpinit:
lodsb
add %rdx,%rax
stosq
loop 0b
.loop 0b
xor %eax,%eax
testb X86_HAVE(ERMS)+kCpuids(%rip)
setnz %al

2
libc/nexgen32e/rldecode.S

@ -34,7 +34,7 @@ rldecode:
lodsb
jrcxz 2f
1: stosb
loop 1b
.loop 1b
jmp 0b
2: .leafepilogue
.endfn rldecode,globl

10
libc/nt/KernelBase/GetComputerNameExW.s

@ -1,2 +1,12 @@
.include "o/libc/nt/codegen.inc"
.imp KernelBase,__imp_GetComputerNameExW,GetComputerNameExW,449
.text.windows
GetComputerNameEx:
push %rbp
mov %rsp,%rbp
.profilable
mov __imp_GetComputerNameExW(%rip),%rax
jmp __sysv2nt
.endfn GetComputerNameEx,globl
.previous

16
libc/nt/enum/computernameformat.h

@ -0,0 +1,16 @@
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_COMPUTERNAMEFORMAT_H_
#define COSMOPOLITAN_LIBC_NT_ENUM_COMPUTERNAMEFORMAT_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#define kNtComputerNameNetBios 0
#define kNtComputerNameDnsHostname 1
#define kNtComputerNameDnsDomain 2
#define kNtComputerNameDnsFullyQualified 3
#define kNtComputerNamePhysicalNetBios 4
#define kNtComputerNamePhysicalDnsHostname 5
#define kNtComputerNamePhysicalDnsDomain 6
#define kNtComputerNamePhysicalDnsFullyQualified 7
#define kNtComputerName_MAX 8
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_COMPUTERNAMEFORMAT_H_ */

2
libc/nt/master.sh

@ -1979,7 +1979,7 @@ imp 'GetCompressedFileSizeTransactedA' GetCompressedFileSizeTransactedA kern
imp 'GetCompressedFileSizeTransacted' GetCompressedFileSizeTransactedW kernel32 479
imp 'GetComputerNameA' GetComputerNameA kernel32 481
imp 'GetComputerNameExA' GetComputerNameExA KernelBase 448
imp 'GetComputerNameEx' GetComputerNameExW KernelBase 449
imp 'GetComputerNameEx' GetComputerNameExW KernelBase 449 3
imp 'GetComputerName' GetComputerNameW kernel32 484
imp 'GetConsoleAliasA' GetConsoleAliasA KernelBase 450
imp 'GetConsoleAliasExesA' GetConsoleAliasExesA KernelBase 451

2
libc/nt/memory.h

@ -46,12 +46,14 @@ int64_t CreateFileMappingNuma(
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);
bool32 UnmapViewOfFile(const void *lpBaseAddress);
bool32 FlushViewOfFile(const void *lpBaseAddress,
size_t dwNumberOfBytesToFlush);

2
libc/nt/nt.mk

@ -152,6 +152,8 @@ $(LIBC_NT_NTDLL_A): \
libc/nt/ntdll/ \
$(LIBC_NT_NTDLL_A).pkg \
$(LIBC_NT_NTDLL_A_OBJS)
@$(file >$@.cmd) $(file >>$@.cmd,$(ARCHIVE) $@ $^ >$(LIBC_NT_NTDLL_A).cmd)
@$(ARCHIVE) $@ $^
$(LIBC_NT_NTDLL_A).pkg: \
$(LIBC_NT_NTDLL_A_OBJS) \

3
libc/nt/systeminfo.h

@ -13,6 +13,9 @@ uint32_t GetSystemDirectoryA(char *lpBuffer, uint32_t uSize);
uint32_t GetWindowsDirectory(char16_t *lpBuffer, uint32_t uSize);
uint32_t GetTempPath(uint32_t uSize, char16_t *lpBuffer);
bool32 GetComputerNameEx(/* enum/computernameformat.h */ int NameType,
char16_t *opt_lpBuffer, uint32_t *nSize);
#if ShouldUseMsabiAttribute()
#include "libc/nt/thunk/systeminfo.inc"
#endif /* ShouldUseMsabiAttribute() */

4
libc/runtime/directmap.c

@ -38,8 +38,8 @@ static textwindows struct DirectMap DirectMapNt(void *addr, size_t size,
protect = prot2nt(prot, flags);
access = fprot2nt(prot, flags);
if ((res.maphandle =
CreateFileMappingNuma(handle, &kNtIsInheritable, protect, size >> 32,
size, NULL, kNtNumaNoPreferredNode))) {
CreateFileMappingNuma(handle, NULL, protect, size >> 32, size, NULL,
kNtNumaNoPreferredNode))) {
if (!(res.addr = MapViewOfFileExNuma(res.maphandle, access, off >> 32, off,
size, addr, kNtNumaNoPreferredNode))) {
CloseHandle(res.maphandle);

15
libc/runtime/executive.S

@ -42,16 +42,13 @@ _executive:
mov %rdx,%r14
mov %rcx,%r15
call _spawn
call _getstack
mov %rax,%rdi
mov %r12d,%edi
mov %r13,%rsi
mov %r14,%rdx
mov %r15,%rcx
.weak main
mov $main,%esi
mov %r12,%rdx
mov %r13,%rcx
mov %r14,%r8
mov %r15,%r9
call _setstack
mov %eax,%edi
call main
xchg %eax,%edi
call exit
.endfn _executive,weak,hidden
ud2

1
libc/runtime/internal.h

@ -25,6 +25,7 @@ void *__cxa_finalize(void *) hidden;
void _executive(int, char **, char **, long (*)[2]) hidden noreturn;
void __stack_chk_fail(void) noreturn relegated;
void __stack_chk_fail_local(void) noreturn relegated hidden;
long _setstack(void *, void *, ...) hidden;
int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden;
forceinline void AssertNeverCalledWhileTerminating(void) {

2
libc/runtime/mapelfread.c

@ -22,7 +22,7 @@
#include "libc/runtime/ezmap.h"
Elf64_Ehdr *mapelfread(const char *filename, struct MappedFile *mf) {
if (mapfileread(filename, mf) != -1 && iself64binary(mf->addr, mf->size)) {
if (mapfileread(filename, mf) != -1 && IsElf64Binary(mf->addr, mf->size)) {
return mf->addr;
} else {
unmapfile(mf);

4
libc/runtime/msync.c

@ -27,7 +27,9 @@
/**
* Synchronize memory mapping changes to disk.
*
* @param flags needs MS_SYNC or MS_ASYNC and can have MS_INVALIDATE
* Without this, there's no guarantee memory is written back to disk.
*
* @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) {

4
libc/runtime/opensymboltable.c

@ -39,8 +39,8 @@ struct SymbolTable *OpenSymbolTable(const char *filename) {
t = MAP_FAILED;
if (filename && (t = mapanon(BIGPAGESIZE)) != MAP_FAILED &&
mapelfread(filename, &t->mf) &&
(t->name_base = getelfstringtable(t->elf, t->elfsize)) != NULL &&
(symtab = getelfsymboltable(t->elf, t->elfsize, &t->count)) &&
(t->name_base = GetElfStringTable(t->elf, t->elfsize)) != NULL &&
(symtab = GetElfSymbolTable(t->elf, t->elfsize, &t->count)) &&
sizeof(struct SymbolTable) + sizeof(struct Symbol) * t->count <
(t->scratch = BIGPAGESIZE)) {
getelfvirtualaddressrange(t->elf, t->elfsize, &t->addr_base, &t->addr_end);

1
libc/runtime/runtime.h

@ -43,7 +43,6 @@ void longjmp(jmp_buf, int) libcesque noreturn paramsnonnull();
void exit(int) noreturn;
void _exit(int) libcesque noreturn;
void _Exit(int) libcesque noreturn;
long _setstack(void *, void *, ...);
void abort(void) noreturn noinstrument;
void panic(void) noreturn noinstrument privileged;
void triplf(void) noreturn noinstrument privileged;

4
libc/runtime/setstack.S

@ -24,7 +24,7 @@
/ @param rdi is new rsp, passed as malloc(size) + size
/ @param rsi is function to call in new stack space
/ @param rdx,rcx,r8,r9 get passed as args to rsi
/ @return happens on original stack
/ @return rax and happens on original stack
_setstack:
push %rbp
mov %rsp,%rbp
@ -43,4 +43,4 @@ _setstack:
pop %rbx
pop %rbp
ret
.endfn _setstack,globl
.endfn _setstack,globl,hidden

30
libc/runtime/winmain.greg.c

@ -25,7 +25,9 @@
#include "libc/nt/enum/consolemodeflags.h"
#include "libc/nt/enum/filetype.h"
#include "libc/nt/enum/loadlibrarysearch.h"