struct objfile *of;
psymtab_storage *partial_symtabs;
partial_symtab *pst;
+ ctf_archive_t *arc;
struct buildsym_compunit *builder;
};
void read_symtab (struct objfile *) override;
void expand_psymtab (struct objfile *) override;
- struct ctf_context *context;
+ struct ctf_context context;
};
/* The routines that read and process fields/members of a C struct, union,
std::vector<struct decl_field> nested_types_list;
};
+/* Data held for a translation unit. */
+
+struct ctf_per_tu_data
+{
+ ctf_dict_t *fp;
+ struct objfile *of;
+ ctf_archive_t *arc;
+ psymtab_storage *pss;
+ psymbol_functions *psf;
+};
/* Local function prototypes */
ids.tid = tid;
ids.type = typ;
slot = (struct ctf_tid_and_type **) htab_find_slot (htab, &ids, INSERT);
- if (*slot)
- complaint (_("An internal GDB problem: ctf_ id_t %ld type already set"),
- (tid));
- *slot = XOBNEW (&of->objfile_obstack, struct ctf_tid_and_type);
+ if (*slot == nullptr)
+ *slot = XOBNEW (&of->objfile_obstack, struct ctf_tid_and_type);
**slot = ids;
return typ;
}
break;
}
- add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
+ add_symbol_to_list (sym, ccp->builder->get_file_symbols ());
}
return sym;
/* If failed to find the argument type, fill it with void_type. */
for (int iparam = 0; iparam < argc; iparam++)
{
- atype = get_tid_type (of, argv[iparam]);
+ atype = fetch_tid_type (ccp, argv[iparam]);
if (atype != nullptr)
type->field (iparam).set_type (atype);
else
case CTF_K_CONST:
case CTF_K_POINTER:
case CTF_K_ARRAY:
- if (type)
+ if (type != nullptr)
{
sym = new_symbol (ccp, type, id);
- sym->compute_and_set_names (name, false, ccp->of->per_bfd);
+ if (sym != nullptr)
+ sym->compute_and_set_names (name, false, ccp->of->per_bfd);
}
break;
case CTF_K_STRUCT:
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
sym->compute_and_set_names (name, false, ccp->of->per_bfd);
- add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
+ add_symbol_to_list (sym, ccp->builder->get_file_symbols ());
break;
default:
complaint (_("ctf_add_var_cb: kind unsupported (%d)"), kind);
return 0;
}
-/* Add an ELF STT_OBJ symbol with index IDX to the symbol table. */
+/* Add entries in either data objects or function info section, controlled
+ by FUNCTIONS. */
-static struct symbol *
-add_stt_obj (struct ctf_context *ccp, unsigned long idx)
+static void
+add_stt_entries (struct ctf_context *ccp, int functions)
{
- struct symbol *sym;
- struct type *type;
+ ctf_next_t *i = nullptr;
+ const char *tname;
ctf_id_t tid;
+ struct symbol *sym = nullptr;
+ struct type *type;
- if ((tid = ctf_lookup_by_symbol (ccp->fp, idx)) == CTF_ERR)
- return nullptr;
-
- type = fetch_tid_type (ccp, tid);
- if (type == nullptr)
- return nullptr;
-
- sym = new_symbol (ccp, type, tid);
-
- return sym;
+ while ((tid = ctf_symbol_next (ccp->fp, &i, &tname, functions)) != CTF_ERR)
+ {
+ type = get_tid_type (ccp->of, tid);
+ if (type == nullptr)
+ continue;
+ sym = new (&ccp->of->objfile_obstack) symbol;
+ OBJSTAT (ccp->of, n_syms++);
+ SYMBOL_TYPE (sym) = type;
+ SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+ sym->compute_and_set_names (tname, false, ccp->of->per_bfd);
+ add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
+ set_symbol_address (ccp->of, sym, tname);
+ }
}
-/* Add an ELF STT_FUNC symbol with index IDX to the symbol table. */
+/* Add entries in data objects section. */
-static struct symbol *
-add_stt_func (struct ctf_context *ccp, unsigned long idx)
+static void
+add_stt_obj (struct ctf_context *ccp)
{
- struct type *ftype, *atyp, *rettyp;
- struct symbol *sym;
- ctf_funcinfo_t finfo;
- ctf_id_t argv[32];
- uint32_t argc;
- ctf_id_t tid;
- struct type *void_type = objfile_type (ccp->of)->builtin_void;
-
- if (ctf_func_info (ccp->fp, idx, &finfo) == CTF_ERR)
- return nullptr;
-
- argc = finfo.ctc_argc;
- if (ctf_func_args (ccp->fp, idx, argc, argv) == CTF_ERR)
- return nullptr;
-
- gdb::unique_xmalloc_ptr<char> name (ctf_type_aname_raw (ccp->fp, idx));
- if (name == nullptr)
- return nullptr;
-
- tid = ctf_lookup_by_symbol (ccp->fp, idx);
- ftype = fetch_tid_type (ccp, tid);
- if ((finfo.ctc_flags & CTF_FUNC_VARARG) != 0)
- ftype->set_has_varargs (true);
- ftype->set_num_fields (argc);
-
- /* If argc is 0, it has a "void" type. */
- if (argc != 0)
- ftype->set_fields
- ((struct field *) TYPE_ZALLOC (ftype, argc * sizeof (struct field)));
-
- /* TYPE_FIELD_TYPE must never be NULL. Fill it with void_type, if failed
- to find the argument type. */
- for (int iparam = 0; iparam < argc; iparam++)
- {
- atyp = fetch_tid_type (ccp, argv[iparam]);
- if (atyp)
- ftype->field (iparam).set_type (atyp);
- else
- ftype->field (iparam).set_type (void_type);
- }
+ add_stt_entries (ccp, 0);
+}
- sym = new_symbol (ccp, ftype, tid);
- rettyp = fetch_tid_type (ccp, finfo.ctc_return);
- if (rettyp != nullptr)
- SYMBOL_TYPE (sym) = rettyp;
- else
- SYMBOL_TYPE (sym) = void_type;
+/* Add entries in function info section. */
- return sym;
+static void
+add_stt_func (struct ctf_context *ccp)
+{
+ add_stt_entries (ccp, 1);
}
/* Get text segment base for OBJFILE, TSIZE contains the segment size. */
{
struct ctf_context *ccp;
- ccp = pst->context;
+ ccp = &pst->context;
ccp->builder = new buildsym_compunit
(of, of->original_name, nullptr,
language_c, text_offset);
{
struct ctf_context *ccp;
- ccp = pst->context;
+ ccp = &pst->context;
struct compunit_symtab *result
= ccp->builder->end_symtab (end_addr, section);
delete ccp->builder;
ctf_errmsg (ctf_errno (ccp->fp)));
}
+/* Add entries in either data objects or function info section, controlled
+ by FUNCTIONS, to psymtab. */
+
+static void
+ctf_psymtab_add_stt_entries (ctf_dict_t *cfp, ctf_psymtab *pst,
+ struct objfile *of, int functions)
+{
+ ctf_next_t *i = nullptr;
+ ctf_id_t tid;
+ const char *tname;
+
+ while ((tid = ctf_symbol_next (cfp, &i, &tname, functions)) != CTF_ERR)
+ {
+ uint32_t kind = ctf_type_kind (cfp, tid);
+ address_class aclass;
+ domain_enum tdomain;
+ switch (kind)
+ {
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ case CTF_K_ENUM:
+ tdomain = STRUCT_DOMAIN;
+ break;
+ default:
+ tdomain = VAR_DOMAIN;
+ break;
+ }
+
+ if (kind == CTF_K_FUNCTION)
+ aclass = LOC_STATIC;
+ else if (kind == CTF_K_CONST)
+ aclass = LOC_CONST;
+ else
+ aclass = LOC_TYPEDEF;
+
+ pst->add_psymbol (tname, true,
+ tdomain, aclass, -1,
+ psymbol_placement::GLOBAL,
+ 0, language_c, pst->context.partial_symtabs, of);
+ }
+}
+
+/* Add entries in data objects section to psymtab. */
+
+static void
+ctf_psymtab_add_stt_obj (ctf_dict_t *cfp, ctf_psymtab *pst,
+ struct objfile *of)
+{
+ ctf_psymtab_add_stt_entries (cfp, pst, of, 0);
+}
+
+/* Add entries in function info section to psymtab. */
+
+static void
+ctf_psymtab_add_stt_func (ctf_dict_t *cfp, ctf_psymtab *pst,
+ struct objfile *of)
+{
+ ctf_psymtab_add_stt_entries (cfp, pst, of, 1);
+}
+
/* Read in full symbols for PST, and anything it depends on. */
void
ctf_psymtab::expand_psymtab (struct objfile *objfile)
{
- struct symbol *sym;
struct ctf_context *ccp;
gdb_assert (!readin);
- ccp = context;
+ ccp = &context;
/* Iterate over entries in data types section. */
if (ctf_type_iter (ccp->fp, ctf_add_type_cb, ccp) == CTF_ERR)
ctf_errmsg (ctf_errno (ccp->fp)));
/* Add entries in data objects and function info sections. */
- for (unsigned long i = 0; ; i++)
- {
- sym = add_stt_obj (ccp, i);
- if (sym == nullptr)
- {
- if (ctf_errno (ccp->fp) == EINVAL
- || ctf_errno (ccp->fp) == ECTF_NOSYMTAB)
- break;
- sym = add_stt_func (ccp, i);
- }
- if (sym == nullptr)
- continue;
-
- set_symbol_address (ccp->of, sym, sym->linkage_name ());
- }
+ add_stt_obj (ccp);
+ add_stt_func (ccp);
readin = true;
}
static ctf_psymtab *
create_partial_symtab (const char *name,
+ ctf_archive_t *arc,
ctf_dict_t *cfp,
psymtab_storage *partial_symtabs,
struct objfile *objfile)
{
ctf_psymtab *pst;
- struct ctf_context *ccx;
pst = new ctf_psymtab (name, partial_symtabs, objfile->per_bfd, 0);
- ccx = XOBNEW (&objfile->objfile_obstack, struct ctf_context);
- ccx->fp = cfp;
- ccx->of = objfile;
- ccx->partial_symtabs = partial_symtabs;
- ccx->pst = pst;
- ccx->builder = nullptr;
- pst->context = ccx;
+ pst->context.arc = arc;
+ pst->context.fp = cfp;
+ pst->context.of = objfile;
+ pst->context.partial_symtabs = partial_symtabs;
+ pst->context.pst = pst;
return pst;
}
ccp->pst->add_psymbol (name, false,
domain, aclass, section,
- psymbol_placement::GLOBAL,
+ psymbol_placement::STATIC,
0, language_c, ccp->partial_symtabs, ccp->of);
return 0;
return 0;
}
+/* Start a subfile for CTF. FNAME is the name of the archive. */
+
+static void
+ctf_start_archive (struct ctf_context *ccx, struct objfile *of,
+ const char *fname)
+{
+ if (ccx->builder == nullptr)
+ {
+ ccx->builder = new buildsym_compunit (of,
+ of->original_name, nullptr, language_c, 0);
+ ccx->builder->record_debugformat ("ctf");
+ }
+ ccx->builder->start_subfile (fname);
+}
+
/* Setup partial_symtab's describing each source file for which
debugging information is available. */
static void
scan_partial_symbols (ctf_dict_t *cfp, psymtab_storage *partial_symtabs,
- struct objfile *of)
+ struct ctf_per_tu_data *tup, const char *fname)
{
- bfd *abfd = of->obfd;
- const char *name = bfd_get_filename (abfd);
- ctf_psymtab *pst = create_partial_symtab (name, cfp, partial_symtabs, of);
+ struct objfile *of = tup->of;
+ bool isparent = false;
+
+ if (strcmp (fname, ".ctf") == 0)
+ {
+ fname = bfd_get_filename (of->obfd);
+ isparent = true;
+ }
- struct ctf_context *ccx = pst->context;
+ ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, cfp,
+ partial_symtabs, of);
+
+ struct ctf_context *ccx = &pst->context;
+ if (isparent == false)
+ {
+ ctf_start_archive (ccx, of, fname);
+ ccx->pst = pst;
+ }
if (ctf_type_iter (cfp, ctf_psymtab_type_cb, ccx) == CTF_ERR)
complaint (_("ctf_type_iter scan_partial_symbols failed - %s"),
/* Scan CTF object and function sections which correspond to each
STT_FUNC or STT_OBJECT entry in the symbol table,
pick up what init_symtab has done. */
- for (unsigned long idx = 0; ; idx++)
- {
- ctf_id_t tid;
- if ((tid = ctf_lookup_by_symbol (cfp, idx)) == CTF_ERR)
- {
- if (ctf_errno (cfp) == EINVAL || ctf_errno (cfp) == ECTF_NOSYMTAB)
- break; // Done, reach end of the section.
- else
- continue;
- }
- const char *tname = ctf_type_name_raw (cfp, tid);
- uint32_t kind = ctf_type_kind (cfp, tid);
- address_class aclass;
- domain_enum tdomain;
- switch (kind)
- {
- case CTF_K_STRUCT:
- case CTF_K_UNION:
- case CTF_K_ENUM:
- tdomain = STRUCT_DOMAIN;
- break;
- default:
- tdomain = VAR_DOMAIN;
- break;
- }
+ ctf_psymtab_add_stt_obj (cfp, pst, of);
+ ctf_psymtab_add_stt_func (cfp, pst, of);
- if (kind == CTF_K_FUNCTION)
- aclass = LOC_STATIC;
- else if (kind == CTF_K_CONST)
- aclass = LOC_CONST;
- else
- aclass = LOC_TYPEDEF;
+ pst->end ();
+}
- pst->add_psymbol (tname, false,
- tdomain, aclass, -1,
- psymbol_placement::STATIC,
- 0, language_c, partial_symtabs, of);
+/* Callback to build the psymtab for archive member NAME. */
+
+static int
+build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
+{
+ struct ctf_per_tu_data *tup = (struct ctf_per_tu_data *) arg;
+ ctf_dict_t *parent = tup->fp;
+
+ if (strcmp (name, ".ctf") != 0)
+ ctf_import (ctf, parent);
+
+ if (info_verbose)
+ {
+ printf_filtered (_("Scanning archive member %s..."), name);
+ gdb_flush (gdb_stdout);
}
- pst->end ();
+ psymtab_storage *pss = tup->psf->get_partial_symtabs ().get ();
+ scan_partial_symbols (ctf, pss, tup, name);
+
+ return 0;
}
/* Read CTF debugging information from a BFD section. This is
void
elfctf_build_psymtabs (struct objfile *of)
{
+ struct ctf_per_tu_data pcu;
bfd *abfd = of->obfd;
int err;
bfd_get_filename (abfd), ctf_errmsg (err));
ctf_dict_key.emplace (of, fp);
+ pcu.fp = fp;
+ pcu.of = of;
+ pcu.arc = arc;
+
psymbol_functions *psf = new psymbol_functions ();
- psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
of->qf.emplace_front (psf);
- scan_partial_symbols (fp, partial_symtabs, of);
+ pcu.psf = psf;
+
+ if (ctf_archive_iter (arc, build_ctf_archive_member, &pcu) < 0)
+ error (_("ctf_archive_iter failed in input file %s: - %s"),
+ bfd_get_filename (abfd), ctf_errmsg (err));
}
#else