/* Read coff symbol tables and convert to internal format, for GDB.
- Copyright (C) 1987-2022 Free Software Foundation, Inc.
+ Copyright (C) 1987-2023 Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
This file is part of GDB.
/* Key for COFF-associated data. */
-static const struct objfile_key<coff_symfile_info> coff_objfile_data_key;
+static const registry<objfile>::key<coff_symfile_info> coff_objfile_data_key;
/* Translate an external name string into a user-visible name. */
#define EXTERNAL_NAME(string, abfd) \
/* Return the section_offsets* that CS points to. */
static int cs_to_section (struct coff_symbol *, struct objfile *);
-struct find_targ_sec_arg
+struct coff_find_targ_sec_arg
{
int targ_index;
asection **resultp;
static void
find_targ_sec (bfd *abfd, asection *sect, void *obj)
{
- struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
+ struct coff_find_targ_sec_arg *args = (struct coff_find_targ_sec_arg *) obj;
if (sect->target_index == args->targ_index)
*args->resultp = sect;
cs_to_bfd_section (struct coff_symbol *cs, struct objfile *objfile)
{
asection *sect = NULL;
- struct find_targ_sec_arg args;
+ struct coff_find_targ_sec_arg args;
args.targ_index = cs->c_secnum;
args.resultp = §
- bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+ bfd_map_over_sections (objfile->obfd.get (), find_targ_sec, &args);
return sect;
}
if (sect == NULL)
return SECT_OFF_TEXT (objfile);
- return gdb_bfd_section_index (objfile->obfd, sect);
+ return gdb_bfd_section_index (objfile->obfd.get (), sect);
}
/* Return the address of the section of a COFF symbol. */
cs_section_address (struct coff_symbol *cs, bfd *abfd)
{
asection *sect = NULL;
- struct find_targ_sec_arg args;
+ struct coff_find_targ_sec_arg args;
CORE_ADDR addr = 0;
args.targ_index = cs->c_secnum;
it indicates the start of data for one original source file. */
static void
-coff_start_symtab (struct objfile *objfile, const char *name)
+coff_start_compunit_symtab (struct objfile *objfile, const char *name)
{
within_function = 0;
- start_symtab (objfile,
- name,
+ start_compunit_symtab (objfile,
+ name,
/* We never know the directory name for COFF. */
- NULL,
+ NULL,
/* The start address is irrelevant, since we call
- set_last_source_start_addr in coff_end_symtab. */
- 0,
+ set_last_source_start_addr in coff_end_compunit_symtab. */
+ 0,
/* Let buildsym.c deduce the language for this symtab. */
- language_unknown);
+ language_unknown);
record_debugformat ("COFF");
}
list of all such. */
static void
-coff_end_symtab (struct objfile *objfile)
+coff_end_compunit_symtab (struct objfile *objfile)
{
set_last_source_start_addr (current_source_start_addr);
- end_symtab (current_source_end_addr, SECT_OFF_TEXT (objfile));
+ end_compunit_symtab (current_source_end_addr, SECT_OFF_TEXT (objfile));
/* Reinitialize for beginning of new file. */
set_last_source_file (NULL);
}
+/* A helper function for coff_symfile_read that reads minimal
+ symbols. It may also read other forms of symbol as well. */
+
+static void
+coff_read_minsyms (file_ptr symtab_offset, unsigned int nsyms,
+ struct objfile *objfile)
+
+{
+ /* If minimal symbols were already read, and if we know we aren't
+ going to read any other kind of symbol here, then we can just
+ return. */
+ if (objfile->per_bfd->minsyms_read && pe_file && nsyms == 0)
+ return;
+
+ minimal_symbol_reader reader (objfile);
+
+ if (pe_file && nsyms == 0)
+ {
+ /* We've got no debugging symbols, but it's a portable
+ executable, so try to read the export table. */
+ read_pe_exported_syms (reader, objfile);
+ }
+ else
+ {
+ /* Now that the executable file is positioned at symbol table,
+ process it and define symbols accordingly. */
+ coff_symtab_read (reader, symtab_offset, nsyms, objfile);
+ }
+
+ /* Install any minimal symbols that have been collected as the
+ current minimal symbols for this objfile. */
+
+ reader.install ();
+
+ if (pe_file)
+ {
+ for (minimal_symbol *msym : objfile->msymbols ())
+ {
+ const char *name = msym->linkage_name ();
+
+ /* If the minimal symbols whose name are prefixed by "__imp_"
+ or "_imp_", get rid of the prefix, and search the minimal
+ symbol in OBJFILE. Note that 'maintenance print msymbols'
+ shows that type of these "_imp_XXXX" symbols is mst_data. */
+ if (msym->type () == mst_data)
+ {
+ const char *name1 = NULL;
+
+ if (startswith (name, "_imp_"))
+ name1 = name + 5;
+ else if (startswith (name, "__imp_"))
+ name1 = name + 6;
+ if (name1 != NULL)
+ {
+ int lead
+ = bfd_get_symbol_leading_char (objfile->obfd.get ());
+ struct bound_minimal_symbol found;
+
+ if (lead != '\0' && *name1 == lead)
+ name1 += 1;
+
+ found = lookup_minimal_symbol (name1, NULL, objfile);
+
+ /* If found, there are symbols named "_imp_foo" and "foo"
+ respectively in OBJFILE. Set the type of symbol "foo"
+ as 'mst_solib_trampoline'. */
+ if (found.minsym != NULL
+ && found.minsym->type () == mst_text)
+ found.minsym->set_type (mst_solib_trampoline);
+ }
+ }
+ }
+ }
+}
+
/* The BFD for this file -- only good while we're actively reading
symbols into a psymtab or a symtab. */
coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
{
struct coff_symfile_info *info;
- bfd *abfd = objfile->obfd;
+ bfd *abfd = objfile->obfd.get ();
coff_data_type *cdata = coff_data (abfd);
const char *filename = bfd_get_filename (abfd);
int val;
FIXME: We should use BFD to read the symbol table, and thus avoid
this problem. */
pe_file =
- startswith (bfd_get_target (objfile->obfd), "pe")
- || startswith (bfd_get_target (objfile->obfd), "epoc-pe");
+ startswith (bfd_get_target (objfile->obfd.get ()), "pe")
+ || startswith (bfd_get_target (objfile->obfd.get ()), "epoc-pe");
/* End of warning. */
if (val < 0)
error (_("\"%s\": can't get string table"), filename);
- minimal_symbol_reader reader (objfile);
-
- /* Now that the executable file is positioned at symbol table,
- process it and define symbols accordingly. */
-
- coff_symtab_read (reader, (long) symtab_offset, num_symbols, objfile);
-
- /* Install any minimal symbols that have been collected as the
- current minimal symbols for this objfile. */
-
- reader.install ();
-
- if (pe_file)
- {
- for (minimal_symbol *msym : objfile->msymbols ())
- {
- const char *name = msym->linkage_name ();
-
- /* If the minimal symbols whose name are prefixed by "__imp_"
- or "_imp_", get rid of the prefix, and search the minimal
- symbol in OBJFILE. Note that 'maintenance print msymbols'
- shows that type of these "_imp_XXXX" symbols is mst_data. */
- if (MSYMBOL_TYPE (msym) == mst_data)
- {
- const char *name1 = NULL;
-
- if (startswith (name, "_imp_"))
- name1 = name + 5;
- else if (startswith (name, "__imp_"))
- name1 = name + 6;
- if (name1 != NULL)
- {
- int lead = bfd_get_symbol_leading_char (objfile->obfd);
- struct bound_minimal_symbol found;
-
- if (lead != '\0' && *name1 == lead)
- name1 += 1;
-
- found = lookup_minimal_symbol (name1, NULL, objfile);
-
- /* If found, there are symbols named "_imp_foo" and "foo"
- respectively in OBJFILE. Set the type of symbol "foo"
- as 'mst_solib_trampoline'. */
- if (found.minsym != NULL
- && MSYMBOL_TYPE (found.minsym) == mst_text)
- MSYMBOL_TYPE (found.minsym) = mst_solib_trampoline;
- }
- }
- }
- }
+ coff_read_minsyms (symtab_offset, num_symbols, objfile);
if (!(objfile->flags & OBJF_READNEVER))
bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
if (dwarf2_has_info (objfile, NULL))
{
/* DWARF2 sections. */
- dwarf2_build_psymtabs (objfile);
+ dwarf2_initialize_objfile (objfile);
}
- dwarf2_build_frame_info (objfile);
-
/* Try to add separate debug file if no symbols table found. */
if (!objfile->has_partial_symbols ())
{
{
gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (debugfile.c_str ()));
- symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
+ symbol_file_add_separate (debug_bfd, debugfile.c_str (),
symfile_flags, objfile);
}
}
FIXME: Find out if this has been reported to Sun, whether it has
been fixed in a later release, etc. */
- bfd_seek (objfile->obfd, 0, 0);
+ bfd_seek (objfile->obfd.get (), 0, 0);
/* Position to read the symbol table. */
- val = bfd_seek (objfile->obfd, symtab_offset, 0);
+ val = bfd_seek (objfile->obfd.get (), symtab_offset, 0);
if (val < 0)
perror_with_name (objfile_name (objfile));
coffread_objfile = objfile;
- nlist_bfd_global = objfile->obfd;
+ nlist_bfd_global = objfile->obfd.get ();
nlist_nsyms_global = nsyms;
set_last_source_file (NULL);
memset (opaque_type_chain, 0, sizeof opaque_type_chain);
type_vector_length = INITIAL_TYPE_VECTOR_LENGTH;
type_vector = XCNEWVEC (struct type *, type_vector_length);
- coff_start_symtab (objfile, "");
+ coff_start_compunit_symtab (objfile, "");
symnum = 0;
while (symnum < nsyms)
if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
{
if (get_last_source_file ())
- coff_end_symtab (objfile);
+ coff_end_compunit_symtab (objfile);
- coff_start_symtab (objfile, "_globals_");
- /* coff_start_symtab will set the language of this symtab to
+ coff_start_compunit_symtab (objfile, "_globals_");
+ /* coff_start_compunit_symtab will set the language of this symtab to
language_unknown, since such a ``file name'' is not
recognized. Override that with the minimal language to
allow printing values in this symtab. */
containing debugging information. */
if (get_last_source_file ())
{
- coff_end_symtab (objfile);
- coff_start_symtab (objfile, filestring);
+ coff_end_compunit_symtab (objfile);
+ coff_start_compunit_symtab (objfile, filestring);
}
in_source_file = 1;
break;
sym = process_coff_symbol
(cs, &main_aux, objfile);
- SYMBOL_VALUE (sym) = tmpaddr + offset;
+ sym->set_value_longest (tmpaddr + offset);
sym->set_section_index (sec);
}
}
}
}
- if ((nsyms == 0) && (pe_file))
- {
- /* We've got no debugging symbols, but it's a portable
- executable, so try to read the export table. */
- read_pe_exported_syms (reader, objfile);
- }
-
if (get_last_source_file ())
- coff_end_symtab (objfile);
+ coff_end_compunit_symtab (objfile);
/* Patch up any opaque types (references to types that are not defined
in the file where they are referenced, e.g. "struct foo *bar"). */
if (aux_entry->x_file.x_n.x_n.x_zeroes == 0)
{
if (strlen (stringtab + aux_entry->x_file.x_n.x_n.x_offset) >= BUFSIZ)
- internal_error (__FILE__, __LINE__, _("coff file name too long"));
+ internal_error (_("coff file name too long"));
strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_n.x_offset);
}
else
static void
patch_type (struct type *type, struct type *real_type)
{
- struct type *target = TYPE_TARGET_TYPE (type);
- struct type *real_target = TYPE_TARGET_TYPE (real_type);
+ struct type *target = type->target_type ();
+ struct type *real_target = real_type->target_type ();
int field_size = real_target->num_fields () * sizeof (struct field);
- TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
+ target->set_length (real_target->length ());
target->set_num_fields (real_target->num_fields ());
field *fields = (struct field *) TYPE_ALLOC (target, field_size);
static void
patch_opaque_types (struct symtab *s)
{
- const struct block *b;
struct block_iterator iter;
struct symbol *real_sym;
/* Go through the per-file symbols only. */
- b = BLOCKVECTOR_BLOCK (s->blockvector (), STATIC_BLOCK);
+ const struct block *b = s->compunit ()->blockvector ()->static_block ();
ALL_BLOCK_SYMBOLS (b, iter, real_sym)
{
/* Find completed typedefs to use to fix opaque ones.
Remove syms from the chain when their types are stored,
but search the whole chain, as there may be several syms
from different files with the same name. */
- if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF
- && SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN
- && SYMBOL_TYPE (real_sym)->code () == TYPE_CODE_PTR
- && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
+ if (real_sym->aclass () == LOC_TYPEDEF
+ && real_sym->domain () == VAR_DOMAIN
+ && real_sym->type ()->code () == TYPE_CODE_PTR
+ && real_sym->type ()->target_type ()->length () != 0)
{
const char *name = real_sym->linkage_name ();
int hash = hashname (name);
&& strcmp (name + 1, sym->linkage_name () + 1) == 0)
{
if (prev)
- {
- SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
- }
+ prev->set_value_chain (sym->value_chain ());
else
- {
- opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
- }
+ opaque_type_chain[hash] = sym->value_chain ();
- patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym));
+ patch_type (sym->type (), real_sym->type ());
if (prev)
- {
- sym = SYMBOL_VALUE_CHAIN (prev);
- }
+ sym = prev->value_chain ();
else
- {
- sym = opaque_type_chain[hash];
- }
+ sym = opaque_type_chain[hash];
}
else
{
prev = sym;
- sym = SYMBOL_VALUE_CHAIN (sym);
+ sym->set_value_chain (sym);
}
}
}
static int
coff_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
{
- return gdbarch_sdb_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+ return gdbarch_sdb_reg_to_regnum (gdbarch, sym->value_longest ());
}
static const struct symbol_register_ops coff_register_funcs = {
char *name;
name = cs->c_name;
- name = EXTERNAL_NAME (name, objfile->obfd);
+ name = EXTERNAL_NAME (name, objfile->obfd.get ());
sym->set_language (get_current_subfile ()->language,
&objfile->objfile_obstack);
sym->compute_and_set_names (name, true, objfile->per_bfd);
/* default assumptions */
- SYMBOL_VALUE (sym) = cs->c_value;
- SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+ sym->set_value_longest (cs->c_value);
+ sym->set_domain (VAR_DOMAIN);
sym->set_section_index (cs_to_section (cs, objfile));
if (ISFCN (cs->c_type))
{
- SYMBOL_VALUE (sym) += objfile->text_section_offset ();
- SYMBOL_TYPE (sym) =
- lookup_function_type (decode_function_type (cs, cs->c_type,
- aux, objfile));
+ sym->set_value_longest
+ (sym->value_longest () + objfile->text_section_offset ());
+ sym->set_type
+ (lookup_function_type (decode_function_type (cs, cs->c_type,
+ aux, objfile)));
sym->set_aclass_index (LOC_BLOCK);
if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
}
else
{
- SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux, objfile);
+ sym->set_type (decode_type (cs, cs->c_type, aux, objfile));
switch (cs->c_sclass)
{
case C_NULL:
case C_THUMBEXTFUNC:
case C_EXT:
sym->set_aclass_index (LOC_STATIC);
- SET_SYMBOL_VALUE_ADDRESS (sym,
- (CORE_ADDR) cs->c_value
- + objfile->section_offsets[SECT_OFF_TEXT (objfile)]);
+ sym->set_value_address ((CORE_ADDR) cs->c_value
+ + objfile->section_offsets[SECT_OFF_TEXT (objfile)]);
add_symbol_to_list (sym, get_global_symbols ());
break;
case C_THUMBSTATFUNC:
case C_STAT:
sym->set_aclass_index (LOC_STATIC);
- SET_SYMBOL_VALUE_ADDRESS (sym,
- (CORE_ADDR) cs->c_value
- + objfile->section_offsets[SECT_OFF_TEXT (objfile)]);
+ sym->set_value_address ((CORE_ADDR) cs->c_value
+ + objfile->section_offsets[SECT_OFF_TEXT (objfile)]);
if (within_function)
{
/* Static symbol of local scope. */
#endif
case C_REG:
sym->set_aclass_index (coff_register_index);
- SYMBOL_VALUE (sym) = cs->c_value;
+ sym->set_value_longest (cs->c_value);
add_symbol_to_list (sym, get_local_symbols ());
break;
case C_ARG:
sym->set_aclass_index (LOC_ARG);
- SYMBOL_IS_ARGUMENT (sym) = 1;
+ sym->set_is_argument (1);
add_symbol_to_list (sym, get_local_symbols ());
break;
case C_REGPARM:
sym->set_aclass_index (coff_register_index);
- SYMBOL_IS_ARGUMENT (sym) = 1;
- SYMBOL_VALUE (sym) = cs->c_value;
+ sym->set_is_argument (1);
+ sym->set_value_longest (cs->c_value);
add_symbol_to_list (sym, get_local_symbols ());
break;
case C_TPDEF:
sym->set_aclass_index (LOC_TYPEDEF);
- SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+ sym->set_domain (VAR_DOMAIN);
/* If type has no name, give it one. */
- if (SYMBOL_TYPE (sym)->name () == 0)
+ if (sym->type ()->name () == 0)
{
- if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_PTR
- || SYMBOL_TYPE (sym)->code () == TYPE_CODE_FUNC)
+ if (sym->type ()->code () == TYPE_CODE_PTR
+ || sym->type ()->code () == TYPE_CODE_FUNC)
{
/* If we are giving a name to a type such as
"pointer to foo" or "function returning foo", we
;
}
else
- SYMBOL_TYPE (sym)->set_name (xstrdup (sym->linkage_name ()));
+ sym->type ()->set_name (xstrdup (sym->linkage_name ()));
}
/* Keep track of any type which points to empty structured
not an empty structured type, though; the forward
references work themselves out via the magic of
coff_lookup_type. */
- if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_PTR
- && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0
- && TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))->code ()
+ if (sym->type ()->code () == TYPE_CODE_PTR
+ && sym->type ()->target_type ()->length () == 0
+ && sym->type ()->target_type ()->code ()
!= TYPE_CODE_UNDEF)
{
int i = hashname (sym->linkage_name ());
- SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
+ sym->set_value_chain (opaque_type_chain[i]);
opaque_type_chain[i] = sym;
}
add_symbol_to_list (sym, get_file_symbols ());
case C_UNTAG:
case C_ENTAG:
sym->set_aclass_index (LOC_TYPEDEF);
- SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+ sym->set_domain (STRUCT_DOMAIN);
/* Some compilers try to be helpful by inventing "fake"
names for anonymous enums, structures, and unions, like
"~0fake" or ".0fake". Thanks, but no thanks... */
- if (SYMBOL_TYPE (sym)->name () == 0)
+ if (sym->type ()->name () == 0)
if (sym->linkage_name () != NULL
&& *sym->linkage_name () != '~'
&& *sym->linkage_name () != '.')
- SYMBOL_TYPE (sym)->set_name (xstrdup (sym->linkage_name ()));
+ sym->type ()->set_name (xstrdup (sym->linkage_name ()));
add_symbol_to_list (sym, get_file_symbols ());
break;
type->set_code (TYPE_CODE_STRUCT);
type->set_name (NULL);
INIT_CPLUS_SPECIFIC (type);
- TYPE_LENGTH (type) = 0;
+ type->set_length (0);
type->set_fields (nullptr);
type->set_num_fields (0);
}
type = coff_alloc_type (cs->c_symnum);
type->set_name (NULL);
INIT_CPLUS_SPECIFIC (type);
- TYPE_LENGTH (type) = 0;
+ type->set_length (0);
type->set_fields (nullptr);
type->set_num_fields (0);
}
type = coff_alloc_type (cs->c_symnum);
type->set_code (TYPE_CODE_ENUM);
type->set_name (NULL);
- TYPE_LENGTH (type) = 0;
+ type->set_length (0);
type->set_fields (nullptr);
type->set_num_fields (0);
}
type = coff_alloc_type (index);
type->set_code (TYPE_CODE_STRUCT);
INIT_CPLUS_SPECIFIC (type);
- TYPE_LENGTH (type) = length;
+ type->set_length (length);
while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
{
read_one_sym (ms, &sub_sym, &sub_aux);
name = ms->c_name;
- name = EXTERNAL_NAME (name, objfile->obfd);
+ name = EXTERNAL_NAME (name, objfile->obfd.get ());
switch (ms->c_sclass)
{
{
read_one_sym (ms, &sub_sym, &sub_aux);
name = ms->c_name;
- name = EXTERNAL_NAME (name, objfile->obfd);
+ name = EXTERNAL_NAME (name, objfile->obfd.get ());
switch (ms->c_sclass)
{
name = obstack_strdup (&objfile->objfile_obstack, name);
sym->set_linkage_name (name);
sym->set_aclass_index (LOC_CONST);
- SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
- SYMBOL_VALUE (sym) = ms->c_value;
+ sym->set_domain (VAR_DOMAIN);
+ sym->set_value_longest (ms->c_value);
add_symbol_to_list (sym, symlist);
nsyms++;
break;
/* Now fill in the fields of the type-structure. */
if (length > 0)
- TYPE_LENGTH (type) = length;
+ type->set_length (length);
else /* Assume ints. */
- TYPE_LENGTH (type) = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
+ type->set_length (gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT);
type->set_code (TYPE_CODE_ENUM);
type->set_num_fields (nsyms);
type->set_fields
{
struct symbol *xsym = syms->symbol[j];
- SYMBOL_TYPE (xsym) = type;
+ xsym->set_type (type);
type->field (n).set_name (xsym->linkage_name ());
- type->field (n).set_loc_enumval (SYMBOL_VALUE (xsym));
- if (SYMBOL_VALUE (xsym) < 0)
+ type->field (n).set_loc_enumval (xsym->value_longest ());
+ if (xsym->value_longest () < 0)
unsigned_enum = 0;
TYPE_FIELD_BITSIZE (type, n) = 0;
}