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

View file

@ -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/strace.internal.h"
#include "libc/errno.h" #include "libc/errno.h"
#define __NR_dup3_linux 0x0124 /*RHEL5:CVE-2010-3301*/ #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; olderr = errno;
fd = __sys_dup3(oldfd, newfd, flags); fd = __sys_dup3(oldfd, newfd, flags);
if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) { if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) {
STRACE("demodernizing %s() due to %s", "dup3", "RHEL5:CVE-2010-3301");
demodernize = true; demodernize = true;
once = true; once = true;
errno = olderr; errno = olderr;

View file

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

View file

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

View file

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

View file

@ -19,6 +19,7 @@
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/macros.internal.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); 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; return rc;
} }

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.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; errno = err;
once = true; once = true;
demodernize = true; demodernize = true;
STRACE("demodernizing %s() due to %s", "pwritev", "ENOSYS");
} else if (IsLinux() && rc == __NR_pwritev_linux) { } else if (IsLinux() && rc == __NR_pwritev_linux) {
if (__iovec_size(iov, iovlen) < __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; once = true;
} else { } else {
return rc; 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, if (ReadFile(fd->handle, data, clampio(size), &got,
offset2overlap(offset, &overlap))) { offset2overlap(offset, &overlap))) {
return got; 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; return 0;
} else { } else {
return __winerr(); return __winerr();

View file

@ -60,6 +60,7 @@ ssize_t read(int fd, void *buf, size_t size) {
} else { } else {
rc = einval(); 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; return rc;
} }

View file

@ -16,8 +16,8 @@
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/errno.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/errno.h"
/** /**
* Deletes "file" or empty directory associtaed with name. * Deletes "file" or empty directory associtaed with name.

View file

@ -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/strace.internal.h"
#include "libc/calls/struct/itimerval.h" #include "libc/calls/struct/itimerval.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/asan.internal.h" #include "libc/intrin/asan.internal.h"
@ -64,18 +65,41 @@
*/ */
int setitimer(int which, const struct itimerval *newvalue, int setitimer(int which, const struct itimerval *newvalue,
struct itimerval *oldvalue) { struct itimerval *oldvalue) {
int rc;
if (IsAsan() && if (IsAsan() &&
((newvalue && !__asan_is_valid(newvalue, sizeof(*newvalue))) || ((newvalue && !__asan_is_valid(newvalue, sizeof(*newvalue))) ||
(oldvalue && !__asan_is_valid(oldvalue, sizeof(*oldvalue))))) { (oldvalue && !__asan_is_valid(oldvalue, sizeof(*oldvalue))))) {
return efault(); rc = efault();
} } else if (!IsWindows()) {
if (!IsWindows()) {
if (newvalue) { if (newvalue) {
return sys_setitimer(which, newvalue, oldvalue); rc = sys_setitimer(which, newvalue, oldvalue);
} else { } else {
return sys_getitimer(which, oldvalue); rc = sys_getitimer(which, oldvalue);
} }
} else { } 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/calls/internal.h"
#include "libc/errno.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/fileflagandattributes.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/nt/enum/io.h" #include "libc/nt/enum/io.h"
#include "libc/nt/errors.h" #include "libc/nt/errors.h"
#include "libc/nt/files.h" #include "libc/nt/files.h"
@ -28,6 +32,48 @@
#include "libc/nt/synchronization.h" #include "libc/nt/synchronization.h"
#include "libc/sysv/consts/at.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) { static textwindows bool IsDirectorySymlink(const char16_t *path) {
int64_t h; int64_t h;
struct NtWin32FindData data; 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) { static textwindows int sys_unlink_nt(const char16_t *path) {
if (IsDirectorySymlink(path)) return sys_rmdir_nt(path); if (IsDirectorySymlink(path)) {
return DeleteFile(path) ? 0 : __winerr(); 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) { textwindows int sys_unlinkat_nt(int dirfd, const char *path, int flags) {
uint16_t path16[PATH_MAX]; int n, rc;
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; char16_t path16[PATH_MAX];
if (flags & AT_REMOVEDIR) { if ((n = __mkntpathat(dirfd, path, 0, path16)) == -1) {
return sys_rmdir_nt(path16); rc = -1;
} else if (flags & AT_REMOVEDIR) {
rc = sys_rmdir_nt(path16);
} else { } 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. * 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 * @param dirfd is normally AT_FDCWD but if it's an open directory and
* path is relative, then path becomes relative to dirfd * path is relative, then path becomes relative to dirfd
* @param path is the thing to delete * @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 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.h"
#include "libc/time/time.h" #include "libc/time/time.h"
@ -23,7 +24,10 @@
* Sleeps for particular amount of microseconds. * Sleeps for particular amount of microseconds.
*/ */
int usleep(uint32_t microseconds) { int usleep(uint32_t microseconds) {
return nanosleep( int rc;
&(struct timespec){microseconds / 1000000, microseconds % 1000000 * 1000}, rc = nanosleep(&(struct timespec){(uint64_t)microseconds / 1000000,
NULL); (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 { } else {
rc = einval(); 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; return rc;
} }

View file

@ -29,41 +29,50 @@
// @noreturn // @noreturn
_start: _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() #if SupportsFreebsd()
// detect free besiyata dishmaya
test %rdi,%rdi test %rdi,%rdi
cmovnz %rdi,%rsp cmovnz %rdi,%rsp
jz 0f jz 0f
movb $FREEBSD,__hostos(%rip) movb $FREEBSD,__hostos(%rip)
#endif #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 8(%rsp),%rsi # argv
lea 16(%rsp,%rbx,8),%rdx # envp lea 16(%rsp,%rbx,8),%rdx # envp
mov %rsp,__oldstack(%rip) mov %rsp,__oldstack(%rip)
and $-16,%rsp and $-16,%rsp
xor %ebp,%ebp xor %ebp,%ebp
// bofram 9f // bofram 9f
// make win32 imps noop
.weak ape_idata_iat .weak ape_idata_iat
.weak ape_idata_iatend .weak ape_idata_iatend
ezlea missingno,ax # make win32 imps noop ezlea missingno,ax
ezlea ape_idata_iat,di ezlea ape_idata_iat,di
ezlea ape_idata_iatend,cx ezlea ape_idata_iatend,cx
sub %rdi,%rcx sub %rdi,%rcx
shr $3,%ecx shr $3,%ecx
rep stosq rep stosq
xor %eax,%eax # find end of environ
// scan through environment varis
// find start of auxiliary values
xor %eax,%eax
or $-1,%ecx or $-1,%ecx
mov %rdx,%rdi mov %rdx,%rdi
repnz scasq repnz scasq
mov %rdi,%rcx # auxv mov %rdi,%rcx # auxv
#if SupportsXnu() #if SupportsXnu()
// should probably be removed in favor of newer apis
testb IsXnu() testb IsXnu()
jz 1f # polyfill xnu auxv jz 1f # polyfill xnu auxv
push $0 # auxv[1][1]=0 push $0 # auxv[1][1]=0
@ -74,9 +83,11 @@ _start:
push $31 # auxv[0][0]=AT_EXECFN push $31 # auxv[0][0]=AT_EXECFN
mov %rsp,%rcx # auxv mov %rsp,%rcx # auxv
#endif #endif
// enter cosmopolitan runtime
1: mov %ebx,%edi 1: mov %ebx,%edi
call cosmo call cosmo
9: ud2 9: .unreachable
.endfn _start,weak,hidden .endfn _start,weak,hidden
#if SupportsXnu() #if SupportsXnu()

View file

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

View file

@ -45,7 +45,7 @@ textwindows void *MapViewOfFileEx(int64_t hFileMappingObject,
hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow,
dwNumberOfBytesToMap, opt_lpDesiredBaseAddress); dwNumberOfBytesToMap, opt_lpDesiredBaseAddress);
if (!pStartingAddress) __winerr(); 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), hFileMappingObject, DescribeNtFileMapFlags(dwDesiredAccess),
(uint64_t)dwFileOffsetHigh << 32 | dwFileOffsetLow, (uint64_t)dwFileOffsetHigh << 32 | dwFileOffsetLow,
dwNumberOfBytesToMap, opt_lpDesiredBaseAddress, pStartingAddress); dwNumberOfBytesToMap, opt_lpDesiredBaseAddress, pStartingAddress);

View file

@ -19,6 +19,7 @@
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/log/internal.h" #include "libc/log/internal.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/str/str.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", kprintf("%n%serror: %s: check failed: 0x%x %s 0x%x (%s)%n",
!__nocolor ? "\e[J" : "", program_invocation_name, want, opchar, got, !__nocolor ? "\e[J" : "", program_invocation_name, want, opchar, got,
strerror(errno)); strerror(errno));
exit(1); __restorewintty();
_Exit(68);
} }

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/bits/bits.h" #include "libc/bits/bits.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.h"
#include "libc/calls/struct/timeval.h" #include "libc/calls/struct/timeval.h"
#include "libc/dce.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, void(vflogf)(unsigned level, const char *file, int line, FILE *f,
const char *fmt, va_list va) { const char *fmt, va_list va) {
int bufmode;
struct tm tm; struct tm tm;
long double t2; long double t2;
int st, bufmode;
const char *prog; const char *prog;
bool issamesecond; bool issamesecond;
char buf32[32]; char buf32[32];
int64_t secs, nsec, dots; int64_t secs, nsec, dots;
if (!f) f = __log_file; if (!f) f = __log_file;
if (!f) return; if (!f) return;
st = __strace;
__strace = 0;
t2 = nowl(); t2 = nowl();
secs = t2; secs = t2;
nsec = (t2 - secs) * 1e9L; nsec = (t2 - secs) * 1e9L;
@ -114,4 +117,5 @@ void(vflogf)(unsigned level, const char *file, int line, FILE *f,
__die(); __die();
unreachable; 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) { static textwindows int OnForkCrash(struct NtExceptionPointers *ep) {
kprintf("error: fork() child crashed!%n" kprintf("error: fork() child crashed!%n"
"\tExceptionCode = %#x%n" "\tExceptionCode = %#x%n"
"\tRip = %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",
ep->ExceptionRecord->ExceptionCode, ep->ExceptionRecord->ExceptionCode,
ep->ContextRecord ? ep->ContextRecord->Rip : -1, 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);
ExitProcess(73); ExitProcess(73);
} }
textwindows void WinMainForked(void) { textwindows void WinMainForked(void) {
bool ok;
jmp_buf jb; jmp_buf jb;
char *addr, *shad; char *addr, *shad;
struct DirectMap dm; struct DirectMap dm;
uint64_t size, upsize; uint64_t size, upsize;
int64_t reader, writer; int64_t reader, writer;
uint32_t flags1, flags2;
struct MemoryInterval *maps; struct MemoryInterval *maps;
char16_t fvar[21 + 1 + 21 + 1]; char16_t fvar[21 + 1 + 21 + 1];
int64_t oncrash, savetsc, savebir; int64_t oncrash, savetsc, savebir;
@ -133,10 +111,8 @@ textwindows void WinMainForked(void) {
long mapcount, mapcapacity, specialz; long mapcount, mapcapacity, specialz;
extern uint64_t ts asm("kStartTsc"); extern uint64_t ts asm("kStartTsc");
/* // check to see if the process was actually forked
* check to see if the process was actually forked // this variable should have the pipe handle numba
* this variable should have the pipe handle numba
*/
varlen = GetEnvironmentVariable(u"_FORK", fvar, ARRAYLEN(fvar)); varlen = GetEnvironmentVariable(u"_FORK", fvar, ARRAYLEN(fvar));
if (!varlen || varlen >= ARRAYLEN(fvar)) return; if (!varlen || varlen >= ARRAYLEN(fvar)) return;
STRACE("WinMainForked()"); STRACE("WinMainForked()");
@ -145,109 +121,134 @@ textwindows void WinMainForked(void) {
oncrash = AddVectoredExceptionHandler(1, NT2SYSV(OnForkCrash)); oncrash = AddVectoredExceptionHandler(1, NT2SYSV(OnForkCrash));
#endif #endif
ParseInt(ParseInt(fvar, &reader), &writer); ParseInt(ParseInt(fvar, &reader), &writer);
CloseHandle(writer);
/* // read the cpu state from the parent process & plus
* read the cpu state from the parent process // read the list of mappings from the parent process
*/ // this is stored in a special secretive memory map!
ReadAll(reader, jb, sizeof(jb)); // read ExtendMemoryIntervals for further details :|
/*
* 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; maps = (void *)kMemtrackStart;
ReadAll(reader, &mapcount, sizeof(_mmi.i)); if (!ReadAll(reader, jb, sizeof(jb)) ||
ReadAll(reader, &mapcapacity, sizeof(_mmi.n)); !ReadAll(reader, &mapcount, sizeof(_mmi.i)) ||
!ReadAll(reader, &mapcapacity, sizeof(_mmi.n))) {
ExitProcess(40);
}
specialz = ROUNDUP(mapcapacity * sizeof(_mmi.p[0]), kMemtrackGran); specialz = ROUNDUP(mapcapacity * sizeof(_mmi.p[0]), kMemtrackGran);
MapViewOfFileEx(CreateFileMapping(-1, &kNtIsInheritable, kNtPageReadwrite, if (!MapViewOfFileEx(CreateFileMapping(-1, 0, kNtPageReadwrite,
specialz >> 32, specialz, 0), specialz >> 32, specialz, 0),
kNtFileMapWrite, 0, 0, specialz, maps); kNtFileMapWrite, 0, 0, specialz, maps)) {
ReadAll(reader, maps, mapcount * sizeof(_mmi.p[0])); ExitProcess(41);
}
if (!ReadAll(reader, maps, mapcount * sizeof(_mmi.p[0]))) {
ExitProcess(42);
}
if (IsAsan()) { if (IsAsan()) {
shad = (char *)(((intptr_t)maps >> 3) + 0x7fff8000); shad = (char *)(((intptr_t)maps >> 3) + 0x7fff8000);
size = ROUNDUP(specialz >> 3, FRAMESIZE); size = ROUNDUP(specialz >> 3, FRAMESIZE);
MapViewOfFileEx(CreateFileMapping(-1, &kNtIsInheritable, kNtPageReadwrite, MapViewOfFileEx(
size >> 32, size, 0), CreateFileMapping(-1, 0, kNtPageReadwrite, size >> 32, size, 0),
kNtFileMapWrite, 0, 0, size, maps); kNtFileMapWrite, 0, 0, size, maps);
#if 0 if (!ReadAll(reader, shad, (mapcount * sizeof(_mmi.p[0])) >> 3)) {
ReadAll(reader, shad, (mapcount * sizeof(_mmi.p[0])) >> 3); ExitProcess(43);
#endif }
} }
/* // read the heap mappings from the parent process
* read the heap mappings from the parent process // we can avoid copying via pipe for shared maps!
* we can avoid copying via pipe for shared maps!
*/
for (i = 0; i < mapcount; ++i) { for (i = 0; i < mapcount; ++i) {
addr = (char *)((uint64_t)maps[i].x << 16); addr = (char *)((uint64_t)maps[i].x << 16);
size = maps[i].size; size = maps[i].size;
if (maps[i].flags & MAP_PRIVATE) { 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); upsize = ROUNDUP(size, FRAMESIZE);
maps[i].h = if (maps[i].prot & PROT_EXEC) {
CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite, flags1 = kNtPageExecuteReadwrite;
upsize >> 32, upsize, NULL); flags2 = kNtFileMapWrite | kNtFileMapExecute;
MapViewOfFileEx(maps[i].h, kNtFileMapWrite | kNtFileMapExecute, 0, 0, } else {
upsize, addr); flags1 = kNtPageReadwrite;
ReadAll(reader, addr, size); 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 { } else {
STRACE("fork() child %p %'zu mapping shared hand:%ld offset:%'lu", addr, // we can however safely inherit MAP_SHARED with zero copy
size, maps[i].h, maps[i].offset); if (maps[i].prot & PROT_WRITE) {
MapViewOfFileEx(maps[i].h, if (maps[i].prot & PROT_EXEC) {
(maps[i].prot & PROT_WRITE) flags2 = kNtFileMapWrite | kNtFileMapExecute;
? kNtFileMapWrite | kNtFileMapExecute } else {
: kNtFileMapRead | kNtFileMapExecute, flags2 = kNtFileMapWrite;
maps[i].offset >> 32, maps[i].offset, size, addr); }
} 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; savepid = __pid;
savebir = __kbirth; savebir = __kbirth;
savetsc = ts; savetsc = ts;
STRACE("fork() child reading %'zu bytes of .data to %p", if (!ReadAll(reader, __data_start, __data_end - __data_start) ||
__data_end - __data_start, __data_start); !ReadAll(reader, __bss_start, __bss_end - __bss_start)) {
ReadAll(reader, __data_start, __data_end - __data_start); ExitProcess(46);
STRACE("fork() child reading %'zu bytes of .bss to %p", }
__bss_end - __bss_start, __bss_start);
ReadAll(reader, __bss_start, __bss_end - __bss_start);
__pid = savepid; __pid = savepid;
__kbirth = savebir; __kbirth = savebir;
ts = savetsc; ts = savetsc;
/* // apply fixups and reapply memory protections
* apply fixups and reapply memory protections
*/
STRACE("fork() child applying fixups to _mmi.p");
_mmi.p = maps; _mmi.p = maps;
_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), ROUNDUP(maps[i].size, FRAMESIZE), flags1, &oldprot);
__prot2nt(maps[i].prot, 0), &oldprot);
} }
} }
/* // we're all done reading!
* clean up and restore old processor state if (!CloseHandle(reader)) {
*/ STRACE("CloseHandle(reader) failed %m");
STRACE("fork() child almost done!"); ExitProcess(47);
CloseHandle(reader); }
CloseHandle(writer);
// clean up, restore state, and jump back into function below
#ifdef SYSDEBUG #ifdef SYSDEBUG
RemoveVectoredExceptionHandler(oncrash); RemoveVectoredExceptionHandler(oncrash);
#endif #endif
if (weaken(__wincrash_nt)) { if (weaken(__wincrash_nt)) {
AddVectoredExceptionHandler(1, (void *)weaken(__wincrash_nt)); AddVectoredExceptionHandler(1, (void *)weaken(__wincrash_nt));
} }
STRACE("fork() child it's time for the big jump (>'.')>");
longjmp(jb, 1); longjmp(jb, 1);
} }
@ -274,10 +275,8 @@ textwindows int sys_fork_nt(void) {
startinfo.hStdError = g_fds.p[2].handle; startinfo.hStdError = g_fds.p[2].handle;
args = __argv; args = __argv;
#ifdef SYSDEBUG #ifdef SYSDEBUG
/* // If --strace was passed to this program, then propagate it the
* If --strace was passed to this program, then propagate it the // forked process since the flag was removed by __intercept_flag
* forked process since the flag was removed by __intercept_flag
*/
if (__strace > 0) { if (__strace > 0) {
for (n = 0; args[n];) ++n; for (n = 0; args[n];) ++n;
args2 = alloca((n + 2) * sizeof(char *)); 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.i, sizeof(_mmi.i)) &&
WriteAll(writer, &_mmi.n, sizeof(_mmi.n)) && WriteAll(writer, &_mmi.n, sizeof(_mmi.n)) &&
WriteAll(writer, _mmi.p, _mmi.i * sizeof(_mmi.p[0])); WriteAll(writer, _mmi.p, _mmi.i * sizeof(_mmi.p[0]));
#if 0
if (IsAsan() && ok) { if (IsAsan() && ok) {
ok = WriteAll(writer, (char *)(((intptr_t)_mmi.p >> 3) + 0x7fff8000), ok = WriteAll(writer, (char *)(((intptr_t)_mmi.p >> 3) + 0x7fff8000),
(_mmi.i * sizeof(_mmi.p[0])) >> 3); (_mmi.i * sizeof(_mmi.p[0])) >> 3);
} }
#endif
for (i = 0; i < _mmi.i && ok; ++i) { for (i = 0; i < _mmi.i && ok; ++i) {
if (_mmi.p[i].flags & MAP_PRIVATE) { if (_mmi.p[i].flags & MAP_PRIVATE) {
ok = WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16), ok = WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16),
_mmi.p[i].size); _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) { if (ok) {
STRACE("fork() parent writing %'zu bytes of .data", if (!CloseHandle(writer)) {
__data_end - __data_start); STRACE("CloseHandle(writer) failed %m");
ok = WriteAll(writer, __data_start, __data_end - __data_start); 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 (ok) {
if (!weaken(__sighandrvas) || if (!weaken(__sighandrvas) ||
weaken(__sighandrvas)[SIGCHLD] != SIG_IGN) { weaken(__sighandrvas)[SIGCHLD] != SIG_IGN) {
@ -338,25 +332,21 @@ textwindows int sys_fork_nt(void) {
rc = GetProcessId(procinfo.hProcess); rc = GetProcessId(procinfo.hProcess);
CloseHandle(procinfo.hProcess); CloseHandle(procinfo.hProcess);
} }
STRACE("fork() parent everything looks good");
} else { } else {
STRACE("fork() parent ~~failed~~ because writing failed");
rc = __winerr(); rc = __winerr();
TerminateProcess(procinfo.hProcess, 127); TerminateProcess(procinfo.hProcess, 127);
CloseHandle(procinfo.hProcess); CloseHandle(procinfo.hProcess);
} }
} else { } else {
STRACE("fork() parent ~~failed~~ because ntspawn failed");
CloseHandle(writer); CloseHandle(writer);
rc = -1; rc = -1;
} }
} else { } else {
STRACE("fork() parent ~~failed~~ because CreatePipe() failed %m"); STRACE("CreatePipe() failed %m");
rc = __winerr(); rc = __winerr();
CloseHandle(writer); CloseHandle(writer);
} }
} else { } else {
STRACE("fork() child welcome back <('.'<)");
rc = 0; rc = 0;
} }
if (untrackpid != -1) { if (untrackpid != -1) {

View file

@ -27,8 +27,8 @@
/** /**
* Synchronize memory mapping changes to disk. * Synchronize memory mapping changes to disk.
* *
* Without this, there's no guarantee memory is written back to disk. In * Without this, there's no guarantee memory is written back to disk.
* practice, what that means is just Windows NT. * Particularly on RHEL5, OpenBSD, and Windows NT.
* *
* @param addr needs to be 4096-byte page aligned * @param addr needs to be 4096-byte page aligned
* @param flags needs MS_ASYNC or MS_SYNC and can have MS_INVALIDATE * @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 = buf;
p = stpcpy(p, ip); p = stpcpy(p, ip);
*p++ = ':'; *p++ = ':';
p = FormatUint32(p, in->sin_port); p = FormatUint32(p, ntohs(in->sin_port));
} }
} else if (sa->sa_family == AF_INET6 && } else if (sa->sa_family == AF_INET6 &&
sasize >= sizeof(struct sockaddr_in6)) { sasize >= sizeof(struct sockaddr_in6)) {

View file

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

View file

@ -1,6 +1,6 @@
# EastAsianWidth-14.0.0.txt # EastAsianWidth-15.0.0.txt
# Date: 2021-07-06, 09:58:53 GMT [KW, LI] # Date: 2022-01-28, 13:07:15 GMT [KW, LI]
# © 2021 Unicode®, Inc. # © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # 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 # 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 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 0CE6..0CEF;N # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
0CF1..0CF2;N # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA 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 0D00..0D01;N # Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
0D02..0D03;N # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA 0D02..0D03;N # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
0D04..0D0C;N # Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L 0D04..0D0C;N # Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
@ -595,7 +596,7 @@
0EBD;N # Lo LAO SEMIVOWEL SIGN NYO 0EBD;N # Lo LAO SEMIVOWEL SIGN NYO
0EC0..0EC4;N # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI 0EC0..0EC4;N # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
0EC6;N # Lm LAO KO LA 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 0ED0..0ED9;N # Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE
0EDC..0EDF;N # Lo [4] LAO HO NO..LAO LETTER KHMU NYO 0EDC..0EDF;N # Lo [4] LAO HO NO..LAO LETTER KHMU NYO
0F00;N # Lo TIBETAN SYLLABLE OM 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 10EAB..10EAC;N # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
10EAD;N # Pd YEZIDI HYPHENATION MARK 10EAD;N # Pd YEZIDI HYPHENATION MARK
10EB0..10EB1;N # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE 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 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 10F1D..10F26;N # No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF
10F27;N # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 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 11236..11237;N # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
11238..1123D;N # Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN 11238..1123D;N # Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN
1123E;N # Mn KHOJKI SIGN SUKUN 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 11280..11286;N # Lo [7] MULTANI LETTER A..MULTANI LETTER GA
11288;N # Lo MULTANI LETTER GHA 11288;N # Lo MULTANI LETTER GHA
1128A..1128D;N # Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA 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 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 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 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 11C00..11C08;N # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L
11C0A..11C2E;N # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C0A..11C2E;N # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA
11C2F;N # Mc BHAIKSUKI VOWEL SIGN AA 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 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 11EF5..11EF6;N # Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
11EF7..11EF8;N # Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION 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 11FB0;N # Lo LISU LETTER YHA
11FC0..11FD4;N # No [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH 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 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 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 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 12FF1..12FF2;N # Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302
13000..1342E;N # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 13000..1342F;N # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D
13430..13438;N # Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT 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 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 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 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 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 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 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 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 1B164..1B167;W # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
1B170..1B2FB;W # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB 1B170..1B2FB;W # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB
1BC00..1BC6A;N # Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M 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 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 1D242..1D244;N # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
1D245;N # So GREEK MUSICAL LEIMMA 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 1D2E0..1D2F3;N # No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN
1D300..1D356;N # So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING 1D300..1D356;N # So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
1D360..1D378;N # No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE 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 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 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 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 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 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 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 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 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 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 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 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 1E2EC..1E2EF;N # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI
1E2F0..1E2F9;N # Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE 1E2F0..1E2F9;N # Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE
1E2FF;N # Sc WANCHO NGUN SIGN 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 1E7E0..1E7E6;N # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO
1E7E8..1E7EB;N # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE 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 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 1F6D0..1F6D2;W # So [3] PLACE OF WORSHIP..SHOPPING TROLLEY
1F6D3..1F6D4;N # So [2] STUPA..PAGODA 1F6D3..1F6D4;N # So [2] STUPA..PAGODA
1F6D5..1F6D7;W # So [3] HINDU TEMPLE..ELEVATOR 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 1F6E0..1F6EA;N # So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE
1F6EB..1F6EC;W # So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING 1F6EB..1F6EC;W # So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING
1F6F0..1F6F3;N # So [4] SATELLITE..PASSENGER SHIP 1F6F0..1F6F3;N # So [4] SATELLITE..PASSENGER SHIP
1F6F4..1F6FC;W # So [9] SCOOTER..ROLLER SKATE 1F6F4..1F6FC;W # So [9] SCOOTER..ROLLER SKATE
1F700..1F773;N # So [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE 1F700..1F776;N # So [119] ALCHEMICAL SYMBOL FOR QUINTESSENCE..LUNAR ECLIPSE
1F780..1F7D8;N # So [89] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NEGATIVE CIRCLED SQUARE 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 1F7E0..1F7EB;W # So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE
1F7F0;W # So HEAVY EQUALS SIGN 1F7F0;W # So HEAVY EQUALS SIGN
1F800..1F80B;N # So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD 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 1F947..1F9FF;W # So [185] FIRST PLACE MEDAL..NAZAR AMULET
1FA00..1FA53;N # So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP 1FA00..1FA53;N # So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP
1FA60..1FA6D;N # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER 1FA60..1FA6D;N # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER
1FA70..1FA74;W # So [5] BALLET SHOES..THONG SANDAL 1FA70..1FA7C;W # So [13] BALLET SHOES..CRUTCH
1FA78..1FA7C;W # So [5] DROP OF BLOOD..CRUTCH 1FA80..1FA88;W # So [9] YO-YO..FLUTE
1FA80..1FA86;W # So [7] YO-YO..NESTING DOLLS 1FA90..1FABD;W # So [46] RINGED PLANET..WING
1FA90..1FAAC;W # So [29] RINGED PLANET..HAMSA 1FABE;W # Cn <reserved-1FABE>
1FAB0..1FABA;W # So [11] FLY..NEST WITH EGGS 1FABF..1FAC5;W # So [7] GOOSE..PERSON WITH CROWN
1FAC0..1FAC5;W # So [6] ANATOMICAL HEART..PERSON WITH CROWN 1FACE..1FADB;W # So [14] MOOSE..PEA POD
1FAD0..1FAD9;W # So [10] BLUEBERRIES..JAR 1FAE0..1FAE8;W # So [9] MELTING FACE..SHAKING FACE
1FAE0..1FAE7;W # So [8] MELTING FACE..BUBBLES 1FAF0..1FAF8;W # So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND
1FAF0..1FAF6;W # So [7] HAND WITH INDEX FINGER AND THUMB CROSSED..HEART HANDS
1FB00..1FB92;N # So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK 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 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 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> 2FA1E..2FA1F;W # Cn [2] <reserved-2FA1E>..<reserved-2FA1F>
2FA20..2FFFD;W # Cn [1502] <reserved-2FA20>..<reserved-2FFFD> 2FA20..2FFFD;W # Cn [1502] <reserved-2FA20>..<reserved-2FFFD>
30000..3134A;W # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A 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 E0001;N # Cf LANGUAGE TAG
E0020..E007F;N # Cf [96] TAG SPACE..CANCEL TAG E0020..E007F;N # Cf [96] TAG SPACE..CANCEL TAG
E0100..E01EF;A # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 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;;;;; 0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; 0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
0CF2;KANNADA SIGN UPADHMANIYA;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;;;;; 0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;
0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
@ -3339,6 +3340,7 @@
0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;; 0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;;
0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;; 0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;;
0ECD;LAO NIGGAHITA;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;;;;; 0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;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;;;;; 10EAD;YEZIDI HYPHENATION MARK;Pd;0;R;;;;;N;;;;;
10EB0;YEZIDI LETTER LAM WITH DOT ABOVE;Lo;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;;;;; 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;;;;; 10F00;OLD SOGDIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;; 10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;;
10F02;OLD SOGDIAN LETTER BETH;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;;;;; 1123C;KHOJKI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
1123E;KHOJKI SIGN SUKUN;Mn;0;NSM;;;;;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;;;;; 11280;MULTANI LETTER A;Lo;0;L;;;;;N;;;;;
11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;; 11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;;
11282;MULTANI LETTER U;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;;;;; 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;;;;; 11AF7;PAU CIN HAU LOW-FALLING TONE FINAL;Lo;0;L;;;;;N;;;;;
11AF8;PAU CIN HAU GLOTTAL STOP 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;;;;; 11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;;
11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;; 11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;;
11C02;BHAIKSUKI LETTER I;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;;;;; 11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;; 11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;;
11EF8;MAKASAR END OF SECTION;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;;;;; 11FB0;LISU LETTER YHA;Lo;0;L;;;;;N;;;;;
11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;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;;;;; 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;;;;; 1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;;
1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;; 1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;;
1342E;EGYPTIAN HIEROGLYPH AA032;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;;;;; 13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;;
13431;EGYPTIAN HIEROGLYPH HORIZONTAL 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;;;;; 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;;;;; 13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;;
13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;; 13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;;
13438;EGYPTIAN HIEROGLYPH END 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;;;;; 14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; 14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
14402;ANATOLIAN HIEROGLYPH A003;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;;;;; 1B120;KATAKANA LETTER ARCHAIC YI;Lo;0;L;;;;;N;;;;;
1B121;KATAKANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;; 1B121;KATAKANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
1B122;KATAKANA LETTER ARCHAIC WU;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;;;;; 1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; 1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
1B152;HIRAGANA LETTER SMALL WO;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;;;;; 1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; 1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
1B166;KATAKANA LETTER SMALL WO;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;;;;; 1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;;
1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;; 1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;;
1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;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;;;;; 1D2E0;MAYAN NUMERAL ZERO;No;0;L;;;;0;N;;;;;
1D2E1;MAYAN NUMERAL ONE;No;0;L;;;;1;N;;;;; 1D2E1;MAYAN NUMERAL ONE;No;0;L;;;;1;N;;;;;
1D2E2;MAYAN NUMERAL TWO;No;0;L;;;;2;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;;;;; 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;;;;; 1DF1D;LATIN SMALL LETTER C WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
1DF1E;LATIN SMALL LETTER S WITH CURL;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;;;;; 1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;;
1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;; 1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;;
1E002;COMBINING GLAGOLITIC LETTER VEDE;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;;;;; 1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
1E029;COMBINING GLAGOLITIC LETTER IOTATED 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;;;;; 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;;;;; 1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;;
1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;; 1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;;
1E102;NYIAKENG PUACHUE HMONG LETTER NTA;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;;;;; 1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;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;;;;; 1E7E0;ETHIOPIC SYLLABLE HHYA;Lo;0;L;;;;;N;;;;;
1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;; 1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;;
1E7E2;ETHIOPIC SYLLABLE HHYI;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;;;;; 1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;;
1F6D6;HUT;So;0;ON;;;;;N;;;;; 1F6D6;HUT;So;0;ON;;;;;N;;;;;
1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;; 1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;;
1F6DC;WIRELESS;So;0;ON;;;;;N;;;;;
1F6DD;PLAYGROUND SLIDE;So;0;ON;;;;;N;;;;; 1F6DD;PLAYGROUND SLIDE;So;0;ON;;;;;N;;;;;
1F6DE;WHEEL;So;0;ON;;;;;N;;;;; 1F6DE;WHEEL;So;0;ON;;;;;N;;;;;
1F6DF;RING BUOY;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;;;;; 1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;;
1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;; 1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;;
1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;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;;;;; 1F780;BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
1F781;BLACK UP-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;;;;; 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;;;;; 1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;;
1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;; 1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;;
1F7D8;NEGATIVE 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;;;;; 1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;;
1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;; 1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;;
1F7E2;LARGE GREEN 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;;;;; 1FA72;BRIEFS;So;0;ON;;;;;N;;;;;
1FA73;SHORTS;So;0;ON;;;;;N;;;;; 1FA73;SHORTS;So;0;ON;;;;;N;;;;;
1FA74;THONG SANDAL;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;;;;; 1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;;
1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;; 1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;;
1FA7A;STETHOSCOPE;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;;;;; 1FA84;MAGIC WAND;So;0;ON;;;;;N;;;;;
1FA85;PINATA;So;0;ON;;;;;N;;;;; 1FA85;PINATA;So;0;ON;;;;;N;;;;;
1FA86;NESTING DOLLS;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;;;;; 1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;;
1FA91;CHAIR;So;0;ON;;;;;N;;;;; 1FA91;CHAIR;So;0;ON;;;;;N;;;;;
1FA92;RAZOR;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;;;;; 1FAAA;IDENTIFICATION CARD;So;0;ON;;;;;N;;;;;
1FAAB;LOW BATTERY;So;0;ON;;;;;N;;;;; 1FAAB;LOW BATTERY;So;0;ON;;;;;N;;;;;
1FAAC;HAMSA;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;;;;; 1FAB0;FLY;So;0;ON;;;;;N;;;;;
1FAB1;WORM;So;0;ON;;;;;N;;;;; 1FAB1;WORM;So;0;ON;;;;;N;;;;;
1FAB2;BEETLE;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;;;;; 1FAB8;CORAL;So;0;ON;;;;;N;;;;;
1FAB9;EMPTY NEST;So;0;ON;;;;;N;;;;; 1FAB9;EMPTY NEST;So;0;ON;;;;;N;;;;;
1FABA;NEST WITH EGGS;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;;;;; 1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;;
1FAC1;LUNGS;So;0;ON;;;;;N;;;;; 1FAC1;LUNGS;So;0;ON;;;;;N;;;;;
1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;; 1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;;
1FAC3;PREGNANT MAN;So;0;ON;;;;;N;;;;; 1FAC3;PREGNANT MAN;So;0;ON;;;;;N;;;;;
1FAC4;PREGNANT PERSON;So;0;ON;;;;;N;;;;; 1FAC4;PREGNANT PERSON;So;0;ON;;;;;N;;;;;
1FAC5;PERSON WITH CROWN;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;;;;; 1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;;
1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;; 1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;;
1FAD2;OLIVE;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;;;;; 1FAD7;POURING LIQUID;So;0;ON;;;;;N;;;;;
1FAD8;BEANS;So;0;ON;;;;;N;;;;; 1FAD8;BEANS;So;0;ON;;;;;N;;;;;
1FAD9;JAR;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;;;;; 1FAE0;MELTING FACE;So;0;ON;;;;;N;;;;;
1FAE1;SALUTING 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;;;;; 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;;;;; 1FAE5;DOTTED LINE FACE;So;0;ON;;;;;N;;;;;
1FAE6;BITING LIP;So;0;ON;;;;;N;;;;; 1FAE6;BITING LIP;So;0;ON;;;;;N;;;;;
1FAE7;BUBBLES;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;;;;; 1FAF0;HAND WITH INDEX FINGER AND THUMB CROSSED;So;0;ON;;;;;N;;;;;
1FAF1;RIGHTWARDS HAND;So;0;ON;;;;;N;;;;; 1FAF1;RIGHTWARDS HAND;So;0;ON;;;;;N;;;;;
1FAF2;LEFTWARDS 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;;;;; 1FAF4;PALM UP HAND;So;0;ON;;;;;N;;;;;
1FAF5;INDEX POINTING AT THE VIEWER;So;0;ON;;;;;N;;;;; 1FAF5;INDEX POINTING AT THE VIEWER;So;0;ON;;;;;N;;;;;
1FAF6;HEART HANDS;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;;;;; 1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;;
1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;; 1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;;
1FB02;BLOCK SEXTANT-12;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;;;;; 2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;
30000;<CJK Ideograph Extension G, First>;Lo;0;L;;;;;N;;;;; 30000;<CJK Ideograph Extension G, First>;Lo;0;L;;;;;N;;;;;
3134A;<CJK Ideograph Extension G, Last>;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;;;;; E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;
E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;; E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;
E0021;TAG EXCLAMATION MARK;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/bits/xchg.internal.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.internal.h" #include "libc/runtime/gc.internal.h"
#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
@ -40,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.%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))); 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));
@ -54,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.%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))); 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));
@ -113,6 +115,7 @@ TEST(mmap, fileOffset) {
EXPECT_NE(-1, ftruncate(fd, FRAMESIZE * 2)); EXPECT_NE(-1, ftruncate(fd, FRAMESIZE * 2));
EXPECT_NE(-1, pwrite(fd, "hello", 5, FRAMESIZE * 0)); EXPECT_NE(-1, pwrite(fd, "hello", 5, FRAMESIZE * 0));
EXPECT_NE(-1, pwrite(fd, "there", 5, FRAMESIZE * 1)); 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, ASSERT_NE(MAP_FAILED, (map = mmap(NULL, FRAMESIZE, PROT_READ, MAP_PRIVATE, fd,
FRAMESIZE))); FRAMESIZE)));
EXPECT_EQ(0, memcmp(map, "there", 5), "%#.*s", 5, map); EXPECT_EQ(0, memcmp(map, "there", 5), "%#.*s", 5, map);
@ -123,7 +126,7 @@ TEST(mmap, fileOffset) {
TEST(mmap, mapPrivate_writesDontChangeFile) { TEST(mmap, mapPrivate_writesDontChangeFile) {
int fd; int fd;
char *map, buf[5]; 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, ftruncate(fd, FRAMESIZE));
EXPECT_NE(-1, pwrite(fd, "hello", 5, 0)); EXPECT_NE(-1, pwrite(fd, "hello", 5, 0));
ASSERT_NE(MAP_FAILED, (map = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, ASSERT_NE(MAP_FAILED, (map = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE,
@ -131,7 +134,7 @@ TEST(mmap, mapPrivate_writesDontChangeFile) {
memcpy(map, "there", 5); memcpy(map, "there", 5);
EXPECT_NE(-1, msync(map, FRAMESIZE, MS_SYNC)); EXPECT_NE(-1, msync(map, FRAMESIZE, MS_SYNC));
EXPECT_NE(-1, munmap(map, FRAMESIZE)); 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_EQ(0, memcmp(buf, "hello", 5), "%#.*s", 5, buf);
EXPECT_NE(-1, close(fd)); EXPECT_NE(-1, close(fd));
} }
@ -152,3 +155,128 @@ TEST(isheap, mallocOffset) {
char *p = gc(malloc(131072)); char *p = gc(malloc(131072));
ASSERT_TRUE(_isheap(p + 100000)); 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 ** 2004 May 22
** **
@ -44,9 +45,9 @@
** plus implementations of sqlite3_os_init() and sqlite3_os_end(). ** plus implementations of sqlite3_os_init() and sqlite3_os_end().
*/ */
#include "libc/rand/rand.h" #include "libc/rand/rand.h"
#include "libc/sysv/consts/lock.h"
#include "third_party/sqlite3/sqliteInt.inc" #include "third_party/sqlite3/sqliteInt.inc"
#if SQLITE_OS_UNIX /* This file is used on unix only */ #if SQLITE_OS_UNIX /* This file is used on unix only */
/* clang-format off */
/* /*
** There are various methods for file locking used for concurrency ** There are various methods for file locking used for concurrency
@ -74,7 +75,7 @@
#endif #endif
/* Use pread() and pwrite() if they are available */ /* Use pread() and pwrite() if they are available */
#if defined(__APPLE__) #if defined(__APPLE__) || defined(__COSMOPOLITAN__)
# define HAVE_PREAD 1 # define HAVE_PREAD 1
# define HAVE_PWRITE 1 # define HAVE_PWRITE 1
#endif #endif
@ -140,10 +141,6 @@
#include "libc/limits.h" #include "libc/limits.h"
#endif /* OS_VXWORKS */ #endif /* OS_VXWORKS */
#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
# include <sys/mount.h>
#endif
#ifdef HAVE_UTIME #ifdef HAVE_UTIME
#include "libc/time/time.h" #include "libc/time/time.h"
#endif #endif
@ -331,14 +328,6 @@ static pid_t randomnessPid = 0;
# endif # endif
#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__ #ifdef __linux__
/* /*
** Linux-specific IOCTL magic numbers used for controlling F2FS ** Linux-specific IOCTL magic numbers used for controlling F2FS

View file

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

View file

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

View file

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

View file

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

View file

@ -175,15 +175,15 @@
(cond ((eq arg 9) "-x") (cond ((eq arg 9) "-x")
(t ""))) (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" (let* ((ext (file-name-extension this)) ;; e.g. "c"
(dir (file-name-directory this)) ;; e.g. "/home/jart/daisy/libc/" (dir (file-name-directory this)) ;; e.g. "/home/jart/daisy/libc/"
(dots (file-relative-name root dir)) ;; e.g. "../" (dots (file-relative-name root dir)) ;; e.g. "../"
(file (file-relative-name this root)) ;; e.g. "libc/crc32c.c" (file (file-relative-name this root)) ;; e.g. "libc/crc32c.c"
(name (file-name-sans-extension file)) ;; e.g. "libc/crc32c" (name (file-name-sans-extension file)) ;; e.g. "libc/crc32c"
(buddy (format "test/%s_test.c" name)) (buddy (format "test/%s_test.c" name))
(runs (format "o/$m/%s.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.runs V=5 TESTARGS=-b" name))) (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"))) (cond ((not (member ext '("c" "cc" "s" "S" "rl" "f")))
(format "m=%s; make -j8 -O MODE=$m o/$m/%s" (format "m=%s; make -j8 -O MODE=$m o/$m/%s"
mode mode
@ -191,6 +191,15 @@
(or (file-name-directory (or (file-name-directory
(file-relative-name this root)) (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 "") ((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"
@ -214,24 +223,8 @@
,(concat "make -j8 -O $f MODE=$m") ,(concat "make -j8 -O $f MODE=$m")
"./$f")) "./$f"))
mode name)) mode name))
((eq kind 'run-win7) ((eq kind 'test)
(format (format `"m=%s; f=o/$m/%s.com.ok && make -j8 -O $f MODE=$m" mode name))
(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)))
((and (file-regular-p this) ((and (file-regular-p this)
(file-executable-p this)) (file-executable-p this))
(format "./%s" file)) (format "./%s" file))
@ -257,7 +250,7 @@
(objdumpflags (cosmo--make-objdump-flags arg)) (objdumpflags (cosmo--make-objdump-flags arg))
(compilation-scroll-output nil) (compilation-scroll-output nil)
(default-directory root) (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))))) (compile compile-command)))))
(defun cosmo-compile-hook () (defun cosmo-compile-hook ()
@ -600,7 +593,7 @@
(format "./%s" file)))) (format "./%s" file))))
((memq major-mode '(c-mode c++-mode asm-mode fortran-mode)) ((memq major-mode '(c-mode c++-mode asm-mode fortran-mode))
(let* ((mode (cosmo--make-mode arg)) (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))) (compile compile-command)))
((eq major-mode 'sh-mode) ((eq major-mode 'sh-mode)
(compile (format "sh %s" file))) (compile (format "sh %s" file)))
@ -614,6 +607,22 @@
('t ('t
(error "cosmo-run: unknown major mode"))))))) (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) (defun cosmo-run-win7 (arg)
(interactive "P") (interactive "P")
(let* ((this (or (buffer-file-name) dired-directory)) (let* ((this (or (buffer-file-name) dired-directory))
@ -624,24 +633,8 @@
(let ((default-directory root)) (let ((default-directory root))
(save-buffer) (save-buffer)
(cond ((memq major-mode '(c-mode c++-mode asm-mode fortran-mode)) (cond ((memq major-mode '(c-mode c++-mode asm-mode fortran-mode))
(let* ((mode (cosmo--make-mode arg)) (let* ((mode (cosmo--make-mode arg ""))
(compile-command (cosmo--compile-command this root 'run-win7 mode "" ""))) (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 "" "")))
(compile compile-command))) (compile compile-command)))
('t ('t
(error "cosmo-run: unknown major mode"))))))) (error "cosmo-run: unknown major mode")))))))
@ -652,8 +645,8 @@
(define-key fortran-mode-map (kbd "C-c C-r") 'cosmo-run) (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 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-win7) (define-key c-mode-map (kbd "C-c C-s") 'cosmo-run-test)
(define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win10)) (define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win7))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -675,7 +668,7 @@
(next (file-name-sans-extension name)) (next (file-name-sans-extension name))
(exec (format "o/%s/%s.com.dbg" mode next)) (exec (format "o/%s/%s.com.dbg" mode next))
(default-directory root) (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) (compile compile-command)
(gdb (format "gdb -q -nh -i=mi %s -ex run" exec)))))) (gdb (format "gdb -q -nh -i=mi %s -ex run" exec))))))
@ -875,6 +868,36 @@
(add-hook 'before-save-hook 'cosmo-before-save) (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) (provide 'cosmo-stuff)
;;; cosmo-stuff.el ends here ;;; cosmo-stuff.el ends here