diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 15334f1..8dea121 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -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 $@ $< diff --git a/bfd/configure b/bfd/configure index abd7b2a..c90db49 100755 --- a/bfd/configure +++ b/bfd/configure @@ -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" diff --git a/bfd/pdb.c b/bfd/pdb.c new file mode 100644 index 0000000..faec57b --- /dev/null +++ b/bfd/pdb.c @@ -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 + }; diff --git a/bfd/pdb.h b/bfd/pdb.h new file mode 100644 index 0000000..9b533b5 --- /dev/null +++ b/bfd/pdb.h @@ -0,0 +1,5 @@ +/* PDB support for BFD. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" \ No newline at end of file diff --git a/bfd/targets.c b/bfd/targets.c index fb0c669..0927672 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -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. */ } diff --git a/gdb/coffread.c b/gdb/coffread.c index 85ee43e..382cbb8 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -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 *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); diff --git a/gdb/pdb.c b/gdb/pdb.c index a5ed08d..c7029e8 100644 --- a/gdb/pdb.c +++ b/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 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 diff --git a/gdb/pdb.h b/gdb/pdb.h index 12dcf80..fa86a48 100644 --- a/gdb/pdb.h +++ b/gdb/pdb.h @@ -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);