New python attribute gdb.Objfile.build_id.
gdb/ChangeLog: * NEWS: Mention gdb.Objfile.build_id. * build-id.c (build_id_bfd_get): Make non-static. * build-id.h (build_id_bfd_get): Add declaration. * python/py-objfile.c: #include "build-id.h", "elf-bfd.h". (OBJFPY_REQUIRE_VALID): New macro. (objfpy_get_build_id): New function. (objfile_getset): Add "build_id". * utils.c (make_hex_string): New function. * utils.h (make_hex_string): Add declaration. gdb/doc/ChangeLog: * python.texi (Objfiles In Python): Document Objfile.build_id. gdb/testsuite/ChangeLog: * lib/gdb.exp (get_build_id): New function. (build_id_debug_filename_get): Rewrite to use it. * gdb.python/py-objfile.exp: Add test for objfile.build_id.
This commit is contained in:
parent
fbad6518c1
commit
7c50a93137
12 changed files with 138 additions and 8 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
2014-12-04 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
* NEWS: Mention gdb.Objfile.build_id.
|
||||||
|
* build-id.c (build_id_bfd_get): Make non-static.
|
||||||
|
* build-id.h (build_id_bfd_get): Add declaration.
|
||||||
|
* python/py-objfile.c: #include "build-id.h", "elf-bfd.h".
|
||||||
|
(OBJFPY_REQUIRE_VALID): New macro.
|
||||||
|
(objfpy_get_build_id): New function.
|
||||||
|
(objfile_getset): Add "build_id".
|
||||||
|
* utils.c (make_hex_string): New function.
|
||||||
|
* utils.h (make_hex_string): Add declaration.
|
||||||
|
|
||||||
2014-12-04 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2014-12-04 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
* block.c (block_lookup_symbol_primary): New function.
|
* block.c (block_lookup_symbol_primary): New function.
|
||||||
|
|
2
gdb/NEWS
2
gdb/NEWS
|
@ -21,6 +21,8 @@
|
||||||
** New attribute 'producer' for gdb.Symtab objects.
|
** New attribute 'producer' for gdb.Symtab objects.
|
||||||
** gdb.Objfile objects have a new attribute "progspace",
|
** gdb.Objfile objects have a new attribute "progspace",
|
||||||
which is the gdb.Progspace object of the containing program space.
|
which is the gdb.Progspace object of the containing program space.
|
||||||
|
** gdb.Objfile objects have a new attribute "build_id",
|
||||||
|
which is the build ID generated when the file was built.
|
||||||
** A new event "gdb.clear_objfiles" has been added, triggered when
|
** A new event "gdb.clear_objfiles" has been added, triggered when
|
||||||
selecting a new file to debug.
|
selecting a new file to debug.
|
||||||
** You can now add attributes to gdb.Objfile and gdb.Progspace objects.
|
** You can now add attributes to gdb.Objfile and gdb.Progspace objects.
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "filenames.h"
|
#include "filenames.h"
|
||||||
|
|
||||||
/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */
|
/* See build-id.h. */
|
||||||
|
|
||||||
static const struct elf_build_id *
|
const struct elf_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)
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
#ifndef BUILD_ID_H
|
#ifndef BUILD_ID_H
|
||||||
#define BUILD_ID_H
|
#define BUILD_ID_H
|
||||||
|
|
||||||
|
/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */
|
||||||
|
|
||||||
|
extern const struct elf_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. */
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2014-12-04 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
* python.texi (Objfiles In Python): Document Objfile.build_id.
|
||||||
|
|
||||||
2014-12-02 Nick Bull <nicholaspbull@gmail.com>
|
2014-12-02 Nick Bull <nicholaspbull@gmail.com>
|
||||||
|
|
||||||
* python.texi (Events In Python): Document new events
|
* python.texi (Events In Python): Document new events
|
||||||
|
|
|
@ -3495,6 +3495,17 @@ class.
|
||||||
The file name of the objfile as a string.
|
The file name of the objfile as a string.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
|
@defvar Objfile.build_id
|
||||||
|
The build ID of the objfile as a string.
|
||||||
|
If the objfile does not have a build ID then the value is @code{None}.
|
||||||
|
|
||||||
|
This is supported only on some operating systems, notably those which use
|
||||||
|
the ELF format for binary files and the @sc{gnu} Binutils. For more details
|
||||||
|
about this feature, see the description of the @option{--build-id}
|
||||||
|
command-line option in @ref{Options, , Command Line Options, ld.info,
|
||||||
|
The GNU Linker}.
|
||||||
|
@end defvar
|
||||||
|
|
||||||
@defvar Objfile.progspace
|
@defvar Objfile.progspace
|
||||||
The containing program space of the objfile as a @code{gdb.Progspace}
|
The containing program space of the objfile as a @code{gdb.Progspace}
|
||||||
object. @xref{Progspaces In Python}.
|
object. @xref{Progspaces In Python}.
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include "charset.h"
|
#include "charset.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
|
#include "build-id.h"
|
||||||
|
#include "elf-bfd.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -51,9 +53,21 @@ static PyTypeObject objfile_object_type
|
||||||
|
|
||||||
static const struct objfile_data *objfpy_objfile_data_key;
|
static const struct objfile_data *objfpy_objfile_data_key;
|
||||||
|
|
||||||
|
/* Require that OBJF be a valid objfile. */
|
||||||
|
#define OBJFPY_REQUIRE_VALID(obj) \
|
||||||
|
do { \
|
||||||
|
if (!(obj)->objfile) \
|
||||||
|
{ \
|
||||||
|
PyErr_SetString (PyExc_RuntimeError, \
|
||||||
|
_("Objfile no longer exists.")); \
|
||||||
|
return NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* An Objfile method which returns the objfile's file name, or None. */
|
/* An Objfile method which returns the objfile's file name, or None. */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
objfpy_get_filename (PyObject *self, void *closure)
|
objfpy_get_filename (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
|
@ -66,6 +80,38 @@ objfpy_get_filename (PyObject *self, void *closure)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* An Objfile method which returns the objfile's build id, or None. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
objfpy_get_build_id (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
objfile_object *obj = (objfile_object *) self;
|
||||||
|
struct objfile *objfile = obj->objfile;
|
||||||
|
const struct elf_build_id *build_id = NULL;
|
||||||
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
|
OBJFPY_REQUIRE_VALID (obj);
|
||||||
|
|
||||||
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
build_id = build_id_bfd_get (objfile->obfd);
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
if (build_id != NULL)
|
||||||
|
{
|
||||||
|
char *hex_form = make_hex_string (build_id->data, build_id->size);
|
||||||
|
PyObject *result;
|
||||||
|
|
||||||
|
result = PyString_Decode (hex_form, strlen (hex_form),
|
||||||
|
host_charset (), NULL);
|
||||||
|
xfree (hex_form);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* An Objfile method which returns the objfile's progspace, or None. */
|
/* An Objfile method which returns the objfile's progspace, or None. */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -364,6 +410,8 @@ static PyGetSetDef objfile_getset[] =
|
||||||
"The __dict__ for this objfile.", &objfile_object_type },
|
"The __dict__ for this objfile.", &objfile_object_type },
|
||||||
{ "filename", objfpy_get_filename, NULL,
|
{ "filename", objfpy_get_filename, NULL,
|
||||||
"The objfile's filename, or None.", NULL },
|
"The objfile's filename, or None.", NULL },
|
||||||
|
{ "build_id", objfpy_get_build_id, NULL,
|
||||||
|
"The objfile's build id, or None.", NULL },
|
||||||
{ "progspace", objfpy_get_progspace, NULL,
|
{ "progspace", objfpy_get_progspace, NULL,
|
||||||
"The objfile's progspace, or None.", NULL },
|
"The objfile's progspace, or None.", NULL },
|
||||||
{ "pretty_printers", objfpy_get_printers, objfpy_set_printers,
|
{ "pretty_printers", objfpy_get_printers, objfpy_set_printers,
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2014-12-04 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
* lib/gdb.exp (get_build_id): New function.
|
||||||
|
(build_id_debug_filename_get): Rewrite to use it.
|
||||||
|
* gdb.python/py-objfile.exp: Add test for objfile.build_id.
|
||||||
|
|
||||||
2014-12-04 Maciej W. Rozycki <macro@codesourcery.com>
|
2014-12-04 Maciej W. Rozycki <macro@codesourcery.com>
|
||||||
|
|
||||||
* gdb.cp/expand-psymtabs-cxx.exp: Accept any address of
|
* gdb.cp/expand-psymtabs-cxx.exp: Accept any address of
|
||||||
|
|
|
@ -39,6 +39,16 @@ gdb_py_test_silent_cmd "python objfile = sym\[0\].symtab.objfile" \
|
||||||
|
|
||||||
gdb_test "python print (objfile.filename)" ".*py-objfile.*" \
|
gdb_test "python print (objfile.filename)" ".*py-objfile.*" \
|
||||||
"Get objfile file name"
|
"Get objfile file name"
|
||||||
|
|
||||||
|
set binfile_build_id [get_build_id $binfile]
|
||||||
|
if [string compare $binfile_build_id ""] {
|
||||||
|
verbose -log "binfile_build_id = $binfile_build_id"
|
||||||
|
gdb_test "python print (objfile.build_id)" "$binfile_build_id" \
|
||||||
|
"Get objfile build id"
|
||||||
|
} else {
|
||||||
|
unsupported "build-id is not supported by the compiler"
|
||||||
|
}
|
||||||
|
|
||||||
gdb_test "python print (objfile.progspace)" "<gdb\.Progspace object at .*>" \
|
gdb_test "python print (objfile.progspace)" "<gdb\.Progspace object at .*>" \
|
||||||
"Get objfile program space"
|
"Get objfile program space"
|
||||||
gdb_test "python print (objfile.is_valid())" "True" \
|
gdb_test "python print (objfile.is_valid())" "True" \
|
||||||
|
|
|
@ -4330,14 +4330,14 @@ gdb_caching_proc gdb_has_argv0 {
|
||||||
# foo.debug --> foo's debug info
|
# foo.debug --> foo's debug info
|
||||||
# foo --> like foo, but with a new .gnu_debuglink section pointing to foo.debug.
|
# foo --> like foo, but with a new .gnu_debuglink section pointing to foo.debug.
|
||||||
|
|
||||||
# Return the build-id hex string (usually 160 bits as 40 hex characters)
|
# Fetch the build id from the file.
|
||||||
# converted to the form: .build-id/ab/cdef1234...89.debug
|
# Returns "" if there is none.
|
||||||
# Return "" if no build-id found.
|
|
||||||
proc build_id_debug_filename_get { exec } {
|
proc get_build_id { filename } {
|
||||||
set tmp [standard_output_file "${exec}-tmp"]
|
set tmp [standard_output_file "${filename}-tmp"]
|
||||||
set objcopy_program [gdb_find_objcopy]
|
set objcopy_program [gdb_find_objcopy]
|
||||||
|
|
||||||
set result [catch "exec $objcopy_program -j .note.gnu.build-id -O binary $exec $tmp" output]
|
set result [catch "exec $objcopy_program -j .note.gnu.build-id -O binary $filename $tmp" output]
|
||||||
verbose "result is $result"
|
verbose "result is $result"
|
||||||
verbose "output is $output"
|
verbose "output is $output"
|
||||||
if {$result == 1} {
|
if {$result == 1} {
|
||||||
|
@ -4355,6 +4355,17 @@ proc build_id_debug_filename_get { exec } {
|
||||||
}
|
}
|
||||||
# Convert it to hex.
|
# Convert it to hex.
|
||||||
binary scan $data H* data
|
binary scan $data H* data
|
||||||
|
return $data
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return the build-id hex string (usually 160 bits as 40 hex characters)
|
||||||
|
# converted to the form: .build-id/ab/cdef1234...89.debug
|
||||||
|
# Return "" if no build-id found.
|
||||||
|
proc build_id_debug_filename_get { filename } {
|
||||||
|
set data [get_build_id $filename]
|
||||||
|
if { $data == "" } {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
regsub {^..} $data {\0/} data
|
regsub {^..} $data {\0/} data
|
||||||
return ".build-id/${data}.debug"
|
return ".build-id/${data}.debug"
|
||||||
}
|
}
|
||||||
|
|
17
gdb/utils.c
17
gdb/utils.c
|
@ -1112,6 +1112,23 @@ gdb_print_host_address (const void *addr, struct ui_file *stream)
|
||||||
{
|
{
|
||||||
fprintf_filtered (stream, "%s", host_address_to_string (addr));
|
fprintf_filtered (stream, "%s", host_address_to_string (addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See utils.h. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
make_hex_string (const gdb_byte *data, size_t length)
|
||||||
|
{
|
||||||
|
char *result = xmalloc (length * 2 + 1);
|
||||||
|
char *p;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
p = result;
|
||||||
|
for (i = 0; i < length; ++i)
|
||||||
|
p += sprintf (p, "%02x", data[i]);
|
||||||
|
*p = '\0';
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* A cleanup function that calls regfree. */
|
/* A cleanup function that calls regfree. */
|
||||||
|
|
|
@ -369,4 +369,9 @@ extern void warn_cant_dump_core (const char *reason);
|
||||||
|
|
||||||
extern void dump_core (void);
|
extern void dump_core (void);
|
||||||
|
|
||||||
|
/* Return the hex string form of LENGTH bytes of DATA.
|
||||||
|
Space for the result is malloc'd, caller must free. */
|
||||||
|
|
||||||
|
extern char *make_hex_string (const gdb_byte *data, size_t length);
|
||||||
|
|
||||||
#endif /* UTILS_H */
|
#endif /* UTILS_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue