Implement PDB section loading in bfd

This commit is contained in:
Les De Ridder 2020-07-12 17:06:40 +02:00
parent dcae9fd7d7
commit c3184e01ce
6 changed files with 1409 additions and 1314 deletions

1304
bfd/pdb-types.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
bfd_boolean bfd_boolean
bfd_pdb_close_and_cleanup (bfd *abfd) bfd_pdb_close_and_cleanup (bfd *abfd)
{ {
abfd->tdata.pdb_data->pdb->finish_pdb_parse (abfd->tdata.pdb_data->pdb);
return TRUE; return TRUE;
} }
@ -17,11 +18,7 @@ bfd_pdb_bfd_free_cached_info (bfd *abfd)
} }
/* Called when a new section is created. */ /* Called when a new section is created. */
bfd_boolean #define bfd_pdb_new_section_hook _bfd_generic_new_section_hook
bfd_pdb_new_section_hook (bfd *abfd, asection *sec)
{
return FALSE;
}
/* Read the contents of a section. */ /* Read the contents of a section. */
#define bfd_pdb_get_section_contents _bfd_generic_get_section_contents #define bfd_pdb_get_section_contents _bfd_generic_get_section_contents
@ -39,11 +36,7 @@ bfd_pdb_canonicalize_symtab (bfd *abfd, asymbol **alocation)
return -1; return -1;
} }
asymbol * #define bfd_pdb_make_empty_symbol _bfd_generic_make_empty_symbol
bfd_pdb_make_empty_symbol (bfd *abfd)
{
return NULL;
}
void void
bfd_pdb_print_symbol (bfd *abfd, bfd_pdb_print_symbol (bfd *abfd,
@ -84,10 +77,10 @@ bfd_pdb_find_nearest_line (bfd *abfd,
/* Back-door to allow format-aware applications to create debug symbols /* Back-door to allow format-aware applications to create debug symbols
while using BFD for everything else. Currently used by the assembler while using BFD for everything else. Currently used by the assembler
when creating COFF files. */ when creating COFF files. */
#define bfd_pdb_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol #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_read_minisymbols _bfd_nosymbols_read_minisymbols
#define bfd_pdb_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #define bfd_pdb_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
static st64 static st64
r_buffer_read (RBuffer *buffer, ut8 *out, ut64 length) r_buffer_read (RBuffer *buffer, ut8 *out, ut64 length)
@ -126,14 +119,65 @@ get_bfd_pdb_data (bfd *abfd)
return NULL; return NULL;
} }
void
bfd_pdb_get_sections (bfd *abfd)
{
R_PDB *r_pdb = abfd->tdata.pdb_data->pdb;
SPEStream *section_stream = NULL;
RListIter *it = r_list_iterator (r_pdb->pdb_streams2);
while (r_list_iter_next (it))
{
SStreamParseFunc *stream = r_list_iter_get (it);
if (stream->type == ePDB_STREAM_SECT_HDR)
section_stream = stream->stream;
}
if (!section_stream)
{
_bfd_error_handler (_("%pB: no sections found in PDB"), abfd);
return;
}
it = r_list_iterator (section_stream->sections_hdrs);
while (r_list_iter_next (it))
{
SIMAGE_SECTION_HEADER *section_header = r_list_iter_get (it);
if (section_header)
{
//FIXME: These flags are probably not correct
asection *section = bfd_make_section_with_flags (abfd,
section_header->name,
SEC_LOAD);
section->vma = section_header->virtual_address;
section->size = section_header->size_of_raw_data;
//section->userdata = section_header;
}
}
}
const bfd_target * const bfd_target *
bfd_pdb_check_format (bfd *abfd) bfd_pdb_check_format (bfd *abfd)
{ {
if ((abfd->tdata.pdb_data = get_bfd_pdb_data (abfd))) if ((abfd->tdata.pdb_data = get_bfd_pdb_data (abfd)))
{ {
R_PDB *r_pdb = abfd->tdata.pdb_data->pdb;
if (r_pdb->pdb_parse (r_pdb))
{
bfd_pdb_get_sections (abfd);
}
else
{
_bfd_error_handler (_("%pB: malformed PDB file"), abfd);
goto fail;
}
return abfd->xvec; return abfd->xvec;
} }
fail:
bfd_set_error (bfd_error_wrong_format); bfd_set_error (bfd_error_wrong_format);
return NULL; return NULL;
} }

View File

@ -5,8 +5,8 @@
#include "libbfd.h" #include "libbfd.h"
#include <libr/r_pdb.h> #include <libr/r_pdb.h>
#include "pdb-types.h"
typedef struct pdb_data_struct typedef struct pdb_data_struct {
{ R_PDB *pdb;
R_PDB* pdb;
} bfd_pdb_data_struct; } bfd_pdb_data_struct;

View File

@ -726,8 +726,7 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (), symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
symfile_flags, objfile); symfile_flags, objfile);
} }
else
if (debugfile.empty ())
{ {
gdb_bfd_ref_ptr debug_bfd (try_load_pdb_bfd (objfile)); gdb_bfd_ref_ptr debug_bfd (try_load_pdb_bfd (objfile));
if (debug_bfd.get ()) if (debug_bfd.get ())

View File

@ -45,19 +45,7 @@ extern "C" {
#include "psympriv.h" #include "psympriv.h"
//BEGIN radare2 imports #include "bfd/pdb-types.h"
#include "pdb_types.h"
typedef void (*parse_stream_) (void *stream, R_STREAM_FILE *stream_file);
typedef struct {
int indx;
parse_stream_ parse_stream;
void *stream;
EStream type;
free_func free;
} SStreamParseFunc;
//END radare2 imports
struct find_section_by_name_args { struct find_section_by_name_args {
const char *name; const char *name;
@ -199,13 +187,8 @@ get_codeview_pdb_path (objfile *objfile)
return nullopt; return nullopt;
bfd_byte *data = nullptr; bfd_byte *data = nullptr;
//TODO: Check if this leaks memory (data isn't freed)
if (!bfd_malloc_and_get_section (abfd, section, &data)) if (!bfd_malloc_and_get_section (abfd, section, &data))
{ return nullopt;
if (data != nullptr)
free (data);
return nullopt;
}
for (auto i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++) for (auto i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
{ {
@ -240,6 +223,8 @@ get_pdb_paths (struct objfile *objfile)
if (!codeview_pdb_path) if (!codeview_pdb_path)
return paths; //if there is no CodeView PDB path, we assume no PDB exists return paths; //if there is no CodeView PDB path, we assume no PDB exists
//TODO: Only push_back 'target:' paths if we have a remote target
paths.push_back (*codeview_pdb_path); paths.push_back (*codeview_pdb_path);
paths.push_back ("target:" + *codeview_pdb_path); paths.push_back ("target:" + *codeview_pdb_path);
@ -387,3 +372,43 @@ read_pdb (struct objfile *objfile, minimal_symbol_reader & reader)
pdb->finish_pdb_parse (pdb.get ()); pdb->finish_pdb_parse (pdb.get ());
} }
static void
pdb_sym_new_init (objfile *objfile)
{
}
static void
pdb_sym_init (objfile *objfile)
{
}
static void
pdb_sym_read (objfile *objfile, symfile_add_flags symfile_flags)
{
}
static void
pdb_sym_finish (objfile *objfile)
{
}
const struct sym_fns pdb_sym_fns = {
pdb_sym_new_init,
pdb_sym_init,
pdb_sym_read,
nullptr, /* sym_read_psymbols */
pdb_sym_finish,
default_symfile_offsets,
default_symfile_segments,
nullptr, /* sym_read_linetable */
default_symfile_relocate,
nullptr, /* sym_probe_fns */
&psym_functions
};
void
_initialize_pdb ()
{
add_symtab_fns (bfd_target_pdb_flavour, &pdb_sym_fns);
}

File diff suppressed because it is too large Load Diff