mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Get codebase completely working with LLVM
You can now build Cosmopolitan with Clang: make -j8 MODE=llvm o/llvm/examples/hello.com The assembler and linker code is now friendly to LLVM too. So it's not needed to configure Clang to use binutils under the hood. If you love LLVM then you can now use pure LLVM.
This commit is contained in:
parent
0e36cb3ac4
commit
e75ffde09e
4528 changed files with 7776 additions and 11640 deletions
|
@ -23,16 +23,16 @@
|
|||
#include "libc/macros.h"
|
||||
.privileged
|
||||
|
||||
/ Terminates program abnormally.
|
||||
/
|
||||
/ This function first tries to trigger your SIGABRT handler. If
|
||||
/ there isn't one or execution resumes, then abort() terminates
|
||||
/ the program using an escalating variety methods of increasing
|
||||
/ brutality.
|
||||
/
|
||||
/ @forcealignargpointer
|
||||
/ @asyncsignalsafe
|
||||
/ @noreturn
|
||||
// Terminates program abnormally.
|
||||
//
|
||||
// This function first tries to trigger your SIGABRT handler. If
|
||||
// there isn't one or execution resumes, then abort() terminates
|
||||
// the program using an escalating variety methods of increasing
|
||||
// brutality.
|
||||
//
|
||||
// @forcealignargpointer
|
||||
// @asyncsignalsafe
|
||||
// @noreturn
|
||||
abort: push %rbp
|
||||
mov %rsp,%rbp
|
||||
and $-16,%rsp
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
.text.startup
|
||||
.source __FILE__
|
||||
|
||||
/ Calls global initialization functions.
|
||||
/
|
||||
/ @param r12 is argc
|
||||
/ @param r13 is argv
|
||||
/ @param r14 is environ
|
||||
/ @param r15 is auxv
|
||||
// Calls global initialization functions.
|
||||
//
|
||||
// @param r12 is argc
|
||||
// @param r13 is argv
|
||||
// @param r14 is environ
|
||||
// @param r15 is auxv
|
||||
_construct:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
#include "libc/dce.h"
|
||||
.text.startup
|
||||
|
||||
/ Cosmopolitan runtime.
|
||||
/
|
||||
/ @param edi is argc
|
||||
/ @param rsi is argv
|
||||
/ @param rdx is environ
|
||||
/ @param rcx is auxv
|
||||
/ @noreturn
|
||||
// Cosmopolitan runtime.
|
||||
//
|
||||
// @param edi is argc
|
||||
// @param rsi is argv
|
||||
// @param rdx is environ
|
||||
// @param rcx is auxv
|
||||
// @noreturn
|
||||
cosmo: push %rbp
|
||||
mov %rsp,%rbp
|
||||
mov %edi,%r12d
|
||||
|
@ -60,10 +60,6 @@ cosmo: push %rbp
|
|||
add $8,%rax
|
||||
jmp 1b
|
||||
2: nop
|
||||
#if !IsTrustworthy()
|
||||
mov $PROT_READ,%edi
|
||||
call _piro
|
||||
#endif
|
||||
call .Largs
|
||||
.weak main
|
||||
call main
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/arraylist.internal.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/gc.internal.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
forceinline bool PointerNotOwnedByParentStackFrame(struct StackFrame *frame,
|
||||
struct StackFrame *parent,
|
||||
void *ptr) {
|
||||
return !(((intptr_t)ptr > (intptr_t)frame) &&
|
||||
((intptr_t)ptr < (intptr_t)parent));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds destructor to garbage shadow stack.
|
||||
*
|
||||
* @param frame is passed automatically by wrapper macro
|
||||
* @param fn takes one argument
|
||||
* @param arg is passed to fn(arg)
|
||||
* @return arg
|
||||
*/
|
||||
void __defer(struct StackFrame *frame, void *fn, void *arg) {
|
||||
struct StackFrame *frame2;
|
||||
/*
|
||||
* To avoid an API requiring dlmalloc dependency, say:
|
||||
* defer(free_s, &ptr_not_owned_by_current_frame)
|
||||
* Rather than:
|
||||
* defer(weak(free), ptr)
|
||||
*/
|
||||
if (!arg) return;
|
||||
frame2 = __builtin_frame_address(0);
|
||||
assert(frame2->next == frame);
|
||||
assert(PointerNotOwnedByParentStackFrame(frame2, frame, arg));
|
||||
if (append(&__garbage,
|
||||
(&(const struct Garbage){frame->next, (intptr_t)fn, (intptr_t)arg,
|
||||
frame->addr})) != -1) {
|
||||
atomic_store(&frame->addr, (intptr_t)&__gc);
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
|
@ -20,8 +20,8 @@
|
|||
.text.exit
|
||||
.source __FILE__
|
||||
|
||||
/ Calls linker registered finalization functions.
|
||||
/ @note functions are called in reverse order
|
||||
// Calls linker registered finalization functions.
|
||||
// @note functions are called in reverse order
|
||||
_destruct:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/notice.inc"
|
||||
.source __FILE__
|
||||
|
||||
/ Uniquely identifies each artifact linked in an address space.
|
||||
// Uniquely identifies each artifact linked in an address space.
|
||||
__dso_handle:
|
||||
.quad __dso_handle
|
||||
.endobj __dso_handle,globl,hidden
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
.text.exit
|
||||
.source __FILE__
|
||||
|
||||
/ Exits program with grace.
|
||||
/
|
||||
/ @param %dil has exit code
|
||||
/ @noreturn
|
||||
// Exits program with grace.
|
||||
//
|
||||
// @param %dil has exit code
|
||||
// @noreturn
|
||||
exit: push %rbp
|
||||
mov %rsp,%rbp
|
||||
push %rdi
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
.privileged
|
||||
.source __FILE__
|
||||
|
||||
/ Terminates process, ignoring destructors and atexit() handlers.
|
||||
/
|
||||
/ @param edi is exit code ∈ [0,256)
|
||||
/ @asyncsignalsafe
|
||||
/ @vforksafe
|
||||
/ @noreturn
|
||||
// Terminates process, ignoring destructors and atexit() handlers.
|
||||
//
|
||||
// @param edi is exit code ∈ [0,256)
|
||||
// @asyncsignalsafe
|
||||
// @vforksafe
|
||||
// @noreturn
|
||||
_exit: jmp _Exit
|
||||
.endfn _exit,globl,protected
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
.privileged
|
||||
.source __FILE__
|
||||
|
||||
/ Terminates process, ignoring destructors and atexit() handlers.
|
||||
/
|
||||
/ @param edi is exit code ∈ [0,256)
|
||||
/ @asyncsignalsafe
|
||||
/ @vforksafe
|
||||
/ @noreturn
|
||||
// Terminates process, ignoring destructors and atexit() handlers.
|
||||
//
|
||||
// @param edi is exit code ∈ [0,256)
|
||||
// @asyncsignalsafe
|
||||
// @vforksafe
|
||||
// @noreturn
|
||||
_Exit: push %rbp
|
||||
mov %rsp,%rbp
|
||||
#if SupportsWindows()
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "libc/macros.h"
|
||||
.source __FILE__
|
||||
|
||||
/ Re-initializes FPU.
|
||||
// Re-initializes FPU.
|
||||
fpreset:
|
||||
_fpreset:
|
||||
.leafprologue
|
||||
|
|
|
@ -20,12 +20,8 @@
|
|||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* Frees memory, the Cosmopolitan way.
|
||||
*
|
||||
* The caller's pointer is zeroed. Stack and static memory is ignored.
|
||||
* This doesn't require a dependency on malloc().
|
||||
*/
|
||||
/* TODO(jart): DELETE */
|
||||
|
||||
void free_s(void *v) {
|
||||
void **pp = (void **)v;
|
||||
void *p = NULL;
|
||||
|
|
66
libc/runtime/ftrace-hook.S
Normal file
66
libc/runtime/ftrace-hook.S
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.privileged
|
||||
|
||||
ftrace_hook:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
and $-16,%rsp
|
||||
sub $0x80,%rsp
|
||||
movaps %xmm0,0x00(%rsp)
|
||||
movaps %xmm1,0x10(%rsp)
|
||||
movaps %xmm2,0x20(%rsp)
|
||||
movaps %xmm3,0x30(%rsp)
|
||||
movaps %xmm4,0x40(%rsp)
|
||||
movaps %xmm5,0x50(%rsp)
|
||||
movaps %xmm6,0x60(%rsp)
|
||||
movaps %xmm7,0x70(%rsp)
|
||||
push %rax
|
||||
push %rax
|
||||
push %rdi
|
||||
push %rsi
|
||||
push %rdx
|
||||
push %rcx
|
||||
push %r8
|
||||
push %r9
|
||||
push %r10
|
||||
push %r11
|
||||
call ftrace
|
||||
pop %r11
|
||||
pop %r10
|
||||
pop %r9
|
||||
pop %r8
|
||||
pop %rcx
|
||||
pop %rdx
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
pop %rax
|
||||
pop %rax
|
||||
movaps 0x00(%rsp),%xmm0
|
||||
movaps 0x10(%rsp),%xmm1
|
||||
movaps 0x20(%rsp),%xmm2
|
||||
movaps 0x30(%rsp),%xmm3
|
||||
movaps 0x40(%rsp),%xmm4
|
||||
movaps 0x50(%rsp),%xmm5
|
||||
movaps 0x60(%rsp),%xmm6
|
||||
movaps 0x70(%rsp),%xmm7
|
||||
leave
|
||||
ret
|
||||
.endfn ftrace_hook,globl
|
|
@ -46,6 +46,9 @@
|
|||
* into gzip.
|
||||
*/
|
||||
|
||||
void ftrace_hook(void);
|
||||
|
||||
static int noreentry;
|
||||
static char g_buf[512];
|
||||
static const char *g_lastsymbol;
|
||||
static struct SymbolTable *g_symbols;
|
||||
|
@ -66,12 +69,14 @@ forceinline int GetNestingLevel(struct StackFrame *frame) {
|
|||
* prologues of other functions. We assume those functions behave
|
||||
* according to the System Five NexGen32e ABI.
|
||||
*/
|
||||
privileged interruptfn void ftrace_hook(void) {
|
||||
privileged void ftrace(void) {
|
||||
size_t i, j, nesting;
|
||||
const char *symbol;
|
||||
struct StackFrame *frame;
|
||||
if (!cmpxchg(&noreentry, 0, 1)) return;
|
||||
if (g_symbols) {
|
||||
frame = __builtin_frame_address(0);
|
||||
frame = frame->next;
|
||||
symbol =
|
||||
&g_symbols->name_base[g_symbols
|
||||
->symbols[bisectcarleft(
|
||||
|
@ -84,18 +89,21 @@ privileged interruptfn void ftrace_hook(void) {
|
|||
i = 2;
|
||||
j = 0;
|
||||
while (nesting--) {
|
||||
asm volatile("" : : : "memory");
|
||||
g_buf[i++] = ' ';
|
||||
g_buf[i++] = ' ';
|
||||
}
|
||||
while (i < ARRAYLEN(g_buf) - 2 && symbol[j]) {
|
||||
asm volatile("" : : : "memory");
|
||||
g_buf[i++] = symbol[j++];
|
||||
}
|
||||
g_buf[i++] = '\r';
|
||||
g_buf[i++] = '\n';
|
||||
__print(g_buf, i);
|
||||
write(2, g_buf, i);
|
||||
}
|
||||
g_lastsymbol = symbol;
|
||||
}
|
||||
noreentry = 0;
|
||||
}
|
||||
|
||||
/**
|
|
@ -19,7 +19,7 @@
|
|||
#include "libc/macros.h"
|
||||
.source __FILE__
|
||||
|
||||
/ Returns granularity of memory manager.
|
||||
// Returns granularity of memory manager.
|
||||
getpagesize:
|
||||
.leafprologue
|
||||
.profilable
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
*
|
||||
* @see ape/ape.lds
|
||||
*/
|
||||
privileged void __hook(void ifunc(void), struct SymbolTable *symbols) {
|
||||
privileged void __hook(void *ifunc, struct SymbolTable *symbols) {
|
||||
size_t i;
|
||||
intptr_t addr;
|
||||
sigset_t oldmask;
|
||||
|
|
|
@ -22,30 +22,30 @@
|
|||
#include "libc/dce.h"
|
||||
.source __FILE__
|
||||
|
||||
/ Decentralized function for process initialization.
|
||||
/
|
||||
/ Modules may inject cheap data structure initialization code into
|
||||
/ this function using the .init.start and .init.end macros. That
|
||||
/ code can use the LODS and STOS instructions to initialize memory
|
||||
/ that's restricted to read-only after initialization by PIRO.
|
||||
/
|
||||
/ This is fast, since the linker is able to roll-up initialization
|
||||
/ for large codebases comprised of many modules, into a perfectly
|
||||
/ linear order. It also enables a common pattern we use, which we
|
||||
/ call “Referencing Is Initialization” (RII).
|
||||
/
|
||||
/ C/C++ code should favor using ordinary constructors, since under
|
||||
/ normal circumstances the compiler will clobber RDI and RSI which
|
||||
/ are granted special meanings within this function.
|
||||
/
|
||||
/ @param r12 is argc (still callee saved)
|
||||
/ @param r13 is argv (still callee saved)
|
||||
/ @param r14 is envp (still callee saved)
|
||||
/ @param r15 is envp (still callee saved)
|
||||
/ @note rdi is __init_bss_start (callee monotonic lockstep)
|
||||
/ @note rsi is __init_rodata_start (callee monotonic lockstep)
|
||||
/ @see .init.start & .init.end (libc/macros.internal.inc)
|
||||
/ @see ape/ape.lds
|
||||
// Decentralized function for process initialization.
|
||||
//
|
||||
// Modules may inject cheap data structure initialization code into
|
||||
// this function using the .init.start and .init.end macros. That
|
||||
// code can use the LODS and STOS instructions to initialize memory
|
||||
// that's restricted to read-only after initialization by PIRO.
|
||||
//
|
||||
// This is fast, since the linker is able to roll-up initialization
|
||||
// for large codebases comprised of many modules, into a perfectly
|
||||
// linear order. It also enables a common pattern we use, which we
|
||||
// call “Referencing Is Initialization” (RII).
|
||||
//
|
||||
// C/C++ code should favor using ordinary constructors, since under
|
||||
// normal circumstances the compiler will clobber RDI and RSI which
|
||||
// are granted special meanings within this function.
|
||||
//
|
||||
// @param r12 is argc (still callee saved)
|
||||
// @param r13 is argv (still callee saved)
|
||||
// @param r14 is envp (still callee saved)
|
||||
// @param r15 is envp (still callee saved)
|
||||
// @note rdi is __init_bss_start (callee monotonic lockstep)
|
||||
// @note rsi is __init_rodata_start (callee monotonic lockstep)
|
||||
// @see .init.start & .init.end (libc/macros.internal.inc)
|
||||
// @see ape/ape.lds
|
||||
.section .initprologue,"ax",@progbits
|
||||
.type _init,@function
|
||||
.globl _init
|
||||
|
@ -75,10 +75,10 @@ _woot: leave
|
|||
ret
|
||||
.previous
|
||||
|
||||
/ Decentralized section for packed data structures & initializers.
|
||||
/
|
||||
/ @see .initro (libc/macros.internal.inc)
|
||||
/ @see ape/ape.lds
|
||||
// Decentralized section for packed data structures & initializers.
|
||||
//
|
||||
// @see .initro (libc/macros.internal.inc)
|
||||
// @see ape/ape.lds
|
||||
.section .initroprologue,"a",@progbits
|
||||
.type __init_rodata_start,@object
|
||||
.type __init_rodata_end,@object
|
||||
|
@ -95,13 +95,13 @@ __init_rodata_end:
|
|||
.byte 0x90
|
||||
.previous
|
||||
|
||||
/ Decentralized section for unpacked data structures.
|
||||
/
|
||||
/ Data in this section becomes read-only after initialization.
|
||||
/
|
||||
/ @see .piro.bss.init (libc/macros.internal.inc)
|
||||
/ @see libc/runtime/piro.c
|
||||
/ @see ape/ape.lds
|
||||
// Decentralized section for unpacked data structures.
|
||||
//
|
||||
// Data in this section becomes read-only after initialization.
|
||||
//
|
||||
// @see .piro.bss.init (libc/macros.internal.inc)
|
||||
// @see libc/runtime/piro.c
|
||||
// @see ape/ape.lds
|
||||
.section .piro.bss.init.1,"aw",@nobits
|
||||
.type __init_bss_start,@object
|
||||
.type __init_bss_end,@object
|
||||
|
@ -118,14 +118,14 @@ __init_bss_end:
|
|||
.byte 0
|
||||
.previous
|
||||
|
||||
/ Special area for Windows NT support code.
|
||||
/
|
||||
/ Isolating this code adds value for Windows users by minimizing
|
||||
/ page faults through improved locality. On System Five the PIRO
|
||||
/ runtime can unmap these pages.
|
||||
/
|
||||
/ @see libc/runtime/piro.c
|
||||
/ @see ape/ape.lds
|
||||
// Special area for Windows NT support code.
|
||||
//
|
||||
// Isolating this code adds value for Windows users by minimizing
|
||||
// page faults through improved locality. On System Five the PIRO
|
||||
// runtime can unmap these pages.
|
||||
//
|
||||
// @see libc/runtime/piro.c
|
||||
// @see ape/ape.lds
|
||||
.section .textwindowsprologue,"ax",@progbits
|
||||
.type __text_windows_start,@object
|
||||
.type __text_windows_end,@object
|
||||
|
|
|
@ -17,7 +17,6 @@ extern hidden char **g_freebsdhint;
|
|||
extern hidden void *g_stacktop;
|
||||
|
||||
void _init(void) hidden;
|
||||
void _piro(int) hidden;
|
||||
void *__cxa_finalize(void *) hidden;
|
||||
void cosmo(int, char **, char **, long (*)[2]) hidden wontreturn;
|
||||
void __stack_chk_fail(void) wontreturn relegated;
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
/ Switches stack.
|
||||
/
|
||||
/ @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
|
||||
/ @noreturn
|
||||
// Switches stack.
|
||||
//
|
||||
// @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
|
||||
// @noreturn
|
||||
_jmpstack:
|
||||
mov %rdi,%rsp
|
||||
mov %rsi,%rax
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/macros.h"
|
||||
.source __FILE__
|
||||
|
||||
/ Loads all pages from program image into memory.
|
||||
// Loads all pages from program image into memory.
|
||||
peekall:.leafprologue
|
||||
ezlea _base,si
|
||||
ezlea _end,cx
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╠──────────────────────────────────────────────────────────────────────────────╣
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│
|
||||
│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│
|
||||
│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│
|
||||
╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│
|
||||
│ αcτµαlly pδrταblε εxεcµταblε § post-initialization read-only │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
#define getaddr(section) ((intptr_t)weakaddr(section))
|
||||
|
||||
static textstartup void _piro_protect(intptr_t start, intptr_t end, int prot) {
|
||||
ssize_t len = end - start;
|
||||
if (len > 0 && start && start % PAGESIZE == 0 && len % PAGESIZE == 0) {
|
||||
if (mprotect((void *)(unsigned long)start, len, prot) == -1) abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Protects memory initialized at startup.
|
||||
* e.g. function hooks, unpacked data structures, etc.
|
||||
*
|
||||
* This is only performed for executables of nontrivial size. It won't
|
||||
* break the build if the αpε linker script wasn't used. Test code is
|
||||
* protected too, so we don't end up like Knight Capital.
|
||||
*
|
||||
* @param prot can have PROT_{NONE,READ,WRITE,EXEC}
|
||||
* @see ape/ape.lds
|
||||
* @see libc/_start.S
|
||||
*/
|
||||
textstartup void _piro(int prot) {
|
||||
if (getaddr("main") < getaddr("__test_start")) {
|
||||
_piro_protect(getaddr("__test_start"), getaddr("__test_end"), PROT_NONE);
|
||||
}
|
||||
_piro_protect(getaddr("__ro"), getaddr("_etext"), PROT_READ);
|
||||
_piro_protect(getaddr("__piro_start"), getaddr("__piro_end"), prot);
|
||||
}
|
|
@ -25,6 +25,8 @@
|
|||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
|
||||
/* TODO(jart): DELETE */
|
||||
|
||||
#define WasImported(SLOT) \
|
||||
((void *)*SLOT && *SLOT != (void *)&missingno /* see libc/crt/crt.S */)
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "libc/macros.h"
|
||||
.source __FILE__
|
||||
|
||||
/ Provides argv[0] The BSD Way.
|
||||
// Provides argv[0] The BSD Way.
|
||||
.initbss 300,_init___progname
|
||||
__progname:
|
||||
.quad 0
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "libc/macros.h"
|
||||
.source __FILE__
|
||||
|
||||
/ Supplies basename(argv[0]) The GNU Way.
|
||||
// Supplies basename(argv[0]) The GNU Way.
|
||||
.initbss 400,_init_program_invocation_short_name
|
||||
program_invocation_short_name:
|
||||
.quad 0
|
||||
|
@ -34,9 +34,9 @@ program_invocation_short_name:
|
|||
mov (%r13),%rsi # argv[0]
|
||||
mov %rsi,%rcx
|
||||
1: lodsb
|
||||
cmp $'/,%al
|
||||
cmp $'/',%al
|
||||
cmoveq %rsi,%rcx
|
||||
cmp $'\\,%al
|
||||
cmp $'\\',%al
|
||||
cmoveq %rsi,%rcx
|
||||
test %al,%al
|
||||
jnz 1b
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
/ Switches stack.
|
||||
/
|
||||
/ @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 rax and happens on original stack
|
||||
// Switches stack.
|
||||
//
|
||||
// @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 rax and happens on original stack
|
||||
_setstack:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
|
|
|
@ -32,7 +32,7 @@ const char *FindComBinary(void);
|
|||
const char *FindDebugBinary(void);
|
||||
struct SymbolTable *OpenSymbolTable(const char *) nodiscard;
|
||||
int CloseSymbolTable(struct SymbolTable **);
|
||||
void __hook(void (*)(void), struct SymbolTable *);
|
||||
void __hook(void *, struct SymbolTable *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -20,20 +20,20 @@
|
|||
#include "libc/macros.h"
|
||||
.privileged
|
||||
|
||||
/ Forks process without copying page tables.
|
||||
/
|
||||
/ This is the same as fork() except it's optimized for the case
|
||||
/ where the caller invokes execve() immediately afterwards. You
|
||||
/ can also call functions like close(), dup2(), etc. You cannot
|
||||
/ call read() safely but you can call pread(). Call _exit() but
|
||||
/ don't call exit(). Look for the vforksafe function annotation
|
||||
/
|
||||
/ Do not make the assumption that the parent is suspended until
|
||||
/ the child terminates since this impl calls fork() on Windows.
|
||||
/
|
||||
/ @return pid of child process or 0 if forked process
|
||||
/ @returnstwice
|
||||
/ @vforksafe
|
||||
// Forks process without copying page tables.
|
||||
//
|
||||
// This is the same as fork() except it's optimized for the case
|
||||
// where the caller invokes execve() immediately afterwards. You
|
||||
// can also call functions like close(), dup2(), etc. You cannot
|
||||
// call read() safely but you can call pread(). Call _exit() but
|
||||
// don't call exit(). Look for the vforksafe function annotation
|
||||
//
|
||||
// Do not make the assumption that the parent is suspended until
|
||||
// the child terminates since this impl calls fork() on Windows.
|
||||
//
|
||||
// @return pid of child process or 0 if forked process
|
||||
// @returnstwice
|
||||
// @vforksafe
|
||||
vfork:
|
||||
#if SupportsWindows()
|
||||
testb IsWindows()
|
||||
|
@ -48,7 +48,7 @@ vfork:
|
|||
syscall
|
||||
push %rsi # note it happens twice in same page
|
||||
cmp $-4095,%eax
|
||||
jae systemfive.error
|
||||
jae systemfive_error
|
||||
0: ezlea __vforked,di
|
||||
test %eax,%eax
|
||||
jz 1f
|
||||
|
@ -62,7 +62,7 @@ vfork:
|
|||
vfork.bsd:
|
||||
syscall
|
||||
push %rsi
|
||||
jc systemfive.errno
|
||||
jc systemfive_errno
|
||||
#if SupportsXnu()
|
||||
testb IsXnu()
|
||||
jz 0b
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
#include "libc/macros.h"
|
||||
.source __FILE__
|
||||
|
||||
/ Thunks free() if it's linked, otherwise do nothing.
|
||||
/
|
||||
/ @see free_s() which can ignore static/stack and clear refs
|
||||
// Thunks free() if it's linked, otherwise do nothing.
|
||||
//
|
||||
// @see free_s() which can ignore static/stack and clear refs
|
||||
weakfree:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
|
|
|
@ -103,8 +103,9 @@ static noasan textwindows wontreturn void WinMainNew(void) {
|
|||
long auxv[1][2];
|
||||
struct WinArgs *wa;
|
||||
const char16_t *env16;
|
||||
extern char os asm("__hostos");
|
||||
os = WINDOWS; /* madness https://news.ycombinator.com/item?id=21019722 */
|
||||
NormalizeCmdExe();
|
||||
*(/*unconst*/ int *)&__hostos = WINDOWS;
|
||||
addr = NtGetVersion() < kNtVersionWindows10 ? 0xff00000 : 0x777000000000;
|
||||
size = ROUNDUP(STACKSIZE + sizeof(struct WinArgs), FRAMESIZE);
|
||||
_mmi.p[0].h =
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue