Perform some code cleanup

This commit is contained in:
Justine Tunney 2021-02-27 10:33:32 -08:00
parent 3e17c7b20f
commit 19d0c15e03
41 changed files with 321 additions and 459 deletions

3
.vscode/vscode.h vendored
View file

@ -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

14
NOTICE
View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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");

View file

@ -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)

View file

@ -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();
}

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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];

View file

@ -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 {

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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));

View file

@ -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,
};

View file

@ -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);

View file

@ -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*/

View file

@ -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;

View file

@ -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;

View file

@ -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));

View file

@ -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);

View file

@ -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;

View file

@ -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);