/* Handle SVR4 shared libraries for GDB, the GNU Debugger.
- Copyright (C) 1990-2017 Free Software Foundation, Inc.
+ Copyright (C) 1990-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "infrun.h"
#include "regcache.h"
#include "gdbthread.h"
-#include "observer.h"
+#include "observable.h"
#include "solist.h"
#include "solib.h"
static void svr4_relocate_main_executable (void);
static void svr4_free_library_list (void *p_list);
-/* Link map info to include in an allocated so_list entry. */
-
-struct lm_info
- {
- /* Amount by which addresses in the binary should be relocated to
- match the inferior. The direct inferior value is L_ADDR_INFERIOR.
- When prelinking is involved and the prelink base address changes,
- we may need a different offset - the recomputed offset is in L_ADDR.
- It is commonly the same value. It is cached as we want to warn about
- the difference and compute it only once. L_ADDR is valid
- iff L_ADDR_P. */
- CORE_ADDR l_addr, l_addr_inferior;
- unsigned int l_addr_p : 1;
-
- /* The target location of lm. */
- CORE_ADDR lm_addr;
-
- /* Values read in from inferior's fields of the same name. */
- CORE_ADDR l_ld, l_next, l_prev, l_name;
- };
-
/* On SVR4 systems, a list of symbols in the dynamic linker where
GDB can try to place a breakpoint to monitor shared library
events.
return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name));
}
-static struct lm_info *
+static lm_info_svr4 *
lm_info_read (CORE_ADDR lm_addr)
{
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
gdb_byte *lm;
- struct lm_info *lm_info;
+ lm_info_svr4 *lm_info;
struct cleanup *back_to;
lm = (gdb_byte *) xmalloc (lmo->link_map_size);
{
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
- lm_info = XCNEW (struct lm_info);
+ lm_info = new lm_info_svr4;
lm_info->lm_addr = lm_addr;
lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
static CORE_ADDR
lm_addr_check (const struct so_list *so, bfd *abfd)
{
- if (!so->lm_info->l_addr_p)
+ lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+ if (!li->l_addr_p)
{
struct bfd_section *dyninfo_sect;
CORE_ADDR l_addr, l_dynaddr, dynaddr;
- l_addr = so->lm_info->l_addr_inferior;
+ l_addr = li->l_addr_inferior;
if (! abfd || ! has_lm_dynamic_from_link_map ())
goto set_addr;
- l_dynaddr = so->lm_info->l_ld;
+ l_dynaddr = li->l_ld;
dyninfo_sect = bfd_get_section_by_name (abfd, ".dynamic");
if (dyninfo_sect == NULL)
}
set_addr:
- so->lm_info->l_addr = l_addr;
- so->lm_info->l_addr_p = 1;
+ li->l_addr = l_addr;
+ li->l_addr_p = 1;
}
- return so->lm_info->l_addr;
+ return li->l_addr;
}
/* Per pspace SVR4 specific data. */
/* Table of struct probe_and_action instances, used by the
probes-based interface to map breakpoint addresses to probes
and their associated actions. Lookup is performed using
- probe_and_action->probe->address. */
+ probe_and_action->prob->address. */
htab_t probes_table;
/* List of objects loaded into the inferior, used by the probes-
newobj = XCNEW (struct so_list);
old_chain = make_cleanup (xfree, newobj);
- newobj->lm_info = lm_info_read (ldsomap);
+ lm_info_svr4 *li = lm_info_read (ldsomap);
+ newobj->lm_info = li;
make_cleanup (xfree, newobj->lm_info);
- name_lm = newobj->lm_info ? newobj->lm_info->l_name : 0;
+ name_lm = li != NULL ? li->l_name : 0;
do_cleanups (old_chain);
return (name_lm >= vaddr && name_lm < vaddr + size);
}
-/* Implement the "open_symbol_file_object" target_so_ops method.
-
- If no open symbol file, attempt to locate and open the main symbol
- file. On SVR4 systems, this is the first link map entry. If its
- name is here, we can open it. Useful when attaching to a process
- without first loading its symbol file. */
+/* See solist.h. */
static int
-open_symbol_file_object (void *from_ttyp)
+open_symbol_file_object (int from_tty)
{
CORE_ADDR lm, l_name;
char *filename;
int errcode;
- int from_tty = *(int *)from_ttyp;
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
int l_name_size = TYPE_LENGTH (ptr_type);
static void
svr4_free_so (struct so_list *so)
{
- xfree (so->lm_info);
+ lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+ delete li;
}
/* Implement target_so_ops.clear_so. */
static void
svr4_clear_so (struct so_list *so)
{
- if (so->lm_info != NULL)
- so->lm_info->l_addr_p = 0;
+ lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+ if (li != NULL)
+ li->l_addr_p = 0;
}
/* Free so_list built so far (called via cleanup). */
newobj = XNEW (struct so_list);
memcpy (newobj, src, sizeof (struct so_list));
- newobj->lm_info = XNEW (struct lm_info);
- memcpy (newobj->lm_info, src->lm_info, sizeof (struct lm_info));
+ lm_info_svr4 *src_li = (lm_info_svr4 *) src->lm_info;
+ newobj->lm_info = new lm_info_svr4 (*src_li);
newobj->next = NULL;
*link = newobj;
static void
library_list_start_library (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
- void *user_data, VEC(gdb_xml_value_s) *attributes)
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
{
struct svr4_library_list *list = (struct svr4_library_list *) user_data;
const char *name
- = (const char *) xml_find_attribute (attributes, "name")->value;
+ = (const char *) xml_find_attribute (attributes, "name")->value.get ();
ULONGEST *lmp
- = (ULONGEST *) xml_find_attribute (attributes, "lm")->value;
+ = (ULONGEST *) xml_find_attribute (attributes, "lm")->value.get ();
ULONGEST *l_addrp
- = (ULONGEST *) xml_find_attribute (attributes, "l_addr")->value;
+ = (ULONGEST *) xml_find_attribute (attributes, "l_addr")->value.get ();
ULONGEST *l_ldp
- = (ULONGEST *) xml_find_attribute (attributes, "l_ld")->value;
+ = (ULONGEST *) xml_find_attribute (attributes, "l_ld")->value.get ();
struct so_list *new_elem;
new_elem = XCNEW (struct so_list);
- new_elem->lm_info = XCNEW (struct lm_info);
- new_elem->lm_info->lm_addr = *lmp;
- new_elem->lm_info->l_addr_inferior = *l_addrp;
- new_elem->lm_info->l_ld = *l_ldp;
+ lm_info_svr4 *li = new lm_info_svr4;
+ new_elem->lm_info = li;
+ li->lm_addr = *lmp;
+ li->l_addr_inferior = *l_addrp;
+ li->l_ld = *l_ldp;
strncpy (new_elem->so_name, name, sizeof (new_elem->so_name) - 1);
new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0;
static void
svr4_library_list_start_list (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
- void *user_data, VEC(gdb_xml_value_s) *attributes)
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
{
struct svr4_library_list *list = (struct svr4_library_list *) user_data;
const char *version
- = (const char *) xml_find_attribute (attributes, "version")->value;
+ = (const char *) xml_find_attribute (attributes, "version")->value.get ();
struct gdb_xml_value *main_lm = xml_find_attribute (attributes, "main-lm");
if (strcmp (version, "1.0") != 0)
version);
if (main_lm)
- list->main_lm = *(ULONGEST *) main_lm->value;
+ list->main_lm = *(ULONGEST *) main_lm->value.get ();
}
/* The allowed elements and attributes for an XML library list.
svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list,
const char *annex)
{
- char *svr4_library_document;
- int result;
- struct cleanup *back_to;
-
gdb_assert (annex == NULL || target_augmented_libraries_svr4_read ());
/* Fetch the list of shared libraries. */
- svr4_library_document = target_read_stralloc (¤t_target,
- TARGET_OBJECT_LIBRARIES_SVR4,
- annex);
+ gdb::unique_xmalloc_ptr<char> svr4_library_document
+ = target_read_stralloc (¤t_target, TARGET_OBJECT_LIBRARIES_SVR4,
+ annex);
if (svr4_library_document == NULL)
return 0;
- back_to = make_cleanup (xfree, svr4_library_document);
- result = svr4_parse_libraries (svr4_library_document, list);
- do_cleanups (back_to);
-
- return result;
+ return svr4_parse_libraries (svr4_library_document.get (), list);
}
#else
return NULL;
newobj = XCNEW (struct so_list);
-
- newobj->lm_info = XCNEW (struct lm_info);
+ lm_info_svr4 *li = new lm_info_svr4;
+ newobj->lm_info = li;
/* Nothing will ever check the other fields if we set l_addr_p. */
- newobj->lm_info->l_addr = info->debug_loader_offset;
- newobj->lm_info->l_addr_p = 1;
+ li->l_addr = info->debug_loader_offset;
+ li->l_addr_p = 1;
strncpy (newobj->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
for (; lm != 0; prev_lm = lm, lm = next_lm)
{
- struct so_list *newobj;
- struct cleanup *old_chain;
int errcode;
char *buffer;
- newobj = XCNEW (struct so_list);
- old_chain = make_cleanup_free_so (newobj);
+ so_list_up newobj (XCNEW (struct so_list));
- newobj->lm_info = lm_info_read (lm);
- if (newobj->lm_info == NULL)
- {
- do_cleanups (old_chain);
- return 0;
- }
+ lm_info_svr4 *li = lm_info_read (lm);
+ newobj->lm_info = li;
+ if (li == NULL)
+ return 0;
- next_lm = newobj->lm_info->l_next;
+ next_lm = li->l_next;
- if (newobj->lm_info->l_prev != prev_lm)
+ if (li->l_prev != prev_lm)
{
warning (_("Corrupted shared library list: %s != %s"),
paddress (target_gdbarch (), prev_lm),
- paddress (target_gdbarch (), newobj->lm_info->l_prev));
- do_cleanups (old_chain);
+ paddress (target_gdbarch (), li->l_prev));
return 0;
}
SVR4, it has no name. For others (Solaris 2.3 for example), it
does have a name, so we can no longer use a missing name to
decide when to ignore it. */
- if (ignore_first && newobj->lm_info->l_prev == 0)
+ if (ignore_first && li->l_prev == 0)
{
struct svr4_info *info = get_svr4_info ();
- first_l_name = newobj->lm_info->l_name;
- info->main_lm_addr = newobj->lm_info->lm_addr;
- do_cleanups (old_chain);
+ first_l_name = li->l_name;
+ info->main_lm_addr = li->lm_addr;
continue;
}
/* Extract this shared object's name. */
- target_read_string (newobj->lm_info->l_name, &buffer,
- SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+ target_read_string (li->l_name, &buffer, SO_NAME_MAX_PATH_SIZE - 1,
+ &errcode);
if (errcode != 0)
{
/* If this entry's l_name address matches that of the
inferior executable, then this is not a normal shared
object, but (most likely) a vDSO. In this case, silently
skip it; otherwise emit a warning. */
- if (first_l_name == 0 || newobj->lm_info->l_name != first_l_name)
+ if (first_l_name == 0 || li->l_name != first_l_name)
warning (_("Can't read pathname for load map: %s."),
safe_strerror (errcode));
- do_cleanups (old_chain);
continue;
}
/* If this entry has no name, or its name matches the name
for the main executable, don't include it in the list. */
if (! newobj->so_name[0] || match_main (newobj->so_name))
- {
- do_cleanups (old_chain);
- continue;
- }
+ continue;
- discard_cleanups (old_chain);
newobj->next = 0;
- **link_ptr_ptr = newobj;
- *link_ptr_ptr = &newobj->next;
+ /* Don't free it now. */
+ **link_ptr_ptr = newobj.release ();
+ *link_ptr_ptr = &(**link_ptr_ptr)->next;
}
return 1;
[...]
[ 9] .dynamic DYNAMIC ffffffffff700580 000580 0000f0
*/
- if (address_in_mem_range (so->lm_info->l_ld, &vsyscall_range))
+
+ lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+ if (address_in_mem_range (li->l_ld, &vsyscall_range))
{
*sop = so->next;
free_so (so);
/* Cause svr4_current_sos() to be run if it hasn't been already. */
if (info->main_lm_addr == 0)
- solib_add (NULL, 0, ¤t_target, auto_solib_add);
+ solib_add (NULL, 0, auto_solib_add);
/* svr4_current_sos() will set main_lm_addr for the main executable. */
if (objfile == symfile_objfile)
of shared libraries. */
for (so = master_so_list (); so; so = so->next)
if (so->objfile == objfile)
- return so->lm_info->lm_addr;
+ {
+ lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+ return li->lm_addr;
+ }
/* Not found! */
return 0;
struct probe_and_action
{
/* The probe. */
- struct probe *probe;
+ probe *prob;
/* The relocated address of the probe. */
CORE_ADDR address;
probes table. */
static void
-register_solib_event_probe (struct probe *probe, CORE_ADDR address,
+register_solib_event_probe (probe *prob, CORE_ADDR address,
enum probe_action action)
{
struct svr4_info *info = get_svr4_info ();
equal_probe_and_action,
xfree, xcalloc, xfree);
- lookup.probe = probe;
+ lookup.prob = prob;
lookup.address = address;
slot = htab_find_slot (info->probes_table, &lookup, INSERT);
gdb_assert (*slot == HTAB_EMPTY_ENTRY);
pa = XCNEW (struct probe_and_action);
- pa->probe = probe;
+ pa->prob = prob;
pa->address = address;
pa->action = action;
arg2: struct link_map *new (optional, for incremental updates) */
TRY
{
- probe_argc = get_probe_argument_count (pa->probe, frame);
+ probe_argc = pa->prob->get_argument_count (frame);
}
CATCH (ex, RETURN_MASK_ERROR)
{
}
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
+ /* If get_argument_count throws an exception, probe_argc will be set
+ to zero. However, if pa->prob does not have arguments, then
+ get_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;
/* Walk to the end of the list. */
for (tail = info->solib_list; tail->next != NULL; tail = tail->next)
/* Nothing. */;
- prev_lm = tail->lm_info->lm_addr;
+
+ lm_info_svr4 *li = (lm_info_svr4 *) tail->lm_info;
+ prev_lm = li->lm_addr;
/* Read the new objects. */
if (info->using_xfer)
return;
}
- /* evaluate_probe_argument looks up symbols in the dynamic linker
+ /* evaluate_argument looks up symbols in the dynamic linker
using find_pc_section. find_pc_section is accelerated by a cache
called the section map. The section map is invalidated every
time a shared library is loaded or unloaded, and if the inferior
We called find_pc_section in svr4_create_solib_event_breakpoints,
so we can guarantee that the dynamic linker's sections are in the
section map. We can therefore inhibit section map updates across
- these calls to evaluate_probe_argument and save a lot of time. */
+ these calls to evaluate_argument and save a lot of time. */
inhibit_section_map_updates (current_program_space);
usm_chain = make_cleanup (resume_section_map_updates_cleanup,
current_program_space);
TRY
{
- val = evaluate_probe_argument (pa->probe, 1, frame);
+ val = pa->prob->evaluate_argument (1, frame);
}
CATCH (ex, RETURN_MASK_ERROR)
{
{
TRY
{
- val = evaluate_probe_argument (pa->probe, 2, frame);
+ val = pa->prob->evaluate_argument (2, frame);
}
CATCH (ex, RETURN_MASK_ERROR)
{
static void
svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
- VEC (probe_p) **probes,
+ const std::vector<probe *> *probes,
struct objfile *objfile)
{
- int i;
-
- for (i = 0; i < NUM_PROBES; i++)
+ for (int i = 0; i < NUM_PROBES; i++)
{
enum probe_action action = probe_info[i].action;
- struct probe *probe;
- int ix;
- for (ix = 0;
- VEC_iterate (probe_p, probes[i], ix, probe);
- ++ix)
+ for (probe *p : probes[i])
{
- CORE_ADDR address = get_probe_address (probe, objfile);
+ CORE_ADDR address = p->get_relocated_address (objfile);
create_solib_event_breakpoint (gdbarch, address);
- register_solib_event_probe (probe, address, action);
+ register_solib_event_probe (p, address, action);
}
}
for (with_prefix = 0; with_prefix <= 1; with_prefix++)
{
- VEC (probe_p) *probes[NUM_PROBES];
+ std::vector<probe *> probes[NUM_PROBES];
int all_probes_found = 1;
int checked_can_use_probe_arguments = 0;
- int i;
- memset (probes, 0, sizeof (probes));
- for (i = 0; i < NUM_PROBES; i++)
+ for (int i = 0; i < NUM_PROBES; i++)
{
const char *name = probe_info[i].name;
- struct probe *p;
+ probe *p;
char buf[32];
/* Fedora 17 and Red Hat Enterprise Linux 6.2-6.4
if (strcmp (name, "rtld_map_failed") == 0)
continue;
- if (VEC_empty (probe_p, probes[i]))
+ if (probes[i].empty ())
{
all_probes_found = 0;
break;
/* Ensure probe arguments can be evaluated. */
if (!checked_can_use_probe_arguments)
{
- p = VEC_index (probe_p, probes[i], 0);
- if (!can_evaluate_probe_arguments (p))
+ p = probes[i][0];
+ if (!p->can_evaluate_arguments ())
{
all_probes_found = 0;
break;
if (all_probes_found)
svr4_create_probe_breakpoints (gdbarch, probes, os->objfile);
- for (i = 0; i < NUM_PROBES; i++)
- VEC_free (probe_p, probes[i]);
-
if (all_probes_found)
return;
}
mean r_brk has already been relocated. Assume the dynamic linker
is the object containing r_brk. */
- solib_add (NULL, from_tty, ¤t_target, auto_solib_add);
+ solib_add (NULL, from_tty, auto_solib_add);
sym_addr = 0;
if (info->debug_base && solib_svr4_r_map (info) != 0)
sym_addr = solib_svr4_r_brk (info);
info->debug_loader_name = xstrdup (interp_name);
info->debug_loader_offset_p = 1;
info->debug_loader_offset = load_addr;
- solib_add (NULL, from_tty, ¤t_target, auto_solib_add);
+ solib_add (NULL, from_tty, auto_solib_add);
}
/* Record the relocated start and end address of the dynamic linker
return lookup_global_symbol_from_objfile (objfile, name, domain);
}
-extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
-
void
_initialize_svr4_solib (void)
{