Print this page
3946 ::gcore
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libproc/common/Psymtab.c
          +++ new/usr/src/lib/libproc/common/Psymtab.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       25 + * Copyright (c) 2013 by Delphix. All rights reserved.
  25   26   */
  26   27  
  27   28  #include <assert.h>
  28   29  #include <stdio.h>
  29   30  #include <stdlib.h>
  30   31  #include <stddef.h>
  31   32  #include <unistd.h>
  32   33  #include <ctype.h>
  33   34  #include <fcntl.h>
  34   35  #include <string.h>
  35   36  #include <strings.h>
  36   37  #include <memory.h>
  37   38  #include <errno.h>
  38   39  #include <dirent.h>
  39   40  #include <signal.h>
  40   41  #include <limits.h>
  41   42  #include <libgen.h>
  42   43  #include <sys/types.h>
  43   44  #include <sys/stat.h>
  44      -#include <sys/systeminfo.h>
  45   45  #include <sys/sysmacros.h>
  46   46  
  47   47  #include "libproc.h"
  48   48  #include "Pcontrol.h"
  49   49  #include "Putil.h"
  50   50  #include "Psymtab_machelf.h"
  51   51  
  52   52  static file_info_t *build_map_symtab(struct ps_prochandle *, map_info_t *);
  53   53  static map_info_t *exec_map(struct ps_prochandle *);
  54   54  static map_info_t *object_to_map(struct ps_prochandle *, Lmid_t, const char *);
↓ open down ↓ 372 lines elided ↑ open up ↑
 427  427  
 428  428          /*
 429  429           * If the dynamic linker exists for this process,
 430  430           * construct the map for it.
 431  431           */
 432  432          if (Pgetauxval(P, AT_BASE) != -1L &&
 433  433              (mptr = object_name_to_map(P, PR_LMID_EVERY, PR_OBJ_LDSO)) != NULL)
 434  434                  map_set(P, mptr, "ld.so.1");
 435  435  }
 436  436  
      437 +int
      438 +Preadmaps(struct ps_prochandle *P, prmap_t **Pmapp, ssize_t *nmapp)
      439 +{
      440 +        return (P->ops.pop_read_maps(P, Pmapp, nmapp, P->data));
      441 +}
      442 +
 437  443  /*
 438  444   * Go through all the address space mappings, validating or updating
 439  445   * the information already gathered, or gathering new information.
 440  446   *
 441  447   * This function is only called when we suspect that the mappings have changed
 442  448   * because this is the first time we're calling it or because of rtld activity.
 443  449   */
 444  450  void
 445  451  Pupdate_maps(struct ps_prochandle *P)
 446  452  {
 447      -        char mapfile[PATH_MAX];
 448      -        int mapfd;
 449      -        struct stat statb;
 450  453          prmap_t *Pmap = NULL;
 451  454          prmap_t *pmap;
 452  455          ssize_t nmap;
 453  456          int i;
 454  457          uint_t oldmapcount;
 455  458          map_info_t *newmap, *newp;
 456  459          map_info_t *mptr;
 457  460  
 458  461          if (P->info_valid || P->state == PS_UNDEAD)
 459  462                  return;
 460  463  
 461  464          Preadauxvec(P);
 462  465  
 463      -        (void) snprintf(mapfile, sizeof (mapfile), "%s/%d/map",
 464      -            procfs_path, (int)P->pid);
 465      -        if ((mapfd = open(mapfile, O_RDONLY)) < 0 ||
 466      -            fstat(mapfd, &statb) != 0 ||
 467      -            statb.st_size < sizeof (prmap_t) ||
 468      -            (Pmap = malloc(statb.st_size)) == NULL ||
 469      -            (nmap = pread(mapfd, Pmap, statb.st_size, 0L)) <= 0 ||
 470      -            (nmap /= sizeof (prmap_t)) == 0) {
 471      -                if (Pmap != NULL)
 472      -                        free(Pmap);
 473      -                if (mapfd >= 0)
 474      -                        (void) close(mapfd);
 475      -                Preset_maps(P); /* utter failure; destroy tables */
      466 +        if (Preadmaps(P, &Pmap, &nmap) != 0)
 476  467                  return;
 477      -        }
 478      -        (void) close(mapfd);
 479  468  
 480  469          if ((newmap = calloc(1, nmap * sizeof (map_info_t))) == NULL)
 481  470                  return;
 482  471  
 483  472          /*
 484  473           * We try to merge any file information we may have for existing
 485  474           * mappings, to avoid having to rebuild the file info.
 486  475           */
 487  476          mptr = P->mappings;
 488  477          pmap = Pmap;
↓ open down ↓ 352 lines elided ↑ open up ↑
 841  830  
 842  831          return (Pbuild_file_ctf(P, fptr));
 843  832  }
 844  833  
 845  834  ctf_file_t *
 846  835  Pname_to_ctf(struct ps_prochandle *P, const char *name)
 847  836  {
 848  837          return (Plmid_to_ctf(P, PR_LMID_EVERY, name));
 849  838  }
 850  839  
 851      -/*
 852      - * If we're not a core file, re-read the /proc/<pid>/auxv file and store
 853      - * its contents in P->auxv.  In the case of a core file, we either
 854      - * initialized P->auxv in Pcore() from the NT_AUXV, or we don't have an
 855      - * auxv because the note was missing.
 856      - */
 857  840  void
 858  841  Preadauxvec(struct ps_prochandle *P)
 859  842  {
 860      -        char auxfile[64];
 861      -        struct stat statb;
 862      -        ssize_t naux;
 863      -        int fd;
 864      -
 865      -        if (P->state == PS_DEAD)
 866      -                return; /* Already read during Pgrab_core() */
 867      -        if (P->state == PS_IDLE)
 868      -                return; /* No aux vec for Pgrab_file() */
 869      -
 870  843          if (P->auxv != NULL) {
 871  844                  free(P->auxv);
 872  845                  P->auxv = NULL;
 873  846                  P->nauxv = 0;
 874  847          }
 875  848  
 876      -        (void) snprintf(auxfile, sizeof (auxfile), "%s/%d/auxv",
 877      -            procfs_path, (int)P->pid);
 878      -        if ((fd = open(auxfile, O_RDONLY)) < 0)
 879      -                return;
 880      -
 881      -        if (fstat(fd, &statb) == 0 &&
 882      -            statb.st_size >= sizeof (auxv_t) &&
 883      -            (P->auxv = malloc(statb.st_size + sizeof (auxv_t))) != NULL) {
 884      -                if ((naux = read(fd, P->auxv, statb.st_size)) < 0 ||
 885      -                    (naux /= sizeof (auxv_t)) < 1) {
 886      -                        free(P->auxv);
 887      -                        P->auxv = NULL;
 888      -                } else {
 889      -                        P->auxv[naux].a_type = AT_NULL;
 890      -                        P->auxv[naux].a_un.a_val = 0L;
 891      -                        P->nauxv = (int)naux;
 892      -                }
 893      -        }
 894      -
 895      -        (void) close(fd);
      849 +        P->ops.pop_read_aux(P, &P->auxv, &P->nauxv, P->data);
 896  850  }
 897  851  
 898  852  /*
 899  853   * Return a requested element from the process's aux vector.
 900  854   * Return -1 on failure (this is adequate for our purposes).
 901  855   */
 902  856  long
 903  857  Pgetauxval(struct ps_prochandle *P, int type)
 904  858  {
 905  859          auxv_t *auxv;
↓ open down ↓ 770 lines elided ↑ open up ↑
1676 1630                      procfs_path, (int)P->pid, fptr->file_pname);
1677 1631          }
1678 1632  
1679 1633          /*
1680 1634           * Open the object file, create the elf file, and then get the elf
1681 1635           * header and .shstrtab data buffer so we can process sections by
1682 1636           * name. If anything goes wrong try to fake up an elf file from
1683 1637           * the in-core elf image.
1684 1638           */
1685 1639  
1686      -        if (_libproc_incore_elf) {
     1640 +        if (_libproc_incore_elf || (P->flags & INCORE)) {
1687 1641                  dprintf("Pbuild_file_symtab: using in-core data for: %s\n",
1688 1642                      fptr->file_pname);
1689 1643  
1690 1644                  if ((elf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) ==
1691 1645                      NULL)
1692 1646                          return;
1693 1647  
1694 1648          } else if ((fptr->file_fd = open(objectfile, O_RDONLY)) < 0) {
1695 1649                  dprintf("Pbuild_file_symtab: failed to open %s: %s\n",
1696 1650                      objectfile, strerror(errno));
↓ open down ↓ 1265 lines elided ↑ open up ↑
2962 2916  
2963 2917  int
2964 2918  Psymbol_iter_by_name(struct ps_prochandle *P,
2965 2919      const char *object_name, int which, int mask, proc_sym_f *func, void *cd)
2966 2920  {
2967 2921          return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask,
2968 2922              PRO_BYNAME, (proc_xsym_f *)func, cd));
2969 2923  }
2970 2924  
2971 2925  /*
2972      - * Get the platform string from the core file if we have it;
2973      - * just perform the system call for the caller if this is a live process.
     2926 + * Get the platform string.
2974 2927   */
2975 2928  char *
2976 2929  Pplatform(struct ps_prochandle *P, char *s, size_t n)
2977 2930  {
2978      -        if (P->state == PS_IDLE) {
2979      -                errno = ENODATA;
2980      -                return (NULL);
2981      -        }
2982      -
2983      -        if (P->state == PS_DEAD) {
2984      -                if (P->core->core_platform == NULL) {
2985      -                        errno = ENODATA;
2986      -                        return (NULL);
2987      -                }
2988      -                (void) strncpy(s, P->core->core_platform, n - 1);
2989      -                s[n - 1] = '\0';
2990      -
2991      -        } else if (sysinfo(SI_PLATFORM, s, n) == -1)
2992      -                return (NULL);
2993      -
2994      -        return (s);
     2931 +        return (P->ops.pop_platform(P, s, n, P->data));
2995 2932  }
2996 2933  
2997 2934  /*
2998      - * Get the uname(2) information from the core file if we have it;
2999      - * just perform the system call for the caller if this is a live process.
     2935 + * Get the uname(2) information.
3000 2936   */
3001 2937  int
3002 2938  Puname(struct ps_prochandle *P, struct utsname *u)
3003 2939  {
3004      -        if (P->state == PS_IDLE) {
3005      -                errno = ENODATA;
3006      -                return (-1);
3007      -        }
3008      -
3009      -        if (P->state == PS_DEAD) {
3010      -                if (P->core->core_uts == NULL) {
3011      -                        errno = ENODATA;
3012      -                        return (-1);
3013      -                }
3014      -                (void) memcpy(u, P->core->core_uts, sizeof (struct utsname));
3015      -                return (0);
3016      -        }
3017      -        return (uname(u));
     2940 +        return (P->ops.pop_uname(P, u, P->data));
3018 2941  }
3019 2942  
3020 2943  /*
3021 2944   * Called from Pcreate(), Pgrab(), and Pfgrab_core() to initialize
3022 2945   * the symbol table heads in the new ps_prochandle.
3023 2946   */
3024 2947  void
3025 2948  Pinitsym(struct ps_prochandle *P)
3026 2949  {
3027 2950          P->num_files = 0;
↓ open down ↓ 201 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX