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

/* Our private data in struct solib.  */

struct lm_info_aix final : public lm_info
{
  /* 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.  */
  std::optional<std::vector<lm_info_aix>> library_list;
};

/* Key to our per-inferior data.  */
static const registry<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 std::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 std::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 std::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;

  std::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_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" solib_ops method.  */

static void
solib_aix_relocate_section_addresses (solib &so, 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);
  auto *info = gdb::checked_static_cast<lm_info_aix *> (so.lm_info.get ());

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

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

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

  /* .text */

  if (objfile->sect_index_text != -1)
    {
      struct bfd_section *sect
	= objfile->sections_start[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_start[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" solib_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...  */

  std::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" solib_ops method.  */

static owning_intrusive_list<solib>
solib_aix_current_sos ()
{
  std::optional<std::vector<lm_info_aix>> &library_list
    = solib_aix_get_library_list (current_inferior (), NULL);
  if (!library_list.has_value ())
    return {};

  owning_intrusive_list<solib> sos;

  /* Build a struct solib 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 (int ix = 1; ix < library_list->size (); ix++)
    {
      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 ());
	}

      /* Add it to the list.  */
      auto &new_solib = sos.emplace_back ();
      new_solib.original_name = so_name;
      new_solib.name = so_name;
      new_solib.lm_info = std::make_unique<lm_info_aix> (info);
    }

  return sos;
}

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

static bool
solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
{
  return false;
}

/* Implement the "bfd_open" solib_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;

      std::string s = bfd_get_filename (object_bfd.get ());

      /* For every inferior after first int bfd system we
	 will have the pathname instead of the member name
	 registered. Hence the below condition exists.  */

      if (s.find ('(') != std::string::npos)
	{
	  int pos = s.find ('(');
	  int len = s.find (')') - s.find ('(');
	  if (s.substr (pos+1, len-1) == member_name)
	    return object_bfd;
	}

      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)
{
  for (obj_section *osect : objfile->sections ())
    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_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 bpstat *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 ();
}

/* The solib_ops for AIX targets.  */
const solib_ops solib_aix_so_ops =
{
  solib_aix_relocate_section_addresses,
  nullptr,
  nullptr,
  solib_aix_solib_create_inferior_hook,
  solib_aix_current_sos,
  nullptr,
  solib_aix_in_dynsym_resolve_code,
  solib_aix_bfd_open,
  nullptr,
  nullptr,
  nullptr,
  nullptr,
  default_find_solib_addr,
};

void _initialize_solib_aix ();
void
_initialize_solib_aix ()
{
  gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer,
				      "solib-aix");
}
