mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-04-25 08:14:42 +00:00
Make improvements
- Make rand64() thread safe - Introduce lemur64 lcg prng - Improve strace on New Technology - Improve msync() on New Technology
This commit is contained in:
parent
43ba3009b2
commit
29bf8b1a30
73 changed files with 888 additions and 269 deletions
|
@ -209,6 +209,7 @@ const struct Function {
|
||||||
{"getrandom", GetRandom}, //
|
{"getrandom", GetRandom}, //
|
||||||
{"inc", inc}, //
|
{"inc", inc}, //
|
||||||
{"knuth", knuth}, //
|
{"knuth", knuth}, //
|
||||||
|
{"lemur64", lemur64}, //
|
||||||
{"libc", libc}, //
|
{"libc", libc}, //
|
||||||
{"moby", moby}, //
|
{"moby", moby}, //
|
||||||
{"mt19937", _mt19937}, //
|
{"mt19937", _mt19937}, //
|
||||||
|
|
46
libc/bits/cmpxchg16b.internal.h
Normal file
46
libc/bits/cmpxchg16b.internal.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_BITS_CMPXCHG16B_INTERNAL_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_BITS_CMPXCHG16B_INTERNAL_H_
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares and exchanges 128-bit value, i.e.
|
||||||
|
*
|
||||||
|
* if (*IfThing == *IsEqualToMe) {
|
||||||
|
* *IfThing = ReplaceItWithMe;
|
||||||
|
* return true;
|
||||||
|
* } else {
|
||||||
|
* *IsEqualToMe = *IfThing;
|
||||||
|
* return false;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Please note that Intel Architecture doesn't guarantee 16-byte memory
|
||||||
|
* accesses to be atomic on their own. Therefore _lockcmpxchg16b should
|
||||||
|
* be considered instead for both thread and asynchronous signal safety
|
||||||
|
*
|
||||||
|
* @param IfThing should point to aligned memory
|
||||||
|
* @param IsEqualToMe should point to in/out local variable
|
||||||
|
* @param ReplaceItWithMe might become the new memory value
|
||||||
|
* @return true if *IfThing was changed
|
||||||
|
*/
|
||||||
|
static inline bool _cmpxchg16b(uint128_t *IfThing, uint128_t *IsEqualToMe,
|
||||||
|
uint128_t ReplaceItWithMe) {
|
||||||
|
bool DidIt;
|
||||||
|
uint64_t ax, bx, cx, dx;
|
||||||
|
ax = *IsEqualToMe;
|
||||||
|
dx = *IsEqualToMe >> 64;
|
||||||
|
bx = ReplaceItWithMe;
|
||||||
|
cx = ReplaceItWithMe >> 64;
|
||||||
|
asm volatile(ZFLAG_ASM("cmpxchg16b\t%1")
|
||||||
|
: ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(ax), "+d"(dx)
|
||||||
|
: "b"(bx), "c"(cx));
|
||||||
|
if (!DidIt) {
|
||||||
|
*IsEqualToMe = ax | (uint128_t)dx << 64;
|
||||||
|
}
|
||||||
|
return DidIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_BITS_CMPXCHG16B_INTERNAL_H_ */
|
44
libc/bits/lockcmpxchg16b.internal.h
Normal file
44
libc/bits/lockcmpxchg16b.internal.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_BITS_LOCKCMPXCHG16B_INTERNAL_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_BITS_LOCKCMPXCHG16B_INTERNAL_H_
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares and exchanges 128-bit value, i.e.
|
||||||
|
*
|
||||||
|
* if (*IfThing == *IsEqualToMe) {
|
||||||
|
* *IfThing = ReplaceItWithMe;
|
||||||
|
* return true;
|
||||||
|
* } else {
|
||||||
|
* *IsEqualToMe = *IfThing;
|
||||||
|
* return false;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @param IfThing should point to aligned memory
|
||||||
|
* @param IsEqualToMe should point to in/out local variable
|
||||||
|
* @param ReplaceItWithMe might become the new memory value
|
||||||
|
* @return true if *IfThing was changed
|
||||||
|
* @asyncsignalsafe
|
||||||
|
* @threadsafe
|
||||||
|
*/
|
||||||
|
static inline bool _lockcmpxchg16b(uint128_t *IfThing, uint128_t *IsEqualToMe,
|
||||||
|
uint128_t ReplaceItWithMe) {
|
||||||
|
bool DidIt;
|
||||||
|
uint64_t ax, bx, cx, dx;
|
||||||
|
ax = *IsEqualToMe;
|
||||||
|
dx = *IsEqualToMe >> 64;
|
||||||
|
bx = ReplaceItWithMe;
|
||||||
|
cx = ReplaceItWithMe >> 64;
|
||||||
|
asm volatile(ZFLAG_ASM("lock cmpxchg16b\t%1")
|
||||||
|
: ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(ax), "+d"(dx)
|
||||||
|
: "b"(bx), "c"(cx));
|
||||||
|
if (!DidIt) {
|
||||||
|
*IsEqualToMe = ax | (uint128_t)dx << 64;
|
||||||
|
}
|
||||||
|
return DidIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_BITS_LOCKCMPXCHG16B_INTERNAL_H_ */
|
16
libc/bits/lockxadd.internal.h
Normal file
16
libc/bits/lockxadd.internal.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_BITS_LOCKXADD_INTERNAL_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_BITS_LOCKXADD_INTERNAL_H_
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
#define _lockxadd(PTR, VAL) \
|
||||||
|
({ \
|
||||||
|
typeof(*(PTR)) Res; \
|
||||||
|
typeof(Res) Val = (VAL); \
|
||||||
|
asm volatile("lock xadd\t%0,%1" : "=r"(Res), "+m"(*(PTR)) : "0"(Val)); \
|
||||||
|
Res; /* contains *PTR before addition cf. InterlockedAdd() */ \
|
||||||
|
})
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_BITS_LOCKXADD_INTERNAL_H_ */
|
|
@ -36,5 +36,5 @@ textwindows int sys_close_nt(struct Fd *fd) {
|
||||||
if (fd->kind == kFdConsole && fd->extra && fd->extra != -1) {
|
if (fd->kind == kFdConsole && fd->extra && fd->extra != -1) {
|
||||||
ok &= CloseHandle(fd->extra);
|
ok &= CloseHandle(fd->extra);
|
||||||
}
|
}
|
||||||
return ok ? 0 : __winerr();
|
return ok ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
int64_t handle, int64_t off) {
|
int64_t handle, int64_t off) {
|
||||||
size_t i;
|
size_t i;
|
||||||
struct DirectMap dm;
|
struct DirectMap dm;
|
||||||
uint32_t flags1, flags2;
|
struct ProtectNt fl;
|
||||||
const struct NtSecurityAttributes *sec;
|
const struct NtSecurityAttributes *sec;
|
||||||
|
|
||||||
if (flags & MAP_PRIVATE) {
|
if (flags & MAP_PRIVATE) {
|
||||||
|
@ -42,37 +42,19 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE) && handle != -1) {
|
if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE) && handle != -1) {
|
||||||
// windows has cow pages but they can't propagate across fork()
|
// windows has cow pages but they can't propagate across fork()
|
||||||
if (prot & PROT_EXEC) {
|
if (prot & PROT_EXEC) {
|
||||||
flags1 = kNtPageExecuteWritecopy;
|
fl = (struct ProtectNt){kNtPageExecuteWritecopy,
|
||||||
flags2 = kNtFileMapCopy | kNtFileMapExecute;
|
kNtFileMapCopy | kNtFileMapExecute};
|
||||||
} else {
|
} else {
|
||||||
flags1 = kNtPageWritecopy;
|
fl = (struct ProtectNt){kNtPageWritecopy, kNtFileMapCopy};
|
||||||
flags2 = kNtFileMapCopy;
|
|
||||||
}
|
|
||||||
} else if (prot & PROT_WRITE) {
|
|
||||||
if (prot & PROT_EXEC) {
|
|
||||||
flags1 = kNtPageExecuteReadwrite;
|
|
||||||
flags2 = kNtFileMapWrite | kNtFileMapExecute;
|
|
||||||
} else {
|
|
||||||
flags1 = kNtPageReadwrite;
|
|
||||||
flags2 = kNtFileMapWrite;
|
|
||||||
}
|
|
||||||
} else if (prot & PROT_READ) {
|
|
||||||
if (prot & PROT_EXEC) {
|
|
||||||
flags1 = kNtPageExecuteRead;
|
|
||||||
flags2 = kNtFileMapRead | kNtFileMapExecute;
|
|
||||||
} else {
|
|
||||||
flags1 = kNtPageReadonly;
|
|
||||||
flags2 = kNtFileMapRead;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
flags1 = kNtPageNoaccess;
|
fl = __nt2prot(prot);
|
||||||
flags2 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dm.maphandle = CreateFileMapping(handle, sec, flags1, (size + off) >> 32,
|
if ((dm.maphandle = CreateFileMapping(handle, sec, fl.flags1,
|
||||||
(size + off), 0))) {
|
(size + off) >> 32, (size + off), 0))) {
|
||||||
if ((dm.addr = MapViewOfFileEx(dm.maphandle, flags2, off >> 32, off, size,
|
if ((dm.addr = MapViewOfFileEx(dm.maphandle, fl.flags2, off >> 32, off,
|
||||||
addr))) {
|
size, addr))) {
|
||||||
return dm;
|
return dm;
|
||||||
}
|
}
|
||||||
CloseHandle(dm.maphandle);
|
CloseHandle(dm.maphandle);
|
||||||
|
|
|
@ -22,10 +22,5 @@
|
||||||
|
|
||||||
textwindows int sys_fdatasync_nt(int fd) {
|
textwindows int sys_fdatasync_nt(int fd) {
|
||||||
if (!__isfdkind(fd, kFdFile)) return ebadf();
|
if (!__isfdkind(fd, kFdFile)) return ebadf();
|
||||||
/*
|
return FlushFileBuffers(g_fds.p[fd].handle) ? 0 : -1;
|
||||||
* XXX: On Windows NT this might be more analagous to fflush() and
|
|
||||||
* Microsoft docs say to do manual block i/o for database-ish
|
|
||||||
* guarantees on disk persistence. Consider: Really good UPS.
|
|
||||||
*/
|
|
||||||
return FlushFileBuffers(g_fds.p[fd].handle) ? 0 : __winerr();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
* This function is typically regarded as a libc implementation detail;
|
* This function is typically regarded as a libc implementation detail;
|
||||||
* thus, the source code is the documentation.
|
* thus, the source code is the documentation.
|
||||||
*
|
*
|
||||||
|
* @return aux val or 0 if not available
|
||||||
* @see libc/sysv/consts.sh
|
* @see libc/sysv/consts.sh
|
||||||
* @see System Five Application Binary Interface § 3.4.3
|
* @see System Five Application Binary Interface § 3.4.3
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
|
|
|
@ -226,7 +226,6 @@ void sys_exit(int) hidden;
|
||||||
|
|
||||||
void __onfork(void) hidden;
|
void __onfork(void) hidden;
|
||||||
i32 __fixupnewfd(i32, i32) hidden;
|
i32 __fixupnewfd(i32, i32) hidden;
|
||||||
u32 __prot2nt(i32, i32) privileged;
|
|
||||||
void __restore_rt() hidden;
|
void __restore_rt() hidden;
|
||||||
int sys_utimensat_xnu(int, const char *, const struct timespec *, int) hidden;
|
int sys_utimensat_xnu(int, const char *, const struct timespec *, int) hidden;
|
||||||
int sys_nanosleep_xnu(const struct timespec *, struct timespec *) hidden;
|
int sys_nanosleep_xnu(const struct timespec *, struct timespec *) hidden;
|
||||||
|
@ -284,7 +283,7 @@ int sys_linkat_nt(int, const char *, int, const char *) hidden;
|
||||||
int sys_lstat_nt(const char *, struct stat *) hidden;
|
int sys_lstat_nt(const char *, struct stat *) hidden;
|
||||||
int sys_madvise_nt(void *, size_t, int) hidden;
|
int sys_madvise_nt(void *, size_t, int) hidden;
|
||||||
int sys_mkdirat_nt(int, const char *, uint32_t) hidden;
|
int sys_mkdirat_nt(int, const char *, uint32_t) hidden;
|
||||||
int sys_msync_nt(void *, size_t, int) hidden;
|
int sys_msync_nt(char *, size_t, int) hidden;
|
||||||
int sys_nanosleep_nt(const struct timespec *, struct timespec *) hidden;
|
int sys_nanosleep_nt(const struct timespec *, struct timespec *) hidden;
|
||||||
int sys_pipe_nt(int[hasatleast 2], unsigned) hidden;
|
int sys_pipe_nt(int[hasatleast 2], unsigned) hidden;
|
||||||
int sys_renameat_nt(int, const char *, int, const char *) hidden;
|
int sys_renameat_nt(int, const char *, int, const char *) hidden;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
#include "libc/nt/thunk/msabi.h"
|
#include "libc/nt/thunk/msabi.h"
|
||||||
|
#include "libc/runtime/directmap.internal.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
#include "libc/sysv/consts/nr.h"
|
#include "libc/sysv/consts/nr.h"
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,8 @@ textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) {
|
||||||
pipefd[1] = writer;
|
pipefd[1] = writer;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
__winerr();
|
|
||||||
CloseHandle(hin);
|
CloseHandle(hin);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
__winerr();
|
|
||||||
}
|
}
|
||||||
__releasefd(writer);
|
__releasefd(writer);
|
||||||
__releasefd(reader);
|
__releasefd(reader);
|
||||||
|
|
|
@ -63,7 +63,7 @@ struct Signals {
|
||||||
struct Signal mem[__SIG_QUEUE_LENGTH];
|
struct Signal mem[__SIG_QUEUE_LENGTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Signals __sig;
|
struct Signals __sig; // TODO(jart): Need TLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates piece of memory for storing pending signal.
|
* Allocates piece of memory for storing pending signal.
|
||||||
|
|
|
@ -51,7 +51,7 @@ static textwindows int SyncDirectory(int df, char16_t path[PATH_MAX], int n) {
|
||||||
if (FlushFileBuffers(df)) {
|
if (FlushFileBuffers(df)) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return __winerr();
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
path[0] = '.';
|
path[0] = '.';
|
||||||
|
@ -65,11 +65,11 @@ static textwindows int SyncDirectory(int df, char16_t path[PATH_MAX], int n) {
|
||||||
if (FlushFileBuffers(fh)) {
|
if (FlushFileBuffers(fh)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
rc = __winerr();
|
rc = -1;
|
||||||
}
|
}
|
||||||
CloseHandle(fh);
|
CloseHandle(fh);
|
||||||
} else {
|
} else {
|
||||||
rc = __winerr();
|
rc = -1;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/rusage.h"
|
#include "libc/calls/struct/rusage.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/accounting.h"
|
#include "libc/nt/accounting.h"
|
||||||
#include "libc/nt/enum/accessmask.h"
|
#include "libc/nt/enum/accessmask.h"
|
||||||
|
|
36
libc/intrin/closehandle.greg.c
Normal file
36
libc/intrin/closehandle.greg.c
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/nt/runtime.h"
|
||||||
|
#include "libc/nt/thunk/msabi.h"
|
||||||
|
|
||||||
|
extern typeof(CloseHandle) *const __imp_CloseHandle __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes an open object handle.
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
*/
|
||||||
|
textwindows bool32 CloseHandle(int64_t hObject) {
|
||||||
|
bool32 ok;
|
||||||
|
ok = __imp_CloseHandle(hObject);
|
||||||
|
if (!ok) __winerr();
|
||||||
|
STRACE("CloseHandle(%ld) → %hhhd% m", hObject, ok);
|
||||||
|
return ok;
|
||||||
|
}
|
55
libc/intrin/createnamedpipe.greg.c
Normal file
55
libc/intrin/createnamedpipe.greg.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/nt/ipc.h"
|
||||||
|
#include "libc/nt/struct/securityattributes.h"
|
||||||
|
#include "libc/nt/thunk/msabi.h"
|
||||||
|
|
||||||
|
extern typeof(CreateNamedPipe) *const __imp_CreateNamedPipeW __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates pipe.
|
||||||
|
*
|
||||||
|
* @return handle to server end
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
*/
|
||||||
|
textwindows int64_t CreateNamedPipe(
|
||||||
|
const char16_t *lpName, uint32_t dwOpenMode, uint32_t dwPipeMode,
|
||||||
|
uint32_t nMaxInstances, uint32_t nOutBufferSize, uint32_t nInBufferSize,
|
||||||
|
uint32_t nDefaultTimeOutMs,
|
||||||
|
const struct NtSecurityAttributes *opt_lpSecurityAttributes) {
|
||||||
|
int64_t hServer;
|
||||||
|
hServer = __imp_CreateNamedPipeW(lpName, dwOpenMode, dwPipeMode,
|
||||||
|
nMaxInstances, nOutBufferSize, nInBufferSize,
|
||||||
|
nDefaultTimeOutMs, opt_lpSecurityAttributes);
|
||||||
|
if (hServer == -1) __winerr();
|
||||||
|
STRACE("CreateNamedPipe(%#hs,"
|
||||||
|
" dwOpenMode=%u,"
|
||||||
|
" dwPipeMode=%u,"
|
||||||
|
" nMaxInstances=%u,"
|
||||||
|
" nOutBufferSize=%'u,"
|
||||||
|
" nInBufferSize=%'u,"
|
||||||
|
" nDefaultTimeOutMs=%'u,"
|
||||||
|
" lpSecurity=%p) → "
|
||||||
|
"%ld% m",
|
||||||
|
lpName, dwOpenMode, dwPipeMode, nMaxInstances, nOutBufferSize,
|
||||||
|
nInBufferSize, nDefaultTimeOutMs, opt_lpSecurityAttributes, hServer);
|
||||||
|
return hServer;
|
||||||
|
}
|
41
libc/intrin/createpipe.greg.c
Normal file
41
libc/intrin/createpipe.greg.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/nt/ipc.h"
|
||||||
|
#include "libc/nt/struct/securityattributes.h"
|
||||||
|
#include "libc/nt/thunk/msabi.h"
|
||||||
|
|
||||||
|
extern typeof(CreatePipe) *const __imp_CreatePipe __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates anonymous pipe.
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
*/
|
||||||
|
textwindows bool32 CreatePipe(
|
||||||
|
int64_t *out_hReadPipe, int64_t *out_hWritePipe,
|
||||||
|
const struct NtSecurityAttributes *opt_lpPipeAttributes, uint32_t nSize) {
|
||||||
|
bool32 ok;
|
||||||
|
ok = __imp_CreatePipe(out_hReadPipe, out_hWritePipe, opt_lpPipeAttributes,
|
||||||
|
nSize);
|
||||||
|
if (!ok) __winerr();
|
||||||
|
STRACE("CreatePipe([%ld], [%ld], %p, %'zu) → %hhhd% m", *out_hReadPipe,
|
||||||
|
*out_hWritePipe, opt_lpPipeAttributes, nSize, ok);
|
||||||
|
return ok;
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ extern typeof(CreateThread) *const __imp_CreateThread __msabi;
|
||||||
/**
|
/**
|
||||||
* Opens file on the New Technology.
|
* Opens file on the New Technology.
|
||||||
*
|
*
|
||||||
|
* @param dwStackSize may be 0 for default per executable
|
||||||
* @return thread handle, or 0 on failure
|
* @return thread handle, or 0 on failure
|
||||||
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
*/
|
*/
|
||||||
|
|
43
libc/intrin/flushfilebuffers.greg.c
Normal file
43
libc/intrin/flushfilebuffers.greg.c
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/nt/files.h"
|
||||||
|
|
||||||
|
extern typeof(FlushFileBuffers) *const __imp_FlushFileBuffers __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes buffers of specified file to disk.
|
||||||
|
*
|
||||||
|
* This provides a stronger degree of assurance and blocking for things
|
||||||
|
* to be sent to a physical medium, but it's not guaranteed unless your
|
||||||
|
* file is opened in a direct non-caching mode. One main advantage here
|
||||||
|
* seems to be coherency.
|
||||||
|
*
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
* @note consider buying a ups
|
||||||
|
* @see FlushViewOfFile()
|
||||||
|
*/
|
||||||
|
textwindows bool32 FlushFileBuffers(int64_t hFile) {
|
||||||
|
bool32 ok;
|
||||||
|
ok = __imp_FlushFileBuffers(hFile);
|
||||||
|
if (!ok) __winerr();
|
||||||
|
STRACE("FlushFileBuffers(%ld) → %hhhd% m", hFile, ok);
|
||||||
|
return ok;
|
||||||
|
}
|
43
libc/intrin/flushviewoffile.greg.c
Normal file
43
libc/intrin/flushviewoffile.greg.c
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/nt/memory.h"
|
||||||
|
|
||||||
|
extern typeof(FlushViewOfFile) *const __imp_FlushViewOfFile __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syncs memory created by MapViewOfFileEx().
|
||||||
|
*
|
||||||
|
* This doesn't wait until the pages are written out to the physical
|
||||||
|
* medium. This doesn't update timestamps or file/dir metadata.
|
||||||
|
*
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
* @note consider buying a ups
|
||||||
|
* @see FlushFileBuffers()
|
||||||
|
*/
|
||||||
|
textwindows bool32 FlushViewOfFile(const void *lpBaseAddress,
|
||||||
|
size_t dwNumberOfBytesToFlush) {
|
||||||
|
bool32 ok;
|
||||||
|
ok = __imp_FlushViewOfFile(lpBaseAddress, dwNumberOfBytesToFlush);
|
||||||
|
if (!ok) __winerr();
|
||||||
|
STRACE("FlushViewOfFile(%p, %'zu) → %hhhd% m", lpBaseAddress,
|
||||||
|
dwNumberOfBytesToFlush, ok);
|
||||||
|
return ok;
|
||||||
|
}
|
|
@ -64,7 +64,14 @@ o/$(MODE)/libc/intrin/kprintf.greg.o: \
|
||||||
$(NO_MAGIC)
|
$(NO_MAGIC)
|
||||||
|
|
||||||
o/$(MODE)/libc/intrin/createfile.greg.o \
|
o/$(MODE)/libc/intrin/createfile.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/createpipe.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/closehandle.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/createthread.greg.o \
|
||||||
o/$(MODE)/libc/intrin/describeflags.greg.o \
|
o/$(MODE)/libc/intrin/describeflags.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/createnamedpipe.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/unmapviewoffile.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/flushviewoffile.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/flushfilebuffers.greg.o \
|
||||||
o/$(MODE)/libc/intrin/mapviewoffileexnuma.greg.o \
|
o/$(MODE)/libc/intrin/mapviewoffileexnuma.greg.o \
|
||||||
o/$(MODE)/libc/intrin/createfilemappingnuma.greg.o \
|
o/$(MODE)/libc/intrin/createfilemappingnuma.greg.o \
|
||||||
o/$(MODE)/libc/intrin/kstarttsc.o \
|
o/$(MODE)/libc/intrin/kstarttsc.o \
|
||||||
|
|
42
libc/intrin/nt2prot.greg.c
Normal file
42
libc/intrin/nt2prot.greg.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 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/nt/enum/filemapflags.h"
|
||||||
|
#include "libc/nt/enum/pageflags.h"
|
||||||
|
#include "libc/runtime/directmap.internal.h"
|
||||||
|
#include "libc/sysv/consts/prot.h"
|
||||||
|
|
||||||
|
privileged struct ProtectNt __nt2prot(int prot) {
|
||||||
|
if (prot & PROT_WRITE) {
|
||||||
|
if (prot & PROT_EXEC) {
|
||||||
|
return (struct ProtectNt){kNtPageExecuteReadwrite,
|
||||||
|
kNtFileMapWrite | kNtFileMapExecute};
|
||||||
|
} else {
|
||||||
|
return (struct ProtectNt){kNtPageReadwrite, kNtFileMapWrite};
|
||||||
|
}
|
||||||
|
} else if (prot & PROT_READ) {
|
||||||
|
if (prot & PROT_EXEC) {
|
||||||
|
return (struct ProtectNt){kNtPageExecuteRead,
|
||||||
|
kNtFileMapRead | kNtFileMapExecute};
|
||||||
|
} else {
|
||||||
|
return (struct ProtectNt){kNtPageReadonly, kNtFileMapRead};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (struct ProtectNt){kNtPageNoaccess};
|
||||||
|
}
|
||||||
|
}
|
35
libc/intrin/unmapviewoffile.greg.c
Normal file
35
libc/intrin/unmapviewoffile.greg.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/nt/memory.h"
|
||||||
|
|
||||||
|
extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmaps memory created by MapViewOfFileEx().
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
*/
|
||||||
|
textwindows bool32 UnmapViewOfFile(const void *lpBaseAddress) {
|
||||||
|
bool32 ok;
|
||||||
|
ok = __imp_UnmapViewOfFile(lpBaseAddress);
|
||||||
|
if (!ok) __winerr();
|
||||||
|
STRACE("UnmapViewOfFile(%p) → %hhhd% m", lpBaseAddress, ok);
|
||||||
|
return ok;
|
||||||
|
}
|
|
@ -171,27 +171,14 @@ void ShowBacktrace(int fd, const struct StackFrame *bp) {
|
||||||
#ifdef __FNO_OMIT_FRAME_POINTER__
|
#ifdef __FNO_OMIT_FRAME_POINTER__
|
||||||
/* asan runtime depends on this function */
|
/* asan runtime depends on this function */
|
||||||
int st, ft;
|
int st, ft;
|
||||||
static bool noreentry;
|
st = __strace, __strace = 0;
|
||||||
if (!noreentry) {
|
ft = g_ftrace, g_ftrace = 0;
|
||||||
noreentry = true;
|
if (!bp) bp = __builtin_frame_address(0);
|
||||||
|
|
||||||
st = __strace;
|
PrintBacktrace(fd, bp);
|
||||||
__strace = 0;
|
|
||||||
|
|
||||||
ft = g_ftrace;
|
__strace = st;
|
||||||
g_ftrace = 0;
|
g_ftrace = ft;
|
||||||
|
|
||||||
if (!bp) {
|
|
||||||
bp = __builtin_frame_address(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintBacktrace(fd, bp);
|
|
||||||
|
|
||||||
__strace = st;
|
|
||||||
g_ftrace = ft;
|
|
||||||
|
|
||||||
noreentry = false;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
kprintf("ShowBacktrace() needs these flags to show C backtrace:%n"
|
kprintf("ShowBacktrace() needs these flags to show C backtrace:%n"
|
||||||
"\t-D__FNO_OMIT_FRAME_POINTER__%n"
|
"\t-D__FNO_OMIT_FRAME_POINTER__%n"
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -296,10 +297,11 @@ static wontreturn relegated noinstrument void __minicrash(int sig,
|
||||||
relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
||||||
ucontext_t *ctx) {
|
ucontext_t *ctx) {
|
||||||
intptr_t rip;
|
intptr_t rip;
|
||||||
int gdbpid, err;
|
int gdbpid, err, st, ft;
|
||||||
static bool noreentry, notpossible;
|
static bool noreentry, notpossible;
|
||||||
--g_ftrace;
|
st = __strace, __strace = 0;
|
||||||
if (cmpxchg(&noreentry, false, true)) {
|
ft = g_ftrace, g_ftrace = 0;
|
||||||
|
if (lockcmpxchg(&noreentry, false, true)) {
|
||||||
if (!__vforked) {
|
if (!__vforked) {
|
||||||
rip = ctx ? ctx->uc_mcontext.rip : 0;
|
rip = ctx ? ctx->uc_mcontext.rip : 0;
|
||||||
err = errno;
|
err = errno;
|
||||||
|
@ -326,9 +328,10 @@ relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
||||||
}
|
}
|
||||||
} else if (sig == SIGTRAP) {
|
} else if (sig == SIGTRAP) {
|
||||||
/* chances are IsDebuggerPresent() confused strace w/ gdb */
|
/* chances are IsDebuggerPresent() confused strace w/ gdb */
|
||||||
++g_ftrace;
|
g_ftrace = ft;
|
||||||
|
__strace = st;
|
||||||
return;
|
return;
|
||||||
} else if (cmpxchg(¬possible, false, true)) {
|
} else if (lockcmpxchg(¬possible, false, true)) {
|
||||||
__minicrash(sig, si, ctx, "WHILE CRASHING");
|
__minicrash(sig, si, ctx, "WHILE CRASHING");
|
||||||
} else {
|
} else {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
|
||||||
.imp KernelBase,__imp_UnmapViewOfFile2,UnmapViewOfFile2,1696
|
|
|
@ -1,2 +0,0 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
|
||||||
.imp KernelBase,__imp_UnmapViewOfFileEx,UnmapViewOfFileEx,1697
|
|
|
@ -2,7 +2,7 @@
|
||||||
.imp kernel32,__imp_CloseHandle,CloseHandle,0
|
.imp kernel32,__imp_CloseHandle,CloseHandle,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
CloseHandle:
|
__CloseHandle:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
|
@ -11,5 +11,5 @@ CloseHandle:
|
||||||
call *__imp_CloseHandle(%rip)
|
call *__imp_CloseHandle(%rip)
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
.endfn CloseHandle,globl
|
.endfn __CloseHandle,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
.imp kernel32,__imp_CreateNamedPipeW,CreateNamedPipeW,0
|
.imp kernel32,__imp_CreateNamedPipeW,CreateNamedPipeW,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
CreateNamedPipe:
|
__CreateNamedPipe:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
mov __imp_CreateNamedPipeW(%rip),%rax
|
mov __imp_CreateNamedPipeW(%rip),%rax
|
||||||
jmp __sysv2nt8
|
jmp __sysv2nt8
|
||||||
.endfn CreateNamedPipe,globl
|
.endfn __CreateNamedPipe,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
.imp kernel32,__imp_CreatePipe,CreatePipe,0
|
.imp kernel32,__imp_CreatePipe,CreatePipe,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
CreatePipe:
|
__CreatePipe:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
mov __imp_CreatePipe(%rip),%rax
|
mov __imp_CreatePipe(%rip),%rax
|
||||||
jmp __sysv2nt
|
jmp __sysv2nt
|
||||||
.endfn CreatePipe,globl
|
.endfn __CreatePipe,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
.imp kernel32,__imp_FlushFileBuffers,FlushFileBuffers,0
|
.imp kernel32,__imp_FlushFileBuffers,FlushFileBuffers,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
FlushFileBuffers:
|
__FlushFileBuffers:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
|
@ -11,5 +11,5 @@ FlushFileBuffers:
|
||||||
call *__imp_FlushFileBuffers(%rip)
|
call *__imp_FlushFileBuffers(%rip)
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
.endfn FlushFileBuffers,globl
|
.endfn __FlushFileBuffers,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
.imp kernel32,__imp_FlushViewOfFile,FlushViewOfFile,0
|
.imp kernel32,__imp_FlushViewOfFile,FlushViewOfFile,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
FlushViewOfFile:
|
__FlushViewOfFile:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
mov __imp_FlushViewOfFile(%rip),%rax
|
mov __imp_FlushViewOfFile(%rip),%rax
|
||||||
jmp __sysv2nt
|
jmp __sysv2nt
|
||||||
.endfn FlushViewOfFile,globl
|
.endfn __FlushViewOfFile,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
.imp kernel32,__imp_UnmapViewOfFile,UnmapViewOfFile,0
|
.imp kernel32,__imp_UnmapViewOfFile,UnmapViewOfFile,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
UnmapViewOfFile:
|
__UnmapViewOfFile:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
|
@ -11,5 +11,5 @@ UnmapViewOfFile:
|
||||||
call *__imp_UnmapViewOfFile(%rip)
|
call *__imp_UnmapViewOfFile(%rip)
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
.endfn UnmapViewOfFile,globl
|
.endfn __UnmapViewOfFile,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
12
libc/nt/kernel32/UnmapViewOfFile2.s
Normal file
12
libc/nt/kernel32/UnmapViewOfFile2.s
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.include "o/libc/nt/codegen.inc"
|
||||||
|
.imp kernel32,__imp_UnmapViewOfFile2,UnmapViewOfFile2,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
UnmapViewOfFile2:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_UnmapViewOfFile2(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn UnmapViewOfFile2,globl
|
||||||
|
.previous
|
12
libc/nt/kernel32/UnmapViewOfFileEx.s
Normal file
12
libc/nt/kernel32/UnmapViewOfFileEx.s
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.include "o/libc/nt/codegen.inc"
|
||||||
|
.imp kernel32,__imp_UnmapViewOfFileEx,UnmapViewOfFileEx,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
UnmapViewOfFileEx:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_UnmapViewOfFileEx(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn UnmapViewOfFileEx,globl
|
||||||
|
.previous
|
|
@ -418,7 +418,7 @@ imp 'CloseEventLog' CloseEventLog advapi32 1102
|
||||||
imp 'CloseFigure' CloseFigure gdi32 1045
|
imp 'CloseFigure' CloseFigure gdi32 1045
|
||||||
imp 'CloseGestureInfoHandle' CloseGestureInfoHandle user32 1589
|
imp 'CloseGestureInfoHandle' CloseGestureInfoHandle user32 1589
|
||||||
imp 'CloseGlobalizationUserSettingsKey' CloseGlobalizationUserSettingsKey KernelBase 133
|
imp 'CloseGlobalizationUserSettingsKey' CloseGlobalizationUserSettingsKey KernelBase 133
|
||||||
imp 'CloseHandle' CloseHandle kernel32 0 1 # KernelBase
|
imp '__CloseHandle' CloseHandle kernel32 0 1 # KernelBase
|
||||||
imp 'CloseMetaFile' CloseMetaFile gdi32 1046
|
imp 'CloseMetaFile' CloseMetaFile gdi32 1046
|
||||||
imp 'ClosePackageInfo' ClosePackageInfo kernel32 0 # KernelBase
|
imp 'ClosePackageInfo' ClosePackageInfo kernel32 0 # KernelBase
|
||||||
imp 'ClosePrivateNamespace' ClosePrivateNamespace kernel32 0 # KernelBase
|
imp 'ClosePrivateNamespace' ClosePrivateNamespace kernel32 0 # KernelBase
|
||||||
|
@ -624,7 +624,7 @@ imp 'CreateMutex' CreateMutexW kernel32 0 # KernelBase
|
||||||
imp 'CreateMutexA' CreateMutexA kernel32 0 # KernelBase
|
imp 'CreateMutexA' CreateMutexA kernel32 0 # KernelBase
|
||||||
imp 'CreateMutexEx' CreateMutexExW kernel32 0 # KernelBase
|
imp 'CreateMutexEx' CreateMutexExW kernel32 0 # KernelBase
|
||||||
imp 'CreateMutexExA' CreateMutexExA kernel32 0 # KernelBase
|
imp 'CreateMutexExA' CreateMutexExA kernel32 0 # KernelBase
|
||||||
imp 'CreateNamedPipe' CreateNamedPipeW kernel32 0 8 # KernelBase
|
imp '__CreateNamedPipe' CreateNamedPipeW kernel32 0 8 # KernelBase
|
||||||
imp 'CreateNamedPipeA' CreateNamedPipeA kernel32 219 8
|
imp 'CreateNamedPipeA' CreateNamedPipeA kernel32 219 8
|
||||||
imp 'CreateOPMProtectedOutput' CreateOPMProtectedOutput gdi32 1089
|
imp 'CreateOPMProtectedOutput' CreateOPMProtectedOutput gdi32 1089
|
||||||
imp 'CreateOPMProtectedOutputs' CreateOPMProtectedOutputs gdi32 1090
|
imp 'CreateOPMProtectedOutputs' CreateOPMProtectedOutputs gdi32 1090
|
||||||
|
@ -633,7 +633,7 @@ imp 'CreatePalmRejectionDelayZone' CreatePalmRejectionDelayZone user32 15
|
||||||
imp 'CreatePatternBrush' CreatePatternBrush gdi32 1092
|
imp 'CreatePatternBrush' CreatePatternBrush gdi32 1092
|
||||||
imp 'CreatePen' CreatePen gdi32 1093
|
imp 'CreatePen' CreatePen gdi32 1093
|
||||||
imp 'CreatePenIndirect' CreatePenIndirect gdi32 1094
|
imp 'CreatePenIndirect' CreatePenIndirect gdi32 1094
|
||||||
imp 'CreatePipe' CreatePipe kernel32 0 4 # KernelBase
|
imp '__CreatePipe' CreatePipe kernel32 0 4 # KernelBase
|
||||||
imp 'CreatePolyPolygonRgn' CreatePolyPolygonRgn gdi32 1095
|
imp 'CreatePolyPolygonRgn' CreatePolyPolygonRgn gdi32 1095
|
||||||
imp 'CreatePolygonRgn' CreatePolygonRgn gdi32 1096
|
imp 'CreatePolygonRgn' CreatePolygonRgn gdi32 1096
|
||||||
imp 'CreatePopupMenu' CreatePopupMenu user32 1622 0
|
imp 'CreatePopupMenu' CreatePopupMenu user32 1622 0
|
||||||
|
@ -1677,11 +1677,11 @@ imp 'FlsGetValue' FlsGetValue kernel32 0 # KernelBase
|
||||||
imp 'FlsSetValue' FlsSetValue kernel32 0 # KernelBase
|
imp 'FlsSetValue' FlsSetValue kernel32 0 # KernelBase
|
||||||
imp 'FlushConsoleInputBuffer' FlushConsoleInputBuffer kernel32 0 1 # KernelBase
|
imp 'FlushConsoleInputBuffer' FlushConsoleInputBuffer kernel32 0 1 # KernelBase
|
||||||
imp 'FlushEfsCache' FlushEfsCache advapi32 1303
|
imp 'FlushEfsCache' FlushEfsCache advapi32 1303
|
||||||
imp 'FlushFileBuffers' FlushFileBuffers kernel32 0 1 # KernelBase
|
imp '__FlushFileBuffers' FlushFileBuffers kernel32 0 1 # KernelBase
|
||||||
imp 'FlushInstructionCache' FlushInstructionCache kernel32 0 # KernelBase
|
imp 'FlushInstructionCache' FlushInstructionCache kernel32 0 # KernelBase
|
||||||
imp 'FlushTraceA' FlushTraceA advapi32 1304
|
imp 'FlushTraceA' FlushTraceA advapi32 1304
|
||||||
imp 'FlushTrace' FlushTraceW advapi32 1305
|
imp 'FlushTrace' FlushTraceW advapi32 1305
|
||||||
imp 'FlushViewOfFile' FlushViewOfFile kernel32 0 2 # KernelBase
|
imp '__FlushViewOfFile' FlushViewOfFile kernel32 0 2 # KernelBase
|
||||||
imp 'FoldStringA' FoldStringA kernel32 424
|
imp 'FoldStringA' FoldStringA kernel32 424
|
||||||
imp 'FoldString' FoldStringW kernel32 0 # KernelBase
|
imp 'FoldString' FoldStringW kernel32 0 # KernelBase
|
||||||
imp 'FontIsLinked' FontIsLinked gdi32 1484
|
imp 'FontIsLinked' FontIsLinked gdi32 1484
|
||||||
|
@ -6714,9 +6714,9 @@ imp 'UnlockFile' UnlockFile kernel32 0 5 # KernelBase
|
||||||
imp 'UnlockFileEx' UnlockFileEx kernel32 0 5 # KernelBase
|
imp 'UnlockFileEx' UnlockFileEx kernel32 0 5 # KernelBase
|
||||||
imp 'UnlockServiceDatabase' UnlockServiceDatabase advapi32 1820
|
imp 'UnlockServiceDatabase' UnlockServiceDatabase advapi32 1820
|
||||||
imp 'UnlockWindowStation' UnlockWindowStation user32 2456
|
imp 'UnlockWindowStation' UnlockWindowStation user32 2456
|
||||||
imp 'UnmapViewOfFile' UnmapViewOfFile kernel32 0 1 # KernelBase
|
imp '__UnmapViewOfFile' UnmapViewOfFile kernel32 0 1 # KernelBase
|
||||||
imp 'UnmapViewOfFile2' UnmapViewOfFile2 KernelBase 1696
|
imp 'UnmapViewOfFile2' UnmapViewOfFile2 kernel32 0 2 # KernelBase
|
||||||
imp 'UnmapViewOfFileEx' UnmapViewOfFileEx KernelBase 1697
|
imp 'UnmapViewOfFileEx' UnmapViewOfFileEx kernel32 0 3 # KernelBase
|
||||||
imp 'UnpackDDElParam' UnpackDDElParam user32 2457
|
imp 'UnpackDDElParam' UnpackDDElParam user32 2457
|
||||||
imp 'UnrealizeObject' UnrealizeObject gdi32 1934
|
imp 'UnrealizeObject' UnrealizeObject gdi32 1934
|
||||||
imp 'UnregisterApplicationRecoveryCallback' UnregisterApplicationRecoveryCallback kernel32 1466
|
imp 'UnregisterApplicationRecoveryCallback' UnregisterApplicationRecoveryCallback kernel32 1466
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
#define CopyFile(...) __imp_CopyFileW(__VA_ARGS__)
|
#define CopyFile(...) __imp_CopyFileW(__VA_ARGS__)
|
||||||
extern typeof(CopyFile) *const __imp_CopyFileW __msabi;
|
extern typeof(CopyFile) *const __imp_CopyFileW __msabi;
|
||||||
|
|
||||||
#define FlushFileBuffers(...) __imp_FlushFileBuffers(__VA_ARGS__)
|
|
||||||
extern typeof(FlushFileBuffers) *const __imp_FlushFileBuffers __msabi;
|
|
||||||
|
|
||||||
#define GetFileType(...) __imp_GetFileType(__VA_ARGS__)
|
#define GetFileType(...) __imp_GetFileType(__VA_ARGS__)
|
||||||
extern typeof(GetFileType) *const __imp_GetFileType __msabi;
|
extern typeof(GetFileType) *const __imp_GetFileType __msabi;
|
||||||
|
|
|
@ -1,6 +1 @@
|
||||||
#define FlushViewOfFile(...) __imp_FlushViewOfFile(__VA_ARGS__)
|
|
||||||
#define UnmapViewOfFile(...) __imp_UnmapViewOfFile(__VA_ARGS__)
|
|
||||||
|
|
||||||
extern typeof(LocalFree) *const __imp_LocalFree __msabi;
|
extern typeof(LocalFree) *const __imp_LocalFree __msabi;
|
||||||
extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile __msabi;
|
|
||||||
extern typeof(FlushViewOfFile) *const __imp_FlushViewOfFile __msabi;
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ static bool have_getrandom;
|
||||||
/**
|
/**
|
||||||
* Returns cryptographic random data.
|
* Returns cryptographic random data.
|
||||||
*
|
*
|
||||||
* This random number seed generator blends information from:
|
* This random number seed generator obtains information from:
|
||||||
*
|
*
|
||||||
* - getrandom() on Linux
|
* - getrandom() on Linux
|
||||||
* - RtlGenRandom() on Windows
|
* - RtlGenRandom() on Windows
|
||||||
|
@ -61,6 +61,9 @@ static bool have_getrandom;
|
||||||
* This function is safe to use with fork() and vfork(). It will also
|
* This function is safe to use with fork() and vfork(). It will also
|
||||||
* close any file descriptor it ends up needing before it returns.
|
* close any file descriptor it ends up needing before it returns.
|
||||||
*
|
*
|
||||||
|
* @note this function could block a nontrivial time on old computers
|
||||||
|
* @note this function is indeed intended for cryptography
|
||||||
|
* @note this function takes around 900 cycles
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
* @restartable
|
* @restartable
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
|
|
|
@ -7,7 +7,7 @@ forceinline uint64_t KnuthLinearCongruentialGenerator(uint64_t prev[1]) {
|
||||||
Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998,
|
Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998,
|
||||||
p. 106 (line 26) & p. 108 */
|
p. 106 (line 26) & p. 108 */
|
||||||
prev[0] = prev[0] * 6364136223846793005 + 1442695040888963407;
|
prev[0] = prev[0] * 6364136223846793005 + 1442695040888963407;
|
||||||
return prev[0];
|
return prev[0]; /* be sure to shift! */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
45
libc/rand/lemur64.c
Normal file
45
libc/rand/lemur64.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/rand/rand.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns linear congruential deterministic pseudorandom data, e.g.
|
||||||
|
*
|
||||||
|
* uint64_t x = lemur64();
|
||||||
|
*
|
||||||
|
* You can generate different types of numbers as follows:
|
||||||
|
*
|
||||||
|
* int64_t x = lemur64() >> 1; // make positive signed integer
|
||||||
|
* double x = _real1(lemur64()); // make float on [0,1]-interval
|
||||||
|
*
|
||||||
|
* If you want a fast pseudorandom number generator that seeds itself
|
||||||
|
* automatically on startup and fork() then consider rand64(). If you
|
||||||
|
* want true random data then consider rdseed, rdrand, and getrandom.
|
||||||
|
*
|
||||||
|
* @return 64 bits of pseudorandom data
|
||||||
|
* @note this is Lemire's Lehmer generator
|
||||||
|
* @note this function takes at minimum 1 cycle
|
||||||
|
* @note this function passes bigcrush and practrand
|
||||||
|
* @note this function is not intended for cryptography
|
||||||
|
* @see rand64(), rngset(), _real1(), _real2(), _real3()
|
||||||
|
*/
|
||||||
|
uint64_t lemur64(void) {
|
||||||
|
static uint128_t s = 2131259787901769494;
|
||||||
|
return (s *= 15750249268501108917ull) >> 64;
|
||||||
|
}
|
|
@ -21,11 +21,18 @@
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns 31-bit random number using a linear congruential generator.
|
* Returns 31-bit linear congruential pseudorandom number, e.g.
|
||||||
*
|
*
|
||||||
* Please note that, unlike rand32(), the rand() function uses the same
|
* int x = rand();
|
||||||
* seed at startup by default, unless srand() is called. This makes it
|
* assert(x >= 0);
|
||||||
* useful in cases where deterministic behavior is needed.
|
*
|
||||||
|
* This function always returns a positive number. If srand() isn't
|
||||||
|
* called, then it'll return the same sequence each time your program
|
||||||
|
* runs. Faster and more modern alternatives exist to this function.
|
||||||
|
*
|
||||||
|
* @note this function does well on bigcrush and practrand
|
||||||
|
* @note this function is not intended for cryptography
|
||||||
|
* @see lemur64(), rand64(), rdrand()
|
||||||
*/
|
*/
|
||||||
int rand(void) {
|
int rand(void) {
|
||||||
return KnuthLinearCongruentialGenerator(&g_rando) >> 33;
|
return KnuthLinearCongruentialGenerator(&g_rando) >> 33;
|
||||||
|
|
|
@ -23,12 +23,13 @@ char *setstate(char *);
|
||||||
long random(void);
|
long random(void);
|
||||||
void srandom(unsigned);
|
void srandom(unsigned);
|
||||||
|
|
||||||
|
uint64_t lemur64(void);
|
||||||
|
uint64_t rand64(void);
|
||||||
uint64_t vigna(void);
|
uint64_t vigna(void);
|
||||||
uint64_t vigna_r(uint64_t[hasatleast 1]);
|
uint64_t vigna_r(uint64_t[hasatleast 1]);
|
||||||
void svigna(uint64_t);
|
void svigna(uint64_t);
|
||||||
uint64_t rdrand(void);
|
uint64_t rdrand(void);
|
||||||
uint64_t rdseed(void);
|
uint64_t rdseed(void);
|
||||||
uint64_t rand64(void);
|
|
||||||
void _smt19937(uint64_t);
|
void _smt19937(uint64_t);
|
||||||
void _Smt19937(uint64_t[], size_t);
|
void _Smt19937(uint64_t[], size_t);
|
||||||
uint64_t _mt19937(void);
|
uint64_t _mt19937(void);
|
||||||
|
|
|
@ -16,59 +16,80 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/assert.h"
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/bits/xadd.h"
|
#include "libc/bits/lockcmpxchg16b.internal.h"
|
||||||
|
#include "libc/bits/lockxadd.internal.h"
|
||||||
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/nexgen32e/rdtsc.h"
|
#include "libc/nexgen32e/rdtsc.h"
|
||||||
#include "libc/nexgen32e/x86feature.h"
|
#include "libc/nt/thread.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sysv/consts/auxv.h"
|
#include "libc/sysv/consts/auxv.h"
|
||||||
|
#include "libc/thread/create.h"
|
||||||
|
|
||||||
static uint64_t thepool;
|
extern int __pid;
|
||||||
|
static int thepid;
|
||||||
|
static int thecount;
|
||||||
|
static uint128_t thepool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns nondeterministic random data.
|
* Returns nondeterministic random data.
|
||||||
*
|
*
|
||||||
* This function automatically seeds itself on startup and reseeds
|
* This function is similar to lemur64() except it'thepool intended to
|
||||||
* itself after fork() and vfork(). It takes about nanosecond to run.
|
* be unpredictable. This PRNG automatically seeds itself on startup
|
||||||
* That makes it much slower than vigna() and rand() but much faster
|
* using a much stronger and faster random source than `srand(time(0))`.
|
||||||
* than rdrand() and rdseed().
|
* This function will automatically reseed itself when new processes and
|
||||||
|
* threads are spawned. This function is thread safe in the sense that a
|
||||||
|
* race condition can't happen where two threads return the same result.
|
||||||
*
|
*
|
||||||
* @see rdseed(), rdrand(), rand(), random(), rngset()
|
* @see rdseed(), rdrand(), rand(), random(), rngset()
|
||||||
* @note based on vigna's algorithm
|
* @note this function is not intended for cryptography
|
||||||
|
* @note this function passes bigcrush and practrand
|
||||||
|
* @note this function takes at minimum 30 cycles
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
|
* @threadsafe
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
uint64_t rand64(void) {
|
uint64_t rand64(void) {
|
||||||
bool cf;
|
void *d;
|
||||||
register uint64_t t;
|
int c1, p1, p2;
|
||||||
if (X86_HAVE(RDSEED)) {
|
uint128_t s1, s2;
|
||||||
asm volatile(CFLAG_ASM("rdseed\t%1")
|
do {
|
||||||
: CFLAG_CONSTRAINT(cf), "=r"(t)
|
p1 = __pid;
|
||||||
: /* no inputs */
|
p2 = thepid;
|
||||||
: "cc");
|
c1 = thecount;
|
||||||
if (cf) {
|
asm volatile("" ::: "memory");
|
||||||
thepool ^= t;
|
s1 = thepool;
|
||||||
return t;
|
if (p1 == p2) {
|
||||||
|
// fast path
|
||||||
|
s2 = s1;
|
||||||
|
} else {
|
||||||
|
// slow path
|
||||||
|
if (!p2) {
|
||||||
|
// first call so get some cheap entropy
|
||||||
|
if ((d = (void *)getauxval(AT_RANDOM))) {
|
||||||
|
memcpy(&s2, d, 16); // kernel entropy
|
||||||
|
} else {
|
||||||
|
s2 = kStartTsc; // rdtsc() @ _start()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// process contention so blend a timestamp
|
||||||
|
s2 = s1 ^ rdtsc();
|
||||||
|
}
|
||||||
|
// toss the new pid in there
|
||||||
|
s2 ^= p1;
|
||||||
|
// ordering for thepid probably doesn't matter
|
||||||
|
thepid = p1;
|
||||||
}
|
}
|
||||||
}
|
// lemur64 pseudorandom number generator
|
||||||
t = _xadd(&thepool, 0x9e3779b97f4a7c15);
|
s2 *= 15750249268501108917ull;
|
||||||
t ^= (getpid() * 0x1001111111110001ull + 0xdeaadead) >> 31;
|
// sadly 128-bit values aren't atomic on x86
|
||||||
t = (t ^ (t >> 30)) * 0xbf58476d1ce4e5b9;
|
_lockcmpxchg16b(&thepool, &s1, s2);
|
||||||
t = (t ^ (t >> 27)) * 0x94d049bb133111eb;
|
// do it again if there's thread contention
|
||||||
return t ^ (t >> 31);
|
} while (_lockxadd(&thecount, 1) != c1);
|
||||||
|
// the most important step in the prng
|
||||||
|
return s2 >> 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
static textstartup void rand64_init(int argc, char **argv, char **envp,
|
|
||||||
intptr_t *auxv) {
|
|
||||||
for (; auxv[0]; auxv += 2) {
|
|
||||||
if (auxv[0] == AT_RANDOM) {
|
|
||||||
thepool = READ64LE((const char *)auxv[1]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thepool = kStartTsc;
|
|
||||||
}
|
|
||||||
|
|
||||||
const void *const g_rand64_init[] initarray = {rand64_init};
|
|
||||||
|
|
|
@ -55,9 +55,12 @@ static dontinline uint64_t rdrand_failover(void) {
|
||||||
* aren't available then we try /dev/urandom and if that fails, we try
|
* aren't available then we try /dev/urandom and if that fails, we try
|
||||||
* getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid().
|
* getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid().
|
||||||
*
|
*
|
||||||
* This function takes between 10 nanoseconds to several microseconds.
|
* @note this function could block a nontrivial time on old computers
|
||||||
*
|
* @note this function is indeed intended for cryptography
|
||||||
|
* @note this function takes around 300 cycles
|
||||||
* @see rngset(), rdseed(), rand64()
|
* @see rngset(), rdseed(), rand64()
|
||||||
|
* @asyncsignalsafe
|
||||||
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
uint64_t rdrand(void) {
|
uint64_t rdrand(void) {
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -31,9 +31,12 @@
|
||||||
* sysctl(KERN_ARND). If those aren't available then we try /dev/urandom
|
* sysctl(KERN_ARND). If those aren't available then we try /dev/urandom
|
||||||
* and if that fails, we use RDTSC and getpid().
|
* and if that fails, we use RDTSC and getpid().
|
||||||
*
|
*
|
||||||
* This function takes about 32 nanoseconds.
|
* @note this function could block a nontrivial time on old computers
|
||||||
*
|
* @note this function is indeed intended for cryptography
|
||||||
|
* @note this function takes around 800 cycles
|
||||||
* @see rngset(), rdrand(), rand64()
|
* @see rngset(), rdrand(), rand64()
|
||||||
|
* @asyncsignalsafe
|
||||||
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
uint64_t rdseed(void) {
|
uint64_t rdseed(void) {
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
/**
|
/**
|
||||||
* Generates number on [0,1]-real-interval, e.g.
|
* Generates number on [0,1]-real-interval, e.g.
|
||||||
*
|
*
|
||||||
* double x = _real1(vigna())
|
* double x = _real1(lemur64())
|
||||||
*
|
*
|
||||||
* @see vigna(), mt19937()
|
* @see lemur64(), mt19937()
|
||||||
*/
|
*/
|
||||||
double _real1(uint64_t x) {
|
double _real1(uint64_t x) {
|
||||||
return 1. / 9007199254740991. * (x >> 11);
|
return 1. / 9007199254740991. * (x >> 11);
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
/**
|
/**
|
||||||
* Generates number on [0,1)-real-interval, e.g.
|
* Generates number on [0,1)-real-interval, e.g.
|
||||||
*
|
*
|
||||||
* double x = _real2(vigna())
|
* double x = _real2(lemur64())
|
||||||
*
|
*
|
||||||
* @see vigna(), mt19937()
|
* @see lemur64(), mt19937()
|
||||||
*/
|
*/
|
||||||
double _real2(uint64_t x) {
|
double _real2(uint64_t x) {
|
||||||
return 1. / 9007199254740992. * (x >> 11);
|
return 1. / 9007199254740992. * (x >> 11);
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
/**
|
/**
|
||||||
* Generates number on (0,1)-real-interval, e.g.
|
* Generates number on (0,1)-real-interval, e.g.
|
||||||
*
|
*
|
||||||
* double x = _real3(vigna())
|
* double x = _real3(lemur64())
|
||||||
*
|
*
|
||||||
* @see vigna(), mt19937()
|
* @see lemur64(), mt19937()
|
||||||
*/
|
*/
|
||||||
double _real3(uint64_t x) {
|
double _real3(uint64_t x) {
|
||||||
return 1. / 4503599627370496. * ((x >> 12) + .5);
|
return 1. / 4503599627370496. * ((x >> 12) + .5);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/xadd.h"
|
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
|
||||||
static uint64_t g_vigna;
|
static uint64_t g_vigna;
|
||||||
|
@ -40,9 +39,8 @@ static uint64_t g_vigna;
|
||||||
* static uint64_t s = 0;
|
* static uint64_t s = 0;
|
||||||
* uint64_t x = svigna_r(&s);
|
* uint64_t x = svigna_r(&s);
|
||||||
*
|
*
|
||||||
* This function is the fastest way to generate good scalar pseudorandom
|
* If you want to fill a buffer with data then rngset() implements
|
||||||
* numbers that aren't truncated. If you want to fill a buffer with data
|
* vigna's algorithm to do that extremely well:
|
||||||
* then rngset() implements vigna's algorithm to do that extremely well:
|
|
||||||
*
|
*
|
||||||
* char buf[4096];
|
* char buf[4096];
|
||||||
* rngset(buf, sizeof(buf), vigna, 0);
|
* rngset(buf, sizeof(buf), vigna, 0);
|
||||||
|
@ -52,6 +50,9 @@ static uint64_t g_vigna;
|
||||||
* want true random data then consider rdseed, rdrand, and getrandom.
|
* want true random data then consider rdseed, rdrand, and getrandom.
|
||||||
*
|
*
|
||||||
* @return 64 bits of pseudorandom data
|
* @return 64 bits of pseudorandom data
|
||||||
|
* @note this function is not intended for cryptography
|
||||||
|
* @note this function passes bigcrush and practrand
|
||||||
|
* @note this function takes at minimum 4 cycles
|
||||||
*/
|
*/
|
||||||
uint64_t vigna(void) {
|
uint64_t vigna(void) {
|
||||||
return vigna_r(&g_vigna);
|
return vigna_r(&g_vigna);
|
||||||
|
|
|
@ -29,7 +29,9 @@ textwindows wontreturn void sys_abort_nt(void) {
|
||||||
info.si_signo = SIGABRT;
|
info.si_signo = SIGABRT;
|
||||||
rva = __sighandrvas[SIGABRT];
|
rva = __sighandrvas[SIGABRT];
|
||||||
if (rva >= kSigactionMinRva) {
|
if (rva >= kSigactionMinRva) {
|
||||||
((sigaction_f)(_base + rva))(SIGABRT, &info, NULL);
|
if (((sigaction_f)(_base + rva))) {
|
||||||
|
((sigaction_f)(_base + rva))(SIGABRT, &info, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_Exit(128 + SIGABRT);
|
_Exit(128 + SIGABRT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/sig.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/nexgen32e/nt2sysv.h"
|
#include "libc/nexgen32e/nt2sysv.h"
|
||||||
#include "libc/nexgen32e/stackframe.h"
|
#include "libc/nexgen32e/stackframe.h"
|
||||||
|
@ -24,6 +25,8 @@
|
||||||
#include "libc/nt/thread.h"
|
#include "libc/nt/thread.h"
|
||||||
#include "libc/sysv/consts/clone.h"
|
#include "libc/sysv/consts/clone.h"
|
||||||
#include "libc/sysv/consts/nr.h"
|
#include "libc/sysv/consts/nr.h"
|
||||||
|
#include "libc/sysv/consts/o.h"
|
||||||
|
#include "libc/sysv/consts/sicode.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
struct WinThread {
|
struct WinThread {
|
||||||
|
@ -32,7 +35,7 @@ struct WinThread {
|
||||||
void *stack;
|
void *stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
static noasan textwindows uint32_t winthread(void *param) {
|
static noasan textwindows uint32_t WinThreadMain(void *param) {
|
||||||
struct WinThread *wt = param;
|
struct WinThread *wt = param;
|
||||||
asm volatile("mov\t%%rbp,%%r14\n\t"
|
asm volatile("mov\t%%rbp,%%r14\n\t"
|
||||||
"mov\t%%rsp,%%r15\n\t"
|
"mov\t%%rsp,%%r15\n\t"
|
||||||
|
@ -50,15 +53,19 @@ static noasan textwindows uint32_t winthread(void *param) {
|
||||||
/**
|
/**
|
||||||
* Creates thread.
|
* Creates thread.
|
||||||
*
|
*
|
||||||
* @note CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND creates thread
|
* @param flags usually has one of
|
||||||
* @note CLONE_VFORK|CLONE_VM|SIGCHLD does vfork()
|
* - `CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND` for threads
|
||||||
* @note SIGCHLD does fork()
|
* - `CLONE_VFORK|CLONE_VM|SIGCHLD` for vfork()
|
||||||
|
* - `SIGCHLD` for fork()
|
||||||
|
* as part high bytes, and the low order byte may optionally contain
|
||||||
|
* a signal e.g. SIGCHLD, to enable parent notification on terminate
|
||||||
*/
|
*/
|
||||||
privileged int clone(int (*f)(void *), void *stack, int flags, void *arg, ...) {
|
privileged int clone(int (*f)(void *), void *stack, int flags, void *arg, ...) {
|
||||||
int64_t h;
|
int tidfd;
|
||||||
va_list va;
|
va_list va;
|
||||||
intptr_t ax;
|
intptr_t ax;
|
||||||
uint32_t tid;
|
uint32_t tid;
|
||||||
|
int64_t hand;
|
||||||
int32_t *ptid;
|
int32_t *ptid;
|
||||||
register void *tls asm("r8");
|
register void *tls asm("r8");
|
||||||
register int32_t *ctid asm("r10");
|
register int32_t *ctid asm("r10");
|
||||||
|
@ -90,11 +97,16 @@ privileged int clone(int (*f)(void *), void *stack, int flags, void *arg, ...) {
|
||||||
: "memory");
|
: "memory");
|
||||||
unreachable;
|
unreachable;
|
||||||
} else if (IsWindows()) {
|
} else if (IsWindows()) {
|
||||||
if (flags == (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)) {
|
if ((tidfd = __reservefd()) == -1) return -1;
|
||||||
if ((h = CreateThread(0, PAGESIZE, NT2SYSV(winthread),
|
if (flags == CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) {
|
||||||
&(struct WinThread){f, arg, stack}, 0, &tid))) {
|
if ((hand = CreateThread(&kNtIsInheritable, 0, NT2SYSV(WinThreadMain),
|
||||||
CloseHandle(h);
|
&(struct WinThread){f, arg, stack}, 0, &tid))) {
|
||||||
return tid;
|
// XXX: this should be tracked in a separate data structure
|
||||||
|
g_fds.p[tidfd].kind = kFdProcess;
|
||||||
|
g_fds.p[tidfd].handle = hand;
|
||||||
|
g_fds.p[tidfd].flags = O_CLOEXEC;
|
||||||
|
g_fds.p[tidfd].zombie = false;
|
||||||
|
return tidfd;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
struct ProtectNt {
|
||||||
|
uint32_t flags1;
|
||||||
|
uint32_t flags2;
|
||||||
|
};
|
||||||
|
|
||||||
struct DirectMap {
|
struct DirectMap {
|
||||||
void *addr;
|
void *addr;
|
||||||
int64_t maphandle;
|
int64_t maphandle;
|
||||||
|
@ -12,6 +17,8 @@ struct DirectMap sys_mmap(void *, size_t, int, int, int, int64_t);
|
||||||
struct DirectMap sys_mmap_nt(void *, size_t, int, int, int64_t, int64_t);
|
struct DirectMap sys_mmap_nt(void *, size_t, int, int, int64_t, int64_t);
|
||||||
struct DirectMap sys_mmap_metal(void *, size_t, int, int, int, int64_t);
|
struct DirectMap sys_mmap_metal(void *, size_t, int, int, int, int64_t);
|
||||||
int sys_munmap_metal(void *, size_t);
|
int sys_munmap_metal(void *, size_t);
|
||||||
|
uint32_t __prot2nt(int, int);
|
||||||
|
struct ProtectNt __nt2prot(int);
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
|
@ -177,23 +177,8 @@ textwindows void WinMainForked(void) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// we can however safely inherit MAP_SHARED with zero copy
|
// we can however safely inherit MAP_SHARED with zero copy
|
||||||
if (maps[i].prot & PROT_WRITE) {
|
if (!MapViewOfFileEx(maps[i].h, __nt2prot(maps[i].prot).flags2,
|
||||||
if (maps[i].prot & PROT_EXEC) {
|
maps[i].offset >> 32, maps[i].offset, size, addr)) {
|
||||||
flags2 = kNtFileMapWrite | kNtFileMapExecute;
|
|
||||||
} else {
|
|
||||||
flags2 = kNtFileMapWrite;
|
|
||||||
}
|
|
||||||
} else if (maps[i].prot & PROT_READ) {
|
|
||||||
if (maps[i].prot & PROT_EXEC) {
|
|
||||||
flags2 = kNtFileMapRead | kNtFileMapExecute;
|
|
||||||
} else {
|
|
||||||
flags2 = kNtFileMapRead;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
flags2 = 0;
|
|
||||||
}
|
|
||||||
if (!MapViewOfFileEx(maps[i].h, flags2, maps[i].offset >> 32,
|
|
||||||
maps[i].offset, size, addr)) {
|
|
||||||
ExitProcess(45);
|
ExitProcess(45);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,29 +201,14 @@ textwindows void WinMainForked(void) {
|
||||||
_mmi.n = specialz / sizeof(_mmi.p[0]);
|
_mmi.n = specialz / sizeof(_mmi.p[0]);
|
||||||
for (i = 0; i < mapcount; ++i) {
|
for (i = 0; i < mapcount; ++i) {
|
||||||
if ((maps[i].flags & MAP_PRIVATE) && (~maps[i].prot & PROT_WRITE)) {
|
if ((maps[i].flags & MAP_PRIVATE) && (~maps[i].prot & PROT_WRITE)) {
|
||||||
if (maps[i].prot & PROT_WRITE) {
|
|
||||||
if (maps[i].prot & PROT_EXEC) {
|
|
||||||
flags1 = kNtPageExecuteReadwrite;
|
|
||||||
} else {
|
|
||||||
flags1 = kNtPageReadwrite;
|
|
||||||
}
|
|
||||||
} else if (maps[i].prot & PROT_READ) {
|
|
||||||
if (maps[i].prot & PROT_EXEC) {
|
|
||||||
flags1 = kNtPageExecuteRead;
|
|
||||||
} else {
|
|
||||||
flags1 = kNtPageReadonly;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
flags1 = kNtPageNoaccess;
|
|
||||||
}
|
|
||||||
VirtualProtect((void *)((uint64_t)maps[i].x << 16),
|
VirtualProtect((void *)((uint64_t)maps[i].x << 16),
|
||||||
ROUNDUP(maps[i].size, FRAMESIZE), flags1, &oldprot);
|
ROUNDUP(maps[i].size, FRAMESIZE),
|
||||||
|
__nt2prot(maps[i].prot).flags1, &oldprot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're all done reading!
|
// we're all done reading!
|
||||||
if (!CloseHandle(reader)) {
|
if (!CloseHandle(reader)) {
|
||||||
STRACE("CloseHandle(reader) failed %m");
|
|
||||||
ExitProcess(47);
|
ExitProcess(47);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +279,6 @@ textwindows int sys_fork_nt(void) {
|
||||||
if (ok) ok = WriteAll(writer, __bss_start, __bss_end - __bss_start);
|
if (ok) ok = WriteAll(writer, __bss_start, __bss_end - __bss_start);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (!CloseHandle(writer)) {
|
if (!CloseHandle(writer)) {
|
||||||
STRACE("CloseHandle(writer) failed %m");
|
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,7 +301,7 @@ textwindows int sys_fork_nt(void) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
STRACE("CreatePipe() failed %m");
|
STRACE("CreatePipe() failed %m");
|
||||||
rc = __winerr();
|
rc = -1;
|
||||||
CloseHandle(writer);
|
CloseHandle(writer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -37,11 +37,7 @@ noasan void ReleaseMemoryNt(struct MemoryIntervals *mm, int l, int r) {
|
||||||
for (i = l; i <= r; ++i) {
|
for (i = l; i <= r; ++i) {
|
||||||
addr = GetFrameAddr(mm->p[i].x);
|
addr = GetFrameAddr(mm->p[i].x);
|
||||||
last = GetFrameAddr(mm->p[i].y);
|
last = GetFrameAddr(mm->p[i].y);
|
||||||
STRACE("UnmapViewOfFile(%p, size:%'zu, hand:%ld)", addr,
|
UnmapViewOfFile(addr);
|
||||||
last - addr + FRAMESIZE, mm->p[i].h);
|
CloseHandle(mm->p[i].h);
|
||||||
ok = UnmapViewOfFile(addr);
|
|
||||||
assert(ok);
|
|
||||||
ok = CloseHandle(mm->p[i].h);
|
|
||||||
assert(ok);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,22 +17,40 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/files.h"
|
#include "libc/nt/files.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
|
#include "libc/sysv/consts/msync.h"
|
||||||
|
|
||||||
noasan textwindows int sys_msync_nt(void *addr, size_t size, int flags) {
|
#define ADDR(x) ((char *)((int64_t)((uint64_t)(x) << 32) >> 16))
|
||||||
int x, y, l, r, i;
|
|
||||||
x = ROUNDDOWN((intptr_t)addr, FRAMESIZE) >> 16;
|
noasan textwindows int sys_msync_nt(char *addr, size_t size, int flags) {
|
||||||
y = ROUNDDOWN((intptr_t)addr + size - 1, FRAMESIZE) >> 16;
|
char *a, *b;
|
||||||
for (i = FindMemoryInterval(&_mmi, x); i < _mmi.i; ++i) {
|
int rc, x, y, l, r, i;
|
||||||
if ((x >= _mmi.p[i].x && x <= _mmi.p[i].y) ||
|
rc = 0;
|
||||||
(y >= _mmi.p[i].x && y <= _mmi.p[i].y)) {
|
for (i = FindMemoryInterval(&_mmi, (intptr_t)addr >> 16); i < _mmi.i; ++i) {
|
||||||
FlushFileBuffers(_mmi.p[i].h);
|
if ((ADDR(_mmi.p[i].x) <= addr && addr < ADDR(_mmi.p[i].y + 1)) ||
|
||||||
|
(ADDR(_mmi.p[i].x) < addr + size &&
|
||||||
|
addr + size <= ADDR(_mmi.p[i].y + 1)) ||
|
||||||
|
(addr < ADDR(_mmi.p[i].x) && ADDR(_mmi.p[i].y + 1) < addr + size)) {
|
||||||
|
a = MIN(MAX(addr, ADDR(_mmi.p[i].x)), ADDR(_mmi.p[i].y + 1));
|
||||||
|
b = MAX(MIN(addr + size, ADDR(_mmi.p[i].y + 1)), ADDR(_mmi.p[i].x));
|
||||||
|
if (!FlushViewOfFile(a, b - a)) {
|
||||||
|
rc = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (flags & MS_SYNC) {
|
||||||
|
if (!FlushFileBuffers(_mmi.p[i].h)) {
|
||||||
|
// TODO(jart): what's up with this?
|
||||||
|
// rc = -1;
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,6 @@ textwindows int sys_socketpair_nt(int family, int type, int proto, int sv[2]) {
|
||||||
}
|
}
|
||||||
if ((hpipe = CreateNamedPipe(pipename, kNtPipeAccessDuplex, mode, 1, 65536,
|
if ((hpipe = CreateNamedPipe(pipename, kNtPipeAccessDuplex, mode, 1, 65536,
|
||||||
65536, 0, &kNtIsInheritable)) == -1) {
|
65536, 0, &kNtIsInheritable)) == -1) {
|
||||||
__winerr();
|
|
||||||
__releasefd(writer);
|
__releasefd(writer);
|
||||||
__releasefd(reader);
|
__releasefd(reader);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -909,6 +909,14 @@ syscon ptrace PTRACE_EVENT_EXEC 4 -1 -1 -1 -1 -1
|
||||||
syscon ptrace PTRACE_EVENT_VFORK_DONE 5 -1 -1 -1 -1 -1
|
syscon ptrace PTRACE_EVENT_VFORK_DONE 5 -1 -1 -1 -1 -1
|
||||||
syscon ptrace PTRACE_EVENT_EXIT 6 -1 -1 -1 -1 -1
|
syscon ptrace PTRACE_EVENT_EXIT 6 -1 -1 -1 -1 -1
|
||||||
|
|
||||||
|
# clone() codes
|
||||||
|
#
|
||||||
|
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||||
|
syscon clone CLONE_VM 0x00000100 0x00000100 0x00000100 0x00000100 0x00000100 0x00000100 # intentionally symbolic so we can tell if clone() is being used to create threads
|
||||||
|
|
||||||
|
# IPPROTO_*
|
||||||
|
#
|
||||||
|
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||||
syscon iproto IPPROTO_IP 0 0 0 0 0 0 # consensus
|
syscon iproto IPPROTO_IP 0 0 0 0 0 0 # consensus
|
||||||
syscon iproto IPPROTO_ICMP 1 1 1 1 1 1 # consensus
|
syscon iproto IPPROTO_ICMP 1 1 1 1 1 1 # consensus
|
||||||
syscon iproto IPPROTO_TCP 6 6 6 6 6 6 # consensus
|
syscon iproto IPPROTO_TCP 6 6 6 6 6 6 # consensus
|
||||||
|
|
2
libc/sysv/consts/CLONE_VM.S
Normal file
2
libc/sysv/consts/CLONE_VM.S
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
|
.syscon clone,CLONE_VM,0x00000100,0x00000100,0x00000100,0x00000100,0x00000100,0x00000100
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon nr,__NR_sigprocmask,0x000e,0x2000030,0x0154,0x0030,0x125,0xfff
|
.syscon nr,__NR_sigprocmask,0x000e,0x2000149,0x0154,0x0030,0x125,0xfff
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_
|
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_
|
||||||
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_
|
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_
|
||||||
|
#include "libc/runtime/symbolic.h"
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
#define CLONE_VM 0x00000100
|
extern const long CLONE_VM;
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
||||||
|
#define CLONE_VM SYMBOLIC(CLONE_VM)
|
||||||
#define CLONE_FS 0x00000200
|
#define CLONE_FS 0x00000200
|
||||||
#define CLONE_FILES 0x00000400
|
#define CLONE_FILES 0x00000400
|
||||||
#define CLONE_SIGHAND 0x00000800
|
#define CLONE_SIGHAND 0x00000800
|
||||||
|
@ -21,6 +27,4 @@ COSMOPOLITAN_C_START_
|
||||||
#define CLONE_CHILD_SETTID 0x01000000
|
#define CLONE_CHILD_SETTID 0x01000000
|
||||||
#define CLONE_STOPPED 0x02000000
|
#define CLONE_STOPPED 0x02000000
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_ */
|
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_CLONE_H_ */
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
*/
|
*/
|
||||||
static uint64_t Rando(void) {
|
static uint64_t Rando(void) {
|
||||||
uint64_t x;
|
uint64_t x;
|
||||||
do x = vigna();
|
do x = lemur64();
|
||||||
while (((x ^ READ64LE("!!!!!!!!")) - 0x0101010101010101) &
|
while (((x ^ READ64LE("!!!!!!!!")) - 0x0101010101010101) &
|
||||||
~(x ^ READ64LE("!!!!!!!!")) & 0x8080808080808080);
|
~(x ^ READ64LE("!!!!!!!!")) & 0x8080808080808080);
|
||||||
return x;
|
return x;
|
||||||
|
@ -225,7 +225,7 @@ TEST(ksnprintf, fuzzTheUnbreakable) {
|
||||||
x = Rando();
|
x = Rando();
|
||||||
memcpy(f + 8, &x, sizeof(x));
|
memcpy(f + 8, &x, sizeof(x));
|
||||||
f[Rando() & 15] = '%';
|
f[Rando() & 15] = '%';
|
||||||
ksnprintf(b, sizeof(b), f, vigna(), vigna(), vigna());
|
ksnprintf(b, sizeof(b), f, lemur64(), lemur64(), lemur64());
|
||||||
}
|
}
|
||||||
EXPECT_SYS(0, 0, mprotect(f, PAGESIZE, PROT_READ));
|
EXPECT_SYS(0, 0, mprotect(f, PAGESIZE, PROT_READ));
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,17 +121,17 @@ BENCH(bcmp, bench) {
|
||||||
EZBENCH_N("bcmp", 256, v = buncmp(a, b, 256));
|
EZBENCH_N("bcmp", 256, v = buncmp(a, b, 256));
|
||||||
a = gc(malloc(16 * 1024));
|
a = gc(malloc(16 * 1024));
|
||||||
b = gc(malloc(16 * 1024));
|
b = gc(malloc(16 * 1024));
|
||||||
rngset(a, 16 * 1024, vigna, -1);
|
rngset(a, 16 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 16 * 1024);
|
memcpy(b, a, 16 * 1024);
|
||||||
EZBENCH_N("bcmp", 16384, v = buncmp(a, b, 16384));
|
EZBENCH_N("bcmp", 16384, v = buncmp(a, b, 16384));
|
||||||
a = gc(malloc(32 * 1024));
|
a = gc(malloc(32 * 1024));
|
||||||
b = gc(malloc(32 * 1024));
|
b = gc(malloc(32 * 1024));
|
||||||
rngset(a, 32 * 1024, vigna, -1);
|
rngset(a, 32 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 32 * 1024);
|
memcpy(b, a, 32 * 1024);
|
||||||
EZBENCH_N("bcmp", 32768, v = buncmp(a, b, 32768));
|
EZBENCH_N("bcmp", 32768, v = buncmp(a, b, 32768));
|
||||||
a = gc(malloc(128 * 1024));
|
a = gc(malloc(128 * 1024));
|
||||||
b = gc(malloc(128 * 1024));
|
b = gc(malloc(128 * 1024));
|
||||||
rngset(a, 128 * 1024, vigna, -1);
|
rngset(a, 128 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 128 * 1024);
|
memcpy(b, a, 128 * 1024);
|
||||||
EZBENCH_N("bcmp", 131072, v = buncmp(a, b, 131072));
|
EZBENCH_N("bcmp", 131072, v = buncmp(a, b, 131072));
|
||||||
}
|
}
|
||||||
|
@ -166,17 +166,17 @@ BENCH(memcmp, bench) {
|
||||||
EZBENCH_N("memcmp", 256, v = funcmp(a, b, 256));
|
EZBENCH_N("memcmp", 256, v = funcmp(a, b, 256));
|
||||||
a = gc(malloc(16 * 1024));
|
a = gc(malloc(16 * 1024));
|
||||||
b = gc(malloc(16 * 1024));
|
b = gc(malloc(16 * 1024));
|
||||||
rngset(a, 16 * 1024, vigna, -1);
|
rngset(a, 16 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 16 * 1024);
|
memcpy(b, a, 16 * 1024);
|
||||||
EZBENCH_N("memcmp", 16384, v = funcmp(a, b, 16384));
|
EZBENCH_N("memcmp", 16384, v = funcmp(a, b, 16384));
|
||||||
a = gc(malloc(32 * 1024));
|
a = gc(malloc(32 * 1024));
|
||||||
b = gc(malloc(32 * 1024));
|
b = gc(malloc(32 * 1024));
|
||||||
rngset(a, 32 * 1024, vigna, -1);
|
rngset(a, 32 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 32 * 1024);
|
memcpy(b, a, 32 * 1024);
|
||||||
EZBENCH_N("memcmp", 32768, v = funcmp(a, b, 32768));
|
EZBENCH_N("memcmp", 32768, v = funcmp(a, b, 32768));
|
||||||
a = gc(malloc(128 * 1024));
|
a = gc(malloc(128 * 1024));
|
||||||
b = gc(malloc(128 * 1024));
|
b = gc(malloc(128 * 1024));
|
||||||
rngset(a, 128 * 1024, vigna, -1);
|
rngset(a, 128 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 128 * 1024);
|
memcpy(b, a, 128 * 1024);
|
||||||
EZBENCH_N("memcmp", 131072, v = funcmp(a, b, 131072));
|
EZBENCH_N("memcmp", 131072, v = funcmp(a, b, 131072));
|
||||||
}
|
}
|
||||||
|
@ -211,17 +211,17 @@ BENCH(timingsafe_memcmp, bench) {
|
||||||
EZBENCH_N("timingsafe_memcmp", 256, v = timingsafe_memcmp(a, b, 256));
|
EZBENCH_N("timingsafe_memcmp", 256, v = timingsafe_memcmp(a, b, 256));
|
||||||
a = gc(malloc(16 * 1024));
|
a = gc(malloc(16 * 1024));
|
||||||
b = gc(malloc(16 * 1024));
|
b = gc(malloc(16 * 1024));
|
||||||
rngset(a, 16 * 1024, vigna, -1);
|
rngset(a, 16 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 16 * 1024);
|
memcpy(b, a, 16 * 1024);
|
||||||
EZBENCH_N("timingsafe_memcmp", 16384, v = timingsafe_memcmp(a, b, 16384));
|
EZBENCH_N("timingsafe_memcmp", 16384, v = timingsafe_memcmp(a, b, 16384));
|
||||||
a = gc(malloc(32 * 1024));
|
a = gc(malloc(32 * 1024));
|
||||||
b = gc(malloc(32 * 1024));
|
b = gc(malloc(32 * 1024));
|
||||||
rngset(a, 32 * 1024, vigna, -1);
|
rngset(a, 32 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 32 * 1024);
|
memcpy(b, a, 32 * 1024);
|
||||||
EZBENCH_N("timingsafe_memcmp", 32768, v = timingsafe_memcmp(a, b, 32768));
|
EZBENCH_N("timingsafe_memcmp", 32768, v = timingsafe_memcmp(a, b, 32768));
|
||||||
a = gc(malloc(128 * 1024));
|
a = gc(malloc(128 * 1024));
|
||||||
b = gc(malloc(128 * 1024));
|
b = gc(malloc(128 * 1024));
|
||||||
rngset(a, 128 * 1024, vigna, -1);
|
rngset(a, 128 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 128 * 1024);
|
memcpy(b, a, 128 * 1024);
|
||||||
EZBENCH_N("timingsafe_memcmp", 131072, v = timingsafe_memcmp(a, b, 131072));
|
EZBENCH_N("timingsafe_memcmp", 131072, v = timingsafe_memcmp(a, b, 131072));
|
||||||
}
|
}
|
||||||
|
@ -256,17 +256,17 @@ BENCH(timingsafe_bcmp, bench) {
|
||||||
EZBENCH_N("timingsafe_bcmp", 256, v = timingsafe_bcmp(a, b, 256));
|
EZBENCH_N("timingsafe_bcmp", 256, v = timingsafe_bcmp(a, b, 256));
|
||||||
a = gc(malloc(16 * 1024));
|
a = gc(malloc(16 * 1024));
|
||||||
b = gc(malloc(16 * 1024));
|
b = gc(malloc(16 * 1024));
|
||||||
rngset(a, 16 * 1024, vigna, -1);
|
rngset(a, 16 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 16 * 1024);
|
memcpy(b, a, 16 * 1024);
|
||||||
EZBENCH_N("timingsafe_bcmp", 16384, v = timingsafe_bcmp(a, b, 16384));
|
EZBENCH_N("timingsafe_bcmp", 16384, v = timingsafe_bcmp(a, b, 16384));
|
||||||
a = gc(malloc(32 * 1024));
|
a = gc(malloc(32 * 1024));
|
||||||
b = gc(malloc(32 * 1024));
|
b = gc(malloc(32 * 1024));
|
||||||
rngset(a, 32 * 1024, vigna, -1);
|
rngset(a, 32 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 32 * 1024);
|
memcpy(b, a, 32 * 1024);
|
||||||
EZBENCH_N("timingsafe_bcmp", 32768, v = timingsafe_bcmp(a, b, 32768));
|
EZBENCH_N("timingsafe_bcmp", 32768, v = timingsafe_bcmp(a, b, 32768));
|
||||||
a = gc(malloc(128 * 1024));
|
a = gc(malloc(128 * 1024));
|
||||||
b = gc(malloc(128 * 1024));
|
b = gc(malloc(128 * 1024));
|
||||||
rngset(a, 128 * 1024, vigna, -1);
|
rngset(a, 128 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 128 * 1024);
|
memcpy(b, a, 128 * 1024);
|
||||||
EZBENCH_N("timingsafe_bcmp", 131072, v = timingsafe_bcmp(a, b, 131072));
|
EZBENCH_N("timingsafe_bcmp", 131072, v = timingsafe_bcmp(a, b, 131072));
|
||||||
}
|
}
|
||||||
|
@ -301,17 +301,17 @@ BENCH(memcasecmp, bench) {
|
||||||
EZBENCH_N("memcasecmp", 256, v = memcasecmp(a, b, 256));
|
EZBENCH_N("memcasecmp", 256, v = memcasecmp(a, b, 256));
|
||||||
a = gc(malloc(16 * 1024));
|
a = gc(malloc(16 * 1024));
|
||||||
b = gc(malloc(16 * 1024));
|
b = gc(malloc(16 * 1024));
|
||||||
rngset(a, 16 * 1024, vigna, -1);
|
rngset(a, 16 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 16 * 1024);
|
memcpy(b, a, 16 * 1024);
|
||||||
EZBENCH_N("memcasecmp", 16384, v = memcasecmp(a, b, 16384));
|
EZBENCH_N("memcasecmp", 16384, v = memcasecmp(a, b, 16384));
|
||||||
a = gc(malloc(32 * 1024));
|
a = gc(malloc(32 * 1024));
|
||||||
b = gc(malloc(32 * 1024));
|
b = gc(malloc(32 * 1024));
|
||||||
rngset(a, 32 * 1024, vigna, -1);
|
rngset(a, 32 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 32 * 1024);
|
memcpy(b, a, 32 * 1024);
|
||||||
EZBENCH_N("memcasecmp", 32768, v = memcasecmp(a, b, 32768));
|
EZBENCH_N("memcasecmp", 32768, v = memcasecmp(a, b, 32768));
|
||||||
a = gc(malloc(128 * 1024));
|
a = gc(malloc(128 * 1024));
|
||||||
b = gc(malloc(128 * 1024));
|
b = gc(malloc(128 * 1024));
|
||||||
rngset(a, 128 * 1024, vigna, -1);
|
rngset(a, 128 * 1024, lemur64, -1);
|
||||||
memcpy(b, a, 128 * 1024);
|
memcpy(b, a, 128 * 1024);
|
||||||
EZBENCH_N("memcasecmp", 131072, v = memcasecmp(a, b, 131072));
|
EZBENCH_N("memcasecmp", 131072, v = memcasecmp(a, b, 131072));
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ BENCH(timingsafe_memcmp, demonstration) {
|
||||||
int bcmp_(const void *, const void *, size_t) asm("bcmp");
|
int bcmp_(const void *, const void *, size_t) asm("bcmp");
|
||||||
int memcmp_(const void *, const void *, size_t) asm("memcmp");
|
int memcmp_(const void *, const void *, size_t) asm("memcmp");
|
||||||
char a[256], b[256];
|
char a[256], b[256];
|
||||||
rngset(a, 256, vigna, -1);
|
rngset(a, 256, lemur64, -1);
|
||||||
memcpy(b, a, 256);
|
memcpy(b, a, 256);
|
||||||
++a[0];
|
++a[0];
|
||||||
EZBENCH_N("bcmp ne", 256, bcmp_(a, b, 256));
|
EZBENCH_N("bcmp ne", 256, bcmp_(a, b, 256));
|
||||||
|
|
|
@ -39,7 +39,7 @@ TEST(memset, hug) {
|
||||||
b = gc(malloc(1025 * 2));
|
b = gc(malloc(1025 * 2));
|
||||||
for (i = 0; i < 1025; ++i) {
|
for (i = 0; i < 1025; ++i) {
|
||||||
for (j = 0; j < 1025 - i; ++j) {
|
for (j = 0; j < 1025 - i; ++j) {
|
||||||
c = vigna();
|
c = lemur64();
|
||||||
rngset(a, i + j, 0, 0);
|
rngset(a, i + j, 0, 0);
|
||||||
memcpy(b, a, i + j);
|
memcpy(b, a, i + j);
|
||||||
ASSERT_EQ(a + i, golden(a + i, c, j));
|
ASSERT_EQ(a + i, golden(a + i, c, j));
|
||||||
|
|
|
@ -155,6 +155,8 @@ TEST(mt19937, test) {
|
||||||
|
|
||||||
BENCH(mt19937, bench8) {
|
BENCH(mt19937, bench8) {
|
||||||
volatile uint64_t x;
|
volatile uint64_t x;
|
||||||
|
EZBENCH2("lemur64", donothing, x = lemur64());
|
||||||
|
EZBENCH2("rand64", donothing, x = rand64());
|
||||||
EZBENCH2("vigna", donothing, x = vigna());
|
EZBENCH2("vigna", donothing, x = vigna());
|
||||||
EZBENCH2("vigna_r", donothing, vigna_r(&x));
|
EZBENCH2("vigna_r", donothing, vigna_r(&x));
|
||||||
EZBENCH2("xorshift", donothing, x = xorshift());
|
EZBENCH2("xorshift", donothing, x = xorshift());
|
||||||
|
|
103
test/libc/rand/rand64_test.c
Normal file
103
test/libc/rand/rand64_test.c
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/sigbits.h"
|
||||||
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
#include "libc/calls/struct/sigset.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/clone.h"
|
||||||
|
#include "libc/sysv/consts/sa.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
#define THREADS 1
|
||||||
|
#define ENTRIES 10
|
||||||
|
|
||||||
|
volatile bool ready;
|
||||||
|
volatile uint64_t A[THREADS * ENTRIES];
|
||||||
|
|
||||||
|
void OnChld(int sig) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
int Thrasher(void *arg) {
|
||||||
|
int i, id = (intptr_t)arg;
|
||||||
|
while (!ready) asm("pause");
|
||||||
|
for (i = 0; i < ENTRIES; ++i) {
|
||||||
|
A[id * ENTRIES + i] = rand64();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(rand64, testLcg_doesntProduceIdenticalValues) {
|
||||||
|
int i, j;
|
||||||
|
bzero(A, sizeof(A));
|
||||||
|
for (i = 0; i < ARRAYLEN(A); ++i) {
|
||||||
|
A[i] = rand64();
|
||||||
|
}
|
||||||
|
for (i = 0; i < ARRAYLEN(A); ++i) {
|
||||||
|
EXPECT_NE(0, A[i], "i=%d", i);
|
||||||
|
for (j = 0; j < ARRAYLEN(A); ++j) {
|
||||||
|
if (i == j) continue;
|
||||||
|
EXPECT_NE(A[i], A[j], "i=%d j=%d", i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(rand64, testThreadSafety_doesntProduceIdenticalValues) {
|
||||||
|
char *stack;
|
||||||
|
sigset_t ss, oldss;
|
||||||
|
int i, j, rc, ws, tid[THREADS], ptid[THREADS], ctid[THREADS], tls[THREADS];
|
||||||
|
if (!IsLinux() && !IsNetbsd()) return;
|
||||||
|
struct sigaction oldsa;
|
||||||
|
struct sigaction sa = {.sa_handler = OnChld, .sa_flags = SA_RESTART};
|
||||||
|
EXPECT_NE(-1, sigaction(SIGCHLD, &sa, &oldsa));
|
||||||
|
bzero(A, sizeof(A));
|
||||||
|
rand64(); // for effect
|
||||||
|
sigemptyset(&ss);
|
||||||
|
sigaddset(&ss, SIGCHLD);
|
||||||
|
EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &ss, &oldss));
|
||||||
|
ready = false;
|
||||||
|
for (i = 0; i < THREADS; ++i) {
|
||||||
|
stack = gc(malloc(FRAMESIZE));
|
||||||
|
tid[i] = clone(Thrasher, stack + FRAMESIZE,
|
||||||
|
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD,
|
||||||
|
(void *)(intptr_t)i, ptid + i, tls + i, ctid + i);
|
||||||
|
EXPECT_NE(-1, tid[i]);
|
||||||
|
}
|
||||||
|
ready = true;
|
||||||
|
for (i = 0; i < THREADS; ++i) {
|
||||||
|
EXPECT_NE(-1, (rc = waitpid(0, &ws, 0)));
|
||||||
|
EXPECT_TRUE(WIFEXITED(ws));
|
||||||
|
EXPECT_EQ(0, WEXITSTATUS(ws));
|
||||||
|
}
|
||||||
|
EXPECT_EQ(0, sigaction(SIGCHLD, &oldsa, 0));
|
||||||
|
EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &oldss, 0));
|
||||||
|
for (i = 0; i < ARRAYLEN(A); ++i) {
|
||||||
|
EXPECT_NE(0, A[i], "i=%d", i);
|
||||||
|
for (j = 0; j < ARRAYLEN(A); ++j) {
|
||||||
|
if (i == j) continue;
|
||||||
|
EXPECT_NE(A[i], A[j], "i=%d j=%d", i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ TEST(clone, test) {
|
||||||
if (!IsLinux() && !IsNetbsd() && !IsWindows()) return;
|
if (!IsLinux() && !IsNetbsd() && !IsWindows()) return;
|
||||||
char *stack;
|
char *stack;
|
||||||
long double t;
|
long double t;
|
||||||
int tid, ptid, ctid, tls, ws;
|
int tid, ptid, ctid, tls;
|
||||||
t = nowl();
|
t = nowl();
|
||||||
stack = gc(malloc(FRAMESIZE));
|
stack = gc(malloc(FRAMESIZE));
|
||||||
EXPECT_NE(-1, (tid = clone(thread, stack + FRAMESIZE,
|
EXPECT_NE(-1, (tid = clone(thread, stack + FRAMESIZE,
|
||||||
|
|
|
@ -42,7 +42,7 @@ TEST(mmap, testMapFile) {
|
||||||
int fd;
|
int fd;
|
||||||
char *p;
|
char *p;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
|
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64());
|
||||||
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
||||||
EXPECT_EQ(5, write(fd, "hello", 5));
|
EXPECT_EQ(5, write(fd, "hello", 5));
|
||||||
EXPECT_NE(-1, fdatasync(fd));
|
EXPECT_NE(-1, fdatasync(fd));
|
||||||
|
@ -56,7 +56,7 @@ TEST(mmap, testMapFile) {
|
||||||
TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) {
|
TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) {
|
||||||
int fd;
|
int fd;
|
||||||
char *p, buf[16], path[PATH_MAX];
|
char *p, buf[16], path[PATH_MAX];
|
||||||
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
|
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64());
|
||||||
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
||||||
EXPECT_EQ(5, write(fd, "hello", 5));
|
EXPECT_EQ(5, write(fd, "hello", 5));
|
||||||
EXPECT_NE(-1, fdatasync(fd));
|
EXPECT_NE(-1, fdatasync(fd));
|
||||||
|
@ -163,7 +163,7 @@ TEST(mmap, cow) {
|
||||||
int fd;
|
int fd;
|
||||||
char *p;
|
char *p;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
|
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64());
|
||||||
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
||||||
EXPECT_EQ(5, write(fd, "hello", 5));
|
EXPECT_EQ(5, write(fd, "hello", 5));
|
||||||
EXPECT_NE(-1, fdatasync(fd));
|
EXPECT_NE(-1, fdatasync(fd));
|
||||||
|
@ -182,7 +182,7 @@ TEST(mmap, cowFileMapReadonlyFork) {
|
||||||
char *p;
|
char *p;
|
||||||
int fd, pid, ws;
|
int fd, pid, ws;
|
||||||
char path[PATH_MAX], lol[6];
|
char path[PATH_MAX], lol[6];
|
||||||
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
|
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64());
|
||||||
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
||||||
EXPECT_EQ(6, write(fd, "hello", 6));
|
EXPECT_EQ(6, write(fd, "hello", 6));
|
||||||
EXPECT_NE(-1, close(fd));
|
EXPECT_NE(-1, close(fd));
|
||||||
|
@ -206,7 +206,7 @@ TEST(mmap, cowFileMapFork) {
|
||||||
char *p;
|
char *p;
|
||||||
int fd, pid, ws;
|
int fd, pid, ws;
|
||||||
char path[PATH_MAX], lol[6];
|
char path[PATH_MAX], lol[6];
|
||||||
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
|
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64());
|
||||||
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
||||||
EXPECT_EQ(6, write(fd, "parnt", 6));
|
EXPECT_EQ(6, write(fd, "parnt", 6));
|
||||||
EXPECT_NE(-1, fdatasync(fd));
|
EXPECT_NE(-1, fdatasync(fd));
|
||||||
|
@ -256,7 +256,7 @@ TEST(mmap, sharedFileMapFork) {
|
||||||
char *p;
|
char *p;
|
||||||
int fd, pid, ws;
|
int fd, pid, ws;
|
||||||
char path[PATH_MAX], lol[6];
|
char path[PATH_MAX], lol[6];
|
||||||
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
|
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, lemur64());
|
||||||
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
||||||
EXPECT_EQ(6, write(fd, "parnt", 6));
|
EXPECT_EQ(6, write(fd, "parnt", 6));
|
||||||
EXPECT_NE(-1, fdatasync(fd));
|
EXPECT_NE(-1, fdatasync(fd));
|
||||||
|
|
|
@ -49,5 +49,5 @@ BENCH(asin, bench) {
|
||||||
EZBENCH2("asin(-0)", donothing, asin(-0.));
|
EZBENCH2("asin(-0)", donothing, asin(-0.));
|
||||||
EZBENCH2("asin(NAN)", donothing, asin(NAN));
|
EZBENCH2("asin(NAN)", donothing, asin(NAN));
|
||||||
EZBENCH2("asin(INFINITY)", donothing, asin(INFINITY));
|
EZBENCH2("asin(INFINITY)", donothing, asin(INFINITY));
|
||||||
EZBENCH_C("asin", _real1(vigna()), asin(_real1(vigna())));
|
EZBENCH_C("asin", _real1(lemur64()), asin(_real1(lemur64())));
|
||||||
}
|
}
|
||||||
|
|
6
third_party/mbedtls/bignum.c
vendored
6
third_party/mbedtls/bignum.c
vendored
|
@ -1128,7 +1128,7 @@ static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
|
||||||
* the two input MPIs is not the same.
|
* the two input MPIs is not the same.
|
||||||
*/
|
*/
|
||||||
int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
|
int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
|
||||||
unsigned *ret )
|
unsigned *ret )
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
/* The value of any of these variables is either 0 or 1 at all times. */
|
/* The value of any of these variables is either 0 or 1 at all times. */
|
||||||
|
@ -1949,8 +1949,8 @@ static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
|
||||||
* Note that unlike the usual convention in the library
|
* Note that unlike the usual convention in the library
|
||||||
* for `const mbedtls_mpi*`, the content of T can change.
|
* for `const mbedtls_mpi*`, the content of T can change.
|
||||||
*/
|
*/
|
||||||
static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
|
static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N,
|
||||||
const mbedtls_mpi *T )
|
mbedtls_mpi_uint mm, const mbedtls_mpi *T )
|
||||||
{
|
{
|
||||||
size_t i, n, m;
|
size_t i, n, m;
|
||||||
mbedtls_mpi_uint u0, u1, *d, *Ap, *Bp, *Np;
|
mbedtls_mpi_uint u0, u1, *d, *Ap, *Bp, *Np;
|
||||||
|
|
26
third_party/mbedtls/ccm.c
vendored
26
third_party/mbedtls/ccm.c
vendored
|
@ -381,10 +381,10 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
||||||
* \return A CCM or cipher-specific error code on failure.
|
* \return A CCM or cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||||
const unsigned char *iv, size_t iv_len,
|
const unsigned char *iv, size_t iv_len,
|
||||||
const unsigned char *add, size_t add_len,
|
const unsigned char *add, size_t add_len,
|
||||||
const unsigned char *input, unsigned char *output,
|
const unsigned char *input, unsigned char *output,
|
||||||
unsigned char *tag, size_t tag_len )
|
unsigned char *tag, size_t tag_len )
|
||||||
{
|
{
|
||||||
CCM_VALIDATE_RET( ctx );
|
CCM_VALIDATE_RET( ctx );
|
||||||
CCM_VALIDATE_RET( iv );
|
CCM_VALIDATE_RET( iv );
|
||||||
|
@ -433,10 +433,10 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||||
* \return A CCM or cipher-specific error code on failure.
|
* \return A CCM or cipher-specific error code on failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||||
const unsigned char *iv, size_t iv_len,
|
const unsigned char *iv, size_t iv_len,
|
||||||
const unsigned char *add, size_t add_len,
|
const unsigned char *add, size_t add_len,
|
||||||
const unsigned char *input, unsigned char *output,
|
const unsigned char *input, unsigned char *output,
|
||||||
unsigned char *tag, size_t tag_len )
|
unsigned char *tag, size_t tag_len )
|
||||||
{
|
{
|
||||||
CCM_VALIDATE_RET( ctx );
|
CCM_VALIDATE_RET( ctx );
|
||||||
CCM_VALIDATE_RET( iv );
|
CCM_VALIDATE_RET( iv );
|
||||||
|
@ -448,7 +448,7 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||||
|
|
||||||
return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
|
return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
|
||||||
add_len, input, output, tag, tag_len ) );
|
add_len, input, output, tag, tag_len ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -491,10 +491,10 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
|
||||||
* \return A cipher-specific error code on calculation failure.
|
* \return A cipher-specific error code on calculation failure.
|
||||||
*/
|
*/
|
||||||
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
|
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
|
||||||
const unsigned char *iv, size_t iv_len,
|
const unsigned char *iv, size_t iv_len,
|
||||||
const unsigned char *add, size_t add_len,
|
const unsigned char *add, size_t add_len,
|
||||||
const unsigned char *input, unsigned char *output,
|
const unsigned char *input, unsigned char *output,
|
||||||
const unsigned char *tag, size_t tag_len )
|
const unsigned char *tag, size_t tag_len )
|
||||||
{
|
{
|
||||||
int ret = MBEDTLS_ERR_THIS_CORRUPTION;
|
int ret = MBEDTLS_ERR_THIS_CORRUPTION;
|
||||||
unsigned char check_tag[16];
|
unsigned char check_tag[16];
|
||||||
|
|
|
@ -456,7 +456,7 @@ static void OpCmpxchg16b(struct Machine *m, uint32_t rde) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpRdrand(struct Machine *m, uint32_t rde) {
|
static void OpRdrand(struct Machine *m, uint32_t rde) {
|
||||||
WriteRegister(rde, RegRexbRm(m, rde), rand64());
|
WriteRegister(rde, RegRexbRm(m, rde), rdrand());
|
||||||
m->flags = SetFlag(m->flags, FLAGS_CF, true);
|
m->flags = SetFlag(m->flags, FLAGS_CF, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,15 @@
|
||||||
"scp $f $f.dbg win7:"
|
"scp $f $f.dbg win7:"
|
||||||
"ssh win7 ./%s.com"))
|
"ssh win7 ./%s.com"))
|
||||||
mode name (file-name-nondirectory name)))
|
mode name (file-name-nondirectory name)))
|
||||||
|
((eq kind 'run-win10)
|
||||||
|
(format
|
||||||
|
(cosmo-join
|
||||||
|
" && "
|
||||||
|
`("m=%s; f=o/$m/%s.com"
|
||||||
|
,(concat "make -j8 -O $f MODE=$m")
|
||||||
|
"scp $f $f.dbg win10:"
|
||||||
|
"ssh win10 ./%s.com"))
|
||||||
|
mode name (file-name-nondirectory name)))
|
||||||
((and (equal suffix "")
|
((and (equal suffix "")
|
||||||
(cosmo-contains "_test." (buffer-file-name)))
|
(cosmo-contains "_test." (buffer-file-name)))
|
||||||
(format "m=%s; make -j8 -O MODE=$m %s"
|
(format "m=%s; make -j8 -O MODE=$m %s"
|
||||||
|
@ -643,6 +652,22 @@
|
||||||
('t
|
('t
|
||||||
(error "cosmo-run: unknown major mode")))))))
|
(error "cosmo-run: unknown major mode")))))))
|
||||||
|
|
||||||
|
(defun cosmo-run-win10 (arg)
|
||||||
|
(interactive "P")
|
||||||
|
(let* ((this (or (buffer-file-name) dired-directory))
|
||||||
|
(proj (locate-dominating-file this "Makefile"))
|
||||||
|
(root (or proj default-directory))
|
||||||
|
(file (file-relative-name this root)))
|
||||||
|
(when root
|
||||||
|
(let ((default-directory root))
|
||||||
|
(save-buffer)
|
||||||
|
(cond ((memq major-mode '(c-mode c++-mode asm-mode fortran-mode))
|
||||||
|
(let* ((mode (cosmo--make-mode arg ""))
|
||||||
|
(compile-command (cosmo--compile-command this root 'run-win10 mode "" "" "")))
|
||||||
|
(compile compile-command)))
|
||||||
|
('t
|
||||||
|
(error "cosmo-run: unknown major mode")))))))
|
||||||
|
|
||||||
(progn
|
(progn
|
||||||
(define-key asm-mode-map (kbd "C-c C-r") 'cosmo-run)
|
(define-key asm-mode-map (kbd "C-c C-r") 'cosmo-run)
|
||||||
(define-key c-mode-base-map (kbd "C-c C-r") 'cosmo-run)
|
(define-key c-mode-base-map (kbd "C-c C-r") 'cosmo-run)
|
||||||
|
@ -650,7 +675,7 @@
|
||||||
(define-key sh-mode-map (kbd "C-c C-r") 'cosmo-run)
|
(define-key sh-mode-map (kbd "C-c C-r") 'cosmo-run)
|
||||||
(define-key python-mode-map (kbd "C-c C-r") 'cosmo-run)
|
(define-key python-mode-map (kbd "C-c C-r") 'cosmo-run)
|
||||||
(define-key c-mode-map (kbd "C-c C-s") 'cosmo-run-test)
|
(define-key c-mode-map (kbd "C-c C-s") 'cosmo-run-test)
|
||||||
(define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win7))
|
(define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win10))
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
Loading…
Add table
Reference in a new issue