pf: Implement unions

This commit is contained in:
Skia 2015-02-05 01:59:32 +01:00 committed by pancake
parent 08414e305b
commit cf5057a229
3 changed files with 36 additions and 11 deletions

View File

@ -125,11 +125,12 @@ static int process_input(RCore *core, const char *input, ut64* blocksize, char *
static void print_format_help(RCore *core) {
const char* help_msg[] = {
"Usage:", " pf[.key[.field[=value]]|[ val]]|[times][ [size] format] [arg0 arg1 ...]", " # Define and print format strings",
"Usage:", " pf[.key[.field[=value]]|[ val]]|[times]|[0][ [size] format] [arg0 arg1 ...]", " # Define and print format strings",
"Examples:","","",
"pf", "?", "Show this help",
"pf?", "fmt", "Show format of that stored one",
"pf", " iwq foo bar troll", "Print the iwq format with foo, bar, troll as the respective names for the fields",
"pf", " 0iwq foo bar troll", "Same as above, but considered as a union (all fields at offset 0)",
"pf", " 10xiz pointer length string", "Print a size 10 array of the xiz struct with its field names",
"pf", " {integer}bifc", "Print integer times the following format (bifc)",
"pf", " [4]w[7]i", "Print an array of 4 words and then an array of 7 integers",
@ -166,7 +167,7 @@ static void print_format_help(RCore *core) {
" ", "Z", "\\0 terminated wide string",
" ", "s", "32bit pointer to string (4 bytes)",
" ", "S", "64bit pointer to string (8 bytes)",
//" t - unix timestamp string\n",
" ", "t", "unix timestamp string",
" ", "?", "data structure `pf ? (struct_type)struct_name`",
" ", "*", "next char is pointer (honors asm.bits)",
" ", "+", "toggle show flags for each offset",
@ -196,14 +197,14 @@ static void cmd_print_format (RCore *core, const char *_input, int len) {
_input++;
val = r_strht_get (core->print->formats, _input);
if (val != NULL)
r_cons_printf ("%d bytes\n", r_print_format_struct_size (val, core->print));
r_cons_printf ("%d bytes\n", r_print_format_struct_size (val, core->print, mode));
else {
eprintf ("Struct %s not defined\nUsage: pfs.struct_name | pfs format\n", _input);
}
} else if (*_input == ' ') {
while (*_input == ' ' && *_input != '\0') _input++;
if (_input != '\0')
r_cons_printf ("%d bytes\n", r_print_format_struct_size (_input, core->print));
r_cons_printf ("%d bytes\n", r_print_format_struct_size (_input, core->print, mode));
else {
eprintf ("Struct %s not defined\nUsage: pfs.struct_name | pfs format\n", _input);
}

View File

@ -96,7 +96,8 @@ R_API void r_print_code(RPrint *p, ut64 addr, ut8 *buf, int len, char lang);
#define R_PRINT_SEEFLAGS (1<<2)
#define R_PRINT_JSON (1<<3)
#define R_PRINT_MUSTSET (1<<4)
R_API int r_print_format_struct_size(const char *format, RPrint *p);
#define R_PRINT_UNIONMODE (1<<5)
R_API int r_print_format_struct_size(const char *format, RPrint *p, int mode);
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* buf, const int len, const char *fmt, int elem, const char *setval, char *field);
R_API int r_print_format_length (const char *fmt);
R_API void r_print_offset(RPrint *p, ut64 off, int invert, int opt, int delta);

View File

@ -628,10 +628,10 @@ static void r_print_format_enum (const RPrint* p, ut64 seeki, char* fmtname,
}
// XXX: this is very incomplete. must be updated to handle all format chars
int r_print_format_struct_size(const char *f, RPrint *p) {
int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
char *o = strdup(f);
char *end = strchr (o, ' '), *args, *fmt = o;
int size = 0, tabsize=0, i, idx=0;
int size = 0, tabsize=0, i, idx=0, biggest = 0;
if (!end && !(end = strchr (o, '\0')))
return -1;
if (*end) {
@ -640,6 +640,13 @@ int r_print_format_struct_size(const char *f, RPrint *p) {
} else {
args = strdup ("");
}
if (fmt[0] == '0') {
mode |= R_PRINT_UNIONMODE;
fmt++;
} else {
mode &= ~R_PRINT_UNIONMODE;
}
r_str_word_set0 (args);
for (i=0; i<strlen (fmt); i++) {
if (fmt[i] == '[') {
@ -710,19 +717,26 @@ int r_print_format_struct_size(const char *f, RPrint *p) {
}
if (endname) *endname = '\0';
format = r_strht_get (p->formats, structname+1);
size += tabsize * r_print_format_struct_size (format, p);
free (structname);
break;
size += tabsize * r_print_format_struct_size (format, p, mode);
}
break;
// TODO continue list
default:
break;
}
idx++;
if (mode & R_PRINT_UNIONMODE) {
if (size > biggest) biggest = size;
size = 0;
}
}
free (o);
free (args);
return size;
if (mode & R_PRINT_UNIONMODE)
return biggest;
else
return size;
}
static int r_print_format_struct(RPrint* p, ut64 seek, const ut8* b, int len,
@ -739,7 +753,7 @@ static int r_print_format_struct(RPrint* p, ut64 seek, const ut8* b, int len,
return 0;
}
r_print_format (p, seek, b, len, fmt, mode, setval, field);
return r_print_format_struct_size(fmt, p);
return r_print_format_struct_size(fmt, p, mode);
}
#define MINUSONE ((void*)(size_t)-1)
@ -818,6 +832,12 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
#define ISPOINTED ((slide%STRUCTFLAG)/STRUCTPTR<=(oldslide%STRUCTFLAG)/STRUCTPTR)
#define ISNESTED ((slide%STRUCTPTR)<=(oldslide%STRUCTPTR))
if (mode == R_PRINT_JSON && slide==0) p->printf("[");
if (arg[0] == '0') {
mode |= R_PRINT_UNIONMODE;
arg++;
} else {
mode &= ~R_PRINT_UNIONMODE;
}
/* go format */
i = 0;
@ -837,6 +857,9 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
for (idx=0; i<len && arg<argend && *arg; arg++) {
int size; /* size of the array */
char *fieldname = NULL, *fmtname = NULL, *oarg = NULL;
if (mode & R_PRINT_UNIONMODE) {
i = 0;
}
seeki = seek+i;
addr = 0LL;
invalid = 0;