mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Perform some code cleanup
This commit is contained in:
parent
3e17c7b20f
commit
19d0c15e03
41 changed files with 321 additions and 459 deletions
3
.vscode/vscode.h
vendored
3
.vscode/vscode.h
vendored
|
@ -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
14
NOTICE
|
@ -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.
|
|
@ -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
|
||||
|
|
13
ape/ape.lds
13
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
30
libc/str/tinystrstr.c → third_party/xed/eamode.c
vendored
30
libc/str/tinystrstr.c → third_party/xed/eamode.c
vendored
|
@ -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,
|
||||
};
|
3
third_party/xed/x86.h
vendored
3
third_party/xed/x86.h
vendored
|
@ -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);
|
||||
|
|
3
third_party/xed/x86features.c
vendored
3
third_party/xed/x86features.c
vendored
|
@ -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*/
|
||||
|
|
303
third_party/xed/x86ild.greg.c
vendored
303
third_party/xed/x86ild.greg.c
vendored
|
@ -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;
|
||||
|
|
8
third_party/xed/x86isa.c
vendored
8
third_party/xed/x86isa.c
vendored
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue