diff --git a/src/plugins/dev-analysis.md b/src/plugins/dev-analysis.md index 85fe54be..22f24193 100644 --- a/src/plugins/dev-analysis.md +++ b/src/plugins/dev-analysis.md @@ -6,8 +6,7 @@ and so on. This is because Rizin requires every architecture plugin to provide also analysis information about every opcode. At the moment the implementation of disassembly and opcodes analysis is separated between two modules - RzAsm and RzAnalysis. Thus, we need to write an analysis plugin too. -The principle is very similar - you just need to create a C file and -corresponding Makefile. +The principle is very similar - you just need to create a C file in `librz/arch/p/analysis/` and declare it in corresponding architecture plugin file `librz/arch/p/arch_mycpu.c`. They structure of RzAnalysis plugin looks like @@ -30,32 +29,6 @@ ESIL, which is enabled in `.esil = true` statement. Thus, `mycpu_op` obliged to corresponding RzAnalysisOp ESIL field for the opcodes. Second important thing for ESIL uplifting and emulation - register profile, like in debugger, which is set within `set_reg_profile` function. -**Makefile** - -```makefile -NAME=analysis_mycpu -RZ_PLUGIN_PATH=$(shell rizin -H RZ_USER_PLUGINS) -LIBEXT=$(shell rizin -H LIBEXT) -CFLAGS=-g -fPIC $(shell pkg-config --cflags rz_analysis) -LDFLAGS=-shared $(shell pkg-config --libs rz_analysis) -OBJS=$(NAME).o -LIB=$(NAME).$(LIBEXT) - -all: $(LIB) - -clean: - rm -f $(LIB) $(OBJS) - -$(LIB): $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(LIB) - -install: - cp -f analysis_mycpu.$(SO_EXT) $(RZ_PLUGIN_PATH) - -uninstall: - rm -f $(RZ_PLUGIN_PATH)/analysis_mycpu.$(SO_EXT) -``` - **analysis_mycpu.c:** This is a dummy example please go check real life examples [in the source](https://github.com/rizinorg/rizin/blob/dev/librz/analysis/p/analysis_snes.c). @@ -124,6 +97,8 @@ RZ_API RzLibStruct rizin_plugin = { #endif ``` +After creating this plugin, include this plugin file in corresponding `librz/arch/p/arch_mycpu.c` + After compiling rizin will list this plugin in the rz-asm output: ``` @@ -134,6 +109,5 @@ Note the `A` just appeared on the left column (a=asm, d=disasm, A=analyze, e=ESI Examples: -* [RzAnalysis plugin for 6502](https://github.com/rizinorg/rizin/commit/64636e9505f9ca8b408958d3c01ac8e3ce254a9b) -* [RzAnalysis plugin for SNES](https://github.com/rizinorg/rizin/commit/60d6e5a1b9d244c7085b22ae8985d00027624b49) - +- [RzAnalysis plugin for Alpha architecture using Capstone](https://github.com/rizinorg/rizin/blob/dev/librz/arch/p/analysis/analysis_alpha_cs.c) +- [RzAnalysis plugin for AVR architecture](https://github.com/rizinorg/rizin/blob/dev/librz/arch/p/analysis/analysis_avr.c) diff --git a/src/plugins/dev-asm.md b/src/plugins/dev-asm.md index 120a3458..52c5e3a0 100644 --- a/src/plugins/dev-asm.md +++ b/src/plugins/dev-asm.md @@ -2,7 +2,8 @@ Rizin has modular architecture, thus adding support for a new architecture is very easy, if you are fluent in C. For various reasons it might be easier to implement it out of the tree. For this we -will need to create single C file, called `asm_mycpu.c` and a meson file for it. +will need two C files mainly, called `asm_mycpu.c` in `librz/arch/p/asm/` , `arch_mycpu.c` in `librz/arch/p/` and declare the asm plugin in architecture plugin file . +Add the newly created architecture plugin file in meson.build The key thing of RzAsm plugin is a structure @@ -25,23 +26,6 @@ and length: static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) ``` -**Meson** - -```bash -project('asm_mycpu', 'c') - -rz_asm_dep = dependency('rz_asm') -plugins_dir = get_option('prefix') / rz_asm_dep.get_variable(pkgconfig: 'plugindir', cmake: 'rz_asm_PLUGINDIR') -message('Plugins install directory: ' + plugins_dir) - -library('asm_mycpu', - ['asm_mycpu.c'], - dependencies: [rz_asm_dep], - install: true, - install_dir: plugins_dir, -) -``` - **asm_mycpu.c** ```c @@ -86,66 +70,75 @@ RZ_API RzLibStruct rizin_plugin = { #endif ``` -After compiling rizin will list this plugin in the rz-asm output: +**arch_mycpu.c** -``` -$ rz-asm -L |grep myc -_d__ _8_32 mycpu LGPL3 MYCPU disassembly plugin +This file is an architecture plugin wrapper that ties together assembler,analysis, and (optionally) parsing components into a single `RzArchPlugin` which is registered using macros from `deprecated_arch_helper.h` + +```c +#include + +#include "analysis/analysis_mycpu.c" +#include "asm/asm_mycpu.c" + +RZ_ARCH_PLUGIN_DEFINE_DEPRECATED(mycpu); // or any other suitable macro from deprecated_arch_helper.h ``` +**If neeeded also add:** + +- `librz/arch/isa/mycpu/` — create this directory with your ISA definition files (instruction tables, opcode maps, disassembler/assembler logic) + +- `librz/arch/opcodes/mycpu.sdb.txt` — optional, human-readable instruction descriptions + ### Moving plugin into the tree Pushing a new architecture into the main branch of rizin requires to modify several files in order to make it fit into the way the rest of plugins are built. -__List of affected files:__ +**List of affected files:** -* `librz/asm/p/asm_mycpu.c` -That's where most of our code will be, the key part is to declare a `RzAsmPlugin` containing a valid `disassemble` -field, a function pointer to the actual disassembler function. +- `librz/arch/p/asm_mycpu.c` + That's where most of our code will be, the key part is to declare a `RzAsmPlugin` containing a valid `disassemble` + field, a function pointer to the actual disassembler function. + +- `librz/arch/meson.build` + The build is handled by meson, we have to add our plugin to the list of things to be compiled : -* `librz/asm/meson.build` -The build is handled by meson, we have to add our plugin to the list of things to be compiled : ```diff -@@ -49,6 +49,7 @@ asm_plugins_list = [ +@@ -49,6 +49,7 @@ arch_plugins_list = [ 'x86_nz', 'xap', 'xcore_cs', + 'mycpu', ] -@@ -129,6 +130,7 @@ rz_asm_sources = [ - #'p/asm_x86_vm.c', - 'p/asm_xap.c', - 'p/asm_xcore_cs.c', -+ 'p/asm_mycpu.c', - #'arch/6502/6502dis.c', - 'arch/amd29k/amd29k.c', - #'arch/8051/8051_disas.c', -+ 'arch/mycpu/mycpu_disas.c', - 'arch/arm/armass.c', - -@@ -129,6 +130,7 @@ rz_asm_inc = [ -+ 'arch/mycpu', +@@ -129,6 +130,7 @@ arch_plugin_sources = [ + #'p/arch_x86_vm.c', + 'p/arch_xap.c', + 'p/arch_xcore_cs.c', ++ 'p/arch_mycpu.c', +] + +@@ -129,6 +131,8 @@ arch_isa_sources = [ ++ 'isa/mycpu/disas.c', ++ 'isa/mycpu/mycpu.c', // any other related files if exist ] ``` -* `librz/include/rz_asm.h` -Make Rizin aware of our plugin by defining our struct: -```diff -@@ -265,6 +265,7 @@ extern RzAsmPlugin rz_asm_plugin_xcore_cs; - extern RzAsmPlugin rz_asm_plugin_xtensa; - extern RzAsmPlugin rz_asm_plugin_z80; - extern RzAsmPlugin rz_asm_plugin_pyc; -+extern RzAsmPlugin rz_asm_plugin_mycpu; +After compiling rizin will list this plugin in the rz-asm output: - #endif ``` +$ rz-asm -L |grep myc +_d__ _8_32 mycpu LGPL3 MYCPU disassembly plugin +``` + +Check out how AVR and Alpha architectures have been implemented by having a look at the following files -Check out how the NIOS II CPU disassembly plugin was implemented by reading those commits: +[RzAsm plugin for AVR](https://github.com/rizinorg/rizin/blob/dev/librz/arch/p/asm/asm_avr.c) -[The RzAsm plugin](https://github.com/rizinorg/rizin/commit/933dc0ef6ddfe44c88bbb261165bf8f8b531476b) +[AVR arch plugin](https://github.com/rizinorg/rizin/blob/dev/librz/arch/p/arch_avr.c) -[The RzAnalysis plugin](https://github.com/rizinorg/rizin/commit/ad430f0d52fbe933e0830c49ee607e9b0e4ac8f2) +[RzAsm plugin for Alpha using Capstone](https://github.com/rizinorg/rizin/blob/dev/librz/arch/p/asm/asm_alpha_cs.c) +[Alpha arch plugin](https://github.com/rizinorg/rizin/blob/dev/librz/arch/p/arch_alpha.c) +Note: Create a disassembly parser plugin if needed under `librz/arch/p/parse/` which will be used when specific evaluable variables are set such as `asm.pseudo`, `asm.sub.jmp`, `asm.sub.reg`, `asm.sub.rel` etc