/* Auxiliary vector support for GDB, the GNU debugger.

   Copyright (C) 2004-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 "target.h"
#include "gdbtypes.h"
#include "command.h"
#include "inferior.h"
#include "valprint.h"
#include "gdbcore.h"
#include "observable.h"
#include "gdbsupport/filestuff.h"
#include "objfiles.h"

#include "auxv.h"
#include "elf/common.h"

#include <unistd.h>
#include <fcntl.h>


/* Implement the to_xfer_partial target_ops method.  This function
   handles access via /proc/PID/auxv, which is a common method for
   native targets.  */

static enum target_xfer_status
procfs_xfer_auxv (gdb_byte *readbuf,
		  const gdb_byte *writebuf,
		  ULONGEST offset,
		  ULONGEST len,
		  ULONGEST *xfered_len)
{
  int fd;
  ssize_t l;

  std::string pathname = string_printf ("/proc/%d/auxv", inferior_ptid.pid ());
  fd = gdb_open_cloexec (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY, 0);
  if (fd < 0)
    return TARGET_XFER_E_IO;

  if (offset != (ULONGEST) 0
      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
    l = -1;
  else if (readbuf != NULL)
    l = read (fd, readbuf, (size_t) len);
  else
    l = write (fd, writebuf, (size_t) len);

  (void) close (fd);

  if (l < 0)
    return TARGET_XFER_E_IO;
  else if (l == 0)
    return TARGET_XFER_EOF;
  else
    {
      *xfered_len = (ULONGEST) l;
      return TARGET_XFER_OK;
    }
}

/* This function handles access via ld.so's symbol `_dl_auxv'.  */

static enum target_xfer_status
ld_so_xfer_auxv (gdb_byte *readbuf,
		 const gdb_byte *writebuf,
		 ULONGEST offset,
		 ULONGEST len, ULONGEST *xfered_len)
{
  struct bound_minimal_symbol msym;
  CORE_ADDR data_address, pointer_address;
  struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
  size_t ptr_size = TYPE_LENGTH (ptr_type);
  size_t auxv_pair_size = 2 * ptr_size;
  gdb_byte *ptr_buf = (gdb_byte *) alloca (ptr_size);
  LONGEST retval;
  size_t block;

  msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL);
  if (msym.minsym == NULL)
    return TARGET_XFER_E_IO;

  if (MSYMBOL_SIZE (msym.minsym) != ptr_size)
    return TARGET_XFER_E_IO;

  /* POINTER_ADDRESS is a location where the `_dl_auxv' variable
     resides.  DATA_ADDRESS is the inferior value present in
     `_dl_auxv', therefore the real inferior AUXV address.  */

  pointer_address = BMSYMBOL_VALUE_ADDRESS (msym);

  /* The location of the _dl_auxv symbol may no longer be correct if
     ld.so runs at a different address than the one present in the
     file.  This is very common case - for unprelinked ld.so or with a
     PIE executable.  PIE executable forces random address even for
     libraries already being prelinked to some address.  PIE
     executables themselves are never prelinked even on prelinked
     systems.  Prelinking of a PIE executable would block their
     purpose of randomizing load of everything including the
     executable.

     If the memory read fails, return -1 to fallback on another
     mechanism for retrieving the AUXV.

     In most cases of a PIE running under valgrind there is no way to
     find out the base addresses of any of ld.so, executable or AUXV
     as everything is randomized and /proc information is not relevant
     for the virtual executable running under valgrind.  We think that
     we might need a valgrind extension to make it work.  This is PR
     11440.  */

  if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0)
    return TARGET_XFER_E_IO;

  data_address = extract_typed_address (ptr_buf, ptr_type);

  /* Possibly still not initialized such as during an inferior
     startup.  */
  if (data_address == 0)
    return TARGET_XFER_E_IO;

  data_address += offset;

  if (writebuf != NULL)
    {
      if (target_write_memory (data_address, writebuf, len) == 0)
	{
	  *xfered_len = (ULONGEST) len;
	  return TARGET_XFER_OK;
	}
      else
	return TARGET_XFER_E_IO;
    }

  /* Stop if trying to read past the existing AUXV block.  The final
     AT_NULL was already returned before.  */

  if (offset >= auxv_pair_size)
    {
      if (target_read_memory (data_address - auxv_pair_size, ptr_buf,
			      ptr_size) != 0)
	return TARGET_XFER_E_IO;

      if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL)
	return TARGET_XFER_EOF;
    }

  retval = 0;
  block = 0x400;
  gdb_assert (block % auxv_pair_size == 0);

  while (len > 0)
    {
      if (block > len)
	block = len;

      /* Reading sizes smaller than AUXV_PAIR_SIZE is not supported.
	 Tails unaligned to AUXV_PAIR_SIZE will not be read during a
	 call (they should be completed during next read with
	 new/extended buffer).  */

      block &= -auxv_pair_size;
      if (block == 0)
	break;

      if (target_read_memory (data_address, readbuf, block) != 0)
	{
	  if (block <= auxv_pair_size)
	    break;

	  block = auxv_pair_size;
	  continue;
	}

      data_address += block;
      len -= block;

      /* Check terminal AT_NULL.  This function is being called
         indefinitely being extended its READBUF until it returns EOF
         (0).  */

      while (block >= auxv_pair_size)
	{
	  retval += auxv_pair_size;

	  if (extract_typed_address (readbuf, ptr_type) == AT_NULL)
	    {
	      *xfered_len = (ULONGEST) retval;
	      return TARGET_XFER_OK;
	    }

	  readbuf += auxv_pair_size;
	  block -= auxv_pair_size;
	}
    }

  *xfered_len = (ULONGEST) retval;
  return TARGET_XFER_OK;
}

/* Implement the to_xfer_partial target_ops method for
   TARGET_OBJECT_AUXV.  It handles access to AUXV.  */

enum target_xfer_status
memory_xfer_auxv (struct target_ops *ops,
		  enum target_object object,
		  const char *annex,
		  gdb_byte *readbuf,
		  const gdb_byte *writebuf,
		  ULONGEST offset,
		  ULONGEST len, ULONGEST *xfered_len)
{
  gdb_assert (object == TARGET_OBJECT_AUXV);
  gdb_assert (readbuf || writebuf);

   /* ld_so_xfer_auxv is the only function safe for virtual
      executables being executed by valgrind's memcheck.  Using
      ld_so_xfer_auxv during inferior startup is problematic, because
      ld.so symbol tables have not yet been relocated.  So GDB uses
      this function only when attaching to a process.
      */

  if (current_inferior ()->attach_flag != 0)
    {
      enum target_xfer_status ret;

      ret = ld_so_xfer_auxv (readbuf, writebuf, offset, len, xfered_len);
      if (ret != TARGET_XFER_E_IO)
	return ret;
    }

  return procfs_xfer_auxv (readbuf, writebuf, offset, len, xfered_len);
}

/* This function compared to other auxv_parse functions: it takes the size of
   the auxv type field as a parameter.  */

static int
generic_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr,
		    gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp,
		    int sizeof_auxv_type)
{
  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
  const int sizeof_auxv_val = TYPE_LENGTH (ptr_type);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte *ptr = *readptr;

  if (endptr == ptr)
    return 0;

  if (endptr - ptr < 2 * sizeof_auxv_val)
    return -1;

  *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order);
  /* Even if the auxv type takes less space than an auxv value, there is
     padding after the type such that the value is aligned on a multiple of
     its size (and this is why we advance by `sizeof_auxv_val` and not
     `sizeof_auxv_type`).  */
  ptr += sizeof_auxv_val;
  *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order);
  ptr += sizeof_auxv_val;

  *readptr = ptr;
  return 1;
}

/* See auxv.h.  */

int
default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
		    gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
{
  struct gdbarch *gdbarch = target_gdbarch ();
  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
  const int sizeof_auxv_type = TYPE_LENGTH (ptr_type);

  return generic_auxv_parse (gdbarch, readptr, endptr, typep, valp,
			     sizeof_auxv_type);
}

/* See auxv.h.  */

int
svr4_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr,
		 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
{
  struct type *int_type = builtin_type (gdbarch)->builtin_int;
  const int sizeof_auxv_type = TYPE_LENGTH (int_type);

  return generic_auxv_parse (gdbarch, readptr, endptr, typep, valp,
			     sizeof_auxv_type);
}

/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
   Return 0 if *READPTR is already at the end of the buffer.
   Return -1 if there is insufficient buffer for a whole entry.
   Return 1 if an entry was read into *TYPEP and *VALP.  */
int
target_auxv_parse (gdb_byte **readptr,
		   gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
{
  struct gdbarch *gdbarch = target_gdbarch();

  if (gdbarch_auxv_parse_p (gdbarch))
    return gdbarch_auxv_parse (gdbarch, readptr, endptr, typep, valp);

  return current_top_target ()->auxv_parse (readptr, endptr, typep, valp);
}


/*  Auxiliary Vector information structure.  This is used by GDB
    for caching purposes for each inferior.  This helps reduce the
    overhead of transfering data from a remote target to the local host.  */
struct auxv_info
{
  gdb::optional<gdb::byte_vector> data;
};

/* Per-inferior data key for auxv.  */
static const struct inferior_key<auxv_info> auxv_inferior_data;

/* Invalidate INF's auxv cache.  */

static void
invalidate_auxv_cache_inf (struct inferior *inf)
{
  auxv_inferior_data.clear (inf);
}

/* Invalidate current inferior's auxv cache.  */

static void
invalidate_auxv_cache (void)
{
  invalidate_auxv_cache_inf (current_inferior ());
}

/* Fetch the auxv object from inferior INF.  If auxv is cached already,
   return a pointer to the cache.  If not, fetch the auxv object from the
   target and cache it.  This function always returns a valid INFO pointer.  */

static struct auxv_info *
get_auxv_inferior_data (struct target_ops *ops)
{
  struct auxv_info *info;
  struct inferior *inf = current_inferior ();

  info = auxv_inferior_data.get (inf);
  if (info == NULL)
    {
      info = auxv_inferior_data.emplace (inf);
      info->data = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL);
    }

  return info;
}

/* Extract the auxiliary vector entry with a_type matching MATCH.
   Return zero if no such entry was found, or -1 if there was
   an error getting the information.  On success, return 1 after
   storing the entry's value field in *VALP.  */
int
target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
{
  CORE_ADDR type, val;
  auxv_info *info = get_auxv_inferior_data (ops);

  if (!info->data)
    return -1;

  gdb_byte *data = info->data->data ();
  gdb_byte *ptr = data;
  size_t len = info->data->size ();

  while (1)
    switch (target_auxv_parse (&ptr, data + len, &type, &val))
      {
      case 1:			/* Here's an entry, check it.  */
	if (type == match)
	  {
	    *valp = val;
	    return 1;
	  }
	break;
      case 0:			/* End of the vector.  */
	return 0;
      default:			/* Bogosity.  */
	return -1;
      }

  /*NOTREACHED*/
}


/* Print the description of a single AUXV entry on the specified file.  */

void
fprint_auxv_entry (struct ui_file *file, const char *name,
		   const char *description, enum auxv_format format,
		   CORE_ADDR type, CORE_ADDR val)
{
  fprintf_filtered (file, ("%-4s %-20s %-30s "),
		    plongest (type), name, description);
  switch (format)
    {
    case AUXV_FORMAT_DEC:
      fprintf_filtered (file, ("%s\n"), plongest (val));
      break;
    case AUXV_FORMAT_HEX:
      fprintf_filtered (file, ("%s\n"), paddress (target_gdbarch (), val));
      break;
    case AUXV_FORMAT_STR:
      {
	struct value_print_options opts;

	get_user_print_options (&opts);
	if (opts.addressprint)
	  fprintf_filtered (file, ("%s "), paddress (target_gdbarch (), val));
	val_print_string (builtin_type (target_gdbarch ())->builtin_char,
			  NULL, val, -1, file, &opts);
	fprintf_filtered (file, ("\n"));
      }
      break;
    }
}

/* The default implementation of gdbarch_print_auxv_entry.  */

void
default_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
			  CORE_ADDR type, CORE_ADDR val)
{
  const char *name = "???";
  const char *description = "";
  enum auxv_format format = AUXV_FORMAT_HEX;

  switch (type)
    {
#define TAG(tag, text, kind) \
      case tag: name = #tag; description = text; format = kind; break
      TAG (AT_NULL, _("End of vector"), AUXV_FORMAT_HEX);
      TAG (AT_IGNORE, _("Entry should be ignored"), AUXV_FORMAT_HEX);
      TAG (AT_EXECFD, _("File descriptor of program"), AUXV_FORMAT_DEC);
      TAG (AT_PHDR, _("Program headers for program"), AUXV_FORMAT_HEX);
      TAG (AT_PHENT, _("Size of program header entry"), AUXV_FORMAT_DEC);
      TAG (AT_PHNUM, _("Number of program headers"), AUXV_FORMAT_DEC);
      TAG (AT_PAGESZ, _("System page size"), AUXV_FORMAT_DEC);
      TAG (AT_BASE, _("Base address of interpreter"), AUXV_FORMAT_HEX);
      TAG (AT_FLAGS, _("Flags"), AUXV_FORMAT_HEX);
      TAG (AT_ENTRY, _("Entry point of program"), AUXV_FORMAT_HEX);
      TAG (AT_NOTELF, _("Program is not ELF"), AUXV_FORMAT_DEC);
      TAG (AT_UID, _("Real user ID"), AUXV_FORMAT_DEC);
      TAG (AT_EUID, _("Effective user ID"), AUXV_FORMAT_DEC);
      TAG (AT_GID, _("Real group ID"), AUXV_FORMAT_DEC);
      TAG (AT_EGID, _("Effective group ID"), AUXV_FORMAT_DEC);
      TAG (AT_CLKTCK, _("Frequency of times()"), AUXV_FORMAT_DEC);
      TAG (AT_PLATFORM, _("String identifying platform"), AUXV_FORMAT_STR);
      TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"),
	   AUXV_FORMAT_HEX);
      TAG (AT_FPUCW, _("Used FPU control word"), AUXV_FORMAT_DEC);
      TAG (AT_DCACHEBSIZE, _("Data cache block size"), AUXV_FORMAT_DEC);
      TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), AUXV_FORMAT_DEC);
      TAG (AT_UCACHEBSIZE, _("Unified cache block size"), AUXV_FORMAT_DEC);
      TAG (AT_IGNOREPPC, _("Entry should be ignored"), AUXV_FORMAT_DEC);
      TAG (AT_BASE_PLATFORM, _("String identifying base platform"),
	   AUXV_FORMAT_STR);
      TAG (AT_RANDOM, _("Address of 16 random bytes"), AUXV_FORMAT_HEX);
      TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX);
      TAG (AT_EXECFN, _("File name of executable"), AUXV_FORMAT_STR);
      TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), AUXV_FORMAT_DEC);
      TAG (AT_SYSINFO, _("Special system info/entry points"), AUXV_FORMAT_HEX);
      TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"),
	   AUXV_FORMAT_HEX);
      TAG (AT_L1I_CACHESHAPE, _("L1 Instruction cache information"),
	   AUXV_FORMAT_HEX);
      TAG (AT_L1I_CACHESIZE, _("L1 Instruction cache size"), AUXV_FORMAT_HEX);
      TAG (AT_L1I_CACHEGEOMETRY, _("L1 Instruction cache geometry"),
	   AUXV_FORMAT_HEX);
      TAG (AT_L1D_CACHESHAPE, _("L1 Data cache information"), AUXV_FORMAT_HEX);
      TAG (AT_L1D_CACHESIZE, _("L1 Data cache size"), AUXV_FORMAT_HEX);
      TAG (AT_L1D_CACHEGEOMETRY, _("L1 Data cache geometry"),
	   AUXV_FORMAT_HEX);
      TAG (AT_L2_CACHESHAPE, _("L2 cache information"), AUXV_FORMAT_HEX);
      TAG (AT_L2_CACHESIZE, _("L2 cache size"), AUXV_FORMAT_HEX);
      TAG (AT_L2_CACHEGEOMETRY, _("L2 cache geometry"), AUXV_FORMAT_HEX);
      TAG (AT_L3_CACHESHAPE, _("L3 cache information"), AUXV_FORMAT_HEX);
      TAG (AT_L3_CACHESIZE, _("L3 cache size"), AUXV_FORMAT_HEX);
      TAG (AT_L3_CACHEGEOMETRY, _("L3 cache geometry"), AUXV_FORMAT_HEX);
      TAG (AT_MINSIGSTKSZ, _("Minimum stack size for signal delivery"),
	   AUXV_FORMAT_HEX);
      TAG (AT_SUN_UID, _("Effective user ID"), AUXV_FORMAT_DEC);
      TAG (AT_SUN_RUID, _("Real user ID"), AUXV_FORMAT_DEC);
      TAG (AT_SUN_GID, _("Effective group ID"), AUXV_FORMAT_DEC);
      TAG (AT_SUN_RGID, _("Real group ID"), AUXV_FORMAT_DEC);
      TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), AUXV_FORMAT_HEX);
      TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"),
	   AUXV_FORMAT_HEX);
      TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"),
	   AUXV_FORMAT_STR);
      TAG (AT_SUN_LPAGESZ, _("Large pagesize"), AUXV_FORMAT_DEC);
      TAG (AT_SUN_PLATFORM, _("Platform name string"), AUXV_FORMAT_STR);
      TAG (AT_SUN_CAP_HW1, _("Machine-dependent CPU capability hints"),
	   AUXV_FORMAT_HEX);
      TAG (AT_SUN_IFLUSH, _("Should flush icache?"), AUXV_FORMAT_DEC);
      TAG (AT_SUN_CPU, _("CPU name string"), AUXV_FORMAT_STR);
      TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), AUXV_FORMAT_HEX);
      TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"),
	   AUXV_FORMAT_DEC);
      TAG (AT_SUN_EXECNAME,
	   _("Canonicalized file name given to execve"), AUXV_FORMAT_STR);
      TAG (AT_SUN_MMU, _("String for name of MMU module"), AUXV_FORMAT_STR);
      TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"),
	   AUXV_FORMAT_HEX);
      TAG (AT_SUN_AUXFLAGS,
	   _("AF_SUN_ flags passed from the kernel"), AUXV_FORMAT_HEX);
      TAG (AT_SUN_EMULATOR, _("Name of emulation binary for runtime linker"),
	   AUXV_FORMAT_STR);
      TAG (AT_SUN_BRANDNAME, _("Name of brand library"), AUXV_FORMAT_STR);
      TAG (AT_SUN_BRAND_AUX1, _("Aux vector for brand modules 1"),
	   AUXV_FORMAT_HEX);
      TAG (AT_SUN_BRAND_AUX2, _("Aux vector for brand modules 2"),
	   AUXV_FORMAT_HEX);
      TAG (AT_SUN_BRAND_AUX3, _("Aux vector for brand modules 3"),
	   AUXV_FORMAT_HEX);
      TAG (AT_SUN_CAP_HW2, _("Machine-dependent CPU capability hints 2"),
	   AUXV_FORMAT_HEX);
    }

  fprint_auxv_entry (file, name, description, format, type, val);
}

/* Print the contents of the target's AUXV on the specified file.  */

int
fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
{
  struct gdbarch *gdbarch = target_gdbarch ();
  CORE_ADDR type, val;
  int ents = 0;
  auxv_info *info = get_auxv_inferior_data (ops);

  if (!info->data)
    return -1;

  gdb_byte *data = info->data->data ();
  gdb_byte *ptr = data;
  size_t len = info->data->size ();

  while (target_auxv_parse (&ptr, data + len, &type, &val) > 0)
    {
      gdbarch_print_auxv_entry (gdbarch, file, type, val);
      ++ents;
      if (type == AT_NULL)
	break;
    }

  return ents;
}

static void
info_auxv_command (const char *cmd, int from_tty)
{
  if (! target_has_stack)
    error (_("The program has no auxiliary information now."));
  else
    {
      int ents = fprint_target_auxv (gdb_stdout, current_top_target ());

      if (ents < 0)
	error (_("No auxiliary vector found, or failed reading it."));
      else if (ents == 0)
	error (_("Auxiliary vector is empty."));
    }
}

void _initialize_auxv ();
void
_initialize_auxv ()
{
  add_info ("auxv", info_auxv_command,
	    _("Display the inferior's auxiliary vector.\n\
This is information provided by the operating system at program startup."));

  /* Observers used to invalidate the auxv cache when needed.  */
  gdb::observers::inferior_exit.attach (invalidate_auxv_cache_inf);
  gdb::observers::inferior_appeared.attach (invalidate_auxv_cache_inf);
  gdb::observers::executable_changed.attach (invalidate_auxv_cache);
}
