From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 110276 invoked by alias); 21 Jun 2015 21:12:18 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 110258 invoked by uid 9674); 21 Jun 2015 21:12:17 -0000 Date: Sun, 21 Jun 2015 21:12:00 -0000 Message-ID: <20150621211217.110224.qmail@sourceware.org> From: jkratoch@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] jankratochvil/gdbserverbuildid: post X-Git-Refname: refs/heads/jankratochvil/gdbserverbuildid X-Git-Reftype: branch X-Git-Oldrev: b1c33d49e13ebb4341ce70666aa4c9ef8f2cea06 X-Git-Newrev: 9dd28e86b67a3aa55c973fabf32719d6d055c646 X-SW-Source: 2015-q2/txt/msg00007.txt.bz2 List-Id: The branch, jankratochvil/gdbserverbuildid has been updated via 9dd28e86b67a3aa55c973fabf32719d6d055c646 (commit) via b3f1ed8156d4f736335fc92ae29027bf890fd56c (commit) via 79c03cbb287878d3e5fcfb8104bdd21aa712f013 (commit) via 6d40ae1db39bdabb415a05aa909178d61cb519ed (commit) via 3be039f17b9eba6e91726477ea85ba35f3ba9643 (commit) via 54d4369e81bc3e7beed9d2ace779802ef7963c96 (commit) via e27ef350d86557c5f0e7e7c25552c23cae56c264 (commit) via 8ac504f352ad74008efbc4bb52ab1bebd191fb2a (commit) from b1c33d49e13ebb4341ce70666aa4c9ef8f2cea06 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 9dd28e86b67a3aa55c973fabf32719d6d055c646 Author: Jan Kratochvil Date: Sun Jun 21 16:44:21 2015 +0200 post commit b3f1ed8156d4f736335fc92ae29027bf890fd56c Author: Jan Kratochvil Date: Sun Jun 21 23:02:39 2015 +0200 mainbuildid commit 79c03cbb287878d3e5fcfb8104bdd21aa712f013 Author: Jan Kratochvil Date: Sun Jun 21 22:49:38 2015 +0200 buildidnoslib commit 6d40ae1db39bdabb415a05aa909178d61cb519ed Author: Jan Kratochvil Date: Sun Jun 21 19:52:50 2015 +0200 sovalidateall commit 3be039f17b9eba6e91726477ea85ba35f3ba9643 Author: Jan Kratochvil Date: Sun Jun 21 22:03:01 2015 +0200 sovalidatemove commit 54d4369e81bc3e7beed9d2ace779802ef7963c96 Author: Jan Kratochvil Date: Sun Jun 21 19:55:22 2015 +0200 buildidforcemove commit e27ef350d86557c5f0e7e7c25552c23cae56c264 Author: Jan Kratochvil Date: Sun Jun 21 19:46:35 2015 +0200 solocate commit 8ac504f352ad74008efbc4bb52ab1bebd191fb2a Author: Jan Kratochvil Date: Sun Jun 21 19:42:35 2015 +0200 hexallocate ----------------------------------------------------------------------- Summary of changes: gdb/NEWS | 11 ++- gdb/build-id.c | 139 ++++++++++++++++++++++++++--- gdb/build-id.h | 5 + gdb/doc/gdb.texinfo | 50 ++++++----- gdb/features/library-list-svr4.dtd | 5 +- gdb/gdbserver/linux-low.c | 17 ++++ gdb/solib-svr4.c | 125 ++++++++++---------------- gdb/solib.c | 82 ++++-------------- gdb/solib.h | 4 +- gdb/solist.h | 7 +- gdb/testsuite/gdb.base/solib-mismatch.exp | 46 +++++++++- 11 files changed, 295 insertions(+), 196 deletions(-) First 500 lines of diff: diff --git a/gdb/NEWS b/gdb/NEWS index 8cbe1fc..45b42c0 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -159,11 +159,12 @@ set debug linux-namespaces show debug linux-namespaces Control display of debugging info regarding Linux namespaces. -set solib-build-id-force (on|off) -show solib-build-id-force - Inferior shared library and symbol file may contain unique build-id. - If both build-ids are present but they do not match then this setting - enables (on) or disables (off) loading of such symbol file. +set build-id-force (on|off) +show build-id-force + Symbol files and separate debug info files (sometimes with file extension + ".debug") may contain unique build-id. If one is present but the other one + is missing or it is not identical then this setting enables (on) + or disables (off) loading of such separate debug info file. * The command 'thread apply all' can now support new option '-ascending' to call its specified command for all threads in ascending order. diff --git a/gdb/build-id.c b/gdb/build-id.c index ebf9f45..b8cb85f 100644 --- a/gdb/build-id.c +++ b/gdb/build-id.c @@ -26,6 +26,23 @@ #include "objfiles.h" #include "filenames.h" #include "gdbcore.h" +#include "gdbcmd.h" +#include "solist.h" +#include "rsp-low.h" + +/* Boolean for command 'set build-id-force'. */ +static int build_id_force = 0; + +/* Implement 'show build-id-force'. */ + +static void +show_build_id_force (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Loading of shared libraries " + "with non-matching build-id is %s.\n"), + value); +} /* See build-id.h. */ @@ -47,28 +64,50 @@ build_id_bfd_get (bfd *abfd) int build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) { - const struct bfd_build_id *found; - int retval = 0; + const struct bfd_build_id *found = build_id_bfd_get (abfd); + char *message, *check_hex = alloca (check_len * 2 + 1); - found = build_id_bfd_get (abfd); + bin2hex (check, check_hex, check_len); if (found == NULL) - warning (_("File \"%s\" has no build-id, file skipped"), - bfd_get_filename (abfd)); + message = xstrprintf (_("inferior build ID is %s but symbol file \"%s\" " + "does not have build ID"), + check_hex, bfd_get_filename (abfd)); else if (found->size != check_len || memcmp (found->data, check, found->size) != 0) - warning (_("File \"%s\" has a different build-id, file skipped"), - bfd_get_filename (abfd)); + { + char *abfd_hex = alloca (found->size * 2 + 1); + + bin2hex (found->data, abfd_hex, found->size); + message = xstrprintf (_("inferior build ID %s is not identical to " + "symbol file \"%s\" build ID %s"), + check_hex, bfd_get_filename (abfd), abfd_hex); + } else - retval = 1; + return 1; - return retval; + if (!build_id_force) + { + warning (_("Symbol file \"%s\" could not be validated (%s) and " + "will be ignored; or use 'set build-id-force'."), + bfd_get_filename (abfd), message); + xfree (message); + return 0; + } + warning (_("Symbol file \"%s\" could not be validated (%s) " + "but it is being loaded due to 'set build-id-force'."), + bfd_get_filename (abfd), message); + xfree (message); + return 1; } -/* See build-id.h. */ +/* Find and open a BFD given a build-id. If no BFD can be found, + return NULL. Use "" or ".debug" for SUFFIX. The returned reference to the + BFD must be released by the caller. */ -bfd * -build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) +static bfd * +build_id_to_bfd (size_t build_id_len, const bfd_byte *build_id, + const char *suffix) { char *link, *debugdir; VEC (char_ptr) *debugdir_vec; @@ -78,7 +117,7 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */ link = alloca (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 - + 2 * build_id_len + (sizeof ".debug" - 1) + 1); + + 2 * build_id_len + strlen (suffix) + 1); /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will cause "/.build-id/..." lookups. */ @@ -106,7 +145,7 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) *s++ = '/'; while (size-- > 0) s += sprintf (s, "%02x", (unsigned) *data++); - strcpy (s, ".debug"); + strcpy (s, suffix); /* lrealpath() is expensive even for the usually non-existent files. */ if (access (link, F_OK) == 0) @@ -133,6 +172,14 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) /* See build-id.h. */ +bfd * +build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) +{ + return build_id_to_bfd (build_id_len, build_id, ".debug"); +} + +/* See build-id.h. */ + char * find_separate_debug_file_by_buildid (struct objfile *objfile) { @@ -163,3 +210,67 @@ find_separate_debug_file_by_buildid (struct objfile *objfile) } return NULL; } + +/* See build-id.h. */ + +void +build_id_so_validate (struct so_list *so) +{ + const struct bfd_build_id *found = NULL; + + /* Target doesn't support reporting the build ID or the remote shared library + does not have build ID. */ + if (so->build_id == NULL) + return; + + if (so->abfd != NULL) + found = build_id_bfd_get (so->abfd); + + if (found != NULL && found->size == so->build_idsz + && memcmp (found->data, so->build_id, found->size) == 0) + return; + + if (!build_id_force) + { + bfd *build_id_bfd = build_id_to_bfd (so->build_idsz, so->build_id, ""); + + if (build_id_bfd != NULL) + { + gdb_bfd_unref (so->abfd); + so->abfd = build_id_bfd; + return; + } + } + + /* Build ID may be present in the local file, just GDB is unable to retrieve + it. (Inferior Build ID report by gdbserver cannot be FSF gdbserver.) */ + if (so->abfd == NULL + || !bfd_check_format (so->abfd, bfd_object) + || bfd_get_flavour (so->abfd) != bfd_target_elf_flavour) + return; + + if (!build_id_verify (so->abfd, so->build_idsz, so->build_id)) + { + gdb_bfd_unref (so->abfd); + so->abfd = NULL; + } +} + +extern initialize_file_ftype _initialize_build_id; /* -Wmissing-prototypes */ + +void +_initialize_build_id (void) +{ + add_setshow_boolean_cmd ("build-id-force", class_support, + &build_id_force, _("\ +Set loading of shared libraries with non-matching build-id."), _("\ +Show loading of shared libraries with non-matching build-id."), _("\ +Inferior shared library and symbol file may contain unique build-id.\n\ +If both build-ids are present but they do not match then this setting\n\ +enables (on) or disables (off) loading of such symbol file.\n\ +Loading non-matching symbol file may confuse debugging including breakage\n\ +of backtrace output."), + NULL, + show_build_id_force, + &setlist, &showlist); +} diff --git a/gdb/build-id.h b/gdb/build-id.h index bea761b..122397a 100644 --- a/gdb/build-id.h +++ b/gdb/build-id.h @@ -45,4 +45,9 @@ extern bfd *build_id_to_debug_bfd (size_t build_id_len, extern char *find_separate_debug_file_by_buildid (struct objfile *objfile); +/* Validate SO by comparing build-id from the associated bfd and + corresponding build-id from target memory. */ + +extern void build_id_so_validate (struct so_list *so); + #endif /* BUILD_ID_H */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f7e4405..71dca76 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -17913,40 +17913,42 @@ discarded. @end table @table @code -@kindex set solib-build-id-force +@kindex set build-id-force @cindex override @value{GDBN} build-id check -@item set solib-build-id-force @var{mode} +@item set build-id-force @var{mode} Setting to override @value{GDBN} build-id check. Inferior shared libraries and symbol files may contain unique build-id. -By default @value{GDBN} will ignore symbol files with non-matching build-id -while printing: +@value{GDBN} expects the build-ids of each shared library and its corresponding +symbol file to be identical. If they are not identical, then by default +@value{GDBN} will @value{GDBN} will ignore symbol files with non-matching +build-id while printing: @smallexample - warning: Shared object "libfoo.so.1" could not be validated (remote - build ID 2bc1745e does not match local build ID a08f8767) and will be - ignored; or use 'set solib-build-id-force'. + warning: Symbol file "libfoo.so.1" could not be validated (inferior + build ID 2bc1745e does not match symbol file build ID a08f8767) and + will be ignored; or use 'set build-id-force'. @end smallexample Turning on this setting would load such symbol file while still printing: @smallexample - warning: Shared object "libfoo.so.1" could not be validated (remote - build ID 2bc1745e does not match local build ID a08f8767) but it is - being loaded due to 'set solib-build-id-force'. + warning: Symbol file "libfoo.so.1" could not be validated (inferior + build ID 2bc1745e is not identical to symbol file build ID a08f8767) + but it is being loaded due to 'set build-id-force'. @end smallexample -If remote build-id is present but it does not match local build-id (or local -build-id is not present) then this setting enables (@var{mode} is @code{on}) or -disables (@var{mode} is @code{off}) loading of such symbol file. On systems -where build-id is not present in the remote system this setting has no effect. -The default value is @code{off}. +If inferior build-id is present but it is not identical to symbol file build-id +(or the symbol file build-id is not present) then this setting enables +(@var{mode} is @code{on}) or disables (@var{mode} is @code{off}) loading of +such symbol file. On systems where build-id is not present in the inferior +system this setting has no effect. The default value is @code{off}. Loading non-matching symbol file may confuse debugging including breakage of backtrace output. -@kindex show solib-build-id-force -@item show solib-build-id-force +@kindex show build-id-force +@item show build-id-force Display the current mode of build-id check override. @end table @@ -39389,8 +39391,10 @@ address the file was prelinked to during the library load. @end itemize Additionally the single @code{main-lm} attribute specifies address of -@code{struct link_map} used for the main executable. This parameter is used -for TLS access and its presence is optional. +@code{struct link_map} used for the main executable. This parameter is +used for TLS access and its presence is optional. Similarly the single +@code{main-build-id} optional attribute specifies hex encoded +@code{NT_GNU_BUILD_ID} note for the main executable. @value{GDBN} must be linked with the Expat library to support XML SVR4 library lists. @xref{Expat}. @@ -39399,7 +39403,8 @@ A simple memory map, with two loaded libraries (which do not use prelink), looks like this: @smallexample - + - - + + + diff --git a/gdb/features/library-list-svr4.dtd b/gdb/features/library-list-svr4.dtd index 5741f03..27799a6 100644 --- a/gdb/features/library-list-svr4.dtd +++ b/gdb/features/library-list-svr4.dtd @@ -6,8 +6,9 @@ - - + + + diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 40921fd..8bb4831 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -6676,8 +6676,25 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf, exited above due to failed get_r_debug. */ if (lm_prev == 0) { + const char *hex_enc_build_id = get_hex_build_id (l_addr, l_ld, &data); + sprintf (p, " main-lm=\"0x%lx\"", (unsigned long) lm_addr); p = p + strlen (p); + + if (hex_enc_build_id != NULL) + { + while (allocated + < p - document + 200 + strlen (hex_enc_build_id)) + { + /* Expand to guarantee sufficient storage. */ + uintptr_t document_len = p - document; + + document = xrealloc (document, 2 * allocated); + allocated *= 2; + p = document + document_len; + } + p += sprintf (p, " main-build-id=\"%s\"", hex_enc_build_id); + } } else { diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index b434c1f..7f16828 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -45,10 +45,9 @@ #include "auxv.h" #include "gdb_bfd.h" #include "probe.h" +#include "build-id.h" #include "rsp-low.h" -#define NOTE_GNU_BUILD_ID_NAME ".note.gnu.build-id" - static struct link_map_offsets *svr4_fetch_link_map_offsets (void); static int svr4_have_link_map_offsets (void); static void svr4_relocate_main_executable (void); @@ -360,6 +359,8 @@ struct svr4_info /* Load map address for the main executable. */ CORE_ADDR main_lm_addr; + size_t main_build_idsz; + gdb_byte *main_build_id; CORE_ADDR interp_text_sect_low; CORE_ADDR interp_text_sect_high; @@ -973,63 +974,6 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) return (name_lm >= vaddr && name_lm < vaddr + size); } -/* Validate SO by comparing build-id from the associated bfd and - corresponding build-id from target memory. */ - -static char * -svr4_validate (const struct so_list *const so) -{ - const bfd_byte *local_id; - size_t local_idsz; - - gdb_assert (so != NULL); - - /* Target doesn't support reporting the build ID or the remote shared library - does not have build ID. */ - if (so->build_id == NULL) - return NULL; - - /* Build ID may be present in the local file, just GDB is unable to retrieve - it. As it has been reported by gdbserver it is not FSF gdbserver. */ - if (so->abfd == NULL - || !bfd_check_format (so->abfd, bfd_object)) - return NULL; - - /* GDB has verified the local file really does not contain the build ID. */ - if (so->abfd->build_id == NULL) - { - char *remote_hex; - - remote_hex = alloca (so->build_idsz * 2 + 1); - bin2hex (so->build_id, remote_hex, so->build_idsz); - - return xstrprintf (_("remote build ID is %s " - "but local file does not have build ID"), - remote_hex); - } - - local_id = so->abfd->build_id->data; - local_idsz = so->abfd->build_id->size; - - if (so->build_idsz != local_idsz - || memcmp (so->build_id, local_id, so->build_idsz) != 0) - { - char *remote_hex, *local_hex; - - remote_hex = alloca (so->build_idsz * 2 + 1); - bin2hex (so->build_id, remote_hex, so->build_idsz); - local_hex = alloca (local_idsz * 2 + 1); - bin2hex (local_id, local_hex, local_idsz); - - return xstrprintf (_("remote build ID %s " - "does not match local build ID %s"), - remote_hex, local_hex); - } - - /* Both build IDs are present and they match. */ - return NULL; -} - /* Implement the "open_symbol_file_object" target_so_ops method. If no open symbol file, attempt to locate and open the main symbol @@ -1115,6 +1059,9 @@ struct svr4_library_list /* Inferior address of struct link_map used for the main executable. It is NULL if not known. */ CORE_ADDR main_lm; + + size_t main_build_idsz; + gdb_byte *main_build_id; }; /* Implementation for target_so_ops.free_so. */ @@ -1188,6 +1135,27 @@ svr4_copy_library_list (struct so_list *src) #include "xml-support.h" +static void +hex2bin_allocate (const char *hex, gdb_byte **binp, size_t *binszp) +{ + size_t hex_len, binsz; + + if (hex == NULL) + return; + hex_len = strlen (hex); + if (hex_len == 0 || (hex_len & 1U) != 0) + return; + binsz = hex_len / 2; + *binp = xmalloc (binsz); + *binszp = hex2bin (hex, *binp, binsz); + if (*binszp != binsz) + { + xfree (*binp); + *binp = NULL; + *binszp = 0; + } +} + /* Handle the start of a element. Note: new elements are added at the tail of the list, keeping the list in order. */ hooks/post-receive -- Repository for Project Archer.