From patchwork Fri Dec 5 18:36:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Evans X-Patchwork-Id: 4089 Received: (qmail 7151 invoked by alias); 5 Dec 2014 18:36:36 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 7139 invoked by uid 89); 5 Dec 2014 18:36:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS, T_RP_MATCHES_RCVD, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: mail-qg0-f74.google.com Received: from mail-qg0-f74.google.com (HELO mail-qg0-f74.google.com) (209.85.192.74) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 05 Dec 2014 18:36:34 +0000 Received: by mail-qg0-f74.google.com with SMTP id q107so60901qgd.5 for ; Fri, 05 Dec 2014 10:36:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:mime-version:content-type :content-transfer-encoding:message-id:date:to:subject:in-reply-to :references; bh=pwYawegDhwXESLAaTpYs1cqpGKg1QgI4BCxmXh90V6k=; b=dr2Jm0od0edJ9/LAzkh1phNe/zm/apeP129VaQJTVDjJEwxqOWF4FubnPgoHqdHW1n PR9penqIsDaurA42YlcTdQLKpkR3de1pxN8DjUHUgrfl8HS5Iw8NSvpl+7PW2YhsA4Mp FJwZeh4M1rsjxh9Y/QmiNPYnxDA8uI3jFPA1WH0tE5s+AfVO9iPPYT2qcMy9n162WAJl g/teFjCXsNrbJZ40ZW1uWNaC5bztwTgW870ybUirD1T+TkCu1VdFSh7WrvLiyPZVCqSN 9F0+rOnHF4ioIBtUvBflIRr5gWuWkvhCbdG++rngjDd73fA/rm9kwhu2f3lNODUNzkze AUKw== X-Gm-Message-State: ALoCoQk7WzymPBbzk6bCkms8ICLqONsOtw7oyPXIhVGM3yPxxqUke8FLqXYsDK6sobQJHDK5jJVjdxlY8LRYFOpBc43pbgwnfZGgiemA8WAENgSTmp375r8La3OmxeWkmMKRR0mXh1HacBkf9lZmPv6lsZo8IQkxkN0XgnMNva5tNosODrS6e3I= X-Received: by 10.236.2.41 with SMTP id 29mr16301435yhe.32.1417804591634; Fri, 05 Dec 2014 10:36:31 -0800 (PST) Received: from corpmail-nozzle1-2.hot.corp.google.com ([100.108.1.103]) by gmr-mx.google.com with ESMTPS id 26si713734yhj.7.2014.12.05.10.36.31 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Dec 2014 10:36:31 -0800 (PST) Received: from ruffy2.mtv.corp.google.com ([172.17.128.107]) by corpmail-nozzle1-2.hot.corp.google.com with ESMTP id 7fTIGMJm.1; Fri, 05 Dec 2014 10:36:31 -0800 From: Doug Evans MIME-Version: 1.0 Message-ID: <21633.64302.165292.579725@ruffy2.mtv.corp.google.com> Date: Fri, 5 Dec 2014 10:36:30 -0800 To: Eli Zaretskii , gdb-patches@sourceware.org Subject: Re: [PATCH 1/4] python support for fetching separate debug files: build_id In-Reply-To: <838uj557ez.fsf@gnu.org> References: <838uj557ez.fsf@gnu.org> X-IsSubscribed: yes Eli Zaretskii writes: > > From: Doug Evans > > Date: Thu, 20 Nov 2014 13:20:13 -0800 > > > > This patch just provides a Python API call to fetch the build id from > > objfiles. In my use-case separate debug files are looked up via the > > build id. > > OK for the documentation parts. > > Thanks. Thanks. Here is what I committed. [no real change from original] commit 7c50a93137df660f7b2d9d68c0db748a9cb7868f Author: Doug Evans Date: Thu Dec 4 11:32:24 2014 -0800 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. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 352d107..e6da0b5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2014-12-04 Doug Evans + + * 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 * block.c (block_lookup_symbol_primary): New function. diff --git a/gdb/NEWS b/gdb/NEWS index 7262502..16ed91e 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -21,6 +21,8 @@ ** New attribute 'producer' for gdb.Symtab objects. ** gdb.Objfile objects have a new attribute "progspace", 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 selecting a new file to debug. ** You can now add attributes to gdb.Objfile and gdb.Progspace objects. diff --git a/gdb/build-id.c b/gdb/build-id.c index 0f553ce..5c1f415 100644 --- a/gdb/build-id.c +++ b/gdb/build-id.c @@ -27,9 +27,9 @@ #include "objfiles.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) { if (!bfd_check_format (abfd, bfd_object) diff --git a/gdb/build-id.h b/gdb/build-id.h index ddd2645..548ea5e 100644 --- a/gdb/build-id.h +++ b/gdb/build-id.h @@ -20,6 +20,10 @@ #ifndef 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. Otherwise, issue a warning and return false. */ diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 08b49f5..7f36a31 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2014-12-04 Doug Evans + + * python.texi (Objfiles In Python): Document Objfile.build_id. + 2014-12-02 Nick Bull * python.texi (Events In Python): Document new events diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 63db2b2..a951410 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -3495,6 +3495,17 @@ class. The file name of the objfile as a string. @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 The containing program space of the objfile as a @code{gdb.Progspace} object. @xref{Progspaces In Python}. diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index c99de87..05a7c21 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -22,6 +22,8 @@ #include "charset.h" #include "objfiles.h" #include "language.h" +#include "build-id.h" +#include "elf-bfd.h" typedef struct { @@ -51,9 +53,21 @@ static PyTypeObject objfile_object_type 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. */ + static PyObject * objfpy_get_filename (PyObject *self, void *closure) { @@ -66,6 +80,38 @@ objfpy_get_filename (PyObject *self, void *closure) 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. */ static PyObject * @@ -364,6 +410,8 @@ static PyGetSetDef objfile_getset[] = "The __dict__ for this objfile.", &objfile_object_type }, { "filename", objfpy_get_filename, 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, "The objfile's progspace, or None.", NULL }, { "pretty_printers", objfpy_get_printers, objfpy_set_printers, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f1584e0..b19a5c0 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-12-04 Doug Evans + + * 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 * gdb.cp/expand-psymtabs-cxx.exp: Accept any address of diff --git a/gdb/testsuite/gdb.python/py-objfile.exp b/gdb/testsuite/gdb.python/py-objfile.exp index 7bf41ed..74384ed 100644 --- a/gdb/testsuite/gdb.python/py-objfile.exp +++ b/gdb/testsuite/gdb.python/py-objfile.exp @@ -39,6 +39,16 @@ gdb_py_test_silent_cmd "python objfile = sym\[0\].symtab.objfile" \ gdb_test "python print (objfile.filename)" ".*py-objfile.*" \ "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)" "" \ "Get objfile program space" gdb_test "python print (objfile.is_valid())" "True" \ diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 2c79bc1..a29b661 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -4330,14 +4330,14 @@ gdb_caching_proc gdb_has_argv0 { # foo.debug --> foo's debug info # 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) -# converted to the form: .build-id/ab/cdef1234...89.debug -# Return "" if no build-id found. -proc build_id_debug_filename_get { exec } { - set tmp [standard_output_file "${exec}-tmp"] +# Fetch the build id from the file. +# Returns "" if there is none. + +proc get_build_id { filename } { + set tmp [standard_output_file "${filename}-tmp"] 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 "output is $output" if {$result == 1} { @@ -4355,6 +4355,17 @@ proc build_id_debug_filename_get { exec } { } # Convert it to hex. 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 return ".build-id/${data}.debug" } diff --git a/gdb/utils.c b/gdb/utils.c index 1f5f4f4..1ab183c 100644 --- a/gdb/utils.c +++ b/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)); } + +/* 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. */ diff --git a/gdb/utils.h b/gdb/utils.h index 1568011..660b548 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -369,4 +369,9 @@ extern void warn_cant_dump_core (const char *reason); 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 */