12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640 |
- /* Compact ANSI-C Type Format (CTF) support in GDB.
- Copyright (C) 2019-2022 Free Software Foundation, Inc.
- This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- /* This file format can be used to compactly represent the information needed
- by a debugger to interpret the ANSI-C types used by a given program.
- Traditionally, this kind of information is generated by the compiler when
- invoked with the -g flag and is stored in "stabs" strings or in the more
- modern DWARF format. A new -gtLEVEL option has been added in gcc to generate
- such information. CTF provides a representation of only the information
- that is relevant to debugging a complex, optimized C program such as the
- operating system kernel in a form that is significantly more compact than
- the equivalent stabs or DWARF representation. The format is data-model
- independent, so consumers do not need different code depending on whether
- they are 32-bit or 64-bit programs. CTF assumes that a standard ELF symbol
- table is available for use in the debugger, and uses the structure and data
- of the symbol table to avoid storing redundant information. The CTF data
- may be compressed on disk or in memory, indicated by a bit in the header.
- CTF may be interpreted in a raw disk file, or it may be stored in an ELF
- section, typically named .ctf. Data structures are aligned so that a raw
- CTF file or CTF ELF section may be manipulated using mmap(2).
- The CTF file or section itself has the following structure:
- +--------+--------+---------+----------+----------+-------+--------+
- | file | type | data | function | variable | data | string |
- | header | labels | objects | info | info | types | table |
- +--------+--------+---------+----------+----------+-------+--------+
- The file header stores a magic number and version information, encoding
- flags, and the byte offset of each of the sections relative to the end of the
- header itself. If the CTF data has been uniquified against another set of
- CTF data, a reference to that data also appears in the header. This
- reference is the name of the label corresponding to the types uniquified
- against.
- Following the header is a list of labels, used to group the types included in
- the data types section. Each label is accompanied by a type ID i. A given
- label refers to the group of types whose IDs are in the range [0, i].
- Data object and function records are stored in the same order as they appear
- in the corresponding symbol table, except that symbols marked SHN_UNDEF are
- not stored and symbols that have no type data are padded out with zeroes.
- For each data object, the type ID (a small integer) is recorded. For each
- function, the type ID of the return type and argument types is recorded.
- Variable records (as distinct from data objects) provide a modicum of support
- for non-ELF systems, mapping a variable name to a CTF type ID. The variable
- names are sorted into ASCIIbetical order, permitting binary searching.
- The data types section is a list of variable size records that represent each
- type, in order by their ID. The types themselves form a directed graph,
- where each node may contain one or more outgoing edges to other type nodes,
- denoted by their ID.
- Strings are recorded as a string table ID (0 or 1) and a byte offset into the
- string table. String table 0 is the internal CTF string table. String table
- 1 is the external string table, which is the string table associated with the
- ELF symbol table for this object. CTF does not record any strings that are
- already in the symbol table, and the CTF string table does not contain any
- duplicated strings. */
- #include "defs.h"
- #include "buildsym.h"
- #include "complaints.h"
- #include "block.h"
- #include "ctfread.h"
- #include "psympriv.h"
- #if ENABLE_LIBCTF
- #include "ctf.h"
- #include "ctf-api.h"
- static const struct objfile_key<htab, htab_deleter> ctf_tid_key;
- struct ctf_fp_info
- {
- explicit ctf_fp_info (ctf_dict_t *cfp) : fp (cfp) {}
- ~ctf_fp_info ();
- ctf_dict_t *fp;
- };
- /* Cleanup function for the ctf_dict_key data. */
- ctf_fp_info::~ctf_fp_info ()
- {
- if (fp == nullptr)
- return;
- ctf_archive_t *arc = ctf_get_arc (fp);
- ctf_dict_close (fp);
- ctf_close (arc);
- }
- static const objfile_key<ctf_fp_info> ctf_dict_key;
- /* A CTF context consists of a file pointer and an objfile pointer. */
- struct ctf_context
- {
- ctf_dict_t *fp;
- struct objfile *of;
- psymtab_storage *partial_symtabs;
- partial_symtab *pst;
- ctf_archive_t *arc;
- struct buildsym_compunit *builder;
- };
- /* A partial symtab, specialized for this module. */
- struct ctf_psymtab : public standard_psymtab
- {
- ctf_psymtab (const char *filename,
- psymtab_storage *partial_symtabs,
- objfile_per_bfd_storage *objfile_per_bfd,
- CORE_ADDR addr)
- : standard_psymtab (filename, partial_symtabs, objfile_per_bfd, addr)
- {
- }
- void read_symtab (struct objfile *) override;
- void expand_psymtab (struct objfile *) override;
- struct ctf_context context;
- };
- /* The routines that read and process fields/members of a C struct, union,
- or enumeration, pass lists of data member fields in an instance of a
- ctf_field_info structure. It is derived from dwarf2read.c. */
- struct ctf_nextfield
- {
- struct field field {};
- };
- struct ctf_field_info
- {
- /* List of data member fields. */
- std::vector<struct ctf_nextfield> fields;
- /* Context. */
- struct ctf_context *cur_context;
- /* Parent type. */
- struct type *ptype;
- /* typedefs defined inside this class. TYPEDEF_FIELD_LIST contains head
- of a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements. */
- std::vector<struct decl_field> typedef_field_list;
- /* Nested types defined by this struct and the number of elements in
- this list. */
- 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 */
- static int ctf_add_type_cb (ctf_id_t tid, void *arg);
- static struct type *read_array_type (struct ctf_context *cp, ctf_id_t tid);
- static struct type *read_pointer_type (struct ctf_context *cp, ctf_id_t tid,
- ctf_id_t btid);
- static struct type *read_structure_type (struct ctf_context *cp, ctf_id_t tid);
- static struct type *read_enum_type (struct ctf_context *cp, ctf_id_t tid);
- static struct type *read_typedef_type (struct ctf_context *cp, ctf_id_t tid,
- ctf_id_t btid, const char *name);
- static struct type *read_type_record (struct ctf_context *cp, ctf_id_t tid);
- 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);
- struct ctf_tid_and_type
- {
- ctf_id_t tid;
- struct type *type;
- };
- /* Hash function for a ctf_tid_and_type. */
- static hashval_t
- tid_and_type_hash (const void *item)
- {
- const struct ctf_tid_and_type *ids
- = (const struct ctf_tid_and_type *) item;
- return ids->tid;
- }
- /* Equality function for a ctf_tid_and_type. */
- static int
- tid_and_type_eq (const void *item_lhs, const void *item_rhs)
- {
- const struct ctf_tid_and_type *ids_lhs
- = (const struct ctf_tid_and_type *) item_lhs;
- const struct ctf_tid_and_type *ids_rhs
- = (const struct ctf_tid_and_type *) item_rhs;
- return ids_lhs->tid == ids_rhs->tid;
- }
- /* Set the type associated with TID to TYP. */
- static struct type *
- set_tid_type (struct objfile *of, ctf_id_t tid, struct type *typ)
- {
- htab_t htab;
- htab = (htab_t) ctf_tid_key.get (of);
- if (htab == NULL)
- {
- htab = htab_create_alloc (1, tid_and_type_hash,
- tid_and_type_eq,
- NULL, xcalloc, xfree);
- ctf_tid_key.set (of, htab);
- }
- struct ctf_tid_and_type **slot, ids;
- ids.tid = tid;
- ids.type = typ;
- slot = (struct ctf_tid_and_type **) htab_find_slot (htab, &ids, INSERT);
- if (*slot == nullptr)
- *slot = XOBNEW (&of->objfile_obstack, struct ctf_tid_and_type);
- **slot = ids;
- return typ;
- }
- /* Look up the type for TID in tid_and_type hash, return NULL if hash is
- empty or TID does not have a saved type. */
- static struct type *
- get_tid_type (struct objfile *of, ctf_id_t tid)
- {
- struct ctf_tid_and_type *slot, ids;
- htab_t htab;
- htab = (htab_t) ctf_tid_key.get (of);
- if (htab == NULL)
- return nullptr;
- ids.tid = tid;
- ids.type = nullptr;
- slot = (struct ctf_tid_and_type *) htab_find (htab, &ids);
- if (slot)
- return slot->type;
- else
- 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
- get_bitsize (ctf_dict_t *fp, ctf_id_t tid, uint32_t kind)
- {
- ctf_encoding_t cet;
- if ((kind == CTF_K_INTEGER || kind == CTF_K_ENUM
- || kind == CTF_K_FLOAT)
- && ctf_type_reference (fp, tid) != CTF_ERR
- && ctf_type_encoding (fp, tid, &cet) != CTF_ERR)
- return cet.cte_bits;
- return 0;
- }
- /* Set SYM's address, with NAME, from its minimal symbol entry. */
- static void
- set_symbol_address (struct objfile *of, struct symbol *sym, const char *name)
- {
- struct bound_minimal_symbol msym;
- msym = lookup_minimal_symbol (name, nullptr, of);
- if (msym.minsym != NULL)
- {
- SET_SYMBOL_VALUE_ADDRESS (sym, BMSYMBOL_VALUE_ADDRESS (msym));
- sym->set_aclass_index (LOC_STATIC);
- sym->set_section_index (msym.minsym->section_index ());
- }
- }
- /* Create the vector of fields, and attach it to TYPE. */
- static void
- attach_fields_to_type (struct ctf_field_info *fip, struct type *type)
- {
- int nfields = fip->fields.size ();
- if (nfields == 0)
- return;
- /* Record the field count, allocate space for the array of fields. */
- type->set_num_fields (nfields);
- type->set_fields
- ((struct field *) TYPE_ZALLOC (type, sizeof (struct field) * nfields));
- /* Copy the saved-up fields into the field vector. */
- for (int i = 0; i < nfields; ++i)
- {
- struct ctf_nextfield &field = fip->fields[i];
- type->field (i) = field.field;
- }
- }
- /* Allocate a floating-point type of size BITS and name NAME. Pass NAME_HINT
- (which may be different from NAME) to the architecture back-end to allow
- it to guess the correct format if necessary. */
- static struct type *
- ctf_init_float_type (struct objfile *objfile,
- int bits,
- const char *name,
- const char *name_hint)
- {
- struct gdbarch *gdbarch = objfile->arch ();
- const struct floatformat **format;
- struct type *type;
- format = gdbarch_floatformat_for_type (gdbarch, name_hint, bits);
- if (format != nullptr)
- type = init_float_type (objfile, bits, name, format);
- else
- type = init_type (objfile, TYPE_CODE_ERROR, bits, name);
- return type;
- }
- /* Callback to add member NAME to a struct/union type. TID is the type
- of struct/union member, OFFSET is the offset of member in bits,
- and ARG contains the ctf_field_info. */
- static int
- ctf_add_member_cb (const char *name,
- ctf_id_t tid,
- unsigned long offset,
- void *arg)
- {
- struct ctf_field_info *fip = (struct ctf_field_info *) arg;
- struct ctf_context *ccp = fip->cur_context;
- struct ctf_nextfield new_field;
- struct field *fp;
- struct type *t;
- uint32_t kind;
- fp = &new_field.field;
- fp->set_name (name);
- kind = ctf_type_kind (ccp->fp, tid);
- t = fetch_tid_type (ccp, tid);
- if (t == nullptr)
- {
- t = read_type_record (ccp, tid);
- if (t == nullptr)
- {
- complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
- t = objfile_type (ccp->of)->builtin_error;
- set_tid_type (ccp->of, tid, t);
- }
- }
- if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
- process_struct_members (ccp, tid, t);
- fp->set_type (t);
- fp->set_loc_bitpos (offset / TARGET_CHAR_BIT);
- FIELD_BITSIZE (*fp) = get_bitsize (ccp->fp, tid, kind);
- fip->fields.emplace_back (new_field);
- return 0;
- }
- /* Callback to add member NAME of EVAL to an enumeration type.
- ARG contains the ctf_field_info. */
- static int
- ctf_add_enum_member_cb (const char *name, int enum_value, void *arg)
- {
- struct ctf_field_info *fip = (struct ctf_field_info *) arg;
- struct ctf_nextfield new_field;
- struct field *fp;
- struct ctf_context *ccp = fip->cur_context;
- fp = &new_field.field;
- fp->set_name (name);
- fp->set_type (nullptr);
- fp->set_loc_enumval (enum_value);
- FIELD_BITSIZE (*fp) = 0;
- if (name != nullptr)
- {
- struct symbol *sym = new (&ccp->of->objfile_obstack) symbol;
- OBJSTAT (ccp->of, n_syms++);
- sym->set_language (language_c, &ccp->of->objfile_obstack);
- sym->compute_and_set_names (name, false, ccp->of->per_bfd);
- sym->set_aclass_index (LOC_CONST);
- sym->set_domain (VAR_DOMAIN);
- sym->set_type (fip->ptype);
- add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
- }
- fip->fields.emplace_back (new_field);
- return 0;
- }
- /* Add a new symbol entry, with its name from TID, its access index and
- domain from TID's kind, and its type from TYPE. */
- static struct symbol *
- new_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
- {
- struct objfile *objfile = ccp->of;
- ctf_dict_t *fp = ccp->fp;
- struct symbol *sym = nullptr;
- const char *name = ctf_type_name_raw (fp, tid);
- if (name != nullptr)
- {
- sym = new (&objfile->objfile_obstack) symbol;
- OBJSTAT (objfile, n_syms++);
- sym->set_language (language_c, &objfile->objfile_obstack);
- sym->compute_and_set_names (name, false, objfile->per_bfd);
- sym->set_domain (VAR_DOMAIN);
- sym->set_aclass_index (LOC_OPTIMIZED_OUT);
- if (type != nullptr)
- sym->set_type (type);
- uint32_t kind = ctf_type_kind (fp, tid);
- switch (kind)
- {
- case CTF_K_STRUCT:
- case CTF_K_UNION:
- case CTF_K_ENUM:
- sym->set_aclass_index (LOC_TYPEDEF);
- sym->set_domain (STRUCT_DOMAIN);
- break;
- case CTF_K_FUNCTION:
- sym->set_aclass_index (LOC_STATIC);
- set_symbol_address (objfile, sym, sym->linkage_name ());
- break;
- case CTF_K_CONST:
- if (sym->type ()->code () == TYPE_CODE_VOID)
- sym->set_type (objfile_type (objfile)->builtin_int);
- break;
- case CTF_K_TYPEDEF:
- case CTF_K_INTEGER:
- case CTF_K_FLOAT:
- sym->set_aclass_index (LOC_TYPEDEF);
- sym->set_domain (VAR_DOMAIN);
- break;
- case CTF_K_POINTER:
- break;
- case CTF_K_VOLATILE:
- case CTF_K_RESTRICT:
- break;
- case CTF_K_SLICE:
- case CTF_K_ARRAY:
- case CTF_K_UNKNOWN:
- break;
- }
- add_symbol_to_list (sym, ccp->builder->get_file_symbols ());
- }
- return sym;
- }
- /* Given a TID of kind CTF_K_INTEGER or CTF_K_FLOAT, find a representation
- and create the symbol for it. */
- static struct type *
- read_base_type (struct ctf_context *ccp, ctf_id_t tid)
- {
- struct objfile *of = ccp->of;
- ctf_dict_t *fp = ccp->fp;
- ctf_encoding_t cet;
- struct type *type = nullptr;
- const char *name;
- uint32_t kind;
- if (ctf_type_encoding (fp, tid, &cet))
- {
- complaint (_("ctf_type_encoding read_base_type failed - %s"),
- ctf_errmsg (ctf_errno (fp)));
- return nullptr;
- }
- name = ctf_type_name_raw (fp, tid);
- if (name == nullptr || strlen (name) == 0)
- {
- name = ctf_type_aname (fp, tid);
- if (name == nullptr)
- complaint (_("ctf_type_aname read_base_type failed - %s"),
- ctf_errmsg (ctf_errno (fp)));
- }
- kind = ctf_type_kind (fp, tid);
- if (kind == CTF_K_INTEGER)
- {
- uint32_t issigned, ischar, isbool;
- struct gdbarch *gdbarch = of->arch ();
- issigned = cet.cte_format & CTF_INT_SIGNED;
- ischar = cet.cte_format & CTF_INT_CHAR;
- isbool = cet.cte_format & CTF_INT_BOOL;
- if (ischar)
- type = init_character_type (of, TARGET_CHAR_BIT, !issigned, name);
- else if (isbool)
- type = init_boolean_type (of, gdbarch_int_bit (gdbarch),
- !issigned, name);
- else
- {
- int bits;
- if (cet.cte_bits && ((cet.cte_bits % TARGET_CHAR_BIT) == 0))
- bits = cet.cte_bits;
- else
- bits = gdbarch_int_bit (gdbarch);
- type = init_integer_type (of, bits, !issigned, name);
- }
- }
- else if (kind == CTF_K_FLOAT)
- {
- uint32_t isflt;
- isflt = !((cet.cte_format & CTF_FP_IMAGRY) == CTF_FP_IMAGRY
- || (cet.cte_format & CTF_FP_DIMAGRY) == CTF_FP_DIMAGRY
- || (cet.cte_format & CTF_FP_LDIMAGRY) == CTF_FP_LDIMAGRY);
- if (isflt)
- type = ctf_init_float_type (of, cet.cte_bits, name, name);
- else
- {
- struct type *t
- = ctf_init_float_type (of, cet.cte_bits / 2, NULL, name);
- type = init_complex_type (name, t);
- }
- }
- else
- {
- complaint (_("read_base_type: unsupported base kind (%d)"), kind);
- type = init_type (of, TYPE_CODE_ERROR, cet.cte_bits, name);
- }
- if (name != nullptr && strcmp (name, "char") == 0)
- type->set_has_no_signedness (true);
- return set_tid_type (of, tid, type);
- }
- static void
- process_base_type (struct ctf_context *ccp, ctf_id_t tid)
- {
- struct type *type;
- type = read_base_type (ccp, tid);
- new_symbol (ccp, type, tid);
- }
- /* Start a structure or union scope (definition) with TID to create a type
- for the structure or union.
- Fill in the type's name and general properties. The members will not be
- processed, nor a symbol table entry be done until process_structure_type
- (assuming the type has a name). */
- static struct type *
- read_structure_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);
- const char *name = ctf_type_name_raw (fp, tid);
- if (name != nullptr && strlen (name) != 0)
- type->set_name (name);
- kind = ctf_type_kind (fp, tid);
- if (kind == CTF_K_UNION)
- type->set_code (TYPE_CODE_UNION);
- else
- type->set_code (TYPE_CODE_STRUCT);
- TYPE_LENGTH (type) = ctf_type_size (fp, tid);
- set_type_align (type, ctf_type_align (fp, tid));
- return set_tid_type (ccp->of, tid, type);
- }
- /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
- and create the symbol for it. */
- static void
- process_struct_members (struct ctf_context *ccp,
- ctf_id_t tid,
- struct type *type)
- {
- struct ctf_field_info fi;
- fi.cur_context = ccp;
- if (ctf_member_iter (ccp->fp, tid, ctf_add_member_cb, &fi) == CTF_ERR)
- complaint (_("ctf_member_iter process_struct_members failed - %s"),
- ctf_errmsg (ctf_errno (ccp->fp)));
- /* Attach fields to the type. */
- attach_fields_to_type (&fi, type);
- new_symbol (ccp, type, tid);
- }
- static void
- process_structure_type (struct ctf_context *ccp, ctf_id_t tid)
- {
- struct type *type;
- type = read_structure_type (ccp, tid);
- process_struct_members (ccp, tid, type);
- }
- /* Create a function type for TID and set its return type. */
- static struct type *
- read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
- {
- struct objfile *of = ccp->of;
- ctf_dict_t *fp = ccp->fp;
- struct type *type, *rettype, *atype;
- ctf_funcinfo_t cfi;
- uint32_t argc;
- type = alloc_type (of);
- type->set_code (TYPE_CODE_FUNC);
- if (ctf_func_type_info (fp, tid, &cfi) < 0)
- {
- const char *fname = ctf_type_name_raw (fp, tid);
- error (_("Error getting function type info: %s"),
- fname == nullptr ? "noname" : fname);
- }
- rettype = fetch_tid_type (ccp, cfi.ctc_return);
- TYPE_TARGET_TYPE (type) = rettype;
- set_type_align (type, ctf_type_align (fp, tid));
- /* Set up function's arguments. */
- argc = cfi.ctc_argc;
- type->set_num_fields (argc);
- if ((cfi.ctc_flags & CTF_FUNC_VARARG) != 0)
- type->set_has_varargs (true);
- if (argc != 0)
- {
- std::vector<ctf_id_t> argv (argc);
- if (ctf_func_type_args (fp, tid, argc, argv.data ()) == CTF_ERR)
- return nullptr;
- type->set_fields
- ((struct field *) TYPE_ZALLOC (type, argc * sizeof (struct field)));
- struct type *void_type = objfile_type (of)->builtin_void;
- /* If failed to find the argument type, fill it with void_type. */
- for (int iparam = 0; iparam < argc; iparam++)
- {
- atype = fetch_tid_type (ccp, argv[iparam]);
- if (atype != nullptr)
- type->field (iparam).set_type (atype);
- else
- type->field (iparam).set_type (void_type);
- }
- }
- return set_tid_type (of, tid, type);
- }
- /* Given a TID of CTF_K_ENUM, process all the members of the
- enumeration, and create the symbol for the enumeration type. */
- static struct type *
- read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
- {
- struct objfile *of = ccp->of;
- ctf_dict_t *fp = ccp->fp;
- struct type *type;
- type = alloc_type (of);
- const char *name = ctf_type_name_raw (fp, tid);
- if (name != nullptr && strlen (name) != 0)
- type->set_name (name);
- type->set_code (TYPE_CODE_ENUM);
- TYPE_LENGTH (type) = ctf_type_size (fp, tid);
- /* Set the underlying type based on its ctf_type_size bits. */
- TYPE_TARGET_TYPE (type) = objfile_int_type (of, TYPE_LENGTH (type), false);
- set_type_align (type, ctf_type_align (fp, tid));
- return set_tid_type (of, tid, type);
- }
- static void
- process_enum_type (struct ctf_context *ccp, ctf_id_t tid)
- {
- struct type *type;
- struct ctf_field_info fi;
- type = read_enum_type (ccp, tid);
- fi.cur_context = ccp;
- fi.ptype = type;
- if (ctf_enum_iter (ccp->fp, tid, ctf_add_enum_member_cb, &fi) == CTF_ERR)
- complaint (_("ctf_enum_iter process_enum_type failed - %s"),
- ctf_errmsg (ctf_errno (ccp->fp)));
- /* Attach fields to the type. */
- attach_fields_to_type (&fi, type);
- new_symbol (ccp, type, tid);
- }
- /* Add given cv-qualifiers CNST+VOLTL to the BASE_TYPE of array TID. */
- static struct type *
- add_array_cv_type (struct ctf_context *ccp,
- ctf_id_t tid,
- struct type *base_type,
- int cnst,
- int voltl)
- {
- struct type *el_type, *inner_array;
- base_type = copy_type (base_type);
- inner_array = base_type;
- while (TYPE_TARGET_TYPE (inner_array)->code () == TYPE_CODE_ARRAY)
- {
- TYPE_TARGET_TYPE (inner_array)
- = copy_type (TYPE_TARGET_TYPE (inner_array));
- inner_array = TYPE_TARGET_TYPE (inner_array);
- }
- el_type = TYPE_TARGET_TYPE (inner_array);
- cnst |= TYPE_CONST (el_type);
- voltl |= TYPE_VOLATILE (el_type);
- TYPE_TARGET_TYPE (inner_array) = make_cv_type (cnst, voltl, el_type, nullptr);
- return set_tid_type (ccp->of, tid, base_type);
- }
- /* Read all information from a TID of CTF_K_ARRAY. */
- static struct type *
- read_array_type (struct ctf_context *ccp, ctf_id_t tid)
- {
- struct objfile *objfile = ccp->of;
- ctf_dict_t *fp = ccp->fp;
- struct type *element_type, *range_type, *idx_type;
- struct type *type;
- ctf_arinfo_t ar;
- if (ctf_array_info (fp, tid, &ar) == CTF_ERR)
- {
- complaint (_("ctf_array_info read_array_type failed - %s"),
- ctf_errmsg (ctf_errno (fp)));
- return nullptr;
- }
- element_type = fetch_tid_type (ccp, ar.ctr_contents);
- if (element_type == nullptr)
- return nullptr;
- idx_type = fetch_tid_type (ccp, ar.ctr_index);
- if (idx_type == nullptr)
- idx_type = objfile_type (objfile)->builtin_int;
- range_type = create_static_range_type (NULL, idx_type, 0, ar.ctr_nelems - 1);
- type = create_array_type (NULL, element_type, range_type);
- if (ar.ctr_nelems <= 1) /* Check if undefined upper bound. */
- {
- range_type->bounds ()->high.set_undefined ();
- TYPE_LENGTH (type) = 0;
- type->set_target_is_stub (true);
- }
- else
- TYPE_LENGTH (type) = ctf_type_size (fp, tid);
- set_type_align (type, ctf_type_align (fp, tid));
- return set_tid_type (objfile, tid, type);
- }
- /* Read TID of kind CTF_K_CONST with base type BTID. */
- static struct type *
- 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 = fetch_tid_type (ccp, btid);
- if (base_type == nullptr)
- {
- base_type = read_type_record (ccp, btid);
- if (base_type == nullptr)
- {
- complaint (_("read_const_type: NULL base type (%ld)"), btid);
- base_type = objfile_type (objfile)->builtin_error;
- }
- }
- cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
- return set_tid_type (objfile, tid, cv_type);
- }
- /* Read TID of kind CTF_K_VOLATILE with base type BTID. */
- static struct type *
- read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
- {
- struct objfile *objfile = ccp->of;
- ctf_dict_t *fp = ccp->fp;
- struct type *base_type, *cv_type;
- base_type = fetch_tid_type (ccp, btid);
- if (base_type == nullptr)
- {
- base_type = read_type_record (ccp, btid);
- if (base_type == nullptr)
- {
- complaint (_("read_volatile_type: NULL base type (%ld)"), btid);
- base_type = objfile_type (objfile)->builtin_error;
- }
- }
- if (ctf_type_kind (fp, btid) == CTF_K_ARRAY)
- return add_array_cv_type (ccp, tid, base_type, 0, 1);
- cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
- return set_tid_type (objfile, tid, cv_type);
- }
- /* Read TID of kind CTF_K_RESTRICT with base type BTID. */
- static struct type *
- 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 = fetch_tid_type (ccp, btid);
- if (base_type == nullptr)
- {
- base_type = read_type_record (ccp, btid);
- if (base_type == nullptr)
- {
- complaint (_("read_restrict_type: NULL base type (%ld)"), btid);
- base_type = objfile_type (objfile)->builtin_error;
- }
- }
- cv_type = make_restrict_type (base_type);
- return set_tid_type (objfile, tid, cv_type);
- }
- /* Read TID of kind CTF_K_TYPEDEF with its NAME and base type BTID. */
- static struct type *
- read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
- ctf_id_t btid, const char *name)
- {
- struct objfile *objfile = ccp->of;
- struct type *this_type, *target_type;
- 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 = fetch_tid_type (ccp, btid);
- if (target_type != this_type)
- TYPE_TARGET_TYPE (this_type) = target_type;
- else
- TYPE_TARGET_TYPE (this_type) = nullptr;
- this_type->set_target_is_stub (TYPE_TARGET_TYPE (this_type) != nullptr);
- return set_tid_type (objfile, tid, this_type);
- }
- /* Read TID of kind CTF_K_POINTER with base type BTID. */
- static struct type *
- 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 = fetch_tid_type (ccp, btid);
- if (target_type == nullptr)
- {
- target_type = read_type_record (ccp, btid);
- if (target_type == nullptr)
- {
- complaint (_("read_pointer_type: NULL target type (%ld)"), btid);
- target_type = objfile_type (ccp->of)->builtin_error;
- }
- }
- type = lookup_pointer_type (target_type);
- set_type_align (type, ctf_type_align (ccp->fp, tid));
- 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);
- const char *name = ctf_type_name_raw (fp, tid);
- if (name != nullptr && strlen (name) != 0)
- type->set_name (name);
- 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 *
- read_type_record (struct ctf_context *ccp, ctf_id_t tid)
- {
- ctf_dict_t *fp = ccp->fp;
- uint32_t kind;
- struct type *type = nullptr;
- ctf_id_t btid;
- kind = ctf_type_kind (fp, tid);
- switch (kind)
- {
- case CTF_K_STRUCT:
- case CTF_K_UNION:
- type = read_structure_type (ccp, tid);
- break;
- case CTF_K_ENUM:
- type = read_enum_type (ccp, tid);
- break;
- case CTF_K_FUNCTION:
- type = read_func_kind_type (ccp, tid);
- break;
- case CTF_K_CONST:
- btid = ctf_type_reference (fp, tid);
- type = read_const_type (ccp, tid, btid);
- break;
- case CTF_K_TYPEDEF:
- {
- const char *name = ctf_type_name_raw (fp, tid);
- btid = ctf_type_reference (fp, tid);
- type = read_typedef_type (ccp, tid, btid, name);
- }
- break;
- case CTF_K_VOLATILE:
- btid = ctf_type_reference (fp, tid);
- type = read_volatile_type (ccp, tid, btid);
- break;
- case CTF_K_RESTRICT:
- btid = ctf_type_reference (fp, tid);
- type = read_restrict_type (ccp, tid, btid);
- break;
- case CTF_K_POINTER:
- btid = ctf_type_reference (fp, tid);
- type = read_pointer_type (ccp, tid, btid);
- break;
- case CTF_K_INTEGER:
- case CTF_K_FLOAT:
- type = read_base_type (ccp, tid);
- break;
- 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:
- break;
- }
- return type;
- }
- /* Callback to add type TID to the symbol table. */
- static int
- ctf_add_type_cb (ctf_id_t tid, void *arg)
- {
- struct ctf_context *ccp = (struct ctf_context *) arg;
- struct type *type;
- uint32_t kind;
- /* Check if tid's type has already been defined. */
- type = get_tid_type (ccp->of, tid);
- if (type != nullptr)
- return 0;
- ctf_id_t btid = ctf_type_reference (ccp->fp, tid);
- kind = ctf_type_kind (ccp->fp, tid);
- switch (kind)
- {
- case CTF_K_STRUCT:
- case CTF_K_UNION:
- process_structure_type (ccp, tid);
- break;
- case CTF_K_ENUM:
- process_enum_type (ccp, tid);
- break;
- case CTF_K_FUNCTION:
- type = read_func_kind_type (ccp, tid);
- new_symbol (ccp, type, tid);
- break;
- case CTF_K_INTEGER:
- case CTF_K_FLOAT:
- process_base_type (ccp, tid);
- break;
- case CTF_K_TYPEDEF:
- new_symbol (ccp, read_type_record (ccp, tid), tid);
- break;
- case CTF_K_CONST:
- type = read_const_type (ccp, tid, btid);
- new_symbol (ccp, type, tid);
- break;
- case CTF_K_VOLATILE:
- type = read_volatile_type (ccp, tid, btid);
- new_symbol (ccp, type, tid);
- break;
- case CTF_K_RESTRICT:
- type = read_restrict_type (ccp, tid, btid);
- new_symbol (ccp, type, tid);
- break;
- case CTF_K_POINTER:
- type = read_pointer_type (ccp, tid, btid);
- new_symbol (ccp, type, tid);
- break;
- case CTF_K_ARRAY:
- type = read_array_type (ccp, tid);
- new_symbol (ccp, type, tid);
- break;
- case CTF_K_UNKNOWN:
- break;
- default:
- break;
- }
- return 0;
- }
- /* Callback to add variable NAME with TID to the symbol table. */
- static int
- ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
- {
- struct ctf_context *ccp = (struct ctf_context *) arg;
- struct symbol *sym = nullptr;
- struct type *type;
- uint32_t kind;
- type = get_tid_type (ccp->of, id);
- kind = ctf_type_kind (ccp->fp, id);
- switch (kind)
- {
- case CTF_K_FUNCTION:
- if (name != nullptr && strcmp (name, "main") == 0)
- set_objfile_main_name (ccp->of, name, language_c);
- break;
- case CTF_K_INTEGER:
- case CTF_K_FLOAT:
- case CTF_K_VOLATILE:
- case CTF_K_RESTRICT:
- case CTF_K_TYPEDEF:
- case CTF_K_CONST:
- case CTF_K_POINTER:
- case CTF_K_ARRAY:
- if (type != nullptr)
- {
- sym = new_symbol (ccp, type, id);
- if (sym != nullptr)
- sym->compute_and_set_names (name, false, ccp->of->per_bfd);
- }
- break;
- case CTF_K_STRUCT:
- case CTF_K_UNION:
- case CTF_K_ENUM:
- if (type == nullptr)
- {
- complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
- type = objfile_type (ccp->of)->builtin_error;
- }
- sym = new (&ccp->of->objfile_obstack) symbol;
- OBJSTAT (ccp->of, n_syms++);
- sym->set_type (type);
- sym->set_domain (VAR_DOMAIN);
- sym->set_aclass_index (LOC_OPTIMIZED_OUT);
- sym->compute_and_set_names (name, false, ccp->of->per_bfd);
- add_symbol_to_list (sym, ccp->builder->get_file_symbols ());
- break;
- default:
- complaint (_("ctf_add_var_cb: kind unsupported (%d)"), kind);
- break;
- }
- if (sym != nullptr)
- set_symbol_address (ccp->of, sym, name);
- return 0;
- }
- /* Add entries in either data objects or function info section, controlled
- by FUNCTIONS. */
- static void
- add_stt_entries (struct ctf_context *ccp, int functions)
- {
- ctf_next_t *i = nullptr;
- const char *tname;
- ctf_id_t tid;
- struct symbol *sym = nullptr;
- struct type *type;
- 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++);
- sym->set_type (type);
- sym->set_domain (VAR_DOMAIN);
- sym->set_aclass_index (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 entries in data objects section. */
- static void
- add_stt_obj (struct ctf_context *ccp)
- {
- add_stt_entries (ccp, 0);
- }
- /* Add entries in function info section. */
- 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. */
- static CORE_ADDR
- get_objfile_text_range (struct objfile *of, int *tsize)
- {
- bfd *abfd = of->obfd;
- const asection *codes;
- codes = bfd_get_section_by_name (abfd, ".text");
- *tsize = codes ? bfd_section_size (codes) : 0;
- return of->text_section_offset ();
- }
- /* Start a symtab for OBJFILE in CTF format. */
- static void
- ctf_start_compunit_symtab (ctf_psymtab *pst,
- struct objfile *of, CORE_ADDR text_offset)
- {
- struct ctf_context *ccp;
- ccp = &pst->context;
- ccp->builder = new buildsym_compunit
- (of, pst->filename, nullptr,
- language_c, text_offset);
- ccp->builder->record_debugformat ("ctf");
- }
- /* Finish reading symbol/type definitions in CTF format.
- END_ADDR is the end address of the file's text. SECTION is
- the .text section number. */
- static struct compunit_symtab *
- ctf_end_compunit_symtab (ctf_psymtab *pst,
- CORE_ADDR end_addr, int section)
- {
- struct ctf_context *ccp;
- ccp = &pst->context;
- struct compunit_symtab *result
- = ccp->builder->end_compunit_symtab (end_addr, section);
- delete ccp->builder;
- ccp->builder = nullptr;
- return result;
- }
- /* Add all members of an enum with type TID to partial symbol table. */
- static void
- ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
- {
- int val;
- const char *ename;
- ctf_next_t *i = nullptr;
- while ((ename = ctf_enum_next (ccp->fp, tid, &i, &val)) != nullptr)
- {
- ccp->pst->add_psymbol (ename, true,
- VAR_DOMAIN, LOC_CONST, -1,
- psymbol_placement::GLOBAL,
- 0, language_c, ccp->partial_symtabs, ccp->of);
- }
- if (ctf_errno (ccp->fp) != ECTF_NEXT_END)
- complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
- 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 ctf_context *ccp;
- gdb_assert (!readin);
- ccp = &context;
- /* Iterate over entries in data types section. */
- if (ctf_type_iter (ccp->fp, ctf_add_type_cb, ccp) == CTF_ERR)
- complaint (_("ctf_type_iter psymtab_to_symtab failed - %s"),
- ctf_errmsg (ctf_errno (ccp->fp)));
- /* Iterate over entries in variable info section. */
- if (ctf_variable_iter (ccp->fp, ctf_add_var_cb, ccp) == CTF_ERR)
- complaint (_("ctf_variable_iter psymtab_to_symtab failed - %s"),
- ctf_errmsg (ctf_errno (ccp->fp)));
- /* Add entries in data objects and function info sections. */
- add_stt_obj (ccp);
- add_stt_func (ccp);
- readin = true;
- }
- /* Expand partial symbol table PST into a full symbol table.
- PST is not NULL. */
- void
- ctf_psymtab::read_symtab (struct objfile *objfile)
- {
- if (readin)
- warning (_("bug: psymtab for %s is already read in."), filename);
- else
- {
- if (info_verbose)
- {
- gdb_printf (_("Reading in CTF data for %s..."), filename);
- gdb_flush (gdb_stdout);
- }
- /* Start a symtab. */
- CORE_ADDR offset; /* Start of text segment. */
- int tsize;
- offset = get_objfile_text_range (objfile, &tsize);
- ctf_start_compunit_symtab (this, objfile, offset);
- expand_psymtab (objfile);
- set_text_low (offset);
- set_text_high (offset + tsize);
- compunit_symtab = ctf_end_compunit_symtab (this, offset + tsize,
- SECT_OFF_TEXT (objfile));
- /* Finish up the debug error message. */
- if (info_verbose)
- gdb_printf (_("done.\n"));
- }
- }
- /* Allocate a new partial_symtab NAME.
- Each source file that has not been fully read in is represented by
- a partial_symtab. This contains the information on where in the
- executable the debugging symbols for a specific file are, and a
- list of names of global symbols which are located in this file.
- They are all chained on partial symtab lists.
- Even after the source file has been read into a symtab, the
- partial_symtab remains around. They are allocated on an obstack,
- objfile_obstack. */
- 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;
- pst = new ctf_psymtab (name, partial_symtabs, objfile->per_bfd, 0);
- pst->context.arc = arc;
- pst->context.fp = cfp;
- pst->context.of = objfile;
- pst->context.partial_symtabs = partial_symtabs;
- pst->context.pst = pst;
- pst->context.builder = nullptr;
- return pst;
- }
- /* Callback to add type TID to partial symbol table. */
- static int
- ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
- {
- struct ctf_context *ccp;
- uint32_t kind;
- short section = -1;
- ccp = (struct ctf_context *) arg;
- domain_enum domain = UNDEF_DOMAIN;
- enum address_class aclass = LOC_UNDEF;
- kind = ctf_type_kind (ccp->fp, tid);
- switch (kind)
- {
- case CTF_K_ENUM:
- ctf_psymtab_add_enums (ccp, tid);
- /* FALL THROUGH */
- case CTF_K_STRUCT:
- case CTF_K_UNION:
- domain = STRUCT_DOMAIN;
- aclass = LOC_TYPEDEF;
- break;
- case CTF_K_FUNCTION:
- case CTF_K_FORWARD:
- domain = VAR_DOMAIN;
- aclass = LOC_STATIC;
- section = SECT_OFF_TEXT (ccp->of);
- break;
- case CTF_K_CONST:
- domain = VAR_DOMAIN;
- aclass = LOC_STATIC;
- break;
- case CTF_K_TYPEDEF:
- case CTF_K_POINTER:
- case CTF_K_VOLATILE:
- case CTF_K_RESTRICT:
- domain = VAR_DOMAIN;
- aclass = LOC_TYPEDEF;
- break;
- case CTF_K_INTEGER:
- case CTF_K_FLOAT:
- domain = VAR_DOMAIN;
- aclass = LOC_TYPEDEF;
- break;
- case CTF_K_ARRAY:
- case CTF_K_UNKNOWN:
- return 0;
- }
- const char *name = ctf_type_name_raw (ccp->fp, tid);
- if (name == nullptr || strlen (name) == 0)
- return 0;
- ccp->pst->add_psymbol (name, false,
- domain, aclass, section,
- psymbol_placement::STATIC,
- 0, language_c, ccp->partial_symtabs, ccp->of);
- return 0;
- }
- /* Callback to add variable NAME with ID to partial symbol table. */
- static int
- ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
- {
- struct ctf_context *ccp = (struct ctf_context *) arg;
- ccp->pst->add_psymbol (name, true,
- VAR_DOMAIN, LOC_STATIC, -1,
- psymbol_placement::GLOBAL,
- 0, language_c, ccp->partial_symtabs, ccp->of);
- return 0;
- }
- /* 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 ctf_per_tu_data *tup, const char *fname)
- {
- struct objfile *of = tup->of;
- bool isparent = false;
- if (strcmp (fname, ".ctf") == 0)
- {
- fname = bfd_get_filename (of->obfd);
- isparent = true;
- }
- ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, cfp,
- partial_symtabs, of);
- struct ctf_context *ccx = &pst->context;
- if (isparent == false)
- ccx->pst = pst;
- if (ctf_type_iter (cfp, ctf_psymtab_type_cb, ccx) == CTF_ERR)
- complaint (_("ctf_type_iter scan_partial_symbols failed - %s"),
- ctf_errmsg (ctf_errno (cfp)));
- if (ctf_variable_iter (cfp, ctf_psymtab_var_cb, ccx) == CTF_ERR)
- complaint (_("ctf_variable_iter scan_partial_symbols failed - %s"),
- ctf_errmsg (ctf_errno (cfp)));
- /* 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. */
- ctf_psymtab_add_stt_obj (cfp, pst, of);
- ctf_psymtab_add_stt_func (cfp, pst, of);
- pst->end ();
- }
- /* 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)
- {
- gdb_printf (_("Scanning archive member %s..."), name);
- gdb_flush (gdb_stdout);
- }
- 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
- called from elfread.c. It does a quick pass through the
- .ctf section to set up the partial symbol table. */
- void
- elfctf_build_psymtabs (struct objfile *of)
- {
- struct ctf_per_tu_data pcu;
- bfd *abfd = of->obfd;
- int err;
- ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
- if (arc == nullptr)
- error (_("ctf_bfdopen failed on %s - %s"),
- bfd_get_filename (abfd), ctf_errmsg (err));
- ctf_dict_t *fp = ctf_dict_open (arc, NULL, &err);
- if (fp == nullptr)
- error (_("ctf_dict_open failed on %s - %s"),
- 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 ();
- of->qf.emplace_front (psf);
- 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
- void
- elfctf_build_psymtabs (struct objfile *of)
- {
- /* Nothing to do if CTF is disabled. */
- }
- #endif /* ENABLE_LIBCTF */
|