Validate symbol file using build-id
Consumer part of the "build-id" attribute. gdb/ChangeLog 2015-07-15 Aleksandar Ristovski <aristovski@qnx.com Jan Kratochvil <jan.kratochvil@redhat.com> Validate symbol file using build-id. * NEWS (Changes since GDB 7.10): Add 'set validate-build-id' and 'show validate-build-id'. Add build-id attribute. * solib-darwin.c (_initialize_darwin_solib): Assign validate value. * solib-dsbt.c (_initialize_dsbt_solib): Ditto. * solib-frv.c (_initialize_frv_solib): Ditto. * solib-spu.c (set_spu_solib_ops): Ditto. * solib-svr4.c: Include rsp-low.h. (NOTE_GNU_BUILD_ID_NAME): New define. (svr4_validate): New function. (svr4_copy_library_list): Duplicate field build_id. (library_list_start_library): Parse 'build-id' attribute. (svr4_library_attributes): Add 'build-id' attribute. (_initialize_svr4_solib): Assign validate value. * solib-target.c (solib.h): Include. (_initialize_solib_target): Assign validate value. * solib.c (validate_build_id, show_validate_build_id): New. (solib_map_sections): Use ops->validate. (clear_so): Free build_id. (default_solib_validate): New function. (_initialize_solib): Add "validate-build-id". * solib.h (default_solib_validate): New declaration. * solist.h (struct so_list): New fields 'build_idsz' and 'build_id'. (target_so_ops): New field 'validate'. gdb/doc/ChangeLog 2015-07-15 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.texinfo (Files): Add 'set validate-build-id' and 'show validate-build-id'.
This commit is contained in:
parent
700ca40f6f
commit
ca5268b6be
@ -1,3 +1,31 @@
|
|||||||
|
2015-07-15 Aleksandar Ristovski <aristovski@qnx.com
|
||||||
|
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
Validate symbol file using build-id.
|
||||||
|
* NEWS (Changes since GDB 7.10): Add 'set validate-build-id'
|
||||||
|
and 'show validate-build-id'. Add build-id attribute.
|
||||||
|
* solib-darwin.c (_initialize_darwin_solib): Assign validate value.
|
||||||
|
* solib-dsbt.c (_initialize_dsbt_solib): Ditto.
|
||||||
|
* solib-frv.c (_initialize_frv_solib): Ditto.
|
||||||
|
* solib-spu.c (set_spu_solib_ops): Ditto.
|
||||||
|
* solib-svr4.c: Include rsp-low.h.
|
||||||
|
(NOTE_GNU_BUILD_ID_NAME): New define.
|
||||||
|
(svr4_validate): New function.
|
||||||
|
(svr4_copy_library_list): Duplicate field build_id.
|
||||||
|
(library_list_start_library): Parse 'build-id' attribute.
|
||||||
|
(svr4_library_attributes): Add 'build-id' attribute.
|
||||||
|
(_initialize_svr4_solib): Assign validate value.
|
||||||
|
* solib-target.c (solib.h): Include.
|
||||||
|
(_initialize_solib_target): Assign validate value.
|
||||||
|
* solib.c (validate_build_id, show_validate_build_id): New.
|
||||||
|
(solib_map_sections): Use ops->validate.
|
||||||
|
(clear_so): Free build_id.
|
||||||
|
(default_solib_validate): New function.
|
||||||
|
(_initialize_solib): Add "validate-build-id".
|
||||||
|
* solib.h (default_solib_validate): New declaration.
|
||||||
|
* solist.h (struct so_list): New fields 'build_idsz' and 'build_id'.
|
||||||
|
(target_so_ops): New field 'validate'.
|
||||||
|
|
||||||
2015-07-15 Aleksandar Ristovski <aristovski@qnx.com
|
2015-07-15 Aleksandar Ristovski <aristovski@qnx.com
|
||||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
14
gdb/NEWS
14
gdb/NEWS
@ -5,6 +5,20 @@
|
|||||||
|
|
||||||
* Support for tracepoints on aarch64-linux was added in GDBserver.
|
* Support for tracepoints on aarch64-linux was added in GDBserver.
|
||||||
|
|
||||||
|
* New options
|
||||||
|
|
||||||
|
set validate-build-id (on|off)
|
||||||
|
show validate-build-id
|
||||||
|
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 (off) or disables (on) loading of such symbol file.
|
||||||
|
|
||||||
|
* New features in the GDB remote stub, GDBserver
|
||||||
|
|
||||||
|
** library-list-svr4 contains also optional attribute 'build-id' for
|
||||||
|
each library. GDB does not load library with build-id that
|
||||||
|
does not match such attribute.
|
||||||
|
|
||||||
*** Changes in GDB 7.10
|
*** Changes in GDB 7.10
|
||||||
|
|
||||||
* Support for process record-replay and reverse debugging on aarch64*-linux*
|
* Support for process record-replay and reverse debugging on aarch64*-linux*
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2015-07-15 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
* gdb.texinfo (Files): Add 'set validate-build-id'
|
||||||
|
and 'show validate-build-id'.
|
||||||
|
|
||||||
2015-07-15 Aleksandar Ristovski <aristovski@qnx.com
|
2015-07-15 Aleksandar Ristovski <aristovski@qnx.com
|
||||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
@ -17950,6 +17950,44 @@ libraries that were loaded by explicit user requests are not
|
|||||||
discarded.
|
discarded.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@kindex set validate-build-id
|
||||||
|
@cindex override @value{GDBN} build-id check
|
||||||
|
@item set validate-build-id @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:
|
||||||
|
|
||||||
|
@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 validate-build-id off'.
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Turning off 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 validate-build-id off'.
|
||||||
|
@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{off}) or
|
||||||
|
disables (@var{mode} is @code{on}) 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{on}.
|
||||||
|
|
||||||
|
Loading non-matching symbol file may confuse debugging including breakage
|
||||||
|
of backtrace output.
|
||||||
|
|
||||||
|
@kindex show validate-build-id
|
||||||
|
@item show validate-build-id
|
||||||
|
Display the current mode of build-id check override.
|
||||||
|
@end table
|
||||||
|
|
||||||
Sometimes you may wish that @value{GDBN} stops and gives you control
|
Sometimes you may wish that @value{GDBN} stops and gives you control
|
||||||
when any of shared library events happen. The best way to do this is
|
when any of shared library events happen. The best way to do this is
|
||||||
to use @code{catch load} and @code{catch unload} (@pxref{Set
|
to use @code{catch load} and @code{catch unload} (@pxref{Set
|
||||||
|
@ -634,4 +634,5 @@ _initialize_darwin_solib (void)
|
|||||||
darwin_so_ops.in_dynsym_resolve_code = darwin_in_dynsym_resolve_code;
|
darwin_so_ops.in_dynsym_resolve_code = darwin_in_dynsym_resolve_code;
|
||||||
darwin_so_ops.lookup_lib_global_symbol = darwin_lookup_lib_symbol;
|
darwin_so_ops.lookup_lib_global_symbol = darwin_lookup_lib_symbol;
|
||||||
darwin_so_ops.bfd_open = darwin_bfd_open;
|
darwin_so_ops.bfd_open = darwin_bfd_open;
|
||||||
|
darwin_so_ops.validate = default_solib_validate;
|
||||||
}
|
}
|
||||||
|
@ -1080,6 +1080,7 @@ _initialize_dsbt_solib (void)
|
|||||||
dsbt_so_ops.open_symbol_file_object = open_symbol_file_object;
|
dsbt_so_ops.open_symbol_file_object = open_symbol_file_object;
|
||||||
dsbt_so_ops.in_dynsym_resolve_code = dsbt_in_dynsym_resolve_code;
|
dsbt_so_ops.in_dynsym_resolve_code = dsbt_in_dynsym_resolve_code;
|
||||||
dsbt_so_ops.bfd_open = solib_bfd_open;
|
dsbt_so_ops.bfd_open = solib_bfd_open;
|
||||||
|
dsbt_so_ops.validate = default_solib_validate;
|
||||||
|
|
||||||
/* Debug this file's internals. */
|
/* Debug this file's internals. */
|
||||||
add_setshow_zuinteger_cmd ("solib-dsbt", class_maintenance,
|
add_setshow_zuinteger_cmd ("solib-dsbt", class_maintenance,
|
||||||
|
@ -1183,6 +1183,7 @@ _initialize_frv_solib (void)
|
|||||||
frv_so_ops.open_symbol_file_object = open_symbol_file_object;
|
frv_so_ops.open_symbol_file_object = open_symbol_file_object;
|
||||||
frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code;
|
frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code;
|
||||||
frv_so_ops.bfd_open = solib_bfd_open;
|
frv_so_ops.bfd_open = solib_bfd_open;
|
||||||
|
frv_so_ops.validate = default_solib_validate;
|
||||||
|
|
||||||
/* Debug this file's internals. */
|
/* Debug this file's internals. */
|
||||||
add_setshow_zuinteger_cmd ("solib-frv", class_maintenance,
|
add_setshow_zuinteger_cmd ("solib-frv", class_maintenance,
|
||||||
|
@ -519,6 +519,7 @@ set_spu_solib_ops (struct gdbarch *gdbarch)
|
|||||||
spu_so_ops.current_sos = spu_current_sos;
|
spu_so_ops.current_sos = spu_current_sos;
|
||||||
spu_so_ops.bfd_open = spu_bfd_open;
|
spu_so_ops.bfd_open = spu_bfd_open;
|
||||||
spu_so_ops.lookup_lib_global_symbol = spu_lookup_lib_symbol;
|
spu_so_ops.lookup_lib_global_symbol = spu_lookup_lib_symbol;
|
||||||
|
spu_so_ops.validate = default_solib_validate;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_solib_ops (gdbarch, &spu_so_ops);
|
set_solib_ops (gdbarch, &spu_so_ops);
|
||||||
|
103
gdb/solib-svr4.c
103
gdb/solib-svr4.c
@ -45,6 +45,9 @@
|
|||||||
#include "auxv.h"
|
#include "auxv.h"
|
||||||
#include "gdb_bfd.h"
|
#include "gdb_bfd.h"
|
||||||
#include "probe.h"
|
#include "probe.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 struct link_map_offsets *svr4_fetch_link_map_offsets (void);
|
||||||
static int svr4_have_link_map_offsets (void);
|
static int svr4_have_link_map_offsets (void);
|
||||||
@ -970,6 +973,64 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
|
|||||||
return (name_lm >= vaddr && name_lm < vaddr + 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. Return NULL for success
|
||||||
|
or a string for error. Caller must call xfree for the error string. */
|
||||||
|
|
||||||
|
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.
|
/* Implement the "open_symbol_file_object" target_so_ops method.
|
||||||
|
|
||||||
If no open symbol file, attempt to locate and open the main symbol
|
If no open symbol file, attempt to locate and open the main symbol
|
||||||
@ -1108,6 +1169,12 @@ svr4_copy_library_list (struct so_list *src)
|
|||||||
newobj->lm_info = xmalloc (sizeof (struct lm_info));
|
newobj->lm_info = xmalloc (sizeof (struct lm_info));
|
||||||
memcpy (newobj->lm_info, src->lm_info, sizeof (struct lm_info));
|
memcpy (newobj->lm_info, src->lm_info, sizeof (struct lm_info));
|
||||||
|
|
||||||
|
if (newobj->build_id != NULL)
|
||||||
|
{
|
||||||
|
newobj->build_id = xmalloc (src->build_idsz);
|
||||||
|
memcpy (newobj->build_id, src->build_id, src->build_idsz);
|
||||||
|
}
|
||||||
|
|
||||||
newobj->next = NULL;
|
newobj->next = NULL;
|
||||||
*link = newobj;
|
*link = newobj;
|
||||||
link = &newobj->next;
|
link = &newobj->next;
|
||||||
@ -1135,6 +1202,9 @@ library_list_start_library (struct gdb_xml_parser *parser,
|
|||||||
ULONGEST *lmp = xml_find_attribute (attributes, "lm")->value;
|
ULONGEST *lmp = xml_find_attribute (attributes, "lm")->value;
|
||||||
ULONGEST *l_addrp = xml_find_attribute (attributes, "l_addr")->value;
|
ULONGEST *l_addrp = xml_find_attribute (attributes, "l_addr")->value;
|
||||||
ULONGEST *l_ldp = xml_find_attribute (attributes, "l_ld")->value;
|
ULONGEST *l_ldp = xml_find_attribute (attributes, "l_ld")->value;
|
||||||
|
const struct gdb_xml_value *const att_build_id
|
||||||
|
= xml_find_attribute (attributes, "build-id");
|
||||||
|
const char *const hex_build_id = att_build_id ? att_build_id->value : NULL;
|
||||||
struct so_list *new_elem;
|
struct so_list *new_elem;
|
||||||
|
|
||||||
new_elem = XCNEW (struct so_list);
|
new_elem = XCNEW (struct so_list);
|
||||||
@ -1146,6 +1216,37 @@ library_list_start_library (struct gdb_xml_parser *parser,
|
|||||||
strncpy (new_elem->so_name, name, sizeof (new_elem->so_name) - 1);
|
strncpy (new_elem->so_name, name, sizeof (new_elem->so_name) - 1);
|
||||||
new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0;
|
new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0;
|
||||||
strcpy (new_elem->so_original_name, new_elem->so_name);
|
strcpy (new_elem->so_original_name, new_elem->so_name);
|
||||||
|
if (hex_build_id != NULL)
|
||||||
|
{
|
||||||
|
const size_t hex_build_id_len = strlen (hex_build_id);
|
||||||
|
|
||||||
|
if (hex_build_id_len == 0)
|
||||||
|
warning (_("Shared library \"%s\" received empty build-id "
|
||||||
|
"from gdbserver"), new_elem->so_original_name);
|
||||||
|
else if ((hex_build_id_len & 1U) != 0)
|
||||||
|
warning (_("Shared library \"%s\" received odd number "
|
||||||
|
"of build-id \"%s\" hex characters from gdbserver"),
|
||||||
|
new_elem->so_original_name, hex_build_id);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_t build_idsz = hex_build_id_len / 2;
|
||||||
|
|
||||||
|
new_elem->build_id = xmalloc (build_idsz);
|
||||||
|
new_elem->build_idsz = hex2bin (hex_build_id, new_elem->build_id,
|
||||||
|
build_idsz);
|
||||||
|
if (new_elem->build_idsz != build_idsz)
|
||||||
|
{
|
||||||
|
warning (_("Shared library \"%s\" received invalid "
|
||||||
|
"build-id \"%s\" hex character at encoded byte "
|
||||||
|
"position %s (first as 0) from gdbserver"),
|
||||||
|
new_elem->so_original_name, hex_build_id,
|
||||||
|
pulongest (new_elem->build_idsz));
|
||||||
|
xfree (new_elem->build_id);
|
||||||
|
new_elem->build_id = NULL;
|
||||||
|
new_elem->build_idsz = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*list->tailp = new_elem;
|
*list->tailp = new_elem;
|
||||||
list->tailp = &new_elem->next;
|
list->tailp = &new_elem->next;
|
||||||
@ -1180,6 +1281,7 @@ static const struct gdb_xml_attribute svr4_library_attributes[] =
|
|||||||
{ "lm", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
|
{ "lm", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
|
||||||
{ "l_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
|
{ "l_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
|
||||||
{ "l_ld", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
|
{ "l_ld", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
|
||||||
|
{ "build-id", GDB_XML_AF_OPTIONAL, NULL, NULL },
|
||||||
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
|
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3258,4 +3360,5 @@ _initialize_svr4_solib (void)
|
|||||||
svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core;
|
svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core;
|
||||||
svr4_so_ops.update_breakpoints = svr4_update_solib_event_breakpoints;
|
svr4_so_ops.update_breakpoints = svr4_update_solib_event_breakpoints;
|
||||||
svr4_so_ops.handle_event = svr4_handle_solib_event;
|
svr4_so_ops.handle_event = svr4_handle_solib_event;
|
||||||
|
svr4_so_ops.validate = svr4_validate;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "vec.h"
|
#include "vec.h"
|
||||||
#include "solib-target.h"
|
#include "solib-target.h"
|
||||||
|
#include "solib.h"
|
||||||
|
|
||||||
/* Private data for each loaded library. */
|
/* Private data for each loaded library. */
|
||||||
struct lm_info
|
struct lm_info
|
||||||
@ -506,6 +507,7 @@ _initialize_solib_target (void)
|
|||||||
solib_target_so_ops.in_dynsym_resolve_code
|
solib_target_so_ops.in_dynsym_resolve_code
|
||||||
= solib_target_in_dynsym_resolve_code;
|
= solib_target_in_dynsym_resolve_code;
|
||||||
solib_target_so_ops.bfd_open = solib_bfd_open;
|
solib_target_so_ops.bfd_open = solib_bfd_open;
|
||||||
|
solib_target_so_ops.validate = default_solib_validate;
|
||||||
|
|
||||||
/* Set current_target_so_ops to solib_target_so_ops if not already
|
/* Set current_target_so_ops to solib_target_so_ops if not already
|
||||||
set. */
|
set. */
|
||||||
|
64
gdb/solib.c
64
gdb/solib.c
@ -518,6 +518,20 @@ solib_bfd_open (char *pathname)
|
|||||||
return abfd;
|
return abfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Boolean for command 'set validate-build-id'. */
|
||||||
|
static int validate_build_id = 1;
|
||||||
|
|
||||||
|
/* Implement 'show validate-build-id'. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_validate_build_id (struct ui_file *file, int from_tty,
|
||||||
|
struct cmd_list_element *c, const char *value)
|
||||||
|
{
|
||||||
|
fprintf_filtered (file, _("Validation a build-id matches to load a shared "
|
||||||
|
"library is %s.\n"),
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
|
||||||
/* Given a pointer to one of the shared objects in our list of mapped
|
/* Given a pointer to one of the shared objects in our list of mapped
|
||||||
objects, use the recorded name to open a bfd descriptor for the
|
objects, use the recorded name to open a bfd descriptor for the
|
||||||
object, build a section table, relocate all the section addresses
|
object, build a section table, relocate all the section addresses
|
||||||
@ -534,7 +548,7 @@ static int
|
|||||||
solib_map_sections (struct so_list *so)
|
solib_map_sections (struct so_list *so)
|
||||||
{
|
{
|
||||||
const struct target_so_ops *ops = solib_ops (target_gdbarch ());
|
const struct target_so_ops *ops = solib_ops (target_gdbarch ());
|
||||||
char *filename;
|
char *filename, *validate_error;
|
||||||
struct target_section *p;
|
struct target_section *p;
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
@ -550,6 +564,29 @@ solib_map_sections (struct so_list *so)
|
|||||||
/* Leave bfd open, core_xfer_memory and "info files" need it. */
|
/* Leave bfd open, core_xfer_memory and "info files" need it. */
|
||||||
so->abfd = abfd;
|
so->abfd = abfd;
|
||||||
|
|
||||||
|
gdb_assert (ops->validate != NULL);
|
||||||
|
|
||||||
|
validate_error = ops->validate (so);
|
||||||
|
if (validate_error != NULL)
|
||||||
|
{
|
||||||
|
if (validate_build_id)
|
||||||
|
{
|
||||||
|
warning (_("Shared object \"%s\" could not be validated (%s) and "
|
||||||
|
"will be ignored; "
|
||||||
|
"or use 'set validate-build-id off'."),
|
||||||
|
so->so_name, validate_error);
|
||||||
|
xfree (validate_error);
|
||||||
|
gdb_bfd_unref (so->abfd);
|
||||||
|
so->abfd = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
warning (_("Shared object \"%s\" could not be validated (%s) "
|
||||||
|
"but it is being loaded due to "
|
||||||
|
"'set validate-build-id off'."),
|
||||||
|
so->so_name, validate_error);
|
||||||
|
xfree (validate_error);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the full path name into so_name, allowing symbol_file_add
|
/* Copy the full path name into so_name, allowing symbol_file_add
|
||||||
to find it later. This also affects the =library-loaded GDB/MI
|
to find it later. This also affects the =library-loaded GDB/MI
|
||||||
event, and in particular the part of that notification providing
|
event, and in particular the part of that notification providing
|
||||||
@ -626,6 +663,9 @@ clear_so (struct so_list *so)
|
|||||||
of the symbol file. */
|
of the symbol file. */
|
||||||
strcpy (so->so_name, so->so_original_name);
|
strcpy (so->so_name, so->so_original_name);
|
||||||
|
|
||||||
|
xfree (so->build_id);
|
||||||
|
so->build_id = NULL;
|
||||||
|
|
||||||
/* Do the same for target-specific data. */
|
/* Do the same for target-specific data. */
|
||||||
if (ops->clear_so != NULL)
|
if (ops->clear_so != NULL)
|
||||||
ops->clear_so (so);
|
ops->clear_so (so);
|
||||||
@ -1657,6 +1697,14 @@ remove_user_added_objfile (struct objfile *objfile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Default implementation does not perform any validation. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
default_solib_validate (const struct so_list *const so)
|
||||||
|
{
|
||||||
|
return NULL; /* No validation. */
|
||||||
|
}
|
||||||
|
|
||||||
extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
|
extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1714,4 +1762,18 @@ PATH and LD_LIBRARY_PATH."),
|
|||||||
reload_shared_libraries,
|
reload_shared_libraries,
|
||||||
show_solib_search_path,
|
show_solib_search_path,
|
||||||
&setlist, &showlist);
|
&setlist, &showlist);
|
||||||
|
|
||||||
|
add_setshow_boolean_cmd ("validate-build-id", class_support,
|
||||||
|
&validate_build_id, _("\
|
||||||
|
Set validation a build-id matches to load a shared library."), _("\
|
||||||
|
SHow validation a build-id matches to load a shared library."), _("\
|
||||||
|
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 (off) or disables (on) loading of such symbol file.\n\
|
||||||
|
Loading non-matching symbol file may confuse debugging including breakage\n\
|
||||||
|
of backtrace output."),
|
||||||
|
NULL,
|
||||||
|
show_validate_build_id,
|
||||||
|
&setlist, &showlist);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -98,4 +98,8 @@ extern void update_solib_breakpoints (void);
|
|||||||
|
|
||||||
extern void handle_solib_event (void);
|
extern void handle_solib_event (void);
|
||||||
|
|
||||||
|
/* Default validation always returns 1. */
|
||||||
|
|
||||||
|
extern char *default_solib_validate (const struct so_list *so);
|
||||||
|
|
||||||
#endif /* SOLIB_H */
|
#endif /* SOLIB_H */
|
||||||
|
18
gdb/solist.h
18
gdb/solist.h
@ -75,6 +75,19 @@ struct so_list
|
|||||||
There may not be just one (e.g. if two segments are relocated
|
There may not be just one (e.g. if two segments are relocated
|
||||||
differently); but this is only used for "info sharedlibrary". */
|
differently); but this is only used for "info sharedlibrary". */
|
||||||
CORE_ADDR addr_low, addr_high;
|
CORE_ADDR addr_low, addr_high;
|
||||||
|
|
||||||
|
/* Build id decoded from .note.gnu.build-id without note header. This is
|
||||||
|
actual BUILD_ID which comes either from the remote target via qXfer
|
||||||
|
packet or via reading target memory. Note that if there's a
|
||||||
|
mismatch with the associated bfd then so->abfd will be cleared.
|
||||||
|
Reading target memory should be done by following execution view
|
||||||
|
of the binary (following program headers in the case of ELF).
|
||||||
|
Computing address from the linking view (following ELF section
|
||||||
|
headers) may give incorrect build-id memory address despite the
|
||||||
|
symbols still match.
|
||||||
|
Such an example is a prelinked vs. unprelinked i386 ELF file. */
|
||||||
|
size_t build_idsz;
|
||||||
|
gdb_byte *build_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct target_so_ops
|
struct target_so_ops
|
||||||
@ -168,6 +181,11 @@ struct target_so_ops
|
|||||||
NULL, in which case no specific preprocessing is necessary
|
NULL, in which case no specific preprocessing is necessary
|
||||||
for this target. */
|
for this target. */
|
||||||
void (*handle_event) (void);
|
void (*handle_event) (void);
|
||||||
|
|
||||||
|
/* Return NULL if SO does match target SO it is supposed to
|
||||||
|
represent. Otherwise return string describing why it does not match.
|
||||||
|
Caller has to free the string. */
|
||||||
|
char *(*validate) (const struct so_list *so);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Free the memory associated with a (so_list *). */
|
/* Free the memory associated with a (so_list *). */
|
||||||
|
Loading…
Reference in New Issue
Block a user