From 302328a76c11ebfc111fc01cda2317f9b7a8e9e7 Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 3 Sep 2013 22:45:43 +0200 Subject: [PATCH] Fix #203 - Call to a section + some more work on utf8 --- TODO.md | 1 - libr/cons/cons.c | 3 +- libr/cons/output.c | 17 + libr/core/anal.c | 2 +- libr/core/cmd_flag.c | 5 + libr/flags/flags.c | 23 +- libr/flags/old_flags.c | 1080 ---------------------------------------- libr/include/r_flags.h | 1 + libr/include/r_util.h | 1 + libr/util/str.c | 10 + 10 files changed, 59 insertions(+), 1084 deletions(-) delete mode 100644 libr/flags/old_flags.c diff --git a/TODO.md b/TODO.md index 23de54121e..3ea1627927 100644 --- a/TODO.md +++ b/TODO.md @@ -15,7 +15,6 @@ Broken stuff to fixe before release ===== * use __unused if available * rafind2 : add support for unicode/widestring search -* e dbg.hwbp para evitar q use hwbps * .dr- # documented... but not working * libr/debug/p/drx.c <- not used .. debug must have a hw reg api for drx and gpio * ah -> add hint to define calls that do not return diff --git a/libr/cons/cons.c b/libr/cons/cons.c index b01c4b0709..7e9a0f6b5d 100644 --- a/libr/cons/cons.c +++ b/libr/cons/cons.c @@ -9,7 +9,7 @@ #include #endif -R_LIB_VERSION(r_cons); +R_LIB_VERSION (r_cons); static RCons r_cons_instance; #define I r_cons_instance @@ -199,6 +199,7 @@ R_API void r_cons_gotoxy(int x, int y) { R_API void r_cons_print_clear() { // xlr8! r_cons_write ("\x1b[0;0H", 6); + r_cons_write ("\x1b[0m", 4); //r_cons_memcat ("\x1b[2J", 4); } diff --git a/libr/cons/output.c b/libr/cons/output.c index 3e456e98e5..6ab55ad45f 100644 --- a/libr/cons/output.c +++ b/libr/cons/output.c @@ -43,6 +43,19 @@ void w32_gotoxy(int x, int y) { SetConsoleCursorPosition (hStdout, coord); } +static int wrapline (const char *s, int len) { + const char *p = s; + int l, n = 0; + for (; nlen) + n -= l; + else n--; + return n; +} + R_API int r_cons_w32_print(ut8 *ptr, int empty) { HANDLE hConsole = GetStdHandle (STD_OUTPUT_HANDLE); int esc = 0; @@ -63,6 +76,7 @@ R_API int r_cons_w32_print(ut8 *ptr, int empty) { if (ll<1) continue; if (empty) { + // TODO: Fix utf8 chop /* only chop columns if necessary */ if (linelen+ll>cols) { // chop line if too long @@ -101,12 +115,15 @@ R_API int r_cons_w32_print(ut8 *ptr, int empty) { } } write (1, "\n\r", 2); + //write (1, "\r\n", 2); //lines--; linelen = 0; } if (linelen+ll>cols) { // chop line if too long ll = (cols-linelen)-1; + // fix utf8 len here + ll = wrapline (str, cols-linelen-1); } if (ll>0) { write (1, str, ll); diff --git a/libr/core/anal.c b/libr/core/anal.c index 64d05c91da..0bc0285359 100644 --- a/libr/core/anal.c +++ b/libr/core/anal.c @@ -363,7 +363,7 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept (fcnlen == R_ANAL_RET_END && fcn->size < 1)) { /* Error analyzing function */ goto error; } else if (fcnlen == R_ANAL_RET_END) { /* Function analysis complete */ - RFlagItem *f = r_flag_get_i (core->flags, at); + RFlagItem *f = r_flag_get_i2 (core->flags, at); if (f) { /* Check if it's already flagged */ fcn->name = strdup (f->name); // memleak here? } else { diff --git a/libr/core/cmd_flag.c b/libr/core/cmd_flag.c index c0a1285597..05cab8e12c 100644 --- a/libr/core/cmd_flag.c +++ b/libr/core/cmd_flag.c @@ -10,6 +10,11 @@ static int cmd_flag(void *data, const char *input) { if (*input) str = strdup (input+1); switch (*input) { + case '2': + { + r_flag_get_i2 (core->flags, r_num_math (core->num, input+1)); + } + break; case 'R': { char *p = strchr (str+1, ' '); diff --git a/libr/flags/flags.c b/libr/flags/flags.c index 5129322cb8..8791ed136f 100644 --- a/libr/flags/flags.c +++ b/libr/flags/flags.c @@ -92,8 +92,28 @@ R_API RFlagItem *r_flag_get(RFlag *f, const char *name) { return NULL; } -#define R_FLAG_TEST 0 +R_API RFlagItem *r_flag_get_i2(RFlag *f, ut64 off) { + RFlagItem *oitem = NULL; + RFlagItem *item = NULL; + RList *list = r_hashtable64_lookup (f->ht_off, off); + if (list) { + RListIter *iter; + r_list_foreach (list, iter, item) { + // XXX: hack, because some times the hashtable is poluted by ghost values + if (item->offset != off) + continue; + if (!strchr (item->name, '.')) + oitem = item; + if (strlen (item->name) < 5 || item->name[3]!='.') + continue; + oitem = item; + } + } + return oitem; +} + +#define R_FLAG_TEST 0 R_API RFlagItem *r_flag_get_i(RFlag *f, ut64 off) { RList *list = r_hashtable64_lookup (f->ht_off, off); if (list) { @@ -118,6 +138,7 @@ R_API int r_flag_set(RFlag *f, const char *name, ut64 off, ut32 size, int dup) { if (!name || !*name) return R_FALSE; if (dup) { +// XXX: doesnt works well item = R_NEW0 (RFlagItem); if (!r_flag_item_set_name (item, name)) { eprintf ("Invalid flag name '%s'.\n", name); diff --git a/libr/flags/old_flags.c b/libr/flags/old_flags.c deleted file mode 100644 index f508d284e2..0000000000 --- a/libr/flags/old_flags.c +++ /dev/null @@ -1,1080 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 - * pancake - * - * radare is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * radare is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with radare; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "main.h" -#include "radare.h" -#include "flags.h" -#include "utils.h" -#include "list.h" -#include -#include -#include -#include - -struct list_head flags; -static int flag_ptr = -1; - -#define FLAG_SPACES 32 -// XXX optimize... FLAG SPACES MUST BE A LINKED LIST TOO! -static struct flags_spaces_t { - const char *name; -} flag_spaces[FLAG_SPACES]; - -static ut64 flag_from_i = 0; -int flag_space_idx = -1; -int flag_space_idx2 = -1; - -void flag_from(const char *str) -{ - if (str[0]) { - flag_from_i = get_math(str); - } else - cons_printf("0x%08"PFMT64x"\n", flag_from_i); -} - -void flag_help() -{ - eprintf("Usage: f[?|d|-] [flag-name]\n" - " fortune ; show fortune message! :D\n" - " ff [addr] ; flag from this address\n" - " fd ; print flag delta offset\n" - " fc cmd ; set command to be executed on flag at current seek\n" - " fi pfx1 pfx2 ; flag interpolation between hit0_ and hit1_ for.example\n" - " fg text[*] ; grep for flag or all flags matching text* (like f | grep foo)\n" - " fh text[*] ; used for \"section_\"\n" - " fn name ; new flag (ignores dupped names)\n" - " fu name ; new flag if no one exists here (shy)\n" - " fm name ; move flag to another flag space\n" - " fs spacename ; create/list/switch flag spaces\n" - " fr old new ; rename a flag or more with '*'\n" - " f sym.main ; flag current offset as sym.main\n" - " f foo @ 0x23 ; flag 0x23 offset as foo\n" - " f -sym.main ; remove sym.main\n" - " f -* ; remove all flags\n" - " f -sym.* ; remove all flags starting with 'sym.'\n"); -} - -int flag_interpolation(const char *from, const char *to) -{ - int ret = 0; - ut64 tmp = 0; - const char *str = NULL; - struct list_head *pos, *pos2; - - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - tmp = 0; - if (!memcmp(from, flag->name, strlen(from))) { - list_for_each(pos2, &flags) { - flag_t *flag2 = (flag_t *)list_entry(pos2, flag_t, list); - if (!memcmp(from, flag->name, strlen(to))) { - if (flag2->offset>flag->offset && (tmp == 0 || flag2->offset < tmp)) { - tmp = flag2->offset; - str = flag2->name; - } - } - } - - if (tmp != 0) { - printf("%s (0x%08"PFMT64x") -> %s (0x%08"PFMT64x") ; size = %"PFMT64d"\n", - flag->name, flag->offset, str, tmp, tmp-flag->offset); - } - } - } - return ret; -} - -void flag_cmd(const char *text) -{ - flag_t *flag = flag_by_offset(config.seek); - if (text == NULL || text[0] == '\0' || text[0]=='?') { - cons_printf("Usage: fc @ \n"); - cons_printf(" > fc pd 20 @ 0x8049104\n"); - } else - if (flag != NULL) { - flag->cmd = estrdup((char*)flag->cmd, text); - cons_printf("flag_cmd(%s) = '%s'\n", flag->name, text); - } -} - -flag_t *flag_get_by_addr(ut64 addr) -{ - struct list_head *pos; - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (flag->offset == addr) - return flag; - } - return NULL; -} - -flag_t *flag_get_i(int id) -{ - struct list_head *pos; - int i = 0; - - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (i++ == id) - return flag; - } - - return NULL; -} - -void flag_show(flag_t *flag, int cmd_flag) -{ - // TODO: use flags[i]->format over flags[i]->data and flags[i]->length - cons_printf("0x%08"PFMT64x"\t %"PFMT64d"\t %s\n", - flag->offset, flag->length, flag->name); - if (cmd_flag && flag->cmd!=NULL && *flag->cmd) { - ut64 seek = config.seek; - radare_seek(flag->offset, SEEK_SET); - radare_cmd_raw(flag->cmd, 0); - radare_seek(seek, SEEK_SET); - cons_newline(); - } -} - -void flag_grep_help() -{ - eprintf("Usage: fg[n|p] [string]\n"); - eprintf(" fg - List flags matching a string\n"); - eprintf(" fgn, fgp - List next/previous flag matching string\n"); - eprintf(" fgn imp.\n"); -} - -void flag_grep_np(const char *str, ut64 addr, int next) -{ - struct list_head *pos; - flag_t *fag = NULL; - ut64 newaddr; - - newaddr = next?0:0xffffffffffffffffLL; - - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (config.interrupted) break; - if (next) { - if (str_grep(flag->name, str)) { - if (flag->offset < addr && flag->offset > newaddr) { - newaddr = flag->offset; - fag = flag; - } - } - } else { - if (str_grep(flag->name, str)) { - if (flag->offset > addr && flag->offset < newaddr) { - newaddr = flag->offset; - fag = flag; - } - } - } - } - - if (fag) - cons_printf("0x%08"PFMT64x" %s\n", fag->offset, fag->name); -} - -// TODO: USE GLOB OR SO... -void flag_grep(const char *grepstr) // TODO: add ut64 arg to grep only certain address -{ - int cmd_flag = config_get_i("cmd.flag"); /* boolean */ - char *grep; - char *mask; - struct list_head *pos; - - grep = alloca(strlen(grepstr)+1); - strcpy(grep, grepstr); - mask = strchr(grep, '*'); - - if (mask) - mask[0]='\0'; - - // TODO: Use str_grep here - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (config.interrupted) break; - if (mask) { - if (strstr(flag->name, grep)) - flag_show(flag, cmd_flag); - } else { - if (!strcmp(flag->name, grep)) - flag_show(flag, cmd_flag); - } - } -} - -ut64 flag_get_addr(const char *name) -{ - flag_t *foo = flag_get(name); - if (foo) - return foo->offset; - return 0; -} - -ut64 flag_delta_between(ut64 from, ut64 to) -{ - struct list_head *pos; - - list_for_each(pos, &flags) { - flag_t *flag = list_entry(pos, flag_t, list); - if (flag->offset > from && flag->offset <= to) { - return flag->offset - from; - } - } - return 0; -} - -flag_t *flag_get_next(int delta) -{ - flag_t *nice = NULL; - struct list_head *pos; - - if (delta == 1) { - list_for_each(pos, &flags) { - flag_t *flag = list_entry(pos, flag_t, list); - if (flag->offset > config.seek) { - if (nice) { - if (flag->offset < nice->offset) - nice = flag; - } else { - nice = flag; - } - } - } - } else { //if (delta == -1) { - list_for_each(pos, &flags) { - flag_t *flag = list_entry(pos, flag_t, list); - if (flag->offset < config.seek) { - if (nice) { - if (flag->offset > nice->offset) - nice = flag; - } else { - nice = flag; - } - } - } - } - return nice; -} - -flag_t *flag_get_reset() -{ - flag_ptr = 0; - return flag_get_next(flag_ptr); -} - -// TODO : use flag size -int flags_between(ut64 from, ut64 to) -{ - int n=0; - struct list_head *pos; - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (flag->offset >= from && flag->offset <= to) - n++; - } - return n; -} - -int flag_rename(char *foo, char *bar) -{ - int n = 0; - int ini = 0; - int end = strlen(foo); - int sz = end-ini; - int glob_end = 0; - struct list_head *pos; - - if (foo[0]=='*') - ini = 1; - if (foo[end-1]=='*') { - glob_end = 1; - foo[end]='\0'; - sz--; - end --; - } - - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (ini) { - char *str = strstr(flag->name, foo+ini); - if (str) { - str = strdup(str); - sprintf(flag->name, "%s%s", bar, str); - free(str); - } - } else - if (!_strnstr(foo+ini, flag->name, sz)) { - if (glob_end) { - char *str = strdup(flag->name+sz); - sprintf(flag->name, "%s%s", bar, str); - free(str); - } else { - if (flag->name[end]=='\0') - strcpy(flag->name, bar); - } - n++; - } - } - return n; -} - -int flag_rename_str(char *text) -{ - int n = 0; - char *arg = text?strchr(text, ' '):NULL; - if (arg) { - arg[0]='\0'; - n = flag_rename(text, arg+1); - cons_printf("%d flags renamed\n", n); - arg[0]=' '; - } else { - cons_printf("Usage: fr old-name new-name\n"); - cons_printf("> fr hit0_* hit_search\n"); - } - return n; -} - -/* deprecated ?!?! */ -void flags_setenv() -{ - int i; - char var[1024]; - char *ptr = environ[0]; - - for(i=0;(ptr = environ[i]);i++) { - if (config.interrupted) break; - if (!memcmp("flag_", environ[i], 5)) { - int len = strchr(environ[i],'=') - environ[i]; - if (len>0) { - memset(var, '\0', 1024); - memcpy(var, environ[i], len); - unsetenv(var); - } - } - } -} - -flag_t *flag_by_offset(ut64 offset) -{ - struct list_head *pos; - - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (flag->offset == offset) - return flag; - if (config.interrupted) break; - } - - return NULL; -} - -const char *flag_name_by_offset(ut64 offset) -{ - struct list_head *pos; - - //if (offset > config.vaddr) - offset=offset-config.paddr+config.vaddr; - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (flag->offset == offset) - return flag->name; - if (config.interrupted) break; - } - - return nullstr; -} - -/* TODO - * idx = -1 : return all flags at given seek separated by comma - * idx = 0 : just return the first one found - * idx = 1 : continue searching for flag after the first one - */ -int string_flag_offset(char *buf, ut64 seek, int idx) -{ - int delta = (int)config_get_i("cfg.delta"); - flag_t *ref = NULL; - struct list_head *pos; - - buf[0]='\0'; - - list_for_each(pos, &flags) { - if (config.interrupted) break; - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (flag->offset == seek) { - ref = flag; - if (idx==-1) { - if (buf[0]) - strcat(buf, ","); - strcat(buf, ref->name); - } else break; - } else - if (!flag->offset) - continue; - else - if (flag->offset <= seek && (!ref || flag->offset > ref->offset)) - ref = flag; - } - if (idx==-1) - return 1; - - if (ref) { - long ul = (seek-ref->offset); - if (ul == 0) - strcpy(buf, ref->name); - else - if (ul >-delta && ulname, ul); - else return 0; - return 1; - } - - return 0; -} - -void print_flag_offset(ut64 seek) -{ - char buf[256]; - - if ( string_flag_offset(buf, seek, -1) ) - cons_strcat(buf); -} - -void flag_do_empty(flag_t *flag) -{ - if (flag == NULL) - return; - - flag->name[0]='\0'; -} - -int flag_is_empty(flag_t *flag) -{ - if (flag == NULL || flag->name[0]=='\0') - return 1; - - return 0; -} - -void flag_list(char *arg) -{ - struct list_head *pos; - - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (config.interrupted) break; - - /* filter per flag spaces */ - if ((flag_space_idx != -1) && (flag->space != flag_space_idx)) - continue; - - flag_show(flag, 0); -#if 0 - cons_printf("%03d 0x%08"PFMT64x" %4lld %s", - i++, flag->offset, flag->length, flag->name); -#endif - // TODO: use flags[i]->format over flags[i]->data and flags[i]->length - } -} - -void flag_clear_by_addr(ut64 seek) -{ - struct list_head *pos; - - _polla: - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (config.interrupted) break; - if (flag->offset == seek) { - list_del(&flag->list); - free(flag); - pos = flags.prev; - goto _polla; - } - } -} - -void flag_space_move(const char *name) -{ - flag_t *f; - - if (name == NULL || name[0] == '\0' || name[0]=='?') { - eprintf("Usage: fm - moves the selected flag to the current flagspace\n"); - } else { - f = flag_get(name); - f->space = flag_space_idx; - } -} - -void flag_space_set(const char *name) -{ - int i; - for(i=0;ispace == i) - flag->space = -1; - } - break; - } - } -} - -void flag_space_list() -{ - int i,j = 0; - for(i=0;i fs regs - create/switch to 'regs' flagspace\n"); - cons_printf(" > fs -regs - remove 'regs' space\n"); - cons_printf(" > fs * - select all spaces\n"); - cons_printf(" > fs - list all flag spaces\n"); - break; - default: - flag_space_set(name); - break; - } -} - -void flag_remove(const char *name) -{ - struct list_head *pos; - char *str, *mask; - int l; - int found = 0; - - if (name == NULL || *name == '\0') - return; - - str = strdup(name); // TODO: strdup only when no mask is used - mask = strchr(str, '*'); - - if (mask) { - mask[0]='\0'; - l = strlen(str); - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (config.interrupted) break; - if (!memcmp(str, flag->name, l)) { - list_del(&(flag->list)); - free(flag); - pos = flags.next; - continue; - } - } - } else { - __restart2: - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - if (config.interrupted) break; - if (!strcmp(name, flag->name)) { - list_del(&(flag->list)); - free(flag); - found = 1; - goto __restart2; - } - } - } - - if (!found) - flag_clear_by_addr(get_math(str)); - - free(str); -} - -int flag_qsort_compare(const void *a, const void *b) -{ - if (a == NULL) - return -1; - if (b == NULL) - return 1; - return strcmp(b, a); -} - -#define MAX_FLAG_LEN 20 -int flag_filter_name(char *name) -{ - int i; - char *oname; - for(;*name==' ';name=name+1); - oname=name; - for(i=0;*name!='\0'; name = name +1,i++) { - if (i>MAX_FLAG_LEN) { - name[0]='\0'; - break; - } - if (!flag_is_valid_char(*name)) { - strcpy(name, name+1); - name = name -1; - } - } - return flag_is_valid_name(oname); -} - - -int flag_set(const char *name, ut64 addr, int dup) -{ - const char *ptr; - flag_t *flag = NULL; - struct list_head *pos; - - if (!dup) { - /* show flags as radare commands */ - if (name[0]=='*' && name[1]=='\0') { - list_for_each(pos, &flags) { - flag_t *f = (flag_t *)list_entry(pos, flag_t, list); - if (config.interrupted) break; - cons_printf("f %s @ 0x"OFF_FMTx"\n", f->name, f->offset); - } - return 2; - } else { - if (!flag_is_valid_name(name)) { - eprintf("invalid flag name '%s'.\n", name); - return 2; - } - - for (ptr = name + 1; *ptr != '\0'; ptr = ptr +1) { - if (!is_printable(*ptr)) { - eprintf("invalid flag name\n"); - return 2; - } - } - } - } - - list_for_each(pos, &flags) { - flag_t *f = (flag_t *)list_entry(pos, flag_t, list); - if (config.interrupted) break; - if (!strcmp(f->name, name)) { - if (dup) { - /* ignore dupped name+offset */ - if (f->offset == addr) - return 1; - } else { - flag = f; - f->offset = addr + flag_from_i; - f->length = config.block_size; - f->format = last_print_format; -/* - memcpy(f->data, config.block, - (config.block_size>sizeof(flags[i]->data))? - sizeof(f->data):config.block_size); - -*/ - return 1; - } - } - } - - if (flag == NULL) { - flag = malloc(sizeof(flag_t)); - memset(flag,'\0', sizeof(flag_t)); - list_add_tail(&(flag->list), &flags); - if (flag==NULL) - return 1; - } - - strncpy(flag->name, name, FLAG_BSIZE); - flag->name[FLAG_BSIZE-1]='\0'; - flag->offset = addr + flag_from_i; - flag->space = flag_space_idx; - flag->length = config.block_size; - flag->format = last_print_format; - flag->cmd = NULL; -#if 0 - // XXX store data in flags is ugly! - if (radare_read(0)!=-1) - memcpy(flag->data, config.block, - (config.block_size>sizeof(flag->data))? - sizeof(flag->data):config.block_size); -#endif - - // TODO qsort(flags, nflags, sizeof(flag_t*), flag_qsort_compare); - - return 0; -} - -int flag_set_undef(const char *name, ut64 addr, int dup) -{ - flag_t *flag = flag_get_by_addr(addr); - if (flag == NULL || (strlen(flag->name)<4)) - return flag_set(name, addr, dup); - return 0; -} - -/* used to get section name for disasembly */ -const char *flag_get_here_filter(ut64 at, const char *str) -{ - static ut64 sec_start=0, sec_end=0; - static char sec_str[64]; - struct list_head *pos; - ut64 ret = 0; - ut64 nextflag = 0xFFFFFFFFFFFFFFFFFFLL; - flag_t *f = NULL; - - if (at >=sec_start && at name, str)) || strstr(flag->name, "end")) - continue; - - if (flag->offset < nextflag && flag->offset > at) { - nextflag = flag->offset; - } else - if (at >= flag->offset && flag->offset > ret) { - f = flag; - ret = flag->offset; - } - } - if (f == NULL) - return nullstr; - sec_start = f->offset; - sec_end = nextflag; - strcpy(sec_str, f->name+strlen(str)); - return sec_str; -} - -//XXX ugly hack -const char *flag_get_here_filter2(ut64 at, const char *str, const char *str2) -{ - static ut64 sec_start=0, sec_end=0; - static char sec_str[64]; - struct list_head *pos; - ut64 ret = 0; - ut64 nextflag = 0xFFFFFFFFFFFFFFFFFFLL; - flag_t *f = NULL; - char *s1,*s2,*s=NULL; - - if (at >=sec_start && at name, str); - s2 = strstr(flag->name, str2); - if ((!s1 && !s2) || strstr(flag->name, "_end")) - continue; - - if (flag->offset < nextflag && flag->offset > at) { - nextflag = flag->offset; - } else - if (at >= flag->offset && flag->offset > ret) { - s = s1?str:str2; - f = flag; - ret = flag->offset; - } - } - if (f == NULL) - return nullstr; - sec_start = f->offset; - sec_end = nextflag; - strcpy(sec_str, f->name+((s!=NULL)?strlen(s):0)); - return sec_str; -} - -/* TODO: move to visual */ -void flags_visual_menu() -{ - char cmd[1024]; - struct list_head *pos; -#define MAX_FORMAT 2 - int format = 0; - const char *ptr; - const char *fs = NULL; - char *fs2 = NULL; - int option = 0; - int _option = 0; - int delta = 7; - int menu = 0; - int i,j, ch; - int hit; - - while(1) { - cons_gotoxy(0,0); - cons_clear(); - /* Execute visual prompt */ - ptr = config_get("cmd.vprompt"); - if (ptr&&ptr[0]) { - int tmp = last_print_format; - radare_cmd_raw(ptr, 0); - last_print_format = tmp; - } - - switch(menu) { - case 0: // flag space - cons_printf("\n Flag spaces:\n\n"); - hit = 0; - for(j=i=0;i=option-delta) && ((i':' ', j, (i==flag_space_idx)?'*':' ', flag_spaces[i].name); - j++; - } - } - } - if (!hit && j>0) { - option = j-1; - continue; - } - break; - case 1: // flag selection - cons_printf("\n Flags in flagspace '%s'. Press '?' for help.\n\n", - flag_spaces[flag_space_idx]); - hit = 0; - i = j = 0; - list_for_each(pos, &flags) { - flag_t *flag = (flag_t *)list_entry(pos, flag_t, list); - /* filter per flag spaces */ - if ((flag_space_idx != -1) && (flag->space != flag_space_idx)) - continue; - if (option==i) { - fs2 = flag->name; - hit = 1; - } - if( (i >=option-delta) && ((i':' ', - i, flag->offset, flag->length, flag->name); - j++; - } - i++; - } - if (!hit && i>0) { - option = i-1; - continue; - } - cons_printf("\n Selected: %s\n\n", fs2); - - switch(format) { - case 0: sprintf(cmd, "px @ %s", fs2); break; - case 1: sprintf(cmd, "pd @ %s", fs2); break; - case 2: sprintf(cmd, "pz @ %s", fs2); break; - default: format = 0; continue; - } -#if 0 - /* TODO: auto seek + print + disasm + string ...analyze stuff and proper print */ - cmd[0]='\0'; - if (strstr(fs2, "str_")) { - sprintf(cmd, "pz @ %s", fs2); - } else - if (strstr(fs2, "sym_")) { - sprintf(cmd, "pd @ %s", fs2); - } else - sprintf(cmd, "px @ %s", fs2); -#endif - if (cmd[0]) - radare_cmd_raw(cmd, 0); - } - cons_flush(); - ch = cons_readchar(); - ch = cons_get_arrow(ch); // get ESC+char, return 'hjkl' char - switch(ch) { - case 'J': - option+=10; - break; - case 'j': - option++; - break; - case 'k': - if (--option<0) - option = 0; - break; - case 'K': - option-=10; - if (option<0) - option = 0; - break; - case 'h': - case 'b': // back - menu = 0; - option = _option; - break; - case 'a': - switch(menu) { - case 0: // new flag space - break; - case 1: // new flag - break; - } - break; - case 'd': - flag_remove(fs2); - break; - case 'e': - /* TODO: prompt for addr, size, name */ - break; - case 'q': - if (menu<=0) return; menu--; - break; - case '*': - case '+': - radare_set_block_size_i(config.block_size+1); - break; - case '/': - case '-': - radare_set_block_size_i(config.block_size-1); - break; - case 'P': - if (--format<0) - format = MAX_FORMAT; - break; - case 'p': - format++; - break; - case 'l': - case ' ': - case '\r': - case '\n': - if (menu == 1) { - sprintf(cmd, "s %s", fs2); - radare_cmd_raw(cmd, 0); - return; - } - flag_space_set(fs); - menu = 1; - _option = option; - option = 0; - break; - case '?': - cons_clear00(); - cons_printf("\nVt: Visual Track help:\n\n"); - cons_printf(" q - quit menu\n"); - cons_printf(" j/k - down/up keys\n"); - cons_printf(" h/b - go back\n"); - cons_printf(" l/' ' - accept current selection\n"); - cons_printf(" a/d/e - add/delete/edit flag\n"); - cons_printf(" +/- - increase/decrease block size\n"); - cons_printf(" p/P - rotate print format\n"); - cons_printf(" : - enter command\n"); - cons_flush(); - cons_any_key(); - break; - case ':': - cons_set_raw(0); -#if HAVE_LIB_READLINE - char *ptr = (char *)readline(VISUAL_PROMPT); - if (ptr) { - strncpy(cmd, ptr, sizeof(cmd)); - radare_cmd(cmd, 1); - //commands_parse(line); - free(ptr); - } -#else - cmd[0]='\0'; - dl_prompt = ":> "; - if (cons_fgets(cmd, 1000, 0, NULL) <0) - cmd[0]='\0'; - //line[strlen(line)-1]='\0'; - radare_cmd(cmd, 1); -#endif - cons_set_raw(1); - if (cmd[0]) - cons_any_key(); - cons_gotoxy(0,0); - cons_clear(); - continue; - } - } -} diff --git a/libr/include/r_flags.h b/libr/include/r_flags.h index 25da84b33b..be9267c63f 100644 --- a/libr/include/r_flags.h +++ b/libr/include/r_flags.h @@ -58,6 +58,7 @@ R_API RFlag * r_flag_free(RFlag *f); R_API void r_flag_list(RFlag *f, int rad); R_API RFlagItem *r_flag_get(RFlag *f, const char *name); R_API RFlagItem *r_flag_get_i(RFlag *f, ut64 off); +R_API RFlagItem *r_flag_get_i2(RFlag *f, ut64 off); R_API int r_flag_unset(RFlag *f, const char *name, RFlagItem *p); R_API int r_flag_unset_i(RFlag *f, ut64 addr, RFlagItem *p); R_API int r_flag_set(RFlag *fo, const char *name, ut64 addr, ut32 size, int dup); diff --git a/libr/include/r_util.h b/libr/include/r_util.h index a650457040..8672cc788d 100644 --- a/libr/include/r_util.h +++ b/libr/include/r_util.h @@ -338,6 +338,7 @@ R_API int r_base64_decode(ut8 *bout, const ut8 *bin, int len); R_API const char *r_str_rchr(const char *base, const char *p, int ch); R_API void r_str_unescape (char *s); R_API int r_str_len_utf8 (const char *s); +R_API int r_str_len_utf8char (const char *s, int left); R_API void r_str_filter_zeroline(char *str, int len); R_API int r_str_write (int fd, const char *b); R_API void r_str_ncpy(char *dst, const char *src, int n); diff --git a/libr/util/str.c b/libr/util/str.c index 52b2e5ad2d..8d88ffd564 100644 --- a/libr/util/str.c +++ b/libr/util/str.c @@ -953,6 +953,16 @@ R_API const char *r_str_lastbut (const char *s, char ch, const char *but) { } // Must be merged inside strlen +R_API int r_str_len_utf8char (const char *s, int left) { + int i = 1; + while (s[i] && (!left || i