Change the "anal" abbreviation to "Analysis" in Code (#117)

This commit is contained in:
Anton Kochkov 2020-12-06 12:25:27 -06:00 committed by GitHub
parent e53e87d8c7
commit 041d73dce3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
467 changed files with 15068 additions and 15068 deletions

View file

@ -1,9 +1,9 @@
* @wargio @XVilka @kazarmy @thestr4ng3r @ret2libc
*.js @wargio
CODEOWNERS @wargio @XVilka @kazarmy @thestr4ng3r @ret2libc
librz/anal/ @thestr4ng3r
librz/anal/esil* @wargio
librz/anal/xrefs.c @ret2libc
librz/analysis/ @thestr4ng3r
librz/analysis/esil* @wargio
librz/analysis/xrefs.c @ret2libc
librz/arch/gb/ @wargio
librz/asm/ @wargio
librz/asm/p/x86_* @ret2libc

View file

@ -82,7 +82,7 @@ rules to make the git history more readable and consistent:
### Commit message hashtag list:
* ##anal - analysis related
* ##analysis - analysis related
* ##asm - assembler
* ##bin - binary parsing
* ##build - build fixes/changes

View file

@ -14,7 +14,7 @@ BUILDSEC=$(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+__%H:%M:%S" 2>/dev/null ||
else
BUILDSEC=$(shell date "+__%H:%M:%S")
endif
DATADIRS=librz/cons/d librz/flag/d librz/bin/d librz/asm/d librz/syscall/d librz/magic/d librz/anal/d
DATADIRS=librz/cons/d librz/flag/d librz/bin/d librz/asm/d librz/syscall/d librz/magic/d librz/analysis/d
USE_ZIP=YES
ZIP=zip
@ -141,7 +141,7 @@ windist:
mkdir -p "${WINDIST}/share/rizin/${VERSION}/sysregs"
cp -f librz/sysregs/d/*.sdb "${WINDIST}/share/rizin/${VERSION}/sysregs"
mkdir -p "${WINDIST}/share/rizin/${VERSION}/fcnsign"
cp -f librz/anal/d/*.sdb "${WINDIST}/share/rizin/${VERSION}/fcnsign"
cp -f librz/analysis/d/*.sdb "${WINDIST}/share/rizin/${VERSION}/fcnsign"
mkdir -p "${WINDIST}/share/rizin/${VERSION}/opcodes"
cp -f librz/asm/d/*.sdb "${WINDIST}/share/rizin/${VERSION}/opcodes"
mkdir -p "${WINDIST}/share/rizin/${VERSION}/flag"
@ -294,7 +294,7 @@ deinstall uninstall:
cd binrz && ${MAKE} uninstall
cd shlr && ${MAKE} uninstall
cd librz/syscall/d && ${MAKE} uninstall
cd librz/anal/d && ${MAKE} uninstall
cd librz/analysis/d && ${MAKE} uninstall
@echo
@echo "Run 'make purge' to also remove installed files from previous versions of rz"
@echo
@ -435,7 +435,7 @@ meson-symstall: symstall-sdb
ln -fs $(PWD)/build/librz/parse/librz_parse.$(EXT_SO) ${L}/librz_parse.$(EXT_SO)
ln -fs $(PWD)/build/librz/lang/librz_lang.$(EXT_SO) ${L}/librz_lang.$(EXT_SO)
ln -fs $(PWD)/build/librz/asm/librz_asm.$(EXT_SO) ${L}/librz_asm.$(EXT_SO)
ln -fs $(PWD)/build/librz/anal/librz_anal.$(EXT_SO) ${L}/librz_anal.$(EXT_SO)
ln -fs $(PWD)/build/librz/analysis/librz_analysis.$(EXT_SO) ${L}/librz_analysis.$(EXT_SO)
ln -fs $(PWD)/build/librz/egg/librz_egg.$(EXT_SO) ${L}/librz_egg.$(EXT_SO)
ln -fs $(PWD)/build/librz/debug/librz_debug.$(EXT_SO) ${L}/librz_debug.$(EXT_SO)
ln -fs $(PWD)/build/librz/core/librz_core.$(EXT_SO) ${L}/librz_core.$(EXT_SO)

View file

@ -36,7 +36,7 @@ LDFLAGS+=-L../../librz/asm -lrz_asm
LDFLAGS+=-L../../librz/lang -lrz_lang
LDFLAGS+=-L../../librz/egg -lrz_egg
LDFLAGS+=-L../../librz/core -lrz_core
LDFLAGS+=-L../../librz/anal -lrz_anal
LDFLAGS+=-L../../librz/analysis -lrz_analysis
LDFLAGS+=-L../../librz/crypto -lrz_crypto
LDFLAGS+=-L../../librz/flag -lrz_flag
LDFLAGS+=-L../../librz/parse -lrz_parse

View file

@ -4,7 +4,7 @@ ifeq ($(ISPPC),)
BIN=librz
ISLIB=1
BINDEPS=rz_core rz_parse rz_search rz_cons rz_config
BINDEPS+=rz_bin rz_debug rz_anal rz_reg rz_bp rz_io
BINDEPS+=rz_bin rz_debug rz_analysis rz_reg rz_bp rz_io
BINDEPS+=rz_lang rz_asm rz_syscall rz_hash rz_crypto
BINDEPS+=rz_magic rz_socket rz_flag rz_util rz_egg

View file

@ -1,6 +1,6 @@
BIN=rizin
BINDEPS=rz_core rz_parse rz_search rz_cons rz_config
BINDEPS+=rz_bin rz_debug rz_anal rz_reg rz_bp rz_io
BINDEPS+=rz_bin rz_debug rz_analysis rz_reg rz_bp rz_io
BINDEPS+=rz_lang rz_asm rz_syscall rz_hash rz_main
BINDEPS+=rz_magic rz_socket rz_flag rz_egg rz_crypto rz_util

View file

@ -15,7 +15,7 @@ executable('rizin', 'rizin.c',
rz_bp_dep,
rz_reg_dep,
rz_syscall_dep,
rz_anal_dep,
rz_analysis_dep,
rz_parse_dep,
rz_egg_dep,
rz_search_dep,

View file

@ -4,7 +4,7 @@ executable('rz-asm', 'rz-asm.c',
rz_main_dep,
rz_util_dep,
rz_asm_dep,
rz_anal_dep,
rz_analysis_dep,
rz_crypto_dep,
rz_syscall_dep,
rz_hash_dep

View file

@ -1,7 +1,7 @@
BIN=rz-bin
BINDEPS=rz_magic rz_core rz_bin rz_egg rz_cons rz_main
BINDEPS+=rz_config rz_io rz_flag rz_asm
BINDEPS+=rz_debug rz_hash rz_lang rz_anal rz_parse rz_bp rz_reg
BINDEPS+=rz_debug rz_hash rz_lang rz_analysis rz_parse rz_bp rz_reg
BINDEPS+=rz_search rz_syscall rz_socket rz_magic rz_crypto rz_util
include ../rules.mk

View file

@ -1,6 +1,6 @@
BIN=rz-diff
BINDEPS=rz_core rz_config rz_cons rz_search rz_anal
BINDEPS=rz_core rz_config rz_cons rz_search rz_analysis
BINDEPS+=rz_bin rz_debug rz_io rz_asm rz_hash rz_crypto
BINDEPS+=rz_socket rz_flag rz_lang rz_reg rz_bp rz_parse
BINDEPS+=rz_syscall rz_magic rz_util rz_parse rz_egg rz_main

View file

@ -8,7 +8,7 @@ executable('rz-diff', 'rz-diff.c',
rz_cons_dep,
rz_core_dep,
rz_bin_dep,
rz_anal_dep,
rz_analysis_dep,
rz_asm_dep,
rz_hash_dep,
rz_config_dep

View file

@ -1,6 +1,6 @@
BIN=rz-find
BINDEPS=rz_search rz_io rz_asm rz_anal rz_reg rz_cons rz_lang rz_crypto
BINDEPS=rz_search rz_io rz_asm rz_analysis rz_reg rz_cons rz_lang rz_crypto
BINDEPS+=rz_socket rz_parse rz_util rz_syscall rz_flag rz_hash rz_main
include ../rules.mk

View file

@ -1,7 +1,7 @@
BIN=rz-gg
BINDEPS=rz_egg rz_syscall rz_asm
BINDEPS+=rz_core rz_hash rz_debug rz_config rz_bp rz_crypto rz_cons
BINDEPS+=rz_lang rz_parse rz_anal rz_reg rz_flag rz_crypto
BINDEPS+=rz_lang rz_parse rz_analysis rz_reg rz_flag rz_crypto
BINDEPS+=rz_bin rz_search rz_io rz_socket
BINDEPS+=rz_magic rz_util rz_main

View file

@ -1,5 +1,5 @@
BIN=rz-sign
BINDEPS=rz_anal rz_util rz_core rz_search rz_main
BINDEPS=rz_analysis rz_util rz_core rz_search rz_main
LDFLAGS+=$(LINK)
include ../../librz/main/deps.mk

2
configure vendored
View file

@ -742,7 +742,7 @@ for A in ${ENVWORDS} ; do
SEDFLAGS="${SEDFLAGS}s,@${A}@,${VAR},g;"
done
SEDFLAGS="${SEDFLAGS}'"
for A in ./config-user.mk librz/include/rz_userconf.h pkgcfg/rz_io.pc pkgcfg/rz_magic.pc pkgcfg/rz_asm.pc pkgcfg/rz_bin.pc pkgcfg/rz_anal.pc pkgcfg/rz_hash.pc pkgcfg/rz_cons.pc pkgcfg/rz_core.pc pkgcfg/rz_lang.pc pkgcfg/rz_socket.pc pkgcfg/rz_debug.pc pkgcfg/rz_reg.pc pkgcfg/rz_config.pc pkgcfg/rz_flag.pc pkgcfg/rz_syscall.pc pkgcfg/rz_util.pc pkgcfg/rz_search.pc pkgcfg/rz_bp.pc pkgcfg/rz_parse.pc pkgcfg/rz_egg.pc pkgcfg/rz_crypto.pc ; do # SUBDIRS
for A in ./config-user.mk librz/include/rz_userconf.h pkgcfg/rz_io.pc pkgcfg/rz_magic.pc pkgcfg/rz_asm.pc pkgcfg/rz_bin.pc pkgcfg/rz_analysis.pc pkgcfg/rz_hash.pc pkgcfg/rz_cons.pc pkgcfg/rz_core.pc pkgcfg/rz_lang.pc pkgcfg/rz_socket.pc pkgcfg/rz_debug.pc pkgcfg/rz_reg.pc pkgcfg/rz_config.pc pkgcfg/rz_flag.pc pkgcfg/rz_syscall.pc pkgcfg/rz_util.pc pkgcfg/rz_search.pc pkgcfg/rz_bp.pc pkgcfg/rz_parse.pc pkgcfg/rz_egg.pc pkgcfg/rz_crypto.pc ; do # SUBDIRS
if [ -f "${VPATH}/${A}.acr" ]; then
SD_TARGET=${A}
else

View file

@ -253,7 +253,7 @@ SUBDIRS ./config-user.mk
pkgcfg/rz_magic.pc
pkgcfg/rz_asm.pc
pkgcfg/rz_bin.pc
pkgcfg/rz_anal.pc
pkgcfg/rz_analysis.pc
pkgcfg/rz_hash.pc
pkgcfg/rz_cons.pc
pkgcfg/rz_core.pc

View file

@ -13,7 +13,7 @@ Attribute list
Note that you will substitute `x` for the calling convention name you will use.
`default.cc=x` : used to set the default calling convention used for all functions in `RAnal` instance for which this key is set, string of this calling convention `"x"` will be returned for every call of `RZ_API const char *r_anal_cc_default(RAnal *anal)`.
`default.cc=x` : used to set the default calling convention used for all functions in `RzAnalysis` instance for which this key is set, string of this calling convention `"x"` will be returned for every call of `RZ_API const char *r_analysis_cc_default(RzAnalysis *analysis)`.
`x=cc`: used to initialize calling convention (think of it as their is calling convention called x).
@ -32,8 +32,8 @@ File Path
In order to integrate the calling convention profile you created with the rizin source, few set of conventions should be followed:
- Store the unparsed sdb file in `path-to-rizin-source/librz/anal/d`.
- Store the unparsed sdb file in `path-to-rizin-source/librz/analysis/d`.
- If you want the sdb to be loaded for specific architecture the file name should follow this convention `cc-arch-bits`, for example to create profile that loads automatically for x86 arch with 16 bits call the file `cc-x86-16`
- In the file `path-to-rizin-source/librz/anal/d/makefile` add entry `F+= cc-arch-bits` with desired arch and bits and you should be ready to go.
- In the file `path-to-rizin-source/librz/analysis/d/makefile` add entry `F+= cc-arch-bits` with desired arch and bits and you should be ready to go.

View file

@ -29,10 +29,10 @@ well as setting up profiles. (??profiles??)
The functionality lives in the following files:
(?? why so many files? can this be simplified??)
librz/reg/arena.c // ?? used by anal and debugger
librz/reg/arena.c // ?? used by analysis and debugger
librz/reg/cond.c // condition registers
librz/reg/double.c // support for double-precision floating point numbers
librz/reg/profile.c // ?? used by anal and debugger
librz/reg/profile.c // ?? used by analysis and debugger
librz/reg/reg.c // top-level register specific code (all of rizin)
librz/reg/value.c // dealing with register values
librz/reg/t/p.c // test code for printing general-purpose registers
@ -76,7 +76,7 @@ The main top-level debugger functionality lives here. It aims to abstract away
the common code flow and integration into Rizin while delegating more nuanced
system interactions to plug-ins.
librz/debug/arg.c // used by the anal engine (??)
librz/debug/arg.c // used by the analysis engine (??)
librz/debug/desc.c // code for handling file descriptors inside an inferior
librz/debug/esil.c // ESIL related debugging code (??)
librz/debug/map.c // top-level API for dealing with memory maps

View file

@ -234,16 +234,16 @@ Disassembly example:
│ │││ 0x100001147 48394a38 rdx,56,+,[8],rcx,==,cz,?=
```
Rizin anal ESIL code example
Rizin analysis ESIL code example
==============================
As an example implementation of ESIL analysis for the AVR family of
microcontrollers there is a `avr_op` function in `/librz/anal/p/anal_avr.c`
microcontrollers there is a `avr_op` function in `/librz/analysis/p/analysis_avr.c`
which contains information on how the instructions are expressed in ESIL and
other opcode information such as cycle counts per instruction:
````
static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
static int avr_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len) {
short ofst;
int d, r, k;
(...)

View file

@ -1,725 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_anal.h>
#include <rz_util.h>
#include <rz_list.h>
#include <rz_io.h>
#include <config.h>
RZ_LIB_VERSION(rz_anal);
static RzAnalPlugin *anal_static_plugins[] = {
RZ_ANAL_STATIC_PLUGINS
};
RZ_API void rz_anal_set_limits(RzAnal *anal, ut64 from, ut64 to) {
free (anal->limit);
anal->limit = RZ_NEW0 (RzAnalRange);
if (anal->limit) {
anal->limit->from = from;
anal->limit->to = to;
}
}
RZ_API void rz_anal_unset_limits(RzAnal *anal) {
RZ_FREE (anal->limit);
}
static void meta_unset_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnal *anal = container_of (s, RzAnal, meta_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
rz_meta_space_unset_for (anal, se->data.unset.space);
}
static void meta_count_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnal *anal = container_of (s, RzAnal, meta_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
se->res = rz_meta_space_count_for (anal, se->data.count.space);
}
static void zign_unset_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnal *anal = container_of (s, RzAnal, zign_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
rz_sign_space_unset_for (anal, se->data.unset.space);
}
static void zign_count_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnal *anal = container_of (s, RzAnal, zign_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
se->res = rz_sign_space_count_for (anal, se->data.count.space);
}
static void zign_rename_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnal *anal = container_of (s, RzAnal, zign_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
rz_sign_space_rename_for (anal, se->data.rename.space,
se->data.rename.oldname, se->data.rename.newname);
}
void rz_anal_hint_storage_init(RzAnal *a);
void rz_anal_hint_storage_fini(RzAnal *a);
static void rz_meta_item_fini(RzAnalMetaItem *item) {
free (item->str);
}
static void rz_meta_item_free(void *_item) {
if (_item) {
RzAnalMetaItem *item = _item;
rz_meta_item_fini (item);
free (item);
}
}
RZ_API RzAnal *rz_anal_new(void) {
int i;
RzAnal *anal = RZ_NEW0 (RzAnal);
if (!anal) {
return NULL;
}
if (!rz_str_constpool_init (&anal->constpool)) {
free (anal);
return NULL;
}
anal->bb_tree = NULL;
anal->ht_addr_fun = ht_up_new0 ();
anal->ht_name_fun = ht_pp_new0 ();
anal->os = strdup (RZ_SYS_OS);
anal->esil_goto_limit = RZ_ANAL_ESIL_GOTO_LIMIT;
anal->opt.nopskip = true; // skip nops in code analysis
anal->opt.hpskip = false; // skip `mov reg,reg` and `lea reg,[reg]`
anal->gp = 0LL;
anal->sdb = sdb_new0 ();
anal->cpp_abi = RZ_ANAL_CPP_ABI_ITANIUM;
anal->opt.depth = 32;
anal->opt.noncode = false; // do not analyze data by default
rz_spaces_init (&anal->meta_spaces, "CS");
rz_event_hook (anal->meta_spaces.event, RZ_SPACE_EVENT_UNSET, meta_unset_for, NULL);
rz_event_hook (anal->meta_spaces.event, RZ_SPACE_EVENT_COUNT, meta_count_for, NULL);
rz_spaces_init (&anal->zign_spaces, "zs");
rz_event_hook (anal->zign_spaces.event, RZ_SPACE_EVENT_UNSET, zign_unset_for, NULL);
rz_event_hook (anal->zign_spaces.event, RZ_SPACE_EVENT_COUNT, zign_count_for, NULL);
rz_event_hook (anal->zign_spaces.event, RZ_SPACE_EVENT_RENAME, zign_rename_for, NULL);
rz_anal_hint_storage_init (anal);
rz_interval_tree_init (&anal->meta, rz_meta_item_free);
anal->sdb_types = sdb_ns (anal->sdb, "types", 1);
anal->sdb_fmts = sdb_ns (anal->sdb, "spec", 1);
anal->sdb_cc = sdb_ns (anal->sdb, "cc", 1);
anal->sdb_zigns = sdb_ns (anal->sdb, "zigns", 1);
anal->sdb_classes = sdb_ns (anal->sdb, "classes", 1);
anal->sdb_classes_attrs = sdb_ns (anal->sdb_classes, "attrs", 1);
anal->zign_path = strdup ("");
anal->cb_printf = (PrintfCallback) printf;
(void)rz_anal_pin_init (anal);
(void)rz_anal_xrefs_init (anal);
anal->diff_thbb = RZ_ANAL_THRESHOLDBB;
anal->diff_thfcn = RZ_ANAL_THRESHOLDFCN;
anal->syscall = rz_syscall_new ();
rz_io_bind_init (anal->iob);
rz_flag_bind_init (anal->flb);
anal->reg = rz_reg_new ();
anal->last_disasm_reg = NULL;
anal->stackptr = 0;
anal->lineswidth = 0;
anal->fcns = rz_list_newf (rz_anal_function_free);
anal->leaddrs = NULL;
anal->imports = rz_list_newf (free);
rz_anal_set_bits (anal, 32);
anal->plugins = rz_list_newf ((RzListFree) rz_anal_plugin_free);
if (anal->plugins) {
for (i = 0; anal_static_plugins[i]; i++) {
rz_anal_add (anal, anal_static_plugins[i]);
}
}
return anal;
}
RZ_API void rz_anal_plugin_free (RzAnalPlugin *p) {
if (p && p->fini) {
p->fini (NULL);
}
}
void __block_free_rb(RBNode *node, void *user);
RZ_API RzAnal *rz_anal_free(RzAnal *a) {
if (!a) {
return NULL;
}
/* TODO: Free anals here */
rz_list_free (a->fcns);
ht_up_free (a->ht_addr_fun);
ht_pp_free (a->ht_name_fun);
set_u_free (a->visited);
rz_anal_hint_storage_fini (a);
rz_interval_tree_fini (&a->meta);
free (a->cpu);
free (a->os);
free (a->zign_path);
rz_list_free (a->plugins);
rz_rbtree_free (a->bb_tree, __block_free_rb, NULL);
rz_spaces_fini (&a->meta_spaces);
rz_spaces_fini (&a->zign_spaces);
rz_anal_pin_fini (a);
rz_syscall_free (a->syscall);
rz_reg_free (a->reg);
ht_up_free (a->dict_refs);
ht_up_free (a->dict_xrefs);
rz_list_free (a->leaddrs);
sdb_free (a->sdb);
if (a->esil) {
rz_anal_esil_free (a->esil);
a->esil = NULL;
}
free (a->last_disasm_reg);
rz_list_free (a->imports);
rz_str_constpool_fini (&a->constpool);
free (a);
return NULL;
}
RZ_API void rz_anal_set_user_ptr(RzAnal *anal, void *user) {
anal->user = user;
}
RZ_API int rz_anal_add(RzAnal *anal, RzAnalPlugin *foo) {
if (foo->init) {
foo->init (anal->user);
}
rz_list_append (anal->plugins, foo);
return true;
}
RZ_API bool rz_anal_use(RzAnal *anal, const char *name) {
RzListIter *it;
RzAnalPlugin *h;
if (anal) {
rz_list_foreach (anal->plugins, it, h) {
if (!h->name || strcmp (h->name, name)) {
continue;
}
#if 0
// regression happening here for asm.emu
if (anal->cur && anal->cur == h) {
return true;
}
#endif
anal->cur = h;
rz_anal_set_reg_profile (anal);
return true;
}
}
return false;
}
RZ_API char *rz_anal_get_reg_profile(RzAnal *anal) {
return (anal && anal->cur && anal->cur->get_reg_profile)
? anal->cur->get_reg_profile (anal) : NULL;
}
// deprecate.. or at least reuse get_reg_profile...
RZ_API bool rz_anal_set_reg_profile(RzAnal *anal) {
bool ret = false;
if (anal && anal->cur && anal->cur->set_reg_profile) {
ret = anal->cur->set_reg_profile (anal);
} else {
char *p = rz_anal_get_reg_profile (anal);
if (p && *p) {
rz_reg_set_profile_string (anal->reg, p);
ret = true;
}
free (p);
}
return ret;
}
RZ_API bool rz_anal_set_triplet(RzAnal *anal, const char *os, const char *arch, int bits) {
rz_return_val_if_fail (anal, false);
if (!os || !*os) {
os = RZ_SYS_OS;
}
if (!arch || !*arch) {
arch = anal->cur? anal->cur->arch: RZ_SYS_ARCH;
}
if (bits < 1) {
bits = anal->bits;
}
free (anal->os);
anal->os = strdup (os);
rz_anal_set_bits (anal, bits);
return rz_anal_use (anal, arch);
}
// copypasta from core/cbin.c
static void sdb_concat_by_path(Sdb *s, const char *path) {
Sdb *db = sdb_new (0, path, 0);
sdb_merge (s, db);
sdb_close (db);
sdb_free (db);
}
RZ_API bool rz_anal_set_os(RzAnal *anal, const char *os) {
Sdb *types = anal->sdb_types;
const char *dir_prefix = rz_sys_prefix (NULL);
const char *dbpath = sdb_fmt (RZ_JOIN_3_PATHS ("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"),
dir_prefix, os);
if (rz_file_exists (dbpath)) {
sdb_concat_by_path (types, dbpath);
}
return rz_anal_set_triplet (anal, os, NULL, -1);
}
RZ_API bool rz_anal_set_bits(RzAnal *anal, int bits) {
switch (bits) {
case 8:
case 16:
case 27:
case 32:
case 64:
if (anal->bits != bits) {
anal->bits = bits;
rz_anal_set_reg_profile (anal);
}
return true;
}
return false;
}
RZ_API void rz_anal_set_cpu(RzAnal *anal, const char *cpu) {
free (anal->cpu);
anal->cpu = cpu ? strdup (cpu) : NULL;
int v = rz_anal_archinfo (anal, RZ_ANAL_ARCHINFO_ALIGN);
if (v != -1) {
anal->pcalign = v;
}
}
RZ_API int rz_anal_set_big_endian(RzAnal *anal, int bigend) {
anal->big_endian = bigend;
anal->reg->big_endian = bigend;
return true;
}
RZ_API ut8 *rz_anal_mask(RzAnal *anal, int size, const ut8 *data, ut64 at) {
RzAnalOp *op = NULL;
ut8 *ret = NULL;
int oplen, idx = 0;
if (!data) {
return NULL;
}
if (anal->cur && anal->cur->anal_mask) {
return anal->cur->anal_mask (anal, size, data, at);
}
if (!(op = rz_anal_op_new ())) {
return NULL;
}
if (!(ret = malloc (size))) {
rz_anal_op_free (op);
return NULL;
}
memset (ret, 0xff, size);
while (idx < size) {
if ((oplen = rz_anal_op (anal, op, at, data + idx, size - idx, RZ_ANAL_OP_MASK_BASIC)) < 1) {
break;
}
if ((op->ptr != UT64_MAX || op->jump != UT64_MAX) && op->nopcode != 0) {
memset (ret + idx + op->nopcode, 0, oplen - op->nopcode);
}
idx += oplen;
at += oplen;
}
rz_anal_op_free (op);
return ret;
}
RZ_API void rz_anal_trace_bb(RzAnal *anal, ut64 addr) {
RzAnalBlock *bbi;
RzAnalFunction *fcni;
RzListIter *iter2;
fcni = rz_anal_get_fcn_in (anal, addr, 0);
if (fcni) {
rz_list_foreach (fcni->bbs, iter2, bbi) {
if (addr >= bbi->addr && addr < (bbi->addr + bbi->size)) {
bbi->traced = true;
break;
}
}
}
}
RZ_API void rz_anal_colorize_bb(RzAnal *anal, ut64 addr, ut32 color) {
RzAnalBlock *bbi;
bbi = rz_anal_bb_from_offset (anal, addr);
if (bbi) {
bbi->colorize = color;
}
}
RZ_API RzList* rz_anal_get_fcns (RzAnal *anal) {
// avoid received to free this thing
anal->fcns->free = NULL;
return anal->fcns;
}
RZ_API RzAnalOp *rz_anal_op_hexstr(RzAnal *anal, ut64 addr, const char *str) {
RzAnalOp *op = RZ_NEW0 (RzAnalOp);
if (!op) {
return NULL;
}
ut8 *buf = calloc (1, strlen (str) + 1);
if (!buf) {
free (op);
return NULL;
}
int len = rz_hex_str2bin (str, buf);
rz_anal_op (anal, op, addr, buf, len, RZ_ANAL_OP_MASK_BASIC);
free (buf);
return op;
}
RZ_API bool rz_anal_op_is_eob(RzAnalOp *op) {
if (op->eob) {
return true;
}
switch (op->type) {
case RZ_ANAL_OP_TYPE_JMP:
case RZ_ANAL_OP_TYPE_UJMP:
case RZ_ANAL_OP_TYPE_RJMP:
case RZ_ANAL_OP_TYPE_IJMP:
case RZ_ANAL_OP_TYPE_IRJMP:
case RZ_ANAL_OP_TYPE_CJMP:
case RZ_ANAL_OP_TYPE_RET:
case RZ_ANAL_OP_TYPE_TRAP:
return true;
default:
return false;
}
}
RZ_API void rz_anal_purge(RzAnal *anal) {
rz_anal_hint_clear (anal);
rz_interval_tree_fini (&anal->meta);
rz_interval_tree_init (&anal->meta, rz_meta_item_free);
sdb_reset (anal->sdb_types);
sdb_reset (anal->sdb_zigns);
sdb_reset (anal->sdb_classes);
sdb_reset (anal->sdb_classes_attrs);
rz_anal_pin_fini (anal);
rz_anal_pin_init (anal);
sdb_reset (anal->sdb_cc);
rz_list_free (anal->fcns);
anal->fcns = rz_list_newf (rz_anal_function_free);
rz_anal_purge_imports (anal);
}
RZ_API int rz_anal_archinfo(RzAnal *anal, int query) {
rz_return_val_if_fail (anal, -1);
switch (query) {
case RZ_ANAL_ARCHINFO_MIN_OP_SIZE:
case RZ_ANAL_ARCHINFO_MAX_OP_SIZE:
case RZ_ANAL_ARCHINFO_ALIGN:
if (anal->cur && anal->cur->archinfo) {
return anal->cur->archinfo (anal, query);
}
break;
}
return -1;
}
static bool __nonreturn_print_commands(void *p, const char *k, const char *v) {
RzAnal *anal = (RzAnal *)p;
if (!strncmp (v, "func", strlen ("func") + 1)) {
char *query = sdb_fmt ("func.%s.noreturn", k);
if (sdb_bool_get (anal->sdb_types, query, NULL)) {
anal->cb_printf ("tnn %s\n", k);
}
}
if (!strncmp (k, "addr.", 5)) {
anal->cb_printf ("tna 0x%s %s\n", k + 5, v);
}
return true;
}
static bool __nonreturn_print(void *p, const char *k, const char *v) {
RzAnal *anal = (RzAnal *)p;
if (!strncmp (k, "func.", 5) && strstr (k, ".noreturn")) {
char *s = strdup (k + 5);
char *d = strchr (s, '.');
if (d) {
*d = 0;
}
anal->cb_printf ("%s\n", s);
free (s);
}
if (!strncmp (k, "addr.", 5)) {
char *off;
if (!(off = strdup (k + 5))) {
return 1;
}
char *ptr = strstr (off, ".noreturn");
if (ptr) {
*ptr = 0;
anal->cb_printf ("0x%s\n", off);
}
free (off);
}
return true;
}
RZ_API void rz_anal_noreturn_list(RzAnal *anal, int mode) {
switch (mode) {
case 1:
case '*':
case 'r':
sdb_foreach (anal->sdb_types, __nonreturn_print_commands, anal);
break;
default:
sdb_foreach (anal->sdb_types, __nonreturn_print, anal);
break;
}
}
#define K_NORET_ADDR(x) sdb_fmt ("addr.%"PFMT64x".noreturn", x)
#define K_NORET_FUNC(x) sdb_fmt ("func.%s.noreturn", x)
RZ_API bool rz_anal_noreturn_add(RzAnal *anal, const char *name, ut64 addr) {
const char *tmp_name = NULL;
Sdb *TDB = anal->sdb_types;
char *fnl_name = NULL;
if (addr != UT64_MAX) {
if (sdb_bool_set (TDB, K_NORET_ADDR (addr), true, 0)) {
RzAnalFunction *fcn = rz_anal_get_function_at (anal, addr);
if (fcn) {
fcn->is_noreturn = true;
}
return true;
}
}
if (name && *name) {
tmp_name = name;
} else {
RzAnalFunction *fcn = rz_anal_get_fcn_in (anal, addr, -1);
RzFlagItem *fi = anal->flb.get_at (anal->flb.f, addr, false);
if (!fcn && !fi) {
eprintf ("Can't find Function at given address\n");
return false;
}
tmp_name = fcn ? fcn->name: fi->name;
if (fcn) {
fcn->is_noreturn = true;
}
}
if (rz_type_func_exist (TDB, tmp_name)) {
fnl_name = strdup (tmp_name);
} else if (!(fnl_name = rz_type_func_guess (TDB, (char *)tmp_name))) {
if (addr == UT64_MAX) {
if (name) {
sdb_bool_set (TDB, K_NORET_FUNC (name), true, 0);
} else {
eprintf ("Can't find prototype for: %s\n", tmp_name);
}
} else {
eprintf ("Can't find prototype for: %s\n", tmp_name);
}
//return false;
}
if (fnl_name) {
sdb_bool_set (TDB, K_NORET_FUNC (fnl_name), true, 0);
free (fnl_name);
}
return true;
}
RZ_API bool rz_anal_noreturn_drop(RzAnal *anal, const char *expr) {
Sdb *TDB = anal->sdb_types;
expr = rz_str_trim_head_ro (expr);
const char *fcnname = NULL;
if (!strncmp (expr, "0x", 2)) {
ut64 n = rz_num_math (NULL, expr);
sdb_unset (TDB, K_NORET_ADDR (n), 0);
RzAnalFunction *fcn = rz_anal_get_fcn_in (anal, n, -1);
if (!fcn) {
// eprintf ("can't find function at 0x%"PFMT64x"\n", n);
return false;
}
fcnname = fcn->name;
} else {
fcnname = expr;
}
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
#if 0
char *tmp;
// unnsecessary checks, imho the noreturn db should be pretty simple to allow forward and custom declarations without having to define the function prototype before
if (rz_type_func_exist (TDB, fcnname)) {
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
return true;
} else if ((tmp = rz_type_func_guess (TDB, (char *)fcnname))) {
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
free (tmp);
return true;
}
eprintf ("Can't find prototype for %s in types database", fcnname);
#endif
return false;
}
static bool rz_anal_noreturn_at_name(RzAnal *anal, const char *name) {
if (sdb_bool_get (anal->sdb_types, K_NORET_FUNC(name), NULL)) {
return true;
}
char *tmp = rz_type_func_guess (anal->sdb_types, (char *)name);
if (tmp) {
if (sdb_bool_get (anal->sdb_types, K_NORET_FUNC (tmp), NULL)) {
free (tmp);
return true;
}
free (tmp);
}
if (rz_str_startswith (name, "reloc.")) {
return rz_anal_noreturn_at_name (anal, name + 6);
}
return false;
}
RZ_API bool rz_anal_noreturn_at_addr(RzAnal *anal, ut64 addr) {
return sdb_bool_get (anal->sdb_types, K_NORET_ADDR (addr), NULL);
}
static bool noreturn_recurse(RzAnal *anal, ut64 addr) {
RzAnalOp op = {0};
ut8 bbuf[0x10] = {0};
ut64 recurse_addr = UT64_MAX;
if (!anal->iob.read_at (anal->iob.io, addr, bbuf, sizeof (bbuf))) {
eprintf ("Couldn't read buffer\n");
return false;
}
if (rz_anal_op (anal, &op, addr, bbuf, sizeof (bbuf), RZ_ANAL_OP_MASK_BASIC | RZ_ANAL_OP_MASK_VAL) < 1) {
return false;
}
switch (op.type & RZ_ANAL_OP_TYPE_MASK) {
case RZ_ANAL_OP_TYPE_JMP:
if (op.jump == UT64_MAX) {
recurse_addr = op.ptr;
} else {
recurse_addr = op.jump;
}
break;
case RZ_ANAL_OP_TYPE_UCALL:
case RZ_ANAL_OP_TYPE_RCALL:
case RZ_ANAL_OP_TYPE_ICALL:
case RZ_ANAL_OP_TYPE_IRCALL:
recurse_addr = op.ptr;
break;
case RZ_ANAL_OP_TYPE_CCALL:
case RZ_ANAL_OP_TYPE_CALL:
recurse_addr = op.jump;
break;
}
if (recurse_addr == UT64_MAX || recurse_addr == addr) {
return false;
}
return rz_anal_noreturn_at (anal, recurse_addr);
}
RZ_API bool rz_anal_noreturn_at(RzAnal *anal, ut64 addr) {
if (!addr || addr == UT64_MAX) {
return false;
}
if (rz_anal_noreturn_at_addr (anal, addr)) {
return true;
}
/* XXX this is very slow */
RzAnalFunction *f = rz_anal_get_function_at (anal, addr);
if (f) {
if (rz_anal_noreturn_at_name (anal, f->name)) {
return true;
}
}
RzFlagItem *fi = anal->flag_get (anal->flb.f, addr);
if (fi) {
if (rz_anal_noreturn_at_name (anal, fi->realname ? fi->realname : fi->name)) {
return true;
}
}
if (anal->recursive_noreturn) {
return noreturn_recurse (anal, addr);
}
return false;
}
RZ_API void rz_anal_bind(RzAnal *anal, RzAnalBind *b) {
if (b) {
b->anal = anal;
b->get_fcn_in = rz_anal_get_fcn_in;
b->get_hint = rz_anal_hint_get;
}
}
RZ_API RzList *rz_anal_preludes(RzAnal *anal) {
if (anal->cur && anal->cur->preludes ) {
return anal->cur->preludes (anal);
}
return NULL;
}
RZ_API bool rz_anal_is_prelude(RzAnal *anal, const ut8 *data, int len) {
RzList *l = rz_anal_preludes (anal);
if (l) {
RzSearchKeyword *kw;
RzListIter *iter;
rz_list_foreach (l, iter, kw) {
int ks = kw->keyword_length;
if (len >= ks && !memcmp (data, kw->bin_keyword, ks)) {
rz_list_free (l);
return true;
}
}
rz_list_free (l);
}
return false;
}
RZ_API void rz_anal_add_import(RzAnal *anal, const char *imp) {
RzListIter *it;
const char *eimp;
rz_list_foreach (anal->imports, it, eimp) {
if (!strcmp (eimp, imp)) {
return;
}
}
char *cimp = strdup (imp);
if (!cimp) {
return;
}
rz_list_push (anal->imports, cimp);
}
RZ_API void rz_anal_remove_import(RzAnal *anal, const char *imp) {
RzListIter *it;
const char *eimp;
rz_list_foreach (anal->imports, it, eimp) {
if (!strcmp (eimp, imp)) {
rz_list_delete (anal->imports, it);
return;
}
}
}
RZ_API void rz_anal_purge_imports(RzAnal *anal) {
rz_list_purge (anal->imports);
}

View file

@ -1,2 +0,0 @@
int hexagon_anal_instruction(HexInsn *hi, RzAnalOp *op);

File diff suppressed because it is too large Load diff

View file

@ -1,9 +0,0 @@
OBJ_6502=anal_6502.o
STATIC_OBJ+=${OBJ_6502}
TARGET_6502=anal_6502.${EXT_SO}
ALL_TARGETS+=${TARGET_6502}
${TARGET_6502}: ${OBJ_6502}
${CC} $(call libname,anal_6502) ${LDFLAGS} ${CFLAGS} -o anal_6502.${EXT_SO} ${OBJ_6502}

View file

@ -1,9 +0,0 @@
OBJ_6502_CS=anal_6502_cs.o
STATIC_OBJ+=${OBJ_6502_CS}
TARGET_6502_CS=anal_6502_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_6502_CS}
${TARGET_6502_CS}: ${OBJ_6502_CS}
${CC} $(call libname,anal_6502_cs) ${LDFLAGS} ${CFLAGS} -o anal_6502_cs.${EXT_SO} ${OBJ_6502_CS}

View file

@ -1,10 +0,0 @@
OBJ_AMD29K=anal_amd29k.o ../../asm/arch/amd29k/amd29k.o
STATIC_OBJ+=${OBJ_AMD29K}
TARGET_AMD29K=anal_amd29k.${EXT_SO}
ALL_TARGETS+=${TARGET_AMD29K}
${TARGET_AMD29K}: ${OBJ_AMD29K}
${CC} ${CFLAGS} $(call libname,anal_amd29k) $(CS_CFLAGS) \
-o anal_amd29k.${EXT_SO} ${OBJ_AMD29K} $(CS_LDFLAGS)

View file

@ -1,9 +0,0 @@
OBJ_ARC=anal_arc.o
STATIC_OBJ+=${OBJ_ARC}
TARGET_ARC=anal_arc.${EXT_SO}
ALL_TARGETS+=${TARGET_ARC}
${TARGET_ARC}: ${OBJ_ARC}
${CC} $(call libname,anal_arc) ${LDFLAGS} ${CFLAGS} -o anal_arc.${EXT_SO} ${OBJ_ARC}

View file

@ -1,9 +0,0 @@
OBJ_AVR=anal_avr.o
STATIC_OBJ+=${OBJ_AVR}
TARGET_AVR=anal_avr.${EXT_SO}
ALL_TARGETS+=${TARGET_AVR}
${TARGET_AVR}: ${OBJ_AVR}
${CC} $(call libname,anal_avr) ${CFLAGS} -o anal_avr.${EXT_SO} ${OBJ_AVR}

View file

@ -1,9 +0,0 @@
OBJ_BF=anal_bf.o
STATIC_OBJ+=${OBJ_BF}
TARGET_BF=anal_bf.${EXT_SO}
ALL_TARGETS+=${TARGET_BF}
${TARGET_BF}: ${OBJ_BF}
${CC} $(call libname,anal_bf) ${LDFLAGS} ${CFLAGS} -o anal_bf.${EXT_SO} ${OBJ_BF}

View file

@ -1,9 +0,0 @@
OBJ_CHIP8=anal_chip8.o
STATIC_OBJ+=${OBJ_CHIP8}
TARGET_CHIP8=anal_chip8.${EXT_SO}
ALL_TARGETS+=${TARGET_CHIP8}
${TARGET_CHIP8}: ${OBJ_CHIP8}
${CC} $(call libname,anal_chip8) ${CFLAGS} -o anal_chip8.${EXT_SO} ${OBJ_CHIP8}

View file

@ -1,10 +0,0 @@
OBJ_CRIS=anal_cris.o
STATIC_OBJ+=$(OBJ_CRIS)
TARGET_CRIS=anal_cris.${EXT_SO}
ALL_TARGETS+=${TARGET_CRIS}
${TARGET_CRIS}: ${OBJ_CRIS}
${CC} ${CFLAGS} $(call libname,anal_cris) \
-o anal_cris.${EXT_SO} ${OBJ_CRIS}

View file

@ -1,9 +0,0 @@
OBJ_DALVIK=anal_dalvik.o
STATIC_OBJ+=${OBJ_DALVIK}
TARGET_DALVIK=anal_dalvik.${EXT_SO}
ALL_TARGETS+=${TARGET_DALVIK}
${TARGET_DALVIK}: ${OBJ_DALVIK}
${CC} $(call libname,anal_dalvik) ${LDFLAGS} ${CFLAGS} -o anal_dalvik.${EXT_SO} ${OBJ_DALVIK}

View file

@ -1,9 +0,0 @@
OBJ_I4004=anal_i4004.o
STATIC_OBJ+=${OBJ_I4004}
TARGET_I4004=anal_i4004.${EXT_SO}
ALL_TARGETS+=${TARGET_I4004}
${TARGET_I4004}: ${OBJ_I4004}
${CC} $(call libname,anal_i4004) ${CFLAGS} -o anal_i4004.${EXT_SO} ${OBJ_I4004}

View file

@ -1,9 +0,0 @@
OBJ_I8080=anal_i8080.o
STATIC_OBJ+=${OBJ_I8080}
TARGET_I8080=anal_i8080.${EXT_SO}
ALL_TARGETS+=${TARGET_I8080}
${TARGET_I8080}: ${OBJ_I8080}
${CC} $(call libname,anal_z80) ${LDFLAGS} ${CFLAGS} -o anal_i8080.${EXT_SO} ${OBJ_I8080}

View file

@ -1,13 +0,0 @@
OBJ_M680X_CS=anal_m680x_cs.o
include ${CURDIR}capstone.mk
STATIC_OBJ+=$(OBJ_M680X_CS)
TARGET_M680X_CS=anal_m680x_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_M680X_CS}
${TARGET_M680X_CS}: ${OBJ_M680X_CS}
${CC} ${CFLAGS} $(call libname,anal_m680x_cs) $(CS_CFLAGS) \
-o anal_m680x_cs.${EXT_SO} ${OBJ_M680X_CS} $(CS_LDFLAGS)

View file

@ -1,13 +0,0 @@
OBJ_M68K_CS=anal_m68k_cs.o
include ${CURDIR}capstone.mk
STATIC_OBJ+=$(OBJ_M68K_CS)
TARGET_M68K_CS=anal_m68k_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_M68K_CS}
${TARGET_M68K_CS}: ${OBJ_M68K_CS}
${CC} ${CFLAGS} $(call libname,anal_m68k_cs) $(CS_CFLAGS) \
-o anal_m68k_cs.${EXT_SO} ${OBJ_M68K_CS} $(CS_LDFLAGS)

View file

@ -1,9 +0,0 @@
OBJ_MALBOLGE=anal_malbolge.o
STATIC_OBJ+=${OBJ_MALBOLGE}
TARGET_MALBOLGE=anal_malbolge.${EXT_SO}
ALL_TARGETS+=${TARGET_MALBOLGE}
${TARGET_MALBOLGE}: ${OBJ_MALBOLGE}
${CC} $(call libname,anal_malbolge) ${LDFLAGS} ${CFLAGS} -o anal_malbolge.${EXT_SO} ${OBJ_MALBOLGE}

View file

@ -1,11 +0,0 @@
OBJ_MCORE=anal_mcore.o ../../asm/arch/mcore/mcore.o
STATIC_OBJ+=${OBJ_MCORE}
TARGET_MCORE=anal_mcore.${EXT_SO}
ALL_TARGETS+=${TARGET_MCORE}
${TARGET_MCORE}: ${OBJ_MCORE}
${CC} ${CFLAGS} $(call libname,anal_mcore) $(CS_LDFLAGS) \
-o anal_mcore.${EXT_SO} ${OBJ_MCORE}

View file

@ -1,12 +0,0 @@
OBJ_MIPS_CS=anal_mips_cs.o
include $(CURDIR)capstone.mk
STATIC_OBJ+=$(OBJ_MIPS_CS)
TARGET_MIPS_CS=anal_mips_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_MIPS_CS}
${TARGET_MIPS_CS}: ${OBJ_MIPS_CS}
${CC} ${CFLAGS} $(call libname,anal_mips_cs) $(CS_CFLAGS) \
-o anal_mips_cs.${EXT_SO} ${OBJ_MIPS_CS} $(CS_LDFLAGS)

View file

@ -1,10 +0,0 @@
OBJ_NIOS2=anal_nios2.o
STATIC_OBJ+=${OBJ_NIOS2}
TARGET_NIOS2=anal_nios2.${EXT_SO}
ALL_TARGETS+=${TARGET_NIOS2}
${TARGET_NIOS2}: ${OBJ_NIOS2}
${CC} $(call libname,anal_nios2) ${LDFLAGS} ${CFLAGS} \
-o anal_nios2.${EXT_SO} ${OBJ_NIOS2}

View file

@ -1,10 +0,0 @@
OBJ_NULL=anal_null.o
STATIC_OBJ+=${OBJ_NULL}
TARGET_NULL=anal_null.${EXT_SO}
ALL_TARGETS+=${TARGET_NULL}
${TARGET_NULL}: ${OBJ_NULL}
${CC} $(call libname,anal_null) ${LDFLAGS} \
${CFLAGS} -o anal_null.${EXT_SO} ${OBJ_NULL}

View file

@ -1,12 +0,0 @@
OBJ_OR1K=anal_or1k.o
OBJ_OR1K+=../../asm/arch/or1k/or1k_disas.o
CFLAGS+=-I../asm/arch/or1k
STATIC_OBJ+=${OBJ_OR1K}
TARGET_OR1K=anal_or1k.${EXT_SO}
ALL_TARGETS+=${TARGET_OR1K}
${TARGET_OR1K}: ${OBJ_OR1K}
${CC} $(call libname,anal_nios2) ${LDFLAGS} ${CFLAGS} \
-o anal_or1k.${EXT_SO} ${OBJ_OR1K}

View file

@ -1,10 +0,0 @@
OBJ_PIC=anal_pic.o
STATIC_OBJ+=$(OBJ_PIC)
OBJ_PIC+=../../asm/arch/pic/pic_midrange.o
TARGET_PIC=anal_pic.$(EXT_SO)
ALL_TARTGETS+=$(TARGET_PIC)
$(TARGET_PIC): $(OBJ_PIC)
$(CC) $(call libname,anal_pic) ${LDFLAGS} ${CFLAGS} -o anal_pic.$(EXT_SO) $(OBJ_PIC)

View file

@ -1,12 +0,0 @@
OBJ_PPC_CS=anal_ppc_cs.o ../../asm/arch/ppc/libvle/vle.o
include $(CURDIR)capstone.mk
STATIC_OBJ+=${OBJ_PPC_CS}
TARGET_PPC_CS=anal_ppc_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_PPC_CS}
${TARGET_PPC_CS}: ${OBJ_PPC_CS}
${CC} ${CFLAGS} $(call libname,anal_ppc_cs) $(CS_CFLAGS) \
-o anal_ppc_cs.${EXT_SO} ${OBJ_PPC_CS} $(CS_LDFLAGS)

View file

@ -1,10 +0,0 @@
OBJ_PPC=anal_ppc_gnu.o
STATIC_OBJ+=${OBJ_PPC}
TARGET_PPC=anal_ppc_gnu.${EXT_SO}
ALL_TARGETS+=${TARGET_PPC}
${TARGET_PPC}: ${OBJ_PPC}
${CC} $(call libname,anal_ppc_gnu) ${CFLAGS} \
-o anal_ppc_gnu.${EXT_SO} ${OBJ_PPC}

View file

@ -1,9 +0,0 @@
OBJ_RISCV=anal_riscv.o
STATIC_OBJ+=${OBJ_RISCV}
TARGET_RISCV=anal_riscv.${EXT_SO}
ALL_TARGETS+=${TARGET_RISCV}
${TARGET_RISCV}: ${OBJ_RISCV}
${CC} $(call libname,anal_RISCV) ${LDFLAGS} ${CFLAGS} -o anal_riscv.${EXT_SO} ${OBJ_RISCV}

View file

@ -1,12 +0,0 @@
OBJ_RISCV_CS=anal_riscv_cs.o
include $(CURDIR)capstone.mk
STATIC_OBJ+=$(OBJ_RISCV_CS)
TARGET_RISCV_CS=anal_riscv_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_RISCV_CS}
${TARGET_RISCV_CS}: ${OBJ_RISCV_CS}
${CC} ${CFLAGS} $(call libname,anal_riscv_cs) $(CS_CFLAGS) \
-o anal_riscv_cs.${EXT_SO} ${OBJ_RISCV_CS} $(CS_LDFLAGS)

View file

@ -1,10 +0,0 @@
OBJ_SH=anal_sh.o
STATIC_OBJ+=${OBJ_SH}
TARGET_SH=anal_sh.${EXT_SO}
ALL_TARGETS+=${TARGET_SH}
${TARGET_SH}: ${OBJ_SH}
${CC} $(call libname,anal_sh) ${LDFLAGS} \
${CFLAGS} -o anal_sh.${EXT_SO} ${OBJ_SH}

View file

@ -1,9 +0,0 @@
OBJ_SNES=anal_snes.o
STATIC_OBJ+=${OBJ_SNES}
TARGET_SNES=anal_snes.${EXT_SO}
ALL_TARGETS+=${TARGET_SNES}
${TARGET_SNES}: ${OBJ_SNES}
${CC} $(call libname,anal_snes) ${LDFLAGS} ${CFLAGS} -o anal_snes.${EXT_SO} ${OBJ_SNES}

View file

@ -1,12 +0,0 @@
OBJ_SPARC_CS=anal_sparc_cs.o
include ${CURDIR}capstone.mk
STATIC_OBJ+=$(OBJ_SPARC_CS)
TARGET_SPARC_CS=anal_sparc_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_SPARC_CS}
${TARGET_SPARC_CS}: ${OBJ_SPARC_CS}
${CC} ${CFLAGS} $(call libname,anal_sparc_cs) $(CS_CFLAGS) \
-o anal_sparc_cs.${EXT_SO} ${OBJ_SPARC_CS} $(CS_LDFLAGS)

View file

@ -1,9 +0,0 @@
OBJ_SPARC=anal_sparc_gnu.o
STATIC_OBJ+=${OBJ_SPARC}
TARGET_SPARC=anal_sparc_gnu.${EXT_SO}
ALL_TARGETS+=${TARGET_SPARC}
${TARGET_SPARC}: ${OBJ_SPARC}
${CC} $(call libname,anal_sparc_gnu) ${CFLAGS} -o anal_sparc_gnu.${EXT_SO} ${OBJ_SPARC}

View file

@ -1,13 +0,0 @@
OBJ_SYSTEMZ_CS=anal_sysz.o
include p/capstone.mk
STATIC_OBJ+=${OBJ_SYSTEMZ_CS}
TARGET_SYSTEMZ_CS=anal_sysz.${EXT_SO}
ALL_TARGETS+=${TARGET_SYSTEMZ_CS}
${TARGET_SYSTEMZ_CS}: ${OBJ_SYSTEMZ_CS}
${CC} ${CFLAGS} $(call libname,anal_sysz) $(CS_LDFLAGS) \
-o anal_sysz.${EXT_SO} ${OBJ_SYSTEMZ_CS}

View file

@ -1,12 +0,0 @@
OBJ_TMS3264C64X_CS=anal_tms320c64x.o
include ${CURDIR}capstone.mk
STATIC_OBJ+=$(OBJ_TMS3264C64X_CS)
TARGET_TMS3264C64X_CS=anal_tms320c64x.${EXT_SO}
ALL_TARGETS+=${TARGET_TMS3264C64X_CS}
${TARGET_TMS3264C64X_CS}: ${OBJ_TMS3264C64X_CS}
${CC} ${CFLAGS} $(call libname,anal_tms320c64x) $(CS_CFLAGS) \
-o anal_tms320c64x.${EXT_SO} ${OBJ_TMS3264C64X_CS} $(CS_LDFLAGS)

View file

@ -1,10 +0,0 @@
OBJ_TRICORE=anal_tricore.o
STATIC_OBJ+=${OBJ_TRICORE}
TARGET_TRICORE=anal_tricore.${EXT_SO}
ALL_TARGETS+=${TARGET_TRICORE}
${TARGET_TRICORE}: ${OBJ_TRICORE}
${CC} $(call libname,anal_tricore) ${LDFLAGS} ${CFLAGS} \
-o $(TARGET_TRICORE) $(OBJ_TRICORE)

View file

@ -1,9 +0,0 @@
OBJ_VAX=anal_vax.o
STATIC_OBJ+=${OBJ_VAX}
TARGET_VAX=anal_vax.${EXT_SO}
ALL_TARGETS+=${TARGET_VAX}
${TARGET_VAX}: ${OBJ_VAX}
${CC} $(call libname,anal_vax) ${CFLAGS} -o anal_vax.${EXT_SO} ${OBJ_VAX}

View file

@ -1,10 +0,0 @@
OBJ_WS=anal_ws.o
STATIC_OBJ+=${OBJ_WS}
TARGET_WS=anal_ws.${EXT_SO}
ALL_TARGETS+=${TARGET_WS}
${TARGET_WS}: ${OBJ_WS}
${CC} $(call libname,anal_ws) ${LDFLAGS} ${CFLAGS} \
-o anal_ws.${EXT_SO} ${OBJ_WS}

View file

@ -1,13 +0,0 @@
OBJ_X86_CS=anal_x86_cs.o
include $(CURDIR)capstone.mk
STATIC_OBJ+=$(OBJ_X86_CS)
TARGET_X86_CS=anal_x86_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_X86_CS}
${TARGET_X86_CS}: ${OBJ_X86_CS}
${CC} ${CFLAGS} $(call libname,anal_x86_cs) $(CS_CFLAGS) \
-o anal_x86_cs.${EXT_SO} ${OBJ_X86_CS} $(CS_LDFLAGS)

View file

@ -1,9 +0,0 @@
OBJ_XAP=anal_xap.o
STATIC_OBJ+=${OBJ_XAP}
TARGET_XAP=anal_xap.${EXT_SO}
ALL_TARGETS+=${TARGET_XAP}
${TARGET_XAP}: ${OBJ_XAP}
${CC} $(call libname,anal_xap) ${CFLAGS} -o anal_xap.${EXT_SO} ${OBJ_XAP}

View file

@ -1,12 +0,0 @@
OBJ_XCORE_CS=anal_xcore_cs.o
include p/capstone.mk
STATIC_OBJ+=${OBJ_XCORE_CS}
TARGET_XCORE_CS=anal_xcore_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_XCORE_CS}
${TARGET_XCORE_CS}: ${OBJ_XCORE_CS}
${CC} ${CFLAGS} $(call libname,anal_xcore_cs) $(CS_CFLAGS) \
-o anal_xcore_cs.${EXT_SO} ${OBJ_XCORE_CS} $(CS_LDFLAGS)

View file

@ -1,10 +0,0 @@
OBJ_XTENSA=anal_xtensa.o
STATIC_OBJ+=${OBJ_XTENSA}
TARGET_XTENSA=anal_xtensa.${EXT_SO}
ALL_TARGETS+=$(TARGET_XTENSA)
$(TARGET_XTENSA): $(OBJ_XTENSA)
$(CC) $(call libname,anal_xtensa) -I$(LTOP)/asm/arch/include/ \
$(LDFLAGS) $(CFLAGS) -o anal_xtensa.$(EXT_SO) $(OBJ_XTENSA)

View file

@ -1,10 +0,0 @@
OBJ_Z80=anal_z80.o
STATIC_OBJ+=${OBJ_Z80}
TARGET_Z80=anal_z80.${EXT_SO}
ALL_TARGETS+=${TARGET_Z80}
${TARGET_Z80}: ${OBJ_Z80}
${CC} $(call libname,anal_z80) ${LDFLAGS} ${CFLAGS} \
-o anal_z80.${EXT_SO} ${OBJ_Z80}

View file

@ -1,54 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_anal.h>
static RzAnalSwitchOp *__switch_op_new(void) {
RzAnalSwitchOp * swop = RZ_NEW0 (RzAnalSwitchOp);
if (swop) {
swop->cases = rz_list_new ();
if (!swop->cases) {
free (swop);
return NULL;
}
swop->cases->free = (void *)free;
swop->min_val = swop->def_val = swop->max_val = 0;
}
return swop;
}
RZ_API RzAnalSwitchOp *rz_anal_switch_op_new(ut64 addr, ut64 min_val, ut64 max_val, ut64 def_val) {
RzAnalSwitchOp *swop = __switch_op_new ();
if (swop) {
swop->addr = addr;
swop->min_val = min_val;
swop->def_val = def_val;
swop->max_val = max_val;
}
return swop;
}
RZ_API RzAnalCaseOp * rz_anal_case_op_new(ut64 addr, ut64 val, ut64 jump) {
RzAnalCaseOp *c = RZ_NEW0 (RzAnalCaseOp);
if (c) {
c->addr = addr;
c->value = val;
c->jump = jump;
}
return c;
}
RZ_API void rz_anal_switch_op_free(RzAnalSwitchOp * swop) {
if (swop) {
rz_list_free (swop->cases);
free (swop);
}
}
RZ_API RzAnalCaseOp* rz_anal_switch_op_add_case(RzAnalSwitchOp * swop, ut64 addr, ut64 value, ut64 jump) {
rz_return_val_if_fail (swop && addr != UT64_MAX, NULL);
RzAnalCaseOp * caseop = rz_anal_case_op_new (addr, value, jump);
if (caseop) {
rz_list_append (swop->cases, caseop);
}
return caseop;
}

View file

@ -4,7 +4,7 @@ EXTRA_TARGETS+=do
EXTRA_CLEAN=doclean
CFLAGS+=-I..
NAME=rz_anal
NAME=rz_analysis
RZ_DEPS=rz_util rz_reg rz_syscall rz_search rz_cons rz_flag rz_hash rz_crypto rz_parse
CFLAGS+=-DRZ_PLUGIN_INCORE -Iarch -I$(TOP)/shlr
CFLAGS+=-I$(LTOP)/asm/arch/include
@ -25,18 +25,18 @@ all: plugins
plugins: ${LIBSO} ${LIBAR}
@${MAKE} -C p all
include ${STATIC_ANAL_PLUGINS}
include ${STATIC_ANALYSIS_PLUGINS}
STATIC_OBJS=$(addprefix $(LTOP)/anal/p/,$(STATIC_OBJ))
STATIC_OBJS=$(addprefix $(LTOP)/analysis/p/,$(STATIC_OBJ))
OBJLIBS=meta.o reflines.o op.o fcn.o bb.o var.o block.o
OBJLIBS+=cond.o value.o cc.o class.o diff.o type.o type_pdb.o dwarf_process.o
OBJLIBS+=hint.o anal.o data.o xrefs.o esil.o sign.o
OBJLIBS+=hint.o analysis.o data.o xrefs.o esil.o sign.o
OBJLIBS+=switch.o cycles.o esil_dfg.o
OBJLIBS+=esil_sources.o esil_interrupt.o esil_cfg.o
OBJLIBS+=esil_stats.o esil_trace.o flirt.o labels.o
OBJLIBS+=esil2reil.o pin.o vtable.o rtti.o
OBJLIBS+=rtti_msvc.o rtti_itanium.o jmptbl.o function.o
OBJLIBS+=serialize_anal.o
OBJLIBS+=serialize_analysis.o
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/xtensa-modules.o
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/xtensa-isa.o
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/elf32-xtensa.o

725
librz/analysis/analysis.c Normal file
View file

@ -0,0 +1,725 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_analysis.h>
#include <rz_util.h>
#include <rz_list.h>
#include <rz_io.h>
#include <config.h>
RZ_LIB_VERSION(rz_analysis);
static RzAnalysisPlugin *anal_static_plugins[] = {
RZ_ANALYSIS_STATIC_PLUGINS
};
RZ_API void rz_analysis_set_limits(RzAnalysis *analysis, ut64 from, ut64 to) {
free (analysis->limit);
analysis->limit = RZ_NEW0 (RzAnalysisRange);
if (analysis->limit) {
analysis->limit->from = from;
analysis->limit->to = to;
}
}
RZ_API void rz_analysis_unset_limits(RzAnalysis *analysis) {
RZ_FREE (analysis->limit);
}
static void meta_unset_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnalysis *analysis = container_of (s, RzAnalysis, meta_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
rz_meta_space_unset_for (analysis, se->data.unset.space);
}
static void meta_count_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnalysis *analysis = container_of (s, RzAnalysis, meta_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
se->res = rz_meta_space_count_for (analysis, se->data.count.space);
}
static void zign_unset_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnalysis *analysis = container_of (s, RzAnalysis, zign_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
rz_sign_space_unset_for (analysis, se->data.unset.space);
}
static void zign_count_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnalysis *analysis = container_of (s, RzAnalysis, zign_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
se->res = rz_sign_space_count_for (analysis, se->data.count.space);
}
static void zign_rename_for(RzEvent *ev, int type, void *user, void *data) {
RzSpaces *s = (RzSpaces *)ev->user;
RzAnalysis *analysis = container_of (s, RzAnalysis, zign_spaces);
RzSpaceEvent *se = (RzSpaceEvent *)data;
rz_sign_space_rename_for (analysis, se->data.rename.space,
se->data.rename.oldname, se->data.rename.newname);
}
void rz_analysis_hint_storage_init(RzAnalysis *a);
void rz_analysis_hint_storage_fini(RzAnalysis *a);
static void rz_meta_item_fini(RzAnalysisMetaItem *item) {
free (item->str);
}
static void rz_meta_item_free(void *_item) {
if (_item) {
RzAnalysisMetaItem *item = _item;
rz_meta_item_fini (item);
free (item);
}
}
RZ_API RzAnalysis *rz_analysis_new(void) {
int i;
RzAnalysis *analysis = RZ_NEW0 (RzAnalysis);
if (!analysis) {
return NULL;
}
if (!rz_str_constpool_init (&analysis->constpool)) {
free (analysis);
return NULL;
}
analysis->bb_tree = NULL;
analysis->ht_addr_fun = ht_up_new0 ();
analysis->ht_name_fun = ht_pp_new0 ();
analysis->os = strdup (RZ_SYS_OS);
analysis->esil_goto_limit = RZ_ANAL_ESIL_GOTO_LIMIT;
analysis->opt.nopskip = true; // skip nops in code analysis
analysis->opt.hpskip = false; // skip `mov reg,reg` and `lea reg,[reg]`
analysis->gp = 0LL;
analysis->sdb = sdb_new0 ();
analysis->cpp_abi = RZ_ANAL_CPP_ABI_ITANIUM;
analysis->opt.depth = 32;
analysis->opt.noncode = false; // do not analyze data by default
rz_spaces_init (&analysis->meta_spaces, "CS");
rz_event_hook (analysis->meta_spaces.event, RZ_SPACE_EVENT_UNSET, meta_unset_for, NULL);
rz_event_hook (analysis->meta_spaces.event, RZ_SPACE_EVENT_COUNT, meta_count_for, NULL);
rz_spaces_init (&analysis->zign_spaces, "zs");
rz_event_hook (analysis->zign_spaces.event, RZ_SPACE_EVENT_UNSET, zign_unset_for, NULL);
rz_event_hook (analysis->zign_spaces.event, RZ_SPACE_EVENT_COUNT, zign_count_for, NULL);
rz_event_hook (analysis->zign_spaces.event, RZ_SPACE_EVENT_RENAME, zign_rename_for, NULL);
rz_analysis_hint_storage_init (analysis);
rz_interval_tree_init (&analysis->meta, rz_meta_item_free);
analysis->sdb_types = sdb_ns (analysis->sdb, "types", 1);
analysis->sdb_fmts = sdb_ns (analysis->sdb, "spec", 1);
analysis->sdb_cc = sdb_ns (analysis->sdb, "cc", 1);
analysis->sdb_zigns = sdb_ns (analysis->sdb, "zigns", 1);
analysis->sdb_classes = sdb_ns (analysis->sdb, "classes", 1);
analysis->sdb_classes_attrs = sdb_ns (analysis->sdb_classes, "attrs", 1);
analysis->zign_path = strdup ("");
analysis->cb_printf = (PrintfCallback) printf;
(void)rz_analysis_pin_init (analysis);
(void)rz_analysis_xrefs_init (analysis);
analysis->diff_thbb = RZ_ANAL_THRESHOLDBB;
analysis->diff_thfcn = RZ_ANAL_THRESHOLDFCN;
analysis->syscall = rz_syscall_new ();
rz_io_bind_init (analysis->iob);
rz_flag_bind_init (analysis->flb);
analysis->reg = rz_reg_new ();
analysis->last_disasm_reg = NULL;
analysis->stackptr = 0;
analysis->lineswidth = 0;
analysis->fcns = rz_list_newf (rz_analysis_function_free);
analysis->leaddrs = NULL;
analysis->imports = rz_list_newf (free);
rz_analysis_set_bits (analysis, 32);
analysis->plugins = rz_list_newf ((RzListFree) rz_analysis_plugin_free);
if (analysis->plugins) {
for (i = 0; anal_static_plugins[i]; i++) {
rz_analysis_add (analysis, anal_static_plugins[i]);
}
}
return analysis;
}
RZ_API void rz_analysis_plugin_free (RzAnalysisPlugin *p) {
if (p && p->fini) {
p->fini (NULL);
}
}
void __block_free_rb(RBNode *node, void *user);
RZ_API RzAnalysis *rz_analysis_free(RzAnalysis *a) {
if (!a) {
return NULL;
}
/* TODO: Free anals here */
rz_list_free (a->fcns);
ht_up_free (a->ht_addr_fun);
ht_pp_free (a->ht_name_fun);
set_u_free (a->visited);
rz_analysis_hint_storage_fini (a);
rz_interval_tree_fini (&a->meta);
free (a->cpu);
free (a->os);
free (a->zign_path);
rz_list_free (a->plugins);
rz_rbtree_free (a->bb_tree, __block_free_rb, NULL);
rz_spaces_fini (&a->meta_spaces);
rz_spaces_fini (&a->zign_spaces);
rz_analysis_pin_fini (a);
rz_syscall_free (a->syscall);
rz_reg_free (a->reg);
ht_up_free (a->dict_refs);
ht_up_free (a->dict_xrefs);
rz_list_free (a->leaddrs);
sdb_free (a->sdb);
if (a->esil) {
rz_analysis_esil_free (a->esil);
a->esil = NULL;
}
free (a->last_disasm_reg);
rz_list_free (a->imports);
rz_str_constpool_fini (&a->constpool);
free (a);
return NULL;
}
RZ_API void rz_analysis_set_user_ptr(RzAnalysis *analysis, void *user) {
analysis->user = user;
}
RZ_API int rz_analysis_add(RzAnalysis *analysis, RzAnalysisPlugin *foo) {
if (foo->init) {
foo->init (analysis->user);
}
rz_list_append (analysis->plugins, foo);
return true;
}
RZ_API bool rz_analysis_use(RzAnalysis *analysis, const char *name) {
RzListIter *it;
RzAnalysisPlugin *h;
if (analysis) {
rz_list_foreach (analysis->plugins, it, h) {
if (!h->name || strcmp (h->name, name)) {
continue;
}
#if 0
// regression happening here for asm.emu
if (analysis->cur && analysis->cur == h) {
return true;
}
#endif
analysis->cur = h;
rz_analysis_set_reg_profile (analysis);
return true;
}
}
return false;
}
RZ_API char *rz_analysis_get_reg_profile(RzAnalysis *analysis) {
return (analysis && analysis->cur && analysis->cur->get_reg_profile)
? analysis->cur->get_reg_profile (analysis) : NULL;
}
// deprecate.. or at least reuse get_reg_profile...
RZ_API bool rz_analysis_set_reg_profile(RzAnalysis *analysis) {
bool ret = false;
if (analysis && analysis->cur && analysis->cur->set_reg_profile) {
ret = analysis->cur->set_reg_profile (analysis);
} else {
char *p = rz_analysis_get_reg_profile (analysis);
if (p && *p) {
rz_reg_set_profile_string (analysis->reg, p);
ret = true;
}
free (p);
}
return ret;
}
RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const char *arch, int bits) {
rz_return_val_if_fail (analysis, false);
if (!os || !*os) {
os = RZ_SYS_OS;
}
if (!arch || !*arch) {
arch = analysis->cur? analysis->cur->arch: RZ_SYS_ARCH;
}
if (bits < 1) {
bits = analysis->bits;
}
free (analysis->os);
analysis->os = strdup (os);
rz_analysis_set_bits (analysis, bits);
return rz_analysis_use (analysis, arch);
}
// copypasta from core/cbin.c
static void sdb_concat_by_path(Sdb *s, const char *path) {
Sdb *db = sdb_new (0, path, 0);
sdb_merge (s, db);
sdb_close (db);
sdb_free (db);
}
RZ_API bool rz_analysis_set_os(RzAnalysis *analysis, const char *os) {
Sdb *types = analysis->sdb_types;
const char *dir_prefix = rz_sys_prefix (NULL);
const char *dbpath = sdb_fmt (RZ_JOIN_3_PATHS ("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"),
dir_prefix, os);
if (rz_file_exists (dbpath)) {
sdb_concat_by_path (types, dbpath);
}
return rz_analysis_set_triplet (analysis, os, NULL, -1);
}
RZ_API bool rz_analysis_set_bits(RzAnalysis *analysis, int bits) {
switch (bits) {
case 8:
case 16:
case 27:
case 32:
case 64:
if (analysis->bits != bits) {
analysis->bits = bits;
rz_analysis_set_reg_profile (analysis);
}
return true;
}
return false;
}
RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu) {
free (analysis->cpu);
analysis->cpu = cpu ? strdup (cpu) : NULL;
int v = rz_analysis_archinfo (analysis, RZ_ANAL_ARCHINFO_ALIGN);
if (v != -1) {
analysis->pcalign = v;
}
}
RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int bigend) {
analysis->big_endian = bigend;
analysis->reg->big_endian = bigend;
return true;
}
RZ_API ut8 *rz_analysis_mask(RzAnalysis *analysis, int size, const ut8 *data, ut64 at) {
RzAnalysisOp *op = NULL;
ut8 *ret = NULL;
int oplen, idx = 0;
if (!data) {
return NULL;
}
if (analysis->cur && analysis->cur->analysis_mask) {
return analysis->cur->analysis_mask (analysis, size, data, at);
}
if (!(op = rz_analysis_op_new ())) {
return NULL;
}
if (!(ret = malloc (size))) {
rz_analysis_op_free (op);
return NULL;
}
memset (ret, 0xff, size);
while (idx < size) {
if ((oplen = rz_analysis_op (analysis, op, at, data + idx, size - idx, RZ_ANAL_OP_MASK_BASIC)) < 1) {
break;
}
if ((op->ptr != UT64_MAX || op->jump != UT64_MAX) && op->nopcode != 0) {
memset (ret + idx + op->nopcode, 0, oplen - op->nopcode);
}
idx += oplen;
at += oplen;
}
rz_analysis_op_free (op);
return ret;
}
RZ_API void rz_analysis_trace_bb(RzAnalysis *analysis, ut64 addr) {
RzAnalysisBlock *bbi;
RzAnalysisFunction *fcni;
RzListIter *iter2;
fcni = rz_analysis_get_fcn_in (analysis, addr, 0);
if (fcni) {
rz_list_foreach (fcni->bbs, iter2, bbi) {
if (addr >= bbi->addr && addr < (bbi->addr + bbi->size)) {
bbi->traced = true;
break;
}
}
}
}
RZ_API void rz_analysis_colorize_bb(RzAnalysis *analysis, ut64 addr, ut32 color) {
RzAnalysisBlock *bbi;
bbi = rz_analysis_bb_from_offset (analysis, addr);
if (bbi) {
bbi->colorize = color;
}
}
RZ_API RzList* rz_analysis_get_fcns (RzAnalysis *analysis) {
// avoid received to free this thing
analysis->fcns->free = NULL;
return analysis->fcns;
}
RZ_API RzAnalysisOp *rz_analysis_op_hexstr(RzAnalysis *analysis, ut64 addr, const char *str) {
RzAnalysisOp *op = RZ_NEW0 (RzAnalysisOp);
if (!op) {
return NULL;
}
ut8 *buf = calloc (1, strlen (str) + 1);
if (!buf) {
free (op);
return NULL;
}
int len = rz_hex_str2bin (str, buf);
rz_analysis_op (analysis, op, addr, buf, len, RZ_ANAL_OP_MASK_BASIC);
free (buf);
return op;
}
RZ_API bool rz_analysis_op_is_eob(RzAnalysisOp *op) {
if (op->eob) {
return true;
}
switch (op->type) {
case RZ_ANAL_OP_TYPE_JMP:
case RZ_ANAL_OP_TYPE_UJMP:
case RZ_ANAL_OP_TYPE_RJMP:
case RZ_ANAL_OP_TYPE_IJMP:
case RZ_ANAL_OP_TYPE_IRJMP:
case RZ_ANAL_OP_TYPE_CJMP:
case RZ_ANAL_OP_TYPE_RET:
case RZ_ANAL_OP_TYPE_TRAP:
return true;
default:
return false;
}
}
RZ_API void rz_analysis_purge(RzAnalysis *analysis) {
rz_analysis_hint_clear (analysis);
rz_interval_tree_fini (&analysis->meta);
rz_interval_tree_init (&analysis->meta, rz_meta_item_free);
sdb_reset (analysis->sdb_types);
sdb_reset (analysis->sdb_zigns);
sdb_reset (analysis->sdb_classes);
sdb_reset (analysis->sdb_classes_attrs);
rz_analysis_pin_fini (analysis);
rz_analysis_pin_init (analysis);
sdb_reset (analysis->sdb_cc);
rz_list_free (analysis->fcns);
analysis->fcns = rz_list_newf (rz_analysis_function_free);
rz_analysis_purge_imports (analysis);
}
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query) {
rz_return_val_if_fail (analysis, -1);
switch (query) {
case RZ_ANAL_ARCHINFO_MIN_OP_SIZE:
case RZ_ANAL_ARCHINFO_MAX_OP_SIZE:
case RZ_ANAL_ARCHINFO_ALIGN:
if (analysis->cur && analysis->cur->archinfo) {
return analysis->cur->archinfo (analysis, query);
}
break;
}
return -1;
}
static bool __nonreturn_print_commands(void *p, const char *k, const char *v) {
RzAnalysis *analysis = (RzAnalysis *)p;
if (!strncmp (v, "func", strlen ("func") + 1)) {
char *query = sdb_fmt ("func.%s.noreturn", k);
if (sdb_bool_get (analysis->sdb_types, query, NULL)) {
analysis->cb_printf ("tnn %s\n", k);
}
}
if (!strncmp (k, "addr.", 5)) {
analysis->cb_printf ("tna 0x%s %s\n", k + 5, v);
}
return true;
}
static bool __nonreturn_print(void *p, const char *k, const char *v) {
RzAnalysis *analysis = (RzAnalysis *)p;
if (!strncmp (k, "func.", 5) && strstr (k, ".noreturn")) {
char *s = strdup (k + 5);
char *d = strchr (s, '.');
if (d) {
*d = 0;
}
analysis->cb_printf ("%s\n", s);
free (s);
}
if (!strncmp (k, "addr.", 5)) {
char *off;
if (!(off = strdup (k + 5))) {
return 1;
}
char *ptr = strstr (off, ".noreturn");
if (ptr) {
*ptr = 0;
analysis->cb_printf ("0x%s\n", off);
}
free (off);
}
return true;
}
RZ_API void rz_analysis_noreturn_list(RzAnalysis *analysis, int mode) {
switch (mode) {
case 1:
case '*':
case 'r':
sdb_foreach (analysis->sdb_types, __nonreturn_print_commands, analysis);
break;
default:
sdb_foreach (analysis->sdb_types, __nonreturn_print, analysis);
break;
}
}
#define K_NORET_ADDR(x) sdb_fmt ("addr.%"PFMT64x".noreturn", x)
#define K_NORET_FUNC(x) sdb_fmt ("func.%s.noreturn", x)
RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut64 addr) {
const char *tmp_name = NULL;
Sdb *TDB = analysis->sdb_types;
char *fnl_name = NULL;
if (addr != UT64_MAX) {
if (sdb_bool_set (TDB, K_NORET_ADDR (addr), true, 0)) {
RzAnalysisFunction *fcn = rz_analysis_get_function_at (analysis, addr);
if (fcn) {
fcn->is_noreturn = true;
}
return true;
}
}
if (name && *name) {
tmp_name = name;
} else {
RzAnalysisFunction *fcn = rz_analysis_get_fcn_in (analysis, addr, -1);
RzFlagItem *fi = analysis->flb.get_at (analysis->flb.f, addr, false);
if (!fcn && !fi) {
eprintf ("Can't find Function at given address\n");
return false;
}
tmp_name = fcn ? fcn->name: fi->name;
if (fcn) {
fcn->is_noreturn = true;
}
}
if (rz_type_func_exist (TDB, tmp_name)) {
fnl_name = strdup (tmp_name);
} else if (!(fnl_name = rz_type_func_guess (TDB, (char *)tmp_name))) {
if (addr == UT64_MAX) {
if (name) {
sdb_bool_set (TDB, K_NORET_FUNC (name), true, 0);
} else {
eprintf ("Can't find prototype for: %s\n", tmp_name);
}
} else {
eprintf ("Can't find prototype for: %s\n", tmp_name);
}
//return false;
}
if (fnl_name) {
sdb_bool_set (TDB, K_NORET_FUNC (fnl_name), true, 0);
free (fnl_name);
}
return true;
}
RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr) {
Sdb *TDB = analysis->sdb_types;
expr = rz_str_trim_head_ro (expr);
const char *fcnname = NULL;
if (!strncmp (expr, "0x", 2)) {
ut64 n = rz_num_math (NULL, expr);
sdb_unset (TDB, K_NORET_ADDR (n), 0);
RzAnalysisFunction *fcn = rz_analysis_get_fcn_in (analysis, n, -1);
if (!fcn) {
// eprintf ("can't find function at 0x%"PFMT64x"\n", n);
return false;
}
fcnname = fcn->name;
} else {
fcnname = expr;
}
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
#if 0
char *tmp;
// unnsecessary checks, imho the noreturn db should be pretty simple to allow forward and custom declarations without having to define the function prototype before
if (rz_type_func_exist (TDB, fcnname)) {
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
return true;
} else if ((tmp = rz_type_func_guess (TDB, (char *)fcnname))) {
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
free (tmp);
return true;
}
eprintf ("Can't find prototype for %s in types database", fcnname);
#endif
return false;
}
static bool rz_analysis_noreturn_at_name(RzAnalysis *analysis, const char *name) {
if (sdb_bool_get (analysis->sdb_types, K_NORET_FUNC(name), NULL)) {
return true;
}
char *tmp = rz_type_func_guess (analysis->sdb_types, (char *)name);
if (tmp) {
if (sdb_bool_get (analysis->sdb_types, K_NORET_FUNC (tmp), NULL)) {
free (tmp);
return true;
}
free (tmp);
}
if (rz_str_startswith (name, "reloc.")) {
return rz_analysis_noreturn_at_name (analysis, name + 6);
}
return false;
}
RZ_API bool rz_analysis_noreturn_at_addr(RzAnalysis *analysis, ut64 addr) {
return sdb_bool_get (analysis->sdb_types, K_NORET_ADDR (addr), NULL);
}
static bool noreturn_recurse(RzAnalysis *analysis, ut64 addr) {
RzAnalysisOp op = {0};
ut8 bbuf[0x10] = {0};
ut64 recurse_addr = UT64_MAX;
if (!analysis->iob.read_at (analysis->iob.io, addr, bbuf, sizeof (bbuf))) {
eprintf ("Couldn't read buffer\n");
return false;
}
if (rz_analysis_op (analysis, &op, addr, bbuf, sizeof (bbuf), RZ_ANAL_OP_MASK_BASIC | RZ_ANAL_OP_MASK_VAL) < 1) {
return false;
}
switch (op.type & RZ_ANAL_OP_TYPE_MASK) {
case RZ_ANAL_OP_TYPE_JMP:
if (op.jump == UT64_MAX) {
recurse_addr = op.ptr;
} else {
recurse_addr = op.jump;
}
break;
case RZ_ANAL_OP_TYPE_UCALL:
case RZ_ANAL_OP_TYPE_RCALL:
case RZ_ANAL_OP_TYPE_ICALL:
case RZ_ANAL_OP_TYPE_IRCALL:
recurse_addr = op.ptr;
break;
case RZ_ANAL_OP_TYPE_CCALL:
case RZ_ANAL_OP_TYPE_CALL:
recurse_addr = op.jump;
break;
}
if (recurse_addr == UT64_MAX || recurse_addr == addr) {
return false;
}
return rz_analysis_noreturn_at (analysis, recurse_addr);
}
RZ_API bool rz_analysis_noreturn_at(RzAnalysis *analysis, ut64 addr) {
if (!addr || addr == UT64_MAX) {
return false;
}
if (rz_analysis_noreturn_at_addr (analysis, addr)) {
return true;
}
/* XXX this is very slow */
RzAnalysisFunction *f = rz_analysis_get_function_at (analysis, addr);
if (f) {
if (rz_analysis_noreturn_at_name (analysis, f->name)) {
return true;
}
}
RzFlagItem *fi = analysis->flag_get (analysis->flb.f, addr);
if (fi) {
if (rz_analysis_noreturn_at_name (analysis, fi->realname ? fi->realname : fi->name)) {
return true;
}
}
if (analysis->recursive_noreturn) {
return noreturn_recurse (analysis, addr);
}
return false;
}
RZ_API void rz_analysis_bind(RzAnalysis *analysis, RzAnalysisBind *b) {
if (b) {
b->analysis = analysis;
b->get_fcn_in = rz_analysis_get_fcn_in;
b->get_hint = rz_analysis_hint_get;
}
}
RZ_API RzList *rz_analysis_preludes(RzAnalysis *analysis) {
if (analysis->cur && analysis->cur->preludes ) {
return analysis->cur->preludes (analysis);
}
return NULL;
}
RZ_API bool rz_analysis_is_prelude(RzAnalysis *analysis, const ut8 *data, int len) {
RzList *l = rz_analysis_preludes (analysis);
if (l) {
RzSearchKeyword *kw;
RzListIter *iter;
rz_list_foreach (l, iter, kw) {
int ks = kw->keyword_length;
if (len >= ks && !memcmp (data, kw->bin_keyword, ks)) {
rz_list_free (l);
return true;
}
}
rz_list_free (l);
}
return false;
}
RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp) {
RzListIter *it;
const char *eimp;
rz_list_foreach (analysis->imports, it, eimp) {
if (!strcmp (eimp, imp)) {
return;
}
}
char *cimp = strdup (imp);
if (!cimp) {
return;
}
rz_list_push (analysis->imports, cimp);
}
RZ_API void rz_analysis_remove_import(RzAnalysis *analysis, const char *imp) {
RzListIter *it;
const char *eimp;
rz_list_foreach (analysis->imports, it, eimp) {
if (!strcmp (eimp, imp)) {
rz_list_delete (analysis->imports, it);
return;
}
}
}
RZ_API void rz_analysis_purge_imports(RzAnalysis *analysis) {
rz_list_purge (analysis->imports);
}

View file

@ -1,9 +1,9 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_io.h>
#include <rz_anal.h>
#include <rz_analysis.h>
void meta_gb_bankswitch_cmt(RzAnal *a, ut64 addr, ut16 ldarg) {
void meta_gb_bankswitch_cmt(RzAnalysis *a, ut64 addr, ut16 ldarg) {
if(0x1fff <ldarg && ldarg < 0x4000 && addr < 0x4000)
rz_meta_set_string (a, RZ_META_TYPE_COMMENT, addr, "Bankswitch");
if(0x6000 > ldarg && ldarg > 0x3fff)

View file

@ -3,11 +3,11 @@
#include <rz_types.h>
#include <rz_util.h>
#include <rz_asm.h>
#include <rz_anal.h>
#include <rz_analysis.h>
#include "hexagon.h"
#include "hexagon_insn.h"
int hexagon_anal_instruction(HexInsn *hi, RzAnalOp *op) {
int hexagon_analysis_instruction(HexInsn *hi, RzAnalysisOp *op) {
switch (hi->instruction) {
case HEX_INS_CALL__R22_2: {
// call #r22:2

View file

@ -0,0 +1,2 @@
int hexagon_analysis_instruction(HexInsn *hi, RzAnalysisOp *op);

View file

@ -1,19 +1,19 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_anal.h>
#include <rz_analysis.h>
#include <rz_util.h>
#include <rz_list.h>
#include <limits.h>
typedef struct {
ut64 addr;
RzAnalBlock *ret;
RzAnalysisBlock *ret;
} BBFromOffsetJmpmidCtx;
static bool bb_from_offset_jmpmid_cb(RzAnalBlock *block, void *user) {
static bool bb_from_offset_jmpmid_cb(RzAnalysisBlock *block, void *user) {
BBFromOffsetJmpmidCtx *ctx = user;
// If an instruction starts exactly at the search addr, return that block immediately
if (rz_anal_block_op_starts_at (block, ctx->addr)) {
if (rz_analysis_block_op_starts_at (block, ctx->addr)) {
ctx->ret = block;
return false;
}
@ -24,28 +24,28 @@ static bool bb_from_offset_jmpmid_cb(RzAnalBlock *block, void *user) {
return true;
}
static bool bb_from_offset_first_cb(RzAnalBlock *block, void *user) {
RzAnalBlock **ret = user;
static bool bb_from_offset_first_cb(RzAnalysisBlock *block, void *user) {
RzAnalysisBlock **ret = user;
*ret = block;
return false;
}
RZ_API RzAnalBlock *rz_anal_bb_from_offset(RzAnal *anal, ut64 off) {
const bool x86 = anal->cur->arch && !strcmp (anal->cur->arch, "x86");
if (anal->opt.jmpmid && x86) {
RZ_API RzAnalysisBlock *rz_analysis_bb_from_offset(RzAnalysis *analysis, ut64 off) {
const bool x86 = analysis->cur->arch && !strcmp (analysis->cur->arch, "x86");
if (analysis->opt.jmpmid && x86) {
BBFromOffsetJmpmidCtx ctx = { off, NULL };
rz_anal_blocks_foreach_in (anal, off, bb_from_offset_jmpmid_cb, &ctx);
rz_analysis_blocks_foreach_in (analysis, off, bb_from_offset_jmpmid_cb, &ctx);
return ctx.ret;
}
RzAnalBlock *ret = NULL;
rz_anal_blocks_foreach_in (anal, off, bb_from_offset_first_cb, &ret);
RzAnalysisBlock *ret = NULL;
rz_analysis_blocks_foreach_in (analysis, off, bb_from_offset_first_cb, &ret);
return ret;
}
/* return the offset of the i-th instruction in the basicblock bb.
* If the index of the instruction is not valid, it returns UT16_MAX */
RZ_API ut16 rz_anal_bb_offset_inst(RzAnalBlock *bb, int i) {
RZ_API ut16 rz_analysis_bb_offset_inst(RzAnalysisBlock *bb, int i) {
if (i < 0 || i >= bb->ninstr) {
return UT16_MAX;
}
@ -54,8 +54,8 @@ RZ_API ut16 rz_anal_bb_offset_inst(RzAnalBlock *bb, int i) {
/* return the address of the i-th instruction in the basicblock bb.
* If the index of the instruction is not valid, it returns UT64_MAX */
RZ_API ut64 rz_anal_bb_opaddr_i(RzAnalBlock *bb, int i) {
ut16 offset = rz_anal_bb_offset_inst (bb, i);
RZ_API ut64 rz_analysis_bb_opaddr_i(RzAnalysisBlock *bb, int i) {
ut16 offset = rz_analysis_bb_offset_inst (bb, i);
if (offset == UT16_MAX) {
return UT64_MAX;
}
@ -63,7 +63,7 @@ RZ_API ut64 rz_anal_bb_opaddr_i(RzAnalBlock *bb, int i) {
}
/* set the offset of the i-th instruction in the basicblock bb */
RZ_API bool rz_anal_bb_set_offset(RzAnalBlock *bb, int i, ut16 v) {
RZ_API bool rz_analysis_bb_set_offset(RzAnalysisBlock *bb, int i, ut16 v) {
// the offset 0 of the instruction 0 is not stored because always 0
if (i > 0 && v > 0) {
if (i >= bb->op_pos_size) {
@ -83,17 +83,17 @@ RZ_API bool rz_anal_bb_set_offset(RzAnalBlock *bb, int i, ut16 v) {
/* return the address of the instruction that occupy a given offset.
* If the offset is not part of the given basicblock, UT64_MAX is returned. */
RZ_API ut64 rz_anal_bb_opaddr_at(RzAnalBlock *bb, ut64 off) {
RZ_API ut64 rz_analysis_bb_opaddr_at(RzAnalysisBlock *bb, ut64 off) {
ut16 delta, delta_off, last_delta;
int i;
if (!rz_anal_block_contains (bb, off)) {
if (!rz_analysis_block_contains (bb, off)) {
return UT64_MAX;
}
last_delta = 0;
delta_off = off - bb->addr;
for (i = 0; i < bb->ninstr; i++) {
delta = rz_anal_bb_offset_inst (bb, i);
delta = rz_analysis_bb_offset_inst (bb, i);
if (delta > delta_off) {
return bb->addr + last_delta;
}
@ -103,18 +103,18 @@ RZ_API ut64 rz_anal_bb_opaddr_at(RzAnalBlock *bb, ut64 off) {
}
// returns the size of the i-th instruction in a basic block
RZ_API ut64 rz_anal_bb_size_i(RzAnalBlock *bb, int i) {
RZ_API ut64 rz_analysis_bb_size_i(RzAnalysisBlock *bb, int i) {
if (i < 0 || i >= bb->ninstr) {
return UT64_MAX;
}
ut16 idx_cur = rz_anal_bb_offset_inst (bb, i);
ut16 idx_next = rz_anal_bb_offset_inst (bb, i + 1);
ut16 idx_cur = rz_analysis_bb_offset_inst (bb, i);
ut16 idx_next = rz_analysis_bb_offset_inst (bb, i + 1);
return idx_next != UT16_MAX? idx_next - idx_cur: bb->size - idx_cur;
}
/* returns the address of the basic block that contains addr or UT64_MAX if
* there is no such basic block */
RZ_API ut64 rz_anal_get_bbaddr(RzAnal *anal, ut64 addr) {
RzAnalBlock *bb = rz_anal_bb_from_offset (anal, addr);
RZ_API ut64 rz_analysis_get_bbaddr(RzAnalysis *analysis, ut64 addr) {
RzAnalysisBlock *bb = rz_analysis_bb_from_offset (analysis, addr);
return bb? bb->addr: UT64_MAX;
}

View file

@ -1,16 +1,16 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_anal.h>
#include <rz_anal.h>
#include <rz_analysis.h>
#include <rz_analysis.h>
#include <rz_hash.h>
#include <ht_uu.h>
#include <assert.h>
#define unwrap(rbnode) container_of (rbnode, RzAnalBlock, _rb)
#define unwrap(rbnode) container_of (rbnode, RzAnalysisBlock, _rb)
static void __max_end(RBNode *node) {
RzAnalBlock *block = unwrap (node);
RzAnalysisBlock *block = unwrap (node);
block->_max_end = block->addr + block->size;
int i;
for (i = 0; i < 2; i++) {
@ -25,7 +25,7 @@ static void __max_end(RBNode *node) {
static int __bb_addr_cmp(const void *incoming, const RBNode *in_tree, void *user) {
ut64 incoming_addr = *(ut64 *)incoming;
const RzAnalBlock *in_tree_block = container_of (in_tree, const RzAnalBlock, _rb);
const RzAnalysisBlock *in_tree_block = container_of (in_tree, const RzAnalysisBlock, _rb);
if (incoming_addr < in_tree_block->addr) {
return -1;
}
@ -35,23 +35,23 @@ static int __bb_addr_cmp(const void *incoming, const RBNode *in_tree, void *user
return 0;
}
#define D if (anal && anal->verbose)
#define D if (analysis && analysis->verbose)
RZ_API void rz_anal_block_ref(RzAnalBlock *bb) {
RZ_API void rz_analysis_block_ref(RzAnalysisBlock *bb) {
assert (bb->ref > 0); // 0-refd must already be freed.
bb->ref++;
}
#define DFLT_NINSTR 3
static RzAnalBlock *block_new(RzAnal *a, ut64 addr, ut64 size) {
RzAnalBlock *block = RZ_NEW0 (RzAnalBlock);
static RzAnalysisBlock *block_new(RzAnalysis *a, ut64 addr, ut64 size) {
RzAnalysisBlock *block = RZ_NEW0 (RzAnalysisBlock);
if (!block) {
return NULL;
}
block->addr = addr;
block->size = size;
block->anal = a;
block->analysis = a;
block->ref = 1;
block->jump = UT64_MAX;
block->fail = UT64_MAX;
@ -62,20 +62,20 @@ static RzAnalBlock *block_new(RzAnal *a, ut64 addr, ut64 size) {
block->cmpval = UT64_MAX;
block->fcns = rz_list_new ();
if (size) {
rz_anal_block_update_hash (block);
rz_analysis_block_update_hash (block);
}
return block;
}
static void block_free(RzAnalBlock *block) {
static void block_free(RzAnalysisBlock *block) {
if (!block) {
return;
}
rz_anal_cond_free (block->cond);
rz_analysis_cond_free (block->cond);
free (block->fingerprint);
rz_anal_diff_free (block->diff);
rz_analysis_diff_free (block->diff);
free (block->op_bytes);
rz_anal_switch_op_free (block->switch_op);
rz_analysis_switch_op_free (block->switch_op);
rz_list_free (block->fcns);
free (block->op_pos);
free (block->parent_reg_arena);
@ -83,17 +83,17 @@ static void block_free(RzAnalBlock *block) {
}
void __block_free_rb(RBNode *node, void *user) {
RzAnalBlock *block = unwrap (node);
RzAnalysisBlock *block = unwrap (node);
block_free (block);
}
RZ_API RzAnalBlock *rz_anal_get_block_at(RzAnal *anal, ut64 addr) {
RBNode *node = rz_rbtree_find (anal->bb_tree, &addr, __bb_addr_cmp, NULL);
RZ_API RzAnalysisBlock *rz_analysis_get_block_at(RzAnalysis *analysis, ut64 addr) {
RBNode *node = rz_rbtree_find (analysis->bb_tree, &addr, __bb_addr_cmp, NULL);
return node? unwrap (node): NULL;
}
// This is a special case of what rz_interval_node_all_in() does
static bool all_in(RzAnalBlock *node, ut64 addr, RzAnalBlockCb cb, void *user) {
static bool all_in(RzAnalysisBlock *node, ut64 addr, RzAnalysisBlockCb cb, void *user) {
while (node && addr < node->addr) {
// less than the current node, but might still be contained further down
node = unwrap (node->_rb.child[0]);
@ -119,26 +119,26 @@ static bool all_in(RzAnalBlock *node, ut64 addr, RzAnalBlockCb cb, void *user) {
return true;
}
RZ_API bool rz_anal_blocks_foreach_in(RzAnal *anal, ut64 addr, RzAnalBlockCb cb, void *user) {
return all_in (anal->bb_tree ? unwrap (anal->bb_tree) : NULL, addr, cb, user);
RZ_API bool rz_analysis_blocks_foreach_in(RzAnalysis *analysis, ut64 addr, RzAnalysisBlockCb cb, void *user) {
return all_in (analysis->bb_tree ? unwrap (analysis->bb_tree) : NULL, addr, cb, user);
}
static bool block_list_cb(RzAnalBlock *block, void *user) {
static bool block_list_cb(RzAnalysisBlock *block, void *user) {
RzList *list = user;
rz_anal_block_ref (block);
rz_analysis_block_ref (block);
rz_list_push (list, block);
return true;
}
RZ_API RzList *rz_anal_get_blocks_in(RzAnal *anal, ut64 addr) {
RzList *list = rz_list_newf ((RzListFree)rz_anal_block_unref);
RZ_API RzList *rz_analysis_get_blocks_in(RzAnalysis *analysis, ut64 addr) {
RzList *list = rz_list_newf ((RzListFree)rz_analysis_block_unref);
if (list) {
rz_anal_blocks_foreach_in (anal, addr, block_list_cb, list);
rz_analysis_blocks_foreach_in (analysis, addr, block_list_cb, list);
}
return list;
}
static void all_intersect(RzAnalBlock *node, ut64 addr, ut64 size, RzAnalBlockCb cb, void *user) {
static void all_intersect(RzAnalysisBlock *node, ut64 addr, ut64 size, RzAnalysisBlockCb cb, void *user) {
ut64 end = addr + size;
while (node && end <= node->addr) {
// less than the current node, but might still be contained further down
@ -158,46 +158,46 @@ static void all_intersect(RzAnalBlock *node, ut64 addr, ut64 size, RzAnalBlockCb
all_intersect (unwrap (node->_rb.child[1]), addr, size, cb, user);
}
RZ_API void rz_anal_blocks_foreach_intersect(RzAnal *anal, ut64 addr, ut64 size, RzAnalBlockCb cb, void *user) {
all_intersect (anal->bb_tree ? unwrap (anal->bb_tree) : NULL, addr, size, cb, user);
RZ_API void rz_analysis_blocks_foreach_intersect(RzAnalysis *analysis, ut64 addr, ut64 size, RzAnalysisBlockCb cb, void *user) {
all_intersect (analysis->bb_tree ? unwrap (analysis->bb_tree) : NULL, addr, size, cb, user);
}
RZ_API RzList *rz_anal_get_blocks_intersect(RzAnal *anal, ut64 addr, ut64 size) {
RzList *list = rz_list_newf ((RzListFree)rz_anal_block_unref);
RZ_API RzList *rz_analysis_get_blocks_intersect(RzAnalysis *analysis, ut64 addr, ut64 size) {
RzList *list = rz_list_newf ((RzListFree)rz_analysis_block_unref);
if (!list) {
return NULL;
}
rz_anal_blocks_foreach_intersect (anal, addr, size, block_list_cb, list);
rz_analysis_blocks_foreach_intersect (analysis, addr, size, block_list_cb, list);
return list;
}
RZ_API RzAnalBlock *rz_anal_create_block(RzAnal *anal, ut64 addr, ut64 size) {
if (rz_anal_get_block_at (anal, addr)) {
RZ_API RzAnalysisBlock *rz_analysis_create_block(RzAnalysis *analysis, ut64 addr, ut64 size) {
if (rz_analysis_get_block_at (analysis, addr)) {
return NULL;
}
RzAnalBlock *block = block_new (anal, addr, size);
RzAnalysisBlock *block = block_new (analysis, addr, size);
if (!block) {
return NULL;
}
rz_rbtree_aug_insert (&anal->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
rz_rbtree_aug_insert (&analysis->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
return block;
}
RZ_API void rz_anal_delete_block(RzAnalBlock *bb) {
rz_anal_block_ref (bb);
RZ_API void rz_analysis_delete_block(RzAnalysisBlock *bb) {
rz_analysis_block_ref (bb);
while (!rz_list_empty (bb->fcns)) {
rz_anal_function_remove_block (rz_list_first (bb->fcns), bb);
rz_analysis_function_remove_block (rz_list_first (bb->fcns), bb);
}
rz_anal_block_unref (bb);
rz_analysis_block_unref (bb);
}
RZ_API void rz_anal_block_set_size(RzAnalBlock *block, ut64 size) {
RZ_API void rz_analysis_block_set_size(RzAnalysisBlock *block, ut64 size) {
if (block->size == size) {
return;
}
// Update the block's function's cached ranges
RzAnalFunction *fcn;
RzAnalysisFunction *fcn;
RzListIter *iter;
rz_list_foreach (block->fcns, iter, fcn) {
if (fcn->meta._min != UT64_MAX && fcn->meta._max == block->addr + block->size) {
@ -207,21 +207,21 @@ RZ_API void rz_anal_block_set_size(RzAnalBlock *block, ut64 size) {
// Do the actual resize
block->size = size;
rz_rbtree_aug_update_sum (block->anal->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
rz_rbtree_aug_update_sum (block->analysis->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
}
RZ_API bool rz_anal_block_relocate(RzAnalBlock *block, ut64 addr, ut64 size) {
RZ_API bool rz_analysis_block_relocate(RzAnalysisBlock *block, ut64 addr, ut64 size) {
if (block->addr == addr) {
rz_anal_block_set_size (block, size);
rz_analysis_block_set_size (block, size);
return true;
}
if (rz_anal_get_block_at (block->anal, addr)) {
if (rz_analysis_get_block_at (block->analysis, addr)) {
// Two blocks at the same addr is illegle you know...
return false;
}
// Update the block's function's cached ranges
RzAnalFunction *fcn;
RzAnalysisFunction *fcn;
RzListIter *iter;
rz_list_foreach (block->fcns, iter, fcn) {
if (fcn->meta._min != UT64_MAX) {
@ -243,29 +243,29 @@ RZ_API bool rz_anal_block_relocate(RzAnalBlock *block, ut64 addr, ut64 size) {
}
}
rz_rbtree_aug_delete (&block->anal->bb_tree, &block->addr, __bb_addr_cmp, NULL, NULL, NULL, __max_end);
rz_rbtree_aug_delete (&block->analysis->bb_tree, &block->addr, __bb_addr_cmp, NULL, NULL, NULL, __max_end);
block->addr = addr;
block->size = size;
rz_anal_block_update_hash (block);
rz_rbtree_aug_insert (&block->anal->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
rz_analysis_block_update_hash (block);
rz_rbtree_aug_insert (&block->analysis->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
return true;
}
RZ_API RzAnalBlock *rz_anal_block_split(RzAnalBlock *bbi, ut64 addr) {
RzAnal *anal = bbi->anal;
RZ_API RzAnalysisBlock *rz_analysis_block_split(RzAnalysisBlock *bbi, ut64 addr) {
RzAnalysis *analysis = bbi->analysis;
rz_return_val_if_fail (bbi && addr >= bbi->addr && addr < bbi->addr + bbi->size && addr != UT64_MAX, 0);
if (addr == bbi->addr) {
rz_anal_block_ref (bbi); // ref to be consistent with splitted return refcount
rz_analysis_block_ref (bbi); // ref to be consistent with splitted return refcount
return bbi;
}
if (rz_anal_get_block_at (bbi->anal, addr)) {
if (rz_analysis_get_block_at (bbi->analysis, addr)) {
// can't have two bbs at the same addr
return NULL;
}
// create the second block
RzAnalBlock *bb = block_new (anal, addr, bbi->addr + bbi->size - addr);
RzAnalysisBlock *bb = block_new (analysis, addr, bbi->addr + bbi->size - addr);
if (!bb) {
return NULL;
}
@ -274,36 +274,36 @@ RZ_API RzAnalBlock *rz_anal_block_split(RzAnalBlock *bbi, ut64 addr) {
bb->parent_stackptr = bbi->stackptr;
// resize the first block
rz_anal_block_set_size (bbi, addr - bbi->addr);
rz_analysis_block_set_size (bbi, addr - bbi->addr);
bbi->jump = addr;
bbi->fail = UT64_MAX;
rz_anal_block_update_hash (bbi);
rz_analysis_block_update_hash (bbi);
// insert the second block into the tree
rz_rbtree_aug_insert (&anal->bb_tree, &bb->addr, &bb->_rb, __bb_addr_cmp, NULL, __max_end);
rz_rbtree_aug_insert (&analysis->bb_tree, &bb->addr, &bb->_rb, __bb_addr_cmp, NULL, __max_end);
// insert the second block into all functions of the first
RzListIter *iter;
RzAnalFunction *fcn;
RzAnalysisFunction *fcn;
rz_list_foreach (bbi->fcns, iter, fcn) {
rz_anal_function_add_block (fcn, bb);
rz_analysis_function_add_block (fcn, bb);
}
// recalculate offset of instructions in both bb and bbi
int i;
i = 0;
while (i < bbi->ninstr && rz_anal_bb_offset_inst (bbi, i) < bbi->size) {
while (i < bbi->ninstr && rz_analysis_bb_offset_inst (bbi, i) < bbi->size) {
i++;
}
int new_bbi_instr = i;
if (bb->addr - bbi->addr == rz_anal_bb_offset_inst (bbi, i)) {
if (bb->addr - bbi->addr == rz_analysis_bb_offset_inst (bbi, i)) {
bb->ninstr = 0;
while (i < bbi->ninstr) {
ut16 off_op = rz_anal_bb_offset_inst (bbi, i);
ut16 off_op = rz_analysis_bb_offset_inst (bbi, i);
if (off_op >= bbi->size + bb->size) {
break;
}
rz_anal_bb_set_offset (bb, bb->ninstr, off_op - bbi->size);
rz_analysis_bb_set_offset (bb, bb->ninstr, off_op - bbi->size);
bb->ninstr++;
i++;
}
@ -312,8 +312,8 @@ RZ_API RzAnalBlock *rz_anal_block_split(RzAnalBlock *bbi, ut64 addr) {
return bb;
}
RZ_API bool rz_anal_block_merge(RzAnalBlock *a, RzAnalBlock *b) {
if (!rz_anal_block_is_contiguous (a, b)) {
RZ_API bool rz_analysis_block_merge(RzAnalysisBlock *a, RzAnalysisBlock *b) {
if (!rz_analysis_block_is_contiguous (a, b)) {
return false;
}
@ -321,7 +321,7 @@ RZ_API bool rz_anal_block_merge(RzAnalBlock *a, RzAnalBlock *b) {
if (rz_list_length (a->fcns) != rz_list_length (b->fcns)) {
return false;
}
RzAnalFunction *fcn;
RzAnalysisFunction *fcn;
RzListIter *iter;
rz_list_foreach (a->fcns, iter, fcn) {
if (!rz_list_contains (b->fcns, fcn)) {
@ -330,25 +330,25 @@ RZ_API bool rz_anal_block_merge(RzAnalBlock *a, RzAnalBlock *b) {
}
// Keep a ref to b, but remove all references of b from its functions
rz_anal_block_ref (b);
rz_analysis_block_ref (b);
while (!rz_list_empty (b->fcns)) {
rz_anal_function_remove_block (rz_list_first (b->fcns), b);
rz_analysis_function_remove_block (rz_list_first (b->fcns), b);
}
// merge ops from b into a
size_t i;
for (i = 0; i < b->ninstr; i++) {
rz_anal_bb_set_offset (a, a->ninstr++, a->size + rz_anal_bb_offset_inst (b, i));
rz_analysis_bb_set_offset (a, a->ninstr++, a->size + rz_analysis_bb_offset_inst (b, i));
}
// merge everything else into a
a->size += b->size;
a->jump = b->jump;
a->fail = b->fail;
rz_anal_block_update_hash (a);
rz_analysis_block_update_hash (a);
// kill b completely
rz_rbtree_aug_delete (&a->anal->bb_tree, &b->addr, __bb_addr_cmp, NULL, __block_free_rb, NULL, __max_end);
rz_rbtree_aug_delete (&a->analysis->bb_tree, &b->addr, __bb_addr_cmp, NULL, __block_free_rb, NULL, __max_end);
// invalidate ranges of a's functions
rz_list_foreach (a->fcns, iter, fcn) {
@ -358,7 +358,7 @@ RZ_API bool rz_anal_block_merge(RzAnalBlock *a, RzAnalBlock *b) {
return true;
}
RZ_API void rz_anal_block_unref(RzAnalBlock *bb) {
RZ_API void rz_analysis_block_unref(RzAnalysisBlock *bb) {
if (!bb) {
return;
}
@ -366,13 +366,13 @@ RZ_API void rz_anal_block_unref(RzAnalBlock *bb) {
bb->ref--;
assert (bb->ref >= rz_list_length (bb->fcns)); // all of the block's functions must hold a reference to it
if (bb->ref < 1) {
RzAnal *anal = bb->anal;
RzAnalysis *analysis = bb->analysis;
assert (!bb->fcns || rz_list_empty (bb->fcns));
rz_rbtree_aug_delete (&anal->bb_tree, &bb->addr, __bb_addr_cmp, NULL, __block_free_rb, NULL, __max_end);
rz_rbtree_aug_delete (&analysis->bb_tree, &bb->addr, __bb_addr_cmp, NULL, __block_free_rb, NULL, __max_end);
}
}
RZ_API bool rz_anal_block_successor_addrs_foreach(RzAnalBlock *block, RzAnalAddrCb cb, void *user) {
RZ_API bool rz_analysis_block_successor_addrs_foreach(RzAnalysisBlock *block, RzAnalysisAddrCb cb, void *user) {
#define CB_ADDR(addr) do { \
if (addr == UT64_MAX) { \
break; \
@ -386,7 +386,7 @@ RZ_API bool rz_anal_block_successor_addrs_foreach(RzAnalBlock *block, RzAnalAddr
CB_ADDR (block->fail);
if (block->switch_op && block->switch_op->cases) {
RzListIter *iter;
RzAnalCaseOp *caseop;
RzAnalysisCaseOp *caseop;
rz_list_foreach (block->switch_op->cases, iter, caseop) {
CB_ADDR (caseop->jump);
}
@ -396,20 +396,20 @@ RZ_API bool rz_anal_block_successor_addrs_foreach(RzAnalBlock *block, RzAnalAddr
#undef CB_ADDR
}
typedef struct rz_anal_block_recurse_context_t {
RzAnal *anal;
RzPVector/*<RzAnalBlock>*/ to_visit;
typedef struct rz_analysis_block_recurse_context_t {
RzAnalysis *analysis;
RzPVector/*<RzAnalysisBlock>*/ to_visit;
HtUP *visited;
} RzAnalBlockRecurseContext;
} RzAnalysisBlockRecurseContext;
static bool block_recurse_successor_cb(ut64 addr, void *user) {
RzAnalBlockRecurseContext *ctx = user;
RzAnalysisBlockRecurseContext *ctx = user;
if (ht_up_find_kv (ctx->visited, addr, NULL)) {
// already visited
return true;
}
ht_up_insert (ctx->visited, addr, NULL);
RzAnalBlock *block = rz_anal_get_block_at (ctx->anal, addr);
RzAnalysisBlock *block = rz_analysis_get_block_at (ctx->analysis, addr);
if (!block) {
return true;
}
@ -417,10 +417,10 @@ static bool block_recurse_successor_cb(ut64 addr, void *user) {
return true;
}
RZ_API bool rz_anal_block_recurse(RzAnalBlock *block, RzAnalBlockCb cb, void *user) {
RZ_API bool rz_analysis_block_recurse(RzAnalysisBlock *block, RzAnalysisBlockCb cb, void *user) {
bool breaked = false;
RzAnalBlockRecurseContext ctx;
ctx.anal = block->anal;
RzAnalysisBlockRecurseContext ctx;
ctx.analysis = block->analysis;
rz_pvector_init (&ctx.to_visit, NULL);
ctx.visited = ht_up_new0 ();
if (!ctx.visited) {
@ -431,12 +431,12 @@ RZ_API bool rz_anal_block_recurse(RzAnalBlock *block, RzAnalBlockCb cb, void *us
rz_pvector_push (&ctx.to_visit, block);
while (!rz_pvector_empty (&ctx.to_visit)) {
RzAnalBlock *cur = rz_pvector_pop (&ctx.to_visit);
RzAnalysisBlock *cur = rz_pvector_pop (&ctx.to_visit);
breaked = !cb (cur, user);
if (breaked) {
break;
}
rz_anal_block_successor_addrs_foreach (cur, block_recurse_successor_cb, &ctx);
rz_analysis_block_successor_addrs_foreach (cur, block_recurse_successor_cb, &ctx);
}
beach:
@ -445,10 +445,10 @@ beach:
return !breaked;
}
RZ_API bool rz_anal_block_recurse_followthrough(RzAnalBlock *block, RzAnalBlockCb cb, void *user) {
RZ_API bool rz_analysis_block_recurse_followthrough(RzAnalysisBlock *block, RzAnalysisBlockCb cb, void *user) {
bool breaked = false;
RzAnalBlockRecurseContext ctx;
ctx.anal = block->anal;
RzAnalysisBlockRecurseContext ctx;
ctx.analysis = block->analysis;
rz_pvector_init (&ctx.to_visit, NULL);
ctx.visited = ht_up_new0 ();
if (!ctx.visited) {
@ -459,12 +459,12 @@ RZ_API bool rz_anal_block_recurse_followthrough(RzAnalBlock *block, RzAnalBlockC
rz_pvector_push (&ctx.to_visit, block);
while (!rz_pvector_empty (&ctx.to_visit)) {
RzAnalBlock *cur = rz_pvector_pop (&ctx.to_visit);
RzAnalysisBlock *cur = rz_pvector_pop (&ctx.to_visit);
bool b = !cb (cur, user);
if (b) {
breaked = true;
} else {
rz_anal_block_successor_addrs_foreach (cur, block_recurse_successor_cb, &ctx);
rz_analysis_block_successor_addrs_foreach (cur, block_recurse_successor_cb, &ctx);
}
}
@ -475,20 +475,20 @@ beach:
}
typedef struct {
RzAnalBlock *bb;
RzAnalysisBlock *bb;
RzListIter *switch_it;
} RecurseDepthFirstCtx;
RZ_API bool rz_anal_block_recurse_depth_first(RzAnalBlock *block, RzAnalBlockCb cb, RZ_NULLABLE RzAnalBlockCb on_exit, void *user) {
RZ_API bool rz_analysis_block_recurse_depth_first(RzAnalysisBlock *block, RzAnalysisBlockCb cb, RZ_NULLABLE RzAnalysisBlockCb on_exit, void *user) {
bool breaked = false;
HtUP *visited = ht_up_new0 ();
if (!visited) {
goto beach;
}
RzAnal *anal = block->anal;
RzAnalysis *analysis = block->analysis;
RzVector path;
rz_vector_init (&path, sizeof (RecurseDepthFirstCtx), NULL, NULL);
RzAnalBlock *cur_bb = block;
RzAnalysisBlock *cur_bb = block;
RecurseDepthFirstCtx ctx = { cur_bb, NULL };
rz_vector_push (&path, &ctx);
ht_up_insert (visited, cur_bb->addr, NULL);
@ -500,11 +500,11 @@ RZ_API bool rz_anal_block_recurse_depth_first(RzAnalBlock *block, RzAnalBlockCb
RecurseDepthFirstCtx *cur_ctx = rz_vector_index_ptr (&path, path.len - 1);
cur_bb = cur_ctx->bb;
if (cur_bb->jump != UT64_MAX && !ht_up_find_kv (visited, cur_bb->jump, NULL)) {
cur_bb = rz_anal_get_block_at (anal, cur_bb->jump);
cur_bb = rz_analysis_get_block_at (analysis, cur_bb->jump);
} else if (cur_bb->fail != UT64_MAX && !ht_up_find_kv (visited, cur_bb->fail, NULL)) {
cur_bb = rz_anal_get_block_at (anal, cur_bb->fail);
cur_bb = rz_analysis_get_block_at (analysis, cur_bb->fail);
} else {
RzAnalCaseOp *cop = NULL;
RzAnalysisCaseOp *cop = NULL;
if (cur_bb->switch_op && !cur_ctx->switch_it) {
cur_ctx->switch_it = cur_bb->switch_op->cases->head;
cop = rz_list_first (cur_bb->switch_op->cases);
@ -517,7 +517,7 @@ RZ_API bool rz_anal_block_recurse_depth_first(RzAnalBlock *block, RzAnalBlockCb
cop = NULL;
}
}
cur_bb = cop ? rz_anal_get_block_at (anal, cop->jump) : NULL;
cur_bb = cop ? rz_analysis_get_block_at (analysis, cop->jump) : NULL;
}
if (cur_bb) {
RecurseDepthFirstCtx ctx = { cur_bb, NULL };
@ -541,30 +541,30 @@ beach:
return !breaked;
}
static bool recurse_list_cb(RzAnalBlock *block, void *user) {
static bool recurse_list_cb(RzAnalysisBlock *block, void *user) {
RzList *list = user;
rz_anal_block_ref (block);
rz_analysis_block_ref (block);
rz_list_push (list, block);
return true;
}
RZ_API RzList *rz_anal_block_recurse_list(RzAnalBlock *block) {
RzList *ret = rz_list_newf ((RzListFree)rz_anal_block_unref);
RZ_API RzList *rz_analysis_block_recurse_list(RzAnalysisBlock *block) {
RzList *ret = rz_list_newf ((RzListFree)rz_analysis_block_unref);
if (ret) {
rz_anal_block_recurse (block, recurse_list_cb, ret);
rz_analysis_block_recurse (block, recurse_list_cb, ret);
}
return ret;
}
RZ_API void rz_anal_block_add_switch_case(RzAnalBlock *block, ut64 switch_addr, ut64 case_value, ut64 case_addr) {
RZ_API void rz_analysis_block_add_switch_case(RzAnalysisBlock *block, ut64 switch_addr, ut64 case_value, ut64 case_addr) {
if (!block->switch_op) {
block->switch_op = rz_anal_switch_op_new (switch_addr, 0, 0, 0);
block->switch_op = rz_analysis_switch_op_new (switch_addr, 0, 0, 0);
}
rz_anal_switch_op_add_case (block->switch_op, case_addr, case_value, case_addr);
rz_analysis_switch_op_add_case (block->switch_op, case_addr, case_value, case_addr);
}
RZ_API bool rz_anal_block_op_starts_at(RzAnalBlock *bb, ut64 addr) {
if (!rz_anal_block_contains (bb, addr)) {
RZ_API bool rz_analysis_block_op_starts_at(RzAnalysisBlock *bb, ut64 addr) {
if (!rz_analysis_block_contains (bb, addr)) {
return false;
}
ut64 off = addr - bb->addr;
@ -573,7 +573,7 @@ RZ_API bool rz_anal_block_op_starts_at(RzAnalBlock *bb, ut64 addr) {
}
size_t i;
for (i = 0; i < bb->ninstr; i++) {
ut16 inst_off = rz_anal_bb_offset_inst (bb, i);
ut16 inst_off = rz_analysis_bb_offset_inst (bb, i);
if (off == inst_off) {
return true;
}
@ -582,11 +582,11 @@ RZ_API bool rz_anal_block_op_starts_at(RzAnalBlock *bb, ut64 addr) {
}
typedef struct {
RzAnal *anal;
RzAnalBlock *cur_parent;
RzAnalysis *analysis;
RzAnalysisBlock *cur_parent;
ut64 dst;
RzPVector/*<RzAnalBlock>*/ *next_visit; // accumulate block of the next level in the tree
HtUP/*<RzAnalBlock>*/ *visited; // maps addrs to their previous block (or NULL for entry)
RzPVector/*<RzAnalysisBlock>*/ *next_visit; // accumulate block of the next level in the tree
HtUP/*<RzAnalysisBlock>*/ *visited; // maps addrs to their previous block (or NULL for entry)
} PathContext;
static bool shortest_path_successor_cb(ut64 addr, void *user) {
@ -596,7 +596,7 @@ static bool shortest_path_successor_cb(ut64 addr, void *user) {
return true;
}
ht_up_insert (ctx->visited, addr, ctx->cur_parent);
RzAnalBlock *block = rz_anal_get_block_at (ctx->anal, addr);
RzAnalysisBlock *block = rz_analysis_get_block_at (ctx->analysis, addr);
if (block) {
rz_pvector_push (ctx->next_visit, block);
}
@ -604,10 +604,10 @@ static bool shortest_path_successor_cb(ut64 addr, void *user) {
}
RZ_API RZ_NULLABLE RzList/*<RzAnalBlock *>*/ *rz_anal_block_shortest_path(RzAnalBlock *block, ut64 dst) {
RZ_API RZ_NULLABLE RzList/*<RzAnalysisBlock *>*/ *rz_analysis_block_shortest_path(RzAnalysisBlock *block, ut64 dst) {
RzList *ret = NULL;
PathContext ctx;
ctx.anal = block->anal;
ctx.analysis = block->analysis;
ctx.dst = dst;
// two vectors to swap cur_visit/next_visit
@ -630,9 +630,9 @@ RZ_API RZ_NULLABLE RzList/*<RzAnalBlock *>*/ *rz_anal_block_shortest_path(RzAnal
while (!rz_pvector_empty (cur_visit)) {
void **it;
rz_pvector_foreach (cur_visit, it) {
RzAnalBlock *cur = *it;
RzAnalysisBlock *cur = *it;
ctx.cur_parent = cur;
rz_anal_block_successor_addrs_foreach (cur, shortest_path_successor_cb, &ctx);
rz_analysis_block_successor_addrs_foreach (cur, shortest_path_successor_cb, &ctx);
}
RzPVector *tmp = cur_visit;
cur_visit = ctx.next_visit;
@ -642,14 +642,14 @@ RZ_API RZ_NULLABLE RzList/*<RzAnalBlock *>*/ *rz_anal_block_shortest_path(RzAnal
// reconstruct the path
bool found = false;
RzAnalBlock *prev = ht_up_find (ctx.visited, dst, &found);
RzAnalBlock *dst_block = rz_anal_get_block_at (block->anal, dst);
RzAnalysisBlock *prev = ht_up_find (ctx.visited, dst, &found);
RzAnalysisBlock *dst_block = rz_analysis_get_block_at (block->analysis, dst);
if (found && dst_block) {
ret = rz_list_newf ((RzListFree)rz_anal_block_unref);
rz_anal_block_ref (dst_block);
ret = rz_list_newf ((RzListFree)rz_analysis_block_unref);
rz_analysis_block_ref (dst_block);
rz_list_prepend (ret, dst_block);
while (prev) {
rz_anal_block_ref (prev);
rz_analysis_block_ref (prev);
rz_list_prepend (ret, prev);
prev = ht_up_find (ctx.visited, prev->addr, NULL);
}
@ -662,16 +662,16 @@ beach:
return ret;
}
RZ_API bool rz_anal_block_was_modified(RzAnalBlock *block) {
RZ_API bool rz_analysis_block_was_modified(RzAnalysisBlock *block) {
rz_return_val_if_fail (block, false);
if (!block->anal->iob.read_at) {
if (!block->analysis->iob.read_at) {
return false;
}
ut8 *buf = malloc (block->size);
if (!buf) {
return false;
}
if (!block->anal->iob.read_at (block->anal->iob.io, block->addr, buf, block->size)) {
if (!block->analysis->iob.read_at (block->analysis->iob.io, block->addr, buf, block->size)) {
free (buf);
return false;
}
@ -680,16 +680,16 @@ RZ_API bool rz_anal_block_was_modified(RzAnalBlock *block) {
return block->bbhash != cur_hash;
}
RZ_API void rz_anal_block_update_hash(RzAnalBlock *block) {
RZ_API void rz_analysis_block_update_hash(RzAnalysisBlock *block) {
rz_return_if_fail (block);
if (!block->anal->iob.read_at) {
if (!block->analysis->iob.read_at) {
return;
}
ut8 *buf = malloc (block->size);
if (!buf) {
return;
}
if (!block->anal->iob.read_at (block->anal->iob.io, block->addr, buf, block->size)) {
if (!block->analysis->iob.read_at (block->analysis->iob.io, block->addr, buf, block->size)) {
free (buf);
return;
}
@ -698,30 +698,30 @@ RZ_API void rz_anal_block_update_hash(RzAnalBlock *block) {
}
typedef struct {
RzAnalBlock *block;
RzAnalysisBlock *block;
bool reachable;
} NoreturnSuccessor;
static void noreturn_successor_free(HtUPKv *kv) {
NoreturnSuccessor *succ = kv->value;
rz_anal_block_unref (succ->block);
rz_analysis_block_unref (succ->block);
free (succ);
}
static bool noreturn_successors_cb(RzAnalBlock *block, void *user) {
static bool noreturn_successors_cb(RzAnalysisBlock *block, void *user) {
HtUP *succs = user;
NoreturnSuccessor *succ = RZ_NEW0 (NoreturnSuccessor);
if (!succ) {
return false;
}
rz_anal_block_ref (block);
rz_analysis_block_ref (block);
succ->block = block;
succ->reachable = false; // reset for first iteration
ht_up_insert (succs, block->addr, succ);
return true;
}
static bool noreturn_successors_reachable_cb(RzAnalBlock *block, void *user) {
static bool noreturn_successors_reachable_cb(RzAnalysisBlock *block, void *user) {
HtUP *succs = user;
NoreturnSuccessor *succ = ht_up_find (succs, block->addr, NULL);
if (succ) {
@ -731,10 +731,10 @@ static bool noreturn_successors_reachable_cb(RzAnalBlock *block, void *user) {
}
static bool noreturn_remove_unreachable_cb(void *user, const ut64 k, const void *v) {
RzAnalFunction *fcn = user;
RzAnalysisFunction *fcn = user;
NoreturnSuccessor *succ = (NoreturnSuccessor *)v;
if (!succ->reachable && rz_list_contains (succ->block->fcns, fcn)) {
rz_anal_function_remove_block (fcn, succ->block);
rz_analysis_function_remove_block (fcn, succ->block);
}
succ->reachable = false; // reset for next iteration
return true;
@ -743,17 +743,17 @@ static bool noreturn_remove_unreachable_cb(void *user, const ut64 k, const void
static bool noreturn_get_blocks_cb(void *user, const ut64 k, const void *v) {
RzList *blocks = user;
NoreturnSuccessor *succ = (NoreturnSuccessor *)v;
rz_anal_block_ref (succ->block);
rz_analysis_block_ref (succ->block);
rz_list_push (blocks, succ->block);
return true;
}
RZ_API RzAnalBlock *rz_anal_block_chop_noreturn(RzAnalBlock *block, ut64 addr) {
RZ_API RzAnalysisBlock *rz_analysis_block_chop_noreturn(RzAnalysisBlock *block, ut64 addr) {
rz_return_val_if_fail (block, NULL);
if (!rz_anal_block_contains (block, addr) || addr == block->addr) {
if (!rz_analysis_block_contains (block, addr) || addr == block->addr) {
return block;
}
rz_anal_block_ref (block);
rz_analysis_block_ref (block);
// Cache all recursive successors of block here.
// These are the candidates that we might have to remove from functions later.
@ -761,24 +761,24 @@ RZ_API RzAnalBlock *rz_anal_block_chop_noreturn(RzAnalBlock *block, ut64 addr) {
if (!succs) {
return block;
}
rz_anal_block_recurse (block, noreturn_successors_cb, succs);
rz_analysis_block_recurse (block, noreturn_successors_cb, succs);
// Chop the block. Resize and remove all destination addrs
rz_anal_block_set_size (block, addr - block->addr);
rz_analysis_block_set_size (block, addr - block->addr);
block->jump = UT64_MAX;
block->fail = UT64_MAX;
rz_anal_switch_op_free (block->switch_op);
rz_analysis_switch_op_free (block->switch_op);
block->switch_op = NULL;
// Now, for each fcn, check which of our successors are still reachable in the function remove and the ones that are not.
RzListIter *it;
RzAnalFunction *fcn;
RzAnalysisFunction *fcn;
// We need to clone the list because block->fcns will get modified in the loop
RzList *fcns_cpy = rz_list_clone (block->fcns);
rz_list_foreach (fcns_cpy, it, fcn) {
RzAnalBlock *entry = rz_anal_get_block_at (block->anal, fcn->addr);
RzAnalysisBlock *entry = rz_analysis_get_block_at (block->analysis, fcn->addr);
if (entry && rz_list_contains (entry->fcns, fcn)) {
rz_anal_block_recurse (entry, noreturn_successors_reachable_cb, succs);
rz_analysis_block_recurse (entry, noreturn_successors_reachable_cb, succs);
}
ht_up_foreach (succs, noreturn_remove_unreachable_cb, fcn);
}
@ -788,21 +788,21 @@ RZ_API RzAnalBlock *rz_anal_block_chop_noreturn(RzAnalBlock *block, ut64 addr) {
// Prepare to merge blocks with their predecessors if possible
RzList merge_blocks;
rz_list_init (&merge_blocks);
merge_blocks.free = (RzListFree)rz_anal_block_unref;
merge_blocks.free = (RzListFree)rz_analysis_block_unref;
ht_up_foreach (succs, noreturn_get_blocks_cb, &merge_blocks);
// Free/unref BEFORE doing the merge!
// Some of the blocks might not be valid anymore later!
rz_anal_block_unref (block);
rz_analysis_block_unref (block);
ht_up_free (succs);
ut64 block_addr = block->addr; // save the addr to identify the block. the automerge might free it so we must not use the pointer!
// Do the actual merge
rz_anal_block_automerge (&merge_blocks);
rz_analysis_block_automerge (&merge_blocks);
// No try to recover the pointer to the block if it still exists
RzAnalBlock *ret = NULL;
RzAnalysisBlock *ret = NULL;
for (it = merge_blocks.head; it && (block = it->data, 1); it = it->n) {
if (block->addr == block_addr) {
// block is still there
@ -818,9 +818,9 @@ RZ_API RzAnalBlock *rz_anal_block_chop_noreturn(RzAnalBlock *block, ut64 addr) {
typedef struct {
HtUP *predecessors; // maps a block to its predecessor if it has exactly one, or NULL if there are multiple or the predecessor has multiple successors
HtUP *visited_blocks; // during predecessor search, mark blocks whose successors we already checked. Value is void *-casted count of successors
HtUP *blocks; // adresses of the blocks we might want to merge with their predecessors => RzAnalBlock *
HtUP *blocks; // adresses of the blocks we might want to merge with their predecessors => RzAnalysisBlock *
RzAnalBlock *cur_pred;
RzAnalysisBlock *cur_pred;
size_t cur_succ_count;
} AutomergeCtx;
@ -833,13 +833,13 @@ static bool count_successors_cb(ut64 addr, void *user) {
static bool automerge_predecessor_successor_cb(ut64 addr, void *user) {
AutomergeCtx *ctx = user;
ctx->cur_succ_count++;
RzAnalBlock *block = ht_up_find (ctx->blocks, addr, NULL);
RzAnalysisBlock *block = ht_up_find (ctx->blocks, addr, NULL);
if (!block) {
// we shouldn't merge this one so GL_DONT_CARE
return true;
}
bool found;
RzAnalBlock *pred = ht_up_find (ctx->predecessors, (ut64)block, &found);
RzAnalysisBlock *pred = ht_up_find (ctx->predecessors, (ut64)block, &found);
if (found) {
if (pred) {
// only one predecessor found so far, but we are the second so there are multiple now
@ -854,9 +854,9 @@ static bool automerge_predecessor_successor_cb(ut64 addr, void *user) {
static bool automerge_get_predecessors_cb(void *user, const ut64 k, const void *v) {
AutomergeCtx *ctx = user;
const RzAnalFunction *fcn = (const RzAnalFunction *)k;
const RzAnalysisFunction *fcn = (const RzAnalysisFunction *)k;
RzListIter *it;
RzAnalBlock *block;
RzAnalysisBlock *block;
rz_list_foreach (fcn->bbs, it, block) {
bool already_visited;
ht_up_find (ctx->visited_blocks, (ut64)block, &already_visited);
@ -865,7 +865,7 @@ static bool automerge_get_predecessors_cb(void *user, const ut64 k, const void *
}
ctx->cur_pred = block;
ctx->cur_succ_count = 0;
rz_anal_block_successor_addrs_foreach (block, automerge_predecessor_successor_cb, ctx);
rz_analysis_block_successor_addrs_foreach (block, automerge_predecessor_successor_cb, ctx);
ht_up_insert (ctx->visited_blocks, (ut64)block, (void *)ctx->cur_succ_count);
}
return true;
@ -873,7 +873,7 @@ static bool automerge_get_predecessors_cb(void *user, const ut64 k, const void *
// Try to find the contiguous predecessors of all given blocks and merge them if possible,
// i.e. if there are no other blocks that have this block as one of their successors
RZ_API void rz_anal_block_automerge(RzList *blocks) {
RZ_API void rz_analysis_block_automerge(RzList *blocks) {
rz_return_if_fail (blocks);
AutomergeCtx ctx = {
.predecessors = ht_up_new0 (),
@ -889,10 +889,10 @@ RZ_API void rz_anal_block_automerge(RzList *blocks) {
// Get all the functions and prepare ctx.blocks
RzListIter *it;
RzAnalBlock *block;
RzAnalysisBlock *block;
rz_list_foreach (blocks, it, block) {
RzListIter *fit;
RzAnalFunction *fcn;
RzAnalysisFunction *fcn;
rz_list_foreach (block->fcns, fit, fcn) {
ht_up_insert (relevant_fcns, (ut64)fcn, NULL);
}
@ -905,7 +905,7 @@ RZ_API void rz_anal_block_automerge(RzList *blocks) {
// Now finally do the merging
RzListIter *tmp;
rz_list_foreach_safe (blocks, it, tmp, block) {
RzAnalBlock *predecessor = ht_up_find (ctx.predecessors, (ut64)block, NULL);
RzAnalysisBlock *predecessor = ht_up_find (ctx.predecessors, (ut64)block, NULL);
if (!predecessor) {
continue;
}
@ -919,19 +919,19 @@ RZ_API void rz_anal_block_automerge(RzList *blocks) {
// However if there are other blocks that have block as the predecessor,
// we would uaf after the merge since block will be freed.
RzListIter *bit;
RzAnalBlock *clock;
RzAnalysisBlock *clock;
for (bit = it->n; bit && (clock = bit->data, 1); bit = bit->n) {
RzAnalBlock *fixup_pred = ht_up_find (ctx.predecessors, (ut64)clock, NULL);
RzAnalysisBlock *fixup_pred = ht_up_find (ctx.predecessors, (ut64)clock, NULL);
if (fixup_pred == block) {
rz_list_push (fixup_candidates, clock);
}
}
if (rz_anal_block_merge (predecessor, block)) { // rz_anal_block_merge() does checks like contiguous, to that's fine
if (rz_analysis_block_merge (predecessor, block)) { // rz_analysis_block_merge() does checks like contiguous, to that's fine
// block was merged into predecessor, it is now freed!
// Update number of successors of the predecessor
ctx.cur_succ_count = 0;
rz_anal_block_successor_addrs_foreach (predecessor, count_successors_cb, &ctx);
rz_analysis_block_successor_addrs_foreach (predecessor, count_successors_cb, &ctx);
ht_up_update (ctx.visited_blocks, (ut64)predecessor, (void *)ctx.cur_succ_count);
rz_list_foreach (fixup_candidates, bit, clock) {
// Make sure all previous pointers to block now go to predecessor

View file

@ -2,10 +2,10 @@
/* Universal calling convention implementation based on sdb */
#include <rz_anal.h>
#define DB anal->sdb_cc
#include <rz_analysis.h>
#define DB analysis->sdb_cc
RZ_API void rz_anal_cc_del(RzAnal *anal, const char *name) {
RZ_API void rz_analysis_cc_del(RzAnalysis *analysis, const char *name) {
size_t i;
RzStrBuf sb;
sdb_unset (DB, rz_strbuf_initf (&sb, "%s", name), 0);
@ -19,7 +19,7 @@ RZ_API void rz_anal_cc_del(RzAnal *anal, const char *name) {
rz_strbuf_fini (&sb);
}
RZ_API bool rz_anal_cc_set(RzAnal *anal, const char *expr) {
RZ_API bool rz_analysis_cc_set(RzAnalysis *analysis, const char *expr) {
char *e = strdup (expr);
char *p = strchr (e, '(');
if (!p) {
@ -68,7 +68,7 @@ RZ_API bool rz_anal_cc_set(RzAnal *anal, const char *expr) {
return true;
}
RZ_API char *rz_anal_cc_get(RzAnal *anal, const char *name) {
RZ_API char *rz_analysis_cc_get(RzAnalysis *analysis, const char *name) {
int i;
// get cc by name and print the expr
if (rz_str_cmp (sdb_const_get (DB, name, 0), "cc", -1)) {
@ -81,7 +81,7 @@ RZ_API char *rz_anal_cc_get(RzAnal *anal, const char *name) {
return NULL;
}
RzStrBuf *sb = rz_strbuf_new (NULL);
const char *self = rz_anal_cc_self (anal, name);
const char *self = rz_analysis_cc_self (analysis, name);
rz_strbuf_appendf (sb, "%s %s%s%s (", ret, self? self: "", self? ".": "", name);
bool isFirst = true;
for (i = 0; i < RZ_ANAL_CC_MAXARG; i++) {
@ -99,7 +99,7 @@ RZ_API char *rz_anal_cc_get(RzAnal *anal, const char *name) {
}
rz_strbuf_append (sb, ")");
const char *error = rz_anal_cc_error (anal, name);
const char *error = rz_analysis_cc_error (analysis, name);
if (error) {
rz_strbuf_appendf (sb, " %s", error);
}
@ -108,14 +108,14 @@ RZ_API char *rz_anal_cc_get(RzAnal *anal, const char *name) {
return rz_strbuf_drain (sb);
}
RZ_API bool rz_anal_cc_exist(RzAnal *anal, const char *convention) {
rz_return_val_if_fail (anal && convention, false);
RZ_API bool rz_analysis_cc_exist(RzAnalysis *analysis, const char *convention) {
rz_return_val_if_fail (analysis && convention, false);
const char *x = sdb_const_get (DB, convention, 0);
return x && *x && !strcmp (x, "cc");
}
RZ_API const char *rz_anal_cc_arg(RzAnal *anal, const char *convention, int n) {
rz_return_val_if_fail (anal, NULL);
RZ_API const char *rz_analysis_cc_arg(RzAnalysis *analysis, const char *convention, int n) {
rz_return_val_if_fail (analysis, NULL);
rz_return_val_if_fail (n >= 0, NULL);
if (!convention) {
return NULL;
@ -127,44 +127,44 @@ RZ_API const char *rz_anal_cc_arg(RzAnal *anal, const char *convention, int n) {
query = sdb_fmt ("cc.%s.argn", convention);
ret = sdb_const_get (DB, query, 0);
}
return ret? rz_str_constpool_get (&anal->constpool, ret): NULL;
return ret? rz_str_constpool_get (&analysis->constpool, ret): NULL;
}
RZ_API const char *rz_anal_cc_self(RzAnal *anal, const char *convention) {
rz_return_val_if_fail (anal && convention, NULL);
RZ_API const char *rz_analysis_cc_self(RzAnalysis *analysis, const char *convention) {
rz_return_val_if_fail (analysis && convention, NULL);
const char *query = sdb_fmt ("cc.%s.self", convention);
const char *self = sdb_const_get (DB, query, 0);
return self? rz_str_constpool_get (&anal->constpool, self): NULL;
return self? rz_str_constpool_get (&analysis->constpool, self): NULL;
}
RZ_API void rz_anal_cc_set_self(RzAnal *anal, const char *convention, const char *self) {
if (!rz_anal_cc_exist (anal, convention)) {
RZ_API void rz_analysis_cc_set_self(RzAnalysis *analysis, const char *convention, const char *self) {
if (!rz_analysis_cc_exist (analysis, convention)) {
return;
}
RzStrBuf sb;
sdb_set (anal->sdb_cc, rz_strbuf_initf (&sb, "cc.%s.self", convention), self, 0);
sdb_set (analysis->sdb_cc, rz_strbuf_initf (&sb, "cc.%s.self", convention), self, 0);
rz_strbuf_fini (&sb);
}
RZ_API const char *rz_anal_cc_error(RzAnal *anal, const char *convention) {
rz_return_val_if_fail (anal && convention, NULL);
RZ_API const char *rz_analysis_cc_error(RzAnalysis *analysis, const char *convention) {
rz_return_val_if_fail (analysis && convention, NULL);
const char *query = sdb_fmt ("cc.%s.error", convention);
const char *error = sdb_const_get (DB, query, 0);
return error? rz_str_constpool_get (&anal->constpool, error): NULL;
return error? rz_str_constpool_get (&analysis->constpool, error): NULL;
}
RZ_API void rz_anal_cc_set_error(RzAnal *anal, const char *convention, const char *error) {
if (!rz_anal_cc_exist (anal, convention)) {
RZ_API void rz_analysis_cc_set_error(RzAnalysis *analysis, const char *convention, const char *error) {
if (!rz_analysis_cc_exist (analysis, convention)) {
return;
}
RzStrBuf sb;
sdb_set (anal->sdb_cc, rz_strbuf_initf (&sb, "cc.%s.error", convention), error, 0);
sdb_set (analysis->sdb_cc, rz_strbuf_initf (&sb, "cc.%s.error", convention), error, 0);
rz_strbuf_fini (&sb);
}
RZ_API int rz_anal_cc_max_arg(RzAnal *anal, const char *cc) {
RZ_API int rz_analysis_cc_max_arg(RzAnalysis *analysis, const char *cc) {
int i = 0;
rz_return_val_if_fail (anal && DB && cc, 0);
rz_return_val_if_fail (analysis && DB && cc, 0);
static void *oldDB = NULL;
static char *oldCC = NULL;
static int oldArg = 0;
@ -185,20 +185,20 @@ RZ_API int rz_anal_cc_max_arg(RzAnal *anal, const char *cc) {
return i;
}
RZ_API const char *rz_anal_cc_ret(RzAnal *anal, const char *convention) {
rz_return_val_if_fail (anal && convention, NULL);
RZ_API const char *rz_analysis_cc_ret(RzAnalysis *analysis, const char *convention) {
rz_return_val_if_fail (analysis && convention, NULL);
char *query = sdb_fmt ("cc.%s.ret", convention);
return sdb_const_get (DB, query, 0);
}
RZ_API const char *rz_anal_cc_default(RzAnal *anal) {
rz_return_val_if_fail (anal, NULL);
RZ_API const char *rz_analysis_cc_default(RzAnalysis *analysis) {
rz_return_val_if_fail (analysis, NULL);
return sdb_const_get (DB, "default.cc", 0);
}
RZ_API const char *rz_anal_cc_func(RzAnal *anal, const char *func_name) {
rz_return_val_if_fail (anal && func_name, NULL);
RZ_API const char *rz_analysis_cc_func(RzAnalysis *analysis, const char *func_name) {
rz_return_val_if_fail (analysis && func_name, NULL);
const char *query = sdb_fmt ("func.%s.cc", func_name);
const char *cc = sdb_const_get (anal->sdb_types, query, 0);
return cc ? cc : rz_anal_cc_default (anal);
const char *cc = sdb_const_get (analysis->sdb_types, query, 0);
return cc ? cc : rz_analysis_cc_default (analysis);
}

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_anal.h>
#include <rz_analysis.h>
RZ_API const char *rz_anal_cond_tostring(int cc) {
RZ_API const char *rz_analysis_cond_tostring(int cc) {
switch (cc) {
case RZ_ANAL_COND_EQ: return "eq";
case RZ_ANAL_COND_NV: return "nv";
@ -24,38 +24,38 @@ RZ_API const char *rz_anal_cond_tostring(int cc) {
return "??";
}
RZ_API RzAnalCond *rz_anal_cond_new(void) {
return RZ_NEW0 (RzAnalCond);
RZ_API RzAnalysisCond *rz_analysis_cond_new(void) {
return RZ_NEW0 (RzAnalysisCond);
}
RZ_API void rz_anal_cond_fini (RzAnalCond *c) {
RZ_API void rz_analysis_cond_fini (RzAnalysisCond *c) {
if (!c) {
return;
}
rz_anal_value_free (c->arg[0]);
rz_anal_value_free (c->arg[1]);
rz_analysis_value_free (c->arg[0]);
rz_analysis_value_free (c->arg[1]);
c->arg[0] = c->arg[1] = NULL;
}
RZ_API void rz_anal_cond_free (RzAnalCond *c) {
RZ_API void rz_analysis_cond_free (RzAnalysisCond *c) {
if (!c) {
return;
}
rz_anal_cond_fini (c);
rz_analysis_cond_fini (c);
free (c);
}
// XXX?
RZ_API RzAnalCond *rz_anal_cond_clone(RzAnalCond *cond) {
RzAnalCond *c = RZ_NEW (RzAnalCond);
RZ_API RzAnalysisCond *rz_analysis_cond_clone(RzAnalysisCond *cond) {
RzAnalysisCond *c = RZ_NEW (RzAnalysisCond);
if (!c) {
return NULL;
}
memcpy (c, cond, sizeof (RzAnalCond));
memcpy (c, cond, sizeof (RzAnalysisCond));
return c;
}
static inline const char *condstring(RzAnalCond *cond) {
static inline const char *condstring(RzAnalysisCond *cond) {
const char *condstr_single[] = { "!", "", "0<", "0<=", "0>", "0>=" };
const char *condstr[] = { "==", "!=", ">=", ">", "<=", "<" };
if (cond) {
@ -68,11 +68,11 @@ static inline const char *condstring(RzAnalCond *cond) {
return "";
}
RZ_API int rz_anal_cond_eval(RzAnal *anal, RzAnalCond *cond) {
RZ_API int rz_analysis_cond_eval(RzAnalysis *analysis, RzAnalysisCond *cond) {
// XXX: sign issue here?
st64 arg0 = (st64) rz_anal_value_to_ut64 (anal, cond->arg[0]);
st64 arg0 = (st64) rz_analysis_value_to_ut64 (analysis, cond->arg[0]);
if (cond->arg[1]) {
st64 arg1 = (st64) rz_anal_value_to_ut64 (anal, cond->arg[1]);
st64 arg1 = (st64) rz_analysis_value_to_ut64 (analysis, cond->arg[1]);
switch (cond->type) {
case RZ_ANAL_COND_EQ: return arg0 == arg1;
case RZ_ANAL_COND_NE: return arg0 != arg1;
@ -95,15 +95,15 @@ RZ_API int rz_anal_cond_eval(RzAnal *anal, RzAnalCond *cond) {
}
// XXX conflict naming with tostring()
RZ_API char *rz_anal_cond_to_string(RzAnalCond *cond) {
RZ_API char *rz_analysis_cond_to_string(RzAnalysisCond *cond) {
char *val0, *val1, *out = NULL;
const char *cnd;
if (!cond) {
return NULL;
}
cnd = condstring (cond);
val0 = rz_anal_value_to_string (cond->arg[0]);
val1 = rz_anal_value_to_string (cond->arg[1]);
val0 = rz_analysis_value_to_string (cond->arg[0]);
val1 = rz_analysis_value_to_string (cond->arg[1]);
if (val0) {
if (RZ_ANAL_COND_SINGLE (cond)) {
int val0len = strlen (val0) + 10;
@ -124,9 +124,9 @@ RZ_API char *rz_anal_cond_to_string(RzAnalCond *cond) {
return out? out: strdup ("?");
}
RZ_API RzAnalCond *rz_anal_cond_new_from_op(RzAnalOp *op) {
RzAnalCond *cond;
if (!(cond = rz_anal_cond_new ())) {
RZ_API RzAnalysisCond *rz_analysis_cond_new_from_op(RzAnalysisOp *op) {
RzAnalysisCond *cond;
if (!(cond = rz_analysis_cond_new ())) {
return NULL;
}
//v->reg[0] = op->src[0];
@ -140,8 +140,8 @@ RZ_API RzAnalCond *rz_anal_cond_new_from_op(RzAnalOp *op) {
return cond;
}
RZ_API RzAnalCond *rz_anal_cond_new_from_string(const char *str) {
RzAnalCond *cond = RZ_NEW (RzAnalCond);
RZ_API RzAnalysisCond *rz_analysis_cond_new_from_string(const char *str) {
RzAnalysisCond *cond = RZ_NEW (RzAnalysisCond);
// TODO: find '<','=','>','!'...
return cond;
}

View file

@ -1,11 +1,11 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_anal.h>
#include <rz_analysis.h>
#include <rz_list.h>
#include <rz_types.h>
RZ_API RzAnalCycleFrame *rz_anal_cycle_frame_new(void) {
RzAnalCycleFrame *cf = RZ_NEW0 (RzAnalCycleFrame);
RZ_API RzAnalysisCycleFrame *rz_analysis_cycle_frame_new(void) {
RzAnalysisCycleFrame *cf = RZ_NEW0 (RzAnalysisCycleFrame);
if (cf) {
if (!(cf->hooks = rz_list_new ())) {
RZ_FREE (cf);
@ -14,7 +14,7 @@ RZ_API RzAnalCycleFrame *rz_anal_cycle_frame_new(void) {
return cf;
}
RZ_API void rz_anal_cycle_frame_free(RzAnalCycleFrame *cf) {
RZ_API void rz_analysis_cycle_frame_free(RzAnalysisCycleFrame *cf) {
if (!cf) {
return;
}

View file

@ -121,7 +121,7 @@ install: ${F_SDB}
CWD=$(shell pwd)
symstall install-symlink: ${F_SDB}
cd ../../.. && mkdir -p "${FCNSIGNPATH}" && \
for FILE in $(shell cd $(TOP)/librz/anal/d ; ls *.sdb); do \
for FILE in $(shell cd $(TOP)/librz/analysis/d ; ls *.sdb); do \
ln -fs "$(CWD)/$$FILE" "$(FCNSIGNPATH)/$$FILE" ; \
done

Some files were not shown because too many files have changed in this diff Show more