Allow gdb to find debug symbols file by build-id for PE file format also
This promotes BFD's struct elf_build_id to the generic struct bfd_build_id, populated when an ELF or PE BFD is read. gdb is updated to use that, and to use the build-id to find symbols for PE files also. There is currently no generic way to extract the build-id from an object file, perhaps an option to objdump to do this might make sense? On x86_64-pc-cygwin, gdb's sepdebug.exp changes: -# of unsupported tests 1 +# of expected passes 90 I don't seem to get consistent testsuite runs on i686-linux-gnu, but there don't appear to be any regressions. bfd/ChangeLog: 2015-06-10 Jon Turney <jon.turney@dronecode.org.uk> * elf-bfd.h : Remove struct elf_build_id. * bfd.c : Add struct bfd_build_id. * bfd-in2.h: Regenerate. * elf.c (elfobj_grok_gnu_build_id): Update to use bfd_build_id. * libpei.h: Add protoype and macros for bfd_XXi_slurp_codeview_record. * peXXigen.c (_bfd_XXi_slurp_codeview_record): Make public * peicode.h (pe_bfd_read_buildid): Add. (pe_bfd_object_p): Use pe_bfd_read_buildid(). gdb/ChangeLog: 2015-06-10 Jon Turney <jon.turney@dronecode.org.uk> * build-id.c: Don't include elf-bfd.h. (build_id_bfd_get): Use bfd_build_id. (build_id_verify): Ditto. * build-id.h: Ditto. (find_separate_debug_file_by_buildid): Ditto. * python/py-objfile.c: Don't include elf-bfd.h. (objfpy_get_build_id) Use bfd_build_id. (objfpy_build_id_matches, objfpy_lookup_objfile_by_build_id): Ditto. * coffread.c: Include build-id.h. (coff_symfile_read): Try find_separate_debug_file_by_buildid. gdb/doc/ChangeLog: 2015-06-10 Jon Turney <jon.turney@dronecode.org.uk> * gdb.texinfo (Separate Debug Files): Document that PE is also supported. gdb/testsuite/ChangeLog: 2015-06-10 Jon Turney <jon.turney@dronecode.org.uk> * gdb.base/sepdebug.exp: Add EXEEXT where needed. * lib/gdb.exp (get_build_id): Teach how to extract build-id from a PE file. * lib/future.exp (gdb_find_objdump): Add gdb_find_objdump. Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
This commit is contained in:
parent
f20c58f51f
commit
c74f7d1c6c
19 changed files with 231 additions and 66 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
2015-06-10 Jon Turney <jon.turney@dronecode.org.uk>
|
||||||
|
|
||||||
|
* elf-bfd.h : Remove struct elf_build_id.
|
||||||
|
* bfd.c : Add struct bfd_build_id.
|
||||||
|
* bfd-in2.h: Regenerate.
|
||||||
|
* elf.c (elfobj_grok_gnu_build_id): Update to use bfd_build_id.
|
||||||
|
* libpei.h: Add protoype and macros for
|
||||||
|
bfd_XXi_slurp_codeview_record.
|
||||||
|
* peXXigen.c (_bfd_XXi_slurp_codeview_record): Make public
|
||||||
|
* peicode.h (pe_bfd_read_buildid): Add.
|
||||||
|
(pe_bfd_object_p): Use pe_bfd_read_buildid().
|
||||||
|
|
||||||
2015-06-15 Renlin Li <renlin.li@arm.com>
|
2015-06-15 Renlin Li <renlin.li@arm.com>
|
||||||
|
|
||||||
* reloc.c (BFD_RELOC_AARCH64_LD64_GOTOFF_LO15): New entry.
|
* reloc.c (BFD_RELOC_AARCH64_LD64_GOTOFF_LO15): New entry.
|
||||||
|
|
|
@ -6326,6 +6326,12 @@ enum bfd_plugin_format
|
||||||
bfd_plugin_no = 2
|
bfd_plugin_no = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bfd_build_id
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
bfd_byte data[1];
|
||||||
|
};
|
||||||
|
|
||||||
struct bfd
|
struct bfd
|
||||||
{
|
{
|
||||||
/* The filename the application opened the BFD with. */
|
/* The filename the application opened the BFD with. */
|
||||||
|
@ -6610,6 +6616,9 @@ struct bfd
|
||||||
struct objalloc *, but we use void * to avoid requiring the inclusion
|
struct objalloc *, but we use void * to avoid requiring the inclusion
|
||||||
of objalloc.h. */
|
of objalloc.h. */
|
||||||
void *memory;
|
void *memory;
|
||||||
|
|
||||||
|
/* For input BFDs, the build ID, if the object has one. */
|
||||||
|
const struct bfd_build_id *build_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* See note beside bfd_set_section_userdata. */
|
/* See note beside bfd_set_section_userdata. */
|
||||||
|
|
|
@ -51,6 +51,12 @@ CODE_FRAGMENT
|
||||||
. bfd_plugin_no = 2
|
. bfd_plugin_no = 2
|
||||||
. };
|
. };
|
||||||
.
|
.
|
||||||
|
.struct bfd_build_id
|
||||||
|
. {
|
||||||
|
. size_t size;
|
||||||
|
. bfd_byte data[1];
|
||||||
|
. };
|
||||||
|
.
|
||||||
.struct bfd
|
.struct bfd
|
||||||
.{
|
.{
|
||||||
. {* The filename the application opened the BFD with. *}
|
. {* The filename the application opened the BFD with. *}
|
||||||
|
@ -335,6 +341,9 @@ CODE_FRAGMENT
|
||||||
. struct objalloc *, but we use void * to avoid requiring the inclusion
|
. struct objalloc *, but we use void * to avoid requiring the inclusion
|
||||||
. of objalloc.h. *}
|
. of objalloc.h. *}
|
||||||
. void *memory;
|
. void *memory;
|
||||||
|
.
|
||||||
|
. {* For input BFDs, the build ID, if the object has one. *}
|
||||||
|
. const struct bfd_build_id *build_id;
|
||||||
.};
|
.};
|
||||||
.
|
.
|
||||||
.{* See note beside bfd_set_section_userdata. *}
|
.{* See note beside bfd_set_section_userdata. *}
|
||||||
|
|
|
@ -1563,13 +1563,6 @@ struct sdt_note
|
||||||
bfd_byte data[1];
|
bfd_byte data[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* NT_GNU_BUILD_ID note type info for input BFDs. */
|
|
||||||
struct elf_build_id
|
|
||||||
{
|
|
||||||
size_t size;
|
|
||||||
bfd_byte data[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tdata information grabbed from an elf core file. */
|
/* tdata information grabbed from an elf core file. */
|
||||||
struct core_elf_obj_tdata
|
struct core_elf_obj_tdata
|
||||||
{
|
{
|
||||||
|
@ -1704,9 +1697,6 @@ struct elf_obj_tdata
|
||||||
obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
|
obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
|
||||||
obj_attribute_list *other_obj_attributes[2];
|
obj_attribute_list *other_obj_attributes[2];
|
||||||
|
|
||||||
/* NT_GNU_BUILD_ID note type. */
|
|
||||||
struct elf_build_id *build_id;
|
|
||||||
|
|
||||||
/* Linked-list containing information about every Systemtap section
|
/* Linked-list containing information about every Systemtap section
|
||||||
found in the object file. Each section corresponds to one entry
|
found in the object file. Each section corresponds to one entry
|
||||||
in the list. */
|
in the list. */
|
||||||
|
|
12
bfd/elf.c
12
bfd/elf.c
|
@ -9116,18 +9116,18 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
|
elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
|
||||||
{
|
{
|
||||||
struct elf_obj_tdata *t;
|
struct bfd_build_id* build_id;
|
||||||
|
|
||||||
if (note->descsz == 0)
|
if (note->descsz == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
t = elf_tdata (abfd);
|
build_id = bfd_alloc (abfd, sizeof (struct bfd_build_id) - 1 + note->descsz);
|
||||||
t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz);
|
if (build_id == NULL)
|
||||||
if (t->build_id == NULL)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
t->build_id->size = note->descsz;
|
build_id->size = note->descsz;
|
||||||
memcpy (t->build_id->data, note->descdata, note->descsz);
|
memcpy (build_id->data, note->descdata, note->descsz);
|
||||||
|
abfd->build_id = build_id;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,6 +238,7 @@
|
||||||
#define _bfd_XXi_swap_debugdir_in _bfd_pex64i_swap_debugdir_in
|
#define _bfd_XXi_swap_debugdir_in _bfd_pex64i_swap_debugdir_in
|
||||||
#define _bfd_XXi_swap_debugdir_out _bfd_pex64i_swap_debugdir_out
|
#define _bfd_XXi_swap_debugdir_out _bfd_pex64i_swap_debugdir_out
|
||||||
#define _bfd_XXi_write_codeview_record _bfd_pex64i_write_codeview_record
|
#define _bfd_XXi_write_codeview_record _bfd_pex64i_write_codeview_record
|
||||||
|
#define _bfd_XXi_slurp_codeview_record _bfd_pex64i_slurp_codeview_record
|
||||||
|
|
||||||
#elif defined COFF_WITH_pep
|
#elif defined COFF_WITH_pep
|
||||||
|
|
||||||
|
@ -272,6 +273,7 @@
|
||||||
#define _bfd_XXi_swap_debugdir_in _bfd_pepi_swap_debugdir_in
|
#define _bfd_XXi_swap_debugdir_in _bfd_pepi_swap_debugdir_in
|
||||||
#define _bfd_XXi_swap_debugdir_out _bfd_pepi_swap_debugdir_out
|
#define _bfd_XXi_swap_debugdir_out _bfd_pepi_swap_debugdir_out
|
||||||
#define _bfd_XXi_write_codeview_record _bfd_pepi_write_codeview_record
|
#define _bfd_XXi_write_codeview_record _bfd_pepi_write_codeview_record
|
||||||
|
#define _bfd_XXi_slurp_codeview_record _bfd_pepi_slurp_codeview_record
|
||||||
|
|
||||||
#else /* !COFF_WITH_pep */
|
#else /* !COFF_WITH_pep */
|
||||||
|
|
||||||
|
@ -306,6 +308,7 @@
|
||||||
#define _bfd_XXi_swap_debugdir_in _bfd_pei_swap_debugdir_in
|
#define _bfd_XXi_swap_debugdir_in _bfd_pei_swap_debugdir_in
|
||||||
#define _bfd_XXi_swap_debugdir_out _bfd_pei_swap_debugdir_out
|
#define _bfd_XXi_swap_debugdir_out _bfd_pei_swap_debugdir_out
|
||||||
#define _bfd_XXi_write_codeview_record _bfd_pei_write_codeview_record
|
#define _bfd_XXi_write_codeview_record _bfd_pei_write_codeview_record
|
||||||
|
#define _bfd_XXi_slurp_codeview_record _bfd_pei_slurp_codeview_record
|
||||||
|
|
||||||
#endif /* !COFF_WITH_pep */
|
#endif /* !COFF_WITH_pep */
|
||||||
|
|
||||||
|
@ -351,6 +354,7 @@ bfd_boolean _bfd_XXi_final_link_postscript (bfd *, struct coff_final_link_info *
|
||||||
void _bfd_XXi_swap_debugdir_in (bfd *, void *, void *);
|
void _bfd_XXi_swap_debugdir_in (bfd *, void *, void *);
|
||||||
unsigned _bfd_XXi_swap_debugdir_out (bfd *, void *, void *);
|
unsigned _bfd_XXi_swap_debugdir_out (bfd *, void *, void *);
|
||||||
unsigned _bfd_XXi_write_codeview_record (bfd *, file_ptr, CODEVIEW_INFO *);
|
unsigned _bfd_XXi_write_codeview_record (bfd *, file_ptr, CODEVIEW_INFO *);
|
||||||
|
CODEVIEW_INFO * _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo);
|
||||||
|
|
||||||
/* The following are needed only for ONE of pe or pei, but don't
|
/* The following are needed only for ONE of pe or pei, but don't
|
||||||
otherwise vary; peicode.h fixes up ifdefs but we provide the
|
otherwise vary; peicode.h fixes up ifdefs but we provide the
|
||||||
|
|
|
@ -1140,7 +1140,7 @@ _bfd_XXi_swap_debugdir_out (bfd * abfd, void * inp, void * extp)
|
||||||
return sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
|
return sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CODEVIEW_INFO *
|
CODEVIEW_INFO *
|
||||||
_bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo)
|
_bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo)
|
||||||
{
|
{
|
||||||
char buffer[256+1];
|
char buffer[256+1];
|
||||||
|
|
100
bfd/peicode.h
100
bfd/peicode.h
|
@ -1255,6 +1255,87 @@ pe_ILF_object_p (bfd * abfd)
|
||||||
return abfd->xvec;
|
return abfd->xvec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pe_bfd_read_buildid(bfd *abfd)
|
||||||
|
{
|
||||||
|
pe_data_type *pe = pe_data (abfd);
|
||||||
|
struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
|
||||||
|
asection *section;
|
||||||
|
bfd_byte *data = 0;
|
||||||
|
bfd_size_type dataoff;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
|
||||||
|
bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
addr += extra->ImageBase;
|
||||||
|
|
||||||
|
/* Search for the section containing the DebugDirectory */
|
||||||
|
for (section = abfd->sections; section != NULL; section = section->next)
|
||||||
|
{
|
||||||
|
if ((addr >= section->vma) && (addr < (section->vma + section->size)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (section == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!(section->flags & SEC_HAS_CONTENTS))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataoff = addr - section->vma;
|
||||||
|
|
||||||
|
/* Read the whole section. */
|
||||||
|
if (!bfd_malloc_and_get_section (abfd, section, &data))
|
||||||
|
{
|
||||||
|
if (data != NULL)
|
||||||
|
free (data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search for a CodeView entry in the DebugDirectory */
|
||||||
|
for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
|
||||||
|
{
|
||||||
|
struct external_IMAGE_DEBUG_DIRECTORY *ext
|
||||||
|
= &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
|
||||||
|
struct internal_IMAGE_DEBUG_DIRECTORY idd;
|
||||||
|
|
||||||
|
_bfd_XXi_swap_debugdir_in (abfd, ext, &idd);
|
||||||
|
|
||||||
|
if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
|
||||||
|
{
|
||||||
|
char buffer[256 + 1];
|
||||||
|
CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The debug entry doesn't have to have to be in a section, in which
|
||||||
|
case AddressOfRawData is 0, so always use PointerToRawData.
|
||||||
|
*/
|
||||||
|
if (_bfd_XXi_slurp_codeview_record (abfd,
|
||||||
|
(file_ptr) idd.PointerToRawData,
|
||||||
|
idd.SizeOfData, cvinfo))
|
||||||
|
{
|
||||||
|
struct bfd_build_id* build_id = bfd_alloc(abfd,
|
||||||
|
sizeof(struct bfd_build_id) + cvinfo->SignatureLength);
|
||||||
|
if (build_id)
|
||||||
|
{
|
||||||
|
build_id->size = cvinfo->SignatureLength;
|
||||||
|
memcpy(build_id->data, cvinfo->Signature,
|
||||||
|
cvinfo->SignatureLength);
|
||||||
|
abfd->build_id = build_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const bfd_target *
|
static const bfd_target *
|
||||||
pe_bfd_object_p (bfd * abfd)
|
pe_bfd_object_p (bfd * abfd)
|
||||||
{
|
{
|
||||||
|
@ -1265,6 +1346,7 @@ pe_bfd_object_p (bfd * abfd)
|
||||||
struct internal_aouthdr internal_a;
|
struct internal_aouthdr internal_a;
|
||||||
file_ptr opt_hdr_size;
|
file_ptr opt_hdr_size;
|
||||||
file_ptr offset;
|
file_ptr offset;
|
||||||
|
const bfd_target *result;
|
||||||
|
|
||||||
/* Detect if this a Microsoft Import Library Format element. */
|
/* Detect if this a Microsoft Import Library Format element. */
|
||||||
/* First read the beginning of the header. */
|
/* First read the beginning of the header. */
|
||||||
|
@ -1358,10 +1440,20 @@ pe_bfd_object_p (bfd * abfd)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
|
|
||||||
(opt_hdr_size != 0
|
result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
|
||||||
? &internal_a
|
(opt_hdr_size != 0
|
||||||
: (struct internal_aouthdr *) NULL));
|
? &internal_a
|
||||||
|
: (struct internal_aouthdr *) NULL));
|
||||||
|
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
/* Now the whole header has been processed, see if there is a build-id */
|
||||||
|
pe_bfd_read_buildid(abfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define coff_object_p pe_bfd_object_p
|
#define coff_object_p pe_bfd_object_p
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
2015-06-10 Jon Turney <jon.turney@dronecode.org.uk>
|
||||||
|
|
||||||
|
* build-id.c: Don't include elf-bfd.h.
|
||||||
|
(build_id_bfd_get): Use bfd_build_id.
|
||||||
|
(build_id_verify): Ditto.
|
||||||
|
* build-id.h: Ditto.
|
||||||
|
(find_separate_debug_file_by_buildid): Ditto.
|
||||||
|
* python/py-objfile.c: Don't include elf-bfd.h.
|
||||||
|
(objfpy_get_build_id) Use bfd_build_id.
|
||||||
|
(objfpy_build_id_matches, objfpy_lookup_objfile_by_build_id): Ditto.
|
||||||
|
* coffread.c: Include build-id.h.
|
||||||
|
(coff_symfile_read): Try find_separate_debug_file_by_buildid.
|
||||||
|
|
||||||
2015-06-03 Jon Turney <jon.turney@dronecode.org.uk>
|
2015-06-03 Jon Turney <jon.turney@dronecode.org.uk>
|
||||||
|
|
||||||
* windows-nat.c (do_windows_fetch_inferior_registers)
|
* windows-nat.c (do_windows_fetch_inferior_registers)
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "elf-bfd.h"
|
|
||||||
#include "gdb_bfd.h"
|
#include "gdb_bfd.h"
|
||||||
#include "build-id.h"
|
#include "build-id.h"
|
||||||
#include "gdb_vecs.h"
|
#include "gdb_vecs.h"
|
||||||
|
@ -30,19 +29,17 @@
|
||||||
|
|
||||||
/* See build-id.h. */
|
/* See build-id.h. */
|
||||||
|
|
||||||
const struct elf_build_id *
|
const struct bfd_build_id *
|
||||||
build_id_bfd_get (bfd *abfd)
|
build_id_bfd_get (bfd *abfd)
|
||||||
{
|
{
|
||||||
if (!bfd_check_format (abfd, bfd_object)
|
if (!bfd_check_format (abfd, bfd_object))
|
||||||
|| bfd_get_flavour (abfd) != bfd_target_elf_flavour
|
|
||||||
/* Although this is ELF_specific, it is safe to do in generic
|
|
||||||
code because it does not rely on any ELF-specific symbols at
|
|
||||||
link time, and if the ELF code is not available in BFD, then
|
|
||||||
ABFD will not have the ELF flavour. */
|
|
||||||
|| elf_tdata (abfd)->build_id == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return elf_tdata (abfd)->build_id;
|
if (abfd->build_id != NULL)
|
||||||
|
return abfd->build_id;
|
||||||
|
|
||||||
|
/* No build-id */
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See build-id.h. */
|
/* See build-id.h. */
|
||||||
|
@ -50,7 +47,7 @@ build_id_bfd_get (bfd *abfd)
|
||||||
int
|
int
|
||||||
build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
|
build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
|
||||||
{
|
{
|
||||||
const struct elf_build_id *found;
|
const struct bfd_build_id *found;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
found = build_id_bfd_get (abfd);
|
found = build_id_bfd_get (abfd);
|
||||||
|
@ -139,7 +136,7 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id)
|
||||||
char *
|
char *
|
||||||
find_separate_debug_file_by_buildid (struct objfile *objfile)
|
find_separate_debug_file_by_buildid (struct objfile *objfile)
|
||||||
{
|
{
|
||||||
const struct elf_build_id *build_id;
|
const struct bfd_build_id *build_id;
|
||||||
|
|
||||||
build_id = build_id_bfd_get (objfile->obfd);
|
build_id = build_id_bfd_get (objfile->obfd);
|
||||||
if (build_id != NULL)
|
if (build_id != NULL)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */
|
/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */
|
||||||
|
|
||||||
extern const struct elf_build_id *build_id_bfd_get (bfd *abfd);
|
extern const struct bfd_build_id *build_id_bfd_get (bfd *abfd);
|
||||||
|
|
||||||
/* Return true if ABFD has NT_GNU_BUILD_ID matching the CHECK value.
|
/* Return true if ABFD has NT_GNU_BUILD_ID matching the CHECK value.
|
||||||
Otherwise, issue a warning and return false. */
|
Otherwise, issue a warning and return false. */
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "coff-pe-read.h"
|
#include "coff-pe-read.h"
|
||||||
|
|
||||||
#include "psymtab.h"
|
#include "psymtab.h"
|
||||||
|
#include "build-id.h"
|
||||||
|
|
||||||
extern void _initialize_coffread (void);
|
extern void _initialize_coffread (void);
|
||||||
|
|
||||||
|
@ -738,7 +739,10 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags)
|
||||||
{
|
{
|
||||||
char *debugfile;
|
char *debugfile;
|
||||||
|
|
||||||
debugfile = find_separate_debug_file_by_debuglink (objfile);
|
debugfile = find_separate_debug_file_by_buildid (objfile);
|
||||||
|
|
||||||
|
if (debugfile == NULL)
|
||||||
|
debugfile = find_separate_debug_file_by_debuglink (objfile);
|
||||||
make_cleanup (xfree, debugfile);
|
make_cleanup (xfree, debugfile);
|
||||||
|
|
||||||
if (debugfile)
|
if (debugfile)
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2015-06-10 Jon Turney <jon.turney@dronecode.org.uk>
|
||||||
|
|
||||||
|
* gdb.texinfo (Separate Debug Files): Document that PE is also
|
||||||
|
supported.
|
||||||
|
|
||||||
2015-06-13 Andrew Burgess <andrew.burgess@embecosm.com>
|
2015-06-13 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* gdb.texinfo (TUI Commands): Bring all 'tui reg' commands into a
|
* gdb.texinfo (TUI Commands): Bring all 'tui reg' commands into a
|
||||||
|
|
|
@ -18170,7 +18170,7 @@ the executable and the debug file came from the same build.
|
||||||
@item
|
@item
|
||||||
The executable contains a @dfn{build ID}, a unique bit string that is
|
The executable contains a @dfn{build ID}, a unique bit string that is
|
||||||
also present in the corresponding debug info file. (This is supported
|
also present in the corresponding debug info file. (This is supported
|
||||||
only on some operating systems, notably those which use the ELF format
|
only on some operating systems, when using the ELF or PE file formats
|
||||||
for binary files and the @sc{gnu} Binutils.) For more details about
|
for binary files and the @sc{gnu} Binutils.) For more details about
|
||||||
this feature, see the description of the @option{--build-id}
|
this feature, see the description of the @option{--build-id}
|
||||||
command-line option in @ref{Options, , Command Line Options, ld.info,
|
command-line option in @ref{Options, , Command Line Options, ld.info,
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
#include "build-id.h"
|
#include "build-id.h"
|
||||||
#include "elf-bfd.h"
|
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -134,7 +133,7 @@ objfpy_get_build_id (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
objfile_object *obj = (objfile_object *) self;
|
objfile_object *obj = (objfile_object *) self;
|
||||||
struct objfile *objfile = obj->objfile;
|
struct objfile *objfile = obj->objfile;
|
||||||
const struct elf_build_id *build_id = NULL;
|
const struct bfd_build_id *build_id = NULL;
|
||||||
|
|
||||||
OBJFPY_REQUIRE_VALID (obj);
|
OBJFPY_REQUIRE_VALID (obj);
|
||||||
|
|
||||||
|
@ -484,7 +483,7 @@ objfpy_build_id_ok (const char *string)
|
||||||
It is assumed that objfpy_build_id_ok (string) returns TRUE. */
|
It is assumed that objfpy_build_id_ok (string) returns TRUE. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
objfpy_build_id_matches (const struct elf_build_id *build_id,
|
objfpy_build_id_matches (const struct bfd_build_id *build_id,
|
||||||
const char *string)
|
const char *string)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -542,7 +541,7 @@ objfpy_lookup_objfile_by_build_id (const char *build_id)
|
||||||
|
|
||||||
ALL_OBJFILES (objfile)
|
ALL_OBJFILES (objfile)
|
||||||
{
|
{
|
||||||
const struct elf_build_id *obfd_build_id;
|
const struct bfd_build_id *obfd_build_id;
|
||||||
|
|
||||||
if (objfile->obfd == NULL)
|
if (objfile->obfd == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2015-06-10 Jon Turney <jon.turney@dronecode.org.uk>
|
||||||
|
|
||||||
|
* gdb.base/sepdebug.exp: Add EXEEXT where needed.
|
||||||
|
* lib/gdb.exp (get_build_id): Teach how to extract build-id from a
|
||||||
|
PE file.
|
||||||
|
* lib/future.exp (gdb_find_objdump): Add gdb_find_objdump.
|
||||||
|
|
||||||
2015-06-12 Antoine Tremblay <antoine.tremblay@ericsson.com>
|
2015-06-12 Antoine Tremblay <antoine.tremblay@ericsson.com>
|
||||||
|
|
||||||
PR breakpoints/16465
|
PR breakpoints/16465
|
||||||
|
|
|
@ -42,7 +42,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
|
||||||
# the name of a debuginfo only file. This file will be stored in the
|
# the name of a debuginfo only file. This file will be stored in the
|
||||||
# gdb.base/ subdirectory.
|
# gdb.base/ subdirectory.
|
||||||
|
|
||||||
if [gdb_gnu_strip_debug $binfile] {
|
if [gdb_gnu_strip_debug $binfile$EXEEXT] {
|
||||||
# check that you have a recent version of strip and objcopy installed
|
# check that you have a recent version of strip and objcopy installed
|
||||||
unsupported "cannot produce separate debug info files"
|
unsupported "cannot produce separate debug info files"
|
||||||
return -1
|
return -1
|
||||||
|
@ -60,7 +60,7 @@ set new_name [standard_output_file ${testfile}${EXEEXT}]
|
||||||
remote_exec build "rm -rf [file dirname $new_name]"
|
remote_exec build "rm -rf [file dirname $new_name]"
|
||||||
|
|
||||||
remote_exec build "mkdir [file dirname $new_name]"
|
remote_exec build "mkdir [file dirname $new_name]"
|
||||||
remote_exec build "ln -s ${binfile} $new_name"
|
remote_exec build "ln -s ${binfile}${EXEEXT} $new_name"
|
||||||
clean_restart ${testfile}${EXEEXT}
|
clean_restart ${testfile}${EXEEXT}
|
||||||
if { $gdb_file_cmd_debug_info != "debug" } then {
|
if { $gdb_file_cmd_debug_info != "debug" } then {
|
||||||
fail "No debug information found."
|
fail "No debug information found."
|
||||||
|
@ -716,10 +716,10 @@ proc test_different_dir {type test_different_dir xfail} {
|
||||||
# the "set debug-file-directory" command.
|
# the "set debug-file-directory" command.
|
||||||
|
|
||||||
set different_dir [standard_output_file ${testfile}.dir]
|
set different_dir [standard_output_file ${testfile}.dir]
|
||||||
set debugfile "${different_dir}/[standard_output_file ${testfile}.debug]"
|
set debugfile "${different_dir}/[standard_output_file ${testfile}${EXEEXT}.debug]"
|
||||||
remote_exec build "rm -rf $different_dir"
|
remote_exec build "rm -rf $different_dir"
|
||||||
remote_exec build "mkdir -p [file dirname $debugfile]"
|
remote_exec build "mkdir -p [file dirname $debugfile]"
|
||||||
remote_exec build "mv -f [standard_output_file ${testfile}.debug] $debugfile"
|
remote_exec build "mv -f [standard_output_file ${testfile}${EXEEXT}.debug] $debugfile"
|
||||||
|
|
||||||
test_different_dir debuglink $different_dir 0
|
test_different_dir debuglink $different_dir 0
|
||||||
|
|
||||||
|
@ -727,7 +727,7 @@ test_different_dir debuglink $different_dir 0
|
||||||
# Test CRC mismatch is reported.
|
# Test CRC mismatch is reported.
|
||||||
|
|
||||||
if {[build_executable sepdebug.exp sepdebug2 sepdebug2.c debug] != -1
|
if {[build_executable sepdebug.exp sepdebug2 sepdebug2.c debug] != -1
|
||||||
&& ![gdb_gnu_strip_debug [standard_output_file sepdebug2]]} {
|
&& ![gdb_gnu_strip_debug [standard_output_file sepdebug2]$EXEEXT]} {
|
||||||
|
|
||||||
remote_exec build "cp ${debugfile} [standard_output_file sepdebug2.debug]"
|
remote_exec build "cp ${debugfile} [standard_output_file sepdebug2.debug]"
|
||||||
|
|
||||||
|
@ -743,7 +743,7 @@ if {[build_executable sepdebug.exp sepdebug2 sepdebug2.c debug] != -1
|
||||||
|
|
||||||
# NT_GNU_BUILD_ID / .note.gnu.build-id test:
|
# NT_GNU_BUILD_ID / .note.gnu.build-id test:
|
||||||
|
|
||||||
set build_id_debug_filename [build_id_debug_filename_get $binfile]
|
set build_id_debug_filename [build_id_debug_filename_get $binfile$EXEEXT]
|
||||||
if ![string compare $build_id_debug_filename ""] then {
|
if ![string compare $build_id_debug_filename ""] then {
|
||||||
unsupported "build-id is not supported by the compiler"
|
unsupported "build-id is not supported by the compiler"
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,17 @@ proc gdb_find_objcopy {} {
|
||||||
return $objcopy
|
return $objcopy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# find target objdump
|
||||||
|
proc gdb_find_objdump {} {
|
||||||
|
global OBJDUMP_FOR_TARGET
|
||||||
|
if [info exists OBJDUMP_FOR_TARGET] {
|
||||||
|
set objdump $OBJDUMP_FOR_TARGET
|
||||||
|
} else {
|
||||||
|
set objdump [transform objdump]
|
||||||
|
}
|
||||||
|
return $objdump
|
||||||
|
}
|
||||||
|
|
||||||
proc gdb_find_readelf {} {
|
proc gdb_find_readelf {} {
|
||||||
global READELF_FOR_TARGET
|
global READELF_FOR_TARGET
|
||||||
if [info exists READELF_FOR_TARGET] {
|
if [info exists READELF_FOR_TARGET] {
|
||||||
|
|
|
@ -4539,28 +4539,41 @@ gdb_caching_proc gdb_has_argv0 {
|
||||||
# Returns "" if there is none.
|
# Returns "" if there is none.
|
||||||
|
|
||||||
proc get_build_id { filename } {
|
proc get_build_id { filename } {
|
||||||
set tmp [standard_output_file "${filename}-tmp"]
|
if { ([istarget "*-*-mingw*"]
|
||||||
set objcopy_program [gdb_find_objcopy]
|
|| [istarget *-*-cygwin*]) } {
|
||||||
|
set objdump_program [gdb_find_objdump]
|
||||||
set result [catch "exec $objcopy_program -j .note.gnu.build-id -O binary $filename $tmp" output]
|
set result [catch {set data [exec $objdump_program -p $filename | grep signature | cut "-d " -f4]} output]
|
||||||
verbose "result is $result"
|
verbose "result is $result"
|
||||||
verbose "output is $output"
|
verbose "output is $output"
|
||||||
if {$result == 1} {
|
if {$result == 1} {
|
||||||
return ""
|
return ""
|
||||||
|
}
|
||||||
|
return $data
|
||||||
}
|
}
|
||||||
set fi [open $tmp]
|
else
|
||||||
fconfigure $fi -translation binary
|
{
|
||||||
# Skip the NOTE header.
|
set tmp [standard_output_file "${filename}-tmp"]
|
||||||
read $fi 16
|
set objcopy_program [gdb_find_objcopy]
|
||||||
set data [read $fi]
|
set result [catch "exec $objcopy_program -j .note.gnu.build-id -O binary $filename $tmp" output]
|
||||||
close $fi
|
verbose "result is $result"
|
||||||
file delete $tmp
|
verbose "output is $output"
|
||||||
if ![string compare $data ""] then {
|
if {$result == 1} {
|
||||||
return ""
|
return ""
|
||||||
|
}
|
||||||
|
set fi [open $tmp]
|
||||||
|
fconfigure $fi -translation binary
|
||||||
|
# Skip the NOTE header.
|
||||||
|
read $fi 16
|
||||||
|
set data [read $fi]
|
||||||
|
close $fi
|
||||||
|
file delete $tmp
|
||||||
|
if ![string compare $data ""] then {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
# Convert it to hex.
|
||||||
|
binary scan $data H* data
|
||||||
|
return $data
|
||||||
}
|
}
|
||||||
# Convert it to hex.
|
|
||||||
binary scan $data H* data
|
|
||||||
return $data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return the build-id hex string (usually 160 bits as 40 hex characters)
|
# Return the build-id hex string (usually 160 bits as 40 hex characters)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue