/* Copyright (C) 2013-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 "solib-aix.h"
#include "solist.h"
#include "inferior.h"
#include "gdb_bfd.h"
#include "gdbcore.h"
#include "objfiles.h"
#include "symtab.h"
#include "xcoffread.h"
#include "observable.h"
#include "gdbcmd.h"
#include "gdbsupport/scope-exit.h"

/* Variable controlling the output of the debugging traces for
   this module.  */
static bool solib_aix_debug;

/* Print an "aix-solib" debug statement.  */

#define solib_aix_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (solib_aix_debug, "aix-solib",fmt, ##__VA_ARGS__)

/* Our private data in struct so_list.  */

struct lm_info_aix : public lm_info_base
{
  /* The name of the file mapped by the loader.  Apart from the entry
     for the main executable, this is usually a shared library (which,
     on AIX, is an archive library file, created using the "ar"
     command).  */
  std::string filename;

  /* The name of the shared object file with the actual dynamic
     loading dependency.  This may be empty (Eg. main executable).  */
  std::string member_name;

  /* The address in inferior memory where the text section got mapped.  */
  CORE_ADDR text_addr = 0;

  /* The size of the text section, obtained via the loader data.  */
  ULONGEST text_size = 0;

  /* The address in inferior memory where the data section got mapped.  */
  CORE_ADDR data_addr = 0;

  /* The size of the data section, obtained via the loader data.  */
  ULONGEST data_size = 0;
};

/* This module's per-inferior data.  */

struct solib_aix_inferior_data
{
  /* The list of shared libraries.

     Note that the first element of this list is always the main
     executable, which is not technically a shared library.  But
     we need that information to perform its relocation, and
     the same principles applied to shared libraries also apply
     to the main executable.  So it's simpler to keep it as part
     of this list.  */
  gdb::optional<std::vector<lm_info_aix>> library_list;
};

/* Key to our per-inferior data.  */
static inferior_key<solib_aix_inferior_data> solib_aix_inferior_data_handle;

/* Return this module's data for the given inferior.
   If none is found, add a zero'ed one now.  */

static struct solib_aix_inferior_data *
get_solib_aix_inferior_data (struct inferior *inf)
{
  struct solib_aix_inferior_data *data;

  data = solib_aix_inferior_data_handle.get (inf);
  if (data == NULL)
    data = solib_aix_inferior_data_handle.emplace (inf);

  return data;
}

#if !defined(HAVE_LIBEXPAT)

/* Dummy implementation if XML support is not compiled in.  */

static gdb::optional<std::vector<lm_info_aix>>
solib_aix_parse_libraries (const char *library)
{
  static int have_warned;

  if (!have_warned)
    {
      have_warned = 1;
      warning (_("Can not parse XML library list; XML support was disabled "
		 "at compile time"));
    }

  return {};
}

#else /* HAVE_LIBEXPAT */

#include "xml-support.h"

/* Handle the start of a <library> element.  */

static void
library_list_start_library (struct gdb_xml_parser *parser,
			    const struct gdb_xml_element *element,
			    void *user_data,
			    std::vector<gdb_xml_value> &attributes)
{
  std::vector<lm_info_aix> *list = (std::vector<lm_info_aix> *) user_data;
  lm_info_aix item;
  struct gdb_xml_value *attr;

  attr = xml_find_attribute (attributes, "name");
  item.filename = (const char *) attr->value.get ();

  attr = xml_find_attribute (attributes, "member");
  if (attr != NULL)
    item.member_name = (const char *) attr->value.get ();

  attr = xml_find_attribute (attributes, "text_addr");
  item.text_addr = * (ULONGEST *) attr->value.get ();

  attr = xml_find_attribute (attributes, "text_size");
  item.text_size = * (ULONGEST *) attr->value.get ();

  attr = xml_find_attribute (attributes, "data_addr");
  item.data_addr = * (ULONGEST *) attr->value.get ();

  attr = xml_find_attribute (attributes, "data_size");
  item.data_size = * (ULONGEST *) attr->value.get ();

  list->push_back (std::move (item));
}

/* Handle the start of a <library-list-aix> element.  */

static void
library_list_start_list (struct gdb_xml_parser *parser,
			 const struct gdb_xml_element *element,
			 void *user_data,
			 std::vector<gdb_xml_value> &attributes)
{
  char *version
    = (char *) xml_find_attribute (attributes, "version")->value.get ();

  if (strcmp (version, "1.0") != 0)
    gdb_xml_error (parser,
		   _("Library list has unsupported version \"%s\""),
		   version);
}

/* The allowed elements and attributes for an AIX library list
   described in XML format.  The root element is a <library-list-aix>.  */

static const struct gdb_xml_attribute library_attributes[] =
{
  { "name", GDB_XML_AF_NONE, NULL, NULL },
  { "member", GDB_XML_AF_OPTIONAL, NULL, NULL },
  { "text_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "text_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "data_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "data_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

static const struct gdb_xml_element library_list_children[] =
{
  { "library", library_attributes, NULL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    library_list_start_library, NULL},
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

static const struct gdb_xml_attribute library_list_attributes[] =
{
  { "version", GDB_XML_AF_NONE, NULL, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

static const struct gdb_xml_element library_list_elements[] =
{
  { "library-list-aix", library_list_attributes, library_list_children,
    GDB_XML_EF_NONE, library_list_start_list, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

/* Parse LIBRARY, a string containing the loader info in XML format,
   and return a vector of lm_info_aix objects.

   Return an empty option if the parsing failed.  */

static gdb::optional<std::vector<lm_info_aix>>
solib_aix_parse_libraries (const char *library)
{
  std::vector<lm_info_aix> result;

  if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
			   library_list_elements, library, &result) == 0)
    return result;

  return {};
}

#endif /* HAVE_LIBEXPAT */

/* Return the loader info for the given inferior (INF), or an empty
   option if the list could not be computed.

   Cache the result in per-inferior data, so as to avoid recomputing it
   each time this function is called.

   If an error occurs while computing this list, and WARNING_MSG
   is not NULL, then print a warning including WARNING_MSG and
   a description of the error.  */

static gdb::optional<std::vector<lm_info_aix>> &
solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
{
  struct solib_aix_inferior_data *data;

  /* If already computed, return the cached value.  */
  data = get_solib_aix_inferior_data (inf);
  if (data->library_list.has_value ())
    return data->library_list;

  gdb::optional<gdb::char_vector> library_document
    = target_read_stralloc (current_inferior ()->top_target (),
			    TARGET_OBJECT_LIBRARIES_AIX,
			    NULL);
  if (!library_document && warning_msg != NULL)
    {
      warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
	       warning_msg);
      return data->library_list;
    }

  solib_aix_debug_printf ("TARGET_OBJECT_LIBRARIES_AIX = %s",
			  library_document->data ());

  data->library_list = solib_aix_parse_libraries (library_document->data ());
  if (!data->library_list.has_value () && warning_msg != NULL)
    warning (_("%s (missing XML support?)"), warning_msg);

  return data->library_list;
}

/* If the .bss section's VMA is set to an address located before
   the end of the .data section, causing the two sections to overlap,
   return the overlap in bytes.  Otherwise, return zero.

   Motivation:

   The GNU linker sometimes sets the start address of the .bss session
   before the end of the .data section, making the 2 sections overlap.
   The loader appears to handle this situation gracefully, by simply
   loading the bss section right after the end of the .data section.

   This means that the .data and the .bss sections are sometimes
   no longer relocated by the same amount.  The problem is that
   the ldinfo data does not contain any information regarding
   the relocation of the .bss section, assuming that it would be
   identical to the information provided for the .data section
   (this is what would normally happen if the program was linked
   correctly).

   GDB therefore needs to detect those cases, and make the corresponding
   adjustment to the .bss section offset computed from the ldinfo data
   when necessary.  This function returns the adjustment amount  (or
   zero when no adjustment is needed).  */

static CORE_ADDR
solib_aix_bss_data_overlap (bfd *abfd)
{
  struct bfd_section *data_sect, *bss_sect;

  data_sect = bfd_get_section_by_name (abfd, ".data");
  if (data_sect == NULL)
    return 0; /* No overlap possible.  */

  bss_sect = bfd_get_section_by_name (abfd, ".bss");
  if (bss_sect == NULL)
    return 0; /* No overlap possible.  */

  /* Assume the problem only occurs with linkers that place the .bss
     section after the .data section (the problem has only been
     observed when using the GNU linker, and the default linker
     script always places the .data and .bss sections in that order).  */
  if (bfd_section_vma (bss_sect) < bfd_section_vma (data_sect))
    return 0;

  if (bfd_section_vma (bss_sect)
      < bfd_section_vma (data_sect) + bfd_section_size (data_sect))
    return (bfd_section_vma (data_sect) + bfd_section_size (data_sect)
	    - bfd_section_vma (bss_sect));

  return 0;
}

/* Implement the "relocate_section_addresses" target_so_ops method.  */

static void
solib_aix_relocate_section_addresses (struct so_list *so,
				      struct target_section *sec)
{
  struct bfd_section *bfd_sect = sec->the_bfd_section;
  bfd *abfd = bfd_sect->owner;
  const char *section_name = bfd_section_name (bfd_sect);
  lm_info_aix *info = (lm_info_aix *) so->lm_info;

  if (strcmp (section_name, ".text") == 0)
    {
      sec->addr = info->text_addr;
      sec->endaddr = sec->addr + info->text_size;

      /* The text address given to us by the loader contains
	 XCOFF headers, so we need to adjust by this much.  */
      sec->addr += bfd_sect->filepos;
    }
  else if (strcmp (section_name, ".data") == 0)
    {
      sec->addr = info->data_addr;
      sec->endaddr = sec->addr + info->data_size;
    }
  else if (strcmp (section_name, ".bss") == 0)
    {
      /* The information provided by the loader does not include
	 the address of the .bss section, but we know that it gets
	 relocated by the same offset as the .data section.  So,
	 compute the relocation offset for the .data section, and
	 apply it to the .bss section as well.  If the .data section
	 is not defined (which seems highly unlikely), do our best
	 by assuming no relocation.  */
      struct bfd_section *data_sect
	= bfd_get_section_by_name (abfd, ".data");
      CORE_ADDR data_offset = 0;

      if (data_sect != NULL)
	data_offset = info->data_addr - bfd_section_vma (data_sect);

      sec->addr = bfd_section_vma (bfd_sect) + data_offset;
      sec->addr += solib_aix_bss_data_overlap (abfd);
      sec->endaddr = sec->addr + bfd_section_size (bfd_sect);
    }
  else
    {
      /* All other sections should not be relocated.  */
      sec->addr = bfd_section_vma (bfd_sect);
      sec->endaddr = sec->addr + bfd_section_size (bfd_sect);
    }
}

/* Implement the "free_so" target_so_ops method.  */

static void
solib_aix_free_so (struct so_list *so)
{
  lm_info_aix *li = (lm_info_aix *) so->lm_info;

  solib_aix_debug_printf ("%s", so->so_name);

  delete li;
}

/* Implement the "clear_solib" target_so_ops method.  */

static void
solib_aix_clear_solib (void)
{
  /* Nothing needed.  */
}

/* Compute and return the OBJFILE's section_offset array, using
   the associated loader info (INFO).  */

static section_offsets
solib_aix_get_section_offsets (struct objfile *objfile,
			       lm_info_aix *info)
{
  bfd *abfd = objfile->obfd;

  section_offsets offsets (objfile->section_offsets.size ());

  /* .text */

  if (objfile->sect_index_text != -1)
    {
      struct bfd_section *sect
	= objfile->sections[objfile->sect_index_text].the_bfd_section;

      offsets[objfile->sect_index_text]
	= info->text_addr + sect->filepos - bfd_section_vma (sect);
    }

  /* .data */

  if (objfile->sect_index_data != -1)
    {
      struct bfd_section *sect
	= objfile->sections[objfile->sect_index_data].the_bfd_section;

      offsets[objfile->sect_index_data]
	= info->data_addr - bfd_section_vma (sect);
    }

  /* .bss

     The offset of the .bss section should be identical to the offset
     of the .data section.  If no .data section (which seems hard to
     believe it is possible), assume it is zero.  */

  if (objfile->sect_index_bss != -1
      && objfile->sect_index_data != -1)
    {
      offsets[objfile->sect_index_bss]
	= (offsets[objfile->sect_index_data]
	   + solib_aix_bss_data_overlap (abfd));
    }

  /* All other sections should not need relocation.  */

  return offsets;
}

/* Implement the "solib_create_inferior_hook" target_so_ops method.  */

static void
solib_aix_solib_create_inferior_hook (int from_tty)
{
  const char *warning_msg = "unable to relocate main executable";

  /* We need to relocate the main executable...  */

  gdb::optional<std::vector<lm_info_aix>> &library_list
    = solib_aix_get_library_list (current_inferior (), warning_msg);
  if (!library_list.has_value ())
    return;  /* Warning already printed.  */

  if (library_list->empty ())
    {
      warning (_("unable to relocate main executable (no info from loader)"));
      return;
    }

  lm_info_aix &exec_info = (*library_list)[0];
  if (current_program_space->symfile_object_file != NULL)
    {
      objfile *objf = current_program_space->symfile_object_file;
      section_offsets offsets = solib_aix_get_section_offsets (objf,
							       &exec_info);

      objfile_relocate (objf, offsets);
    }
}

/* Implement the "current_sos" target_so_ops method.  */

static struct so_list *
solib_aix_current_sos (void)
{
  struct so_list *start = NULL, *last = NULL;
  int ix;

  gdb::optional<std::vector<lm_info_aix>> &library_list
    = solib_aix_get_library_list (current_inferior (), NULL);
  if (!library_list.has_value ())
    return NULL;

  /* Build a struct so_list for each entry on the list.
     We skip the first entry, since this is the entry corresponding
     to the main executable, not a shared library.  */
  for (ix = 1; ix < library_list->size (); ix++)
    {
      struct so_list *new_solib = XCNEW (struct so_list);
      std::string so_name;

      lm_info_aix &info = (*library_list)[ix];
      if (info.member_name.empty ())
	{
	 /* INFO.FILENAME is probably not an archive, but rather
	    a shared object.  Unusual, but it should be possible
	    to link a program against a shared object directory,
	    without having to put it in an archive first.  */
	 so_name = info.filename;
	}
      else
	{
	 /* This is the usual case on AIX, where the shared object
	    is a member of an archive.  Create a synthetic so_name
	    that follows the same convention as AIX's ldd tool
	    (Eg: "/lib/libc.a(shr.o)").  */
	 so_name = string_printf ("%s(%s)", info.filename.c_str (),
				  info.member_name.c_str ());
	}
      strncpy (new_solib->so_original_name, so_name.c_str (),
	       SO_NAME_MAX_PATH_SIZE - 1);
      new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
      memcpy (new_solib->so_name, new_solib->so_original_name,
	      SO_NAME_MAX_PATH_SIZE);
      new_solib->lm_info = new lm_info_aix (info);

      /* Add it to the list.  */
      if (!start)
	last = start = new_solib;
      else
	{
	  last->next = new_solib;
	  last = new_solib;
	}
    }

  return start;
}

/* Implement the "open_symbol_file_object" target_so_ops method.  */

static int
solib_aix_open_symbol_file_object (int from_tty)
{
  return 0;
}

/* Implement the "in_dynsym_resolve_code" target_so_ops method.  */

static int
solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
{
  return 0;
}

/* Implement the "bfd_open" target_so_ops method.  */

static gdb_bfd_ref_ptr
solib_aix_bfd_open (const char *pathname)
{
  /* The pathname is actually a synthetic filename with the following
     form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
     split this into archive name and member name.

     FIXME: This is a little hacky.  Perhaps we should provide access
     to the solib's lm_info here?  */
  const int path_len = strlen (pathname);
  const char *sep;
  int filename_len;
  int found_file;

  if (pathname[path_len - 1] != ')')
    return solib_bfd_open (pathname);

  /* Search for the associated parens.  */
  sep = strrchr (pathname, '(');
  if (sep == NULL)
    {
      /* Should never happen, but recover as best as we can (trying
	 to open pathname without decoding, possibly leading to
	 a failure), rather than triggering an assert failure).  */
      warning (_("missing '(' in shared object pathname: %s"), pathname);
      return solib_bfd_open (pathname);
    }
  filename_len = sep - pathname;

  std::string filename (string_printf ("%.*s", filename_len, pathname));
  std::string member_name (string_printf ("%.*s", path_len - filename_len - 2,
					  sep + 1));

  /* Calling solib_find makes certain that sysroot path is set properly
     if program has a dependency on .a archive and sysroot is set via
     set sysroot command.  */
  gdb::unique_xmalloc_ptr<char> found_pathname
    = solib_find (filename.c_str (), &found_file);
  if (found_pathname == NULL)
      perror_with_name (pathname);
  gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname.get (),
						found_file));
  if (archive_bfd == NULL)
    {
      warning (_("Could not open `%s' as an executable file: %s"),
	       filename.c_str (), bfd_errmsg (bfd_get_error ()));
      return NULL;
    }

  if (bfd_check_format (archive_bfd.get (), bfd_object))
    return archive_bfd;

  if (! bfd_check_format (archive_bfd.get (), bfd_archive))
    {
      warning (_("\"%s\": not in executable format: %s."),
	       filename.c_str (), bfd_errmsg (bfd_get_error ()));
      return NULL;
    }

  gdb_bfd_ref_ptr object_bfd
    (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));
  while (object_bfd != NULL)
    {
      if (member_name == bfd_get_filename (object_bfd.get ()))
	break;

      object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
						     object_bfd.get ());
    }

  if (object_bfd == NULL)
    {
      warning (_("\"%s\": member \"%s\" missing."), filename.c_str (),
	       member_name.c_str ());
      return NULL;
    }

  if (! bfd_check_format (object_bfd.get (), bfd_object))
    {
      warning (_("%s(%s): not in object format: %s."),
	       filename.c_str (), member_name.c_str (),
	       bfd_errmsg (bfd_get_error ()));
      return NULL;
    }

  /* Override the returned bfd's name with the name returned from solib_find
     along with appended parenthesized member name in order to allow commands
     listing all shared libraries to display.  Otherwise, we would only be
     displaying the name of the archive member object.  */
  std::string fname = string_printf ("%s%s",
				     bfd_get_filename (archive_bfd.get ()),
				     sep);
  bfd_set_filename (object_bfd.get (), fname.c_str ());

  return object_bfd;
}

/* Return the obj_section corresponding to OBJFILE's data section,
   or NULL if not found.  */
/* FIXME: Define in a more general location? */

static struct obj_section *
data_obj_section_from_objfile (struct objfile *objfile)
{
  struct obj_section *osect;

  ALL_OBJFILE_OSECTIONS (objfile, osect)
    if (strcmp (bfd_section_name (osect->the_bfd_section), ".data") == 0)
      return osect;

  return NULL;
}

/* Return the TOC value corresponding to the given PC address,
   or raise an error if the value could not be determined.  */

CORE_ADDR
solib_aix_get_toc_value (CORE_ADDR pc)
{
  struct obj_section *pc_osect = find_pc_section (pc);
  struct obj_section *data_osect;
  CORE_ADDR result;

  if (pc_osect == NULL)
    error (_("unable to find TOC entry for pc %s "
	     "(no section contains this PC)"),
	   core_addr_to_string (pc));

  data_osect = data_obj_section_from_objfile (pc_osect->objfile);
  if (data_osect == NULL)
    error (_("unable to find TOC entry for pc %s "
	     "(%s has no data section)"),
	   core_addr_to_string (pc), objfile_name (pc_osect->objfile));

  result = data_osect->addr () + xcoff_get_toc_offset (pc_osect->objfile);

  solib_aix_debug_printf ("pc=%s -> %s", core_addr_to_string (pc),
			  core_addr_to_string (result));

  return result;
}

/* This module's normal_stop observer.  */

static void
solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2)
{
  struct solib_aix_inferior_data *data
    = get_solib_aix_inferior_data (current_inferior ());

  /* The inferior execution has been resumed, and it just stopped
     again.  This means that the list of shared libraries may have
     evolved.  Reset our cached value.  */
  data->library_list.reset ();
}

/* Implements the "show debug aix-solib" command.  */

static void
show_solib_aix_debug (struct ui_file *file, int from_tty,
		      struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value);
}

/* The target_so_ops for AIX targets.  */
struct target_so_ops solib_aix_so_ops;

void _initialize_solib_aix ();
void
_initialize_solib_aix ()
{
  solib_aix_so_ops.relocate_section_addresses
    = solib_aix_relocate_section_addresses;
  solib_aix_so_ops.free_so = solib_aix_free_so;
  solib_aix_so_ops.clear_solib = solib_aix_clear_solib;
  solib_aix_so_ops.solib_create_inferior_hook
    = solib_aix_solib_create_inferior_hook;
  solib_aix_so_ops.current_sos = solib_aix_current_sos;
  solib_aix_so_ops.open_symbol_file_object
    = solib_aix_open_symbol_file_object;
  solib_aix_so_ops.in_dynsym_resolve_code
    = solib_aix_in_dynsym_resolve_code;
  solib_aix_so_ops.bfd_open = solib_aix_bfd_open;

  gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer,
				      "solib-aix");

  /* Debug this file's internals.  */
  add_setshow_boolean_cmd ("aix-solib", class_maintenance,
			   &solib_aix_debug, _("\
Control the debugging traces for the solib-aix module."), _("\
Show whether solib-aix debugging traces are enabled."), _("\
When on, solib-aix debugging traces are enabled."),
			    NULL,
			    show_solib_aix_debug,
			    &setdebuglist, &showdebuglist);
}
