mirror of
https://github.com/radareorg/r0.git
synced 2026-11-07 23:02:41 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d0704c4e5 | ||
|
|
667723039f | ||
|
|
02af08b96c | ||
|
|
01b42dce26 | ||
|
|
39bede8372 | ||
|
|
30709b9b1d | ||
|
|
b01e0d7b34 | ||
|
|
5a5b11ef98 | ||
|
|
b3551aa7a2 | ||
|
|
b0fa755b4b | ||
|
|
7139b88824 | ||
|
|
0fce443275 | ||
|
|
3bd7ce6beb | ||
|
|
ca297b60a0 | ||
|
|
1ac42e0af6 | ||
|
|
04187f5984 | ||
|
|
8e9a02fec4 | ||
|
|
c3f761ff94 | ||
|
|
8897ce01e8 | ||
|
|
c8771027c1 | ||
|
|
f35349f466 | ||
|
|
bed3edc0cd | ||
|
|
223a733c42 | ||
|
|
8a3e45cc98 | ||
|
|
ce68d7c936 | ||
|
|
dc6bd361bb | ||
|
|
00b9e7c01f | ||
|
|
255ac37f51 | ||
|
|
5259039363 | ||
|
|
764e36319b | ||
|
|
93a2864ffb | ||
|
|
f21459b970 | ||
|
|
36de8f16bd | ||
|
|
92923ebf64 | ||
|
|
e4aecf63df | ||
|
|
b7d3b44937 | ||
|
|
596339f094 | ||
|
|
3322a0bf72 | ||
|
|
a1fa7904e6 | ||
|
|
d8583f144c | ||
|
|
2acde29402 | ||
|
|
e5297647d4 | ||
|
|
921aabad60 | ||
|
|
b312fdcb30 | ||
|
|
28ef01b9cd | ||
|
|
a1f06765a7 | ||
|
|
8603794279 | ||
|
|
bb011f88af | ||
|
|
c5498bd961 | ||
|
|
a173daa812 | ||
|
|
9096ed5126 | ||
|
|
b074f2280d | ||
|
|
ec8e0225c3 |
No files matched your search
@@ -0,0 +1,49 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
# build-windows:
|
||||
# runs-on: windows-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Windows Dependencies
|
||||
# run: pip install meson ninja
|
||||
# - name: Building Sdb
|
||||
# run: meson build && ninja -C build
|
||||
# - name: Pub
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# path: build/*.exe
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Building
|
||||
run: export CFLAGS="-Werror -Wall" && make
|
||||
# - name: Packaging
|
||||
# run: make -C dist/debian
|
||||
- name: Running tests
|
||||
run: make -C t
|
||||
- name: Pub
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: r0
|
||||
build-macos:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Building
|
||||
run: make -j4
|
||||
# - name: Packaging
|
||||
# run: cd dist/macos && make && cd ../../..
|
||||
- name: Running tests
|
||||
run: make -C t
|
||||
- name: Pub
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: r0
|
||||
@@ -0,0 +1,7 @@
|
||||
Copyright 2019 pancake
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,48 +1,113 @@
|
||||
-include config.mk
|
||||
|
||||
CC?=gcc
|
||||
VERSION=0.5
|
||||
VERSION=0.9
|
||||
CCw32?=i486-mingw32-gcc
|
||||
CFLAGS+=-O2 -Wall
|
||||
CFLAGS+=-DVERSION=\"${VERSION}\"
|
||||
CFLAGS+=-O0 -Wall -g
|
||||
#CFLAGS+=-DVERSION=\"${VERSION}\"
|
||||
PREFIX?=/usr/local
|
||||
DESTDIR?=
|
||||
|
||||
all: ired bdiff
|
||||
# ARCH: X32 X86 8086 ARM M68K
|
||||
# ARCH=X32
|
||||
# ARCH=X86
|
||||
# ARCH=M68K
|
||||
# ARCH=ARM
|
||||
ARCH=NONE
|
||||
|
||||
bdiff: bdiff.o
|
||||
${CC} ${CFLAGS} bdiff.o -o bdiff
|
||||
all: r0 r0d
|
||||
|
||||
ired.o: cmd.c io.c util.c hexparse.c
|
||||
r0: r0.o
|
||||
${CC} ${CFLAGS} r0.o -o r0
|
||||
|
||||
ired: ired.o
|
||||
${CC} ${CFLAGS} ired.o -o ired
|
||||
r0.o: calc.c cmd.c io.c util.c hexparse.c
|
||||
$(CC) -c r0.c -DUSE_DISASM_$(ARCH)=1
|
||||
|
||||
r0d: r0d.o
|
||||
${CC} ${CFLAGS} r0d.o -o r0d
|
||||
|
||||
r0.js:
|
||||
emcc -s FORCE_FILESYSTEM=1 -lnodefs.js -s EXPORTED_FUNCTIONS='["_r0_open", "_r0_cmd"]' -DUSE_DISASM_X32=1 -Os -o r0.js r0.c
|
||||
|
||||
r0.arm:
|
||||
$(CC) -DUSE_DISASM_ARM=1 r0.c -o r0.arm
|
||||
|
||||
r0.8086:
|
||||
$(CC) -fsanitize=address -g -DUSE_DISASM_8086=1 r0.c -o r0.8086
|
||||
|
||||
r0.x86:
|
||||
$(CC) -DUSE_DISASM_X32=1 -Os r0.c -o r0.x86
|
||||
# $(CC) -fsanitize=address -g -DUSE_DISASM_X86=1 r0.c -o r0.x86
|
||||
|
||||
r0.com: # msdos
|
||||
owcc -DUSE_DISASM_X32=1 r0.c -o r0.exe
|
||||
|
||||
r0.wasm:
|
||||
emcc -Os -o r0.html r0.c
|
||||
|
||||
# https://github.com/bebbo/amiga-gcc
|
||||
AMICC=/opt/amiga/bin/m68k-amigaos-gcc
|
||||
AMICFLAGS=-Os -fomit-frame-pointer -msmall-code -m68000
|
||||
AMICFLAGS+=-DUSE_DISASM_M68K=1 -DUSE_DISASM=1
|
||||
r0.amiga ami:
|
||||
rm -f r0.run
|
||||
$(AMICC) $(AMICFLAGS) -mcrt=nix20 -o r0.run r0.c
|
||||
lha c r0-nix20.lha r0.run
|
||||
ami13:
|
||||
rm -f r0.run
|
||||
$(AMICC) $(AMICFLAGS) -DR0_NOENV=1 -DHAVE_FTRUNCATE=0 -mcrt=nix13 -o r0.run r0.c
|
||||
lha c r0-nix13.lha r0.run
|
||||
|
||||
r0.bc:
|
||||
clang -emit-llvm -o r0.bc -c r0.c
|
||||
|
||||
WASI_SDK=$(HOME)/Downloads/wasi/wasi-sdk-12.0
|
||||
WASI_SYSROOT=$(HOME)/Downloads/wasi/wasi-sysroot
|
||||
|
||||
wasi:
|
||||
export CC="$(WASI_SDK)/bin/clang --sysroot=$(WASI_SYSROOT) -DHAVE_SYSTEM=0" ; $(MAKE) clean ; $(MAKE)
|
||||
mv r0 r0.wasm
|
||||
|
||||
dist:
|
||||
@if [ -z "${VERSION}" ]; then echo "Try: make dist VERSION=0.5" ; exit 1 ; fi
|
||||
git clone . ired-${VERSION}
|
||||
rm -rf ired-${VERSION}/.git
|
||||
tar czvf ired-${VERSION}.tar.gz ired-${VERSION}
|
||||
rm -rf ired-${VERSION}
|
||||
git clone . r0-${VERSION}
|
||||
rm -rf r0-${VERSION}/.git
|
||||
tar czvf r0-${VERSION}.tar.gz r0-${VERSION}
|
||||
rm -rf r0-${VERSION}
|
||||
|
||||
ios:
|
||||
$(MAKE) CC="xcrun --sdk iphoneos gcc -arch arm64 -DHAVE_SYSTEM=0"
|
||||
|
||||
ios16:
|
||||
$(MAKE) CC="xcrun --sdk iphoneos gcc -arch armv7 -mno-thumb -DHAVE_SYSTEM=0"
|
||||
|
||||
ios32:
|
||||
$(MAKE) CC="xcrun --sdk iphoneos gcc -arch armv7 -DHAVE_SYSTEM=0"
|
||||
|
||||
w32:
|
||||
${CCw32} ${CFLAGS} ired.c -o ired.exe
|
||||
${CCw32} ${CFLAGS} r0.c -o r0.exe
|
||||
|
||||
v850:
|
||||
./v850.sh
|
||||
|
||||
loc:
|
||||
@wc -l *.c *.h | grep total
|
||||
|
||||
clean:
|
||||
rm -f ired ired.o bdiff bdiff.o
|
||||
rm -f r0 r0.o r0d r0d.o
|
||||
rm -f r0.x86 r0.arm r0.wasm r0.js
|
||||
|
||||
install:
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
cp -f ired ${DESTDIR}${PREFIX}/bin
|
||||
cp -f bdiff ${DESTDIR}${PREFIX}/bin
|
||||
cp -f vired ${DESTDIR}${PREFIX}/bin
|
||||
cp -f r0 ${DESTDIR}${PREFIX}/bin
|
||||
cp -f r0d ${DESTDIR}${PREFIX}/bin
|
||||
cp -f r0v ${DESTDIR}${PREFIX}/bin
|
||||
mkdir -p ${DESTDIR}${PREFIX}/share/man/man1
|
||||
cp -f ired.1 ${DESTDIR}${PREFIX}/share/man/man1
|
||||
cp -f vired.1 ${DESTDIR}${PREFIX}/share/man/man1
|
||||
cp -f r0.1 ${DESTDIR}${PREFIX}/share/man/man1
|
||||
cp -f r0v.1 ${DESTDIR}${PREFIX}/share/man/man1
|
||||
|
||||
deinstall uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/ired
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/vired
|
||||
rm -f ${DESTDIR}${PREFIX}/share/man/man1/ired.1
|
||||
rm -f ${DESTDIR}${PREFIX}/share/man/man1/vired.1
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/r0
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/r0v
|
||||
rm -f ${DESTDIR}${PREFIX}/share/man/man1/r0.1
|
||||
rm -f ${DESTDIR}${PREFIX}/share/man/man1/r0v.1
|
||||
@@ -1,47 +1,64 @@
|
||||
IRED stands for the independent raw editor
|
||||
==========================================
|
||||
# R0 stands for radare-zero
|
||||
|
||||
red aims to be a minimalistic reimplementation of the radare shell
|
||||
[](https://github.com/radareorg/r0/actions/workflows/ci.yml)
|
||||
|
||||
r0 aims to be a minimalistic reimplementation of the radare shell
|
||||
without much complexity and relaying all the extensibility to external
|
||||
applications trying to keep the source as small as possible.
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
pancake<nopcode.org>
|
||||
## Features
|
||||
|
||||
COMMANDS
|
||||
========
|
||||
* Small footprint (50KB)
|
||||
* Minimalistic Intel and ARM disassemblers (90KB)
|
||||
* Minimum set of commands to inspect and manipulate binaries
|
||||
* r0d does binary diffing and patching files
|
||||
* r0v is the visual interactive frontend of r0
|
||||
* Very portable: Compiles for wasm, js.. even for MS-DOS!
|
||||
* Single binary without any external dependency
|
||||
|
||||
? is for help get help or evaluate numeric expression
|
||||
/ search search strings or hexpairs
|
||||
!cmd run command from shell
|
||||
x hexdump hexdump
|
||||
X dword dump hexpair dump
|
||||
> file dump current block to file
|
||||
< file slurp file into current block
|
||||
w "string\x00" write string
|
||||
w 023839400 write hexpairs
|
||||
b 30 set block size
|
||||
s addr seek address
|
||||
r [size|-rmv] get filesize, truncate file to size, or -remove bytes
|
||||
p [bwWdDqQiIF.] print formatted the current block
|
||||
q quit
|
||||
## AUTHOR
|
||||
* pancake<nopcode.org>
|
||||
|
||||
## COMMANDS
|
||||
|
||||
```
|
||||
[0x00000000]> ?
|
||||
s[+-addr] seek to relative or absolute address
|
||||
b[+-size] change block size
|
||||
w[hex|"str"] write hexpair or string
|
||||
/[hex|"str"] search hexpair or string
|
||||
x[size] hexdump
|
||||
d[size] disassemble n bytes
|
||||
X[size] hexpair dump
|
||||
p[fmt] print formatted current block ('p' for help)
|
||||
d[size] disasemble
|
||||
r[+-[num]] truncate or -remove N bytes
|
||||
.[file] interpret file
|
||||
<[file] load file in current seek
|
||||
>[file] dump current block to file
|
||||
!cmd run shell command
|
||||
?expr calculate numeric expression
|
||||
q quit
|
||||
[0x00000000]>
|
||||
```
|
||||
|
||||
WORK IN PROGRESS
|
||||
================
|
||||
print command
|
||||
b/w/d/q byte, word, dword, qword (little endian)
|
||||
B/W/D/Q byte, word, dword, qword (big endian)
|
||||
i/I/f/F int32 (lil, big), float (lil, big)
|
||||
z/Z zero-terminatted strings (ascii, widechar)
|
||||
./: skip 1 or 4 chars
|
||||
* repeat last value until death
|
||||
|
||||
```
|
||||
[0x00000000]> p?
|
||||
ob/wW/dD/qQ byte (oct,hex), word, dword, qword (lil, big endian)
|
||||
i/I/f/F int32 (lil, big), float (lil, big)
|
||||
s/S short int16 (lil, big)
|
||||
z/Z zero-terminatted string (ascii, wide-ascii)
|
||||
./:/* skip 1 or 4 chars, repeat last format instead of cycle
|
||||
```
|
||||
|
||||
PORTABILITY
|
||||
===========
|
||||
ired is known to build and run on several OS.
|
||||
- GNU, Linux, OSX, Windows (mingw), cygwin, Solaris, BSD, ...
|
||||
r0 is known to build and run on several OS.
|
||||
- GNU/Hurd, Plan9, DOS, BSD, Solaris, Linux, macOS, Windows, Wasm, Javascript, ...
|
||||
|
||||
TODO:
|
||||
=====
|
||||
|
||||
@@ -0,0 +1,334 @@
|
||||
/* ported to C by pancake for r2 in 2012-2013 */
|
||||
// TODO: integrate floating point support
|
||||
// TODO: do not use global variables
|
||||
/*
|
||||
Reference Chapter 6:
|
||||
"The C++ Programming Language", Special Edition.
|
||||
Bjarne Stroustrup,Addison-Wesley Pub Co; 3 edition (February 15, 2000)
|
||||
ISBN: 0201700735
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define R_API
|
||||
#define R_NUMCALC_STRSZ 4096
|
||||
|
||||
typedef struct {
|
||||
double d;
|
||||
ut64 n;
|
||||
} RNumCalcValue;
|
||||
typedef enum {
|
||||
RNCNAME, RNCNUMBER, RNCEND, RNCINC, RNCDEC,
|
||||
RNCPLUS='+', RNCMINUS='-', RNCMUL='*', RNCDIV='/',
|
||||
//RNCXOR='^', RNCOR='|', RNCAND='&',
|
||||
RNCPRINT=';', RNCASSIGN='=', RNCLEFTP='(', RNCRIGHTP=')'
|
||||
} RNumCalcToken;
|
||||
|
||||
typedef struct r_num_calc_t {
|
||||
RNumCalcToken curr_tok;
|
||||
RNumCalcValue number_value;
|
||||
char string_value[R_NUMCALC_STRSZ];
|
||||
int errors;
|
||||
char oc;
|
||||
const char *calc_err;
|
||||
int calc_i;
|
||||
const char *calc_buf;
|
||||
int calc_len;
|
||||
} RNumCalc;
|
||||
|
||||
|
||||
typedef struct r_num_t {
|
||||
ut64 (*callback)(struct r_num_t *userptr, const char *str, int *ok);
|
||||
// RNumCallback callback;
|
||||
ut64 value;
|
||||
double fvalue;
|
||||
void *userptr;
|
||||
RNumCalc nc;
|
||||
} RNum;
|
||||
/* accessors */
|
||||
static inline RNumCalcValue Nset(ut64 v) { RNumCalcValue n; n.d = (double)v; n.n = v; return n; }
|
||||
static inline RNumCalcValue Nsetf(double v) { RNumCalcValue n; n.d = v; n.n = (ut64)v; return n; }
|
||||
static inline RNumCalcValue Naddf(RNumCalcValue n, double v) { n.d += v; n.n += (ut64)v; return n; }
|
||||
static inline RNumCalcValue Naddi(RNumCalcValue n, ut64 v) { n.d += (double)v; n.n += v; return n; }
|
||||
static inline RNumCalcValue Nsubi(RNumCalcValue n, ut64 v) { n.d -= (double)v; n.n -= v; return n; }
|
||||
static inline RNumCalcValue Nadd(RNumCalcValue n, RNumCalcValue v) { n.d += v.d; n.n += v.n; return n; }
|
||||
static inline RNumCalcValue Nsub(RNumCalcValue n, RNumCalcValue v) { n.d -= v.d; n.n -= v.n; return n; }
|
||||
static inline RNumCalcValue Nmul(RNumCalcValue n, RNumCalcValue v) { n.d *= v.d; n.n *= v.n; return n; }
|
||||
static inline RNumCalcValue Ndiv(RNumCalcValue n, RNumCalcValue v) {
|
||||
if (v.d) n.d /= v.d; else n.d = 0;
|
||||
if (v.n) n.n /= v.n; else n.n = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
static RNumCalcValue expr(RNum*, RNumCalc*, int);
|
||||
static RNumCalcValue term(RNum*, RNumCalc*, int);
|
||||
static void error(RNum*, RNumCalc*, const char *);
|
||||
static RNumCalcValue prim(RNum*, RNumCalc*, int);
|
||||
static RNumCalcToken get_token(RNum*, RNumCalc*);
|
||||
|
||||
static void error(RNum *num, RNumCalc *nc, const char *s) {
|
||||
nc->errors++;
|
||||
nc->calc_err = s;
|
||||
//fprintf (stderr, "error: %s\n", s);
|
||||
}
|
||||
|
||||
static RNumCalcValue expr(RNum *num, RNumCalc *nc, int get) {
|
||||
RNumCalcValue left = term (num, nc, get);
|
||||
for (;;) {
|
||||
if (nc->curr_tok == RNCPLUS)
|
||||
left = Nadd (left, term (num, nc, 1));
|
||||
else if (nc->curr_tok == RNCMINUS)
|
||||
left = Nsub (left, term (num, nc, 1));
|
||||
else break;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
static RNumCalcValue term(RNum *num, RNumCalc *nc, int get) {
|
||||
RNumCalcValue left = prim (num, nc, get);
|
||||
for (;;) {
|
||||
if (nc->curr_tok == RNCMUL) {
|
||||
left = Nmul (left, prim (num, nc, 1));
|
||||
} else
|
||||
if (nc->curr_tok == RNCDIV) {
|
||||
RNumCalcValue d = prim (num, nc, 1);
|
||||
if (!d.d) {
|
||||
error (num, nc, "divide by 0");
|
||||
return d;
|
||||
}
|
||||
left = Ndiv (left, d);
|
||||
} else return left;
|
||||
}
|
||||
}
|
||||
|
||||
static RNumCalcValue prim(RNum *num, RNumCalc *nc, int get) {
|
||||
char *p;
|
||||
RNumCalcValue v = {0};
|
||||
if (get) get_token (num, nc);
|
||||
switch (nc->curr_tok) {
|
||||
case RNCNUMBER:
|
||||
v = nc->number_value;
|
||||
get_token (num, nc);
|
||||
return v;
|
||||
case RNCNAME:
|
||||
for(p=nc->string_value;*p&&*p==' ';p++) {};
|
||||
v = Nset (str2ut64 (nc->string_value));
|
||||
get_token (num, nc);
|
||||
if (nc->curr_tok == RNCASSIGN)
|
||||
v = expr (num, nc, 1);
|
||||
if (nc->curr_tok == RNCINC) Naddi (v, 1);
|
||||
if (nc->curr_tok == RNCDEC) Nsubi (v, 1);
|
||||
return v;
|
||||
case RNCINC: return Naddi (prim (num, nc, 1), 1);
|
||||
case RNCDEC: return Naddi (prim (num, nc, 1), -1);
|
||||
case RNCMINUS: return Nsub (v, prim (num, nc, 1));
|
||||
case RNCLEFTP:
|
||||
v = expr (num, nc, 1);
|
||||
if (nc->curr_tok == RNCRIGHTP)
|
||||
get_token (num, nc);
|
||||
else error (num, nc, " ')' expected");
|
||||
case RNCEND:
|
||||
case RNCPLUS:
|
||||
case RNCMUL:
|
||||
case RNCDIV:
|
||||
case RNCPRINT:
|
||||
case RNCASSIGN:
|
||||
case RNCRIGHTP:
|
||||
return v;
|
||||
//default: error (num, nc, "primary expected");
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static void cin_putback (RNum *num, RNumCalc *nc, char c) {
|
||||
nc->oc = c;
|
||||
}
|
||||
|
||||
R_API const char *r_num_calc_index(RNum *num, const char *p) {
|
||||
if (num == NULL)
|
||||
return NULL;
|
||||
if (p) {
|
||||
num->nc.calc_buf = p;
|
||||
num->nc.calc_len = strlen (p);
|
||||
num->nc.calc_i = 0;
|
||||
}
|
||||
//if (num->nc.calc_i>num->nc.calc_len) return NULL;
|
||||
return num->nc.calc_buf + num->nc.calc_i;
|
||||
}
|
||||
|
||||
static int cin_get(RNumCalc *nc, char *c) {
|
||||
if (nc->oc) {
|
||||
*c = nc->oc;
|
||||
nc->oc = 0;
|
||||
} else {
|
||||
if (!nc->calc_buf)
|
||||
return 0;
|
||||
//if (nc->calc_i>nc->calc_len) return 0;
|
||||
*c = nc->calc_buf[nc->calc_i];
|
||||
if (*c) nc->calc_i++;
|
||||
else return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cin_get_num(RNum *num, RNumCalc *nc, RNumCalcValue *n) {
|
||||
char c, str[R_NUMCALC_STRSZ];
|
||||
double d;
|
||||
int i = 0;
|
||||
str[0] = 0;
|
||||
while (cin_get (nc, &c)) {
|
||||
if (c!=':' && c!='.' && !isalnum (c)) {
|
||||
cin_putback (num, nc, c);
|
||||
break;
|
||||
}
|
||||
if (i<R_NUMCALC_STRSZ)
|
||||
str[i++] = c;
|
||||
}
|
||||
str[i] = 0;
|
||||
*n = Nset (str2ut64 (str));
|
||||
if (*str>='0' && *str<='9' && strchr (str, '.')) {
|
||||
if (sscanf (str, "%lf", &d)<1)
|
||||
return 0;
|
||||
*n = Nsetf (d);
|
||||
}
|
||||
#if 0
|
||||
// XXX: use r_num_get here
|
||||
if (str[0]=='0' && str[1]=='x') {
|
||||
ut64 x = 0;
|
||||
if (sscanf (str+2, "%llx", &x)<1)
|
||||
return 0;
|
||||
*n = Nset (x);
|
||||
} else
|
||||
if (strchr (str, '.')) {
|
||||
if (sscanf (str, "%lf", &d)<1)
|
||||
return 0;
|
||||
*n = Nsetf (d);
|
||||
} else {
|
||||
ut64 u;
|
||||
if (sscanf (str, "%"PFMT64d, &u)<1)
|
||||
return 0;
|
||||
*n = Nset (u);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static RNumCalcToken get_token(RNum *num, RNumCalc *nc) {
|
||||
char ch = 0, c = 0;
|
||||
|
||||
do { if (!cin_get (nc, &ch)) return nc->curr_tok = RNCEND;
|
||||
} while (ch!='\n' && isspace (ch));
|
||||
|
||||
switch (ch) {
|
||||
case 0:
|
||||
case ';':
|
||||
case '\n':
|
||||
return nc->curr_tok = RNCEND;
|
||||
case '+': // added for ++name and name++
|
||||
if (cin_get (nc, &c) && c == '+')
|
||||
return nc->curr_tok = RNCINC;
|
||||
cin_putback (num, nc, c);
|
||||
return nc->curr_tok = (RNumCalcToken) ch;
|
||||
case '-':
|
||||
if (cin_get (nc, &c) && c == '-')
|
||||
return nc->curr_tok = RNCDEC;
|
||||
cin_putback (num, nc, c);
|
||||
return nc->curr_tok = (RNumCalcToken) ch;
|
||||
case '*':
|
||||
case '/':
|
||||
case '(':
|
||||
case ')':
|
||||
case '=':
|
||||
return nc->curr_tok = (RNumCalcToken) ch;
|
||||
case '0':case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case '.':
|
||||
cin_putback (num, nc, ch);
|
||||
if (!cin_get_num (num, nc, &nc->number_value)) {
|
||||
error (num, nc, "invalid number conversion");
|
||||
return 1;
|
||||
}
|
||||
return nc->curr_tok = RNCNUMBER;
|
||||
default:
|
||||
#define isvalidchar(x) \
|
||||
(isalnum(x) || x==':' || x=='$' || x=='.' || x=='_' || x=='?' || x=='\\' \
|
||||
|| x==' ' || x=='[' || x==']' || x=='}' || x=='{' || x=='/' || (x>='0'&&x<='9'))
|
||||
{
|
||||
int i = 0;
|
||||
nc->string_value[i++] = ch;
|
||||
if (ch == '[') {
|
||||
while (cin_get (nc, &ch) && ch!=']') {
|
||||
if (i>=R_NUMCALC_STRSZ) {
|
||||
error (num, nc, "string too long");
|
||||
return 0;
|
||||
}
|
||||
nc->string_value[i++] = ch;
|
||||
}
|
||||
nc->string_value[i++] = ch;
|
||||
} else {
|
||||
while (cin_get (nc, &ch) && isvalidchar (ch)) {
|
||||
if (i>=R_NUMCALC_STRSZ) {
|
||||
error (num, nc, "string too long");
|
||||
return 0;
|
||||
}
|
||||
nc->string_value[i++] = ch;
|
||||
}
|
||||
}
|
||||
nc->string_value[i] = 0;
|
||||
cin_putback (num, nc, ch);
|
||||
|
||||
return nc->curr_tok = RNCNAME;
|
||||
}
|
||||
//}
|
||||
error (num, nc, "bad token");
|
||||
return nc->curr_tok = RNCPRINT;
|
||||
}
|
||||
}
|
||||
|
||||
static void load_token(RNum *num, RNumCalc *nc, const char *s) {
|
||||
nc->calc_i = 0;
|
||||
nc->calc_len = 0;
|
||||
nc->calc_buf = s;
|
||||
nc->calc_err = NULL;
|
||||
}
|
||||
|
||||
R_API ut64 r_num_calc(RNum *num, const char *str, const char **err) {
|
||||
RNumCalcValue n;
|
||||
RNumCalc *nc, nc_local;
|
||||
if (!str || !*str)
|
||||
return 0LL;
|
||||
|
||||
if (num == NULL)
|
||||
nc = &nc_local;
|
||||
else nc = &num->nc;
|
||||
|
||||
/* init */
|
||||
nc->curr_tok = RNCPRINT;
|
||||
nc->number_value.d = 0.0;
|
||||
nc->number_value.n = 0LL;
|
||||
nc->errors = 0;
|
||||
nc->oc = 0;
|
||||
nc->calc_err = NULL;
|
||||
nc->calc_i = 0;
|
||||
nc->calc_len = 0;
|
||||
nc->calc_buf = NULL;
|
||||
|
||||
load_token (num, nc, str);
|
||||
get_token (num, nc);
|
||||
n = expr (num, nc, 0);
|
||||
if (err) *err = nc->calc_err;
|
||||
//if (nc->curr_tok == RNCEND) return 0LL; // XXX: Error
|
||||
//if (nc->curr_tok == RNCPRINT) //return 0LL; // XXX: the fuck
|
||||
// n = expr (num, nc, 0);
|
||||
if (n.d != ((double)(ut64)n.d)) {
|
||||
if (num) num->fvalue = n.d;
|
||||
} else if (num) num->fvalue = (double)n.n;
|
||||
return n.n;
|
||||
}
|
||||
|
||||
R_API ut64 calc(const char *str) {
|
||||
return r_num_calc (NULL, str, NULL);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,30 @@
|
||||
/* Copyleft 2009-2013 -- pancake /at/ nopcode /dot/ org */
|
||||
/* cmd.c - MIT - Copyright 2009-2023 -- pancake /at/ nopcode /dot/ org */
|
||||
|
||||
static int cmd_hexdump(char *arg) {
|
||||
#ifndef HAVE_SYSTEM
|
||||
#define HAVE_SYSTEM 1
|
||||
#endif
|
||||
|
||||
#define USE_DISASM 1
|
||||
#if USE_DISASM_X86
|
||||
#include "dis/x86.c"
|
||||
#elif USE_DISASM_X32
|
||||
#include "dis/x32.c"
|
||||
#elif USE_DISASM_8086
|
||||
#include "dis/8086.c"
|
||||
#elif USE_DISASM_ARM
|
||||
#include "dis/arm.c"
|
||||
#elif USE_DISASM_M68K
|
||||
// #define M68030 1
|
||||
// #define M68020 1
|
||||
// #define M68010 1
|
||||
#include "dis/m68k.c"
|
||||
#else
|
||||
#undef USE_DISASM
|
||||
#define USE_DISASM 0
|
||||
#endif
|
||||
|
||||
|
||||
static int cmd_hexdump(const char *arg) {
|
||||
int len = bsize;
|
||||
ut8 *buf = getcurblk(arg, &len);
|
||||
if(buf && len>0) {
|
||||
@@ -11,7 +35,7 @@ static int cmd_hexdump(char *arg) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int cmd_print(char *arg) {
|
||||
static int cmd_print(const char *arg) {
|
||||
ut8 *buf;
|
||||
int len = bsize;
|
||||
if(*arg) {
|
||||
@@ -28,6 +52,78 @@ static int cmd_print(char *arg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_system(const char *arg) {
|
||||
int len = bsize;
|
||||
char str[1024];
|
||||
ut8 *buf;
|
||||
if(strstr(arg, "BLOCK")) {
|
||||
FILE *fd = fopen(".curblk", "wb");
|
||||
if(fd) {
|
||||
if((buf = getcurblk("", &len))) {
|
||||
setenv("BLOCK", ".curblk", 1);
|
||||
fwrite(buf, len, 1, fd);
|
||||
free(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
if(strstr(arg, "BSIZE")) {
|
||||
sprintf(str, "%d", len);
|
||||
setenv("BSIZE", str, 1);
|
||||
}
|
||||
if(strstr(arg, "OFFSET")) {
|
||||
sprintf(str, "%"LLF"d", curseek);
|
||||
setenv("OFFSET", str, 1);
|
||||
}
|
||||
if(strstr(arg, "XOFFSET")) {
|
||||
sprintf(str, "0x%"LLF"x", curseek);
|
||||
setenv("XOFFSET", str, 1);
|
||||
}
|
||||
#if HAVE_SYSTEM
|
||||
if(io_system(arg)<0)
|
||||
perror("system");
|
||||
#endif
|
||||
unlink(".curblk");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if USE_DISASM
|
||||
static int cmd_disasm(const char *arg) {
|
||||
char output[256];
|
||||
int i, j, len = bsize, ilen;
|
||||
int pad = 8;
|
||||
ut8 *buf = getcurblk(arg, &len);
|
||||
if (!buf) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
for(i = 0; i < len ;i++) {
|
||||
*output = 0;
|
||||
ilen = disasm(buf + i, len - i, curseek+i, output);
|
||||
printf("0x%08"LLF"x ", curseek+i);
|
||||
pad = 10;
|
||||
if (ilen > 0) {
|
||||
pad -= ilen;
|
||||
for(j=i;j < i+ilen && j < len;j++)
|
||||
printf("%02x", buf[j]);
|
||||
i += ilen - 1;
|
||||
if (pad > 0)
|
||||
for (j = i; j< i+pad;j++)
|
||||
printf(" ");
|
||||
} else {
|
||||
strcpy(output, "invalid");
|
||||
}
|
||||
printf("%s\n", output);
|
||||
}
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
static int cmd_disasm(const char *arg) {
|
||||
return cmd_system("echo X | r0 -n $BLOCK | rasm2 -o $OFFSET -D -"); // |head -n $(($LINES-1))");
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cmd_bytedump(const char *arg) {
|
||||
int i, len = bsize;
|
||||
ut8 *buf = getcurblk(arg, &len);
|
||||
@@ -68,26 +164,26 @@ static int cmd_search(const char *arg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_bsize(char *arg) {
|
||||
static int cmd_bsize(const char *arg) {
|
||||
if(!*arg) printf("%d\n", bsize);
|
||||
else if(*arg=='+') bsize += (int)str2ut64(arg+1);
|
||||
else if(*arg=='-') bsize -= (int)str2ut64(arg+1);
|
||||
else bsize = str2ut64(arg);
|
||||
else if(*arg=='+') bsize += (int)calc(arg+1);
|
||||
else if(*arg=='-') bsize -= (int)calc(arg+1);
|
||||
else bsize = calc(arg);
|
||||
if(bsize<1) bsize = 1;
|
||||
obsize = bsize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_seek(char *arg) {
|
||||
static int cmd_seek(const char *arg) {
|
||||
if(!*arg) printf("%"LLF"d\n", curseek);
|
||||
else if(*arg=='+') curseek += str2ut64(arg+1);
|
||||
else if(*arg=='-') curseek -= str2ut64(arg+1);
|
||||
else curseek = str2ut64(arg);
|
||||
else if(*arg=='+') curseek += calc(arg+1);
|
||||
else if(*arg=='-') curseek -= calc(arg+1);
|
||||
else curseek = calc(arg);
|
||||
io_seek((oldseek=curseek), 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_dump(char *file) {
|
||||
static int cmd_dump(const char *file) {
|
||||
int len = bsize;
|
||||
ut8 *buf = getcurblk("", &len);
|
||||
if(len<1 || buf) {
|
||||
@@ -106,7 +202,7 @@ static int cmd_dump(char *file) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_load(char *file) {
|
||||
static int cmd_load(const char *file) {
|
||||
FILE *fd = fopen(file, "rb");
|
||||
if(fd) {
|
||||
void *buf = malloc(bsize);
|
||||
@@ -144,7 +240,7 @@ static int cmd_write(const char *arg) {
|
||||
return 2;
|
||||
}
|
||||
io_seek(curseek, SEEK_SET);
|
||||
if(len<1 || io_write(barg, len)<len) {
|
||||
if(io_write(barg, len)<len) {
|
||||
perror("io_write");
|
||||
return -1;
|
||||
}
|
||||
@@ -152,9 +248,9 @@ static int cmd_write(const char *arg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_help(char *arg) {
|
||||
static int cmd_help(const char *arg) {
|
||||
if(*arg) {
|
||||
ut64 ret = str2ut64(arg);
|
||||
ut64 ret = r_num_calc (NULL, arg, NULL);
|
||||
printf("0x%"LLF"x %"LLF"d 0%"LLF"o\n", ret, ret, ret);
|
||||
} else printf(
|
||||
"s[+-addr] seek to relative or absolute address\n"
|
||||
@@ -162,8 +258,10 @@ static int cmd_help(char *arg) {
|
||||
"w[hex|\"str\"] write hexpair or string\n"
|
||||
"/[hex|\"str\"] search hexpair or string\n"
|
||||
"x[size] hexdump\n"
|
||||
"d[size] disassemble n bytes\n"
|
||||
"X[size] hexpair dump\n"
|
||||
"p[fmt] print formatted current block ('p' for help)\n"
|
||||
"d[size] disasemble\n"
|
||||
"r[+-[num]] truncate or -remove N bytes\n"
|
||||
".[file] interpret file\n"
|
||||
"<[file] load file in current seek\n"
|
||||
@@ -174,7 +272,7 @@ static int cmd_help(char *arg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_resize(char *arg) {
|
||||
static int cmd_resize(const char *arg) {
|
||||
ut8 *buf;
|
||||
ut64 tail, n;
|
||||
int i, len, ret = 0;
|
||||
@@ -183,21 +281,24 @@ static int cmd_resize(char *arg) {
|
||||
printf("%"LLF"d\n", (ut64)io_seek(0, SEEK_END));
|
||||
break;
|
||||
case '+': // XXX: needs cleanup
|
||||
n = str2ut64(arg+1);
|
||||
n = calc(arg+1);
|
||||
len = (ut64)io_seek(0, SEEK_END);
|
||||
tail = len-curseek;
|
||||
if((buf=malloc(tail))) { // XXX: Use block
|
||||
io_seek(curseek, SEEK_SET);
|
||||
io_read(buf, tail);
|
||||
io_seek(curseek+n, SEEK_SET);
|
||||
io_write(buf, tail);
|
||||
free (buf);
|
||||
i = io_read(buf, tail);
|
||||
if (i > 0) {
|
||||
io_seek(curseek+n, SEEK_SET);
|
||||
if (io_write(buf, tail) < 1)
|
||||
perror ("write");
|
||||
free (buf);
|
||||
}
|
||||
} else perror("malloc");
|
||||
break;
|
||||
case '-':
|
||||
buf = malloc(bsize);
|
||||
if(buf) {
|
||||
n = str2ut64(arg+1);
|
||||
n = calc(arg+1);
|
||||
for(i=0;!ret;i+=len) {
|
||||
io_seek(curseek+n+i, SEEK_SET);
|
||||
if((len = io_read(buf, bsize))>0) {
|
||||
@@ -212,38 +313,9 @@ static int cmd_resize(char *arg) {
|
||||
} else perror("malloc");
|
||||
break;
|
||||
default:
|
||||
ret = io_truncate(str2ut64(arg));
|
||||
ret = io_truncate(calc(arg));
|
||||
}
|
||||
if(ret<0) perror("truncate");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_system(char *arg) {
|
||||
int len = bsize;
|
||||
char str[1024];
|
||||
ut8 *buf;
|
||||
if(strstr(arg, "BLOCK")) {
|
||||
FILE *fd = fopen(".curblk", "wb");
|
||||
if(fd) {
|
||||
if((buf = getcurblk("", &len))) {
|
||||
setenv("BLOCK", ".curblk", 1);
|
||||
if(fwrite(buf, len, 1, fd)<len)
|
||||
perror("fwrite");
|
||||
free(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
if(strstr(arg, "OFFSET")) {
|
||||
sprintf(str, "%"LLF"d", curseek);
|
||||
setenv("OFFSET", str, 1);
|
||||
}
|
||||
if(strstr(arg, "XOFFSET")) {
|
||||
sprintf(str, "0x%"LLF"x", curseek);
|
||||
setenv("XOFFSET", str, 1);
|
||||
}
|
||||
if(io_system(arg)<0)
|
||||
perror("system");
|
||||
unlink(".curblk");
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
VERSION=@VERSION@
|
||||
PREFIX=@PREFIX@
|
||||
@@ -0,0 +1,382 @@
|
||||
#!/bin/sh
|
||||
# This script was automatically generated by ACR v2.1.2
|
||||
# @author: pancake <nopcode.org>
|
||||
# @url: http://www.nopcode.org
|
||||
# @repo: git clone https://github.com/radare/acr
|
||||
|
||||
[ -z "${AWK}" ] && AWK=awk
|
||||
do_remove() {
|
||||
if [ "${ACR_RMFILES}" ]; then
|
||||
printf "cleaning temporally files... "
|
||||
rm -f ${ACR_RMFILES}
|
||||
echo "done"
|
||||
fi
|
||||
}
|
||||
control_c() {
|
||||
printf "\n\n^C control-c : script execution interrupted.\n"
|
||||
do_remove
|
||||
exit 1
|
||||
}
|
||||
trap control_c 2
|
||||
split_host() {
|
||||
S="$"
|
||||
while : ; do
|
||||
ENVWORDS="${ENVWORDS} $1_CPU $1_OS"
|
||||
STR=`eval "echo ${S}$1"`
|
||||
SPLIT_CPU="`echo "$STR" | cut -d - -f 1`"
|
||||
SPLIT_OS="`echo "$STR" | $AWK -F - '{
|
||||
if ($2=="unknown"){
|
||||
if (NF<3) { print $2; } else { print $3; }
|
||||
} else {
|
||||
if ($2=="linux") { print $2; } else
|
||||
if (NF<3) { print $2; } else { print $3; }
|
||||
}
|
||||
}'`"
|
||||
eval "$1_CPU=\"$SPLIT_CPU\""
|
||||
eval "$1_OS=\"$SPLIT_OS\""
|
||||
shift
|
||||
[ -z "$1" ] && break
|
||||
done
|
||||
}
|
||||
|
||||
QUIET=0
|
||||
be_quiet() {
|
||||
QUIET=1
|
||||
}
|
||||
|
||||
VPATH=`dirname ${0}`
|
||||
if [ "${VPATH}" = "." ]; then
|
||||
WODIS=current
|
||||
else
|
||||
if [ "${VPATH}" = "${PWD}" ]; then
|
||||
VPATH=.
|
||||
WODIS=current
|
||||
else
|
||||
WODIS=crosspath
|
||||
CURDIR=$PWD
|
||||
cd $VPATH
|
||||
VPATH="${PWD}/"
|
||||
cd $CURDIR
|
||||
fi
|
||||
fi
|
||||
|
||||
guess_os() {
|
||||
if [ -e "${VPATH}/config.guess" ]; then
|
||||
sh ${VPATH}/config.guess
|
||||
return
|
||||
fi
|
||||
CPU="`uname -m|sed -e 's, ,,g'|cut -d - -f 1`"
|
||||
OS="`uname -s|tr A-Z a-z`"
|
||||
uname -r | grep -qE "(Microsoft|WSL)" 2>/dev/null && OS="wsl"
|
||||
GNU="`uname --help 2>&1 | grep gnu`"
|
||||
[ "${GNU}" ] && OS="${OS}-gnu"
|
||||
[ "${CPU}" = ppc ] && CPU="powerpc"
|
||||
echo "${CPU}-unknown-${OS}"
|
||||
}
|
||||
|
||||
SEARCHPATH="/usr /usr/local /usr/pkg /sw"
|
||||
|
||||
: ${PREFIX:=/usr/local}
|
||||
CROSSBUILD=0
|
||||
BUILD=`guess_os`
|
||||
HOST="${BUILD}"
|
||||
TARGET="${HOST}"
|
||||
ETCDIR="/etc"
|
||||
SYSCONFDIR=""
|
||||
DESCRIPTION=""
|
||||
|
||||
create_environ() {
|
||||
: ${EPREFIX:="${PREFIX}"}
|
||||
: ${SPREFIX:="${PREFIX}"}
|
||||
: ${BINDIR:="${SPREFIX}/bin"}
|
||||
: ${SBINDIR:="${PREFIX}/sbin"}
|
||||
: ${ETCDIR:="${SPREFIX}/etc"}
|
||||
: ${LIBDIR:="${SPREFIX}/lib"}
|
||||
: ${PKGCFG_LIBDIR:='${exec_prefix}/lib'}
|
||||
: ${PKGCFG_INCDIR:='${prefix}/include'}
|
||||
: ${LIBEXECDIR:="${SPREFIX}/libexec"}
|
||||
: ${INCLUDEDIR:="${SPREFIX}/include"}
|
||||
: ${DATADIR:="${SPREFIX}/share"}
|
||||
: ${INFODIR:="${DATADIR}/info"}
|
||||
: ${MANDIR:="${DATADIR}/man"}
|
||||
: ${DOCDIR:="${DATADIR}/doc/r0"}
|
||||
: ${LOCALSTATEDIR:="${SPREFIX}/var"}
|
||||
for A in `echo ${PATH} | sed -e 's,:, ,g'` ; do
|
||||
[ -e "$A"/ginstall ] && : ${INSTALL:="$A"/ginstall} && break
|
||||
[ -e "$A"/install ] && : ${INSTALL:="$A"/install} && break
|
||||
done
|
||||
: ${INSTALL_DIR:=${INSTALL} -d}
|
||||
: ${INSTALL_DATA:=${INSTALL} -m 644}
|
||||
: ${INSTALL_SCRIPT:=${INSTALL} -m 755}
|
||||
: ${INSTALL_PROGRAM:=${INSTALL} -m 755}
|
||||
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
|
||||
: ${INSTALL_MAN:=${INSTALL} -m 444}
|
||||
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
|
||||
PKGNAME='r0' ; VERSION='0.9' ; VERSION_MAJOR=0; VERSION_MINOR=9; VERSION_PATCH=0; VERSION_NUMBER=00900; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF2
|
||||
'configure' configures r0-0.9 to adapt to many kinds of systems.
|
||||
|
||||
Usage: ./configure [OPTION]... [VAR=VALUE]...
|
||||
|
||||
To assign environment variables (e.g., CC, CFLAGS...), specify them as
|
||||
VAR=VALUE. See below for descriptions of some of the useful variables.
|
||||
|
||||
Defaults for the options are specified in brackets.
|
||||
|
||||
Configuration:
|
||||
-h, --help display this help and exit
|
||||
-r, --report show what libs/programs require to work
|
||||
-q, --quiet be quiet, less verbose (see ./configure -qV)
|
||||
-V, --version display version information and exit
|
||||
|
||||
Installation directories:
|
||||
--exec-prefix=EPREFIX install arch-dependent files in EPREFIX [PREFIX]
|
||||
--prefix=PREFIX install arch-independent files in PREFIX [/usr/local]
|
||||
--sandbox=SPREFIX sandbox prefix directory: SPREFIX [PREFIX]
|
||||
|
||||
Fine tuning of the installation directories:
|
||||
--bindir=DIR user executables [EPREFIX/bin]
|
||||
--datadir=DIR read-only architecture-independent data [PREFIX/share]
|
||||
--docdir=DIR documentation directory [DATADIR/doc/r0]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--infodir=DIR info documentation [DATADIR/info]
|
||||
--libexecdir=DIR program executables [EPREFIX/libexec]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--libpath=DIR set rpath/libname-path to linker
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--mandir=DIR man documentation [DATADIR/man]
|
||||
--sbindir=DIR system admin executables [EPREFIX/sbin]
|
||||
--etcdir=DIR same as --sysconfdir (/etc)
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
|
||||
System types:
|
||||
--build=BUILD configure for building on BUILD [guessed]
|
||||
--host=HOST cross-compile to build programs to run on HOST [BUILD]
|
||||
--target=TARGET configure for building compilers for TARGET [HOST]
|
||||
EOF2
|
||||
|
||||
printf "
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
CFLAGS C compiler flags
|
||||
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
||||
nonstandard directory <lib dir>
|
||||
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
|
||||
headers in a nonstandard directory <include dir>
|
||||
CPP C preprocessor
|
||||
"
|
||||
printf "
|
||||
Report bugs to: pancake <[email protected]>"
|
||||
echo ""
|
||||
exit 0
|
||||
}
|
||||
|
||||
take_environ() {
|
||||
: ${SH:=/bin/sh}
|
||||
: ${CPP:=cpp}
|
||||
: ${CC:=gcc}
|
||||
: ${PREFIX:=/usr/local/}
|
||||
}
|
||||
|
||||
ochof() {
|
||||
[ "$QUIET" = 1 ] && return
|
||||
printf "$*"
|
||||
}
|
||||
|
||||
ocho() {
|
||||
[ "$QUIET" = 1 ] && return
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
show_version() {
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
echo "0.9"
|
||||
exit 0
|
||||
fi
|
||||
echo "r0-0.9 configuration script done with acr v2.1.2.
|
||||
The 'Free Software Foundation' message is only for autodetection.
|
||||
Originally written by pancake <nopcode.org>."
|
||||
exit 0
|
||||
}
|
||||
|
||||
parse_options() {
|
||||
flag=`echo $1| cut -d = -f 1`
|
||||
value=`echo $1| $AWK 'BEGIN{FS="=";}{print $2}'`
|
||||
flag2=`echo $flag|cut -f2- -d -| sed -e 's,-,_,g' -e 's,^_,,g'|tr '[a-z]' '[A-Z]'`
|
||||
|
||||
if [ "${TARGET_OS}" = "darwin" ]; then
|
||||
LIBPATH=-Wl,-install_name,
|
||||
else
|
||||
LIBPATH=-Wl,-R
|
||||
fi
|
||||
|
||||
case $flag in
|
||||
-h|--help|--hel|--h|--he|-help)
|
||||
show_usage ; ;;
|
||||
-qV|-quiet-version|--quiet-version)
|
||||
be_quiet
|
||||
show_version ; ;;
|
||||
-q|-quiet|--quiet)
|
||||
be_quiet ; ;;
|
||||
-V|-version|--version)
|
||||
show_version ; ;;
|
||||
-r|--r|--report)
|
||||
echo "PKGNAME: r0"
|
||||
echo "VERSION: 0.9"
|
||||
echo "AUTHOR: pancake"
|
||||
echo "EMAIL: [email protected]"
|
||||
echo "LANGS: c"
|
||||
exit 0
|
||||
;;
|
||||
--cache-file)
|
||||
# ignored: acr have no cache
|
||||
;;
|
||||
--build)
|
||||
BUILD="$value"; split_host BUILD ; ;;
|
||||
--host)
|
||||
CROSSBUILD=1 # XXX
|
||||
HOST="$value"; split_host HOST ; ;;
|
||||
--target)
|
||||
TARGET="$value"; split_host TARGET ; ;;
|
||||
--prefix)
|
||||
PREFIX="$value"; ;;
|
||||
--exec-prefix)
|
||||
EPREFIX="$value"; ;;
|
||||
--sandbox|--sprefix)
|
||||
SPREFIX="$value"; ;;
|
||||
--bindir)
|
||||
BINDIR="$value"; ;;
|
||||
--sbindir)
|
||||
SBINDIR="$value"; ;;
|
||||
--libexecdir)
|
||||
LIBEXECDIR="$value"; ;;
|
||||
--docdir)
|
||||
DOCDIR="$value"; ;;
|
||||
--datadir)
|
||||
DATADIR="$value"; ;;
|
||||
--sysconfdir)
|
||||
SYSCONFDIR="$value"
|
||||
ETCDIR="$value"; ;;
|
||||
--etcdir)
|
||||
SYSCONFDIR="$value"
|
||||
ETCDIR="$value"; ;;
|
||||
--sharedstatedir)
|
||||
SHAREDSTATEDIR="$value"; ;;
|
||||
--localstatedir)
|
||||
LOCALSTATEDIR="$value"; ;;
|
||||
--libdir)
|
||||
LIBDIR="$value"
|
||||
PKGCFG_LIBDIR="$value"; ;;
|
||||
--libpath)
|
||||
LDFLAGS="${LDFLAGS} ${LIBPATH}$value"; ;;
|
||||
--includedir)
|
||||
PKGCFG_INCDIR="$value"
|
||||
INCLUDEDIR="$value"; CFLAGS="${CFLAGS} -I$value"; ;;
|
||||
--infodir)
|
||||
INFODIR="$value"; ;;
|
||||
--mandir)
|
||||
MANDIR="$value"; ;;
|
||||
|
||||
*) if [ "$value" ]; then eval "`echo $flag2=$value`" ;
|
||||
else echo ; echo "WARNING: Unknown flag '$flag'." >&2 ; echo ; fi ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# MAIN #
|
||||
take_environ
|
||||
split_host BUILD HOST TARGET
|
||||
[ -z "$ACRHOOK" ] && ACRHOOK=./configure.hook
|
||||
[ -e "$ACRHOOK" ] && . ${ACRHOOK}
|
||||
|
||||
while : ; do
|
||||
[ -z "$1" ] && break
|
||||
parse_options "$1"
|
||||
shift
|
||||
done
|
||||
|
||||
ENVWORDS="MANDIR DESCRIPTION INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR ETCDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGCFG_LIBDIR PKGCFG_INCDIR PKGNAME VPATH CONTACT CONTACT_NAME CONTACT_MAIL CC CFLAGS CPPFLAGS LDFLAGS HAVE_LANG_C"
|
||||
|
||||
create_environ
|
||||
|
||||
ocho "checking build system type... ${BUILD}"
|
||||
ocho "checking host system type... ${HOST}"
|
||||
ocho "checking target system type... ${TARGET}"
|
||||
[ "${CROSSBUILD}" = 1 ] && echo "using crosscompilation mode."
|
||||
|
||||
#split_host BUILD HOST TARGET
|
||||
[ -n "${prefix}" ] && PREFIX="${prefix}"
|
||||
ocho "checking for working directories... ${WODIS}"
|
||||
ocho "using prefix '${PREFIX}'"
|
||||
ACR_RMFILES=" test.c a.out a.exe"
|
||||
|
||||
COMPILER=CC
|
||||
ochof "checking for c compiler... "
|
||||
HAVE_LANG_C=1
|
||||
if [ "${CROSSBUILD}" = 1 ]; then
|
||||
(command -v ${HOST}-${CC} >/dev/null 2>&1)
|
||||
if [ $? = 0 ]; then CC="${HOST}-${CC}"; fi
|
||||
fi
|
||||
echo "int main(int argc, char **argv){return 0;}" > test.c
|
||||
(exec ${CC} -o a.out ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} test.c >/dev/null 2>&1)
|
||||
if [ $? = 0 ]; then echo ${CC}; else
|
||||
echo no ; HAVE_LANG_C=0
|
||||
do_remove
|
||||
echo "ERROR: ${CC} cannot create executables" >&2 ;
|
||||
exit 1 ; fi
|
||||
SEDFLAGS=" -e '"
|
||||
COUNT=0
|
||||
for A in ${ENVWORDS} ; do
|
||||
[ "${A}" = VPATH ] && continue
|
||||
[ "${A}" = srcdir ] && continue
|
||||
eval "VAR=\$${A}"
|
||||
VAR="`echo ${VAR} | sed -e 's/\,/\\\,/g'`"
|
||||
[ $COUNT = 10 ] && COUNT=0 && SEDFLAGS="${SEDFLAGS}' -e '"
|
||||
COUNT=$(($COUNT+1))
|
||||
SEDFLAGS="${SEDFLAGS}s,@${A}@,${VAR},g;"
|
||||
done
|
||||
SEDFLAGS="${SEDFLAGS}'"
|
||||
for A in config.mk ; do # SUBDIRS
|
||||
if [ -f "${VPATH}/${A}.acr" ]; then
|
||||
SD_TARGET=${A}
|
||||
else
|
||||
if [ -d "${VPATH}/${A}" ]; then
|
||||
SD_TARGET=${A}/Makefile
|
||||
mkdir -p ${A}
|
||||
else
|
||||
echo "ERROR: Cannot find ${VPATH}/${A}.acr" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
ocho "creating ${SD_TARGET}"
|
||||
[ "${VPATH}" != '.' ] && mkdir -p $(echo ${A} | sed -e "s,/`basename ${A}`$,,g")
|
||||
cat ${VPATH}/${SD_TARGET}.acr | \
|
||||
eval sed -e "s,@VPATH@,${VPATH}/${A},g" ${SEDFLAGS} > ${SD_TARGET}.tmp
|
||||
|
||||
for A in ${ENVWORDS}; do
|
||||
VALUE=`eval echo "$"${A}`
|
||||
if [ "$VALUE" = 0 ]; then ## FALSE
|
||||
MARK="##${A}##"
|
||||
if [ -n "`grep \"${MARK}\" ${SD_TARGET}.tmp`" ]; then
|
||||
mv ${SD_TARGET}.tmp ${SD_TARGET}.tmp2
|
||||
cat ${SD_TARGET}.tmp2 | MARK=$MARK $AWK 'BEGIN{a=0;}{if($1==ENVIRON["MARK"]){if(a)a=0;else a=1}else{if(!a)print;}}' > ${SD_TARGET}.tmp
|
||||
fi
|
||||
fi
|
||||
done
|
||||
mv ${SD_TARGET}.tmp ${SD_TARGET} && rm -f ${SD_TARGET}.tmp2
|
||||
if [ ! $? = 0 ]; then echo Cannot write target file ; control_c ; fi
|
||||
done
|
||||
|
||||
do_remove
|
||||
if [ "$QUIET" = 0 ]; then
|
||||
echo
|
||||
echo "Final report:"
|
||||
for A in VERSION PREFIX ; do
|
||||
eval VAL="\$${A}"
|
||||
[ -z "${VAL}" ] && VAL="\"\""
|
||||
echo " - ${A} = ${VAL}"
|
||||
done
|
||||
fi
|
||||
@@ -0,0 +1,10 @@
|
||||
PKGNAME r0
|
||||
VERSION 0.9
|
||||
CONTACT pancake ; [email protected]
|
||||
|
||||
LANG_C!
|
||||
|
||||
SUBDIRS config.mk ;
|
||||
|
||||
REPORT VERSION PREFIX ;
|
||||
|
||||
+1189
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,491 @@
|
||||
/* 2015 - tiny Thumb2 disassembler based on winedbg code */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARM_INSN_SIZE 4
|
||||
#define THUMB_INSN_SIZE 2
|
||||
#define THUMB2_INSN_SIZE 4
|
||||
|
||||
#define ROR32(n, r) (((n) >> (r)) | ((n) << (32 - (r))))
|
||||
|
||||
#define get_cond(ins) tbl_cond[(ins >> 28) & 0x0f]
|
||||
#define get_nibble(ins, num) ((ins >> (num * 4)) & 0x0f)
|
||||
|
||||
|
||||
struct thumb_disasm_t {
|
||||
uint32_t pc;
|
||||
const uint8_t *buf;
|
||||
char str[32];
|
||||
char hex[32];
|
||||
uint32_t jmp, fail;
|
||||
};
|
||||
|
||||
struct inst_thumb16 {
|
||||
uint16_t mask;
|
||||
uint16_t pattern;
|
||||
uint16_t (*func)(struct thumb_disasm_t*, uint16_t);
|
||||
};
|
||||
|
||||
struct inst_arm {
|
||||
uint32_t mask;
|
||||
uint32_t pattern;
|
||||
uint32_t (*func)(struct thumb_disasm_t*, uint32_t);
|
||||
};
|
||||
|
||||
static const char *tbl_regs[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
|
||||
"fp", "ip", "sp", "lr", "pc", "cpsr"
|
||||
};
|
||||
|
||||
static char const tbl_cond[][3] = {
|
||||
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge",
|
||||
"lt", "gt", "le", "", ""
|
||||
};
|
||||
|
||||
static char const tbl_shifts[][4] = {
|
||||
"lsl", "lsr", "asr", "ror"
|
||||
};
|
||||
|
||||
static char const tbl_hiops_t[][4] = {
|
||||
"add", "cmp", "mov", "bx"
|
||||
};
|
||||
|
||||
static char const tbl_aluops_t[][4] = {
|
||||
"and", "eor", "lsl", "lsr", "asr", "adc", "sbc", "ror", "tst", "neg",
|
||||
"cmp", "cmn", "orr", "mul", "bic", "mvn"
|
||||
};
|
||||
|
||||
static char const tbl_immops_t[][4] = {
|
||||
"mov", "cmp", "add", "sub"
|
||||
};
|
||||
|
||||
static char const tbl_sregops_t[][5] = {
|
||||
"strh", "ldsb", "ldrh", "ldsh"
|
||||
};
|
||||
|
||||
static uint32_t db_get_inst(const uint8_t* buf, int size) {
|
||||
if (size == 4) return *(uint32_t*)buf;
|
||||
if (size == 2) return (uint32_t)*(uint16_t*)buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_hireg(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
short dst = inst & 0x07;
|
||||
short src = (inst >> 3) & 0x07;
|
||||
short h2 = (inst >> 6) & 0x01;
|
||||
short h1 = (inst >> 7) & 0x01;
|
||||
short op = (inst >> 8) & 0x03;
|
||||
|
||||
if (h1) dst += 8;
|
||||
if (h2) src += 8;
|
||||
|
||||
if (op == 2 && dst == src) { /* mov rx, rx */
|
||||
strcpy (ai->str, "nop");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (op == 3)
|
||||
snprintf (ai->str, sizeof (ai->str), "b%sx %s", h1?"l":"", tbl_regs[src]);
|
||||
else
|
||||
snprintf (ai->str, sizeof (ai->str), "%s %s, %s", tbl_hiops_t[op], tbl_regs[dst], tbl_regs[src]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_aluop(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
short dst = inst & 0x07;
|
||||
short src = (inst >> 3) & 0x07;
|
||||
short op = (inst >> 6) & 0x0f;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s %s, %s", tbl_aluops_t[op], tbl_regs[dst], tbl_regs[src]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// XXX possible overflow here? resize str plz
|
||||
static uint16_t thumb_disasm_pushpop(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
short lrpc = (inst >> 8) & 0x01;
|
||||
short load = (inst >> 11) & 0x01;
|
||||
short i;
|
||||
short last;
|
||||
|
||||
for (i=7;i>=0;i--)
|
||||
if ((inst>>i) & 1) break;
|
||||
last = i;
|
||||
|
||||
strcpy (ai->str, load? "pop {": "push {");
|
||||
|
||||
for (i=0;i<=7;i++) {
|
||||
if ((inst>>i) & 1) {
|
||||
if (i == last) strcat (ai->str, tbl_regs[i]); // overflow ??
|
||||
else strcat (ai->str, tbl_regs[i]);
|
||||
}
|
||||
}
|
||||
if (lrpc) {
|
||||
if (last) strcat (ai->str, ", ");
|
||||
strcat (ai->str, load? "pc": "lr");
|
||||
}
|
||||
|
||||
strcat (ai->str, "}");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_blocktrans(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
short load = (inst >> 11) & 0x01;
|
||||
short i;
|
||||
short last;
|
||||
|
||||
for (i=7;i>=0;i--)
|
||||
if ((inst>>i) & 1) break;
|
||||
last = i;
|
||||
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s %s!, {", load ? "ldmia" : "stmia", tbl_regs[(inst >> 8) & 0x07]);
|
||||
|
||||
for (i=0;i<=7;i++) {
|
||||
if ((inst>>i) & 1) {
|
||||
strcat (ai->str, tbl_regs[i]);
|
||||
if (i != last) {
|
||||
strcat (ai->str, ", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcat (ai->str, "}");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_condbranch(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t offset = inst & 0x00ff;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"b%s 0x%x", tbl_cond[(inst >> 8) & 0x0f], ai->pc+offset);
|
||||
ai->jmp = ai->pc + offset;
|
||||
ai->fail = ai->pc + 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_uncondbranch(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
short offset = (inst & 0x07ff) << 1;
|
||||
if (offset & 0x0800) offset |= 0xf000;
|
||||
offset += 4;
|
||||
snprintf (ai->str, sizeof (ai->str), "b 0x%x", ai->pc+offset);
|
||||
ai->jmp = ai->pc+offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_loadadr(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t src = (inst >> 11) & 0x01;
|
||||
uint16_t offset = (inst & 0xff) << 2;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"add %s, %s, #%d", tbl_regs[(inst >> 8) & 0x07], src ? "sp" : "pc",
|
||||
offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_swi(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t comment = inst & 0x00ff;
|
||||
snprintf (ai->str, sizeof (ai->str), "swi #%d", comment);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_nop(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
strcpy (ai->str, "nop");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_ldrpcrel(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t offset = (inst & 0xff) << 2;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"ldr %s, [pc, #%u]", tbl_regs[(inst >> 8) & 0x07], offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_ldrsprel(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t offset = (inst & 0xff) << 2;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s %s, [sp, #%u]", (inst & 0x0800)?"ldr":"str",
|
||||
tbl_regs[(inst >> 8) & 0x07], offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_addsprel(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t offset = (inst & 0x7f) << 2;
|
||||
int sub = ((inst >> 7) & 0x01);
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s sp, sp, #%u", sub? "sub": "add", offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_ldrimm(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t offset = (inst & 0x07c0) >> 6;
|
||||
snprintf (ai->str, sizeof (ai->str), "%s%s %s, [%s, #%u]",
|
||||
(inst & 0x0800)?"ldr":"str", (inst & 0x1000)?"b":"",
|
||||
tbl_regs[inst & 0x07], tbl_regs[(inst >> 3) & 0x07],
|
||||
(inst & 0x1000)?offset:(offset << 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_ldrhimm(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t offset = (inst & 0x07c0) >> 5;
|
||||
snprintf (ai->str, sizeof (ai->str), "%s %s, [%s, #%u]", (inst & 0x0800)?"ldrh":"strh",
|
||||
tbl_regs[inst & 0x07], tbl_regs[(inst >> 3) & 0x07], offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_ldrreg(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
snprintf (ai->str, sizeof (ai->str), "%s%s %s, [%s, %s]",
|
||||
(inst & 0x0800)?"ldr":"str", (inst & 0x0400)?"b":"",
|
||||
tbl_regs[inst & 0x07], tbl_regs[(inst >> 3) & 0x07],
|
||||
tbl_regs[(inst >> 6) & 0x07]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_ldrsreg(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
snprintf (ai->str, sizeof (ai->str), "%s %s, [%s, %s]",
|
||||
tbl_sregops_t[(inst >> 10) & 0x03], tbl_regs[inst & 0x07],
|
||||
tbl_regs[(inst >> 3) & 0x07], tbl_regs[(inst >> 6) & 0x07]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_immop(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t op = (inst >> 11) & 0x03;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s %s, #%u", tbl_immops_t[op], tbl_regs[(inst >> 8) & 0x07], inst & 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_addsub(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
char last [32];
|
||||
uint16_t op = (inst >> 9) & 0x01;
|
||||
uint16_t immediate = (inst >> 10) & 0x01;
|
||||
if (immediate) snprintf (last, sizeof (last), "#%d", (inst >> 6) & 0x07);
|
||||
else strcpy (last, tbl_regs[(inst >> 6) & 0x07]);
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s %s, %s, %s", op ? "sub" : "add",
|
||||
tbl_regs[inst & 0x07], tbl_regs[(inst >> 3) & 0x07], last);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t thumb_disasm_movshift(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t op = (inst >> 11) & 0x03;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s %s, %s, #%u", tbl_shifts[op],
|
||||
tbl_regs[inst & 0x07], tbl_regs[(inst >> 3) & 0x07], (inst >> 6) & 0x1f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t thumb2_disasm_branchlinked(struct thumb_disasm_t *ai, uint32_t inst) {
|
||||
uint32_t offset = (((inst & 0x07ff0000) >> 4) | ((inst & 0x000007ff) << 1)) + 4;
|
||||
snprintf (ai->str, sizeof (ai->str), "bl 0x%x", ai->pc+offset);
|
||||
ai->jmp = ai->pc+offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t thumb2_disasm_misc(struct thumb_disasm_t *ai, uint32_t inst) {
|
||||
uint16_t op1 = (inst >> 20) & 0x03;
|
||||
uint16_t op2 = (inst >> 4) & 0x03;
|
||||
|
||||
if (get_nibble(inst, 4) != get_nibble(inst, 0))
|
||||
return inst;
|
||||
|
||||
if (op1 == 3 && op2 == 0) {
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"clz %s, %s ", tbl_regs[get_nibble(inst, 2)],
|
||||
tbl_regs[get_nibble(inst, 0)]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (op1 == 1) {
|
||||
const char *op = "";
|
||||
switch (op2) {
|
||||
case 0: op = "rev "; break;
|
||||
case 1: op = "rev16 "; break;
|
||||
case 2: op = "rbit "; break;
|
||||
case 3: op = "revsh "; break;
|
||||
}
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s %s, %s ", op, tbl_regs[get_nibble(inst, 2)], tbl_regs[get_nibble(inst, 0)]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
static uint32_t thumb2_disasm_mul(struct thumb_disasm_t *ai, uint32_t inst) {
|
||||
uint16_t op1 = (inst >> 20) & 0x07;
|
||||
uint16_t op2 = (inst >> 4) & 0x03;
|
||||
|
||||
if (op1)
|
||||
return inst;
|
||||
|
||||
if (op2 == 0) {
|
||||
uint16_t nib = get_nibble (inst, 3);
|
||||
if (nib == 0xf) {
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"mul %s, %s, %s ", tbl_regs[get_nibble(inst, 2)],
|
||||
tbl_regs[get_nibble(inst, 4)],
|
||||
tbl_regs[get_nibble(inst, 0)]);
|
||||
} else {
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"mla %s, %s, %s, %s ", tbl_regs[get_nibble(inst, 2)],
|
||||
tbl_regs[get_nibble(inst, 4)],
|
||||
tbl_regs[get_nibble(inst, 0)],
|
||||
tbl_regs[get_nibble(inst, 3)]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (op2 == 1) {
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"mls %s, %s, %s, %s ", tbl_regs[get_nibble(inst, 2)],
|
||||
tbl_regs[get_nibble(inst, 4)],
|
||||
tbl_regs[get_nibble(inst, 0)],
|
||||
tbl_regs[get_nibble(inst, 3)]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
static uint32_t thumb2_disasm_longmuldiv(struct thumb_disasm_t *ai, uint32_t inst) {
|
||||
const char *op = "";
|
||||
uint16_t op1 = (inst >> 20) & 0x07;
|
||||
uint16_t op2 = (inst >> 4) & 0x0f;
|
||||
|
||||
if (op2 == 0) {
|
||||
switch (op1) {
|
||||
case 0: op = "smull "; break;
|
||||
case 2: op = "umull "; break;
|
||||
case 4: op = "smlal "; break;
|
||||
case 6: op = "umlal "; break;
|
||||
default: return inst;
|
||||
}
|
||||
snprintf (ai->str, sizeof (ai->str), "%s%s, %s, %s, %s ", op,
|
||||
tbl_regs[get_nibble(inst, 3)], tbl_regs[get_nibble(inst, 2)],
|
||||
tbl_regs[get_nibble(inst, 4)], tbl_regs[get_nibble(inst, 0)]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (op2 == 0xffff) {
|
||||
switch (op1) {
|
||||
case 1: op = "sdiv "; break;
|
||||
case 3: op = "udiv "; break;
|
||||
default: return inst;
|
||||
}
|
||||
snprintf (ai->str, sizeof (ai->str), "%s%s, %s, %s ", op,
|
||||
tbl_regs[get_nibble(inst, 2)], tbl_regs[get_nibble(inst, 4)],
|
||||
tbl_regs[get_nibble(inst, 0)]);
|
||||
return 0;
|
||||
}
|
||||
return inst;
|
||||
}
|
||||
|
||||
static uint32_t thumb2_disasm_coprocmov1(struct thumb_disasm_t *ai, uint32_t inst) {
|
||||
uint16_t opc1 = (inst >> 21) & 0x07;
|
||||
uint16_t opc2 = (inst >> 5) & 0x07;
|
||||
char last[32];
|
||||
if (opc2) snprintf (last, sizeof (last), ", #%u", opc2); else *last = 0;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s%s p%u, #%u, %s, cr%u, cr%u%s", (inst & 0x00100000)?"mrc":"mcr",
|
||||
(inst & 0x10000000)?"2":"", get_nibble(inst, 2), opc1,
|
||||
tbl_regs[get_nibble(inst, 3)], get_nibble(inst, 4), get_nibble(inst, 0), last);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct inst_thumb16 tbl_thumb16[] = {
|
||||
{ 0xfc00, 0x4400, thumb_disasm_hireg },
|
||||
{ 0xfc00, 0x4000, thumb_disasm_aluop },
|
||||
{ 0xf600, 0xb400, thumb_disasm_pushpop },
|
||||
{ 0xf000, 0xc000, thumb_disasm_blocktrans },
|
||||
{ 0xf000, 0xd000, thumb_disasm_condbranch },
|
||||
{ 0xf800, 0xe000, thumb_disasm_uncondbranch },
|
||||
{ 0xf000, 0xa000, thumb_disasm_loadadr },
|
||||
{ 0xf800, 0x4800, thumb_disasm_ldrpcrel },
|
||||
{ 0xf000, 0x9000, thumb_disasm_ldrsprel },
|
||||
{ 0xff00, 0xb000, thumb_disasm_addsprel },
|
||||
{ 0xe000, 0x6000, thumb_disasm_ldrimm },
|
||||
{ 0xf000, 0x8000, thumb_disasm_ldrhimm },
|
||||
{ 0xf200, 0x5000, thumb_disasm_ldrreg },
|
||||
{ 0xf200, 0x5200, thumb_disasm_ldrsreg },
|
||||
{ 0xe000, 0x2000, thumb_disasm_immop },
|
||||
{ 0xff00, 0xdf00, thumb_disasm_swi },
|
||||
{ 0xff00, 0xbf00, thumb_disasm_nop },
|
||||
{ 0xf800, 0x1800, thumb_disasm_addsub },
|
||||
{ 0xe000, 0x0000, thumb_disasm_movshift },
|
||||
{ 0x0000, 0x0000, NULL }
|
||||
};
|
||||
|
||||
static const struct inst_arm tbl_thumb32[] = {
|
||||
{ 0xf800f800, 0xf000f800, thumb2_disasm_branchlinked },
|
||||
{ 0xffc0f0c0, 0xfa80f080, thumb2_disasm_misc },
|
||||
{ 0xff8000c0, 0xfb000000, thumb2_disasm_mul },
|
||||
{ 0xff8000f0, 0xfb800000, thumb2_disasm_longmuldiv },
|
||||
{ 0xff8000f0, 0xfb8000f0, thumb2_disasm_longmuldiv },
|
||||
{ 0xef100010, 0xee100010, thumb2_disasm_coprocmov1 },
|
||||
{ 0xef100010, 0xee000010, thumb2_disasm_coprocmov1 },
|
||||
{ 0x00000000, 0x00000000, NULL }
|
||||
};
|
||||
|
||||
int thumb_disasm(struct thumb_disasm_t *ai) {
|
||||
struct inst_thumb16 *t_ptr = (struct inst_thumb16 *)&tbl_thumb16;
|
||||
struct inst_arm *t2_ptr = (struct inst_arm *)&tbl_thumb32;
|
||||
uint32_t inst;
|
||||
uint16_t tinst;
|
||||
int size;
|
||||
int matched = 0;
|
||||
|
||||
ai->jmp = ai->fail = -1;
|
||||
|
||||
tinst = db_get_inst(ai->buf, THUMB_INSN_SIZE);
|
||||
switch (tinst & 0xf800) {
|
||||
case 0xe800:
|
||||
case 0xf000:
|
||||
case 0xf800:
|
||||
size = THUMB2_INSN_SIZE;
|
||||
inst = db_get_inst(ai->buf+1, THUMB_INSN_SIZE);
|
||||
inst |= (tinst << 16);
|
||||
|
||||
while (t2_ptr->func) {
|
||||
if ((inst & t2_ptr->mask) == t2_ptr->pattern) {
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
t2_ptr++;
|
||||
}
|
||||
if (!matched) strcpy (ai->str, "invalid"); // thumb2
|
||||
else t2_ptr->func (ai, inst);
|
||||
snprintf (ai->hex, sizeof (ai->hex), "%02x%02x%02x%02x",
|
||||
*((uint8_t*)(&inst)), *((uint8_t*)(&inst)+1),
|
||||
*((uint8_t*)(&inst)+2), *((uint8_t*)(&inst)+3));
|
||||
return size;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
size = THUMB_INSN_SIZE;
|
||||
while (t_ptr->func) {
|
||||
if ((tinst & t_ptr->mask) == t_ptr->pattern) {
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
t_ptr++;
|
||||
}
|
||||
|
||||
if (!matched) snprintf (ai->str, sizeof (ai->str), "0x%04x", tinst);
|
||||
else t_ptr->func(ai, tinst);
|
||||
snprintf (ai->hex, sizeof (ai->hex), "%02x%02x", *((uint8_t*)(&tinst)), *((uint8_t*)(&tinst)+1));
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned int disasm(const unsigned char *bytes, unsigned int max, int offset, char *output) {
|
||||
int len;
|
||||
struct thumb_disasm_t dis;
|
||||
dis.pc = offset;
|
||||
dis.buf = bytes;
|
||||
len = thumb_disasm (&dis);
|
||||
if (len > 0) {
|
||||
strcpy (output, dis.str);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
+3076
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,148 @@
|
||||
#ifndef __X86_INSTR_H
|
||||
#define __X86_INSTR_H
|
||||
|
||||
|
||||
enum argtype {
|
||||
NONE = 0,
|
||||
|
||||
/* the literal value 1, used for bit shift ops */
|
||||
ONE,
|
||||
|
||||
/* specific registers */
|
||||
AL, CL, DL, BL, AH, CH, DH, BH,
|
||||
AX, CX, DX, BX, SP, BP, SI, DI,
|
||||
ES, CS, SS, DS, FS, GS,
|
||||
ALS, AXS, /* the same as AL/AX except MASM doesn't print them */
|
||||
DXS, /* the same as DX except GAS puts it in parentheses */
|
||||
|
||||
/* absolute or relative numbers, given as 1/2/4 bytes */
|
||||
IMM8, IMM16, IMM, /* immediate number */
|
||||
REL8, REL16, /* relative to current instruction */
|
||||
PTR32, /* absolute instruction, used for far calls/jumps */
|
||||
MOFFS16, /* absolute location in memory, for A0-A3 MOV */
|
||||
|
||||
/* specific memory addresses for string operations */
|
||||
DSBX, DSSI, ESDI,
|
||||
|
||||
/* to be read from ModRM, appropriately */
|
||||
RM, /* register/memory */
|
||||
MM, /* MMX register/memory */
|
||||
XM, /* SSE register/memory */
|
||||
MEM, /* memory only (using 0x11xxxxxx is invalid) */
|
||||
REGONLY, /* register only (not using 0x11xxxxxx is invalid) */
|
||||
MMXONLY, /* MMX register only (not using 0x11xxxxxx is invalid) */
|
||||
XMMONLY, /* SSE register only (not using 0x11xxxxxx is invalid) */
|
||||
REG, /* register */
|
||||
MMX, /* MMX register */
|
||||
XMM, /* SSE register */
|
||||
SEG16, /* segment register */
|
||||
REG32, /* 32-bit only register, used for cr/dr/tr */
|
||||
CR32, /* control register */
|
||||
DR32, /* debug register */
|
||||
TR32, /* test register */
|
||||
|
||||
/* floating point regs */
|
||||
ST, /* top of stack aka st(0) */
|
||||
STX, /* element of stack given by lowest three bytes of "modrm" */
|
||||
};
|
||||
|
||||
/* opcode flags */
|
||||
|
||||
#define OP_ARG2_IMM 0x0001 /* has IMM16/32 as third argument */
|
||||
#define OP_ARG2_IMM8 0x0002 /* has IMM8 as third argument */
|
||||
#define OP_ARG2_CL 0x0004 /* has CL as third argument */
|
||||
#define OP_64 0x0008 /* opcodes which are 64-bit by default (call, jmp), most being 32-bit */
|
||||
|
||||
#define OP_REPNE 0x0010 /* repne prefix valid */
|
||||
#define OP_REPE 0x0020 /* repe prefix valid */
|
||||
#define OP_REP OP_REPE /* rep prefix valid */
|
||||
#define OP_OP32_REGONLY 0x0040 /* operand-size prefix only valid if used with reg */
|
||||
#define OP_LOCK 0x0080 /* lock prefix valid */
|
||||
|
||||
#define OP_STACK 0x0100 /* only marked for size if overridden */
|
||||
#define OP_STRING 0x0200 /* string operations */
|
||||
#define OP_FAR 0x0400 /* far operation */
|
||||
#define OP_IMM64 0x0800 /* IMM argument can be 64-bit */
|
||||
|
||||
#define OP_S 0x1000 /* (FPU) op takes -s if GCC */
|
||||
#define OP_L 0x2000 /* (FPU) op takes -l if GCC */
|
||||
#define OP_LL 0x3000 /* (FPU) op takes -ll if GCC */
|
||||
/* -t doesn't need to be marked */
|
||||
|
||||
#define OP_STOP 0x4000 /* stop scanning (jmp, ret) */
|
||||
#define OP_BRANCH 0x8000 /* branch to target (jmp, jXX) */
|
||||
|
||||
struct op {
|
||||
word opcode;
|
||||
byte subcode;
|
||||
signed char size; /* 0 if not sized, -1 if size == bitness */
|
||||
char name[16];
|
||||
enum argtype arg0; /* usually dest */
|
||||
enum argtype arg1; /* usually src */
|
||||
/* arg2 only for imul, shrd, shld */
|
||||
dword flags;
|
||||
};
|
||||
|
||||
#define PREFIX_ES 0x0001 /* 26 */
|
||||
#define PREFIX_CS 0x0002 /* 2E */
|
||||
#define PREFIX_SS 0x0003 /* 36 */
|
||||
#define PREFIX_DS 0x0004 /* 3E */
|
||||
#define PREFIX_FS 0x0005 /* 64 */
|
||||
#define PREFIX_GS 0x0006 /* 65 */
|
||||
#define PREFIX_SEG_MASK 0x0007
|
||||
|
||||
#define PREFIX_OP32 0x0008 /* 66 */
|
||||
#define PREFIX_ADDR32 0x0010 /* 67 */
|
||||
#define PREFIX_LOCK 0x0020 /* F0 */
|
||||
#define PREFIX_REPNE 0x0040 /* F2 */
|
||||
#define PREFIX_REPE 0x0080 /* F3 */
|
||||
#define PREFIX_WAIT 0x0100 /* 9B */
|
||||
|
||||
#define PREFIX_REX 0x0800 /* 40 */
|
||||
#define PREFIX_REXB 0x1000 /* 41 */
|
||||
#define PREFIX_REXX 0x2000 /* 42 */
|
||||
#define PREFIX_REXR 0x4000 /* 44 */
|
||||
#define PREFIX_REXW 0x8000 /* 48 */
|
||||
|
||||
enum disptype {
|
||||
DISP_NONE = 0, /* no disp, i.e. mod == 0 && m != 6 */
|
||||
DISP_8 = 1, /* one byte */
|
||||
DISP_16 = 2, /* two bytes */
|
||||
DISP_REG = 3, /* register, i.e. mod == 3 */
|
||||
};
|
||||
|
||||
struct arg {
|
||||
char string[32];
|
||||
dword ip;
|
||||
qword value;
|
||||
enum argtype type;
|
||||
};
|
||||
|
||||
struct instr {
|
||||
word prefix;
|
||||
struct op op;
|
||||
struct arg args[3];
|
||||
byte addrsize;
|
||||
enum disptype modrm_disp;
|
||||
int8_t modrm_reg; /* This is a little ugly, but 16 is IP and -1 is none (aka IZ). */
|
||||
byte sib_scale;
|
||||
signed char sib_index;
|
||||
int usedmem:1; /* used for error checking */
|
||||
|
||||
int vex:1;
|
||||
unsigned int vex_reg:3;
|
||||
int vex_256:1;
|
||||
};
|
||||
|
||||
/* 66 + 67 + seg + lock/rep + 2 bytes opcode + modrm + sib + 4 bytes displacement + 4 bytes immediate */
|
||||
#define MAX_INSTR 16
|
||||
|
||||
/* flags relating to specific instructions */
|
||||
#define INSTR_SCANNED 0x01 /* byte has been scanned */
|
||||
#define INSTR_VALID 0x02 /* byte begins an instruction */
|
||||
#define INSTR_JUMP 0x04 /* instruction is jumped to */
|
||||
#define INSTR_FUNC 0x08 /* instruction begins a function */
|
||||
#define INSTR_FAR 0x10 /* instruction is target of far call/jmp */
|
||||
#define INSTR_RELOC 0x20 /* byte has relocation data */
|
||||
|
||||
#endif /* __X86_INSTR_H */
|
||||
@@ -0,0 +1,762 @@
|
||||
// https://github.com/btbd/disassembler
|
||||
|
||||
#if defined(__WATCOMC__)
|
||||
#define HUGE huge
|
||||
#else
|
||||
#define HUGE
|
||||
#endif
|
||||
static char register_mnemonics8[][0xF] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
|
||||
static char register_mnemonics16[][0xF] = { "ax", "cx", "dx", "bx", "ax", "cx", "dx", "bx" };
|
||||
static char register_mnemonics32[][0xF] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" };
|
||||
|
||||
static char sib_base_mnemonics[][0xF] = { "[eax", "[ecx", "[edx", "[ebx", "[esp", "[ebp", "[esi", "[edi" };
|
||||
static char sib_scale_mnemonics[][0xF] = { "*1", "*2", "*4", "*8" };
|
||||
|
||||
enum {
|
||||
AL, EAX, ES, CS, SS, DS, ONE, CL, XMM0, BND0, BAD, MM0,
|
||||
IMM8, IMM16, IMM32, REL8, REL16, REL32, PTR1632, R, RM,
|
||||
BYTE, WORD, DWORD, QWORD, FWORD, XMMWORD
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char hasModRM, size;
|
||||
char mnemonic[64];
|
||||
char argument_count;
|
||||
char arguments[4];
|
||||
} INSTRUCTION;
|
||||
|
||||
static INSTRUCTION HUGE standard_instructions[256] = {
|
||||
{ 1, BYTE, "add ", 2, RM, R }, // 0
|
||||
{ 1, DWORD, "add ", 2, RM, R }, // 1
|
||||
{ 1, BYTE, "add ", 2, R, RM }, // 2
|
||||
{ 1, DWORD, "add ", 2, R, RM }, // 3
|
||||
{ 0, 0, "add ", 2, AL, IMM8 }, // 4
|
||||
{ 0, 0, "add ", 2, EAX, IMM32 }, // 5
|
||||
{ 0, 0, "push es", 0 }, // 6
|
||||
{ 0, 0, "pop es", 0 }, // 7
|
||||
{ 1, BYTE, "or ", 2, RM, R }, // 8
|
||||
{ 1, DWORD, "or ", 2, RM, R }, // 9
|
||||
{ 1, BYTE, "or ", 2, R, RM }, // A
|
||||
{ 1, DWORD, "or ", 2, R, RM }, // B
|
||||
{ 0, 0, "or ", 2, AL, IMM8 }, // C
|
||||
{ 0, 0, "or ", 2, EAX, IMM32 }, // D
|
||||
{ 0, 0, "push cs", 0 }, // E
|
||||
{ 0 }, // F - Two-byte instructions
|
||||
{ 1, BYTE, "adc ", 2, RM, R }, // 10
|
||||
{ 1, DWORD, "adc ", 2, RM, R }, // 11
|
||||
{ 1, BYTE, "adc ", 2, R, RM }, // 12
|
||||
{ 1, DWORD, "adc ", 2, R, RM }, // 13
|
||||
{ 0, 0, "adc ", 2, AL, IMM8 }, // 14
|
||||
{ 0, 0, "adc ", 2, EAX, IMM32 }, // 15
|
||||
{ 0, 0, "push ss", 0 }, // 16
|
||||
{ 0, 0, "pop ss", 0 }, // 17
|
||||
{ 1, BYTE, "sbb ", 2, RM, R }, // 18
|
||||
{ 1, DWORD, "sbb ", 2, RM, R }, // 19
|
||||
{ 1, BYTE, "sbb ", 2, R, RM }, // 1A
|
||||
{ 1, DWORD, "sbb ", 2, R, RM }, // 1B
|
||||
{ 0, 0, "sbb ", 2, AL, IMM8 }, // 1C
|
||||
{ 0, 0, "sbb ", 2, EAX, IMM32 }, // 1D
|
||||
{ 0, 0, "push ds", 0 }, // 1E
|
||||
{ 0, 0, "pop ds", 0 }, // 1F
|
||||
{ 1, BYTE, "and ", 2, RM, R }, // 20
|
||||
{ 1, DWORD, "and ", 2, RM, R }, // 21
|
||||
{ 1, BYTE, "and ", 2, R, RM }, // 22
|
||||
{ 1, DWORD, "and ", 2, R, RM }, // 23
|
||||
{ 0, 0, "and ", 2, AL, IMM8 }, // 24
|
||||
{ 0, 0, "and ", 2, EAX, IMM32 }, // 25
|
||||
{ 0, 0, "es ", 0 }, // 26
|
||||
{ 0, 0, "daa ", 0 }, // 27
|
||||
{ 1, BYTE, "sub ", 2, RM, R }, // 28
|
||||
{ 1, DWORD, "sub ", 2, RM, R }, // 29
|
||||
{ 1, BYTE, "sub ", 2, R, RM }, // 2A
|
||||
{ 1, DWORD, "sub ", 2, R, RM }, // 2B
|
||||
{ 0, 0, "sub ", 2, AL, IMM8 }, // 2C
|
||||
{ 0, 0, "sub ", 2, EAX, IMM32 }, // 2D
|
||||
{ 0, 0, "cs ", 0 }, // 2E
|
||||
{ 0, 0, "das ", 0 }, // 2F
|
||||
{ 1, BYTE, "xor ", 2, RM, R }, // 30
|
||||
{ 1, DWORD, "xor ", 2, RM, R }, // 31
|
||||
{ 1, BYTE, "xor ", 2, R, RM }, // 32
|
||||
{ 1, DWORD, "xor ", 2, R, RM }, // 33
|
||||
{ 0, 0, "xor ", 2, AL, IMM8 }, // 34
|
||||
{ 0, 0, "xor ", 2, EAX, IMM32 }, // 35
|
||||
{ 0, 0, "ss ", 0 }, // 36
|
||||
{ 0, 0, "aaa ", 0 }, // 37
|
||||
{ 1, BYTE, "cmp ", 2, RM, R }, // 38
|
||||
{ 1, DWORD, "cmp ", 2, RM, R }, // 39
|
||||
{ 1, BYTE, "cmp ", 2, R, RM }, // 3A
|
||||
{ 1, DWORD, "cmp ", 2, R, RM }, // 3B
|
||||
{ 0, 0, "cmp ", 2, AL, IMM8 }, // 3C
|
||||
{ 0, 0, "cmp ", 2, EAX, IMM32 }, // 3D
|
||||
{ 0, 0, "ds ", 0 }, // 3E
|
||||
{ 0, 0, "aas ", 0 }, // 3F
|
||||
{ 0, 0, "inc eax", 0 }, // 40
|
||||
{ 0, 0, "inc ecx", 0 }, // 41
|
||||
{ 0, 0, "inc edx", 0 }, // 42
|
||||
{ 0, 0, "inc ebx", 0 }, // 43
|
||||
{ 0, 0, "inc esp", 0 }, // 44
|
||||
{ 0, 0, "inc ebp", 0 }, // 45
|
||||
{ 0, 0, "inc esi", 0 }, // 46
|
||||
{ 0, 0, "inc edi", 0 }, // 47
|
||||
{ 0, 0, "dec eax", 0 }, // 48
|
||||
{ 0, 0, "dec ecx", 0 }, // 49
|
||||
{ 0, 0, "dec edx", 0 }, // 4A
|
||||
{ 0, 0, "dec ebx", 0 }, // 4B
|
||||
{ 0, 0, "dec esp", 0 }, // 4C
|
||||
{ 0, 0, "dec ebp", 0 }, // 4D
|
||||
{ 0, 0, "dec esi", 0 }, // 4E
|
||||
{ 0, 0, "dec edi", 0 }, // 4F
|
||||
{ 0, 0, "push eax", 0 }, // 50
|
||||
{ 0, 0, "push ecx", 0 }, // 51
|
||||
{ 0, 0, "push edx", 0 }, // 52
|
||||
{ 0, 0, "push ebx", 0 }, // 53
|
||||
{ 0, 0, "push esp", 0 }, // 54
|
||||
{ 0, 0, "push ebp", 0 }, // 55
|
||||
{ 0, 0, "push esi", 0 }, // 56
|
||||
{ 0, 0, "push edi", 0 }, // 57
|
||||
{ 0, 0, "pop eax", 0 }, // 58
|
||||
{ 0, 0, "pop ecx", 0 }, // 59
|
||||
{ 0, 0, "pop edx", 0 }, // 5A
|
||||
{ 0, 0, "pop ebx", 0 }, // 5B
|
||||
{ 0, 0, "pop esp", 0 }, // 5C
|
||||
{ 0, 0, "pop ebp", 0 }, // 5D
|
||||
{ 0, 0, "pop esi", 0 }, // 5E
|
||||
{ 0, 0, "pop edi", 0 }, // 5F
|
||||
{ 0, 0, "pusha", 0 }, // 60
|
||||
{ 0, 0, "popa", 0 }, // 61
|
||||
{ 1, QWORD, "bound ", 2, R, RM }, // 62
|
||||
{ 1, WORD, "arpl ", 2, RM, R }, // 63
|
||||
{ 0, 0, "fs ", 0 }, // 64
|
||||
{ 0, 0, "gs ", 0 }, // 65
|
||||
{ 0, 0, "data16 ", 0 }, // 66
|
||||
{ 0, 0, "addr16 ", 0 }, // 67
|
||||
{ 0, 0, "push ", 1, IMM32 }, // 68
|
||||
{ 1, DWORD, "imul ", 3, R, RM, IMM32 }, // 69
|
||||
{ 0, 0, "push ", 1, IMM8 }, // 6A
|
||||
{ 1, DWORD, "imul ", 3, R, RM, IMM8 }, // 6B
|
||||
{ 0, 0, "ins BYTE PTR es:[edi],dx", 0 }, // 6C
|
||||
{ 0, 0, "ins DWORD PTR es:[edi],dx", 0 }, // 6D
|
||||
{ 0, 0, "outs dx,BYTE PTR ds:[esi]", 0 }, // 6E
|
||||
{ 0, 0, "outs dx,DWORD PTR ds:[esi]", 0 }, // 6F
|
||||
{ 0, 0, "jo ", 1, REL8 }, // 70
|
||||
{ 0, 0, "jno ", 1, REL8 }, // 71
|
||||
{ 0, 0, "jb ", 1, REL8 }, // 72
|
||||
{ 0, 0, "jnb ", 1, REL8 }, // 73
|
||||
{ 0, 0, "jz ", 1, REL8 }, // 74
|
||||
{ 0, 0, "jne ", 1, REL8 }, // 75
|
||||
{ 0, 0, "jbe ", 1, REL8 }, // 76
|
||||
{ 0, 0, "ja ", 1, REL8 }, // 77
|
||||
{ 0, 0, "js ", 1, REL8 }, // 78
|
||||
{ 0, 0, "jns ", 1, REL8 }, // 79
|
||||
{ 0, 0, "jp ", 1, REL8 }, // 7A
|
||||
{ 0, 0, "jnp ", 1, REL8 }, // 7B
|
||||
{ 0, 0, "jl ", 1, REL8 }, // 7C
|
||||
{ 0, 0, "jnl ", 1, REL8 }, // 7D
|
||||
{ 0, 0, "jle ", 1, REL8 }, // 7E
|
||||
{ 0, 0, "jnle ", 1, REL8 }, // 7F
|
||||
{ 1, BYTE, "add ", 2, RM, IMM8 }, // 80
|
||||
{ 1, DWORD, "add ", 2, RM, IMM32 }, // 81
|
||||
{ 0, 0, ".byte 0x82", 0 }, // 82
|
||||
{ 1, DWORD, "adc ", 2, RM, IMM8 }, // 83
|
||||
{ 1, BYTE, "test ", 2, RM, R }, // 84
|
||||
{ 1, DWORD, "test ", 2, RM, R }, // 85
|
||||
{ 1, BYTE, "xchg ", 2, RM, R }, // 86
|
||||
{ 1, DWORD, "xchg ", 2, RM, R }, // 87
|
||||
{ 1, BYTE, "mov ", 2, RM, R }, // 88
|
||||
{ 1, DWORD, "mov ", 2, RM, R }, // 89
|
||||
{ 1, BYTE, "mov ", 2, R, RM }, // 8A
|
||||
{ 1, DWORD, "mov ", 2, R, RM }, // 8B
|
||||
{ 1, WORD, "mov ", 2, RM, SS }, // 8C
|
||||
{ 1, 0, "lea ", 2, R, RM }, // 8D
|
||||
{ 1, WORD, "mov ss,", 1, RM }, // 8E
|
||||
{ 1, DWORD, "pop ", 1, RM }, // 8F
|
||||
{ 0, 0, "nop", 0 }, // 90
|
||||
{ 0, 0, "xchg ecx,eax", 0 }, // 91
|
||||
{ 0, 0, "xchg edx,eax", 0 }, // 92
|
||||
{ 0, 0, "xchg ebx,eax", 0 }, // 93
|
||||
{ 0, 0, "xchg esp,eax", 0 }, // 94
|
||||
{ 0, 0, "xchg ebp,eax", 0 }, // 95
|
||||
{ 0, 0, "xchg esi,eax", 0 }, // 96
|
||||
{ 0, 0, "xchg edi,eax", 0 }, // 97
|
||||
{ 0, 0, "cwde", 0 }, // 98
|
||||
{ 0, 0, "cdq", 0 }, // 99
|
||||
{ 0, 0, "call ", 1, PTR1632 }, // 9A
|
||||
{ 0, 0, "fwait", 0 }, // 9B
|
||||
{ 0, 0, "pushf", 0 }, // 9C
|
||||
{ 0, 0, "popf", 0 }, // 9D
|
||||
{ 0, 0, "sahf", 0 }, // 9E
|
||||
{ 0, 0, "lahf", 0 }, // 9F
|
||||
{ 0, 0, "mov al,ds:", 1, IMM8 }, // A0
|
||||
{ 0, 0, "mov eax,ds:", 1, IMM8 }, // A1
|
||||
{ 0, 0, "mov ds:", 2, IMM8, AL }, // A2
|
||||
{ 0, 0, "mov ds:", 2, IMM32, EAX }, // A3
|
||||
{ 0, 0, "movs BYTE PTR es:[edi],BYTE PTR ds:[esi]", 0 }, // A4
|
||||
{ 0, 0, "movs DWORD PTR es:[edi],DWORD PTR ds:[esi]", 0 }, // A5
|
||||
{ 0, 0, "cmps BYTE PTR es:[esi],BYTE PTR ds:[edi]", 0 }, // A6
|
||||
{ 0, 0, "cmps DWORD PTR es:[esi],DWORD PTR ds:[edi]", 0 }, // A7
|
||||
{ 0, 0, "test al,", 1, IMM8 }, // A8
|
||||
{ 0, 0, "test eax,", 1, IMM32 }, // A9
|
||||
{ 0, 0, "stos BYTE PTR es:[edi],al", 0 }, // AA
|
||||
{ 0, 0, "stos DWORD PTR es:[edi],eax", 0 }, // AB
|
||||
{ 0, 0, "lods al,BYTE PTR ds:[esi]", 0 }, // AC
|
||||
{ 0, 0, "lods eax,DWORD PTR ds:[esi]", 0 }, // AD
|
||||
{ 0, 0, "scas al,BYTE PTR es:[edi]", 0 }, // AE
|
||||
{ 0, 0, "scas eax,DWORD PTR es:[edi]", 0 }, // AF
|
||||
{ 0, 0, "mov al,", 1, IMM8 }, // B0
|
||||
{ 0, 0, "mov cl,", 1, IMM8 }, // B1
|
||||
{ 0, 0, "mov dl,", 1, IMM8 }, // B2
|
||||
{ 0, 0, "mov bl,", 1, IMM8 }, // B3
|
||||
{ 0, 0, "mov ah,", 1, IMM8 }, // B4
|
||||
{ 0, 0, "mov ch,", 1, IMM8 }, // B5
|
||||
{ 0, 0, "mov dh,", 1, IMM8 }, // B6
|
||||
{ 0, 0, "mov bh,", 1, IMM8 }, // B7
|
||||
{ 0, 0, "mov eax,", 1, IMM32 }, // B8
|
||||
{ 0, 0, "mov ecx,", 1, IMM32 }, // B9
|
||||
{ 0, 0, "mov edx,", 1, IMM32 }, // BA
|
||||
{ 0, 0, "mov ebx,", 1, IMM32 }, // BB
|
||||
{ 0, 0, "mov esp,", 1, IMM32 }, // BC
|
||||
{ 0, 0, "mov ebp,", 1, IMM32 }, // BD
|
||||
{ 0, 0, "mov esi,", 1, IMM32 }, // BE
|
||||
{ 0, 0, "mov edi,", 1, IMM32 }, // BF
|
||||
{ 1, BYTE, "rol ", 2, RM, IMM8 }, // C0
|
||||
{ 1, DWORD, "rol ", 2, RM, IMM8 }, // C1
|
||||
{ 0, 0, "ret ", 1, IMM16 }, // C2
|
||||
{ 0, 0, "ret", 0 }, // C3
|
||||
{ 1, FWORD, "les eax,", 1, RM }, // C4
|
||||
{ 1, FWORD, "lds eax,", 1, RM }, // C5
|
||||
{ 1, BYTE, "mov ", 2, RM, IMM8 }, // C6
|
||||
{ 1, DWORD, "mov ", 2, RM, IMM32 }, // C7
|
||||
{ 0, 0, "enter ", 2, IMM16, IMM8 }, // C8
|
||||
{ 0, 0, "leave", 0 }, // C9
|
||||
{ 0, 0, "retf ", 1, IMM16 }, // CA
|
||||
{ 0, 0, "retf", 0 }, // CB
|
||||
{ 0, 0, "int3", 0 }, // CC
|
||||
{ 0, 0, "int ", 1, IMM8 }, // CD
|
||||
{ 0, 0, "into", 0 }, // CE
|
||||
{ 0, 0, "iret", 0 }, // CF
|
||||
{ 1, BYTE, "rol ", 2, RM, ONE }, // D0
|
||||
{ 1, DWORD, "rol ", 2, RM, ONE }, // D1
|
||||
{ 1, BYTE, "rol ", 2, RM, CL }, // D2
|
||||
{ 1, DWORD, "rol ", 2, RM, CL }, // D3
|
||||
{ 0, 0, "aam ", 1, IMM8 }, // D4
|
||||
{ 0, 0, "aad ", 1, IMM8 }, // D5
|
||||
{ 0, 0, ".byte 0xd6", 0 }, // D6
|
||||
{ 0, 0, "xlat BYTE PTR ds:[ebx]", 0 }, // D7
|
||||
{ 1, DWORD, "fadd ", 1, RM }, // D8
|
||||
{ 1, DWORD, "fld ", 1, RM }, // D9
|
||||
{ 1, DWORD, "fiadd ", 1, RM }, // DA
|
||||
{ 1, DWORD, "fild ", 1, RM }, // DB
|
||||
{ 1, QWORD, "fadd ", 1, RM }, // DC
|
||||
{ 1, QWORD, "fld ", 1, RM }, // DD
|
||||
{ 1, WORD, "fiadd ", 1, RM }, // DE
|
||||
{ 1, WORD, "fild ", 1, RM }, // DF
|
||||
{ 0, 0, "loopne ", 1, REL8 }, // E0
|
||||
{ 0, 0, "loope ", 1, REL8 }, // E1
|
||||
{ 0, 0, "loop ", 1, REL8 }, // E2
|
||||
{ 0, 0, "jecxz ", 1, REL8 }, // E3
|
||||
{ 0, 0, "in al,", 1, IMM8 }, // E4
|
||||
{ 0, 0, "in eax,", 1, IMM8 }, // E5
|
||||
{ 0, 0, "out ", 2, IMM8, AL }, // E6
|
||||
{ 0, 0, "out ", 2, IMM8, EAX }, // E7
|
||||
{ 0, 0, "call ", 1, REL32 }, // E8
|
||||
// { 0, 0, "jmp ", 1, REL32 }, // E9
|
||||
{ 0, 0, "jmp ", 1, REL16 }, // E9
|
||||
{ 0, 0, "jmpf ", 1, PTR1632 }, // EA
|
||||
{ 0, 0, "jmp ", 1, REL8 }, // EB
|
||||
{ 0, 0, "in al,dx", 0 }, // EC
|
||||
{ 0, 0, "in eax,dx", 0 }, // ED
|
||||
{ 0, 0, "out dx,al", 0 }, // EE
|
||||
{ 0, 0, "out dx,eax", 0 }, // EF
|
||||
{ 0, 0, "lock ", 0 }, // F0
|
||||
{ 0, 0, "icebp", 0 }, // F1
|
||||
{ 0, 0, "repnz ", 0 }, // F2
|
||||
{ 0, 0, "repz", 0 }, // F3
|
||||
{ 0, 0, "hlt", 0 }, // F4
|
||||
{ 0, 0, "cmc", 0 }, // F5
|
||||
{ 1, BYTE, "test ", 2, RM, IMM8 }, // F6
|
||||
{ 1, DWORD, "test ", 2, RM, IMM32 }, // F7
|
||||
{ 0, 0, "clc", 0 }, // F8
|
||||
{ 0, 0, "stc", 0 }, // F9
|
||||
{ 0, 0, "cli", 0 }, // FA
|
||||
{ 0, 0, "sti", 0 }, // FB
|
||||
{ 0, 0, "cld", 0 }, // FC
|
||||
{ 0, 0, "std", 0 }, // FD
|
||||
{ 1, BYTE, "inc ", 1, RM }, // FE
|
||||
{ 1, DWORD, "inc ", 1, RM } // FF
|
||||
};
|
||||
static INSTRUCTION HUGE extended_instructions[256] = {
|
||||
{ 1, WORD, "sldt ", 1, RM }, // 0
|
||||
{ 1, 0, "sgdtd ", 1, RM }, // 1
|
||||
{ 1, 0, "lar eax,WORD PTR ", 1, RM }, // 2
|
||||
{ 1, 0, "lsl eax,WORD PTR ", 1, RM }, // 3
|
||||
{ 0, 0, ".word 0x0f04", 0 }, // 4
|
||||
{ 0, 0, "syscall", 0 }, // 5
|
||||
{ 0, 0, "clts", 0 }, // 6
|
||||
{ 0, 0, "sysret", 0 }, // 7
|
||||
{ 0, 0, "invd", 0 }, // 8
|
||||
{ 0, 0, "wbinvd", 0 }, // 9
|
||||
{ 0, 0, ".word 0x0f0a", 0 }, // A
|
||||
{ 0, 0, "ud2", 0 }, // B
|
||||
{ 0, 0, ".word 0x0f0c", 0 }, // C
|
||||
{ 1, BYTE, "prefetch ", 1, RM }, // D
|
||||
{ 0, 0, "femms", 0 }, // E
|
||||
{ 0 }, // F - Illegal
|
||||
{ 1, XMMWORD, "movups xmm0,", 1, RM }, // 10
|
||||
{ 1, XMMWORD, "movups ", 2, RM, XMM0 }, // 11
|
||||
{ 1, QWORD, "movlps xmm0,", 1, RM }, // 12
|
||||
{ 1, QWORD, "movlps ", 2, RM, XMM0 }, // 13
|
||||
{ 1, XMMWORD, "unpcklps xmm0,", 1, RM }, // 14
|
||||
{ 1, XMMWORD, "unpckhps xmm0,", 1, RM }, // 15
|
||||
{ 1, QWORD, "movhps xmm0,", 1, RM }, // 16
|
||||
{ 1, QWORD, "movhps ", 2, RM, XMM0 }, // 17
|
||||
{ 1, BYTE, "prefetchnta ", 1, RM }, // 18
|
||||
{ 1, DWORD, "nop ", 1, RM }, // 19
|
||||
{ 1, 0, "bndldx bnd0,", 1, RM }, // 1A
|
||||
{ 1, 0, "bndstx ", 2, RM, BND0 }, // 1B
|
||||
{ 1, DWORD, "nop ", 1, RM }, // 1C
|
||||
{ 1, DWORD, "nop ", 1, RM }, // 1D
|
||||
{ 1, DWORD, "nop ", 1, RM }, // 1E
|
||||
{ 1, DWORD, "nop ", 1, RM }, // 1F
|
||||
{ 0, 0, ".word 0x0f20", 0 }, // 20
|
||||
{ 0, 0, ".word 0x0f21", 0 }, // 21
|
||||
{ 0, 0, ".word 0x0f22", 0 }, // 22
|
||||
{ 0, 0, ".word 0x0f23", 0 }, // 23
|
||||
{ 0, 0, ".word 0x0f24", 0 }, // 24
|
||||
{ 0, 0, ".word 0x0f25", 0 }, // 25
|
||||
{ 0, 0, ".word 0x0f26", 0 }, // 26
|
||||
{ 0, 0, ".word 0x0f27", 0 }, // 27
|
||||
{ 1, XMMWORD, "movaps xmm0,", 1, RM }, // 28
|
||||
{ 1, XMMWORD, "movaps ", 2, RM, XMM0 }, // 29
|
||||
{ 1, QWORD, "cvtpi2ps xmm0,", 1, RM }, // 2A
|
||||
{ 1, XMMWORD, "movntps ", 2, RM, XMM0 }, // 2B
|
||||
{ 1, QWORD, "cvttps2pi mm0,", 1, RM }, // 2C
|
||||
{ 1, QWORD, "cvtps2pi mm0,", 1, RM }, // 2D
|
||||
{ 1, DWORD, "ucomiss xmm0,", 1, RM }, // 2E
|
||||
{ 1, DWORD, "comiss xmm0,", 1, RM }, // 2F
|
||||
{ 0, 0, "wrmsr", 0 }, // 30
|
||||
{ 0, 0, "rdtsc", 0 }, // 31
|
||||
{ 0, 0, "rdmsr", 0 }, // 32
|
||||
{ 0, 0, "rdpmc", 0 }, // 33
|
||||
{ 0, 0, "sysenter", 0 }, // 34
|
||||
{ 0, 0, "sysexit", 0 }, // 35
|
||||
{ 0, 0, ".word 0x0f36", 0 }, // 36
|
||||
{ 0, 0, "getsec", 0 }, // 37
|
||||
{ 1, QWORD, "pshufb mm0,", 1, RM }, // 38
|
||||
{ 0, 0, ".word 0x0f39", 0 }, // 39
|
||||
{ 0, 0, "(bad)", 1, BAD }, // 3A
|
||||
{ 0, 0, ".word 0x0f3b", 0 }, // 3B
|
||||
{ 0, 0, ".word 0x0f3c", 0 }, // 3C
|
||||
{ 0, 0, ".word 0x0f3d", 0 }, // 3D
|
||||
{ 0, 0, ".word 0x0f3e", 0 }, // 3E
|
||||
{ 0, 0, ".word 0x0f3f", 0 }, // 3F
|
||||
{ 1, DWORD, "cmovo ", 2, R, RM }, // 40
|
||||
{ 1, DWORD, "cmovno ", 2, R, RM }, // 41
|
||||
{ 1, DWORD, "cmovb ", 2, R, RM }, // 42
|
||||
{ 1, DWORD, "cmovae ", 2, R, RM }, // 43
|
||||
{ 1, DWORD, "cmove ", 2, R, RM }, // 44
|
||||
{ 1, DWORD, "cmovne ", 2, R, RM }, // 45
|
||||
{ 1, DWORD, "cmovbe ", 2, R, RM }, // 46
|
||||
{ 1, DWORD, "cmova ", 2, R, RM }, // 47
|
||||
{ 1, DWORD, "cmovs ", 2, R, RM }, // 48
|
||||
{ 1, DWORD, "cmovns ", 2, R, RM }, // 49
|
||||
{ 1, DWORD, "cmovp ", 2, R, RM }, // 4A
|
||||
{ 1, DWORD, "cmovnp ", 2, R, RM }, // 4B
|
||||
{ 1, DWORD, "cmovl ", 2, R, RM }, // 4C
|
||||
{ 1, DWORD, "cmovge ", 2, R, RM }, // 4D
|
||||
{ 1, DWORD, "cmovle ", 2, R, RM }, // 4E
|
||||
{ 1, DWORD, "cmovg ", 2, R, RM }, // 4F
|
||||
{ 0, 0, ".word 0x0f50", 0 }, // 50
|
||||
{ 1, XMMWORD, "sqrtps xmm0,", 1, RM }, // 51
|
||||
{ 1, XMMWORD, "rsqrtps xmm0,", 1, RM }, // 52
|
||||
{ 1, XMMWORD, "rcpps xmm0,", 1, RM }, // 53
|
||||
{ 1, XMMWORD, "andps xmm0,", 1, RM }, // 54
|
||||
{ 1, XMMWORD, "andnps xmm0,", 1, RM }, // 55
|
||||
{ 1, XMMWORD, "orps xmm0,", 1, RM }, // 56
|
||||
{ 1, XMMWORD, "xorps xmm0,", 1, RM }, // 57
|
||||
{ 1, XMMWORD, "addps xmm0,", 1, RM }, // 58
|
||||
{ 1, XMMWORD, "mulps xmm0,", 1, RM }, // 59
|
||||
{ 1, QWORD, "cvtps2pd xmm0,", 1, RM }, // 5A
|
||||
{ 1, XMMWORD, "cvtdp2ps xmm0,", 1, RM }, // 5B
|
||||
{ 1, XMMWORD, "subps xmm0,", 1, RM }, // 5C
|
||||
{ 1, XMMWORD, "minps xmm0,", 1, RM }, // 5D
|
||||
{ 1, XMMWORD, "divps xmm0,", 1, RM }, // 5E
|
||||
{ 1, XMMWORD, "maxps xmm0,", 1, RM }, // 5F
|
||||
{ 1, DWORD, "punpcklbw mm0,", 1, RM }, // 60
|
||||
{ 1, DWORD, "punpcklwd mm0,", 1, RM }, // 61
|
||||
{ 1, DWORD, "punpckldq mm0,", 1, RM }, // 62
|
||||
{ 1, QWORD, "packsswb mm0,", 1, RM }, // 63
|
||||
{ 1, QWORD, "pcmpgtb mm0,", 1, RM }, // 64
|
||||
{ 1, QWORD, "pcmpgtw mm0,", 1, RM }, // 65
|
||||
{ 1, QWORD, "pcmpgtd mm0,", 1, RM }, // 66
|
||||
{ 1, QWORD, "packuswb mm0,", 1, RM }, // 67
|
||||
{ 1, QWORD, "punpckhbw mm0,", 1, RM }, // 68
|
||||
{ 1, QWORD, "punpckhwd mm0,", 1, RM }, // 69
|
||||
{ 1, QWORD, "punpckhdq mm0,", 1, RM }, // 6A
|
||||
{ 1, QWORD, "packssdw mm0,", 1, RM }, // 6B
|
||||
{ 0, 0, ".word 0x0f6c", 0 }, // 6C
|
||||
{ 0, 0, ".word 0x0f6d", 0 }, // 6D
|
||||
{ 1, DWORD, "movd mm0,", 1, RM }, // 6E
|
||||
{ 1, QWORD, "movq mm0,", 1, RM }, // 6F
|
||||
{ 1, QWORD, "pshufw mm0,", 2, RM, IMM8 }, // 70
|
||||
{ 0, 0, ".word 0x0f71", 0 }, // 71
|
||||
{ 0, 0, ".word 0x0f72", 0 }, // 72
|
||||
{ 0, 0, ".word 0x0f73", 0 }, // 73
|
||||
{ 1, QWORD, "pcmpeqb mm0,", 1, RM }, // 74
|
||||
{ 1, QWORD, "pcmpeqw mm0,", 1, RM }, // 75
|
||||
{ 1, QWORD, "pcmpeqd mm0,", 1, RM }, // 76
|
||||
{ 0, 0, "emms", 0 }, // 77
|
||||
{ 1, DWORD, "vmread ", 2, RM, R }, // 78
|
||||
{ 1, DWORD, "vmwrite ", 2, R, RM }, // 79
|
||||
{ 0, 0, "(bad)", 1, BAD }, // 7A
|
||||
{ 0, 0, ".word 0x0f7b", 0 }, // 7B
|
||||
{ 0, 0, ".word 0x0f7c", 0 }, // 7C
|
||||
{ 0, 0, ".word 0x0f7d", 0 }, // 7D
|
||||
{ 1, DWORD, "movd ", 2, RM, MM0 }, // 7E
|
||||
{ 1, QWORD, "movq ", 2, RM, MM0 }, // 7F
|
||||
{ 0, 0, "jo ", 1, REL32 }, // 80
|
||||
{ 0, 0, "jno ", 1, REL32 }, // 81
|
||||
{ 0, 0, "jb ", 1, REL32 }, // 82
|
||||
{ 0, 0, "jae ", 1, REL32 }, // 83
|
||||
{ 0, 0, "je ", 1, REL32 }, // 84
|
||||
{ 0, 0, "jne ", 1, REL32 }, // 85
|
||||
{ 0, 0, "jbe ", 1, REL32 }, // 86
|
||||
{ 0, 0, "ja ", 1, REL32 }, // 87
|
||||
{ 0, 0, "js ", 1, REL32 }, // 88
|
||||
{ 0, 0, "jns ", 1, REL32 }, // 89
|
||||
{ 0, 0, "jp ", 1, REL32 }, // 8A
|
||||
{ 0, 0, "jnp ", 1, REL32 }, // 8B
|
||||
{ 0, 0, "jl ", 1, REL32 }, // 8C
|
||||
{ 0, 0, "jge ", 1, REL32 }, // 8D
|
||||
{ 0, 0, "jle ", 1, REL32 }, // 8E
|
||||
{ 0, 0, "jg ", 1, REL32 }, // 8F
|
||||
{ 1, BYTE, "seto ", 1, RM }, // 90
|
||||
{ 1, BYTE, "setno ", 1, RM }, // 91
|
||||
{ 1, BYTE, "setb ", 1, RM }, // 92
|
||||
{ 1, BYTE, "setae ", 1, RM }, // 93
|
||||
{ 1, BYTE, "sete ", 1, RM }, // 94
|
||||
{ 1, BYTE, "setne ", 1, RM }, // 95
|
||||
{ 1, BYTE, "setbe ", 1, RM }, // 96
|
||||
{ 1, BYTE, "seta ", 1, RM }, // 97
|
||||
{ 1, BYTE, "sets ", 1, RM }, // 98
|
||||
{ 1, BYTE, "setns ", 1, RM }, // 99
|
||||
{ 1, BYTE, "setp ", 1, RM }, // 9A
|
||||
{ 1, BYTE, "setnp ", 1, RM }, // 9B
|
||||
{ 1, BYTE, "setl ", 1, RM }, // 9C
|
||||
{ 1, BYTE, "setge ", 1, RM }, // 9D
|
||||
{ 1, BYTE, "setle ", 1, RM }, // 9E
|
||||
{ 1, BYTE, "setg ", 1, RM }, // 9F
|
||||
{ 0, 0, "push fs", 0 }, // A0
|
||||
{ 0, 0, "pop fs", 0 }, // A1
|
||||
{ 0, 0, "cpuid", 0 }, // A2
|
||||
{ 1, DWORD, "bt ", 2, RM, R }, // A3
|
||||
{ 1, DWORD, "shld ", 3, RM, R, IMM8 }, // A4
|
||||
{ 1, DWORD, "shld ", 3, RM, R, CL }, // A5
|
||||
{ 0 }, // A6 - Illegal
|
||||
{ 0 }, // A7 - Illegal
|
||||
{ 0, 0, "push gs", 0 }, // A8
|
||||
{ 0, 0, "pop gs", 0 }, // A9
|
||||
{ 0, 0, "rsm", 0 }, // AA
|
||||
{ 1, DWORD, "bts ", 2, RM, R }, // AB
|
||||
{ 1, DWORD, "shrd ", 3, RM, R, IMM8 }, // AC
|
||||
{ 1, DWORD, "shrd ", 3, RM, R, CL }, // AD
|
||||
{ 1, 0, "fxsave ", 1, RM }, // AE
|
||||
{ 1, DWORD, "imul ", 2, R, RM }, // AF
|
||||
{ 1, BYTE, "cmpxchg ", 2, RM, AL }, // B0
|
||||
{ 1, DWORD, "cmpxchg ", 2, RM, R }, // B1
|
||||
{ 1, FWORD, "lss ", 2, R, RM }, // B2
|
||||
{ 1, DWORD, "btr ", 2, RM, R }, // B3
|
||||
{ 1, FWORD, "lfs ", 2, R, RM }, // B4
|
||||
{ 1, FWORD, "lgs ", 2, R, RM }, // B5
|
||||
{ 1, BYTE, "movzx ", 2, R, RM }, // B6
|
||||
{ 1, WORD, "movzx ", 2, R, RM }, // B7
|
||||
{ 0, 0, ".word 0x0fb8", 0 }, // B8
|
||||
{ 0, 0, "ud1", 0 }, // B9
|
||||
{ 0, 0, ".word 0x0fba", 0 }, // BA
|
||||
{ 1, DWORD, "btc ", 2, RM, R }, // BB
|
||||
{ 1, DWORD, "bsf ", 2, R, RM }, // BC
|
||||
{ 1, DWORD, "bsr ", 2, R, RM }, // BD
|
||||
{ 1, BYTE, "movsx ", 2, R, RM }, // BE
|
||||
{ 1, WORD, "movsx ", 2, R, RM }, // BF
|
||||
{ 1, BYTE, "xadd ", 2, RM, R }, // C0
|
||||
{ 1, DWORD, "xadd ", 2, RM, R }, // C1
|
||||
{ 1, XMMWORD, "cmpeqps xmm0,", 1, RM }, // C2
|
||||
{ 1, QWORD, "movnti ", 2, RM, R }, // C3
|
||||
{ 1, WORD, "pinsrw mm0,", 2, RM, IMM8 }, // C4
|
||||
{ 1, 0, "pextrw ", 3, R, MM0, IMM8 }, // C5
|
||||
{ 1, XMMWORD, "shufps xmm0,", 2, RM, IMM8 }, // C6
|
||||
{ 0, 0, ".word 0x0fc7", 0 }, // C7
|
||||
{ 0, 0, "bswap eax", 0 }, // C8
|
||||
{ 0, 0, "bswap ecx", 0 }, // C9
|
||||
{ 0, 0, "bswap edx", 0 }, // CA
|
||||
{ 0, 0, "bswap ebx", 0 }, // CB
|
||||
{ 0, 0, "bswap esp", 0 }, // CC
|
||||
{ 0, 0, "bswap ebp", 0 }, // CD
|
||||
{ 0, 0, "bswap esi", 0 }, // CE
|
||||
{ 0, 0, "bswap edi", 0 }, // CF
|
||||
{ 0, 0, ".word 0x0fd0", 0 }, // D0
|
||||
{ 1, QWORD, "psrlw mm0,", 1, RM }, // D1
|
||||
{ 1, QWORD, "psrld mm0,", 1, RM }, // D2
|
||||
{ 1, QWORD, "psrlq mm0,", 1, RM }, // D3
|
||||
{ 1, QWORD, "paddq mm0,", 1, RM }, // D4
|
||||
{ 1, QWORD, "pmullw mm0,", 1, RM }, // D5
|
||||
{ 0, 0, ".word 0x0fd6,", 0 }, // D6
|
||||
{ 0, 0, ".word 0x0fd7,", 0 }, // D7
|
||||
{ 1, QWORD, "psubusb mm0,", 1, RM }, // D8
|
||||
{ 1, QWORD, "psubusw mm0,", 1, RM }, // D9
|
||||
{ 1, QWORD, "pminub mm0,", 1, RM }, // DA
|
||||
{ 1, QWORD, "pand mm0,", 1, RM }, // DB
|
||||
{ 1, QWORD, "paddusb mm0,", 1, RM }, // DC
|
||||
{ 1, QWORD, "psubusw mm0,", 1, RM }, // DD
|
||||
{ 1, QWORD, "pmaxub mm0,", 1, RM }, // DE
|
||||
{ 1, QWORD, "pandn mm0,", 1, RM }, // DF
|
||||
{ 1, QWORD, "pavgb mm0,", 1, RM }, // E0
|
||||
{ 1, QWORD, "psraw mm0,", 1, RM }, // E1
|
||||
{ 1, QWORD, "psrad mm0,", 1, RM }, // E2
|
||||
{ 1, QWORD, "pavgw mm0,", 1, RM }, // E3
|
||||
{ 1, QWORD, "pmulhuw mm0,", 1, RM }, // E4
|
||||
{ 1, QWORD, "pmulhw mm0,", 1, RM }, // E5
|
||||
{ 0, 0, ".word 0x0fe6", 0 }, // E6
|
||||
{ 1, QWORD, "movntq ", 2, RM, MM0 }, // E7
|
||||
{ 1, QWORD, "psubsb mm0,", 1, RM }, // E8
|
||||
{ 1, QWORD, "psubsw mm0,", 1, RM }, // E9
|
||||
{ 1, QWORD, "pminsw mm0,", 1, RM }, // EA
|
||||
{ 1, QWORD, "por mm0,", 1, RM }, // EB
|
||||
{ 1, QWORD, "paddsb mm0,", 1, RM }, // EC
|
||||
{ 1, QWORD, "paddsw mm0,", 1, RM }, // ED
|
||||
{ 1, QWORD, "pmaxsw mm0,", 1, RM }, // EE
|
||||
{ 1, QWORD, "pxor mm0,", 1, RM }, // EF
|
||||
{ 0, 0, ".word 0x0ff0", 0 }, // F0
|
||||
{ 1, QWORD, "psllow mm0,", 1, RM }, // F1
|
||||
{ 1, QWORD, "pslld mm0,", 1, RM }, // F2
|
||||
{ 1, QWORD, "psllq mm0,", 1, RM }, // F3
|
||||
{ 1, QWORD, "pmuludq mm0,", 1, RM }, // F4
|
||||
{ 1, QWORD, "pmaddwd mm0,", 1, RM }, // F5
|
||||
{ 1, QWORD, "psadbw mm0,", 1, RM }, // F6
|
||||
{ 0 }, // F7 - Illegal
|
||||
{ 1, QWORD, "psubb mm0,", 1, RM }, // F8
|
||||
{ 1, QWORD, "psubw mm0,", 1, RM }, // F9
|
||||
{ 1, QWORD, "psubd mm0,", 1, RM }, // FA
|
||||
{ 1, QWORD, "psubq mm0,", 1, RM }, // FB
|
||||
{ 1, QWORD, "paddb mm0,", 1, RM }, // FC
|
||||
{ 1, QWORD, "paddw mm0,", 1, RM }, // FD
|
||||
{ 1, QWORD, "paddd mm0,", 1, RM }, // FE
|
||||
{ 0 }, // FF - Illegal
|
||||
};
|
||||
|
||||
unsigned int disasm(const unsigned char *__bytes, unsigned int max, unsigned long offset, char *output) {
|
||||
unsigned char *pad[32];
|
||||
unsigned char *bytes;
|
||||
const unsigned char *base;
|
||||
unsigned char opcode;
|
||||
char RM_output[32];
|
||||
char R_output[32];
|
||||
|
||||
char modRM_mod;
|
||||
char modRM_reg;
|
||||
char modRM_rm;
|
||||
int i;
|
||||
INSTRUCTION *instructions ;
|
||||
|
||||
memset (pad, 0, sizeof (pad));
|
||||
if (max > sizeof (pad))
|
||||
max = sizeof (pad);
|
||||
memcpy (pad, __bytes, max);
|
||||
bytes = (unsigned char *)pad;
|
||||
base = bytes;
|
||||
opcode = *bytes;
|
||||
bytes++;
|
||||
|
||||
*output = 0;
|
||||
instructions = standard_instructions;
|
||||
if (opcode == 0x0F) { // Extended opcodes
|
||||
if (max < 2 || *bytes == 0x0F || *bytes == 0xA6 || *bytes == 0xA7 || *bytes == 0xF7 || *bytes == 0xFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
instructions = extended_instructions;
|
||||
opcode = *bytes++;
|
||||
}
|
||||
|
||||
if (!instructions[opcode].hasModRM) {
|
||||
goto OUTPUT; // Skip ModRM byte parsing
|
||||
}
|
||||
|
||||
modRM_mod = ((*bytes) >> 6) & 3; // 3; // Bits 7-6.
|
||||
modRM_reg = ((*bytes) >> 3) & 7; // 7; // Bits 5-3.
|
||||
modRM_rm = (*bytes++) & 7; // 7; // Bits 2-0.
|
||||
|
||||
switch (instructions[opcode].size) {
|
||||
case WORD:
|
||||
strcpy(R_output, register_mnemonics16[modRM_reg]);
|
||||
break;
|
||||
case BYTE:
|
||||
strcpy(R_output, register_mnemonics8[modRM_reg]);
|
||||
break;
|
||||
default:
|
||||
strcpy(R_output, register_mnemonics32[modRM_reg]);
|
||||
}
|
||||
|
||||
if (modRM_mod == 3) { // Register addressing mode.
|
||||
switch (instructions[opcode].size) {
|
||||
case BYTE:
|
||||
sprintf(RM_output, "%s", register_mnemonics8[modRM_rm]);
|
||||
break;
|
||||
case WORD:
|
||||
sprintf(RM_output, "%s", register_mnemonics16[modRM_rm]);
|
||||
break;
|
||||
default:
|
||||
sprintf(RM_output, "%s", register_mnemonics32[modRM_rm]);
|
||||
}
|
||||
} else if (modRM_mod == 0 && modRM_rm == 5) { // Displacement only addressing mode.
|
||||
sprintf(RM_output, "[0x%x]", *(int *)bytes);
|
||||
bytes += 4;
|
||||
} else { // One-byte or four-byte signed displacement follows addressing mode byte(s).
|
||||
if (modRM_rm == 4) { // Contains SIB byte
|
||||
char SIB_scale = ((*bytes) >> 6) & 3; // Bits 7-6.
|
||||
char SIB_index = ((*bytes) >> 3) & 7; // Bits 5-3.
|
||||
char SIB_base = (*bytes++) & 7; // Bits 2-0.
|
||||
|
||||
if (SIB_base == 5 && modRM_mod == 0) {
|
||||
sprintf(RM_output, "[0x%x", *(int *)bytes);
|
||||
bytes += 4;
|
||||
} else {
|
||||
strcpy(RM_output, sib_base_mnemonics[SIB_base]);
|
||||
}
|
||||
|
||||
if (SIB_index != 20) {
|
||||
strcat(RM_output, "+");
|
||||
strcat(RM_output, register_mnemonics32[SIB_index]);
|
||||
strcat(RM_output, sib_scale_mnemonics[SIB_scale]);
|
||||
}
|
||||
} else {
|
||||
sprintf(RM_output, "[%s", register_mnemonics32[modRM_rm]);
|
||||
}
|
||||
|
||||
if (modRM_mod == 1) { // One-byte signed displacement follows addressing mode byte(s).
|
||||
if (*bytes > 0x7F) {
|
||||
sprintf(RM_output + strlen(RM_output), "-0x%x]", -*(char *)bytes++);
|
||||
} else {
|
||||
sprintf(RM_output + strlen(RM_output), "+0x%x]", *(char *)bytes++);
|
||||
}
|
||||
} else if (modRM_mod == 2) { // Four-byte signed displacement follows addressing mode byte(s).
|
||||
if (*(unsigned int *)bytes > 0x7FFFFFFF) {
|
||||
sprintf(RM_output + strlen(RM_output), "-0x%x]", -*(int *)bytes);
|
||||
} else {
|
||||
sprintf(RM_output + strlen(RM_output), "+0x%x]", *(unsigned int *)bytes);
|
||||
}
|
||||
|
||||
bytes += 4;
|
||||
} else {
|
||||
strcat(RM_output, "]");
|
||||
}
|
||||
}
|
||||
|
||||
OUTPUT:
|
||||
strcpy(output, instructions[opcode].mnemonic);
|
||||
for (i = 0; i < instructions[opcode].argument_count; i++) {
|
||||
if (i > 0) {
|
||||
strcat(output, ",");
|
||||
}
|
||||
|
||||
switch (instructions[opcode].arguments[i]) {
|
||||
case RM:
|
||||
if (modRM_mod != 3) {
|
||||
switch (instructions[opcode].size) {
|
||||
case BYTE:
|
||||
strcat(output, "BYTE PTR ");
|
||||
break;
|
||||
case WORD:
|
||||
strcat(output, "WORD PTR ");
|
||||
break;
|
||||
case DWORD:
|
||||
strcat(output, "DWORD PTR ");
|
||||
break;
|
||||
case QWORD:
|
||||
strcat(output, "QWORD PTR ");
|
||||
break;
|
||||
case FWORD:
|
||||
strcat(output, "FWORD PTR ");
|
||||
break;
|
||||
case XMMWORD:
|
||||
strcat(output, "XMMWORD PTR ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strcat(output, RM_output);
|
||||
break;
|
||||
case R:
|
||||
strcat(output, R_output);
|
||||
break;
|
||||
case IMM8:
|
||||
sprintf(output + strlen(output), "0x%x", *bytes++);
|
||||
break;
|
||||
case IMM16:
|
||||
sprintf(output + strlen(output), "0x%x", *(short *)bytes);
|
||||
bytes += 2;
|
||||
break;
|
||||
case IMM32:
|
||||
sprintf(output + strlen(output), "0x%x", *(int *)bytes);
|
||||
bytes += 4;
|
||||
break;
|
||||
case REL8:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int) (offset + ((bytes - base) + 1) + *bytes));
|
||||
bytes++;
|
||||
break;
|
||||
case REL16:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int)(offset + ((bytes - base) + 2) + *(short *)bytes));
|
||||
bytes += 2;
|
||||
break;
|
||||
case REL32:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int)(offset + ((bytes - base) + 4) + *(int *)bytes));
|
||||
bytes += 4;
|
||||
break;
|
||||
case PTR1632:
|
||||
sprintf(output + strlen(output), "0x%x:0x%x", *(short *)(bytes + 4), *(int *)bytes);
|
||||
bytes += 6;
|
||||
break;
|
||||
case AL:
|
||||
strcat(output, "al");
|
||||
break;
|
||||
case EAX:
|
||||
strcat(output, "eax");
|
||||
break;
|
||||
case ES:
|
||||
strcat(output, "es");
|
||||
break;
|
||||
case CS:
|
||||
strcat(output, "cs");
|
||||
break;
|
||||
case SS:
|
||||
strcat(output, "ss");
|
||||
break;
|
||||
case DS:
|
||||
strcat(output, "ds");
|
||||
break;
|
||||
case ONE:
|
||||
strcat(output, "1");
|
||||
break;
|
||||
case CL:
|
||||
strcat(output, "cl");
|
||||
break;
|
||||
case XMM0:
|
||||
strcat(output, "xmm0");
|
||||
break;
|
||||
case BND0:
|
||||
strcat(output, "bnd0");
|
||||
break;
|
||||
case BAD:
|
||||
bytes++;
|
||||
break;
|
||||
case MM0:
|
||||
strcat(output, "mm0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (((unsigned int)(bytes - base)) <= max) {
|
||||
return bytes - base;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
|
||||
/* io.c - MIT - Copyleft 2009-2021 -- pancake */
|
||||
|
||||
#ifndef HAVE_FTRUNCATE
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#endif
|
||||
|
||||
#define DEMO 0
|
||||
#if DEMO
|
||||
int bo = 0;
|
||||
char b[4096];
|
||||
static inline int io_open(char *file) {
|
||||
static inline int io_open(const char *file) {
|
||||
memset (b, 0, sizeof (b));
|
||||
return 10;
|
||||
}
|
||||
@@ -25,7 +29,7 @@ static int io_seek (int x,int y) {
|
||||
|
||||
#include <windows.h>
|
||||
static HANDLE _fd = NULL;
|
||||
static inline int io_open(char *file) {
|
||||
static inline int io_open(const char *file) {
|
||||
_fd = CreateFile(file, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_ALWAYS, 0, NULL);
|
||||
@@ -51,7 +55,7 @@ static inline int io_read(void *x, int y) {
|
||||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
static int _fd = -1;
|
||||
static inline int io_open(char *file) {
|
||||
static inline int io_open(const char *file) {
|
||||
_fd = open(file, O_RDWR|O_CREAT, 0644);
|
||||
if(_fd == -1) _fd = open(file, O_RDONLY);
|
||||
return _fd;
|
||||
@@ -61,7 +65,11 @@ static inline int io_open(char *file) {
|
||||
#define io_seek(x,y) lseek(_fd, x, y)
|
||||
#define io_close() close(_fd)
|
||||
#define io_system(x) system(x)
|
||||
#define io_truncate(x) ftruncate(_fd, (unsigned long)x)
|
||||
#if HAVE_FTRUNCATE
|
||||
#define io_truncate(x) ftruncate(_fd, (off_t)x)
|
||||
#else
|
||||
#define io_truncate(x) printf("truncate: TODO\n");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+8
-8
@@ -1,11 +1,11 @@
|
||||
.Dd Oct 7, 2009
|
||||
.Dt IRED 1
|
||||
.Dd Mar 7, 2021
|
||||
.Dt R0 1
|
||||
.Os
|
||||
.Th IRED 1
|
||||
.Th R0 1
|
||||
.Sh NAME
|
||||
ired \- interactive raw editor
|
||||
r0 \- interactive raw editor
|
||||
.Sh SYNOPSIS
|
||||
.Nm ired
|
||||
.Nm r0
|
||||
.Op Fl hnv
|
||||
.Op Fl i Ar script
|
||||
.Ar file ...
|
||||
@@ -22,9 +22,9 @@ Show version information
|
||||
.It Fl n
|
||||
Do not be verbose
|
||||
.It Fl i Ar script
|
||||
Interpret a script file as ired commands.
|
||||
Interpret a script file as r0 commands.
|
||||
.Pp
|
||||
Same as "ired file < script"
|
||||
Same as "r0 file < script"
|
||||
.El
|
||||
.PP
|
||||
.Sh COMMANDS
|
||||
@@ -117,7 +117,7 @@ quit
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Pp
|
||||
.Xr vired(1)
|
||||
.Xr r0v(1)
|
||||
.Sh AUTHORS
|
||||
.PP
|
||||
pancake <@nopcode.org>
|
||||
+64
-33
@@ -1,20 +1,33 @@
|
||||
/* Copyleft 2009-2013 -- pancake /at/ nopcode /dot/ org */
|
||||
/* MIT 2009-2021 -- pancake /at/ nopcode /dot/ org */
|
||||
|
||||
#define ut64 unsigned long long
|
||||
#define ut8 unsigned char
|
||||
|
||||
static int earlyquit = 0;
|
||||
static int verbose = 1;
|
||||
static char *script = 0;
|
||||
static int scriptn = 0;
|
||||
static const char **scripts = 0;
|
||||
static int cmdn = 0;
|
||||
static char **cmds = 0;
|
||||
static ut64 oldseek, curseek = 0LL;
|
||||
static int obsize, bsize = 256;
|
||||
static int red_cmd(char *cmd); // XXX : recursive depenency
|
||||
int r0_cmd(const char *cmd); // XXX : recursive depenency
|
||||
#if defined(__WATCOMC__)
|
||||
#define HAVE_FTRUNCATE 0
|
||||
#define BUFSZ 1024
|
||||
#elif __wasi__
|
||||
#define BUFSZ 128
|
||||
#else
|
||||
#define BUFSZ 128*1024
|
||||
#endif
|
||||
|
||||
#include "ired.h"
|
||||
ut64 calc(const char *str);
|
||||
#include "r0.h"
|
||||
#include "util.c"
|
||||
#include "calc.c"
|
||||
#include "cmd.c"
|
||||
|
||||
static void red_slurpin() {
|
||||
static void r0_slurpin() {
|
||||
ut8 buf[BUFSZ];
|
||||
for(;;) {
|
||||
int len = read(0, buf, sizeof(buf));
|
||||
@@ -24,14 +37,14 @@ static void red_slurpin() {
|
||||
}
|
||||
}
|
||||
|
||||
static int red_interpret(char *file) {
|
||||
static int r0_interpret(const char *file) {
|
||||
char buf[BUFSZ];
|
||||
FILE *fd = fopen(file, "r");
|
||||
if(fd != NULL) {
|
||||
for(;;) {
|
||||
if(fgets(buf, sizeof(buf), fd) == NULL)
|
||||
break;
|
||||
red_cmd(buf);
|
||||
r0_cmd(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
} else if (file)
|
||||
@@ -39,31 +52,33 @@ static int red_interpret(char *file) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int red_cmd(char *cmd) {
|
||||
char *arg = cmd+1;
|
||||
int r0_cmd(const char *cmd) {
|
||||
const char *arg = cmd+1;
|
||||
SKIPSPACES(arg);
|
||||
switch(*cmd) {
|
||||
case 'q': return 0;
|
||||
case ';': case '#': break; // comment
|
||||
case '>': return cmd_dump(arg); break;
|
||||
case '<': return cmd_load(arg); break;
|
||||
case '.': return red_interpret(arg); break;
|
||||
case '.': return r0_interpret(arg); break;
|
||||
case 's': return cmd_seek(arg); break;
|
||||
case 'b': return cmd_bsize(arg); break;
|
||||
case '/': return cmd_search(arg); break;
|
||||
case 'd': return cmd_disasm(arg); break;
|
||||
case 'p': return cmd_print(arg); break;
|
||||
case 'r': return cmd_resize(arg); break;
|
||||
case 'x': return cmd_hexdump(arg); break;
|
||||
case 'X': return cmd_bytedump(arg); break;
|
||||
case 'w': return cmd_write(arg); break;
|
||||
case '!': return cmd_system(arg); break;
|
||||
case 'V': return cmd_system("vr0 $FILE"); break;
|
||||
case '?': return cmd_help(arg); break;
|
||||
default: fprintf(stderr, "? %s\n", cmd);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int red_prompt() {
|
||||
static int r0_prompt() {
|
||||
char *at, *at2, line[BUFSZ];
|
||||
if(verbose) {
|
||||
printf("[0x%08"LLF"x]> ", curseek);
|
||||
@@ -81,24 +96,30 @@ static int red_prompt() {
|
||||
at2 = strchr(++at, ':');
|
||||
if(at2) {
|
||||
*at2 = 0; at2++;
|
||||
if(*at2) bsize = (int)str2ut64(at2);
|
||||
if(*at2) bsize = (int)calc(at2);
|
||||
}
|
||||
if(*at) curseek = str2ut64(at);
|
||||
if(*at) curseek = calc(at);
|
||||
}
|
||||
}
|
||||
at = line;
|
||||
SKIPSPACES(at);
|
||||
return red_cmd(at);
|
||||
return r0_cmd(at);
|
||||
}
|
||||
|
||||
static int red_open(char *file) {
|
||||
int r0_open(const char *file) {
|
||||
int ret = io_open(file);
|
||||
if(ret != -1) {
|
||||
oldseek = 0;
|
||||
setenv("FILE", file, 1);
|
||||
if(script)
|
||||
red_interpret(script);
|
||||
while((ret=red_prompt())>0) {
|
||||
if(scripts)
|
||||
for (ret=0;ret<scriptn;ret++)
|
||||
r0_interpret(scripts[ret]);
|
||||
if(cmds)
|
||||
for (ret=0;ret<cmdn;ret++)
|
||||
r0_cmd(cmds[ret]);
|
||||
if(earlyquit)
|
||||
return 0;
|
||||
while((ret=r0_prompt())>0) {
|
||||
curseek = oldseek;
|
||||
bsize = obsize;
|
||||
}
|
||||
@@ -108,27 +129,37 @@ static int red_open(char *file) {
|
||||
return ret==-1 ?1:0;
|
||||
}
|
||||
|
||||
static int red_help() {
|
||||
puts("ired [-hnv] [-i script] [file] [..]");
|
||||
static int r0_help() {
|
||||
puts("r0 [-qhnv] [-c cmd] [-i script] [-|file ..]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i, ret = 1;
|
||||
argc++;
|
||||
if(argc>1 && argv[1])
|
||||
for(i=1; i<argc; i++) {
|
||||
if(argv[i] && argv[i][0]=='-')
|
||||
switch(argv[i][1]) {
|
||||
case 'i': script = argv[++i]; break;
|
||||
case 'n': verbose = 0; break;
|
||||
case 'v': puts("ired "VERSION); ret = 0; break;
|
||||
case 'h': ret = red_help(); break;
|
||||
case 0x0: red_slurpin(); ret = 0; break;
|
||||
} else {
|
||||
if (!argv[i]) break;
|
||||
ret = red_open(argv[i]);
|
||||
cmdn = 0;
|
||||
scriptn = 0;
|
||||
scripts = calloc(sizeof(const char*), argc);
|
||||
cmds = calloc(sizeof(const char*), argc);
|
||||
if(argc > 1 && argv[1]) {
|
||||
for(i = 1; i < argc; i++) {
|
||||
if(argv[i] && argv[i][0]=='-')
|
||||
switch(argv[i][1]) {
|
||||
case 'q': earlyquit = 1; break;
|
||||
case 'i': scripts[scriptn++] = argv[++i]; break;
|
||||
case 'c': cmds[cmdn++] = argv[++i]; break;
|
||||
case 'n': verbose = 0; break;
|
||||
case 'v': puts(VERSION); ret = 0; break;
|
||||
case 'h': ret = r0_help(); break;
|
||||
case 0x0: r0_slurpin(); ret = 0; break;
|
||||
} else {
|
||||
if (!argv[i]) break;
|
||||
ret = r0_open(argv[i]);
|
||||
}
|
||||
}
|
||||
} else ret = red_help();
|
||||
} else {
|
||||
ret = r0_help();
|
||||
}
|
||||
free(scripts);
|
||||
return ret;
|
||||
}
|
||||
+6
-2
@@ -1,4 +1,4 @@
|
||||
#define VERSION "0.5"
|
||||
#define VERSION "0.9"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -10,7 +10,11 @@
|
||||
|
||||
#define SKIPSPACES(x) for(;*(x)==' '||*(x)=='\t';x++) {};
|
||||
|
||||
#if(plan9)
|
||||
#if(R0_NOENV)
|
||||
#define LLF "ll"
|
||||
#define setenv(x,y,z) //
|
||||
// static int setenv(char *var, char *val, int force) { return 0; }
|
||||
#elif(plan9)
|
||||
static int setenv(char *var, char *val, int force) {
|
||||
char str[256];
|
||||
snprintf(str, sizeof(str), "echo %s > /env/%s", var, val);
|
||||
+7
-3
@@ -1,4 +1,4 @@
|
||||
/* bdiff - MIT - Copyright 2010-2013 - pancake */
|
||||
/* bdiff - MIT - Copyright 2010-2021 - pancake */
|
||||
/* Adapted code from:
|
||||
|
||||
bdiff.c - efficient binary diff extension for Mercurial
|
||||
@@ -90,7 +90,7 @@ static int equatelines(struct line *a, int an, struct line *b, int bn) {
|
||||
|
||||
/* try to allocate a large hash table to avoid collisions */
|
||||
for(scale = 4; scale; scale /= 2) {
|
||||
h = (struct pos *)malloc(scale * buckets * sizeof(struct pos));
|
||||
h = (struct pos *)calloc(buckets, scale * sizeof(struct pos));
|
||||
if(h)
|
||||
break;
|
||||
}
|
||||
@@ -302,6 +302,8 @@ int bdiff(const char *filea, const char *fileb) {
|
||||
la = lb = 0;
|
||||
for(h = l.base; h != l.head; h++) {
|
||||
if(h->a1 != la || h->b1 != lb) {
|
||||
if (h->b1 > bn) break;
|
||||
if (lb > bn) break;
|
||||
len = bl[h->b1].l - bl[lb].l;
|
||||
offa = al[la].l - al->l;
|
||||
offb = al[h->a1].l - al->l;
|
||||
@@ -316,6 +318,8 @@ int bdiff(const char *filea, const char *fileb) {
|
||||
|
||||
if(len == rlen) {
|
||||
for(i=0; i<len; i++) {
|
||||
if (lb < bn) break;
|
||||
if (la < bn) break;
|
||||
if(bl[lb].l[i] != bl[la].l[i])
|
||||
fprintf(stderr, "%02x %02x\n",
|
||||
(unsigned char)
|
||||
@@ -355,6 +359,6 @@ int main(int argc, const char **argv) {
|
||||
if(bdiff(argv[1], argv[2]) == -1)
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
else ret = 0;
|
||||
} else fprintf(stderr, "bdiff [file] [file2] > patch.ired\n");
|
||||
} else fprintf(stderr, "r0d [file] [file2] > patch.ired\n");
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/bin/sh
|
||||
# r0v: the visual raw editor
|
||||
# copyleft: pancake at nopcode dot org @ 2009-2013
|
||||
|
||||
PATH=.:$PATH
|
||||
|
||||
ttyset=`stty -g`
|
||||
bye() {
|
||||
[ -n "$ttyset" ] && stty $ttyset
|
||||
exit 0
|
||||
}
|
||||
case "$1" in
|
||||
-) : ; ;;
|
||||
'') echo "r0v [-hv] [file]" ; exit 1 ; ;;
|
||||
*) $0 - | r0 -n $@ ; bye ; ;;
|
||||
esac
|
||||
|
||||
ttyset=`stty -g`
|
||||
stty -echo -icanon min 1
|
||||
trap bye 2
|
||||
|
||||
getkey() {
|
||||
read -n 1 A
|
||||
echo "$A"
|
||||
#echo "` stty -echo -icanon min 1 ; dd if=/dev/tty count=1 bs=1 2>/dev/null`"
|
||||
}
|
||||
|
||||
getstr() {
|
||||
stty icanon echo 2>/dev/null
|
||||
read A
|
||||
echo "$A"
|
||||
stty -icanon -echo 2>/dev/null
|
||||
}
|
||||
|
||||
OLINES=0
|
||||
autobs() {
|
||||
NLINES=`tput lines 2> /dev/null`
|
||||
#echo "b "$(($NLINES*16))
|
||||
#return
|
||||
if [ -n "${NLINES}" -a "${OLINES}" != "${NLINES}" ]; then
|
||||
LINES=${NLINES}
|
||||
[ -n "${LINES}" ] && \
|
||||
echo "b "$((($LINES-1)*16))
|
||||
OLINES=${LINES}
|
||||
fi
|
||||
}
|
||||
|
||||
trap autobs 28
|
||||
|
||||
P=''
|
||||
echo "b 256"
|
||||
while : ; do
|
||||
echo '!clear'
|
||||
# autobs
|
||||
case $P in
|
||||
#'d') echo '!echo X | r0 -n $| rasm2 -o $OFFSET -vd -|head -n '$LINES ; ;;
|
||||
d) echo d ;;
|
||||
*) echo x ;;
|
||||
esac
|
||||
case "`getkey`" in
|
||||
'j') echo "s+16" ;;
|
||||
'k') echo "s-16" ;;
|
||||
'J') echo "s+b" ;;
|
||||
'K') echo "s-b" ;;
|
||||
'h') echo "s-1" ;;
|
||||
'l') echo "s+1" ;;
|
||||
'q') bye ; ;;
|
||||
'b') printf 'b'>/dev/tty; echo b`getstr` ;;
|
||||
'w') printf 'w'>/dev/tty; echo w`getstr` ;;
|
||||
'i') printf 'w'>/dev/tty; echo w`getstr` ;; ## alias to mimic r2
|
||||
's') printf 's'>/dev/tty; echo s`getstr` ;;
|
||||
'r') printf 'r '>/dev/tty; echo r`getstr` ;;
|
||||
':') printf ': '>/dev/tty; getstr; getkey >/dev/null ; ;;
|
||||
'?') echo '!clear' ; echo '?'; getkey ; ;;
|
||||
'+') echo "b+1" ;;
|
||||
'-') echo "b-1" ;;
|
||||
'.') echo "s0" ;;
|
||||
'^') echo "s0" ;;
|
||||
'^') echo "s0" ;;
|
||||
'$') echo 's`r`' ;;
|
||||
'G') echo 's`r`' ;;
|
||||
'*') echo "b+16" ;;
|
||||
'/') echo "b-16" ;;
|
||||
p|P) if [ -n "$P" ]; then P=''; else P=d; fi ;;
|
||||
esac
|
||||
done
|
||||
+9
-9
@@ -1,14 +1,14 @@
|
||||
.Dd Oct 7, 2009
|
||||
.Dt VIRED 1
|
||||
.Dd Mar 7, 2021
|
||||
.Dt VR0 1
|
||||
.Os
|
||||
.Th VIRED 1
|
||||
.Th VR0 1
|
||||
.Sh NAME
|
||||
vired \- visual interactive raw editor
|
||||
r0v \- visual radare zero
|
||||
.Sh SYNOPSIS
|
||||
.Nm vired
|
||||
.Nm r0v
|
||||
.Ar file
|
||||
.Sh DESCRIPTION
|
||||
Visual mode for ired(1)
|
||||
Visual mode for r0(1)
|
||||
.Pp
|
||||
.Sh KEYS
|
||||
.Bl -tag -width Fl
|
||||
@@ -17,7 +17,7 @@ seek left(-1), down(+16), up(-16), right(+1)
|
||||
.It +-*/
|
||||
change block size (+1,-1,+16,-16)
|
||||
.It :[cmd]
|
||||
input ired command
|
||||
input r0 command
|
||||
.It b
|
||||
prompt to change block size
|
||||
.It s
|
||||
@@ -27,7 +27,7 @@ prompt for resize, remove command
|
||||
.It p
|
||||
change print mode
|
||||
.It :
|
||||
enter raw ired command
|
||||
enter raw r0 command
|
||||
.It ?
|
||||
show help
|
||||
.It q
|
||||
@@ -35,7 +35,7 @@ quit program
|
||||
.Pp
|
||||
.Sh SEE ALSO
|
||||
.Pp
|
||||
.Xr ired(1)
|
||||
.Xr r0(1)
|
||||
.Sh AUTHORS
|
||||
.PP
|
||||
pancake <@nopcode.org>
|
||||
@@ -0,0 +1,7 @@
|
||||
while : ; do
|
||||
rm -f r0.x86
|
||||
gcc -DUSE_DISASM_X32=1 -flto -O3 r0.c -o r0.x86
|
||||
strip r0.x86
|
||||
ls -l r0.x86
|
||||
sleep 1
|
||||
done
|
||||
+1
-1
@@ -2,4 +2,4 @@ all:
|
||||
sh test.sh
|
||||
|
||||
clean:
|
||||
rm -f tmp tmp.ired
|
||||
rm -f tmp tmp.r0 tmp.ired
|
||||
@@ -9,21 +9,21 @@ else
|
||||
fi
|
||||
|
||||
|
||||
md5sum -h 2>/dev/null
|
||||
echo |md5sum 2>/dev/null
|
||||
if [ $? = 0 ]; then
|
||||
md5=md5sum
|
||||
else
|
||||
md5=md5
|
||||
fi
|
||||
|
||||
function hash {
|
||||
hash() {
|
||||
$md5 $1 | awk '{print $1}'
|
||||
}
|
||||
|
||||
function btest {
|
||||
btest() {
|
||||
cp $1 tmp
|
||||
../bdiff $1 $2 > tmp.ired
|
||||
../ired -n tmp < tmp.ired
|
||||
../r0d $1 $2 > tmp.r0
|
||||
../r0 -n tmp < tmp.r0
|
||||
test `hash tmp` = `hash $2`
|
||||
ret=$?
|
||||
echo $ret $1 $2
|
||||
@@ -32,7 +32,7 @@ function btest {
|
||||
diff -u $2 tmp
|
||||
fi
|
||||
fi
|
||||
#/ rm -f tmp.ired tmp
|
||||
#/ rm -f tmp.r0 tmp
|
||||
}
|
||||
|
||||
(cd .. && make -s)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* ired - Copyleft 2009-2013 -- pancake */
|
||||
/* ired - MIT - Copyleft 2009-2019 -- pancake */
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -7,11 +7,8 @@ static inline void hexdump(const ut8 *buf, unsigned int len, int w) {
|
||||
for(i=0;i<len;i+=w) {
|
||||
printf("0x%08"LLF"x: ", curseek+i);
|
||||
for(j=i;j<i+w;j++) {
|
||||
if(j>=len) {
|
||||
printf(j%2?" ":" ");
|
||||
continue;
|
||||
}
|
||||
printf(j%2?"%02x ":"%02x", buf[j]);
|
||||
if(j<len) printf(j%2?"%02x ":"%02x", buf[j]);
|
||||
else printf(j%2?" ":" ");
|
||||
}
|
||||
printf(" ");
|
||||
for(j=i;j<i+w;j++)
|
||||
@@ -20,15 +17,16 @@ static inline void hexdump(const ut8 *buf, unsigned int len, int w) {
|
||||
}
|
||||
}
|
||||
|
||||
static void print_fmt(const ut8 *buf, char *fmt, unsigned int len) {
|
||||
#define u(x) ((unsigned long)(x&0xff))
|
||||
static void print_fmt(const ut8 *buf, const char *fmt, unsigned int len) {
|
||||
unsigned int i, up, inc = 0, lup = 0, rep = 0;
|
||||
char *ofmt = fmt;
|
||||
const char *ofmt = fmt;
|
||||
do { /* TODO: needs cleanup */
|
||||
for(;(*fmt||rep);fmt++) {
|
||||
up = rep?rep:*fmt;
|
||||
switch(up) {
|
||||
case 'i': if(len>3) printf("%d\n", ((buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3])); inc=4; break;
|
||||
case 'I': if(len>3) printf("%d\n", ((buf[3]<<24) | (buf[2]<<16) | (buf[1]<<8) | buf[0])); inc=4; break;
|
||||
case 'i': if(len>3) printf("%d\n", (int)(u(buf[0]&0xff)<<24 | (u(buf[1])<<16) | (buf[2]<<8) | buf[3])); inc=4; break;
|
||||
case 'I': if(len>3) printf("%d\n", (int)((u(buf[3])<<24) | (u(buf[2])<<16) | (u(buf[1])<<8) | buf[0])); inc=4; break;
|
||||
case 's': if(len>1) printf("%d\n", (buf[0]<<8 | buf[1])); inc=2; break;
|
||||
case 'S': if(len>1) printf("%d\n", (buf[1]<<8 | buf[0])); inc=2; break;
|
||||
case 'o': if(len>0) printf("0%o\n", buf[0]); inc=1; break;
|
||||
@@ -103,7 +101,7 @@ static unsigned int hexstr2raw(ut8 *arg) {
|
||||
static ut8 *getcurblk(const char *arg, int *len) {
|
||||
ut8 *buf = NULL;
|
||||
if(*arg) {
|
||||
*len = (int)str2ut64((const char *)arg);
|
||||
*len = (int)calc((const char *)arg);
|
||||
if(*len<1) *len = bsize;
|
||||
}
|
||||
if(*len>0 && (buf = malloc(*len)) != NULL) {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
CC="docker run --rm --volume $(pwd):$(pwd) -w $(pwd) dkulacz/gcc-v850-elf-toolchain:latest"
|
||||
TOOLCHAIN_PREFIX="v850-elf-"
|
||||
# FLAGS="-mv850e3v5 -mloop -mrh850-abi -mprolog-function"
|
||||
FLAGS="-mv850e3v5 -mprolog-function"
|
||||
FLAGS="-mprolog-function -mv850e3v5"
|
||||
FLAGS="-DHAVE_FTRUNCATE=0"
|
||||
$CC ${TOOLCHAIN_PREFIX}gcc ${FLAGS} ired.c -o ired_v850
|
||||
# $CC ${TOOLCHAIN_PREFIX}size --format=berkeley -o ired_v850
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/bin/sh
|
||||
# vired: the visual raw editor
|
||||
# copyleft: pancake at nopcode dot org @ 2009-2013
|
||||
|
||||
PATH=.:$PATH
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
$0 | ired -n $@
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ttyset=`stty -g`
|
||||
stty -echo -icanon min 1
|
||||
|
||||
getstr() {
|
||||
stty icanon echo
|
||||
read A
|
||||
echo $A
|
||||
stty -icanon -echo
|
||||
}
|
||||
|
||||
P=''
|
||||
echo "b 256"
|
||||
while : ; do
|
||||
echo "!clear"
|
||||
case $P in
|
||||
'd') echo '!echo X | ired -n $BLOCK | rasm2 -o $OFFSET -d -' ;;
|
||||
*) echo x ;;
|
||||
esac
|
||||
A=`dd if=/dev/tty count=1 bs=1 2>/dev/null`
|
||||
case $A in
|
||||
'j') echo "s+16" ;;
|
||||
'k') echo "s-16" ;;
|
||||
'J') echo "s+b" ;;
|
||||
'K') echo "s-b" ;;
|
||||
'h') echo "s-1" ;;
|
||||
'l') echo "s+1" ;;
|
||||
'q') stty $ttyset; exit ;;
|
||||
'b') printf 'b '>/dev/tty; echo b `getstr` ;;
|
||||
'w') printf 'w '>/dev/tty; echo w `getstr` ;;
|
||||
's') printf 's '>/dev/tty; echo s `getstr` ;;
|
||||
'r') printf 'r '>/dev/tty; echo r `getstr` ;;
|
||||
':') printf ': '>/dev/tty; echo `getstr`; read A ;;
|
||||
'?') echo '?'; read A ;;
|
||||
'+') echo "b+1" ;;
|
||||
'-') echo "b-1" ;;
|
||||
'*') echo "b+16" ;;
|
||||
'/') echo "b-16" ;;
|
||||
'p') if [ -n "$P" ]; then P=''; else P=d; fi ;;
|
||||
esac
|
||||
done
|
||||
Reference in new issue
Block a user