diff --git a/TODO b/TODO index cd1f6e9361..d5849ada0b 100644 --- a/TODO +++ b/TODO @@ -8,10 +8,16 @@ ====[[ 0.9.1 ]]==== +Discuss +Add $EDITOR alias for file open(read/write) - + pd > - + wf - + ... +======= + * refactor vmenus.c -> refresh function must be redefined for each menu EVAL -? [0] => doesnt works! do it like in r1 ? flag -flag2 => fails because of the ' ' before the minus sign ? flag-flag2 works diff --git a/binr/rabin2/rabin2.c b/binr/rabin2/rabin2.c index a3f7c0b572..b895b9a6fb 100644 --- a/binr/rabin2/rabin2.c +++ b/binr/rabin2/rabin2.c @@ -30,6 +30,7 @@ #define ACTION_LISTARCHS 0x04000 #define ACTION_CREATE 0x08000 #define ACTION_CLASSES 0x10000 +#define ACTION_DWARF 0x20000 static struct r_lib_t *l; static struct r_bin_t *bin = NULL; @@ -254,6 +255,13 @@ static int rabin_do_operation(const char *op) { return R_TRUE; } +static int rabin_show_dwarf(RCore *core) { +//TODO RBinDwarfLine *lines = + r_bin_dwarf_parse_info (core->bin); + r_bin_dwarf_parse_line (core->bin); + return R_TRUE; +} + static int rabin_show_srcline(ut64 at) { char *srcline; if ((srcline = r_bin_meta_get_source_line (bin, at))) { @@ -309,7 +317,7 @@ int main(int argc, char **argv) { r_lib_opendir (l, LIBDIR"/radare2/"); } - while ((c = getopt (argc, argv, "Af:a:B:b:c:CMm:n:@:VisSzIHelRwO:o:p:rvLhx")) != -1) { + while ((c = getopt (argc, argv, "Af:a:B:b:c:CdMm:n:@:VisSzIHelRwO:o:p:rvLhx")) != -1) { switch(c) { case 'A': action |= ACTION_LISTARCHS; @@ -356,6 +364,9 @@ int main(int argc, char **argv) { case 'H': action |= ACTION_FIELDS; break; + case 'd': + action |= ACTION_DWARF; + break; case 'e': action |= ACTION_ENTRIES; break; @@ -514,6 +525,8 @@ int main(int argc, char **argv) { r_core_bin_info (&core, R_CORE_BIN_ACC_LIBS, rad, va, NULL, 0); if (action&ACTION_RELOCS) r_core_bin_info (&core, R_CORE_BIN_ACC_RELOCS, rad, va, NULL, 0); + if (action&ACTION_DWARF) + rabin_show_dwarf (&core); if (action&ACTION_SRCLINE) rabin_show_srcline (at); if (action&ACTION_EXTRACT) diff --git a/binr/radare2/radare2.c b/binr/radare2/radare2.c index 5fa72726a0..6d199ded29 100644 --- a/binr/radare2/radare2.c +++ b/binr/radare2/radare2.c @@ -57,17 +57,16 @@ static int main_help(int line) { } static int main_version() { - printf ("radare2 "R2_VERSION" @ "R_SYS_OS"-"R_SYS_ENDIAN"-"R_SYS_ARCH" build "R2_BIRTH"\n"); + printf ("radare2 "R2_VERSION" @ "R_SYS_OS"-"R_SYS_ENDIAN"-"R_SYS_ARCH"-%d build "R2_BIRTH"\n", R_SYS_BITS&8?64:32); return 0; } -static int list_io_plugins(RIO *io) { +static void list_io_plugins(RIO *io) { struct list_head *pos; list_for_each_prev(pos, &io->io_list) { struct r_io_list_t *il = list_entry(pos, struct r_io_list_t, list); printf (" %-10s %s\n", il->plugin->name, il->plugin->desc); } - return 0; } // Load the binary information from rabin2 @@ -211,10 +210,8 @@ int main(int argc, char **argv) { return 1; } } - if (help>1) - return main_help (2); - else if (help) - return main_help (0); + if (help>1) return main_help (2); + else if (help) return main_help (0); // DUP if (asmarch) r_config_set (r.config, "asm.arch", asmarch); diff --git a/libr/bin/Makefile b/libr/bin/Makefile index d21a843787..acc33b421a 100644 --- a/libr/bin/Makefile +++ b/libr/bin/Makefile @@ -13,7 +13,7 @@ include ${STATIC_BIN_PLUGINS} include ${STATIC_BIN_XTR_PLUGINS} STATIC_OBJS=$(subst ..,p/..,$(subst bin_,p/bin_,$(STATIC_OBJ))) -OBJ=bin.o bin_meta.o bin_write.o demangle.o ${STATIC_OBJS} +OBJ=bin.o bin_meta.o bin_write.o demangle.o dwarf.o ${STATIC_OBJS} OBJ+=mangling/cxx/cp-demangle.o pre: diff --git a/libr/bin/dwarf.c b/libr/bin/dwarf.c new file mode 100644 index 0000000000..2e6d7c1d68 --- /dev/null +++ b/libr/bin/dwarf.c @@ -0,0 +1,317 @@ +/* radare - LGPL - Copyright 2012 pancake */ + +#include +#include + +#define STANDARD_OPERAND_COUNT_DWARF2 9 +#define STANDARD_OPERAND_COUNT_DWARF3 12 +#define R_BIN_DWARF_INFO 1 + +#define READ(x,y) *((y *)x); x += sizeof (y) + +R_API int r_bin_dwarf_parse_line(RBin *a); + +R_API int r_bin_dwarf_parse(RBin *bin, int type) { + //RBinSection *s = NULL; + ut8 *p; + // find debug_line section // + r_bin_dwarf_parse_line (p); +} + +struct Line_Table_File_Entry_s { + ut8 *lte_filename; + ut32 lte_directory_index; + ut32 lte_last_modification_time; + ut32 lte_length_of_file; +}; + +static const ut8 *r_bin_dwarf_info(const ut8 *buf, RBinDwarfInfoHeader *hdr) { + eprintf ("PARSE INFO!\n"); + return buf; +} + +R_API int r_bin_dwarf_parse_info_raw(const ut8 *obuf) { +int i; + const char *buf = obuf; + ut32 len, version, addr_size, abbr_offset, nextcu; + + len = READ (buf, ut32); + version = READ (buf, ut16); + abbr_offset = READ (buf, ut32); + addr_size = READ (buf, ut8); + //nextcu = READ (buf, ut8); + + eprintf ("Compile unit: 0x%x\n", len); + eprintf ("Version: %d\n", version); + eprintf ("abbr offset: 0x%x\n", abbr_offset); + eprintf ("addr size: 0x%x\n", addr_size); + //eprintf ("nextcu: 0x%x\n", nextcu); + +for (i=0;i<256; i++) { + eprintf ("%02x ", buf[i]); +} +eprintf("\n"); + +eprintf ("Compile Unit: length = 0x000000f1 version = 0x0002\n"); +eprintf ("abbr_offset = 0x00000000 addr_size = 0x04 (next CU at 0x000000f5)\n"); +#if 0 +0x00004197 |f100 0000 0200 0000 0000 0401 0100 0000| ................ +0x000041a7 |0125 0000 0030 0000 00fa 1d00 004d 1f00| .%...0.......M.. +0x000041b7 |0000 0000 0002 015a 0000 0001 013d 0000| .......Z.....=.. +0x000041c7 |00fa 1d00 001b 1e00 0000 0000 0003 0405| ................ +#endif + eprintf ("PARSE INFO\n"); +} + +static const ut8 *r_bin_dwarf_parse_header (const ut8 *buf, RBinDwarfInfoHeader *hdr) { + int count, i; + hdr->len = READ (buf, ut32); + hdr->version = READ (buf, ut16); + hdr->plen = READ (buf, ut32); + hdr->minislen = READ (buf, ut8); + hdr->is_stmt = READ (buf, ut8); + hdr->line_base = READ (buf, char); + hdr->line_range = READ (buf, ut8); + hdr->opcode_base = READ (buf, ut8); + + printf ("DWARF LINE HEADER\n"); + printf (" payload length: %d\n", hdr->len); + printf (" version: %d\n", hdr->version); + printf (" plen: %d\n", hdr->plen); + printf (" minislen: %d\n", hdr->minislen); + printf (" is_stmt: %d\n", hdr->is_stmt); + printf (" line_base: %d\n", hdr->line_base); + printf (" line_range: %d\n", hdr->line_range); + printf (" opcode_base: %d\n", hdr->opcode_base); + + count = hdr->opcode_base - 1; + printf ("-opcode arguments:\n"); + for (i = 0; ioplentable[i] = n; + } + return buf; +} + +R_API int r_bin_dwarf_parse_line_raw(const ut8 *obuf) { + RBinDwarfInfoHeader hdr; + const char *buf, *code; + int type, opi, i; + int opcount = 12; // TODO must autodetect if 9 or 12 coz versioning is crap + ut8 opcode; + + buf = r_bin_dwarf_parse_header (obuf, &hdr); + code = obuf+hdr.len; + + // parse filenames + while (*buf++ == 0) { + int len = strlen (buf); + if (!len) { + buf += 3; + break; + } + eprintf ("FILE (%s)\n", buf); + buf += len+3; + } +#if 0 + for (i=0;i<20;i++) { + printf ("%02x %c\n", buf[i], buf[i]); + } +file_names[ 1] 0 0x00000000 0x00000000 backtest.c +0x0000002b: DW_LNE_set_address( 0x0000000100000cf0 ) +0x00000036: address += 0, line += 6 + 0x0000000100000cf0 1 7 0 is_stmt +#endif +// parse opcodes + +for (opi= 0; opi<8;opi++) { + opcode = *buf++; + if (opcode < hdr.opcode_base) { + if (opcode == DW_EXTENDED_OPCODE) + type = LOP_EXTENDED; + else if (opcount >= hdr.opcode_base) + //else if ((pf_std_op_count+1) >= base) + type = LOP_STANDARD; + else type = LOP_DISCARD; + } else type = LOP_SPECIAL; + +printf ("type %d opcode %d\n", type, opcode); + switch (type) { + case LOP_DISCARD: + { int i; + ut32 n = 0; + int opcnt = hdr.oplentable[opcode]; + + for (i=0; i %d\n", opcode); +{ + // hardcoded set_lie + ut32 a = READ (buf, ut32); + ut32 l = READ (buf, ut32); + eprintf ("addr += %d line += %d\n", a, l); +} +// address = address+ mininslen * (opcode / line_range); +// line = line + line_base + opcode % line_range; +// bb = 0; +#endif + break; + case LOP_STANDARD: +eprintf ("standard opcode\n"); +#if 0 + switch (opcode) { + case DW_LNS_copy: + break; + case DW_LNS_advance_pc: + + break; + case DW_LNS_advance_line: + st32 *b = ptr; // little endian foo + line = line + *b; + break; + case DW_LNS_set_file: + ut32 *b = ptr; // little endian foo + file = *b; + break; + case DW_LNS_set_column: + ut32 *b = ptr; // little endian foo + column = *b; + break; + case DW_LNS_negate_stmt: + is_stmt = !is_stmt; + break; + case DW_LNS_set_basic_block: + bb = 1; + break; + case DW_LNS_const_add_pc: + opcode = MAX_LINE_OP_CODE - opcode_base; + address = address + mininslen * (opcode / line_range); + break; + case DW_LNS_fixed_advance_pc: + ut16 *w = ptr; + opcode = MAX_LINE_OP_CODE - opcode_base; + address = address + mininslen * (opcode / line_range); + break; + case DW_LNS_set_prologue_end: + prologue_end = 1; + break; + case DW_LNS_set_prologue_begin: + epilogue_begin = 1; + break; + case DW_LNS_set_isa: + break; + } + break; +#endif + case LOP_EXTENDED: + { + int inslen = READ (buf, int); + ut8 ext_opcode = *buf++; + printf ("ext op %d\n", ext_opcode); + switch (ext_opcode) { + case 1: // end seq + break; + case 2: // set addr + { ut32 addr = READ (buf, ut32); + eprintf ("set address 0x%08x\n", addr); +} + break; + case 3: // define file + break; + case 4: // set discriminator + break; + default: + eprintf ("Invalid extended opcode %d in dwarf's debug_line\n", ext_opcode); + break; + } + } + // TODO + break; + } +} + return R_TRUE; +} + +RBinSection *getsection(RBin *a, const char *sn) { + RListIter *iter; + RBinSection *section; + + if (a->curarch.sections) { + r_list_foreach (a->curarch.sections, iter, section) { + if (strstr (section->name, sn)) + return section; + } + } + return NULL; +} + +R_API int r_bin_dwarf_parse_info(RBin *a) { + ut8 *buf; + int len, ret; + RBinSection *section = getsection (a, "debug_info"); + if (section) { + len = section->size; + buf = malloc (len); + r_buf_read_at (a->curarch.buf, section->offset, buf, len); + ret = r_bin_dwarf_parse_info_raw (buf); + free (buf); + return ret; + } + return R_FALSE; +} + +R_API int r_bin_dwarf_parse_line(RBin *a) { + ut8 *buf; + int len, ret; + RBinSection *section = getsection (a, "debug_line"); + if (section) { + len = section->size; + buf = malloc (len); + r_buf_read_at (a->curarch.buf, section->offset, buf, len); + ret = r_bin_dwarf_parse_line_raw (buf); + free (buf); + return ret; + } + return R_FALSE; +} diff --git a/libr/core/cmd.c b/libr/core/cmd.c index e83489529a..f6e7ba9998 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -329,6 +329,9 @@ static int cmd_eval(void *data, const char *input) { r_core_config_init (core); eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n"); break; + case 'v': + eprintf ("Invalid command '%s'. Use 'e?'\n", input); + break; case '*': r_config_list (core->config, NULL, 1); break; @@ -929,6 +932,12 @@ R_API int r_core_cmd0(void *user, const char *cmd) { return r_core_cmd ((RCore *)user, cmd, 0); } +R_API int r_core_flush(void *user, const char *cmd) { + int ret = r_core_cmd ((RCore *)user, cmd, 0); + r_cons_flush (); + return ret; +} + /* return: pointer to a buffer with the output of the command */ R_API char *r_core_cmd_str(RCore *core, const char *cmd) { const char *static_str; diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index e66d266588..d074dce789 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -189,8 +189,10 @@ static int cmd_anal(void *data, const char *input) { case '8': if (input[1]==' ') { RAsmCode *c = r_asm_mdisassemble_hexstr (core->assembler, input+2); - r_cons_puts (c->buf_asm); - r_asm_code_free (c); + if (c) { + r_cons_puts (c->buf_asm); + r_asm_code_free (c); + } else eprintf ("Invalid hexstr\n"); } else eprintf ("Usage: a8 [hexpair-bytes]\n"); break; case 'x': diff --git a/libr/core/core.c b/libr/core/core.c index 541897189a..aba677f4ae 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -20,6 +20,49 @@ static ut64 num_callback(RNum *userptr, const char *str, int *ok) { RAnalOp op; ut64 ret = 0; *ok = 0; + if (str[0]=='[') { + int refsz = (core->assembler->bits & R_SYS_BITS_64)? 8: 4; + const char *p = strchr (str+1, ':'); + ut64 n; +// TODO: honor endian + if (p) { + refsz = atoi (str+1); + str = p; + } +// push state +{ +const char *q = r_num_calc_index (NULL); + n = r_num_math (core->num, str+1); +r_num_calc_index (q); +} +// pop state + + switch (refsz) { + case 8: { + ut64 num = 0; + r_io_read_at (core->io, n, (ut8*)&num, sizeof (num)); + return num; + } + case 4: { + ut32 num = 0; + r_io_read_at (core->io, n, (ut8*)&num, sizeof (num)); + return num; + } + case 2: { + ut16 num = 0; + r_io_read_at (core->io, n, (ut8*)&num, sizeof (num)); + return num; + } + case 1: { + ut8 num = 0; + r_io_read_at (core->io, n, (ut8*)&num, sizeof (num)); + return num; + } + default: + eprintf ("Invalid reference size: %d\n", refsz); + break; + } + } else if (str[0]=='$') { *ok = 1; r_anal_op (core->anal, &op, core->offset, core->block, core->blocksize); @@ -48,7 +91,7 @@ static ut64 num_callback(RNum *userptr, const char *str, int *ok) { case '$': return core->offset; case 'o': return core->io->off; } - } + } else if (*str>'A') { if ((flag = r_flag_get (core->flags, str))) { ret = flag->offset; diff --git a/libr/include/r_bin_dwarf.h b/libr/include/r_bin_dwarf.h new file mode 100644 index 0000000000..6a7fc843c5 --- /dev/null +++ b/libr/include/r_bin_dwarf.h @@ -0,0 +1,126 @@ +#ifndef _INCLUDE_BIN_DWARF_H_ +#define _INCLUDE_BIN_DWARF_H_ + +#define DW_EXTENDED_OPCODE 0 +#define LOP_EXTENDED 1 +#define LOP_DISCARD 2 +#define LOP_STANDARD 3 +#define LOP_SPECIAL 4 + +#define DW_LNS_copy 0x01 +#define DW_LNS_advance_pc 0x02 +#define DW_LNS_advance_line 0x03 +#define DW_LNS_set_file 0x04 +#define DW_LNS_set_column 0x05 +#define DW_LNS_negate_stmt 0x06 +#define DW_LNS_set_basic_block 0x07 +#define DW_LNS_const_add_pc 0x08 +#define DW_LNS_fixed_advance_pc 0x09 +#define DW_LNS_set_prologue_end 0x0a /* DWARF3 */ +#define DW_LNS_set_epilogue_begin 0x0b /* DWARF3 */ +#define DW_LNS_set_isa 0x0c /* DWARF3 */ +/* Line number extended opcode name. */ +#define DW_LNE_end_sequence 0x01 +#define DW_LNE_set_address 0x02 +#define DW_LNE_define_file 0x03 +#define DW_LNE_set_discriminator 0x04 /* DWARF4 */ + +/* HP extensions. */ +#define DW_LNE_HP_negate_is_UV_update 0x11 /* 17 HP */ +#define DW_LNE_HP_push_context 0x12 /* 18 HP */ +#define DW_LNE_HP_pop_context 0x13 /* 19 HP */ +#define DW_LNE_HP_set_file_line_column 0x14 /* 20 HP */ +#define DW_LNE_HP_set_routine_name 0x15 /* 21 HP */ +#define DW_LNE_HP_set_sequence 0x16 /* 22 HP */ +#define DW_LNE_HP_negate_post_semantics 0x17 /* 23 HP */ +#define DW_LNE_HP_negate_function_exit 0x18 /* 24 HP */ +#define DW_LNE_HP_negate_front_end_logical 0x19 /* 25 HP */ +#define DW_LNE_HP_define_proc 0x20 /* 32 HP */ + +#define DW_LNE_lo_user 0x80 /* DWARF3 */ +#define DW_LNE_hi_user 0xff /* DWARF3 */ + +/* debug_info tags */ +#define DW_TAG_array_type 0x01 +#define DW_TAG_class_type 0x02 +#define DW_TAG_entry_point 0x03 +#define DW_TAG_enumeration_type 0x04 +#define DW_TAG_formal_parameter 0x05 +#define DW_TAG_imported_declaration 0x08 +#define DW_TAG_label 0x0a +#define DW_TAG_lexical_block 0x0b +#define DW_TAG_member 0x0d +#define DW_TAG_pointer_type 0x0f +#define DW_TAG_reference_type 0x10 +#define DW_TAG_compile_unit 0x11 // +#define DW_TAG_string_type 0x12 +#define DW_TAG_structure_type 0x13 +#define DW_TAG_subroutine_type 0x15 +#define DW_TAG_typedef 0x16 +#define DW_TAG_union_type 0x17 +#define DW_TAG_unspecified_parameters 0x18 +#define DW_TAG_variant 0x19 +#define DW_TAG_common_block 0x1a +#define DW_TAG_common_inclusion 0x1b +#define DW_TAG_inheritance 0x1c +#define DW_TAG_inlined_subroutine 0x1d +#define DW_TAG_module 0x1e +#define DW_TAG_ptr_to_member_type 0x1f +#define DW_TAG_set_type 0x20 +#define DW_TAG_subrange_type 0x21 +#define DW_TAG_with_stmt 0x22 +#define DW_TAG_access_declaration 0x23 +#define DW_TAG_base_type 0x24 +#define DW_TAG_catch_block 0x25 +#define DW_TAG_const_type 0x26 +#define DW_TAG_constant 0x27 +#define DW_TAG_enumerator 0x28 +#define DW_TAG_file_type 0x29 +#define DW_TAG_friend 0x2a +#define DW_TAG_namelist 0x2b + /* Early releases of this header had the following + misspelled with a trailing 's' */ +#define DW_TAG_namelist_item 0x2c /* DWARF3/2 spelling */ +#define DW_TAG_namelist_items 0x2c /* SGI misspelling/typo */ +#define DW_TAG_packed_type 0x2d +#define DW_TAG_subprogram 0x2e + /* The DWARF2 document had two spellings of the following + two TAGs, DWARF3 specifies the longer spelling. */ +#define DW_TAG_template_type_parameter 0x2f /* DWARF3/2 spelling*/ +#define DW_TAG_template_type_param 0x2f /* DWARF2 spelling*/ +#define DW_TAG_template_value_parameter 0x30 /* DWARF3/2 spelling*/ +#define DW_TAG_template_value_param 0x30 /* DWARF2 spelling*/ +#define DW_TAG_thrown_type 0x31 +#define DW_TAG_try_block 0x32 +#define DW_TAG_variant_part 0x33 +#define DW_TAG_variable 0x34 +#define DW_TAG_volatile_type 0x35 +#define DW_TAG_dwarf_procedure 0x36 /* DWARF3 */ +#define DW_TAG_restrict_type 0x37 /* DWARF3 */ +#define DW_TAG_interface_type 0x38 /* DWARF3 */ +#define DW_TAG_namespace 0x39 /* DWARF3 */ +#define DW_TAG_imported_module 0x3a /* DWARF3 */ +#define DW_TAG_unspecified_type 0x3b /* DWARF3 */ +#define DW_TAG_partial_unit 0x3c /* DWARF3 */ +#define DW_TAG_imported_unit 0x3d /* DWARF3 */ + /* Do not use DW_TAG_mutable_type */ +#define DW_TAG_mutable_type 0x3e /* Withdrawn from DWARF3 by DWARF3f. */ +#define DW_TAG_condition 0x3f /* DWARF3f */ +#define DW_TAG_shared_type 0x40 /* DWARF3f */ +#define DW_TAG_type_unit 0x41 /* DWARF4 */ +#define DW_TAG_rvalue_reference_type 0x42 /* DWARF4 */ +#define DW_TAG_template_alias 0x43 /* DWARF4 */ + +typedef struct { + ut32 len; + ut16 version; + ut32 plen; + ut8 minislen; + ut8 is_stmt; + char line_base; + ut8 line_range; + ut8 opcode_base; + ut32 oplentable[12]; +} RBinDwarfInfoHeader; + +#endif diff --git a/libr/include/r_core.h b/libr/include/r_core.h index 43f79dc609..ac4685b2e7 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -142,6 +142,7 @@ R_API void r_core_cmd_repeat(RCore *core, int next); R_API char *r_core_editor (RCore *core, const char *str); // XXX void*?? must be RCore ! R_API int r_core_cmdf(void *user, const char *fmt, ...); +R_API int r_core_flush(void *user, const char *cmd); R_API int r_core_cmd0(void *user, const char *cmd); R_API void r_core_cmd_init(struct r_core_t *core); R_API char *r_core_cmd_str(struct r_core_t *core, const char *cmd); diff --git a/libr/include/r_util.h b/libr/include/r_util.h index 8bcb09e7d0..c8527f6cd5 100644 --- a/libr/include/r_util.h +++ b/libr/include/r_util.h @@ -235,6 +235,7 @@ R_API void r_file_mmap_free (RMmap *m); R_API RNum *r_num_new(RNumCallback cb, void *ptr); R_API ut64 r_num_calc (RNum *num, const char *str, const char **err); +R_API const char *r_num_calc_index (const char *p); #define R_BUF_CUR -1 R_API RBuffer *r_buf_new(); diff --git a/libr/util/Makefile b/libr/util/Makefile index 2bfd53d6f0..d780266fb1 100644 --- a/libr/util/Makefile +++ b/libr/util/Makefile @@ -4,6 +4,7 @@ NAME=r_util OBJ=mem.o pool.o num.o str.o hex.o file.o alloca.o range.o log.o OBJ+=prof.o cache.o sys.o buf.o w32-sys.o base64.o name.o calc.o OBJ+=list.o flist.o ht.o ht64.o mixed.o btree.o chmod.o graph.o +OBJ+=uleb128.o OBJ+=regex/regcomp.o regex/regerror.o regex/regexec.o diff --git a/libr/util/calc.c b/libr/util/calc.c index b09b628ea8..88aa97c51b 100644 --- a/libr/util/calc.c +++ b/libr/util/calc.c @@ -15,7 +15,10 @@ #include /* TODO: move into libr/include */ +#ifndef ut64 #define ut64 unsigned long long +#endif + typedef struct { double d; ut64 n; @@ -26,7 +29,7 @@ typedef enum { PLUS='+', MINUS='-', MUL='*', DIV='/', //XOR='^', OR='|', AND='&', PRINT=';', ASSIGN='=', LEFTP='(', RIGHTP=')' -} Token; +} RNumToken; /* accessors */ static inline NumValue Nset(ut64 v) { NumValue n; n.d = (double)v; n.n = v; return n; } @@ -47,13 +50,12 @@ static NumValue expr(int); static NumValue term(int); static void error(const char *); static NumValue prim(int); -static Token get_token(); - +static RNumToken get_token(); static RNum *calc_num = NULL; /* global shit */ #define STRSZ 128 -static Token curr_tok = PRINT; +static RNumToken curr_tok = PRINT; static NumValue number_value = { 0 }; static char string_value[STRSZ]; static int errors = 0; @@ -142,6 +144,14 @@ static void cin_putback (char c) { static int calc_i = 0; static const char *calc_buf = NULL; +R_API const char *r_num_calc_index (const char *p) { + if (p) { + calc_buf = p; + calc_i = 0; + } + return calc_buf +calc_i; +} + static int cin_get(char *c) { if (oc) { *c = oc; @@ -199,32 +209,33 @@ static int cin_get_num(NumValue *n) { return 1; } -static Token get_token() { +static RNumToken get_token() { char c, ch; do { if (!cin_get (&ch)) return curr_tok = END; } while (ch!='\n' && isspace (ch)); switch (ch) { + case 0: case ';': case '\n': - case 0: return curr_tok = END; + return curr_tok = END; case '+': // added for ++name and name++ if (cin_get (&c) && c == '+') return curr_tok = INC; cin_putback (c); - return curr_tok = (Token) ch; + return curr_tok = (RNumToken) ch; case '-': if (cin_get (&c) && c == '-') return curr_tok = DEC; cin_putback (c); - return curr_tok = (Token) ch; + return curr_tok = (RNumToken) ch; case '*': case '/': case '(': case ')': case '=': - return curr_tok = (Token) ch; + return curr_tok = (RNumToken) ch; case '0':case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': @@ -235,23 +246,35 @@ static Token get_token() { } return curr_tok = NUMBER; default: - //if (ch=='$' || isalpha (ch)) { #define isvalidchar(x) \ (isalnum(x) || x==':' || x=='$' || x=='.' || x=='_' || x=='?' || x=='\\' \ - || x==' ' || x=='}' || x=='{' || x=='/' || (x>='0'&&x<='9')) + || x==' ' || x=='[' || x==']' || x=='}' || x=='{' || x=='/' || (x>='0'&&x<='9')) { int i = 0; string_value[i++] = ch; - //while (cin_get (&ch)) { // && ( isalnum (ch) || ch=='$')) { - while (cin_get (&ch) && isvalidchar (ch)) { - if (i>=STRSZ) { - error ("string too long"); - return 0; + if (ch == '[') { +eprintf ("laraalalala\n"); + while (cin_get (&ch) && ch!=']') { + if (i>=STRSZ) { + error ("string too long"); + return 0; + } + string_value[i++] = ch; } +eprintf ("BREAK (%c)\n", ch); string_value[i++] = ch; - } + } else { + while (cin_get (&ch) && isvalidchar (ch)) { + if (i>=STRSZ) { + error ("string too long"); + return 0; + } + string_value[i++] = ch; + } + } string_value[i] = 0; cin_putback (ch); + return curr_tok = NAME; } //} @@ -260,28 +283,12 @@ static Token get_token() { } } -void load_token(const char *s) { +static void load_token(const char *s) { calc_i = 0; calc_buf = s; calc_err = NULL; } -#ifdef TEST -int main(int argc, char* argv[]) { - NumValue n; - while (!feof (stdin)) { - get_token (); - if (curr_tok == END) break; - if (curr_tok == PRINT) continue; - n = expr (0); - if (n.d == ((double)(int)n.d)) - printf ("%llx\n", n.n); - else printf ("%lf\n", n.d); - } - return errors; -} -#endif - R_API ut64 r_num_calc (RNum *num, const char *str, const char **err) { NumValue n; if (!*str) @@ -299,3 +306,19 @@ R_API ut64 r_num_calc (RNum *num, const char *str, const char **err) { } else if (num) num->fvalue = (double)n.n; return n.n; } + +#ifdef TEST +int main(int argc, char* argv[]) { + NumValue n; + while (!feof (stdin)) { + get_token (); + if (curr_tok == END) break; + if (curr_tok == PRINT) continue; + n = expr (0); + if (n.d == ((double)(int)n.d)) + printf ("%llx\n", n.n); + else printf ("%lf\n", n.d); + } + return errors; +} +#endif diff --git a/libr/util/num.c b/libr/util/num.c index f7cc9d82af..25e1328cd9 100644 --- a/libr/util/num.c +++ b/libr/util/num.c @@ -79,13 +79,10 @@ R_API ut64 r_num_get(RNum *num, const char *str) { return (ut64)str[1]; len = strlen (str); - if (len>3 && str[4] == ':') { - if (sscanf (str, "%04x", &s)==1) { - if (sscanf (str+5, "%04x", &a)==1) { + if (len>3 && str[4] == ':') + if (sscanf (str, "%04x", &s)==1) + if (sscanf (str+5, "%04x", &a)==1) return (ut64) ((s<<16) | a); - } - } - } if (sscanf (str, "0x%04x:0x%04x", &s, &a) == 2) return (ut64) ((s<<16) |a); if (str[0]=='0' && str[1]=='x') { @@ -108,9 +105,6 @@ R_API ut64 r_num_get(RNum *num, const char *str) { else if (str[i]!='0') break; } break; - default: - sscanf (str, "%"PFMT64d"", &ret); - break; case 'K': case 'k': sscanf (str, "%"PFMT64d"", &ret); ret *= 1024; @@ -123,6 +117,9 @@ R_API ut64 r_num_get(RNum *num, const char *str) { sscanf (str, "%"PFMT64d"", &ret); ret *= 1024*1024*1024; break; + default: + sscanf (str, "%"PFMT64d"", &ret); + break; } } diff --git a/libr/util/uleb128.c b/libr/util/uleb128.c new file mode 100644 index 0000000000..7a9f86af5c --- /dev/null +++ b/libr/util/uleb128.c @@ -0,0 +1,38 @@ +#include + +/* dwarf uleb128 implementation */ + +R_API const ut8 *r_uleb128 (const ut8 *data, ut32 *v) { + ut8 c; + ut32 s, sum; + for (s = sum = 0; ; s+= 7) { + c = *(data++) & 0xff; + sum |= ((ut32) (c&0x7f)<