Add PDB stubs to bfd

Most of the PDB stuff should be moved to bfd. This commit sets that up
and adds a reference to it from coffread.c.

The PDB path resolving will still be in gdb.
This commit is contained in:
Les De Ridder 2020-07-11 12:48:36 +02:00
parent a8451d40c1
commit 995f44ff35
8 changed files with 257 additions and 44 deletions

View File

@ -822,7 +822,8 @@ BFD32_BACKENDS = \
xcofflink.lo \
xsym.lo \
xtensa-isa.lo \
xtensa-modules.lo
xtensa-modules.lo \
pdb.lo
BFD32_BACKENDS_CFILES = \
aout-cris.c \
@ -957,7 +958,8 @@ BFD32_BACKENDS_CFILES = \
xcofflink.c \
xsym.c \
xtensa-isa.c \
xtensa-modules.c
xtensa-modules.c \
pdb.c
# The .o files needed by all of the 64 bit vectors that are configured into
@ -1128,7 +1130,8 @@ SOURCE_HFILES = \
som.h sysdep.h \
version.h vms.h \
wasm-module.h \
xcofflink.h xsym.h
xcofflink.h xsym.h \
pdb.h
BUILD_HFILES = \
bfdver.h elf32-target.h elf64-target.h targmatch.h bfd_stdint.h
@ -1595,6 +1598,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsym.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtensa-isa.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtensa-modules.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdb.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<

2
bfd/configure vendored
View File

@ -14667,7 +14667,7 @@ selarchs="$f"
tb=
elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo
dwarf1.lo dwarf2.lo"
dwarf1.lo dwarf2.lo pdb.lo"
coffgen="coffgen.lo dwarf2.lo"
coff="cofflink.lo $coffgen"
ecoff="ecofflink.lo $coffgen"

157
bfd/pdb.c Normal file
View File

@ -0,0 +1,157 @@
/* PDB support for BFD. */
#include "pdb.h"
/* Called when the BFD is being closed to do any necessary cleanup. */
bfd_boolean
bfd_pdb_close_and_cleanup (bfd *abfd)
{
return FALSE;
}
/* Ask the BFD to free all cached information. */
bfd_boolean
bfd_pdb_bfd_free_cached_info (bfd *abfd)
{
return FALSE;
}
/* Called when a new section is created. */
bfd_boolean
bfd_pdb_new_section_hook (bfd *abfd, asection *sec)
{
return FALSE;
}
/* Read the contents of a section. */
#define bfd_pdb_get_section_contents _bfd_generic_get_section_contents
#define bfd_pdb_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
long
bfd_pdb_get_symtab_upper_bound (bfd *abfd)
{
return -1;
}
long
bfd_pdb_canonicalize_symtab (bfd *abfd, asymbol **alocation)
{
return -1;
}
asymbol *
bfd_pdb_make_empty_symbol (bfd *abfd)
{
return NULL;
}
void
bfd_pdb_print_symbol (bfd *abfd,
void *afile,
asymbol *symbol,
bfd_print_symbol_type how)
{
}
void
bfd_pdb_get_symbol_info (bfd *abfd,
asymbol *symbol,
symbol_info *ret)
{
}
#define bfd_pdb_get_symbol_version_string _bfd_nosymbols_get_symbol_version_string
#define bfd_pdb_bfd_is_local_label_name bfd_generic_is_local_label_name
#define bfd_pdb_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
#define bfd_pdb_get_lineno _bfd_nosymbols_get_lineno
bfd_boolean
bfd_pdb_find_nearest_line (bfd *abfd,
asymbol **symbols,
asection *section,
bfd_vma offset,
const char **filename_ptr,
const char **functionname_ptr,
unsigned int *line_pt,
unsigned int *discriminator_ptr)
{
return FALSE;
}
#define bfd_pdb_find_line _bfd_nosymbols_find_line
#define bfd_pdb_find_inliner_info _bfd_nosymbols_find_inliner_info
/* Back-door to allow format-aware applications to create debug symbols
while using BFD for everything else. Currently used by the assembler
when creating COFF files. */
#define bfd_pdb_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
#define bfd_pdb_read_minisymbols _bfd_generic_read_minisymbols
#define bfd_pdb_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
const bfd_target *
bfd_pdb_check_format (bfd *abfd)
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
const bfd_target pdb_vec =
{
"pdb", /* Name. */
bfd_target_pdb_flavour, /* Flavour. */
BFD_ENDIAN_LITTLE, /* Byteorder. */
BFD_ENDIAN_LITTLE, /* Header_byteorder. */
/* FIXME: These might not be correct */
(HAS_RELOC | EXEC_P | /* Object flags. */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
(SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
| SEC_DEBUGGING
| SEC_ROM | SEC_HAS_CONTENTS), /* Section_flags. */
0, /* Symbol_leading_char. */
'/', /* AR_pad_char. */
15, /* AR_max_namelen. */
0, /* match priority. */
bfd_getl64, bfd_getl_signed_64, bfd_putb64,
bfd_getl32, bfd_getl_signed_32, bfd_putb32,
bfd_getl16, bfd_getl_signed_16, bfd_putb16, /* Data. */
bfd_getl64, bfd_getl_signed_64, bfd_putb64,
bfd_getl32, bfd_getl_signed_32, bfd_putb32,
bfd_getl16, bfd_getl_signed_16, bfd_putb16, /* Headers. */
{ /* bfd_check_format. */
_bfd_dummy_target,
bfd_pdb_check_format, /* bfd_check_format. */
_bfd_dummy_target,
_bfd_dummy_target,
},
{ /* bfd_set_format. */
_bfd_bool_bfd_false_error,
_bfd_bool_bfd_false,
_bfd_bool_bfd_false_error,
_bfd_bool_bfd_false_error,
},
{ /* bfd_write_contents. */
_bfd_bool_bfd_false_error,
_bfd_bool_bfd_false,
_bfd_bool_bfd_false_error,
_bfd_bool_bfd_false_error,
},
BFD_JUMP_TABLE_GENERIC (bfd_pdb),
BFD_JUMP_TABLE_COPY (_bfd_generic),
BFD_JUMP_TABLE_CORE (_bfd_nocore),
BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
BFD_JUMP_TABLE_SYMBOLS (bfd_pdb),
BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
BFD_JUMP_TABLE_WRITE (_bfd_nowrite),
BFD_JUMP_TABLE_LINK (_bfd_nolink),
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
NULL,
NULL
};

5
bfd/pdb.h Normal file
View File

@ -0,0 +1,5 @@
/* PDB support for BFD. */
#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"

View File

@ -955,6 +955,8 @@ extern const bfd_target core_ptrace_vec;
extern const bfd_target core_sco5_vec;
extern const bfd_target core_trad_vec;
extern const bfd_target pdb_vec;
static const bfd_target * const _bfd_target_vector[] =
{
#ifdef SELECT_VECS
@ -1412,6 +1414,8 @@ static const bfd_target * const _bfd_target_vector[] =
&core_trad_vec,
#endif
&pdb_vec,
NULL /* end of list marker */
};
const bfd_target * const *bfd_target_vector = _bfd_target_vector;
@ -1799,6 +1803,7 @@ bfd_flavour_name (enum bfd_flavour flavour)
case bfd_target_pef_flavour: return "PEF";
case bfd_target_pef_xlib_flavour: return "PEF_XLIB";
case bfd_target_sym_flavour: return "SYM";
case bfd_target_pdb_flavour: return "PDB";
/* There is no "default" case here so that -Wswitch (part of -Wall)
catches missing entries. */
}

View File

@ -447,7 +447,7 @@ is_import_fixup_symbol (struct coff_symbol *cs,
static struct minimal_symbol *
record_minimal_symbol (minimal_symbol_reader &reader,
struct coff_symbol *cs, CORE_ADDR address,
enum minimal_symbol_type type, int section,
enum minimal_symbol_type type, int section,
struct objfile *objfile)
{
/* We don't want TDESC entry points in the minimal symbol table. */
@ -545,7 +545,7 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
int symtab_offset;
int stringtab_offset;
int stabstrsize;
info = coff_objfile_data_key.get (objfile);
symfile_bfd = abfd; /* Kludge for swap routines. */
@ -717,15 +717,25 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
std::string debugfile = find_separate_debug_file_by_buildid (objfile);
if (debugfile.empty ())
debugfile = find_separate_debug_file_by_debuglink (objfile);
debugfile = find_separate_debug_file_by_debuglink (objfile);
if (!debugfile.empty ())
{
gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (debugfile.c_str ()));
{
gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (debugfile.c_str ()));
symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
symfile_flags, objfile);
}
symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
symfile_flags, objfile);
}
if (debugfile.empty ())
{
gdb_bfd_ref_ptr debug_bfd (try_load_pdb_bfd (objfile));
if (debug_bfd.get ())
{
symbol_file_add_separate (debug_bfd.get (), debug_bfd->filename,
symfile_flags, objfile);
}
}
}
}
@ -1058,7 +1068,7 @@ coff_symtab_read (minimal_symbol_reader &reader,
newobj = push_context (depth, fcn_start_addr);
fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
newobj->name =
process_coff_symbol (&fcn_cs_saved,
process_coff_symbol (&fcn_cs_saved,
&fcn_aux_saved, objfile);
}
else if (strcmp (cs->c_name, ".ef") == 0)
@ -1309,7 +1319,7 @@ init_stringtab (bfd *abfd, long offset, gdb::unique_xmalloc_ptr<char> *storage)
if (length == sizeof length) /* Empty table -- just the count. */
return 0;
val = bfd_bread (stringtab + sizeof lengthbuf,
val = bfd_bread (stringtab + sizeof lengthbuf,
length - sizeof lengthbuf, abfd);
if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
return -1;
@ -1469,8 +1479,8 @@ patch_type (struct type *type, struct type *real_type)
TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target,
field_size);
memcpy (TYPE_FIELDS (target),
TYPE_FIELDS (real_target),
memcpy (TYPE_FIELDS (target),
TYPE_FIELDS (real_target),
field_size);
if (TYPE_NAME (real_target))
@ -1679,7 +1689,7 @@ process_coff_symbol (struct coff_symbol *cs,
/* If we are giving a name to a type such as
"pointer to foo" or "function returning foo", we
better not set the TYPE_NAME. If the program
contains "typedef char *caddr_t;", we don't want
contains "typedef char *caddr_t;", we don't want
all variables of type char * to print as caddr_t.
This is not just a consequence of GDB's type
management; CC and GCC (at least through version
@ -1827,9 +1837,9 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
return the type that the function returns. */
static struct type *
decode_function_type (struct coff_symbol *cs,
decode_function_type (struct coff_symbol *cs,
unsigned int c_type,
union internal_auxent *aux,
union internal_auxent *aux,
struct objfile *objfile)
{
if (aux->x_sym.x_tagndx.l == 0)
@ -1842,9 +1852,9 @@ decode_function_type (struct coff_symbol *cs,
/* Basic C types. */
static struct type *
decode_base_type (struct coff_symbol *cs,
decode_base_type (struct coff_symbol *cs,
unsigned int c_type,
union internal_auxent *aux,
union internal_auxent *aux,
struct objfile *objfile)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);

View File

@ -13,7 +13,9 @@ HACK: Honestly, this whole thing is a hack:
*/
#include "defs.h"
#include "pdb.h"
extern const bfd_target pdb_vec; //from targets.c
//BEGIN HACK (conflicting symbols)
#undef QUIT
@ -57,6 +59,33 @@ typedef struct {
} SStreamParseFunc;
//END radare2 imports
struct find_section_by_name_args {
const char *name;
asection **resultp;
};
static void
find_section_by_name_filter (bfd *abfd, asection *sect, void *obj)
{
(void) abfd;
auto *args = (struct find_section_by_name_args *) obj;
if (strcmp (sect->name, args->name) == 0)
*args->resultp = sect;
}
static struct bfd_section *
section_by_name (const char *name, struct objfile *objfile)
{
asection *sect = nullptr;
struct find_section_by_name_args args{};
args.name = name;
args.resultp = &sect;
bfd_map_over_sections (objfile->obfd, find_section_by_name_filter, &args);
return sect;
}
static std::unique_ptr<R_PDB>
get_r_pdb (const std::string & path)
{
@ -245,31 +274,30 @@ load_pdb (objfile *objfile)
return {nullptr, std::string ()};
}
struct find_section_by_name_args {
const char *name;
asection **resultp;
};
static void
find_section_by_name_filter (bfd *abfd, asection *sect, void *obj)
gdb_bfd_ref_ptr
try_load_pdb_bfd (objfile *objfile)
{
(void) abfd;
auto paths = get_pdb_paths (objfile);
auto *args = (struct find_section_by_name_args *) obj;
if (paths.empty ()) return nullptr;
if (strcmp (sect->name, args->name) == 0)
*args->resultp = sect;
}
for (auto & path : paths)
{
try
{
gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (path.c_str ()));
if (debug_bfd.get () && debug_bfd.get ()->xvec == &pdb_vec)
{
return debug_bfd;
}
}
catch (gdb_exception_error & error)
{
continue;
}
}
static struct bfd_section *
section_by_name (const char *name, struct objfile *objfile)
{
asection *sect = nullptr;
struct find_section_by_name_args args{};
args.name = name;
args.resultp = &sect;
bfd_map_over_sections (objfile->obfd, find_section_by_name_filter, &args);
return sect;
return nullptr;
}
void

View File

@ -1,6 +1,10 @@
#include "defs.h"
#include "symtab.h"
#include "minsyms.h"
#include "gdb_bfd.h"
extern void
read_pdb (struct objfile *objfile, minimal_symbol_reader &reader);
read_pdb (struct objfile *objfile, minimal_symbol_reader & reader);
extern gdb_bfd_ref_ptr
try_load_pdb_bfd (objfile *objfile);