From: Weimin Pan Date: Wed, 7 Apr 2021 18:07:48 +0000 (-0400) Subject: CTF: handle forward reference type X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=dc2b480f3df3bc7673c892e0cb8459a4ea72d447;p=binutils-gdb.git CTF: handle forward reference type Added function fetch_tid_type which calls get_tid_type and will set up the type, associated with a tid, if it is not read in yet. Also implement function read_forward_type which handles the CTF_K_FORWARD kind. Expanded gdb.base/ctf-ptype.exp to add cases with forward references. gdb/ChangeLog: * ctfread.c (fetch_tid_type): New function, use throughout file. (read_forward_type): New function. (read_type_record): Call read_forward_type. gdb/testsuite/ChangeLog: * gdb.base/ctf-ptype.c: Add struct link containing a forward reference type. * gdb.base/ctf-ptype.exp: Add "ptype struct link". --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 42d4bf5e0d5..e817ba66b04 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2021-04-07 Weimin Pan + + * ctfread.c (fetch_tid_type): New function, use throughout file. + (read_forward_type): New function. + (read_type_record): Call read_forward_type. + 2021-04-07 Andrew Burgess * f-exp.h (class fortran_structop_operation): New class. diff --git a/gdb/ctfread.c b/gdb/ctfread.c index fae244d4481..e2b65b622de 100644 --- a/gdb/ctfread.c +++ b/gdb/ctfread.c @@ -190,6 +190,8 @@ static void process_structure_type (struct ctf_context *cp, ctf_id_t tid); static void process_struct_members (struct ctf_context *cp, ctf_id_t tid, struct type *type); +static struct type *read_forward_type (struct ctf_context *cp, ctf_id_t tid); + static struct symbol *new_symbol (struct ctf_context *cp, struct type *type, ctf_id_t tid); @@ -273,6 +275,25 @@ get_tid_type (struct objfile *of, ctf_id_t tid) return nullptr; } +/* Fetch the type for TID in CCP OF's tid_and_type hash, add the type to + * context CCP if hash is empty or TID does not have a saved type. */ + +static struct type * +fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid) +{ + struct objfile *of = ccp->of; + struct type *typ; + + typ = get_tid_type (of, tid); + if (typ == nullptr) + { + ctf_add_type_cb (tid, ccp); + typ = get_tid_type (of, tid); + } + + return typ; +} + /* Return the size of storage in bits for INTEGER, FLOAT, or ENUM. */ static int @@ -372,7 +393,7 @@ ctf_add_member_cb (const char *name, FIELD_NAME (*fp) = name; kind = ctf_type_kind (ccp->fp, tid); - t = get_tid_type (ccp->of, tid); + t = fetch_tid_type (ccp, tid); if (t == nullptr) { t = read_type_record (ccp, tid); @@ -667,7 +688,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid) type->set_code (TYPE_CODE_FUNC); ctf_func_type_info (fp, tid, &cfi); - rettype = get_tid_type (of, cfi.ctc_return); + rettype = fetch_tid_type (ccp, cfi.ctc_return); TYPE_TARGET_TYPE (type) = rettype; set_type_align (type, ctf_type_align (fp, tid)); @@ -794,11 +815,11 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid) return nullptr; } - element_type = get_tid_type (objfile, ar.ctr_contents); + element_type = fetch_tid_type (ccp, ar.ctr_contents); if (element_type == nullptr) return nullptr; - idx_type = get_tid_type (objfile, ar.ctr_index); + idx_type = fetch_tid_type (ccp, ar.ctr_index); if (idx_type == nullptr) idx_type = objfile_type (objfile)->builtin_int; @@ -826,7 +847,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid) struct objfile *objfile = ccp->of; struct type *base_type, *cv_type; - base_type = get_tid_type (objfile, btid); + base_type = fetch_tid_type (ccp, btid); if (base_type == nullptr) { base_type = read_type_record (ccp, btid); @@ -850,7 +871,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid) ctf_dict_t *fp = ccp->fp; struct type *base_type, *cv_type; - base_type = get_tid_type (objfile, btid); + base_type = fetch_tid_type (ccp, btid); if (base_type == nullptr) { base_type = read_type_record (ccp, btid); @@ -876,7 +897,7 @@ read_restrict_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid) struct objfile *objfile = ccp->of; struct type *base_type, *cv_type; - base_type = get_tid_type (objfile, btid); + base_type = fetch_tid_type (ccp, btid); if (base_type == nullptr) { base_type = read_type_record (ccp, btid); @@ -903,7 +924,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid, char *aname = obstack_strdup (&objfile->objfile_obstack, name); this_type = init_type (objfile, TYPE_CODE_TYPEDEF, 0, aname); set_tid_type (objfile, tid, this_type); - target_type = get_tid_type (objfile, btid); + target_type = fetch_tid_type (ccp, btid); if (target_type != this_type) TYPE_TARGET_TYPE (this_type) = target_type; else @@ -922,7 +943,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid) struct objfile *of = ccp->of; struct type *target_type, *type; - target_type = get_tid_type (of, btid); + target_type = fetch_tid_type (ccp, btid); if (target_type == nullptr) { target_type = read_type_record (ccp, btid); @@ -939,6 +960,34 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid) return set_tid_type (of, tid, type); } +/* Read information from a TID of CTF_K_FORWARD. */ + +static struct type * +read_forward_type (struct ctf_context *ccp, ctf_id_t tid) +{ + struct objfile *of = ccp->of; + ctf_dict_t *fp = ccp->fp; + struct type *type; + uint32_t kind; + + type = alloc_type (of); + + gdb::unique_xmalloc_ptr name (ctf_type_aname_raw (fp, tid)); + if (name != NULL && strlen (name.get()) != 0) + type->set_name (obstack_strdup (&of->objfile_obstack, name.get ())); + + kind = ctf_type_kind_forwarded (fp, tid); + if (kind == CTF_K_UNION) + type->set_code (TYPE_CODE_UNION); + else + type->set_code (TYPE_CODE_STRUCT); + + TYPE_LENGTH (type) = 0; + type->set_is_stub (true); + + return set_tid_type (of, tid, type); +} + /* Read information associated with type TID. */ static struct type * @@ -992,6 +1041,9 @@ read_type_record (struct ctf_context *ccp, ctf_id_t tid) case CTF_K_ARRAY: type = read_array_type (ccp, tid); break; + case CTF_K_FORWARD: + type = read_forward_type (ccp, tid); + break; case CTF_K_UNKNOWN: break; default: @@ -1138,7 +1190,7 @@ add_stt_obj (struct ctf_context *ccp, unsigned long idx) if ((tid = ctf_lookup_by_symbol (ccp->fp, idx)) == CTF_ERR) return nullptr; - type = get_tid_type (ccp->of, tid); + type = fetch_tid_type (ccp, tid); if (type == nullptr) return nullptr; @@ -1172,7 +1224,7 @@ add_stt_func (struct ctf_context *ccp, unsigned long idx) return nullptr; tid = ctf_lookup_by_symbol (ccp->fp, idx); - ftype = get_tid_type (ccp->of, tid); + ftype = fetch_tid_type (ccp, tid); if ((finfo.ctc_flags & CTF_FUNC_VARARG) != 0) ftype->set_has_varargs (true); ftype->set_num_fields (argc); @@ -1186,7 +1238,7 @@ add_stt_func (struct ctf_context *ccp, unsigned long idx) to find the argument type. */ for (int iparam = 0; iparam < argc; iparam++) { - atyp = get_tid_type (ccp->of, argv[iparam]); + atyp = fetch_tid_type (ccp, argv[iparam]); if (atyp) ftype->field (iparam).set_type (atyp); else @@ -1194,7 +1246,7 @@ add_stt_func (struct ctf_context *ccp, unsigned long idx) } sym = new_symbol (ccp, ftype, tid); - rettyp = get_tid_type (ccp->of, finfo.ctc_return); + rettyp = fetch_tid_type (ccp, finfo.ctc_return); if (rettyp != nullptr) SYMBOL_TYPE (sym) = rettyp; else diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 19803150677..53333f93379 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2021-04-07 Weimin Pan + + * gdb.base/ctf-ptype.c: Add struct link containing a forward + reference type. + * gdb.base/ctf-ptype.exp: Add "ptype struct link". + 2021-04-07 Andrew Burgess * gdb.fortran/dynamic-ptype-whatis.exp: New file. diff --git a/gdb/testsuite/gdb.base/ctf-ptype.c b/gdb/testsuite/gdb.base/ctf-ptype.c index cbc781560ba..51c7c6868ee 100644 --- a/gdb/testsuite/gdb.base/ctf-ptype.c +++ b/gdb/testsuite/gdb.base/ctf-ptype.c @@ -124,6 +124,18 @@ typedef struct { a symbol. */ t_struct3 v_struct3; +/**** Some misc more complicated things *******/ + +struct link { + struct link *next; +#ifdef __STDC__ + struct link *(*linkfunc) (struct link *self, int flags); +#else + struct link *(*linkfunc) (); +#endif + struct t_struct stuff[3]; +} *s_link; + /**** unions *******/ union t_union { diff --git a/gdb/testsuite/gdb.base/ctf-ptype.exp b/gdb/testsuite/gdb.base/ctf-ptype.exp index 056f7129f42..7dd6d95ce77 100644 --- a/gdb/testsuite/gdb.base/ctf-ptype.exp +++ b/gdb/testsuite/gdb.base/ctf-ptype.exp @@ -76,6 +76,8 @@ if [gdb_test "ptype v_t_struct_p->v_float_member" "type = float"]<0 then { return -1 } +gdb_test "ptype struct link" "type = struct link \{\[\r\n\]+\[ \t\]+struct link \\*next;\[\r\n\]+\[ \t\]+struct link \\*\\(\\*linkfunc\\)\\((struct link \\*, int|void|)\\);\[\r\n\]+\[ \t\]+struct t_struct stuff.3.;\[\r\n\]+\}.*" "ptype linked list structure" + # # test ptype command with unions #