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_pdb_close_and_cleanup (bfd *abfd)
{
abfd->tdata.pdb_data->pdb->finish_pdb_parse (abfd->tdata.pdb_data->pdb);
return TRUE;
}
@ -17,11 +18,7 @@ bfd_pdb_bfd_free_cached_info (bfd *abfd)
}
/* Called when a new section is created. */
bfd_boolean
bfd_pdb_new_section_hook (bfd *abfd, asection *sec)
{
return FALSE;
}
#define bfd_pdb_new_section_hook _bfd_generic_new_section_hook
/* Read the contents of a section. */
#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;
}
asymbol *
bfd_pdb_make_empty_symbol (bfd *abfd)
{
return NULL;
}
#define bfd_pdb_make_empty_symbol _bfd_generic_make_empty_symbol
void
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
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_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
#define bfd_pdb_read_minisymbols _bfd_nosymbols_read_minisymbols
#define bfd_pdb_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
static st64
r_buffer_read (RBuffer *buffer, ut8 *out, ut64 length)
@ -126,14 +119,65 @@ get_bfd_pdb_data (bfd *abfd)
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 *
bfd_pdb_check_format (bfd *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;
}
fail:
bfd_set_error (bfd_error_wrong_format);
return NULL;
}

View File

@ -5,8 +5,8 @@
#include "libbfd.h"
#include <libr/r_pdb.h>
#include "pdb-types.h"
typedef struct pdb_data_struct
{
R_PDB* pdb;
typedef struct pdb_data_struct {
R_PDB *pdb;
} 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 (),
symfile_flags, objfile);
}
if (debugfile.empty ())
else
{
gdb_bfd_ref_ptr debug_bfd (try_load_pdb_bfd (objfile));
if (debug_bfd.get ())

View File

@ -45,19 +45,7 @@ extern "C" {
#include "psympriv.h"
//BEGIN radare2 imports
#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
#include "bfd/pdb-types.h"
struct find_section_by_name_args {
const char *name;
@ -199,13 +187,8 @@ get_codeview_pdb_path (objfile *objfile)
return nullopt;
bfd_byte *data = nullptr;
//TODO: Check if this leaks memory (data isn't freed)
if (!bfd_malloc_and_get_section (abfd, section, &data))
{
if (data != nullptr)
free (data);
return nullopt;
}
return nullopt;
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)
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 ("target:" + *codeview_pdb_path);
@ -387,3 +372,43 @@ read_pdb (struct objfile *objfile, minimal_symbol_reader & reader)
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