/* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger.
- Copyright (C) 2004, 2007-2012 Free Software Foundation, Inc.
+ Copyright (C) 2004-2024 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#include "defs.h"
-#include "gdb_string.h"
-#include "inferior.h"
+#include "extract-store-integer.h"
#include "gdbcore.h"
#include "solib.h"
#include "solist.h"
#include "frv-tdep.h"
#include "objfiles.h"
#include "symtab.h"
-#include "language.h"
-#include "command.h"
-#include "gdbcmd.h"
#include "elf/frv.h"
-#include "exceptions.h"
#include "gdb_bfd.h"
-
-/* Flag which indicates whether internal debug messages should be printed. */
-static unsigned int solib_frv_debug;
+#include "inferior.h"
/* FR-V pointers are four bytes wide. */
enum { FRV_PTR_SIZE = 4 };
static struct int_elf32_fdpic_loadmap *
fetch_loadmap (CORE_ADDR ldmaddr)
{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+ bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
struct ext_elf32_fdpic_loadmap ext_ldmbuf_partial;
struct ext_elf32_fdpic_loadmap *ext_ldmbuf;
struct int_elf32_fdpic_loadmap *int_ldmbuf;
/* Fetch initial portion of the loadmap. */
if (target_read_memory (ldmaddr, (gdb_byte *) &ext_ldmbuf_partial,
- sizeof ext_ldmbuf_partial))
+ sizeof ext_ldmbuf_partial))
{
/* Problem reading the target's memory. */
return NULL;
/* Extract the version. */
version = extract_unsigned_integer (ext_ldmbuf_partial.version,
- sizeof ext_ldmbuf_partial.version,
+ sizeof ext_ldmbuf_partial.version,
byte_order);
if (version != 0)
{
/* Extract the number of segments. */
nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
- sizeof ext_ldmbuf_partial.nsegs,
+ sizeof ext_ldmbuf_partial.nsegs,
byte_order);
if (nsegs <= 0)
/* Allocate space for the complete (external) loadmap. */
ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap)
- + (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
- ext_ldmbuf = xmalloc (ext_ldmbuf_size);
+ + (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
+ ext_ldmbuf = (struct ext_elf32_fdpic_loadmap *) xmalloc (ext_ldmbuf_size);
/* Copy over the portion of the loadmap that's already been read. */
memcpy (ext_ldmbuf, &ext_ldmbuf_partial, sizeof ext_ldmbuf_partial);
/* Read the rest of the loadmap from the target. */
if (target_read_memory (ldmaddr + sizeof ext_ldmbuf_partial,
- (gdb_byte *) ext_ldmbuf + sizeof ext_ldmbuf_partial,
- ext_ldmbuf_size - sizeof ext_ldmbuf_partial))
+ (gdb_byte *) ext_ldmbuf + sizeof ext_ldmbuf_partial,
+ ext_ldmbuf_size - sizeof ext_ldmbuf_partial))
{
/* Couldn't read rest of the loadmap. */
xfree (ext_ldmbuf);
/* Allocate space into which to put information extract from the
external loadsegs. I.e, allocate the internal loadsegs. */
int_ldmbuf_size = sizeof (struct int_elf32_fdpic_loadmap)
- + (nsegs - 1) * sizeof (struct int_elf32_fdpic_loadseg);
- int_ldmbuf = xmalloc (int_ldmbuf_size);
+ + (nsegs - 1) * sizeof (struct int_elf32_fdpic_loadseg);
+ int_ldmbuf = (struct int_elf32_fdpic_loadmap *) xmalloc (int_ldmbuf_size);
/* Place extracted information in internal structs. */
int_ldmbuf->version = version;
{
int_ldmbuf->segs[seg].addr
= extract_unsigned_integer (ext_ldmbuf->segs[seg].addr,
- sizeof (ext_ldmbuf->segs[seg].addr),
+ sizeof (ext_ldmbuf->segs[seg].addr),
byte_order);
int_ldmbuf->segs[seg].p_vaddr
= extract_unsigned_integer (ext_ldmbuf->segs[seg].p_vaddr,
- sizeof (ext_ldmbuf->segs[seg].p_vaddr),
+ sizeof (ext_ldmbuf->segs[seg].p_vaddr),
byte_order);
int_ldmbuf->segs[seg].p_memsz
= extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz,
- sizeof (ext_ldmbuf->segs[seg].p_memsz),
+ sizeof (ext_ldmbuf->segs[seg].p_memsz),
byte_order);
}
/* Link map info to include in an allocated so_list entry. */
-struct lm_info
+struct lm_info_frv final : public lm_info
+{
+ ~lm_info_frv ()
{
- /* The loadmap, digested into an easier to use form. */
- struct int_elf32_fdpic_loadmap *map;
- /* The GOT address for this link map entry. */
- CORE_ADDR got_value;
- /* The link map address, needed for frv_fetch_objfile_link_map(). */
- CORE_ADDR lm_addr;
-
- /* Cached dynamic symbol table and dynamic relocs initialized and
- used only by find_canonical_descriptor_in_load_object().
-
- Note: kevinb/2004-02-26: It appears that calls to
- bfd_canonicalize_dynamic_reloc() will use the same symbols as
- those supplied to the first call to this function. Therefore,
- it's important to NOT free the asymbol ** data structure
- supplied to the first call. Thus the caching of the dynamic
- symbols (dyn_syms) is critical for correct operation. The
- caching of the dynamic relocations could be dispensed with. */
- asymbol **dyn_syms;
- arelent **dyn_relocs;
- int dyn_reloc_count; /* Number of dynamic relocs. */
-
- };
+ xfree (this->map);
+ xfree (this->dyn_syms);
+ xfree (this->dyn_relocs);
+ }
+
+ /* The loadmap, digested into an easier to use form. */
+ int_elf32_fdpic_loadmap *map = NULL;
+ /* The GOT address for this link map entry. */
+ CORE_ADDR got_value = 0;
+ /* The link map address, needed for frv_fetch_objfile_link_map(). */
+ CORE_ADDR lm_addr = 0;
+
+ /* Cached dynamic symbol table and dynamic relocs initialized and
+ used only by find_canonical_descriptor_in_load_object().
+
+ Note: kevinb/2004-02-26: It appears that calls to
+ bfd_canonicalize_dynamic_reloc() will use the same symbols as
+ those supplied to the first call to this function. Therefore,
+ it's important to NOT free the asymbol ** data structure
+ supplied to the first call. Thus the caching of the dynamic
+ symbols (dyn_syms) is critical for correct operation. The
+ caching of the dynamic relocations could be dispensed with. */
+ asymbol **dyn_syms = NULL;
+ arelent **dyn_relocs = NULL;
+ int dyn_reloc_count = 0; /* Number of dynamic relocs. */
+};
/* The load map, got value, etc. are not available from the chain
of loaded shared objects. ``main_executable_lm_info'' provides
a way to get at this information so that it doesn't need to be
frequently recomputed. Initialized by frv_relocate_main_executable(). */
-static struct lm_info *main_executable_lm_info;
+static lm_info_frv *main_executable_lm_info;
static void frv_relocate_main_executable (void);
static CORE_ADDR main_got (void);
static int enable_break2 (void);
-/* Implement the "open_symbol_file_object" target_so_ops method. */
+/* Implement the "open_symbol_file_object" solib_ops method. */
static int
-open_symbol_file_object (void *from_ttyp)
+open_symbol_file_object (int from_tty)
{
/* Unimplemented. */
return 0;
static CORE_ADDR
lm_base (void)
{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- struct minimal_symbol *got_sym;
+ bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
+ struct bound_minimal_symbol got_sym;
CORE_ADDR addr;
gdb_byte buf[FRV_PTR_SIZE];
return lm_base_cache;
got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL,
- symfile_objfile);
- if (got_sym == 0)
+ current_program_space->symfile_object_file);
+ if (got_sym.minsym == 0)
{
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "lm_base: _GLOBAL_OFFSET_TABLE_ not found.\n");
+ solib_debug_printf ("_GLOBAL_OFFSET_TABLE_ not found.");
return 0;
}
- addr = SYMBOL_VALUE_ADDRESS (got_sym) + 8;
+ addr = got_sym.value_address () + 8;
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "lm_base: _GLOBAL_OFFSET_TABLE_ + 8 = %s\n",
- hex_string_custom (addr, 8));
+ solib_debug_printf ("_GLOBAL_OFFSET_TABLE_ + 8 = %s",
+ hex_string_custom (addr, 8));
if (target_read_memory (addr, buf, sizeof buf) != 0)
return 0;
lm_base_cache = extract_unsigned_integer (buf, sizeof buf, byte_order);
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "lm_base: lm_base_cache = %s\n",
- hex_string_custom (lm_base_cache, 8));
+ solib_debug_printf ("lm_base_cache = %s",
+ hex_string_custom (lm_base_cache, 8));
return lm_base_cache;
}
-/* Implement the "current_sos" target_so_ops method. */
+/* Implement the "current_sos" solib_ops method. */
-static struct so_list *
-frv_current_sos (void)
+static intrusive_list<solib>
+frv_current_sos ()
{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+ bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
CORE_ADDR lm_addr, mgot;
- struct so_list *sos_head = NULL;
- struct so_list **sos_next_ptr = &sos_head;
+ intrusive_list<solib> sos;
/* Make sure that the main executable has been relocated. This is
required in order to find the address of the global offset table,
for details.)
Note that the relocation of the main executable is also performed
- by SOLIB_CREATE_INFERIOR_HOOK(), however, in the case of core
+ by solib_create_inferior_hook(), however, in the case of core
files, this hook is called too late in order to be of benefit to
- SOLIB_ADD. SOLIB_ADD eventually calls this this function,
+ solib_add. solib_add eventually calls this this function,
frv_current_sos, and also precedes the call to
- SOLIB_CREATE_INFERIOR_HOOK(). (See post_create_inferior() in
+ solib_create_inferior_hook(). (See post_create_inferior() in
infcmd.c.) */
- if (main_executable_lm_info == 0 && core_bfd != NULL)
+ if (main_executable_lm_info == 0
+ && current_program_space->core_bfd () != nullptr)
frv_relocate_main_executable ();
/* Fetch the GOT corresponding to the main executable. */
struct ext_link_map lm_buf;
CORE_ADDR got_addr;
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "current_sos: reading link_map entry at %s\n",
- hex_string_custom (lm_addr, 8));
+ solib_debug_printf ("reading link_map entry at %s",
+ hex_string_custom (lm_addr, 8));
if (target_read_memory (lm_addr, (gdb_byte *) &lm_buf,
sizeof (lm_buf)) != 0)
this in the list of shared objects. */
if (got_addr != mgot)
{
- int errcode;
- char *name_buf;
struct int_elf32_fdpic_loadmap *loadmap;
- struct so_list *sop;
CORE_ADDR addr;
/* Fetch the load map address. */
break;
}
- sop = xcalloc (1, sizeof (struct so_list));
- sop->lm_info = xcalloc (1, sizeof (struct lm_info));
- sop->lm_info->map = loadmap;
- sop->lm_info->got_value = got_addr;
- sop->lm_info->lm_addr = lm_addr;
+ solib *sop = new solib;
+ auto li = std::make_unique<lm_info_frv> ();
+ li->map = loadmap;
+ li->got_value = got_addr;
+ li->lm_addr = lm_addr;
/* Fetch the name. */
addr = extract_unsigned_integer (lm_buf.l_name,
sizeof (lm_buf.l_name),
byte_order);
- target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1,
- &errcode);
-
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n",
- name_buf);
-
- if (errcode != 0)
- warning (_("Can't read pathname for link map entry: %s."),
- safe_strerror (errcode));
+ gdb::unique_xmalloc_ptr<char> name_buf
+ = target_read_string (addr, SO_NAME_MAX_PATH_SIZE - 1);
+
+ solib_debug_printf ("name = %s", name_buf.get ());
+
+ if (name_buf == nullptr)
+ warning (_("Can't read pathname for link map entry."));
else
{
- strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1);
- sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
- xfree (name_buf);
- strcpy (sop->so_original_name, sop->so_name);
+ sop->so_name = name_buf.get ();
+ sop->so_original_name = sop->so_name;
}
- *sos_next_ptr = sop;
- sos_next_ptr = &sop->next;
+ sos.push_back (*sop);
}
else
{
enable_break2 ();
- return sos_head;
+ return sos;
}
{
return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
|| (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
- || in_plt_section (pc, NULL));
+ || in_plt_section (pc));
}
/* Given a loadmap and an address, return the displacement needed
static CORE_ADDR
displacement_from_map (struct int_elf32_fdpic_loadmap *map,
- CORE_ADDR addr)
+ CORE_ADDR addr)
{
int seg;
for (seg = 0; seg < map->nsegs; seg++)
{
if (map->segs[seg].p_vaddr <= addr
- && addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
+ && addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
{
return map->segs[seg].addr - map->segs[seg].p_vaddr;
}
enable_break_failure_warning (void)
{
warning (_("Unable to find dynamic linker breakpoint function.\n"
- "GDB will be unable to debug shared library initializers\n"
+ "GDB will be unable to debug shared library initializers\n"
"and track explicitly loaded dynamic code."));
}
-/* Helper function for gdb_bfd_lookup_symbol. */
-
-static int
-cmp_name (asymbol *sym, void *data)
-{
- return (strcmp (sym->name, (const char *) data) == 0);
-}
-
/* Arrange for dynamic linker to hit breakpoint.
The dynamic linkers has, as part of its debugger interface, support
static int
enable_break2 (void)
{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- int success = 0;
- char **bkpt_namep;
+ bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
asection *interp_sect;
if (enable_break2_done)
/* Find the .interp section; if not found, warn the user and drop
into the old breakpoint at symbol code. */
- interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+ interp_sect = bfd_get_section_by_name (current_program_space->exec_bfd (),
+ ".interp");
if (interp_sect)
{
unsigned int interp_sect_size;
- gdb_byte *buf;
- bfd *tmp_bfd = NULL;
+ char *buf;
int status;
CORE_ADDR addr, interp_loadmap_addr;
gdb_byte addr_buf[FRV_PTR_SIZE];
struct int_elf32_fdpic_loadmap *ldm;
- volatile struct gdb_exception ex;
/* Read the contents of the .interp section into a local buffer;
- the contents specify the dynamic linker this program uses. */
- interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
- buf = alloca (interp_sect_size);
- bfd_get_section_contents (exec_bfd, interp_sect,
- buf, 0, interp_sect_size);
+ the contents specify the dynamic linker this program uses. */
+ interp_sect_size = bfd_section_size (interp_sect);
+ buf = (char *) alloca (interp_sect_size);
+ bfd_get_section_contents (current_program_space->exec_bfd (),
+ interp_sect, buf, 0, interp_sect_size);
/* Now we need to figure out where the dynamic linker was
- loaded so that we can load its symbols and place a breakpoint
- in the dynamic linker itself.
-
- This address is stored on the stack. However, I've been unable
- to find any magic formula to find it for Solaris (appears to
- be trivial on GNU/Linux). Therefore, we have to try an alternate
- mechanism to find the dynamic linker's base address. */
-
- TRY_CATCH (ex, RETURN_MASK_ALL)
- {
- tmp_bfd = solib_bfd_open (buf);
- }
+ loaded so that we can load its symbols and place a breakpoint
+ in the dynamic linker itself.
+
+ This address is stored on the stack. However, I've been unable
+ to find any magic formula to find it for Solaris (appears to
+ be trivial on GNU/Linux). Therefore, we have to try an alternate
+ mechanism to find the dynamic linker's base address. */
+
+ gdb_bfd_ref_ptr tmp_bfd;
+ try
+ {
+ tmp_bfd = solib_bfd_open (buf);
+ }
+ catch (const gdb_exception &ex)
+ {
+ }
+
if (tmp_bfd == NULL)
{
enable_break_failure_warning ();
return 0;
}
- status = frv_fdpic_loadmap_addresses (target_gdbarch (),
- &interp_loadmap_addr, 0);
+ status = frv_fdpic_loadmap_addresses (current_inferior ()->arch (),
+ &interp_loadmap_addr, 0);
if (status < 0)
{
warning (_("Unable to determine dynamic linker loadmap address."));
enable_break_failure_warning ();
- gdb_bfd_unref (tmp_bfd);
return 0;
}
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: interp_loadmap_addr = %s\n",
- hex_string_custom (interp_loadmap_addr, 8));
+ solib_debug_printf ("interp_loadmap_addr = %s",
+ hex_string_custom (interp_loadmap_addr, 8));
ldm = fetch_loadmap (interp_loadmap_addr);
if (ldm == NULL)
{
warning (_("Unable to load dynamic linker loadmap at address %s."),
- hex_string_custom (interp_loadmap_addr, 8));
+ hex_string_custom (interp_loadmap_addr, 8));
enable_break_failure_warning ();
- gdb_bfd_unref (tmp_bfd);
return 0;
}
/* Record the relocated start and end address of the dynamic linker
- text and plt section for svr4_in_dynsym_resolve_code. */
- interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+ text and plt section for svr4_in_dynsym_resolve_code. */
+ interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text");
if (interp_sect)
{
- interp_text_sect_low
- = bfd_section_vma (tmp_bfd, interp_sect);
+ interp_text_sect_low = bfd_section_vma (interp_sect);
interp_text_sect_low
+= displacement_from_map (ldm, interp_text_sect_low);
interp_text_sect_high
- = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ = interp_text_sect_low + bfd_section_size (interp_sect);
}
- interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
+ interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt");
if (interp_sect)
{
- interp_plt_sect_low =
- bfd_section_vma (tmp_bfd, interp_sect);
+ interp_plt_sect_low = bfd_section_vma (interp_sect);
interp_plt_sect_low
+= displacement_from_map (ldm, interp_plt_sect_low);
interp_plt_sect_high =
- interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ interp_plt_sect_low + bfd_section_size (interp_sect);
}
- addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr");
+ addr = (gdb_bfd_lookup_symbol
+ (tmp_bfd.get (),
+ [] (const asymbol *sym)
+ {
+ return strcmp (sym->name, "_dl_debug_addr") == 0;
+ }));
if (addr == 0)
{
warning (_("Could not find symbol _dl_debug_addr "
"in dynamic linker"));
enable_break_failure_warning ();
- gdb_bfd_unref (tmp_bfd);
return 0;
}
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: _dl_debug_addr "
- "(prior to relocation) = %s\n",
- hex_string_custom (addr, 8));
+ solib_debug_printf ("_dl_debug_addr (prior to relocation) = %s",
+ hex_string_custom (addr, 8));
addr += displacement_from_map (ldm, addr);
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: _dl_debug_addr "
- "(after relocation) = %s\n",
- hex_string_custom (addr, 8));
+ solib_debug_printf ("_dl_debug_addr (after relocation) = %s",
+ hex_string_custom (addr, 8));
/* Fetch the address of the r_debug struct. */
if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
{
warning (_("Unable to fetch contents of _dl_debug_addr "
"(at address %s) from dynamic linker"),
- hex_string_custom (addr, 8));
+ hex_string_custom (addr, 8));
}
addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: _dl_debug_addr[0..3] = %s\n",
- hex_string_custom (addr, 8));
+ solib_debug_printf ("_dl_debug_addr[0..3] = %s",
+ hex_string_custom (addr, 8));
/* If it's zero, then the ldso hasn't initialized yet, and so
- there are no shared libs yet loaded. */
+ there are no shared libs yet loaded. */
if (addr == 0)
{
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: ldso not yet initialized\n");
+ solib_debug_printf ("ldso not yet initialized");
/* Do not warn, but mark to run again. */
return 0;
}
/* Fetch the r_brk field. It's 8 bytes from the start of
- _dl_debug_addr. */
+ _dl_debug_addr. */
if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0)
{
warning (_("Unable to fetch _dl_debug_addr->r_brk "
"(at address %s) from dynamic linker"),
- hex_string_custom (addr + 8, 8));
+ hex_string_custom (addr + 8, 8));
enable_break_failure_warning ();
- gdb_bfd_unref (tmp_bfd);
return 0;
}
addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
{
warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point "
"(at address %s) from dynamic linker"),
- hex_string_custom (addr, 8));
+ hex_string_custom (addr, 8));
enable_break_failure_warning ();
- gdb_bfd_unref (tmp_bfd);
return 0;
}
addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
- /* We're done with the temporary bfd. */
- gdb_bfd_unref (tmp_bfd);
-
- /* We're also done with the loadmap. */
+ /* We're done with the loadmap. */
xfree (ldm);
/* Remove all the solib event breakpoints. Their addresses
- may have changed since the last time we ran the program. */
+ may have changed since the last time we ran the program. */
remove_solib_event_breakpoints ();
/* Now (finally!) create the solib breakpoint. */
- create_solib_event_breakpoint (target_gdbarch (), addr);
+ create_solib_event_breakpoint (current_inferior ()->arch (), addr);
enable_break2_done = 1;
enable_break (void)
{
asection *interp_sect;
+ CORE_ADDR entry_point;
- if (symfile_objfile == NULL)
+ if (current_program_space->symfile_object_file == NULL)
{
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: No symbol file found.\n");
+ solib_debug_printf ("No symbol file found.");
return 0;
}
- if (!symfile_objfile->ei.entry_point_p)
+ if (!entry_point_address_query (&entry_point))
{
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: Symbol file has no entry point.\n");
+ solib_debug_printf ("Symbol file has no entry point.");
return 0;
}
/* Check for the presence of a .interp section. If there is no
such section, the executable is statically linked. */
- interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+ interp_sect = bfd_get_section_by_name (current_program_space->exec_bfd (),
+ ".interp");
if (interp_sect == NULL)
{
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: No .interp section found.\n");
+ solib_debug_printf ("No .interp section found.");
return 0;
}
- create_solib_event_breakpoint (target_gdbarch (),
- symfile_objfile->ei.entry_point);
+ create_solib_event_breakpoint (current_inferior ()->arch (), entry_point);
- if (solib_frv_debug)
- fprintf_unfiltered (gdb_stdlog,
- "enable_break: solib event breakpoint "
- "placed at entry point: %s\n",
- hex_string_custom (symfile_objfile->ei.entry_point,
- 8));
+ solib_debug_printf ("solib event breakpoint placed at entry point: %s",
+ hex_string_custom (entry_point, 8));
return 1;
}
-/* Implement the "special_symbol_handling" target_so_ops method. */
-
-static void
-frv_special_symbol_handling (void)
-{
- /* Nothing needed for FRV. */
-}
-
static void
frv_relocate_main_executable (void)
{
int status;
CORE_ADDR exec_addr, interp_addr;
struct int_elf32_fdpic_loadmap *ldm;
- struct cleanup *old_chain;
- struct section_offsets *new_offsets;
int changed;
- struct obj_section *osect;
- status = frv_fdpic_loadmap_addresses (target_gdbarch (),
- &interp_addr, &exec_addr);
+ status = frv_fdpic_loadmap_addresses (current_inferior ()->arch (),
+ &interp_addr, &exec_addr);
if (status < 0 || (exec_addr == 0 && interp_addr == 0))
{
if (ldm == NULL)
error (_("Unable to load the executable's loadmap."));
- if (main_executable_lm_info)
- xfree (main_executable_lm_info);
- main_executable_lm_info = xcalloc (1, sizeof (struct lm_info));
+ delete main_executable_lm_info;
+ main_executable_lm_info = new lm_info_frv;
main_executable_lm_info->map = ldm;
- new_offsets = xcalloc (symfile_objfile->num_sections,
- sizeof (struct section_offsets));
- old_chain = make_cleanup (xfree, new_offsets);
+ objfile *objf = current_program_space->symfile_object_file;
+ section_offsets new_offsets (objf->section_offsets.size ());
changed = 0;
- ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
+ for (obj_section *osect : objf->sections ())
{
CORE_ADDR orig_addr, addr, offset;
int osect_idx;
int seg;
- osect_idx = osect->the_bfd_section->index;
+ osect_idx = osect - objf->sections_start;
/* Current address of section. */
- addr = obj_section_addr (osect);
+ addr = osect->addr ();
/* Offset from where this section started. */
- offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
+ offset = objf->section_offsets[osect_idx];
/* Original address prior to any past relocations. */
orig_addr = addr - offset;
if (ldm->segs[seg].p_vaddr <= orig_addr
&& orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
{
- new_offsets->offsets[osect_idx]
+ new_offsets[osect_idx]
= ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;
- if (new_offsets->offsets[osect_idx] != offset)
+ if (new_offsets[osect_idx] != offset)
changed = 1;
break;
}
}
if (changed)
- objfile_relocate (symfile_objfile, new_offsets);
+ objfile_relocate (objf, new_offsets);
- do_cleanups (old_chain);
-
- /* Now that symfile_objfile has been relocated, we can compute the
- GOT value and stash it away. */
+ /* Now that OBJF has been relocated, we can compute the GOT value
+ and stash it away. */
main_executable_lm_info->got_value = main_got ();
}
}
static void
-frv_clear_solib (void)
+frv_clear_solib (program_space *pspace)
{
lm_base_cache = 0;
enable_break2_done = 0;
main_lm_addr = 0;
- if (main_executable_lm_info != 0)
- {
- xfree (main_executable_lm_info->map);
- xfree (main_executable_lm_info->dyn_syms);
- xfree (main_executable_lm_info->dyn_relocs);
- xfree (main_executable_lm_info);
- main_executable_lm_info = 0;
- }
-}
-static void
-frv_free_so (struct so_list *so)
-{
- xfree (so->lm_info->map);
- xfree (so->lm_info->dyn_syms);
- xfree (so->lm_info->dyn_relocs);
- xfree (so->lm_info);
+ delete main_executable_lm_info;
+ main_executable_lm_info = NULL;
}
static void
-frv_relocate_section_addresses (struct so_list *so,
- struct target_section *sec)
+frv_relocate_section_addresses (solib &so, target_section *sec)
{
int seg;
- struct int_elf32_fdpic_loadmap *map;
-
- map = so->lm_info->map;
+ auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
+ int_elf32_fdpic_loadmap *map = li->map;
for (seg = 0; seg < map->nsegs; seg++)
{
if (map->segs[seg].p_vaddr <= sec->addr
- && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
+ && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
{
CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr;
static CORE_ADDR
main_got (void)
{
- struct minimal_symbol *got_sym;
+ struct bound_minimal_symbol got_sym;
- got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_",
- NULL, symfile_objfile);
- if (got_sym == 0)
+ objfile *objf = current_program_space->symfile_object_file;
+ got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, objf);
+ if (got_sym.minsym == 0)
return 0;
- return SYMBOL_VALUE_ADDRESS (got_sym);
+ return got_sym.value_address ();
}
/* Find the global pointer for the given function address ADDR. */
CORE_ADDR
frv_fdpic_find_global_pointer (CORE_ADDR addr)
{
- struct so_list *so;
-
- so = master_so_list ();
- while (so)
+ for (const solib &so : current_program_space->solibs ())
{
int seg;
- struct int_elf32_fdpic_loadmap *map;
-
- map = so->lm_info->map;
+ auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
+ int_elf32_fdpic_loadmap *map = li->map;
for (seg = 0; seg < map->nsegs; seg++)
{
if (map->segs[seg].addr <= addr
&& addr < map->segs[seg].addr + map->segs[seg].p_memsz)
- return so->lm_info->got_value;
+ return li->got_value;
}
-
- so = so->next;
}
/* Didn't find it in any of the shared objects. So assume it's in the
/* Forward declarations for frv_fdpic_find_canonical_descriptor(). */
static CORE_ADDR find_canonical_descriptor_in_load_object
- (CORE_ADDR, CORE_ADDR, const char *, bfd *, struct lm_info *);
+ (CORE_ADDR, CORE_ADDR, const char *, bfd *, lm_info_frv *);
/* Given a function entry point, attempt to find the canonical descriptor
associated with that entry point. Return 0 if no canonical descriptor
const char *name;
CORE_ADDR addr;
CORE_ADDR got_value;
- struct int_elf32_fdpic_loadmap *ldm = 0;
struct symbol *sym;
/* Fetch the corresponding global pointer for the entry point. */
if (sym == 0)
name = 0;
else
- name = SYMBOL_LINKAGE_NAME (sym);
+ name = sym->linkage_name ();
/* Check the main executable. */
+ objfile *objf = current_program_space->symfile_object_file;
addr = find_canonical_descriptor_in_load_object
- (entry_point, got_value, name, symfile_objfile->obfd,
+ (entry_point, got_value, name, objf->obfd.get (),
main_executable_lm_info);
/* If descriptor not found via main executable, check each load object
in list of shared objects. */
if (addr == 0)
{
- struct so_list *so;
-
- so = master_so_list ();
- while (so)
+ for (const solib &so : current_program_space->solibs ())
{
+ auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
+
addr = find_canonical_descriptor_in_load_object
- (entry_point, got_value, name, so->abfd, so->lm_info);
+ (entry_point, got_value, name, so.abfd.get(), li);
if (addr != 0)
break;
-
- so = so->next;
}
}
static CORE_ADDR
find_canonical_descriptor_in_load_object
(CORE_ADDR entry_point, CORE_ADDR got_value, const char *name, bfd *abfd,
- struct lm_info *lm)
+ lm_info_frv *lm)
{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+ bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
arelent *rel;
unsigned int i;
CORE_ADDR addr = 0;
rel = lm->dyn_relocs[i];
/* Relocs of interest are those which meet the following
- criteria:
+ criteria:
- the names match (assuming the caller could provide
a name which matches ``entry_point'').
this address (which is a GOT entry) to obtain a descriptor
address. */
if ((name == 0 || strcmp (name, (*rel->sym_ptr_ptr)->name) == 0)
- && rel->howto->type == R_FRV_FUNCDESC)
+ && rel->howto->type == R_FRV_FUNCDESC)
{
gdb_byte buf [FRV_PTR_SIZE];
CORE_ADDR
frv_fetch_objfile_link_map (struct objfile *objfile)
{
- struct so_list *so;
-
/* Cause frv_current_sos() to be run if it hasn't been already. */
if (main_lm_addr == 0)
- solib_add (0, 0, 0, 1);
+ solib_add (0, 0, 1);
/* frv_current_sos() will set main_lm_addr for the main executable. */
- if (objfile == symfile_objfile)
+ if (objfile == current_program_space->symfile_object_file)
return main_lm_addr;
/* The other link map addresses may be found by examining the list
of shared libraries. */
- for (so = master_so_list (); so; so = so->next)
+ for (const solib &so : current_program_space->solibs ())
{
- if (so->objfile == objfile)
- return so->lm_info->lm_addr;
+ auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
+
+ if (so.objfile == objfile)
+ return li->lm_addr;
}
/* Not found! */
return 0;
}
-struct target_so_ops frv_so_ops;
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_frv_solib;
-
-void
-_initialize_frv_solib (void)
+const solib_ops frv_so_ops =
{
- frv_so_ops.relocate_section_addresses = frv_relocate_section_addresses;
- frv_so_ops.free_so = frv_free_so;
- frv_so_ops.clear_solib = frv_clear_solib;
- frv_so_ops.solib_create_inferior_hook = frv_solib_create_inferior_hook;
- frv_so_ops.special_symbol_handling = frv_special_symbol_handling;
- frv_so_ops.current_sos = frv_current_sos;
- 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.bfd_open = solib_bfd_open;
-
- /* Debug this file's internals. */
- add_setshow_zuinteger_cmd ("solib-frv", class_maintenance,
- &solib_frv_debug, _("\
-Set internal debugging of shared library code for FR-V."), _("\
-Show internal debugging of shared library code for FR-V."), _("\
-When non-zero, FR-V solib specific internal debugging is enabled."),
- NULL,
- NULL, /* FIXME: i18n: */
- &setdebuglist, &showdebuglist);
-}
+ frv_relocate_section_addresses,
+ nullptr,
+ frv_clear_solib,
+ frv_solib_create_inferior_hook,
+ frv_current_sos,
+ open_symbol_file_object,
+ frv_in_dynsym_resolve_code,
+ solib_bfd_open,
+};