gdb: fully separate coff and elf reading from dbx

With the previous commits, the only thing entangling elf and coff file
reading with dbx file reading is the functions
{elf|coff}stab_build_psymtabs, defined in dbxread.c. These functions
depend on dbx_symfile_read.

To solve this, I renamed read_stabs_symtab to read_stabs_symtab_1, and
created a function with the original name that does what
dbx_symfile_read used to do.

This way, dbx_symfile_read can just call read_stabs_symtab, and the elf
and coff psymtab builders can also call it directly, fully disentangling
the readers, which would allow us to selectively not compile dbxread in
the future.

Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
Guinevere Larsen 2024-09-10 14:42:30 -03:00
parent 3cd1748a7d
commit 59d41830a3
5 changed files with 272 additions and 264 deletions

View File

@ -37,6 +37,7 @@
#include "block.h"
#include "dictionary.h"
#include "dwarf2/public.h"
#include "gdb-stabs.h"
#include "coff-pe-read.h"
@ -204,6 +205,98 @@ static void read_one_sym (struct coff_symbol *,
static void coff_symtab_read (minimal_symbol_reader &,
file_ptr, unsigned int, struct objfile *);
/* Scan and build partial symbols for an coff symbol file.
The coff file has already been processed to get its minimal symbols.
This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
rolled into one.
OBJFILE is the object file we are reading symbols from.
ADDR is the address relative to which the symbols are (e.g.
the base address of the text segment).
TEXTADDR is the address of the text section.
TEXTSIZE is the size of the text section.
STABSECTS is the list of .stab sections in OBJFILE.
STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
.stabstr section exists.
This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
adjusted for coff details. */
void
coffstab_build_psymtabs (struct objfile *objfile,
CORE_ADDR textaddr, unsigned int textsize,
const std::vector<asection *> &stabsects,
file_ptr stabstroffset, unsigned int stabstrsize)
{
int val;
bfd *sym_bfd = objfile->obfd.get ();
const char *name = bfd_get_filename (sym_bfd);
unsigned int stabsize;
/* Allocate struct to keep track of stab reading. */
dbx_objfile_data_key.emplace (objfile);
dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
DBX_TEXT_ADDR (objfile) = textaddr;
DBX_TEXT_SIZE (objfile) = textsize;
#define COFF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */
DBX_SYMBOL_SIZE (objfile) = COFF_STABS_SYMBOL_SIZE;
DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
if (stabstrsize > bfd_get_size (sym_bfd))
error (_("ridiculous string table size: %d bytes"), stabstrsize);
DBX_STRINGTAB (objfile) = (char *)
obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1);
OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
/* Now read in the string table in one big gulp. */
val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
if (val < 0)
perror_with_name (name);
val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
if (val != stabstrsize)
perror_with_name (name);
stabsread_new_init ();
free_header_files ();
init_header_files ();
key->ctx.processing_acc_compilation = 1;
/* In a coff file, we've already installed the minimal symbols that came
from the coff (non-stab) symbol table, so always act like an
incremental load here. */
scoped_restore save_symbuf_sections
= make_scoped_restore (&key->ctx.symbuf_sections);
if (stabsects.size () == 1)
{
stabsize = bfd_section_size (stabsects[0]);
DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
DBX_SYMTAB_OFFSET (objfile) = stabsects[0]->filepos;
}
else
{
DBX_SYMCOUNT (objfile) = 0;
for (asection *section : stabsects)
{
stabsize = bfd_section_size (section);
DBX_SYMCOUNT (objfile) += stabsize / DBX_SYMBOL_SIZE (objfile);
}
DBX_SYMTAB_OFFSET (objfile) = stabsects[0]->filepos;
key->ctx.sect_idx = 1;
key->ctx.symbuf_sections = &stabsects;
key->ctx.symbuf_left = bfd_section_size (stabsects[0]);
key->ctx.symbuf_read = 0;
}
read_stabs_symtab (objfile, 0);
}
/* We are called once per section from coff_symfile_read. We
need to examine each section we are passed, check to see
if it is something we are interested in processing, and

View File

@ -58,52 +58,6 @@
#include "gdb-stabs.h"
/* find_text_range --- find start and end of loadable code sections
The find_text_range function finds the shortest address range that
encloses all sections containing executable code, and stores it in
objfile's text_addr and text_size members.
dbx_symfile_read will use this to finish off the partial symbol
table, in some cases. */
static void
find_text_range (bfd * sym_bfd, struct objfile *objfile)
{
asection *sec;
int found_any = 0;
CORE_ADDR start = 0;
CORE_ADDR end = 0;
for (sec = sym_bfd->sections; sec; sec = sec->next)
if (bfd_section_flags (sec) & SEC_CODE)
{
CORE_ADDR sec_start = bfd_section_vma (sec);
CORE_ADDR sec_end = sec_start + bfd_section_size (sec);
if (found_any)
{
if (sec_start < start)
start = sec_start;
if (sec_end > end)
end = sec_end;
}
else
{
start = sec_start;
end = sec_end;
}
found_any = 1;
}
if (!found_any)
error (_("Can't find any code sections in symbol file"));
DBX_TEXT_ADDR (objfile) = start;
DBX_TEXT_SIZE (objfile) = end - start;
}
@ -144,40 +98,7 @@ explicit_lookup_type (int real_filenum, int index)
static void
dbx_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
{
bfd *sym_bfd;
int val;
struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
sym_bfd = objfile->obfd.get ();
/* .o and .nlm files are relocatables with text, data and bss segs based at
0. This flag disables special (Solaris stabs-in-elf only) fixups for
symbols with a value of 0. */
key->ctx.symfile_relocatable = bfd_get_file_flags (sym_bfd) & HAS_RELOC;
val = bfd_seek (sym_bfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
if (val < 0)
perror_with_name (objfile_name (objfile));
key->ctx.symbol_size = DBX_SYMBOL_SIZE (objfile);
key->ctx.symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
scoped_free_pendings free_pending;
minimal_symbol_reader reader (objfile);
/* Read stabs data from executable file and define symbols. */
psymbol_functions *psf = new psymbol_functions ();
psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
objfile->qf.emplace_front (psf);
read_stabs_symtab (reader, partial_symtabs, objfile);
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
reader.install ();
read_stabs_symtab (objfile, symfile_flags);
}
/* Initialize anything that needs initializing when a completely new
@ -330,184 +251,6 @@ dbx_symfile_finish (struct objfile *objfile)
/* FIXME: The only difference between this and elfstab_build_psymtabs
is the call to install_minimal_symbols for elf, and the support for
split sections. If the differences are really that small, the code
should be shared. */
/* Scan and build partial symbols for an coff symbol file.
The coff file has already been processed to get its minimal symbols.
This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
rolled into one.
OBJFILE is the object file we are reading symbols from.
ADDR is the address relative to which the symbols are (e.g.
the base address of the text segment).
TEXTADDR is the address of the text section.
TEXTSIZE is the size of the text section.
STABSECTS is the list of .stab sections in OBJFILE.
STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
.stabstr section exists.
This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
adjusted for coff details. */
void
coffstab_build_psymtabs (struct objfile *objfile,
CORE_ADDR textaddr, unsigned int textsize,
const std::vector<asection *> &stabsects,
file_ptr stabstroffset, unsigned int stabstrsize)
{
int val;
bfd *sym_bfd = objfile->obfd.get ();
const char *name = bfd_get_filename (sym_bfd);
unsigned int stabsize;
/* Allocate struct to keep track of stab reading. */
dbx_objfile_data_key.emplace (objfile);
dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
DBX_TEXT_ADDR (objfile) = textaddr;
DBX_TEXT_SIZE (objfile) = textsize;
#define COFF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */
DBX_SYMBOL_SIZE (objfile) = COFF_STABS_SYMBOL_SIZE;
DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
if (stabstrsize > bfd_get_size (sym_bfd))
error (_("ridiculous string table size: %d bytes"), stabstrsize);
DBX_STRINGTAB (objfile) = (char *)
obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1);
OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
/* Now read in the string table in one big gulp. */
val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
if (val < 0)
perror_with_name (name);
val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
if (val != stabstrsize)
perror_with_name (name);
stabsread_new_init ();
free_header_files ();
init_header_files ();
key->ctx.processing_acc_compilation = 1;
/* In a coff file, we've already installed the minimal symbols that came
from the coff (non-stab) symbol table, so always act like an
incremental load here. */
scoped_restore save_symbuf_sections
= make_scoped_restore (&key->ctx.symbuf_sections);
if (stabsects.size () == 1)
{
stabsize = bfd_section_size (stabsects[0]);
DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
DBX_SYMTAB_OFFSET (objfile) = stabsects[0]->filepos;
}
else
{
DBX_SYMCOUNT (objfile) = 0;
for (asection *section : stabsects)
{
stabsize = bfd_section_size (section);
DBX_SYMCOUNT (objfile) += stabsize / DBX_SYMBOL_SIZE (objfile);
}
DBX_SYMTAB_OFFSET (objfile) = stabsects[0]->filepos;
key->ctx.sect_idx = 1;
key->ctx.symbuf_sections = &stabsects;
key->ctx.symbuf_left = bfd_section_size (stabsects[0]);
key->ctx.symbuf_read = 0;
}
dbx_symfile_read (objfile, 0);
}
/* Scan and build partial symbols for an ELF symbol file.
This ELF file has already been processed to get its minimal symbols.
This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
rolled into one.
OBJFILE is the object file we are reading symbols from.
ADDR is the address relative to which the symbols are (e.g.
the base address of the text segment).
STABSECT is the BFD section information for the .stab section.
STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
.stabstr section exists.
This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
adjusted for elf details. */
void
elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
file_ptr stabstroffset, unsigned int stabstrsize)
{
int val;
bfd *sym_bfd = objfile->obfd.get ();
const char *name = bfd_get_filename (sym_bfd);
stabsread_new_init ();
/* Allocate struct to keep track of stab reading. */
dbx_objfile_data_key.emplace (objfile);
dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
/* Find the first and last text address. dbx_symfile_read seems to
want this. */
find_text_range (sym_bfd, objfile);
#define ELF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */
DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
DBX_SYMCOUNT (objfile)
= bfd_section_size (stabsect) / DBX_SYMBOL_SIZE (objfile);
DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;
DBX_STAB_SECTION (objfile) = stabsect;
if (stabstrsize > bfd_get_size (sym_bfd))
error (_("ridiculous string table size: %d bytes"), stabstrsize);
DBX_STRINGTAB (objfile) = (char *)
obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1);
OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
/* Now read in the string table in one big gulp. */
val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
if (val < 0)
perror_with_name (name);
val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
if (val != stabstrsize)
perror_with_name (name);
stabsread_new_init ();
free_header_files ();
init_header_files ();
key->ctx.processing_acc_compilation = 1;
key->ctx.symbuf_read = 0;
key->ctx.symbuf_left = bfd_section_size (stabsect);
scoped_restore restore_stabs_data = make_scoped_restore (&key->ctx.stabs_data);
gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
key->ctx.stabs_data = symfile_relocate_debug_section (objfile, stabsect, NULL);
if (key->ctx.stabs_data)
data_holder.reset (key->ctx.stabs_data);
/* In an elf file, we've already installed the minimal symbols that came
from the elf (non-stab) symbol table, so always act like an
incremental load here. dbx_symfile_read should not generate any new
minimal symbols, since we will have already read the ELF dynamic symbol
table and normal symbol entries won't be in the ".stab" section; but in
case it does, it will install them itself. */
dbx_symfile_read (objfile, 0);
}
/* Scan and build partial symbols for a file with special sections for stabs
and stabstrings. The file has already been processed to get its minimal

View File

@ -49,6 +49,7 @@
#include "gdbsupport/scoped_fd.h"
#include "dwarf2/public.h"
#include "cli/cli-cmds.h"
#include "gdb-stabs.h"
/* Whether ctf should always be read, or only if no dwarf is present. */
static bool always_read_ctf;
@ -1225,6 +1226,134 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
return has_dwarf2;
}
/* find_text_range --- find start and end of loadable code sections
The find_text_range function finds the shortest address range that
encloses all sections containing executable code, and stores it in
objfile's text_addr and text_size members.
dbx_symfile_read will use this to finish off the partial symbol
table, in some cases. */
static void
find_text_range (bfd * sym_bfd, struct objfile *objfile)
{
asection *sec;
int found_any = 0;
CORE_ADDR start = 0;
CORE_ADDR end = 0;
for (sec = sym_bfd->sections; sec; sec = sec->next)
if (bfd_section_flags (sec) & SEC_CODE)
{
CORE_ADDR sec_start = bfd_section_vma (sec);
CORE_ADDR sec_end = sec_start + bfd_section_size (sec);
if (found_any)
{
if (sec_start < start)
start = sec_start;
if (sec_end > end)
end = sec_end;
}
else
{
start = sec_start;
end = sec_end;
}
found_any = 1;
}
if (!found_any)
error (_("Can't find any code sections in symbol file"));
DBX_TEXT_ADDR (objfile) = start;
DBX_TEXT_SIZE (objfile) = end - start;
}
/* Scan and build partial symbols for an ELF symbol file.
This ELF file has already been processed to get its minimal symbols.
This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
rolled into one.
OBJFILE is the object file we are reading symbols from.
ADDR is the address relative to which the symbols are (e.g.
the base address of the text segment).
STABSECT is the BFD section information for the .stab section.
STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
.stabstr section exists.
This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
adjusted for elf details. */
void
elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
file_ptr stabstroffset, unsigned int stabstrsize)
{
int val;
bfd *sym_bfd = objfile->obfd.get ();
const char *name = bfd_get_filename (sym_bfd);
stabsread_new_init ();
/* Allocate struct to keep track of stab reading. */
dbx_objfile_data_key.emplace (objfile);
dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
/* Find the first and last text address. dbx_symfile_read seems to
want this. */
find_text_range (sym_bfd, objfile);
#define ELF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */
DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
DBX_SYMCOUNT (objfile)
= bfd_section_size (stabsect) / DBX_SYMBOL_SIZE (objfile);
DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;
DBX_STAB_SECTION (objfile) = stabsect;
if (stabstrsize > bfd_get_size (sym_bfd))
error (_("ridiculous string table size: %d bytes"), stabstrsize);
DBX_STRINGTAB (objfile) = (char *)
obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1);
OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
/* Now read in the string table in one big gulp. */
val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
if (val < 0)
perror_with_name (name);
val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
if (val != stabstrsize)
perror_with_name (name);
stabsread_new_init ();
free_header_files ();
init_header_files ();
key->ctx.processing_acc_compilation = 1;
key->ctx.symbuf_read = 0;
key->ctx.symbuf_left = bfd_section_size (stabsect);
scoped_restore restore_stabs_data = make_scoped_restore (&key->ctx.stabs_data);
gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
key->ctx.stabs_data = symfile_relocate_debug_section (objfile, stabsect, NULL);
if (key->ctx.stabs_data)
data_holder.reset (key->ctx.stabs_data);
/* In an elf file, we've already installed the minimal symbols that came
from the elf (non-stab) symbol table, so always act like an
incremental load here. dbx_symfile_read should not generate any new
minimal symbols, since we will have already read the ELF dynamic symbol
table and normal symbol entries won't be in the ".stab" section; but in
case it does, it will install them itself. */
read_stabs_symtab (objfile, 0);
}
/* Scan and build partial symbols for a symbol file.
We have been initialized by a call to elf_symfile_init, which
currently does nothing.

View File

@ -1196,10 +1196,10 @@ start_psymtab (psymtab_storage *partial_symtabs, struct objfile *objfile,
/* See stabsread.h. */
void
read_stabs_symtab (minimal_symbol_reader &reader,
psymtab_storage *partial_symtabs,
struct objfile *objfile)
static void
read_stabs_symtab_1 (minimal_symbol_reader &reader,
psymtab_storage *partial_symtabs,
struct objfile *objfile)
{
struct gdbarch *gdbarch = objfile->arch ();
struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch. */
@ -2212,6 +2212,50 @@ read_stabs_symtab (minimal_symbol_reader &reader,
}
}
/* Scan and build partial symbols for a symbol file.
We have been initialized by a call to dbx_symfile_init, which
put all the relevant info into a "struct dbx_symfile_info",
hung off the objfile structure. */
void
read_stabs_symtab (struct objfile *objfile, symfile_add_flags symfile_flags)
{
bfd *sym_bfd;
int val;
struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
sym_bfd = objfile->obfd.get ();
/* .o and .nlm files are relocatables with text, data and bss segs based at
0. This flag disables special (Solaris stabs-in-elf only) fixups for
symbols with a value of 0. */
key->ctx.symfile_relocatable = bfd_get_file_flags (sym_bfd) & HAS_RELOC;
val = bfd_seek (sym_bfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
if (val < 0)
perror_with_name (objfile_name (objfile));
key->ctx.symbol_size = DBX_SYMBOL_SIZE (objfile);
key->ctx.symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
scoped_free_pendings free_pending;
minimal_symbol_reader reader (objfile);
/* Read stabs data from executable file and define symbols. */
psymbol_functions *psf = new psymbol_functions ();
psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
objfile->qf.emplace_front (psf);
read_stabs_symtab_1 (reader, partial_symtabs, objfile);
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
reader.install ();
}
/* Record the namespace that the function defined by SYMBOL was
defined in, if necessary. BLOCK is the associated block; use
OBSTACK for allocation. */

View File

@ -189,8 +189,7 @@ extern void process_one_symbol (int, int, CORE_ADDR, const char *,
debugging information is available. */
void
read_stabs_symtab (minimal_symbol_reader &,
psymtab_storage *, struct objfile *);
read_stabs_symtab (struct objfile *, symfile_add_flags);
extern void elfstab_build_psymtabs (struct objfile *objfile,
asection *stabsect,