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:
parent
a8451d40c1
commit
995f44ff35
|
@ -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 $@ $<
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
/* PDB support for BFD. */
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
|
@ -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. */
|
||||
}
|
||||
|
|
|
@ -726,6 +726,16 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
70
gdb/pdb.c
70
gdb/pdb.c
|
@ -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 = §
|
||||
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 = §
|
||||
bfd_map_over_sections (objfile->obfd, find_section_by_name_filter, &args);
|
||||
return sect;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue