From 19d0c15e034db22d71758c6f21d24b868dffd9a5 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 27 Feb 2021 10:33:32 -0800 Subject: [PATCH] Perform some code cleanup --- .vscode/vscode.h | 3 +- NOTICE | 14 - ape/ape.S | 8 +- ape/ape.lds | 13 +- build/config.mk | 8 +- libc/calls/calls.mk | 5 +- libc/calls/sigenter-freebsd.c | 42 +-- libc/calls/sigenter-netbsd.c | 4 +- libc/calls/sigenter-openbsd.c | 4 +- .../calls/{xnutrampoline.c => sigenter-xnu.c} | 0 libc/log/commandvenv.c | 12 +- libc/runtime/efimain.greg.c | 1 - libc/runtime/exit3.c | 4 +- libc/runtime/runtime.mk | 19 +- libc/runtime/winmain.greg.c | 10 +- libc/sock/internal.h | 2 +- libc/sock/kntwsadata.c | 6 +- libc/str/endswith.c | 2 +- libc/str/str.h | 6 +- libc/str/strsep.c | 8 +- libc/str/strsignal.c | 2 +- libc/str/strstr16.c | 13 +- libc/str/tinymemmem.c | 37 --- libc/str/tinystrstr16.c | 38 --- libc/tinymath/hypot.c | 1 - libc/tinymath/hypotf.c | 1 - libc/tinymath/hypotl.c | 1 - libc/tinymath/log10.S | 3 +- libc/tinymath/log2.S | 3 +- libc/tinymath/log2f.S | 3 +- test/tool/build/lib/disinst_test.c | 109 +++---- test/tool/build/lib/modrm_test.c | 31 +- .../tinystrstr.c => third_party/xed/eamode.c | 30 +- third_party/xed/x86.h | 3 +- third_party/xed/x86features.c | 3 +- third_party/xed/x86ild.greg.c | 303 ++++++++---------- third_party/xed/x86isa.c | 8 +- tool/build/lib/dis.c | 2 + tool/build/lib/instruction.c | 2 + tool/build/lib/modrm.c | 15 + tool/build/lib/modrm.h | 1 + 41 files changed, 321 insertions(+), 459 deletions(-) delete mode 100644 NOTICE rename libc/calls/{xnutrampoline.c => sigenter-xnu.c} (100%) delete mode 100644 libc/str/tinymemmem.c delete mode 100644 libc/str/tinystrstr16.c rename libc/str/tinystrstr.c => third_party/xed/eamode.c (78%) diff --git a/.vscode/vscode.h b/.vscode/vscode.h index 129587b6..535d7a93 100644 --- a/.vscode/vscode.h +++ b/.vscode/vscode.h @@ -145,8 +145,7 @@ typedef struct { int ax, dx; } axdx_t; #define offsetof(x, y) 0 #define INITIALIZER(...) struct _dummy #define __far -#define tinystrstr(...) 0 -#define BENCHLOOP(...) 0 +#define BENCHLOOP(...) 0 #ifdef __hook #undef __hook diff --git a/NOTICE b/NOTICE deleted file mode 100644 index ca403142..00000000 --- a/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright 2020 Justine Alexandra Roberts Tunney - -Permission to use, copy, modify, and/or distribute this software for -any purpose with or without fee is hereby granted, provided that the -above copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. diff --git a/ape/ape.S b/ape/ape.S index 93ab3fae..126b2df9 100644 --- a/ape/ape.S +++ b/ape/ape.S @@ -44,7 +44,7 @@ #include "libc/runtime/pc.internal.h" #include "libc/sysv/consts/prot.h" -#define USE_SYMBOL_HACK 0 +#define USE_SYMBOL_HACK 1 .section .text,"ax",@progbits .align __SIZEOF_POINTER__ @@ -1486,12 +1486,6 @@ ape_pad_text: ape_pad_privileged: .previous - .section .ape.pad.test,"a",@progbits - .type ape_pad_test,@object - .hidden ape_pad_test -ape_pad_test: - .previous - .section .ape.pad.rodata,"a",@progbits .type ape_pad_rodata,@object .hidden ape_pad_rodata diff --git a/ape/ape.lds b/ape/ape.lds index 794ce113..18e60f63 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -238,9 +238,8 @@ SECTIONS { /* Code that needs to be addressable in Real Mode */ *(.text.real) KEEP(*(SORT_BY_NAME(.sort.text.real.*))) - /**(.rodata.real) - KEEP(*(SORT_BY_NAME(.sort.rodata.real.*)))*/ HIDDEN(_ereal = .); + . += 1; /*END: realmode addressability guarantee */ @@ -273,16 +272,17 @@ SECTIONS { KEEP(*(SORT_BY_NAME(.sort.text.*))) KEEP(*(.ape.pad.test)); - HIDDEN(__test_start = .); *(.test.unlikely) *(.test .test.*) /* Privileged code invulnerable to magic */ KEEP(*(.ape.pad.privileged)); + . += . > 0 ? 1 : 0; HIDDEN(__privileged_start = .); - HIDDEN(__test_end = .); + . += . > 0 ? 1 : 0; *(.privileged) HIDDEN(__privileged_end = .); + . += . > 0 ? 1 : 0; /*BEGIN: Read Only Data */ @@ -302,7 +302,7 @@ SECTIONS { KEEP(*(.comment)) KEEP(*(.commentepilogue)) #endif - + /* Windows DLL Import Directory */ KEEP(*(.idata.ro)); KEEP(*(SORT_BY_NAME(.idata.ro.*))) @@ -369,6 +369,7 @@ SECTIONS { *(.piro.bss) KEEP(*(SORT_BY_NAME(.piro.bss.sort.*))) HIDDEN(__piro_end = .); + . += . > 0 ? 1 : 0; /*END: Post-Initialization Read-Only */ /* Statically Allocated Empty Space */ @@ -378,7 +379,7 @@ SECTIONS { KEEP(*(SORT_BY_NAME(.sort.bss.*))) - . = ALIGN(0x10000); /* for brk()/sbrk() allocation */ + . = ALIGN(FRAMESIZE); /* for brk()/sbrk() allocation */ HIDDEN(_end = .); PROVIDE_HIDDEN(end = .); } :Ram diff --git a/build/config.mk b/build/config.mk index 9b0e3d39..665a2e3e 100644 --- a/build/config.mk +++ b/build/config.mk @@ -130,7 +130,7 @@ endif # Linux-Only Tiny Mode # -# - `make MODE=tiny` +# - `make MODE=tinylinux` # - No checks # - No asserts # - No canaries @@ -158,7 +158,7 @@ endif # Linux+BSD Tiny Mode # -# - `make MODE=tiny` +# - `make MODE=tinylinuxbsd` # - No apple # - No checks # - No asserts @@ -187,7 +187,7 @@ endif # Unix Tiny Mode # -# - `make MODE=tiny` +# - `make MODE=tinysysv` # - No checks # - No asserts # - No canaries @@ -215,7 +215,7 @@ endif # Tiny Metallic Unix Mode # -# - `make MODE=tiny` +# - `make MODE=tinynowin` # - No checks # - No asserts # - No canaries diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index 38227c8b..ee041a1c 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -68,7 +68,10 @@ o/$(MODE)/libc/calls/siggy.o: \ OVERRIDE_COPTS += \ -ffunction-sections -o/$(MODE)/libc/calls/xnutrampoline.o \ +o/$(MODE)/libc/calls/sigenter-freebsd.o \ +o/$(MODE)/libc/calls/sigenter-netbsd.o \ +o/$(MODE)/libc/calls/sigenter-openbsd.o \ +o/$(MODE)/libc/calls/sigenter-xnu.o \ o/$(MODE)/libc/calls/ntcontext2linux.o: \ OVERRIDE_COPTS += \ -O3 diff --git a/libc/calls/sigenter-freebsd.c b/libc/calls/sigenter-freebsd.c index 9e74230b..7acb710e 100644 --- a/libc/calls/sigenter-freebsd.c +++ b/libc/calls/sigenter-freebsd.c @@ -43,21 +43,21 @@ struct siginfo_freebsd { union sigval_freebsd si_value; union { struct { - int _trapno; + int32_t _trapno; } _fault; struct { - int _timerid; - int _overrun; + int32_t _timerid; + int32_t _overrun; } _timer; struct { - int _mqd; + int32_t _mqd; } _mesgq; struct { - long _band; + int64_t _band; } _poll; struct { - long __spare1__; - int __spare2__[7]; + int64_t __spare1__; + int32_t __spare2__[7]; } __spare__; } _reason; }; @@ -106,7 +106,7 @@ struct mcontext_freebsd { int64_t mc_gsbase; int64_t mc_xfpustate; int64_t mc_xfpustate_len; - long mc_spare[4]; + int64_t mc_spare[4]; }; struct ucontext_freebsd { @@ -118,8 +118,8 @@ struct ucontext_freebsd { int32_t __spare__[4]; }; -hidden void __sigenter_freebsd(int sig, struct siginfo_freebsd *si, - struct ucontext_freebsd *ctx) { +void __sigenter_freebsd(int sig, struct siginfo_freebsd *si, + struct ucontext_freebsd *ctx) { int rva; ucontext_t uc; rva = __sighandrvas[sig & (NSIG - 1)]; @@ -133,28 +133,28 @@ hidden void __sigenter_freebsd(int sig, struct siginfo_freebsd *si, uc.uc_flags = ctx->uc_flags; memcpy(&uc.uc_sigmask, &ctx->uc_sigmask, MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask))); - uc.uc_mcontext.rdi = ctx->uc_mcontext.mc_rdi; - uc.uc_mcontext.rsi = ctx->uc_mcontext.mc_rsi; - uc.uc_mcontext.rdx = ctx->uc_mcontext.mc_rdx; - uc.uc_mcontext.rcx = ctx->uc_mcontext.mc_rcx; uc.uc_mcontext.r8 = ctx->uc_mcontext.mc_r8; uc.uc_mcontext.r9 = ctx->uc_mcontext.mc_r9; - uc.uc_mcontext.rax = ctx->uc_mcontext.mc_rax; - uc.uc_mcontext.rbx = ctx->uc_mcontext.mc_rbx; - uc.uc_mcontext.rbp = ctx->uc_mcontext.mc_rbp; uc.uc_mcontext.r10 = ctx->uc_mcontext.mc_r10; uc.uc_mcontext.r11 = ctx->uc_mcontext.mc_r11; uc.uc_mcontext.r12 = ctx->uc_mcontext.mc_r12; uc.uc_mcontext.r13 = ctx->uc_mcontext.mc_r13; uc.uc_mcontext.r14 = ctx->uc_mcontext.mc_r14; uc.uc_mcontext.r15 = ctx->uc_mcontext.mc_r15; - uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno; + uc.uc_mcontext.rdi = ctx->uc_mcontext.mc_rdi; + uc.uc_mcontext.rsi = ctx->uc_mcontext.mc_rsi; + uc.uc_mcontext.rbp = ctx->uc_mcontext.mc_rbp; + uc.uc_mcontext.rbx = ctx->uc_mcontext.mc_rbx; + uc.uc_mcontext.rdx = ctx->uc_mcontext.mc_rdx; + uc.uc_mcontext.rax = ctx->uc_mcontext.mc_rax; + uc.uc_mcontext.rcx = ctx->uc_mcontext.mc_rcx; + uc.uc_mcontext.rsp = ctx->uc_mcontext.mc_rsp; + uc.uc_mcontext.rip = ctx->uc_mcontext.mc_rip; + uc.uc_mcontext.eflags = ctx->uc_mcontext.mc_flags; uc.uc_mcontext.fs = ctx->uc_mcontext.mc_fs; uc.uc_mcontext.gs = ctx->uc_mcontext.mc_gs; - uc.uc_mcontext.eflags = ctx->uc_mcontext.mc_flags; uc.uc_mcontext.err = ctx->uc_mcontext.mc_err; - uc.uc_mcontext.rip = ctx->uc_mcontext.mc_rip; - uc.uc_mcontext.rsp = ctx->uc_mcontext.mc_rsp; + uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno; } ((sigaction_f)(_base + rva))(sig, (void *)si, &uc); if (ctx) { diff --git a/libc/calls/sigenter-netbsd.c b/libc/calls/sigenter-netbsd.c index 283f500d..46baac23 100644 --- a/libc/calls/sigenter-netbsd.c +++ b/libc/calls/sigenter-netbsd.c @@ -125,8 +125,8 @@ struct ucontext_netbsd { struct mcontext_netbsd uc_mcontext; }; -hidden void __sigenter_netbsd(int sig, struct siginfo_netbsd *si, - struct ucontext_netbsd *ctx) { +void __sigenter_netbsd(int sig, struct siginfo_netbsd *si, + struct ucontext_netbsd *ctx) { int rva; ucontext_t uc; struct siginfo si2; diff --git a/libc/calls/sigenter-openbsd.c b/libc/calls/sigenter-openbsd.c index b923f2af..85e8fd29 100644 --- a/libc/calls/sigenter-openbsd.c +++ b/libc/calls/sigenter-openbsd.c @@ -90,8 +90,8 @@ struct ucontext_openbsd { int64_t sc_cookie; }; -hidden void __sigenter_openbsd(int sig, struct siginfo_openbsd *si, - struct ucontext_openbsd *ctx) { +void __sigenter_openbsd(int sig, struct siginfo_openbsd *si, + struct ucontext_openbsd *ctx) { int rva; ucontext_t uc; struct siginfo si2; diff --git a/libc/calls/xnutrampoline.c b/libc/calls/sigenter-xnu.c similarity index 100% rename from libc/calls/xnutrampoline.c rename to libc/calls/sigenter-xnu.c diff --git a/libc/log/commandvenv.c b/libc/log/commandvenv.c index 98ee58c3..3318908b 100644 --- a/libc/log/commandvenv.c +++ b/libc/log/commandvenv.c @@ -30,12 +30,12 @@ * that spawn subprocesses can use this function to determine the path * at startup. Here's an example how you could use it: * - * if ((strace = commandvenv("STRACE", "strace"))) { - * strace = strdup(strace); - * } else { - * fprintf(stderr, "error: please install strace\n"); - * exit(1); - * } + * if ((strace = commandvenv("STRACE", "strace"))) { + * strace = strdup(strace); + * } else { + * fprintf(stderr, "error: please install strace\n"); + * exit(1); + * } * * @param var is environment variable which may be used to override * PATH search, and it can force a NULL result if it's empty diff --git a/libc/runtime/efimain.greg.c b/libc/runtime/efimain.greg.c index b9323154..5737ba15 100644 --- a/libc/runtime/efimain.greg.c +++ b/libc/runtime/efimain.greg.c @@ -63,7 +63,6 @@ static const EFI_GUID kEfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL; */ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { - bool ispml5t; int type, x87cw; struct mman *mm; uint32_t DescVersion; diff --git a/libc/runtime/exit3.c b/libc/runtime/exit3.c index 657a6350..02d0e0ad 100644 --- a/libc/runtime/exit3.c +++ b/libc/runtime/exit3.c @@ -23,6 +23,8 @@ #include "libc/nt/thunk/msabi.h" #include "libc/sysv/consts/nr.h" +extern void(__msabi* __imp_ExitProcess)(uint32_t); + /** * Terminates process, ignoring destructors and atexit() handlers. * @@ -41,10 +43,10 @@ privileged wontreturn void _Exit(int exitcode) { : "a"(__NR_exit_group), "D"(exitcode) : "memory"); } else if (IsWindows()) { - extern void(__msabi * __imp_ExitProcess)(uint32_t); __imp_ExitProcess(exitcode & 0xff); } asm("push\t$0\n\t" + "push\t$0\n\t" "cli\n\t" "lidt\t(%rsp)"); for (;;) asm("ud2"); diff --git a/libc/runtime/runtime.mk b/libc/runtime/runtime.mk index 26a2c5e4..7495f6f2 100644 --- a/libc/runtime/runtime.mk +++ b/libc/runtime/runtime.mk @@ -57,21 +57,22 @@ $(LIBC_RUNTIME_A).pkg: \ $(foreach x,$(LIBC_RUNTIME_A_DIRECTDEPS),$($(x)_A).pkg) o/$(MODE)/libc/runtime/abort-nt.o \ -o/$(MODE)/libc/runtime/assertfail.o \ -o/$(MODE)/libc/runtime/memtrack.o \ -o/$(MODE)/libc/runtime/memtracknt.o \ -o/$(MODE)/libc/runtime/findmemoryinterval.o \ o/$(MODE)/libc/runtime/arememoryintervalsok.o \ -o/$(MODE)/libc/runtime/isheap.o \ +o/$(MODE)/libc/runtime/assertfail.o \ o/$(MODE)/libc/runtime/directmap.o \ o/$(MODE)/libc/runtime/directmapnt.o \ -o/$(MODE)/libc/runtime/stackchkfail.o \ -o/$(MODE)/libc/runtime/stackchkfaillocal.o \ -o/$(MODE)/libc/runtime/hook.greg.o \ -o/$(MODE)/libc/runtime/print.greg.o \ +o/$(MODE)/libc/runtime/findmemoryinterval.o \ o/$(MODE)/libc/runtime/ftrace.greg.o \ o/$(MODE)/libc/runtime/getdosargv.o \ o/$(MODE)/libc/runtime/getdosenviron.o \ +o/$(MODE)/libc/runtime/hook.greg.o \ +o/$(MODE)/libc/runtime/isheap.o \ +o/$(MODE)/libc/runtime/memtrack.o \ +o/$(MODE)/libc/runtime/memtracknt.o \ +o/$(MODE)/libc/runtime/mman.greg.o \ +o/$(MODE)/libc/runtime/print.greg.o \ +o/$(MODE)/libc/runtime/stackchkfail.o \ +o/$(MODE)/libc/runtime/stackchkfaillocal.o \ o/$(MODE)/libc/runtime/winmain.greg.o: \ OVERRIDE_CFLAGS += \ $(NO_MAGIC) diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index dfd37367..de6823dc 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -61,10 +61,6 @@ struct WinArgs { char envblock[ARG_MAX]; }; -static noasan textwindows void SetTrueColor(void) { - SetEnvironmentVariable(u"TERM", u"xterm-truecolor"); -} - static noasan textwindows void MakeLongDoubleLongAgain(void) { /* 8087 FPU Control Word IM: Invalid Operation ───────────────┐ @@ -92,7 +88,6 @@ static noasan textwindows void NormalizeCmdExe(int version) { hstdout = GetStdHandle(pushpop(kNtStdOutputHandle)); hstderr = GetStdHandle(pushpop(kNtStdErrorHandle)); if (GetFileType((handle = hstdin)) == kNtFileTypeChar) { - /* SetTrueColor(); */ SetConsoleCP(kNtCpUtf8); GetConsoleMode(handle, &mode); SetConsoleMode(handle, mode | kNtEnableProcessedInput | @@ -102,7 +97,6 @@ static noasan textwindows void NormalizeCmdExe(int version) { } if (GetFileType((handle = hstdout)) == kNtFileTypeChar || GetFileType((handle = hstderr)) == kNtFileTypeChar) { - /* SetTrueColor(); */ SetConsoleOutputCP(kNtCpUtf8); GetConsoleMode(handle, &mode); SetConsoleMode( @@ -135,7 +129,7 @@ static noasan textwindows wontreturn void WinMainNew(void) { _mmi.p[0].y = (addr >> 16) + ((size >> 16) - 1); _mmi.p[0].prot = PROT_READ | PROT_WRITE | PROT_EXEC; _mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS; - _mmi.i = pushpop(1L); + _mmi.i = 1; wa = (struct WinArgs *)(addr + size - sizeof(struct WinArgs)); count = GetDosArgv(GetCommandLine(), wa->argblock, ARRAYLEN(wa->argblock), wa->argv, ARRAYLEN(wa->argv)); @@ -193,7 +187,7 @@ static noasan textwindows wontreturn void WinMainNew(void) { noasan textwindows int64_t WinMain(int64_t hInstance, int64_t hPrevInstance, const char *lpCmdLine, int nCmdShow) { MakeLongDoubleLongAgain(); - if (weaken(__winsockinit)) weaken(__winsockinit)(); + if (weaken(WinSockInit)) weaken(WinSockInit)(); if (weaken(WinMainForked)) weaken(WinMainForked)(); WinMainNew(); } diff --git a/libc/sock/internal.h b/libc/sock/internal.h index 6d7619dc..d10ea6a8 100644 --- a/libc/sock/internal.h +++ b/libc/sock/internal.h @@ -114,7 +114,7 @@ ssize_t sys_sendto_nt(struct Fd *, const struct iovec *, size_t, uint32_t, ssize_t sys_recvfrom_nt(struct Fd *, const struct iovec *, size_t, uint32_t, void *, uint32_t *) hidden; -void __winsockinit(void) hidden; +void WinSockInit(void) hidden; int64_t __winsockerr(void) nocallback hidden; int __fixupnewsockfd(int, int) hidden; int64_t __winsockblock(int64_t, unsigned, int64_t) hidden; diff --git a/libc/sock/kntwsadata.c b/libc/sock/kntwsadata.c index 5a931f83..4e1f015c 100644 --- a/libc/sock/kntwsadata.c +++ b/libc/sock/kntwsadata.c @@ -33,13 +33,13 @@ */ hidden struct NtWsaData kNtWsaData; -static textwindows void __winsockfini(void) { +static textwindows void WinSockCleanup(void) { WSACleanup(); } -textwindows noasan void __winsockinit(void) { +textwindows noasan void WinSockInit(void) { int rc; - atexit(__winsockfini); + atexit(WinSockCleanup); if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 || kNtWsaData.wVersion != VERSION) { ExitProcess(123); diff --git a/libc/str/endswith.c b/libc/str/endswith.c index fa638f30..2b58edd1 100644 --- a/libc/str/endswith.c +++ b/libc/str/endswith.c @@ -29,5 +29,5 @@ bool endswith(const char *s, const char *suffix) { n = strlen(s); m = strlen(suffix); if (m > n) return false; - return memcmp(s + n - m, suffix, m) == 0; + return !memcmp(s + n - m, suffix, m); } diff --git a/libc/str/str.h b/libc/str/str.h index a3b52a6e..13439414 100644 --- a/libc/str/str.h +++ b/libc/str/str.h @@ -179,17 +179,13 @@ compatfn wchar_t *wmemcpy(wchar_t *, const wchar_t *, size_t) memcpyesque; compatfn wchar_t *wmempcpy(wchar_t *, const wchar_t *, size_t) memcpyesque; compatfn wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t) memcpyesque; int timingsafe_memcmp(const void *, const void *, size_t); +void *tinymemccpy(void *, const void *, int, size_t) memcpyesque; void *memmem(const void *, size_t, const void *, size_t) paramsnonnull() nothrow nocallback nosideeffect; char *strerror(int) returnsnonnull nothrow nocallback; long a64l(const char *); char *l64a(long); -char *tinystrstr(const char *, const char *) strlenesque; -char16_t *tinystrstr16(const char16_t *, const char16_t *) strlenesque; -void *tinymemmem(const void *, size_t, const void *, size_t) strlenesque; -void *tinymemccpy(void *, const void *, int, size_t) memcpyesque; - char *strntolower(char *, size_t); char *strtolower(char *) paramsnonnull(); char *strntoupper(char *, size_t); diff --git a/libc/str/strsep.c b/libc/str/strsep.c index 4a3fda66..bc3b8cee 100644 --- a/libc/str/strsep.c +++ b/libc/str/strsep.c @@ -34,10 +34,12 @@ * @note unlike strtok() this does empty tokens and is re-entrant */ char *strsep(char **str, const char *delim) { - char *token = *str; + size_t i; + char *token, *next; + token = *str; if (token) { - size_t i = strcspn(token, delim); - char *next = NULL; + i = strcspn(token, delim); + next = NULL; if (token[i]) { token[i] = '\0'; next = &token[i + 1]; diff --git a/libc/str/strsignal.c b/libc/str/strsignal.c index a3cb21d8..dbd16f8e 100644 --- a/libc/str/strsignal.c +++ b/libc/str/strsignal.c @@ -37,7 +37,7 @@ static char g_strsignal[4 + 8]; * @see sigaction() */ char *strsignal(int sig) { - if (0 <= sig && (unsigned)sig < ARRAYLEN(kStrSignals)) { + if (0 <= sig && sig < ARRAYLEN(kStrSignals)) { memcpy(g_strsignal, kSig, 4); memcpy(&g_strsignal[3], kStrSignals[sig], 8); } else { diff --git a/libc/str/strstr16.c b/libc/str/strstr16.c index 20ebdaec..53281ca2 100644 --- a/libc/str/strstr16.c +++ b/libc/str/strstr16.c @@ -28,6 +28,15 @@ * @see memmem() */ char16_t *strstr16(const char16_t *haystack, const char16_t *needle) { - return memmem(haystack, strlen16(haystack) * sizeof(char16_t), needle, - strlen16(needle) * sizeof(char16_t)); + size_t i; + for (;;) { + for (i = 0;;) { + if (!needle[i]) return (/*unconst*/ char16_t *)haystack; + if (!haystack[i]) break; + if (needle[i] != haystack[i]) break; + ++i; + } + if (!*haystack++) break; + } + return NULL; } diff --git a/libc/str/tinymemmem.c b/libc/str/tinymemmem.c deleted file mode 100644 index dcc9476b..00000000 --- a/libc/str/tinymemmem.c +++ /dev/null @@ -1,37 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/str/str.h" - -/** - * Naïve substring search implementation. - * @see libc/alg/memmem.c - */ -void *tinymemmem(const void *haystack, size_t haystacksize, const void *needle, - size_t needlesize) { - size_t i; - const char *p, *pe; - for (p = haystack, pe = p + haystacksize; p < pe;) { - for (++p, i = 0;;) { - if (++i > needlesize) return p - 1; - if (p == pe) break; - if (((const char *)needle)[i - 1] != (p - 1)[i - 1]) break; - } - } - return !haystacksize && !needlesize ? haystack : NULL; -} diff --git a/libc/str/tinystrstr16.c b/libc/str/tinystrstr16.c deleted file mode 100644 index a1719568..00000000 --- a/libc/str/tinystrstr16.c +++ /dev/null @@ -1,38 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/str/internal.h" - -/** - * Naïve substring search implementation. - * @see libc/str/strstr.c - * @asyncsignalsafe - */ -char16_t *tinystrstr16(const char16_t *haystack, const char16_t *needle) { - size_t i; - for (;;) { - for (i = 0;;) { - if (!needle[i]) return (/*unconst*/ char16_t *)haystack; - if (!haystack[i]) break; - if (needle[i] != haystack[i]) break; - ++i; - } - if (!*haystack++) break; - } - return NULL; -} diff --git a/libc/tinymath/hypot.c b/libc/tinymath/hypot.c index 5ecaea73..46555c1f 100644 --- a/libc/tinymath/hypot.c +++ b/libc/tinymath/hypot.c @@ -24,7 +24,6 @@ double hypot(double a, double b) { double r, t; if (isinf(a) || isinf(b)) return INFINITY; - if (isunordered(a, b)) return NAN; a = fabs(a); b = fabs(b); if (a < b) t = b, b = a, a = t; diff --git a/libc/tinymath/hypotf.c b/libc/tinymath/hypotf.c index e61869fc..4ddd691b 100644 --- a/libc/tinymath/hypotf.c +++ b/libc/tinymath/hypotf.c @@ -24,7 +24,6 @@ float hypotf(float a, float b) { float r, t; if (isinf(a) || isinf(b)) return INFINITY; - if (isunordered(a, b)) return NAN; a = fabsf(a); b = fabsf(b); if (a < b) t = b, b = a, a = t; diff --git a/libc/tinymath/hypotl.c b/libc/tinymath/hypotl.c index 5a409735..6e418a4f 100644 --- a/libc/tinymath/hypotl.c +++ b/libc/tinymath/hypotl.c @@ -24,7 +24,6 @@ long double hypotl(long double a, long double b) { long double r, t; if (isinf(a) || isinf(b)) return INFINITY; - if (isunordered(a, b)) return NAN; a = fabsl(a); b = fabsl(b); if (a < b) t = b, b = a, a = t; diff --git a/libc/tinymath/log10.S b/libc/tinymath/log10.S index 2fac31f6..40da8088 100644 --- a/libc/tinymath/log10.S +++ b/libc/tinymath/log10.S @@ -23,7 +23,6 @@ // // @param 𝑥 is double scalar in low half of %xmm0 // @return double scalar in low half of %xmm0 -log10: - ezlea log10l,ax +log10: ezlea log10l,ax jmp _d2ld2 .endfn log10,globl diff --git a/libc/tinymath/log2.S b/libc/tinymath/log2.S index 37591c74..00b9fca3 100644 --- a/libc/tinymath/log2.S +++ b/libc/tinymath/log2.S @@ -22,8 +22,7 @@ // // @param 𝑥 is a double passed in the lower quadword of %xmm0 // @return result in lower quadword of %xmm0 -log2: - push %rbp +log2: push %rbp mov %rsp,%rbp .profilable push %rax diff --git a/libc/tinymath/log2f.S b/libc/tinymath/log2f.S index 14c63656..ed26731c 100644 --- a/libc/tinymath/log2f.S +++ b/libc/tinymath/log2f.S @@ -23,8 +23,7 @@ // // @param 𝑥 is a float passed in the lower quarter of %xmm0 // @return result in lower quarter of %xmm0 -log2f: - push %rbp +log2f: push %rbp mov %rsp,%rbp .profilable push %rax diff --git a/test/tool/build/lib/disinst_test.c b/test/tool/build/lib/disinst_test.c index 13e12043..e34dd58e 100644 --- a/test/tool/build/lib/disinst_test.c +++ b/test/tool/build/lib/disinst_test.c @@ -28,26 +28,30 @@ char b1[64]; char b2[64]; struct Dis d[1]; +#define ILD(OP, MODE) \ + do { \ + xed_decoded_inst_zero_set_mode(d->xedd, MODE); \ + ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, OP, sizeof(OP))); \ + d->xedd->op.rde = EncodeRde(d->xedd); \ + } while (0) + TEST(DisInst, testInt3) { uint8_t op[] = {0xcc}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("int3 ", b1); } TEST(DisInst, testImmMem_needsSuffix) { uint8_t op[] = {0x80, 0x3c, 0x07, 0x00}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("cmpb $0,(%rdi,%rax)", b1); } TEST(DisInst, testImmReg_doesntNeedSuffix) { uint8_t op[] = {0xb8, 0x08, 0x70, 0x40, 0x00}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("mov $0x407008,%eax", b1); } @@ -60,56 +64,47 @@ TEST(DisInst, testPuttingOnTheRiz) { {0x8d, 0b00110100, 0b11100101, 0x37, 0x13, 0x03, 0}, {0x8d, 0b10110100, 0b11100101, 0, 0, 0, 0}, }; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[0], sizeof(ops[0]))); + ILD(ops[0], XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("lea (%rsi),%esi", b1); - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[1], sizeof(ops[1]))); + ILD(ops[1], XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("lea (%esi,%eiz,8),%esi", b1); - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[2], sizeof(ops[2]))); + ILD(ops[2], XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("lea 0(%ebp,%eiz,8),%esi", b1); - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[3], sizeof(ops[3]))); + ILD(ops[3], XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("lea 0x31337,%esi", b1); - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[4], sizeof(ops[4]))); + ILD(ops[4], XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("lea 0(%rbp,%riz,8),%esi", b1); } TEST(DisInst, testSibIndexOnly) { uint8_t op[] = {76, 141, 4, 141, 0, 0, 0, 0}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("lea 0(,%rcx,4),%r8", b1); } TEST(DisInst, testRealMode) { uint8_t op[] = {0x89, 0xe5}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("mov %sp,%bp", b1); } TEST(DisInst, testNop) { uint8_t op[] = {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("nopw %cs:0(%rax,%rax)", b1); } TEST(DisInst, testPush) { uint8_t op[] = {0x41, 0x5c}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); EXPECT_EQ(4, ModrmSrm(d->xedd->op.rde)); EXPECT_EQ(1, Rexb(d->xedd->op.rde)); DisInst(d, b1, DisSpec(d->xedd, b2)); @@ -118,108 +113,94 @@ TEST(DisInst, testPush) { TEST(DisInst, testMovb) { uint8_t op[] = {0x8a, 0x1e, 0x0c, 0x32}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("mov (%rsi),%bl", b1); - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("mov 0x320c,%bl", b1); } TEST(DisInst, testLes) { uint8_t op[] = {0xc4, 0x3e, 0x16, 0x32}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("les 0x3216,%di", b1); } TEST(DisInst, testStosbLong) { uint8_t op[] = {0xAA}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("stosb %al,(%rdi)", b1); } TEST(DisInst, testStosbReal) { uint8_t op[] = {0xAA}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("stosb %al,(%di)", b1); } TEST(DisInst, testStosbLegacy) { uint8_t op[] = {0xAA}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LEGACY_32); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LEGACY_32); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("stosb %al,(%edi)", b1); } TEST(DisInst, testStosbLongAsz) { uint8_t op[] = {0x67, 0xAA}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("stosb %al,(%edi)", b1); } TEST(DisInst, testAddLong) { uint8_t op[] = {0x01, 0xff}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("add %edi,%edi", b1); } TEST(DisInst, testAddLegacy) { uint8_t op[] = {0x01, 0xff}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LEGACY_32); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LEGACY_32); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("add %edi,%edi", b1); } TEST(DisInst, testAddReal) { uint8_t op[] = {0x01, 0xff}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("add %di,%di", b1); } TEST(DisInst, testAddLongOsz) { uint8_t op[] = {0x66, 0x01, 0xff}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("add %di,%di", b1); } TEST(DisInst, testAddLegacyOsz) { uint8_t op[] = {0x66, 0x01, 0xff}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LEGACY_32); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LEGACY_32); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("add %di,%di", b1); } TEST(DisInst, testAddRealOsz) { uint8_t op[] = {0x66, 0x01, 0xff}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("add %edi,%edi", b1); } TEST(DisInst, testFxam) { uint8_t op[] = {0xd9, 0xe5}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); ASSERT_EQ(4, ModrmReg(d->xedd->op.rde)); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("fxam ", b1); @@ -227,64 +208,56 @@ TEST(DisInst, testFxam) { TEST(DisInst, testOrImmCode16gcc) { uint8_t op[] = {0x67, 0x81, 0x4c, 0x24, 0x0c, 0x00, 0x0c}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("orw $0xc00,12(%esp)", b1); } TEST(DisInst, testPause) { uint8_t op[] = {0xf3, 0x90}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("pause ", b1); } TEST(DisInst, testJmpEw) { uint8_t op[] = {0xff, 0xe0}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("jmp %ax", b1); } TEST(DisInst, testJmpEv16) { uint8_t op[] = {0x66, 0xff, 0xe0}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("jmp %eax", b1); } TEST(DisInst, testJmpEv32) { uint8_t op[] = {0xff, 0xe0}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LEGACY_32); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LEGACY_32); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("jmp %eax", b1); } TEST(DisInst, testJmpEq) { uint8_t op[] = {0x66, 0xff, 0xe0}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_LONG_64); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("jmp %rax", b1); } TEST(DisInst, testMovswSs) { uint8_t op[] = {0x36, 0xA5}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("movs %ss:(%si),(%di)", b1); } TEST(DisInst, testRealModrm_sibOverlap_showsNoDisplacement) { uint8_t op[] = {0x8b, 0b00100101}; - xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL); - ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op))); + ILD(op, XED_MACHINE_MODE_REAL); DisInst(d, b1, DisSpec(d->xedd, b2)); EXPECT_STREQ("mov (%di),%sp", b1); } diff --git a/test/tool/build/lib/modrm_test.c b/test/tool/build/lib/modrm_test.c index 54bda49e..17de47ab 100644 --- a/test/tool/build/lib/modrm_test.c +++ b/test/tool/build/lib/modrm_test.c @@ -24,6 +24,13 @@ #include "tool/build/lib/machine.h" #include "tool/build/lib/modrm.h" +#define ILD(XEDD, OP, MODE) \ + do { \ + xed_decoded_inst_zero_set_mode(XEDD, MODE); \ + ASSERT_EQ(0, xed_instruction_length_decode(XEDD, OP, sizeof(OP))); \ + XEDD->op.rde = EncodeRde(XEDD); \ + } while (0) + TEST(modrm, testAddressSizeOverride_isNotPresent_keepsWholeExpression) { struct Machine *m = gc(NewMachine()); struct XedDecodedInst *xedd = gc(calloc(1, sizeof(struct XedDecodedInst))); @@ -31,8 +38,7 @@ TEST(modrm, testAddressSizeOverride_isNotPresent_keepsWholeExpression) { m->xedd = xedd; Write64(m->bx, 0x2); Write64(m->ax, 0xffffffff); - xed_decoded_inst_zero_set_mode(xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(xedd, op, sizeof(op))); + ILD(xedd, op, XED_MACHINE_MODE_LONG_64); EXPECT_EQ(0x100000001, ComputeAddress(m, m->xedd->op.rde)); } @@ -43,8 +49,7 @@ TEST(modrm, testAddressSizeOverride_isPresent_modulesWholeExpression) { m->xedd = xedd; Write64(m->bx, 0x2); Write64(m->ax, 0xffffffff); - xed_decoded_inst_zero_set_mode(xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(xedd, op, sizeof(op))); + ILD(xedd, op, XED_MACHINE_MODE_LONG_64); EXPECT_EQ(0x000000001, ComputeAddress(m, m->xedd->op.rde)); } @@ -55,8 +60,7 @@ TEST(modrm, testOverflow_doesntTriggerTooling) { m->xedd = xedd; Write64(m->bx, 0x0000000000000001); Write64(m->ax, 0x7fffffffffffffff); - xed_decoded_inst_zero_set_mode(xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(xedd, op, sizeof(op))); + ILD(xedd, op, XED_MACHINE_MODE_LONG_64); EXPECT_EQ(0x8000000000000000ull, (uint64_t)ComputeAddress(m, m->xedd->op.rde)); } @@ -72,17 +76,13 @@ TEST(modrm, testPuttingOnTheRiz) { m->xedd = gc(calloc(1, sizeof(struct XedDecodedInst))); Write64(m->si, 0x100000001); Write64(m->bp, 0x200000002); - xed_decoded_inst_zero_set_mode(m->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(m->xedd, ops[0], sizeof(ops[0]))); + ILD(m->xedd, ops[0], XED_MACHINE_MODE_LONG_64); EXPECT_EQ(0x100000001, ComputeAddress(m, m->xedd->op.rde)); - xed_decoded_inst_zero_set_mode(m->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(m->xedd, ops[1], sizeof(ops[1]))); + ILD(m->xedd, ops[1], XED_MACHINE_MODE_LONG_64); EXPECT_EQ(0x000000001, ComputeAddress(m, m->xedd->op.rde)); - xed_decoded_inst_zero_set_mode(m->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(m->xedd, ops[2], sizeof(ops[2]))); + ILD(m->xedd, ops[2], XED_MACHINE_MODE_LONG_64); EXPECT_EQ(0x31339, ComputeAddress(m, m->xedd->op.rde)); - xed_decoded_inst_zero_set_mode(m->xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(m->xedd, ops[3], sizeof(ops[3]))); + ILD(m->xedd, ops[3], XED_MACHINE_MODE_LONG_64); EXPECT_EQ(0x31337, ComputeAddress(m, m->xedd->op.rde)); } @@ -100,8 +100,7 @@ TEST(modrm, testSibIndexOnly) { m->xedd = xedd; Write64(m->bp, 0x123); Write64(m->cx, 0x123); - xed_decoded_inst_zero_set_mode(xedd, XED_MACHINE_MODE_LONG_64); - ASSERT_EQ(0, xed_instruction_length_decode(xedd, op, sizeof(op))); + ILD(xedd, op, XED_MACHINE_MODE_LONG_64); EXPECT_TRUE(Rexw(m->xedd->op.rde)); EXPECT_TRUE(Rexr(m->xedd->op.rde)); EXPECT_FALSE(Rexb(m->xedd->op.rde)); diff --git a/libc/str/tinystrstr.c b/third_party/xed/eamode.c similarity index 78% rename from libc/str/tinystrstr.c rename to third_party/xed/eamode.c index 86a53d3e..52806ab3 100644 --- a/libc/str/tinystrstr.c +++ b/third_party/xed/eamode.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ 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 │ @@ -16,23 +16,13 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/str/internal.h" +#include "third_party/xed/x86.h" -/** - * Naïve substring search implementation. - * @see libc/str/strstr.c - * @asyncsignalsafe - */ -char *tinystrstr(const char *haystack, const char *needle) { - size_t i; - for (;;) { - for (i = 0;;) { - if (!needle[i]) return (/*unconst*/ char *)haystack; - if (!haystack[i]) break; - if (needle[i] != haystack[i]) break; - ++i; - } - if (!*haystack++) break; - } - return NULL; -} +const uint8_t kXedEamode[2][3] = { + [0][XED_MODE_REAL] = XED_MODE_REAL, + [0][XED_MODE_LEGACY] = XED_MODE_LEGACY, + [0][XED_MODE_LONG] = XED_MODE_LONG, + [1][XED_MODE_REAL] = XED_MODE_LEGACY, + [1][XED_MODE_LEGACY] = XED_MODE_REAL, + [1][XED_MODE_LONG] = XED_MODE_LEGACY, +}; diff --git a/third_party/xed/x86.h b/third_party/xed/x86.h index 8e1835d9..d60e05c7 100644 --- a/third_party/xed/x86.h +++ b/third_party/xed/x86.h @@ -487,7 +487,8 @@ forceinline void xed_set_chip_modes(struct XedDecodedInst *d, } extern const char kXedErrorNames[]; -extern const uint64_t xed_chip_features[XED_CHIP_LAST][3]; +extern const uint64_t kXedChipFeatures[XED_CHIP_LAST][3]; +extern const uint8_t kXedEamode[2][3]; struct XedDecodedInst *xed_decoded_inst_zero_set_mode(struct XedDecodedInst *, enum XedMachineMode); diff --git a/third_party/xed/x86features.c b/third_party/xed/x86features.c index bd9d1c0d..ef0ac4f2 100644 --- a/third_party/xed/x86features.c +++ b/third_party/xed/x86features.c @@ -36,8 +36,7 @@ asm(".include \"libc/disclaimer.inc\""); * example, 0x2800000ul was calculated as: 1UL<<(XED_ISA_SET_I86-64) | * 1UL<<(XED_ISA_SET_LAHF-64). */ -const uint64_t xed_chip_features[XED_CHIP_LAST][3] /* clang-format off */ -_Section(".text") = { +const uint64_t kXedChipFeatures[XED_CHIP_LAST][3] /* clang-format off */ = { {0, 0, 0, }, {0, 0x02800000, 0, }, /*I86*/ {0, 0x02800000, 0x02000}, /*I86FP*/ diff --git a/third_party/xed/x86ild.greg.c b/third_party/xed/x86ild.greg.c index 83154868..be3fada1 100644 --- a/third_party/xed/x86ild.greg.c +++ b/third_party/xed/x86ild.greg.c @@ -111,7 +111,6 @@ extern const uint8_t xed_disp_bits_2d[XED_ILD_MAP2][256] hidden; static const struct XedDenseMagnums { unsigned vex_prefix_recoding[4]; - xed_bits_t eamode[2][3]; xed_bits_t BRDISPz_BRDISP_WIDTH[4]; xed_bits_t MEMDISPv_DISP_WIDTH[4]; xed_bits_t SIMMz_IMM_WIDTH[4]; @@ -136,186 +135,177 @@ static const struct XedDenseMagnums { .UIMMv_IMM_WIDTH = {0x00, 0x10, 0x20, 0x40}, .ASZ_NONTERM_EASZ = { - [0][0] = 0x1, - [1][0] = 0x2, - [0][1] = 0x2, - [1][1] = 0x1, - [0][2] = 0x3, - [1][2] = 0x2, + [0][0] = 1, + [1][0] = 2, + [0][1] = 2, + [1][1] = 1, + [0][2] = 3, + [1][2] = 2, }, .OSZ_NONTERM_CR_WIDTH_EOSZ = { - [0][0][0] = 0x2, - [1][0][0] = 0x2, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x2, - [1][1][1] = 0x2, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x3, - [0][0][2] = 0x3, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 2, + [1][0][0] = 2, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 2, + [1][1][1] = 2, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 3, + [0][0][2] = 3, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_DF64_EOSZ = { - [0][0][0] = 0x1, - [1][0][0] = 0x1, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x1, - [1][1][1] = 0x1, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x1, - [0][0][2] = 0x3, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 1, + [1][0][0] = 1, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 1, + [1][1][1] = 1, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 1, + [0][0][2] = 3, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_DF64_FORCE64_EOSZ = { - [0][0][0] = 0x1, - [1][0][0] = 0x1, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x1, - [1][1][1] = 0x1, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x3, - [0][0][2] = 0x3, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 1, + [1][0][0] = 1, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 1, + [1][1][1] = 1, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 3, + [0][0][2] = 3, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_DF64_IMMUNE66_LOOP64_EOSZ = { - [0][0][0] = 0x1, - [1][0][0] = 0x1, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x1, - [1][1][1] = 0x1, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x3, - [0][0][2] = 0x3, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 1, + [1][0][0] = 1, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 1, + [1][1][1] = 1, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 3, + [0][0][2] = 3, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_EOSZ = { - [0][0][0] = 0x1, - [1][0][0] = 0x1, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x1, - [1][1][1] = 0x1, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x1, - [0][0][2] = 0x2, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 1, + [1][0][0] = 1, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 1, + [1][1][1] = 1, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 1, + [0][0][2] = 2, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_FORCE64_EOSZ = { - [0][0][0] = 0x1, - [1][0][0] = 0x1, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x1, - [1][1][1] = 0x1, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x3, - [0][0][2] = 0x3, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 1, + [1][0][0] = 1, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 1, + [1][1][1] = 1, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 3, + [0][0][2] = 3, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_IGNORE66_EOSZ = { - [0][0][0] = 0x1, - [1][0][0] = 0x1, - [0][1][0] = 0x1, - [1][1][0] = 0x1, - [0][1][1] = 0x2, - [1][1][1] = 0x2, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x2, - [0][0][2] = 0x2, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 1, + [1][0][0] = 1, + [0][1][0] = 1, + [1][1][0] = 1, + [0][1][1] = 2, + [1][1][1] = 2, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 2, + [0][0][2] = 2, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_IMMUNE66_EOSZ = { - [0][0][0] = 0x2, - [1][0][0] = 0x2, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x2, - [1][1][1] = 0x2, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x2, - [0][0][2] = 0x2, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 2, + [1][0][0] = 2, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 2, + [1][1][1] = 2, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 2, + [0][0][2] = 2, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_IMMUNE_REXW_EOSZ = { - [0][0][0] = 0x1, - [1][0][0] = 0x1, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x1, - [1][1][1] = 0x1, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x1, - [0][0][2] = 0x2, - [1][1][2] = 0x2, - [1][0][2] = 0x2, + [0][0][0] = 1, + [1][0][0] = 1, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 1, + [1][1][1] = 1, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 1, + [0][0][2] = 2, + [1][1][2] = 2, + [1][0][2] = 2, }, .OSZ_NONTERM_REFINING66_CR_WIDTH_EOSZ = { - [0][0][0] = 0x2, - [1][0][0] = 0x2, - [0][1][0] = 0x2, - [1][1][0] = 0x2, - [0][1][1] = 0x2, - [1][1][1] = 0x2, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x3, - [0][0][2] = 0x3, - [1][1][2] = 0x3, - [1][0][2] = 0x3, + [0][0][0] = 2, + [1][0][0] = 2, + [0][1][0] = 2, + [1][1][0] = 2, + [0][1][1] = 2, + [1][1][1] = 2, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 3, + [0][0][2] = 3, + [1][1][2] = 3, + [1][0][2] = 3, }, .OSZ_NONTERM_REFINING66_EOSZ = { - [0][0][0] = 0x1, - [1][0][0] = 0x1, - [0][1][0] = 0x1, - [1][1][0] = 0x1, - [0][1][1] = 0x2, - [1][1][1] = 0x2, - [0][0][1] = 0x2, - [1][0][1] = 0x2, - [0][1][2] = 0x2, - [0][0][2] = 0x2, - [1][1][2] = 0x3, - [1][0][2] = 0x3, - }, - .eamode = - { - [0][XED_MODE_REAL] = XED_MODE_REAL, - [0][XED_MODE_LEGACY] = XED_MODE_LEGACY, - [0][XED_MODE_LONG] = XED_MODE_LONG, - [1][XED_MODE_REAL] = XED_MODE_LEGACY, - [1][XED_MODE_LEGACY] = XED_MODE_REAL, - [1][XED_MODE_LONG] = XED_MODE_LEGACY, + [0][0][0] = 1, + [1][0][0] = 1, + [0][1][0] = 1, + [1][1][0] = 1, + [0][1][1] = 2, + [1][1][1] = 2, + [0][0][1] = 2, + [1][0][1] = 2, + [0][1][2] = 2, + [0][0][2] = 2, + [1][1][2] = 3, + [1][0][2] = 3, }, }; @@ -633,7 +623,6 @@ privileged static void xed_get_next_as_opcode(struct XedDecodedInst *d) { b = d->bytes[length]; d->op.opcode = b; d->length++; - /* d->op.srm = xed_modrm_rm(b); */ } else { xed_too_short(d); } @@ -722,7 +711,6 @@ privileged static void xed_opcode_scanner(struct XedDecodedInst *d) { return; } } - /* d->op.srm = xed_modrm_rm(d->op.opcode); */ } privileged static bool xed_is_bound_instruction(struct XedDecodedInst *d) { @@ -974,7 +962,7 @@ privileged static void xed_modrm_scanner(struct XedDecodedInst *d) { if (has_modrm != XED_ILD_HASMODRM_IGNORE_MOD) { asz = d->op.asz; mode = d->op.mode; - eamode = kXed.eamode[asz][mode]; + eamode = kXedEamode[asz][mode]; d->op.disp_width = xed_bytes2bits(xed_has_disp_regular[eamode][mod][rm]); d->op.has_sib = xed_has_sib_table[eamode][mod][rm]; @@ -1123,18 +1111,6 @@ privileged static void xed_decode_instruction_length( } } -privileged static void xed_encode_rde(struct XedDecodedInst *x) { - const uint8_t kWordLog2[2][2][2] = {{{2, 3}, {1, 3}}, {{0, 0}, {0, 0}}}; - uint32_t osz = x->op.osz ^ x->op.realmode; - x->op.rde = kWordLog2[~x->op.opcode & 1][osz][x->op.rexw] << 28 | - x->op.mode << 26 | kXed.eamode[x->op.asz][x->op.mode] << 24 | - x->op.rep << 30 | x->op.mod << 22 | x->op.asz << 17 | - x->op.seg_ovd << 18 | x->op.rexw << 6 | osz << 5 | - (x->op.rex << 4 | x->op.rexb << 3 | x->op.srm) << 12 | - (x->op.rex << 4 | x->op.rexb << 3 | x->op.rm) << 7 | - (x->op.rex << 4 | x->op.rexr << 3 | x->op.reg); -} - /** * Clears instruction decoder state. */ @@ -1160,7 +1136,6 @@ privileged enum XedError xed_instruction_length_decode( __builtin_memcpy(xedd->bytes, itext, MIN(15, bytes)); xedd->op.max_bytes = MIN(15, bytes); xed_decode_instruction_length(xedd); - xed_encode_rde(xedd); if (!xedd->op.out_of_bytes) { if (xedd->op.map != XED_ILD_MAP_INVALID) { return xedd->op.error; diff --git a/third_party/xed/x86isa.c b/third_party/xed/x86isa.c index cf23a242..b9106e28 100644 --- a/third_party/xed/x86isa.c +++ b/third_party/xed/x86isa.c @@ -29,7 +29,7 @@ bool xed_isa_set_is_valid_for_chip(enum XedIsaSet isa_set, enum XedChip chip) { unsigned n, r; n = isa_set / 64; r = isa_set - (64 * n); - return !!(xed_chip_features[chip][n] & (1ul << r)); + return !!(kXedChipFeatures[chip][n] & (1ul << r)); } bool xed_test_chip_features(struct XedChipFeatures *p, enum XedIsaSet isa_set) { @@ -42,9 +42,9 @@ bool xed_test_chip_features(struct XedChipFeatures *p, enum XedIsaSet isa_set) { void xed_get_chip_features(struct XedChipFeatures *p, enum XedChip chip) { if (p) { if (chip < XED_CHIP_LAST) { - p->f[0] = xed_chip_features[chip][0]; - p->f[1] = xed_chip_features[chip][1]; - p->f[2] = xed_chip_features[chip][2]; + p->f[0] = kXedChipFeatures[chip][0]; + p->f[1] = kXedChipFeatures[chip][1]; + p->f[2] = kXedChipFeatures[chip][2]; } else { p->f[0] = 0; p->f[1] = 0; diff --git a/tool/build/lib/dis.c b/tool/build/lib/dis.c index 47153477..aaca950e 100644 --- a/tool/build/lib/dis.c +++ b/tool/build/lib/dis.c @@ -219,6 +219,7 @@ static long DisAppendOpLines(struct Dis *d, struct Machine *m, int64_t addr) { } xed_decoded_inst_zero_set_mode(d->xedd, m->mode); xed_instruction_length_decode(d->xedd, p, n); + d->xedd->op.rde = EncodeRde(d->xedd); n = d->xedd->op.error ? 1 : d->xedd->length; op.addr = addr; op.size = n; @@ -255,6 +256,7 @@ const char *DisGetLine(struct Dis *d, struct Machine *m, size_t i) { xed_instruction_length_decode( d->xedd, AccessRam(m, d->ops.p[i].addr, d->ops.p[i].size, r, b, true), d->ops.p[i].size); + d->xedd->op.rde = EncodeRde(d->xedd); d->m = m; d->addr = d->ops.p[i].addr; CHECK_LT(DisLineCode(d, d->buf) - d->buf, sizeof(d->buf)); diff --git a/tool/build/lib/instruction.c b/tool/build/lib/instruction.c index 08200cf6..59f09594 100644 --- a/tool/build/lib/instruction.c +++ b/tool/build/lib/instruction.c @@ -24,6 +24,7 @@ #include "tool/build/lib/endian.h" #include "tool/build/lib/machine.h" #include "tool/build/lib/memory.h" +#include "tool/build/lib/modrm.h" #include "tool/build/lib/stats.h" #include "tool/build/lib/throw.h" @@ -45,6 +46,7 @@ static void DecodeInstruction(struct Machine *m, uint8_t *p, unsigned n) { struct XedDecodedInst xedd[1]; xed_decoded_inst_zero_set_mode(xedd, m->mode); if (!xed_instruction_length_decode(xedd, p, n)) { + xedd->op.rde = EncodeRde(xedd); memcpy(m->xedd, xedd, sizeof(m->icache[0])); } else { HaltMachine(m, kMachineDecodeError); diff --git a/tool/build/lib/modrm.c b/tool/build/lib/modrm.c index 03dbf5bb..99d2b3f6 100644 --- a/tool/build/lib/modrm.c +++ b/tool/build/lib/modrm.c @@ -25,6 +25,21 @@ #include "tool/build/lib/modrm.h" #include "tool/build/lib/throw.h" +/** + * Compactly represents important parts of xed ild result. + */ +uint32_t EncodeRde(struct XedDecodedInst *x) { + uint8_t kWordLog2[2][2][2] = {{{2, 3}, {1, 3}}, {{0, 0}, {0, 0}}}; + uint32_t osz = x->op.osz ^ x->op.realmode; + return kWordLog2[~x->op.opcode & 1][osz][x->op.rexw] << 28 | + x->op.mode << 26 | kXedEamode[x->op.asz][x->op.mode] << 24 | + x->op.rep << 30 | x->op.mod << 22 | x->op.asz << 17 | + x->op.seg_ovd << 18 | x->op.rexw << 6 | osz << 5 | + (x->op.rex << 4 | x->op.rexb << 3 | x->op.srm) << 12 | + (x->op.rex << 4 | x->op.rexb << 3 | x->op.rm) << 7 | + (x->op.rex << 4 | x->op.rexr << 3 | x->op.reg); +} + struct AddrSeg LoadEffectiveAddress(const struct Machine *m, uint32_t rde) { uint8_t *s = m->ds; uint64_t i = m->xedd->op.disp; diff --git a/tool/build/lib/modrm.h b/tool/build/lib/modrm.h index acc3d20b..87d62811 100644 --- a/tool/build/lib/modrm.h +++ b/tool/build/lib/modrm.h @@ -57,6 +57,7 @@ struct AddrSeg { extern const uint8_t kByteReg[32]; +uint32_t EncodeRde(struct XedDecodedInst *); int64_t ComputeAddress(const struct Machine *, uint32_t); struct AddrSeg LoadEffectiveAddress(const struct Machine *, uint32_t); void *ComputeReserveAddressRead(struct Machine *, uint32_t, size_t);