mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-04-21 14:24:43 +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 offsetof(x, y) 0
|
||||||
#define INITIALIZER(...) struct _dummy
|
#define INITIALIZER(...) struct _dummy
|
||||||
#define __far
|
#define __far
|
||||||
#define tinystrstr(...) 0
|
#define BENCHLOOP(...) 0
|
||||||
#define BENCHLOOP(...) 0
|
|
||||||
|
|
||||||
#ifdef __hook
|
#ifdef __hook
|
||||||
#undef __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/runtime/pc.internal.h"
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
|
|
||||||
#define USE_SYMBOL_HACK 0
|
#define USE_SYMBOL_HACK 1
|
||||||
|
|
||||||
.section .text,"ax",@progbits
|
.section .text,"ax",@progbits
|
||||||
.align __SIZEOF_POINTER__
|
.align __SIZEOF_POINTER__
|
||||||
|
@ -1486,12 +1486,6 @@ ape_pad_text:
|
||||||
ape_pad_privileged:
|
ape_pad_privileged:
|
||||||
.previous
|
.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
|
.section .ape.pad.rodata,"a",@progbits
|
||||||
.type ape_pad_rodata,@object
|
.type ape_pad_rodata,@object
|
||||||
.hidden ape_pad_rodata
|
.hidden ape_pad_rodata
|
||||||
|
|
11
ape/ape.lds
11
ape/ape.lds
|
@ -238,9 +238,8 @@ SECTIONS {
|
||||||
/* Code that needs to be addressable in Real Mode */
|
/* Code that needs to be addressable in Real Mode */
|
||||||
*(.text.real)
|
*(.text.real)
|
||||||
KEEP(*(SORT_BY_NAME(.sort.text.real.*)))
|
KEEP(*(SORT_BY_NAME(.sort.text.real.*)))
|
||||||
/**(.rodata.real)
|
|
||||||
KEEP(*(SORT_BY_NAME(.sort.rodata.real.*)))*/
|
|
||||||
HIDDEN(_ereal = .);
|
HIDDEN(_ereal = .);
|
||||||
|
. += 1;
|
||||||
|
|
||||||
/*END: realmode addressability guarantee */
|
/*END: realmode addressability guarantee */
|
||||||
|
|
||||||
|
@ -273,16 +272,17 @@ SECTIONS {
|
||||||
KEEP(*(SORT_BY_NAME(.sort.text.*)))
|
KEEP(*(SORT_BY_NAME(.sort.text.*)))
|
||||||
|
|
||||||
KEEP(*(.ape.pad.test));
|
KEEP(*(.ape.pad.test));
|
||||||
HIDDEN(__test_start = .);
|
|
||||||
*(.test.unlikely)
|
*(.test.unlikely)
|
||||||
*(.test .test.*)
|
*(.test .test.*)
|
||||||
|
|
||||||
/* Privileged code invulnerable to magic */
|
/* Privileged code invulnerable to magic */
|
||||||
KEEP(*(.ape.pad.privileged));
|
KEEP(*(.ape.pad.privileged));
|
||||||
|
. += . > 0 ? 1 : 0;
|
||||||
HIDDEN(__privileged_start = .);
|
HIDDEN(__privileged_start = .);
|
||||||
HIDDEN(__test_end = .);
|
. += . > 0 ? 1 : 0;
|
||||||
*(.privileged)
|
*(.privileged)
|
||||||
HIDDEN(__privileged_end = .);
|
HIDDEN(__privileged_end = .);
|
||||||
|
. += . > 0 ? 1 : 0;
|
||||||
|
|
||||||
/*BEGIN: Read Only Data */
|
/*BEGIN: Read Only Data */
|
||||||
|
|
||||||
|
@ -369,6 +369,7 @@ SECTIONS {
|
||||||
*(.piro.bss)
|
*(.piro.bss)
|
||||||
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
||||||
HIDDEN(__piro_end = .);
|
HIDDEN(__piro_end = .);
|
||||||
|
. += . > 0 ? 1 : 0;
|
||||||
/*END: Post-Initialization Read-Only */
|
/*END: Post-Initialization Read-Only */
|
||||||
|
|
||||||
/* Statically Allocated Empty Space */
|
/* Statically Allocated Empty Space */
|
||||||
|
@ -378,7 +379,7 @@ SECTIONS {
|
||||||
|
|
||||||
KEEP(*(SORT_BY_NAME(.sort.bss.*)))
|
KEEP(*(SORT_BY_NAME(.sort.bss.*)))
|
||||||
|
|
||||||
. = ALIGN(0x10000); /* for brk()/sbrk() allocation */
|
. = ALIGN(FRAMESIZE); /* for brk()/sbrk() allocation */
|
||||||
HIDDEN(_end = .);
|
HIDDEN(_end = .);
|
||||||
PROVIDE_HIDDEN(end = .);
|
PROVIDE_HIDDEN(end = .);
|
||||||
} :Ram
|
} :Ram
|
||||||
|
|
|
@ -130,7 +130,7 @@ endif
|
||||||
|
|
||||||
# Linux-Only Tiny Mode
|
# Linux-Only Tiny Mode
|
||||||
#
|
#
|
||||||
# - `make MODE=tiny`
|
# - `make MODE=tinylinux`
|
||||||
# - No checks
|
# - No checks
|
||||||
# - No asserts
|
# - No asserts
|
||||||
# - No canaries
|
# - No canaries
|
||||||
|
@ -158,7 +158,7 @@ endif
|
||||||
|
|
||||||
# Linux+BSD Tiny Mode
|
# Linux+BSD Tiny Mode
|
||||||
#
|
#
|
||||||
# - `make MODE=tiny`
|
# - `make MODE=tinylinuxbsd`
|
||||||
# - No apple
|
# - No apple
|
||||||
# - No checks
|
# - No checks
|
||||||
# - No asserts
|
# - No asserts
|
||||||
|
@ -187,7 +187,7 @@ endif
|
||||||
|
|
||||||
# Unix Tiny Mode
|
# Unix Tiny Mode
|
||||||
#
|
#
|
||||||
# - `make MODE=tiny`
|
# - `make MODE=tinysysv`
|
||||||
# - No checks
|
# - No checks
|
||||||
# - No asserts
|
# - No asserts
|
||||||
# - No canaries
|
# - No canaries
|
||||||
|
@ -215,7 +215,7 @@ endif
|
||||||
|
|
||||||
# Tiny Metallic Unix Mode
|
# Tiny Metallic Unix Mode
|
||||||
#
|
#
|
||||||
# - `make MODE=tiny`
|
# - `make MODE=tinynowin`
|
||||||
# - No checks
|
# - No checks
|
||||||
# - No asserts
|
# - No asserts
|
||||||
# - No canaries
|
# - No canaries
|
||||||
|
|
|
@ -68,7 +68,10 @@ o/$(MODE)/libc/calls/siggy.o: \
|
||||||
OVERRIDE_COPTS += \
|
OVERRIDE_COPTS += \
|
||||||
-ffunction-sections
|
-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: \
|
o/$(MODE)/libc/calls/ntcontext2linux.o: \
|
||||||
OVERRIDE_COPTS += \
|
OVERRIDE_COPTS += \
|
||||||
-O3
|
-O3
|
||||||
|
|
|
@ -43,21 +43,21 @@ struct siginfo_freebsd {
|
||||||
union sigval_freebsd si_value;
|
union sigval_freebsd si_value;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
int _trapno;
|
int32_t _trapno;
|
||||||
} _fault;
|
} _fault;
|
||||||
struct {
|
struct {
|
||||||
int _timerid;
|
int32_t _timerid;
|
||||||
int _overrun;
|
int32_t _overrun;
|
||||||
} _timer;
|
} _timer;
|
||||||
struct {
|
struct {
|
||||||
int _mqd;
|
int32_t _mqd;
|
||||||
} _mesgq;
|
} _mesgq;
|
||||||
struct {
|
struct {
|
||||||
long _band;
|
int64_t _band;
|
||||||
} _poll;
|
} _poll;
|
||||||
struct {
|
struct {
|
||||||
long __spare1__;
|
int64_t __spare1__;
|
||||||
int __spare2__[7];
|
int32_t __spare2__[7];
|
||||||
} __spare__;
|
} __spare__;
|
||||||
} _reason;
|
} _reason;
|
||||||
};
|
};
|
||||||
|
@ -106,7 +106,7 @@ struct mcontext_freebsd {
|
||||||
int64_t mc_gsbase;
|
int64_t mc_gsbase;
|
||||||
int64_t mc_xfpustate;
|
int64_t mc_xfpustate;
|
||||||
int64_t mc_xfpustate_len;
|
int64_t mc_xfpustate_len;
|
||||||
long mc_spare[4];
|
int64_t mc_spare[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ucontext_freebsd {
|
struct ucontext_freebsd {
|
||||||
|
@ -118,8 +118,8 @@ struct ucontext_freebsd {
|
||||||
int32_t __spare__[4];
|
int32_t __spare__[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
hidden void __sigenter_freebsd(int sig, struct siginfo_freebsd *si,
|
void __sigenter_freebsd(int sig, struct siginfo_freebsd *si,
|
||||||
struct ucontext_freebsd *ctx) {
|
struct ucontext_freebsd *ctx) {
|
||||||
int rva;
|
int rva;
|
||||||
ucontext_t uc;
|
ucontext_t uc;
|
||||||
rva = __sighandrvas[sig & (NSIG - 1)];
|
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;
|
uc.uc_flags = ctx->uc_flags;
|
||||||
memcpy(&uc.uc_sigmask, &ctx->uc_sigmask,
|
memcpy(&uc.uc_sigmask, &ctx->uc_sigmask,
|
||||||
MIN(sizeof(uc.uc_sigmask), sizeof(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.r8 = ctx->uc_mcontext.mc_r8;
|
||||||
uc.uc_mcontext.r9 = ctx->uc_mcontext.mc_r9;
|
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.r10 = ctx->uc_mcontext.mc_r10;
|
||||||
uc.uc_mcontext.r11 = ctx->uc_mcontext.mc_r11;
|
uc.uc_mcontext.r11 = ctx->uc_mcontext.mc_r11;
|
||||||
uc.uc_mcontext.r12 = ctx->uc_mcontext.mc_r12;
|
uc.uc_mcontext.r12 = ctx->uc_mcontext.mc_r12;
|
||||||
uc.uc_mcontext.r13 = ctx->uc_mcontext.mc_r13;
|
uc.uc_mcontext.r13 = ctx->uc_mcontext.mc_r13;
|
||||||
uc.uc_mcontext.r14 = ctx->uc_mcontext.mc_r14;
|
uc.uc_mcontext.r14 = ctx->uc_mcontext.mc_r14;
|
||||||
uc.uc_mcontext.r15 = ctx->uc_mcontext.mc_r15;
|
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.fs = ctx->uc_mcontext.mc_fs;
|
||||||
uc.uc_mcontext.gs = ctx->uc_mcontext.mc_gs;
|
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.err = ctx->uc_mcontext.mc_err;
|
||||||
uc.uc_mcontext.rip = ctx->uc_mcontext.mc_rip;
|
uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno;
|
||||||
uc.uc_mcontext.rsp = ctx->uc_mcontext.mc_rsp;
|
|
||||||
}
|
}
|
||||||
((sigaction_f)(_base + rva))(sig, (void *)si, &uc);
|
((sigaction_f)(_base + rva))(sig, (void *)si, &uc);
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
|
|
|
@ -125,8 +125,8 @@ struct ucontext_netbsd {
|
||||||
struct mcontext_netbsd uc_mcontext;
|
struct mcontext_netbsd uc_mcontext;
|
||||||
};
|
};
|
||||||
|
|
||||||
hidden void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
||||||
struct ucontext_netbsd *ctx) {
|
struct ucontext_netbsd *ctx) {
|
||||||
int rva;
|
int rva;
|
||||||
ucontext_t uc;
|
ucontext_t uc;
|
||||||
struct siginfo si2;
|
struct siginfo si2;
|
||||||
|
|
|
@ -90,8 +90,8 @@ struct ucontext_openbsd {
|
||||||
int64_t sc_cookie;
|
int64_t sc_cookie;
|
||||||
};
|
};
|
||||||
|
|
||||||
hidden void __sigenter_openbsd(int sig, struct siginfo_openbsd *si,
|
void __sigenter_openbsd(int sig, struct siginfo_openbsd *si,
|
||||||
struct ucontext_openbsd *ctx) {
|
struct ucontext_openbsd *ctx) {
|
||||||
int rva;
|
int rva;
|
||||||
ucontext_t uc;
|
ucontext_t uc;
|
||||||
struct siginfo si2;
|
struct siginfo si2;
|
||||||
|
|
|
@ -30,12 +30,12 @@
|
||||||
* that spawn subprocesses can use this function to determine the path
|
* that spawn subprocesses can use this function to determine the path
|
||||||
* at startup. Here's an example how you could use it:
|
* at startup. Here's an example how you could use it:
|
||||||
*
|
*
|
||||||
* if ((strace = commandvenv("STRACE", "strace"))) {
|
* if ((strace = commandvenv("STRACE", "strace"))) {
|
||||||
* strace = strdup(strace);
|
* strace = strdup(strace);
|
||||||
* } else {
|
* } else {
|
||||||
* fprintf(stderr, "error: please install strace\n");
|
* fprintf(stderr, "error: please install strace\n");
|
||||||
* exit(1);
|
* exit(1);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @param var is environment variable which may be used to override
|
* @param var is environment variable which may be used to override
|
||||||
* PATH search, and it can force a NULL result if it's empty
|
* 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,
|
__msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
||||||
EFI_SYSTEM_TABLE *SystemTable) {
|
EFI_SYSTEM_TABLE *SystemTable) {
|
||||||
bool ispml5t;
|
|
||||||
int type, x87cw;
|
int type, x87cw;
|
||||||
struct mman *mm;
|
struct mman *mm;
|
||||||
uint32_t DescVersion;
|
uint32_t DescVersion;
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "libc/nt/thunk/msabi.h"
|
#include "libc/nt/thunk/msabi.h"
|
||||||
#include "libc/sysv/consts/nr.h"
|
#include "libc/sysv/consts/nr.h"
|
||||||
|
|
||||||
|
extern void(__msabi* __imp_ExitProcess)(uint32_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminates process, ignoring destructors and atexit() handlers.
|
* Terminates process, ignoring destructors and atexit() handlers.
|
||||||
*
|
*
|
||||||
|
@ -41,10 +43,10 @@ privileged wontreturn void _Exit(int exitcode) {
|
||||||
: "a"(__NR_exit_group), "D"(exitcode)
|
: "a"(__NR_exit_group), "D"(exitcode)
|
||||||
: "memory");
|
: "memory");
|
||||||
} else if (IsWindows()) {
|
} else if (IsWindows()) {
|
||||||
extern void(__msabi * __imp_ExitProcess)(uint32_t);
|
|
||||||
__imp_ExitProcess(exitcode & 0xff);
|
__imp_ExitProcess(exitcode & 0xff);
|
||||||
}
|
}
|
||||||
asm("push\t$0\n\t"
|
asm("push\t$0\n\t"
|
||||||
|
"push\t$0\n\t"
|
||||||
"cli\n\t"
|
"cli\n\t"
|
||||||
"lidt\t(%rsp)");
|
"lidt\t(%rsp)");
|
||||||
for (;;) asm("ud2");
|
for (;;) asm("ud2");
|
||||||
|
|
|
@ -57,21 +57,22 @@ $(LIBC_RUNTIME_A).pkg: \
|
||||||
$(foreach x,$(LIBC_RUNTIME_A_DIRECTDEPS),$($(x)_A).pkg)
|
$(foreach x,$(LIBC_RUNTIME_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||||
|
|
||||||
o/$(MODE)/libc/runtime/abort-nt.o \
|
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/arememoryintervalsok.o \
|
||||||
o/$(MODE)/libc/runtime/isheap.o \
|
o/$(MODE)/libc/runtime/assertfail.o \
|
||||||
o/$(MODE)/libc/runtime/directmap.o \
|
o/$(MODE)/libc/runtime/directmap.o \
|
||||||
o/$(MODE)/libc/runtime/directmapnt.o \
|
o/$(MODE)/libc/runtime/directmapnt.o \
|
||||||
o/$(MODE)/libc/runtime/stackchkfail.o \
|
o/$(MODE)/libc/runtime/findmemoryinterval.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/ftrace.greg.o \
|
o/$(MODE)/libc/runtime/ftrace.greg.o \
|
||||||
o/$(MODE)/libc/runtime/getdosargv.o \
|
o/$(MODE)/libc/runtime/getdosargv.o \
|
||||||
o/$(MODE)/libc/runtime/getdosenviron.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: \
|
o/$(MODE)/libc/runtime/winmain.greg.o: \
|
||||||
OVERRIDE_CFLAGS += \
|
OVERRIDE_CFLAGS += \
|
||||||
$(NO_MAGIC)
|
$(NO_MAGIC)
|
||||||
|
|
|
@ -61,10 +61,6 @@ struct WinArgs {
|
||||||
char envblock[ARG_MAX];
|
char envblock[ARG_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
static noasan textwindows void SetTrueColor(void) {
|
|
||||||
SetEnvironmentVariable(u"TERM", u"xterm-truecolor");
|
|
||||||
}
|
|
||||||
|
|
||||||
static noasan textwindows void MakeLongDoubleLongAgain(void) {
|
static noasan textwindows void MakeLongDoubleLongAgain(void) {
|
||||||
/* 8087 FPU Control Word
|
/* 8087 FPU Control Word
|
||||||
IM: Invalid Operation ───────────────┐
|
IM: Invalid Operation ───────────────┐
|
||||||
|
@ -92,7 +88,6 @@ static noasan textwindows void NormalizeCmdExe(int version) {
|
||||||
hstdout = GetStdHandle(pushpop(kNtStdOutputHandle));
|
hstdout = GetStdHandle(pushpop(kNtStdOutputHandle));
|
||||||
hstderr = GetStdHandle(pushpop(kNtStdErrorHandle));
|
hstderr = GetStdHandle(pushpop(kNtStdErrorHandle));
|
||||||
if (GetFileType((handle = hstdin)) == kNtFileTypeChar) {
|
if (GetFileType((handle = hstdin)) == kNtFileTypeChar) {
|
||||||
/* SetTrueColor(); */
|
|
||||||
SetConsoleCP(kNtCpUtf8);
|
SetConsoleCP(kNtCpUtf8);
|
||||||
GetConsoleMode(handle, &mode);
|
GetConsoleMode(handle, &mode);
|
||||||
SetConsoleMode(handle, mode | kNtEnableProcessedInput |
|
SetConsoleMode(handle, mode | kNtEnableProcessedInput |
|
||||||
|
@ -102,7 +97,6 @@ static noasan textwindows void NormalizeCmdExe(int version) {
|
||||||
}
|
}
|
||||||
if (GetFileType((handle = hstdout)) == kNtFileTypeChar ||
|
if (GetFileType((handle = hstdout)) == kNtFileTypeChar ||
|
||||||
GetFileType((handle = hstderr)) == kNtFileTypeChar) {
|
GetFileType((handle = hstderr)) == kNtFileTypeChar) {
|
||||||
/* SetTrueColor(); */
|
|
||||||
SetConsoleOutputCP(kNtCpUtf8);
|
SetConsoleOutputCP(kNtCpUtf8);
|
||||||
GetConsoleMode(handle, &mode);
|
GetConsoleMode(handle, &mode);
|
||||||
SetConsoleMode(
|
SetConsoleMode(
|
||||||
|
@ -135,7 +129,7 @@ static noasan textwindows wontreturn void WinMainNew(void) {
|
||||||
_mmi.p[0].y = (addr >> 16) + ((size >> 16) - 1);
|
_mmi.p[0].y = (addr >> 16) + ((size >> 16) - 1);
|
||||||
_mmi.p[0].prot = PROT_READ | PROT_WRITE | PROT_EXEC;
|
_mmi.p[0].prot = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||||
_mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
_mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||||
_mmi.i = pushpop(1L);
|
_mmi.i = 1;
|
||||||
wa = (struct WinArgs *)(addr + size - sizeof(struct WinArgs));
|
wa = (struct WinArgs *)(addr + size - sizeof(struct WinArgs));
|
||||||
count = GetDosArgv(GetCommandLine(), wa->argblock, ARRAYLEN(wa->argblock),
|
count = GetDosArgv(GetCommandLine(), wa->argblock, ARRAYLEN(wa->argblock),
|
||||||
wa->argv, ARRAYLEN(wa->argv));
|
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,
|
noasan textwindows int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
|
||||||
const char *lpCmdLine, int nCmdShow) {
|
const char *lpCmdLine, int nCmdShow) {
|
||||||
MakeLongDoubleLongAgain();
|
MakeLongDoubleLongAgain();
|
||||||
if (weaken(__winsockinit)) weaken(__winsockinit)();
|
if (weaken(WinSockInit)) weaken(WinSockInit)();
|
||||||
if (weaken(WinMainForked)) weaken(WinMainForked)();
|
if (weaken(WinMainForked)) weaken(WinMainForked)();
|
||||||
WinMainNew();
|
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,
|
ssize_t sys_recvfrom_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
||||||
void *, uint32_t *) hidden;
|
void *, uint32_t *) hidden;
|
||||||
|
|
||||||
void __winsockinit(void) hidden;
|
void WinSockInit(void) hidden;
|
||||||
int64_t __winsockerr(void) nocallback hidden;
|
int64_t __winsockerr(void) nocallback hidden;
|
||||||
int __fixupnewsockfd(int, int) hidden;
|
int __fixupnewsockfd(int, int) hidden;
|
||||||
int64_t __winsockblock(int64_t, unsigned, int64_t) hidden;
|
int64_t __winsockblock(int64_t, unsigned, int64_t) hidden;
|
||||||
|
|
|
@ -33,13 +33,13 @@
|
||||||
*/
|
*/
|
||||||
hidden struct NtWsaData kNtWsaData;
|
hidden struct NtWsaData kNtWsaData;
|
||||||
|
|
||||||
static textwindows void __winsockfini(void) {
|
static textwindows void WinSockCleanup(void) {
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows noasan void __winsockinit(void) {
|
textwindows noasan void WinSockInit(void) {
|
||||||
int rc;
|
int rc;
|
||||||
atexit(__winsockfini);
|
atexit(WinSockCleanup);
|
||||||
if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 ||
|
if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 ||
|
||||||
kNtWsaData.wVersion != VERSION) {
|
kNtWsaData.wVersion != VERSION) {
|
||||||
ExitProcess(123);
|
ExitProcess(123);
|
||||||
|
|
|
@ -29,5 +29,5 @@ bool endswith(const char *s, const char *suffix) {
|
||||||
n = strlen(s);
|
n = strlen(s);
|
||||||
m = strlen(suffix);
|
m = strlen(suffix);
|
||||||
if (m > n) return false;
|
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 *wmempcpy(wchar_t *, const wchar_t *, size_t) memcpyesque;
|
||||||
compatfn wchar_t *wmemmove(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);
|
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)
|
void *memmem(const void *, size_t, const void *, size_t)
|
||||||
paramsnonnull() nothrow nocallback nosideeffect;
|
paramsnonnull() nothrow nocallback nosideeffect;
|
||||||
char *strerror(int) returnsnonnull nothrow nocallback;
|
char *strerror(int) returnsnonnull nothrow nocallback;
|
||||||
long a64l(const char *);
|
long a64l(const char *);
|
||||||
char *l64a(long);
|
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 *strntolower(char *, size_t);
|
||||||
char *strtolower(char *) paramsnonnull();
|
char *strtolower(char *) paramsnonnull();
|
||||||
char *strntoupper(char *, size_t);
|
char *strntoupper(char *, size_t);
|
||||||
|
|
|
@ -34,10 +34,12 @@
|
||||||
* @note unlike strtok() this does empty tokens and is re-entrant
|
* @note unlike strtok() this does empty tokens and is re-entrant
|
||||||
*/
|
*/
|
||||||
char *strsep(char **str, const char *delim) {
|
char *strsep(char **str, const char *delim) {
|
||||||
char *token = *str;
|
size_t i;
|
||||||
|
char *token, *next;
|
||||||
|
token = *str;
|
||||||
if (token) {
|
if (token) {
|
||||||
size_t i = strcspn(token, delim);
|
i = strcspn(token, delim);
|
||||||
char *next = NULL;
|
next = NULL;
|
||||||
if (token[i]) {
|
if (token[i]) {
|
||||||
token[i] = '\0';
|
token[i] = '\0';
|
||||||
next = &token[i + 1];
|
next = &token[i + 1];
|
||||||
|
|
|
@ -37,7 +37,7 @@ static char g_strsignal[4 + 8];
|
||||||
* @see sigaction()
|
* @see sigaction()
|
||||||
*/
|
*/
|
||||||
char *strsignal(int sig) {
|
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, kSig, 4);
|
||||||
memcpy(&g_strsignal[3], kStrSignals[sig], 8);
|
memcpy(&g_strsignal[3], kStrSignals[sig], 8);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,6 +28,15 @@
|
||||||
* @see memmem()
|
* @see memmem()
|
||||||
*/
|
*/
|
||||||
char16_t *strstr16(const char16_t *haystack, const char16_t *needle) {
|
char16_t *strstr16(const char16_t *haystack, const char16_t *needle) {
|
||||||
return memmem(haystack, strlen16(haystack) * sizeof(char16_t), needle,
|
size_t i;
|
||||||
strlen16(needle) * sizeof(char16_t));
|
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 hypot(double a, double b) {
|
||||||
double r, t;
|
double r, t;
|
||||||
if (isinf(a) || isinf(b)) return INFINITY;
|
if (isinf(a) || isinf(b)) return INFINITY;
|
||||||
if (isunordered(a, b)) return NAN;
|
|
||||||
a = fabs(a);
|
a = fabs(a);
|
||||||
b = fabs(b);
|
b = fabs(b);
|
||||||
if (a < b) t = b, b = a, a = t;
|
if (a < b) t = b, b = a, a = t;
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
float hypotf(float a, float b) {
|
float hypotf(float a, float b) {
|
||||||
float r, t;
|
float r, t;
|
||||||
if (isinf(a) || isinf(b)) return INFINITY;
|
if (isinf(a) || isinf(b)) return INFINITY;
|
||||||
if (isunordered(a, b)) return NAN;
|
|
||||||
a = fabsf(a);
|
a = fabsf(a);
|
||||||
b = fabsf(b);
|
b = fabsf(b);
|
||||||
if (a < b) t = b, b = a, a = t;
|
if (a < b) t = b, b = a, a = t;
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
long double hypotl(long double a, long double b) {
|
long double hypotl(long double a, long double b) {
|
||||||
long double r, t;
|
long double r, t;
|
||||||
if (isinf(a) || isinf(b)) return INFINITY;
|
if (isinf(a) || isinf(b)) return INFINITY;
|
||||||
if (isunordered(a, b)) return NAN;
|
|
||||||
a = fabsl(a);
|
a = fabsl(a);
|
||||||
b = fabsl(b);
|
b = fabsl(b);
|
||||||
if (a < b) t = b, b = a, a = t;
|
if (a < b) t = b, b = a, a = t;
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
//
|
//
|
||||||
// @param 𝑥 is double scalar in low half of %xmm0
|
// @param 𝑥 is double scalar in low half of %xmm0
|
||||||
// @return double scalar in low half of %xmm0
|
// @return double scalar in low half of %xmm0
|
||||||
log10:
|
log10: ezlea log10l,ax
|
||||||
ezlea log10l,ax
|
|
||||||
jmp _d2ld2
|
jmp _d2ld2
|
||||||
.endfn log10,globl
|
.endfn log10,globl
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
//
|
//
|
||||||
// @param 𝑥 is a double passed in the lower quadword of %xmm0
|
// @param 𝑥 is a double passed in the lower quadword of %xmm0
|
||||||
// @return result in lower quadword of %xmm0
|
// @return result in lower quadword of %xmm0
|
||||||
log2:
|
log2: push %rbp
|
||||||
push %rbp
|
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
push %rax
|
push %rax
|
||||||
|
|
|
@ -23,8 +23,7 @@
|
||||||
//
|
//
|
||||||
// @param 𝑥 is a float passed in the lower quarter of %xmm0
|
// @param 𝑥 is a float passed in the lower quarter of %xmm0
|
||||||
// @return result in lower quarter of %xmm0
|
// @return result in lower quarter of %xmm0
|
||||||
log2f:
|
log2f: push %rbp
|
||||||
push %rbp
|
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
push %rax
|
push %rax
|
||||||
|
|
|
@ -28,26 +28,30 @@ char b1[64];
|
||||||
char b2[64];
|
char b2[64];
|
||||||
struct Dis d[1];
|
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) {
|
TEST(DisInst, testInt3) {
|
||||||
uint8_t op[] = {0xcc};
|
uint8_t op[] = {0xcc};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("int3 ", b1);
|
EXPECT_STREQ("int3 ", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testImmMem_needsSuffix) {
|
TEST(DisInst, testImmMem_needsSuffix) {
|
||||||
uint8_t op[] = {0x80, 0x3c, 0x07, 0x00};
|
uint8_t op[] = {0x80, 0x3c, 0x07, 0x00};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("cmpb $0,(%rdi,%rax)", b1);
|
EXPECT_STREQ("cmpb $0,(%rdi,%rax)", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testImmReg_doesntNeedSuffix) {
|
TEST(DisInst, testImmReg_doesntNeedSuffix) {
|
||||||
uint8_t op[] = {0xb8, 0x08, 0x70, 0x40, 0x00};
|
uint8_t op[] = {0xb8, 0x08, 0x70, 0x40, 0x00};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("mov $0x407008,%eax", b1);
|
EXPECT_STREQ("mov $0x407008,%eax", b1);
|
||||||
}
|
}
|
||||||
|
@ -60,56 +64,47 @@ TEST(DisInst, testPuttingOnTheRiz) {
|
||||||
{0x8d, 0b00110100, 0b11100101, 0x37, 0x13, 0x03, 0},
|
{0x8d, 0b00110100, 0b11100101, 0x37, 0x13, 0x03, 0},
|
||||||
{0x8d, 0b10110100, 0b11100101, 0, 0, 0, 0},
|
{0x8d, 0b10110100, 0b11100101, 0, 0, 0, 0},
|
||||||
};
|
};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(ops[0], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[0], sizeof(ops[0])));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("lea (%rsi),%esi", b1);
|
EXPECT_STREQ("lea (%rsi),%esi", b1);
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(ops[1], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[1], sizeof(ops[1])));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("lea (%esi,%eiz,8),%esi", b1);
|
EXPECT_STREQ("lea (%esi,%eiz,8),%esi", b1);
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(ops[2], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[2], sizeof(ops[2])));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("lea 0(%ebp,%eiz,8),%esi", b1);
|
EXPECT_STREQ("lea 0(%ebp,%eiz,8),%esi", b1);
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(ops[3], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[3], sizeof(ops[3])));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("lea 0x31337,%esi", b1);
|
EXPECT_STREQ("lea 0x31337,%esi", b1);
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(ops[4], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, ops[4], sizeof(ops[4])));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("lea 0(%rbp,%riz,8),%esi", b1);
|
EXPECT_STREQ("lea 0(%rbp,%riz,8),%esi", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testSibIndexOnly) {
|
TEST(DisInst, testSibIndexOnly) {
|
||||||
uint8_t op[] = {76, 141, 4, 141, 0, 0, 0, 0};
|
uint8_t op[] = {76, 141, 4, 141, 0, 0, 0, 0};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("lea 0(,%rcx,4),%r8", b1);
|
EXPECT_STREQ("lea 0(,%rcx,4),%r8", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testRealMode) {
|
TEST(DisInst, testRealMode) {
|
||||||
uint8_t op[] = {0x89, 0xe5};
|
uint8_t op[] = {0x89, 0xe5};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("mov %sp,%bp", b1);
|
EXPECT_STREQ("mov %sp,%bp", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testNop) {
|
TEST(DisInst, testNop) {
|
||||||
uint8_t op[] = {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
|
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);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("nopw %cs:0(%rax,%rax)", b1);
|
EXPECT_STREQ("nopw %cs:0(%rax,%rax)", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testPush) {
|
TEST(DisInst, testPush) {
|
||||||
uint8_t op[] = {0x41, 0x5c};
|
uint8_t op[] = {0x41, 0x5c};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
EXPECT_EQ(4, ModrmSrm(d->xedd->op.rde));
|
EXPECT_EQ(4, ModrmSrm(d->xedd->op.rde));
|
||||||
EXPECT_EQ(1, Rexb(d->xedd->op.rde));
|
EXPECT_EQ(1, Rexb(d->xedd->op.rde));
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
|
@ -118,108 +113,94 @@ TEST(DisInst, testPush) {
|
||||||
|
|
||||||
TEST(DisInst, testMovb) {
|
TEST(DisInst, testMovb) {
|
||||||
uint8_t op[] = {0x8a, 0x1e, 0x0c, 0x32};
|
uint8_t op[] = {0x8a, 0x1e, 0x0c, 0x32};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("mov (%rsi),%bl", b1);
|
EXPECT_STREQ("mov (%rsi),%bl", b1);
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("mov 0x320c,%bl", b1);
|
EXPECT_STREQ("mov 0x320c,%bl", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testLes) {
|
TEST(DisInst, testLes) {
|
||||||
uint8_t op[] = {0xc4, 0x3e, 0x16, 0x32};
|
uint8_t op[] = {0xc4, 0x3e, 0x16, 0x32};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("les 0x3216,%di", b1);
|
EXPECT_STREQ("les 0x3216,%di", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testStosbLong) {
|
TEST(DisInst, testStosbLong) {
|
||||||
uint8_t op[] = {0xAA};
|
uint8_t op[] = {0xAA};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("stosb %al,(%rdi)", b1);
|
EXPECT_STREQ("stosb %al,(%rdi)", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testStosbReal) {
|
TEST(DisInst, testStosbReal) {
|
||||||
uint8_t op[] = {0xAA};
|
uint8_t op[] = {0xAA};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("stosb %al,(%di)", b1);
|
EXPECT_STREQ("stosb %al,(%di)", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testStosbLegacy) {
|
TEST(DisInst, testStosbLegacy) {
|
||||||
uint8_t op[] = {0xAA};
|
uint8_t op[] = {0xAA};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LEGACY_32);
|
ILD(op, XED_MACHINE_MODE_LEGACY_32);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("stosb %al,(%edi)", b1);
|
EXPECT_STREQ("stosb %al,(%edi)", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testStosbLongAsz) {
|
TEST(DisInst, testStosbLongAsz) {
|
||||||
uint8_t op[] = {0x67, 0xAA};
|
uint8_t op[] = {0x67, 0xAA};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("stosb %al,(%edi)", b1);
|
EXPECT_STREQ("stosb %al,(%edi)", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testAddLong) {
|
TEST(DisInst, testAddLong) {
|
||||||
uint8_t op[] = {0x01, 0xff};
|
uint8_t op[] = {0x01, 0xff};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("add %edi,%edi", b1);
|
EXPECT_STREQ("add %edi,%edi", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testAddLegacy) {
|
TEST(DisInst, testAddLegacy) {
|
||||||
uint8_t op[] = {0x01, 0xff};
|
uint8_t op[] = {0x01, 0xff};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LEGACY_32);
|
ILD(op, XED_MACHINE_MODE_LEGACY_32);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("add %edi,%edi", b1);
|
EXPECT_STREQ("add %edi,%edi", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testAddReal) {
|
TEST(DisInst, testAddReal) {
|
||||||
uint8_t op[] = {0x01, 0xff};
|
uint8_t op[] = {0x01, 0xff};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("add %di,%di", b1);
|
EXPECT_STREQ("add %di,%di", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testAddLongOsz) {
|
TEST(DisInst, testAddLongOsz) {
|
||||||
uint8_t op[] = {0x66, 0x01, 0xff};
|
uint8_t op[] = {0x66, 0x01, 0xff};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("add %di,%di", b1);
|
EXPECT_STREQ("add %di,%di", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testAddLegacyOsz) {
|
TEST(DisInst, testAddLegacyOsz) {
|
||||||
uint8_t op[] = {0x66, 0x01, 0xff};
|
uint8_t op[] = {0x66, 0x01, 0xff};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LEGACY_32);
|
ILD(op, XED_MACHINE_MODE_LEGACY_32);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("add %di,%di", b1);
|
EXPECT_STREQ("add %di,%di", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testAddRealOsz) {
|
TEST(DisInst, testAddRealOsz) {
|
||||||
uint8_t op[] = {0x66, 0x01, 0xff};
|
uint8_t op[] = {0x66, 0x01, 0xff};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("add %edi,%edi", b1);
|
EXPECT_STREQ("add %edi,%edi", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testFxam) {
|
TEST(DisInst, testFxam) {
|
||||||
uint8_t op[] = {0xd9, 0xe5};
|
uint8_t op[] = {0xd9, 0xe5};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
ASSERT_EQ(4, ModrmReg(d->xedd->op.rde));
|
ASSERT_EQ(4, ModrmReg(d->xedd->op.rde));
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("fxam ", b1);
|
EXPECT_STREQ("fxam ", b1);
|
||||||
|
@ -227,64 +208,56 @@ TEST(DisInst, testFxam) {
|
||||||
|
|
||||||
TEST(DisInst, testOrImmCode16gcc) {
|
TEST(DisInst, testOrImmCode16gcc) {
|
||||||
uint8_t op[] = {0x67, 0x81, 0x4c, 0x24, 0x0c, 0x00, 0x0c};
|
uint8_t op[] = {0x67, 0x81, 0x4c, 0x24, 0x0c, 0x00, 0x0c};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("orw $0xc00,12(%esp)", b1);
|
EXPECT_STREQ("orw $0xc00,12(%esp)", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testPause) {
|
TEST(DisInst, testPause) {
|
||||||
uint8_t op[] = {0xf3, 0x90};
|
uint8_t op[] = {0xf3, 0x90};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("pause ", b1);
|
EXPECT_STREQ("pause ", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testJmpEw) {
|
TEST(DisInst, testJmpEw) {
|
||||||
uint8_t op[] = {0xff, 0xe0};
|
uint8_t op[] = {0xff, 0xe0};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("jmp %ax", b1);
|
EXPECT_STREQ("jmp %ax", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testJmpEv16) {
|
TEST(DisInst, testJmpEv16) {
|
||||||
uint8_t op[] = {0x66, 0xff, 0xe0};
|
uint8_t op[] = {0x66, 0xff, 0xe0};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("jmp %eax", b1);
|
EXPECT_STREQ("jmp %eax", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testJmpEv32) {
|
TEST(DisInst, testJmpEv32) {
|
||||||
uint8_t op[] = {0xff, 0xe0};
|
uint8_t op[] = {0xff, 0xe0};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LEGACY_32);
|
ILD(op, XED_MACHINE_MODE_LEGACY_32);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("jmp %eax", b1);
|
EXPECT_STREQ("jmp %eax", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testJmpEq) {
|
TEST(DisInst, testJmpEq) {
|
||||||
uint8_t op[] = {0x66, 0xff, 0xe0};
|
uint8_t op[] = {0x66, 0xff, 0xe0};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("jmp %rax", b1);
|
EXPECT_STREQ("jmp %rax", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testMovswSs) {
|
TEST(DisInst, testMovswSs) {
|
||||||
uint8_t op[] = {0x36, 0xA5};
|
uint8_t op[] = {0x36, 0xA5};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("movs %ss:(%si),(%di)", b1);
|
EXPECT_STREQ("movs %ss:(%si),(%di)", b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DisInst, testRealModrm_sibOverlap_showsNoDisplacement) {
|
TEST(DisInst, testRealModrm_sibOverlap_showsNoDisplacement) {
|
||||||
uint8_t op[] = {0x8b, 0b00100101};
|
uint8_t op[] = {0x8b, 0b00100101};
|
||||||
xed_decoded_inst_zero_set_mode(d->xedd, XED_MACHINE_MODE_REAL);
|
ILD(op, XED_MACHINE_MODE_REAL);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(d->xedd, op, sizeof(op)));
|
|
||||||
DisInst(d, b1, DisSpec(d->xedd, b2));
|
DisInst(d, b1, DisSpec(d->xedd, b2));
|
||||||
EXPECT_STREQ("mov (%di),%sp", b1);
|
EXPECT_STREQ("mov (%di),%sp", b1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,13 @@
|
||||||
#include "tool/build/lib/machine.h"
|
#include "tool/build/lib/machine.h"
|
||||||
#include "tool/build/lib/modrm.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) {
|
TEST(modrm, testAddressSizeOverride_isNotPresent_keepsWholeExpression) {
|
||||||
struct Machine *m = gc(NewMachine());
|
struct Machine *m = gc(NewMachine());
|
||||||
struct XedDecodedInst *xedd = gc(calloc(1, sizeof(struct XedDecodedInst)));
|
struct XedDecodedInst *xedd = gc(calloc(1, sizeof(struct XedDecodedInst)));
|
||||||
|
@ -31,8 +38,7 @@ TEST(modrm, testAddressSizeOverride_isNotPresent_keepsWholeExpression) {
|
||||||
m->xedd = xedd;
|
m->xedd = xedd;
|
||||||
Write64(m->bx, 0x2);
|
Write64(m->bx, 0x2);
|
||||||
Write64(m->ax, 0xffffffff);
|
Write64(m->ax, 0xffffffff);
|
||||||
xed_decoded_inst_zero_set_mode(xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(xedd, op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(xedd, op, sizeof(op)));
|
|
||||||
EXPECT_EQ(0x100000001, ComputeAddress(m, m->xedd->op.rde));
|
EXPECT_EQ(0x100000001, ComputeAddress(m, m->xedd->op.rde));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +49,7 @@ TEST(modrm, testAddressSizeOverride_isPresent_modulesWholeExpression) {
|
||||||
m->xedd = xedd;
|
m->xedd = xedd;
|
||||||
Write64(m->bx, 0x2);
|
Write64(m->bx, 0x2);
|
||||||
Write64(m->ax, 0xffffffff);
|
Write64(m->ax, 0xffffffff);
|
||||||
xed_decoded_inst_zero_set_mode(xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(xedd, op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(xedd, op, sizeof(op)));
|
|
||||||
EXPECT_EQ(0x000000001, ComputeAddress(m, m->xedd->op.rde));
|
EXPECT_EQ(0x000000001, ComputeAddress(m, m->xedd->op.rde));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +60,7 @@ TEST(modrm, testOverflow_doesntTriggerTooling) {
|
||||||
m->xedd = xedd;
|
m->xedd = xedd;
|
||||||
Write64(m->bx, 0x0000000000000001);
|
Write64(m->bx, 0x0000000000000001);
|
||||||
Write64(m->ax, 0x7fffffffffffffff);
|
Write64(m->ax, 0x7fffffffffffffff);
|
||||||
xed_decoded_inst_zero_set_mode(xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(xedd, op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(xedd, op, sizeof(op)));
|
|
||||||
EXPECT_EQ(0x8000000000000000ull,
|
EXPECT_EQ(0x8000000000000000ull,
|
||||||
(uint64_t)ComputeAddress(m, m->xedd->op.rde));
|
(uint64_t)ComputeAddress(m, m->xedd->op.rde));
|
||||||
}
|
}
|
||||||
|
@ -72,17 +76,13 @@ TEST(modrm, testPuttingOnTheRiz) {
|
||||||
m->xedd = gc(calloc(1, sizeof(struct XedDecodedInst)));
|
m->xedd = gc(calloc(1, sizeof(struct XedDecodedInst)));
|
||||||
Write64(m->si, 0x100000001);
|
Write64(m->si, 0x100000001);
|
||||||
Write64(m->bp, 0x200000002);
|
Write64(m->bp, 0x200000002);
|
||||||
xed_decoded_inst_zero_set_mode(m->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(m->xedd, ops[0], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(m->xedd, ops[0], sizeof(ops[0])));
|
|
||||||
EXPECT_EQ(0x100000001, ComputeAddress(m, m->xedd->op.rde));
|
EXPECT_EQ(0x100000001, ComputeAddress(m, m->xedd->op.rde));
|
||||||
xed_decoded_inst_zero_set_mode(m->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(m->xedd, ops[1], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(m->xedd, ops[1], sizeof(ops[1])));
|
|
||||||
EXPECT_EQ(0x000000001, ComputeAddress(m, m->xedd->op.rde));
|
EXPECT_EQ(0x000000001, ComputeAddress(m, m->xedd->op.rde));
|
||||||
xed_decoded_inst_zero_set_mode(m->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(m->xedd, ops[2], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(m->xedd, ops[2], sizeof(ops[2])));
|
|
||||||
EXPECT_EQ(0x31339, ComputeAddress(m, m->xedd->op.rde));
|
EXPECT_EQ(0x31339, ComputeAddress(m, m->xedd->op.rde));
|
||||||
xed_decoded_inst_zero_set_mode(m->xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(m->xedd, ops[3], XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(m->xedd, ops[3], sizeof(ops[3])));
|
|
||||||
EXPECT_EQ(0x31337, ComputeAddress(m, m->xedd->op.rde));
|
EXPECT_EQ(0x31337, ComputeAddress(m, m->xedd->op.rde));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +100,7 @@ TEST(modrm, testSibIndexOnly) {
|
||||||
m->xedd = xedd;
|
m->xedd = xedd;
|
||||||
Write64(m->bp, 0x123);
|
Write64(m->bp, 0x123);
|
||||||
Write64(m->cx, 0x123);
|
Write64(m->cx, 0x123);
|
||||||
xed_decoded_inst_zero_set_mode(xedd, XED_MACHINE_MODE_LONG_64);
|
ILD(xedd, op, XED_MACHINE_MODE_LONG_64);
|
||||||
ASSERT_EQ(0, xed_instruction_length_decode(xedd, op, sizeof(op)));
|
|
||||||
EXPECT_TRUE(Rexw(m->xedd->op.rde));
|
EXPECT_TRUE(Rexw(m->xedd->op.rde));
|
||||||
EXPECT_TRUE(Rexr(m->xedd->op.rde));
|
EXPECT_TRUE(Rexr(m->xedd->op.rde));
|
||||||
EXPECT_FALSE(Rexb(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 -*-│
|
/*-*- 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│
|
│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 │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ 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 │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/str/internal.h"
|
#include "third_party/xed/x86.h"
|
||||||
|
|
||||||
/**
|
const uint8_t kXedEamode[2][3] = {
|
||||||
* Naïve substring search implementation.
|
[0][XED_MODE_REAL] = XED_MODE_REAL,
|
||||||
* @see libc/str/strstr.c
|
[0][XED_MODE_LEGACY] = XED_MODE_LEGACY,
|
||||||
* @asyncsignalsafe
|
[0][XED_MODE_LONG] = XED_MODE_LONG,
|
||||||
*/
|
[1][XED_MODE_REAL] = XED_MODE_LEGACY,
|
||||||
char *tinystrstr(const char *haystack, const char *needle) {
|
[1][XED_MODE_LEGACY] = XED_MODE_REAL,
|
||||||
size_t i;
|
[1][XED_MODE_LONG] = XED_MODE_LEGACY,
|
||||||
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;
|
|
||||||
}
|
|
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 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 *,
|
struct XedDecodedInst *xed_decoded_inst_zero_set_mode(struct XedDecodedInst *,
|
||||||
enum XedMachineMode);
|
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) |
|
* example, 0x2800000ul was calculated as: 1UL<<(XED_ISA_SET_I86-64) |
|
||||||
* 1UL<<(XED_ISA_SET_LAHF-64).
|
* 1UL<<(XED_ISA_SET_LAHF-64).
|
||||||
*/
|
*/
|
||||||
const uint64_t xed_chip_features[XED_CHIP_LAST][3] /* clang-format off */
|
const uint64_t kXedChipFeatures[XED_CHIP_LAST][3] /* clang-format off */ = {
|
||||||
_Section(".text") = {
|
|
||||||
{0, 0, 0, },
|
{0, 0, 0, },
|
||||||
{0, 0x02800000, 0, }, /*I86*/
|
{0, 0x02800000, 0, }, /*I86*/
|
||||||
{0, 0x02800000, 0x02000}, /*I86FP*/
|
{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 {
|
static const struct XedDenseMagnums {
|
||||||
unsigned vex_prefix_recoding[4];
|
unsigned vex_prefix_recoding[4];
|
||||||
xed_bits_t eamode[2][3];
|
|
||||||
xed_bits_t BRDISPz_BRDISP_WIDTH[4];
|
xed_bits_t BRDISPz_BRDISP_WIDTH[4];
|
||||||
xed_bits_t MEMDISPv_DISP_WIDTH[4];
|
xed_bits_t MEMDISPv_DISP_WIDTH[4];
|
||||||
xed_bits_t SIMMz_IMM_WIDTH[4];
|
xed_bits_t SIMMz_IMM_WIDTH[4];
|
||||||
|
@ -136,186 +135,177 @@ static const struct XedDenseMagnums {
|
||||||
.UIMMv_IMM_WIDTH = {0x00, 0x10, 0x20, 0x40},
|
.UIMMv_IMM_WIDTH = {0x00, 0x10, 0x20, 0x40},
|
||||||
.ASZ_NONTERM_EASZ =
|
.ASZ_NONTERM_EASZ =
|
||||||
{
|
{
|
||||||
[0][0] = 0x1,
|
[0][0] = 1,
|
||||||
[1][0] = 0x2,
|
[1][0] = 2,
|
||||||
[0][1] = 0x2,
|
[0][1] = 2,
|
||||||
[1][1] = 0x1,
|
[1][1] = 1,
|
||||||
[0][2] = 0x3,
|
[0][2] = 3,
|
||||||
[1][2] = 0x2,
|
[1][2] = 2,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_CR_WIDTH_EOSZ =
|
.OSZ_NONTERM_CR_WIDTH_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x2,
|
[0][0][0] = 2,
|
||||||
[1][0][0] = 0x2,
|
[1][0][0] = 2,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x2,
|
[0][1][1] = 2,
|
||||||
[1][1][1] = 0x2,
|
[1][1][1] = 2,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x3,
|
[0][1][2] = 3,
|
||||||
[0][0][2] = 0x3,
|
[0][0][2] = 3,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_DF64_EOSZ =
|
.OSZ_NONTERM_DF64_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x1,
|
[0][0][0] = 1,
|
||||||
[1][0][0] = 0x1,
|
[1][0][0] = 1,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x1,
|
[0][1][1] = 1,
|
||||||
[1][1][1] = 0x1,
|
[1][1][1] = 1,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x1,
|
[0][1][2] = 1,
|
||||||
[0][0][2] = 0x3,
|
[0][0][2] = 3,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_DF64_FORCE64_EOSZ =
|
.OSZ_NONTERM_DF64_FORCE64_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x1,
|
[0][0][0] = 1,
|
||||||
[1][0][0] = 0x1,
|
[1][0][0] = 1,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x1,
|
[0][1][1] = 1,
|
||||||
[1][1][1] = 0x1,
|
[1][1][1] = 1,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x3,
|
[0][1][2] = 3,
|
||||||
[0][0][2] = 0x3,
|
[0][0][2] = 3,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_DF64_IMMUNE66_LOOP64_EOSZ =
|
.OSZ_NONTERM_DF64_IMMUNE66_LOOP64_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x1,
|
[0][0][0] = 1,
|
||||||
[1][0][0] = 0x1,
|
[1][0][0] = 1,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x1,
|
[0][1][1] = 1,
|
||||||
[1][1][1] = 0x1,
|
[1][1][1] = 1,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x3,
|
[0][1][2] = 3,
|
||||||
[0][0][2] = 0x3,
|
[0][0][2] = 3,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_EOSZ =
|
.OSZ_NONTERM_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x1,
|
[0][0][0] = 1,
|
||||||
[1][0][0] = 0x1,
|
[1][0][0] = 1,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x1,
|
[0][1][1] = 1,
|
||||||
[1][1][1] = 0x1,
|
[1][1][1] = 1,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x1,
|
[0][1][2] = 1,
|
||||||
[0][0][2] = 0x2,
|
[0][0][2] = 2,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_FORCE64_EOSZ =
|
.OSZ_NONTERM_FORCE64_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x1,
|
[0][0][0] = 1,
|
||||||
[1][0][0] = 0x1,
|
[1][0][0] = 1,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x1,
|
[0][1][1] = 1,
|
||||||
[1][1][1] = 0x1,
|
[1][1][1] = 1,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x3,
|
[0][1][2] = 3,
|
||||||
[0][0][2] = 0x3,
|
[0][0][2] = 3,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_IGNORE66_EOSZ =
|
.OSZ_NONTERM_IGNORE66_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x1,
|
[0][0][0] = 1,
|
||||||
[1][0][0] = 0x1,
|
[1][0][0] = 1,
|
||||||
[0][1][0] = 0x1,
|
[0][1][0] = 1,
|
||||||
[1][1][0] = 0x1,
|
[1][1][0] = 1,
|
||||||
[0][1][1] = 0x2,
|
[0][1][1] = 2,
|
||||||
[1][1][1] = 0x2,
|
[1][1][1] = 2,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x2,
|
[0][1][2] = 2,
|
||||||
[0][0][2] = 0x2,
|
[0][0][2] = 2,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_IMMUNE66_EOSZ =
|
.OSZ_NONTERM_IMMUNE66_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x2,
|
[0][0][0] = 2,
|
||||||
[1][0][0] = 0x2,
|
[1][0][0] = 2,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x2,
|
[0][1][1] = 2,
|
||||||
[1][1][1] = 0x2,
|
[1][1][1] = 2,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x2,
|
[0][1][2] = 2,
|
||||||
[0][0][2] = 0x2,
|
[0][0][2] = 2,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_IMMUNE_REXW_EOSZ =
|
.OSZ_NONTERM_IMMUNE_REXW_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x1,
|
[0][0][0] = 1,
|
||||||
[1][0][0] = 0x1,
|
[1][0][0] = 1,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x1,
|
[0][1][1] = 1,
|
||||||
[1][1][1] = 0x1,
|
[1][1][1] = 1,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x1,
|
[0][1][2] = 1,
|
||||||
[0][0][2] = 0x2,
|
[0][0][2] = 2,
|
||||||
[1][1][2] = 0x2,
|
[1][1][2] = 2,
|
||||||
[1][0][2] = 0x2,
|
[1][0][2] = 2,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_REFINING66_CR_WIDTH_EOSZ =
|
.OSZ_NONTERM_REFINING66_CR_WIDTH_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x2,
|
[0][0][0] = 2,
|
||||||
[1][0][0] = 0x2,
|
[1][0][0] = 2,
|
||||||
[0][1][0] = 0x2,
|
[0][1][0] = 2,
|
||||||
[1][1][0] = 0x2,
|
[1][1][0] = 2,
|
||||||
[0][1][1] = 0x2,
|
[0][1][1] = 2,
|
||||||
[1][1][1] = 0x2,
|
[1][1][1] = 2,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x3,
|
[0][1][2] = 3,
|
||||||
[0][0][2] = 0x3,
|
[0][0][2] = 3,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
},
|
||||||
.OSZ_NONTERM_REFINING66_EOSZ =
|
.OSZ_NONTERM_REFINING66_EOSZ =
|
||||||
{
|
{
|
||||||
[0][0][0] = 0x1,
|
[0][0][0] = 1,
|
||||||
[1][0][0] = 0x1,
|
[1][0][0] = 1,
|
||||||
[0][1][0] = 0x1,
|
[0][1][0] = 1,
|
||||||
[1][1][0] = 0x1,
|
[1][1][0] = 1,
|
||||||
[0][1][1] = 0x2,
|
[0][1][1] = 2,
|
||||||
[1][1][1] = 0x2,
|
[1][1][1] = 2,
|
||||||
[0][0][1] = 0x2,
|
[0][0][1] = 2,
|
||||||
[1][0][1] = 0x2,
|
[1][0][1] = 2,
|
||||||
[0][1][2] = 0x2,
|
[0][1][2] = 2,
|
||||||
[0][0][2] = 0x2,
|
[0][0][2] = 2,
|
||||||
[1][1][2] = 0x3,
|
[1][1][2] = 3,
|
||||||
[1][0][2] = 0x3,
|
[1][0][2] = 3,
|
||||||
},
|
|
||||||
.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,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -633,7 +623,6 @@ privileged static void xed_get_next_as_opcode(struct XedDecodedInst *d) {
|
||||||
b = d->bytes[length];
|
b = d->bytes[length];
|
||||||
d->op.opcode = b;
|
d->op.opcode = b;
|
||||||
d->length++;
|
d->length++;
|
||||||
/* d->op.srm = xed_modrm_rm(b); */
|
|
||||||
} else {
|
} else {
|
||||||
xed_too_short(d);
|
xed_too_short(d);
|
||||||
}
|
}
|
||||||
|
@ -722,7 +711,6 @@ privileged static void xed_opcode_scanner(struct XedDecodedInst *d) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* d->op.srm = xed_modrm_rm(d->op.opcode); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
privileged static bool xed_is_bound_instruction(struct XedDecodedInst *d) {
|
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) {
|
if (has_modrm != XED_ILD_HASMODRM_IGNORE_MOD) {
|
||||||
asz = d->op.asz;
|
asz = d->op.asz;
|
||||||
mode = d->op.mode;
|
mode = d->op.mode;
|
||||||
eamode = kXed.eamode[asz][mode];
|
eamode = kXedEamode[asz][mode];
|
||||||
d->op.disp_width =
|
d->op.disp_width =
|
||||||
xed_bytes2bits(xed_has_disp_regular[eamode][mod][rm]);
|
xed_bytes2bits(xed_has_disp_regular[eamode][mod][rm]);
|
||||||
d->op.has_sib = xed_has_sib_table[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.
|
* Clears instruction decoder state.
|
||||||
*/
|
*/
|
||||||
|
@ -1160,7 +1136,6 @@ privileged enum XedError xed_instruction_length_decode(
|
||||||
__builtin_memcpy(xedd->bytes, itext, MIN(15, bytes));
|
__builtin_memcpy(xedd->bytes, itext, MIN(15, bytes));
|
||||||
xedd->op.max_bytes = MIN(15, bytes);
|
xedd->op.max_bytes = MIN(15, bytes);
|
||||||
xed_decode_instruction_length(xedd);
|
xed_decode_instruction_length(xedd);
|
||||||
xed_encode_rde(xedd);
|
|
||||||
if (!xedd->op.out_of_bytes) {
|
if (!xedd->op.out_of_bytes) {
|
||||||
if (xedd->op.map != XED_ILD_MAP_INVALID) {
|
if (xedd->op.map != XED_ILD_MAP_INVALID) {
|
||||||
return xedd->op.error;
|
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;
|
unsigned n, r;
|
||||||
n = isa_set / 64;
|
n = isa_set / 64;
|
||||||
r = isa_set - (64 * n);
|
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) {
|
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) {
|
void xed_get_chip_features(struct XedChipFeatures *p, enum XedChip chip) {
|
||||||
if (p) {
|
if (p) {
|
||||||
if (chip < XED_CHIP_LAST) {
|
if (chip < XED_CHIP_LAST) {
|
||||||
p->f[0] = xed_chip_features[chip][0];
|
p->f[0] = kXedChipFeatures[chip][0];
|
||||||
p->f[1] = xed_chip_features[chip][1];
|
p->f[1] = kXedChipFeatures[chip][1];
|
||||||
p->f[2] = xed_chip_features[chip][2];
|
p->f[2] = kXedChipFeatures[chip][2];
|
||||||
} else {
|
} else {
|
||||||
p->f[0] = 0;
|
p->f[0] = 0;
|
||||||
p->f[1] = 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_decoded_inst_zero_set_mode(d->xedd, m->mode);
|
||||||
xed_instruction_length_decode(d->xedd, p, n);
|
xed_instruction_length_decode(d->xedd, p, n);
|
||||||
|
d->xedd->op.rde = EncodeRde(d->xedd);
|
||||||
n = d->xedd->op.error ? 1 : d->xedd->length;
|
n = d->xedd->op.error ? 1 : d->xedd->length;
|
||||||
op.addr = addr;
|
op.addr = addr;
|
||||||
op.size = n;
|
op.size = n;
|
||||||
|
@ -255,6 +256,7 @@ const char *DisGetLine(struct Dis *d, struct Machine *m, size_t i) {
|
||||||
xed_instruction_length_decode(
|
xed_instruction_length_decode(
|
||||||
d->xedd, AccessRam(m, d->ops.p[i].addr, d->ops.p[i].size, r, b, true),
|
d->xedd, AccessRam(m, d->ops.p[i].addr, d->ops.p[i].size, r, b, true),
|
||||||
d->ops.p[i].size);
|
d->ops.p[i].size);
|
||||||
|
d->xedd->op.rde = EncodeRde(d->xedd);
|
||||||
d->m = m;
|
d->m = m;
|
||||||
d->addr = d->ops.p[i].addr;
|
d->addr = d->ops.p[i].addr;
|
||||||
CHECK_LT(DisLineCode(d, d->buf) - d->buf, sizeof(d->buf));
|
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/endian.h"
|
||||||
#include "tool/build/lib/machine.h"
|
#include "tool/build/lib/machine.h"
|
||||||
#include "tool/build/lib/memory.h"
|
#include "tool/build/lib/memory.h"
|
||||||
|
#include "tool/build/lib/modrm.h"
|
||||||
#include "tool/build/lib/stats.h"
|
#include "tool/build/lib/stats.h"
|
||||||
#include "tool/build/lib/throw.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];
|
struct XedDecodedInst xedd[1];
|
||||||
xed_decoded_inst_zero_set_mode(xedd, m->mode);
|
xed_decoded_inst_zero_set_mode(xedd, m->mode);
|
||||||
if (!xed_instruction_length_decode(xedd, p, n)) {
|
if (!xed_instruction_length_decode(xedd, p, n)) {
|
||||||
|
xedd->op.rde = EncodeRde(xedd);
|
||||||
memcpy(m->xedd, xedd, sizeof(m->icache[0]));
|
memcpy(m->xedd, xedd, sizeof(m->icache[0]));
|
||||||
} else {
|
} else {
|
||||||
HaltMachine(m, kMachineDecodeError);
|
HaltMachine(m, kMachineDecodeError);
|
||||||
|
|
|
@ -25,6 +25,21 @@
|
||||||
#include "tool/build/lib/modrm.h"
|
#include "tool/build/lib/modrm.h"
|
||||||
#include "tool/build/lib/throw.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) {
|
struct AddrSeg LoadEffectiveAddress(const struct Machine *m, uint32_t rde) {
|
||||||
uint8_t *s = m->ds;
|
uint8_t *s = m->ds;
|
||||||
uint64_t i = m->xedd->op.disp;
|
uint64_t i = m->xedd->op.disp;
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct AddrSeg {
|
||||||
|
|
||||||
extern const uint8_t kByteReg[32];
|
extern const uint8_t kByteReg[32];
|
||||||
|
|
||||||
|
uint32_t EncodeRde(struct XedDecodedInst *);
|
||||||
int64_t ComputeAddress(const struct Machine *, uint32_t);
|
int64_t ComputeAddress(const struct Machine *, uint32_t);
|
||||||
struct AddrSeg LoadEffectiveAddress(const struct Machine *, uint32_t);
|
struct AddrSeg LoadEffectiveAddress(const struct Machine *, uint32_t);
|
||||||
void *ComputeReserveAddressRead(struct Machine *, uint32_t, size_t);
|
void *ComputeReserveAddressRead(struct Machine *, uint32_t, size_t);
|
||||||
|
|
Loading…
Add table
Reference in a new issue