Introduce RzArchPlatform and support for platform profiles (#1254)
* Remove the unnecessary `sdb` pointer of `RzArchTarget` The SDB pointer in `RzArchTarget` is not needed as `sdb_load_arch_profile_by_path` creates a new SDB pointer and takes care of our requirements. * Introduce `RzArchPlatformTarget` and `RzArchPlatformItem` and the new APIs Also define a new flagspace: `RZ_FLAGS_FS_PLATFORM_PORTS` * Introduce a new configuration variable `asm.platform` to choose the platform profile * Define and call the APIs for platform profiles * Add the SDB file for BCM 2835 and a unit test * Check for NULL at various places and run `clang-format` * Use `RZ_NONULL` for the parameters of `rz_arch_platform_init` * Add `RZ_NONNULL` to all of the arguments which gets `rz_return[_val]_if()`-ed * Let `platform` be NULLABLE and fix the ASAN tests
This commit is contained in:
parent
f807a447aa
commit
381f22d7cc
19 changed files with 546 additions and 18 deletions
|
|
@ -125,6 +125,7 @@ RZ_API RzAnalysis *rz_analysis_new(void) {
|
|||
analysis->diff_thfcn = RZ_ANALYSIS_THRESHOLDFCN;
|
||||
analysis->syscall = rz_syscall_new();
|
||||
analysis->arch_target = rz_arch_target_new();
|
||||
analysis->platform_target = rz_arch_platform_target_new();
|
||||
rz_io_bind_init(analysis->iob);
|
||||
rz_flag_bind_init(analysis->flb);
|
||||
analysis->reg = rz_reg_new();
|
||||
|
|
@ -177,6 +178,7 @@ RZ_API RzAnalysis *rz_analysis_free(RzAnalysis *a) {
|
|||
rz_analysis_pin_fini(a);
|
||||
rz_syscall_free(a->syscall);
|
||||
rz_arch_target_free(a->arch_target);
|
||||
rz_arch_platform_target_free(a->platform_target);
|
||||
rz_reg_free(a->reg);
|
||||
ht_up_free(a->ht_xrefs_from);
|
||||
ht_up_free(a->ht_xrefs_to);
|
||||
|
|
|
|||
147
librz/analysis/arch_platform.c
Normal file
147
librz/analysis/arch_platform.c
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
// SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_arch.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* \brief Creates a new RzArchPlatformItem type
|
||||
*/
|
||||
RZ_API RZ_OWN RzArchPlatformItem *rz_arch_platform_item_new(RZ_NULLABLE const char *name) {
|
||||
RzArchPlatformItem *item = RZ_NEW0(RzArchPlatformItem);
|
||||
if (!item) {
|
||||
return NULL;
|
||||
}
|
||||
item->name = name ? strdup(name) : NULL;
|
||||
item->comment = NULL;
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates a new RzArchPlatformTarget type
|
||||
*/
|
||||
RZ_API RZ_OWN RzArchPlatformTarget *rz_arch_platform_target_new() {
|
||||
RzArchPlatformTarget *target = RZ_NEW0(RzArchPlatformTarget);
|
||||
if (!target) {
|
||||
return NULL;
|
||||
}
|
||||
target->platforms = ht_up_new0();
|
||||
if (!target->platforms) {
|
||||
free(target);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Frees an RzArchPlatformTarget type
|
||||
*/
|
||||
RZ_API void rz_arch_platform_target_free(RzArchPlatformTarget *target) {
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
ht_up_free(target->platforms);
|
||||
free(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Frees an RzArchPlatformItem type
|
||||
*/
|
||||
RZ_API void rz_arch_platform_item_free(RzArchPlatformItem *item) {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
free(item->name);
|
||||
free(item->comment);
|
||||
free(item);
|
||||
}
|
||||
|
||||
static bool sdb_load_platform_profile(RZ_NONNULL RzArchPlatformTarget *t, RZ_NONNULL Sdb *sdb) {
|
||||
rz_return_val_if_fail(t && sdb, NULL);
|
||||
SdbKv *kv;
|
||||
SdbListIter *iter;
|
||||
SdbList *l = sdb_foreach_list(sdb, false);
|
||||
char *argument_key, *comment, *name;
|
||||
ls_foreach (l, iter, kv) {
|
||||
if (!strcmp(sdbkv_value(kv), "name")) {
|
||||
name = sdbkv_key(kv);
|
||||
|
||||
RzArchPlatformItem *item = rz_arch_platform_item_new(name);
|
||||
|
||||
argument_key = rz_str_newf("%s.address", item->name);
|
||||
if (!argument_key) {
|
||||
rz_arch_platform_item_free(item);
|
||||
return NULL;
|
||||
}
|
||||
ut64 address = sdb_num_get(sdb, argument_key, NULL);
|
||||
if (!address) {
|
||||
rz_arch_platform_item_free(item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
argument_key = rz_str_newf("%s.comment", item->name);
|
||||
comment = sdb_get(sdb, argument_key, NULL);
|
||||
if (comment) {
|
||||
item->comment = comment;
|
||||
}
|
||||
ht_up_insert(t->platforms, address, item);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sdb_load_arch_platform_by_path(RZ_NONNULL RzArchPlatformTarget *t, RZ_NONNULL const char *path) {
|
||||
rz_return_val_if_fail(t && path, NULL);
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
Sdb *db = sdb_new(0, path, 0);
|
||||
if (!db) {
|
||||
return false;
|
||||
}
|
||||
bool result = sdb_load_platform_profile(t, db);
|
||||
sdb_close(db);
|
||||
sdb_free(db);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Loads the contents of the Platform Profile to the RzArchPlatformTarget
|
||||
*
|
||||
* \param t reference to RzArchPlatformTarget
|
||||
* \param path reference to path of the SDB file
|
||||
*/
|
||||
RZ_API bool rz_arch_load_platform_sdb(RZ_NONNULL RzArchPlatformTarget *t, RZ_NONNULL const char *path) {
|
||||
rz_return_val_if_fail(t && path, NULL);
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
if (!rz_file_exists(path)) {
|
||||
return false;
|
||||
}
|
||||
return sdb_load_arch_platform_by_path(t, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize Platform Profiles by setting the path to the corresponding SDB file
|
||||
*
|
||||
* \param t reference to RzArchPlatformTarget
|
||||
* \param arch reference to the selected architecture (value of `asm.arch`
|
||||
* \param platform reference to the selected platform (value of `asm.platform`)
|
||||
* \param dir_prefix reference to the directory prefix or the value of dir.prefix
|
||||
*/
|
||||
RZ_API bool rz_arch_platform_init(RzArchPlatformTarget *t, RZ_NONNULL const char *arch, RZ_NONNULL const char *cpu,
|
||||
const char *platform, RZ_NONNULL const char *dir_prefix) {
|
||||
|
||||
if (!platform) {
|
||||
return false;
|
||||
}
|
||||
rz_return_val_if_fail(arch && cpu && dir_prefix, NULL);
|
||||
char *path = rz_str_newf(RZ_JOIN_4_PATHS("%s", RZ_SDB, "asm/platforms", "%s-%s-%s.sdb"),
|
||||
dir_prefix, arch, cpu, platform);
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
rz_arch_load_platform_sdb(t, path);
|
||||
free(path);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,10 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_types.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_arch.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
|
|
@ -52,15 +49,9 @@ RZ_API RZ_OWN RzArchTarget *rz_arch_target_new() {
|
|||
if (!profile) {
|
||||
return NULL;
|
||||
}
|
||||
profile->db = sdb_new0();
|
||||
if (!profile->db) {
|
||||
free(profile);
|
||||
return NULL;
|
||||
}
|
||||
profile->profile = rz_arch_profile_new();
|
||||
if (!profile->profile) {
|
||||
free(profile);
|
||||
sdb_free(profile->db);
|
||||
return NULL;
|
||||
}
|
||||
return profile;
|
||||
|
|
@ -75,7 +66,6 @@ RZ_API void rz_arch_target_free(RzArchTarget *t) {
|
|||
if (!t) {
|
||||
return;
|
||||
}
|
||||
sdb_free(t->db);
|
||||
rz_arch_profile_free(t->profile);
|
||||
free(t);
|
||||
}
|
||||
|
|
@ -191,7 +181,7 @@ static bool is_cpu_valid(char *cpu_dir, const char *cpu) {
|
|||
*
|
||||
* \param t reference to RzArchTarget
|
||||
* \param cpu reference to the selected CPU (value of `asm.cpu`)
|
||||
* \param arch reference to the seletec architecture (value of `asm.arch`)
|
||||
* \param arch reference to the selected architecture (value of `asm.arch`)
|
||||
* \param dir_prefix reference to the directory prefix or the value of dir.prefix
|
||||
*/
|
||||
RZ_API bool rz_arch_profiles_init(RzArchTarget *t, const char *cpu, const char *arch, const char *dir_prefix) {
|
||||
|
|
@ -211,10 +201,7 @@ RZ_API bool rz_arch_profiles_init(RzArchTarget *t, const char *cpu, const char *
|
|||
path = rz_str_newf("%s" RZ_SYS_DIR RZ_SDB RZ_SYS_DIR "asm" RZ_SYS_DIR "cpus" RZ_SYS_DIR "avr-ATmega8.sdb", dir_prefix);
|
||||
}
|
||||
}
|
||||
if (!rz_arch_load_profile_sdb(t, path)) {
|
||||
sdb_free(t->db);
|
||||
t->db = NULL;
|
||||
}
|
||||
rz_arch_load_profile_sdb(t, path);
|
||||
free(path);
|
||||
free(cpu_dir);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
rz_analysis_sources = [
|
||||
'analysis.c',
|
||||
'arch_profile.c',
|
||||
'arch_platform.c',
|
||||
'block.c',
|
||||
'function.c',
|
||||
'jmptbl.c',
|
||||
|
|
|
|||
|
|
@ -336,7 +336,8 @@ static char *mnemonics(RzAsm *a, int id, bool json) {
|
|||
RzAsmPlugin rz_asm_plugin_arm_cs = {
|
||||
.name = "arm",
|
||||
.desc = "Capstone ARM disassembler",
|
||||
.cpus = ",v8,cortex",
|
||||
.cpus = "v8,cortex,arm1176",
|
||||
.platforms = "bcm2835,omap3430",
|
||||
.features = "v8",
|
||||
.license = "BSD",
|
||||
.arch = "arm",
|
||||
|
|
|
|||
230
librz/asm/platforms/arm-arm1176-bcm2835.sdb.txt
Normal file
230
librz/asm/platforms/arm-arm1176-bcm2835.sdb.txt
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
AUX_IRQ=name
|
||||
AUX_IRQ.address=0x7e215000
|
||||
AUX_IRQ.comment=Auxiliary Interrupt status
|
||||
|
||||
AUX_ENABLES=name
|
||||
AUX_ENABLES.address=0x7e21500
|
||||
|
||||
AUX_MU_IO_REG=name
|
||||
AUX_MU_IO_REG.address=0x7e215040
|
||||
AUX_MU_IO_REG.comment=Mini UART I/O Data
|
||||
|
||||
AUX_MU_IER_REG=name
|
||||
AUX_MU_IER_REG.address=0x7e215044
|
||||
AUX_MU_IER_REG.comment=Mini UART Interrupt Enable
|
||||
|
||||
AUX_MU_IIR_REG=name
|
||||
AUX_MU_IIR_REG.address=0x7e215048
|
||||
AUX_MU_IIR_REG.comment=Mini UART Interrupt Identify
|
||||
|
||||
AUX_MU_LCR_REG=name
|
||||
AUX_MU_LCR_REG.address=0x7e21504c
|
||||
AUX_MU_LCR_REG.comment=Mini UART Line Control
|
||||
|
||||
AUX_MU_MCR_REG=name
|
||||
AUX_MU_MCR_REG.address=0x7e215050
|
||||
AUX_MU_MCR_REG.comment=Mini UART Modem Control
|
||||
|
||||
AUX_MU_LSR_REG=name
|
||||
AUX_MU_LSR_REG.address=0x7e215054
|
||||
AUX_MU_LSR_REG.comment=Mini UART Line Status
|
||||
|
||||
AUX_MU_MSR_REG=name
|
||||
AUX_MU_MSR_REG.address=0x7e215058
|
||||
AUX_MU_MSR_REG.comment=Mini UART Modem Status
|
||||
|
||||
AUX_MU_SCRATCH=name
|
||||
AUX_MU_SCRATCH.address=0x7e21505c
|
||||
AUX_MU_SCRATCH.comment=Mini UART Scratch
|
||||
|
||||
AUX_MU_CNTL_REG=name
|
||||
AUX_MU_CNTL_REG.address=0x7e215060
|
||||
AUX_MU_CNTL_REG.comment=Mini UART Extra Control
|
||||
|
||||
AUX_MU_STAT_REG=name
|
||||
AUX_MU_STAT_REG.address=0x7e215064
|
||||
AUX_MU_STAT_REG.comment=Mini UART Extra Status
|
||||
|
||||
AUX_MU_BAUD_REG=name
|
||||
AUX_MU_BAUD_REG.address=0x7e215068
|
||||
AUX_MU_BAUD_REG.comment=Mini UART Baudrate
|
||||
|
||||
AUX_SPI0_CNTL0_REG=name
|
||||
AUX_SPI0_CNTL0_REG.address=0x7e215080
|
||||
AUX_SPI0_CNTL0_REG.comment=SPI 1 Control register 0
|
||||
|
||||
AUX_SPI0_CNTL1_REG=name
|
||||
AUX_SPI0_CNTL1_REG.address=0x7e215084
|
||||
AUX_SPI0_CNTL1_REG.comment=SPI 1 Control register 1
|
||||
|
||||
AUX_SPI0_STAT_REG=name
|
||||
AUX_SPI0_STAT_REG.address=0x7e215088
|
||||
AUX_SPI0_STAT_REG.comment=SPI 1 Status
|
||||
|
||||
AUX_SPI0_IO_REG=name
|
||||
AUX_SPI0_IO_REG.address=0x7e215090
|
||||
AUX_SPI0_IO_REG.comment=SPI 1 Data
|
||||
|
||||
AUX_SPI0_PEEK_REG=name
|
||||
AUX_SPI0_PEEK_REG.address=0x7e215094
|
||||
AUX_SPI0_PEEK_REG.comment=SPI 1 Peek
|
||||
|
||||
AUX_SPI1_CNTL0_REG=name
|
||||
AUX_SPI1_CNTL0_REG.address=0x7e2150c0
|
||||
AUX_SPI1_CNTL0_REG.comment=SPI 2 Control register 0
|
||||
|
||||
AUX_SPI1_CNTL1_REG=name
|
||||
AUX_SPI1_CNTL1_REG.address=0x7e2150c4
|
||||
AUX_SPI1_CNTL1_REG.comment=SPI 2 Control register 1
|
||||
|
||||
AUX_SPI1_STAT_REG=name
|
||||
AUX_SPI1_STAT_REG.address=0x7e2150c8
|
||||
AUX_SPI1_STAT_REG.comment=SPI 2 Status
|
||||
|
||||
AUX_SPI1_IO_REG=name
|
||||
AUX_SPI1_IO_REG.address=0x7e2150d0
|
||||
AUX_SPI1_IO_REG.comment=SPI 2 Data
|
||||
|
||||
AUX_SPI1_PEEK_REG=name
|
||||
AUX_SPI1_PEEK_REG.address=0x7e2150d4
|
||||
AUX_SPI1_PEEK_REG.comment=SPI 2 Peek
|
||||
|
||||
BSC0=name
|
||||
BSC0.address=0x7e205000
|
||||
BSC0.comment=Broadcom Serial Controller 0 (BSC)
|
||||
|
||||
BSC1=name
|
||||
BSC1.address=0x7e804000
|
||||
BSC1.comment=Broadcom Serial Controller 1 (BSC)
|
||||
|
||||
BSC2=name
|
||||
BSC2.address=0x7e805000
|
||||
BSC2.comment=Broadcom Serial Controller 2 (BSC)
|
||||
|
||||
DMA=name
|
||||
DMA.address=0x7e007000
|
||||
DMA.comment=DMA Controller (adjacent DMA Channels are offset by 0x100)
|
||||
|
||||
EMMC=name
|
||||
EMMC.address=0x7e300000
|
||||
EMMC.comment=External Mass Media Controller
|
||||
|
||||
GPFSEL0=name
|
||||
GPFSEL0.address=0x7e200000
|
||||
GPFSEL0.comment=GPIO Function Select 0
|
||||
|
||||
GPFSEL1=name
|
||||
GPFSEL1.address=0x7e200004
|
||||
GPFSEL1.comment=GPIO Function Select 1
|
||||
|
||||
GPFSEL2=name
|
||||
GPFSEL2.address=0x7e200008
|
||||
GPFSEL2.comment=GPIO Function Select 2
|
||||
|
||||
GPFSEL3=name
|
||||
GPFSEL3.address=0x7e20000c
|
||||
GPFSEL3.comment=GPIO Function Select 3
|
||||
|
||||
GPFSEL4=name
|
||||
GPFSEL4.address=0x7e200010
|
||||
GPFSEL4.comment=GPIO Function Select 4
|
||||
|
||||
GPFSEL5=name
|
||||
GPFSEL5.address=0x7e200014
|
||||
GPFSEL5.comment=GPIO Function Select 5
|
||||
|
||||
GPSET0=name
|
||||
GPSET0.address=0x7e20001c
|
||||
GPSET0.comment=GPIO Pin Output Set 0
|
||||
|
||||
GPSET1=name
|
||||
GPSET1.address=0x7e200020
|
||||
GPSET1.comment=GPIO Pin Output Set 1
|
||||
|
||||
GPCLR0=name
|
||||
GPCLR0.address=0x7e200028
|
||||
GPCLR0.comment=GPIO Pin Output Clear 0
|
||||
|
||||
GPCLR1=name
|
||||
GPCLR1.address=0x7e20002c
|
||||
GPCLR1.comment=GPIO Pin Output Clear 1
|
||||
|
||||
GPLEV0=name
|
||||
GPLEV0.address=0x7e200034
|
||||
GPLEV0.comment=GPIO Pin Level 0
|
||||
|
||||
GPLEV0=name
|
||||
GPLEV0.address=0x7e200038
|
||||
GPLEV0.comment=GPIO Pin Level 1
|
||||
|
||||
GPEDS0=name
|
||||
GPEDS0.address=0x7e200040
|
||||
GPEDS0.comment=GPIO Pin Event Detect Status 0
|
||||
|
||||
GPEDS1=name
|
||||
GPEDS1.address=0x7e200044
|
||||
GPEDS1.comment=GPIO Pin Event Detect Status 0
|
||||
|
||||
GPREN0=name
|
||||
GPREN0.address=0x7e20004c
|
||||
GPREN0.comment=GPIO Pin Rising Edge Detect Enable 0
|
||||
|
||||
GPREN1=name
|
||||
GPREN1.address=0x7e200050
|
||||
GPREN1.comment=GPIO Pin Rising Edge Detect Enable 0
|
||||
|
||||
GPFEN0=name
|
||||
GPFEN0.address=0x7e200058
|
||||
GPFEN0.comment=GPIO Pin Falling Edge Detect Enable 0
|
||||
|
||||
GPFEN1=name
|
||||
GPFEN1.address=0x7e20005c
|
||||
GPFEN1.comment=GPIO Pin Falling Edge Detect Enable 1
|
||||
|
||||
GPHEN0=name
|
||||
GPHEN0.address=0x7e200064
|
||||
GPHEN0.comment=GPIO Pin High Detect Enable 0
|
||||
|
||||
GPLEN1=name
|
||||
GPLEN1.address=0x7e200068
|
||||
GPLEN1.comment=GPIO Pin High Detect Enable 1
|
||||
|
||||
GPLEN0=name
|
||||
GPLEN0.address=0x7e200070
|
||||
GPLEN0.comment=GPIO Pin High Detect Enable 2
|
||||
|
||||
GPAREN0=name
|
||||
GPAREN0.address=0x7e20007c
|
||||
GPAREN0.comment=GPIO Pin Async. Rising Edge Detect 0
|
||||
|
||||
GPAREN1=name
|
||||
GPAREN1.address=0x7e200080
|
||||
GPAREN1.comment=GPIO Pin Async. Rising Edge Detect 1
|
||||
|
||||
GPPUD=name
|
||||
GPPUD.address=0x7e200094
|
||||
GPPUD.comment=GPIO Pin Pull-up/down Enable
|
||||
|
||||
GPPUDCLK0=name
|
||||
GPPUDCLK0.address=0x7e200098
|
||||
GPPUDCLK0.comment=PIO Pin Pull-up/down Enable Clock 0
|
||||
|
||||
GPPUDCLK1=name
|
||||
GPPUDCLK1.address=0x7e20009c
|
||||
GPPUDCLK1.comment=PIO Pin Pull-up/down Enable Clock 1
|
||||
|
||||
System Timer=name
|
||||
System Timer.address=0x7E003000
|
||||
System Timer.comment=The System Timer provides four 32-bit timer channels and a single 64-bit free running counter
|
||||
|
||||
USB_MDIO_CNTL=name
|
||||
USB_MDIO_CNTL.address=0x7e980080
|
||||
USB_MDIO_CNTL.comment=USB MDIO interface control
|
||||
|
||||
USB_MDIO_GEN=name
|
||||
USB_MDIO_GEN.address=0x7e980084
|
||||
USB_MDIO_GEN.comment=USB Data for MDIO interface
|
||||
|
||||
USB_VBUS_DRV=name
|
||||
USB_VBUS_DRV.address=0x7e980088
|
||||
USB_VBUS_DRV.comment=USB Vbus and other Miscellaneous controls
|
||||
16
librz/asm/platforms/meson.build
Normal file
16
librz/asm/platforms/meson.build
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
sdb_files = [
|
||||
'arm-arm1176-bcm2835',
|
||||
]
|
||||
|
||||
foreach file : sdb_files
|
||||
outfile = '@0@.sdb'.format(file)
|
||||
custom_target(outfile,
|
||||
input: '@0@.sdb.txt'.format(file),
|
||||
output: outfile,
|
||||
command: sdb_gen_cmd,
|
||||
depends: sdb_exe,
|
||||
build_by_default: true,
|
||||
install: true,
|
||||
install_dir: join_paths(rizin_sdb, 'asm/platforms')
|
||||
)
|
||||
endforeach
|
||||
|
|
@ -6479,6 +6479,32 @@ RZ_API void rz_arch_profile_add_flag_every_io(RzArchProfile *profile, RzFlag *fl
|
|||
ht_up_foreach(profile->registers_extended, add_mmio_extended_flag_cb, flags);
|
||||
}
|
||||
|
||||
static bool add_arch_platform_flag_comment_cb(void *user, const ut64 addr, const void *v) {
|
||||
if (!v) {
|
||||
return false;
|
||||
}
|
||||
RzArchPlatformItem *item = (RzArchPlatformItem *)v;
|
||||
RzCore *core = (RzCore *)user;
|
||||
rz_flag_space_push(core->flags, RZ_FLAGS_FS_PLATFORM_PORTS);
|
||||
rz_flag_set(core->flags, item->name, addr, 1);
|
||||
rz_flag_space_pop(core->flags);
|
||||
if (item->comment) {
|
||||
rz_core_meta_comment_add(core, item->comment, addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds the information from the Platform Profiles as flags and comments
|
||||
*
|
||||
* \param core reference to RzCore
|
||||
*/
|
||||
RZ_API bool rz_arch_platform_add_flags_comments(RzCore *core) {
|
||||
rz_flag_unset_all_in_space(core->flags, RZ_FLAGS_FS_PLATFORM_PORTS);
|
||||
ht_up_foreach(core->analysis->platform_target->platforms, add_arch_platform_flag_comment_cb, core);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* TODO: move into rz_analysis_function_rename (); */
|
||||
RZ_API bool rz_core_analysis_function_rename(RzCore *core, ut64 addr, const char *_name) {
|
||||
rz_return_val_if_fail(core && _name, false);
|
||||
|
|
|
|||
|
|
@ -435,6 +435,8 @@ static bool cb_asmcpu(void *user, void *data) {
|
|||
|
||||
const char *dir_prefix = rz_config_get(core->config, "dir.prefix");
|
||||
rz_arch_profiles_init(core->analysis->arch_target, node->value, rz_config_get(core->config, "asm.arch"), dir_prefix);
|
||||
const char *platform = rz_config_get(core->config, "asm.platform");
|
||||
rz_arch_platform_init(core->analysis->platform_target, rz_config_get(core->config, "asm.arch"), node->value, platform, dir_prefix);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -563,11 +565,13 @@ static bool cb_asmarch(void *user, void *data) {
|
|||
if (core->analysis) {
|
||||
const char *asmcpu = rz_config_get(core->config, "asm.cpu");
|
||||
const char *dir_prefix = rz_config_get(core->config, "dir.prefix");
|
||||
const char *platform = rz_config_get(core->config, "asm.platform");
|
||||
if (!rz_syscall_setup(core->analysis->syscall, node->value, core->analysis->bits, asmcpu, asmos)) {
|
||||
//eprintf ("asm.arch: Cannot setup syscall '%s/%s' from '%s'\n",
|
||||
// node->value, asmos, RZ_LIBDIR"/rizin/"RZ_VERSION"/syscall");
|
||||
}
|
||||
update_syscall_ns(core);
|
||||
rz_arch_platform_init(core->analysis->platform_target, node->value, asmcpu, platform, dir_prefix);
|
||||
rz_arch_profiles_init(core->analysis->arch_target, asmcpu, node->value, dir_prefix);
|
||||
}
|
||||
//if (!strcmp (node->value, "bf"))
|
||||
|
|
@ -612,8 +616,10 @@ static bool cb_asmarch(void *user, void *data) {
|
|||
rz_core_analysis_cc_init(core);
|
||||
|
||||
const char *dir_prefix = rz_config_get(core->config, "dir.prefix");
|
||||
const char *platform = rz_config_get(core->config, "asm.platform");
|
||||
rz_sysreg_set_arch(core->analysis->syscall, node->value, dir_prefix);
|
||||
if (asmcpu) {
|
||||
rz_arch_platform_init(core->analysis->platform_target, node->value, asmcpu->value, platform, dir_prefix);
|
||||
rz_arch_profiles_init(core->analysis->arch_target, asmcpu->value, node->value, dir_prefix);
|
||||
}
|
||||
|
||||
|
|
@ -727,6 +733,7 @@ static void update_asmfeatures_options(RzCore *core, RzConfigNode *node) {
|
|||
if (core && core->rasm && core->rasm->cur) {
|
||||
if (core->rasm->cur->features) {
|
||||
char *features = strdup(core->rasm->cur->features);
|
||||
rz_list_purge(node->options);
|
||||
argc = rz_str_split(features, ',');
|
||||
for (i = 0; i < argc; i++) {
|
||||
node->options->free = free;
|
||||
|
|
@ -762,6 +769,48 @@ static bool cb_asmfeatures(void *user, void *data) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void update_asmplatforms_options(RzCore *core, RzConfigNode *node) {
|
||||
int i, argc;
|
||||
|
||||
if (core && core->rasm && core->rasm->cur) {
|
||||
if (core->rasm->cur->platforms) {
|
||||
char *platforms = strdup(core->rasm->cur->platforms);
|
||||
rz_list_purge(node->options);
|
||||
argc = rz_str_split(platforms, ',');
|
||||
for (i = 0; i < argc; i++) {
|
||||
node->options->free = free;
|
||||
const char *feature = rz_str_word_get0(platforms, i);
|
||||
if (feature) {
|
||||
rz_list_append(node->options, strdup(feature));
|
||||
}
|
||||
}
|
||||
free(platforms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool cb_asmplatform(void *user, void *data) {
|
||||
RzCore *core = (RzCore *)user;
|
||||
RzConfigNode *node = (RzConfigNode *)data;
|
||||
if (!core) {
|
||||
return false;
|
||||
}
|
||||
if (*node->value == '?') {
|
||||
update_asmplatforms_options(core, node);
|
||||
print_node_options(node);
|
||||
return 0;
|
||||
}
|
||||
RZ_FREE(core->rasm->platforms);
|
||||
if (node->value[0]) {
|
||||
core->rasm->platforms = strdup(node->value);
|
||||
}
|
||||
const char *dir_prefix = rz_config_get(core->config, "dir.prefix");
|
||||
const char *asmcpu = rz_config_get(core->config, "asm.cpu");
|
||||
const char *asmarch = rz_config_get(core->config, "asm.arch");
|
||||
rz_arch_platform_init(core->analysis->platform_target, asmarch, asmcpu, node->value, dir_prefix);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool cb_asmlineswidth(void *user, void *data) {
|
||||
RzCore *core = (RzCore *)user;
|
||||
RzConfigNode *node = (RzConfigNode *)data;
|
||||
|
|
@ -3017,6 +3066,9 @@ RZ_API int rz_core_config_init(RzCore *core) {
|
|||
n = NODECB("asm.features", "", &cb_asmfeatures);
|
||||
SETDESC(n, "Specify supported features by the target CPU");
|
||||
update_asmfeatures_options(core, n);
|
||||
n = NODECB("asm.platform", "", &cb_asmplatform);
|
||||
SETDESC(n, "Specify supported platforms by the target architecture");
|
||||
update_asmplatforms_options(core, n);
|
||||
n = NODECB("asm.parser", "x86.pseudo", &cb_asmparser);
|
||||
SETDESC(n, "Set the asm parser to use");
|
||||
update_asmparser_options(core, n);
|
||||
|
|
|
|||
|
|
@ -7949,6 +7949,7 @@ static int cmd_analysis_all(RzCore *core, const char *input) {
|
|||
rz_cons_break_timeout(rz_config_get_i(core->config, "analysis.timeout"));
|
||||
rz_core_analysis_all(core);
|
||||
rz_arch_profile_add_flag_every_io(core->analysis->arch_target->profile, core->flags);
|
||||
rz_arch_platform_add_flags_comments(core);
|
||||
rz_print_rowlog_done(core->print, oldstr);
|
||||
rz_core_task_yield(&core->tasks);
|
||||
// Run pending analysis immediately after analysis
|
||||
|
|
|
|||
|
|
@ -635,6 +635,7 @@ typedef struct rz_analysis_t {
|
|||
RzStrConstPool constpool;
|
||||
RzList *leaddrs;
|
||||
RzArchTarget *arch_target;
|
||||
RzArchPlatformTarget *platform_target;
|
||||
} RzAnalysis;
|
||||
|
||||
typedef enum rz_analysis_addr_hint_type_t {
|
||||
|
|
|
|||
|
|
@ -27,12 +27,20 @@ typedef struct rz_arch_profile_t {
|
|||
} RzArchProfile;
|
||||
|
||||
typedef struct rz_arch_target_t {
|
||||
Sdb *db;
|
||||
char *cpu;
|
||||
char *arch;
|
||||
RzArchProfile *profile;
|
||||
} RzArchTarget;
|
||||
|
||||
typedef struct rz_platform_item_t {
|
||||
char *name;
|
||||
char *comment;
|
||||
} RzArchPlatformItem;
|
||||
|
||||
typedef struct rz_platform_target_t {
|
||||
HtUP /* <ut64 , RzArchPlatformItem> */ *platforms;
|
||||
} RzArchPlatformTarget;
|
||||
|
||||
RZ_API RZ_OWN RzArchProfile *rz_arch_profile_new();
|
||||
RZ_API RZ_OWN RzArchTarget *rz_arch_target_new();
|
||||
RZ_API void rz_arch_profile_free(RzArchProfile *profile);
|
||||
|
|
@ -41,6 +49,14 @@ RZ_API bool rz_arch_profiles_init(RzArchTarget *c, const char *cpu, const char *
|
|||
RZ_API void rz_arch_profile_add_flag_every_io(RzArchProfile *profile, RzFlag *flags);
|
||||
RZ_API bool rz_arch_load_profile_sdb(RzArchTarget *t, const char *path);
|
||||
|
||||
RZ_API RZ_OWN RzArchPlatformItem *rz_arch_platform_item_new(RZ_NULLABLE const char *name);
|
||||
RZ_API RZ_OWN RzArchPlatformTarget *rz_arch_platform_target_new();
|
||||
RZ_API void rz_arch_platform_target_free(RzArchPlatformTarget *target);
|
||||
RZ_API void rz_arch_platform_item_free(RzArchPlatformItem *item);
|
||||
RZ_API bool rz_arch_load_platform_sdb(RZ_NONNULL RzArchPlatformTarget *t, RZ_NONNULL const char *path);
|
||||
RZ_API bool rz_arch_platform_init(RzArchPlatformTarget *t, RZ_NONNULL const char *arch, RZ_NONNULL const char *cpu,
|
||||
const char *platform, RZ_NONNULL const char *dir_prefix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ typedef struct rz_asm_t {
|
|||
RzSyscall *syscall;
|
||||
RNum *num;
|
||||
char *features;
|
||||
char *platforms;
|
||||
int invhex; // invalid instructions displayed in hex
|
||||
int pcalign;
|
||||
int dataalign;
|
||||
|
|
@ -139,6 +140,7 @@ typedef struct rz_asm_plugin_t {
|
|||
RzAsmModifyCallback modify;
|
||||
char *(*mnemonics)(RzAsm *a, int id, bool json);
|
||||
const char *features;
|
||||
const char *platforms;
|
||||
} RzAsmPlugin;
|
||||
|
||||
#ifdef RZ_API
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ RZ_LIB_VERSION_HEADER(rz_core);
|
|||
#define RZ_FLAGS_FS_SYSCALLS "syscalls"
|
||||
#define RZ_FLAGS_FS_MMIO_REGISTERS "registers.mmio"
|
||||
#define RZ_FLAGS_FS_MMIO_REGISTERS_EXTENDED "registers.extended"
|
||||
#define RZ_FLAGS_FS_PLATFORM_PORTS "platform.ports"
|
||||
|
||||
#define RZ_GRAPH_FORMAT_NO 0
|
||||
#define RZ_GRAPH_FORMAT_GMLFCN 1
|
||||
|
|
@ -1101,6 +1102,8 @@ RZ_API bool rz_serialize_core_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core,
|
|||
*/
|
||||
RZ_API bool rz_core_project_load_for_cli(RzCore *core, const char *file, bool load_bin_io);
|
||||
|
||||
RZ_API bool rz_arch_platform_add_flags_comments(RzCore *core);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ typedef struct rz_sysreg_item_t {
|
|||
char *comment;
|
||||
} RzSysregItem;
|
||||
|
||||
typedef struct rz_type_db_sysreg {
|
||||
typedef struct rz_sysreg_db_t {
|
||||
HtUP /* <ut64 , RzSysregItem> */ *port;
|
||||
} RzSysregsDB;
|
||||
|
||||
|
|
|
|||
|
|
@ -540,6 +540,7 @@ subdir('librz/core')
|
|||
subdir('librz/analysis/d')
|
||||
subdir('librz/asm/d')
|
||||
subdir('librz/asm/cpus')
|
||||
subdir('librz/asm/platforms')
|
||||
subdir('librz/bin/d')
|
||||
subdir('librz/syscall/d')
|
||||
subdir('librz/reg/d')
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ EXPECT=<<EOF
|
|||
0 * classes
|
||||
110 * functions
|
||||
38 * imports
|
||||
0 * platform.ports
|
||||
0 * registers
|
||||
0 * registers.extended
|
||||
0 * registers.mmio
|
||||
|
|
@ -61,6 +62,7 @@ EXPECT=<<EOF
|
|||
0 * classes
|
||||
85 * functions
|
||||
38 * imports
|
||||
0 * platform.ports
|
||||
0 * registers
|
||||
0 * registers.extended
|
||||
0 * registers.mmio
|
||||
|
|
|
|||
|
|
@ -887,6 +887,45 @@ EXPECT=<<EOF
|
|||
EOF
|
||||
RUN
|
||||
|
||||
NAME=test platform profiles for arm BCM 2835
|
||||
FILE=bins/arm/elf/hello_world
|
||||
CMDS=<<EOF
|
||||
e asm.cpu=arm1176
|
||||
e asm.platform=bcm2835
|
||||
aa
|
||||
f~AUX
|
||||
CC~Broadcom
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
0x07e21500 1 AUX_ENABLES
|
||||
0x7e215000 1 AUX_IRQ
|
||||
0x7e215040 1 AUX_MU_IO_REG
|
||||
0x7e215044 1 AUX_MU_IER_REG
|
||||
0x7e215048 1 AUX_MU_IIR_REG
|
||||
0x7e21504c 1 AUX_MU_LCR_REG
|
||||
0x7e215050 1 AUX_MU_MCR_REG
|
||||
0x7e215054 1 AUX_MU_LSR_REG
|
||||
0x7e215058 1 AUX_MU_MSR_REG
|
||||
0x7e21505c 1 AUX_MU_SCRATCH
|
||||
0x7e215060 1 AUX_MU_CNTL_REG
|
||||
0x7e215064 1 AUX_MU_STAT_REG
|
||||
0x7e215068 1 AUX_MU_BAUD_REG
|
||||
0x7e215080 1 AUX_SPI0_CNTL0_REG
|
||||
0x7e215084 1 AUX_SPI0_CNTL1_REG
|
||||
0x7e215088 1 AUX_SPI0_STAT_REG
|
||||
0x7e215090 1 AUX_SPI0_IO_REG
|
||||
0x7e215094 1 AUX_SPI0_PEEK_REG
|
||||
0x7e2150c0 1 AUX_SPI1_CNTL0_REG
|
||||
0x7e2150c4 1 AUX_SPI1_CNTL1_REG
|
||||
0x7e2150c8 1 AUX_SPI1_STAT_REG
|
||||
0x7e2150d0 1 AUX_SPI1_IO_REG
|
||||
0x7e2150d4 1 AUX_SPI1_PEEK_REG
|
||||
0x7e205000 CCu "Broadcom Serial Controller 0 (BSC)"
|
||||
0x7e804000 CCu "Broadcom Serial Controller 1 (BSC)"
|
||||
0x7e805000 CCu "Broadcom Serial Controller 2 (BSC)"
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=ao 16 after ao 32
|
||||
FILE=bins/arm/elf/hello_world
|
||||
CMDS=<<EOF
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@ EXPECT=<<EOF
|
|||
0 * classes
|
||||
0 * functions
|
||||
3 * imports
|
||||
0 * platform.ports
|
||||
0 * registers.extended
|
||||
0 * registers.mmio
|
||||
4 * relocs
|
||||
|
|
|
|||
Loading…
Reference in a new issue