Implement PDB section loading in bfd
This commit is contained in:
parent
dcae9fd7d7
commit
c3184e01ce
File diff suppressed because it is too large
Load Diff
70
bfd/pdb.c
70
bfd/pdb.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 ())
|
||||||
|
|
63
gdb/pdb.c
63
gdb/pdb.c
|
@ -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);
|
||||||
|
}
|
1277
gdb/pdb_types.h
1277
gdb/pdb_types.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue