diff options
Diffstat (limited to 'gdb/solib.c')
-rw-r--r-- | gdb/solib.c | 230 |
1 files changed, 108 insertions, 122 deletions
diff --git a/gdb/solib.c b/gdb/solib.c index 85ec6bb..e43b1a3 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -37,7 +37,6 @@ #include "elf/common.h" #include "filenames.h" #include "exec.h" -#include "solist.h" #include "observable.h" #include "readline/tilde.h" #include "solib.h" @@ -468,6 +467,12 @@ solib_bfd_open (const char *pathname) return abfd; } +gdb_bfd_ref_ptr +solib_ops::bfd_open (const char *pathname) const +{ + return solib_bfd_open (pathname); +} + /* 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 object, build a section table, relocate all the section addresses @@ -483,10 +488,8 @@ solib_bfd_open (const char *pathname) static int solib_map_sections (solib &so) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); - - gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so.so_name.c_str ())); - gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ())); + gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so.name.c_str ())); + gdb_bfd_ref_ptr abfd (so.ops ().bfd_open (filename.get ())); /* If we have a core target then the core target might have some helpful information (i.e. build-ids) about the shared libraries we are trying @@ -496,9 +499,9 @@ solib_map_sections (solib &so) If we don't have a core target then this will return an empty struct with no hint information, we then lookup the shared library based on its filename. */ - std::optional<CORE_ADDR> solib_addr = ops->find_solib_addr (so); + std::optional<CORE_ADDR> solib_addr = so.ops ().find_solib_addr (so); std::optional <const core_target_mapped_file_info> mapped_file_info - = core_target_find_mapped_file (so.so_name.c_str (), solib_addr); + = core_target_find_mapped_file (so.name.c_str (), solib_addr); /* If we already know the build-id of this solib from a core file, verify it matches ABFD's build-id. If there is a mismatch or the solib wasn't @@ -520,14 +523,14 @@ solib_map_sections (solib &so) However, if it was good enough during the mapped file processing, we assume it's good enough now. */ if (!mapped_file_info->filename ().empty ()) - abfd = ops->bfd_open (mapped_file_info->filename ().c_str ()); + abfd = so.ops ().bfd_open (mapped_file_info->filename ().c_str ()); else abfd = nullptr; if (abfd == nullptr) abfd = find_objfile_by_build_id (current_program_space, mapped_file_info->build_id (), - so.so_name.c_str ()); + so.name.c_str ()); if (abfd == nullptr && mismatch) { @@ -545,14 +548,14 @@ solib_map_sections (solib &so) /* Leave bfd open, core_xfer_memory and "info files" need it. */ so.abfd = std::move (abfd); - /* 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 event, and in particular the part of that notification providing the library's host-side path. If we let the target dictate that objfile's path, and the target is different from the host, GDB/MI will not provide the correct host-side path. */ - so.so_name = bfd_get_filename (so.abfd.get ()); + so.name = bfd_get_filename (so.abfd.get ()); so.sections = build_section_table (so.abfd.get ()); for (target_section &p : so.sections) @@ -560,7 +563,7 @@ solib_map_sections (solib &so) /* Relocate the section binding addresses as recorded in the shared object's file by the base address to which the object was actually mapped. */ - ops->relocate_section_addresses (so, &p); + so.ops ().relocate_section_addresses (so, &p); /* If the target didn't provide information about the address range of the shared object, assume we want the location of @@ -582,13 +585,11 @@ solib_map_sections (solib &so) return 1; } -/* See solist.h. */ +/* See solib.h. */ void solib::clear () { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); - this->sections.clear (); this->abfd = nullptr; @@ -600,11 +601,10 @@ solib::clear () /* Restore the target-supplied file name. SO_NAME may be the path of the symbol file. */ - this->so_name = this->so_original_name; + this->name = this->original_name; /* Do the same for target-specific data. */ - if (ops->clear_so != NULL) - ops->clear_so (*this); + this->ops ().clear_so (*this); } lm_info::~lm_info () = default; @@ -634,7 +634,7 @@ solib_read_symbols (solib &so, symfile_add_flags flags) so.objfile = nullptr; for (objfile *objfile : current_program_space->objfiles ()) { - if (filename_cmp (objfile_name (objfile), so.so_name.c_str ()) + if (filename_cmp (objfile_name (objfile), so.name.c_str ()) == 0 && objfile->addr_low == so.addr_low) { @@ -648,7 +648,7 @@ solib_read_symbols (solib &so, symfile_add_flags flags) = build_section_addr_info_from_section_table (so.sections); gdb_bfd_ref_ptr tmp_bfd = so.abfd; so.objfile - = symbol_file_add_from_bfd (tmp_bfd, so.so_name.c_str (), + = symbol_file_add_from_bfd (tmp_bfd, so.name.c_str (), flags, &sap, OBJF_SHARED, nullptr); so.objfile->addr_low = so.addr_low; } @@ -660,7 +660,7 @@ solib_read_symbols (solib &so, symfile_add_flags flags) exception_fprintf (gdb_stderr, e, _ ("Error while reading shared" " library symbols for %s:\n"), - so.so_name.c_str ()); + so.name.c_str ()); } return true; @@ -712,7 +712,10 @@ notify_solib_unloaded (program_space *pspace, const solib &so, void update_solib_list (int from_tty) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); + const solib_ops *ops = current_program_space->solib_ops (); + + if (ops == nullptr) + return; /* We can reach here due to changing solib-search-path or the sysroot, before having any inferior. */ @@ -724,7 +727,7 @@ update_solib_list (int from_tty) have not opened a symbol file, we may be able to get its symbols now! */ if (inf->attach_flag - && current_program_space->symfile_object_file == NULL) + && current_program_space->symfile_object_file == nullptr) { try { @@ -765,27 +768,16 @@ update_solib_list (int from_tty) owning_intrusive_list<solib> inferior = ops->current_sos (); owning_intrusive_list<solib>::iterator gdb_iter - = current_program_space->so_list.begin (); - while (gdb_iter != current_program_space->so_list.end ()) + = current_program_space->solibs ().begin (); + while (gdb_iter != current_program_space->solibs ().end ()) { intrusive_list<solib>::iterator inferior_iter = inferior.begin (); /* Check to see whether the shared object *gdb also appears in the inferior's current list. */ for (; inferior_iter != inferior.end (); ++inferior_iter) - { - if (ops->same) - { - if (ops->same (*gdb_iter, *inferior_iter)) - break; - } - else - { - if (!filename_cmp (gdb_iter->so_original_name.c_str (), - inferior_iter->so_original_name.c_str ())) - break; - } - } + if (ops->same (*gdb_iter, *inferior_iter)) + break; /* If the shared object appears on the inferior's list too, then it's still loaded, so we don't need to do anything. Delete @@ -814,13 +806,13 @@ update_solib_list (int from_tty) && !still_in_use) gdb_iter->objfile->unlink (); - current_program_space->deleted_solibs.push_back (gdb_iter->so_name); + current_program_space->deleted_solibs.push_back (gdb_iter->name); /* Some targets' section tables might be referring to sections from so.abfd; remove them. */ current_program_space->remove_target_sections (&*gdb_iter); - gdb_iter = current_program_space->so_list.erase (gdb_iter); + gdb_iter = current_program_space->solibs ().erase (gdb_iter); } } @@ -844,7 +836,7 @@ update_solib_list (int from_tty) { not_found++; if (not_found_filename == NULL) - not_found_filename = new_so.so_original_name.c_str (); + not_found_filename = new_so.original_name.c_str (); } } @@ -861,7 +853,7 @@ update_solib_list (int from_tty) } /* Add the new shared objects to GDB's list. */ - current_program_space->so_list.splice (std::move (inferior)); + current_program_space->solibs ().splice (std::move (inferior)); /* If a library was not found, issue an appropriate warning message. We have to use a single call to warning in case the @@ -918,7 +910,7 @@ libpthread_name_p (const char *name) static bool libpthread_solib_p (const solib &so) { - return libpthread_name_p (so.so_name.c_str ()); + return libpthread_name_p (so.name.c_str ()); } /* Read in symbolic information for any shared objects whose names @@ -968,7 +960,7 @@ solib_add (const char *pattern, int from_tty, int readsyms) add_flags |= SYMFILE_VERBOSE; for (solib &gdb : current_program_space->solibs ()) - if (!pattern || re_exec (gdb.so_name.c_str ())) + if (!pattern || re_exec (gdb.name.c_str ())) { /* Normally, we would read the symbols from that library only if READSYMS is set. However, we're making a small @@ -987,7 +979,7 @@ solib_add (const char *pattern, int from_tty, int readsyms) if (pattern && (from_tty || info_verbose)) gdb_printf (_ ("Symbols already loaded for %ps\n"), styled_string (file_name_style.style (), - gdb.so_name.c_str ())); + gdb.name.c_str ())); } else if (solib_read_symbols (gdb, add_flags)) loaded_any_symbols = true; @@ -1025,16 +1017,21 @@ print_solib_list_table (std::vector<const solib *> solib_list, gdbarch *gdbarch = current_inferior ()->arch (); /* "0x", a little whitespace, and two hex digits per byte of pointers. */ int addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4); - const solib_ops *ops = gdbarch_so_ops (gdbarch); + const solib_ops *ops = current_program_space->solib_ops (); struct ui_out *uiout = current_uiout; bool so_missing_debug_info = false; + if (ops == nullptr) + return; + /* There are 3 conditions for this command to print solib namespaces, first PRINT_NAMESPACE has to be true, second the solib_ops has to support multiple namespaces, and third there must be more than one active namespace. Fold all these into the PRINT_NAMESPACE condition. */ - print_namespace = print_namespace && ops->num_active_namespaces != nullptr - && ops->num_active_namespaces () > 1; + print_namespace = (print_namespace + && ops != nullptr + && ops->supports_namespaces () + && ops->num_active_namespaces () > 1); int num_cols = 4; if (print_namespace) @@ -1056,7 +1053,7 @@ print_solib_list_table (std::vector<const solib *> solib_list, for (const solib *so : solib_list) { - if (so->so_name.empty ()) + if (so->name.empty ()) continue; ui_out_emit_tuple tuple_emitter (uiout, "lib"); @@ -1085,7 +1082,7 @@ print_solib_list_table (std::vector<const solib *> solib_list, } if (!top_level_interpreter ()->interp_ui_out ()->is_mi_like_p () - && so->symbols_loaded && !objfile_has_symbols (so->objfile)) + && so->symbols_loaded && !so->objfile->has_symbols ()) { so_missing_debug_info = true; uiout->field_string ("syms-read", "Yes (*)"); @@ -1093,7 +1090,7 @@ print_solib_list_table (std::vector<const solib *> solib_list, else uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No"); - uiout->field_string ("name", so->so_name, file_name_style.style ()); + uiout->field_string ("name", so->name, file_name_style.style ()); uiout->text ("\n"); } @@ -1130,9 +1127,9 @@ info_sharedlibrary_command (const char *pattern, int from_tty) std::vector<const solib *> print_libs; for (const solib &so : current_program_space->solibs ()) { - if (!so.so_name.empty ()) + if (!so.name.empty ()) { - if (pattern && !re_exec (so.so_name.c_str ())) + if (pattern && !re_exec (so.name.c_str ())) continue; print_libs.push_back (&so); } @@ -1159,12 +1156,13 @@ info_sharedlibrary_command (const char *pattern, int from_tty) static void info_linker_namespace_command (const char *pattern, int from_tty) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); + const solib_ops *ops = current_program_space->solib_ops (); + /* This command only really makes sense for inferiors that support linker namespaces, so we can leave early. */ - if (ops->num_active_namespaces == nullptr) - error (_("Current inferior does not support linker namespaces." \ - "Use \"info sharedlibrary\" instead")); + if (ops == nullptr || !ops->supports_namespaces ()) + error (_("Current inferior does not support linker namespaces. " + "Use \"info sharedlibrary\" instead.")); struct ui_out *uiout = current_uiout; std::vector<std::pair<int, std::vector<const solib *>>> all_solibs_to_print; @@ -1265,24 +1263,28 @@ solib_contains_address_p (const solib &solib, CORE_ADDR address) const char * solib_name_from_address (struct program_space *pspace, CORE_ADDR address) { - for (const solib &so : pspace->so_list) + for (const solib &so : pspace->solibs ()) if (solib_contains_address_p (so, address)) - return so.so_name.c_str (); + return so.name.c_str (); return nullptr; } +bool +solib_ops::same (const solib &a, const solib &b) const +{ + return (filename_cmp (a.original_name.c_str (), b.original_name.c_str ()) + == 0); +} + /* See solib.h. */ bool solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); + const solib_ops *ops = current_program_space->solib_ops (); - if (ops->keep_data_in_core) - return ops->keep_data_in_core (vaddr, size) != 0; - else - return false; + return ops != nullptr && ops->keep_data_in_core (vaddr, size); } /* See solib.h. */ @@ -1290,9 +1292,7 @@ solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) void clear_solib (program_space *pspace) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); - - for (solib &so : pspace->so_list) + for (solib &so : pspace->solibs ()) { bool still_in_use = (so.objfile != nullptr && solib_used (pspace, so)); @@ -1301,9 +1301,10 @@ clear_solib (program_space *pspace) pspace->remove_target_sections (&so); }; - pspace->so_list.clear (); + pspace->solibs ().clear (); - if (ops->clear_solib != nullptr) + if (const solib_ops *ops = pspace->solib_ops (); + ops != nullptr) ops->clear_solib (pspace); } @@ -1315,9 +1316,9 @@ clear_solib (program_space *pspace) void solib_create_inferior_hook (int from_tty) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); - - ops->solib_create_inferior_hook (from_tty); + if (const solib_ops *ops = current_program_space->solib_ops (); + ops != nullptr) + ops->create_inferior_hook (from_tty); } /* See solib.h. */ @@ -1325,9 +1326,9 @@ solib_create_inferior_hook (int from_tty) bool in_solib_dynsym_resolve_code (CORE_ADDR pc) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); + const solib_ops *ops = current_program_space->solib_ops (); - return ops->in_dynsym_resolve_code (pc) != 0; + return ops != nullptr && ops->in_dynsym_resolve_code (pc); } /* Implements the "sharedlibrary" command. */ @@ -1369,9 +1370,9 @@ no_shared_libraries_command (const char *ignored, int from_tty) void update_solib_breakpoints (void) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); + const solib_ops *ops = current_program_space->solib_ops (); - if (ops->update_breakpoints != NULL) + if (ops != nullptr) ops->update_breakpoints (); } @@ -1380,9 +1381,8 @@ update_solib_breakpoints (void) void handle_solib_event (void) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); - - if (ops->handle_event != NULL) + if (const solib_ops *ops = current_program_space->solib_ops (); + ops != nullptr) ops->handle_event (); current_inferior ()->pspace->clear_solib_cache (); @@ -1414,8 +1414,9 @@ reload_shared_libraries_1 (int from_tty) add_flags |= SYMFILE_VERBOSE; gdb::unique_xmalloc_ptr<char> filename ( - tilde_expand (so.so_original_name.c_str ())); - gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ())); + tilde_expand (so.original_name.c_str ())); + + gdb_bfd_ref_ptr abfd = so.ops ().bfd_open (filename.get ()); if (abfd != NULL) found_pathname = bfd_get_filename (abfd.get ()); @@ -1423,7 +1424,7 @@ reload_shared_libraries_1 (int from_tty) symbol file, close that. */ if ((found_pathname == NULL && was_loaded) || (found_pathname != NULL - && filename_cmp (found_pathname, so.so_name.c_str ()) != 0)) + && filename_cmp (found_pathname, so.name.c_str ()) != 0)) { if (so.objfile && !(so.objfile->flags & OBJF_USERLOADED) && !solib_used (current_program_space, so)) @@ -1436,7 +1437,7 @@ reload_shared_libraries_1 (int from_tty) file, open it. */ if (found_pathname != NULL && (!was_loaded - || filename_cmp (found_pathname, so.so_name.c_str ()) != 0)) + || filename_cmp (found_pathname, so.name.c_str ()) != 0)) { bool got_error = false; @@ -1466,8 +1467,6 @@ reload_shared_libraries (const char *ignored, int from_tty, { reload_shared_libraries_1 (from_tty); - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); - /* Creating inferior hooks here has two purposes. First, if we reload shared libraries then the address of solib breakpoint we've computed previously might be no longer valid. For example, if we forgot to set @@ -1480,8 +1479,9 @@ reload_shared_libraries (const char *ignored, int from_tty, if (target_has_execution ()) { /* Reset or free private data structures not associated with - so_list entries. */ - if (ops->clear_solib != nullptr) + solib entries. */ + if (const solib_ops *ops = current_program_space->solib_ops (); + ops != nullptr) ops->clear_solib (current_program_space); /* Remove any previous solib event breakpoint. This is usually @@ -1808,56 +1808,42 @@ remove_user_added_objfile (struct objfile *objfile) } } -/* See solist.h. */ +/* Implementation of the linker_namespace convenience variable. -std::optional<CORE_ADDR> -default_find_solib_addr (solib &so) -{ - return {}; -} - -/* Implementation of the current_linker_namespace convenience variable. This returns the GDB internal identifier of the linker namespace, - for the current frame, in the form '[[<number>]]'. If the inferior - doesn't support linker namespaces, this always returns [[0]]. */ + for the selected frame, as an integer. If the inferior doesn't support + linker namespaces, this always returns 0. */ static value * -current_linker_namespace_make_value (gdbarch *gdbarch, internalvar *var, +linker_namespace_make_value (gdbarch *gdbarch, internalvar *var, void *ignore) { - const solib_ops *ops = gdbarch_so_ops (gdbarch); - const language_defn *lang = language_def (get_frame_language - (get_current_frame ())); - std::string nsid = "[[0]]"; - if (ops->find_solib_ns != nullptr) - { - CORE_ADDR curr_pc = get_frame_pc (get_current_frame ()); - for (const solib &so : current_program_space->solibs ()) - if (solib_contains_address_p (so, curr_pc)) - { - nsid = string_printf ("[[%d]]", ops->find_solib_ns (so)); - break; - } - } + int nsid = 0; + CORE_ADDR curr_pc = get_frame_pc (get_selected_frame ()); + + for (const solib &so : current_program_space->solibs ()) + if (solib_contains_address_p (so, curr_pc)) + { + if (so.ops ().supports_namespaces ()) + nsid = so.ops ().find_solib_ns (so); + break; + } /* If the PC is not in an SO, or the solib_ops doesn't support linker namespaces, the inferior is in the default namespace. */ - return lang->value_string (gdbarch, nsid.c_str (), nsid.length ()); + return value_from_longest (builtin_type (gdbarch)->builtin_int, nsid); } -/* Implementation of `$_current_linker_namespace' variable. */ +/* Implementation of `$_linker_namespace' variable. */ -static const struct internalvar_funcs current_linker_namespace_funcs = +static const struct internalvar_funcs linker_namespace_funcs = { - current_linker_namespace_make_value, + linker_namespace_make_value, nullptr, }; -void _initialize_solib (); - -void -_initialize_solib () +INIT_GDB_FILE (solib) { gdb::observers::free_objfile.attach (remove_user_added_objfile, "solib"); gdb::observers::inferior_execd.attach ( @@ -1869,8 +1855,8 @@ _initialize_solib () /* Convenience variables for debugging linker namespaces. These are set here, even if the solib_ops doesn't support them, for consistency. */ - create_internalvar_type_lazy ("_current_linker_namespace", - ¤t_linker_namespace_funcs, nullptr); + create_internalvar_type_lazy ("_linker_namespace", + &linker_namespace_funcs, nullptr); set_internalvar_integer (lookup_internalvar ("_active_linker_namespaces"), 1); add_com ( |