/* Read and display shared object profiling data.
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <argp.h>
#include <dlfcn.h>
#include <elf.h>
#include <error.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libintl.h>
#include <locale.h>
#include <obstack.h>
#include <search.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <ldsodefs.h>
#include <sys/gmon.h>
#include <sys/gmon_out.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>

/* Get libc version number.  */
#include "../version.h"

#define PACKAGE _libc_intl_domainname


#include <endian.h>
#if BYTE_ORDER == BIG_ENDIAN
# define byteorder ELFDATA2MSB
# define byteorder_name "big-endian"
#elif BYTE_ORDER == LITTLE_ENDIAN
# define byteorder ELFDATA2LSB
# define byteorder_name "little-endian"
#else
# error "Unknown BYTE_ORDER " BYTE_ORDER
# define byteorder ELFDATANONE
#endif

#ifndef PATH_MAX
# define PATH_MAX 1024
#endif


extern int __profile_frequency (void);

/* Name and version of program.  */
static void print_version (FILE *stream, struct argp_state *state);
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;

#define OPT_TEST	1

/* Definitions of arguments for argp functions.  */
static const struct argp_option options[] =
{
  { NULL, 0, NULL, 0, N_("Output selection:") },
  { "call-pairs", 'c', NULL, 0,
    N_("print list of count paths and their number of use") },
  { "flat-profile", 'p', NULL, 0,
    N_("generate flat profile with counts and ticks") },
  { "graph", 'q', NULL, 0, N_("generate call graph") },

  { "test", OPT_TEST, NULL, OPTION_HIDDEN, NULL },
  { NULL, 0, NULL, 0, NULL }
};

/* Short description of program.  */
static const char doc[] = N_("Read and display shared object profiling data.");
//For bug reporting instructions, please see:\n
//<http://www.gnu.org/software/libc/bugs.html>.\n");

/* Strings for arguments in help texts.  */
static const char args_doc[] = N_("SHOBJ [PROFDATA]");

/* Prototype for option handler.  */
static error_t parse_opt (int key, char *arg, struct argp_state *state);

/* Function to print some extra text in the help message.  */
static char *more_help (int key, const char *text, void *input);

/* Data structure to communicate with argp functions.  */
static struct argp argp =
{
  options, parse_opt, args_doc, doc, NULL, more_help
};


/* Operation modes.  */
static enum
{
  NONE = 0,
  FLAT_MODE = 1 << 0,
  CALL_GRAPH_MODE = 1 << 1,
  CALL_PAIRS = 1 << 2,

  DEFAULT_MODE = FLAT_MODE | CALL_GRAPH_MODE
} mode;

/* Nozero for testing.  */
static int do_test;

/* Strcuture describing calls.  */
struct here_fromstruct
{
  struct here_cg_arc_record volatile *here;
  uint16_t link;
};

/* We define a special type to address the elements of the arc table.
   This is basically the `gmon_cg_arc_record' format but it includes
   the room for the tag and it uses real types.  */
struct here_cg_arc_record
{
  uintptr_t from_pc;
  uintptr_t self_pc;
  uint32_t count;
} __attribute__ ((packed));


struct known_symbol;
struct arc_list
{
  size_t idx;
  uintmax_t count;

  struct arc_list *next;
};

static struct obstack ob_list;


struct known_symbol
{
  const char *name;
  uintptr_t addr;
  size_t size;
  bool weak;
  bool hidden;

  uintmax_t ticks;
  uintmax_t calls;

  struct arc_list *froms;
  struct arc_list *tos;
};


struct shobj
{
  const char *name;		/* User-provided name.  */

  struct link_map *map;
  const char *dynstrtab;	/* Dynamic string table of shared object.  */
  const char *soname;		/* Soname of shared object.  */

  uintptr_t lowpc;
  uintptr_t highpc;
  unsigned long int kcountsize;
  size_t expected_size;		/* Expected size of profiling file.  */
  size_t tossize;
  size_t fromssize;
  size_t fromlimit;
  unsigned int hashfraction;
  int s_scale;

  void *symbol_map;
  size_t symbol_mapsize;
  const ElfW(Sym) *symtab;
  size_t symtab_size;
  const char *strtab;

  struct obstack ob_str;
  struct obstack ob_sym;
};


struct real_gmon_hist_hdr
{
  char *low_pc;
  char *high_pc;
  int32_t hist_size;
  int32_t prof_rate;
  char dimen[15];
  char dimen_abbrev;
};


struct profdata
{
  void *addr;
  off_t size;

  char *hist;
  struct real_gmon_hist_hdr *hist_hdr;
  uint16_t *kcount;
  uint32_t narcs;		/* Number of arcs in toset.  */
  struct here_cg_arc_record *data;
  uint16_t *tos;
  struct here_fromstruct *froms;
};

/* Search tree for symbols.  */
static void *symroot;
static struct known_symbol **sortsym;
static size_t symidx;
static uintmax_t total_ticks;

/* Prototypes for local functions.  */
static struct shobj *load_shobj (const char *name);
static void unload_shobj (struct shobj *shobj);
static struct profdata *load_profdata (const char *name, struct shobj *shobj);
static void unload_profdata (struct profdata *profdata);
static void count_total_ticks (struct shobj *shobj, struct profdata *profdata);
static void count_calls (struct shobj *shobj, struct profdata *profdata);
static void read_symbols (struct shobj *shobj);
static void add_arcs (struct profdata *profdata);
static void generate_flat_profile (struct profdata *profdata);
static void generate_call_graph (struct profdata *profdata);
static void generate_call_pair_list (struct profdata *profdata);


int
main (int argc, char *argv[])
{
  const char *shobj;
  const char *profdata;
  struct shobj *shobj_handle;
  struct profdata *profdata_handle;
  int remaining;

  setlocale (LC_ALL, "");

  /* Initialize the message catalog.  */
  textdomain (_libc_intl_domainname);

  /* Parse and process arguments.  */
  argp_parse (&argp, argc, argv, 0, &remaining, NULL);

  if (argc - remaining == 0 || argc - remaining > 2)
    {
      /* We need exactly two non-option parameter.  */
      argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
		 program_invocation_short_name);
      exit (1);
    }

  /* Get parameters.  */
  shobj = argv[remaining];
  if (argc - remaining == 2)
    profdata = argv[remaining + 1];
  else
    /* No filename for the profiling data given.  We will determine it
       from the soname of the shobj, later.  */
    profdata = NULL;

  /* First see whether we can load the shared object.  */
  shobj_handle = load_shobj (shobj);
  if (shobj_handle == NULL)
    exit (1);

  /* We can now determine the filename for the profiling data, if
     nececessary.  */
  if (profdata == NULL)
    {
      char *newp;
      const char *soname;
      size_t soname_len;

      soname = shobj_handle->soname ?: basename (shobj);
      soname_len = strlen (soname);
      newp = (char *) alloca (soname_len + sizeof ".profile");
      stpcpy (mempcpy (newp, soname, soname_len), ".profile");
      profdata = newp;
    }

  /* Now see whether the profiling data file matches the given object.   */
  profdata_handle = load_profdata (profdata, shobj_handle);
  if (profdata_handle == NULL)
    {
      unload_shobj (shobj_handle);

      exit (1);
    }

  read_symbols (shobj_handle);

  /* Count the ticks.  */
  count_total_ticks (shobj_handle, profdata_handle);

  /* Count the calls.  */
  count_calls (shobj_handle, profdata_handle);

  /* Add the arc information.  */
  add_arcs (profdata_handle);

  /* If no mode is specified fall back to the default mode.  */
  if (mode == NONE)
    mode = DEFAULT_MODE;

  /* Do some work.  */
  if (mode & FLAT_MODE)
    generate_flat_profile (profdata_handle);

  if (mode & CALL_GRAPH_MODE)
    generate_call_graph (profdata_handle);

  if (mode & CALL_PAIRS)
    generate_call_pair_list (profdata_handle);

  /* Free the resources.  */
  unload_shobj (shobj_handle);
  unload_profdata (profdata_handle);

  return 0;
}


/* Handle program arguments.  */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
  switch (key)
    {
    case 'c':
      mode |= CALL_PAIRS;
      break;
    case 'p':
      mode |= FLAT_MODE;
      break;
    case 'q':
      mode |= CALL_GRAPH_MODE;
      break;
    case OPT_TEST:
      do_test = 1;
      break;
    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}


static char *
more_help (int key, const char *text, void *input)
{
  char *tp = NULL;
  switch (key)
    {
    case ARGP_KEY_HELP_EXTRA:
      /* We print some extra information.  */
      if (asprintf (&tp, gettext ("\
For bug reporting instructions, please see:\n\
%s.\n"), REPORT_BUGS_TO) < 0)
	return NULL;
      return tp;
    default:
      break;
    }
  return (char *) text;
}


/* Print the version information.  */
static void
print_version (FILE *stream, struct argp_state *state)
{
  fprintf (stream, "sprof %s%s\n", PKGVERSION, VERSION);
  fprintf (stream, gettext ("\
Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"),
	   "2018");
  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
}


/* Note that we must not use `dlopen' etc.  The shobj object must not
   be loaded for use.  */
static struct shobj *
load_shobj (const char *name)
{
  struct link_map *map = NULL;
  struct shobj *result;
  ElfW(Addr) mapstart = ~((ElfW(Addr)) 0);
  ElfW(Addr) mapend = 0;
  const ElfW(Phdr) *ph;
  size_t textsize;
  ElfW(Ehdr) *ehdr;
  int fd;
  ElfW(Shdr) *shdr;
  size_t pagesize = getpagesize ();

  /* Since we use dlopen() we must be prepared to work around the sometimes
     strange lookup rules for the shared objects.  If we have a file foo.so
     in the current directory and the user specfies foo.so on the command
     line (without specifying a directory) we should load the file in the
     current directory even if a normal dlopen() call would read the other
     file.  We do this by adding a directory portion to the name.  */
  if (strchr (name, '/') == NULL)
    {
      char *load_name = (char *) alloca (strlen (name) + 3);
      stpcpy (stpcpy (load_name, "./"), name);

      map = (struct link_map *) dlopen (load_name, RTLD_LAZY | __RTLD_SPROF);
    }
  if (map == NULL)
    {
      map = (struct link_map *) dlopen (name, RTLD_LAZY | __RTLD_SPROF);
      if (map == NULL)
	{
	  error (0, errno, _("failed to load shared object `%s'"), name);
	  return NULL;
	}
    }

  /* Prepare the result.  */
  result = (struct shobj *) calloc (1, sizeof (struct shobj));
  if (result == NULL)
    {
      error (0, errno, _("cannot create internal descriptor"));
      dlclose (map);
      return NULL;
    }
  result->name = name;
  result->map = map;

  /* Compute the size of the sections which contain program code.
     This must match the code in dl-profile.c (_dl_start_profile).  */
  for (ph = map->l_phdr; ph < &map->l_phdr[map->l_phnum]; ++ph)
    if (ph->p_type == PT_LOAD && (ph->p_flags & PF_X))
      {
	ElfW(Addr) start = (ph->p_vaddr & ~(pagesize - 1));
	ElfW(Addr) end = ((ph->p_vaddr + ph->p_memsz + pagesize - 1)
			  & ~(pagesize - 1));

	if (start < mapstart)
	  mapstart = start;
	if (end > mapend)
	  mapend = end;
      }

  result->lowpc = ROUNDDOWN ((uintptr_t) (mapstart + map->l_addr),
			     HISTFRACTION * sizeof (HISTCOUNTER));
  result->highpc = ROUNDUP ((uintptr_t) (mapend + map->l_addr),
			    HISTFRACTION * sizeof (HISTCOUNTER));
  if (do_test)
    printf ("load addr: %0#*" PRIxPTR "\n"
	    "lower bound PC: %0#*" PRIxPTR "\n"
	    "upper bound PC: %0#*" PRIxPTR "\n",
	    __ELF_NATIVE_CLASS == 32 ? 10 : 18, map->l_addr,
	    __ELF_NATIVE_CLASS == 32 ? 10 : 18, result->lowpc,
	    __ELF_NATIVE_CLASS == 32 ? 10 : 18, result->highpc);

  textsize = result->highpc - result->lowpc;
  result->kcountsize = textsize / HISTFRACTION;
  result->hashfraction = HASHFRACTION;
  if (do_test)
    printf ("hashfraction = %d\ndivider = %Zu\n",
	    result->hashfraction,
	    result->hashfraction * sizeof (struct here_fromstruct));
  result->tossize = textsize / HASHFRACTION;
  result->fromlimit = textsize * ARCDENSITY / 100;
  if (result->fromlimit < MINARCS)
    result->fromlimit = MINARCS;
  if (result->fromlimit > MAXARCS)
    result->fromlimit = MAXARCS;
  result->fromssize = result->fromlimit * sizeof (struct here_fromstruct);

  result->expected_size = (sizeof (struct gmon_hdr)
			   + 4 + sizeof (struct gmon_hist_hdr)
			   + result->kcountsize
			   + 4 + 4
			   + (result->fromssize
			      * sizeof (struct here_cg_arc_record)));

  if (do_test)
    printf ("expected size: %Zd\n", result->expected_size);

#define SCALE_1_TO_1	0x10000L

  if (result->kcountsize < result->highpc - result->lowpc)
    {
      size_t range = result->highpc - result->lowpc;
      size_t quot = range / result->kcountsize;

      if (quot >= SCALE_1_TO_1)
	result->s_scale = 1;
      else if (quot >= SCALE_1_TO_1 / 256)
	result->s_scale = SCALE_1_TO_1 / quot;
      else if (range > ULONG_MAX / 256)
	result->s_scale = ((SCALE_1_TO_1 * 256)
			   / (range / (result->kcountsize / 256)));
      else
	result->s_scale = ((SCALE_1_TO_1 * 256)
			   / ((range * 256) / result->kcountsize));
    }
  else
    result->s_scale = SCALE_1_TO_1;

  if (do_test)
    printf ("s_scale: %d\n", result->s_scale);

  /* Determine the dynamic string table.  */
  if (map->l_info[DT_STRTAB] == NULL)
    result->dynstrtab = NULL;
  else
    result->dynstrtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
  if (do_test)
    printf ("string table: %p\n", result->dynstrtab);

  /* Determine the soname.  */
  if (map->l_info[DT_SONAME] == NULL)
    result->soname = NULL;
  else
    result->soname = result->dynstrtab + map->l_info[DT_SONAME]->d_un.d_val;
  if (do_test && result->soname != NULL)
    printf ("soname: %s\n", result->soname);

  /* Now we have to load the symbol table.

     First load the section header table.  */
  ehdr = (ElfW(Ehdr) *) map->l_map_start;

  /* Make sure we are on the right party.  */
  if (ehdr->e_shentsize != sizeof (ElfW(Shdr)))
    abort ();

  /* And we need the shared object file descriptor again.  */
  fd = open (map->l_name, O_RDONLY);
  if (fd == -1)
    /* Dooh, this really shouldn't happen.  We know the file is available.  */
    error (EXIT_FAILURE, errno, _("Reopening shared object `%s' failed"),
	   map->l_name);

  /* Map the section header.  */
  size_t size = ehdr->e_shnum * sizeof (ElfW(Shdr));
  shdr = (ElfW(Shdr) *) alloca (size);
  if (pread (fd, shdr, size, ehdr->e_shoff) != size)
    error (EXIT_FAILURE, errno, _("reading of section headers failed"));

  /* Get the section header string table.  */
  char *shstrtab = (char *) alloca (shdr[ehdr->e_shstrndx].sh_size);
  if (pread (fd, shstrtab, shdr[ehdr->e_shstrndx].sh_size,
	     shdr[ehdr->e_shstrndx].sh_offset)
      != shdr[ehdr->e_shstrndx].sh_size)
    error (EXIT_FAILURE, errno,
	   _("reading of section header string table failed"));

  /* Search for the ".symtab" section.  */
  ElfW(Shdr) *symtab_entry = NULL;
  ElfW(Shdr) *debuglink_entry = NULL;
  for (int idx = 0; idx < ehdr->e_shnum; ++idx)
    if (shdr[idx].sh_type == SHT_SYMTAB
	&& strcmp (shstrtab + shdr[idx].sh_name, ".symtab") == 0)
      {
	symtab_entry = &shdr[idx];
	break;
      }
    else if (shdr[idx].sh_type == SHT_PROGBITS
	     && strcmp (shstrtab + shdr[idx].sh_name, ".gnu_debuglink") == 0)
      debuglink_entry = &shdr[idx];

  /* Get the file name of the debuginfo file if necessary.  */
  int symfd = fd;
  if (symtab_entry == NULL && debuglink_entry != NULL)
    {
      size_t size = debuglink_entry->sh_size;
      char *debuginfo_fname = (char *) alloca (size + 1);
      debuginfo_fname[size] = '\0';
      if (pread (fd, debuginfo_fname, size, debuglink_entry->sh_offset)
	  != size)
	{
	  fprintf (stderr, _("*** Cannot read debuginfo file name: %m\n"));
	  goto no_debuginfo;
	}

      static const char procpath[] = "/proc/self/fd/%d";
      char origprocname[sizeof (procpath) + sizeof (int) * 3];
      snprintf (origprocname, sizeof (origprocname), procpath, fd);
      char *origlink = (char *) alloca (PATH_MAX);
      ssize_t n = readlink (origprocname, origlink, PATH_MAX - 1);
      if (n == -1)
	goto no_debuginfo;
      origlink[n] = '\0';

      /* Try to find the actual file.  There are three places:
	 1. the same directory the DSO is in
	 2. in a subdir named .debug of the directory the DSO is in
	 3. in /usr/lib/debug/PATH-OF-DSO
      */
      char *realname = canonicalize_file_name (origlink);
      char *cp = NULL;
      if (realname == NULL || (cp = strrchr (realname, '/')) == NULL)
	error (EXIT_FAILURE, errno, _("cannot determine file name"));

      /* Leave the last slash in place.  */
      *++cp = '\0';

      /* First add the debuginfo file name only.  */
      static const char usrlibdebug[]= "/usr/lib/debug/";
      char *workbuf = (char *) alloca (sizeof (usrlibdebug)
				       + (cp - realname)
				       + strlen (debuginfo_fname));
      strcpy (stpcpy (workbuf, realname), debuginfo_fname);

      int fd2 = open (workbuf, O_RDONLY);
      if (fd2 == -1)
	{
	  strcpy (stpcpy (stpcpy (workbuf, realname), ".debug/"),
		  debuginfo_fname);
	  fd2 = open (workbuf, O_RDONLY);
	  if (fd2 == -1)
	    {
	      strcpy (stpcpy (stpcpy (workbuf, usrlibdebug), realname),
		      debuginfo_fname);
	      fd2 = open (workbuf, O_RDONLY);
	    }
	}

      if (fd2 != -1)
	{
	  ElfW(Ehdr) ehdr2;

	  /* Read the ELF header.  */
	  if (pread (fd2, &ehdr2, sizeof (ehdr2), 0) != sizeof (ehdr2))
	    error (EXIT_FAILURE, errno,
		   _("reading of ELF header failed"));

	  /* Map the section header.  */
	  size_t size = ehdr2.e_shnum * sizeof (ElfW(Shdr));
	  ElfW(Shdr) *shdr2 = (ElfW(Shdr) *) alloca (size);
	  if (pread (fd2, shdr2, size, ehdr2.e_shoff) != size)
	    error (EXIT_FAILURE, errno,
		   _("reading of section headers failed"));

	  /* Get the section header string table.  */
	  shstrtab = (char *) alloca (shdr2[ehdr2.e_shstrndx].sh_size);
	  if (pread (fd2, shstrtab, shdr2[ehdr2.e_shstrndx].sh_size,
		     shdr2[ehdr2.e_shstrndx].sh_offset)
	      != shdr2[ehdr2.e_shstrndx].sh_size)
	    error (EXIT_FAILURE, errno,
		   _("reading of section header string table failed"));

	  /* Search for the ".symtab" section.  */
	  for (int idx = 0; idx < ehdr2.e_shnum; ++idx)
	    if (shdr2[idx].sh_type == SHT_SYMTAB
		&& strcmp (shstrtab + shdr2[idx].sh_name, ".symtab") == 0)
	      {
		symtab_entry = &shdr2[idx];
		shdr = shdr2;
		symfd = fd2;
		break;
	      }

	  if  (fd2 != symfd)
	    close (fd2);
	}
    }

 no_debuginfo:
  if (symtab_entry == NULL)
    {
      fprintf (stderr, _("\
*** The file `%s' is stripped: no detailed analysis possible\n"),
	      name);
      result->symtab = NULL;
      result->strtab = NULL;
    }
  else
    {
      ElfW(Off) min_offset, max_offset;
      ElfW(Shdr) *strtab_entry;

      strtab_entry = &shdr[symtab_entry->sh_link];

      /* Find the minimum and maximum offsets that include both the symbol
	 table and the string table.  */
      if (symtab_entry->sh_offset < strtab_entry->sh_offset)
	{
	  min_offset = symtab_entry->sh_offset & ~(pagesize - 1);
	  max_offset = strtab_entry->sh_offset + strtab_entry->sh_size;
	}
      else
	{
	  min_offset = strtab_entry->sh_offset & ~(pagesize - 1);
	  max_offset = symtab_entry->sh_offset + symtab_entry->sh_size;
	}

      result->symbol_map = mmap (NULL, max_offset - min_offset,
				 PROT_READ, MAP_SHARED|MAP_FILE, symfd,
				 min_offset);
      if (result->symbol_map == MAP_FAILED)
	error (EXIT_FAILURE, errno, _("failed to load symbol data"));

      result->symtab
	= (const ElfW(Sym) *) ((const char *) result->symbol_map
			       + (symtab_entry->sh_offset - min_offset));
      result->symtab_size = symtab_entry->sh_size;
      result->strtab = ((const char *) result->symbol_map
			+ (strtab_entry->sh_offset - min_offset));
      result->symbol_mapsize = max_offset - min_offset;
    }

  /* Free the descriptor for the shared object.  */
  close (fd);
  if (symfd != fd)
    close (symfd);

  return result;
}


static void
unload_shobj (struct shobj *shobj)
{
  munmap (shobj->symbol_map, shobj->symbol_mapsize);
  dlclose (shobj->map);
}


static struct profdata *
load_profdata (const char *name, struct shobj *shobj)
{
  struct profdata *result;
  int fd;
  struct stat64 st;
  void *addr;
  uint32_t *narcsp;
  size_t fromlimit;
  struct here_cg_arc_record *data;
  struct here_fromstruct *froms;
  uint16_t *tos;
  size_t fromidx;
  size_t idx;

  fd = open (name, O_RDONLY);
  if (fd == -1)
    {
      char *ext_name;

      if (errno != ENOENT || strchr (name, '/') != NULL)
	/* The file exists but we are not allowed to read it or the
	   file does not exist and the name includes a path
	   specification..  */
	return NULL;

      /* A file with the given name does not exist in the current
	 directory, try it in the default location where the profiling
	 files are created.  */
      ext_name = (char *) alloca (strlen (name) + sizeof "/var/tmp/");
      stpcpy (stpcpy (ext_name, "/var/tmp/"), name);
      name = ext_name;

      fd = open (ext_name, O_RDONLY);
      if (fd == -1)
	{
	  /* Even this file does not exist.  */
	  error (0, errno, _("cannot load profiling data"));
	  return NULL;
	}
    }

  /* We have found the file, now make sure it is the right one for the
     data file.  */
  if (fstat64 (fd, &st) < 0)
    {
      error (0, errno, _("while stat'ing profiling data file"));
      close (fd);
      return NULL;
    }

  if ((size_t) st.st_size != shobj->expected_size)
    {
      error (0, 0,
	     _("profiling data file `%s' does not match shared object `%s'"),
	     name, shobj->name);
      close (fd);
      return NULL;
    }

  /* The data file is most probably the right one for our shared
     object.  Map it now.  */
  addr = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
  if (addr == MAP_FAILED)
    {
      error (0, errno, _("failed to mmap the profiling data file"));
      close (fd);
      return NULL;
    }

  /* We don't need the file desriptor anymore.  */
  if (close (fd) < 0)
    {
      error (0, errno, _("error while closing the profiling data file"));
      munmap (addr, st.st_size);
      return NULL;
    }

  /* Prepare the result.  */
  result = (struct profdata *) calloc (1, sizeof (struct profdata));
  if (result == NULL)
    {
      error (0, errno, _("cannot create internal descriptor"));
      munmap (addr, st.st_size);
      return NULL;
    }

  /* Store the address and size so that we can later free the resources.  */
  result->addr = addr;
  result->size = st.st_size;

  /* Pointer to data after the header.  */
  result->hist = (char *) ((struct gmon_hdr *) addr + 1);
  result->hist_hdr = (struct real_gmon_hist_hdr *) ((char *) result->hist
						    + sizeof (uint32_t));
  result->kcount = (uint16_t *) ((char *) result->hist + sizeof (uint32_t)
				 + sizeof (struct real_gmon_hist_hdr));

  /* Compute pointer to array of the arc information.  */
  narcsp = (uint32_t *) ((char *) result->kcount + shobj->kcountsize
			 + sizeof (uint32_t));
  result->narcs = *narcsp;
  result->data = (struct here_cg_arc_record *) ((char *) narcsp
						+ sizeof (uint32_t));

  /* Create the gmon_hdr we expect or write.  */
  struct real_gmon_hdr
  {
    char cookie[4];
    int32_t version;
    char spare[3 * 4];
  } gmon_hdr;
  if (sizeof (gmon_hdr) != sizeof (struct gmon_hdr)
      || (offsetof (struct real_gmon_hdr, cookie)
	  != offsetof (struct gmon_hdr, cookie))
      || (offsetof (struct real_gmon_hdr, version)
	  != offsetof (struct gmon_hdr, version)))
    abort ();

  memcpy (&gmon_hdr.cookie[0], GMON_MAGIC, sizeof (gmon_hdr.cookie));
  gmon_hdr.version = GMON_SHOBJ_VERSION;
  memset (gmon_hdr.spare, '\0', sizeof (gmon_hdr.spare));

  /* Create the hist_hdr we expect or write.  */
  struct real_gmon_hist_hdr hist_hdr;
  if (sizeof (hist_hdr) != sizeof (struct gmon_hist_hdr)
      || (offsetof (struct real_gmon_hist_hdr, low_pc)
	  != offsetof (struct gmon_hist_hdr, low_pc))
      || (offsetof (struct real_gmon_hist_hdr, high_pc)
	  != offsetof (struct gmon_hist_hdr, high_pc))
      || (offsetof (struct real_gmon_hist_hdr, hist_size)
	  != offsetof (struct gmon_hist_hdr, hist_size))
      || (offsetof (struct real_gmon_hist_hdr, prof_rate)
	  != offsetof (struct gmon_hist_hdr, prof_rate))
      || (offsetof (struct real_gmon_hist_hdr, dimen)
	  != offsetof (struct gmon_hist_hdr, dimen))
      || (offsetof (struct real_gmon_hist_hdr, dimen_abbrev)
	  != offsetof (struct gmon_hist_hdr, dimen_abbrev)))
    abort ();

  hist_hdr.low_pc = (char *) shobj->lowpc - shobj->map->l_addr;
  hist_hdr.high_pc = (char *) shobj->highpc - shobj->map->l_addr;
  if (do_test)
    printf ("low_pc = %p\nhigh_pc = %p\n", hist_hdr.low_pc, hist_hdr.high_pc);
  hist_hdr.hist_size = shobj->kcountsize / sizeof (HISTCOUNTER);
  hist_hdr.prof_rate = __profile_frequency ();
  strncpy (hist_hdr.dimen, "seconds", sizeof (hist_hdr.dimen));
  hist_hdr.dimen_abbrev = 's';

  /* Test whether the header of the profiling data is ok.  */
  if (memcmp (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0
      || *(uint32_t *) result->hist != GMON_TAG_TIME_HIST
      || memcmp (result->hist_hdr, &hist_hdr,
		 sizeof (struct gmon_hist_hdr)) != 0
      || narcsp[-1] != GMON_TAG_CG_ARC)
    {
      error (0, 0, _("`%s' is no correct profile data file for `%s'"),
	     name, shobj->name);
      if (do_test)
	{
	  if (memcmp (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0)
	    puts ("gmon_hdr differs");
	  if (*(uint32_t *) result->hist != GMON_TAG_TIME_HIST)
	    puts ("result->hist differs");
	  if (memcmp (result->hist_hdr, &hist_hdr,
		      sizeof (struct gmon_hist_hdr)) != 0)
	    puts ("hist_hdr differs");
	  if (narcsp[-1] != GMON_TAG_CG_ARC)
	    puts ("narcsp[-1] differs");
	}
      free (result);
      munmap (addr, st.st_size);
      return NULL;
    }

  /* We are pretty sure now that this is a correct input file.  Set up
     the remaining information in the result structure and return.  */
  result->tos = (uint16_t *) calloc (shobj->tossize + shobj->fromssize, 1);
  if (result->tos == NULL)
    {
      error (0, errno, _("cannot create internal descriptor"));
      munmap (addr, st.st_size);
      free (result);
      return NULL;
    }

  result->froms = (struct here_fromstruct *) ((char *) result->tos
					      + shobj->tossize);
  fromidx = 0;

  /* Now we have to process all the arc count entries.  */
  fromlimit = shobj->fromlimit;
  data = result->data;
  froms = result->froms;
  tos = result->tos;
  for (idx = 0; idx < MIN (*narcsp, fromlimit); ++idx)
    {
      size_t to_index;
      size_t newfromidx;
      to_index = (data[idx].self_pc / (shobj->hashfraction * sizeof (*tos)));
      newfromidx = fromidx++;
      froms[newfromidx].here = &data[idx];
      froms[newfromidx].link = tos[to_index];
      tos[to_index] = newfromidx;
    }

  return result;
}


static void
unload_profdata (struct profdata *profdata)
{
  free (profdata->tos);
  munmap (profdata->addr, profdata->size);
  free (profdata);
}


static void
count_total_ticks (struct shobj *shobj, struct profdata *profdata)
{
  volatile uint16_t *kcount = profdata->kcount;
  size_t maxkidx = shobj->kcountsize;
  size_t factor = 2 * (65536 / shobj->s_scale);
  size_t kidx = 0;
  size_t sidx = 0;

  while (sidx < symidx)
    {
      uintptr_t start = sortsym[sidx]->addr;
      uintptr_t end = start + sortsym[sidx]->size;

      while (kidx < maxkidx && factor * kidx < start)
	++kidx;
      if (kidx == maxkidx)
	break;

      while (kidx < maxkidx && factor * kidx < end)
	sortsym[sidx]->ticks += kcount[kidx++];
      if (kidx == maxkidx)
	break;

      total_ticks += sortsym[sidx++]->ticks;
    }
}


static size_t
find_symbol (uintptr_t addr)
{
  size_t sidx = 0;

  while (sidx < symidx)
    {
      uintptr_t start = sortsym[sidx]->addr;
      uintptr_t end = start + sortsym[sidx]->size;

      if (addr >= start && addr < end)
	return sidx;

      if (addr < start)
	break;

      ++sidx;
    }

  return (size_t) -1l;
}


static void
count_calls (struct shobj *shobj, struct profdata *profdata)
{
  struct here_cg_arc_record *data = profdata->data;
  uint32_t narcs = profdata->narcs;
  uint32_t cnt;

  for (cnt = 0; cnt < narcs; ++cnt)
    {
      uintptr_t here = data[cnt].self_pc;
      size_t symbol_idx;

      /* Find the symbol for this address.  */
      symbol_idx = find_symbol (here);
      if (symbol_idx != (size_t) -1l)
	sortsym[symbol_idx]->calls += data[cnt].count;
    }
}


static int
symorder (const void *o1, const void *o2)
{
  const struct known_symbol *p1 = (const struct known_symbol *) o1;
  const struct known_symbol *p2 = (const struct known_symbol *) o2;

  return p1->addr - p2->addr;
}


static void
printsym (const void *node, VISIT value, int level)
{
  if (value == leaf || value == postorder)
    sortsym[symidx++] = *(struct known_symbol **) node;
}


static void
read_symbols (struct shobj *shobj)
{
  int n = 0;

  /* Initialize the obstacks.  */
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
  obstack_init (&shobj->ob_str);
  obstack_init (&shobj->ob_sym);
  obstack_init (&ob_list);

  /* Process the symbols.  */
  if (shobj->symtab != NULL)
    {
      const ElfW(Sym) *sym = shobj->symtab;
      const ElfW(Sym) *sym_end
	= (const ElfW(Sym) *) ((const char *) sym + shobj->symtab_size);
      for (; sym < sym_end; sym++)
	if ((ELFW(ST_TYPE) (sym->st_info) == STT_FUNC
	     || ELFW(ST_TYPE) (sym->st_info) == STT_NOTYPE)
	    && sym->st_size != 0)
	  {
	    struct known_symbol **existp;
	    struct known_symbol *newsym
	      = (struct known_symbol *) obstack_alloc (&shobj->ob_sym,
						       sizeof (*newsym));
	    if (newsym == NULL)
	      error (EXIT_FAILURE, errno, _("cannot allocate symbol data"));

	    newsym->name = &shobj->strtab[sym->st_name];
	    newsym->addr = sym->st_value;
	    newsym->size = sym->st_size;
	    newsym->weak = ELFW(ST_BIND) (sym->st_info) == STB_WEAK;
	    newsym->hidden = (ELFW(ST_VISIBILITY) (sym->st_other)
			      != STV_DEFAULT);
	    newsym->ticks = 0;
	    newsym->calls = 0;

	    existp = tfind (newsym, &symroot, symorder);
	    if (existp == NULL)
	      {
		/* New function.  */
		tsearch (newsym, &symroot, symorder);
		++n;
	      }
	    else
	      {
		/* The function is already defined.  See whether we have
		   a better name here.  */
		if (((*existp)->hidden && !newsym->hidden)
		    || ((*existp)->name[0] == '_' && newsym->name[0] != '_')
		    || ((*existp)->name[0] != '_' && newsym->name[0] != '_'
			&& ((*existp)->weak && !newsym->weak)))
		  *existp = newsym;
		else
		  /* We don't need the allocated memory.  */
		  obstack_free (&shobj->ob_sym, newsym);
	      }
	  }
    }
  else
    {
      /* Blarg, the binary is stripped.  We have to rely on the
	 information contained in the dynamic section of the object.  */
      const ElfW(Sym) *symtab = (ElfW(Sym) *) D_PTR (shobj->map,
						     l_info[DT_SYMTAB]);
      const char *strtab = (const char *) D_PTR (shobj->map,
						 l_info[DT_STRTAB]);

      /* We assume that the string table follows the symbol table,
	 because there is no way in ELF to know the size of the
	 dynamic symbol table without looking at the section headers.  */
      while ((void *) symtab < (void *) strtab)
	{
	  if ((ELFW(ST_TYPE)(symtab->st_info) == STT_FUNC
	       || ELFW(ST_TYPE)(symtab->st_info) == STT_NOTYPE)
	      && symtab->st_size != 0)
	    {
	      struct known_symbol *newsym;
	      struct known_symbol **existp;

	      newsym =
		(struct known_symbol *) obstack_alloc (&shobj->ob_sym,
						       sizeof (*newsym));
	      if (newsym == NULL)
		error (EXIT_FAILURE, errno, _("cannot allocate symbol data"));

	      newsym->name = &strtab[symtab->st_name];
	      newsym->addr = symtab->st_value;
	      newsym->size = symtab->st_size;
	      newsym->weak = ELFW(ST_BIND) (symtab->st_info) == STB_WEAK;
	      newsym->hidden = (ELFW(ST_VISIBILITY) (symtab->st_other)
				!= STV_DEFAULT);
	      newsym->ticks = 0;
	      newsym->froms = NULL;
	      newsym->tos = NULL;

	      existp = tfind (newsym, &symroot, symorder);
	      if (existp == NULL)
		{
		  /* New function.  */
		  tsearch (newsym, &symroot, symorder);
		  ++n;
		}
	      else
		{
		  /* The function is already defined.  See whether we have
		     a better name here.  */
		  if (((*existp)->hidden && !newsym->hidden)
		      || ((*existp)->name[0] == '_' && newsym->name[0] != '_')
		      || ((*existp)->name[0] != '_' && newsym->name[0] != '_'
			  && ((*existp)->weak && !newsym->weak)))
		    *existp = newsym;
		  else
		    /* We don't need the allocated memory.  */
		    obstack_free (&shobj->ob_sym, newsym);
		}
	    }

	  ++symtab;
	}
    }

  sortsym = malloc (n * sizeof (struct known_symbol *));
  if (sortsym == NULL)
    abort ();

  twalk (symroot, printsym);
}


static void
add_arcs (struct profdata *profdata)
{
  uint32_t narcs = profdata->narcs;
  struct here_cg_arc_record *data = profdata->data;
  uint32_t cnt;

  for (cnt = 0; cnt < narcs; ++cnt)
    {
      /* First add the incoming arc.  */
      size_t sym_idx = find_symbol (data[cnt].self_pc);

      if (sym_idx != (size_t) -1l)
	{
	  struct known_symbol *sym = sortsym[sym_idx];
	  struct arc_list *runp = sym->froms;

	  while (runp != NULL
		 && ((data[cnt].from_pc == 0 && runp->idx != (size_t) -1l)
		     || (data[cnt].from_pc != 0
			 && (runp->idx == (size_t) -1l
			     || data[cnt].from_pc < sortsym[runp->idx]->addr
			     || (data[cnt].from_pc
				 >= (sortsym[runp->idx]->addr
				     + sortsym[runp->idx]->size))))))
	    runp = runp->next;

	  if (runp == NULL)
	    {
	      /* We need a new entry.  */
	      struct arc_list *newp = (struct arc_list *)
		obstack_alloc (&ob_list, sizeof (struct arc_list));

	      if (data[cnt].from_pc == 0)
		newp->idx = (size_t) -1l;
	      else
		newp->idx = find_symbol (data[cnt].from_pc);
	      newp->count = data[cnt].count;
	      newp->next = sym->froms;
	      sym->froms = newp;
	    }
	  else
	    /* Increment the counter for the found entry.  */
	    runp->count += data[cnt].count;
	}

      /* Now add it to the appropriate outgoing list.  */
      sym_idx = find_symbol (data[cnt].from_pc);
      if (sym_idx != (size_t) -1l)
	{
	  struct known_symbol *sym = sortsym[sym_idx];
	  struct arc_list *runp = sym->tos;

	  while (runp != NULL
		 && (runp->idx == (size_t) -1l
		     || data[cnt].self_pc < sortsym[runp->idx]->addr
		     || data[cnt].self_pc >= (sortsym[runp->idx]->addr
					      + sortsym[runp->idx]->size)))
	    runp = runp->next;

	  if (runp == NULL)
	    {
	      /* We need a new entry.  */
	      struct arc_list *newp = (struct arc_list *)
		obstack_alloc (&ob_list, sizeof (struct arc_list));

	      newp->idx = find_symbol (data[cnt].self_pc);
	      newp->count = data[cnt].count;
	      newp->next = sym->tos;
	      sym->tos = newp;
	    }
	  else
	    /* Increment the counter for the found entry.  */
	    runp->count += data[cnt].count;
	}
    }
}


static int
countorder (const void *p1, const void *p2)
{
  struct known_symbol *s1 = (struct known_symbol *) p1;
  struct known_symbol *s2 = (struct known_symbol *) p2;

  if (s1->ticks != s2->ticks)
    return (int) (s2->ticks - s1->ticks);

  if (s1->calls != s2->calls)
    return (int) (s2->calls - s1->calls);

  return strcmp (s1->name, s2->name);
}


static double tick_unit;
static uintmax_t cumu_ticks;

static void
printflat (const void *node, VISIT value, int level)
{
  if (value == leaf || value == postorder)
    {
      struct known_symbol *s = *(struct known_symbol **) node;

      cumu_ticks += s->ticks;

      printf ("%6.2f%10.2f%9.2f%9" PRIdMAX "%9.2f           %s\n",
	      total_ticks ? (100.0 * s->ticks) / total_ticks : 0.0,
	      tick_unit * cumu_ticks,
	      tick_unit * s->ticks,
	      s->calls,
	      s->calls ? (s->ticks * 1000000) * tick_unit / s->calls : 0,
	      /* FIXME: don't know about called functions.  */
	      s->name);
    }
}


/* ARGUSED */
static void
freenoop (void *p)
{
}


static void
generate_flat_profile (struct profdata *profdata)
{
  size_t n;
  void *data = NULL;

  tick_unit = 1.0 / profdata->hist_hdr->prof_rate;

  printf ("Flat profile:\n\n"
	  "Each sample counts as %g %s.\n",
	  tick_unit, profdata->hist_hdr->dimen);
  fputs ("  %   cumulative   self              self     total\n"
	 " time   seconds   seconds    calls  us/call  us/call  name\n",
	 stdout);

  for (n = 0; n < symidx; ++n)
    if (sortsym[n]->calls != 0 || sortsym[n]->ticks != 0)
      tsearch (sortsym[n], &data, countorder);

  twalk (data, printflat);

  tdestroy (data, freenoop);
}


static void
generate_call_graph (struct profdata *profdata)
{
  size_t cnt;

  puts ("\nindex % time    self  children    called     name\n");

  for (cnt = 0; cnt < symidx; ++cnt)
    if (sortsym[cnt]->froms != NULL || sortsym[cnt]->tos != NULL)
      {
	struct arc_list *runp;
	size_t n;

	/* First print the from-information.  */
	runp = sortsym[cnt]->froms;
	while (runp != NULL)
	  {
	    printf ("            %8.2f%8.2f%9" PRIdMAX "/%-9" PRIdMAX "   %s",
		    (runp->idx != (size_t) -1l
		     ? sortsym[runp->idx]->ticks * tick_unit : 0.0),
		    0.0, /* FIXME: what's time for the children, recursive */
		    runp->count, sortsym[cnt]->calls,
		    (runp->idx != (size_t) -1l ?
		     sortsym[runp->idx]->name : "<UNKNOWN>"));

	    if (runp->idx != (size_t) -1l)
	      printf (" [%Zd]", runp->idx);
	    putchar_unlocked ('\n');

	    runp = runp->next;
	  }

	/* Info about the function itself.  */
	n = printf ("[%Zu]", cnt);
	printf ("%*s%5.1f%8.2f%8.2f%9" PRIdMAX "         %s [%Zd]\n",
		(int) (7 - n), " ",
		total_ticks ? (100.0 * sortsym[cnt]->ticks) / total_ticks : 0,
		sortsym[cnt]->ticks * tick_unit,
		0.0, /* FIXME: what's time for the children, recursive */
		sortsym[cnt]->calls,
		sortsym[cnt]->name, cnt);

	/* Info about the functions this function calls.  */
	runp = sortsym[cnt]->tos;
	while (runp != NULL)
	  {
	    printf ("            %8.2f%8.2f%9" PRIdMAX "/",
		    (runp->idx != (size_t) -1l
		     ? sortsym[runp->idx]->ticks * tick_unit : 0.0),
		    0.0, /* FIXME: what's time for the children, recursive */
		    runp->count);

	    if (runp->idx != (size_t) -1l)
	      printf ("%-9" PRIdMAX "   %s [%Zd]\n",
		      sortsym[runp->idx]->calls,
		      sortsym[runp->idx]->name,
		      runp->idx);
	    else
	      fputs ("???         <UNKNOWN>\n\n", stdout);

	    runp = runp->next;
	  }

	fputs ("-----------------------------------------------\n", stdout);
      }
}


static void
generate_call_pair_list (struct profdata *profdata)
{
  size_t cnt;

  for (cnt = 0; cnt < symidx; ++cnt)
    if (sortsym[cnt]->froms != NULL || sortsym[cnt]->tos != NULL)
      {
	struct arc_list *runp;

	/* First print the incoming arcs.  */
	runp = sortsym[cnt]->froms;
	while (runp != NULL)
	  {
	    if (runp->idx == (size_t) -1l)
	      printf ("\
<UNKNOWN>                          %-34s %9" PRIdMAX "\n",
		      sortsym[cnt]->name, runp->count);
	    runp = runp->next;
	  }

	/* Next the outgoing arcs.  */
	runp = sortsym[cnt]->tos;
	while (runp != NULL)
	  {
	    printf ("%-34s %-34s %9" PRIdMAX "\n",
		    sortsym[cnt]->name,
		    (runp->idx != (size_t) -1l
		     ? sortsym[runp->idx]->name : "<UNKNOWN>"),
		    runp->count);
	    runp = runp->next;
	  }
      }
}
