void ls_free(list* ls) { if (!ls) return; if (ls->next) { ls_free(ls->next); } if (ls->type == TYPE_LIST) { ls_free(ls->data); } gc_free(ls); }
static void tcp_listen_cb(uv_stream_t *handle, int status) { lua_State *l = ls_default_state(); ls_tcp_t *server = containerof(handle, ls_tcp_t, handle); uv_loop_t *loop = uv_default_loop(); lua_State *nl; if (ls_object_is_waited(&server->wait_object)) { int ref = server->wait_object.mthread_ref; server->wait_object.mthread_ref = LUA_NOREF; ls_getref(l, ref); nl = lua_tothread(l, -1); lua_pop(l, 1); if (nl) { ls_clear_waiting(nl); if (status != 0) { ls_last_error_resume(nl, loop); } else { ls_tcp_t *client = new_tcp_handle(l); if (uv_accept(handle, (uv_stream_t*)&client->handle)) { ls_free(nl, client); luaL_error(nl, "accept failed"); } if (uv_read_start((uv_stream_t*)&client->handle, tcp_alloc_cb, tcp_read_cb)) { ls_free(nl, client); luaL_error(nl, "start read failed."); } if (LUA_YIELD == lua_status(nl)) { lua_pushboolean(nl, 1); new_tcp_connection_udata(nl, client); ls_resume(nl, 2); } else { ls_free(nl, client); } } } ls_unref(l, ref); } }
static void tcp_close_cb(uv_handle_t *handle) { ls_tcp_t *tcp; lua_State *l, *nl; tcp = containerof(handle, ls_tcp_t, handle); l = ls_default_state(); if (ls_object_is_waited(&tcp->wait_object)) { int ref = tcp->wait_object.mthread_ref; tcp->wait_object.mthread_ref = LUA_NOREF; ls_getref(l, ref); nl = lua_tothread(l, -1); lua_pop(l, 1); if (nl) { ls_clear_waiting(nl); if (LUA_YIELD == lua_status(nl)) ls_error_resume(nl, LS_ERRCODE_EOF, "tcp closed"); } ls_unref(l, ref); } ls_free(l, tcp); }
void btree_free(btree_t *t) { if (!t) return; ls_free(&t->list); lsPairInt_free(&t->children); lsInt_free(&t->parent); }
R_API char *r_type_link_at (Sdb *TDB, ut64 addr) { char* res = NULL; if (addr == UT64_MAX) { return NULL; } char* query = sdb_fmt ("link.%08"PFMT64x, addr); res = sdb_get (TDB, query, 0); if (!res) { // resolve struct memb if possible for given addr SdbKv *kv; SdbListIter *sdb_iter; SdbList *sdb_list = sdb_foreach_list (TDB, true); ls_foreach (sdb_list, sdb_iter, kv) { if (strncmp (kv->key, "link.", strlen ("link."))) { continue; } const char *linkptr = sdb_fmt ("0x%s", kv->key + strlen ("link.")); ut64 baseaddr = r_num_math (NULL, linkptr); int delta = (addr > baseaddr)? addr - baseaddr: -1; res = r_type_get_struct_memb (TDB, kv->value, delta); if (res) { break; } } ls_free (sdb_list); }
void ht_free(SdbHash *ht) { if (ht) { free (ht->table); ls_free (ht->list); free (ht); } }
static int tcp_write(lua_State *l) { tcp_udata_t *udata = connection_udata(l); ls_tcp_t *tcp = udata->handle; uv_stream_t *handle = (uv_stream_t *)&tcp->handle; uv_buf_t bufs[MAX_WRITE_BUF_COUNT]; int refs[MAX_WRITE_BUF_COUNT]; int datacnt; int i; ls_write_t *write_req; if (tcp == NULL) return ls_error_return(l, LS_ERRCODE_EOF, "tcp connection closed."); datacnt = lua_gettop(l) - 1; if (datacnt > arraysize(bufs)) return ls_error_return(l, LS_ERRCODE_ARGSIZE, "too much data to write."); else if (datacnt <= 0) { lua_pushboolean(l, 1); return 1; } for (i=0; i<datacnt; i++) { size_t len; const char *data = lua_tolstring(l, i+2, &len); if (data == NULL) return ls_error_return(l, LS_ERRCODE_INVAL, "invalid data to be writen: should be string or number"); bufs[i] = uv_buf_init((char*)data, len); } // now, number in the stack has already been converted into string write_req = new_write_req(l); if (uv_write(&write_req->req, handle, bufs, datacnt, tcp_write_cb)) { ls_free(l, write_req); return ls_last_error_return(l, handle->loop); } // make ref to the string for (i=0; i<datacnt; i++) { write_req->data_refs[i] = ls_ref_value(l, i+2); } write_req->refcnt = datacnt; // libuv make sure now tcp_write_cb is not called, even the data // has been writen already. ls_set_waiting(l, &write_req->wait_object, udata->timeout); return lua_yield(l, 0); }
list_t * ls_setPt(list_t * il_to, int n, LIST_TYPE * items) { if (!il_to) il_to = ls_Nil(); ls_free(il_to); LS_ITEMS(il_to) = items; LS_N(il_to) = n; il_to->max_list = n; return (il_to); }
list_t * ls_cpyPt(list_t * il_to, list_t * il_from) { if (!il_to) il_to = ls_Nil(); ls_free(il_to); LS_ITEMS(il_to) = LS_ITEMS(il_from); LS_N(il_to) = LS_N(il_from); il_to->max_list = il_from->max_list; return (il_to); }
SDB_VISIBLE void sdb_free (Sdb* s) { if (!s) return; cdb_free (&s->db); if (s->lock) sdb_unlock (sdb_lockfile (s->dir)); ls_free (s->ns); ht_free (s->ht); if (s->fd != -1) close (s->fd); free (s->ndump); free (s->dir); free (s); }
R_API RList* r_type_get_by_offset(Sdb *TDB, ut64 offset) { RList *offtypes = r_list_new (); SdbList *ls = sdb_foreach_list (TDB, true); SdbListIter *lsi; SdbKv *kv; ls_foreach (ls, lsi, kv) { // TODO: Add unions support if (!strncmp (kv->value, "struct", 6) && strncmp (kv->key, "struct.", 7)) { char *res = r_type_get_struct_memb (TDB, kv->key, offset); if (res) { r_list_append (offtypes, res); } } } ls_free (ls); return offtypes; }
int main() { List *ls = ls_make(); S_t *val1 = malloc(sizeof(S_t)); val1->num = 5; S_t *val2 = malloc(sizeof(S_t)); val2->num = 7; S_t *val3 = malloc(sizeof(S_t)); val3->num = 9; S_t *val4 = malloc(sizeof(S_t)); val4->num = 14; S_t *val5 = malloc(sizeof(S_t)); val5->num = 2; S_t *val6 = malloc(sizeof(S_t)); val6->num = 12; S_t *val7 = malloc(sizeof(S_t)); val7->num = 6; S_t *val8 = malloc(sizeof(S_t)); val8->num = 1; ls = ls_cons(ls_cons(ls_cons(ls_cons(ls_cons(ls_cons(ls_cons(ls_cons(ls, val6), val7), val8), val5), val4), val3), val2), val1); printf("list\n"); ls_walk(ls, printer); printf("sorted C\n"); ls_sort(ls, comparator); ls_walk(ls, printer); printf("list reverse\n"); ls_reverse(ls); ls_walk(ls, printer); printf("list mapped\n"); List *cp = ls_map(ls, copy_num); ls_walk(cp, printer); //clean up ls_free(ls, 1); ls = NULL; return 0; }
static void tcp_connect_cb(uv_connect_t *connect_req, int status) { ls_tcp_t *client = containerof(connect_req->handle, ls_tcp_t, handle); uv_tcp_t *handle = &client->handle; lua_State *l = ls_default_state(); lua_State *nl; uv_loop_t *loop = uv_default_loop(); ls_free(l, connect_req); if (ls_object_is_waited(&client->wait_object)) { int ref = client->wait_object.mthread_ref; client->wait_object.mthread_ref = LUA_NOREF; ls_getref(l, ref); nl = lua_tothread(l, -1); lua_pop(l, 1); if (nl) { ls_clear_waiting(nl); if (status) { uv_close((uv_handle_t*)handle, tcp_close_cb); ls_last_error_resume(nl, loop); } else { if (uv_read_start((uv_stream_t*)handle, tcp_alloc_cb, tcp_read_cb)) { uv_close((uv_handle_t*)handle, tcp_close_cb); ls_last_error_resume(nl, loop); } else { lua_pushboolean(nl, 1); new_tcp_connection_udata(nl, client); ls_resume(nl, 2); } } } ls_unref(l, ref); } }
static int tcp_create_client(lua_State *l) { const char *rip4 = "0.0.0.0"; int rport = 0; ls_tcp_t *client; uv_tcp_t *handle; uv_loop_t *loop = uv_default_loop(); uv_connect_t *connect_req; int connect_timeout; if (lua_gettop(l) >= 2) { rip4 = luaL_checkstring(l, 1); rport = luaL_checkint(l, 2); luaL_argcheck(l, strnlen(rip4, 256) > 0, 1, "invalid ipv4 address"); luaL_argcheck(l, rport > 0, 2, "port number should > 0"); } else if (lua_gettop(l) == 1) { rport = luaL_checkint(l, 1); luaL_argcheck(l, rport > 0, 1, "port number should > 0"); } else return ls_error_return(l, LS_ERRCODE_INVAL, "server ip and port should be specified."); client = new_tcp_handle(l); connect_req = (uv_connect_t*)ls_malloc(l, sizeof(uv_connect_t)); if (uv_tcp_connect(connect_req, &client->handle, uv_ip4_addr(rip4, rport), tcp_connect_cb)) { ls_free(l, connect_req); uv_close((uv_handle_t*)client, tcp_close_cb); return ls_last_error_return(l, loop); } lua_getglobal(l, "tcp"); lua_getfield(l, -1, "connect_timeout"); connect_timeout = lua_tointeger(l, -1); lua_pop(l, 2); ls_set_waiting(l, &client->wait_object, connect_timeout); return lua_yield(l, 0); }
static void tcp_write_cb(uv_write_t *req, int status) { ls_write_t *write_req = containerof(req, ls_write_t, req); uv_loop_t *loop = uv_default_loop(); lua_State *l, *nl; int i; l = ls_default_state(); for (i=0; i<write_req->refcnt; i++) { ls_unref(l, write_req->data_refs[i]); lua_pop(l, 1); write_req->data_refs[i] = LUA_NOREF; } write_req->refcnt = 0; if (ls_object_is_waited(&write_req->wait_object)) { int ref = write_req->wait_object.mthread_ref; write_req->wait_object.mthread_ref = LUA_NOREF; ls_getref(l, ref); nl = lua_tothread(l, -1); lua_pop(l, 1); if (nl) { ls_clear_waiting(nl); if (status) { ls_last_error_resume(nl, req->handle->loop); } else { ls_ok_resume(nl); } } ls_unref(l, ref); } ls_free(l, write_req); }
R_API void r_anal_xrefs_list(RAnal *anal, int rad) { switch (rad) { case 1: case '*': sdb_foreach (DB, (SdbForeachCallback)xrefs_list_cb_rad, anal); break; case 'j': { anal->cb_printf ("{"); bool is_first = true; SdbListIter *sdb_iter; SdbKv *kv; SdbList *sdb_list = sdb_foreach_match (DB, "^ref.", false); ls_foreach (sdb_list, sdb_iter, kv) { is_first = xrefs_list_cb_json (anal, is_first, kv->key, kv->value); } ls_free (sdb_list); anal->cb_printf ("}\n"); } break; default: sdb_foreach (DB, (SdbForeachCallback)xrefs_list_cb_plain, anal); break; }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore*)data; switch (input[0]) { // t [typename] - show given type in C syntax case 'k': if (input[1]==' ') { sdb_query (core->anal->sdb_types, input+2); } else sdb_query (core->anal->sdb_types, "*"); break; case 's': { char *q, *p, *o, *e; p = o = strdup (input+1); for (;;) { if (*p == '\0'){ eprintf ("Usage: ts <k>=<v> Set fields at curseek linked type\n"); break; } q = strchr (p, ' '); if (q) *q = 0; if (!*p) { p++; continue; } e = strchr (p, '='); if (e) { *e = 0; r_anal_type_set (core->anal, core->offset, p, r_num_math (core->num, e+1)); } else eprintf ("TODO: implement get\n"); if (!q) break; p = q+1; } free (o); } break; case 'b': { int i; char *p, *s = (strlen (input) > 1) ? strdup (input+2): NULL; const char *isenum; p = s ? strchr (s, ' ') : NULL; if (p) { *p++ = 0; // dupp in core.c (see getbitfield()) #if 1 isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { int empty = 1; ut32 num = (ut32)r_num_math (core->num, p); r_cons_printf ("0x%08"PFMT64x" : ", num); for (i=0; i< 32; i++) { if (num & (1<<i)) { const char *q = sdb_fmt (0, "%s.0x%x", s, (1<<i)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (!empty) r_cons_printf (" | "); if (res) r_cons_printf ("%s", res); else r_cons_printf ("0x%x", (1<<i)); empty = 0; } } } else { eprintf ("This is not an enum\n"); } #endif } else { eprintf ("Missing value\n"); } free (s); } break; case 'e': { if (!input[1]) { char *name = NULL; SdbKv *kv; SdbListIter *iter; SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strcmp (kv->value, "enum")) { if (!name || strcmp (kv->value, name)) { free (name); name = strdup (kv->key); r_cons_printf ("%s\n", name); } } } free (name); ls_free (l); break; } char *p, *s = strdup (input+2); const char *isenum; p = strchr (s, ' '); if (p) { *p++ = 0; isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (res) r_cons_printf ("%s\n", res); } else { eprintf ("This is not an enum\n"); } } else { //eprintf ("Missing value\n"); r_core_cmdf (core, "t~&%s,=0x", s); } free (s); } break; case ' ': { const char *isenum = sdb_const_get (core->anal->sdb_types, input+2, 0); if (isenum && !strcmp (isenum, "enum")) { eprintf ("IS ENUM! \n"); } else { char *fmt = r_anal_type_format (core->anal, input +1); if (fmt) { r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input+1); } } break; // t* - list all types in 'pf' syntax case '*': sdb_foreach (core->anal->sdb_types, typelist, core); break; case 0: sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (input[1] == ' ') { const char *filename = input + 2; char *homefile = NULL; if (*filename == '~') { if (filename[1] && filename[2]) { homefile = r_str_home (filename + 2); filename = homefile; } } if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, NULL, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { // r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { // r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } free (homefile); } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char * help_message[] = { "Usage:", "td[...]", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help(core, help_message); } else if (input[1] == '-') { const char *arg = strchr (input+1, ' '); if (arg) arg++; else arg = input+2; r_anal_type_del (core->anal, arg); } else if (input[1] == ' ') { char tmp[8192]; snprintf (tmp, sizeof (tmp)-1, "%s;", input+2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { //r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': if (input[1]=='?') { const char * help_message[] = { "Usage: tl", " [typename|addr] ([addr])@[addr|function]", "", NULL }; r_core_cmd_help(core, help_message); } else if (input[1]) { ut64 addr = r_num_math (core->num, input+2); char *ptr = strchr (input + 2, ' '); if (ptr) { addr = r_num_math (core->num, ptr + 1); *ptr = '\0'; } else addr = core->offset; r_anal_type_link (core->anal, input+2, addr); } else { r_core_cmd0 (core, "t~^link"); } break; case '-': if (input[1] == '?') { const char * help_message[] = { "Usage: t-", " <type>", "Delete type by its name", NULL }; r_core_cmd_help(core, help_message); } else if (input[1]=='*') { eprintf ("TODO\n"); } else { const char *name = input + 1; if (*name==' ') name++; if (*name) { r_anal_type_del (core->anal, name); } else eprintf ("Invalid use of t- . See t-? for help.\n"); } break; // tv - get/set type value linked to a given address case 'f': { ut64 addr; char *fmt, key[128]; const char *type; if (input[1]) { addr = r_num_math (core->num, input+1); } else addr = core->offset; snprintf (key, sizeof (key), "link.%08"PFMT64x, addr); type = sdb_const_get (core->anal->sdb_types, key, 0); if (type) { fmt = r_anal_type_format (core->anal, type); r_cons_printf ("struct %s {\n", type); if (fmt) { r_core_cmdf (core, "pf %s @ 0x%08"PFMT64x"\n", fmt, addr); free (fmt); }// else eprintf ("Cannot find '%s' type\n", input+1); r_cons_printf ("}\n"); } //else eprintf ("Cannot find type at 0x%llx\n", addr); } break; case '?': show_help (core); break; }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore *)data; switch (input[0]) { // t [typename] - show given type in C syntax case 'u': // "tu" switch (input[1]) { case '?': { const char *help_message[] = { "USAGE tu[...]", "", "", "tu", "", "List all loaded unions", "tu?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); } break; case 0: sdb_foreach (core->anal->sdb_types, stdprintifunion, core); break; } break; case 'k': // "tk" if (input[1] == ' ') { sdb_query (core->anal->sdb_types, input + 2); } else sdb_query (core->anal->sdb_types, "*"); fflush (stdout); break; case 's': // "ts" switch (input[1]) { case '?': { const char *help_message[] = { "USAGE ts[...]", "", "", "ts", "", "List all loaded structs", "ts?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); } break; case 0: sdb_foreach (core->anal->sdb_types, stdprintifstruct, core); break; } break; case 'b': { char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL; const char *isenum; p = s? strchr (s, ' '): NULL; if (p) { *p++ = 0; // dupp in core.c (see getbitfield()) isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { *--p = '.'; const char *res = sdb_const_get (core->anal->sdb_types, s, 0); if (res) r_cons_println (res); else eprintf ("Invalid enum member\n"); } else { eprintf ("This is not an enum\n"); } } else { eprintf ("Missing value\n"); } free (s); } break; case 'e': { if (!input[1]) { char *name = NULL; SdbKv *kv; SdbListIter *iter; SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strcmp (kv->value, "enum")) { if (!name || strcmp (kv->value, name)) { free (name); name = strdup (kv->key); r_cons_println (name); } } } free (name); ls_free (l); break; } if (input[1] == '?') { const char *help_message[] = { "USAGE te[...]", "", "", "te", "", "List all loaded enums", "te", " <enum> <value>", "Show name for given enum number", "te?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); break; } char *p, *s = strdup (input + 2); const char *isenum; p = strchr (s, ' '); if (p) { *p++ = 0; isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strncmp (isenum, "enum", 4)) { const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (res) r_cons_println (res); } else { eprintf ("This is not an enum\n"); } } else { //eprintf ("Missing value\n"); r_core_cmdf (core, "t~&%s,=0x", s); } free (s); } break; case ' ': { const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0); if (isenum && !strcmp (isenum, "enum")) { eprintf ("IS ENUM! \n"); } else { char *fmt = r_anal_type_format (core->anal, input + 1); if (fmt) { r_str_chop (fmt); r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input + 1); } } break; // t* - list all types in 'pf' syntax case '*': sdb_foreach (core->anal->sdb_types, typelist, core); break; case 0: sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (!r_sandbox_enable (0)) { if (input[1] == ' ') { const char *filename = input + 2; char *homefile = NULL; if (*filename == '~') { if (filename[1] && filename[2]) { homefile = r_str_home (filename + 2); filename = homefile; } } if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, NULL, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { // r_cons_strcat (out); save_parsed_type (core, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { //r_cons_strcat (out); save_parsed_type (core, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } free (homefile); } else if (input[1] == 's') { const char *dbpath = input + 3; if (r_file_exists (dbpath)) { Sdb *db_tmp = sdb_new (0, dbpath, 0); sdb_merge (core->anal->sdb_types, db_tmp); sdb_close (db_tmp); sdb_free (db_tmp); } } } else { eprintf ("Sandbox: system call disabled\n"); } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char *help_message[] = { "Usage:", "\"td [...]\"", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help (core, help_message); r_cons_printf ("Note: The td command should be put between double quotes\n" "Example: \" td struct foo {int bar;int cow};\"" "\nt"); } else if (input[1] == ' ') { char tmp[8192]; snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { //r_cons_strcat (out); save_parsed_type (core, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': switch (input[1]) { case '?': { const char *help_message[] = { "Usage:", "", "", "tl", "", "list all links in readable format", "tl", "[typename]", "link a type to current adress.", "tl", "[typename] = [address]", "link type to given address.", "tls", "[address]", "show link at given address", "tl-*", "", "delete all links.", "tl-", "[address]", "delete link at given address.", "tl*", "", "list all links in radare2 command format", "tl?", "", "print this help.", NULL }; r_core_cmd_help (core, help_message); } break; case ' ': { char *type = strdup (input + 2); char *ptr = strchr (type, '='); ut64 addr; if (ptr) { *ptr++ = 0; r_str_chop (ptr); if (ptr && *ptr) { addr = r_num_math (core->num, ptr); } else { eprintf ("address is unvalid\n"); free (type); break; } } else { addr = core->offset; } r_str_chop (type); char *tmp = sdb_get (core->anal->sdb_types, type, 0); if (tmp && *tmp) { r_anal_type_link (core->anal, type, addr); free (tmp); } else { eprintf ("unknown type %s\n", type); } free (type); } break; case 's': { int ptr; char *addr = strdup (input + 2); SdbKv *kv; SdbListIter *sdb_iter; SdbList *sdb_list = sdb_foreach_list (core->anal->sdb_types); r_str_chop (addr); ptr = r_num_math (NULL, addr); //r_core_cmdf (core, "tl~0x%08"PFMT64x" = ", addr); ls_foreach (sdb_list, sdb_iter, kv) { char *linkptr; if (strncmp (kv->key, "link.", strlen ("link."))) { continue; } linkptr = sdb_fmt (-1,"0x%s", kv->key + strlen ("link.")); if (ptr == r_num_math (NULL, linkptr)) { linklist_readable (core, kv->key, kv->value); } } free (addr); ls_free (sdb_list); } break; case '-': switch (input[2]) { case '*': sdb_foreach (core->anal->sdb_types, sdbdeletelink, core); break; case ' ': { const char *ptr = input + 3; ut64 addr = r_num_math (core->num, ptr); r_anal_type_unlink (core->anal, addr); } break; } break; case '*': sdb_foreach (core->anal->sdb_types, linklist, core); break; case '\0': sdb_foreach (core->anal->sdb_types, linklist_readable, core); break; }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore *)data; switch (input[0]) { // t [typename] - show given type in C syntax case 'k': if (input[1] == ' ') { sdb_query (core->anal->sdb_types, input + 2); } else sdb_query (core->anal->sdb_types, "*"); break; case 's': { char *q, *p, *o, *e; p = o = strdup (input + 1); for (;;) { if (*p == '\0') { eprintf ("Usage: ts <k>=<v> Set fields at curseek linked type\n"); break; } q = strchr (p, ' '); if (q) *q = 0; if (!*p) { p++; continue; } e = strchr (p, '='); if (e) { *e = 0; r_anal_type_set (core->anal, core->offset, p, r_num_math (core->num, e + 1)); } else eprintf ("TODO: implement get\n"); if (!q) break; p = q + 1; } free (o); } break; case 'b': { char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL; const char *isenum; p = s? strchr (s, ' '): NULL; if (p) { *p++ = 0; // dupp in core.c (see getbitfield()) isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { *--p = '.'; const char *res = sdb_const_get (core->anal->sdb_types, s, 0); if (res) r_cons_printf ("%s\n", res); else eprintf ("Invalid enum member\n"); } else { eprintf ("This is not an enum\n"); } } else { eprintf ("Missing value\n"); } free (s); } break; case 'e': { if (!input[1]) { char *name = NULL; SdbKv *kv; SdbListIter *iter; SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strcmp (kv->value, "enum")) { if (!name || strcmp (kv->value, name)) { free (name); name = strdup (kv->key); r_cons_printf ("%s\n", name); } } } free (name); ls_free (l); break; } char *p, *s = strdup (input + 2); const char *isenum; p = strchr (s, ' '); if (p) { *p++ = 0; isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (res) r_cons_printf ("%s\n", res); } else { eprintf ("This is not an enum\n"); } } else { //eprintf ("Missing value\n"); r_core_cmdf (core, "t~&%s,=0x", s); } free (s); } break; case ' ': { const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0); if (isenum && !strcmp (isenum, "enum")) { eprintf ("IS ENUM! \n"); } else { char *fmt = r_anal_type_format (core->anal, input + 1); if (fmt) { r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input + 1); } } break; // t* - list all types in 'pf' syntax case '*': sdb_foreach (core->anal->sdb_types, typelist, core); break; case 0: sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (!r_sandbox_enable (0)) { if (input[1] == ' ') { const char *filename = input + 2; char *homefile = NULL; if (*filename == '~') { if (filename[1] && filename[2]) { homefile = r_str_home (filename + 2); filename = homefile; } } if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, NULL, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { // r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { //r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } free (homefile); } } else { eprintf ("Sandbox: system call disabled\n"); } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char *help_message[] = { "Usage:", "\"td [...]\"", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help (core, help_message); r_cons_printf ("Note: The td command should be put between double quotes\n" "Example: \" td struct foo {int bar;int cow};\"" "\nt"); } else if (input[1] == ' ') { char tmp[8192]; snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { //r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': if (input[1] == '?') { const char *help_message[] = { "Usage: tl", " [typename|addr] ([addr])@[addr|function]", "", NULL }; r_core_cmd_help (core, help_message); } else if (input[1]) { ut64 addr = r_num_math (core->num, input + 2); char *ptr = strchr (input + 2, ' '); if (ptr) { addr = r_num_math (core->num, ptr + 1); *ptr = '\0'; } else addr = core->offset; r_anal_type_link (core->anal, input + 2, addr); } else { r_core_cmd0 (core, "t~^link"); } break; case '-': if (input[1] == '?') { const char *help_message[] = { "Usage: t-", " <type>", "Delete type by its name", NULL }; r_core_cmd_help (core, help_message); } else if (input[1] == '*') { sdb_foreach (core->anal->sdb_types, sdbdelete, core); } else { const char *name = input + 1; while (IS_WHITESPACE (*name)) name++; if (*name) { SdbKv *kv; SdbListIter *iter; int tmp_len = strlen (name); char *tmp = malloc (tmp_len + 2); r_anal_type_del (core->anal, name); if (tmp) { snprintf (tmp, tmp_len + 1, "%s.", name); SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strncmp (kv->key, tmp, tmp_len - 1)) r_anal_type_del (core->anal, kv->key); } free (tmp); } } else eprintf ("Invalid use of t- . See t-? for help.\n"); }