/* Standard libdwfl callbacks for debugging a live Linux process.
   Copyright (C) 2005-2010, 2013, 2014 Red Hat, Inc.
   This file is part of elfutils.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at
       your option) any later version

   or both in parallel, as here.

   elfutils 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 copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

#include "libdwflP.h"
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <endian.h>
#include "system.h"


#define PROCMAPSFMT	"/proc/%d/maps"
#define PROCMEMFMT	"/proc/%d/mem"
#define PROCAUXVFMT	"/proc/%d/auxv"
#define PROCEXEFMT	"/proc/%d/exe"


/* Return ELFCLASS64 or ELFCLASS32 for the main ELF executable.  Return
   ELFCLASSNONE for an error.  */

static unsigned char
get_pid_class (pid_t pid)
{
  char *fname;
  if (asprintf (&fname, PROCEXEFMT, pid) < 0)
    return ELFCLASSNONE;

  int fd = open64 (fname, O_RDONLY);
  free (fname);
  if (fd < 0)
    return ELFCLASSNONE;

  unsigned char buf[EI_CLASS + 1];
  ssize_t nread = pread_retry (fd, &buf, sizeof buf, 0);
  close (fd);
  if (nread != sizeof buf || buf[EI_MAG0] != ELFMAG0
      || buf[EI_MAG1] != ELFMAG1 || buf[EI_MAG2] != ELFMAG2
      || buf[EI_MAG3] != ELFMAG3
      || (buf[EI_CLASS] != ELFCLASS64 && buf[EI_CLASS] != ELFCLASS32))
    return ELFCLASSNONE;

  return buf[EI_CLASS];
}

/* Search /proc/PID/auxv for the AT_SYSINFO_EHDR tag.

   It would be easiest to call get_pid_class and parse everything according to
   the 32-bit or 64-bit class.  But this would bring the overhead of syscalls
   to open and read the "/proc/%d/exe" file.

   Therefore this function tries to parse the "/proc/%d/auxv" content both
   ways, as if it were the 32-bit format and also if it were the 64-bit format.
   Only if it gives some valid data in both cases get_pid_class gets called.
   In most cases only one of the format bit sizes gives valid data and the
   get_pid_class call overhead can be saved.  */

static int
grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr)
{
  char *fname;
  if (asprintf (&fname, PROCAUXVFMT, pid) < 0)
    return ENOMEM;

  int fd = open64 (fname, O_RDONLY);
  free (fname);
  if (fd < 0)
    return errno == ENOENT ? 0 : errno;

  GElf_Addr sysinfo_ehdr64 = 0;
  GElf_Addr sysinfo_ehdr32 = 0;
  GElf_Addr segment_align64 = dwfl->segment_align;
  GElf_Addr segment_align32 = dwfl->segment_align;
  off_t offset = 0;
  ssize_t nread;
  union
  {
    Elf64_auxv_t a64[64];
    Elf32_auxv_t a32[128];
  } d;
  do
    {
      eu_static_assert (sizeof d.a64 == sizeof d.a32);
      nread = pread_retry (fd, d.a64, sizeof d.a64, offset);
      if (nread < 0)
	{
	  int ret = errno;
	  close (fd);
	  return ret;
	}
      for (size_t a32i = 0; a32i < nread / sizeof d.a32[0]; a32i++)
	{
	  const Elf32_auxv_t *a32 = d.a32 + a32i;
	  switch (a32->a_type)
	  {
	    case AT_SYSINFO_EHDR:
	      sysinfo_ehdr32 = a32->a_un.a_val;
	      break;
	    case AT_PAGESZ:
	      segment_align32 = a32->a_un.a_val;
	      break;
	  }
	}
      for (size_t a64i = 0; a64i < nread / sizeof d.a64[0]; a64i++)
	{
	  const Elf64_auxv_t *a64 = d.a64 + a64i;
	  switch (a64->a_type)
	  {
	    case AT_SYSINFO_EHDR:
	      sysinfo_ehdr64 = a64->a_un.a_val;
	      break;
	    case AT_PAGESZ:
	      segment_align64 = a64->a_un.a_val;
	      break;
	  }
	}
      offset += nread;
    }
  while (nread == sizeof d.a64);

  close (fd);

  bool valid64 = sysinfo_ehdr64 != 0 || segment_align64 != dwfl->segment_align;
  bool valid32 = sysinfo_ehdr32 != 0 || segment_align32 != dwfl->segment_align;

  unsigned char pid_class = ELFCLASSNONE;
  if (valid64 && valid32)
    pid_class = get_pid_class (pid);

  if (pid_class == ELFCLASS64 || (valid64 && ! valid32))
    {
      *sysinfo_ehdr = sysinfo_ehdr64;
      dwfl->segment_align = segment_align64;
      return 0;
    }
  if (pid_class == ELFCLASS32 || (! valid64 && valid32))
    {
      *sysinfo_ehdr = sysinfo_ehdr32;
      dwfl->segment_align = segment_align32;
      return 0;
    }
  return ENOEXEC;
}

static int
proc_maps_report (Dwfl *dwfl, FILE *f, GElf_Addr sysinfo_ehdr, pid_t pid)
{
  unsigned int last_dmajor = -1, last_dminor = -1;
  uint64_t last_ino = -1;
  char *last_file = NULL;
  Dwarf_Addr low = 0, high = 0;

  inline bool report (void)
    {
      if (last_file != NULL)
	{
	  Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, last_file,
							 low, high);
	  free (last_file);
	  last_file = NULL;
	  if (unlikely (mod == NULL))
	    return true;
	}
      return false;
    }

  char *line = NULL;
  size_t linesz;
  ssize_t len;
  while ((len = getline (&line, &linesz, f)) > 0)
    {
      if (line[len - 1] == '\n')
	line[len - 1] = '\0';

      Dwarf_Addr start, end, offset;
      unsigned int dmajor, dminor;
      uint64_t ino;
      int nread = -1;
      if (sscanf (line, "%" PRIx64 "-%" PRIx64 " %*s %" PRIx64
		  " %x:%x %" PRIi64 " %n",
		  &start, &end, &offset, &dmajor, &dminor, &ino, &nread) < 6
	  || nread <= 0)
	{
	  free (line);
	  return ENOEXEC;
	}

      /* If this is the special mapping AT_SYSINFO_EHDR pointed us at,
	 report the last one and then this special one.  */
      if (start == sysinfo_ehdr && start != 0)
	{
	  if (report ())
	    {
	    bad_report:
	      free (line);
	      return -1;
	    }

	  low = start;
	  high = end;
	  if (asprintf (&last_file, "[vdso: %d]", (int) pid) < 0
	      || report ())
	    goto bad_report;
	}

      char *file = line + nread + strspn (line + nread, " \t");
      if (file[0] != '/' || (ino == 0 && dmajor == 0 && dminor == 0))
	/* This line doesn't indicate a file mapping.  */
	continue;

      if (last_file != NULL
	  && ino == last_ino && dmajor == last_dmajor && dminor == last_dminor)
	{
	  /* This is another portion of the same file's mapping.  */
	  if (strcmp (last_file, file) != 0)
	    goto bad_report;
	  high = end;
	}
      else
	{
	  /* This is a different file mapping.  Report the last one.  */
	  if (report ())
	    goto bad_report;
	  low = start;
	  high = end;
	  last_file = strdup (file);
	  last_ino = ino;
	  last_dmajor = dmajor;
	  last_dminor = dminor;
	}
    }
  free (line);

  int result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;

  /* Report the final one.  */
  bool lose = report ();

  return result != 0 ? result : lose ? -1 : 0;
}

int
dwfl_linux_proc_maps_report (Dwfl *dwfl, FILE *f)
{
  return proc_maps_report (dwfl, f, 0, 0);
}
INTDEF (dwfl_linux_proc_maps_report)

int
dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid)
{
  if (dwfl == NULL)
    return -1;

  /* We'll notice the AT_SYSINFO_EHDR address specially when we hit it.  */
  GElf_Addr sysinfo_ehdr = 0;
  int result = grovel_auxv (pid, dwfl, &sysinfo_ehdr);
  if (result != 0)
    return result;

  char *fname;
  if (asprintf (&fname, PROCMAPSFMT, pid) < 0)
    return ENOMEM;

  FILE *f = fopen (fname, "r");
  free (fname);
  if (f == NULL)
    return errno;

  (void) __fsetlocking (f, FSETLOCKING_BYCALLER);

  result = proc_maps_report (dwfl, f, sysinfo_ehdr, pid);

  fclose (f);

  return result;
}
INTDEF (dwfl_linux_proc_report)

static ssize_t
read_proc_memory (void *arg, void *data, GElf_Addr address,
		  size_t minread, size_t maxread)
{
  const int fd = *(const int *) arg;
  ssize_t nread = pread64 (fd, data, maxread, (off64_t) address);
  /* Some kernels don't actually let us do this read, ignore those errors.  */
  if (nread < 0 && (errno == EINVAL || errno == EPERM))
    return 0;
  if (nread > 0 && (size_t) nread < minread)
    nread = 0;
  return nread;
}

extern Elf *elf_from_remote_memory (GElf_Addr ehdr_vma,
				    GElf_Xword pagesize,
				    GElf_Addr *loadbasep,
				    ssize_t (*read_memory) (void *arg,
							    void *data,
							    GElf_Addr address,
							    size_t minread,
							    size_t maxread),
				    void *arg);


/* Dwfl_Callbacks.find_elf */

int
dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)),
			  void **userdata __attribute__ ((unused)),
			  const char *module_name, Dwarf_Addr base,
			  char **file_name, Elf **elfp)
{
  int pid = -1;
  if (module_name[0] == '/')
    {
      /* When this callback is used together with dwfl_linux_proc_report
	 then we might see mappings of special character devices.  Make
	 sure we only open and return regular files.  Special devices
	 might hang on open or read.  (deleted) files are super special.
	 The image might come from memory if we are attached.  */
      struct stat sb;
      if (stat (module_name, &sb) == -1 || (sb.st_mode & S_IFMT) != S_IFREG)
	{
	  if (strcmp (strrchr (module_name, ' ') ?: "", " (deleted)") == 0)
	    pid = INTUSE(dwfl_pid) (mod->dwfl);
	  else
	    return -1;
	}

      if (pid == -1)
	{
	  int fd = open64 (module_name, O_RDONLY);
	  if (fd >= 0)
	    {
	      *file_name = strdup (module_name);
	      if (*file_name == NULL)
		{
		  close (fd);
		  return ENOMEM;
		}
	    }
	  return fd;
	}
    }

  if (pid != -1 || sscanf (module_name, "[vdso: %d]", &pid) == 1)
    {
      /* Special case for in-memory ELF image.  */

      bool detach = false;
      bool tid_was_stopped = false;
      struct __libdwfl_pid_arg *pid_arg = __libdwfl_get_pid_arg (mod->dwfl);
      if (pid_arg != NULL && ! pid_arg->assume_ptrace_stopped)
	{
	  /* If any thread is already attached we are fine.  Read
	     through that thread.  It doesn't have to be the main
	     thread pid.  */
	  pid_t tid = pid_arg->tid_attached;
	  if (tid != 0)
	    pid = tid;
	  else
	    detach = __libdwfl_ptrace_attach (pid, &tid_was_stopped);
	}

      char *fname;
      if (asprintf (&fname, PROCMEMFMT, pid) < 0)
	goto detach;

      int fd = open64 (fname, O_RDONLY);
      free (fname);
      if (fd < 0)
	goto detach;

      *elfp = elf_from_remote_memory (base, getpagesize (), NULL,
				      &read_proc_memory, &fd);

      close (fd);

      *file_name = NULL;

    detach:
      if (detach)
	__libdwfl_ptrace_detach (pid, tid_was_stopped);
      return -1;
    }

  return -1;
}
INTDEF (dwfl_linux_proc_find_elf)
