static void fields(node_t * sym) { int follow[] = {INT, CONST, '}', IF, 0}; node_t *sty = SYM_TYPE(sym); if (!first_decl(token)) { error("expect type name or qualifiers"); return; } struct vector *v = vec_new(); do { node_t *basety = specifiers(NULL, NULL); for (;;) { node_t *field = new_field(); if (token->id == ':') { bitfield(field); FIELD_TYPE(field) = basety; } else { node_t *ty = NULL; struct token *id = NULL; declarator(&ty, &id, NULL); attach_type(&ty, basety); if (token->id == ':') bitfield(field); FIELD_TYPE(field) = ty; if (id) { for (int i = 0; i < vec_len(v); i++) { node_t *f = vec_at(v, i); if (FIELD_NAME(f) && !strcmp(FIELD_NAME(f), id->name)) { errorf(id->src, "redefinition of '%s'", id->name); break; } } FIELD_NAME(field) = id->name; AST_SRC(field) = id->src; } } vec_push(v, field); if (token->id != ',') break; expect(','); ensure_field(field, vec_len(v), false); } match(';', follow); ensure_field(vec_tail(v), vec_len(v), isstruct(sty) && !first_decl(token)); } while (first_decl(token)); TYPE_FIELDS(sty) = (node_t **) vtoa(v); set_typesize(sty); }
/* Return a GDB type representing `struct gdb_gnu_v3_abi_vtable', described above, laid out appropriately for ARCH. We use this function as the gdbarch per-architecture data initialization function. */ static void * build_gdb_vtable_type (struct gdbarch *arch) { struct type *t; struct field *field_list, *field; int offset; struct type *void_ptr_type = builtin_type (arch)->builtin_data_ptr; struct type *ptr_to_void_fn_type = builtin_type (arch)->builtin_func_ptr; /* ARCH can't give us the true ptrdiff_t type, so we guess. */ struct type *ptrdiff_type = arch_integer_type (arch, gdbarch_ptr_bit (arch), 0, "ptrdiff_t"); /* We assume no padding is necessary, since GDB doesn't know anything about alignment at the moment. If this assumption bites us, we should add a gdbarch method which, given a type, returns the alignment that type requires, and then use that here. */ /* Build the field list. */ field_list = xmalloc (sizeof (struct field [4])); memset (field_list, 0, sizeof (struct field [4])); field = &field_list[0]; offset = 0; /* ptrdiff_t vcall_and_vbase_offsets[0]; */ FIELD_NAME (*field) = "vcall_and_vbase_offsets"; FIELD_TYPE (*field) = lookup_array_range_type (ptrdiff_type, 0, -1); SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* ptrdiff_t offset_to_top; */ FIELD_NAME (*field) = "offset_to_top"; FIELD_TYPE (*field) = ptrdiff_type; SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* void *type_info; */ FIELD_NAME (*field) = "type_info"; FIELD_TYPE (*field) = void_ptr_type; SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* void (*virtual_functions[0]) (); */ FIELD_NAME (*field) = "virtual_functions"; FIELD_TYPE (*field) = lookup_array_range_type (ptr_to_void_fn_type, 0, -1); SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* We assumed in the allocation above that there were four fields. */ gdb_assert (field == (field_list + 4)); t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL); TYPE_NFIELDS (t) = field - field_list; TYPE_FIELDS (t) = field_list; TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable"; INIT_CPLUS_SPECIFIC (t); return t; }
/** * Handle adding a class type. * * @param df The debug file to add information to. * @param cl The class to add to the debugging file. */ static void dfHandleClass(struct debug_file *df, struct Hjava_lang_Class *cl) { int lpc; assert(df != NULL); assert(cl != NULL); /* Allocate a type id if necessary. */ if( cl->stab_id == 0 ) { cl->stab_id = df->df_current_type_id + 1; df->df_current_type_id += 2; } /* Add the structure type, */ fmanglef(df->df_file, ".stabs \"%t", "/", ".", cl->name->data); if( cl->loader != NULL ) { fmanglef(df->df_file, "_%p", cl->loader); } fprintf(df->df_file, ":T%d=s%d", cl->stab_id - 1, CLASS_FSIZE(cl)); /* ... fill in the base fields/class, */ if( cl->superclass == NULL ) { fprintf(df->df_file, "vtable:%d,%d,%d;", STYPE_DISPATCH_TABLE, 0, sizeof(dispatchTable *) * 8); fprintf(df->df_file, "_$lock:%d,%d,%d;", STYPE_ILOCK, sizeof(dispatchTable *) * 8, sizeof(iLock *) * 8); } else { fprintf(df->df_file, "!1,020,%d;", cl->superclass->stab_id - 1); } /* ... fill in the instance fields, */ for( lpc = 0; lpc < CLASS_NIFIELDS(cl); lpc++ ) { fields *fld = CLASS_IFIELDS(cl); struct Hjava_lang_Class *ftype; if( (ftype = FIELD_TYPE(&fld[lpc])) != NULL ) { fprintf(df->df_file, "%s:/%d%d,%d,%d;", fld[lpc].name->data, acc2prot(fld[lpc].accflags), ftype->stab_id, FIELD_BOFFSET(&fld[lpc]) * 8, FIELD_SIZE(&fld[lpc]) * 8); } } /* ... the static fields, and */ for( lpc = 0; lpc < CLASS_NSFIELDS(cl); lpc++ ) { fields *fld = CLASS_SFIELDS(cl); struct Hjava_lang_Class *ftype; if( (ftype = FIELD_TYPE(&fld[lpc])) != NULL ) { fprintf(df->df_file, "%s:/%d%d:", fld[lpc].name->data, acc2prot(fld[lpc].accflags), ftype->stab_id); fmanglef(df->df_file, "_ZN%q%d%sE;", df_quals, cl->name->data, cl->loader, strlen(fld[lpc].name->data), fld[lpc].name->data); } } /* ... the synthetic 'class' static member. */ fmanglef(df->df_file, "class:xsHjava_lang_Class:" ":_ZN%q%d%sE;", df_quals, cl->name->data, cl->loader, strlen("class"), "class"); fprintf(df->df_file, ";\",%d,0,0,0\n", N_LSYM); /* Add a typedef and */ fmanglef(df->df_file, ".stabs \"%t", "/", ".", cl->name->data); if( cl->loader != NULL ) { fprintf(df->df_file, "_%p", cl->loader); } fprintf(df->df_file, ":t%d\",%d,0,0,0\n", cl->stab_id - 1, N_LSYM); /* ... an anonymous pointer type. */ fprintf(df->df_file, ".stabs \" :%d=*%d\",%d,0,0,0\n", cl->stab_id, cl->stab_id - 1, N_LSYM); /* Add symbols and their values. */ for( lpc = 0; lpc < CLASS_NSFIELDS(cl); lpc++ ) { fields *fld = CLASS_SFIELDS(cl); struct Hjava_lang_Class *ftype; if( (ftype = FIELD_TYPE(&fld[lpc])) != NULL ) { fmanglef(df->df_file, ".globl _ZN%q%d%sE\n", df_quals, cl->name->data, cl->loader, strlen(fld[lpc].name->data), fld[lpc].name->data); fmanglef(df->df_file, "_ZN%q%d%sE = %p\n", df_quals, cl->name->data, cl->loader, strlen(fld[lpc].name->data), fld[lpc].name->data, FIELD_ADDRESS(&fld[lpc])); fmanglef(df->df_file, ".stabs \"_ZN%q%d%sE:", df_quals, cl->name->data, cl->loader, strlen(fld[lpc].name->data), fld[lpc].name->data); fprintf(df->df_file, "G%d\",%d,0,0,0\n", ftype->stab_id, N_GSYM); } } fmanglef(df->df_file, ".globl _ZN%q%d%sE\n", df_quals, cl->name->data, cl->loader, strlen("class"), "class"); fmanglef(df->df_file, "_ZN%q%d%sE = %p\n", df_quals, cl->name->data, cl->loader, strlen("class"), "class", cl); fmanglef(df->df_file, ".stabs \"_ZN%q%d%sE:", df_quals, cl->name->data, cl->loader, strlen("class"), "class"); fprintf(df->df_file, "GxsHjava_lang_Class:\",%d,0,0,0\n", N_GSYM); }
static void get_register (int regnum, map_arg arg) { int realnum; CORE_ADDR addr; enum lval_type lval; struct type *reg_vtype; gdb_byte buffer[MAX_REGISTER_SIZE]; int optim, format; struct cleanup *old_chain = NULL; struct ui_file *stb; long dummy; char *res; format = regformat[regnum]; if (format == 0) format = 'x'; reg_vtype = regtype[regnum]; if (reg_vtype == NULL) reg_vtype = register_type (get_current_arch (), regnum); if (!target_has_registers) { if (result_ptr->flags & GDBTK_MAKES_LIST) Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj ("", -1)); else Tcl_SetStringObj (result_ptr->obj_ptr, "", -1); return; } frame_register (get_selected_frame (NULL), regnum, &optim, &lval, &addr, &realnum, buffer); if (optim) { Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj ("Optimized out", -1)); return; } stb = mem_fileopen (); old_chain = make_cleanup_ui_file_delete (stb); if (format == 'r') { /* shouldn't happen. raw format is deprecated */ int j; char *ptr, buf[1024]; strcpy (buf, "0x"); ptr = buf + 2; for (j = 0; j < register_size (get_current_arch (), regnum); j++) { int idx = ((gdbarch_byte_order (get_current_arch ()) == BFD_ENDIAN_BIG) ? j : register_size (get_current_arch (), regnum) - 1 - j); sprintf (ptr, "%02x", (unsigned char) buffer[idx]); ptr += 2; } fputs_unfiltered (buf, stb); } else { struct value_print_options opts; get_formatted_print_options (&opts, format); opts.deref_ref = 1; opts.pretty = Val_pretty_default; if ((TYPE_CODE (reg_vtype) == TYPE_CODE_UNION) && (strcmp (FIELD_NAME (TYPE_FIELD (reg_vtype, 0)), gdbarch_register_name (get_current_arch (), regnum)) == 0)) { val_print (FIELD_TYPE (TYPE_FIELD (reg_vtype, 0)), buffer, 0, 0, stb, 0, NULL, &opts, current_language); } else val_print (reg_vtype, buffer, 0, 0, stb, 0, NULL, &opts, current_language); } res = ui_file_xstrdup (stb, &dummy); if (result_ptr->flags & GDBTK_MAKES_LIST) Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj (res, -1)); else Tcl_SetStringObj (result_ptr->obj_ptr, res, -1); xfree (res); do_cleanups (old_chain); }