static void svr4_relocate_main_executable (void);
static void svr4_free_library_list (void *p_list);
static void probes_table_remove_objfile_probes (struct objfile *objfile);
+static void svr4_iterate_over_objfiles_in_search_order (
+ struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb,
+ void *cb_data, struct objfile *objfile);
+
/* On SVR4 systems, a list of symbols in the dynamic linker where
GDB can try to place a breakpoint to monitor shared library
if (dyninfo_sect == NULL)
goto set_addr;
- dynaddr = bfd_section_vma (abfd, dyninfo_sect);
+ dynaddr = bfd_section_vma (dyninfo_sect);
if (dynaddr + l_addr != l_dynaddr)
{
interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
if (interp_sect != NULL)
{
- int sect_size = bfd_section_size (exec_bfd, interp_sect);
+ int sect_size = bfd_section_size (interp_sect);
gdb::byte_vector buf (sect_size);
bfd_get_section_contents (exec_bfd, interp_sect, buf.data (), 0,
such fallback to the file VMA address without the possibility of
having the section relocated to its actual in-memory address. */
- dyn_addr = bfd_section_vma (abfd, sect);
+ dyn_addr = bfd_section_vma (sect);
}
/* Read in .dynamic from the BFD. We will get the actual value
from memory later. */
- sect_size = bfd_section_size (abfd, sect);
+ sect_size = bfd_section_size (sect);
buf = bufstart = (gdb_byte *) alloca (sect_size);
if (!bfd_get_section_contents (abfd, sect,
buf, 0, sect_size))
arg2: struct link_map *new (optional, for incremental updates) */
try
{
- probe_argc = pa->prob->get_argument_count (frame);
+ probe_argc = pa->prob->get_argument_count (get_frame_arch (frame));
}
catch (const gdb_exception_error &ex)
{
svr4_update_solib_event_breakpoints ();
}
+/* Find all the glibc named probes. Only if all of the probes are found, then
+ create them and return true. Otherwise return false. If WITH_PREFIX is set
+ then add "rtld" to the front of the probe names. */
+static bool
+svr4_find_and_create_probe_breakpoints (svr4_info *info,
+ struct gdbarch *gdbarch,
+ struct obj_section *os,
+ bool with_prefix)
+{
+ std::vector<probe *> probes[NUM_PROBES];
+
+ for (int i = 0; i < NUM_PROBES; i++)
+ {
+ const char *name = probe_info[i].name;
+ char buf[32];
+
+ /* Fedora 17 and Red Hat Enterprise Linux 6.2-6.4 shipped with an early
+ version of the probes code in which the probes' names were prefixed
+ with "rtld_" and the "map_failed" probe did not exist. The locations
+ of the probes are otherwise the same, so we check for probes with
+ prefixed names if probes with unprefixed names are not present. */
+ if (with_prefix)
+ {
+ xsnprintf (buf, sizeof (buf), "rtld_%s", name);
+ name = buf;
+ }
+
+ probes[i] = find_probes_in_objfile (os->objfile, "rtld", name);
+
+ /* The "map_failed" probe did not exist in early
+ versions of the probes code in which the probes'
+ names were prefixed with "rtld_". */
+ if (with_prefix && streq (name, "rtld_map_failed"))
+ continue;
+
+ /* Ensure at least one probe for the current name was found. */
+ if (probes[i].empty ())
+ return false;
+
+ /* Ensure probe arguments can be evaluated. */
+ for (probe *p : probes[i])
+ {
+ if (!p->can_evaluate_arguments ())
+ return false;
+ /* This will fail if the probe is invalid. This has been seen on Arm
+ due to references to symbols that have been resolved away. */
+ try
+ {
+ p->get_argument_count (gdbarch);
+ }
+ catch (const gdb_exception_error &ex)
+ {
+ exception_print (gdb_stderr, ex);
+ warning (_("Initializing probes-based dynamic linker interface "
+ "failed.\nReverting to original interface."));
+ return false;
+ }
+ }
+ }
+
+ /* All probes found. Now create them. */
+ svr4_create_probe_breakpoints (info, gdbarch, probes, os->objfile);
+ return true;
+}
+
/* Both the SunOS and the SVR4 dynamic linkers call a marker function
before and after mapping and unmapping shared libraries. The sole
purpose of this method is to allow debuggers to set a breakpoint so
svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
CORE_ADDR address)
{
- struct obj_section *os;
-
- os = find_pc_section (address);
- if (os != NULL)
- {
- int with_prefix;
-
- for (with_prefix = 0; with_prefix <= 1; with_prefix++)
- {
- std::vector<probe *> probes[NUM_PROBES];
- int all_probes_found = 1;
- int checked_can_use_probe_arguments = 0;
-
- for (int i = 0; i < NUM_PROBES; i++)
- {
- const char *name = probe_info[i].name;
- probe *p;
- char buf[32];
-
- /* Fedora 17 and Red Hat Enterprise Linux 6.2-6.4
- shipped with an early version of the probes code in
- which the probes' names were prefixed with "rtld_"
- and the "map_failed" probe did not exist. The
- locations of the probes are otherwise the same, so
- we check for probes with prefixed names if probes
- with unprefixed names are not present. */
- if (with_prefix)
- {
- xsnprintf (buf, sizeof (buf), "rtld_%s", name);
- name = buf;
- }
+ struct obj_section *os = find_pc_section (address);
- probes[i] = find_probes_in_objfile (os->objfile, "rtld", name);
-
- /* The "map_failed" probe did not exist in early
- versions of the probes code in which the probes'
- names were prefixed with "rtld_". */
- if (strcmp (name, "rtld_map_failed") == 0)
- continue;
-
- if (probes[i].empty ())
- {
- all_probes_found = 0;
- break;
- }
-
- /* Ensure probe arguments can be evaluated. */
- if (!checked_can_use_probe_arguments)
- {
- p = probes[i][0];
- if (!p->can_evaluate_arguments ())
- {
- all_probes_found = 0;
- break;
- }
- checked_can_use_probe_arguments = 1;
- }
- }
-
- if (all_probes_found)
- svr4_create_probe_breakpoints (info, gdbarch, probes, os->objfile);
-
- if (all_probes_found)
- return;
- }
- }
-
- create_solib_event_breakpoint (gdbarch, address);
+ if (os == nullptr
+ || (!svr4_find_and_create_probe_breakpoints (info, gdbarch, os, false)
+ && !svr4_find_and_create_probe_breakpoints (info, gdbarch, os, true)))
+ create_solib_event_breakpoint (gdbarch, address);
}
/* Helper function for gdb_bfd_lookup_symbol. */
interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
if (interp_sect)
{
- info->interp_text_sect_low =
- bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
- info->interp_text_sect_high =
- info->interp_text_sect_low
- + bfd_section_size (tmp_bfd, interp_sect);
+ info->interp_text_sect_low
+ = bfd_section_vma (interp_sect) + load_addr;
+ info->interp_text_sect_high
+ = info->interp_text_sect_low + bfd_section_size (interp_sect);
}
interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
if (interp_sect)
{
- info->interp_plt_sect_low =
- bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
- info->interp_plt_sect_high =
- info->interp_plt_sect_low
- + bfd_section_size (tmp_bfd, interp_sect);
+ info->interp_plt_sect_low
+ = bfd_section_vma (interp_sect) + load_addr;
+ info->interp_plt_sect_high
+ = info->interp_plt_sect_low + bfd_section_size (interp_sect);
}
svr4_create_solib_event_breakpoints (info, target_gdbarch (), sym_addr);
interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text");
if (interp_sect)
{
- info->interp_text_sect_low =
- bfd_section_vma (tmp_bfd.get (), interp_sect) + load_addr;
- info->interp_text_sect_high =
- info->interp_text_sect_low
- + bfd_section_size (tmp_bfd.get (), interp_sect);
+ info->interp_text_sect_low
+ = bfd_section_vma (interp_sect) + load_addr;
+ info->interp_text_sect_high
+ = info->interp_text_sect_low + bfd_section_size (interp_sect);
}
interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt");
if (interp_sect)
{
- info->interp_plt_sect_low =
- bfd_section_vma (tmp_bfd.get (), interp_sect) + load_addr;
- info->interp_plt_sect_high =
- info->interp_plt_sect_low
- + bfd_section_size (tmp_bfd.get (), interp_sect);
+ info->interp_plt_sect_low
+ = bfd_section_vma (interp_sect) + load_addr;
+ info->interp_plt_sect_high
+ = info->interp_plt_sect_low + bfd_section_size (interp_sect);
}
/* Now try to set a breakpoint in the dynamic linker. */
gdb_byte *buf_filesz_p = (gdb_byte *) &phdrp->p_filesz;
CORE_ADDR filesz;
- content2 = (bfd_get_section_flags (exec_bfd, plt2_asect)
+ content2 = (bfd_section_flags (plt2_asect)
& SEC_HAS_CONTENTS) != 0;
filesz = extract_unsigned_integer (buf_filesz_p, 4,
/* PLT2_ASECT is from on-disk file (exec_bfd) while
FILESZ is from the in-memory image. */
if (content2)
- filesz += bfd_get_section_size (plt2_asect);
+ filesz += bfd_section_size (plt2_asect);
else
- filesz -= bfd_get_section_size (plt2_asect);
+ filesz -= bfd_section_size (plt2_asect);
store_unsigned_integer (buf_filesz_p, 4, byte_order,
filesz);
gdb_byte *buf_filesz_p = (gdb_byte *) &phdrp->p_filesz;
CORE_ADDR filesz;
- content2 = (bfd_get_section_flags (exec_bfd, plt2_asect)
+ content2 = (bfd_section_flags (plt2_asect)
& SEC_HAS_CONTENTS) != 0;
filesz = extract_unsigned_integer (buf_filesz_p, 8,
/* PLT2_ASECT is from on-disk file (exec_bfd) while
FILESZ is from the in-memory image. */
if (content2)
- filesz += bfd_get_section_size (plt2_asect);
+ filesz += bfd_section_size (plt2_asect);
else
- filesz -= bfd_get_section_size (plt2_asect);
+ filesz -= bfd_section_size (plt2_asect);
store_unsigned_integer (buf_filesz_p, 8, byte_order,
filesz);
for (asect = exec_bfd->sections; asect != NULL; asect = asect->next)
exec_set_section_address (bfd_get_filename (exec_bfd), asect->index,
- (bfd_section_vma (exec_bfd, asect)
- + displacement));
+ bfd_section_vma (asect) + displacement);
}
}
ops->fetch_link_map_offsets = flmo;
set_solib_ops (gdbarch, &svr4_so_ops);
+ set_gdbarch_iterate_over_objfiles_in_search_order
+ (gdbarch, svr4_iterate_over_objfiles_in_search_order);
}
/* Fetch a link_map_offsets structure using the architecture-specific
struct target_so_ops svr4_so_ops;
-/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
+/* Search order for ELF DSOs linked with -Bsymbolic. Those DSOs have a
different rule for symbol lookup. The lookup begins here in the DSO, not in
the main executable. */
-static struct block_symbol
-elf_lookup_lib_symbol (struct objfile *objfile,
- const char *name,
- const domain_enum domain)
+static void
+svr4_iterate_over_objfiles_in_search_order
+ (struct gdbarch *gdbarch,
+ iterate_over_objfiles_in_search_order_cb_ftype *cb,
+ void *cb_data, struct objfile *current_objfile)
{
- bfd *abfd;
-
- if (objfile == symfile_objfile)
- abfd = exec_bfd;
- else
+ bool checked_current_objfile = false;
+ if (current_objfile != nullptr)
{
- /* OBJFILE should have been passed as the non-debug one. */
- gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
+ bfd *abfd;
- abfd = objfile->obfd;
- }
+ if (current_objfile->separate_debug_objfile_backlink != nullptr)
+ current_objfile = current_objfile->separate_debug_objfile_backlink;
- if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL, NULL) != 1)
- return {};
+ if (current_objfile == symfile_objfile)
+ abfd = exec_bfd;
+ else
+ abfd = current_objfile->obfd;
- return lookup_global_symbol_from_objfile (objfile, name, domain);
+ if (abfd != nullptr &&
+ scan_dyntag (DT_SYMBOLIC, abfd, nullptr, nullptr) == 1)
+ {
+ checked_current_objfile = true;
+ if (cb (current_objfile, cb_data) != 0)
+ return;
+ }
+ }
+
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ if (checked_current_objfile && objfile == current_objfile)
+ continue;
+ if (cb (objfile, cb_data) != 0)
+ return;
+ }
}
void
svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
svr4_so_ops.bfd_open = solib_bfd_open;
- svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
svr4_so_ops.same = svr4_same;
svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core;
svr4_so_ops.update_breakpoints = svr4_update_solib_event_breakpoints;