/* Handle TIC6X (DSBT) shared libraries for GDB, the GNU Debugger.
   Copyright (C) 2010-2020 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_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_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;
  struct target_section *target_section;

  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;

  for (target_section = current_target_sections->sections;
       target_section < current_target_sections->sections_end;
       target_section++)
    if (sect == target_section->the_bfd_section)
      break;
  if (target_section < current_target_sections->sections_end)
    dyn_addr = target_section->addr;
  else
    {
      /* 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,
				   symfile_objfile);

  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, 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 (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 (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 (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;

  section_offsets new_offsets (symfile_objfile->section_offsets.size ());
  changed = 0;

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

      osect_idx = osect - symfile_objfile->sections;

      /* Current address of section.  */
      addr = obj_section_addr (osect);
      /* Offset from where this section started.  */
      offset = symfile_objfile->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 (symfile_objfile, new_offsets);

  /* Now that symfile_objfile 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);
}
