Deprecate RzSyscallPort and move the existing sysregs to SDB (#1160)

This commit is contained in:
Aswin C 2021-06-01 23:31:51 +05:30 committed by GitHub
parent 2e4becf7c6
commit 92b5783fa1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 453 additions and 137 deletions

View file

@ -605,6 +605,9 @@ static bool cb_asmarch(void *user, void *data) {
rz_analysis_set_big_endian(core->analysis, bigbin);
rz_core_analysis_cc_init(core);
const char *dir_prefix = rz_config_get(core->config, "dir.prefix");
rz_sysreg_set_arch(core->analysis->syscall, node->value, dir_prefix);
return true;
}

View file

@ -3385,9 +3385,8 @@ static void ds_print_sysregs(RDisasmState *ds) {
// Syscalls first
case RZ_ANALYSIS_OP_TYPE_IO: {
const int imm = (int)ds->analop.val;
RzSyscall *sc = core->analysis->syscall;
const char *ioname = rz_syscall_get_io(sc, imm);
if (ioname && *ioname) {
const char *ioname = rz_sysreg_get(core->analysis->syscall, "mmio", imm);
if (ioname) {
CMT_ALIGN;
ds_comment(ds, true, "; IO %s", ioname);
ds->has_description = true;
@ -3399,7 +3398,7 @@ static void ds_print_sysregs(RDisasmState *ds) {
case RZ_ANALYSIS_OP_TYPE_LOAD:
case RZ_ANALYSIS_OP_TYPE_STORE: {
const int imm = (int)ds->analop.ptr;
const char *sr = rz_syscall_sysreg(core->analysis->syscall, "reg", imm);
const char *sr = rz_sysreg_get(core->analysis->syscall, "reg", imm);
if (sr) {
CMT_ALIGN;
ds_comment(ds, true, "; REG %s - %s", sr, "");

View file

@ -24,10 +24,15 @@ typedef struct rz_syscall_item_t {
char *sargs;
} RzSyscallItem;
typedef struct rz_syscall_port_t {
int port;
const char *name;
} RzSyscallPort;
typedef struct rz_sysreg_item_t {
char *type;
char *name;
char *comment;
} RzSysregItem;
typedef struct rz_type_db_sysreg {
HtUP /* <ut64 , RzSysregItem> */ *port;
} RzSysregsDB;
typedef struct rz_syscall_t {
FILE *fd;
@ -38,9 +43,8 @@ typedef struct rz_syscall_t {
char *cpu;
// database
RzSyscallItem *sysptr;
RzSyscallPort *sysport;
Sdb *db;
Sdb *srdb;
RzSysregsDB *srdb;
int refs;
} RzSyscall;
@ -94,12 +98,15 @@ RZ_API bool rz_syscall_setup(RzSyscall *s, const char *arch, int bits, const cha
RZ_API RzSyscallItem *rz_syscall_get(RzSyscall *ctx, int num, int swi);
RZ_API int rz_syscall_get_num(RzSyscall *ctx, const char *str);
RZ_API const char *rz_syscall_get_i(RzSyscall *ctx, int num, int swi);
RZ_API const char *rz_syscall_sysreg(RzSyscall *s, const char *type, ut64 num);
RZ_API RzList *rz_syscall_list(RzSyscall *ctx);
RZ_API int rz_syscall_get_swi(RzSyscall *s);
/* io */
RZ_API const char *rz_syscall_get_io(RzSyscall *s, int ioport);
RZ_API const char *rz_sysreg_get(RzSyscall *s, const char *type, ut64 num);
RZ_API bool rz_sysreg_set_arch(RzSyscall *s, const char *arch, const char *dir_prefix);
RZ_API bool rz_type_db_load_sysregs_sdb(RzSysregsDB *sysregdb, const char *path);
RZ_API RzSysregsDB *rz_sysregs_db_new();
RZ_API RZ_OWN RzSysregItem *rz_sysreg_item_new(RZ_NULLABLE const char *name);
RZ_API void rz_sysreg_item_free(RzSysregItem *sysregitem);
#endif
#ifdef __cplusplus

View file

@ -0,0 +1,255 @@
SREG=reg
SREG.address=0x3f
SREG.comment=SREG Flags
SPH=reg
SPH.address=0x3e
SPH.comment=Stack higher bits SP8 SP10
SPL=reg
SPL.address=0x3d
SPL.comment=Stack lower bits SP0 SP7
OCR0=reg
OCR0.address=0x3c
OCR0.comment=Timer Counter0 Output Compare Register
GICR=reg
GICR.address=0x3b
GICR.comment=General Interrupt Control Register
GIFR=reg
GIFR.address=0x3a
GIFR.comment=General Interrupt Flag Register
TIMSK=reg
TIMSK.address=0x39
TIMSK.comment=Timer-Counter Interrupt Mask
TIFR=reg
TIFR.address=0x38
TIFR.comment=Timer-Counter Interrupt Flag Register
SPMCR=reg
SPMCR.address=0x37
SPMCR.comment=Store Program Memory Control Register
TWCR=reg
TWCR.address=0x36
TWCR.comment=I2C (Two wire) Control Register
MCUCR=reg
MCUCR.address=0x35
MCUCR.comment=MCU (Power Management) Control Register
MCUCSR=reg
MCUCSR.address=0x34
MCUCSR.comment=MCU Control and Status Register Watchdog Brown out Power on
TCCR0=reg
TCCR0.address=0x33
TCCR0.comment=Timer-Counter Control Register
TCNT0=reg
TCNT0.address=0x32
TCNT0.comment=Timer-Counter Register 0 (8 bits)
OSCCAL=reg
OSCCAL.address=0x31
OSCCAL.comment=(Internal) Oscillator Calibration Register
SFIOR=reg
SFIOR.address=0x30
SFIOR.comment=Special Function IO Register
TCCR1A=reg
TCCR1A.address=0x2f
TCCR1A.comment=Timer-Counter Control Register 1A (16 bits) Used for (fast) PWM
TCCR1B=reg
TCCR1B=0x2e
TCCR1B.comment=Timer-Counter Control Register 1B (16 bits) PWM mode select
TCNT1H=reg
TCNT1H.address=0x2d
TCNT1H.comment=Timer-Counter1 Register High byte
TCNT1L=reg
TCNT1L.address=0x2c
TCNT1L.comment=Timer-Counter1 Register Low byte
OCR1AH=reg
OCR1AH.address=0x2b
OCR1AH.comment=Timer-Counter1 Output Compare Register A High byte
OCR1AL=reg
OCR1AL.address=0x2a
OCR1AL.comment=Timer-Counter1 Output Compare Register A Low byte
OCR1BH=reg
OCR1BH.address=0x29
OCR1BH.comment=Timer-Counter1 Output Compare Register B High byte
OCR1BL=reg
OCR1BL.address=0x28
OCR1BL.comment=Timer-Counter1 Output Compare Register B Low byte
ICR1H=reg
ICR1H.address=0x27
ICR1H.comment=Timer-Counter1 Input Capture Register High byte
ICR1L=reg
ICR1L.address=0x26
ICR1L.comment=Timer-Counter1 Input Capture Register Low byte
TCCR2=reg
TCCR2.address=0x25
TCCR2.comment=Timer-Counter2 Control Register (8 bits)
TCNT2=reg
TCNT2.address=0x24
TCNT2.comment=Timer-Counter2 (8 bits)
OCR2=reg
OCR2.address=0x23
OCR2.comment=Timer-Counter2 Output Compare Register
ASSR=reg
ASSR.address=0x22
ASSR.comment=Asynchronous Operation of the Timer-Counter
WDTCR=reg
WDTCR.address=0x21
WDTCR.comment=Watchdog Timer Control Register
UBRRH=reg
UBRRH.address=0x20
UBRRH.comment=USART Baud Rate Registers=High byte and Control Aka setting serial port speed
EEARH=reg
EEARH.address=0x1f
EEARH.comment=EEPROM Address Register High byte
EEARL=reg
EEARL.address=0x1e
EEARL.comment=EEPROM Address Register Low byte
EEDR=reg
EEDR.address=0x1d
EEDR.comment= EEPROM Data Register
EECR=reg
EECR.address=0x1c
EECR.comment= EEPROM Control Register
PORTA=reg
PORTA.address=0x1b
PORTA.comment= Output pins-pullups address for port A
DDRA=reg
DDRA.address=0x1a
DDRA.comment= Data Direction Register for Port A
PINA=reg
PINA.address=0x19
PINA.comment= Input Pins Address for Port A
SPDR=reg
SPDR.address=0x0f
SPDR.comment= SPI Data Register
SPSR=reg
SPSR.address=0x0e
SPSR.comment= SPI Status Register
SPCR=reg
SPCR.address=0x0d
SPCR.comment= SPI Control Register
UDR=reg
UDR.address=0x0c
UDR.comment= USART I-O Data Register
UCSRA=reg
UCSRA.address=0x0b
UCSRA.comment= USART Control and Status Register A
UCSRB=reg
UCSRB.address=0x0a
UCSRB.comment= USART Control and Status Register B
UBRRL=reg
UBRRL.address=0x09
UBRRL.comment= USART Baud Rate Registers Low byte Aka setting serial port speed
ACSR=reg
ACSR.address=0x08
ACSR.comment= Analog Comparator Control and Status Register
ADMUX=reg
ADMUX.address=0x07
ADMUX.comment= ADC Multiplexer Selection Register
ADCSRA=reg
ADCSRA.address=0x06
ADCSRA.comment= ADC Control and Status Register A
ADCH=reg
ADCH.address=0x05
ADCH.comment= ADC Data Register High byte
ADCL=reg
ADCL.address=0x04
ADCL.comment= ADC Data Register Low byte
TWDR=reg
TWDR.address=0x03
TWDR.comment= I2C (Two wire) Serial Interface Data Register
TWAR=reg
TWAR.address=0x02
TWAR.comment= I2C (Two wire) Serial Interface (Slave) Address Register
TWSR=reg
TWSR.address=0x01
TWSR.comment= I2C (Two wire) Serial Interface Status Register
TWBR=reg
TWBR.address=0x99
TWBR.comment= I2C (Two wire) Serial Interface Bit Rate Register
PORTB=mmio
PORTB.address=0x18
PORTB.comment=Output pins/pullups address for port B
DDRB=mmio
DDRB.address=0x17
DDRB.comment=Data Direction Register for Port B
PINB=mmio
PINB.address=0x16
PINB.comment=Input Pins Address for Port B
PORTC=mmio
PORTC.address=0x15
PORTC.comment=Output pins/pullups address for port C
DDRC=mmio
DDRC.address=0x14
DDRC.comment=Data Direction Register for Port C
PINC=mmio
PINC.address=0x13
PINC.comment=Input Pins Address for Port C
PORTD=mmio
PORTD.address=0x12
PORTD.comment=Output pins/pullups address for port D
DDRD=mmio
DDRD.address=0x11
DDRD.comment=Data Direction Register for Port D
PIND=mmio
PIND.address=0x10
PIND.comment=Input Pins Address for Port D

16
librz/reg/d/meson.build Normal file
View file

@ -0,0 +1,16 @@
sdb_files = [
'avr-ATmega8-8'
]
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, 'reg')
)
endforeach

View file

@ -1,4 +0,0 @@
TWBR=0x00,0
TWSR=0x01,0
TWAR=0x02,0

View file

@ -1,81 +0,0 @@
// SPDX-FileCopyrightText: 2010-2020 pancake <pancake@nopcode.org>
// SPDX-FileCopyrightText: 2016 Roman Valls Guimera <brainstorm@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include "rz_syscall.h"
RzSyscallPort sysport_x86[] = {
{ 0x3, "HELLO WORLD" },
{ 0x378, "lp1" },
{ 0, NULL }
};
// XXX: This is for Atmega8A, check other datasheets Register Summary to be sure about your MCU:
// http://www.atmel.com/Images/Atmel-2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf
RzSyscallPort sysport_avr[] = {
{ 0x3f, "SREG: flags" },
{ 0x3e, "SPH: Stack higher bits SP8-SP10" },
{ 0x3d, "SPL: Stack lower bits SP0-SP7" },
{ 0x3c, "OCR0: Timer/Counter0 Output Compare Register." },
{ 0x3b, "GICR: General Interrupt Control Register" },
{ 0x3a, "GIFR: General Interrupt Flag Register" },
{ 0x39, "TIMSK: Timer/Counter Interrupt Mask" },
{ 0x38, "TIFR: Timer/Counter Interrupt Flag Register" },
{ 0x37, "SPMCR: Store Program Memory Control Register" },
{ 0x36, "TWCR: I2C (Two-wire) Control Register" },
{ 0x35, "MCUCR: MCU (Power Management) Control Register" },
{ 0x34, "MCUCSR: MCU Control and Status Register. Watchdog, Brown-out, Power-on..." },
{ 0x33, "TCCR0: Timer/Counter Control Register 0" },
{ 0x32, "TCNT0: Timer/Counter Register 0 (8 bits)" },
{ 0x31, "OSCCAL: (Internal) Oscillator Calibration Register" },
{ 0x30, "SFIOR: Special Function IO Register" },
{ 0x2f, "TCCR1A: Timer/Counter Control Register 1A (16 bits). Used for (fast) PWM." },
{ 0x2e, "TCCR1B: Timer/Counter Control Register 1B (16 bits). PWM mode select." },
{ 0x2d, "TCNT1H: Timer/Counter1 Register High byte." },
{ 0x2c, "TCNT1L: Timer/Counter1 Register Low byte." },
{ 0x2b, "OCR1AH: Timer/Counter1 Output Compare Register A High byte." },
{ 0x2a, "OCR1AL: Timer/Counter1 Output Compare Register A Low byte." },
{ 0x29, "OCR1BH: Timer/Counter1 Output Compare Register B High byte." },
{ 0x28, "OCR1BL: Timer/Counter1 Output Compare Register B Low byte." },
{ 0x27, "ICR1H: Timer/Counter1 Input Capture Register High byte." },
{ 0x26, "ICR1L: Timer/Counter1 Input Capture Register Low byte." },
{ 0x25, "TCCR2: Timer/Counter2 Control Register (8 bits)." },
{ 0x24, "TCNT2: Timer/Counter2 (8 bits)." },
{ 0x23, "OCR2: Timer/Counter2 Output Compare Register." },
{ 0x22, "ASSR: Asynchronous Operation of the Timer/Counter." },
{ 0x21, "WDTCR: Watchdog Timer Control Register." },
{ 0x20, "UBRRH, UCSRC: USART Baud Rate Registers, High byte and Control. A.k.a setting serial port speed." },
{ 0x1f, "EEARH: EEPROM Address Register High byte." },
{ 0x1e, "EEARL: EEPROM Address Register Low byte." },
{ 0x1d, "EEDR: EEPROM Data Register." },
{ 0x1c, "EECR: EEPROM Control Register." },
{ 0x1b, "PORTA: Output pins/pullups address for port A." },
{ 0x1a, "DDRA: Data Direction Register for Port A." },
{ 0x19, "PINA: Input Pins Address for Port A." },
{ 0x18, "PORTB: Output pins/pullups address for port B." },
{ 0x17, "DDRB: Data Direction Register for Port B." },
{ 0x16, "PINB: Input Pins Address for Port B." },
{ 0x15, "PORTC: Output pins/pullups address for port C." },
{ 0x14, "DDRC: Data Direction Register for Port C." },
{ 0x13, "PINC: Input Pins Address for Port C." },
{ 0x12, "PORTD: Output pins/pullups address for port D." },
{ 0x11, "DDRD: Data Direction Register for Port D." },
{ 0x10, "PIND: Input Pins Address for Port D." },
{ 0x0f, "SPDR: SPI Data Register." },
{ 0x0e, "SPSR: SPI Status Register." },
{ 0x0d, "SPCR: SPI Control Register." },
{ 0x0c, "UDR: USART I/O Data Register." },
{ 0x0b, "UCSRA: USART Control and Status Register A." },
{ 0x0a, "UCSRB: USART Control and Status Register B." },
{ 0x09, "UBRRL: USART Baud Rate Registers Low byte. A.k.a setting serial port speed." },
{ 0x08, "ACSR: Analog Comparator Control and Status Register." },
{ 0x07, "ADMUX: ADC Multiplexer Selection Register." },
{ 0x06, "ADCSRA: ADC Control and Status Register A." },
{ 0x05, "ADCH: ADC Data Register High byte." },
{ 0x04, "ADCL: ADC Data Register Low byte." },
{ 0x03, "TWDR: I2C (Two-wire) Serial Interface Data Register." },
{ 0x02, "TWAR: I2C (Two-wire) Serial Interface (Slave) Address Register." },
{ 0x01, "TWSR: I2C (Two-wire) Serial Interface Status Register." },
{ 0x00, "TWBR: I2C (Two-wire) Serial Interface Bit Rate Register." },
{ 0, NULL }
};

View file

@ -1,6 +1,5 @@
rz_syscall_sources = [
'syscall.c',
'ioports.c'
]
rz_syscall = library('rz_syscall', rz_syscall_sources,

View file

@ -9,32 +9,63 @@
RZ_LIB_VERSION(rz_syscall);
// TODO: now we use sdb
extern RzSyscallPort sysport_x86[];
extern RzSyscallPort sysport_avr[];
RZ_API RzSyscall *rz_syscall_ref(RzSyscall *sc) {
sc->refs++;
return sc;
}
/**
* \brief Creates a new RzSysregItem type
*
* \param name Name of the callable type
*/
RZ_API RZ_OWN RzSysregItem *rz_sysreg_item_new(RZ_NULLABLE const char *name) {
RzSysregItem *sysregitem = RZ_NEW0(RzSysregItem);
if (!sysregitem) {
return NULL;
}
sysregitem->comment = NULL;
sysregitem->type = NULL;
sysregitem->name = name ? strdup(name) : NULL;
return sysregitem;
}
/**
* \brief Creates a new RzSysregDB type
*/
RZ_API RzSysregsDB *rz_sysregs_db_new() {
RzSysregsDB *sysregdb = RZ_NEW0(RzSysregsDB);
if (!sysregdb) {
return NULL;
}
sysregdb->port = ht_up_new0();
if (!sysregdb->port) {
return NULL;
}
return sysregdb;
}
/**
* \brief Creates a new RzSyscall type
*/
RZ_API RzSyscall *rz_syscall_new(void) {
RzSyscall *rs = RZ_NEW0(RzSyscall);
if (rs) {
rs->sysport = sysport_x86;
rs->srdb = sdb_new0(); // sysregs database
rs->srdb = rz_sysregs_db_new(); // sysregs database
rs->db = sdb_new0();
}
return rs;
}
/**
* \brief Frees an RzSyscall type
*/
RZ_API void rz_syscall_free(RzSyscall *s) {
if (s) {
if (s->refs > 0) {
s->refs--;
return;
}
sdb_free(s->srdb);
sdb_free(s->db);
free(s->os);
free(s->cpu);
@ -43,6 +74,19 @@ RZ_API void rz_syscall_free(RzSyscall *s) {
}
}
/**
* \brief Frees an RzSysregItem type
*/
RZ_API void rz_sysreg_item_free(RzSysregItem *s) {
if (!s) {
return;
}
free(s->comment);
free(s->name);
free(s->type);
free(s);
}
static bool load_sdb(Sdb **db, const char *name) {
rz_return_val_if_fail(db, false);
char *sdb_path = rz_str_rz_prefix(RZ_SDB);
@ -84,6 +128,83 @@ static inline bool sysregs_reload_needed(RzSyscall *s, const char *arch, int bit
return !s->cpu || strcmp(s->cpu, cpu);
}
static bool sdb_load_sysregs(RzSysregsDB *sysregdb, Sdb *sdb) {
rz_return_val_if_fail(sysregdb && sdb, NULL);
RzSysregItem *sysregitem;
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), "mmio") || !strcmp(sdbkv_value(kv), "reg")) {
name = sdbkv_key(kv);
sysregitem = rz_sysreg_item_new(name);
argument_key = rz_str_newf("%s.address", name);
if (!argument_key) {
return NULL;
}
ut64 address = sdb_num_get(sdb, argument_key, NULL);
if (!address) {
rz_sysreg_item_free(sysregitem);
return NULL;
}
argument_key = rz_str_newf("%s.comment", name);
comment = sdb_get(sdb, argument_key, NULL);
sysregitem->type = sdbkv_value(kv);
sysregitem->name = strdup(name);
sysregitem->comment = strdup(comment);
ht_up_insert(sysregdb->port, address, sysregitem);
}
}
return true;
}
static bool sdb_load_by_path(RZ_NONNULL RzSysregsDB *sysregdb, const char *path) {
Sdb *db = sdb_new(0, path, 0);
bool result = sdb_load_sysregs(sysregdb, db);
sdb_close(db);
sdb_free(db);
return result;
}
/**
* \brief Loads the RzSysregDB from the path to the hashtable
*
* \param s reference to RzSysregDB
* \param path reference to path of the SDB file
*/
RZ_API bool rz_type_db_load_sysregs_sdb(RzSysregsDB *sysregdb, const char *path) {
if (!rz_file_exists(path)) {
return false;
}
return sdb_load_by_path(sysregdb, path);
}
/**
* \brief Sets the architecture for sysregs during analysis and
* loads up the sysregs SDB database
*
* \param s reference to RzSyscall
* \param arch reference to value of asm.arch
* \param dir_prefix reference to value of directory prefix or the value of dir.prefix
*/
RZ_API bool rz_sysreg_set_arch(RzSyscall *s, const char *arch, const char *dir_prefix) {
char *path = sdb_fmt(RZ_JOIN_4_PATHS("%s", RZ_SDB, "reg", "%s-%s-%d.sdb"), dir_prefix,
arch, s->cpu, s->bits);
s->srdb = rz_sysregs_db_new();
if (path) {
if (!rz_type_db_load_sysregs_sdb(s->srdb, path)) {
s->srdb = NULL;
return false;
}
}
return true;
}
// TODO: should be renamed to rz_syscall_use();
RZ_API bool rz_syscall_setup(RzSyscall *s, const char *arch, int bits, const char *cpu, const char *os) {
bool syscall_changed, sysregs_changed;
@ -113,13 +234,8 @@ RZ_API bool rz_syscall_setup(RzSyscall *s, const char *arch, int bits, const cha
if (!strcmp(os, "any")) { // ignored
return true;
}
if (!strcmp(arch, "avr")) {
s->sysport = sysport_avr;
} else if (!strcmp(os, "darwin") || !strcmp(os, "osx") || !strcmp(os, "macos")) {
os = "darwin";
} else if (!strcmp(arch, "x86")) {
s->sysport = sysport_x86;
}
if (syscall_changed) {
@ -135,11 +251,10 @@ RZ_API bool rz_syscall_setup(RzSyscall *s, const char *arch, int bits, const cha
}
if (sysregs_changed) {
char *dbName = rz_str_newf(RZ_JOIN_2_PATHS("sysregs", "%s-%d-%s"),
arch, bits, cpu);
char *dbName = rz_str_newf(RZ_JOIN_2_PATHS("reg", "%s-%s-%d"),
arch, cpu, bits);
if (dbName) {
if (!load_sdb(&s->srdb, dbName)) {
sdb_free(s->srdb);
if (!rz_type_db_load_sysregs_sdb(s->srdb, dbName)) {
s->srdb = NULL;
}
free(dbName);
@ -287,27 +402,21 @@ RZ_API RzList *rz_syscall_list(RzSyscall *s) {
return list;
}
/* io and sysregs */
RZ_API const char *rz_syscall_get_io(RzSyscall *s, int ioport) {
/**
* \brief Searches the sysregs SDB database inside librz/reg/d for the type (mmio/reg) and
* returns its value as a string
*
* \param s reference to RzSyscall
* \param type reference to the type of key: mmio/reg
* \param port reference to the io port
*/
RZ_API const char *rz_sysreg_get(RzSyscall *s, const char *type, ut64 port) {
rz_return_val_if_fail(s, NULL);
int i;
const char *name = rz_syscall_sysreg(s, "io", ioport);
if (name) {
return name;
}
for (i = 0; s->sysport[i].name; i++) {
if (ioport == s->sysport[i].port) {
return s->sysport[i].name;
}
}
return NULL;
}
RZ_API const char *rz_syscall_sysreg(RzSyscall *s, const char *type, ut64 num) {
rz_return_val_if_fail(s, NULL);
if (!s->db) {
if (!s->srdb) {
return NULL;
}
const char *key = sdb_fmt("%s,%" PFMT64d, type, num);
return sdb_const_get(s->db, key, 0);
RzSysregItem *item = ht_up_find(s->srdb->port, port, NULL);
if (item)
return item->comment;
return NULL;
}

View file

@ -541,6 +541,7 @@ subdir('librz/analysis/d')
subdir('librz/asm/d')
subdir('librz/bin/d')
subdir('librz/syscall/d')
subdir('librz/reg/d')
subdir('librz/cons/d')
subdir('librz/magic/d')
subdir('librz/flag/d')

View file

@ -64,9 +64,21 @@ RUN
NAME=avr DISasm: IO-Ports
FILE=bins/firmware/arduino_avr.bin
CMDS=pd 1 @ 0x00000170~?IO
CMDS=pd 13 @ 0x00000282
EXPECT=<<EOF
1
0x00000282 in r24, 0x12 ; IO Output pins/pullups address for port D
0x00000284 subi r24, 0x80
0x00000286 out 0x12, r24 ; IO Output pins/pullups address for port D
0x00000288 ret
0x0000028a ldi r22, 0x7d
0x0000028c ldi r23, 0x01
0x0000028e ldi r24, 0x2f
0x00000290 ldi r25, 0x02
0x00000292 call 0x8e6
0x00000296 in r24, 0x18 ; IO Output pins/pullups address for port B
0x00000298 subi r24, 0x80
0x0000029a out 0x18, r24 ; IO Output pins/pullups address for port B
0x0000029c ret
EOF
RUN