R_API int r_space_push(RSpaces *f, const char *name) { int ret = R_FALSE; if (name && *name) { if (f->space_idx != -1 && f->spaces[f->space_idx]) { r_list_push (f->spacestack, f->spaces[f->space_idx]); } else { r_list_push (f->spacestack, "*"); } r_space_set (f, name); ret = R_TRUE; } return ret; }
static RList* _extract_regs(char *regstr, RList *flags, char *pc_alias) { char *regstr_end, *regname, *regtype, *tmp1; ut32 flagnum, regname_len, regsize, regnum; RList *regs; RListIter *iter; gdbr_xml_reg_t *tmpreg; gdbr_xml_flags_t *tmpflag; if (!(regs = r_list_new ())) { return NULL; } while ((regstr = strstr (regstr, "<reg"))) { if (!(regstr_end = strchr (regstr, '/'))) { goto exit_err; } *regstr_end = '\0'; // name if (!(regname = strstr (regstr, "name="))) { goto exit_err; } regname += 6; if (!(tmp1 = strchr (regname, '"'))) { goto exit_err; } regname_len = tmp1 - regname; // size if (!(tmp1 = strstr (regstr, "bitsize="))) { goto exit_err; } tmp1 += 9; if (!isdigit (*tmp1)) { goto exit_err; } regsize = strtoul (tmp1, NULL, 10); // regnum regnum = UINT32_MAX; if ((tmp1 = strstr (regstr, "regnum="))) { tmp1 += 8; if (!isdigit (*tmp1)) { goto exit_err; } regnum = strtoul (tmp1, NULL, 10); } // type regtype = "gpr"; flagnum = r_list_length (flags); if ((tmp1 = strstr (regstr, "group="))) { tmp1 += 7; if (r_str_startswith (tmp1, "float")) { regtype = "fpu"; } // We need type information in r2 register profiles } else if ((tmp1 = strstr (regstr, "type="))) { tmp1 += 6; if (r_str_startswith (tmp1, "vec") || r_str_startswith (tmp1, "i387_ext") || r_str_startswith (tmp1, "ieee_single") || r_str_startswith (tmp1, "ieee_double")) { regtype = "fpu"; } else if (r_str_startswith (tmp1, "code_ptr")) { strcpy (pc_alias, "=PC "); strncpy (pc_alias + 4, regname, regname_len); strcpy (pc_alias + 4 + regname_len, "\n"); } else { // Check all flags. If reg is a flag, write flag data flagnum = 0; r_list_foreach (flags, iter, tmpflag) { if (r_str_startswith (tmp1, tmpflag->type)) { // Max 64-bit :/ if (tmpflag->num_bits <= 64) { break; } } flagnum++; } } // We need type information in r2 register profiles } if (!(tmpreg = calloc (1, sizeof (gdbr_xml_reg_t)))) { goto exit_err; } regname[regname_len] = '\0'; if (regname_len > sizeof (tmpreg->name) - 1) { eprintf ("Register name too long: %s\n", regname); } strncpy (tmpreg->name, regname, sizeof (tmpreg->name) - 1); tmpreg->name[sizeof (tmpreg->name) - 1] = '\0'; regname[regname_len] = '"'; strncpy (tmpreg->type, regtype, sizeof (tmpreg->type) - 1); tmpreg->type[sizeof (tmpreg->type) - 1] = '\0'; tmpreg->size = regsize / 8; tmpreg->flagnum = flagnum; if (regnum == UINT32_MAX) { r_list_push (regs, tmpreg); } else if (regnum >= r_list_length (regs)) { int i; for (i = regnum - r_list_length (regs); i > 0; i--) { // temporary placeholder reg. we trust the xml is correct and this will be replaced. r_list_push (regs, tmpreg); r_list_tail (regs)->data = NULL; } r_list_push (regs, tmpreg); } else { // this is where we replace those placeholder regs r_list_set_n (regs, regnum, tmpreg); } *regstr_end = '/'; regstr = regstr_end + 2; }
static RList* _extract_flags(char *flagstr) { char *tmp1, *tmp2, *flagsend, *field_start, *field_end; ut64 num_fields, type_sz, name_sz; gdbr_xml_flags_t *tmpflag = NULL; RList *flags; if (!(flags = r_list_new ())) { return NULL; } flags->free = free; while ((flagstr = strstr (flagstr, "<flags"))) { if (!(flagsend = strstr (flagstr, "</flags>"))) { goto exit_err; } *flagsend = '\0'; if (!(tmpflag = calloc (1, sizeof (gdbr_xml_flags_t)))) { goto exit_err; } // Get id if (!(tmp1 = strstr (flagstr, "id="))) { goto exit_err; } tmp1 += 4; if (!(tmp2 = strchr (tmp1, '"'))) { goto exit_err; } *tmp2 = '\0'; type_sz = sizeof (tmpflag->type); strncpy (tmpflag->type, tmp1, type_sz - 1); tmpflag->type[type_sz - 1] = '\0'; *tmp2 = '"'; // Get size of flags register if (!(tmp1 = strstr (flagstr, "size="))) { goto exit_err; } tmp1 += 6; if (!(tmpflag->num_bits = (ut32) strtoul (tmp1, NULL, 10))) { goto exit_err; } tmpflag->num_bits *= 8; // Get fields num_fields = 0; field_start = flagstr; while ((field_start = strstr (field_start, "<field"))) { // Max 64 fields if (num_fields >= 64) { break; } if (!(field_end = strstr (field_start, "/>"))) { goto exit_err; } *field_end = '\0'; // Get name if (!(tmp1 = strstr (field_start, "name="))) { goto exit_err; } tmp1 += 6; if (!(tmp2 = strchr (tmp1, '"'))) { goto exit_err; } // If name length is 0, it is a 1 field. Don't include if (tmp2 - tmp1 <= 1) { *field_end = '/'; field_start = field_end + 1; continue; } *tmp2 = '\0'; name_sz = sizeof (tmpflag->fields[num_fields].name); strncpy (tmpflag->fields[num_fields].name, tmp1, name_sz - 1); tmpflag->fields[num_fields].name[name_sz - 1] = '\0'; *tmp2 = '"'; // Get offset if (!(tmp1 = strstr (field_start, "start="))) { goto exit_err; } tmp1 += 7; if (!isdigit (*tmp1)) { goto exit_err; } tmpflag->fields[num_fields].bit_num = (ut32) strtoul (tmp1, NULL, 10); // Get end if (!(tmp1 = strstr (field_start, "end="))) { goto exit_err; } tmp1 += 5; if (!isdigit (*tmp1)) { goto exit_err; } tmpflag->fields[num_fields].sz = (ut32) strtoul (tmp1, NULL, 10) + 1; tmpflag->fields[num_fields].sz -= tmpflag->fields[num_fields].bit_num; num_fields++; *field_end = '/'; field_start = field_end + 1; } tmpflag->num_fields = num_fields; r_list_push (flags, tmpflag); *flagsend = '<'; flagstr = flagsend + 1; } return flags; exit_err: if (flags) { r_list_free (flags); } free (tmpflag); return NULL; }