error (0, 0, _("profiling data file `%s' does match shared object `%s'"),
error (0, 0, _("profiling data file `%s' does not match shared object `%s'"),
load_profdata (const char *name, struct shobj *shobj){  struct profdata *result;  int fd;  struct stat st;  void *addr;  struct gmon_hdr gmon_hdr;  struct gmon_hist_hdr hist_hdr;  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 (fstat (fd, &st) < 0)    {      error (0, errno, _("while stat'ing profiling data file"));      close (fd);      return NULL;    }  if (st.st_size != shobj->expected_size)    {      error (0, 0, _("profiling data file `%s' does 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 gmon_hist_hdr *) ((char *) result->hist					       + sizeof (uint32_t));  result->kcount = (uint16_t *) ((char *) result->hist + sizeof (uint32_t)				 + sizeof (struct 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.  */  memset (&gmon_hdr, '\0', sizeof (struct gmon_hdr));  memcpy (&gmon_hdr.cookie[0], GMON_MAGIC, sizeof (gmon_hdr.cookie));  *(int32_t *) gmon_hdr.version = GMON_SHOBJ_VERSION;  /* Create the hist_hdr we expect or write.  */  *(char **) hist_hdr.low_pc = (char *) shobj->lowpc - shobj->map->l_addr;  *(char **) hist_hdr.high_pc = (char *) shobj->highpc - shobj->map->l_addr;  if (do_test)    printf ("low_pc = %p\nhigh_pc = %p\n",	    *(char **) hist_hdr.low_pc, *(char **) hist_hdr.high_pc);  *(int32_t *) hist_hdr.hist_size = shobj->kcountsize / sizeof (HISTCOUNTER);  *(int32_t *) 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)    {      free (result);      error (0, 0, _("`%s' is no correct profile data file for `%s'"),	     name, shobj->name);      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;}