#include "auxv.h"
#include "gdb_bfd.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 int svr4_have_link_map_offsets (void);
{
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
- lm_info = xzalloc (sizeof (*lm_info));
+ lm_info = XCNEW (struct lm_info);
lm_info->lm_addr = lm_addr;
lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
Return a pointer to allocated memory holding the program header contents,
or NULL on failure. If sucessful, and unless P_SECT_SIZE is NULL, the
size of those contents is returned to P_SECT_SIZE. Likewise, the target
- architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE. */
+ architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE and
+ the base address of the section is returned in BASE_ADDR. */
static gdb_byte *
-read_program_header (int type, int *p_sect_size, int *p_arch_size)
+read_program_header (int type, int *p_sect_size, int *p_arch_size,
+ CORE_ADDR *base_addr)
{
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0;
*p_arch_size = arch_size;
if (p_sect_size)
*p_sect_size = sect_size;
+ if (base_addr)
+ *base_addr = sect_addr;
return buf;
}
/* If we didn't find it, use the target auxillary vector. */
if (!buf)
- buf = read_program_header (PT_INTERP, NULL, NULL);
+ buf = read_program_header (PT_INTERP, NULL, NULL, NULL);
return (char *) buf;
}
found, 1 is returned and the corresponding PTR is set. */
static int
-scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
+scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
+ CORE_ADDR *ptr_addr)
{
int arch_size, step, sect_size;
long current_dyntag;
{
struct type *ptr_type;
gdb_byte ptr_buf[8];
- CORE_ADDR ptr_addr;
+ CORE_ADDR ptr_addr_1;
ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
- ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
- if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
+ ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
+ if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
*ptr = dyn_ptr;
+ if (ptr_addr)
+ *ptr_addr = dyn_addr + (buf - bufstart);
}
return 1;
}
is returned and the corresponding PTR is set. */
static int
-scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
+scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr,
+ CORE_ADDR *ptr_addr)
{
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
int sect_size, arch_size, step;
long current_dyntag;
CORE_ADDR dyn_ptr;
+ CORE_ADDR base_addr;
gdb_byte *bufend, *bufstart, *buf;
/* Read in .dynamic section. */
- buf = bufstart = read_program_header (PT_DYNAMIC, §_size, &arch_size);
+ buf = bufstart = read_program_header (PT_DYNAMIC, §_size, &arch_size,
+ &base_addr);
if (!buf)
return 0;
if (ptr)
*ptr = dyn_ptr;
+ if (ptr_addr)
+ *ptr_addr = base_addr + buf - bufstart;
+
xfree (bufstart);
return 1;
}
elf_locate_base (void)
{
struct bound_minimal_symbol msymbol;
- CORE_ADDR dyn_ptr;
+ CORE_ADDR dyn_ptr, dyn_ptr_addr;
/* Look for DT_MIPS_RLD_MAP first. MIPS executables use this
instead of DT_DEBUG, although they sometimes contain an unused
DT_DEBUG. */
- if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)
- || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr))
+ if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr, NULL)
+ || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL))
{
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
gdb_byte *pbuf;
return extract_typed_address (pbuf, ptr_type);
}
+ /* Then check DT_MIPS_RLD_MAP_REL. MIPS executables now use this form
+ because of needing to support PIE. DT_MIPS_RLD_MAP will also exist
+ in non-PIE. */
+ if (scan_dyntag (DT_MIPS_RLD_MAP_REL, exec_bfd, &dyn_ptr, &dyn_ptr_addr)
+ || scan_dyntag_auxv (DT_MIPS_RLD_MAP_REL, &dyn_ptr, &dyn_ptr_addr))
+ {
+ struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+ gdb_byte *pbuf;
+ int pbuf_size = TYPE_LENGTH (ptr_type);
+
+ pbuf = alloca (pbuf_size);
+ /* DT_MIPS_RLD_MAP_REL contains an offset from the address of the
+ DT slot to the address of the dynamic link structure. */
+ if (target_read_memory (dyn_ptr + dyn_ptr_addr, pbuf, pbuf_size))
+ return 0;
+ return extract_typed_address (pbuf, ptr_type);
+ }
+
/* Find DT_DEBUG. */
- if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)
- || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr))
+ if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr, NULL)
+ || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL))
return dyn_ptr;
/* This may be a static executable. Look for the symbol
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.
If no open symbol file, attempt to locate and open the main symbol
{
struct so_list *newobj;
- newobj = xmalloc (sizeof (struct so_list));
+ newobj = XNEW (struct so_list);
memcpy (newobj, src, sizeof (struct so_list));
- newobj->lm_info = xmalloc (sizeof (struct lm_info));
+ newobj->lm_info = XNEW (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;
*link = newobj;
link = &newobj->next;
ULONGEST *lmp = xml_find_attribute (attributes, "lm")->value;
ULONGEST *l_addrp = xml_find_attribute (attributes, "l_addr")->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;
new_elem = XCNEW (struct so_list);
strncpy (new_elem->so_name, name, sizeof (new_elem->so_name) - 1);
new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0;
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->next;
{ "lm", 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 },
- { "build-id", GDB_XML_AF_OPTIONAL, NULL, NULL },
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
newobj = XCNEW (struct so_list);
- newobj->lm_info = xzalloc (sizeof (struct lm_info));
+ newobj->lm_info = XCNEW (struct lm_info);
/* Nothing will ever check the other fields if we set l_addr_p. */
newobj->lm_info->l_addr = info->debug_loader_offset;
solib_event_probe_action (struct probe_and_action *pa)
{
enum probe_action action;
- unsigned probe_argc;
+ unsigned probe_argc = 0;
struct frame_info *frame = get_current_frame ();
action = pa->action;
arg0: Lmid_t lmid (mandatory)
arg1: struct r_debug *debug_base (mandatory)
arg2: struct link_map *new (optional, for incremental updates) */
- probe_argc = get_probe_argument_count (pa->probe, frame);
+ TRY
+ {
+ probe_argc = get_probe_argument_count (pa->probe, frame);
+ }
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ exception_print (gdb_stderr, ex);
+ probe_argc = 0;
+ }
+ END_CATCH
+
+ /* If get_probe_argument_count throws an exception, probe_argc will
+ be set to zero. However, if pa->probe does not have arguments,
+ then get_probe_argument_count will succeed but probe_argc will
+ also be zero. Both cases happen because of different things, but
+ they are treated equally here: action will be set to
+ PROBES_INTERFACE_FAILED. */
if (probe_argc == 2)
action = FULL_RELOAD;
else if (probe_argc < 2)
struct probe_and_action *pa;
enum probe_action action;
struct cleanup *old_chain, *usm_chain;
- struct value *val;
+ struct value *val = NULL;
CORE_ADDR pc, debug_base, lm = 0;
int is_initial_ns;
struct frame_info *frame = get_current_frame ();
usm_chain = make_cleanup (resume_section_map_updates_cleanup,
current_program_space);
- val = evaluate_probe_argument (pa->probe, 1, frame);
+ TRY
+ {
+ val = evaluate_probe_argument (pa->probe, 1, frame);
+ }
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ exception_print (gdb_stderr, ex);
+ val = NULL;
+ }
+ END_CATCH
+
if (val == NULL)
{
do_cleanups (old_chain);
if (action == UPDATE_OR_RELOAD)
{
- val = evaluate_probe_argument (pa->probe, 2, frame);
+ TRY
+ {
+ val = evaluate_probe_argument (pa->probe, 2, frame);
+ }
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ exception_print (gdb_stderr, ex);
+ do_cleanups (old_chain);
+ return;
+ }
+ END_CATCH
+
if (val != NULL)
lm = value_as_address (val);
gdb_byte *buf, *buf2;
int arch_size;
- buf = read_program_header (-1, &phdrs_size, &arch_size);
+ buf = read_program_header (-1, &phdrs_size, &arch_size, NULL);
buf2 = read_program_headers_from_bfd (exec_bfd, &phdrs2_size);
if (buf != NULL && buf2 != NULL)
{
different rule for symbol lookup. The lookup begins here in the DSO, not in
the main executable. */
-static struct symbol *
+static struct block_symbol
elf_lookup_lib_symbol (struct objfile *objfile,
const char *name,
const domain_enum domain)
abfd = objfile->obfd;
}
- if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1)
- return NULL;
+ if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL, NULL) != 1)
+ return (struct block_symbol) {NULL, NULL};
return lookup_global_symbol_from_objfile (objfile, name, domain);
}
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.handle_event = svr4_handle_solib_event;
- svr4_so_ops.validate = svr4_validate;
}