Compare commits

...
111 Commits
Author SHA1 Message Date
pancake 7ec6dbcf88 Release 4.0 2019-10-28 16:52:59 +01:00
pancake bc6d3f36da Import r2ida from https://github.com/radare/radare2ida 2019-10-28 11:03:42 +01:00
Sylvain Pelissier 96d68f14ed Microblaze ESIL update (#215)
* Corrected jumps and remove git messages
* Add ESIL for right shift and correct imm value
* Separate branch with immediate instructions
2019-10-16 12:52:27 +02:00
dependabot[bot] a67e7f0adb Bump lodash from 4.17.11 to 4.17.15 in /r2jadx (#213)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.15.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.15)

Signed-off-by: dependabot[bot] <[email protected]>
2019-10-07 18:24:45 +08:00
dependabot[bot] 7125f795b4 Bump eslint-utils from 1.3.1 to 1.4.2 in /r2jadx (#212)
Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.3.1...v1.4.2)

Signed-off-by: dependabot[bot] <[email protected]>
2019-10-07 18:24:36 +08:00
Sylvain Pelissier 6ad247901d Update test to use NodeJS 10 (#211) 2019-10-07 17:24:36 +08:00
Maijin 7ecb70cd26 Change radare->radareorg links 2019-10-07 10:53:33 +02:00
Sylvain Pelissier f90380fc23 Improvements for Microblaze ESIL of jump an return operations 2019-10-07 15:53:45 +08:00
Anton Kochkov a0d0c360da Fix urls 2019-10-07 15:48:54 +08:00
Anton Kochkov 80e37a663d Fix urls 2019-10-07 15:48:15 +08:00
pancake fb3c96694e Add checkm8 io plugin 2019-09-30 20:01:56 +02:00
Sylvain Pelissier 2ee3d1153b Microblaze add calls and delay branch (#209) 2019-09-24 20:19:46 +02:00
Sylvain Pelissier 972e774df8 Add Travis CI test for Microblaze and update ESIL (#207) 2019-09-18 14:15:21 +02:00
pancake 4325c5c797 Release 3.9.0 2019-09-17 18:50:05 +02:00
Sylvain Pelissier 738ed6451c Improve Microblaze ESIL ##anal (#206) 2019-09-16 09:36:43 +02:00
Sylvain Pelissier d686d94c0e Correct pointer for r_str_newf function (#205) 2019-09-10 13:25:21 +02:00
Sylvain Pelissier 86a32aa11e Handle negative immediate values in instructions (#204) 2019-09-08 19:09:49 +02:00
pancake 0d830052ad Release 3.7.0 2019-08-01 05:10:31 +02:00
pancake cb31b4c934 Fixes and improvements in cmdline handling and such for r2snow 2019-07-24 12:06:33 +02:00
pancake 78336f4977 More fixes for r2snow 2019-07-24 06:45:43 +02:00
pancake 85f79f83b3 Import snowman output as comments into r2 in r2snow 2019-07-24 04:41:53 +02:00
pancake 940dfec369 More fixes and ipmrovements for r2jadx 2019-07-11 06:45:45 +02:00
pancake 807d1999c0 Update r2pipe dependency for r2jadx 2019-07-10 20:15:31 +02:00
pancake b74f1d306b Lots of improvements for r2jadx! 2019-07-10 12:54:43 +02:00
pancake 3134973ee0 Fix indent and add one more try/catch block 2019-07-09 15:42:37 +02:00
pancake 6993b40789 Use --illegal-access=warn 2019-07-09 15:39:04 +02:00
pancake f54381e411 Add missing md380 Makefile 2019-07-09 15:34:21 +02:00
pancake bd89b33d1a Add ^C message 2019-07-09 15:33:55 +02:00
pancake 96a6b07921 Check for jadx version and use r2pipe.isAvailable() after upgrading dependencies 2019-07-09 15:24:39 +02:00
pancake 05f76e5578 Release 3.6.0 2019-06-24 15:49:47 +02:00
pancake 2e8fac708c Initial working version of r2jadx 2019-06-21 10:27:44 +02:00
pancake c7ffc478e5 Initial implementation of r2jadx 2019-06-16 20:15:02 +02:00
meme c276d25c57 Update <mybfd.h> to reflect the static inlining of bfd_get_bits
https://github.com/radare/radare2/blob/master/libr/asm/arch/include/mybfd.h#L584-L585
2019-06-15 16:35:17 +02:00
dissonant-research c45284dab5 Switching from RIOSection to RIOMap in unicorn debug 2019-05-24 09:27:58 +02:00
pancake e9b20fb9eb Release 3.5.0 2019-05-13 11:18:56 +02:00
pancake cabcd22f39 refix 2019-04-26 00:28:49 +02:00
pancake 65b16c4ea2 Fix build for udis 2019-04-26 00:25:37 +02:00
pancake 32caa03626 Fix bin-md380 crash 2019-04-20 11:48:55 +02:00
pancake 710bd658e3 Implement loadbuffer ni md380 2019-04-20 02:17:43 +02:00
pancake a39b5dfac7 Fix build of md380 bin 2019-04-20 02:15:27 +02:00
pancake 207a4677a1 Initial import of the r2emuhash 2019-04-14 13:35:49 +02:00
pancake 9eb4ca72bb Release 3.4.0 2019-04-01 22:16:24 +02:00
Fedor Sakharov 0459dfa816 fixes trimmed last bytes in disassembly (#195)
Fixes #194
2019-03-10 23:20:46 +08:00
pancake d8517a28ec Fix truncated numbers issue 2019-03-08 19:44:30 +01:00
pancake 5a0cc39fac Release 3.3.0 2019-02-19 14:50:08 +01:00
Andrew Barbarello 5883f35f20 yara-r2: replace r_io_read_at with r_io_pread_at
r_io_read_at is deprecated, and the intention is clearly to read all
bytes of the current file to be scanned with yara rules.
2019-02-17 16:25:15 +01:00
Andrew Barbarello 93f603828e yara-r2: remove unused yara2 sigs/refs to yara2 2019-02-17 16:25:15 +01:00
Andrew Barbarello fdcd534137 yara-r2: install to R2PM_USERPLUGIN_DIR
Makefile was using `R2_PLUGDIR`, which is no longer exported in
environment by `r2pm`, see
https://github.com/radare/radare2/issues/12751 .

Instead, we use `R2PM_USRPLUGIN_DIR`. Also update
`r_cmd_yara_load_default_rules` to load yara3 rules from the correct
path
2019-02-17 16:25:15 +01:00
Maijin 37e60e452c Add pcap in r2r-extras travis 2019-01-03 22:12:26 +01:00
Francesco Tamagni 43be0652d4 Move BPF plugin here 2018-12-31 20:27:38 +01:00
Stevie Johnstone 9d081e9f84 Fix unicorn README. dh is now dL 2018-12-30 01:36:32 +01:00
Stevie Johnstone 277114e466 Fix unicorn plugin build
* debug_evm.so was being built instead of debug_unicorn.so fix Makefiles
* "sections" is now an SdbList
* debug interface has changed to take RDebug* as the first argument
* "flags" member is now "perm"
* R_IO_READ and friends are now R_PERM_R etc
2018-12-30 01:36:32 +01:00
Federico G. Schwindt b2244eb386 More fixes to get these building (#187)
While here silence some warnings and simplify.
2018-12-20 12:24:28 +01:00
Federico G. Schwindt 038878331c Fix compilation (#186)
* Add missing object file

* Correctly append the insn

* Fix compilation
2018-12-19 15:18:55 +01:00
pancake 7436fe335a Missing ; 2018-12-04 17:05:47 +01:00
pancake 5be184ad09 Add one more NE url reference 2018-12-04 15:39:41 +01:00
pancake 412a2b3c10 Add NE and JNI headers 2018-12-04 15:39:11 +01:00
pancake e369064b38 Release 3.1.0 2018-11-26 04:24:12 +01:00
Sebastien Alaiwan 4c6150eb72 Use new buf_asm interface for mycpu example plugin (#183) 2018-11-21 13:53:44 +01:00
Sebastien Alaiwan 111f9716de Add Jaguar GPU disassembler (#184) 2018-11-21 13:32:27 +01:00
Giovanni 87cf193fa9 Update README.md (#182) 2018-11-19 13:03:21 +01:00
pancake a5a5d23273 Release 3.0.1 2018-11-09 17:49:04 +01:00
condret 7db8694ccf refix bale anal-plugin (use the new interrupt api) (#177) 2018-10-21 18:41:49 +02:00
Fedor Sakharov c9268f928d fixes r_io flags in io_evm (#180) 2018-10-21 18:41:40 +02:00
Fedor Sakharov bc5297eb66 Fixes permissions flag for the EVM plugin (#179) 2018-10-21 15:50:40 +02:00
Christopher Hewitt fe6b3f0356 nios: Update to match new RasmOp API. (#178) 2018-10-21 13:26:12 +02:00
pancake 6a2b0792bd Fix some more asm plugins, more to go! 2018-10-18 19:09:41 +02:00
pancake 49b143ecec Fix snprintf issue in last baleful commit 2018-10-18 19:02:22 +02:00
pancake 78aae788e2 Delete unnecessary yara/build.mk 2018-10-18 17:47:12 +02:00
pancake d6dac273e9 Start to improve the makefiles and add missing bitcoin.h 2018-10-18 17:46:14 +02:00
d4em0n 3edba75c46 Bring back the missing dmangle.d 2018-10-18 17:08:53 +02:00
skuater f5743ad7ee fixed baleful 2018-10-18 16:05:38 +02:00
pancake 7f322a2194 Fix #175 - build for udis86 plugin 2018-10-16 22:36:21 +02:00
pancake b22e3a37ef Add r2elisa 2018-10-04 02:40:51 +02:00
Fedor Sakharov 0d721e2d33 Fixes long push operands display (#171) 2018-09-20 19:20:03 +02:00
pancake d087a6076e Release 2.9.0 2018-09-04 02:08:10 +02:00
Fedor Sakharov 2479d03e9d Updates EVM code for the new RasmOp API (#169) 2018-09-03 10:16:22 +02:00
David Douard 26650ee04e mc6809: update to match new RasmOp API (#168) 2018-08-31 18:00:09 +02:00
Rene Laemmert 63ecdc603a fix usage of RStrBuf in keystone.c 2018-08-26 17:30:33 +02:00
pancake 0c43eec6cf Refix olly(2) 2018-08-25 13:50:19 +02:00
pancake 3b8c967d7d Refix olly 2018-08-25 13:49:46 +02:00
pancake ec86d7d221 Fix atom and x86 plugins 2018-08-25 13:47:45 +02:00
pancake 206108514e Release 2.8.0 2018-08-14 16:15:17 +02:00
Maijin 25d39975d5 Add more R2_ prefix for some var 2018-08-07 22:15:32 +02:00
pancake af308ea3bd Release radare2-extras 2.7.0 2018-07-09 16:17:36 +02:00
pancake 89bf3cc1e7 Fix build of lief 2018-06-20 19:51:20 +02:00
Christopher Hewitt becc4cfb70 nios: Update libr/Makefile for r2pm plugin use. 2018-06-08 00:37:10 +02:00
Christopher Hewitt f00cecbc5f nios: Add nios to libr/asm/Makefile. 2018-06-07 09:42:28 +02:00
Christopher Hewitt 1a56c842e1 nios: Working disassembler plugin. 2018-06-07 09:42:28 +02:00
Christopher Hewitt 33882645ba nios: Update dis-asm.h and mybfd.h. 2018-06-07 09:42:28 +02:00
Christopher Hewitt cb010aff69 nios: Manually merge in contemporary binutils code and other fixes for modern compilers. 2018-06-07 09:42:28 +02:00
Christopher Hewitt e809b61b47 nios: Add missing headers and support code. 2018-06-07 09:42:28 +02:00
Christopher Hewitt 956b3aaf14 nios: Import cpu definitions from bfd and cgen opcodes support code. 2018-06-07 09:42:28 +02:00
Christopher Hewitt f64cec8e36 nios: Create asm_nios target. Update mybfd.h. 2018-06-07 09:42:28 +02:00
Christopher Hewitt 7028bab425 nios: Initial import of nios binutils. 2018-06-07 09:42:28 +02:00
pancake 5a9d5c4b36 Fix overflow in swf 2018-06-06 17:55:48 +02:00
Damien Zammit ec624bef6f dwarf: Fix broken test 2018-06-02 17:01:24 +02:00
Damien Zammit 6f5fa00837 x86zyan: Fix broken test 2018-06-02 17:01:24 +02:00
Damien Zammit 525c42ef94 yara: Fix broken test 2018-06-02 17:01:24 +02:00
Damien Zammit 9127f0e92d TESTS: Comment out broken tests, add build id where it broke 2018-06-02 17:01:24 +02:00
Damien Zammit f41d4b1305 travis: Install rust as default, use gcc-7, 14.04 and install GNU make 2018-06-02 17:01:24 +02:00
Damien Zammit 9b6801955e atombios: Improvements
- Include local data blocks as locs
- Autodetect binary fix
- Include global data blocks as sections
- Add ESIL to resolve data from tables
- Bugfix ESIL for various instructions
- Bugfix ESIL for jmp conditions
- Easier to read disasm, still with ESIL support
2018-05-30 14:27:02 +08:00
Anton Kochkov b64bc715dc Enable sudo for Travis 2018-05-30 14:22:15 +08:00
Damien Zammit d2137ab4e4 atombios: disasm + analysis + bin plugins (#158) 2018-05-26 12:32:51 +02:00
pancake 1780ea5dd2 Add task_struct pointer field in the proc_info struct 2018-05-25 22:19:55 +10:00
pancake d2e83eda06 Fix format string 2018-05-25 13:03:42 +02:00
pancake 5445b2ae79 Release 2.6.0 and generate acr files with 1.6.2 2018-05-21 18:39:01 +02:00
pancake 1e04d8b4e9 +x r2crash.js 2018-04-23 02:11:57 +02:00
pancake aad642538c Use enum instead of define 2018-04-12 11:20:51 +02:00
pancake 938e608c62 Initial import of types/ 2018-04-12 11:14:35 +02:00
ilovezfs 8cce5eb0a4 x86_udis.mk: also pass LDFLAGS (#154) 2018-04-11 16:33:28 +02:00
163 changed files with 20074 additions and 1168 deletions

No files matched your search

+30 -27
View File
@@ -1,20 +1,21 @@
dist:
- trusty
sudo:
- false
os:
- linux
compiler:
- clang
addons:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++
- gcc-7
- llvm-dev
- libatomic-ops-dev
- mono-xbuild
- curl
- make
- tcc
- libboost-dev
- libqt4-dev
@@ -31,42 +32,44 @@ addons:
env:
- TESTS="r2pm -i armthumb"
- TESTS="r2pm -i baleful"
# - TESTS="r2pm -i bcl" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
# - TESTS="r2pm -i bcl" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
- TESTS="r2pm -i blackfin"
- TESTS="r2pm -i blessr2"
# - TESTS="r2pm -i bpf" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
# - TESTS="r2pm -i dlang" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
# - TESTS="r2pm -i bpf" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
# - TESTS="r2pm -i dlang" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
- TESTS="r2pm -i dirtycow"
- TESTS="r2pm -i lang-duktape"
- TESTS="git clone git://git.code.sf.net/p/libdwarf/code libdwarf-code && cd libdwarf-code && ./configure && make && cd .. && r2pm -i dwarf-parser && cd radare2-regressions && ./r2r dwarf && cd .. && r2pm -u libdwarf && rm -rf libdwarf-code" #need to remove libdwarf? or travis destroys the vm so no issue in that?
- TESTS="r2pm -i r2frida"
# - TESTS="r2pm -i io-ewf" # https://github.com/travis-ci/apt-package-whitelist/issues/3205
# - TESTS="r2pm -i keystone-lib && r2pm -i keystone && cd radare2-regressions && make keystone && cd .." [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i microblaze"
# - TESTS="r2pm -i keystone-lib && r2pm -i keystone && cd radare2-regressions && make keystone && cd .." [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
- TESTS="r2pm -i mc6809"
- TESTS="r2pm -i microblaze && cd radare2-regressions && make microblaze"
- TESTS="r2pm -i msil"
- TESTS="r2pm -i pcap"
- TESTS="r2pm -i ppcdisasm"
- TESTS="r2pm -i psosvm"
- TESTS="r2pm -i pyc"
- TESTS="r2pm -i vala && r2pm -i valabind && r2pm -i r2api-python"
# - TESTS="r2pm -i r2pipe-cs" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i r2pipe-go"
# - TESTS="r2pm -i vala && r2pm -i valabind && r2pm -i r2api-python" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/387043680
# - TESTS="r2pm -i r2pipe-cs" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
# - TESTS="r2pm -i r2pipe-go" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/387043680
- TESTS="r2pm -i r2pipe-js"
- TESTS="r2pm -i r2pipe-py"
- TESTS="r2pm -i r2pipe-rb"
# - TESTS="r2pm -i r2pipe-vala" https://travis-ci.org/radare/radare2-extras/builds/157522362
# - TESTS="r2pm -i r2pipe-vala" https://travis-ci.org/radareorg/radare2-extras/builds/157522362
- TESTS="r2pm -i radare2"
# - TESTS="r2pm -i r2snow" https://travis-ci.org/radare/radare2-extras/jobs/199500082
# - TESTS="r2pm -i r2snow" https://travis-ci.org/radareorg/radare2-extras/jobs/199500082
# - TESTS="r2pm -i radeco" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i retdec"
- TESTS="r2pm -i swf && cd radare2-regressions && make swf && cd .."
- TESTS="r2pm -i m68k-net && cd radare2-regressions && make m68k-extras && cd .."
# - TESTS="r2pm -i m68k-net && cd radare2-regressions && make m68k-extras && cd .." [BR] https://travis-ci.org/radare/radare2-extras/builds/387043680
# - TESTS="r2pm -i swig" Sorry. This package cannot be installed in your home.
- TESTS="r2pm -i syms2elf"
# - TESTS="r2pm -i tcc" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i unicorn-lib && r2pm -i unicorn" # need to do this properly
- TESTS="r2pm -i vala"
- TESTS="r2pm -i valabind"
- TESTS="r2pm -i vapi"
# - TESTS="r2pm -i valabind" [BR] https://travis-ci.org/radare/radare2-extras/builds/387043680
# - TESTS="r2pm -i vapi" [BR] https://travis-ci.org/radare/radare2-extras/builds/387043680
- TESTS="r2pm -i vc4"
- TESTS="r2pm -i winapi"
- TESTS="r2pm -i www-enyo"
@@ -80,10 +83,10 @@ env:
- TESTS="r2pm -i z80-nc"
- TESTS="r2pm -i yara && r2pm -i yara-r2"
- TESTS="r2pm -i x86zyan"
sudo:
- false
language:
- c
- rust
rust:
- stable
cache:
- ccache
- apt
@@ -91,9 +94,10 @@ cache:
before_script:
- export WORKING_DIR=${TRAVIS_BUILD_DIR}/..
- cd ${WORKING_DIR}
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install 7
- git clone https://github.com/radare/radare2-regressions
- git clone https://github.com/radare/radare2 && cd radare2
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install 10
- git clone https://github.com/radareorg/radare2-regressions
- git clone https://github.com/radareorg/radare2 && cd radare2
- export CC=gcc-7
- ./configure --prefix=${WORKING_DIR}/install > /dev/null
- make -s -j2 > /dev/null
- make install > /dev/null
@@ -104,7 +108,6 @@ before_script:
- export LIBR_UTIL=${WORKING_DIR}/radare2/libr/util
- export PKG_CONFIG_PATH=${WORKING_DIR}/radare2/pkgcfg
- export GOPATH=${WORKING_DIR}/
- curl -sSf https://static.rust-lang.org/rustup.sh | sh
- r2pm init
- export R2PM_GITDIR=${WORKING_DIR}
- cd radare2-extras
+5 -4
View File
@@ -1,6 +1,5 @@
VERSION=@VERSION@
HAVE_LIB_YARA=@HAVE_LIB_YARA@
PREFIX=@PREFIX@
include options.mk
DESTDIR?=
TAR=tar -cvf
CZ=xz -f
@@ -24,7 +23,9 @@ help:
@echo " yara - build yara3 r2 plugin"
@echo " (target)-install - install given plugin"
@echo " (target)-clean - clean given plugin"
@echo " install-yara{2,3} - install Yara 2 or 3 from Git"
# @echo " install-yara{2,3} - install Yara 2 or 3 from Git"
baleful:
$(MAKE) -C baleful
+2 -2
View File
@@ -1,4 +1,4 @@
radare2-extras [![Build Status](https://travis-ci.org/radare/radare2-extras.svg?branch=master)](https://travis-ci.org/radare/radare2-extras)
radare2-extras [![Build Status](https://travis-ci.org/radareorg/radare2-extras.svg?branch=master)](https://travis-ci.org/radareorg/radare2-extras)
==============
This repository contains extra plugins for radare2.
@@ -33,4 +33,4 @@ Building
The recommended way to build and install those plugins for users
is to use r2pm. See the radare2-pm repository for details:
https://github.com/radare/radare2-pm
https://github.com/radareorg/radare2-pm
+29 -3
View File
@@ -543,6 +543,32 @@ static int esil_baleful_intr (RAnalEsil *esil, int intr) {
return true;
}
static bool esil_bale_interrupt_wrapper_cb (RAnalEsil *esil, ut32 interrupt, void *user) { //user is always NULL, bc we has no init and fini
return !!esil_baleful_intr(esil, interrupt);
}
RAnalEsilInterruptHandler bale_intr_handler00 = {
.num = 0x00, //interrupt number
.cb = esil_bale_interrupt_wrapper_cb, //the actual handler
};
RAnalEsilInterruptHandler bale_intr_handler04 = {
.num = 0x04, //interrupt number
.cb = esil_bale_interrupt_wrapper_cb, //the actual handler
};
RAnalEsilInterruptHandler bale_intr_handler11 = {
.num = 0x11, //interrupt number
.cb = esil_bale_interrupt_wrapper_cb, //the actual handler
};
RAnalEsilInterruptHandler *bale_intr_handlers[] = {
&bale_intr_handler00,
&bale_intr_handler04,
&bale_intr_handler11,
NULL,
};
static int set_reg_profile(RAnal *anal) {
const char *p = \
"=PC pc\n"
@@ -598,8 +624,10 @@ static int set_reg_profile(RAnal *anal) {
return r_reg_set_profile_string (anal->reg, p);
}
static int esil_baleful_init (RAnalEsil *esil) {
if (!esil)
if (!esil) {
return false;
}
return r_anal_esil_load_interrupts (esil, bale_intr_handlers, 0);
/*
internalMemory=malloc(4096);
if (!internalMemory) {
@@ -610,7 +638,6 @@ static int esil_baleful_init (RAnalEsil *esil) {
*((ut32 *)internalMemory)=0xdeadbeef;
eprintf("leido :%08x\n",*((ut32 *)internalMemory));
*/
return true;
}
static int esil_baleful_fini (RAnalEsil *esil) {
@@ -628,7 +655,6 @@ static RAnalPlugin r_anal_plugin_baleful = {
.bits = 32,
.esil_init = esil_baleful_init,
.esil_fini = esil_baleful_fini,
.esil_intr = esil_baleful_intr,
.esil = true,
.op = &baleful_op,
.set_reg_profile = set_reg_profile,
+36 -35
View File
@@ -211,124 +211,125 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
const ut8 *r1;
const ut32 *imm;
const ut32 *imm1;
char outbuf[32] = {0};
switch (*buf) {
case 2://8 8 11 5
op->size = asm_baleful_getregs(buf,op->buf_asm,"+",0);
op->size = asm_baleful_getregs(buf,outbuf,"+",0);
break;
case 3://8 8 11 5
op->size = asm_baleful_getregs(buf,op->buf_asm,"-",0);
op->size = asm_baleful_getregs(buf,outbuf,"-",0);
break;
case 4://8 8 11 5
op->size = asm_baleful_getregs(buf,op->buf_asm,"*",0);
op->size = asm_baleful_getregs(buf,outbuf,"*",0);
break;
case 6://8 8 11 5
op->size = asm_baleful_getregs(buf,op->buf_asm,"^",0);
op->size = asm_baleful_getregs(buf,outbuf,"^",0);
break;
case 9://8 8 11 5
op->size = asm_baleful_getregs(buf,op->buf_asm,"&",0);
op->size = asm_baleful_getregs(buf,outbuf,"&",0);
break;
case 10://8 8 11 5
op->size = asm_baleful_getregs(buf,op->buf_asm,"|",0);
op->size = asm_baleful_getregs(buf,outbuf,"|",0);
break;
case 12://8 8 11 5
op->size = asm_baleful_getregs(buf,op->buf_asm,"<<",0);
op->size = asm_baleful_getregs(buf,outbuf,"<<",0);
break;
case 13://8 8 11 5
op->size = asm_baleful_getregs(buf,op->buf_asm,">>",0);
op->size = asm_baleful_getregs(buf,outbuf,">>",0);
break;
case 5: // //9 9 12 6
op->size = asm_baleful_getregs(buf,op->buf_asm,"/",1);
op->size = asm_baleful_getregs(buf,outbuf,"/",1);
break;
case 22: // 7 7 10 4
op->size = asm_baleful_getregs(buf,op->buf_asm,"and",2);
op->size = asm_baleful_getregs(buf,outbuf,"and",2);
break;
case 23: // 7 7 10 4
op->size = asm_baleful_getregs(buf,op->buf_asm,"cmp",2);
op->size = asm_baleful_getregs(buf,outbuf,"cmp",2);
break;
case 24: //7 4
op->size = asm_baleful_getregs(buf,op->buf_asm,"mov",3);
op->size = asm_baleful_getregs(buf,outbuf,"mov",3);
break;
case 30: // 6 3
op->size = asm_baleful_getregs(buf,op->buf_asm,"push",4);
op->size = asm_baleful_getregs(buf,outbuf,"push",4);
break;
case 15: //5
op->size = asm_baleful_getregs(buf,op->buf_asm,"call",5);
op->size = asm_baleful_getregs(buf,outbuf,"call",5);
break;
case 14: //5
op->size = asm_baleful_getregs(buf,op->buf_asm,"jmp",5);
op->size = asm_baleful_getregs(buf,outbuf,"jmp",5);
break;
case 16: //5
op->size = asm_baleful_getregs(buf,op->buf_asm,"jz",5);
op->size = asm_baleful_getregs(buf,outbuf,"jz",5);
break;
case 17: //5
op->size = asm_baleful_getregs(buf,op->buf_asm,"js",5);
op->size = asm_baleful_getregs(buf,outbuf,"js",5);
break;
case 18: //5
op->size = asm_baleful_getregs(buf,op->buf_asm,"jbe",5);
op->size = asm_baleful_getregs(buf,outbuf,"jbe",5);
break;
case 19: //5
op->size = asm_baleful_getregs(buf,op->buf_asm,"jg",5);
op->size = asm_baleful_getregs(buf,outbuf,"jg",5);
break;
case 20: //5
op->size = asm_baleful_getregs(buf,op->buf_asm,"jns",5);
op->size = asm_baleful_getregs(buf,outbuf,"jns",5);
break;
case 21: //5
op->size = asm_baleful_getregs(buf,op->buf_asm,"jnz",5);
op->size = asm_baleful_getregs(buf,outbuf,"jnz",5);
break;
case 27: //3
op->size = 3;
r = buf + 1;
r1 = buf + 2;
snprintf (op->buf_asm, R_ASM_BUFSIZE, "mov r_%02x,[r_%02x]",*r,*r1);
snprintf (outbuf, sizeof (outbuf), "mov r_%02x,[r_%02x]",*r,*r1);
break;
case 28: //3
r = buf + 1;
r1 = buf + 2;
op->size = 3;
snprintf (op->buf_asm, R_ASM_BUFSIZE, "mov [r_%02x],r_%02x",*r,*r1);
snprintf (outbuf, sizeof (outbuf), "mov [r_%02x],r_%02x",*r,*r1);
break;
case 11: //3
op->size = 3;
snprintf (op->buf_asm, R_ASM_BUFSIZE, "regX= regY==0");
snprintf (outbuf, sizeof (outbuf), "regX= regY==0");
break;
case 7: //3
op->size = 3;
snprintf (op->buf_asm, R_ASM_BUFSIZE, "regX= NEG regY");
snprintf (outbuf, sizeof (outbuf), "regX= NEG regY");
break;
case 8: //3
op->size = 3;
snprintf (op->buf_asm, R_ASM_BUFSIZE, "regX= NOT regY");
snprintf (outbuf, sizeof (outbuf), "regX= NOT regY");
break;
case 25: //2
op->size = asm_baleful_getregs(buf,op->buf_asm,"++",6);
op->size = asm_baleful_getregs(buf,outbuf,"++",6);
break;
case 26: //2
op->size = asm_baleful_getregs(buf,op->buf_asm,"--",6);
op->size = asm_baleful_getregs(buf,outbuf,"--",6);
break;
case 31: //2
op->size = asm_baleful_getregs(buf,op->buf_asm,"pop",6);
op->size = asm_baleful_getregs(buf,outbuf,"pop",6);
break;
case 32: // 2
op->size = asm_baleful_getregs(buf,op->buf_asm,"apicall",7);
op->size = asm_baleful_getregs(buf,outbuf,"apicall",7);
break;
case 1:
op->size = 1;
strcpy (op->buf_asm, "ret");
strcpy (outbuf, "ret");
break;
case 0:
op->size = 1;
strcpy (op->buf_asm, "nop");
strcpy (outbuf, "nop");
break;
case 29:
op->size = 1;
strcpy (op->buf_asm, "end virtual");
strcpy (outbuf, "end virtual");
break;
default:
op->size = 1;
strcpy (op->buf_asm, "nop");
strcpy (outbuf, "nop");
break;
}
r_strbuf_set (&op->buf_asm, outbuf);
return op->size;
}
+2 -2
View File
@@ -5,7 +5,7 @@
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/radare/radare2-bindings.git"
"url": "https://github.com/radareorg/radare2-bindings.git"
},
"keywords": [
"radare",
@@ -24,7 +24,7 @@
},
"license": "LGPL-3.0",
"bugs": {
"url": "https://github.com/radare/radare2-extras/issues"
"url": "https://github.com/radareorg/radare2-extras/issues"
},
"homepage": "http://www.radare.org",
"devDependencies": {
+31
View File
@@ -0,0 +1,31 @@
R2_PLUGIN_PATH=$(shell r2 -hh|grep LIBR_PLUGINS|awk '{print $$2}')
R2_INCLUDE_PATH=$(shell r2 -hh|grep INCDIR|awk '{print $$2}')
R2_LIB_PATH=$(shell r2 -hh|grep LIBDIR|awk '{print $$2}')
CFLAGS=-g -fPIC
CFLAGS+=-I$(R2_INCLUDE_PATH)
SUDO=sudo
LDFLAGS=-shared -L$(R2_LIB_PATH) -lr_util -lr_parse -lr_syscall
EXT_SO=$(shell r2 -hh|grep LIBEXT|awk '{print $$2}')
CC_ASM=$(CC) $(CFLAGS) $(LDFLAGS) $(shell pkg-config --libs r_asm)
CC_ANA=$(CC) $(CFLAGS) $(LDFLAGS) $(shell pkg-config --libs r_anal)
CC_BIN=$(CC) $(CFLAGS) $(LDFLAGS) $(shell pkg-config --libs r_bin) -lr_magic
CC_COR=$(CC) $(CFLAGS) $(LDFLAGS) $(shell pkg-config --libs r_core)
all:
$(CC_ASM) -o asm_bpf.$(EXT_SO) asm_bpf.c
$(CC_ANA) -o anal_bpf.$(EXT_SO) anal_bpf.c
$(CC_BIN) -o bin_bpf.$(EXT_SO) bin_bpf.c
# $(CC_COR) -o bpf_core.$(EXT_SO) bpf_core.c
install: all
$(SUDO) cp -f *.$(EXT_SO) $(R2_PLUGIN_PATH)
uninstall:
for a in *.$(EXT_SO) ; do rm -f $(R2_PLUGIN_PATH)/$$a ; done
clean:
rm -f *.$(EXT_SO)
rm -rf *.$(EXT_SO).dSYM
+54
View File
@@ -0,0 +1,54 @@
#BPF architecture for radare2
This is meant to add support for Berkeley Packet Filter in radare2, with full [ESIL](https://radare.gitbooks.io/radare2book/content/esil.html) emulation. The main purpose is to ease the analysis of existing filters encountered in reverse engineering, but can also aid filter development through ESIL emulation.
## Components
It is composed by three plugins:
* **asm_bpf** is the disassembler, i'm planning to add also assembler functionality, but for now it's only disassembler - it is mostly ripped from bpf_dbg.c in the Linux kernel
* **anal_bpf** this is the major contribution of this package, i.e. the analysis plugin which translates everything to ESIL and permits to emulate it completely
* **bin_bpf** is a placeholder, not sure if it's useful at all since there isn't a specific file format - i'm using it just to remember that data is represented big endian by enforcing this information
## Installing using r2pm
This plugin is available in latest r2pm, therefore can be installed simply by:
```
r2pm -i bpf
```
## Building manually
In unix system (tested on mac, but should work in Linux or *BSD out of the box) it should be as easy as doing:
```bash
make install
```
There are two known warnings:
* be sure to have the latest [radare2 from git](https://github.com/radareorg/radare2)
* on mac systems radare2 should be installed with sys/install.sh (and not sys/user.sh) because the Makefile relies on a properly working `pkg-config`
## Example
The provided [bpf.bin](bpf.bin) is ripped from the [berkeley crackme](http://crackmes.de/users/kwisatz_haderach/berkeley/), here is an example session:
[![asciicast](https://asciinema.org/a/1q8oq25bjpp00aut5v5sd4sez.png)](https://asciinema.org/a/1q8oq25bjpp00aut5v5sd4sez)
Moreover, i wrote an [r2pipe script](https://github.com/mrmacete/r2scripts/tree/master/bpf-test/bpftest.py) able to read a pcap file, iterate packets, and test them against the filter by using ESIL emulation.
Here is a not-so-clear live action trying to explain the steps of the above python script:
[![asciicast](https://asciinema.org/a/e22kxl5wncmcnqfvseq0k6dxj.png)](https://asciinema.org/a/e22kxl5wncmcnqfvseq0k6dxj)
## Testing
There's a [python script](https://github.com/mrmacete/r2scripts/tree/master/bpf-test/testtool.py) which parses the Linux kernel's BPF test suite and runs it on radare2's emulated BPF using r2pipe. Until now, all the test which doesn't involve kernel emulation are passing (for the CLASSIC bpf test category only).
If you have collections of test cases you can disclose they're welcome, please open an issue or just PR a test script.
## License
Since most of asm_bpf.c is ripped from Linux kernel, it's licensed on GPLv2.
+538
View File
@@ -0,0 +1,538 @@
/*
*
* Copyright 2015 - mrmacete <[email protected]>
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <r_anal.h>
#include "bpf.h"
#define EMIT_CJMP(op, addr, f)\
(op)->type = R_ANAL_OP_TYPE_CJMP;\
(op)->jump = (addr) + 8 + (st8) (f)->jt * 8;\
(op)->fail = (addr) + 8 + (st8) (f)->jf * 8;
#define EMIT_LOAD(op, addr, size)\
(op)->type = R_ANAL_OP_TYPE_LOAD;\
(op)->ptr = (addr);\
(op)->ptrsize = (size);
#define NEW_SRC_DST(op)\
(op)->src[0] = r_anal_value_new ();\
(op)->dst = r_anal_value_new ();
#define SET_REG_SRC_DST(op, _src, _dst)\
NEW_SRC_DST ((op));\
(op)->src[0]->reg = r_reg_get (anal->reg, (_src), R_REG_TYPE_GPR);\
(op)->dst->reg = r_reg_get (anal->reg, (_dst), R_REG_TYPE_GPR);
#define SET_REG_DST_IMM(op, _dst, _imm)\
NEW_SRC_DST ((op));\
(op)->dst->reg = r_reg_get (anal->reg, (_dst), R_REG_TYPE_GPR);\
(op)->src[0]->imm = (_imm);
#define SET_A_SRC(op)\
(op)->src[0] = r_anal_value_new ();\
(op)->src[0]->reg = r_reg_get (anal->reg, "A", R_REG_TYPE_GPR);
#define SET_A_DST(op)\
(op)->dst = r_anal_value_new ();\
(op)->dst->reg = r_reg_get (anal->reg, "A", R_REG_TYPE_GPR);
#define INSIDE_M(k) ((k) >= 0 && (k) <= 16)
static bool bpf_int_exit(RAnalEsil *esil, ut32 interrupt, void *user);
RAnalEsilInterruptHandler ih = { 0, NULL, NULL, &bpf_int_exit, NULL };
static const char *M[] = {
"M[0]",
"M[1]",
"M[2]",
"M[3]",
"M[4]",
"M[5]",
"M[6]",
"M[7]",
"M[8]",
"M[9]",
"M[10]",
"M[11]",
"M[12]",
"M[13]",
"M[14]",
"M[15]"
};
static int bpf_anal(RAnal *anal, RAnalOp *op, ut64 addr,
const ut8 *data, int len) {
RBpfSockFilter *f = (RBpfSockFilter *)data;
memset (op, '\0', sizeof (RAnalOp));
op->jump = UT64_MAX;
op->fail = UT64_MAX;
op->ptr = op->val = UT64_MAX;
op->type = R_ANAL_OP_TYPE_UNK;
op->size = 8;
op->addr = addr;
r_strbuf_init (&op->esil);
switch (f->code) {
case BPF_RET | BPF_A:
op->type = R_ANAL_OP_TYPE_RET;
esilprintf (op, "A,R0,=,0,$");
break;
case BPF_RET | BPF_K:
case BPF_RET | BPF_X:
op->type = R_ANAL_OP_TYPE_RET;
if (BPF_SRC (f->code) == BPF_K) {
esilprintf (op, "%" PFMT64d ",R0,=,0,$", f->k);
} else if (BPF_SRC (f->code) == BPF_X) {
esilprintf (op, "X,R0,=,0,$");
}
break;
case BPF_MISC_TAX:
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "A", "X");
esilprintf (op, "A,X,=");
break;
case BPF_MISC_TXA:
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,=");
break;
case BPF_ST:
if (INSIDE_M (f->k)) {
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "A", M[f->k]);
esilprintf (op, "A,M[%" PFMT64d "],=", f->k);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_STX:
if (INSIDE_M (f->k)) {
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "X", M[f->k]);
esilprintf (op, "X,M[%" PFMT64d "],=", f->k);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_LD_W | BPF_LEN:
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "len", "A");
esilprintf (op, "len,A,=", f->k);
break;
case BPF_LDX | BPF_LEN:
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "len", "X");
esilprintf (op, "len,X,=", f->k);
break;
case BPF_LD_W | BPF_ABS:
EMIT_LOAD (op, anal->gp + f->k, 4);
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",>,?{,0,R0,=,0,$,BREAK,},%" PFMT64d ",[4],A,=",
f->k + 4, op->ptr);
break;
case BPF_LD_H | BPF_ABS:
EMIT_LOAD (op, anal->gp + f->k, 2);
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",[2],A,=",
f->k + 2, op->ptr);
break;
case BPF_LD_B | BPF_ABS:
EMIT_LOAD (op, anal->gp + f->k, 1);
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",[1],A,=",
f->k + 1, op->ptr);
break;
case BPF_LD_W | BPF_IND:
op->type = R_ANAL_OP_TYPE_LOAD;
op->ptrsize = 4;
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",X,+,0xffffffff,&,>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",X,+,0xffffffff,&,[4],A,=",
(st32)f->k + 4, anal->gp + (st32)f->k);
break;
case BPF_LD_H | BPF_IND:
op->type = R_ANAL_OP_TYPE_LOAD;
op->ptrsize = 2;
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",X,+,0xffffffff,&,>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",X,+,0xffffffff,&,[2],A,=",
(st32)f->k + 2, anal->gp + (st32)f->k);
break;
case BPF_LD_B | BPF_IND:
op->type = R_ANAL_OP_TYPE_LOAD;
op->ptrsize = 1;
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",X,+,0xffffffff,&,>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",X,+,0xffffffff,&,[1],A,=",
(st32)f->k + 1, anal->gp + (st32)f->k);
break;
case BPF_LD | BPF_IMM:
op->type = R_ANAL_OP_TYPE_MOV;
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "0x%08" PFMT64x ",A,=", f->k);
break;
case BPF_LDX | BPF_IMM:
op->type = R_ANAL_OP_TYPE_MOV;
op->val = f->k;
SET_REG_DST_IMM (op, "X", f->k);
esilprintf (op, "0x%08" PFMT64x ",X,=", f->k);
break;
case BPF_LDX_B | BPF_MSH:
op->type = R_ANAL_OP_TYPE_LOAD;
op->ptrsize = 1;
op->ptr = anal->gp + f->k;
SET_A_DST (op);
esilprintf (op, "%" PFMT64d ",[1],0xf,&,4,*,X,=", op->ptr);
break;
case BPF_LD | BPF_MEM:
op->type = R_ANAL_OP_TYPE_MOV;
if (INSIDE_M (f->k)) {
SET_REG_SRC_DST (op, M[f->k], "A");
esilprintf (op, "M[%" PFMT64d "],A,=", f->k);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_LDX | BPF_MEM:
op->type = R_ANAL_OP_TYPE_MOV;
if (INSIDE_M (f->k)) {
SET_REG_SRC_DST (op, M[f->k], "X");
esilprintf (op, "M[%" PFMT64d "],X,=", f->k);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_JMP_JA:
op->type = R_ANAL_OP_TYPE_JMP;
op->jump = addr + 8 + f->k * 8;
esilprintf (op, "%" PFMT64d ",pc,=", op->jump);
break;
case BPF_JMP_JGT | BPF_X:
case BPF_JMP_JGT | BPF_K:
EMIT_CJMP (op, addr, f);
op->cond = R_ANAL_COND_GT;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
esilprintf (op,
"%" PFMT64d ",A,>,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
} else if (BPF_SRC (f->code) == BPF_X) {
esilprintf (op,
"X,A,>,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->jump, op->fail);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_JMP_JGE | BPF_X:
case BPF_JMP_JGE | BPF_K:
EMIT_CJMP (op, addr, f);
op->cond = R_ANAL_COND_GE;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
esilprintf (op,
"%" PFMT64d ",A,>=,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
} else {
esilprintf (op,
"X,A,>=,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->jump, op->fail);
}
break;
case BPF_JMP_JEQ | BPF_X:
case BPF_JMP_JEQ | BPF_K:
EMIT_CJMP (op, addr, f);
op->cond = R_ANAL_COND_EQ;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
esilprintf (op,
"%" PFMT64d ",A,==,$z,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
} else {
esilprintf (op,
"X,A,==,$z,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->jump, op->fail);
}
break;
case BPF_JMP_JSET | BPF_X:
case BPF_JMP_JSET | BPF_K:
EMIT_CJMP (op, addr, f);
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
esilprintf (op,
"%" PFMT64d ",A,&,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
} else {
esilprintf (op,
"X,A,&,!,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
}
break;
case BPF_ALU_NEG:
op->type = R_ANAL_OP_TYPE_NOT;
esilprintf (op, "A,0,-,A,=");
SET_REG_SRC_DST (op, "A", "A");
break;
case BPF_ALU_LSH | BPF_X:
case BPF_ALU_LSH | BPF_K:
op->type = R_ANAL_OP_TYPE_SHL;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,<<=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,<<=");
}
break;
case BPF_ALU_RSH | BPF_X:
case BPF_ALU_RSH | BPF_K:
op->type = R_ANAL_OP_TYPE_SHR;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,>>=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,>>=");
}
break;
case BPF_ALU_ADD | BPF_X:
case BPF_ALU_ADD | BPF_K:
op->type = R_ANAL_OP_TYPE_ADD;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", op->val);
esilprintf (op, "%" PFMT64d ",A,+=", op->val);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,+=");
}
break;
case BPF_ALU_SUB | BPF_X:
case BPF_ALU_SUB | BPF_K:
op->type = R_ANAL_OP_TYPE_SUB;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", op->val);
esilprintf (op, "%" PFMT64d ",A,-=", op->val);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,-=");
}
break;
case BPF_ALU_MUL | BPF_X:
case BPF_ALU_MUL | BPF_K:
op->type = R_ANAL_OP_TYPE_MUL;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,*=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,*=");
}
break;
case BPF_ALU_DIV | BPF_X:
case BPF_ALU_DIV | BPF_K:
op->type = R_ANAL_OP_TYPE_DIV;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
if (f->k == 0) {
esilprintf (op, "0,R0,=,0,$");
} else {
esilprintf (op, "%" PFMT64d ",A,/=", f->k);
}
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "0,X,==,$z,?{,0,R0,=,0,$,BREAK,},X,A,/=");
}
break;
case BPF_ALU_MOD | BPF_X:
case BPF_ALU_MOD | BPF_K:
op->type = R_ANAL_OP_TYPE_MOD;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
if (f->k == 0) {
esilprintf (op, "0,R0,=,0,$");
} else {
esilprintf (op, "%" PFMT64d ",A,%%=", f->k);
}
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "0,X,==,$z,?{,0,R0,=,0,$,BREAK,},X,A,%%=");
}
break;
case BPF_ALU_AND | BPF_X:
case BPF_ALU_AND | BPF_K:
op->type = R_ANAL_OP_TYPE_AND;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,&=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,&=");
}
break;
case BPF_ALU_OR | BPF_X:
case BPF_ALU_OR | BPF_K:
op->type = R_ANAL_OP_TYPE_OR;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,|=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,|,A,=");
}
break;
case BPF_ALU_XOR | BPF_X:
case BPF_ALU_XOR | BPF_K:
op->type = R_ANAL_OP_TYPE_XOR;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,^=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,^=");
}
break;
default:
op->type = R_ANAL_OP_TYPE_ILL;
break;
}
return op->size;
}
static int set_reg_profile(RAnal *anal) {
const char *p =
"=PC pc\n"
"gpr A .32 0 0\n"
"gpr X .32 4 0\n"
"gpr M[0] .32 8 0\n"
"gpr M[1] .32 12 0\n"
"gpr M[2] .32 16 0\n"
"gpr M[3] .32 20 0\n"
"gpr M[4] .32 24 0\n"
"gpr M[5] .32 28 0\n"
"gpr M[6] .32 32 0\n"
"gpr M[7] .32 36 0\n"
"gpr M[8] .32 40 0\n"
"gpr M[9] .32 44 0\n"
"gpr M[10] .32 48 0\n"
"gpr M[11] .32 52 0\n"
"gpr M[12] .32 56 0\n"
"gpr M[13] .32 60 0\n"
"gpr M[14] .32 64 0\n"
"gpr M[15] .32 68 0\n"
"gpr pc .32 72 0\n"
"gpr len .32 76 0\n"
"gpr R0 .32 80 0\n"
"gpr R1 .32 84 0\n"
"gpr R2 .32 88 0\n"
"gpr R3 .32 92 0\n"
"gpr R4 .32 96 0\n"
"gpr R5 .32 100 0\n";
return r_reg_set_profile_string (anal->reg, p);
}
static bool bpf_int_exit(RAnalEsil *esil, ut32 interrupt, void *user) {
int syscall;
ut64 r0;
if (!esil || (interrupt != 0x0))
return false;
r_anal_esil_reg_read (esil, "R0", &r0, NULL);
if (r0 == 0) {
esil->anal->cb_printf ("; BPF result: DROP value: %d\n", (int)r0);
eprintf ("BPF result: DROP value: %d\n", (int)r0);
} else {
esil->anal->cb_printf ("; BPF result: ACCEPT value: %d\n", (int)r0);
eprintf ("BPF result: ACCEPT value: %d\n", (int)r0);
}
return true;
}
static int esil_bpf_init(RAnalEsil *esil) {
if (!esil)
return false;
RAnalEsilInterrupt *intr = r_anal_esil_interrupt_new (esil, 0, &ih);
r_anal_esil_set_interrupt (esil, intr);
return true;
}
static int esil_bpf_fini(RAnalEsil *esil) {
return true;
}
struct r_anal_plugin_t r_anal_plugin_bpf = {
.name = "bpf",
.desc = "Berkely packet filter analysis plugin",
.license = "GPLv2",
.arch = "bpf",
.bits = 32,
.esil = true,
.init = NULL,
.fini = NULL,
.reset_counter = NULL,
.archinfo = NULL,
.op = &bpf_anal,
.bb = NULL,
.fcn = NULL,
.analyze_fns = NULL,
.op_from_buffer = NULL,
.bb_from_buffer = NULL,
.fn_from_buffer = NULL,
.analysis_algorithm = NULL,
.set_reg_profile = &set_reg_profile,
.fingerprint_bb = NULL,
.fingerprint_fcn = NULL,
.diff_bb = NULL,
.diff_fcn = NULL,
.diff_eval = NULL,
.pre_anal = NULL,
.pre_anal_fn_cb = NULL,
.pre_anal_op_cb = NULL,
.post_anal_op_cb = NULL,
.pre_anal_bb_cb = NULL,
.post_anal_bb_cb = NULL,
.post_anal_fn_cb = NULL,
.post_anal = NULL,
.revisit_bb_anal = NULL,
.cmd_ext = NULL,
.esil_init = &esil_bpf_init,
.esil_post_loop = NULL,
.esil_trap = NULL,
.esil_fini = &esil_bpf_fini
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_bpf,
.version = R2_VERSION
};
#endif
+767
View File
@@ -0,0 +1,767 @@
/*
* Most of this is copied and pasted from linux source (except
* for the assembler part).
*
* Copyright 2015 - mrmacete <[email protected]>
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/
#include <r_types.h>
#include <r_util.h>
#include <r_lib.h>
#include <r_asm.h>
#include "bpf.h"
static int disassemble(RAsm *a, RAsmOp *r_op, const ut8 *buf, int len) {
const char *op, *fmt;
RBpfSockFilter *f = (RBpfSockFilter *)buf;
int val = f->k;
char vbuf[256];
switch (f->code) {
case BPF_RET | BPF_K:
op = r_bpf_op_table[BPF_RET];
fmt = "%#x";
break;
case BPF_RET | BPF_A:
op = r_bpf_op_table[BPF_RET];
fmt = "a";
break;
case BPF_RET | BPF_X:
op = r_bpf_op_table[BPF_RET];
fmt = "x";
break;
case BPF_MISC_TAX:
op = r_bpf_op_table[BPF_MISC_TAX];
fmt = "";
break;
case BPF_MISC_TXA:
op = r_bpf_op_table[BPF_MISC_TXA];
fmt = "";
break;
case BPF_ST:
op = r_bpf_op_table[BPF_ST];
fmt = "M[%d]";
break;
case BPF_STX:
op = r_bpf_op_table[BPF_STX];
fmt = "M[%d]";
break;
case BPF_LD_W | BPF_ABS:
op = r_bpf_op_table[BPF_LD_W];
fmt = "[%d]";
break;
case BPF_LD_H | BPF_ABS:
op = r_bpf_op_table[BPF_LD_H];
fmt = "[%d]";
break;
case BPF_LD_B | BPF_ABS:
op = r_bpf_op_table[BPF_LD_B];
fmt = "[%d]";
break;
case BPF_LD_W | BPF_LEN:
op = r_bpf_op_table[BPF_LD_W];
fmt = "len";
break;
case BPF_LD_W | BPF_IND:
op = r_bpf_op_table[BPF_LD_W];
fmt = "[x+%d]";
break;
case BPF_LD_H | BPF_IND:
op = r_bpf_op_table[BPF_LD_H];
fmt = "[x+%d]";
break;
case BPF_LD_B | BPF_IND:
op = r_bpf_op_table[BPF_LD_B];
fmt = "[x+%d]";
break;
case BPF_LD | BPF_IMM:
op = r_bpf_op_table[BPF_LD_W];
fmt = "%#x";
break;
case BPF_LDX | BPF_IMM:
op = r_bpf_op_table[BPF_LDX];
fmt = "%#x";
break;
case BPF_LDX | BPF_LEN:
op = r_bpf_op_table[BPF_LDX];
fmt = "len";
break;
case BPF_LDX | BPF_ABS:
op = r_bpf_op_table[BPF_LDX];
fmt = "[%d]";
break;
case BPF_LDX_B | BPF_MSH:
op = r_bpf_op_table[BPF_LDX_B];
fmt = "4*([%d]&0xf)";
break;
case BPF_LD | BPF_MEM:
op = r_bpf_op_table[BPF_LD_W];
fmt = "M[%d]";
break;
case BPF_LDX | BPF_MEM:
op = r_bpf_op_table[BPF_LDX];
fmt = "M[%d]";
break;
case BPF_JMP_JA:
op = r_bpf_op_table[BPF_JMP_JA];
fmt = "%d";
val = a->pc + 8 + f->k * 8;
break;
case BPF_JMP_JGT | BPF_X:
op = r_bpf_op_table[BPF_JMP_JGT];
fmt = "x";
break;
case BPF_JMP_JGT | BPF_K:
op = r_bpf_op_table[BPF_JMP_JGT];
fmt = "%#x";
break;
case BPF_JMP_JGE | BPF_X:
op = r_bpf_op_table[BPF_JMP_JGE];
fmt = "x";
break;
case BPF_JMP_JGE | BPF_K:
op = r_bpf_op_table[BPF_JMP_JGE];
fmt = "%#x";
break;
case BPF_JMP_JEQ | BPF_X:
op = r_bpf_op_table[BPF_JMP_JEQ];
fmt = "x";
break;
case BPF_JMP_JEQ | BPF_K:
op = r_bpf_op_table[BPF_JMP_JEQ];
fmt = "%#x";
break;
case BPF_JMP_JSET | BPF_X:
op = r_bpf_op_table[BPF_JMP_JSET];
fmt = "x";
break;
case BPF_JMP_JSET | BPF_K:
op = r_bpf_op_table[BPF_JMP_JSET];
fmt = "%#x";
break;
case BPF_ALU_NEG:
op = r_bpf_op_table[BPF_ALU_NEG];
fmt = "";
break;
case BPF_ALU_LSH | BPF_X:
op = r_bpf_op_table[BPF_ALU_LSH];
fmt = "x";
break;
case BPF_ALU_LSH | BPF_K:
op = r_bpf_op_table[BPF_ALU_LSH];
fmt = "%d";
break;
case BPF_ALU_RSH | BPF_X:
op = r_bpf_op_table[BPF_ALU_RSH];
fmt = "x";
break;
case BPF_ALU_RSH | BPF_K:
op = r_bpf_op_table[BPF_ALU_RSH];
fmt = "%d";
break;
case BPF_ALU_ADD | BPF_X:
op = r_bpf_op_table[BPF_ALU_ADD];
fmt = "x";
break;
case BPF_ALU_ADD | BPF_K:
op = r_bpf_op_table[BPF_ALU_ADD];
fmt = "%d";
break;
case BPF_ALU_SUB | BPF_X:
op = r_bpf_op_table[BPF_ALU_SUB];
fmt = "x";
break;
case BPF_ALU_SUB | BPF_K:
op = r_bpf_op_table[BPF_ALU_SUB];
fmt = "%d";
break;
case BPF_ALU_MUL | BPF_X:
op = r_bpf_op_table[BPF_ALU_MUL];
fmt = "x";
break;
case BPF_ALU_MUL | BPF_K:
op = r_bpf_op_table[BPF_ALU_MUL];
fmt = "%d";
break;
case BPF_ALU_DIV | BPF_X:
op = r_bpf_op_table[BPF_ALU_DIV];
fmt = "x";
break;
case BPF_ALU_DIV | BPF_K:
op = r_bpf_op_table[BPF_ALU_DIV];
fmt = "%d";
break;
case BPF_ALU_MOD | BPF_X:
op = r_bpf_op_table[BPF_ALU_MOD];
fmt = "x";
break;
case BPF_ALU_MOD | BPF_K:
op = r_bpf_op_table[BPF_ALU_MOD];
fmt = "%d";
break;
case BPF_ALU_AND | BPF_X:
op = r_bpf_op_table[BPF_ALU_AND];
fmt = "x";
break;
case BPF_ALU_AND | BPF_K:
op = r_bpf_op_table[BPF_ALU_AND];
fmt = "%#x";
break;
case BPF_ALU_OR | BPF_X:
op = r_bpf_op_table[BPF_ALU_OR];
fmt = "x";
break;
case BPF_ALU_OR | BPF_K:
op = r_bpf_op_table[BPF_ALU_OR];
fmt = "%#x";
break;
case BPF_ALU_XOR | BPF_X:
op = r_bpf_op_table[BPF_ALU_XOR];
fmt = "x";
break;
case BPF_ALU_XOR | BPF_K:
op = r_bpf_op_table[BPF_ALU_XOR];
fmt = "%#x";
break;
default:
op = "invalid";
fmt = "%#x";
val = f->code;
break;
}
memset (vbuf, 0, sizeof (vbuf));
snprintf (vbuf, sizeof (vbuf), fmt, val);
vbuf[sizeof (vbuf) - 1] = 0;
if ((BPF_CLASS (f->code) == BPF_JMP && BPF_OP (f->code) != BPF_JA))
r_strbuf_setf (&r_op->buf_asm, "%s %s, 0x%08" PFMT64x ", 0x%08" PFMT64x "", op, vbuf,
a->pc + 8 + f->jt * 8, a->pc + 8 + f->jf * 8);
else r_strbuf_setf (&r_op->buf_asm, "%s %s", op, vbuf);
return r_op->size = 8;
}
/* start of ASSEMBLER code */
#define PARSER_MAX_TOKENS 4
#define COPY_AND_RET(a, b)\
r_strbuf_setbin (&a, (const ut8 *)b, sizeof (*b) + 1);\
return 0;
#define PARSE_FAILURE(message, arg...)\
{\
eprintf ("PARSE FAILURE: " message "\n", ##arg);\
return -1;\
}
#define CMP4(tok, n, x, y, z, w)\
(tok[n][0] == x && tok[n][1] == y && tok[n][2] == z && tok[n][3] == w)
#define CMP3(tok, n, x, y, z)\
(tok[n][0] == x && tok[n][1] == y && tok[n][2] == z)
#define CMP2(tok, n, x, y)\
(tok[n][0] == x && tok[n][1] == y)
#define IS_K_TOK(tok, n)\
(tok[n][0] == '-' || R_BETWEEN ('0', tok[n][0], '9'))
#define IS_LEN(tok, n)\
CMP4 (tok, n, 'l', 'e', 'n', '\0')
#define PARSE_K_OR_FAIL(dst, tok, n)\
dst = strtol (&tok[n][0], &end, 0);\
if (*end != '\0' && *end != ',')\
PARSE_FAILURE ("could not parse k");
#define PARSE_LABEL_OR_FAIL(dst, tok, n)\
dst = strtoul (&tok[n][0], &end, 0);\
if (*end != '\0' && *end != ',') {\
return -1;\
}
#define PARSE_OFFSET_OR_FAIL(dst, tok, n, off)\
dst = strtoul (&tok[n][off], &end, 10);\
if (*end != ']')\
PARSE_FAILURE ("could not parse offset value");
#define PARSE_IND_ABS_OR_FAIL(f, tok, n)\
if (CMP3 (tok, 1, '[', 'x', '+')) {\
f->code = f->code | BPF_IND;\
PARSE_OFFSET_OR_FAIL (f->k, tok, 1, 3);\
return 0;\
} else if (tok[1][0] == '[') {\
f->code = f->code | BPF_ABS;\
PARSE_OFFSET_OR_FAIL (f->k, tok, 1, 1);\
return 0;\
}\
PARSE_FAILURE ("could not parse addressing mode");
#define PARSE_K_OR_X_OR_FAIL(f, tok)\
if (IS_K_TOK (tok, 1)) {\
PARSE_K_OR_FAIL (f->k, tok, 1);\
f->code = f->code | BPF_K;\
} else if (tok[1][0] == 'x' && (tok[1][1] == '\0' || tok[1][1] == ',')) {\
f->code = f->code | BPF_X;\
} else {\
PARSE_FAILURE ("could not parse k or x: %s", tok[1]);\
}
#define PARSE_A_OR_X_OR_FAIL(f, tok)\
if (tok[1][0] == 'x' && (tok[1][1] == '\0' || tok[1][1] == ',')) {\
f->code = f->code | BPF_X;\
} else if (tok[1][0] == 'a' && (tok[1][1] == '\0' || tok[1][1] == ',')) {\
f->code = f->code | BPF_A;\
} else {\
PARSE_FAILURE ("could not parse a or x");\
}
#define PARSE_JUMP_TARGETS(a, f, tok, count)\
PARSE_K_OR_X_OR_FAIL (f, tok);\
if (count >= 3) {\
PARSE_LABEL_OR_FAIL (label, tok, 2);\
f->jt = (st64) (label - a->pc - 8) / 8;\
f->jf = (a->pc >> 3) + 1;\
}\
if (count == 4) {\
PARSE_LABEL_OR_FAIL (label, tok, 3);\
f->jf = (st64) (label - a->pc - 8) / 8;\
}
#define SWAP_JUMP_TARGETS(f)\
temp = f->jt;\
f->jt = f->jf;\
f->jf = temp;
#define ENFORCE_COUNT(count, n)\
if (count != n)\
PARSE_FAILURE ("invalid argument count, try to omit '#'");
#define ENFORCE_COUNT_GE(count, n)\
if (count < n)\
PARSE_FAILURE ("invalid argument count, try to omit '#'");
static int assemble_ld(RAsm *a, RAsmOp *op,
char *tok[PARSER_MAX_TOKENS], int count, RBpfSockFilter *f) {
char *end;
switch (tok[0][2]) {
case '\0':
if (CMP2 (tok, 1, 'm', '[')) {
f->code = BPF_LD | BPF_MEM;
PARSE_OFFSET_OR_FAIL (f->k, tok, 1, 2);
} else if (IS_K_TOK (tok, 1)) {
f->code = BPF_LD | BPF_IMM;
PARSE_K_OR_FAIL (f->k, tok, 1);
} else if (IS_LEN (tok, 1)) {
f->code = BPF_LD | BPF_LEN;
} else {
f->code = BPF_LD_W;
PARSE_IND_ABS_OR_FAIL (f, tok, 1);
}
break;
case 'i':
if (IS_K_TOK (tok, 1)) {
f->code = BPF_LD | BPF_IMM;
PARSE_K_OR_FAIL (f->k, tok, 1);
} else {
PARSE_FAILURE ("ldi without k");
}
break;
case 'b':
f->code = BPF_LD_B;
PARSE_IND_ABS_OR_FAIL (f, tok, 1);
break;
case 'h':
f->code = BPF_LD_H;
PARSE_IND_ABS_OR_FAIL (f, tok, 1);
break;
case 'x':
switch (tok[0][3]) {
case '\0':
if (CMP2 (tok, 1, 'm', '[')) {
f->code = BPF_LDX | BPF_MEM;
PARSE_OFFSET_OR_FAIL (f->k, tok, 1, 2);
} else if (IS_K_TOK (tok, 1)) {
f->code = BPF_LDX | BPF_IMM;
PARSE_K_OR_FAIL (f->k, tok, 1);
} else if (IS_LEN (tok, 1)) {
f->code = BPF_LDX | BPF_LEN;
} else {
f->code = BPF_LDX_W;
PARSE_IND_ABS_OR_FAIL (f, tok, 1);
}
break;
case 'i':
if (IS_K_TOK (tok, 1)) {
f->code = BPF_LDX | BPF_IMM;
PARSE_K_OR_FAIL (f->k, tok, 1);
} else {
PARSE_FAILURE ("ldxi without k");
}
break;
case 'b':
f->code = BPF_LDX_B | BPF_MSH;
if (sscanf (tok[1], "4*([%d]&0xf)", &f->k) != 1) {
PARSE_FAILURE ("invalid nibble addressing");
}
break;
}
break;
default:
PARSE_FAILURE ("unsupported load instruction");
}
return 0;
}
static int assemble_j(RAsm *a, RAsmOp *op, char *tok[PARSER_MAX_TOKENS],
int count, RBpfSockFilter *f) {
int label;
ut8 temp;
char *end;
if (CMP4 (tok, 0, 'j', 'm', 'p', '\0') ||
CMP3 (tok, 0, 'j', 'a', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_JMP_JA;
PARSE_LABEL_OR_FAIL (f->k, tok, 1);
return 0;
}
if (CMP4 (tok, 0, 'j', 'n', 'e', '\0') ||
CMP4 (tok, 0, 'j', 'n', 'e', 'q')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JEQ;
PARSE_JUMP_TARGETS (a, f, tok, count);
SWAP_JUMP_TARGETS (f);
return 0;
}
if (CMP4 (tok, 0, 'j', 'e', 'q', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JEQ;
PARSE_JUMP_TARGETS (a, f, tok, count);
return 0;
}
if (CMP4 (tok, 0, 'j', 'l', 't', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JGE;
PARSE_JUMP_TARGETS (a, f, tok, count);
SWAP_JUMP_TARGETS (f);
return 0;
}
if (CMP4 (tok, 0, 'j', 'l', 'e', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JGT;
PARSE_JUMP_TARGETS (a, f, tok, count);
SWAP_JUMP_TARGETS (f);
return 0;
}
if (CMP4 (tok, 0, 'j', 'g', 't', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JGT;
PARSE_JUMP_TARGETS (a, f, tok, count);
return 0;
}
if (CMP4 (tok, 0, 'j', 'g', 'e', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JGE;
PARSE_JUMP_TARGETS (a, f, tok, count);
return 0;
}
if (CMP4 (tok, 0, 'j', 's', 'e', 't')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JSET;
PARSE_JUMP_TARGETS (a, f, tok, count);
return 0;
}
return -1;
}
static int assemble_alu(RAsm *a, RAsmOp *op, char *tok[PARSER_MAX_TOKENS],
int count, RBpfSockFilter *f) {
char *end;
if (CMP4 (tok, 0, 'a', 'd', 'd', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_ADD;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 's', 'u', 'b', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_SUB;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'm', 'u', 'l', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_MUL;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'd', 'i', 'v', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_DIV;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'm', 'o', 'd', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_MOD;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'n', 'e', 'g', '\0')) {
ENFORCE_COUNT (count, 1);
f->code = BPF_ALU_NEG;
return 0;
}
if (CMP4 (tok, 0, 'a', 'n', 'd', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_AND;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP3 (tok, 0, 'o', 'r', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_OR;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'x', 'o', 'r', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_XOR;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'l', 's', 'h', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_LSH;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'r', 's', 'h', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_RSH;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
return -1;
}
static int assemble_tok(RAsm *a, RAsmOp *op,
char *tok[PARSER_MAX_TOKENS], int count) {
char *end;
int oplen = 0;
RBpfSockFilter f = { 0, 0, 0, 0 };
oplen = strnlen (tok[0], 5);
if (oplen < 2 || oplen > 4) {
PARSE_FAILURE ("mnemonic length not valid");
}
if (CMP4 (tok, 0, 't', 'x', 'a', '\0')) {
ENFORCE_COUNT (count, 1);
f.code = BPF_MISC_TXA;
COPY_AND_RET (op->buf, &f);
}
if (CMP4 (tok, 0, 't', 'a', 'x', '\0')) {
ENFORCE_COUNT (count, 1);
f.code = BPF_MISC_TAX;
COPY_AND_RET (op->buf, &f);
}
if (CMP4 (tok, 0, 'r', 'e', 't', '\0')) {
ENFORCE_COUNT (count, 2);
if (IS_K_TOK (tok, 1)) {
f.code = BPF_RET | BPF_K;
PARSE_K_OR_FAIL (f.k, tok, 1);
} else if (tok[1][0] == 'x') {
f.code = BPF_RET | BPF_X;
} else if (tok[1][0] == 'a') {
f.code = BPF_RET | BPF_A;
} else {
PARSE_FAILURE ("unsupported ret instruction");
}
COPY_AND_RET (op->buf, &f);
}
if (CMP2 (tok, 0, 'l', 'd')) {
ENFORCE_COUNT (count, 2);
if (assemble_ld (a, op, tok, count, &f) == 0) {
COPY_AND_RET (op->buf, &f);
} else {
return -1;
}
}
if (CMP2 (tok, 0, 's', 't')) {
ENFORCE_COUNT (count, 2);
if (tok[0][2] == '\0') {
f.code = BPF_ST;
} else if (tok[0][2] == 'x') {
f.code = BPF_STX;
}
if (CMP2 (tok, 1, 'm', '[')) {
PARSE_OFFSET_OR_FAIL (f.k, tok, 1, 2);
if (f.k > 15) {
PARSE_FAILURE ("mem addressing out of bounds");
}
COPY_AND_RET (op->buf, &f);
} else {
PARSE_FAILURE ("invalid store addressing");
}
}
if (tok[0][0] == 'j') {
if (assemble_j (a, op, tok, count, &f) == 0) {
COPY_AND_RET (op->buf, &f);
} else {
return -1;
}
}
if (assemble_alu (a, op, tok, count, &f) == 0) {
COPY_AND_RET (op->buf, &f);
} else {
return -1;
}
}
static void lower_op(char *c) {
if ((c[0] <= 'Z') && (c[0] >= 'A')) {
c[0] += 0x20;
}
}
#define R_TRUE 1
static void normalize(RStrBuf *buf) {
int i;
char *buf_asm;
if (!buf)
return;
buf_asm = r_strbuf_get (buf);
/* this normalization step is largely sub-optimal */
i = strlen (buf_asm);
while (strstr (buf_asm, " ")) {
r_str_replace_in (buf_asm, (ut32)i, " ", " ", R_TRUE);
}
r_str_replace_in (buf_asm, (ut32)i, " ,", ",", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "[ ", "[", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " ]", "]", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "( ", "(", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " )", ")", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "+ ", "+", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " +", "+", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "* ", "*", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " *", "*", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "& ", "&", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " &", "&", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "%", "", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "#", "", R_TRUE);
r_str_do_until_token (lower_op, buf_asm, '\0');
r_strbuf_set (buf, buf_asm);
}
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
char *tok[PARSER_MAX_TOKENS];
char tmp[128];
int i, j, l;
const char *p = NULL;
if (!a || !op || !buf) {
return 0;
}
r_strbuf_set (&op->buf_asm, buf);
normalize (&op->buf_asm);
// tokenization, copied from profile.c
j = 0;
p = r_strbuf_get (&op->buf_asm);
// For every word
while (*p) {
// Skip the whitespace
while (*p == ' ' || *p == '\t') {
p++;
}
// Skip the rest of the line is a comment is encountered
if (*p == ';') {
while (*p != '\0') {
p++;
}
}
// EOL ?
if (*p == '\0') {
break;
}
// Gather a handful of chars
// Use isgraph instead of isprint because the latter considers ' ' printable
for (i = 0; isgraph ((const unsigned char)*p) && i < sizeof (tmp) - 1;) {
tmp[i++] = *p++;
}
tmp[i] = '\0';
// Limit the number of tokens
if (j > PARSER_MAX_TOKENS - 1) {
break;
}
// Save the token
tok[j++] = strdup (tmp);
}
if (j) {
if (assemble_tok (a, op, tok, j) < 0) {
return -1;
}
// Clean up
for (i = 0; i < j; i++) {
free (tok[i]);
}
}
return op->size = 8;
}
RAsmPlugin r_asm_plugin_bpf = {
.name = "bpf",
.desc = "Berkeley Packet Filter disassembler",
.license = "GPLv2",
.arch = "bpf",
.bits = 32,
.disassemble = &disassemble,
.assemble = &assemble
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_bpf,
.version = R2_VERSION
};
#endif
+98
View File
@@ -0,0 +1,98 @@
/* LGPL3 - Copyright 2015 - mrmacete */
/* it's a blatant copy of "any" bin plugin from radare, big_endian = 1 */
#include <r_types.h>
#include <r_util.h>
#include <r_lib.h>
#include <r_bin.h>
#include <r_magic.h>
static char *get_filetype(RBinFile *arch) {
ut8 buf[4096] = { 0 };
char *res = NULL;
RMagic *ck;
if (!arch)
return NULL;
ck = r_magic_new (0);
if (ck && arch && arch->buf) {
const char *tmp = NULL;
r_magic_load (ck, R2_SDB_MAGIC);
r_buf_read_at (arch->buf, 0, buf, sizeof (buf));
tmp = r_magic_buffer (ck, buf, sizeof (buf));
if (tmp)
res = strdup (tmp);
}
r_magic_free (ck);
return res;
}
static RBinInfo *info(RBinFile *arch) {
RBinInfo *ret = R_NEW0 (RBinInfo);
if (!ret)
return NULL;
ret->lang = "";
ret->file = arch->file ? strdup (arch->file) : NULL;
ret->type = get_filetype (arch);
ret->has_pi = 0;
ret->has_canary = 0;
if (R_SYS_BITS & R_SYS_BITS_64) {
ret->bits = 64;
} else {
ret->bits = 32;
}
ret->big_endian = 1;
ret->has_va = 0;
ret->has_nx = 0;
ret->dbg_info = 0;
ret->dbg_info = 0;
ret->dbg_info = 0;
return ret;
}
static bool load(RBinFile *arch) {
return true;
}
static int destroy(RBinFile *arch) {
return true;
}
static ut64 baddr(RBinFile *arch) {
return 0LL;
}
struct r_bin_plugin_t r_bin_plugin_bpf = {
.name = "bpf",
.desc = "Berkeley Packet Filter - raw binary",
.license = "LGPL3",
.init = NULL,
.fini = NULL,
.get_sdb = NULL,
.load = &load,
.load_bytes = NULL,
.destroy = &destroy,
.baddr = &baddr,
.boffset = NULL,
.binsym = NULL,
.entries = NULL,
.sections = NULL,
.symbols = NULL,
.imports = NULL,
.strings = NULL,
.info = info,
.fields = NULL,
.libs = NULL,
.relocs = NULL,
.dbginfo = NULL,
.create = NULL,
.write = NULL,
.minstrlen = 0,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bin_plugin_bpf,
.version = R2_VERSION
};
#endif
BIN
View File
Binary file not shown.
+82
View File
@@ -0,0 +1,82 @@
/*
* Most of this is copied and pasted from linux kernel source
*
* Copyright 2015 - mrmacete <[email protected]>
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/
#ifndef _BPF_H_
#define _BPF_H_
#include "bpf_common.h"
/* defines ripped from linux/filter.h : */
#define BPF_A 0x10
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/* defines ripped from bpf_dbg.c : */
#define BPF_LDX_B (BPF_LDX | BPF_B)
#define BPF_LDX_W (BPF_LDX | BPF_W)
#define BPF_JMP_JA (BPF_JMP | BPF_JA)
#define BPF_JMP_JEQ (BPF_JMP | BPF_JEQ)
#define BPF_JMP_JGT (BPF_JMP | BPF_JGT)
#define BPF_JMP_JGE (BPF_JMP | BPF_JGE)
#define BPF_JMP_JSET (BPF_JMP | BPF_JSET)
#define BPF_ALU_ADD (BPF_ALU | BPF_ADD)
#define BPF_ALU_SUB (BPF_ALU | BPF_SUB)
#define BPF_ALU_MUL (BPF_ALU | BPF_MUL)
#define BPF_ALU_DIV (BPF_ALU | BPF_DIV)
#define BPF_ALU_MOD (BPF_ALU | BPF_MOD)
#define BPF_ALU_NEG (BPF_ALU | BPF_NEG)
#define BPF_ALU_AND (BPF_ALU | BPF_AND)
#define BPF_ALU_OR (BPF_ALU | BPF_OR)
#define BPF_ALU_XOR (BPF_ALU | BPF_XOR)
#define BPF_ALU_LSH (BPF_ALU | BPF_LSH)
#define BPF_ALU_RSH (BPF_ALU | BPF_RSH)
#define BPF_MISC_TAX (BPF_MISC | BPF_TAX)
#define BPF_MISC_TXA (BPF_MISC | BPF_TXA)
#define BPF_LD_B (BPF_LD | BPF_B)
#define BPF_LD_H (BPF_LD | BPF_H)
#define BPF_LD_W (BPF_LD | BPF_W)
static const char * const r_bpf_op_table[] = {
[BPF_ST] = "st",
[BPF_STX] = "stx",
[BPF_LD_B] = "ldb",
[BPF_LD_H] = "ldh",
[BPF_LD_W] = "ld",
[BPF_LDX] = "ldx",
[BPF_LDX_B] = "ldxb",
[BPF_JMP_JA] = "ja",
[BPF_JMP_JEQ] = "jeq",
[BPF_JMP_JGT] = "jgt",
[BPF_JMP_JGE] = "jge",
[BPF_JMP_JSET] = "jset",
[BPF_ALU_ADD] = "add",
[BPF_ALU_SUB] = "sub",
[BPF_ALU_MUL] = "mul",
[BPF_ALU_DIV] = "div",
[BPF_ALU_MOD] = "mod",
[BPF_ALU_NEG] = "neg",
[BPF_ALU_AND] = "and",
[BPF_ALU_OR] = "or",
[BPF_ALU_XOR] = "xor",
[BPF_ALU_LSH] = "lsh",
[BPF_ALU_RSH] = "rsh",
[BPF_MISC_TAX] = "tax",
[BPF_MISC_TXA] = "txa",
[BPF_RET] = "ret",
};
typedef struct r_bpf_sock_filter { /* Filter block */
ut16 code; /* Actual filter code */
st8 jt; /* Jump true */
st8 jf; /* Jump false */
ut32 k; /* Generic multiuse field */
} RBpfSockFilter;
#endif
+60
View File
@@ -0,0 +1,60 @@
/*
* this file is directly copied from linux source
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/
#ifndef _UAPI__LINUX_BPF_COMMON_H__
#define _UAPI__LINUX_BPF_COMMON_H__
/* Instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_MOD 0x90
#define BPF_XOR 0xa0
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
#ifndef BPF_MAXINSNS
#define BPF_MAXINSNS 4096
#endif
#endif /* _UAPI__LINUX_BPF_COMMON_H__ */
+11
View File
@@ -0,0 +1,11 @@
This is the r2 plugin to read/write memory using the checkm8 exploit.
1. Clone https://github.com/axi0mX/ipwndfu
2. Copy this file into the root directory of this repository
3. r2 -I r2io.py ipwndfu://
4. enjoy
NOTES
* This is very unstable, reading on unallocated regions results in device reboot
* Requires python3 .. so maybe better use @geohot's fork
+65
View File
@@ -0,0 +1,65 @@
# iOS pwndfu checkm8 io plugin for radare2
# ========================================
#
# -- pancake @ nopcode.org
#
# Usage:
# r2 -I test-py-io.py pwndfu://
#
# The r2lang.plugin function exposes a way to register new plugins
# into the RCore instance. This API is only available from RLang.
# You must call with with '#!python test.py' or 'r2 -i test.py ..'
import r2lang
from dfuexec import *
FAKESIZE = 512
device = None
def pyio(a):
def _open(path, rw, perm):
global device
device = dfu.acquire_device()
serial_number = device.serial_number
dfu.release_device(device)
device = PwnedDFUDevice()
print("MyPyIO Opening %s"%(path))
return 1234
def _check(path, many):
print("python-check %s"%(path))
return path[0:9] == "pwndfu://"
def _read(offset, length):
global device
res = device.read_memory(address, length)
print("python-read")
return res
def _seek(offset, whence):
print("python-seek")
if whence == 0: # SET
return offset
if whence == 1: # CUR
return offset
if whence == 2: # END
return ROM_SIZE
return ROM_SIZE
def _write(offset, data, length):
print("TODO: python-write")
return True
def _system(cmd):
print("pwndfu://%s"%(cmd))
return True
return {
"name": "pwndfu",
"license": "GPL",
"desc": "pwndfu IO plugin (pwndfu://3)",
"check": _check,
"open": _open,
"read": _read,
"seek": _seek,
"write": _write,
"system": _system,
}
print("Registering Python IO plugin...")
print(r2lang.plugin("io", pyio))
Vendored
+10 -5
View File
@@ -1,5 +1,5 @@
#!/bin/sh
# This script was automatically generated by ACR v1.4
# This script was automatically generated by ACR v1.7.2
# @author: pancake <nopcode.org>
# @url: http://www.nopcode.org
# @repo: git clone https://github.com/radare/acr
@@ -64,6 +64,7 @@ if [ -e "${VPATH}/config.guess" ]; then
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"
@@ -104,12 +105,12 @@ done
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
: ${INSTALL_MAN:=${INSTALL} -m 444}
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
PKGNAME='radare2-extras' ; VERSION='2.5.0' ; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
PKGNAME='radare2-extras' ; VERSION='4.0.0' ; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
}
show_usage() {
cat <<EOF2
'configure' configures radare2-extras-2.5.0 to adapt to many kinds of systems.
'configure' configures radare2-extras-4.0.0 to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
@@ -179,7 +180,7 @@ take_environ() {
}
show_version() {
echo "radare2-extras-2.5.0 configuration script done with acr v1.4.
echo "radare2-extras-4.0.0 configuration script done with acr v1.7.2.
The 'Free Software Foundation' message is only for autodetection.
Originally written by pancake <nopcode.org>."
exit 0
@@ -203,7 +204,7 @@ case $flag in
show_version ; ;;
-r|--r|--report)
echo "PKGNAME: radare2-extras"
echo "VERSION: 2.5.0"
echo "VERSION: 4.0.0"
echo "LANGS: c"
echo "OPTIONAL: libewf libyara"
echo "PKG-CONFIG: r_core libewf unicorn yara"
@@ -308,6 +309,7 @@ echo 'Using PKGCONFIG: '${PKGCONFIG}
printf 'checking pkg-config flags for r_core... '
tmp=`${PKGCONFIG} --cflags r_core 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_R_CORE=0;
R2_CFLAGS='';R2_LDFLAGS='';
echo 'This package is required'
exit 1
else
@@ -344,6 +346,7 @@ check_library HAVE_LIB_EWF ewf 0
printf 'checking pkg-config flags for libewf... '
tmp=`${PKGCONFIG} --cflags libewf 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_LIBEWF=0;
EWF_CFLAGS='';EWF_LDFLAGS='';
else
EWF_CFLAGS=$tmp;
tmp=`${PKGCONFIG} --libs libewf 2>/dev/null`
@@ -360,6 +363,7 @@ HAVE_LIB_EWF="0"; fi
printf 'checking pkg-config flags for unicorn... '
tmp=`${PKGCONFIG} --cflags unicorn 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_UNICORN=0;
UC_CFLAGS='';UC_LDFLAGS='';
else
UC_CFLAGS=$tmp;
tmp=`${PKGCONFIG} --libs unicorn 2>/dev/null`
@@ -371,6 +375,7 @@ check_library HAVE_LIB_YARA yara 0
printf 'checking pkg-config flags for yara... '
tmp=`${PKGCONFIG} --cflags yara 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_YARA=0;
YARA_CFLAGS='';YARA_LDFLAGS='';
else
YARA_CFLAGS=$tmp;
tmp=`${PKGCONFIG} --libs yara 2>/dev/null`
+1 -1
View File
@@ -1,5 +1,5 @@
PKGNAME radare2-extras
VERSION 2.5.0
VERSION 4.0.0
CONTACT pancake ; [email protected]
REPORT PREFIX ;
Regular → Executable
View File
File mode changed.
+1 -1
View File
@@ -51,7 +51,7 @@ RUN cd /opt/code && \
tar -Jxf ${VALA_TAR}.tar.xz
RUN cd /opt/code/${VALA_TAR}; ./configure --prefix=/usr ; make && make install
# compile radare and bindings
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
#install Go
+1 -1
View File
@@ -28,7 +28,7 @@ RUN cd /opt/code && \
tar -Jxf ${VALA_TAR}.tar.xz
RUN cd /opt/code/${VALA_TAR}; ./configure --prefix=/usr ; make && make install
# compile radare and bindings
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
#install Go
+2 -2
View File
@@ -39,7 +39,7 @@ RUN apt-get install -y python-pip jython
RUN cd /opt/code; wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz
RUN cd /opt/code/vala-0.24.0; ./configure --prefix=/usr ; make && make install
# compile radare
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
@@ -48,7 +48,7 @@ RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN cd /opt/code; wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz
RUN cd /opt/code/vala-0.24.0; ./configure --prefix=/usr ; make && make install
# compile radare
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
#install oracle jre stuffs
+2 -2
View File
@@ -23,7 +23,7 @@ RUN apt-get install -y python-pip jython
RUN cd /opt/code; wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz
RUN cd /opt/code/vala-0.24.0; ./configure --prefix=/usr ; make && make install
# compile radare
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
@@ -32,7 +32,7 @@ RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN cd /opt/code; wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz
RUN cd /opt/code/vala-0.24.0; ./configure --prefix=/usr ; make && make install
# compile radare
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
#install oracle jre stuffs
+2 -2
View File
@@ -2212,7 +2212,7 @@ static int r_cmd_dwarf_call (void *user, const char *input) {
return true;
}
static int r_cmd_dwarf_deinit () {
static int r_cmd_dwarf_fini () {
int res = DW_DLV_ERROR;
if (fd && dbg) {
@@ -2236,7 +2236,7 @@ RCorePlugin r_core_plugin_dwarf = {
.desc = "DWARF parser to analyse various structure and set flags (global variables and function declaration)",
.license = "gpl",
.call = r_cmd_dwarf_call,
.deinit = r_cmd_dwarf_deinit
.fini = r_cmd_dwarf_fini
};
#ifndef CORELIB
+1 -1
View File
@@ -1,5 +1,5 @@
NAME=mycpu
R2_PLUGIN_PATH=$(shell r2 -hh|grep LIBR_PLUGINS|awk '{print $$2}')
R2_PLUGIN_PATH=$(shell r2 -hh|grep R2_LIBR_PLUGINS|awk '{print $$2}')
CFLAGS=-g -fPIC $(shell pkg-config --cflags r_asm)
LDFLAGS=-shared $(shell pkg-config --libs r_asm)
OBJS=$(NAME).o
+5 -5
View File
@@ -30,10 +30,10 @@ static int disassemble (RAsm *a, RAsmOp *op, const ut8 *b, int l) {
int idx = (b[0]&0xf)*2;
op->size = 2;
if (idx>=(OPS*2)) {
strcpy (op->buf_asm, "invalid");
r_strbuf_set (&op->buf_asm, "invalid");
return -1;
}
strcpy (op->buf_asm, ops[idx]);
r_strbuf_set (&op->buf_asm, ops[idx]);
if (ops[idx+1]) {
const char *p = ops[idx+1];
arg[0] = 0;
@@ -50,8 +50,8 @@ static int disassemble (RAsm *a, RAsmOp *op, const ut8 *b, int l) {
sprintf (arg, "r%d, %d", b[1]>>4, (char)b[1]&0xf);
}
if (*arg) {
strcat (op->buf_asm, " ");
strcat (op->buf_asm, arg);
r_strbuf_append (&op->buf_asm, " ");
r_strbuf_append (&op->buf_asm, arg);
}
}
return op->size;
@@ -67,7 +67,7 @@ RAsmPlugin r_asm_plugin_mycpu = {
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_mycpu
};
+21
View File
@@ -0,0 +1,21 @@
NAME=jaguar-gpu
R2_PLUGIN_PATH=$(shell r2 -hh|grep R2_LIBR_PLUGINS|awk '{print $$2}')
CFLAGS=-g -fPIC $(shell pkg-config --cflags r_asm)
LDFLAGS=-shared $(shell pkg-config --libs r_asm)
OBJS=$(NAME).o
SO_EXT=$(shell uname|grep -q Darwin && echo dylib || echo so)
LIB=$(NAME).$(SO_EXT)
all: $(LIB)
clean:
rm -f $(LIB) $(OBJS)
$(LIB): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(LIB)
install:
cp -f $(LIB) $(R2_PLUGIN_PATH)
uninstall:
rm -f $(R2_PLUGIN_PATH)/$(LIB)
+222
View File
@@ -0,0 +1,222 @@
/*
* Disassembler for the Jaguar GPU/DSP
* Copyright (C) 2018 - Sebastien Alaiwan
*/
#include <r_asm.h>
#include <r_lib.h>
static int read16_BE (const ut8** b)
{
int val = ((*b)[0] << 8) | ((*b)[1] << 0);
(*b) += 2;
return val;
}
static const char* condition (int code)
{
switch (code)
{
case 0: return "mp"; /* always */
case 1: return "nz";
case 2: return "z";
case 4: return "nc";
case 5: return "nc/nz";
case 6: return "nc/z";
case 8: return "c";
case 9: return "c/nz";
case 10: return "c/z";
case 20: return "nn";
case 21: return "nn/nz";
case 22: return "nn/z";
case 24: return "n";
case 25: return "n/nz";
case 26: return "n/z";
case 31: return "never";
default: return "?";
}
};
static int notZero (int val)
{
return val == 0 ? 32 : val;
}
static int disassemble (RAsm *a, RAsmOp *op, const ut8 *b, int l) {
const ut8* p = b; /* read pointer */
const uint word = read16_BE (&p);
const uint opCode = (word >> 10) & 63;
const uint reg1 = (word >> 5) & 31;
const uint reg2 = (word >> 0) & 31;
uint pc = a->pc;
pc += 2;
switch (opCode)
{
case 0: r_strbuf_setf (&op->buf_asm, "add r%d, r%d", reg1, reg2);
break;
case 1: r_strbuf_setf (&op->buf_asm, "addc r%d, r%d", reg1, reg2);
break;
case 2: r_strbuf_setf (&op->buf_asm, "addq 0x%x, r%d", notZero (reg1), reg2);
break;
case 3: r_strbuf_setf (&op->buf_asm, "addqt 0x%x, r%d", notZero (reg1), reg2);
break;
case 4: r_strbuf_setf (&op->buf_asm, "sub r%d, r%d", reg1, reg2);
break;
case 5: r_strbuf_setf (&op->buf_asm, "subc r%d, r%d", reg1, reg2);
break;
case 6: r_strbuf_setf (&op->buf_asm, "subq 0x%x, r%d", notZero (reg1), reg2);
break;
case 7: r_strbuf_setf (&op->buf_asm, "subqt 0x%x, r%d", notZero (reg1), reg2);
break;
case 8: r_strbuf_setf (&op->buf_asm, "neg r%d", reg2);
break;
case 9: r_strbuf_setf (&op->buf_asm, "and r%d, r%d", reg1, reg2);
break;
case 10: r_strbuf_setf (&op->buf_asm, "or r%d, r%d", reg1, reg2);
break;
case 11: r_strbuf_setf (&op->buf_asm, "xor r%d, r%d", reg1, reg2);
break;
case 12: r_strbuf_setf (&op->buf_asm, "not r%d", reg2);
break;
case 13: r_strbuf_setf (&op->buf_asm, "btst 0x%x, r%d", reg1, reg2);
break;
case 14: r_strbuf_setf (&op->buf_asm, "bset 0x%x, r%d", reg1, reg2);
break;
case 15: r_strbuf_setf (&op->buf_asm, "bclr 0x%x, r%d", reg1, reg2);
break;
case 16: r_strbuf_setf (&op->buf_asm, "mult r%d, r%d", reg1, reg2);
break;
case 17: r_strbuf_setf (&op->buf_asm, "imult r%d, r%d", reg1, reg2);
break;
case 18: r_strbuf_setf (&op->buf_asm, "imultn r%d, r%d", reg1, reg2);
break;
case 19: r_strbuf_setf (&op->buf_asm, "resmac r%d", reg2);
break;
case 20: r_strbuf_setf (&op->buf_asm, "imacn r%d, r%d", reg1, reg2);
break;
case 21: r_strbuf_setf (&op->buf_asm, "div r%d, r%d", reg1, reg2);
break;
case 22: r_strbuf_setf (&op->buf_asm, "abs r%d", reg2);
break;
case 23: r_strbuf_setf (&op->buf_asm, "sh r%d, r%d", reg1, reg2);
break;
case 24: r_strbuf_setf (&op->buf_asm, "shlq 0x%x, r%d", 32 - notZero (reg1), reg2);
break;
case 25: r_strbuf_setf (&op->buf_asm, "shrq 0x%x, r%d", notZero (reg1), reg2);
break;
case 26: r_strbuf_setf (&op->buf_asm, "sha r%d, r%d", reg1, reg2);
break;
case 27: r_strbuf_setf (&op->buf_asm, "sharq 0x%x, r%d", notZero (reg1), reg2);
break;
case 28: r_strbuf_setf (&op->buf_asm, "ror r%d, r%d", reg1, reg2);
break;
case 29: r_strbuf_setf (&op->buf_asm, "rorq 0x%x, r%d", notZero (reg1), reg2);
break;
case 30: r_strbuf_setf (&op->buf_asm, "cmp r%d, r%d", reg1, reg2);
break;
case 31: r_strbuf_setf (&op->buf_asm, "cmpq 0x%x, r%d", reg1, reg2);
break;
case 32: r_strbuf_setf (&op->buf_asm, "sat8 r%d", reg2);
break;
case 33: r_strbuf_setf (&op->buf_asm, "sat16 r%d", reg2);
break;
case 34: r_strbuf_setf (&op->buf_asm, "move r%d, r%d", reg1, reg2);
break;
case 35: r_strbuf_setf (&op->buf_asm, "moveq 0x%x, r%d", reg1, reg2);
break;
case 36: r_strbuf_setf (&op->buf_asm, "moveta r%d, r%d", reg1, reg2);
break;
case 37: r_strbuf_setf (&op->buf_asm, "movefa r%d, r%d", reg1, reg2);
break;
case 38:
{
uint low = read16_BE (&p);
uint high = read16_BE (&p);
r_strbuf_setf (&op->buf_asm, "movei 0x%x, r%d", low | (high << 16), reg2);
break;
}
case 39: r_strbuf_setf (&op->buf_asm, "loadb [r%d], r%d", reg1, reg2);
break;
case 40: r_strbuf_setf (&op->buf_asm, "loadw [r%d], r%d", reg1, reg2);
break;
case 41: r_strbuf_setf (&op->buf_asm, "load [r%d], r%d", reg1, reg2);
break;
case 42: r_strbuf_setf (&op->buf_asm, "loadp [r%d], r%d", reg1, reg2);
break;
case 43: r_strbuf_setf (&op->buf_asm, "load [r14+0x%x], r%d", notZero (reg1)*4, reg2);
break;
case 44: r_strbuf_setf (&op->buf_asm, "load [r15+0x%x], r%d", notZero (reg1)*4, reg2);
break;
case 45: r_strbuf_setf (&op->buf_asm, "storeb r%d, [r%d]", reg2, reg1);
break;
case 46: r_strbuf_setf (&op->buf_asm, "storew r%d, [r%d]", reg2, reg1);
break;
case 47: r_strbuf_setf (&op->buf_asm, "store r%d, [r%d]", reg2, reg1);
break;
case 48: r_strbuf_setf (&op->buf_asm, "storep r%d, [r%d]", reg2, reg1);
break;
case 49: r_strbuf_setf (&op->buf_asm, "store r%d, [r14+0x%x]", reg2, notZero (reg1)*4);
break;
case 50: r_strbuf_setf (&op->buf_asm, "store r%d, [r15+0x%x]", reg2, notZero (reg1)*4);
break;
case 51: r_strbuf_setf (&op->buf_asm, "move pc, r%d", reg2);
break;
case 52: r_strbuf_setf (&op->buf_asm, "j%s [r%d]", condition(reg2), reg1);
break;
case 53: r_strbuf_setf (&op->buf_asm, "j%s 0x%.8X", condition(reg2), pc + ((int8_t)(reg1 << 3) >> 2));
break;
case 54: r_strbuf_setf (&op->buf_asm, "mmult r%d, r%d", reg1, reg2);
break;
case 55: r_strbuf_setf (&op->buf_asm, "mtoi r%d, r%d", reg1, reg2);
break;
case 56: r_strbuf_setf (&op->buf_asm, "normi r%d, r%d", reg1, reg2);
break;
case 57: r_strbuf_setf (&op->buf_asm, "nop");
break;
case 58: r_strbuf_setf (&op->buf_asm, "load [r14+r%d], r%d", reg1, reg2);
break;
case 59: r_strbuf_setf (&op->buf_asm, "load [r15+r%d], r%d", reg1, reg2);
break;
case 60: r_strbuf_setf (&op->buf_asm, "store r%d, [r14+r%d]", reg2, reg1);
break;
case 61: r_strbuf_setf (&op->buf_asm, "store r%d, [r15+r%d]", reg2, reg1);
break;
case 62: r_strbuf_setf (&op->buf_asm, "sat24 r%d", reg2);
break;
case 63:
{
if (reg1 == 0)
r_strbuf_setf (&op->buf_asm, "pack r%d", reg2);
else if (reg1 == 1)
r_strbuf_setf (&op->buf_asm, "unpack r%d", reg2);
else
r_strbuf_setf (&op->buf_asm, "invalid");
break;
}
}
op->size = p - b;
r_strbuf_setbin (&op->buf_hex, b, op->size);
return op->size;
}
RAsmPlugin r_asm_plugin_jaguar_gpu = {
.name = "jaguar-gpu",
.arch = "jaguar-gpu",
.author = "Sebastien Alaiwan",
.bits = 32,
.desc = "Disassembler for the Jaguar GPU",
.license = "LGPL3",
.disassemble = &disassemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_jaguar_gpu
};
#endif
+4 -2
View File
@@ -1,5 +1,5 @@
#!/bin/sh
# This script was automatically generated by ACR v1.4
# This script was automatically generated by ACR v1.7.2
# @author: pancake <nopcode.org>
# @url: http://www.nopcode.org
# @repo: git clone https://github.com/radare/acr
@@ -62,6 +62,7 @@ if [ -e "${VPATH}/config.guess" ]; then
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"
@@ -176,7 +177,7 @@ take_environ() {
}
show_version() {
echo "radare2-keystone-0.1 configuration script done with acr v1.4.
echo "radare2-keystone-0.1 configuration script done with acr v1.7.2.
The 'Free Software Foundation' message is only for autodetection.
Originally written by pancake <nopcode.org>."
exit 0
@@ -346,6 +347,7 @@ echo 'Using PKGCONFIG: '${PKGCONFIG}
printf 'checking pkg-config flags for r_asm... '
tmp=`${PKGCONFIG} --cflags r_asm 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_R_ASM=0;
R2_CFLAGS='';R2_LDFLAGS='';
echo 'This package is required'
exit 1
else
+1 -1
View File
@@ -58,7 +58,7 @@ static int keystone_assemble(RAsm *a, RAsmOp *ao, const char *str, ks_arch arch,
}
return -1;
}
memcpy (ao->buf, insn, R_MIN (size, sizeof (ao->buf) -1));
r_asm_op_set_buf (ao, insn, size);
ks_free (insn);
if (ks) {
ks_close (ks);
+16
View File
@@ -4,6 +4,11 @@ bea:
$(MAKE) -C asm bea
$(MAKE) -C anal bea
atombios:
$(MAKE) -C asm atombios
$(MAKE) -C anal atombios
$(MAKE) -C bin atombios
blackfin:
$(MAKE) -C asm blackfin
@@ -30,10 +35,18 @@ evm:
$(MAKE) -C io evm
$(MAKE) -C debug evm
nios:
$(MAKE) -C asm nios
clean:
$(MAKE) -C asm clean
$(MAKE) -C anal clean
atombios-install:
cp -f asm/p/asm_atombios.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f anal/p/anal_atombios.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f bin/p/bin_atombios.$(LIBEXT) $(R2PM_PLUGDIR)
bea-install:
cp -f asm/p/asm_x86_bea.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f anal/p/anal_x86_bea.$(LIBEXT) $(R2PM_PLUGDIR)
@@ -61,4 +74,7 @@ evm-install:
cp -f io/p/io_evm.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f debug/p/debug_evm.$(LIBEXT) $(R2PM_PLUGDIR)
nios-install:
cp -f asm/p/asm_nios.$(LIBEXT) $(R2PM_PLUGDIR)
include ../options.mk
+4
View File
@@ -7,11 +7,15 @@ x86_udis udis udis86:
m68k_net:
cd p ; $(MAKE) anal_m68k_net.$(LIBEXT)
atombios:
cd p ; $(MAKE) anal_atombios.$(LIBEXT)
evm:
cd p ; $(MAKE) anal_evm.$(LIBEXT)
clean:
rm -f p/anal_x86_bea.$(LIBEXT)
rm -f p/anal_m68k_net.$(LIBEXT)
rm -f p/anal_atombios.{$(LIBEXT),o}
include ../../options.mk
+1
View File
@@ -6,5 +6,6 @@ ARCHS+=x86_simple.mk
ARCHS+=x86_udis.mk
ARCHS+=m68k_net.mk
ARCHS+=evm.mk
ARCHS+=atombios.mk
include ../../plugs.mk
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -176,7 +176,7 @@ static struct evm_sigs_info *sigs_info = 0;
static int evm_oplen(ut8 opcode) {
int ret;
EvmOpDef *opdef = &opcodes[opcode];
const EvmOpDef *opdef = &opcodes[opcode];
if (opdef->txt) {
return opdef->len;
@@ -453,7 +453,7 @@ static int evm_load_symbol_map (RAnal *anal, const char *file) {
if (sigs_info) {
sigs_info->rio = r_io_new ();
sigs_info->riodesc = r_io_open (sigs_info->rio, file, R_IO_READ, 0644);
sigs_info->riodesc = r_io_open (sigs_info->rio, file, R_PERM_R, 0644);
if (!sigs_info->riodesc) {
printf ("Failed to open %s: %s\n", file, strerror (errno));
+3 -1
View File
@@ -191,7 +191,9 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
op->id = u.mnemonic;
oplen = op->size = ud_insn_len (&u);
r_strbuf_init (&op->esil);
if (anal->decode && (handler = udis86_esil_get_handler (u.mnemonic))) {
const bool decode = true;
if (decode && (handler = udis86_esil_get_handler (u.mnemonic))) {
info.oplen = oplen;
//if (anal->bits==32)
info.bitmask = UT32_MAX;
+10
View File
@@ -0,0 +1,10 @@
OBJ_ATOMBIOS=anal_atombios.o
OBJ_ATOMBIOS+=../../asm/arch/atombios/atombios.o
STATIC_OBJ+=${OBJ_ATOMBIOS}
TARGET_ATOMBIOS=anal_atombios.${LIBEXT}
ALL_TARGETS+=${TARGET_ATOMBIOS}
${TARGET_ATOMBIOS}: ${OBJ_ATOMBIOS}
${CC} -g $(call libname,anal_atombios) ${LDFLAGS} ${CFLAGS} -o anal_atombios.${LIBEXT} ${OBJ_ATOMBIOS}
+1
View File
@@ -1,4 +1,5 @@
OBJ_evm=anal_evm.o
OBJ_evm+=../../asm/arch/evm/evm.o
CFLAGS+=-I../../asm/arch/evm/
STATIC_OBJ+=${OBJ_evm}
+1 -1
View File
@@ -19,5 +19,5 @@ ALL_TARGETS+=${TARGET_X86_UDIS86}
CFLAGS+=-I../../asm/arch/x86 -I../../asm/arch/x86/udis86 -DHAVE_STRING_H=1
${TARGET_X86_UDIS86}: ${OBJ_X86_UDIS86} ${OBJ_ESIL_UDIS86}
${CC} ${CFLAGS} $(call libname,anal_x86) -lr_reg -lr_anal -lr_util \
${CC} ${CFLAGS} ${LDFLAGS} $(call libname,anal_x86) -lr_reg -lr_anal -lr_util \
$(SRC_X86_UDIS86) -o anal_x86_udis.${EXT_SO} ${OBJ_X86_UDIS86} ${OBJ_ESIL_UDIS86}
+16 -3
View File
@@ -1,4 +1,7 @@
D=$(HOME)/.config/radare2/plugins
R2PM_PLUGDIR ?=$(HOME)/.config/radare2/plugins
atombios:
cd p ; $(MAKE) asm_atombios.$(LIBEXT)
blackfin:
cd p ; $(MAKE) asm_blackfin.$(LIBEXT)
@@ -12,6 +15,9 @@ msil:
x86_udis udis udis86:
cd p ; $(MAKE) asm_x86_udis.$(LIBEXT)
udis86-clean:
rm -rf p/asm_x86_udis.$(LIBEXT)*
tab:
cd p ; $(MAKE) asm_x86_tab.$(LIBEXT)
@@ -33,11 +39,15 @@ zyan:
evm:
$(MAKE) -C p asm_evm.$(LIBEXT)
nios:
$(MAKE) -C p asm_nios.$(LIBEXT)
zyan-install: zyan
cp -f p/asm_x86_zyan.$(LIBEXT) $(D)
mkdir -p $(R2PM_PLUGDIR)
cp -f p/asm_x86_zyan.$(LIBEXT) $(R2PM_PLUGDIR)
zyan-uninstall:
$(RM) $(D)/asm_x86_zyan.$(LIBEXT)
$(RM) $(R2PM_PLUGDIR)/asm_x86_zyan.$(LIBEXT)
clean:
rm -f p/asm_x86_bea.$(LIBEXT)
@@ -45,5 +55,8 @@ clean:
rm -f p/asm_x86_olly.$(LIBEXT)
rm -f p/asm_m68k.$(LIBEXT)
rm -f p/asm_x86_zyan.$(LIBEXT)
rm -f p/asm_atombios.{$(LIBEXT),o}
rm -f arch/atombios/atombios.o
rm -f p/asm_nios.$(LIBEXT)
include ../../options.mk
+606
View File
@@ -0,0 +1,606 @@
/* radare - LGPL - Copyright 2018 damo22 */
#include <stdio.h>
#include <string.h>
#include <r_types.h>
#include <r_endian.h>
#include "atombios.h"
// FIXME: Globals ugh
static int last_reg_index = INDEX_NONE;
static int last_reg_offset = 0;
static int opt_reg_addresses = 0;
const char *align_source_esil[] = {
"",
"_01",
"_12",
"_23",
"_0",
"_1",
"_2",
"_3"
};
const char *align_byte_esil[] = { "_0", "_1", "_2", "_3" };
const char *align_word_esil[] = { "_01", "_12", "_23", "" };
const char *align_long_esil[] = { "", "", "", "" };
const char *addrtypes_esil[] = {
"0x%04x,r", "p%d", "w%d", "0x%02x,f", "0x%04x,dt", "0x%04x,D_IDunimpl",
"0x%04x,pll", "0x%04x,mc",
"0x%02x", "0x%04x", "0x%08x"
};
const char *align_source[] = {
"XXXX",
"..XX",
".XX.",
"XX..",
"...X",
"..X.",
".X..",
"X..."
};
const char *align_byte[] = { "...X", "..X.", ".X..", "X..." };
const char *align_word[] = { "..XX", ".XX.", "XX..", "?..?" };
const char *align_long[] = { "XXXX", "????", "????", "????" };
const int size_align[] = { 4, 2, 2, 2, 1, 1, 1, 1 };
const char *addrnames[] = { "REG", "PS", "WS", "FB", "ID", "IM", "PLL", "MC", "dec", "hex8", "hex16", "null" };
const char *addrtypes[] = {
"REG[0x%04x]", "PARAM[%d]", "WORK[%d]", "FB[0x%02x]", "DATA[0x%04x]", "0x%04x,<!impl>",
"PLL[0x%04x]", "MC[0x%04x]",
"0x%02x", "0x%04x", "0x%08x"
};
int addrtypes_shift[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
const char *addrtypes_im[] = { NULL, "0x%02x", "0x%04x", NULL, "0x%08x" };
const char *index_command_table[] = {
"ASIC_Init", "GetDisplaySurfaceSize", "ASIC_RegistersInit",
"VRAM_BlockVenderDetection", "SetClocksRatio_DIGxEncoderControl", "MemoryControllerInit",
"EnableCRTCMemReq", "MemoryParamAdjust", "DVOEncoderControl",
"GPIOPinControl", "SetEngineClock", "SetMemoryClock",
"SetPixelClock", "DynamicClockGating", "ResetMemoryDLL",
"ResetMemoryDevice", "MemoryPLLInit", "AdjustDisplayPll",
"AdjustMemoryController", "EnableASIC_StaticPwrMgt", "ASIC_StaticPwrMgtStatusChange_SetUniphyInstance",
"DAC_LoadDetection", "LVTMAEncoderControl", "LCD1OutputControl",
"DAC1EncoderControl", "DAC2EncoderControl", "DVOOutputControl",
"CV1OutputControl", "GetConditionalGoldenSetting_SetCRTC_DPM_State", "TVEncoderControl",
"TMDSAEncoderControl", "LVDSEncoderControl", "TV1OutputControl",
"EnableScaler", "BlankCRTC", "EnableCRTC",
"GetPixelClock", "EnableVGA_Render", "EnableVGA_Access_GetSCLKOverMCLKRatio",
"SetCRTC_Timing", "SetCRTC_OverScan", "SetCRTC_Replication",
"SelectCRTC_Source", "EnableGraphSurfaces", "UpdateCRTC_DoubleBufferRegisters",
"LUT_AutoFill", "EnableHW_IconCursor", "GetMemoryClock",
"GetEngineClock", "SetCRTC_UsingDTDTiming", "ExternalEncoderControl",
"LVTMAOutputControl", "VRAM_BlockDetectionByStrap", "MemoryCleanUp",
"ReadEDIDFromHWAssistedI2C_ProcessI2cChannelTransaction",
"WriteOneByteToHWAssistedI2C", "ReadHWAssistedI2CStatus_HPDInterruptService",
"SpeedFanControl", "PowerConnectorDetection", "MC_Synchronization",
"ComputeMemoryEnginePLL", "MemoryRefreshConversion", "VRAM_GetCurrentInfoBlock",
"DynamicMemorySettings", "MemoryTraining", "EnableSpreadSpectrumOnPPLL",
"TMDSAOutputControl", "SetVoltage", "DAC1OutputControl",
"DAC2OutputControl", "SetupHWAssistedI2CStatus", "ClockSource",
"MemoryDeviceInit", "EnableYUV", "DIG1EncoderControl",
"DIG2EncoderControl", "DIG1TransmitterControl_UNIPHYTransmitterControl",
"DIG2TransmitterControl_LVTMATransmitterControl",
"ProcessAuxChannelTransaction", "DPEncoderService"
};
const char *index_data_table[] = {
"UtilityPipeLine", "MultimediaCapabilityInfo", "MultimediaConfigInfo",
"StandardVESA_Timing", "FirmwareInfo", "DAC_Info",
"LVDS_Info", "TMDS_Info", "AnalogTV_Info",
"SupportedDevicesInfo", "GPIO_I2C_Info", "VRAM_UsageByFirmware",
"GPIO_Pin_LUT", "VESA_ToInternalModeLUT", "ComponentVideoInfo",
"PowerPlayInfo", "CompassionateData", "SaveRestoreInfo_DispDevicePriorityInfo",
"PPLL_SS_Info_SS_Info", "OemInfo", "XTMDS_Info",
"MclkSS_Info", "Object_Info_Object_Header", "IndirectIOAccess",
"MC_InitParameter_AdjustARB_SEQ", "ASIC_VDDC_Info", "ASIC_InternalSS_Info_ASIC_MVDDC_Info",
"TV_VideoMode_DispOutInfo", "VRAM_Info", "MemoryTrainingInfo_ASIC_MVDDQ_Info",
"IntegratedSystemInfo", "ASIC_ProfilingInfo_ASIC_VDDCI_Info",
"VoltageObjectInfo_VRAM_GPIO_DetectionInfo",
"PowerSourceInfo"
};
const char *index_ati_port[] = {
"INDIRECT_IO_MM",
"INDIRECT_IO_PLL",
"INDIRECT_IO_MC",
"INDIRECT_IO_PCIE",
};
const char *index_work_reg[] = {
[WS_QUOTIENT] = "w0",
[WS_REMAINDER] = "w1",
[WS_DATAPTR] = "w2",
[WS_SHIFT] = "w3",
[WS_OR_MASK] = "w4",
[WS_AND_MASK] = "w5",
[WS_FB_WINDOW] = "w6",
[WS_ATTRIBUTES] = "w7",
[WS_REGPTR] = "w8"
};
#define TABENTRY(x) { #x, (index_ ## x), sizeof (index_ ## x) / sizeof (const char **) }
index_table_t index_tables[INDEXTABLE_SIZEOF] = {
{ NULL, NULL, 0 },
TABENTRY (command_table),
TABENTRY (data_table),
TABENTRY (ati_port),
TABENTRY (work_reg),
{ "REG_MM", NULL, 0 },
{ "REG_PLL", NULL, 0 },
{ "REG_MC", NULL, 0 },
{ "REG_PCIE", NULL, 0 },
{ "REG_PCICONFIG", NULL, 0 },
{ "REG_SYSTEMIO", NULL, 0 }
};
const char *get_index (int type, int val)
{
if (type < 0 || val < 0 ||
type >= sizeof (index_tables) / sizeof (const struct index_table_s))
return NULL;
if (! index_tables[type].tab || val >= index_tables[type].len)
return NULL;
return index_tables[type].tab[val];
}
static int op_ds (const ut8 *, char *);
static int op_sdb (const ut8 *, char *);
static int op_0x (const ut8 *, char *);
static int op_1x8 (const ut8 *, char *);
static int op_1x16 (const ut8 *, char *);
static int op_src (const ut8 *, char *);
static int op_dest (const ut8 *, char *);
static int op_destsrc (const ut8 *, char *);
static int op_shift (const ut8 *, char *);
static int op_switch (const ut8 *, char *);
static int op_mask (const ut8 *, char *);
static int op_setpt0 (const ut8 *, char *);
static int op_setpt1 (const ut8 *, char *);
static int op_setrb (const ut8 *, char *);
const optab_t optable[256] = {
{ NULL, NULL, NULL, D_null, 0, 0 },
{ op_destsrc, "move", "=", D_REG, 0, 0 },
{ op_destsrc, "move", "=", D_PS, 0, 0 },
{ op_destsrc, "move", "=", D_WS, 0, 0 },
{ op_destsrc, "move", "=", D_FB, 0, 0 },
{ op_destsrc, "move", "=", D_PLL, 0, 0 },
{ op_destsrc, "move", "=", D_MC, 0, 0 },
{ op_destsrc, "and", "&=", D_REG, 0, 0 },
{ op_destsrc, "and", "&=", D_PS, 0, 0 },
{ op_destsrc, "and", "&=", D_WS, 0, 0 },
{ op_destsrc, "and", "&=", D_FB, 0, 0 },
{ op_destsrc, "and", "&=", D_PLL, 0, 0 },
{ op_destsrc, "and", "&=", D_MC, 0, 0 },
{ op_destsrc, "or", "|=", D_REG, 0, 0 },
{ op_destsrc, "or", "|=", D_PS, 0, 0 },
{ op_destsrc, "or", "|=", D_WS, 0, 0 },
{ op_destsrc, "or", "|=", D_FB, 0, 0 },
{ op_destsrc, "or", "|=", D_PLL, 0, 0 },
{ op_destsrc, "or", "|=", D_MC, 0, 0 },
{ op_shift, "shiftl", "<<=", D_REG, 0, 0 },
{ op_shift, "shiftl", "<<=", D_PS, 0, 0 },
{ op_shift, "shiftl", "<<=", D_WS, 0, 0 },
{ op_shift, "shiftl", "<<=", D_FB, 0, 0 },
{ op_shift, "shiftl", "<<=", D_PLL, 0, 0 },
{ op_shift, "shiftl", "<<=", D_MC, 0, 0 },
{ op_shift, "shiftr", ">>=", D_REG, 0, 0 },
{ op_shift, "shiftr", ">>=", D_PS, 0, 0 },
{ op_shift, "shiftr", ">>=", D_WS, 0, 0 },
{ op_shift, "shiftr", ">>=", D_FB, 0, 0 },
{ op_shift, "shiftr", ">>=", D_PLL, 0, 0 },
{ op_shift, "shiftr", ">>=", D_MC, 0, 0 },
{ op_destsrc, "mul", "*=", D_REG, 0, 0 },
{ op_destsrc, "mul", "*=", D_PS, 0, 0 },
{ op_destsrc, "mul", "*=", D_WS, 0, 0 },
{ op_destsrc, "mul", "*=", D_FB, 0, 0 },
{ op_destsrc, "mul", "*=", D_PLL, 0, 0 },
{ op_destsrc, "mul", "*=", D_MC, 0, 0 },
{ op_destsrc, "div", "/=", D_REG, 0, 0 },
{ op_destsrc, "div", "/=", D_PS, 0, 0 },
{ op_destsrc, "div", "/=", D_WS, 0, 0 },
{ op_destsrc, "div", "/=", D_FB, 0, 0 },
{ op_destsrc, "div", "/=", D_PLL, 0, 0 },
{ op_destsrc, "div", "/=", D_MC, 0, 0 },
{ op_destsrc, "add", "+=", D_REG, 0, 0 },
{ op_destsrc, "add", "+=", D_PS, 0, 0 },
{ op_destsrc, "add", "+=", D_WS, 0, 0 },
{ op_destsrc, "add", "+=", D_FB, 0, 0 },
{ op_destsrc, "add", "+=", D_PLL, 0, 0 },
{ op_destsrc, "add", "+=", D_MC, 0, 0 },
{ op_destsrc, "sub", "-=", D_REG, 0, 0 },
{ op_destsrc, "sub", "-=", D_PS, 0, 0 },
{ op_destsrc, "sub", "-=", D_WS, 0, 0 },
{ op_destsrc, "sub", "-=", D_FB, 0, 0 },
{ op_destsrc, "sub", "-=", D_PLL, 0, 0 },
{ op_destsrc, "sub", "-=", D_MC, 0, 0 },
{ op_setpt1, "set_ati_port", NULL, D_hex16, INDEX_REG_MM, INDEX_ATI_PORT },
{ op_setpt0, "set_pci_port", NULL, D_null, INDEX_REG_PCICONFIG, 0 },
{ op_setpt0, "set_systemio_port", NULL, D_null, INDEX_REG_SYSTEMIO, 0 },
{ op_setrb, "set_reg_block", NULL, D_hex16, 0, 0 },
{ op_src, "set_fb_base", NULL, D_hex16, 0, 0 },
{ op_destsrc, "cmp", "==", D_REG, 0, 0 },
{ op_destsrc, "cmp", "==", D_PS, 0, 0 },
{ op_destsrc, "cmp", "==", D_WS, 0, 0 },
{ op_destsrc, "cmp", "==", D_FB, 0, 0 },
{ op_destsrc, "cmp", "==", D_PLL, 0, 0 },
{ op_destsrc, "cmp", "==", D_MC, 0, 0 },
{ op_switch, "switch", NULL, D_hex16, 0, 0 },
{ op_1x16, "jmp", NULL, D_hex16, 0, 0 },
{ op_1x16, "je ", "==", D_hex16, 0, 0 },
{ op_1x16, "jl ", "<", D_hex16, 0, 0 },
{ op_1x16, "jg ", ">", D_hex16, 0, 0 },
{ op_1x16, "jle", "<=", D_hex16, 0, 0 },
{ op_1x16, "jge", ">=", D_hex16, 0, 0 },
{ op_1x16, "jne", "!=", D_hex16, 0, 0 },
{ op_destsrc, "bitest", "&", D_REG, 0, 0 },
{ op_destsrc, "bitest", "&", D_PS, 0, 0 },
{ op_destsrc, "bitest", "&", D_WS, 0, 0 },
{ op_destsrc, "bitest", "&", D_FB, 0, 0 },
{ op_destsrc, "bitest", "&", D_PLL, 0, 0 },
{ op_destsrc, "bitest", "&", D_MC, 0, 0 },
{ op_1x8, "mdelay", NULL, D_hex8, 0, 0 },
{ op_1x8, "udelay", NULL, D_hex8, 0, 0 },
{ op_1x8, "call", NULL, D_hex8, 0, INDEX_COMMAND_TABLE },
{ op_1x8, "<deprecated> repeat", NULL, D_hex8, 0, 0 },
{ op_dest, "clear", "0", D_REG, 0, 0 },
{ op_dest, "clear", "0", D_PS, 0, 0 },
{ op_dest, "clear", "0", D_WS, 0, 0 },
{ op_dest, "clear", "0", D_FB, 0, 0 },
{ op_dest, "clear", "0", D_PLL, 0, 0 },
{ op_dest, "clear", "0", D_MC, 0, 0 },
{ op_0x, "nop", NULL, D_null, 0, 0 },
{ op_0x, "ret", NULL, D_null, 0, 0 },
{ op_mask, "mask", NULL, D_REG, 0, 0 },
{ op_mask, "mask", NULL, D_PS, 0, 0 },
{ op_mask, "mask", NULL, D_WS, 0, 0 },
{ op_mask, "mask", NULL, D_FB, 0, 0 },
{ op_mask, "mask", NULL, D_PLL, 0, 0 },
{ op_mask, "mask", NULL, D_MC, 0, 0 },
{ op_1x8, "post_card", NULL, D_hex8, 0, 0 },
{ op_1x8, "<!impl> beep", NULL, D_hex8, 0, 0 },
{ op_0x, "<deprecated> save_reg", NULL, D_null, 0, 0 },
{ op_0x, "<deprecated> restore_reg", NULL, D_null, 0, 0 },
{ op_sdb, "set_data_block", NULL, D_hex8, 0, INDEX_DATA_TABLE },
{ op_destsrc, "xor", "^=", D_REG, 0, 0 },
{ op_destsrc, "xor", "^=", D_PS, 0, 0 },
{ op_destsrc, "xor", "^=", D_WS, 0, 0 },
{ op_destsrc, "xor", "^=", D_FB, 0, 0 },
{ op_destsrc, "xor", "^=", D_PLL, 0, 0 },
{ op_destsrc, "xor", "^=", D_MC, 0, 0 },
{ op_destsrc, "shl", "<<=", D_REG, 0, 0 },
{ op_destsrc, "shl", "<<=", D_PS, 0, 0 },
{ op_destsrc, "shl", "<<=", D_WS, 0, 0 },
{ op_destsrc, "shl", "<<=", D_FB, 0, 0 },
{ op_destsrc, "shl", "<<=", D_PLL, 0, 0 },
{ op_destsrc, "shl", "<<=", D_MC, 0, 0 },
{ op_destsrc, "shr", ">>=", D_REG, 0, 0 },
{ op_destsrc, "shr", ">>=", D_PS, 0, 0 },
{ op_destsrc, "shr", ">>=", D_WS, 0, 0 },
{ op_destsrc, "shr", ">>=", D_FB, 0, 0 },
{ op_destsrc, "shr", ">>=", D_PLL, 0, 0 },
{ op_destsrc, "shr", ">>=", D_MC, 0, 0 },
{ op_0x, "<!doc> debug", NULL, D_null, 0, 0 },
{ op_ds, "bindata", NULL, D_null, 0, 0 },
[0x80] = { op_0x, "<!impl> extended", NULL, D_null, 0, 0 },
[0xff] = { op_0x, "<reserved>", NULL, D_null, 0, 0 }
};
int get_table_offset(ut16 *table, int idx) {
int i, last = 0, offset = 0;
static int wrapwarning = 0;
if (! table || ! table[idx])
return 0;
for (i = 0; i <= idx; i++) {
int off = table[i];
if (off) {
if (off < last)
offset += 0x10000;
last = off - 0x8000;
}
}
if (offset && ! wrapwarning++)
printf ("*** Wrap around of table offset - assuming offset\n");
return table[idx] + offset;
}
int sub_dest (const ut8 *d, char *out, int type, int align, int size, int index) {
ut32 val;
int r;
const char *ind;
switch (type) {
case D_REG:
val = *((ut16 *) d);
r = 2;
break;
case D_ID: case D_IM:
out += sprintf (out, "<internal - illegal addrtype %s>", addrnames [type]);
val = 0;
r = 0;
break;
default:
val = *d;
r = 1;
}
if (type == D_WS && (ind = get_index (INDEX_WORK_REG, val)) )
out += sprintf (out, "%s", ind);
else if (r)
out += sprintf (out, addrtypes [type], val << addrtypes_shift[type]);
switch (size) {
case 1:
out += sprintf (out, " [%s]", align_byte[align]);
break;
case 2:
out += sprintf (out, " [%s]", align_word[align]);
break;
case 4:
out += sprintf (out, " [%s]", align_long[align]);
break;
}
if (type == D_REG && (ind = get_index (last_reg_index, val+last_reg_offset)) )
out += sprintf (out, " (%s)", ind);
if (r && (ind = get_index (index, val)) )
out += sprintf (out, " (%s)", ind);
return r;
}
int sub_src (const ut8 *d, char *out, int type, int align, int size, int index) {
ut32 val;
int r;
const char *ind;
switch (type) {
case D_IM:
r = size;
break;
case D_PS: case D_WS: case D_FB: case D_PLL: case D_MC:
r = 1;
break;
case D_REG: case D_ID:
r = 2;
}
switch (r) {
case 1:
val = *d;
break;
case 2:
val = r_read_le16(d);
break;
case 4:
val = r_read_le32(d);
break;
}
if (type == D_IM) {
out += sprintf (out, addrtypes_im [size], val);
} else if (type == D_WS && (ind = get_index (INDEX_WORK_REG, val)) ) {
out += sprintf (out, "%s", ind);
out += sprintf (out, " [%s]", align_source[align]);
} else {
out += sprintf (out, addrtypes [type], val << addrtypes_shift [type]);
out += sprintf (out, " [%s]", align_source[align]);
}
if (type == D_REG && (ind = get_index (last_reg_index, val+last_reg_offset)) )
out += sprintf (out, " (%s)", ind);
if ( (ind = get_index (index, val)) )
out += sprintf (out, " (%s)", ind);
return r;
}
int op_ds (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
ut16 size = r_read_at_le16(d, 1);
out += sprintf (out, "%-5s %d bytes", op->name, size + 2);
return size + 3;
}
int op_sdb (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
const char *ind;
out += sprintf (out, "%-5s ", op->name);
out += sprintf (out, addrtypes [op->desttype],
d[1] << addrtypes_shift [op->desttype]);
if (d[1] == 0xff)
out += sprintf (out, " (this table)");
else if ( (ind = get_index (op->destindex, d[1])) )
out += sprintf (out, " (%s)", ind);
return 2;
}
int op_0x (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
strcpy (out, op->name);
return 1;
}
int op_1x8 (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
const char *ind;
out += sprintf (out, "%-5s ", op->name);
out += sprintf (out, addrtypes [op->desttype],
d[1] << addrtypes_shift [op->desttype]);
if ( (ind = get_index (op->destindex, d[1])) )
out += sprintf (out, " (%s)", ind);
return 2;
}
int op_1x16 (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
const char *ind;
out += sprintf (out, "%-5s ", op->name);
out += sprintf (out, addrtypes [op->desttype],
r_read_at_le16(d, 1) << addrtypes_shift [op->desttype]);
if ( (ind = get_index (op->destindex, d[1])) )
out += sprintf (out, " (%s)", ind);
return 3;
}
int op_src (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
ut8 *t = (ut8 *)&d[1];
int attr = *t++;
out += sprintf (out, "%-5s ", op->name);
t += sub_src (t, out, attr & 0x07, (attr & 0x38) >> 3, size_align[(attr & 0x38)>>3], op->srcindex);
return t - d;
}
int op_dest (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
ut8 *t = (ut8 *)&d[1];
int attr = *t++;
out += sprintf (out, "%-5s ", op->name);
t += sub_src (t, out, op->desttype, (attr & 0x38) >> 3, size_align[(attr & 0x38)>>3], op->destindex);
return t - d;
}
int op_destsrc (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
ut8 *t = (ut8 *)&d[1];
int attr = *t++;
out += sprintf (out, "%-5s ", op->name);
t += sub_dest (t, out, op->desttype, attr >> 6, size_align[(attr & 0x38)>>3], op->destindex);
out += strlen (out);
out += sprintf (out, " <- ");
t += sub_src (t, out, attr & 0x07, (attr & 0x38) >> 3, size_align[(attr & 0x38)>>3], op->srcindex);
return t - d;
}
int op_shift (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
ut8 *t = (ut8 *)&d[1];
int attr = *t++;
out += sprintf (out, "%-5s ", op->name);
t += sub_src (t, out, op->desttype, (attr & 0x38) >> 3, size_align[(attr & 0x38)>>3], op->destindex);
out += strlen (out);
out += sprintf (out, " by %02x", *t++);
return t - d;
}
int op_switch (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
ut8 *t = (ut8 *)&d[1];
int attr = *t++;
out += sprintf (out, "%-5s ", op->name);
t += sub_src (t, out, attr & 0x07, (attr & 0x38) >> 3, size_align[(attr & 0x38)>>3], op->srcindex);
out += strlen (out);
while (t[0] != 0x5a && t[1] != 0x5a) { /* EndOfSwitch: 2x NOP */
if (*t++ != 'c') {
out += sprintf (out, " (missing CASE for switch)");
t -= 3;
break;
}
switch (size_align[(attr & 0x38)>>3]) {
case 1:
out += sprintf (out, " %02x ->", *t++);
break;
case 2:
out += sprintf (out, " %04x ->", r_read_le16(t));
t += 2;
break;
case 4:
out += sprintf (out, " %08x ->", r_read_le32(t));
t += 4;
break;
}
out += sprintf (out, " %04x", r_read_le16(t));
t += 2;
}
t += 2;
return t - d;
}
int op_mask (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
ut8 *t = (ut8 *)&d[1];
int attr = *t++;
out += sprintf (out, "%-5s ", op->name);
t += sub_dest (t, out, op->desttype, attr >> 6, size_align[(attr & 0x38)>>3], op->destindex);
out += strlen (out);
out += sprintf (out, " & ");
t += sub_src (t, out, D_IM, (attr & 0x38) >> 3, size_align[(attr & 0x38)>>3], 0);
out += strlen (out);
out += sprintf (out, " | ");
t += sub_src (t, out, attr & 0x07, (attr & 0x38) >> 3, size_align[(attr & 0x38)>>3], 0);
return t - d;
}
int op_setpt0 (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
last_reg_index = op->srcindex;
/* is never INDEX_REG_MM */
addrtypes_shift[D_REG] = 0;
return op_0x (d, out);
}
int op_setpt1 (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
last_reg_index = op->srcindex + r_read_at_le16(d, 1);
if (last_reg_index == INDEX_REG_MM && opt_reg_addresses)
addrtypes_shift[D_REG] = 2;
else
addrtypes_shift[D_REG] = 0;
return op_1x16 (d, out);
}
int op_setrb (const ut8 *d, char *out) {
const optab_t *op = &optable[d[0]];
last_reg_offset = op->srcindex + r_read_at_le16(d, 1);
return op_1x16 (d, out);
}
/*
void do_data (const ut8 *data, int off, int nr)
{
int len;
const char *comment = NULL;
int frev = data[off+2];
int crev = data[off+3];
data_dumper_t *dt = get_data_dumper (nr, &frev, &crev, &comment);
if (! dt)
return;
if (frev == 0)
fprintf (stdout, " NOTE: General revisionless dumper only.\n");
else if (frev != data[off+2] || crev != data[off+3])
fprintf (stdout, " NOTE: Dumper revision differs. "
"Used: Format Rev. %02x Content Rev. %02x\n", frev, crev);
if (comment)
fprintf (stdout, " NOTE: %s\n", comment);
if (frev == 0 || frev != data[off+2] || crev != data[off+3] || comment)
fputs ("\n", stdout);
len = (*dt) (data+off, data+off, 1);
fprintf (stdout, "\n Total data structure size: %04x\n\n", len);
}
*/
int atombios_inst_len(const ut8 *buf) {
const ut8 *d = buf;
char tmpbuf[1024] = {0}; // can have data table with hugeass instruction
ut8 size = 0;
if (optable[*d].process) {
size = optable[*d].process (d, tmpbuf);
} else {
size = 1;
}
return size;
}
int atombios_disassemble(const ut8 *inbuf, char *outbuf) {
const ut8 *d = inbuf;
ut8 size = 0;
if (optable[*d].process) {
size = optable[*d].process (d, outbuf);
} else {
sprintf (outbuf, "<unknown opcode> %02x", *d);
size = 1;
}
return size;
}
+98
View File
@@ -0,0 +1,98 @@
#ifndef _INCLUDE_ATOMBIOS_H_
#define _INCLUDE_ATOMBIOS_H_
#include <r_types.h>
#define HEADER_OFFSET 0x48
#define ATOM_MAGIC (const ut8 *)"ATOM"
#define N_TABLES_CMD 80
#define N_TABLES_DATA 34
typedef struct index_table_s {
const char *name;
const char **tab;
int len;
} index_table_t;
enum {
WS_QUOTIENT = 0x40,
WS_PRODUCT_LOW32 = 0x40,
WS_REMAINDER,
WS_PRODUCT_HI32_XXX = 0x41,
WS_DATAPTR,
WS_SHIFT,
WS_OR_MASK,
WS_AND_MASK,
WS_FB_WINDOW,
WS_ATTRIBUTES,
WS_REGPTR
};
enum {
D_REG = 0,
D_PS,
D_WS,
D_FB,
D_ID,
D_IM,
D_PLL,
D_MC,
D_hex8,
D_hex16,
D_null
};
enum {
INDEX_NONE = 0,
INDEX_COMMAND_TABLE,
INDEX_DATA_TABLE,
INDEX_ATI_PORT,
INDEX_WORK_REG,
INDEX_REG_MM,
INDEX_REG_PLL,
INDEX_REG_MC,
INDEX_REG_PCIE,
INDEX_REG_PCICONFIG,
INDEX_REG_SYSTEMIO,
INDEXTABLE_SIZEOF
};
typedef struct {
int (*process) (const ut8 *d, char *out);
const char *name;
const char *esilop;
ut8 desttype;
ut8 srcindex;
ut8 destindex;
} optab_t;
int atombios_inst_len(const ut8 *buf);
int atombios_disassemble(const ut8 *inbuf, char *outbuf);
const char *get_index (int type, int val);
extern const char *align_source_esil[];
extern const char *align_byte_esil[];
extern const char *align_word_esil[];
extern const char *align_long_esil[];
extern const char *addrtypes_esil[];
extern const char *align_source[];
extern const char *align_byte[];
extern const char *align_word[];
extern const char *align_long[];
extern const int size_align[];
extern const char *addrnames[];
extern const char *addrtypes[];
extern int addrtypes_shift[];
extern const char *addrtypes_im[];
extern const char *index_command_table[];
extern const char *index_data_table[];
extern const char *index_ati_port[];
extern const char *index_work_reg[];
#define TABENTRY(x) { #x, (index_ ## x), sizeof (index_ ## x) / sizeof (const char **) }
extern index_table_t index_tables[INDEXTABLE_SIZEOF];
extern const optab_t optable[256];
#endif
+79 -10
View File
@@ -6,6 +6,75 @@
#include "evm.h"
const EvmOpDef opcodes[256] = {
[EVM_OP_STOP] = { "stop", 1 },
[EVM_OP_ADD] = { "add", 1 },
[EVM_OP_MUL] = { "mul", 1 },
[EVM_OP_SUB] = { "sub", 1 },
[EVM_OP_DIV] = { "div", 1 },
[EVM_OP_SDIV] = { "sdiv", 1 },
[EVM_OP_MOD] = { "mod", 1 },
[EVM_OP_SMOD] = { "smod", 1 },
[EVM_OP_ADDMOD] = { "addmod", 1 },
[EVM_OP_MULMOD] = { "mulmod", 1 },
[EVM_OP_EXP] = { "exp", 1 },
[EVM_OP_SIGNEXTEND] = { "signextend", 1 },
[EVM_OP_LT] = { "lt", 1 },
[EVM_OP_GT] = { "gt", 1 },
[EVM_OP_SLT] = { "slt", 1 },
[EVM_OP_SGT] = { "sgt", 1 },
[EVM_OP_EQ] = { "eq", 1 },
[EVM_OP_ISZERO] = { "iszero", 1 },
[EVM_OP_AND] = { "and", 1 },
[EVM_OP_OR] = { "or", 1 },
[EVM_OP_XOR] = { "xor", 1 },
[EVM_OP_NOT] = { "not", 1 },
[EVM_OP_BYTE] = { "byte", 1 },
[EVM_OP_SHA3] = { "sha3", 1 },
[EVM_OP_ADDRESS] = { "address", 1 },
[EVM_OP_BALANCE] = { "balance", 1 },
[EVM_OP_ORIGIN] = { "origin", 1 },
[EVM_OP_CALLER] = { "caller", 1 },
[EVM_OP_CALLVALUE] = { "callvalue", 1 },
[EVM_OP_CALLDATALOAD] = { "calldataload", 1 },
[EVM_OP_CALLDATASIZE] = { "calldatasize", 1 },
[EVM_OP_CALLDATACOPY] = { "calldatacopy", 1 },
[EVM_OP_CODESIZE] = { "codesize", 1 },
[EVM_OP_CODECOPY] = { "codecopy", 1 },
[EVM_OP_GASPRICE] = { "gasprice", 1 },
[EVM_OP_EXTCODESIZE] = { "extcodesize", 1 },
[EVM_OP_EXTCODECOPY] = { "extcodecopy", 1 },
[EVM_OP_RETURNDATASIZE] = { "returndatasize", 1},
[EVM_OP_RETURNDATACOPY] = { "returndatacopy", 1},
[EVM_OP_BLOCKHASH] = { "blockhash", 1 },
[EVM_OP_COINBASE] = { "coinbase", 1 },
[EVM_OP_TIMESTAMP] = { "timestamp", 1 },
[EVM_OP_NUMBER] = { "number", 1 },
[EVM_OP_DIFFICULTY] = { "difficulty", 1 },
[EVM_OP_GASLIMIT] = { "gaslimit", 1 },
[EVM_OP_POP] = { "pop", 1 },
[EVM_OP_MLOAD] = { "mload", 1 },
[EVM_OP_MSTORE] = { "mstore", 1 },
[EVM_OP_MSTORE8] = { "mstore8", 1 },
[EVM_OP_SLOAD] = { "sload", 1 },
[EVM_OP_SSTORE] = { "sstore", 1 },
[EVM_OP_JUMP] = { "jump", 1 },
[EVM_OP_JUMPI] = { "jumpi", 1 },
[EVM_OP_PC] = { "pc", 1 },
[EVM_OP_MSIZE] = { "msize", 1 },
[EVM_OP_GAS] = { "gas", 1 },
[EVM_OP_JUMPDEST] = { "jumpdest", 1 },
// ....
[EVM_OP_CREATE] = { "create", 1 },
[EVM_OP_CALL] = { "call", 1 },
[EVM_OP_CALLCODE] = { "callcode", 1 },
[EVM_OP_RETURN] = { "return", 1 },
[EVM_OP_DELEGATECALL] = { "delegatecall", 1 },
[EVM_OP_STATICCALL] = { "staticcall", 1 },
[EVM_OP_REVERT] = { "revert", 1 },
[EVM_OP_SELFDESTRUCT] = { "selfdestruct", 1 },
};
static void settxtf(EvmOp *op, const char *fmt, ...) {
if (strchr (fmt, '%')) {
va_list ap;
@@ -18,13 +87,13 @@ static void settxtf(EvmOp *op, const char *fmt, ...) {
}
}
int evm_asm(const char *str, unsigned char *buf, int buf_len) {
int evm_asm(const char *str, RStrBuf *buf, int buf_len) {
int i, len = -1;
for (i = 0; i < 0xff; i++) {
EvmOpDef *opdef = &opcodes[i];
const EvmOpDef *opdef = &opcodes[i];
if (opdef->txt) {
if (!strcmp (opdef->txt, str)) {
buf[0] = i;
r_strbuf_appendf (buf, "%d", i);
return 1;
}
}
@@ -36,7 +105,7 @@ int evm_asm(const char *str, unsigned char *buf, int buf_len) {
int evm_dis(EvmOp *op, const unsigned char *buf, int buf_len) {
op->len = 1;
op->op = buf[0];
EvmOpDef *opdef = &opcodes[buf[0]];
const EvmOpDef *opdef = &opcodes[buf[0]];
if (opdef->txt) {
op->txt = opdef->txt;
op->len = opdef->len;
@@ -79,13 +148,13 @@ int evm_dis(EvmOp *op, const unsigned char *buf, int buf_len) {
case EVM_OP_PUSH31:
case EVM_OP_PUSH32:
{
int i, pushSize = buf[0] - EVM_OP_PUSH1;
op->imm = 0;
for (i = 0; i < pushSize + 1; i++) {
op->imm <<= 8;
op->imm |= buf[i + 1];
int pushSize = buf[0] - EVM_OP_PUSH1;
char hexbuf[64] = {0};
int res = r_hex_bin2str (buf + 1, pushSize + 1, hexbuf);
if (res < 1 || !*hexbuf) {
strcpy (hexbuf, "0");
}
settxtf (op, "push%d 0x%x", pushSize + 1, op->imm);
settxtf (op, "push%d 0x%s", pushSize + 1, hexbuf);
op->len = 2 + pushSize;
}
break;
+3 -72
View File
@@ -1,6 +1,7 @@
#ifndef EVM_EVM_H
#define EVM_EVM_H
#include <r_util.h>
typedef enum {
EVM_OP_STOP = 0x00,
@@ -149,7 +150,6 @@ typedef enum {
typedef struct EvmOp {
EvmOpcodes op;
int len;
uint64_t imm;
const char *txt;
char txt_buf[32];
} EvmOp;
@@ -159,77 +159,8 @@ typedef struct {
int len;
} EvmOpDef;
static EvmOpDef opcodes[256] = {
[EVM_OP_STOP] = { "stop", 1 },
[EVM_OP_ADD] = { "add", 1 },
[EVM_OP_MUL] = { "mul", 1 },
[EVM_OP_SUB] = { "sub", 1 },
[EVM_OP_DIV] = { "div", 1 },
[EVM_OP_SDIV] = { "sdiv", 1 },
[EVM_OP_MOD] = { "mod", 1 },
[EVM_OP_SMOD] = { "smod", 1 },
[EVM_OP_ADDMOD] = { "addmod", 1 },
[EVM_OP_MULMOD] = { "mulmod", 1 },
[EVM_OP_EXP] = { "exp", 1 },
[EVM_OP_SIGNEXTEND] = { "signextend", 1 },
[EVM_OP_LT] = { "lt", 1 },
[EVM_OP_GT] = { "gt", 1 },
[EVM_OP_SLT] = { "slt", 1 },
[EVM_OP_SGT] = { "sgt", 1 },
[EVM_OP_EQ] = { "eq", 1 },
[EVM_OP_ISZERO] = { "iszero", 1 },
[EVM_OP_AND] = { "and", 1 },
[EVM_OP_OR] = { "or", 1 },
[EVM_OP_XOR] = { "xor", 1 },
[EVM_OP_NOT] = { "not", 1 },
[EVM_OP_BYTE] = { "byte", 1 },
[EVM_OP_SHA3] = { "sha3", 1 },
[EVM_OP_ADDRESS] = { "address", 1 },
[EVM_OP_BALANCE] = { "balance", 1 },
[EVM_OP_ORIGIN] = { "origin", 1 },
[EVM_OP_CALLER] = { "caller", 1 },
[EVM_OP_CALLVALUE] = { "callvalue", 1 },
[EVM_OP_CALLDATALOAD] = { "calldataload", 1 },
[EVM_OP_CALLDATASIZE] = { "calldatasize", 1 },
[EVM_OP_CALLDATACOPY] = { "calldatacopy", 1 },
[EVM_OP_CODESIZE] = { "codesize", 1 },
[EVM_OP_CODECOPY] = { "codecopy", 1 },
[EVM_OP_GASPRICE] = { "gasprice", 1 },
[EVM_OP_EXTCODESIZE] = { "extcodesize", 1 },
[EVM_OP_EXTCODECOPY] = { "extcodecopy", 1 },
[EVM_OP_RETURNDATASIZE] = { "returndatasize", 1},
[EVM_OP_RETURNDATACOPY] = { "returndatacopy", 1},
[EVM_OP_BLOCKHASH] = { "blockhash", 1 },
[EVM_OP_COINBASE] = { "coinbase", 1 },
[EVM_OP_TIMESTAMP] = { "timestamp", 1 },
[EVM_OP_NUMBER] = { "number", 1 },
[EVM_OP_DIFFICULTY] = { "difficulty", 1 },
[EVM_OP_GASLIMIT] = { "gaslimit", 1 },
[EVM_OP_POP] = { "pop", 1 },
[EVM_OP_MLOAD] = { "mload", 1 },
[EVM_OP_MSTORE] = { "mstore", 1 },
[EVM_OP_MSTORE8] = { "mstore8", 1 },
[EVM_OP_SLOAD] = { "sload", 1 },
[EVM_OP_SSTORE] = { "sstore", 1 },
[EVM_OP_JUMP] = { "jump", 1 },
[EVM_OP_JUMPI] = { "jumpi", 1 },
[EVM_OP_PC] = { "pc", 1 },
[EVM_OP_MSIZE] = { "msize", 1 },
[EVM_OP_GAS] = { "gas", 1 },
[EVM_OP_JUMPDEST] = { "jumpdest", 1 },
// ....
[EVM_OP_CREATE] = { "create", 1 },
[EVM_OP_CALL] = { "call", 1 },
[EVM_OP_CALLCODE] = { "callcode", 1 },
[EVM_OP_RETURN] = { "return", 1 },
[EVM_OP_DELEGATECALL] = { "delegatecall", 1 },
[EVM_OP_STATICCALL] = { "staticcall", 1 },
[EVM_OP_REVERT] = { "revert", 1 },
[EVM_OP_SELFDESTRUCT] = { "selfdestruct", 1 },
};
extern const EvmOpDef opcodes[256];
int evm_dis(EvmOp *op, const unsigned char *buf, int buf_len);
int evm_asm(const char *str, unsigned char *buf, int buf_len);
int evm_asm(const char *str, RStrBuf *buf, int buf_len);
#endif /* EVM_EVM_H */
+1
View File
@@ -274,6 +274,7 @@ extern int print_insn_mn10300 (bfd_vma, disassemble_info *);
extern int print_insn_moxie (bfd_vma, disassemble_info *);
extern int print_insn_msp430 (bfd_vma, disassemble_info *);
extern int print_insn_mt (bfd_vma, disassemble_info *);
extern int print_insn_nios (bfd_vma, disassemble_info *);
extern int print_insn_ns32k (bfd_vma, disassemble_info *);
extern int print_insn_openrisc (bfd_vma, disassemble_info *);
extern int print_insn_pdp11 (bfd_vma, disassemble_info *);
+57
View File
@@ -0,0 +1,57 @@
/* NIOS ELF support for BFD.
Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _ELF_NIOS_H
#define _ELF_NIOS_H
#include "elf/reloc-macros.h"
/* Relocations. */
START_RELOC_NUMBERS (elf_nios_reloc_type)
RELOC_NUMBER (R_NIOS_NONE, 0)
RELOC_NUMBER (R_NIOS_32, 1)
RELOC_NUMBER (R_NIOS_LO16_LO5, 2)
RELOC_NUMBER (R_NIOS_LO16_HI11, 3)
RELOC_NUMBER (R_NIOS_HI16_LO5, 4)
RELOC_NUMBER (R_NIOS_HI16_HI11, 5)
RELOC_NUMBER (R_NIOS_PCREL6, 6)
RELOC_NUMBER (R_NIOS_PCREL8, 7)
RELOC_NUMBER (R_NIOS_PCREL11, 8)
RELOC_NUMBER (R_NIOS_16, 9)
RELOC_NUMBER (R_NIOS_H_LO5, 10)
RELOC_NUMBER (R_NIOS_H_HI11,11)
RELOC_NUMBER (R_NIOS_H_XLO5, 12)
RELOC_NUMBER (R_NIOS_H_XHI11, 13)
RELOC_NUMBER (R_NIOS_H_16, 14)
RELOC_NUMBER (R_NIOS_H_32, 15)
RELOC_NUMBER (R_NIOS_GNU_VTINHERIT, 200)
RELOC_NUMBER (R_NIOS_GNU_VTENTRY, 201)
EMPTY_RELOC (R_NIOS_max)
END_RELOC_NUMBERS
#define EF_NIOS_CPU_16 0x00000001 /* nios16 */
#define EF_NIOS_CPU_32 0x00000002 /* nios32 */
#define EF_NIOS_CPU_MASK 0x00000003 /* specific cpu bits */
#define EF_NIOS_ALL_FLAGS (EF_NIOS_CPU_MASK)
#endif /* _ELF_NIOS_H */
+18
View File
@@ -1927,6 +1927,9 @@ enum bfd_architecture
#define bfd_mach_mn10300 300
#define bfd_mach_am33 330
#define bfd_mach_am33_2 332
bfd_arch_nios,
#define bfd_mach_nios16 0
#define bfd_mach_nios32 1
bfd_arch_fr30,
#define bfd_mach_fr30 0x46523330
bfd_arch_frv,
@@ -3434,6 +3437,21 @@ significant 7 bits of a 23-bit extended address are placed into
the opcode. */
BFD_RELOC_TIC54X_MS7_OF_23,
/* Altera Nios Relocations. */
BFD_RELOC_NIOS_LO16_LO5,
BFD_RELOC_NIOS_LO16_HI11,
BFD_RELOC_NIOS_HI16_LO5,
BFD_RELOC_NIOS_HI16_HI11,
BFD_RELOC_NIOS_PCREL6,
BFD_RELOC_NIOS_PCREL8,
BFD_RELOC_NIOS_PCREL11,
BFD_RELOC_NIOS_H_LO5,
BFD_RELOC_NIOS_H_HI11,
BFD_RELOC_NIOS_H_XLO5,
BFD_RELOC_NIOS_H_XHI11,
BFD_RELOC_NIOS_H_16,
BFD_RELOC_NIOS_H_32,
/* This is a 48 bit reloc for the FR30 that stores 32 bits. */
BFD_RELOC_FR30_48,
+150
View File
@@ -0,0 +1,150 @@
/* <ctype.h> replacement macros.
Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Zack Weinberg <[email protected]>.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/* This is a compatible replacement of the standard C library's <ctype.h>
with the following properties:
- Implements all isxxx() macros required by C99.
- Also implements some character classes useful when
parsing C-like languages.
- Does not change behavior depending on the current locale.
- Behaves properly for all values in the range of a signed or
unsigned char.
To avoid conflicts, this header defines the isxxx functions in upper
case, e.g. ISALPHA not isalpha. */
#ifndef SAFE_CTYPE_H
#define SAFE_CTYPE_H
/* Determine host character set. */
#define HOST_CHARSET_UNKNOWN 0
#define HOST_CHARSET_ASCII 1
#define HOST_CHARSET_EBCDIC 2
#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
&& 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21
# define HOST_CHARSET HOST_CHARSET_ASCII
#else
# if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \
&& 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A
# define HOST_CHARSET HOST_CHARSET_EBCDIC
# else
# define HOST_CHARSET HOST_CHARSET_UNKNOWN
# endif
#endif
/* Categories. */
enum {
/* In C99 */
_sch_isblank = 0x0001, /* space \t */
_sch_iscntrl = 0x0002, /* nonprinting characters */
_sch_isdigit = 0x0004, /* 0-9 */
_sch_islower = 0x0008, /* a-z */
_sch_isprint = 0x0010, /* any printing character including ' ' */
_sch_ispunct = 0x0020, /* all punctuation */
_sch_isspace = 0x0040, /* space \t \n \r \f \v */
_sch_isupper = 0x0080, /* A-Z */
_sch_isxdigit = 0x0100, /* 0-9A-Fa-f */
/* Extra categories useful to cpplib. */
_sch_isidst = 0x0200, /* A-Za-z_ */
_sch_isvsp = 0x0400, /* \n \r */
_sch_isnvsp = 0x0800, /* space \t \f \v \0 */
/* Combinations of the above. */
_sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */
_sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */
_sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */
_sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */
_sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */
_sch_isbasic = _sch_isprint|_sch_iscppsp /* basic charset of ISO C
(plus ` and @) */
};
/* Character classification. */
extern const unsigned short _sch_istable[256];
#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit))
#define ISALPHA(c) _sch_test(c, _sch_isalpha)
#define ISALNUM(c) _sch_test(c, _sch_isalnum)
#define ISBLANK(c) _sch_test(c, _sch_isblank)
#define ISCNTRL(c) _sch_test(c, _sch_iscntrl)
#define ISDIGIT(c) _sch_test(c, _sch_isdigit)
#define ISGRAPH(c) _sch_test(c, _sch_isgraph)
#define ISLOWER(c) _sch_test(c, _sch_islower)
#define ISPRINT(c) _sch_test(c, _sch_isprint)
#define ISPUNCT(c) _sch_test(c, _sch_ispunct)
#define ISSPACE(c) _sch_test(c, _sch_isspace)
#define ISUPPER(c) _sch_test(c, _sch_isupper)
#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit)
#define ISIDNUM(c) _sch_test(c, _sch_isidnum)
#define ISIDST(c) _sch_test(c, _sch_isidst)
#define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic)
#define IS_VSPACE(c) _sch_test(c, _sch_isvsp)
#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp)
#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp)
/* Character transformation. */
extern const unsigned char _sch_toupper[256];
extern const unsigned char _sch_tolower[256];
#define TOUPPER(c) _sch_toupper[(c) & 0xff]
#define TOLOWER(c) _sch_tolower[(c) & 0xff]
/* Prevent the users of safe-ctype.h from accidently using the routines
from ctype.h. Initially, the approach was to produce an error when
detecting that ctype.h has been included. But this was causing
trouble as ctype.h might get indirectly included as a result of
including another system header (for instance gnulib's stdint.h).
So we include ctype.h here and then immediately redefine its macros. */
#include <ctype.h>
#undef isalpha
#define isalpha(c) do_not_use_isalpha_with_safe_ctype
#undef isalnum
#define isalnum(c) do_not_use_isalnum_with_safe_ctype
#undef iscntrl
#define iscntrl(c) do_not_use_iscntrl_with_safe_ctype
#undef isdigit
#define isdigit(c) do_not_use_isdigit_with_safe_ctype
#undef isgraph
#define isgraph(c) do_not_use_isgraph_with_safe_ctype
#undef islower
#define islower(c) do_not_use_islower_with_safe_ctype
#undef isprint
#define isprint(c) do_not_use_isprint_with_safe_ctype
#undef ispunct
#define ispunct(c) do_not_use_ispunct_with_safe_ctype
#undef isspace
#define isspace(c) do_not_use_isspace_with_safe_ctype
#undef isupper
#define isupper(c) do_not_use_isupper_with_safe_ctype
#undef isxdigit
#define isxdigit(c) do_not_use_isxdigit_with_safe_ctype
#undef toupper
#define toupper(c) do_not_use_toupper_with_safe_ctype
#undef tolower
#define tolower(c) do_not_use_tolower_with_safe_ctype
#endif /* SAFE_CTYPE_H */
+29
View File
@@ -0,0 +1,29 @@
/* This file redefines all regex external names before including
a renamed copy of glibc's regex.h. */
#ifndef _XREGEX_H
#define _XREGEX_H 1
# define regfree xregfree
# define regexec xregexec
# define regcomp xregcomp
# define regerror xregerror
# define regoff_t xregoff_t
# define re_set_registers xre_set_registers
# define re_match_2 xre_match_2
# define re_match xre_match
# define re_search xre_search
# define re_compile_pattern xre_compile_pattern
# define re_set_syntax xre_set_syntax
# define re_search_2 xre_search_2
# define re_compile_fastmap xre_compile_fastmap
# define re_syntax_options xre_syntax_options
# define re_max_failures xre_max_failures
# define _REGEX_RE_COMP
# define re_comp xre_comp
# define re_exec xre_exec
#include "xregex2.h"
#endif /* xregex.h */
+564
View File
@@ -0,0 +1,564 @@
/* Definitions for data structures and routines for the regular
expression library, version 0.12.
Copyright (C) 1985-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in /gd/gnu/lib.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA. */
#ifndef _REGEX_H
#define _REGEX_H 1
/* Allow the use in C++ code. */
#ifdef __cplusplus
extern "C" {
#endif
/* POSIX says that <sys/types.h> must be included (by the caller) before
<regex.h>. */
#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
should be there. */
# include <stddef.h>
#endif
/* The following two types have to be signed and unsigned integer type
wide enough to hold a value of a pointer. For most ANSI compilers
ptrdiff_t and size_t should be likely OK. Still size of these two
types is 2 for Microsoft C. Ugh... */
typedef long int s_reg_t;
typedef unsigned long int active_reg_t;
/* The following bits are used to determine the regexp syntax we
recognize. The set/not-set meanings are chosen so that Emacs syntax
remains the value 0. The bits are given in alphabetical order, and
the definitions shifted by one from the previous bit; thus, when we
add or remove a bit, only one other definition need change. */
typedef unsigned long int reg_syntax_t;
/* If this bit is not set, then \ inside a bracket expression is literal.
If set, then such a \ quotes the following character. */
#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
/* If this bit is not set, then + and ? are operators, and \+ and \? are
literals.
If set, then \+ and \? are operators and + and ? are literals. */
#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
/* If this bit is set, then character classes are supported. They are:
[:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
[:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
If not set, then character classes are not supported. */
#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
/* If this bit is set, then ^ and $ are always anchors (outside bracket
expressions, of course).
If this bit is not set, then it depends:
^ is an anchor if it is at the beginning of a regular
expression or after an open-group or an alternation operator;
$ is an anchor if it is at the end of a regular expression, or
before a close-group or an alternation operator.
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
POSIX draft 11.2 says that * etc. in leading positions is undefined.
We already implemented a previous draft which made those constructs
invalid, though, so we haven't changed the code back. */
#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
/* If this bit is set, then special characters are always special
regardless of where they are in the pattern.
If this bit is not set, then special characters are special only in
some contexts; otherwise they are ordinary. Specifically,
* + ? and intervals are only special when not after the beginning,
open-group, or alternation operator. */
#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
/* If this bit is set, then *, +, ?, and { cannot be first in an re or
immediately after an alternation or begin-group operator. */
#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
/* If this bit is set, then . matches newline.
If not set, then it doesn't. */
#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
/* If this bit is set, then . doesn't match NUL.
If not set, then it does. */
#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
/* If this bit is set, nonmatching lists [^...] do not match newline.
If not set, they do. */
#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
/* If this bit is set, either \{...\} or {...} defines an
interval, depending on RE_NO_BK_BRACES.
If not set, \{, \}, {, and } are literals. */
#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
/* If this bit is set, +, ? and | aren't recognized as operators.
If not set, they are. */
#define RE_LIMITED_OPS (RE_INTERVALS << 1)
/* If this bit is set, newline is an alternation operator.
If not set, newline is literal. */
#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
/* If this bit is set, then `{...}' defines an interval, and \{ and \}
are literals.
If not set, then `\{...\}' defines an interval. */
#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
/* If this bit is set, (...) defines a group, and \( and \) are literals.
If not set, \(...\) defines a group, and ( and ) are literals. */
#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
/* If this bit is set, then \<digit> matches <digit>.
If not set, then \<digit> is a back-reference. */
#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
/* If this bit is set, then | is an alternation operator, and \| is literal.
If not set, then \| is an alternation operator, and | is literal. */
#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
/* If this bit is set, then an ending range point collating higher
than the starting range point, as in [z-a], is invalid.
If not set, then when ending range point collates higher than the
starting range point, the range is ignored. */
#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
/* If this bit is set, then an unmatched ) is ordinary.
If not set, then an unmatched ) is invalid. */
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
/* If this bit is set, succeed as soon as we match the whole pattern,
without further backtracking. */
#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
/* If this bit is set, do not process the GNU regex operators.
If not set, then the GNU regex operators are recognized. */
#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
/* If this bit is set, turn on internal regex debugging.
If not set, and debugging was on, turn it off.
This only works if regex.c is compiled -DDEBUG.
We define this bit always, so that all that's needed to turn on
debugging is to recompile regex.c; the calling code can always have
this bit set, and it won't affect anything in the normal case. */
#define RE_DEBUG (RE_NO_GNU_OPS << 1)
/* If this bit is set, a syntactically invalid interval is treated as
a string of ordinary characters. For example, the ERE 'a{1' is
treated as 'a\{1'. */
#define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
/* This global variable defines the particular regexp syntax to use (for
some interfaces). When a regexp is compiled, the syntax used is
stored in the pattern buffer, so changing this does not affect
already-compiled regexps. */
extern reg_syntax_t re_syntax_options;
/* Define combinations of the above bits for the standard possibilities.
(The [[[ comments delimit what gets put into the Texinfo file, so
don't delete them!) */
/* [[[begin syntaxes]]] */
#define RE_SYNTAX_EMACS 0
#define RE_SYNTAX_AWK \
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
| RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
| RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
#define RE_SYNTAX_GNU_AWK \
((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
& ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS))
#define RE_SYNTAX_POSIX_AWK \
(RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
| RE_INTERVALS | RE_NO_GNU_OPS)
#define RE_SYNTAX_GREP \
(RE_BK_PLUS_QM | RE_CHAR_CLASSES \
| RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
| RE_NEWLINE_ALT)
#define RE_SYNTAX_EGREP \
(RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
| RE_NEWLINE_ALT | RE_NO_BK_PARENS \
| RE_NO_BK_VBAR)
#define RE_SYNTAX_POSIX_EGREP \
(RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \
| RE_INVALID_INTERVAL_ORD)
/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
/* Syntax bits common to both basic and extended POSIX regex syntax. */
#define _RE_SYNTAX_POSIX_COMMON \
(RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
| RE_INTERVALS | RE_NO_EMPTY_RANGES)
#define RE_SYNTAX_POSIX_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
isn't minimal, since other operators, such as \`, aren't disabled. */
#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
#define RE_SYNTAX_POSIX_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_VBAR \
| RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
removed and RE_NO_BK_REFS is added. */
#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* [[[end syntaxes]]] */
/* Maximum number of duplicates an interval can allow. Some systems
(erroneously) define this in other header files, but we want our
value, so remove any previous define. */
#ifdef RE_DUP_MAX
# undef RE_DUP_MAX
#endif
/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */
#define RE_DUP_MAX (0x7fff)
/* POSIX `cflags' bits (i.e., information for `regcomp'). */
/* If this bit is set, then use extended regular expression syntax.
If not set, then use basic regular expression syntax. */
#define REG_EXTENDED 1
/* If this bit is set, then ignore case when matching.
If not set, then case is significant. */
#define REG_ICASE (REG_EXTENDED << 1)
/* If this bit is set, then anchors do not match at newline
characters in the string.
If not set, then anchors do match at newlines. */
#define REG_NEWLINE (REG_ICASE << 1)
/* If this bit is set, then report only success or fail in regexec.
If not set, then returns differ between not matching and errors. */
#define REG_NOSUB (REG_NEWLINE << 1)
/* POSIX `eflags' bits (i.e., information for regexec). */
/* If this bit is set, then the beginning-of-line operator doesn't match
the beginning of the string (presumably because it's not the
beginning of a line).
If not set, then the beginning-of-line operator does match the
beginning of the string. */
#define REG_NOTBOL 1
/* Like REG_NOTBOL, except for the end-of-line. */
#define REG_NOTEOL (1 << 1)
/* If any error codes are removed, changed, or added, update the
`re_error_msg' table in regex.c. */
typedef enum
{
#ifdef _XOPEN_SOURCE
REG_ENOSYS = -1, /* This will never happen for this implementation. */
#endif
REG_NOERROR = 0, /* Success. */
REG_NOMATCH, /* Didn't find a match (for regexec). */
/* POSIX regcomp return error codes. (In the order listed in the
standard.) */
REG_BADPAT, /* Invalid pattern. */
REG_ECOLLATE, /* Not implemented. */
REG_ECTYPE, /* Invalid character class name. */
REG_EESCAPE, /* Trailing backslash. */
REG_ESUBREG, /* Invalid back reference. */
REG_EBRACK, /* Unmatched left bracket. */
REG_EPAREN, /* Parenthesis imbalance. */
REG_EBRACE, /* Unmatched \{. */
REG_BADBR, /* Invalid contents of \{\}. */
REG_ERANGE, /* Invalid range end. */
REG_ESPACE, /* Ran out of memory. */
REG_BADRPT, /* No preceding re for repetition op. */
/* Error codes we've added. */
REG_EEND, /* Premature end. */
REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
} reg_errcode_t;
/* This data structure represents a compiled pattern. Before calling
the pattern compiler, the fields `buffer', `allocated', `fastmap',
`translate', and `no_sub' can be set. After the pattern has been
compiled, the `re_nsub' field is available. All other fields are
private to the regex routines. */
#ifndef RE_TRANSLATE_TYPE
# define RE_TRANSLATE_TYPE char *
#endif
struct re_pattern_buffer
{
/* [[[begin pattern_buffer]]] */
/* Space that holds the compiled pattern. It is declared as
`unsigned char *' because its elements are
sometimes used as array indexes. */
unsigned char *buffer;
/* Number of bytes to which `buffer' points. */
unsigned long int allocated;
/* Number of bytes actually used in `buffer'. */
unsigned long int used;
/* Syntax setting with which the pattern was compiled. */
reg_syntax_t syntax;
/* Pointer to a fastmap, if any, otherwise zero. re_search uses
the fastmap, if there is one, to skip over impossible
starting points for matches. */
char *fastmap;
/* Either a translate table to apply to all characters before
comparing them, or zero for no translation. The translation
is applied to a pattern when it is compiled and to a string
when it is matched. */
RE_TRANSLATE_TYPE translate;
/* Number of subexpressions found by the compiler. */
size_t re_nsub;
/* Zero if this pattern cannot match the empty string, one else.
Well, in truth it's used only in `re_search_2', to see
whether or not we should use the fastmap, so we don't set
this absolutely perfectly; see `re_compile_fastmap' (the
`duplicate' case). */
unsigned can_be_null : 1;
/* If REGS_UNALLOCATED, allocate space in the `regs' structure
for `max (RE_NREGS, re_nsub + 1)' groups.
If REGS_REALLOCATE, reallocate space if necessary.
If REGS_FIXED, use what's there. */
#define REGS_UNALLOCATED 0
#define REGS_REALLOCATE 1
#define REGS_FIXED 2
unsigned regs_allocated : 2;
/* Set to zero when `regex_compile' compiles a pattern; set to one
by `re_compile_fastmap' if it updates the fastmap. */
unsigned fastmap_accurate : 1;
/* If set, `re_match_2' does not return information about
subexpressions. */
unsigned no_sub : 1;
/* If set, a beginning-of-line anchor doesn't match at the
beginning of the string. */
unsigned not_bol : 1;
/* Similarly for an end-of-line anchor. */
unsigned not_eol : 1;
/* If true, an anchor at a newline matches. */
unsigned newline_anchor : 1;
/* [[[end pattern_buffer]]] */
};
typedef struct re_pattern_buffer regex_t;
/* Type for byte offsets within the string. POSIX mandates this. */
typedef int regoff_t;
/* This is the structure we store register match data in. See
regex.texinfo for a full description of what registers match. */
struct re_registers
{
unsigned num_regs;
regoff_t *start;
regoff_t *end;
};
/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
`re_match_2' returns information about at least this many registers
the first time a `regs' structure is passed. */
#ifndef RE_NREGS
# define RE_NREGS 30
#endif
/* POSIX specification for registers. Aside from the different names than
`re_registers', POSIX uses an array of structures, instead of a
structure of arrays. */
typedef struct
{
regoff_t rm_so; /* Byte offset from string's start to substring's start. */
regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
} regmatch_t;
/* Declarations for routines. */
/* To avoid duplicating every routine declaration -- once with a
prototype (if we are ANSI), and once without (if we aren't) -- we
use the following macro to declare argument types. This
unfortunately clutters up the declarations a bit, but I think it's
worth it. */
/* Sets the current default syntax to SYNTAX, and return the old syntax.
You can also simply assign to the `re_syntax_options' variable. */
extern reg_syntax_t re_set_syntax (reg_syntax_t syntax);
/* Compile the regular expression PATTERN, with length LENGTH
and syntax given by the global `re_syntax_options', into the buffer
BUFFER. Return NULL if successful, and an error string if not. */
extern const char *re_compile_pattern (const char *pattern, size_t length,
struct re_pattern_buffer *buffer);
/* Compile a fastmap for the compiled pattern in BUFFER; used to
accelerate searches. Return 0 if successful and -2 if was an
internal error. */
extern int re_compile_fastmap (struct re_pattern_buffer *buffer);
/* Search in the string STRING (with length LENGTH) for the pattern
compiled into BUFFER. Start searching at position START, for RANGE
characters. Return the starting position of the match, -1 for no
match, or -2 for an internal error. Also return register
information in REGS (if REGS and BUFFER->no_sub are nonzero). */
extern int re_search (struct re_pattern_buffer *buffer, const char *string,
int length, int start, int range,
struct re_registers *regs);
/* Like `re_search', but search in the concatenation of STRING1 and
STRING2. Also, stop searching at index START + STOP. */
extern int re_search_2 (struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, int range, struct re_registers *regs,
int stop);
/* Like `re_search', but return how many characters in STRING the regexp
in BUFFER matched, starting at position START. */
extern int re_match (struct re_pattern_buffer *buffer, const char *string,
int length, int start, struct re_registers *regs);
/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
extern int re_match_2 (struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, struct re_registers *regs, int stop);
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
ENDS. Subsequent matches using BUFFER and REGS will use this memory
for recording register information. STARTS and ENDS must be
allocated with malloc, and must each be at least `NUM_REGS * sizeof
(regoff_t)' bytes long.
If NUM_REGS == 0, then subsequent matches should allocate their own
register data.
Unless this function is called, the first search or match using
PATTERN_BUFFER will allocate its own register data, without
freeing the old data. */
extern void re_set_registers (struct re_pattern_buffer *buffer,
struct re_registers *regs,
unsigned num_regs, regoff_t *starts,
regoff_t *ends);
#if defined _REGEX_RE_COMP || defined _LIBC
# ifndef _CRAY
/* 4.2 bsd compatibility. */
extern char *re_comp (const char *);
extern int re_exec (const char *);
# endif
#endif
/* GCC 2.95 and later have "__restrict"; C99 compilers have
"restrict", and "configure" may have defined "restrict". */
#ifndef __restrict
# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
# if defined restrict || 199901L <= __STDC_VERSION__
# define __restrict restrict
# else
# define __restrict
# endif
# endif
#endif
/* GCC 3.1 and later support declaring arrays as non-overlapping
using the syntax array_name[restrict] */
#ifndef __restrict_arr
# if ! (3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) || defined (__GNUG__)
# define __restrict_arr
# else
# define __restrict_arr __restrict
# endif
#endif
/* POSIX compatibility. */
extern int regcomp (regex_t *__restrict __preg,
const char *__restrict __pattern,
int __cflags);
#if (__GNUC__)
__extension__
#endif
extern int regexec (const regex_t *__restrict __preg,
const char *__restrict __string, size_t __nmatch,
regmatch_t __pmatch[__restrict_arr],
int __eflags);
extern size_t regerror (int __errcode, const regex_t *__preg,
char *__errbuf, size_t __errbuf_size);
extern void regfree (regex_t *__preg);
#ifdef __cplusplus
}
#endif /* C++ */
#endif /* regex.h */
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/
+382
View File
@@ -0,0 +1,382 @@
/* CGEN generic assembler support code.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of libopcodes.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "sysdep.h"
#include <stdio.h>
#include <string.h>
#include "ansidecl.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "ctype.h"
//#include "bfd.h"
#include "mybfd.h"
#include "symcat.h"
#include "opcode/cgen.h"
#include "opintl.h"
static CGEN_INSN_LIST * hash_insn_array (CGEN_CPU_DESC, const CGEN_INSN *, int, int, CGEN_INSN_LIST **, CGEN_INSN_LIST *);
static CGEN_INSN_LIST * hash_insn_list (CGEN_CPU_DESC, const CGEN_INSN_LIST *, CGEN_INSN_LIST **, CGEN_INSN_LIST *);
static void build_asm_hash_table (CGEN_CPU_DESC);
/* Set the cgen_parse_operand_fn callback. */
void
cgen_set_parse_operand_fn (CGEN_CPU_DESC cd, cgen_parse_operand_fn fn)
{
cd->parse_operand_fn = fn;
}
/* Called whenever starting to parse an insn. */
void
cgen_init_parse_operand (CGEN_CPU_DESC cd)
{
/* This tells the callback to re-initialize. */
(void) (* cd->parse_operand_fn)
(cd, CGEN_PARSE_OPERAND_INIT, NULL, 0, 0, NULL, NULL);
}
/* Subroutine of build_asm_hash_table to add INSNS to the hash table.
COUNT is the number of elements in INSNS.
ENTSIZE is sizeof (CGEN_IBASE) for the target.
??? No longer used but leave in for now.
HTABLE points to the hash table.
HENTBUF is a pointer to sufficiently large buffer of hash entries.
The result is a pointer to the next entry to use.
The table is scanned backwards as additions are made to the front of the
list and we want earlier ones to be prefered. */
static CGEN_INSN_LIST *
hash_insn_array (CGEN_CPU_DESC cd,
const CGEN_INSN *insns,
int count,
int entsize ATTRIBUTE_UNUSED,
CGEN_INSN_LIST **htable,
CGEN_INSN_LIST *hentbuf)
{
int i;
for (i = count - 1; i >= 0; --i, ++hentbuf)
{
unsigned int hash;
const CGEN_INSN *insn = &insns[i];
if (! (* cd->asm_hash_p) (insn))
continue;
hash = (* cd->asm_hash) (CGEN_INSN_MNEMONIC (insn));
hentbuf->next = htable[hash];
hentbuf->insn = insn;
htable[hash] = hentbuf;
}
return hentbuf;
}
/* Subroutine of build_asm_hash_table to add INSNS to the hash table.
This function is identical to hash_insn_array except the insns are
in a list. */
static CGEN_INSN_LIST *
hash_insn_list (CGEN_CPU_DESC cd,
const CGEN_INSN_LIST *insns,
CGEN_INSN_LIST **htable,
CGEN_INSN_LIST *hentbuf)
{
const CGEN_INSN_LIST *ilist;
for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf)
{
unsigned int hash;
if (! (* cd->asm_hash_p) (ilist->insn))
continue;
hash = (* cd->asm_hash) (CGEN_INSN_MNEMONIC (ilist->insn));
hentbuf->next = htable[hash];
hentbuf->insn = ilist->insn;
htable[hash] = hentbuf;
}
return hentbuf;
}
/* Build the assembler instruction hash table. */
static void
build_asm_hash_table (CGEN_CPU_DESC cd)
{
int count = cgen_insn_count (cd) + cgen_macro_insn_count (cd);
CGEN_INSN_TABLE *insn_table = &cd->insn_table;
CGEN_INSN_TABLE *macro_insn_table = &cd->macro_insn_table;
unsigned int hash_size = cd->asm_hash_size;
CGEN_INSN_LIST *hash_entry_buf;
CGEN_INSN_LIST **asm_hash_table;
CGEN_INSN_LIST *asm_hash_table_entries;
/* The space allocated for the hash table consists of two parts:
the hash table and the hash lists. */
asm_hash_table = (CGEN_INSN_LIST **)
xmalloc (hash_size * sizeof (CGEN_INSN_LIST *));
memset (asm_hash_table, 0, hash_size * sizeof (CGEN_INSN_LIST *));
asm_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
xmalloc (count * sizeof (CGEN_INSN_LIST));
/* Add compiled in insns.
Don't include the first one as it is a reserved entry. */
/* ??? It was the end of all hash chains, and also the special
"invalid insn" marker. May be able to do it differently now. */
hash_entry_buf = hash_insn_array (cd,
insn_table->init_entries + 1,
insn_table->num_init_entries - 1,
insn_table->entry_size,
asm_hash_table, hash_entry_buf);
/* Add compiled in macro-insns. */
hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
macro_insn_table->num_init_entries,
macro_insn_table->entry_size,
asm_hash_table, hash_entry_buf);
/* Add runtime added insns.
Later added insns will be prefered over earlier ones. */
hash_entry_buf = hash_insn_list (cd, insn_table->new_entries,
asm_hash_table, hash_entry_buf);
/* Add runtime added macro-insns. */
hash_insn_list (cd, macro_insn_table->new_entries,
asm_hash_table, hash_entry_buf);
cd->asm_hash_table = asm_hash_table;
cd->asm_hash_table_entries = asm_hash_table_entries;
}
/* Return the first entry in the hash list for INSN. */
CGEN_INSN_LIST *
cgen_asm_lookup_insn (CGEN_CPU_DESC cd, const char *insn)
{
unsigned int hash;
if (cd->asm_hash_table == NULL)
build_asm_hash_table (cd);
hash = (* cd->asm_hash) (insn);
return cd->asm_hash_table[hash];
}
/* Keyword parser.
The result is NULL upon success or an error message.
If successful, *STRP is updated to point passed the keyword.
??? At present we have a static notion of how to pick out a keyword.
Later we can allow a target to customize this if necessary [say by
recording something in the keyword table]. */
const char *
cgen_parse_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
const char **strp,
CGEN_KEYWORD *keyword_table,
long *valuep)
{
const CGEN_KEYWORD_ENTRY *ke;
char buf[256];
const char *p,*start;
if (keyword_table->name_hash_table == NULL)
(void) cgen_keyword_search_init (keyword_table, NULL);
p = start = *strp;
/* Allow any first character. This is to make life easier for
the fairly common case of suffixes, eg. 'ld.b.w', where the first
character of the suffix ('.') is special. */
if (*p)
++p;
/* Allow letters, digits, and any special characters. */
while (((p - start) < (int) sizeof (buf))
&& *p
&& (ISALNUM (*p)
|| *p == '_'
|| strchr (keyword_table->nonalpha_chars, *p)))
++p;
if (p - start >= (int) sizeof (buf))
{
/* All non-empty CGEN keywords can fit into BUF. The only thing
we can match here is the empty keyword. */
buf[0] = 0;
}
else
{
memcpy (buf, start, p - start);
buf[p - start] = 0;
}
ke = cgen_keyword_lookup_name (keyword_table, buf);
if (ke != NULL)
{
*valuep = ke->value;
/* Don't advance pointer if we recognized the null keyword. */
if (ke->name[0] != 0)
*strp = p;
return NULL;
}
return "unrecognized keyword/register name";
}
/* Parse a small signed integer parser.
??? VALUEP is not a bfd_vma * on purpose, though this is confusing.
Note that if the caller expects a bfd_vma result, it should call
cgen_parse_address. */
const char *
cgen_parse_signed_integer (CGEN_CPU_DESC cd,
const char **strp,
int opindex,
long *valuep)
{
bfd_vma value;
enum cgen_parse_operand_result result;
const char *errmsg;
errmsg = (* cd->parse_operand_fn)
(cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
&result, &value);
/* FIXME: Examine `result'. */
if (!errmsg)
{
/* Handle the case where a hex value is parsed on a 64-bit host.
A value like 0xffffe000 is clearly intended to be a negative
16-bit value, but on a 64-bit host it will be parsed by gas
as 0x00000000ffffe000.
The shifts below are designed not to produce compile time
warnings on a 32-bit host. */
if (sizeof (value) > 4
&& result == CGEN_PARSE_OPERAND_RESULT_NUMBER
&& value > 0
&& (value & 0x80000000)
&& ((value >> 31) == 1))
value |= ((bfd_vma) -1) << 31;
*valuep = value;
}
return errmsg;
}
/* Parse a small unsigned integer parser.
??? VALUEP is not a bfd_vma * on purpose, though this is confusing.
Note that if the caller expects a bfd_vma result, it should call
cgen_parse_address. */
const char *
cgen_parse_unsigned_integer (CGEN_CPU_DESC cd,
const char **strp,
int opindex,
unsigned long *valuep)
{
bfd_vma value;
enum cgen_parse_operand_result result;
const char *errmsg;
errmsg = (* cd->parse_operand_fn)
(cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
&result, &value);
/* FIXME: Examine `result'. */
if (!errmsg)
*valuep = value;
return errmsg;
}
/* Address parser. */
const char *
cgen_parse_address (CGEN_CPU_DESC cd,
const char **strp,
int opindex,
int opinfo,
enum cgen_parse_operand_result *resultp,
bfd_vma *valuep)
{
bfd_vma value;
enum cgen_parse_operand_result result_type;
const char *errmsg;
errmsg = (* cd->parse_operand_fn)
(cd, CGEN_PARSE_OPERAND_ADDRESS, strp, opindex, opinfo,
&result_type, &value);
/* FIXME: Examine `result'. */
if (!errmsg)
{
if (resultp != NULL)
*resultp = result_type;
*valuep = value;
}
return errmsg;
}
/* Signed integer validation routine. */
const char *
cgen_validate_signed_integer (long value, long min, long max)
{
if (value < min || value > max)
{
static char buf[100];
/* xgettext:c-format */
sprintf (buf, _("operand out of range (%ld not between %ld and %ld)"),
value, min, max);
return buf;
}
return NULL;
}
/* Unsigned integer validation routine.
Supplying `min' here may seem unnecessary, but we also want to handle
cases where min != 0 (and max > LONG_MAX). */
const char *
cgen_validate_unsigned_integer (unsigned long value,
unsigned long min,
unsigned long max)
{
if (value < min || value > max)
{
static char buf[100];
/* xgettext:c-format */
sprintf (buf, _("operand out of range (%lu not between %lu and %lu)"),
value, min, max);
return buf;
}
return NULL;
}
+172
View File
@@ -0,0 +1,172 @@
/* CGEN generic opcode support.
Copyright (C) 2002-2018 Free Software Foundation, Inc.
This file is part of libopcodes.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* Functions for manipulating CGEN_BITSET. */
#include "libiberty.h"
#include "cgen/bitset.h"
#include <string.h>
/* Create a bit mask. */
CGEN_BITSET *
cgen_bitset_create (unsigned bit_count)
{
CGEN_BITSET * mask = xmalloc (sizeof (* mask));
cgen_bitset_init (mask, bit_count);
return mask;
}
/* Initialize an existing bit mask. */
void
cgen_bitset_init (CGEN_BITSET * mask, unsigned bit_count)
{
if (! mask)
return;
mask->length = (bit_count / 8) + 1;
mask->bits = xmalloc (mask->length);
cgen_bitset_clear (mask);
}
/* Clear the bits of a bit mask. */
void
cgen_bitset_clear (CGEN_BITSET * mask)
{
unsigned i;
if (! mask)
return;
for (i = 0; i < mask->length; ++i)
mask->bits[i] = 0;
}
/* Add a bit to a bit mask. */
void
cgen_bitset_add (CGEN_BITSET * mask, unsigned bit_num)
{
int byte_ix, bit_ix;
int bit_mask;
if (! mask)
return;
byte_ix = bit_num / 8;
bit_ix = bit_num % 8;
bit_mask = 1 << (7 - bit_ix);
mask->bits[byte_ix] |= bit_mask;
}
/* Set a bit mask. */
void
cgen_bitset_set (CGEN_BITSET * mask, unsigned bit_num)
{
if (! mask)
return;
cgen_bitset_clear (mask);
cgen_bitset_add (mask, bit_num);
}
/* Test for a bit in a bit mask.
Returns 1 if the bit is found */
int
cgen_bitset_contains (CGEN_BITSET * mask, unsigned bit_num)
{
int byte_ix, bit_ix;
int bit_mask;
if (! mask)
return 1; /* No bit restrictions. */
byte_ix = bit_num / 8;
bit_ix = 7 - (bit_num % 8);
bit_mask = 1 << bit_ix;
return (mask->bits[byte_ix] & bit_mask) >> bit_ix;
}
/* Compare two bit masks for equality.
Returns 0 if they are equal. */
int
cgen_bitset_compare (CGEN_BITSET * mask1, CGEN_BITSET * mask2)
{
if (mask1 == mask2)
return 0;
if (! mask1 || ! mask2)
return 1;
if (mask1->length != mask2->length)
return 1;
return memcmp (mask1->bits, mask2->bits, mask1->length);
}
/* Test two bit masks for common bits.
Returns 1 if a common bit is found. */
int
cgen_bitset_intersect_p (CGEN_BITSET * mask1, CGEN_BITSET * mask2)
{
unsigned i, limit;
if (mask1 == mask2)
return 1;
if (! mask1 || ! mask2)
return 0;
limit = mask1->length < mask2->length ? mask1->length : mask2->length;
for (i = 0; i < limit; ++i)
if ((mask1->bits[i] & mask2->bits[i]))
return 1;
return 0;
}
/* Make a copy of a bit mask. */
CGEN_BITSET *
cgen_bitset_copy (CGEN_BITSET * mask)
{
CGEN_BITSET* newmask;
if (! mask)
return NULL;
newmask = cgen_bitset_create ((mask->length * 8) - 1);
memcpy (newmask->bits, mask->bits, mask->length);
return newmask;
}
/* Combine two bit masks. */
void
cgen_bitset_union (CGEN_BITSET * mask1, CGEN_BITSET * mask2,
CGEN_BITSET * result)
{
unsigned i;
if (! mask1 || ! mask2 || ! result
|| mask1->length != mask2->length
|| mask1->length != result->length)
return;
for (i = 0; i < result->length; ++i)
result->bits[i] = mask1->bits[i] | mask2->bits[i];
}
+286
View File
@@ -0,0 +1,286 @@
/* CGEN generic disassembler support code.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of libopcodes.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "sysdep.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ansidecl.h"
#include "libiberty.h"
//#include "bfd.h"
#include "mybfd.h"
#include "symcat.h"
#include "opcode/cgen.h"
static CGEN_INSN_LIST * hash_insn_array (CGEN_CPU_DESC, const CGEN_INSN *, int, int, CGEN_INSN_LIST **, CGEN_INSN_LIST *);
static CGEN_INSN_LIST * hash_insn_list (CGEN_CPU_DESC, const CGEN_INSN_LIST *, CGEN_INSN_LIST **, CGEN_INSN_LIST *);
static void build_dis_hash_table (CGEN_CPU_DESC);
static int count_decodable_bits (const CGEN_INSN *);
static void add_insn_to_hash_chain (CGEN_INSN_LIST *,
const CGEN_INSN *,
CGEN_INSN_LIST **,
unsigned int);
bfd_uint64_t
bfd_get_bits (const void *p, int bits, bfd_boolean big_p)
{
const bfd_byte *addr = (const bfd_byte *) p;
bfd_uint64_t data;
int i;
int bytes;
if (bits % 8 != 0)
return 0;
data = 0;
bytes = bits / 8;
for (i = 0; i < bytes; i++)
{
int addr_index = big_p ? i : bytes - i - 1;
data = (data << 8) | addr[addr_index];
}
return data;
}
void
bfd_put_bits (bfd_uint64_t data, void *p, int bits, bfd_boolean big_p)
{
bfd_byte *addr = (bfd_byte *) p;
int i;
int bytes;
if (bits % 8 != 0)
abort ();
bytes = bits / 8;
for (i = 0; i < bytes; i++)
{
int addr_index = big_p ? bytes - i - 1 : i;
addr[addr_index] = data & 0xff;
data >>= 8;
}
}
/* Return the number of decodable bits in this insn. */
static int
count_decodable_bits (const CGEN_INSN *insn)
{
unsigned mask = CGEN_INSN_BASE_MASK (insn);
int bits = 0;
unsigned m;
for (m = 1; m != 0; m <<= 1)
{
if (mask & m)
++bits;
}
return bits;
}
/* Add an instruction to the hash chain. */
static void
add_insn_to_hash_chain (CGEN_INSN_LIST *hentbuf,
const CGEN_INSN *insn,
CGEN_INSN_LIST **htable,
unsigned int hash)
{
CGEN_INSN_LIST *current_buf;
CGEN_INSN_LIST *previous_buf;
int insn_decodable_bits;
/* Add insns sorted by the number of decodable bits, in decreasing order.
This ensures that any insn which is a special case of another will be
checked first. */
insn_decodable_bits = count_decodable_bits (insn);
previous_buf = NULL;
for (current_buf = htable[hash]; current_buf != NULL;
current_buf = current_buf->next)
{
int current_decodable_bits = count_decodable_bits (current_buf->insn);
if (insn_decodable_bits >= current_decodable_bits)
break;
previous_buf = current_buf;
}
/* Now insert the new insn. */
hentbuf->insn = insn;
hentbuf->next = current_buf;
if (previous_buf == NULL)
htable[hash] = hentbuf;
else
previous_buf->next = hentbuf;
}
/* Subroutine of build_dis_hash_table to add INSNS to the hash table.
COUNT is the number of elements in INSNS.
ENTSIZE is sizeof (CGEN_IBASE) for the target.
??? No longer used but leave in for now.
HTABLE points to the hash table.
HENTBUF is a pointer to sufficiently large buffer of hash entries.
The result is a pointer to the next entry to use.
The table is scanned backwards as additions are made to the front of the
list and we want earlier ones to be prefered. */
static CGEN_INSN_LIST *
hash_insn_array (CGEN_CPU_DESC cd,
const CGEN_INSN * insns,
int count,
int entsize ATTRIBUTE_UNUSED,
CGEN_INSN_LIST ** htable,
CGEN_INSN_LIST * hentbuf)
{
int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
int i;
for (i = count - 1; i >= 0; --i, ++hentbuf)
{
unsigned int hash;
char buf [4];
unsigned long value;
const CGEN_INSN *insn = &insns[i];
if (! (* cd->dis_hash_p) (insn))
continue;
/* We don't know whether the target uses the buffer or the base insn
to hash on, so set both up. */
value = CGEN_INSN_BASE_VALUE (insn);
bfd_put_bits ((bfd_vma) value,
buf,
CGEN_INSN_MASK_BITSIZE (insn),
big_p);
hash = (* cd->dis_hash) (buf, value);
add_insn_to_hash_chain (hentbuf, insn, htable, hash);
}
return hentbuf;
}
/* Subroutine of build_dis_hash_table to add INSNS to the hash table.
This function is identical to hash_insn_array except the insns are
in a list. */
static CGEN_INSN_LIST *
hash_insn_list (CGEN_CPU_DESC cd,
const CGEN_INSN_LIST *insns,
CGEN_INSN_LIST **htable,
CGEN_INSN_LIST *hentbuf)
{
int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
const CGEN_INSN_LIST *ilist;
for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf)
{
unsigned int hash;
char buf[4];
unsigned long value;
if (! (* cd->dis_hash_p) (ilist->insn))
continue;
/* We don't know whether the target uses the buffer or the base insn
to hash on, so set both up. */
value = CGEN_INSN_BASE_VALUE (ilist->insn);
bfd_put_bits((bfd_vma) value,
buf,
CGEN_INSN_MASK_BITSIZE (ilist->insn),
big_p);
hash = (* cd->dis_hash) (buf, value);
add_insn_to_hash_chain (hentbuf, ilist->insn, htable, hash);
}
return hentbuf;
}
/* Build the disassembler instruction hash table. */
static void
build_dis_hash_table (CGEN_CPU_DESC cd)
{
int count = cgen_insn_count (cd) + cgen_macro_insn_count (cd);
CGEN_INSN_TABLE *insn_table = & cd->insn_table;
CGEN_INSN_TABLE *macro_insn_table = & cd->macro_insn_table;
unsigned int hash_size = cd->dis_hash_size;
CGEN_INSN_LIST *hash_entry_buf;
CGEN_INSN_LIST **dis_hash_table;
CGEN_INSN_LIST *dis_hash_table_entries;
/* The space allocated for the hash table consists of two parts:
the hash table and the hash lists. */
dis_hash_table = (CGEN_INSN_LIST **)
xmalloc (hash_size * sizeof (CGEN_INSN_LIST *));
memset (dis_hash_table, 0, hash_size * sizeof (CGEN_INSN_LIST *));
dis_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
xmalloc (count * sizeof (CGEN_INSN_LIST));
/* Add compiled in insns.
Don't include the first one as it is a reserved entry. */
/* ??? It was the end of all hash chains, and also the special
"invalid insn" marker. May be able to do it differently now. */
hash_entry_buf = hash_insn_array (cd,
insn_table->init_entries + 1,
insn_table->num_init_entries - 1,
insn_table->entry_size,
dis_hash_table, hash_entry_buf);
/* Add compiled in macro-insns. */
hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
macro_insn_table->num_init_entries,
macro_insn_table->entry_size,
dis_hash_table, hash_entry_buf);
/* Add runtime added insns.
Later added insns will be prefered over earlier ones. */
hash_entry_buf = hash_insn_list (cd, insn_table->new_entries,
dis_hash_table, hash_entry_buf);
/* Add runtime added macro-insns. */
hash_insn_list (cd, macro_insn_table->new_entries,
dis_hash_table, hash_entry_buf);
cd->dis_hash_table = dis_hash_table;
cd->dis_hash_table_entries = dis_hash_table_entries;
}
/* Return the first entry in the hash list for INSN. */
CGEN_INSN_LIST *
cgen_dis_lookup_insn (CGEN_CPU_DESC cd, const char * buf, CGEN_INSN_INT value)
{
unsigned int hash;
if (cd->dis_hash_table == NULL)
build_dis_hash_table (cd);
hash = (* cd->dis_hash) (buf, value);
return cd->dis_hash_table[hash];
}
+616
View File
@@ -0,0 +1,616 @@
/* CGEN generic opcode support.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of libopcodes.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "sysdep.h"
//#include "alloca-conf.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ansidecl.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "ctype.h"
//#include "bfd.h"
#include "mybfd.h"
#include "symcat.h"
#include "opcode/cgen.h"
static unsigned int hash_keyword_name
(const CGEN_KEYWORD *, const char *, int);
static unsigned int hash_keyword_value
(const CGEN_KEYWORD *, unsigned int);
static void build_keyword_hash_tables
(CGEN_KEYWORD *);
/* Return number of hash table entries to use for N elements. */
#define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
/* Look up *NAMEP in the keyword table KT.
The result is the keyword entry or NULL if not found. */
const CGEN_KEYWORD_ENTRY *
cgen_keyword_lookup_name (CGEN_KEYWORD *kt, const char *name)
{
const CGEN_KEYWORD_ENTRY *ke;
const char *p,*n;
if (kt->name_hash_table == NULL)
build_keyword_hash_tables (kt);
ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)];
/* We do case insensitive comparisons.
If that ever becomes a problem, add an attribute that denotes
"do case sensitive comparisons". */
while (ke != NULL)
{
n = name;
p = ke->name;
while (*p
&& (*p == *n
|| (ISALPHA (*p) && (TOLOWER (*p) == TOLOWER (*n)))))
++n, ++p;
if (!*p && !*n)
return ke;
ke = ke->next_name;
}
if (kt->null_entry)
return kt->null_entry;
return NULL;
}
/* Look up VALUE in the keyword table KT.
The result is the keyword entry or NULL if not found. */
const CGEN_KEYWORD_ENTRY *
cgen_keyword_lookup_value (CGEN_KEYWORD *kt, int value)
{
const CGEN_KEYWORD_ENTRY *ke;
if (kt->name_hash_table == NULL)
build_keyword_hash_tables (kt);
ke = kt->value_hash_table[hash_keyword_value (kt, value)];
while (ke != NULL)
{
if (value == ke->value)
return ke;
ke = ke->next_value;
}
return NULL;
}
/* Add an entry to a keyword table. */
void
cgen_keyword_add (CGEN_KEYWORD *kt, CGEN_KEYWORD_ENTRY *ke)
{
unsigned int hash;
size_t i;
if (kt->name_hash_table == NULL)
build_keyword_hash_tables (kt);
hash = hash_keyword_name (kt, ke->name, 0);
ke->next_name = kt->name_hash_table[hash];
kt->name_hash_table[hash] = ke;
hash = hash_keyword_value (kt, ke->value);
ke->next_value = kt->value_hash_table[hash];
kt->value_hash_table[hash] = ke;
if (ke->name[0] == 0)
kt->null_entry = ke;
for (i = 1; i < strlen (ke->name); i++)
if (! ISALNUM (ke->name[i])
&& ! strchr (kt->nonalpha_chars, ke->name[i]))
{
size_t idx = strlen (kt->nonalpha_chars);
/* If you hit this limit, please don't just
increase the size of the field, instead
look for a better algorithm. */
if (idx >= sizeof (kt->nonalpha_chars) - 1)
abort ();
kt->nonalpha_chars[idx] = ke->name[i];
kt->nonalpha_chars[idx+1] = 0;
}
}
/* FIXME: Need function to return count of keywords. */
/* Initialize a keyword table search.
SPEC is a specification of what to search for.
A value of NULL means to find every keyword.
Currently NULL is the only acceptable value [further specification
deferred].
The result is an opaque data item used to record the search status.
It is passed to each call to cgen_keyword_search_next. */
CGEN_KEYWORD_SEARCH
cgen_keyword_search_init (CGEN_KEYWORD *kt, const char *spec)
{
CGEN_KEYWORD_SEARCH search;
/* FIXME: Need to specify format of params. */
if (spec != NULL)
abort ();
if (kt->name_hash_table == NULL)
build_keyword_hash_tables (kt);
search.table = kt;
search.spec = spec;
search.current_hash = 0;
search.current_entry = NULL;
return search;
}
/* Return the next keyword specified by SEARCH.
The result is the next entry or NULL if there are no more. */
const CGEN_KEYWORD_ENTRY *
cgen_keyword_search_next (CGEN_KEYWORD_SEARCH *search)
{
/* Has search finished? */
if (search->current_hash == search->table->hash_table_size)
return NULL;
/* Search in progress? */
if (search->current_entry != NULL
/* Anything left on this hash chain? */
&& search->current_entry->next_name != NULL)
{
search->current_entry = search->current_entry->next_name;
return search->current_entry;
}
/* Move to next hash chain [unless we haven't started yet]. */
if (search->current_entry != NULL)
++search->current_hash;
while (search->current_hash < search->table->hash_table_size)
{
search->current_entry = search->table->name_hash_table[search->current_hash];
if (search->current_entry != NULL)
return search->current_entry;
++search->current_hash;
}
return NULL;
}
/* Return first entry in hash chain for NAME.
If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
static unsigned int
hash_keyword_name (const CGEN_KEYWORD *kt,
const char *name,
int case_sensitive_p)
{
unsigned int hash;
if (case_sensitive_p)
for (hash = 0; *name; ++name)
hash = (hash * 97) + (unsigned char) *name;
else
for (hash = 0; *name; ++name)
hash = (hash * 97) + (unsigned char) TOLOWER (*name);
return hash % kt->hash_table_size;
}
/* Return first entry in hash chain for VALUE. */
static unsigned int
hash_keyword_value (const CGEN_KEYWORD *kt, unsigned int value)
{
return value % kt->hash_table_size;
}
/* Build a keyword table's hash tables.
We probably needn't build the value hash table for the assembler when
we're using the disassembler, but we keep things simple. */
static void
build_keyword_hash_tables (CGEN_KEYWORD *kt)
{
int i;
/* Use the number of compiled in entries as an estimate for the
typical sized table [not too many added at runtime]. */
unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);
kt->hash_table_size = size;
kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
/* The table is scanned backwards as we want keywords appearing earlier to
be prefered over later ones. */
for (i = kt->num_init_entries - 1; i >= 0; --i)
cgen_keyword_add (kt, &kt->init_entries[i]);
}
/* Hardware support. */
/* Lookup a hardware element by its name.
Returns NULL if NAME is not supported by the currently selected
mach/isa. */
const CGEN_HW_ENTRY *
cgen_hw_lookup_by_name (CGEN_CPU_DESC cd, const char *name)
{
unsigned int i;
const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
for (i = 0; i < cd->hw_table.num_entries; ++i)
if (hw[i] && strcmp (name, hw[i]->name) == 0)
return hw[i];
return NULL;
}
/* Lookup a hardware element by its number.
Hardware elements are enumerated, however it may be possible to add some
at runtime, thus HWNUM is not an enum type but rather an int.
Returns NULL if HWNUM is not supported by the currently selected mach. */
const CGEN_HW_ENTRY *
cgen_hw_lookup_by_num (CGEN_CPU_DESC cd, unsigned int hwnum)
{
unsigned int i;
const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
/* ??? This can be speeded up. */
for (i = 0; i < cd->hw_table.num_entries; ++i)
if (hw[i] && hwnum == hw[i]->type)
return hw[i];
return NULL;
}
/* Operand support. */
/* Lookup an operand by its name.
Returns NULL if NAME is not supported by the currently selected
mach/isa. */
const CGEN_OPERAND *
cgen_operand_lookup_by_name (CGEN_CPU_DESC cd, const char *name)
{
unsigned int i;
const CGEN_OPERAND **op = cd->operand_table.entries;
for (i = 0; i < cd->operand_table.num_entries; ++i)
if (op[i] && strcmp (name, op[i]->name) == 0)
return op[i];
return NULL;
}
/* Lookup an operand by its number.
Operands are enumerated, however it may be possible to add some
at runtime, thus OPNUM is not an enum type but rather an int.
Returns NULL if OPNUM is not supported by the currently selected
mach/isa. */
const CGEN_OPERAND *
cgen_operand_lookup_by_num (CGEN_CPU_DESC cd, int opnum)
{
return cd->operand_table.entries[opnum];
}
/* Instruction support. */
/* Return number of instructions. This includes any added at runtime. */
int
cgen_insn_count (CGEN_CPU_DESC cd)
{
int count = cd->insn_table.num_init_entries;
CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
++count;
return count;
}
/* Return number of macro-instructions.
This includes any added at runtime. */
int
cgen_macro_insn_count (CGEN_CPU_DESC cd)
{
int count = cd->macro_insn_table.num_init_entries;
CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
++count;
return count;
}
/* Cover function to read and properly byteswap an insn value. */
CGEN_INSN_INT
cgen_get_insn_value (CGEN_CPU_DESC cd, unsigned char *buf, int length)
{
int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
int insn_chunk_bitsize = cd->insn_chunk_bitsize;
CGEN_INSN_INT value = 0;
if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
{
/* We need to divide up the incoming value into insn_chunk_bitsize-length
segments, and endian-convert them, one at a time. */
int i;
/* Enforce divisibility. */
if ((length % insn_chunk_bitsize) != 0)
abort ();
for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
{
int bit_index;
bfd_vma this_value;
bit_index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
this_value = bfd_get_bits (& buf[bit_index / 8], insn_chunk_bitsize, big_p);
value = (value << insn_chunk_bitsize) | this_value;
}
}
else
{
value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
}
return value;
}
/* Cover function to store an insn value properly byteswapped. */
void
cgen_put_insn_value (CGEN_CPU_DESC cd,
unsigned char *buf,
int length,
CGEN_INSN_INT value)
{
int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
int insn_chunk_bitsize = cd->insn_chunk_bitsize;
if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
{
/* We need to divide up the incoming value into insn_chunk_bitsize-length
segments, and endian-convert them, one at a time. */
int i;
/* Enforce divisibility. */
if ((length % insn_chunk_bitsize) != 0)
abort ();
for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
{
int bit_index;
bit_index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
bfd_put_bits ((bfd_vma) value, & buf[bit_index / 8], insn_chunk_bitsize, big_p);
value >>= insn_chunk_bitsize;
}
}
else
{
bfd_put_bits ((bfd_vma) value, buf, length, big_p);
}
}
/* Look up instruction INSN_*_VALUE and extract its fields.
INSN_INT_VALUE is used if CGEN_INT_INSN_P.
Otherwise INSN_BYTES_VALUE is used.
INSN, if non-null, is the insn table entry.
Otherwise INSN_*_VALUE is examined to compute it.
LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
If INSN != NULL, LENGTH must be valid.
ALIAS_P is non-zero if alias insns are to be included in the search.
The result is a pointer to the insn table entry, or NULL if the instruction
wasn't recognized. */
/* ??? Will need to be revisited for VLIW architectures. */
const CGEN_INSN *
cgen_lookup_insn (CGEN_CPU_DESC cd,
const CGEN_INSN *insn,
CGEN_INSN_INT insn_int_value,
/* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
unsigned char *insn_bytes_value,
int length,
CGEN_FIELDS *fields,
int alias_p)
{
CGEN_EXTRACT_INFO ex_info;
CGEN_EXTRACT_INFO *info;
if (cd->int_insn_p)
{
info = NULL;
insn_bytes_value = (unsigned char *) xmalloc (cd->max_insn_bitsize / 8);
cgen_put_insn_value (cd, insn_bytes_value, length, insn_int_value);
}
else
{
info = &ex_info;
ex_info.dis_info = NULL;
ex_info.insn_bytes = insn_bytes_value;
ex_info.valid = -1;
insn_int_value = cgen_get_insn_value (cd, insn_bytes_value, length);
}
if (!insn)
{
const CGEN_INSN_LIST *insn_list;
/* The instructions are stored in hash lists.
Pick the first one and keep trying until we find the right one. */
insn_list = cgen_dis_lookup_insn (cd, (char *) insn_bytes_value,
insn_int_value);
while (insn_list != NULL)
{
insn = insn_list->insn;
if (alias_p
/* FIXME: Ensure ALIAS attribute always has same index. */
|| ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
{
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the
extract handler. */
if ((insn_int_value & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
/* ??? 0 is passed for `pc' */
int elength = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, info, insn_int_value, fields, (bfd_vma) 0);
if (elength > 0)
{
/* sanity check */
if (length != 0 && length != elength)
abort ();
break;
}
}
}
insn_list = insn_list->next;
}
}
else
{
/* Sanity check: can't pass an alias insn if ! alias_p. */
if (! alias_p
&& CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
abort ();
/* Sanity check: length must be correct. */
if (length != CGEN_INSN_BITSIZE (insn))
abort ();
/* ??? 0 is passed for `pc' */
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, info, insn_int_value, fields, (bfd_vma) 0);
/* Sanity check: must succeed.
Could relax this later if it ever proves useful. */
if (length == 0)
abort ();
}
if (cd->int_insn_p)
free (insn_bytes_value);
return insn;
}
/* Fill in the operand instances used by INSN whose operands are FIELDS.
INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
in. */
void
cgen_get_insn_operands (CGEN_CPU_DESC cd,
const CGEN_INSN *insn,
const CGEN_FIELDS *fields,
int *indices)
{
const CGEN_OPINST *opinst;
int i;
if (insn->opinst == NULL)
abort ();
for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
{
enum cgen_operand_type op_type = opinst->op_type;
if (op_type == CGEN_OPERAND_NIL)
indices[i] = opinst->index;
else
indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
}
}
/* Cover function to cgen_get_insn_operands when either INSN or FIELDS
isn't known.
The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
cgen_lookup_insn unchanged.
INSN_INT_VALUE is used if CGEN_INT_INSN_P.
Otherwise INSN_BYTES_VALUE is used.
The result is the insn table entry or NULL if the instruction wasn't
recognized. */
const CGEN_INSN *
cgen_lookup_get_insn_operands (CGEN_CPU_DESC cd,
const CGEN_INSN *insn,
CGEN_INSN_INT insn_int_value,
/* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
unsigned char *insn_bytes_value,
int length,
int *indices,
CGEN_FIELDS *fields)
{
/* Pass non-zero for ALIAS_P only if INSN != NULL.
If INSN == NULL, we want a real insn. */
insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
length, fields, insn != NULL);
if (! insn)
return NULL;
cgen_get_insn_operands (cd, insn, fields, indices);
return insn;
}
/* Allow signed overflow of instruction fields. */
void
cgen_set_signed_overflow_ok (CGEN_CPU_DESC cd)
{
cd->signed_overflow_ok_p = 1;
}
/* Generate an error message if a signed field in an instruction overflows. */
void
cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd)
{
cd->signed_overflow_ok_p = 0;
}
/* Will an error message be generated if a signed field in an instruction overflows ? */
unsigned int
cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd)
{
return cd->signed_overflow_ok_p;
}
+89
View File
@@ -0,0 +1,89 @@
/* BFD support for the NIOS processor.
Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
//#include "bfd.h"
#include "mybfd.h"
#include "sysdep.h"
//#include "libbfd.h"
static int
bfd_default_scan (info, string)
const bfd_arch_info_type *info;
const char *string;
{
return 1;
}
static const bfd_arch_info_type *
bfd_default_compatible (a, b)
const bfd_arch_info_type *a;
const bfd_arch_info_type *b;
{
if (a->arch != b->arch)
return NULL;
if (a->bits_per_word != b->bits_per_word)
return NULL;
if (a->mach > b->mach) {
return a;
} else {
return b;
}
}
static const bfd_arch_info_type arch_info_struct[] =
{
{
32, /* bits per word */
32, /* bits per address */
8, /* bits per byte */
bfd_arch_nios, /* architecture */
bfd_mach_nios32, /* machine */
"nios", /* architecture name */
"nios32", /* printable name */
4, /* section align power */
false, /* the default ? */
bfd_default_compatible, /* architecture comparison fn */
bfd_default_scan, /* string to architecture convert fn */
NULL, /* next in list */
}
};
const bfd_arch_info_type bfd_nios_arch =
{
16, /* bits per word */
16, /* bits per address */
8, /* bits per byte */
bfd_arch_nios, /* architecture */
bfd_mach_nios16, /* machine */
"nios", /* architecture name */
"nios16", /* printable name */
4, /* section align power */
true, /* the default ? */
bfd_default_compatible, /* architecture comparison fn */
bfd_default_scan, /* string to architecture convert fn */
&arch_info_struct[0], /* next in list */
};
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+315
View File
@@ -0,0 +1,315 @@
/* CPU data header for nios.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef NIOS_CPU_H
#define NIOS_CPU_H
#ifdef __cplusplus
extern "C" {
#endif
#define CGEN_ARCH nios
/* Given symbol S, return nios_cgen_<S>. */
#define CGEN_SYM(s) nios##_cgen_##s
/* Selected cpu families. */
#define HAVE_CPU_NIOS16BF
#define HAVE_CPU_NIOS32BF
#define CGEN_INSN_LSB0_P 1
/* Minimum size of any insn (in bytes). */
#define CGEN_MIN_INSN_SIZE 2
/* Maximum size of any insn (in bytes). */
#define CGEN_MAX_INSN_SIZE 2
#define CGEN_INT_INSN_P 1
/* Maximum number of syntax elements in an instruction. */
#define CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 16
/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands.
e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands
we can't hash on everything up to the space. */
#define CGEN_MNEMONIC_OPERANDS
/* Maximum number of fields in an instruction. */
#define CGEN_ACTUAL_MAX_IFMT_OPERANDS 4
/* Enums. */
/* Enum declaration for insn op6 enums. */
typedef enum insn_op6 {
OP_ADD = 0, OP_ADDI = 1, OP_SUB = 2, OP_SUBI = 3
, OP_CMP = 4, OP_CMPI = 5, OP_LSL = 6, OP_LSLI = 7
, OP_LSR = 8, OP_LSRI = 9, OP_ASR = 10, OP_ASRI = 11
, OP_MOV = 12, OP_MOVI = 13, OP_AND = 14, OP_ANDN = 15
, OP_OR = 16, OP_XOR = 17, OP_BGEN = 18, OP_EXT8D = 19
, OP_SKP0 = 20, OP_SKP1 = 21, OP_LD = 22, OP_ST = 23
, OP_STS8S = 24, OP_STS16S = 25, OP_ADDC = 26, OP_EXT16D = 26
, OP_SUBC = 27, OP_MOVHI = 27, OP_USR0 = 28
} INSN_OP6;
/* Enum declaration for insn pfx enum. */
typedef enum insn_pfx_hi {
OP_PFX_HI = 19
} INSN_PFX_HI;
/* Enum declaration for insn op3 enums. */
typedef enum insn_op3 {
OP_STS = 6, OP_LDS = 7
} INSN_OP3;
/* Enum declaration for insn op4 enums. */
typedef enum insn_op4 {
OP_STP = 10, OP_LDP = 11
} INSN_OP4;
/* Enum declaration for insn op5 enums. */
typedef enum insn_op5 {
OP_BR = 16, OP_BSR = 17, OP_PFXIO = 18, OP_PFX = 19
} INSN_OP5;
/* Enum declaration for insn op8 enums. */
typedef enum insn_op8 {
OP_SAVE = 120, OP_TRAP = 121, OP_JMPC = 122, OP_CALLC = 123
} INSN_OP8;
/* Enum declaration for insn op9 enums. */
typedef enum insn_op9 {
OP_EXT8S = 232, OP_EXT16S = 233, OP_ST8S = 236, OP_ST16S = 237
} INSN_OP9;
/* Enum declaration for insn op11 enums. */
typedef enum insn_op11 {
OP_NOT = 992, OP_NEG = 993, OP_ABS = 994, OP_SEXT8 = 995
, OP_SEXT16 = 996, OP_RLC = 997, OP_RRC = 998, OP_TRET = 1006
, OP_RESTORE = 1005, OP_ST8D = 1008, OP_ST16D = 1009, OP_FILL8 = 1010
, OP_FILL16 = 1011, OP_LDM = 1012, OP_STM = 1013, OP_SKPRZ = 1014
, OP_SKPS = 1015, OP_WRCTL = 1016, OP_RDCTL = 1017, OP_SKPRNZ = 1018
, OP_JMP = 1022, OP_CALL = 1023, OP_SWAP = 1000, OP_USR1 = 1001
, OP_USR2 = 1002, OP_USR3 = 1003, OP_USR4 = 1004, OP_MSTEP = 1012
, OP_MUL = 1013
} INSN_OP11;
/* Enum declaration for . */
typedef enum ctl_names {
H_CTL__CTL0 = 0, H_CTL__CTL1 = 1, H_CTL__CTL2 = 2, H_CTL__CTL3 = 3
, H_CTL__CTL4 = 4, H_CTL__CTL5 = 5, H_CTL__STATUS = 0, H_CTL__ISTATUS = 1
, H_CTL__WVALID = 2, H_CTL__CD_BANK = 3, H_CTL__ST_BANK = 4, H_CTL__LD_BANK = 5
} CTL_NAMES;
/* Enum declaration for . */
typedef enum gr_names {
H_GR__SP = 14, H_GR__FP = 30, H_GR__G0 = 0, H_GR__G1 = 1
, H_GR__G2 = 2, H_GR__G3 = 3, H_GR__G4 = 4, H_GR__G5 = 5
, H_GR__G6 = 6, H_GR__G7 = 7, H_GR__R0 = 0, H_GR__R1 = 1
, H_GR__R2 = 2, H_GR__R3 = 3, H_GR__R4 = 4, H_GR__R5 = 5
, H_GR__R6 = 6, H_GR__R7 = 7, H_GR__O0 = 8, H_GR__O1 = 9
, H_GR__O2 = 10, H_GR__O3 = 11, H_GR__O4 = 12, H_GR__O5 = 13
, H_GR__O6 = 14, H_GR__O7 = 15, H_GR__R8 = 8, H_GR__R9 = 9
, H_GR__R10 = 10, H_GR__R11 = 11, H_GR__R12 = 12, H_GR__R13 = 13
, H_GR__R14 = 14, H_GR__R15 = 15, H_GR__L0 = 16, H_GR__L1 = 17
, H_GR__L2 = 18, H_GR__L3 = 19, H_GR__L4 = 20, H_GR__L5 = 21
, H_GR__L6 = 22, H_GR__L7 = 23, H_GR__R16 = 16, H_GR__R17 = 17
, H_GR__R18 = 18, H_GR__R19 = 19, H_GR__R20 = 20, H_GR__R21 = 21
, H_GR__R22 = 22, H_GR__R23 = 23, H_GR__I0 = 24, H_GR__I1 = 25
, H_GR__I2 = 26, H_GR__I3 = 27, H_GR__I4 = 28, H_GR__I5 = 29
, H_GR__I6 = 30, H_GR__I7 = 31, H_GR__R24 = 24, H_GR__R25 = 25
, H_GR__R26 = 26, H_GR__R27 = 27, H_GR__R28 = 28, H_GR__R29 = 29
, H_GR__R30 = 30, H_GR__R31 = 31
} GR_NAMES;
/* Enum declaration for . */
typedef enum gr0_name {
H_GR0__R0
} GR0_NAME;
/* Enum declaration for . */
typedef enum bp_names {
H_BP__L0 = 0, H_BP__L1 = 1, H_BP__L2 = 2, H_BP__L3 = 3
, H_BP__R16 = 0, H_BP__R17 = 1, H_BP__R18 = 2, H_BP__R19 = 3
} BP_NAMES;
/* Attributes. */
/* Enum declaration for machine type selection. */
typedef enum mach_attr {
MACH_BASE, MACH_NIOS16, MACH_NIOS32, MACH_MAX
} MACH_ATTR;
/* Enum declaration for instruction set selection. */
typedef enum isa_attr {
ISA_NIOS, ISA_MAX
} ISA_ATTR;
/* Number of architecture variants. */
#define MAX_ISAS 1
#define MAX_MACHS ((int) MACH_MAX)
/* Ifield support. */
/* Ifield attribute indices. */
/* Enum declaration for cgen_ifld attrs. */
typedef enum cgen_ifld_attr {
CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED
, CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_END_BOOLS, CGEN_IFLD_START_NBOOLS = 31
, CGEN_IFLD_MACH, CGEN_IFLD_END_NBOOLS
} CGEN_IFLD_ATTR;
/* Number of non-boolean elements in cgen_ifld_attr. */
#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1)
/* Enum declaration for nios ifield types. */
typedef enum ifield_type {
NIOS_F_NIL, NIOS_F_ANYOF, NIOS_F_OP6, NIOS_F_OP3
, NIOS_F_OP4, NIOS_F_OP5, NIOS_F_OP5_HI, NIOS_F_OP8
, NIOS_F_OP9, NIOS_F_OP11, NIOS_F_RA, NIOS_F_RB
, NIOS_F_RBI5, NIOS_F_RZ, NIOS_F_RP, NIOS_F_CTLC
, NIOS_F_I2, NIOS_F_I4W, NIOS_F_X1, NIOS_F_O1
, NIOS_F_O2, NIOS_F_I5, NIOS_F_I6V, NIOS_F_I8
, NIOS_F_I8V, NIOS_F_I9, NIOS_F_I10, NIOS_F_I11
, NIOS_F_I6_REL_H, NIOS_F_I6_REL_W, NIOS_F_BSRR_I6_REL, NIOS_F_I8V_REL_H
, NIOS_F_I8V_REL_W, NIOS_F_I11_REL, NIOS_F_I1, NIOS_F_MAX
} IFIELD_TYPE;
#define MAX_IFLD ((int) NIOS_F_MAX)
/* Hardware attribute indices. */
/* Enum declaration for cgen_hw attrs. */
typedef enum cgen_hw_attr {
CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE
, CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH, CGEN_HW_END_NBOOLS
} CGEN_HW_ATTR;
/* Number of non-boolean elements in cgen_hw_attr. */
#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1)
/* Enum declaration for nios hardware types. */
typedef enum cgen_hw_type {
HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR
, HW_H_IADDR, HW_H_PC, HW_H_CWP, HW_H_OLD_CWP
, HW_H_IPRI, HW_H_ZERO, HW_H_TEBIT, HW_H_NBIT
, HW_H_ZBIT, HW_H_VBIT, HW_H_CBIT, HW_H_PBIT
, HW_H_SBIT, HW_H_WBIT, HW_H_STATUS, HW_H_K
, HW_H_M16_GR, HW_H_M16_GR0, HW_H_M16_BP, HW_H_M16_RZ
, HW_H_M16_SP, HW_H_M16_CTL, HW_H_M32_GR, HW_H_M32_GR0
, HW_H_M32_BP, HW_H_M32_RZ, HW_H_M32_SP, HW_H_M32_CTL
, HW_MAX
} CGEN_HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Operand attribute indices. */
/* Enum declaration for cgen_operand attrs. */
typedef enum cgen_operand_attr {
CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT
, CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY
, CGEN_OPERAND_HASH_PREFIX, CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31, CGEN_OPERAND_MACH
, CGEN_OPERAND_END_NBOOLS
} CGEN_OPERAND_ATTR;
/* Number of non-boolean elements in cgen_operand_attr. */
#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1)
/* Enum declaration for nios operand types. */
typedef enum cgen_operand_type {
NIOS_OPERAND_PC, NIOS_OPERAND_K, NIOS_OPERAND_CTLC, NIOS_OPERAND_XRA
, NIOS_OPERAND_X1, NIOS_OPERAND_O1, NIOS_OPERAND_O2, NIOS_OPERAND_I1
, NIOS_OPERAND_I2, NIOS_OPERAND_SI5, NIOS_OPERAND_I8, NIOS_OPERAND_I8V
, NIOS_OPERAND_I6V, NIOS_OPERAND_SI11, NIOS_OPERAND_REL11, NIOS_OPERAND_BSRR_REL6
, NIOS_OPERAND_NBIT, NIOS_OPERAND_VBIT, NIOS_OPERAND_ZBIT, NIOS_OPERAND_CBIT
, NIOS_OPERAND_TEBIT, NIOS_OPERAND_PBIT, NIOS_OPERAND_SBIT, NIOS_OPERAND_WBIT
, NIOS_OPERAND_I4W, NIOS_OPERAND_I4WN, NIOS_OPERAND_I5, NIOS_OPERAND_SAVE_I8V
, NIOS_OPERAND_I11, NIOS_OPERAND_I10, NIOS_OPERAND_I9, NIOS_OPERAND_I16
, NIOS_OPERAND_I32, NIOS_OPERAND_RBI5, NIOS_OPERAND_M16_RA, NIOS_OPERAND_M16_RB
, NIOS_OPERAND_M16_R0, NIOS_OPERAND_M16_SP, NIOS_OPERAND_M16_RP, NIOS_OPERAND_M16_RZ
, NIOS_OPERAND_M16_I6, NIOS_OPERAND_M16_I8V, NIOS_OPERAND_M32_RA, NIOS_OPERAND_M32_RB
, NIOS_OPERAND_M32_R0, NIOS_OPERAND_M32_SP, NIOS_OPERAND_M32_RP, NIOS_OPERAND_M32_RZ
, NIOS_OPERAND_M32_I6, NIOS_OPERAND_M32_I8V, NIOS_OPERAND_MAX
} CGEN_OPERAND_TYPE;
/* Number of operands types. */
#define MAX_OPERANDS ((int) NIOS_OPERAND_MAX)
/* Maximum number of operands referenced by any insn. */
#define MAX_OPERAND_INSTANCES 8
/* Insn attribute indices. */
/* Enum declaration for cgen_insn attrs. */
typedef enum cgen_insn_attr {
CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI
, CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAXED
, CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_PREFIX, CGEN_INSN_PREFIXED_INSN
, CGEN_INSN_SKIP_INSN, CGEN_INSN_DUAL_MODE, CGEN_INSN_END_BOOLS, CGEN_INSN_START_NBOOLS = 31
, CGEN_INSN_MACH, CGEN_INSN_END_NBOOLS
} CGEN_INSN_ATTR;
/* Number of non-boolean elements in cgen_insn_attr. */
#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1)
/* cgen.h uses things we just defined. */
#include "opcode/cgen.h"
extern const struct cgen_ifld nios_cgen_ifld_table[];
/* Attributes. */
extern const CGEN_ATTR_TABLE nios_cgen_hardware_attr_table[];
extern const CGEN_ATTR_TABLE nios_cgen_ifield_attr_table[];
extern const CGEN_ATTR_TABLE nios_cgen_operand_attr_table[];
extern const CGEN_ATTR_TABLE nios_cgen_insn_attr_table[];
/* Hardware decls. */
extern CGEN_KEYWORD nios_cgen_opval_gr_names;
extern CGEN_KEYWORD nios_cgen_opval_h_m16_gr0;
extern CGEN_KEYWORD nios_cgen_opval_bp_names;
extern CGEN_KEYWORD nios_cgen_opval_gr_names;
extern CGEN_KEYWORD nios_cgen_opval_h_m16_sp;
extern CGEN_KEYWORD nios_cgen_opval_ctl_names;
extern CGEN_KEYWORD nios_cgen_opval_gr_names;
extern CGEN_KEYWORD nios_cgen_opval_gr0_name;
extern CGEN_KEYWORD nios_cgen_opval_bp_names;
extern CGEN_KEYWORD nios_cgen_opval_gr_names;
extern CGEN_KEYWORD nios_cgen_opval_h_m32_sp;
extern CGEN_KEYWORD nios_cgen_opval_ctl_names;
extern const CGEN_HW_ENTRY nios_cgen_hw_table[];
#ifndef opcodes_error_handler
#define opcodes_error_handler(...) \
fprintf (stderr, __VA_ARGS__); fputc ('\n', stderr)
#endif
#ifdef __cplusplus
}
#endif
#endif /* NIOS_CPU_H */
+791
View File
@@ -0,0 +1,791 @@
/* Altera Nios disassemble routines
Copyright (C) 2012-2018 Free Software Foundation, Inc.
THIS FILE IS MACHINE GENERATED WITH CGEN.
- the resultant file is machine generated, cgen-dis.in isn't
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of libopcodes.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
Keep that in mind. */
#include "sysdep.h"
#include <stdio.h>
#include <stdlib.h>
#include "ansidecl.h"
#include "dis-asm.h"
//#include "bfd.h"
#include "mybfd.h"
#include "symcat.h"
#include "libiberty.h"
#include "nios-desc.h"
#include "nios-opc.h"
#include "opintl.h"
extern const bfd_arch_info_type bfd_nios_arch;
const bfd_arch_info_type *
bfd_lookup_arch (enum bfd_architecture arch, unsigned long machine)
{
if (arch != bfd_arch_nios) {
return NULL;
}
if (machine == MACH_NIOS16) {
return &bfd_nios_arch;
} else if (machine == MACH_NIOS32) {
return bfd_nios_arch.next;
} else {
return NULL;
}
}
/* Default text to print if an instruction isn't recognized. */
#define UNKNOWN_INSN_MSG _("*unknown*")
static void print_normal
(CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
static void print_address
(CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
static void print_keyword
(CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
static void print_insn_normal
(CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
static int print_insn
(CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned);
static int default_print_insn
(CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
static int read_insn
(CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
unsigned long *);
/* -- disassembler routines inserted here. */
/* -- dis.c */
/* Include "%hi(foo) in output. */
ATTRIBUTE_UNUSED static void
print_Rbi5 (CGEN_CPU_DESC cd, void *dis_info, long value, unsigned int attrs, bfd_vma pc, int length)
{
int status;
bfd_byte buf[2];
unsigned long insn_value;
const CGEN_INSN_LIST *insn_list;
disassemble_info *info = (disassemble_info *) dis_info;
/* look at previous instruction, if possible, to see if it is PFX */
if (pc > 0)
{
status = (*info->read_memory_func) (pc - 2, buf, 2, info);
if (status != 0)
{
print_keyword (cd, info, & nios_cgen_opval_gr_names, value, 0);
return;
}
insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
while (insn_list != NULL)
{
const CGEN_INSN *insn = insn_list->insn;
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
if ((insn_value & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_PREFIX))
(*info->fprintf_func) (info->stream, "0x%lx", value);
else
print_keyword (cd, info, & nios_cgen_opval_gr_names, value, 0);
return;
}
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
}
}
print_keyword (cd, info, & nios_cgen_opval_gr_names, value, 0);
}
ATTRIBUTE_UNUSED static void
print_i11 (CGEN_CPU_DESC cd, void *dis_info, long value, unsigned int attrs, bfd_vma pc, int length)
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "hi(0x%lx)", value << 5);
}
ATTRIBUTE_UNUSED static void
print_r0 (CGEN_CPU_DESC cd, void *dis_info, long value, unsigned int attrs, bfd_vma pc, int length)
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "g0");
}
ATTRIBUTE_UNUSED static void
print_i16 (CGEN_CPU_DESC cd, void *dis_info, long value, unsigned int attrs, bfd_vma pc, int length)
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "#0x%hx)", (short)value);
}
ATTRIBUTE_UNUSED static void
print_i32 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
void *dis_info,
long value,
unsigned int attrs,
bfd_vma pc,
int length)
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "#0x%lx)", value);
}
ATTRIBUTE_UNUSED static void
print_i4w (CGEN_CPU_DESC cd, void *dis_info, long value, unsigned int attrs, bfd_vma pc, int length)
{
char *str;
disassemble_info *info = (disassemble_info *) dis_info;
switch (value)
{
case CC_Z:
str = "cc_eq";
break;
case CC_NZ:
str = "cc_ne";
break;
case CC_C:
str = "cc_c";
break;
case CC_NC:
str = "cc_nc";
break;
case CC_V:
str = "cc_v";
break;
case CC_NV:
str = "cc_nv";
break;
case CC_GT:
str = "cc_gt";
break;
case CC_GE:
str = "cc_ge";
break;
case CC_LT:
str = "cc_lt";
break;
case CC_LE:
str = "cc_le";
break;
case CC_LS:
str = "cc_ls";
break;
case CC_HI:
str = "cc_hi";
break;
case CC_PL:
str = "cc_pl";
break;
case CC_MI:
str = "cc_mi";
break;
}
if (str != NULL)
(*info->fprintf_func) (info->stream, "%s", str);
else
(*info->fprintf_func) (info->stream, "0x%lx", value);
}
/* -- */
void nios_cgen_print_operand
(CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int);
/* Main entry point for printing operands.
XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
of dis-asm.h on cgen.h.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers. */
void
nios_cgen_print_operand (CGEN_CPU_DESC cd,
int opindex,
void * xinfo,
CGEN_FIELDS *fields,
void const *attrs ATTRIBUTE_UNUSED,
bfd_vma pc,
int length)
{
disassemble_info *info = (disassemble_info *) xinfo;
switch (opindex)
{
case NIOS_OPERAND_CTLC :
print_normal (cd, info, fields->f_CTLc, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_RBI5 :
print_Rbi5 (cd, info, fields->f_Rbi5, 0, pc, length);
break;
case NIOS_OPERAND_BSRR_REL6 :
print_address (cd, info, fields->f_bsrr_i6_rel, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case NIOS_OPERAND_I1 :
print_normal (cd, info, fields->f_i1, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I10 :
print_normal (cd, info, fields->f_i10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I11 :
print_i11 (cd, info, fields->f_i11, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I2 :
print_normal (cd, info, fields->f_i2, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I4W :
print_i4w (cd, info, fields->f_i4w, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I4WN :
print_i4w (cd, info, fields->f_i4w, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I5 :
print_normal (cd, info, fields->f_i5, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I6V :
print_normal (cd, info, fields->f_i6v, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I8 :
print_normal (cd, info, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I8V :
print_normal (cd, info, fields->f_i8v, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_I9 :
print_normal (cd, info, fields->f_i9, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_M16_R0 :
print_keyword (cd, info, & nios_cgen_opval_h_m16_gr0, 0, 0);
break;
case NIOS_OPERAND_M16_RA :
print_keyword (cd, info, & nios_cgen_opval_gr_names, fields->f_Ra, 0);
break;
case NIOS_OPERAND_M16_RB :
print_keyword (cd, info, & nios_cgen_opval_gr_names, fields->f_Rb, 0);
break;
case NIOS_OPERAND_M16_RP :
print_keyword (cd, info, & nios_cgen_opval_bp_names, fields->f_Rp, 0);
break;
case NIOS_OPERAND_M16_RZ :
print_keyword (cd, info, & nios_cgen_opval_gr_names, fields->f_Rz, 0);
break;
case NIOS_OPERAND_M16_I6 :
print_address (cd, info, fields->f_i6_rel_h, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case NIOS_OPERAND_M16_I8V :
print_address (cd, info, fields->f_i8v_rel_h, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case NIOS_OPERAND_M16_SP :
print_keyword (cd, info, & nios_cgen_opval_h_m16_sp, 0, 0);
break;
case NIOS_OPERAND_M32_R0 :
print_keyword (cd, info, & nios_cgen_opval_gr0_name, 0, 0);
break;
case NIOS_OPERAND_M32_RA :
print_keyword (cd, info, & nios_cgen_opval_gr_names, fields->f_Ra, 0);
break;
case NIOS_OPERAND_M32_RB :
print_keyword (cd, info, & nios_cgen_opval_gr_names, fields->f_Rb, 0);
break;
case NIOS_OPERAND_M32_RP :
print_keyword (cd, info, & nios_cgen_opval_bp_names, fields->f_Rp, 0);
break;
case NIOS_OPERAND_M32_RZ :
print_keyword (cd, info, & nios_cgen_opval_gr_names, fields->f_Rz, 0);
break;
case NIOS_OPERAND_M32_I6 :
print_address (cd, info, fields->f_i6_rel_w, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case NIOS_OPERAND_M32_I8V :
print_address (cd, info, fields->f_i8v_rel_w, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case NIOS_OPERAND_M32_SP :
print_keyword (cd, info, & nios_cgen_opval_h_m32_sp, 0, 0);
break;
case NIOS_OPERAND_O1 :
print_normal (cd, info, fields->f_o1, 0, pc, length);
break;
case NIOS_OPERAND_O2 :
print_normal (cd, info, fields->f_o2, 0, pc, length);
break;
case NIOS_OPERAND_REL11 :
print_address (cd, info, fields->f_i11_rel, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case NIOS_OPERAND_SAVE_I8V :
print_normal (cd, info, fields->f_i8v, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_SI11 :
print_normal (cd, info, fields->f_i11, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_SI5 :
print_normal (cd, info, fields->f_i5, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case NIOS_OPERAND_X1 :
print_normal (cd, info, fields->f_x1, 0, pc, length);
break;
case NIOS_OPERAND_XRA :
print_normal (cd, info, fields->f_Ra, 0, pc, length);
break;
default :
/* xgettext:c-format */
opcodes_error_handler
(_("internal error: unrecognized field %d while printing insn"),
opindex);
abort ();
}
}
cgen_print_fn * const nios_cgen_print_handlers[] =
{
print_insn_normal,
};
void
nios_cgen_init_dis (CGEN_CPU_DESC cd)
{
nios_cgen_init_opcode_table (cd);
nios_cgen_init_ibld_table (cd);
cd->print_handlers = & nios_cgen_print_handlers[0];
cd->print_operand = nios_cgen_print_operand;
}
/* Default print handler. */
static void
print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
void *dis_info,
long value,
unsigned int attrs,
bfd_vma pc ATTRIBUTE_UNUSED,
int length ATTRIBUTE_UNUSED)
{
disassemble_info *info = (disassemble_info *) dis_info;
/* Print the operand as directed by the attributes. */
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
; /* nothing to do */
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
(*info->fprintf_func) (info->stream, "%ld", value);
else
(*info->fprintf_func) (info->stream, "0x%lx", value);
}
/* Default address handler. */
static void
print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
void *dis_info,
bfd_vma value,
unsigned int attrs,
bfd_vma pc ATTRIBUTE_UNUSED,
int length ATTRIBUTE_UNUSED)
{
disassemble_info *info = (disassemble_info *) dis_info;
/* Print the operand as directed by the attributes. */
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
; /* Nothing to do. */
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
(*info->print_address_func) (value, info);
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
(*info->print_address_func) (value, info);
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
(*info->fprintf_func) (info->stream, "%ld", (long) value);
else
(*info->fprintf_func) (info->stream, "0x%lx", (long) value);
}
/* Keyword print handler. */
static void
print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
void *dis_info,
CGEN_KEYWORD *keyword_table,
long value,
unsigned int attrs ATTRIBUTE_UNUSED)
{
disassemble_info *info = (disassemble_info *) dis_info;
const CGEN_KEYWORD_ENTRY *ke;
ke = cgen_keyword_lookup_value (keyword_table, value);
if (ke != NULL)
(*info->fprintf_func) (info->stream, "%s", ke->name);
else
(*info->fprintf_func) (info->stream, "???");
}
/* Default insn printer.
DIS_INFO is defined as `void *' so the disassembler needn't know anything
about disassemble_info. */
static void
print_insn_normal (CGEN_CPU_DESC cd,
void *dis_info,
const CGEN_INSN *insn,
CGEN_FIELDS *fields,
bfd_vma pc,
int length)
{
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
disassemble_info *info = (disassemble_info *) dis_info;
const CGEN_SYNTAX_CHAR_TYPE *syn;
CGEN_INIT_PRINT (cd);
for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
{
if (CGEN_SYNTAX_MNEMONIC_P (*syn))
{
(*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
continue;
}
if (CGEN_SYNTAX_CHAR_P (*syn))
{
(*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
continue;
}
/* We have an operand. */
nios_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
fields, CGEN_INSN_ATTRS (insn), pc, length);
}
}
/* Subroutine of print_insn. Reads an insn into the given buffers and updates
the extract info.
Returns 0 if all is well, non-zero otherwise. */
static int
read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
bfd_vma pc,
disassemble_info *info,
bfd_byte *buf,
int buflen,
CGEN_EXTRACT_INFO *ex_info,
unsigned long *insn_value)
{
int status = (*info->read_memory_func) (pc, buf, buflen, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
ex_info->dis_info = info;
ex_info->valid = (1 << buflen) - 1;
ex_info->insn_bytes = buf;
*insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
return 0;
}
/* Utility to print an insn.
BUF is the base part of the insn, target byte order, BUFLEN bytes long.
The result is the size of the insn in bytes or zero for an unknown insn
or -1 if an error occurs fetching data (memory_error_func will have
been called). */
static int
print_insn (CGEN_CPU_DESC cd,
bfd_vma pc,
disassemble_info *info,
bfd_byte *buf,
unsigned int buflen)
{
CGEN_INSN_INT insn_value;
const CGEN_INSN_LIST *insn_list;
CGEN_EXTRACT_INFO ex_info;
int basesize;
/* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
basesize = cd->base_insn_bitsize < buflen * 8 ?
cd->base_insn_bitsize : buflen * 8;
insn_value = cgen_get_insn_value (cd, buf, basesize);
/* Fill in ex_info fields like read_insn would. Don't actually call
read_insn, since the incoming buffer is already read (and possibly
modified a la m32r). */
ex_info.valid = (1 << buflen) - 1;
ex_info.dis_info = info;
ex_info.insn_bytes = buf;
/* The instructions are stored in hash lists.
Pick the first one and keep trying until we find the right one. */
insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
while (insn_list != NULL)
{
const CGEN_INSN *insn = insn_list->insn;
CGEN_FIELDS fields;
int length;
unsigned long insn_value_cropped;
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
/* Not needed as insn shouldn't be in hash lists if not supported. */
/* Supported by this cpu? */
if (! nios_cgen_insn_supported (cd, insn))
{
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
continue;
}
#endif
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
/* Base size may exceed this instruction's size. Extract the
relevant part from the buffer. */
if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
(unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
info->endian == BFD_ENDIAN_BIG);
else
insn_value_cropped = insn_value;
if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
/* Printing is handled in two passes. The first pass parses the
machine insn and extracts the fields. The second pass prints
them. */
/* Make sure the entire insn is loaded into insn_value, if it
can fit. */
if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
(unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
{
unsigned long full_insn_value;
int rc = read_insn (cd, pc, info, buf,
CGEN_INSN_BITSIZE (insn) / 8,
& ex_info, & full_insn_value);
if (rc != 0)
return rc;
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, full_insn_value, &fields, pc);
}
else
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, insn_value_cropped, &fields, pc);
/* Length < 0 -> error. */
if (length < 0)
return length;
if (length > 0)
{
CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
/* Length is in bits, result is in bytes. */
return length / 8;
}
}
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
}
return 0;
}
/* Default value for CGEN_PRINT_INSN.
The result is the size of the insn in bytes or zero for an unknown insn
or -1 if an error occured fetching bytes. */
#ifndef CGEN_PRINT_INSN
#define CGEN_PRINT_INSN default_print_insn
#endif
static int
default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
{
bfd_byte buf[CGEN_MAX_INSN_SIZE];
int buflen;
int status;
/* Attempt to read the base part of the insn. */
buflen = cd->base_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
/* Try again with the minimum part, if min < base. */
if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
{
buflen = cd->min_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
}
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
return print_insn (cd, pc, info, buf, buflen);
}
/* Main entry point.
Print one instruction from PC on INFO->STREAM.
Return the size of the instruction (in bytes). */
typedef struct cpu_desc_list
{
struct cpu_desc_list *next;
CGEN_BITSET *isa;
int mach;
int endian;
CGEN_CPU_DESC cd;
} cpu_desc_list;
int
print_insn_nios (bfd_vma pc, disassemble_info *info)
{
static cpu_desc_list *cd_list = 0;
cpu_desc_list *cl = 0;
static CGEN_CPU_DESC cd = 0;
static CGEN_BITSET *prev_isa;
static int prev_mach;
static int prev_endian;
int length;
CGEN_BITSET *isa;
int mach;
int endian = (info->endian == BFD_ENDIAN_BIG
? CGEN_ENDIAN_BIG
: CGEN_ENDIAN_LITTLE);
enum bfd_architecture arch;
/* ??? gdb will set mach but leave the architecture as "unknown" */
#ifndef CGEN_BFD_ARCH
#define CGEN_BFD_ARCH bfd_arch_nios
#endif
arch = info->arch;
if (arch == bfd_arch_unknown)
arch = CGEN_BFD_ARCH;
/* There's no standard way to compute the machine or isa number
so we leave it to the target. */
#ifdef CGEN_COMPUTE_MACH
mach = CGEN_COMPUTE_MACH (info);
#else
mach = info->mach;
#endif
#ifdef CGEN_COMPUTE_ISA
{
static CGEN_BITSET *permanent_isa;
if (!permanent_isa)
permanent_isa = cgen_bitset_create (MAX_ISAS);
isa = permanent_isa;
cgen_bitset_clear (isa);
cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info));
}
#else
isa = info->insn_sets;
#endif
/* If we've switched cpu's, try to find a handle we've used before */
if (cd
&& (cgen_bitset_compare (isa, prev_isa) != 0
|| mach != prev_mach
|| endian != prev_endian))
{
cd = 0;
for (cl = cd_list; cl; cl = cl->next)
{
if (cgen_bitset_compare (cl->isa, isa) == 0 &&
cl->mach == mach &&
cl->endian == endian)
{
cd = cl->cd;
prev_isa = cd->isas;
break;
}
}
}
/* If we haven't initialized yet, initialize the opcode table. */
if (! cd)
{
const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
//const bfd_arch_info_type *arch_type = &bfd_nios_arch;
const char *mach_name;
if (!arch_type)
abort ();
mach_name = arch_type->printable_name;
prev_isa = cgen_bitset_copy (isa);
prev_mach = mach;
prev_endian = endian;
cd = nios_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
CGEN_CPU_OPEN_BFDMACH, mach_name,
CGEN_CPU_OPEN_ENDIAN, prev_endian,
CGEN_CPU_OPEN_END);
if (!cd)
abort ();
/* Save this away for future reference. */
cl = xmalloc (sizeof (struct cpu_desc_list));
cl->cd = cd;
cl->isa = prev_isa;
cl->mach = mach;
cl->endian = endian;
cl->next = cd_list;
cd_list = cl;
nios_cgen_init_dis (cd);
}
/* We try to have as much common code as possible.
But at this point some targets need to take over. */
/* ??? Some targets may need a hook elsewhere. Try to avoid this,
but if not possible try to move this hook elsewhere rather than
have two hooks. */
length = CGEN_PRINT_INSN (cd, pc, info);
if (length > 0)
return length;
if (length < 0)
return -1;
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
return cd->default_insn_bitsize / 8;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+186
View File
@@ -0,0 +1,186 @@
/* Instruction opcode header for nios.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef NIOS_OPC_H
#define NIOS_OPC_H
#ifdef __cplusplus
extern "C" {
#endif
/* -- opc.h */
#undef CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 65
#undef CGEN_DIS_HASH
#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[1] >> 5)
/* condition code masks for SKPS instruction */
#define CC_C 0x0
#define CC_NC 0x1
#define CC_Z 0x2
#define CC_NZ 0x3
#define CC_MI 0x4
#define CC_PL 0x5
#define CC_GE 0x6
#define CC_LT 0x7
#define CC_LE 0x8
#define CC_GT 0x9
#define CC_V 0xa
#define CC_NV 0xb
#define CC_LS 0xc
#define CC_HI 0xd
#define CC_MAX CC_HI
/* following activates check beyond hashing since m16 and m32 instructions
* hash identically, but have different descriptions */
#define CGEN_VALIDATE_INSN_SUPPORTED
/* following allows reason codes to be output when assembler errors occur */
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
/* Special check to ensure that instruction exists for given machine */
ATTRIBUTE_UNUSED static int
nios_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
{
int machs = cd->machs;
return ((CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH) & machs) != 0);
}
/* values to signal between parse routines and md_assemble */
extern int nios_parsed_i11;
extern int nios_Rbi5;
/* values of nios_Rbi5 to help catch Rbi5 syntax errors */
#define NIOS_RBI5_REGISTER 1
#define NIOS_RBI5_IMMEDIATE 2
/* -- */
/* Enum declaration for nios instruction types. */
typedef enum cgen_insn_type {
NIOS_INSN_INVALID, NIOS_INSN_EXT8S16, NIOS_INSN_ST8S16, NIOS_INSN_STS8S16
, NIOS_INSN_ST8D16, NIOS_INSN_WRCTL16, NIOS_INSN_ADDC16, NIOS_INSN_SUBC16
, NIOS_INSN_ADD16, NIOS_INSN_SUB16, NIOS_INSN_ADDI16, NIOS_INSN_SUBI16
, NIOS_INSN_OR16, NIOS_INSN_XOR16, NIOS_INSN_AND16, NIOS_INSN_ANDN16
, NIOS_INSN_LSL16, NIOS_INSN_LSR16, NIOS_INSN_ASR16, NIOS_INSN_LSLI16
, NIOS_INSN_LSRI16, NIOS_INSN_ASRI16, NIOS_INSN_NOT16, NIOS_INSN_NEG16
, NIOS_INSN_ABS16, NIOS_INSN_MOV16, NIOS_INSN_MOVI16, NIOS_INSN_BGEN16
, NIOS_INSN_CMP16, NIOS_INSN_CMPI16, NIOS_INSN_EXT8D16
, NIOS_INSN_SEXT816, NIOS_INSN_FILL816, NIOS_INSN_LDS16, NIOS_INSN_STS16
, NIOS_INSN_LDP16, NIOS_INSN_STP16, NIOS_INSN_LD16, NIOS_INSN_ST16
, NIOS_INSN_TRAP16, NIOS_INSN_TRET16, NIOS_INSN_SAVE16, NIOS_INSN_RESTORE16
, NIOS_INSN_BSR16, NIOS_INSN_BSRR16, NIOS_INSN_JMP16, NIOS_INSN_CALL16
, NIOS_INSN_JMPC16, NIOS_INSN_CALLC16, NIOS_INSN_SKP016, NIOS_INSN_SKP116
, NIOS_INSN_SKPRZ16, NIOS_INSN_SKPRNZ16, NIOS_INSN_SKPS16, NIOS_INSN_RRC16
, NIOS_INSN_RLC16, NIOS_INSN_RDCTL16, NIOS_INSN_USR016, NIOS_INSN_USR116
, NIOS_INSN_USR216, NIOS_INSN_USR316, NIOS_INSN_USR416, NIOS_INSN_STS8S32
, NIOS_INSN_STS16S, NIOS_INSN_MOVHI, NIOS_INSN_EXT16D, NIOS_INSN_SEXT16
, NIOS_INSN_ST16D, NIOS_INSN_FILL16, NIOS_INSN_EXT8S32, NIOS_INSN_ST8S32
, NIOS_INSN_EXT16S, NIOS_INSN_ST16S, NIOS_INSN_ST8D32, NIOS_INSN_WRCTL32
, NIOS_INSN_ADD32, NIOS_INSN_SUB32, NIOS_INSN_ADDI32, NIOS_INSN_SUBI32
, NIOS_INSN_OR32, NIOS_INSN_XOR32, NIOS_INSN_AND32, NIOS_INSN_ANDN32
, NIOS_INSN_LSL32, NIOS_INSN_LSR32, NIOS_INSN_ASR32, NIOS_INSN_LSLI32
, NIOS_INSN_LSRI32, NIOS_INSN_ASRI32, NIOS_INSN_NOT32, NIOS_INSN_NEG32
, NIOS_INSN_ABS32, NIOS_INSN_MOV32, NIOS_INSN_MOVI32, NIOS_INSN_BGEN32
, NIOS_INSN_CMP32, NIOS_INSN_CMPI32, NIOS_INSN_EXT8D32
, NIOS_INSN_SEXT832, NIOS_INSN_FILL832, NIOS_INSN_LDS32, NIOS_INSN_STS32
, NIOS_INSN_LDP32, NIOS_INSN_STP32, NIOS_INSN_LD32, NIOS_INSN_ST32
, NIOS_INSN_TRAP32, NIOS_INSN_TRET32, NIOS_INSN_SAVE32, NIOS_INSN_RESTORE32
, NIOS_INSN_BSR32, NIOS_INSN_BSRR32, NIOS_INSN_JMP32, NIOS_INSN_CALL32
, NIOS_INSN_JMPC32, NIOS_INSN_CALLC32, NIOS_INSN_SKP032, NIOS_INSN_SKP132
, NIOS_INSN_SKPRZ32, NIOS_INSN_SKPRNZ32, NIOS_INSN_SKPS32, NIOS_INSN_RRC32
, NIOS_INSN_RLC32, NIOS_INSN_RDCTL32, NIOS_INSN_PFX, NIOS_INSN_BR
, NIOS_INSN_SWAP32, NIOS_INSN_MSTEP32, NIOS_INSN_MUL32, NIOS_INSN_USR032
, NIOS_INSN_USR132, NIOS_INSN_USR232, NIOS_INSN_USR332, NIOS_INSN_USR432
, NIOS_INSN_PFXIO, NIOS_INSN_MAX
} CGEN_INSN_TYPE;
/* Index of `invalid' insn place holder. */
#define CGEN_INSN_INVALID NIOS_INSN_INVALID
/* Total number of insns in table. */
#define MAX_INSNS ((int) NIOS_INSN_MAX)
/* This struct records data prior to insertion or after extraction. */
struct cgen_fields
{
int length;
long f_nil;
long f_anyof;
long f_op6;
long f_op3;
long f_op4;
long f_op5;
long f_op5_hi;
long f_op8;
long f_op9;
long f_op11;
long f_Ra;
long f_Rb;
long f_Rbi5;
long f_Rz;
long f_Rp;
long f_CTLc;
long f_i2;
long f_i4w;
long f_x1;
long f_o1;
long f_o2;
long f_i5;
long f_i6v;
long f_i8;
long f_i8v;
long f_i9;
long f_i10;
long f_i11;
long f_i6_rel_h;
long f_i6_rel_w;
long f_bsrr_i6_rel;
long f_i8v_rel_h;
long f_i8v_rel_w;
long f_i11_rel;
long f_i1;
};
#define CGEN_INIT_PARSE(od) \
{\
}
#define CGEN_INIT_INSERT(od) \
{\
}
#define CGEN_INIT_EXTRACT(od) \
{\
}
#define CGEN_INIT_PRINT(od) \
{\
}
#ifdef __cplusplus
}
#endif
#endif /* NIOS_OPC_H */
+254
View File
@@ -0,0 +1,254 @@
/* <ctype.h> replacement macros.
Copyright (C) 2000-2018 Free Software Foundation, Inc.
Contributed by Zack Weinberg <zackw@stanford.edu>.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/*
@defvr Extension HOST_CHARSET
This macro indicates the basic character set and encoding used by the
host: more precisely, the encoding used for character constants in
preprocessor @samp{#if} statements (the C "execution character set").
It is defined by @file{safe-ctype.h}, and will be an integer constant
with one of the following values:
@ftable @code
@item HOST_CHARSET_UNKNOWN
The host character set is unknown - that is, not one of the next two
possibilities.
@item HOST_CHARSET_ASCII
The host character set is ASCII.
@item HOST_CHARSET_EBCDIC
The host character set is some variant of EBCDIC. (Only one of the
nineteen EBCDIC varying characters is tested; exercise caution.)
@end ftable
@end defvr
@deffn Extension ISALPHA (@var{c})
@deffnx Extension ISALNUM (@var{c})
@deffnx Extension ISBLANK (@var{c})
@deffnx Extension ISCNTRL (@var{c})
@deffnx Extension ISDIGIT (@var{c})
@deffnx Extension ISGRAPH (@var{c})
@deffnx Extension ISLOWER (@var{c})
@deffnx Extension ISPRINT (@var{c})
@deffnx Extension ISPUNCT (@var{c})
@deffnx Extension ISSPACE (@var{c})
@deffnx Extension ISUPPER (@var{c})
@deffnx Extension ISXDIGIT (@var{c})
These twelve macros are defined by @file{safe-ctype.h}. Each has the
same meaning as the corresponding macro (with name in lowercase)
defined by the standard header @file{ctype.h}. For example,
@code{ISALPHA} returns true for alphabetic characters and false for
others. However, there are two differences between these macros and
those provided by @file{ctype.h}:
@itemize @bullet
@item These macros are guaranteed to have well-defined behavior for all
values representable by @code{signed char} and @code{unsigned char}, and
for @code{EOF}.
@item These macros ignore the current locale; they are true for these
fixed sets of characters:
@multitable {@code{XDIGIT}} {yada yada yada yada yada yada yada yada}
@item @code{ALPHA} @tab @kbd{A-Za-z}
@item @code{ALNUM} @tab @kbd{A-Za-z0-9}
@item @code{BLANK} @tab @kbd{space tab}
@item @code{CNTRL} @tab @code{!PRINT}
@item @code{DIGIT} @tab @kbd{0-9}
@item @code{GRAPH} @tab @code{ALNUM || PUNCT}
@item @code{LOWER} @tab @kbd{a-z}
@item @code{PRINT} @tab @code{GRAPH ||} @kbd{space}
@item @code{PUNCT} @tab @kbd{`~!@@#$%^&*()_-=+[@{]@}\|;:'",<.>/?}
@item @code{SPACE} @tab @kbd{space tab \n \r \f \v}
@item @code{UPPER} @tab @kbd{A-Z}
@item @code{XDIGIT} @tab @kbd{0-9A-Fa-f}
@end multitable
Note that, if the host character set is ASCII or a superset thereof,
all these macros will return false for all values of @code{char} outside
the range of 7-bit ASCII. In particular, both ISPRINT and ISCNTRL return
false for characters with numeric values from 128 to 255.
@end itemize
@end deffn
@deffn Extension ISIDNUM (@var{c})
@deffnx Extension ISIDST (@var{c})
@deffnx Extension IS_VSPACE (@var{c})
@deffnx Extension IS_NVSPACE (@var{c})
@deffnx Extension IS_SPACE_OR_NUL (@var{c})
@deffnx Extension IS_ISOBASIC (@var{c})
These six macros are defined by @file{safe-ctype.h} and provide
additional character classes which are useful when doing lexical
analysis of C or similar languages. They are true for the following
sets of characters:
@multitable {@code{SPACE_OR_NUL}} {yada yada yada yada yada yada yada yada}
@item @code{IDNUM} @tab @kbd{A-Za-z0-9_}
@item @code{IDST} @tab @kbd{A-Za-z_}
@item @code{VSPACE} @tab @kbd{\r \n}
@item @code{NVSPACE} @tab @kbd{space tab \f \v \0}
@item @code{SPACE_OR_NUL} @tab @code{VSPACE || NVSPACE}
@item @code{ISOBASIC} @tab @code{VSPACE || NVSPACE || PRINT}
@end multitable
@end deffn
*/
#include "ansidecl.h"
#include <safe-ctype.h>
#include <stdio.h> /* for EOF */
#if EOF != -1
#error "<safe-ctype.h> requires EOF == -1"
#endif
/* Shorthand */
#define bl _sch_isblank
#define cn _sch_iscntrl
#define di _sch_isdigit
#define is _sch_isidst
#define lo _sch_islower
#define nv _sch_isnvsp
#define pn _sch_ispunct
#define pr _sch_isprint
#define sp _sch_isspace
#define up _sch_isupper
#define vs _sch_isvsp
#define xd _sch_isxdigit
/* Masks. */
#define L (const unsigned short) (lo|is |pr) /* lower case letter */
#define XL (const unsigned short) (lo|is|xd|pr) /* lowercase hex digit */
#define U (const unsigned short) (up|is |pr) /* upper case letter */
#define XU (const unsigned short) (up|is|xd|pr) /* uppercase hex digit */
#define D (const unsigned short) (di |xd|pr) /* decimal digit */
#define P (const unsigned short) (pn |pr) /* punctuation */
#define _ (const unsigned short) (pn|is |pr) /* underscore */
#define C (const unsigned short) ( cn) /* control character */
#define Z (const unsigned short) (nv |cn) /* NUL */
#define M (const unsigned short) (nv|sp |cn) /* cursor movement: \f \v */
#define V (const unsigned short) (vs|sp |cn) /* vertical space: \r \n */
#define T (const unsigned short) (nv|sp|bl|cn) /* tab */
#define S (const unsigned short) (nv|sp|bl|pr) /* space */
/* Are we ASCII? */
#if HOST_CHARSET == HOST_CHARSET_ASCII
const unsigned short _sch_istable[256] =
{
Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */
C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */
C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */
S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */
P, P, P, P, P, P, P, P, /* ( ) * + , - . / */
D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */
D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */
P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */
U, U, U, U, U, U, U, U, /* H I J K L M N O */
U, U, U, U, U, U, U, U, /* P Q R S T U V W */
U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */
P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */
L, L, L, L, L, L, L, L, /* h i j k l m n o */
L, L, L, L, L, L, L, L, /* p q r s t u v w */
L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */
/* high half of unsigned char is locale-specific, so all tests are
false in "C" locale */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const unsigned char _sch_tolower[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64,
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
91, 92, 93, 94, 95, 96,
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
123,124,125,126,127,
128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
};
const unsigned char _sch_toupper[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64,
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
91, 92, 93, 94, 95, 96,
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
123,124,125,126,127,
128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
};
#else
# if HOST_CHARSET == HOST_CHARSET_EBCDIC
#error "FIXME: write tables for EBCDIC"
# else
#error "Unrecognized host character set"
# endif
#endif
+3 -3
View File
@@ -159,7 +159,7 @@ int r_pyc_disasm (RAsmOp *opstruct, const ut8 *code, RList *cobjs, RList *intern
op = code[i];
i += 1;
name = op_name[op];
strcpy (opstruct->buf_asm, name);
r_strbuf_set (&opstruct->buf_asm, name);
if (name == NULL) {
return 0;
}
@@ -171,7 +171,7 @@ int r_pyc_disasm (RAsmOp *opstruct, const ut8 *code, RList *cobjs, RList *intern
extended_arg = oparg*65536;
arg = parse_arg (op, oparg, names, consts, varnames, interned_table);
if (arg != NULL) {
strcat (opstruct->buf_asm, r_str_newf ("%20s", arg));
r_strbuf_appendf (&opstruct->buf_asm, "%20s", arg);
}
}
return i;
@@ -304,4 +304,4 @@ void dump_cobj (pyc_code_object *c) {
eprintf("varnames_start\n");
dump(c->varnames->data);
eprintf("varnames_end\n");
}
}
+1
View File
@@ -20,6 +20,7 @@
#include "sysdep.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "dis-asm.h"
#include "ansidecl.h"
+2
View File
@@ -22,6 +22,8 @@
#include "sysdep.h"
#include <alloca.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ansidecl.h"
#include "libiberty.h"
#include <ctype.h>
+1
View File
@@ -28,6 +28,7 @@
#include "sysdep.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ansidecl.h"
#include "dis-asm.h"
+1
View File
@@ -28,6 +28,7 @@
#include "sysdep.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ansidecl.h"
#include "dis-asm.h"
#include "mybfd.h"
+2
View File
@@ -10,6 +10,7 @@ ARCHS+=m68k_net.mk
ARCHS+=blackfin.mk
ARCHS+=x86_bea.mk
ARCHS+=msil.mk
ARCHS+=nios.mk
ARCHS+=swf.mk
ARCHS+=vc4.mk
ARCHS+=mc6809.mk
@@ -17,6 +18,7 @@ ARCHS+=z80_nc.mk
ARCHS+=pyc.mk
ARCHS+=x86_zyan.mk
ARCHS+=evm.mk
ARCHS+=atombios.mk
include ../../plugs.mk
+9 -8
View File
@@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2015 - pancake */
/* radare - LGPL - Copyright 2010-2018 - pancake */
#include <stdio.h>
#include <stdarg.h>
@@ -11,10 +11,13 @@
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
int *p = (int*)buf; // TODO : endian
op->buf_asm[0]='\0';
op->size = armthumb_disassemble (op->buf_asm, (ut32)a->pc, *p);
if (!op->size)
strncpy (op->buf_asm, " (data)", R_ASM_BUFSIZE);
char buf_asm[64] = {0};
op->size = armthumb_disassemble (buf_asm, (ut32)a->pc, *p);
if (op->size > 0) {
r_strbuf_set (&op->buf_asm, buf_asm);
} else {
r_strbuf_set (&op->buf_asm, " (data)");
}
return op->size;
}
@@ -33,14 +36,12 @@ RAsmPlugin r_asm_plugin_armthumb = {
.arch = "arm",
.bits = 16,
.desc = "ARM THUMB disassembly plugin",
.init = NULL,
.fini = NULL,
.disassemble = &disassemble,
// .assemble = &assemble
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_armthumb,
.version = R2_VERSION
+37
View File
@@ -0,0 +1,37 @@
/* radare - LGPL - Copyright 2018 - damo22 */
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include "../arch/atombios/atombios.h"
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
op->size = atombios_disassemble (buf, r_asm_op_get_asm (op));
return op->size;
}
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
return 0; // n
}
RAsmPlugin r_asm_plugin_atombios = {
.name = "atombios",
.author = "damo22",
.version = "0.0.1",
.arch = "atombios",
.license = "LGPL3",
.bits = 32 | 64,
.endian = R_SYS_ENDIAN_NONE,
.desc = "AtomBIOS",
.disassemble = &disassemble,
.assemble = &assemble
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_atombios,
.version = R2_VERSION
};
#endif
+6 -18
View File
@@ -11,7 +11,7 @@
#include "blackfin/bfin-dis.c"
static unsigned long Offset = 0;
static char *buf_global = NULL;
static RStrBuf *buf_global = NULL;
static unsigned char bytes[4];
static int bfin_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, ut32 length, struct disassemble_info *info) {
@@ -28,41 +28,29 @@ static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_in
}
static void print_address(bfd_vma address, struct disassemble_info *info) {
char tmp[32];
if (buf_global == NULL)
return;
sprintf(tmp, "0x%08"PFMT64x"", (ut64)address);
strcat(buf_global, tmp);
r_strbuf_appendf (buf_global, "0x%08"PFMT64x"", (ut64)address);
}
static int buf_fprintf(void *stream, const char *format, ...) {
int flen, glen;
va_list ap;
char *tmp;
if (buf_global == NULL)
return 0;
va_start (ap, format);
flen = strlen (format);
glen = strlen (buf_global);
tmp = malloc (flen + glen + 2);
memcpy (tmp, buf_global, glen);
memcpy (tmp+glen, format, flen);
tmp[flen+glen] = 0;
// XXX: overflow here?
vsprintf (buf_global, tmp, ap);
r_strbuf_vappendf (buf_global, format, ap);
va_end (ap);
free (tmp);
return 0;
}
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
struct disassemble_info disasm_obj;
op->buf_asm[0]='\0';
r_strbuf_set (&op->buf_asm, "");
op->size = 4;
if (len<4)
return -1;
buf_global = op->buf_asm;
buf_global = &op->buf_asm;
Offset = a->pc;
memcpy (bytes, buf, 4); // TODO handle thumb
@@ -81,7 +69,7 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
op->size = print_insn_bfin((bfd_vma)Offset, &disasm_obj);
if (op->size == -1)
strncpy (op->buf_asm, " (data)", R_ASM_BUFSIZE);
r_strbuf_set (&op->buf_asm, " (data)");
return op->size;
}
+4 -3
View File
@@ -12,15 +12,16 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
EvmOp eop = {
0
};
evm_dis (&eop, buf, len);
strncpy (op->buf_asm, eop.txt, sizeof (op->buf_asm));
op->buf_asm[sizeof (op->buf_asm) - 1] = 0;
op->size = eop.len;
r_asm_op_set_asm (op, eop.txt);
return eop.len;
}
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
op->size = evm_asm (buf, op->buf, sizeof (op->buf));
op->size = evm_asm (buf, &op->buf, sizeof (op->buf));
return op->size;
}
+6 -3
View File
@@ -17,6 +17,7 @@ static int disassemble(RAsm *a, RAsmOp *aop, const ut8 *buf, int len) {
const unsigned char *buf2;
int ilen ;
static struct DisasmPara_68k dp;
char *buf_asm;
/* initialize DisasmPara */
*operands = *opcode = 0;
memcpy (bof, buf, R_MIN(len, sizeof(bof)));
@@ -31,9 +32,11 @@ static int disassemble(RAsm *a, RAsmOp *aop, const ut8 *buf, int len) {
}
ilen = (buf2-(const ut8*)bof);
if (*operands)
snprintf (aop->buf_asm, R_ASM_BUFSIZE, "%s %s", opcode, operands);
else snprintf (aop->buf_asm, R_ASM_BUFSIZE, "%s", opcode);
r_str_rmch (aop->buf_asm, '#');
buf_asm = sdb_fmt ("%s %s", opcode, operands);
else
buf_asm = sdb_fmt ("%s", opcode);
r_str_rmch (buf_asm, '#');
r_asm_op_set_asm (aop, buf_asm);
aop->size = ilen;
return aop->size;
}
+30 -34
View File
@@ -827,8 +827,7 @@ static const char mc6809_index_registers[] = {
/* 0b11 */ 's',
};
static int mc6809_append_indexed_args (char *buf_asm, const ut8 *buf)
{
static int mc6809_append_indexed_args(RStrBuf *buf_asm, const ut8 *buf) {
char postop_buffer[32];
int postop_bytes = 0;
@@ -992,42 +991,43 @@ static int mc6809_append_indexed_args (char *buf_asm, const ut8 *buf)
}
}
}
strcat (buf_asm, postop_buffer);
r_strbuf_append (buf_asm, postop_buffer);
return postop_bytes;
}
static int mc6809_append_pushpull_args(enum instruction_mode mode,
char *buf_asm,
RStrBuf *buf_asm,
const ut8 *opcode_args)
{
strcat (buf_asm, " ");
r_strbuf_append (buf_asm, " ");
if (*opcode_args & 0x80) {
strcat (buf_asm, "pc,");
r_strbuf_append (buf_asm, "pc,");
}
if (*opcode_args & 0x40) {
strcat (buf_asm, (mode == PUSHPULLSYSTEM) ? "u," : "s,");
r_strbuf_append (buf_asm, (mode == PUSHPULLSYSTEM) ? "u," : "s,");
}
if (*opcode_args & 0x20) {
strcat (buf_asm, "y,");
r_strbuf_append (buf_asm, "y,");
}
if (*opcode_args & 0x10) {
strcat (buf_asm, "x,");
r_strbuf_append (buf_asm, "x,");
}
if (*opcode_args & 0x08) {
strcat (buf_asm, "dp,");
r_strbuf_append (buf_asm, "dp,");
}
if (*opcode_args & 0x04) {
strcat (buf_asm, "b,");
r_strbuf_append (buf_asm, "b,");
}
if (*opcode_args & 0x02) {
strcat (buf_asm, "a,");
r_strbuf_append (buf_asm, "a,");
}
if (*opcode_args & 0x01) {
strcat (buf_asm, "cc,");
r_strbuf_append (buf_asm, "cc,");
}
/* Trim off the final unwanted comma */
buf_asm[strlen(buf_asm)-1] = '\0';
/* XXX we miss a proper r_str_buf_trim function here */
r_strbuf_get (buf_asm)[r_strbuf_length(buf_asm)-1] = '\0';
return 2;
}
@@ -1035,7 +1035,7 @@ static int mc6809_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
ut8 tfrexg_regmasked;
const char *tfrexg_source_reg;
const char *tfrexg_dest_reg;
const char *buf_asm = "invalid";
const mc6809_opcodes_t *mc6809_opcode = &mc6809_opcodes[buf[0]];
/* opcode_args points to the first argument byte of the opcode */
@@ -1066,37 +1066,33 @@ static int mc6809_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
case PAGE2: /* PAGE2 and PAGE3 shouldn't occur twice in a row */
case PAGE3:
op->size++;
strcpy (op->buf_asm, "INVALID");
break;
case INHERENT:
op->size++;
strcpy (op->buf_asm, mc6809_opcode->name);
buf_asm = sdb_fmt ("%s", mc6809_opcode->name);
break;
case IMMEDIATE:
op->size += 2;
sprintf (op->buf_asm,
"%s #$%02x", mc6809_opcode->name, *opcode_args);
buf_asm = sdb_fmt ("%s #$%02x", mc6809_opcode->name, *opcode_args);
break;
case IMMEDIATELONG:
op->size += 3;
sprintf (op->buf_asm,
"%s #$%04x", mc6809_opcode->name,
buf_asm = sdb_fmt ("%s #$%04x", mc6809_opcode->name,
opcode_args[0] * 256 + opcode_args[1]);
break;
case DIRECT:
op->size += 2;
sprintf (op->buf_asm,
"%s <$%02x", mc6809_opcode->name, *opcode_args);
buf_asm = sdb_fmt ("%s <$%02x", mc6809_opcode->name, *opcode_args);
break;
case RELATIVE:
op->size += 2;
sprintf (op->buf_asm, "%s $%04x",
buf_asm = sdb_fmt ("%s $%04x",
mc6809_opcode->name,
(ut16) (a->pc + (st8) *opcode_args + op->size) & 0xFFFF);
break;
case RELATIVELONG:
op->size += 3;
sprintf (op->buf_asm, "%s $%04x", mc6809_opcode->name,
buf_asm = sdb_fmt ("%s $%04x", mc6809_opcode->name,
(ut16) (a->pc + (st16)(opcode_args[0]*256+opcode_args[1])+op->size) & 0xFFFF);
break;
case TFREXG:
@@ -1105,7 +1101,6 @@ static int mc6809_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
tfrexg_regmasked = *opcode_args & 0x88;
if (tfrexg_regmasked && tfrexg_regmasked != 0x88) {
op->size += 1;
strcpy (op->buf_asm, "INVALID");
} else {
tfrexg_source_reg = \
mc6809_register_field[(*opcode_args >> 4) & 0x0f];
@@ -1113,10 +1108,9 @@ static int mc6809_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
mc6809_register_field[*opcode_args & 0x0f];
if (!tfrexg_source_reg || !tfrexg_dest_reg) {
op->size += 1;
strcpy (op->buf_asm, "INVALID");
} else {
op->size += 2;
sprintf (op->buf_asm,
buf_asm = sdb_fmt (
"%s %s,%s",
mc6809_opcode->name,
tfrexg_source_reg,
@@ -1127,19 +1121,19 @@ static int mc6809_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
break;
case INDEXED:
/* Load Effective Address opcode - variable length */
strcpy (op->buf_asm, mc6809_opcode->name);
op->size += mc6809_append_indexed_args (op->buf_asm,
buf_asm = sdb_fmt ("%s", mc6809_opcode->name);
op->size += mc6809_append_indexed_args (&op->buf_asm,
opcode_args) + 1;
break;
case PUSHPULLSYSTEM:
case PUSHPULLUSER:
strcpy (op->buf_asm, mc6809_opcode->name);
buf_asm = sdb_fmt ("%s", mc6809_opcode->name);
op->size += mc6809_append_pushpull_args(mc6809_opcode->mode,
op->buf_asm,
&op->buf_asm,
opcode_args);
break;
case EXTENDED:
sprintf (op->buf_asm,
buf_asm = sdb_fmt (
"%s $%04x",
mc6809_opcode->name,
opcode_args[0] * 256 + opcode_args[1]);
@@ -1147,6 +1141,8 @@ static int mc6809_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
break;
}
r_asm_op_set_asm (op, buf_asm);
return op->size;
}
@@ -1167,4 +1163,4 @@ struct r_lib_struct_t radare_plugin = {
.data = &r_asm_plugin_mc6809,
.version = R2_VERSION
};
#endif
#endif
+3 -3
View File
@@ -8,18 +8,18 @@
#include <r_asm.h>
#include "msil/demsil.c"
static int arch_msil_disasm(char *str, const ut8 *buf, ut64 seek) {
static int arch_msil_disasm(RStrBuf *buf_asm, const ut8 *buf, ut64 seek) {
ut32 n;
int o;
DISASMSIL_OFFSET CodeBase = seek;
ILOPCODE_STRUCT ilopar[8];
o = DisasMSIL (buf, 16, CodeBase, ilopar, 8, &n);
sprintf (str,"%s", ilopar[0].Mnemonic);
r_strbuf_setf (buf_asm, "%s", ilopar[0].Mnemonic);
return o;
}
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
return (op->size = arch_msil_disasm (op->buf_asm, buf, a->pc));
return (op->size = arch_msil_disasm (&op->buf_asm, buf, a->pc));
}
RAsmPlugin r_asm_plugin_msil = {
+93
View File
@@ -0,0 +1,93 @@
/* nios plugin by hewittc at 2018 */
#include <r_asm.h>
#include <r_lib.h>
#include <r_types.h>
#include <r_util.h>
#include "dis-asm.h"
#include "nios/gnu/nios-desc.h"
static RStrBuf *buf_global = NULL;
static ut8 bytes[2];
static int nios_buffer_read_memory(bfd_vma address, bfd_byte *byte, ut32 len, disassemble_info *info) {
memcpy(byte, bytes, len);
return 0;
}
static int nios_symbol_at_address(bfd_vma address, disassemble_info *info) {
return 0;
}
static void nios_memory_error(int status, bfd_vma address, disassemble_info *info) {
//--
}
static void nios_print_address(bfd_vma address, disassemble_info *info) {
if (buf_global) {
r_strbuf_appendf (buf_global, "0x%08"PFMT64x, (ut64) address);
}
}
static int nios_fprintf(void *stream, const char *format, ...) {
if (!buf_global) {
return 0;
}
va_list args;
va_start(args, format);
r_strbuf_vappendf (buf_global, format, args);
va_end(args);
return 0;
}
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
if (len < 2) {
return -1;
}
buf_global = &op->buf_asm;
memcpy(bytes, buf, 2);
struct disassemble_info info = {0};
info.disassembler_options = "";
info.mach = a->bits == 16 ? MACH_NIOS16 : MACH_NIOS32;
info.buffer = bytes;
info.read_memory_func = &nios_buffer_read_memory;
info.symbol_at_address_func = &nios_symbol_at_address;
info.memory_error_func = &nios_memory_error;
info.print_address_func = &nios_print_address;
info.endian = !a->big_endian;
info.fprintf_func = &nios_fprintf;
info.stream = stdout;
op->size = print_insn_nios((bfd_vma) a->pc, &info);
if (op->size == -1) {
r_strbuf_set(&op->buf_asm, " (data)");
}
return op->size;
}
RAsmPlugin r_asm_plugin_nios = {
.name = "nios",
.arch = "nios",
.desc = "Nios embedded processor",
.license = "GPL3",
.bits = 16 | 32,
.endian = R_SYS_ENDIAN_LITTLE | R_SYS_ENDIAN_BIG,
.disassemble = &disassemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_nios,
.version = R2_VERSION
};
#endif
+6 -7
View File
@@ -1,4 +1,4 @@
/* radare - GPL3 - Copyright 2009-2015 pancake, nibble */
/* radare - GPL3 - Copyright 2009-2018 pancake, nibble */
#include <stdio.h>
#include <string.h>
@@ -18,13 +18,15 @@ static int disassemble(RAsm *a, RAsmOp *aop, const ut8 *buf, int len) {
static struct DisasmPara_PPC dp;
/* initialize DisasmPara */
memcpy(bof, buf, 4);
memcpy (bof, buf, 4);
dp.opcode = opcode;
dp.operands = operands;
dp.iaddr = &iaddr;
dp.instr = bof;
PPC_Disassemble (&dp, a->big_endian);
snprintf (aop->buf_asm, R_ASM_BUFSIZE, "%s %s", opcode, operands);
char res[64] = {0};
snprintf (res, sizeof (res), "%s %s", opcode, operands);
r_strbuf_set (&aop->buf_asm, res);
aop->size = 4;
return aop->size;
}
@@ -34,14 +36,11 @@ RAsmPlugin r_asm_plugin_ppc_disasm = {
.arch = "ppc",
.bits = 32,
.desc = "Tiny PowerPC disassembly plugin",
.init = NULL,
.fini = NULL,
.disassemble = &disassemble,
.assemble = NULL
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_ppc_disasm,
.version = R2_VERSION
+8 -2
View File
@@ -7,13 +7,19 @@
#include <psosvm/vmas/vmas.h>
static int disassemble(RAsm *a, struct r_asm_op_t *op, const ut8 *buf, int len) {
char buf_asm[64] = {0};
psosvmasm_init();
op->size = psosvm_disasm(buf, op->buf_asm);
op->size = psosvm_disasm(buf, buf_asm);
if (op->size > 0) {
r_asm_op_set_asm (op, buf_asm);
} else {
r_asm_op_set_asm (op, " (data)");
}
return op->size;
}
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
op->size = psosvm_assemble(op->buf, buf);
op->size = psosvm_assemble((ut8*)r_strbuf_get (&op->buf), buf);
return op->size;
}
+14 -24
View File
@@ -13,7 +13,7 @@
static unsigned long Offset = 0;
static char *buf_global = NULL;
static RStrBuf *buf_global = NULL;
static unsigned char bytes[4];
static int vc4_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, ut32 length, struct disassemble_info *info) {
@@ -30,39 +30,28 @@ static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_in
}
static void print_address(bfd_vma address, struct disassemble_info *info) {
char tmp[32];
if (buf_global == NULL)
return;
snprintf (tmp, sizeof (tmp)-1, "0x%08" PFMT64x, (ut64)address);
strcat (buf_global, tmp);
if (buf_global) {
r_strbuf_appendf (buf_global, "0x%08" PFMT64x, (ut64)address);
}
}
static int buf_fprintf(void *stream, const char *format, ...) {
int flen, glen;
va_list ap;
char *tmp;
if (buf_global == NULL)
if (!buf_global) {
return 0;
}
va_start (ap, format);
flen = strlen (format);
glen = strlen (buf_global);
tmp = malloc (flen + glen + 2);
memcpy (tmp, buf_global, glen);
memcpy (tmp+glen, format, flen);
tmp[flen+glen] = 0;
// XXX: overflow here?
vsprintf (buf_global, tmp, ap);
r_strbuf_vappendf (buf_global, format, ap);
va_end (ap);
free (tmp);
return 0;
}
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
struct disassemble_info disasm_obj;
op->buf_asm[0]='\0';
if (len<4)
if (len < 4) {
return -1;
buf_global = op->buf_asm;
}
buf_global = &op->buf_asm;
Offset = a->pc;
memcpy (bytes, buf, 4); // TODO handle thumb
@@ -80,8 +69,9 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
op->size = print_insn_vc4 ((bfd_vma)Offset, &disasm_obj);
if (op->size == -1)
strncpy (op->buf_asm, " (data)", R_ASM_BUFSIZE);
if (op->size == -1) {
r_strbuf_set (&op->buf_asm, " (data)");
}
return op->size;
}
@@ -97,7 +87,7 @@ RAsmPlugin r_asm_plugin_vc4 = {
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_vc4,
.version = R2_VERSION
+1 -1
View File
@@ -24,7 +24,7 @@ static int disassemble(RAsm *a, RAsmOp *aop, const ut8 *buf, int len) {
else disasm_obj.Options = 0;
aop->size = Disasm (&disasm_obj);
snprintf (aop->buf_asm, R_ASM_BUFSIZE, disasm_obj.CompleteInstr);
r_asm_op_set_asm (aop, disasm_obj.CompleteInstr);
return aop->size;
}
+6 -6
View File
@@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2016 - pancake, nibble */
/* radare - LGPL - Copyright 2009-2018 - pancake, nibble */
#include <stdio.h>
#include <string.h>
@@ -11,8 +11,8 @@
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
t_disasm disasm_obj;
op->size = Disasm_olly(buf, len, a->pc, &disasm_obj, DISASM_FILE);
snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s", disasm_obj.result);
op->size = Disasm_olly (buf, len, a->pc, &disasm_obj, DISASM_FILE);
r_asm_op_set_asm (op, disasm_obj.result);
return op->size;
}
@@ -25,7 +25,7 @@ static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
/* constsize == 0: Address constants and inmediate data of 16/32b */
for (constsize = 0; constsize < 4; constsize++) {
for (attempt = 0; ret > 0; attempt++) {
ret = Assemble((char*)buf, a->pc, &asm_obj, attempt, constsize, buf_err);
ret = Assemble ((char*)buf, a->pc, &asm_obj, attempt, constsize, buf_err);
if (ret > 0 && ret < oret) {
oret = ret;
oattempt = attempt;
@@ -35,7 +35,7 @@ static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
}
op->size = R_MAX (0, Assemble ((char*)buf, a->pc, &asm_obj, oattempt, oconstsize, buf_err));
if (op->size > 0) {
memcpy (op->buf, asm_obj.code, R_MIN (R_MIN (16, op->size), sizeof (op->buf)));
r_asm_op_set_buf (op, asm_obj.code, R_MIN (16, op->size));
}
return op->size;
}
@@ -52,7 +52,7 @@ RAsmPlugin r_asm_plugin_x86_olly = {
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_x86_olly,
.version = R2_VERSION
+1 -1
View File
@@ -1293,7 +1293,7 @@ static int write_asm(ut8 *data, Opcode *opcode_ptr, Operand *operands) {
*/
static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
ut64 offset = a->pc;
ut8 *data = ao->buf;
ut8 *data = (ut8 *)r_strbuf_get (&ao->buf);
size_t pos = 0, nextpos;
x86newTokenType ttype;
char mnemonic[12];
+9 -9
View File
@@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2014 - pancake, nibble */
/* radare - LGPL - Copyright 2009-2018 - pancake, nibble */
#include <stdio.h>
#include <string.h>
@@ -11,7 +11,7 @@
// TODO : split into get/set... we need a way to create binary masks from asm buffers
// -- move this shit into r_anal.. ??
// -- delta, size, mode.. mode is for a->pc-5, register handling and things like this
static int modify(RAsm *a, ut8 *buf, int field, ut64 val) {
static bool modify(RAsm *a, ut8 *buf, int field, ut64 val) {
ut32 val32 = (ut32)val;
switch (buf[0]) {
case 0x68: // push dword
@@ -56,16 +56,16 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
ud_set_pc (&d, a->pc);
ud_set_mode (&d, a->bits);
opsize = ud_disassemble (&d);
strncpy (op->buf_asm, ud_insn_asm (&d), R_ASM_BUFSIZE-1);
op->buf_asm[R_ASM_BUFSIZE-1] = 0;
if (opsize<1 || strstr (op->buf_asm, "invalid"))
r_strbuf_set (&op->buf_asm, ud_insn_asm (&d));
char *buf_asm = r_strbuf_get (&op->buf_asm);
if (opsize<1 || strstr (buf_asm, "invalid"))
opsize = 0;
op->size = opsize;
if (a->syntax == R_ASM_SYNTAX_JZ) {
if (!strncmp (op->buf_asm, "je ", 3)) {
memcpy (op->buf_asm, "jz", 2);
} else if (!strncmp (op->buf_asm, "jne ", 4)) {
memcpy (op->buf_asm, "jnz", 3);
if (!strncmp (buf_asm, "je ", 3)) {
memcpy (buf_asm, "jz", 2);
} else if (!strncmp (buf_asm, "jne ", 4)) {
memcpy (buf_asm, "jnz", 3);
}
}
return opsize;
+9
View File
@@ -0,0 +1,9 @@
OBJ_ATOMBIOS=asm_atombios.o
OBJ_ATOMBIOS+=../arch/atombios/atombios.o
TARGET_ATOMBIOS=asm_atombios.${LIBEXT}
STATIC_OBJ+=${OBJ_ATOMBIOS}
ALL_TARGETS+=${TARGET_ATOMBIOS}
${TARGET_ATOMBIOS}: ${OBJ_ATOMBIOS}
${CC} -g $(call libname,asm_atombios) ${LDFLAGS} ${CFLAGS} -o ${TARGET_ATOMBIOS} ${OBJ_ATOMBIOS}
+1 -1
View File
@@ -7,4 +7,4 @@ TARGET_BLACKFIN=asm_blackfin.${LIBEXT}
ALL_TARGETS+=${TARGET_BLACKFIN}
${TARGET_BLACKFIN}: ${OBJ_BLACKFIN}
${CC} ${CFLAGS} -o asm_blackfin.${LIBEXT} ${OBJ_BLACKFIN}
${CC} ${CFLAGS} -o asm_blackfin.${LIBEXT} ${OBJ_BLACKFIN} ${LDFLAGS}
+1 -1
View File
@@ -7,4 +7,4 @@ TARGET_M68K=asm_m68k_net.${LIBEXT}
ALL_TARGETS+=${TARGET_M68K}
${TARGET_M68K}: ${OBJ_M68K}
${CC} -shared ${CFLAGS} -o asm_m68k_net.${LIBEXT} ${OBJ_M68K}
${CC} -shared ${CFLAGS} -o asm_m68k_net.${LIBEXT} ${OBJ_M68K} ${LDFLAGS}
+22
View File
@@ -0,0 +1,22 @@
OBJ_NIOS=asm_nios.o
OBJ_NIOS+=../arch/nios/gnu/safe-ctype.o
OBJ_NIOS+=../arch/nios/gnu/cgen-bitset.o
OBJ_NIOS+=../arch/nios/gnu/cgen-dis.o
OBJ_NIOS+=../arch/nios/gnu/cgen-asm.o
OBJ_NIOS+=../arch/nios/gnu/cgen-opc.o
OBJ_NIOS+=../arch/nios/gnu/cpu-nios.o
OBJ_NIOS+=../arch/nios/gnu/nios-dis.o
OBJ_NIOS+=../arch/nios/gnu/nios-asm.o
OBJ_NIOS+=../arch/nios/gnu/nios-desc.o
OBJ_NIOS+=../arch/nios/gnu/nios-ibld.o
OBJ_NIOS+=../arch/nios/gnu/nios-opc.o
STATIC_OBJ+=${OBJ_NIOS}
TARGET_NIOS=asm_nios.${LIBEXT}
ALL_TARGETS+=${TARGET_NIOS}
${TARGET_NIOS}: ${OBJ_NIOS}
${CC} $(call libname,asm_nios) ${LDFLAGS} ${CFLAGS} \
-o asm_nios.${LIBEXT} ${OBJ_NIOS}
+1 -1
View File
@@ -6,4 +6,4 @@ TARGET_PPC_DISASM=asm_ppc_disasm.${LIBEXT}
ALL_TARGETS+=${TARGET_PPC_DISASM}
${TARGET_PPC_DISASM}: ${OBJ_PPC_DISASM}
${CC} ${CFLAGS} -o asm_ppc_disasm.${LIBEXT} ${OBJ_PPC_DISASM}
${CC} ${CFLAGS} -o asm_ppc_disasm.${LIBEXT} ${OBJ_PPC_DISASM} ${LDFLAGS}
+1 -1
View File
@@ -11,4 +11,4 @@ CFLAGS+=-I../arch/x86/bea/include
CFLAGS+=-DUint64=uint64_t
${TARGET_X86_BEA}: ${OBJ_X86_BEA}
${CC} ${CFLAGS} -o ${TARGET_X86_BEA} ${OBJ_X86_BEA}
${CC} ${CFLAGS} -o ${TARGET_X86_BEA} ${OBJ_X86_BEA} ${LDFLAGS}
+3
View File
@@ -10,6 +10,9 @@ swf:
pcap:
cd p ; $(MAKE) bin_pcap.$(LIBEXT)
atombios:
cd p ; $(MAKE) bin_atombios.$(LIBEXT)
clean:
rm -f p/*.$(LIBEXT)
+14
View File
@@ -0,0 +1,14 @@
import core.demangle;
import std.stdio;
import std.conv;
import std.string;
extern (C) const(char)* dlangDemangle(const(char)* str) {
return str.to!string().demangle ().toStringz();
//return demangle (str.to!string()).toStringz();
}
/*
void main() {
auto str = D_DEMANGLE("_D1a1bFiZi");
writeln (str);
}
*/
+7 -7
View File
@@ -5,28 +5,28 @@
#include "swf_op_names.h"
char* get_swf_file_type(char compression, char flashVersion) {
char* type = calloc (0, sizeof(SWF_FILE_TYPE) + sizeof(SWF_FILE_TYPE_ZLIB));
char* type = NULL;
switch (compression) {
case ISWF_MAGIC_0_0:
sprintf(type, SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_SWF);
type = r_str_newf (SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_SWF);
break;
case ISWF_MAGIC_0_1:
if (flashVersion < 6) {
sprintf(type, SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_ERROR);
type = r_str_newf (SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_ERROR);
} else {
sprintf(type, SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_ZLIB);
type = r_str_newf (SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_ZLIB);
}
break;
case ISWF_MAGIC_0_2:
if (flashVersion < 13) {
sprintf(type, SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_ERROR);
type = r_str_newf (SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_ERROR);
} else {
sprintf(type, SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_LZMA);
type = r_str_newf (SWF_FILE_TYPE, flashVersion, SWF_FILE_TYPE_LZMA);
}
break;
default:
sprintf (type, SWF_FILE_TYPE, flashVersion, "");
type = r_str_newf (SWF_FILE_TYPE, flashVersion, "");
break;
}
return type;
+1
View File
@@ -4,6 +4,7 @@ ARCHS+=dlang.mk
ARCHS+=swf.mk
ARCHS+=pyc.mk
ARCHS+=pcap.mk
ARCHS+=atombios.mk
# doesnt build yet
#ARCHS+=m68k.mk
#ARCHS+=x86_bea.mk
+14
View File
@@ -0,0 +1,14 @@
OBJ_ATOMBIOS=bin_atombios.o
OBJ_ATOMBIOS+=../../asm/arch/atombios/atombios.o
STATIC_OBJ+=${OBJ_ATOMBIOS}
TARGET_ATOMBIOS=bin_atombios.$(LIBEXT)
ALL_TARGETS+=${TARGET_ATOMBIOS}
CFLAGS+=-I../format/atombios
CFLAGS+=-I../../asm/arch/atombios/
${TARGET_ATOMBIOS}: ${OBJ_ATOMBIOS}
${CC} -g ${CFLAGS} -o ${TARGET_ATOMBIOS} ${OBJ_ATOMBIOS} \
$(R2_CFLAGS) $(R2_LDFLAGS) -lr_util
+211
View File
@@ -0,0 +1,211 @@
/* radare - LGPL3 - Copyright 2018 - damo22 */
#include <r_types.h>
#include <r_util.h>
#include <r_lib.h>
#include <r_bin.h>
#include <r_endian.h>
#include "../../asm/arch/atombios/atombios.h"
static ut16 header;
static ut16 mastercmdoffset;
static ut16 masterdataoffset;
static ut32 cmdtableoffs[N_TABLES_CMD];
static ut32 cmdtablesize[N_TABLES_CMD];
static ut32 datatableoffs[N_TABLES_DATA];
static ut32 datatablesize[N_TABLES_DATA];
static bool check_bytes(const ut8 *buf, ut64 length) {
if (!buf || length < 0x70)
return false;
header = r_read_at_le16(buf, HEADER_OFFSET);
if (memcmp (buf + header + 4, ATOM_MAGIC, 4))
return false;
return true;
}
static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
ut8 i;
if (!check_bytes(buf, sz))
return false;
mastercmdoffset = r_read_at_le16(buf, header + 30) + 4;
masterdataoffset = r_read_at_le16(buf, header + 32) + 4;
for (i = 0; i < N_TABLES_CMD; i++) {
cmdtableoffs[i] = r_read_at_le16 (buf, mastercmdoffset + i * sizeof (ut16));
if (!cmdtableoffs[i]) {
cmdtablesize[i] = 0;
} else {
cmdtablesize[i] = r_read_at_le16 (buf, cmdtableoffs[i]) - 6;
cmdtableoffs[i] += 6;
}
}
for (i = 0; i < N_TABLES_DATA; i++) {
datatableoffs[i] = r_read_at_le16 (buf, masterdataoffset + i * sizeof (ut16));
if (!datatableoffs[i]) {
datatablesize[i] = 0;
} else {
datatablesize[i] = r_read_at_le16 (buf, datatableoffs[i]) - 4;
datatableoffs[i] += 4;
}
}
return true;
}
static bool load(RBinFile *bf) {
const ut8 *bytes = bf ? r_buf_buffer (bf->buf) : NULL;
ut64 sz = bf ? r_buf_size (bf->buf): 0;
if (!bf || !bf->o) {
return false;
}
return load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
}
static RBinInfo* info(RBinFile *arch) {
RBinInfo *ret = R_NEW0 (RBinInfo);
if (!ret) {
return NULL;
}
ret->file = strdup (arch->file);
ret->bclass = strdup ("AtomBIOS");
ret->rclass = strdup ("atombios");
ret->type = strdup ("AtomBIOS Video BIOS ROM");
ret->machine = strdup ("atombios");
ret->os = strdup ("any");
ret->arch = strdup ("atombios");
ret->bits = 32;
ret->has_va = false;
ret->dbg_info = 0;
ret->has_nx = false;
return ret;
}
static void addsym(RList *ret, const char *name, ut64 addr, ut32 size) {
RBinSymbol *ptr = R_NEW0 (RBinSymbol);
if (!ptr) return;
ptr->name = strdup (name? name: "");
ptr->paddr = ptr->vaddr = addr;
ptr->size = size;
ptr->ordinal = 0;
r_list_append (ret, ptr);
}
static RList* symbols(RBinFile *bf) {
ut8 i;
RList *ret = NULL;
if (!(ret = r_list_newf (free))) {
return NULL;
}
/* Data table symbols */
for (i = 0; i < N_TABLES_DATA; i++) {
if (datatableoffs[i])
addsym (ret, index_data_table[i], datatableoffs[i], datatablesize[i]);
}
return ret;
}
static RList* sections(RBinFile *arch) {
ut8 i;
ut16 sz = 0;
RList *ret = NULL;
RBinSection *sect;
if (!(ret = r_list_new()))
return NULL;
/* Command table sections */
for (i = 0; i < N_TABLES_CMD; i++) {
sz = cmdtablesize[i];
if (!(sect = R_NEW0 (RBinSection))) {
return false;
}
if (cmdtableoffs[i]) {
strcpy (sect->name, index_command_table[i]);
sect->paddr = cmdtableoffs[i];
sect->vaddr = cmdtableoffs[i];
sect->size = sz;
sect->vsize = sz;
sect->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE;
r_list_append (ret, sect);
} else {
strcpy (sect->name, "dummy");
sect->paddr = 0;
sect->vaddr = 0;
sect->size = 0;
sect->vsize = 0;
sect->srwx = 0;
r_list_append (ret, sect);
}
}
/* Data table sections */
for (i = 0; i < N_TABLES_DATA; i++) {
sz = datatablesize[i];
if (!(sect = R_NEW0 (RBinSection))) {
return false;
}
if (datatableoffs[i]) {
strcpy (sect->name, index_data_table[i]);
sect->paddr = datatableoffs[i];
sect->vaddr = datatableoffs[i];
sect->size = sz;
sect->vsize = sz;
sect->srwx = R_BIN_SCN_READABLE;
r_list_append (ret, sect);
} else {
strcpy (sect->name, "dummy");
sect->paddr = 0;
sect->vaddr = 0;
sect->size = 0;
sect->vsize = 0;
sect->srwx = 0;
r_list_append (ret, sect);
}
}
return ret;
}
static RList* entries(RBinFile *arch) {
RList *ret = NULL;
RBinAddr *ptr = NULL;
if (!(ret = r_list_new()))
return NULL;
if (!(ptr = R_NEW0 (RBinAddr)))
return ret;
ptr->paddr = cmdtableoffs[0];
ptr->vaddr = cmdtableoffs[0];
r_list_append(ret, ptr);
return ret;
}
RBinPlugin r_bin_plugin_atombios = {
.name = "atombios",
.desc = "AtomBIOS",
.license = "LGPL3",
.load = &load,
.load_bytes = &load_bytes,
.check_bytes = &check_bytes,
.entries = &entries,
.sections = &sections,
.symbols = &symbols,
.info = &info,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bin_plugin_atombios,
.version = R2_VERSION
};
#endif
+2 -3
View File
@@ -19,9 +19,8 @@ static bool check_bytes(const ut8 *buf, ut64 length) {
return version.magic != -1;
}
static void *load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) {
check_bytes (buf, sz);
return R_NOTNULL;
static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) {
return check_bytes (buf, sz);
}
static RBinInfo *info(RBinFile *arch) {
+7 -5
View File
@@ -13,11 +13,13 @@ static int check_bytes(const ut8 *buf, ut64 length);
static char compression;
static char flashVersion;
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
check_bytes (buf, sz);
compression = buf[0];
flashVersion = buf[3];
return R_NOTNULL;
static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
if (check_bytes (buf, sz)) {
compression = buf[0];
flashVersion = buf[3];
return true;
}
return false;
}
static int check_bytes(const ut8 *buf, ut64 length) {
+5
View File
@@ -1,6 +1,9 @@
evm:
$(MAKE) -C p debug_evm.$(LIBEXT)
unicorn:
$(MAKE) -C p debug_unicorn.$(LIBEXT)
all:
$(MAKE) -C p
@@ -9,3 +12,5 @@ clean:
install:
$(MAKE) -C p install
include ../../options.mk
+1 -1
View File
@@ -194,7 +194,7 @@ static int compare_addrs(const void *a1, const void *a2) {
return *(ut64*)a1 - *(ut64*)a2;
}
static int r_debug_evm_breakpoint (void *bp, RBreakpointItem *b, bool set) {
static int r_debug_evm_breakpoint (struct r_bp_t *bp, RBreakpointItem *b, bool set) {
if (!b || !rio->ops_size) {
return false;
}
Loaded 100 of 163 files, more files were not shown because too many files have changed in this diff. Show more