/* Handle TIC6X (DSBT) shared libraries for GDB, the GNU Debugger.
- Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Copyright (C) 2010-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
-#include <string.h>
#include "inferior.h"
#include "gdbcore.h"
#include "solib.h"
#include "command.h"
#include "gdbcmd.h"
#include "elf-bfd.h"
-#include "exceptions.h"
#include "gdb_bfd.h"
#define GOT_MODULE_OFFSET 4
/* Link map info to include in an allocated so_list entry */
-struct lm_info
+struct lm_info_dsbt : public lm_info_base
{
+ ~lm_info_dsbt ()
+ {
+ xfree (this->map);
+ }
+
/* The loadmap, digested into an easier to use form. */
- struct int_elf32_dsbt_loadmap *map;
+ int_elf32_dsbt_loadmap *map = NULL;
};
/* Per pspace dsbt specific data. */
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 dsbt_relocate_main_executable. */
- struct lm_info *main_executable_lm_info;
+ struct lm_info_dsbt *main_executable_lm_info;
/* Load maps for the main executable and the interpreter. These are obtained
from ptrace. They are the starting point for getting into the program,
{
struct dsbt_info *info;
- info = program_space_data (current_program_space, solib_dsbt_pspace_data);
+ info = (struct dsbt_info *) program_space_data (current_program_space,
+ solib_dsbt_pspace_data);
if (info != NULL)
return info;
- info = XZALLOC (struct dsbt_info);
+ info = XCNEW (struct dsbt_info);
set_program_space_data (current_program_space, solib_dsbt_pspace_data, info);
info->lm_base_cache = 0;
/* Decode int_elf32_dsbt_loadmap from BUF. */
static struct int_elf32_dsbt_loadmap *
-decode_loadmap (gdb_byte *buf)
+decode_loadmap (const gdb_byte *buf)
{
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- struct ext_elf32_dsbt_loadmap *ext_ldmbuf;
+ const struct ext_elf32_dsbt_loadmap *ext_ldmbuf;
struct int_elf32_dsbt_loadmap *int_ldmbuf;
int version, seg, nsegs;
external loadsegs. I.e, allocate the internal loadsegs. */
int_ldmbuf_size = (sizeof (struct int_elf32_dsbt_loadmap)
+ (nsegs - 1) * sizeof (struct int_elf32_dsbt_loadseg));
- int_ldmbuf = xmalloc (int_ldmbuf_size);
+ int_ldmbuf = (struct int_elf32_dsbt_loadmap *) xmalloc (int_ldmbuf_size);
/* Place extracted information in internal structs. */
int_ldmbuf->version = version;
byte_order);
}
- xfree (ext_ldmbuf);
return int_ldmbuf;
}
static void
dsbt_get_initial_loadmaps (void)
{
- gdb_byte *buf;
struct dsbt_info *info = get_dsbt_info ();
+ gdb::optional<gdb::byte_vector> buf
+ = target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC, "exec");
- if (0 >= target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC,
- "exec", &buf))
+ if (!buf || buf->empty ())
{
info->exec_loadmap = NULL;
error (_("Error reading DSBT exec loadmap"));
}
- info->exec_loadmap = decode_loadmap (buf);
+ info->exec_loadmap = decode_loadmap (buf->data ());
if (solib_dsbt_debug)
dsbt_print_loadmap (info->exec_loadmap);
- if (0 >= target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC,
- "interp", &buf))
+ buf = target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC, "exec");
+ if (!buf || buf->empty ())
{
info->interp_loadmap = NULL;
error (_("Error reading DSBT interp loadmap"));
}
- info->interp_loadmap = decode_loadmap (buf);
+ info->interp_loadmap = decode_loadmap (buf->data ());
if (solib_dsbt_debug)
dsbt_print_loadmap (info->interp_loadmap);
}
/* Allocate space for the complete (external) loadmap. */
ext_ldmbuf_size = sizeof (struct ext_elf32_dsbt_loadmap)
+ (nsegs - 1) * sizeof (struct ext_elf32_dsbt_loadseg);
- ext_ldmbuf = xmalloc (ext_ldmbuf_size);
+ ext_ldmbuf = (struct ext_elf32_dsbt_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);
external loadsegs. I.e, allocate the internal loadsegs. */
int_ldmbuf_size = sizeof (struct int_elf32_dsbt_loadmap)
+ (nsegs - 1) * sizeof (struct int_elf32_dsbt_loadseg);
- int_ldmbuf = xmalloc (int_ldmbuf_size);
+ int_ldmbuf = (struct int_elf32_dsbt_loadmap *) xmalloc (int_ldmbuf_size);
/* Place extracted information in internal structs. */
int_ldmbuf->version = version;
/* Read in .dynamic from the BFD. We will get the actual value
from memory later. */
sect_size = bfd_section_size (abfd, sect);
- buf = bufstart = alloca (sect_size);
+ buf = bufstart = (gdb_byte *) alloca (sect_size);
if (!bfd_get_section_contents (abfd, sect,
buf, 0, sect_size))
return 0;
return 0;
}
-/* If no open symbol file, attempt to locate and open the main symbol
- file.
-
- If FROM_TTYP dereferences to a non-zero integer, allow messages to
- be printed. This parameter is a pointer rather than an int because
- open_symbol_file_object is called via catch_errors and
- catch_errors requires a pointer argument. */
+/* See solist.h. */
static int
-open_symbol_file_object (void *from_ttyp)
+open_symbol_file_object (int from_tty)
{
/* Unimplemented. */
return 0;
lm_base (void)
{
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- struct minimal_symbol *got_sym;
+ struct bound_minimal_symbol got_sym;
CORE_ADDR addr;
gdb_byte buf[TIC6X_PTR_SIZE];
struct dsbt_info *info = get_dsbt_info ();
got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL,
symfile_objfile);
- if (got_sym != 0)
+ if (got_sym.minsym != 0)
{
- addr = SYMBOL_VALUE_ADDRESS (got_sym);
+ addr = BMSYMBOL_VALUE_ADDRESS (got_sym);
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog,
"lm_base: get addr %x by _GLOBAL_OFFSET_TABLE_.\n",
if (dsbt_index != 0)
{
int errcode;
- char *name_buf;
+ gdb::unique_xmalloc_ptr<char> name_buf;
struct int_elf32_dsbt_loadmap *loadmap;
struct so_list *sop;
CORE_ADDR addr;
break;
}
- sop = xcalloc (1, sizeof (struct so_list));
- sop->lm_info = xcalloc (1, sizeof (struct lm_info));
- sop->lm_info->map = loadmap;
+ sop = XCNEW (struct so_list);
+ lm_info_dsbt *li = new lm_info_dsbt;
+ sop->lm_info = li;
+ li->map = loadmap;
/* Fetch the name. */
addr = extract_unsigned_integer (lm_buf.l_name,
sizeof (lm_buf.l_name),
{
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n",
- name_buf);
+ name_buf.get ());
- strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1);
+ strncpy (sop->so_name, name_buf.get (), 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);
}
/* Helper function for gdb_bfd_lookup_symbol. */
static int
-cmp_name (asymbol *sym, void *data)
+cmp_name (const asymbol *sym, const void *data)
{
return (strcmp (sym->name, (const char *) data) == 0);
}
static int
enable_break (void)
{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
asection *interp_sect;
struct dsbt_info *info;
{
unsigned int interp_sect_size;
char *buf;
- bfd *tmp_bfd = NULL;
CORE_ADDR addr;
- gdb_byte addr_buf[TIC6X_PTR_SIZE];
struct int_elf32_dsbt_loadmap *ldm;
- volatile struct gdb_exception ex;
int ret;
/* 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);
+ buf = (char *) alloca (interp_sect_size);
bfd_get_section_contents (exec_bfd, interp_sect,
buf, 0, interp_sect_size);
loaded so that we can load its symbols and place a breakpoint
in the dynamic linker itself. */
- TRY_CATCH (ex, RETURN_MASK_ALL)
+ gdb_bfd_ref_ptr tmp_bfd;
+ TRY
{
tmp_bfd = solib_bfd_open (buf);
}
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ }
+ END_CATCH
+
if (tmp_bfd == NULL)
{
enable_break_failure_warning ();
/* Record the relocated start and end address of the dynamic linker
text and plt section for dsbt_in_dynsym_resolve_code. */
- interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+ interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text");
if (interp_sect)
{
info->interp_text_sect_low
- = bfd_section_vma (tmp_bfd, interp_sect);
+ = bfd_section_vma (tmp_bfd.get (), interp_sect);
info->interp_text_sect_low
+= displacement_from_map (ldm, info->interp_text_sect_low);
info->interp_text_sect_high
= info->interp_text_sect_low
- + bfd_section_size (tmp_bfd, interp_sect);
+ + bfd_section_size (tmp_bfd.get (), 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)
{
info->interp_plt_sect_low =
- bfd_section_vma (tmp_bfd, interp_sect);
+ bfd_section_vma (tmp_bfd.get (), interp_sect);
info->interp_plt_sect_low
+= displacement_from_map (ldm, info->interp_plt_sect_low);
info->interp_plt_sect_high =
- info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ info->interp_plt_sect_low + bfd_section_size (tmp_bfd.get (),
+ interp_sect);
}
- addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state");
+ addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), cmp_name,
+ "_dl_debug_state");
if (addr != 0)
{
if (solib_dsbt_debug)
ret = 0;
}
- /* 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);
return ret;
return 0;
}
-/* Once the symbols from a shared object have been loaded in the usual
- way, we are called to do any system specific symbol handling that
- is needed. */
-
-static void
-dsbt_special_symbol_handling (void)
-{
-}
-
static void
dsbt_relocate_main_executable (void)
{
dsbt_get_initial_loadmaps ();
ldm = info->exec_loadmap;
- xfree (info->main_executable_lm_info);
- info->main_executable_lm_info = xcalloc (1, sizeof (struct lm_info));
+ delete info->main_executable_lm_info;
+ info->main_executable_lm_info = new lm_info_dsbt;
info->main_executable_lm_info->map = ldm;
- new_offsets = xcalloc (symfile_objfile->num_sections,
- sizeof (struct section_offsets));
+ new_offsets = XCNEWVEC (struct section_offsets,
+ symfile_objfile->num_sections);
old_chain = make_cleanup (xfree, new_offsets);
changed = 0;
info->lm_base_cache = 0;
info->main_lm_addr = 0;
- if (info->main_executable_lm_info != 0)
- {
- xfree (info->main_executable_lm_info->map);
- xfree (info->main_executable_lm_info);
- info->main_executable_lm_info = 0;
- }
+
+ delete info->main_executable_lm_info;
+ info->main_executable_lm_info = NULL;
}
static void
dsbt_free_so (struct so_list *so)
{
- xfree (so->lm_info->map);
- xfree (so->lm_info);
+ lm_info_dsbt *li = (lm_info_dsbt *) so->lm_info;
+
+ delete li;
}
static void
struct target_section *sec)
{
int seg;
- struct int_elf32_dsbt_loadmap *map;
-
- map = so->lm_info->map;
+ lm_info_dsbt *li = (lm_info_dsbt *) so->lm_info;
+ int_elf32_dsbt_loadmap *map = li->map;
for (seg = 0; seg < map->nsegs; seg++)
{
struct target_so_ops dsbt_so_ops;
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_dsbt_solib;
-
void
_initialize_dsbt_solib (void)
{
dsbt_so_ops.free_so = dsbt_free_so;
dsbt_so_ops.clear_solib = dsbt_clear_solib;
dsbt_so_ops.solib_create_inferior_hook = dsbt_solib_create_inferior_hook;
- dsbt_so_ops.special_symbol_handling = dsbt_special_symbol_handling;
dsbt_so_ops.current_sos = dsbt_current_sos;
dsbt_so_ops.open_symbol_file_object = open_symbol_file_object;
dsbt_so_ops.in_dynsym_resolve_code = dsbt_in_dynsym_resolve_code;