/* Handle TIC6X (DSBT) shared libraries for GDB, the GNU Debugger.
   Copyright (C) 2010-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */


#include "defs.h"
#include "inferior.h"
#include "gdbcore.h"
#include "solib.h"
#include "solist.h"
#include "objfiles.h"
#include "symtab.h"
#include "language.h"
#include "command.h"
#include "gdbcmd.h"
#include "elf-bfd.h"
#include "gdb_bfd.h"

#define GOT_MODULE_OFFSET 4

/* Flag which indicates whether internal debug messages should be printed.  */
static unsigned int solib_dsbt_debug = 0;

/* TIC6X pointers are four bytes wide.  */
enum { TIC6X_PTR_SIZE = 4 };

/* Representation of loadmap and related structs for the TIC6X DSBT.  */

/* External versions; the size and alignment of the fields should be
   the same as those on the target.  When loaded, the placement of
   the bits in each field will be the same as on the target.  */
typedef gdb_byte ext_Elf32_Half[2];
typedef gdb_byte ext_Elf32_Addr[4];
typedef gdb_byte ext_Elf32_Word[4];

struct ext_elf32_dsbt_loadseg
{
  /* Core address to which the segment is mapped.  */
  ext_Elf32_Addr addr;
  /* VMA recorded in the program header.  */
  ext_Elf32_Addr p_vaddr;
  /* Size of this segment in memory.  */
  ext_Elf32_Word p_memsz;
};

struct ext_elf32_dsbt_loadmap {
  /* Protocol version number, must be zero.  */
  ext_Elf32_Word version;
  /* A pointer to the DSBT table; the DSBT size and the index of this
     module.  */
  ext_Elf32_Word dsbt_table_ptr;
  ext_Elf32_Word dsbt_size;
  ext_Elf32_Word dsbt_index;
  /* Number of segments in this map.  */
  ext_Elf32_Word nsegs;
  /* The actual memory map.  */
  struct ext_elf32_dsbt_loadseg segs[1 /* nsegs, actually */];
};

/* Internal versions; the types are GDB types and the data in each
   of the fields is (or will be) decoded from the external struct
   for ease of consumption.  */
struct int_elf32_dsbt_loadseg
{
  /* Core address to which the segment is mapped.  */
  CORE_ADDR addr;
  /* VMA recorded in the program header.  */
  CORE_ADDR p_vaddr;
  /* Size of this segment in memory.  */
  long p_memsz;
};

struct int_elf32_dsbt_loadmap
{
  /* Protocol version number, must be zero.  */
  int version;
  CORE_ADDR dsbt_table_ptr;
  /* A pointer to the DSBT table; the DSBT size and the index of this
     module.  */
  int dsbt_size, dsbt_index;
  /* Number of segments in this map.  */
  int nsegs;
  /* The actual memory map.  */
  struct int_elf32_dsbt_loadseg segs[1 /* nsegs, actually */];
};

/* External link_map and elf32_dsbt_loadaddr struct definitions.  */

typedef gdb_byte ext_ptr[4];

struct ext_elf32_dsbt_loadaddr
{
  ext_ptr map;			/* struct elf32_dsbt_loadmap *map; */
};

struct ext_link_map
{
  struct ext_elf32_dsbt_loadaddr l_addr;

  /* Absolute file name object was found in.  */
  ext_ptr l_name;		/* char *l_name; */

  /* Dynamic section of the shared object.  */
  ext_ptr l_ld;			/* ElfW(Dyn) *l_ld; */

  /* Chain of loaded objects.  */
  ext_ptr l_next, l_prev;	/* struct link_map *l_next, *l_prev; */
};

/* Link map info to include in an allocated so_list entry */

struct lm_info_dsbt : public lm_info_base
{
  ~lm_info_dsbt ()
  {
    xfree (this->map);
  }

  /* The loadmap, digested into an easier to use form.  */
  int_elf32_dsbt_loadmap *map = NULL;
};

/* Per pspace dsbt specific data.  */

struct dsbt_info
{
  /* 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 dsbt_relocate_main_executable.  */
  struct lm_info_dsbt *main_executable_lm_info = nullptr;

  /* Load maps for the main executable and the interpreter.  These are obtained
     from ptrace.  They are the starting point for getting into the program,
     and are required to find the solib list with the individual load maps for
     each module.  */
  struct int_elf32_dsbt_loadmap *exec_loadmap = nullptr;
  struct int_elf32_dsbt_loadmap *interp_loadmap = nullptr;

  /* Cached value for lm_base, below.  */
  CORE_ADDR lm_base_cache = 0;

  /* Link map address for main module.  */
  CORE_ADDR main_lm_addr = 0;

  CORE_ADDR interp_text_sect_low = 0;
  CORE_ADDR interp_text_sect_high = 0;
  CORE_ADDR interp_plt_sect_low = 0;
  CORE_ADDR interp_plt_sect_high = 0;
};

/* Per-program-space data key.  */
static program_space_key<dsbt_info> solib_dsbt_pspace_data;

/* Get the current dsbt data.  If none is found yet, add it now.  This
   function always returns a valid object.  */

static struct dsbt_info *
get_dsbt_info (void)
{
  struct dsbt_info *info;

  info = solib_dsbt_pspace_data.get (current_program_space);
  if (info != NULL)
    return info;

  return solib_dsbt_pspace_data.emplace (current_program_space);
}


static void
dsbt_print_loadmap (struct int_elf32_dsbt_loadmap *map)
{
  int i;

  if (map == NULL)
    printf_filtered ("(null)\n");
  else if (map->version != 0)
    printf_filtered (_("Unsupported map version: %d\n"), map->version);
  else
    {
      printf_filtered ("version %d\n", map->version);

      for (i = 0; i < map->nsegs; i++)
	printf_filtered ("%s:%s -> %s:%s\n",
			 print_core_address (target_gdbarch (),
					     map->segs[i].p_vaddr),
			 print_core_address (target_gdbarch (),
					     map->segs[i].p_vaddr
					     + map->segs[i].p_memsz),
			 print_core_address (target_gdbarch (), map->segs[i].addr),
			 print_core_address (target_gdbarch (), map->segs[i].addr
					     + map->segs[i].p_memsz));
    }
}

/* Decode int_elf32_dsbt_loadmap from BUF.  */

static struct int_elf32_dsbt_loadmap *
decode_loadmap (const gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  const struct ext_elf32_dsbt_loadmap *ext_ldmbuf;
  struct int_elf32_dsbt_loadmap *int_ldmbuf;

  int version, seg, nsegs;
  int int_ldmbuf_size;

  ext_ldmbuf = (struct ext_elf32_dsbt_loadmap *) buf;

  /* Extract the version.  */
  version = extract_unsigned_integer (ext_ldmbuf->version,
				      sizeof ext_ldmbuf->version,
				      byte_order);
  if (version != 0)
    {
      /* We only handle version 0.  */
      return NULL;
    }

  /* Extract the number of segments.  */
  nsegs = extract_unsigned_integer (ext_ldmbuf->nsegs,
				    sizeof ext_ldmbuf->nsegs,
				    byte_order);

  if (nsegs <= 0)
    return NULL;

  /* 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_dsbt_loadmap)
		     + (nsegs - 1) * sizeof (struct int_elf32_dsbt_loadseg));
  int_ldmbuf = (struct int_elf32_dsbt_loadmap *) xmalloc (int_ldmbuf_size);

  /* Place extracted information in internal structs.  */
  int_ldmbuf->version = version;
  int_ldmbuf->nsegs = nsegs;
  for (seg = 0; seg < nsegs; seg++)
    {
      int_ldmbuf->segs[seg].addr
	= extract_unsigned_integer (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),
				    byte_order);
      int_ldmbuf->segs[seg].p_memsz
	= extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz,
				    sizeof (ext_ldmbuf->segs[seg].p_memsz),
				    byte_order);
    }

  return int_ldmbuf;
}


static struct dsbt_info *get_dsbt_info (void);

/* Interrogate the Linux kernel to find out where the program was loaded.
   There are two load maps; one for the executable and one for the
   interpreter (only in the case of a dynamically linked executable).  */

static void
dsbt_get_initial_loadmaps (void)
{
  struct dsbt_info *info = get_dsbt_info ();
  gdb::optional<gdb::byte_vector> buf
    = target_read_alloc (current_inferior ()->top_target (),
			 TARGET_OBJECT_FDPIC, "exec");

  if (!buf || buf->empty ())
    {
      info->exec_loadmap = NULL;
      error (_("Error reading DSBT exec loadmap"));
    }
  info->exec_loadmap = decode_loadmap (buf->data ());
  if (solib_dsbt_debug)
    dsbt_print_loadmap (info->exec_loadmap);

  buf = target_read_alloc (current_inferior ()->top_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->data ());
  if (solib_dsbt_debug)
    dsbt_print_loadmap (info->interp_loadmap);
}

/* Given address LDMADDR, fetch and decode the loadmap at that address.
   Return NULL if there is a problem reading the target memory or if
   there doesn't appear to be a loadmap at the given address.  The
   allocated space (representing the loadmap) returned by this
   function may be freed via a single call to xfree.  */

static struct int_elf32_dsbt_loadmap *
fetch_loadmap (CORE_ADDR ldmaddr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  struct ext_elf32_dsbt_loadmap ext_ldmbuf_partial;
  struct ext_elf32_dsbt_loadmap *ext_ldmbuf;
  struct int_elf32_dsbt_loadmap *int_ldmbuf;
  int ext_ldmbuf_size, int_ldmbuf_size;
  int version, seg, nsegs;

  /* Fetch initial portion of the loadmap.  */
  if (target_read_memory (ldmaddr, (gdb_byte *) &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,
				      byte_order);
  if (version != 0)
    {
      /* We only handle version 0.  */
      return NULL;
    }

  /* Extract the number of segments.  */
  nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
				    sizeof ext_ldmbuf_partial.nsegs,
				    byte_order);

  if (nsegs <= 0)
    return NULL;

  /* 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 = (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);

  /* 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))
    {
      /* Couldn't read rest of the loadmap.  */
      xfree (ext_ldmbuf);
      return NULL;
    }

  /* 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_dsbt_loadmap)
    + (nsegs - 1) * sizeof (struct int_elf32_dsbt_loadseg);
  int_ldmbuf = (struct int_elf32_dsbt_loadmap *) xmalloc (int_ldmbuf_size);

  /* Place extracted information in internal structs.  */
  int_ldmbuf->version = version;
  int_ldmbuf->nsegs = nsegs;
  for (seg = 0; seg < nsegs; seg++)
    {
      int_ldmbuf->segs[seg].addr
	= extract_unsigned_integer (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),
				    byte_order);
      int_ldmbuf->segs[seg].p_memsz
	= extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz,
				    sizeof (ext_ldmbuf->segs[seg].p_memsz),
				    byte_order);
    }

  xfree (ext_ldmbuf);
  return int_ldmbuf;
}

static void dsbt_relocate_main_executable (void);
static int enable_break (void);

/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
   returned and the corresponding PTR is set.  */

static int
scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
{
  int arch_size, step, sect_size;
  long dyn_tag;
  CORE_ADDR dyn_ptr, dyn_addr;
  gdb_byte *bufend, *bufstart, *buf;
  Elf32_External_Dyn *x_dynp_32;
  Elf64_External_Dyn *x_dynp_64;
  struct bfd_section *sect;

  if (abfd == NULL)
    return 0;

  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    return 0;

  arch_size = bfd_get_arch_size (abfd);
  if (arch_size == -1)
    return 0;

  /* Find the start address of the .dynamic section.  */
  sect = bfd_get_section_by_name (abfd, ".dynamic");
  if (sect == NULL)
    return 0;

  bool found = false;
  for (const target_section &target_section
	 : current_program_space->target_sections ())
    if (sect == target_section.the_bfd_section)
      {
	dyn_addr = target_section.addr;
	found = true;
	break;
      }
  if (!found)
    {
      /* ABFD may come from OBJFILE acting only as a symbol file without being
	 loaded into the target (see add_symbol_file_command).  This case is
	 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 (sect);
    }

  /* Read in .dynamic from the BFD.  We will get the actual value
     from memory later.  */
  sect_size = bfd_section_size (sect);
  buf = bufstart = (gdb_byte *) alloca (sect_size);
  if (!bfd_get_section_contents (abfd, sect,
				 buf, 0, sect_size))
    return 0;

  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
			   : sizeof (Elf64_External_Dyn);
  for (bufend = buf + sect_size;
       buf < bufend;
       buf += step)
  {
    if (arch_size == 32)
      {
	x_dynp_32 = (Elf32_External_Dyn *) buf;
	dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
      }
    else
      {
	x_dynp_64 = (Elf64_External_Dyn *) buf;
	dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
      }
     if (dyn_tag == DT_NULL)
       return 0;
     if (dyn_tag == dyntag)
       {
	 /* If requested, try to read the runtime value of this .dynamic
	    entry.  */
	 if (ptr)
	   {
	     struct type *ptr_type;
	     gdb_byte ptr_buf[8];
	     CORE_ADDR ptr_addr;

	     ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
	     ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
	     if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
	       dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
	     *ptr = dyn_ptr;
	   }
	 return 1;
       }
  }

  return 0;
}

/* See solist.h. */

static int
open_symbol_file_object (int from_tty)
{
  /* Unimplemented.  */
  return 0;
}

/* Given a loadmap and an address, return the displacement needed
   to relocate the address.  */

static CORE_ADDR
displacement_from_map (struct int_elf32_dsbt_loadmap *map,
		       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)
      return map->segs[seg].addr - map->segs[seg].p_vaddr;

  return 0;
}

/* Return the address from which the link map chain may be found.  On
   DSBT, a pointer to the start of the link map will be located at the
   word found at base of GOT + GOT_MODULE_OFFSET.

   The base of GOT may be found in a number of ways.  Assuming that the
   main executable has already been relocated,
   1 The easiest way to find this value is to look up the address of
   _GLOBAL_OFFSET_TABLE_.
   2 The other way is to look for tag DT_PLTGOT, which contains the virtual
   address of Global Offset Table.  .*/

static CORE_ADDR
lm_base (void)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  struct bound_minimal_symbol got_sym;
  CORE_ADDR addr;
  gdb_byte buf[TIC6X_PTR_SIZE];
  struct dsbt_info *info = get_dsbt_info ();

  /* One of our assumptions is that the main executable has been relocated.
     Bail out if this has not happened.  (Note that post_create_inferior
     in infcmd.c will call solib_add prior to solib_create_inferior_hook.
     If we allow this to happen, lm_base_cache will be initialized with
     a bogus value.  */
  if (info->main_executable_lm_info == 0)
    return 0;

  /* If we already have a cached value, return it.  */
  if (info->lm_base_cache)
    return info->lm_base_cache;

  got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL,
				   current_program_space->symfile_object_file);

  if (got_sym.minsym != 0)
    {
      addr = BMSYMBOL_VALUE_ADDRESS (got_sym);
      if (solib_dsbt_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "lm_base: get addr %x by _GLOBAL_OFFSET_TABLE_.\n",
			    (unsigned int) addr);
    }
  else if (scan_dyntag (DT_PLTGOT, current_program_space->exec_bfd (), &addr))
    {
      struct int_elf32_dsbt_loadmap *ldm;

      dsbt_get_initial_loadmaps ();
      ldm = info->exec_loadmap;
      addr += displacement_from_map (ldm, addr);
      if (solib_dsbt_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "lm_base: get addr %x by DT_PLTGOT.\n",
			    (unsigned int) addr);
    }
  else
    {
      if (solib_dsbt_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "lm_base: _GLOBAL_OFFSET_TABLE_ not found.\n");
      return 0;
    }
  addr += GOT_MODULE_OFFSET;

  if (solib_dsbt_debug)
    fprintf_unfiltered (gdb_stdlog,
			"lm_base: _GLOBAL_OFFSET_TABLE_ + %d = %s\n",
			GOT_MODULE_OFFSET, hex_string_custom (addr, 8));

  if (target_read_memory (addr, buf, sizeof buf) != 0)
    return 0;
  info->lm_base_cache = extract_unsigned_integer (buf, sizeof buf, byte_order);

  if (solib_dsbt_debug)
    fprintf_unfiltered (gdb_stdlog,
			"lm_base: lm_base_cache = %s\n",
			hex_string_custom (info->lm_base_cache, 8));

  return info->lm_base_cache;
}


/* Build a list of `struct so_list' objects describing the shared
   objects currently loaded in the inferior.  This list does not
   include an entry for the main executable file.

   Note that we only gather information directly available from the
   inferior --- we don't examine any of the shared library files
   themselves.  The declaration of `struct so_list' says which fields
   we provide values for.  */

static struct so_list *
dsbt_current_sos (void)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  CORE_ADDR lm_addr;
  struct so_list *sos_head = NULL;
  struct so_list **sos_next_ptr = &sos_head;
  struct dsbt_info *info = get_dsbt_info ();

  /* Make sure that the main executable has been relocated.  This is
     required in order to find the address of the global offset table,
     which in turn is used to find the link map info.  (See lm_base
     for details.)

     Note that the relocation of the main executable is also performed
     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 function,
     dsbt_current_sos, and also precedes the call to
     solib_create_inferior_hook.   (See post_create_inferior in
     infcmd.c.)  */
  if (info->main_executable_lm_info == 0 && core_bfd != NULL)
    dsbt_relocate_main_executable ();

  /* Locate the address of the first link map struct.  */
  lm_addr = lm_base ();

  /* We have at least one link map entry.  Fetch the lot of them,
     building the solist chain.  */
  while (lm_addr)
    {
      struct ext_link_map lm_buf;
      ext_Elf32_Word indexword;
      CORE_ADDR map_addr;
      int dsbt_index;
      int ret;

      if (solib_dsbt_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "current_sos: reading link_map entry at %s\n",
			    hex_string_custom (lm_addr, 8));

      ret = target_read_memory (lm_addr, (gdb_byte *) &lm_buf, sizeof (lm_buf));
      if (ret)
	{
	  warning (_("dsbt_current_sos: Unable to read link map entry."
		     "  Shared object chain may be incomplete."));
	  break;
	}

      /* Fetch the load map address.  */
      map_addr = extract_unsigned_integer (lm_buf.l_addr.map,
					   sizeof lm_buf.l_addr.map,
					   byte_order);

      ret = target_read_memory (map_addr + 12, (gdb_byte *) &indexword,
				sizeof indexword);
      if (ret)
	{
	  warning (_("dsbt_current_sos: Unable to read dsbt index."
		     "  Shared object chain may be incomplete."));
	  break;
	}
      dsbt_index = extract_unsigned_integer (indexword, sizeof indexword,
					     byte_order);

      /* If the DSBT index is zero, then we're looking at the entry
	 for the main executable.  By convention, we don't include
	 this in the list of shared objects.  */
      if (dsbt_index != 0)
	{
	  struct int_elf32_dsbt_loadmap *loadmap;
	  struct so_list *sop;
	  CORE_ADDR addr;

	  loadmap = fetch_loadmap (map_addr);
	  if (loadmap == NULL)
	    {
	      warning (_("dsbt_current_sos: Unable to fetch load map."
			 "  Shared object chain may be incomplete."));
	      break;
	    }

	  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),
					   byte_order);
	  gdb::unique_xmalloc_ptr<char> name_buf
	    = target_read_string (addr, SO_NAME_MAX_PATH_SIZE - 1);

	  if (name_buf == nullptr)
	    warning (_("Can't read pathname for link map entry."));
	  else
	    {
	      if (solib_dsbt_debug)
		fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n",
				    name_buf.get ());

	      strncpy (sop->so_name, name_buf.get (), SO_NAME_MAX_PATH_SIZE - 1);
	      sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
	      strcpy (sop->so_original_name, sop->so_name);
	    }

	  *sos_next_ptr = sop;
	  sos_next_ptr = &sop->next;
	}
      else
	{
	  info->main_lm_addr = lm_addr;
	}

      lm_addr = extract_unsigned_integer (lm_buf.l_next,
					  sizeof (lm_buf.l_next), byte_order);
    }

  return sos_head;
}

/* Return 1 if PC lies in the dynamic symbol resolution code of the
   run time loader.  */

static int
dsbt_in_dynsym_resolve_code (CORE_ADDR pc)
{
  struct dsbt_info *info = get_dsbt_info ();

  return ((pc >= info->interp_text_sect_low && pc < info->interp_text_sect_high)
	  || (pc >= info->interp_plt_sect_low && pc < info->interp_plt_sect_high)
	  || in_plt_section (pc));
}

/* Print a warning about being unable to set the dynamic linker
   breakpoint.  */

static void
enable_break_failure_warning (void)
{
  warning (_("Unable to find dynamic linker breakpoint function.\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 (const asymbol *sym, const void *data)
{
  return (strcmp (sym->name, (const char *) data) == 0);
}

/* The dynamic linkers has, as part of its debugger interface, support
   for arranging for the inferior to hit a breakpoint after mapping in
   the shared libraries.  This function enables that breakpoint.

   On the TIC6X, using the shared library (DSBT), GDB can try to place
   a breakpoint on '_dl_debug_state' to monitor the shared library
   event.  */

static int
enable_break (void)
{
  asection *interp_sect;
  struct dsbt_info *info;

  if (current_program_space->exec_bfd () == NULL)
    return 0;

  if (!target_has_execution ())
    return 0;

  info = get_dsbt_info ();

  info->interp_text_sect_low = 0;
  info->interp_text_sect_high = 0;
  info->interp_plt_sect_low = 0;
  info->interp_plt_sect_high = 0;

  /* 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 (current_program_space->exec_bfd (),
					 ".interp");
  if (interp_sect)
    {
      unsigned int interp_sect_size;
      char *buf;
      CORE_ADDR addr;
      struct int_elf32_dsbt_loadmap *ldm;
      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 (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.  */

      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;
	}

      dsbt_get_initial_loadmaps ();
      ldm = info->interp_loadmap;

      /* 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.get (), ".text");
      if (interp_sect)
	{
	  info->interp_text_sect_low = bfd_section_vma (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 (interp_sect);
	}
      interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt");
      if (interp_sect)
	{
	  info->interp_plt_sect_low = bfd_section_vma (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 (interp_sect);
	}

      addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), cmp_name,
				    "_dl_debug_state");
      if (addr != 0)
	{
	  if (solib_dsbt_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"enable_break: _dl_debug_state (prior to relocation) = %s\n",
				hex_string_custom (addr, 8));
	  addr += displacement_from_map (ldm, addr);

	  if (solib_dsbt_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"enable_break: _dl_debug_state (after relocation) = %s\n",
				hex_string_custom (addr, 8));

	  /* Now (finally!) create the solib breakpoint.  */
	  create_solib_event_breakpoint (target_gdbarch (), addr);

	  ret = 1;
	}
      else
	{
	  if (solib_dsbt_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"enable_break: _dl_debug_state is not found\n");
	  ret = 0;
	}

      /* We're done with the loadmap.  */
      xfree (ldm);

      return ret;
    }

  /* Tell the user we couldn't set a dynamic linker breakpoint.  */
  enable_break_failure_warning ();

  /* Failure return.  */
  return 0;
}

static void
dsbt_relocate_main_executable (void)
{
  struct int_elf32_dsbt_loadmap *ldm;
  int changed;
  struct obj_section *osect;
  struct dsbt_info *info = get_dsbt_info ();

  dsbt_get_initial_loadmaps ();
  ldm = info->exec_loadmap;

  delete info->main_executable_lm_info;
  info->main_executable_lm_info = new lm_info_dsbt;
  info->main_executable_lm_info->map = ldm;

  objfile *objf = current_program_space->symfile_object_file;
  section_offsets new_offsets (objf->section_offsets.size ());
  changed = 0;

  ALL_OBJFILE_OSECTIONS (objf, osect)
    {
      CORE_ADDR orig_addr, addr, offset;
      int osect_idx;
      int seg;

      osect_idx = osect - objf->sections;

      /* Current address of section.  */
      addr = osect->addr ();
      /* Offset from where this section started.  */
      offset = objf->section_offsets[osect_idx];
      /* Original address prior to any past relocations.  */
      orig_addr = addr - offset;

      for (seg = 0; seg < ldm->nsegs; seg++)
	{
	  if (ldm->segs[seg].p_vaddr <= orig_addr
	      && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
	    {
	      new_offsets[osect_idx]
		= ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;

	      if (new_offsets[osect_idx] != offset)
		changed = 1;
	      break;
	    }
	}
    }

  if (changed)
    objfile_relocate (objf, new_offsets);

  /* Now that OBJF has been relocated, we can compute the GOT value
     and stash it away.  */
}

/* When gdb starts up the inferior, it nurses it along (through the
   shell) until it is ready to execute it's first instruction.  At this
   point, this function gets called via solib_create_inferior_hook.

   For the DSBT shared library, the main executable needs to be relocated.
   The shared library breakpoints also need to be enabled.  */

static void
dsbt_solib_create_inferior_hook (int from_tty)
{
  /* Relocate main executable.  */
  dsbt_relocate_main_executable ();

  /* Enable shared library breakpoints.  */
  if (!enable_break ())
    {
      warning (_("shared library handler failed to enable breakpoint"));
      return;
    }
}

static void
dsbt_clear_solib (void)
{
  struct dsbt_info *info = get_dsbt_info ();

  info->lm_base_cache = 0;
  info->main_lm_addr = 0;

  delete info->main_executable_lm_info;
  info->main_executable_lm_info = NULL;
}

static void
dsbt_free_so (struct so_list *so)
{
  lm_info_dsbt *li = (lm_info_dsbt *) so->lm_info;

  delete li;
}

static void
dsbt_relocate_section_addresses (struct so_list *so,
				 struct target_section *sec)
{
  int seg;
  lm_info_dsbt *li = (lm_info_dsbt *) so->lm_info;
  int_elf32_dsbt_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)
	{
	  CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr;

	  sec->addr += displ;
	  sec->endaddr += displ;
	  break;
	}
    }
}
static void
show_dsbt_debug (struct ui_file *file, int from_tty,
		 struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("solib-dsbt debugging is %s.\n"), value);
}

struct target_so_ops dsbt_so_ops;

void _initialize_dsbt_solib ();
void
_initialize_dsbt_solib ()
{
  dsbt_so_ops.relocate_section_addresses = dsbt_relocate_section_addresses;
  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.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;
  dsbt_so_ops.bfd_open = solib_bfd_open;

  /* Debug this file's internals.  */
  add_setshow_zuinteger_cmd ("solib-dsbt", class_maintenance,
			     &solib_dsbt_debug, _("\
Set internal debugging of shared library code for DSBT ELF."), _("\
Show internal debugging of shared library code for DSBT ELF."), _("\
When non-zero, DSBT solib specific internal debugging is enabled."),
			     NULL,
			     show_dsbt_debug,
			     &setdebuglist, &showdebuglist);
}
