Fix more things

- Update a couple unicode data files
- Disable strace during logger calls
- SQLite now uses pread() / pwrite()
- pread() past EOF on NT now returns 0
- Make the NT mmap() and fork() code elegant
- Give NT a big performance boost with memory
- Add many more mmap() tests to prove it works
This commit is contained in:
Justine Tunney 2022-03-24 00:05:59 -07:00
parent b90fa996b4
commit 98909b1391
36 changed files with 1034 additions and 318 deletions

View file

@ -16,14 +16,10 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/filemapflags.h"
#include "libc/nt/enum/pageflags.h"
#include "libc/nt/memory.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/overlapped.h"
#include "libc/runtime/directmap.internal.h"
@ -33,55 +29,56 @@
textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
int prot, int flags,
int64_t handle, int64_t off) {
/* asan runtime depends on this function */
uint32_t got;
size_t i, upsize;
size_t i;
struct DirectMap dm;
struct NtOverlapped op;
uint32_t flags1, flags2;
const struct NtSecurityAttributes *sec;
if (flags & MAP_PRIVATE) {
sec = 0; // MAP_PRIVATE isn't inherited across fork()
} else {
sec = &kNtIsInheritable; // MAP_SHARED gives us zero-copy fork()
}
if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE) && handle != -1) {
/*
* WIN32 claims it can do COW mappings but we still haven't found a
* combination of flags, that'll cause Windows to actually do this!
*/
upsize = ROUNDUP(size, FRAMESIZE);
if ((dm.maphandle =
CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite,
upsize >> 32, upsize, NULL))) {
if ((dm.addr = MapViewOfFileEx(dm.maphandle,
kNtFileMapWrite | kNtFileMapExecute, 0, 0,
upsize, addr))) {
for (i = 0; i < size; i += got) {
got = 0;
op.Internal = 0;
op.InternalHigh = 0;
op.Pointer = (void *)(uintptr_t)i;
op.hEvent = 0;
if (!ReadFile(handle, (char *)dm.addr + i, size - i, &got, &op)) {
break;
}
}
if (i == size) {
return dm;
}
UnmapViewOfFile(dm.addr);
}
CloseHandle(dm.maphandle);
// windows has cow pages but they can't propagate across fork()
if (prot & PROT_EXEC) {
flags1 = kNtPageExecuteWritecopy;
flags2 = kNtFileMapCopy | kNtFileMapExecute;
} else {
flags1 = kNtPageWritecopy;
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 {
if ((dm.maphandle = CreateFileMapping(
handle, &kNtIsInheritable,
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL))) {
if ((dm.addr = MapViewOfFileEx(dm.maphandle,
(prot & PROT_WRITE)
? kNtFileMapWrite | kNtFileMapExecute
: kNtFileMapRead | kNtFileMapExecute,
off >> 32, off, size, addr))) {
return dm;
}
CloseHandle(dm.maphandle);
}
flags1 = kNtPageNoaccess;
flags2 = 0;
}
if ((dm.maphandle = CreateFileMapping(handle, sec, flags1, (size + off) >> 32,
(size + off), 0))) {
if ((dm.addr = MapViewOfFileEx(dm.maphandle, flags2, off >> 32, off, size,
addr))) {
return dm;
}
CloseHandle(dm.maphandle);
}
dm.maphandle = kNtInvalidHandleValue;
dm.addr = (void *)(intptr_t)-1;
return dm;

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/errno.h"
#define __NR_dup3_linux 0x0124 /*RHEL5:CVE-2010-3301*/
@ -28,6 +29,7 @@ int32_t sys_dup3(int32_t oldfd, int32_t newfd, int flags) {
olderr = errno;
fd = __sys_dup3(oldfd, newfd, flags);
if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) {
STRACE("demodernizing %s() due to %s", "dup3", "RHEL5:CVE-2010-3301");
demodernize = true;
once = true;
errno = olderr;

View file

@ -29,7 +29,7 @@ hidden struct Fds g_fds;
static textwindows int64_t GetHandleNt(long a) {
int64_t b;
b = GetStdHandle(a);
STRACE("GetStdHandle(%ld) → %p% m", a, b);
STRACE("GetStdHandle(%ld) → %ld% m", a, b);
return b;
}

View file

@ -20,6 +20,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/macros.internal.h"
@ -54,8 +55,8 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) {
} else {
rc = ebadf();
}
if (!IsTrustworthy() && rc != -1) {
if ((size_t)rc > size) abort();
}
assert(rc == -1 || (size_t)rc <= size);
STRACE("pread(%d, [%#.*hhs%s], %'zu, %'zd) → %'zd% m", fd,
MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, offset, rc);
return rc;
}

View file

@ -20,6 +20,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/errno.h"
@ -70,9 +71,11 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
errno = err;
once = true;
demodernize = true;
STRACE("demodernizing %s() due to %s", "preadv", "ENOSYS");
} else if (IsLinux() && rc == __NR_preadv_linux) {
if (__iovec_size(iov, iovlen) < __NR_preadv_linux) {
demodernize = true; /*RHEL5:CVE-2010-3301*/
demodernize = true;
STRACE("demodernizing %s() due to %s", "preadv", "RHEL5:CVE-2010-3301");
once = true;
} else {
return rc;

View file

@ -19,6 +19,7 @@
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/macros.internal.h"
@ -57,5 +58,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) {
assert(wrote <= size);
}
}
STRACE("pwrite(%d, %#.*hhs%s, %'zu, %'zd) → %'zd% m", fd, MAX(0, MIN(40, rc)),
buf, rc > 40 ? "..." : "", size, offset, rc);
return rc;
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/errno.h"
@ -74,9 +75,12 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
errno = err;
once = true;
demodernize = true;
STRACE("demodernizing %s() due to %s", "pwritev", "ENOSYS");
} else if (IsLinux() && rc == __NR_pwritev_linux) {
if (__iovec_size(iov, iovlen) < __NR_pwritev_linux) {
demodernize = true; /*RHEL5:CVE-2010-3301*/
demodernize = true;
STRACE("demodernizing %s() due to %s", "pwritev",
"RHEL5:CVE-2010-3301");
once = true;
} else {
return rc;

View file

@ -35,7 +35,11 @@ static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
if (ReadFile(fd->handle, data, clampio(size), &got,
offset2overlap(offset, &overlap))) {
return got;
} else if (GetLastError() == kNtErrorBrokenPipe) {
} else if (
// make sure read() returns 0 on broken pipe
GetLastError() == kNtErrorBrokenPipe ||
// make sure pread() returns 0 if we start reading after EOF
GetLastError() == kNtErrorHandleEof) {
return 0;
} else {
return __winerr();

View file

@ -60,6 +60,7 @@ ssize_t read(int fd, void *buf, size_t size) {
} else {
rc = einval();
}
STRACE("read(%d, %p, %'zu) → %'zd% m", fd, buf, size, rc);
STRACE("read(%d, [%#.*hhs%s], %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), buf,
rc > 40 ? "..." : "", size, rc);
return rc;
}

View file

@ -16,8 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/errno.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
/**
* Deletes "file" or empty directory associtaed with name.

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/itimerval.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
@ -64,18 +65,41 @@
*/
int setitimer(int which, const struct itimerval *newvalue,
struct itimerval *oldvalue) {
int rc;
if (IsAsan() &&
((newvalue && !__asan_is_valid(newvalue, sizeof(*newvalue))) ||
(oldvalue && !__asan_is_valid(oldvalue, sizeof(*oldvalue))))) {
return efault();
}
if (!IsWindows()) {
rc = efault();
} else if (!IsWindows()) {
if (newvalue) {
return sys_setitimer(which, newvalue, oldvalue);
rc = sys_setitimer(which, newvalue, oldvalue);
} else {
return sys_getitimer(which, oldvalue);
rc = sys_getitimer(which, oldvalue);
}
} else {
return sys_setitimer_nt(which, newvalue, oldvalue);
rc = sys_setitimer_nt(which, newvalue, oldvalue);
}
if (newvalue && oldvalue) {
STRACE("setitimer(%d, "
"{{%'ld, %'ld}, {%'ld, %'ld}}, "
"[{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m",
which, newvalue->it_interval.tv_sec, newvalue->it_interval.tv_usec,
newvalue->it_value.tv_sec, newvalue->it_value.tv_usec,
oldvalue->it_interval.tv_sec, oldvalue->it_interval.tv_usec,
oldvalue->it_value.tv_sec, oldvalue->it_value.tv_usec, rc);
} else if (newvalue) {
STRACE("setitimer(%d, {{%'ld, %'ld}, {%'ld, %'ld}}, NULL) → %d% m", which,
newvalue->it_interval.tv_sec, newvalue->it_interval.tv_usec,
newvalue->it_value.tv_sec, newvalue->it_value.tv_usec, rc);
} else if (oldvalue) {
STRACE("setitimer(%d, NULL, [{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m", which,
oldvalue->it_interval.tv_sec, oldvalue->it_interval.tv_usec,
oldvalue->it_value.tv_sec, oldvalue->it_value.tv_usec, rc);
} else {
STRACE("setitimer(%d, NULL, NULL) → %d% m", which, rc);
}
return rc;
}

View file

@ -18,7 +18,11 @@
*/
#include "libc/calls/internal.h"
#include "libc/errno.h"
#include "libc/nt/createfile.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/creationdisposition.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/nt/enum/io.h"
#include "libc/nt/errors.h"
#include "libc/nt/files.h"
@ -28,6 +32,48 @@
#include "libc/nt/synchronization.h"
#include "libc/sysv/consts/at.h"
/**
* Performs synchronization on directory of pathname.
*
* This code is intended to help prevent subsequent i/o operations
* from failing for no reason at all. For example a unit test that
* repeatedly opens and unlinks the same filename.
*/
static textwindows int SyncDirectory(int df, char16_t path[PATH_MAX], int n) {
int rc;
int64_t fh;
char16_t *p;
if ((p = memrchr16(path, '\\', n))) {
if (p - path == 2 && path[1] == ':') return 0; // XXX: avoid syncing volume
*p = 0;
} else {
if (df != AT_FDCWD) {
if (FlushFileBuffers(df)) {
return 0;
} else {
return __winerr();
}
}
path[0] = '.';
path[1] = 0;
}
if ((fh = CreateFile(
path, kNtFileGenericWrite,
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, 0,
kNtOpenExisting, kNtFileAttributeNormal | kNtFileFlagBackupSemantics,
0)) != -1) {
if (FlushFileBuffers(fh)) {
rc = 0;
} else {
rc = __winerr();
}
CloseHandle(fh);
} else {
rc = __winerr();
}
return rc;
}
static textwindows bool IsDirectorySymlink(const char16_t *path) {
int64_t h;
struct NtWin32FindData data;
@ -67,16 +113,28 @@ static textwindows int sys_rmdir_nt(const char16_t *path) {
}
static textwindows int sys_unlink_nt(const char16_t *path) {
if (IsDirectorySymlink(path)) return sys_rmdir_nt(path);
return DeleteFile(path) ? 0 : __winerr();
if (IsDirectorySymlink(path)) {
return sys_rmdir_nt(path);
} else if (DeleteFile(path)) {
return 0;
} else {
return __winerr();
}
}
textwindows int sys_unlinkat_nt(int dirfd, const char *path, int flags) {
uint16_t path16[PATH_MAX];
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
if (flags & AT_REMOVEDIR) {
return sys_rmdir_nt(path16);
int n, rc;
char16_t path16[PATH_MAX];
if ((n = __mkntpathat(dirfd, path, 0, path16)) == -1) {
rc = -1;
} else if (flags & AT_REMOVEDIR) {
rc = sys_rmdir_nt(path16);
} else {
return sys_unlink_nt(path16);
rc = sys_unlink_nt(path16);
if (rc != -1) {
// TODO(jart): prove that it helps first
// rc = SyncDirectory(dirfd, path16, n);
}
}
return rc;
}

View file

@ -29,6 +29,8 @@
/**
* Deletes inode and maybe the file too.
*
* This may be used to delete files and directories and symlinks.
*
* @param dirfd is normally AT_FDCWD but if it's an open directory and
* path is relative, then path becomes relative to dirfd
* @param path is the thing to delete

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/time/time.h"
@ -23,7 +24,10 @@
* Sleeps for particular amount of microseconds.
*/
int usleep(uint32_t microseconds) {
return nanosleep(
&(struct timespec){microseconds / 1000000, microseconds % 1000000 * 1000},
NULL);
int rc;
rc = nanosleep(&(struct timespec){(uint64_t)microseconds / 1000000,
(uint64_t)microseconds % 1000000 * 1000},
NULL);
STRACE("usleep(%'u) → %d% m", microseconds, rc);
return rc;
}

View file

@ -58,6 +58,7 @@ ssize_t write(int fd, const void *buf, size_t size) {
} else {
rc = einval();
}
STRACE("write(%d, %p, %'zu) → %'zd% m", fd, buf, size, rc);
STRACE("write(%d, %#.*hhs%s, %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), buf,
rc > 40 ? "..." : "", size, rc);
return rc;
}

View file

@ -29,41 +29,50 @@
// @noreturn
_start:
// Get startup timestamp as early as possible.
// Used by --strace flag and kprintf() %T.
rdtsc
ezlea kStartTsc,bx
mov %eax,(%rbx)
mov %edx,4(%rbx)
#if SupportsFreebsd()
// detect free besiyata dishmaya
test %rdi,%rdi
cmovnz %rdi,%rsp
jz 0f
movb $FREEBSD,__hostos(%rip)
#endif
0: mov (%rsp),%ebx # argc
// get startup timestamp as early as possible
// its used by --strace flag and kprintf() %T
0: rdtsc
ezlea kStartTsc,bx
mov %eax,(%rbx)
mov %edx,4(%rbx)
// translates arguments from old stack abi
mov (%rsp),%ebx # argc
lea 8(%rsp),%rsi # argv
lea 16(%rsp,%rbx,8),%rdx # envp
mov %rsp,__oldstack(%rip)
and $-16,%rsp
xor %ebp,%ebp
// bofram 9f
// make win32 imps noop
.weak ape_idata_iat
.weak ape_idata_iatend
ezlea missingno,ax # make win32 imps noop
ezlea missingno,ax
ezlea ape_idata_iat,di
ezlea ape_idata_iatend,cx
sub %rdi,%rcx
shr $3,%ecx
rep stosq
xor %eax,%eax # find end of environ
// scan through environment varis
// find start of auxiliary values
xor %eax,%eax
or $-1,%ecx
mov %rdx,%rdi
repnz scasq
mov %rdi,%rcx # auxv
#if SupportsXnu()
// should probably be removed in favor of newer apis
testb IsXnu()
jz 1f # polyfill xnu auxv
push $0 # auxv[1][1]=0
@ -74,9 +83,11 @@ _start:
push $31 # auxv[0][0]=AT_EXECFN
mov %rsp,%rcx # auxv
#endif
// enter cosmopolitan runtime
1: mov %ebx,%edi
call cosmo
9: ud2
9: .unreachable
.endfn _start,weak,hidden
#if SupportsXnu()

View file

@ -21,6 +21,7 @@
#include "libc/bits/weaken.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
/**
@ -36,7 +37,9 @@ relegated wontreturn void __assert_fail(const char *expr, const char *file,
} else {
kprintf("can't backtrace b/c `__die` not linked%n");
}
quick_exit(23);
__restorewintty();
_Exit(23);
}
__restorewintty();
_Exit(24);
}

View file

@ -45,7 +45,7 @@ textwindows void *MapViewOfFileEx(int64_t hFileMappingObject,
hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow,
dwNumberOfBytesToMap, opt_lpDesiredBaseAddress);
if (!pStartingAddress) __winerr();
STRACE("MapViewOfFileEx(%ld, %s, off:%'ld, size:%'zu, %p) → %p% m",
STRACE("MapViewOfFileEx(%ld, %s, off:%'ld, size:%'zu, addr:%p) → %p% m",
hFileMappingObject, DescribeNtFileMapFlags(dwDesiredAccess),
(uint64_t)dwFileOffsetHigh << 32 | dwFileOffsetLow,
dwNumberOfBytesToMap, opt_lpDesiredBaseAddress, pStartingAddress);

View file

@ -19,6 +19,7 @@
#include "libc/errno.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/internal.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
@ -38,5 +39,6 @@ relegated void ___check_fail_ndebug(uint64_t want, uint64_t got,
kprintf("%n%serror: %s: check failed: 0x%x %s 0x%x (%s)%n",
!__nocolor ? "\e[J" : "", program_invocation_name, want, opchar, got,
strerror(errno));
exit(1);
__restorewintty();
_Exit(68);
}

View file

@ -18,6 +18,7 @@
*/
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/struct/timeval.h"
#include "libc/dce.h"
@ -74,15 +75,17 @@ void vflogf_onfail(FILE *f) {
*/
void(vflogf)(unsigned level, const char *file, int line, FILE *f,
const char *fmt, va_list va) {
int bufmode;
struct tm tm;
long double t2;
int st, bufmode;
const char *prog;
bool issamesecond;
char buf32[32];
int64_t secs, nsec, dots;
if (!f) f = __log_file;
if (!f) return;
st = __strace;
__strace = 0;
t2 = nowl();
secs = t2;
nsec = (t2 - secs) * 1e9L;
@ -114,4 +117,5 @@ void(vflogf)(unsigned level, const char *file, int line, FILE *f,
__die();
unreachable;
}
__strace = st;
}

View file

@ -90,42 +90,20 @@ static textwindows dontinline bool ReadAll(int64_t h, void *buf, size_t n) {
static textwindows int OnForkCrash(struct NtExceptionPointers *ep) {
kprintf("error: fork() child crashed!%n"
"\tExceptionCode = %#x%n"
"\tRip = %x%n"
"\tRax = %.16x R8 = %.16x%n"
"\tRbx = %.16x R9 = %.16x%n"
"\tRcx = %.16x R10 = %.16x%n"
"\tRdx = %.16x R11 = %.16x%n"
"\tRdi = %.16x R12 = %.16x%n"
"\tRsi = %.16x R13 = %.16x%n"
"\tRbp = %.16x R14 = %.16x%n"
"\tRsp = %.16x R15 = %.16x%n",
"\tRip = %x%n",
ep->ExceptionRecord->ExceptionCode,
ep->ContextRecord ? ep->ContextRecord->Rip : -1,
ep->ContextRecord ? ep->ContextRecord->Rax : -1,
ep->ContextRecord ? ep->ContextRecord->R8 : -1,
ep->ContextRecord ? ep->ContextRecord->Rbx : -1,
ep->ContextRecord ? ep->ContextRecord->R9 : -1,
ep->ContextRecord ? ep->ContextRecord->Rcx : -1,
ep->ContextRecord ? ep->ContextRecord->R10 : -1,
ep->ContextRecord ? ep->ContextRecord->Rdx : -1,
ep->ContextRecord ? ep->ContextRecord->R11 : -1,
ep->ContextRecord ? ep->ContextRecord->Rdi : -1,
ep->ContextRecord ? ep->ContextRecord->R12 : -1,
ep->ContextRecord ? ep->ContextRecord->Rsi : -1,
ep->ContextRecord ? ep->ContextRecord->R13 : -1,
ep->ContextRecord ? ep->ContextRecord->Rbp : -1,
ep->ContextRecord ? ep->ContextRecord->R14 : -1,
ep->ContextRecord ? ep->ContextRecord->Rsp : -1,
ep->ContextRecord ? ep->ContextRecord->R15 : -1);
ep->ContextRecord ? ep->ContextRecord->Rip : -1);
ExitProcess(73);
}
textwindows void WinMainForked(void) {
bool ok;
jmp_buf jb;
char *addr, *shad;
struct DirectMap dm;
uint64_t size, upsize;
int64_t reader, writer;
uint32_t flags1, flags2;
struct MemoryInterval *maps;
char16_t fvar[21 + 1 + 21 + 1];
int64_t oncrash, savetsc, savebir;
@ -133,10 +111,8 @@ textwindows void WinMainForked(void) {
long mapcount, mapcapacity, specialz;
extern uint64_t ts asm("kStartTsc");
/*
* check to see if the process was actually forked
* this variable should have the pipe handle numba
*/
// check to see if the process was actually forked
// this variable should have the pipe handle numba
varlen = GetEnvironmentVariable(u"_FORK", fvar, ARRAYLEN(fvar));
if (!varlen || varlen >= ARRAYLEN(fvar)) return;
STRACE("WinMainForked()");
@ -145,109 +121,134 @@ textwindows void WinMainForked(void) {
oncrash = AddVectoredExceptionHandler(1, NT2SYSV(OnForkCrash));
#endif
ParseInt(ParseInt(fvar, &reader), &writer);
CloseHandle(writer);
/*
* read the cpu state from the parent process
*/
ReadAll(reader, jb, sizeof(jb));
/*
* read the list of mappings from the parent process
* this is stored in a special secretive memory map!
* read ExtendMemoryIntervals for further details :|
*/
// read the cpu state from the parent process & plus
// read the list of mappings from the parent process
// this is stored in a special secretive memory map!
// read ExtendMemoryIntervals for further details :|
maps = (void *)kMemtrackStart;
ReadAll(reader, &mapcount, sizeof(_mmi.i));
ReadAll(reader, &mapcapacity, sizeof(_mmi.n));
if (!ReadAll(reader, jb, sizeof(jb)) ||
!ReadAll(reader, &mapcount, sizeof(_mmi.i)) ||
!ReadAll(reader, &mapcapacity, sizeof(_mmi.n))) {
ExitProcess(40);
}
specialz = ROUNDUP(mapcapacity * sizeof(_mmi.p[0]), kMemtrackGran);
MapViewOfFileEx(CreateFileMapping(-1, &kNtIsInheritable, kNtPageReadwrite,
specialz >> 32, specialz, 0),
kNtFileMapWrite, 0, 0, specialz, maps);
ReadAll(reader, maps, mapcount * sizeof(_mmi.p[0]));
if (!MapViewOfFileEx(CreateFileMapping(-1, 0, kNtPageReadwrite,
specialz >> 32, specialz, 0),
kNtFileMapWrite, 0, 0, specialz, maps)) {
ExitProcess(41);
}
if (!ReadAll(reader, maps, mapcount * sizeof(_mmi.p[0]))) {
ExitProcess(42);
}
if (IsAsan()) {
shad = (char *)(((intptr_t)maps >> 3) + 0x7fff8000);
size = ROUNDUP(specialz >> 3, FRAMESIZE);
MapViewOfFileEx(CreateFileMapping(-1, &kNtIsInheritable, kNtPageReadwrite,
size >> 32, size, 0),
kNtFileMapWrite, 0, 0, size, maps);
#if 0
ReadAll(reader, shad, (mapcount * sizeof(_mmi.p[0])) >> 3);
#endif
MapViewOfFileEx(
CreateFileMapping(-1, 0, kNtPageReadwrite, size >> 32, size, 0),
kNtFileMapWrite, 0, 0, size, maps);
if (!ReadAll(reader, shad, (mapcount * sizeof(_mmi.p[0])) >> 3)) {
ExitProcess(43);
}
}
/*
* read the heap mappings from the parent process
* we can avoid copying via pipe for shared maps!
*/
// read the heap mappings from the parent process
// we can avoid copying via pipe for shared maps!
for (i = 0; i < mapcount; ++i) {
addr = (char *)((uint64_t)maps[i].x << 16);
size = maps[i].size;
if (maps[i].flags & MAP_PRIVATE) {
STRACE("fork() child %p %'zu copying private map", addr, size);
if (!CloseHandle(maps[i].h)) {
STRACE("fork() child CloseHandle(%ld) ~~~FAILED~~~ %m", maps[i].h);
}
upsize = ROUNDUP(size, FRAMESIZE);
maps[i].h =
CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite,
upsize >> 32, upsize, NULL);
MapViewOfFileEx(maps[i].h, kNtFileMapWrite | kNtFileMapExecute, 0, 0,
upsize, addr);
ReadAll(reader, addr, size);
if (maps[i].prot & PROT_EXEC) {
flags1 = kNtPageExecuteReadwrite;
flags2 = kNtFileMapWrite | kNtFileMapExecute;
} else {
flags1 = kNtPageReadwrite;
flags2 = kNtFileMapWrite;
}
// we don't need to close the map handle because sys_mmap_nt
// doesn't mark it inheritable across fork() for MAP_PRIVATE
if (!(maps[i].h =
CreateFileMapping(-1, 0, flags1, upsize >> 32, upsize, 0)) ||
!MapViewOfFileEx(maps[i].h, flags2, 0, 0, upsize, addr) ||
!ReadAll(reader, addr, size)) {
ExitProcess(44);
}
} else {
STRACE("fork() child %p %'zu mapping shared hand:%ld offset:%'lu", addr,
size, maps[i].h, maps[i].offset);
MapViewOfFileEx(maps[i].h,
(maps[i].prot & PROT_WRITE)
? kNtFileMapWrite | kNtFileMapExecute
: kNtFileMapRead | kNtFileMapExecute,
maps[i].offset >> 32, maps[i].offset, size, addr);
// we can however safely inherit MAP_SHARED with zero copy
if (maps[i].prot & PROT_WRITE) {
if (maps[i].prot & PROT_EXEC) {
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);
}
}
}
/*
* read the .data and .bss program image sections
*/
// read the .data and .bss program image sections
savepid = __pid;
savebir = __kbirth;
savetsc = ts;
STRACE("fork() child reading %'zu bytes of .data to %p",
__data_end - __data_start, __data_start);
ReadAll(reader, __data_start, __data_end - __data_start);
STRACE("fork() child reading %'zu bytes of .bss to %p",
__bss_end - __bss_start, __bss_start);
ReadAll(reader, __bss_start, __bss_end - __bss_start);
if (!ReadAll(reader, __data_start, __data_end - __data_start) ||
!ReadAll(reader, __bss_start, __bss_end - __bss_start)) {
ExitProcess(46);
}
__pid = savepid;
__kbirth = savebir;
ts = savetsc;
/*
* apply fixups and reapply memory protections
*/
STRACE("fork() child applying fixups to _mmi.p");
// apply fixups and reapply memory protections
_mmi.p = maps;
_mmi.n = specialz / sizeof(_mmi.p[0]);
for (i = 0; i < mapcount; ++i) {
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),
ROUNDUP(maps[i].size, FRAMESIZE),
__prot2nt(maps[i].prot, 0), &oldprot);
ROUNDUP(maps[i].size, FRAMESIZE), flags1, &oldprot);
}
}
/*
* clean up and restore old processor state
*/
STRACE("fork() child almost done!");
CloseHandle(reader);
CloseHandle(writer);
// we're all done reading!
if (!CloseHandle(reader)) {
STRACE("CloseHandle(reader) failed %m");
ExitProcess(47);
}
// clean up, restore state, and jump back into function below
#ifdef SYSDEBUG
RemoveVectoredExceptionHandler(oncrash);
#endif
if (weaken(__wincrash_nt)) {
AddVectoredExceptionHandler(1, (void *)weaken(__wincrash_nt));
}
STRACE("fork() child it's time for the big jump (>'.')>");
longjmp(jb, 1);
}
@ -274,10 +275,8 @@ textwindows int sys_fork_nt(void) {
startinfo.hStdError = g_fds.p[2].handle;
args = __argv;
#ifdef SYSDEBUG
/*
* If --strace was passed to this program, then propagate it the
* forked process since the flag was removed by __intercept_flag
*/
// If --strace was passed to this program, then propagate it the
// forked process since the flag was removed by __intercept_flag
if (__strace > 0) {
for (n = 0; args[n];) ++n;
args2 = alloca((n + 2) * sizeof(char *));
@ -296,29 +295,24 @@ textwindows int sys_fork_nt(void) {
WriteAll(writer, &_mmi.i, sizeof(_mmi.i)) &&
WriteAll(writer, &_mmi.n, sizeof(_mmi.n)) &&
WriteAll(writer, _mmi.p, _mmi.i * sizeof(_mmi.p[0]));
#if 0
if (IsAsan() && ok) {
ok = WriteAll(writer, (char *)(((intptr_t)_mmi.p >> 3) + 0x7fff8000),
(_mmi.i * sizeof(_mmi.p[0])) >> 3);
}
#endif
for (i = 0; i < _mmi.i && ok; ++i) {
if (_mmi.p[i].flags & MAP_PRIVATE) {
ok = WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16),
_mmi.p[i].size);
}
}
if (ok) ok = WriteAll(writer, __data_start, __data_end - __data_start);
if (ok) ok = WriteAll(writer, __bss_start, __bss_end - __bss_start);
if (ok) {
STRACE("fork() parent writing %'zu bytes of .data",
__data_end - __data_start);
ok = WriteAll(writer, __data_start, __data_end - __data_start);
if (!CloseHandle(writer)) {
STRACE("CloseHandle(writer) failed %m");
ok = false;
}
}
if (ok) {
STRACE("fork() parent writing %'zu bytes of .bss",
__bss_end - __bss_start);
ok = WriteAll(writer, __bss_start, __bss_end - __bss_start);
}
ok = ok & !!CloseHandle(writer);
if (ok) {
if (!weaken(__sighandrvas) ||
weaken(__sighandrvas)[SIGCHLD] != SIG_IGN) {
@ -338,25 +332,21 @@ textwindows int sys_fork_nt(void) {
rc = GetProcessId(procinfo.hProcess);
CloseHandle(procinfo.hProcess);
}
STRACE("fork() parent everything looks good");
} else {
STRACE("fork() parent ~~failed~~ because writing failed");
rc = __winerr();
TerminateProcess(procinfo.hProcess, 127);
CloseHandle(procinfo.hProcess);
}
} else {
STRACE("fork() parent ~~failed~~ because ntspawn failed");
CloseHandle(writer);
rc = -1;
}
} else {
STRACE("fork() parent ~~failed~~ because CreatePipe() failed %m");
STRACE("CreatePipe() failed %m");
rc = __winerr();
CloseHandle(writer);
}
} else {
STRACE("fork() child welcome back <('.'<)");
rc = 0;
}
if (untrackpid != -1) {

View file

@ -27,8 +27,8 @@
/**
* Synchronize memory mapping changes to disk.
*
* Without this, there's no guarantee memory is written back to disk. In
* practice, what that means is just Windows NT.
* Without this, there's no guarantee memory is written back to disk.
* Particularly on RHEL5, OpenBSD, and Windows NT.
*
* @param addr needs to be 4096-byte page aligned
* @param flags needs MS_ASYNC or MS_SYNC and can have MS_INVALIDATE

View file

@ -85,7 +85,7 @@ const char *__describe_sockaddr(const struct sockaddr *sa, size_t sasize) {
p = buf;
p = stpcpy(p, ip);
*p++ = ':';
p = FormatUint32(p, in->sin_port);
p = FormatUint32(p, ntohs(in->sin_port));
}
} else if (sa->sa_family == AF_INET6 &&
sasize >= sizeof(struct sockaddr_in6)) {

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/color.internal.h"
@ -35,18 +36,20 @@ testonly void testlib_showerror(const char *file, int line, const char *func,
const char *method, const char *symbol,
const char *code, char *v1, char *v2) {
char *p;
/* TODO(jart): Pay off tech debt re duplication */
char hostname[128];
__getpid(); /* make strace easier to read */
__getpid();
kprintf("%serror%s%s:%s:%d%s: %s() in %s(%s)\n"
__stpcpy(hostname, "unknown");
gethostname(hostname, sizeof(hostname));
kprintf("%serror%s%s:%s:%d%s: %s() in %s(%s) on %s\n"
"\t%s\n"
"\t\tneed %s %s\n"
"\t\t got %s\n"
"\t%s%s\n"
"\t%s%s\n",
RED2, UNBOLD, BLUE1, file, (long)line, RESET, method, func,
g_fixturename, code, v1, symbol, v2, SUBTLE, strerror(errno),
GetProgramExecutableName(), RESET);
g_fixturename, hostname, code, v1, symbol, v2, SUBTLE,
strerror(errno), GetProgramExecutableName(), RESET);
free_s(&v1);
free_s(&v2);
}
@ -57,15 +60,17 @@ testonly void testlib_showerror_(int line, const char *wantcode,
char *FREED_got, const char *fmt, ...) {
int e;
va_list va;
char hostname[32];
char hostname[128];
e = errno;
__getpid();
__getpid();
kprintf("%serror%s:%s%s:%d%s: %s(%s)\n"
__stpcpy(hostname, "unknown");
gethostname(hostname, sizeof(hostname));
kprintf("%serror%s:%s%s:%d%s: %s(%s) on %s\n"
"\t%s(%s, %s)\n",
RED2, UNBOLD, BLUE1, testlib_showerror_file, line, RESET,
testlib_showerror_func, g_fixturename, testlib_showerror_macro,
wantcode, gotcode);
testlib_showerror_func, g_fixturename, hostname,
testlib_showerror_macro, wantcode, gotcode);
if (wantcode) {
kprintf("\t\tneed %s %s\n"
"\t\t got %s\n",
@ -80,8 +85,6 @@ testonly void testlib_showerror_(int line, const char *wantcode,
va_end(va);
kprintf("\n");
}
__stpcpy(hostname, "unknown");
gethostname(hostname, sizeof(hostname));
kprintf("\t%s%s%s\n"
"\t%s%s @ %s%s\n",
SUBTLE, strerror(e), RESET, SUBTLE, program_invocation_name, hostname,

View file

@ -1,6 +1,6 @@
# EastAsianWidth-14.0.0.txt
# Date: 2021-07-06, 09:58:53 GMT [KW, LI]
# © 2021 Unicode®, Inc.
# EastAsianWidth-15.0.0.txt
# Date: 2022-01-28, 13:07:15 GMT [KW, LI]
# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
# For terms of use, see https://www.unicode.org/terms_of_use.html
#
@ -534,6 +534,7 @@
0CE2..0CE3;N # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
0CE6..0CEF;N # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
0CF1..0CF2;N # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
0CF3;N # Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT
0D00..0D01;N # Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
0D02..0D03;N # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
0D04..0D0C;N # Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
@ -595,7 +596,7 @@
0EBD;N # Lo LAO SEMIVOWEL SIGN NYO
0EC0..0EC4;N # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
0EC6;N # Lm LAO KO LA
0EC8..0ECD;N # Mn [6] LAO TONE MAI EK..LAO NIGGAHITA
0EC8..0ECE;N # Mn [7] LAO TONE MAI EK..LAO YAMAKKAN
0ED0..0ED9;N # Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE
0EDC..0EDF;N # Lo [4] LAO HO NO..LAO LETTER KHMU NYO
0F00;N # Lo TIBETAN SYLLABLE OM
@ -1946,6 +1947,7 @@ FFFD;A # So REPLACEMENT CHARACTER
10EAB..10EAC;N # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
10EAD;N # Pd YEZIDI HYPHENATION MARK
10EB0..10EB1;N # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
10EFD..10EFF;N # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA
10F00..10F1C;N # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
10F1D..10F26;N # No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF
10F27;N # Lo OLD SOGDIAN LIGATURE AYIN-DALETH
@ -2028,6 +2030,8 @@ FFFD;A # So REPLACEMENT CHARACTER
11236..11237;N # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
11238..1123D;N # Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN
1123E;N # Mn KHOJKI SIGN SUKUN
1123F..11240;N # Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I
11241;N # Mn KHOJKI VOWEL SIGN VOCALIC R
11280..11286;N # Lo [7] MULTANI LETTER A..MULTANI LETTER GA
11288;N # Lo MULTANI LETTER GHA
1128A..1128D;N # Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA
@ -2190,6 +2194,7 @@ FFFD;A # So REPLACEMENT CHARACTER
11A9E..11AA2;N # Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2
11AB0..11ABF;N # Lo [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA
11AC0..11AF8;N # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL
11B00..11B09;N # Po [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU
11C00..11C08;N # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L
11C0A..11C2E;N # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA
11C2F;N # Mc BHAIKSUKI VOWEL SIGN AA
@ -2235,6 +2240,19 @@ FFFD;A # So REPLACEMENT CHARACTER
11EF3..11EF4;N # Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U
11EF5..11EF6;N # Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
11EF7..11EF8;N # Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION
11F00..11F01;N # Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA
11F02;N # Lo KAWI SIGN REPHA
11F03;N # Mc KAWI SIGN VISARGA
11F04..11F10;N # Lo [13] KAWI LETTER A..KAWI LETTER O
11F12..11F33;N # Lo [34] KAWI LETTER KA..KAWI LETTER JNYA
11F34..11F35;N # Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA
11F36..11F3A;N # Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R
11F3E..11F3F;N # Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI
11F40;N # Mn KAWI VOWEL SIGN EU
11F41;N # Mc KAWI SIGN KILLER
11F42;N # Mn KAWI CONJOINER
11F43..11F4F;N # Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL
11F50..11F59;N # Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE
11FB0;N # Lo LISU LETTER YHA
11FC0..11FD4;N # No [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH
11FD5..11FDC;N # So [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI
@ -2247,8 +2265,10 @@ FFFD;A # So REPLACEMENT CHARACTER
12480..12543;N # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
12F90..12FF0;N # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114
12FF1..12FF2;N # Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302
13000..1342E;N # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032
13430..13438;N # Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT
13000..1342F;N # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D
13430..13440;N # Cf [17] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY
13441..13446;N # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN
13447..13455;N # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED
14400..14646;N # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530
16800..16A38;N # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ
16A40..16A5E;N # Lo [31] MRO LETTER TA..MRO LETTER TEK
@ -2293,7 +2313,9 @@ FFFD;A # So REPLACEMENT CHARACTER
1AFFD..1AFFE;W # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8
1B000..1B0FF;W # Lo [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2
1B100..1B122;W # Lo [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU
1B132;W # Lo HIRAGANA LETTER SMALL KO
1B150..1B152;W # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
1B155;W # Lo KATAKANA LETTER SMALL KO
1B164..1B167;W # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
1B170..1B2FB;W # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB
1BC00..1BC6A;N # Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M
@ -2324,6 +2346,7 @@ FFFD;A # So REPLACEMENT CHARACTER
1D200..1D241;N # So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54
1D242..1D244;N # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
1D245;N # So GREEK MUSICAL LEIMMA
1D2C0..1D2D3;N # No [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN
1D2E0..1D2F3;N # No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN
1D300..1D356;N # So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
1D360..1D378;N # No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE
@ -2383,11 +2406,14 @@ FFFD;A # So REPLACEMENT CHARACTER
1DF00..1DF09;N # Ll [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK
1DF0A;N # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK
1DF0B..1DF1E;N # Ll [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL
1DF25..1DF2A;N # Ll [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK
1E000..1E006;N # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
1E008..1E018;N # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
1E01B..1E021;N # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI
1E023..1E024;N # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
1E026..1E02A;N # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
1E030..1E06D;N # Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE
1E08F;N # Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
1E100..1E12C;N # Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W
1E130..1E136;N # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D
1E137..1E13D;N # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER
@ -2400,6 +2426,10 @@ FFFD;A # So REPLACEMENT CHARACTER
1E2EC..1E2EF;N # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI
1E2F0..1E2F9;N # Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE
1E2FF;N # Sc WANCHO NGUN SIGN
1E4D0..1E4EA;N # Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL
1E4EB;N # Lm NAG MUNDARI SIGN OJOD
1E4EC..1E4EF;N # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH
1E4F0..1E4F9;N # Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE
1E7E0..1E7E6;N # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO
1E7E8..1E7EB;N # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE
1E7ED..1E7EE;N # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE
@ -2528,13 +2558,14 @@ FFFD;A # So REPLACEMENT CHARACTER
1F6D0..1F6D2;W # So [3] PLACE OF WORSHIP..SHOPPING TROLLEY
1F6D3..1F6D4;N # So [2] STUPA..PAGODA
1F6D5..1F6D7;W # So [3] HINDU TEMPLE..ELEVATOR
1F6DD..1F6DF;W # So [3] PLAYGROUND SLIDE..RING BUOY
1F6DC..1F6DF;W # So [4] WIRELESS..RING BUOY
1F6E0..1F6EA;N # So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE
1F6EB..1F6EC;W # So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING
1F6F0..1F6F3;N # So [4] SATELLITE..PASSENGER SHIP
1F6F4..1F6FC;W # So [9] SCOOTER..ROLLER SKATE
1F700..1F773;N # So [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE
1F780..1F7D8;N # So [89] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NEGATIVE CIRCLED SQUARE
1F700..1F776;N # So [119] ALCHEMICAL SYMBOL FOR QUINTESSENCE..LUNAR ECLIPSE
1F77B..1F77F;N # So [5] HAUMEA..ORCUS
1F780..1F7D9;N # So [90] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NINE POINTED WHITE STAR
1F7E0..1F7EB;W # So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE
1F7F0;W # So HEAVY EQUALS SIGN
1F800..1F80B;N # So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD
@ -2551,15 +2582,14 @@ FFFD;A # So REPLACEMENT CHARACTER
1F947..1F9FF;W # So [185] FIRST PLACE MEDAL..NAZAR AMULET
1FA00..1FA53;N # So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP
1FA60..1FA6D;N # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER
1FA70..1FA74;W # So [5] BALLET SHOES..THONG SANDAL
1FA78..1FA7C;W # So [5] DROP OF BLOOD..CRUTCH
1FA80..1FA86;W # So [7] YO-YO..NESTING DOLLS
1FA90..1FAAC;W # So [29] RINGED PLANET..HAMSA
1FAB0..1FABA;W # So [11] FLY..NEST WITH EGGS
1FAC0..1FAC5;W # So [6] ANATOMICAL HEART..PERSON WITH CROWN
1FAD0..1FAD9;W # So [10] BLUEBERRIES..JAR
1FAE0..1FAE7;W # So [8] MELTING FACE..BUBBLES
1FAF0..1FAF6;W # So [7] HAND WITH INDEX FINGER AND THUMB CROSSED..HEART HANDS
1FA70..1FA7C;W # So [13] BALLET SHOES..CRUTCH
1FA80..1FA88;W # So [9] YO-YO..FLUTE
1FA90..1FABD;W # So [46] RINGED PLANET..WING
1FABE;W # Cn <reserved-1FABE>
1FABF..1FAC5;W # So [7] GOOSE..PERSON WITH CROWN
1FACE..1FADB;W # So [14] MOOSE..PEA POD
1FAE0..1FAE8;W # So [9] MELTING FACE..SHAKING FACE
1FAF0..1FAF8;W # So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND
1FB00..1FB92;N # So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK
1FB94..1FBCA;N # So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON
1FBF0..1FBF9;N # Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE
@ -2577,7 +2607,9 @@ FFFD;A # So REPLACEMENT CHARACTER
2FA1E..2FA1F;W # Cn [2] <reserved-2FA1E>..<reserved-2FA1F>
2FA20..2FFFD;W # Cn [1502] <reserved-2FA20>..<reserved-2FFFD>
30000..3134A;W # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
3134B..3FFFD;W # Cn [60595] <reserved-3134B>..<reserved-3FFFD>
3134B..3134F;W # Cn [5] <reserved-3134B>..<reserved-3134F>
31350..323AF;W # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF
323B0..3FFFD;W # Cn [56398] <reserved-323B0>..<reserved-3FFFD>
E0001;N # Cf LANGUAGE TAG
E0020..E007F;N # Cf [96] TAG SPACE..CANCEL TAG
E0100..E01EF;A # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256

View file

@ -2975,6 +2975,7 @@
0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
0CF3;KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT;Mc;0;L;;;;;N;;;;;
0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;
0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
@ -3339,6 +3340,7 @@
0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;;
0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;;
0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;;
0ECE;LAO YAMAKKAN;Mn;0;NSM;;;;;N;;;;;
0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@ -19393,6 +19395,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10EAD;YEZIDI HYPHENATION MARK;Pd;0;R;;;;;N;;;;;
10EB0;YEZIDI LETTER LAM WITH DOT ABOVE;Lo;0;R;;;;;N;;;;;
10EB1;YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE;Lo;0;R;;;;;N;;;;;
10EFD;ARABIC SMALL LOW WORD SAKTA;Mn;220;NSM;;;;;N;;;;;
10EFE;ARABIC SMALL LOW WORD QASR;Mn;220;NSM;;;;;N;;;;;
10EFF;ARABIC SMALL LOW WORD MADDA;Mn;220;NSM;;;;;N;;;;;
10F00;OLD SOGDIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;;
10F02;OLD SOGDIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
@ -20058,6 +20063,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1123C;KHOJKI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
1123E;KHOJKI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;;
1123F;KHOJKI LETTER QA;Lo;0;L;;;;;N;;;;;
11240;KHOJKI LETTER SHORT I;Lo;0;L;;;;;N;;;;;
11241;KHOJKI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
11280;MULTANI LETTER A;Lo;0;L;;;;;N;;;;;
11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;;
11282;MULTANI LETTER U;Lo;0;L;;;;;N;;;;;
@ -21256,6 +21264,16 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
11AF6;PAU CIN HAU LOW-FALLING TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
11AF7;PAU CIN HAU LOW-FALLING TONE FINAL;Lo;0;L;;;;;N;;;;;
11AF8;PAU CIN HAU GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;;
11B00;DEVANAGARI HEAD MARK;Po;0;L;;;;;N;;;;;
11B01;DEVANAGARI HEAD MARK WITH HEADSTROKE;Po;0;L;;;;;N;;;;;
11B02;DEVANAGARI SIGN BHALE;Po;0;L;;;;;N;;;;;
11B03;DEVANAGARI SIGN BHALE WITH HOOK;Po;0;L;;;;;N;;;;;
11B04;DEVANAGARI SIGN EXTENDED BHALE;Po;0;L;;;;;N;;;;;
11B05;DEVANAGARI SIGN EXTENDED BHALE WITH HOOK;Po;0;L;;;;;N;;;;;
11B06;DEVANAGARI SIGN WESTERN FIVE-LIKE BHALE;Po;0;L;;;;;N;;;;;
11B07;DEVANAGARI SIGN WESTERN NINE-LIKE BHALE;Po;0;L;;;;;N;;;;;
11B08;DEVANAGARI SIGN REVERSED NINE-LIKE BHALE;Po;0;L;;;;;N;;;;;
11B09;DEVANAGARI SIGN MINDU;Po;0;L;;;;;N;;;;;
11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;;
11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;;
11C02;BHAIKSUKI LETTER I;Lo;0;L;;;;;N;;;;;
@ -21584,6 +21602,92 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;;
11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;;
11F00;KAWI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
11F01;KAWI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
11F02;KAWI SIGN REPHA;Lo;0;L;;;;;N;;;;;
11F03;KAWI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
11F04;KAWI LETTER A;Lo;0;L;;;;;N;;;;;
11F05;KAWI LETTER AA;Lo;0;L;;;;;N;;;;;
11F06;KAWI LETTER I;Lo;0;L;;;;;N;;;;;
11F07;KAWI LETTER II;Lo;0;L;;;;;N;;;;;
11F08;KAWI LETTER U;Lo;0;L;;;;;N;;;;;
11F09;KAWI LETTER UU;Lo;0;L;;;;;N;;;;;
11F0A;KAWI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
11F0B;KAWI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
11F0C;KAWI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
11F0D;KAWI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
11F0E;KAWI LETTER E;Lo;0;L;;;;;N;;;;;
11F0F;KAWI LETTER AI;Lo;0;L;;;;;N;;;;;
11F10;KAWI LETTER O;Lo;0;L;;;;;N;;;;;
11F12;KAWI LETTER KA;Lo;0;L;;;;;N;;;;;
11F13;KAWI LETTER KHA;Lo;0;L;;;;;N;;;;;
11F14;KAWI LETTER GA;Lo;0;L;;;;;N;;;;;
11F15;KAWI LETTER GHA;Lo;0;L;;;;;N;;;;;
11F16;KAWI LETTER NGA;Lo;0;L;;;;;N;;;;;
11F17;KAWI LETTER CA;Lo;0;L;;;;;N;;;;;
11F18;KAWI LETTER CHA;Lo;0;L;;;;;N;;;;;
11F19;KAWI LETTER JA;Lo;0;L;;;;;N;;;;;
11F1A;KAWI LETTER JHA;Lo;0;L;;;;;N;;;;;
11F1B;KAWI LETTER NYA;Lo;0;L;;;;;N;;;;;
11F1C;KAWI LETTER TTA;Lo;0;L;;;;;N;;;;;
11F1D;KAWI LETTER TTHA;Lo;0;L;;;;;N;;;;;
11F1E;KAWI LETTER DDA;Lo;0;L;;;;;N;;;;;
11F1F;KAWI LETTER DDHA;Lo;0;L;;;;;N;;;;;
11F20;KAWI LETTER NNA;Lo;0;L;;;;;N;;;;;
11F21;KAWI LETTER TA;Lo;0;L;;;;;N;;;;;
11F22;KAWI LETTER THA;Lo;0;L;;;;;N;;;;;
11F23;KAWI LETTER DA;Lo;0;L;;;;;N;;;;;
11F24;KAWI LETTER DHA;Lo;0;L;;;;;N;;;;;
11F25;KAWI LETTER NA;Lo;0;L;;;;;N;;;;;
11F26;KAWI LETTER PA;Lo;0;L;;;;;N;;;;;
11F27;KAWI LETTER PHA;Lo;0;L;;;;;N;;;;;
11F28;KAWI LETTER BA;Lo;0;L;;;;;N;;;;;
11F29;KAWI LETTER BHA;Lo;0;L;;;;;N;;;;;
11F2A;KAWI LETTER MA;Lo;0;L;;;;;N;;;;;
11F2B;KAWI LETTER YA;Lo;0;L;;;;;N;;;;;
11F2C;KAWI LETTER RA;Lo;0;L;;;;;N;;;;;
11F2D;KAWI LETTER LA;Lo;0;L;;;;;N;;;;;
11F2E;KAWI LETTER WA;Lo;0;L;;;;;N;;;;;
11F2F;KAWI LETTER SHA;Lo;0;L;;;;;N;;;;;
11F30;KAWI LETTER SSA;Lo;0;L;;;;;N;;;;;
11F31;KAWI LETTER SA;Lo;0;L;;;;;N;;;;;
11F32;KAWI LETTER HA;Lo;0;L;;;;;N;;;;;
11F33;KAWI LETTER JNYA;Lo;0;L;;;;;N;;;;;
11F34;KAWI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
11F35;KAWI VOWEL SIGN ALTERNATE AA;Mc;0;L;;;;;N;;;;;
11F36;KAWI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
11F37;KAWI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
11F38;KAWI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
11F39;KAWI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
11F3A;KAWI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
11F3E;KAWI VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
11F3F;KAWI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
11F40;KAWI VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;;
11F41;KAWI SIGN KILLER;Mc;9;L;;;;;N;;;;;
11F42;KAWI CONJOINER;Mn;9;NSM;;;;;N;;;;;
11F43;KAWI DANDA;Po;0;L;;;;;N;;;;;
11F44;KAWI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
11F45;KAWI PUNCTUATION SECTION MARKER;Po;0;L;;;;;N;;;;;
11F46;KAWI PUNCTUATION ALTERNATE SECTION MARKER;Po;0;L;;;;;N;;;;;
11F47;KAWI PUNCTUATION FLOWER;Po;0;L;;;;;N;;;;;
11F48;KAWI PUNCTUATION SPACE FILLER;Po;0;L;;;;;N;;;;;
11F49;KAWI PUNCTUATION DOT;Po;0;L;;;;;N;;;;;
11F4A;KAWI PUNCTUATION DOUBLE DOT;Po;0;L;;;;;N;;;;;
11F4B;KAWI PUNCTUATION TRIPLE DOT;Po;0;L;;;;;N;;;;;
11F4C;KAWI PUNCTUATION CIRCLE;Po;0;L;;;;;N;;;;;
11F4D;KAWI PUNCTUATION FILLED CIRCLE;Po;0;L;;;;;N;;;;;
11F4E;KAWI PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;;
11F4F;KAWI PUNCTUATION CLOSING SPIRAL;Po;0;L;;;;;N;;;;;
11F50;KAWI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
11F51;KAWI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
11F52;KAWI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
11F53;KAWI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
11F54;KAWI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
11F55;KAWI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
11F56;KAWI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
11F57;KAWI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
11F58;KAWI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
11F59;KAWI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
11FB0;LISU LETTER YHA;Lo;0;L;;;;;N;;;;;
11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;;
11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;;
@ -24040,6 +24144,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;;
1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;;
1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;;
1342F;EGYPTIAN HIEROGLYPH V011D;Lo;0;L;;;;;N;;;;;
13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;;
13431;EGYPTIAN HIEROGLYPH HORIZONTAL JOINER;Cf;0;L;;;;;N;;;;;
13432;EGYPTIAN HIEROGLYPH INSERT AT TOP START;Cf;0;L;;;;;N;;;;;
@ -24049,6 +24154,35 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;;
13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;;
13438;EGYPTIAN HIEROGLYPH END SEGMENT;Cf;0;L;;;;;N;;;;;
13439;EGYPTIAN HIEROGLYPH INSERT AT MIDDLE;Cf;0;L;;;;;N;;;;;
1343A;EGYPTIAN HIEROGLYPH INSERT AT TOP;Cf;0;L;;;;;N;;;;;
1343B;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM;Cf;0;L;;;;;N;;;;;
1343C;EGYPTIAN HIEROGLYPH BEGIN ENCLOSURE;Cf;0;L;;;;;N;;;;;
1343D;EGYPTIAN HIEROGLYPH END ENCLOSURE;Cf;0;L;;;;;N;;;;;
1343E;EGYPTIAN HIEROGLYPH BEGIN WALLED ENCLOSURE;Cf;0;L;;;;;N;;;;;
1343F;EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE;Cf;0;L;;;;;N;;;;;
13440;EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY;Cf;0;L;;;;;N;;;;;
13441;EGYPTIAN HIEROGLYPH FULL BLANK;Lo;0;L;;;;;N;;;;;
13442;EGYPTIAN HIEROGLYPH HALF BLANK;Lo;0;L;;;;;N;;;;;
13443;EGYPTIAN HIEROGLYPH LOST SIGN;Lo;0;L;;;;;N;;;;;
13444;EGYPTIAN HIEROGLYPH HALF LOST SIGN;Lo;0;L;;;;;N;;;;;
13445;EGYPTIAN HIEROGLYPH TALL LOST SIGN;Lo;0;L;;;;;N;;;;;
13446;EGYPTIAN HIEROGLYPH WIDE LOST SIGN;Lo;0;L;;;;;N;;;;;
13447;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START;Mn;0;NSM;;;;;N;;;;;
13448;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM START;Mn;0;NSM;;;;;N;;;;;
13449;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START;Mn;0;NSM;;;;;N;;;;;
1344A;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP END;Mn;0;NSM;;;;;N;;;;;
1344B;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP;Mn;0;NSM;;;;;N;;;;;
1344C;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM START AND TOP END;Mn;0;NSM;;;;;N;;;;;
1344D;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START AND TOP;Mn;0;NSM;;;;;N;;;;;
1344E;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM END;Mn;0;NSM;;;;;N;;;;;
1344F;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START AND BOTTOM END;Mn;0;NSM;;;;;N;;;;;
13450;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM;Mn;0;NSM;;;;;N;;;;;
13451;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START AND BOTTOM;Mn;0;NSM;;;;;N;;;;;
13452;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT END;Mn;0;NSM;;;;;N;;;;;
13453;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP AND END;Mn;0;NSM;;;;;N;;;;;
13454;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM AND END;Mn;0;NSM;;;;;N;;;;;
13455;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED;Mn;0;NSM;;;;;N;;;;;
14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
@ -27289,9 +27423,11 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1B120;KATAKANA LETTER ARCHAIC YI;Lo;0;L;;;;;N;;;;;
1B121;KATAKANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
1B122;KATAKANA LETTER ARCHAIC WU;Lo;0;L;;;;;N;;;;;
1B132;HIRAGANA LETTER SMALL KO;Lo;0;L;;;;;N;;;;;
1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;
1B155;KATAKANA LETTER SMALL KO;Lo;0;L;;;;;N;;;;;
1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
1B166;KATAKANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;
@ -28573,6 +28709,26 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;;
1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;;
1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;;
1D2C0;KAKTOVIK NUMERAL ZERO;No;0;ON;;;;0;N;;;;;
1D2C1;KAKTOVIK NUMERAL ONE;No;0;ON;;;;1;N;;;;;
1D2C2;KAKTOVIK NUMERAL TWO;No;0;ON;;;;2;N;;;;;
1D2C3;KAKTOVIK NUMERAL THREE;No;0;ON;;;;3;N;;;;;
1D2C4;KAKTOVIK NUMERAL FOUR;No;0;ON;;;;4;N;;;;;
1D2C5;KAKTOVIK NUMERAL FIVE;No;0;ON;;;;5;N;;;;;
1D2C6;KAKTOVIK NUMERAL SIX;No;0;ON;;;;6;N;;;;;
1D2C7;KAKTOVIK NUMERAL SEVEN;No;0;ON;;;;7;N;;;;;
1D2C8;KAKTOVIK NUMERAL EIGHT;No;0;ON;;;;8;N;;;;;
1D2C9;KAKTOVIK NUMERAL NINE;No;0;ON;;;;9;N;;;;;
1D2CA;KAKTOVIK NUMERAL TEN;No;0;ON;;;;10;N;;;;;
1D2CB;KAKTOVIK NUMERAL ELEVEN;No;0;ON;;;;11;N;;;;;
1D2CC;KAKTOVIK NUMERAL TWELVE;No;0;ON;;;;12;N;;;;;
1D2CD;KAKTOVIK NUMERAL THIRTEEN;No;0;ON;;;;13;N;;;;;
1D2CE;KAKTOVIK NUMERAL FOURTEEN;No;0;ON;;;;14;N;;;;;
1D2CF;KAKTOVIK NUMERAL FIFTEEN;No;0;ON;;;;15;N;;;;;
1D2D0;KAKTOVIK NUMERAL SIXTEEN;No;0;ON;;;;16;N;;;;;
1D2D1;KAKTOVIK NUMERAL SEVENTEEN;No;0;ON;;;;17;N;;;;;
1D2D2;KAKTOVIK NUMERAL EIGHTEEN;No;0;ON;;;;18;N;;;;;
1D2D3;KAKTOVIK NUMERAL NINETEEN;No;0;ON;;;;19;N;;;;;
1D2E0;MAYAN NUMERAL ZERO;No;0;L;;;;0;N;;;;;
1D2E1;MAYAN NUMERAL ONE;No;0;L;;;;1;N;;;;;
1D2E2;MAYAN NUMERAL TWO;No;0;L;;;;2;N;;;;;
@ -30404,6 +30560,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1DF1C;LATIN SMALL LETTER TESH DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
1DF1D;LATIN SMALL LETTER C WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
1DF1E;LATIN SMALL LETTER S WITH CURL;Ll;0;L;;;;;N;;;;;
1DF25;LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
1DF26;LATIN SMALL LETTER L WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
1DF27;LATIN SMALL LETTER N WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
1DF28;LATIN SMALL LETTER R WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
1DF29;LATIN SMALL LETTER S WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
1DF2A;LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;;
1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;;
1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;;
@ -30442,6 +30604,69 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;;
1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;
1E030;MODIFIER LETTER CYRILLIC SMALL A;Lm;0;L;<super> 0430;;;;N;;;;;
1E031;MODIFIER LETTER CYRILLIC SMALL BE;Lm;0;L;<super> 0431;;;;N;;;;;
1E032;MODIFIER LETTER CYRILLIC SMALL VE;Lm;0;L;<super> 0432;;;;N;;;;;
1E033;MODIFIER LETTER CYRILLIC SMALL GHE;Lm;0;L;<super> 0433;;;;N;;;;;
1E034;MODIFIER LETTER CYRILLIC SMALL DE;Lm;0;L;<super> 0434;;;;N;;;;;
1E035;MODIFIER LETTER CYRILLIC SMALL IE;Lm;0;L;<super> 0435;;;;N;;;;;
1E036;MODIFIER LETTER CYRILLIC SMALL ZHE;Lm;0;L;<super> 0436;;;;N;;;;;
1E037;MODIFIER LETTER CYRILLIC SMALL ZE;Lm;0;L;<super> 0437;;;;N;;;;;
1E038;MODIFIER LETTER CYRILLIC SMALL I;Lm;0;L;<super> 0438;;;;N;;;;;
1E039;MODIFIER LETTER CYRILLIC SMALL KA;Lm;0;L;<super> 043A;;;;N;;;;;
1E03A;MODIFIER LETTER CYRILLIC SMALL EL;Lm;0;L;<super> 043B;;;;N;;;;;
1E03B;MODIFIER LETTER CYRILLIC SMALL EM;Lm;0;L;<super> 043C;;;;N;;;;;
1E03C;MODIFIER LETTER CYRILLIC SMALL O;Lm;0;L;<super> 043E;;;;N;;;;;
1E03D;MODIFIER LETTER CYRILLIC SMALL PE;Lm;0;L;<super> 043F;;;;N;;;;;
1E03E;MODIFIER LETTER CYRILLIC SMALL ER;Lm;0;L;<super> 0440;;;;N;;;;;
1E03F;MODIFIER LETTER CYRILLIC SMALL ES;Lm;0;L;<super> 0441;;;;N;;;;;
1E040;MODIFIER LETTER CYRILLIC SMALL TE;Lm;0;L;<super> 0442;;;;N;;;;;
1E041;MODIFIER LETTER CYRILLIC SMALL U;Lm;0;L;<super> 0443;;;;N;;;;;
1E042;MODIFIER LETTER CYRILLIC SMALL EF;Lm;0;L;<super> 0444;;;;N;;;;;
1E043;MODIFIER LETTER CYRILLIC SMALL HA;Lm;0;L;<super> 0445;;;;N;;;;;
1E044;MODIFIER LETTER CYRILLIC SMALL TSE;Lm;0;L;<super> 0446;;;;N;;;;;
1E045;MODIFIER LETTER CYRILLIC SMALL CHE;Lm;0;L;<super> 0447;;;;N;;;;;
1E046;MODIFIER LETTER CYRILLIC SMALL SHA;Lm;0;L;<super> 0448;;;;N;;;;;
1E047;MODIFIER LETTER CYRILLIC SMALL YERU;Lm;0;L;<super> 044B;;;;N;;;;;
1E048;MODIFIER LETTER CYRILLIC SMALL E;Lm;0;L;<super> 044D;;;;N;;;;;
1E049;MODIFIER LETTER CYRILLIC SMALL YU;Lm;0;L;<super> 044E;;;;N;;;;;
1E04A;MODIFIER LETTER CYRILLIC SMALL DZZE;Lm;0;L;<super> A689;;;;N;;;;;
1E04B;MODIFIER LETTER CYRILLIC SMALL SCHWA;Lm;0;L;<super> 04D9;;;;N;;;;;
1E04C;MODIFIER LETTER CYRILLIC SMALL BYELORUSSIAN-UKRAINIAN I;Lm;0;L;<super> 0456;;;;N;;;;;
1E04D;MODIFIER LETTER CYRILLIC SMALL JE;Lm;0;L;<super> 0458;;;;N;;;;;
1E04E;MODIFIER LETTER CYRILLIC SMALL BARRED O;Lm;0;L;<super> 04D9;;;;N;;;;;
1E04F;MODIFIER LETTER CYRILLIC SMALL STRAIGHT U;Lm;0;L;<super> 04AF;;;;N;;;;;
1E050;MODIFIER LETTER CYRILLIC SMALL PALOCHKA;Lm;0;L;<super> 04CF;;;;N;;;;;
1E051;CYRILLIC SUBSCRIPT SMALL LETTER A;Lm;0;L;<sub> 0430;;;;N;;;;;
1E052;CYRILLIC SUBSCRIPT SMALL LETTER BE;Lm;0;L;<sub> 0431;;;;N;;;;;
1E053;CYRILLIC SUBSCRIPT SMALL LETTER VE;Lm;0;L;<sub> 0432;;;;N;;;;;
1E054;CYRILLIC SUBSCRIPT SMALL LETTER GHE;Lm;0;L;<sub> 0433;;;;N;;;;;
1E055;CYRILLIC SUBSCRIPT SMALL LETTER DE;Lm;0;L;<sub> 0434;;;;N;;;;;
1E056;CYRILLIC SUBSCRIPT SMALL LETTER IE;Lm;0;L;<sub> 0435;;;;N;;;;;
1E057;CYRILLIC SUBSCRIPT SMALL LETTER ZHE;Lm;0;L;<sub> 0436;;;;N;;;;;
1E058;CYRILLIC SUBSCRIPT SMALL LETTER ZE;Lm;0;L;<sub> 0437;;;;N;;;;;
1E059;CYRILLIC SUBSCRIPT SMALL LETTER I;Lm;0;L;<sub> 0438;;;;N;;;;;
1E05A;CYRILLIC SUBSCRIPT SMALL LETTER KA;Lm;0;L;<sub> 043A;;;;N;;;;;
1E05B;CYRILLIC SUBSCRIPT SMALL LETTER EL;Lm;0;L;<sub> 043B;;;;N;;;;;
1E05C;CYRILLIC SUBSCRIPT SMALL LETTER O;Lm;0;L;<sub> 043E;;;;N;;;;;
1E05D;CYRILLIC SUBSCRIPT SMALL LETTER PE;Lm;0;L;<sub> 043F;;;;N;;;;;
1E05E;CYRILLIC SUBSCRIPT SMALL LETTER ES;Lm;0;L;<sub> 0441;;;;N;;;;;
1E05F;CYRILLIC SUBSCRIPT SMALL LETTER U;Lm;0;L;<sub> 0443;;;;N;;;;;
1E060;CYRILLIC SUBSCRIPT SMALL LETTER EF;Lm;0;L;<sub> 0444;;;;N;;;;;
1E061;CYRILLIC SUBSCRIPT SMALL LETTER HA;Lm;0;L;<sub> 0445;;;;N;;;;;
1E062;CYRILLIC SUBSCRIPT SMALL LETTER TSE;Lm;0;L;<sub> 0446;;;;N;;;;;
1E063;CYRILLIC SUBSCRIPT SMALL LETTER CHE;Lm;0;L;<sub> 0447;;;;N;;;;;
1E064;CYRILLIC SUBSCRIPT SMALL LETTER SHA;Lm;0;L;<sub> 0448;;;;N;;;;;
1E065;CYRILLIC SUBSCRIPT SMALL LETTER HARD SIGN;Lm;0;L;<sub> 044A;;;;N;;;;;
1E066;CYRILLIC SUBSCRIPT SMALL LETTER YERU;Lm;0;L;<sub> 044B;;;;N;;;;;
1E067;CYRILLIC SUBSCRIPT SMALL LETTER GHE WITH UPTURN;Lm;0;L;<sub> 0491;;;;N;;;;;
1E068;CYRILLIC SUBSCRIPT SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Lm;0;L;<sub> 0456;;;;N;;;;;
1E069;CYRILLIC SUBSCRIPT SMALL LETTER DZE;Lm;0;L;<sub> 0455;;;;N;;;;;
1E06A;CYRILLIC SUBSCRIPT SMALL LETTER DZHE;Lm;0;L;<sub> 045F;;;;N;;;;;
1E06B;MODIFIER LETTER CYRILLIC SMALL ES WITH DESCENDER;Lm;0;L;<super> 04AB;;;;N;;;;;
1E06C;MODIFIER LETTER CYRILLIC SMALL YERU WITH BACK YER;Lm;0;L;<super> A651;;;;N;;;;;
1E06D;MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE;Lm;0;L;<super> 04B1;;;;N;;;;;
1E08F;COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Mn;230;NSM;;;;;N;;;;;
1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;;
1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;;
1E102;NYIAKENG PUACHUE HMONG LETTER NTA;Lo;0;L;;;;;N;;;;;
@ -30603,6 +30828,48 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;;
1E4D0;NAG MUNDARI LETTER O;Lo;0;L;;;;;N;;;;;
1E4D1;NAG MUNDARI LETTER OP;Lo;0;L;;;;;N;;;;;
1E4D2;NAG MUNDARI LETTER OL;Lo;0;L;;;;;N;;;;;
1E4D3;NAG MUNDARI LETTER OY;Lo;0;L;;;;;N;;;;;
1E4D4;NAG MUNDARI LETTER ONG;Lo;0;L;;;;;N;;;;;
1E4D5;NAG MUNDARI LETTER A;Lo;0;L;;;;;N;;;;;
1E4D6;NAG MUNDARI LETTER AJ;Lo;0;L;;;;;N;;;;;
1E4D7;NAG MUNDARI LETTER AB;Lo;0;L;;;;;N;;;;;
1E4D8;NAG MUNDARI LETTER ANY;Lo;0;L;;;;;N;;;;;
1E4D9;NAG MUNDARI LETTER AH;Lo;0;L;;;;;N;;;;;
1E4DA;NAG MUNDARI LETTER I;Lo;0;L;;;;;N;;;;;
1E4DB;NAG MUNDARI LETTER IS;Lo;0;L;;;;;N;;;;;
1E4DC;NAG MUNDARI LETTER IDD;Lo;0;L;;;;;N;;;;;
1E4DD;NAG MUNDARI LETTER IT;Lo;0;L;;;;;N;;;;;
1E4DE;NAG MUNDARI LETTER IH;Lo;0;L;;;;;N;;;;;
1E4DF;NAG MUNDARI LETTER U;Lo;0;L;;;;;N;;;;;
1E4E0;NAG MUNDARI LETTER UC;Lo;0;L;;;;;N;;;;;
1E4E1;NAG MUNDARI LETTER UD;Lo;0;L;;;;;N;;;;;
1E4E2;NAG MUNDARI LETTER UK;Lo;0;L;;;;;N;;;;;
1E4E3;NAG MUNDARI LETTER UR;Lo;0;L;;;;;N;;;;;
1E4E4;NAG MUNDARI LETTER E;Lo;0;L;;;;;N;;;;;
1E4E5;NAG MUNDARI LETTER ENN;Lo;0;L;;;;;N;;;;;
1E4E6;NAG MUNDARI LETTER EG;Lo;0;L;;;;;N;;;;;
1E4E7;NAG MUNDARI LETTER EM;Lo;0;L;;;;;N;;;;;
1E4E8;NAG MUNDARI LETTER EN;Lo;0;L;;;;;N;;;;;
1E4E9;NAG MUNDARI LETTER ETT;Lo;0;L;;;;;N;;;;;
1E4EA;NAG MUNDARI LETTER ELL;Lo;0;L;;;;;N;;;;;
1E4EB;NAG MUNDARI SIGN OJOD;Lm;0;L;;;;;N;;;;;
1E4EC;NAG MUNDARI SIGN MUHOR;Mn;232;NSM;;;;;N;;;;;
1E4ED;NAG MUNDARI SIGN TOYOR;Mn;232;NSM;;;;;N;;;;;
1E4EE;NAG MUNDARI SIGN IKIR;Mn;220;NSM;;;;;N;;;;;
1E4EF;NAG MUNDARI SIGN SUTUH;Mn;230;NSM;;;;;N;;;;;
1E4F0;NAG MUNDARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
1E4F1;NAG MUNDARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
1E4F2;NAG MUNDARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
1E4F3;NAG MUNDARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
1E4F4;NAG MUNDARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
1E4F5;NAG MUNDARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
1E4F6;NAG MUNDARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
1E4F7;NAG MUNDARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
1E4F8;NAG MUNDARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
1E4F9;NAG MUNDARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
1E7E0;ETHIOPIC SYLLABLE HHYA;Lo;0;L;;;;;N;;;;;
1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;;
1E7E2;ETHIOPIC SYLLABLE HHYI;Lo;0;L;;;;;N;;;;;
@ -32678,6 +32945,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;;
1F6D6;HUT;So;0;ON;;;;;N;;;;;
1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;;
1F6DC;WIRELESS;So;0;ON;;;;;N;;;;;
1F6DD;PLAYGROUND SLIDE;So;0;ON;;;;;N;;;;;
1F6DE;WHEEL;So;0;ON;;;;;N;;;;;
1F6DF;RING BUOY;So;0;ON;;;;;N;;;;;
@ -32823,6 +33091,14 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;;
1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;;
1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;So;0;ON;;;;;N;;;;;
1F774;LOT OF FORTUNE;So;0;ON;;;;;N;;;;;
1F775;OCCULTATION;So;0;ON;;;;;N;;;;;
1F776;LUNAR ECLIPSE;So;0;ON;;;;;N;;;;;
1F77B;HAUMEA;So;0;ON;;;;;N;;;;;
1F77C;MAKEMAKE;So;0;ON;;;;;N;;;;;
1F77D;GONGGONG;So;0;ON;;;;;N;;;;;
1F77E;QUAOAR;So;0;ON;;;;;N;;;;;
1F77F;ORCUS;So;0;ON;;;;;N;;;;;
1F780;BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
1F781;BLACK UP-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
1F782;BLACK RIGHT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
@ -32912,6 +33188,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;;
1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;;
1F7D8;NEGATIVE CIRCLED SQUARE;So;0;ON;;;;;N;;;;;
1F7D9;NINE POINTED WHITE STAR;So;0;ON;;;;;N;;;;;
1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;;
1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;;
1F7E2;LARGE GREEN CIRCLE;So;0;ON;;;;;N;;;;;
@ -33434,6 +33711,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FA72;BRIEFS;So;0;ON;;;;;N;;;;;
1FA73;SHORTS;So;0;ON;;;;;N;;;;;
1FA74;THONG SANDAL;So;0;ON;;;;;N;;;;;
1FA75;LIGHT BLUE HEART;So;0;ON;;;;;N;;;;;
1FA76;GREY HEART;So;0;ON;;;;;N;;;;;
1FA77;PINK HEART;So;0;ON;;;;;N;;;;;
1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;;
1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;;
1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;;
@ -33446,6 +33726,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FA84;MAGIC WAND;So;0;ON;;;;;N;;;;;
1FA85;PINATA;So;0;ON;;;;;N;;;;;
1FA86;NESTING DOLLS;So;0;ON;;;;;N;;;;;
1FA87;MARACAS;So;0;ON;;;;;N;;;;;
1FA88;FLUTE;So;0;ON;;;;;N;;;;;
1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;;
1FA91;CHAIR;So;0;ON;;;;;N;;;;;
1FA92;RAZOR;So;0;ON;;;;;N;;;;;
@ -33475,6 +33757,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAAA;IDENTIFICATION CARD;So;0;ON;;;;;N;;;;;
1FAAB;LOW BATTERY;So;0;ON;;;;;N;;;;;
1FAAC;HAMSA;So;0;ON;;;;;N;;;;;
1FAAD;FOLDING HAND FAN;So;0;ON;;;;;N;;;;;
1FAAE;HAIR PICK;So;0;ON;;;;;N;;;;;
1FAAF;KHANDA;So;0;ON;;;;;N;;;;;
1FAB0;FLY;So;0;ON;;;;;N;;;;;
1FAB1;WORM;So;0;ON;;;;;N;;;;;
1FAB2;BEETLE;So;0;ON;;;;;N;;;;;
@ -33486,12 +33771,18 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAB8;CORAL;So;0;ON;;;;;N;;;;;
1FAB9;EMPTY NEST;So;0;ON;;;;;N;;;;;
1FABA;NEST WITH EGGS;So;0;ON;;;;;N;;;;;
1FABB;HYACINTH;So;0;ON;;;;;N;;;;;
1FABC;JELLYFISH;So;0;ON;;;;;N;;;;;
1FABD;WING;So;0;ON;;;;;N;;;;;
1FABF;GOOSE;So;0;ON;;;;;N;;;;;
1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;;
1FAC1;LUNGS;So;0;ON;;;;;N;;;;;
1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;;
1FAC3;PREGNANT MAN;So;0;ON;;;;;N;;;;;
1FAC4;PREGNANT PERSON;So;0;ON;;;;;N;;;;;
1FAC5;PERSON WITH CROWN;So;0;ON;;;;;N;;;;;
1FACE;MOOSE;So;0;ON;;;;;N;;;;;
1FACF;DONKEY;So;0;ON;;;;;N;;;;;
1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;;
1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;;
1FAD2;OLIVE;So;0;ON;;;;;N;;;;;
@ -33502,6 +33793,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAD7;POURING LIQUID;So;0;ON;;;;;N;;;;;
1FAD8;BEANS;So;0;ON;;;;;N;;;;;
1FAD9;JAR;So;0;ON;;;;;N;;;;;
1FADA;GINGER ROOT;So;0;ON;;;;;N;;;;;
1FADB;PEA POD;So;0;ON;;;;;N;;;;;
1FAE0;MELTING FACE;So;0;ON;;;;;N;;;;;
1FAE1;SALUTING FACE;So;0;ON;;;;;N;;;;;
1FAE2;FACE WITH OPEN EYES AND HAND OVER MOUTH;So;0;ON;;;;;N;;;;;
@ -33510,6 +33803,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAE5;DOTTED LINE FACE;So;0;ON;;;;;N;;;;;
1FAE6;BITING LIP;So;0;ON;;;;;N;;;;;
1FAE7;BUBBLES;So;0;ON;;;;;N;;;;;
1FAE8;SHAKING FACE;So;0;ON;;;;;N;;;;;
1FAF0;HAND WITH INDEX FINGER AND THUMB CROSSED;So;0;ON;;;;;N;;;;;
1FAF1;RIGHTWARDS HAND;So;0;ON;;;;;N;;;;;
1FAF2;LEFTWARDS HAND;So;0;ON;;;;;N;;;;;
@ -33517,6 +33811,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAF4;PALM UP HAND;So;0;ON;;;;;N;;;;;
1FAF5;INDEX POINTING AT THE VIEWER;So;0;ON;;;;;N;;;;;
1FAF6;HEART HANDS;So;0;ON;;;;;N;;;;;
1FAF7;LEFTWARDS PUSHING HAND;So;0;ON;;;;;N;;;;;
1FAF8;RIGHTWARDS PUSHING HAND;So;0;ON;;;;;N;;;;;
1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;;
1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;;
1FB02;BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;;
@ -34283,6 +34579,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;
30000;<CJK Ideograph Extension G, First>;Lo;0;L;;;;;N;;;;;
3134A;<CJK Ideograph Extension G, Last>;Lo;0;L;;;;;N;;;;;
31350;<CJK Ideograph Extension H, First>;Lo;0;L;;;;;N;;;;;
323AF;<CJK Ideograph Extension H, Last>;Lo;0;L;;;;;N;;;;;
E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;
E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;
E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;;

View file

@ -0,0 +1,39 @@
/*-*- 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/sysv/consts/o.h"
#include "libc/testlib/testlib.h"
char testlib_enable_tmp_setup_teardown;
static int fd;
static char buf[8];
TEST(dog, testReadPastEof_returnsZero) {
EXPECT_NE(-1, (fd = open("a", O_RDWR | O_CREAT | O_TRUNC, 0644)));
EXPECT_EQ(0, pread(fd, buf, 8, 0));
EXPECT_EQ(0, close(fd));
}
TEST(dog, testReadOverlapsEof_returnsShortNumber) {
EXPECT_NE(-1, (fd = open("b", O_RDWR | O_CREAT | O_TRUNC, 0644)));
EXPECT_EQ(4, pwrite(fd, buf, 4, 0));
EXPECT_EQ(4, pread(fd, buf, 8, 0));
EXPECT_EQ(0, close(fd));
}

View file

@ -0,0 +1,34 @@
/*-*- 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/sysv/consts/at.h"
#include "libc/testlib/testlib.h"
char testlib_enable_tmp_setup_teardown;
TEST(unlinkat, test) {
int i, fd;
EXPECT_EQ(0, touch("mytmp", 0644));
EXPECT_EQ(0, unlinkat(AT_FDCWD, "mytmp", 0));
for (i = 0; i < 8; ++i) {
EXPECT_NE(-1, (fd = creat("mytmp", 0644)));
EXPECT_EQ(0, close(fd));
EXPECT_EQ(0, unlinkat(AT_FDCWD, "mytmp", 0));
}
}

View file

@ -0,0 +1,34 @@
/*-*- 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 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/nexgen32e/nexgen32e.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(memrchr16, test) {
EXPECT_EQ(NULL, memrchr16(u"yo.hi.thereeuhcruhrceeuhcre", '-', 27));
EXPECT_STREQ(u".there", memrchr16(u"yo.hi.there", '.', 11));
EXPECT_STREQ(u".thereeuhcruhrceeuhcre",
memrchr16(u"yo.hi.thereeuhcruhrceeuhcre", '.', 27));
}
BENCH(memrchr16, bench) {
EZBENCH2("memrchr16", donothing,
EXPROPRIATE(memrchr16(u"yo.hi.there", '.', 11)));
}

View file

@ -20,8 +20,10 @@
#include "libc/bits/xchg.internal.h"
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
@ -40,7 +42,7 @@ TEST(mmap, testMapFile) {
int fd;
char *p;
char path[PATH_MAX];
sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid());
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
EXPECT_EQ(5, write(fd, "hello", 5));
EXPECT_NE(-1, fdatasync(fd));
@ -54,7 +56,7 @@ TEST(mmap, testMapFile) {
TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) {
int fd;
char *p, buf[16], path[PATH_MAX];
sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid());
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
EXPECT_EQ(5, write(fd, "hello", 5));
EXPECT_NE(-1, fdatasync(fd));
@ -113,6 +115,7 @@ TEST(mmap, fileOffset) {
EXPECT_NE(-1, ftruncate(fd, FRAMESIZE * 2));
EXPECT_NE(-1, pwrite(fd, "hello", 5, FRAMESIZE * 0));
EXPECT_NE(-1, pwrite(fd, "there", 5, FRAMESIZE * 1));
EXPECT_NE(-1, fdatasync(fd));
ASSERT_NE(MAP_FAILED, (map = mmap(NULL, FRAMESIZE, PROT_READ, MAP_PRIVATE, fd,
FRAMESIZE)));
EXPECT_EQ(0, memcmp(map, "there", 5), "%#.*s", 5, map);
@ -123,7 +126,7 @@ TEST(mmap, fileOffset) {
TEST(mmap, mapPrivate_writesDontChangeFile) {
int fd;
char *map, buf[5];
ASSERT_NE(-1, (fd = open("foo", O_CREAT | O_RDWR, 0644)));
ASSERT_NE(-1, (fd = open("bar", O_CREAT | O_RDWR, 0644)));
EXPECT_NE(-1, ftruncate(fd, FRAMESIZE));
EXPECT_NE(-1, pwrite(fd, "hello", 5, 0));
ASSERT_NE(MAP_FAILED, (map = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE,
@ -131,7 +134,7 @@ TEST(mmap, mapPrivate_writesDontChangeFile) {
memcpy(map, "there", 5);
EXPECT_NE(-1, msync(map, FRAMESIZE, MS_SYNC));
EXPECT_NE(-1, munmap(map, FRAMESIZE));
EXPECT_NE(-1, pread(fd, buf, 5, 0));
EXPECT_NE(-1, pread(fd, buf, 6, 0));
EXPECT_EQ(0, memcmp(buf, "hello", 5), "%#.*s", 5, buf);
EXPECT_NE(-1, close(fd));
}
@ -152,3 +155,128 @@ TEST(isheap, mallocOffset) {
char *p = gc(malloc(131072));
ASSERT_TRUE(_isheap(p + 100000));
}
////////////////////////////////////////////////////////////////////////////////
// NON-SHARED READ-ONLY FILE MEMORY
TEST(mmap, cow) {
int fd;
char *p;
char path[PATH_MAX];
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
EXPECT_EQ(5, write(fd, "hello", 5));
EXPECT_NE(-1, fdatasync(fd));
EXPECT_NE(MAP_FAILED,
(p = mmap(NULL, 5, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)));
EXPECT_STREQN("hello", p, 5);
EXPECT_NE(-1, munmap(p, 5));
EXPECT_NE(-1, close(fd));
EXPECT_NE(-1, unlink(path));
}
////////////////////////////////////////////////////////////////////////////////
// NON-SHARED READ-ONLY FILE MEMORY BETWEEN PROCESSES
TEST(mmap, cowFileMapReadonlyFork) {
char *p;
int fd, pid, ws;
char path[PATH_MAX], lol[6];
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
EXPECT_EQ(6, write(fd, "hello", 6));
EXPECT_NE(-1, close(fd));
ASSERT_NE(-1, (fd = open(path, O_RDONLY)));
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ, MAP_PRIVATE, fd, 0)));
EXPECT_STREQN("hello", p, 5);
ASSERT_NE(-1, (ws = xspawn(0)));
if (ws == -2) {
ASSERT_STREQN("hello", p, 5);
_exit(0);
}
EXPECT_STREQN("hello", p, 5);
EXPECT_NE(-1, munmap(p, 6));
EXPECT_NE(-1, unlink(path));
}
////////////////////////////////////////////////////////////////////////////////
// NON-SHARED READ/WRITE FILE MEMORY BETWEEN PROCESSES
TEST(mmap, cowFileMapFork) {
char *p;
int fd, pid, ws;
char path[PATH_MAX], lol[6];
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
EXPECT_EQ(6, write(fd, "parnt", 6));
EXPECT_NE(-1, fdatasync(fd));
EXPECT_NE(MAP_FAILED,
(p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)));
EXPECT_STREQN("parnt", p, 5);
ASSERT_NE(-1, (ws = xspawn(0)));
if (ws == -2) {
ASSERT_STREQN("parnt", p, 5);
strcpy(p, "child");
ASSERT_STREQN("child", p, 5);
_exit(0);
}
EXPECT_STREQN("parnt", p, 5); // child changing memory did not change parent
EXPECT_EQ(6, pread(fd, lol, 6, 0));
EXPECT_STREQN("parnt", lol, 5); // changing memory did not change file
EXPECT_NE(-1, munmap(p, 6));
EXPECT_NE(-1, close(fd));
EXPECT_NE(-1, unlink(path));
}
////////////////////////////////////////////////////////////////////////////////
// SHARED ANONYMOUS MEMORY BETWEEN PROCESSES
TEST(mmap, sharedAnonMapFork) {
char *p;
int pid, ws;
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0)));
strcpy(p, "parnt");
EXPECT_STREQN("parnt", p, 5);
ASSERT_NE(-1, (ws = xspawn(0)));
if (ws == -2) {
ASSERT_STREQN("parnt", p, 5);
strcpy(p, "child");
ASSERT_STREQN("child", p, 5);
_exit(0);
}
EXPECT_STREQN("child", p, 5); // boom
EXPECT_NE(-1, munmap(p, 5));
}
////////////////////////////////////////////////////////////////////////////////
// SHARED FILE MEMORY BETWEEN PROCESSES
TEST(mmap, sharedFileMapFork) {
char *p;
int fd, pid, ws;
char path[PATH_MAX], lol[6];
sprintf(path, "%s%s.%ld", kTmpPath, program_invocation_short_name, vigna());
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
EXPECT_EQ(6, write(fd, "parnt", 6));
EXPECT_NE(-1, fdatasync(fd));
EXPECT_NE(MAP_FAILED,
(p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
EXPECT_STREQN("parnt", p, 5);
ASSERT_NE(-1, (ws = xspawn(0)));
if (ws == -2) {
ASSERT_STREQN("parnt", p, 5);
strcpy(p, "child");
ASSERT_STREQN("child", p, 5);
ASSERT_NE(-1, msync(p, 6, MS_SYNC | MS_INVALIDATE));
_exit(0);
}
EXPECT_STREQN("child", p, 5); // child changing memory changed parent memory
// XXX: RHEL5 has a weird issue where if we read the file into its own
// shared memory then corruption occurs!
EXPECT_EQ(6, pread(fd, lol, 6, 0));
EXPECT_STREQN("child", lol, 5); // changing memory changed file
EXPECT_NE(-1, munmap(p, 6));
EXPECT_NE(-1, close(fd));
EXPECT_NE(-1, unlink(path));
}

View file

@ -1,3 +1,4 @@
// clang-format off
/*
** 2004 May 22
**
@ -44,9 +45,9 @@
** plus implementations of sqlite3_os_init() and sqlite3_os_end().
*/
#include "libc/rand/rand.h"
#include "libc/sysv/consts/lock.h"
#include "third_party/sqlite3/sqliteInt.inc"
#if SQLITE_OS_UNIX /* This file is used on unix only */
/* clang-format off */
/*
** There are various methods for file locking used for concurrency
@ -74,7 +75,7 @@
#endif
/* Use pread() and pwrite() if they are available */
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(__COSMOPOLITAN__)
# define HAVE_PREAD 1
# define HAVE_PWRITE 1
#endif
@ -140,10 +141,6 @@
#include "libc/limits.h"
#endif /* OS_VXWORKS */
#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
# include <sys/mount.h>
#endif
#ifdef HAVE_UTIME
#include "libc/time/time.h"
#endif
@ -331,14 +328,6 @@ static pid_t randomnessPid = 0;
# endif
#endif
/*
** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek()
** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined.
*/
#ifdef __ANDROID__
# define lseek lseek64
#endif
#ifdef __linux__
/*
** Linux-specific IOCTL magic numbers used for controlling F2FS

View file

@ -106,6 +106,8 @@ THIRD_PARTY_SQLITE3_FLAGS = \
-DSQLITE_OS_UNIX \
-DBUILD_sqlite \
-DHAVE_USLEEP \
-DHAVE_READLINK \
-DHAVE_LSTAT \
-DHAVE_GMTIME_R \
-DHAVE_FDATASYNC \
-DHAVE_STRCHRNUL \

View file

@ -34,6 +34,7 @@
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/ipclassify.internal.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ex.h"
@ -54,6 +55,9 @@
#include "tool/build/lib/psk.h"
#include "tool/build/runit.h"
#define MAX_WAIT_CONNECT_SECONDS 30
#define INITIAL_CONNECT_TIMEOUT 100000
/**
* @fileoverview Remote test runner.
*
@ -243,17 +247,10 @@ void DeployEphemeralRunItDaemonRemotelyViaSsh(struct addrinfo *ai) {
LOGIFNEG1(close(lock));
}
void SetDeadline(int micros) {
alarmed = false;
LOGIFNEG1(
sigaction(SIGALRM, &(struct sigaction){.sa_handler = OnAlarm}, NULL));
LOGIFNEG1(setitimer(ITIMER_REAL,
&(const struct itimerval){{0, 0}, {0, micros}}, NULL));
}
void Connect(void) {
const char *ip4;
int rc, err, expo;
long double t1, t2;
struct addrinfo *ai;
if ((rc = getaddrinfo(g_hostname, gc(xasprintf("%hu", g_runitdport)),
&kResolvHints, &ai)) != 0) {
@ -267,24 +264,46 @@ void Connect(void) {
g_hostname, ip4[0], ip4[1], ip4[2], ip4[3]);
unreachable;
}
DEBUGF("connecting to %d.%d.%d.%d port %d", ip4[0], ip4[1], ip4[2], ip4[3],
ntohs(ai->ai_addr4->sin_port));
CHECK_NE(-1,
(g_sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)));
expo = 1;
expo = INITIAL_CONNECT_TIMEOUT;
t1 = nowl();
LOGIFNEG1(sigaction(SIGALRM, &(struct sigaction){.sa_handler = OnAlarm}, 0));
Reconnect:
DEBUGF("connecting to %s (%hhu.%hhu.%hhu.%hhu) to run %s", g_hostname, ip4[0],
ip4[1], ip4[2], ip4[3], g_prog);
SetDeadline(100000);
TryAgain:
alarmed = false;
LOGIFNEG1(setitimer(
ITIMER_REAL,
&(const struct itimerval){{0, 0}, {expo / 1000000, expo % 1000000}},
NULL));
rc = connect(g_sock, ai->ai_addr, ai->ai_addrlen);
err = errno;
SetDeadline(0);
t2 = nowl();
if (rc == -1) {
if (err == EINTR) goto TryAgain;
if (err == EINTR) {
expo *= 1.5;
if (t2 > t1 + MAX_WAIT_CONNECT_SECONDS) {
FATALF("timeout connecting to %s (%hhu.%hhu.%hhu.%hhu:%d)", g_hostname,
ip4[0], ip4[1], ip4[2], ip4[3], ntohs(ai->ai_addr4->sin_port));
unreachable;
}
goto TryAgain;
}
if (err == ECONNREFUSED || err == EHOSTUNREACH || err == ECONNRESET) {
DEBUGF("got %s from %s (%hhu.%hhu.%hhu.%hhu)", strerror(err), g_hostname,
ip4[0], ip4[1], ip4[2], ip4[3]);
usleep((expo *= 2));
setitimer(ITIMER_REAL, &(const struct itimerval){0}, 0);
DeployEphemeralRunItDaemonRemotelyViaSsh(ai);
if (t2 > t1 + MAX_WAIT_CONNECT_SECONDS) {
FATALF("timeout connecting to %s (%hhu.%hhu.%hhu.%hhu:%d)", g_hostname,
ip4[0], ip4[1], ip4[2], ip4[3], ntohs(ai->ai_addr4->sin_port));
unreachable;
}
usleep((expo *= 2));
goto Reconnect;
} else {
FATALF("%s(%s:%hu): %s", "connect", g_hostname, g_runitdport,
@ -294,6 +313,7 @@ TryAgain:
} else {
DEBUGF("connected to %s", g_hostname);
}
setitimer(ITIMER_REAL, &(const struct itimerval){0}, 0);
freeaddrinfo(ai);
}
@ -401,6 +421,7 @@ int RunOnHost(char *spec) {
CHECK_GE(sscanf(spec, "%100s %hu %hu", g_hostname, &g_runitdport, &g_sshport),
1);
if (!strchr(g_hostname, '.')) strcat(g_hostname, ".test.");
DEBUGF("connecting to %s port %d", g_hostname, g_runitdport);
do {
for (;;) {
Connect();
@ -441,8 +462,6 @@ int SpawnSubprocesses(int argc, char *argv[]) {
LOGIFNEG1(sigprocmask(SIG_BLOCK, &chldmask, &savemask));
for (i = 0; i < argc; ++i) {
args[3] = argv[i];
fprintf(stderr, "spawning %s %s %s %s\n", args[0], args[1], args[2],
args[3]);
CHECK_NE(-1, (pids[i] = vfork()));
if (!pids[i]) {
xsigaction(SIGINT, SIG_DFL, 0, 0, 0);
@ -483,7 +502,9 @@ int SpawnSubprocesses(int argc, char *argv[]) {
int main(int argc, char *argv[]) {
ShowCrashReports();
__log_level = kLogDebug;
if (getenv("DEBUG")) {
__log_level = kLogDebug;
}
if (argc > 1 &&
(strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
ShowUsage(stdout, 0);

View file

@ -87,7 +87,7 @@
* - 1 byte exit status
*/
#define DEATH_CLOCK_SECONDS 32
#define DEATH_CLOCK_SECONDS 128
#define kLogFile "o/runitd.log"
#define kLogMaxBytes (2 * 1000 * 1000)
@ -191,7 +191,6 @@ void StartTcpServer(void) {
g_servfd = 10;
LOGIFNEG1(setsockopt(g_servfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)));
LOGIFNEG1(setsockopt(g_servfd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)));
if (bind(g_servfd, &g_servaddr, sizeof(g_servaddr)) == -1) {
if (g_servaddr.sin_port != 0) {
g_servaddr.sin_port = 0;

View file

@ -32,7 +32,7 @@
struct BitaBuilder {
size_t i, n;
unsigned *p;
uint32_t *p;
};
struct BitaBuilder *bitabuilder_new(void) {
@ -66,7 +66,7 @@ bool bitabuilder_setbit(struct BitaBuilder *bb, size_t bit) {
}
}
bb->i = i;
bts(bb->p, bit);
bb->p[bit / 32] |= 1u << (bit % 32);
return true;
}

View file

@ -175,15 +175,15 @@
(cond ((eq arg 9) "-x")
(t "")))
(defun cosmo--compile-command (this root kind mode suffix objdumpflags)
(defun cosmo--compile-command (this root kind mode suffix objdumpflags runsuffix)
(let* ((ext (file-name-extension this)) ;; e.g. "c"
(dir (file-name-directory this)) ;; e.g. "/home/jart/daisy/libc/"
(dots (file-relative-name root dir)) ;; e.g. "../"
(file (file-relative-name this root)) ;; e.g. "libc/crc32c.c"
(name (file-name-sans-extension file)) ;; e.g. "libc/crc32c"
(buddy (format "test/%s_test.c" name))
(runs (format "o/$m/%s.com.runs V=5 TESTARGS=-b" name))
(buns (format "o/$m/test/%s_test.com.runs V=5 TESTARGS=-b" name)))
(runs (format "o/$m/%s.com%s V=5 TESTARGS=-b" name runsuffix))
(buns (format "o/$m/test/%s_test.com%s V=5 TESTARGS=-b" name runsuffix)))
(cond ((not (member ext '("c" "cc" "s" "S" "rl" "f")))
(format "m=%s; make -j8 -O MODE=$m o/$m/%s"
mode
@ -191,6 +191,15 @@
(or (file-name-directory
(file-relative-name this root))
""))))
((eq kind 'run-win7)
(format
(cosmo-join
" && "
`("m=%s; f=o/$m/%s.com"
,(concat "make -j8 -O $f MODE=$m")
"scp $f $f.dbg win7:"
"ssh win7 ./%s.com"))
mode name (file-name-nondirectory name)))
((and (equal suffix "")
(cosmo-contains "_test." (buffer-file-name)))
(format "m=%s; make -j8 -O MODE=$m %s"
@ -214,24 +223,8 @@
,(concat "make -j8 -O $f MODE=$m")
"./$f"))
mode name))
((eq kind 'run-win7)
(format
(cosmo-join
" && "
`("m=%s; f=o/$m/%s.com"
,(concat "make -j8 -O $f MODE=$m")
"scp $f $f.dbg win7:"
"ssh win7 ./%s.com"))
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)))
((eq kind 'test)
(format `"m=%s; f=o/$m/%s.com.ok && make -j8 -O $f MODE=$m" mode name))
((and (file-regular-p this)
(file-executable-p this))
(format "./%s" file))
@ -257,7 +250,7 @@
(objdumpflags (cosmo--make-objdump-flags arg))
(compilation-scroll-output nil)
(default-directory root)
(compile-command (cosmo--compile-command this root nil mode suffix objdumpflags)))
(compile-command (cosmo--compile-command this root nil mode suffix objdumpflags ".runs")))
(compile compile-command)))))
(defun cosmo-compile-hook ()
@ -600,7 +593,7 @@
(format "./%s" file))))
((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 mode "" "")))
(compile-command (cosmo--compile-command this root 'run mode "" "" ".runs")))
(compile compile-command)))
((eq major-mode 'sh-mode)
(compile (format "sh %s" file)))
@ -614,6 +607,22 @@
('t
(error "cosmo-run: unknown major mode")))))))
(defun cosmo-run-test (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 'test mode "" "" ".ok")))
(compile compile-command)))
('t
(error "cosmo-run: unknown major mode")))))))
(defun cosmo-run-win7 (arg)
(interactive "P")
(let* ((this (or (buffer-file-name) dired-directory))
@ -624,24 +633,8 @@
(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-win7 mode "" "")))
(compile compile-command)))
('t
(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 "" "")))
(let* ((mode (cosmo--make-mode arg ""))
(compile-command (cosmo--compile-command this root 'run-win7 mode "" "" "")))
(compile compile-command)))
('t
(error "cosmo-run: unknown major mode")))))))
@ -652,8 +645,8 @@
(define-key fortran-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 c-mode-map (kbd "C-c C-s") 'cosmo-run-win7)
(define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win10))
(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))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -675,7 +668,7 @@
(next (file-name-sans-extension name))
(exec (format "o/%s/%s.com.dbg" mode next))
(default-directory root)
(compile-command (cosmo--compile-command this root nil mode "" "")))
(compile-command (cosmo--compile-command this root nil mode "" "" ".runs")))
(compile compile-command)
(gdb (format "gdb -q -nh -i=mi %s -ex run" exec))))))
@ -875,6 +868,36 @@
(add-hook 'before-save-hook 'cosmo-before-save)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Cosmopolitan Logger Integration
;; Cosmopolitan logger
;;
;; W2022-03-23T15:58:19.102930:tool/build/runit.c:274:runit:20719] hello
;; warn date time micros file line prog pid message
;;
;; I2022-03-23T15:58:19.+00033:tool/build/runit.c:274:runit:20719] there
;; info date time delta file line prog pid message
;;
(defvar cosmo-compilation-regexps
(list (cosmo-join
""
'("^[FEWIVDNT]" ;; level
"[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]" ;; date
"T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]" ;; time
"[+.][0-9][0-9][0-9][0-9][0-9][0-9]" ;; micros
":\\([^:]+\\)" ;; file
":\\([0-9]+\\)")) ;; line
1 2))
(eval-after-load 'compile
'(progn
(add-to-list 'compilation-error-regexp-alist-alist
(cons 'cosmo cosmo-compilation-regexps))
(add-to-list 'compilation-error-regexp-alist 'cosmo)))
(provide 'cosmo-stuff)
;;; cosmo-stuff.el ends here