diff options
author | nn35248 <none@none> | 2006-09-11 22:51:59 -0700 |
---|---|---|
committer | nn35248 <none@none> | 2006-09-11 22:51:59 -0700 |
commit | 9acbbeaf2a1ffe5c14b244867d427714fab43c5c (patch) | |
tree | d1ecd54896325c19a463220e9cbc50864874fc82 /usr/src/lib/libproc/common | |
parent | da51466dc253d7c98dda4956059042bd0c476328 (diff) | |
download | illumos-joyent-9acbbeaf2a1ffe5c14b244867d427714fab43c5c.tar.gz |
PSARC/2005/471 BrandZ: Support for non-native zones
6374606 ::nm -D without an object may not work on processes in zones
6409350 BrandZ project integration into Solaris
6455289 pthread_setschedparam() should return EPERM rather than panic libc
6455591 setpriority(3C) gets errno wrong for deficient privileges failure
6458178 fifofs doesn't support lofs mounts of fifos
6460380 Attempted open() of a symlink with the O_NOFOLLOW flag set returns EINVAL, not ELOOP
6463857 renice(1) errors erroneously
--HG--
rename : usr/src/lib/libzonecfg/zones/SUNWblank.xml => usr/src/lib/brand/native/zone/SUNWblank.xml
rename : usr/src/lib/libzonecfg/zones/SUNWdefault.xml => usr/src/lib/brand/native/zone/SUNWdefault.xml
Diffstat (limited to 'usr/src/lib/libproc/common')
-rw-r--r-- | usr/src/lib/libproc/common/Pbrand.c | 42 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcontrol.c | 37 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcontrol.h | 9 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcore.c | 54 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pexecname.c | 23 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pisprocdir.c | 15 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Plwpregs.c | 20 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pscantext.c | 13 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pservice.c | 19 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Psymtab.c | 133 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Psyscall.c | 12 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/libproc.h | 10 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/mapfile-vers | 2 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/proc_arg.c | 24 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/proc_get_info.c | 41 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/proc_names.c | 13 |
16 files changed, 319 insertions, 148 deletions
diff --git a/usr/src/lib/libproc/common/Pbrand.c b/usr/src/lib/libproc/common/Pbrand.c new file mode 100644 index 0000000000..f7f3c337ac --- /dev/null +++ b/usr/src/lib/libproc/common/Pbrand.c @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "libproc.h" + +char * +Pbrandname(struct ps_prochandle *P, char *buf, size_t buflen) +{ + long addr; + + if ((addr = Pgetauxval(P, AT_SUN_BRANDNAME)) == -1) + return (NULL); + + if (ps_pread(P, addr, buf, buflen) != PS_OK) + return (NULL); + + return (buf); +} diff --git a/usr/src/lib/libproc/common/Pcontrol.c b/usr/src/lib/libproc/common/Pcontrol.c index 00e1c9f0a6..e30d5758cb 100644 --- a/usr/src/lib/libproc/common/Pcontrol.c +++ b/usr/src/lib/libproc/common/Pcontrol.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -33,6 +32,7 @@ #include <ctype.h> #include <fcntl.h> #include <string.h> +#include <strings.h> #include <memory.h> #include <errno.h> #include <dirent.h> @@ -56,6 +56,7 @@ int _libproc_debug; /* set non-zero to enable debugging printfs */ sigset_t blockable_sigs; /* signals to block when we need to be safe */ static int minfd; /* minimum file descriptor returned by dupfd(fd, 0) */ +char procfs_path[PATH_MAX] = "/proc"; /* * Function prototypes for static routines in this module. @@ -97,6 +98,12 @@ _libproc_init(void) (void) sigdelset(&blockable_sigs, SIGSTOP); } +void +Pset_procfs_path(const char *path) +{ + (void) snprintf(procfs_path, sizeof (procfs_path), "%s", path); +} + /* * Call set_minfd() once before calling dupfd() several times. * We assume that the application will not reduce its current file @@ -168,7 +175,7 @@ Pxcreate(const char *file, /* executable file name */ size_t len) /* size of the path buffer */ { char execpath[PATH_MAX]; - char procname[100]; + char procname[PATH_MAX]; struct ps_prochandle *P; pid_t pid; int fd; @@ -238,7 +245,8 @@ Pxcreate(const char *file, /* executable file name */ /* * Open the /proc/pid files. */ - (void) sprintf(procname, "/proc/%d/", (int)pid); + (void) snprintf(procname, sizeof (procname), "%s/%d/", + procfs_path, (int)pid); fname = procname + strlen(procname); (void) set_minfd(); @@ -505,7 +513,7 @@ Pgrab(pid_t pid, int flags, int *perr) { struct ps_prochandle *P; int fd, omode; - char procname[100]; + char procname[PATH_MAX]; char *fname; int rc = 0; @@ -545,7 +553,8 @@ again: /* Come back here if we lose it in the Window of Vulnerability */ /* * Open the /proc/pid files */ - (void) sprintf(procname, "/proc/%d/", (int)pid); + (void) snprintf(procname, sizeof (procname), "%s/%d/", + procfs_path, (int)pid); fname = procname + strlen(procname); (void) set_minfd(); @@ -1264,7 +1273,7 @@ int Preopen(struct ps_prochandle *P) { int fd; - char procname[100]; + char procname[PATH_MAX]; char *fname; if (P->state == PS_DEAD || P->state == PS_IDLE) @@ -1275,7 +1284,8 @@ Preopen(struct ps_prochandle *P) Pdestroy_agent(P); } - (void) sprintf(procname, "/proc/%d/", (int)P->pid); + (void) snprintf(procname, sizeof (procname), "%s/%d/", + procfs_path, (int)P->pid); fname = procname + strlen(procname); (void) strcpy(fname, "as"); @@ -2653,13 +2663,13 @@ static prheader_t * read_lfile(struct ps_prochandle *P, const char *lname) { prheader_t *Lhp; - char lpath[64]; + char lpath[PATH_MAX]; struct stat64 statb; int fd; size_t size; ssize_t rval; - (void) snprintf(lpath, sizeof (lpath), "/proc/%d/%s", + (void) snprintf(lpath, sizeof (lpath), "%s/%d/%s", procfs_path, (int)P->status.pr_pid, lname); if ((fd = open(lpath, O_RDONLY)) < 0 || fstat64(fd, &statb) != 0) { if (fd >= 0) @@ -2931,7 +2941,7 @@ Lgrab(struct ps_prochandle *P, lwpid_t lwpid, int *perr) struct ps_lwphandle **Lp; struct ps_lwphandle *L; int fd; - char procname[100]; + char procname[PATH_MAX]; char *fname; int rc = 0; @@ -2974,7 +2984,8 @@ Lgrab(struct ps_prochandle *P, lwpid_t lwpid, int *perr) /* * Open the /proc/<pid>/lwp/<lwpid> files */ - (void) sprintf(procname, "/proc/%d/lwp/%d/", (int)P->pid, (int)lwpid); + (void) snprintf(procname, sizeof (procname), "%s/%d/lwp/%d/", + procfs_path, (int)P->pid, (int)lwpid); fname = procname + strlen(procname); (void) set_minfd(); diff --git a/usr/src/lib/libproc/common/Pcontrol.h b/usr/src/lib/libproc/common/Pcontrol.h index 12dfc1a078..ec105a7ad5 100644 --- a/usr/src/lib/libproc/common/Pcontrol.h +++ b/usr/src/lib/libproc/common/Pcontrol.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,6 +40,7 @@ #include <rtld_db.h> #include <libproc.h> #include <libctf.h> +#include <limits.h> #ifdef __cplusplus extern "C" { @@ -247,6 +247,7 @@ extern int Padd_mapping(struct ps_prochandle *, off64_t, file_info_t *, prmap_t *); extern void Psort_mappings(struct ps_prochandle *); +extern char procfs_path[PATH_MAX]; /* * Architecture-dependent definition of the breakpoint instruction. diff --git a/usr/src/lib/libproc/common/Pcore.c b/usr/src/lib/libproc/common/Pcore.c index eb55e20894..80b7e16311 100644 --- a/usr/src/lib/libproc/common/Pcore.c +++ b/usr/src/lib/libproc/common/Pcore.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -813,8 +812,10 @@ fake_up_symtab(struct ps_prochandle *P, const elf_file_header_t *ehdr, if (symtab->sh_addr == 0 || (mp = Paddr2mptr(P, symtab->sh_addr)) == NULL || (fp = mp->map_file) == NULL || - fp->file_symtab.sym_data != NULL) + fp->file_symtab.sym_data != NULL) { + dprintf("fake_up_symtab: invalid section\n"); return; + } if (P->status.pr_dmodel == PR_MODEL_ILP32) { struct { @@ -851,6 +852,7 @@ fake_up_symtab(struct ps_prochandle *P, const elf_file_header_t *ehdr, if (pread64(P->asfd, &b->data[off], b->shdr[1].sh_size, symtab->sh_offset) != b->shdr[1].sh_size) { + dprintf("fake_up_symtab: pread of symtab[1] failed\n"); free(b); return; } @@ -866,6 +868,7 @@ fake_up_symtab(struct ps_prochandle *P, const elf_file_header_t *ehdr, if (pread64(P->asfd, &b->data[off], b->shdr[2].sh_size, strtab->sh_offset) != b->shdr[2].sh_size) { + dprintf("fake_up_symtab: pread of symtab[2] failed\n"); free(b); return; } @@ -949,8 +952,11 @@ fake_up_symtab(struct ps_prochandle *P, const elf_file_header_t *ehdr, if ((scn = elf_getscn(fp->file_symtab.sym_elf, 1)) == NULL || (fp->file_symtab.sym_data = elf_getdata(scn, NULL)) == NULL || (scn = elf_getscn(fp->file_symtab.sym_elf, 2)) == NULL || - (data = elf_getdata(scn, NULL)) == NULL) + (data = elf_getdata(scn, NULL)) == NULL) { + dprintf("fake_up_symtab: failed to get section data at %p\n", + (void *)scn); goto err; + } fp->file_symtab.sym_strs = data->d_buf; fp->file_symtab.sym_strsz = data->d_size; @@ -1447,12 +1453,16 @@ core_iter_mapping(const rd_loadobj_t *rlp, struct ps_prochandle *P) Pbuild_file_symtab(P, fp); - if (fp->file_elf == NULL) + if (fp->file_elf == NULL) { + dprintf("core_iter_mapping: no symtab - going to next\n"); return (1); /* No symbol table; advance to next mapping */ + } /* - * Locate the start of a data segment associated with this file, - * name it after the file, and establish the mp->map_file link: + * Locate the start of a data segment associated with this file. + * Starting with that data segment, name all mappings that + * fall within this file's address range after the file and + * establish their mp->map_file links. */ if ((mp = core_find_data(P, fp->file_elf, fp->file_lo)) != NULL) { dprintf("found data for %s at %p (pr_offset 0x%llx)\n", @@ -1463,14 +1473,25 @@ core_iter_mapping(const rd_loadobj_t *rlp, struct ps_prochandle *P) if (mp->map_pmap.pr_vaddr > fp->file_lo->rl_bend) break; if (mp->map_file == NULL) { + dprintf("%s: associating segment at %p\n", + fp->file_pname, + (void *)mp->map_pmap.pr_vaddr); mp->map_file = fp; fp->file_ref++; + } else { + dprintf("%s: segment at %p already associated " + "with %s\n", fp->file_pname, + (void *)mp->map_pmap.pr_vaddr, + mp->map_file->file_pname); } if (!(mp->map_pmap.pr_mflags & MA_BREAK)) (void) strcpy(mp->map_pmap.pr_mapname, fp->file_pname); } + } else { + dprintf("core_iter_mapping: no data found for %s\n", + fp->file_pname); } return (1); /* Advance to next mapping */ @@ -1514,14 +1535,17 @@ core_load_shdrs(struct ps_prochandle *P, elf_file_t *efp) * Read the section header table from the core file and then iterate * over the section headers, converting each to a GElf_Shdr. */ - shdrs = malloc(efp->e_hdr.e_shnum * sizeof (GElf_Shdr)); - nbytes = efp->e_hdr.e_shnum * efp->e_hdr.e_shentsize; - buf = malloc(nbytes); - - if (shdrs == NULL || buf == NULL) { + if ((shdrs = malloc(efp->e_hdr.e_shnum * sizeof (GElf_Shdr))) == NULL) { dprintf("failed to malloc %u section headers: %s\n", (uint_t)efp->e_hdr.e_shnum, strerror(errno)); - free(buf); + return; + } + + nbytes = efp->e_hdr.e_shnum * efp->e_hdr.e_shentsize; + if ((buf = malloc(nbytes)) == NULL) { + dprintf("failed to malloc %d bytes: %s\n", (int)nbytes, + strerror(errno)); + free(shdrs); goto out; } diff --git a/usr/src/lib/libproc/common/Pexecname.c b/usr/src/lib/libproc/common/Pexecname.c index 3abe134e41..a2c2ccf574 100644 --- a/usr/src/lib/libproc/common/Pexecname.c +++ b/usr/src/lib/libproc/common/Pexecname.c @@ -34,6 +34,7 @@ #include <stdio.h> #include <errno.h> #include <unistd.h> +#include <libzonecfg.h> #include "Pcontrol.h" @@ -84,7 +85,7 @@ Pfindexec(struct ps_prochandle *P, const char *aout, char buf[PATH_MAX]; struct stat st; uintptr_t addr; - char *p, *q; + char *p = path, *q; if (P->execname) return (P->execname); /* Already found */ @@ -118,10 +119,14 @@ Pfindexec(struct ps_prochandle *P, const char *aout, * Second try: read the string pointed to by the AT_SUN_EXECNAME * auxv element, saved when the program was exec'd. If the full * pathname try_exec() forms fails, try again using just the - * basename appended to our cwd. + * basename appended to our cwd. If that also fails, and the process + * is in a zone, try again with the zone path instead of our cwd. */ if ((addr = Pgetauxval(P, AT_SUN_EXECNAME)) != (uintptr_t)-1L && Pread_string(P, path, sizeof (path), (off_t)addr) > 0) { + char zname[ZONENAME_MAX]; + char zpath[PATH_MAX]; + const psinfo_t *pi = Ppsinfo(P); if (try_exec(cwd, path, buf, isexec, isdata)) goto found; @@ -129,6 +134,14 @@ Pfindexec(struct ps_prochandle *P, const char *aout, if (strchr(path, '/') != NULL && (p = basename(path)) != NULL && try_exec(cwd, p, buf, isexec, isdata)) goto found; + + if (getzonenamebyid(pi->pr_zoneid, zname, + sizeof (zname)) != -1 && strcmp(zname, "global") != 0 && + zone_get_zonepath(zname, zpath, sizeof (zpath)) == Z_OK) { + (void) strcat(zpath, "/root"); + if (try_exec(zpath, p, buf, isexec, isdata)) + goto found; + } } /* @@ -245,7 +258,7 @@ Pexecname(struct ps_prochandle *P, char *buf, size_t buflen) * Try to get the path information first. */ (void) snprintf(exec_name, sizeof (exec_name), - "/proc/%d/path/a.out", (int)P->pid); + "%s/%d/path/a.out", procfs_path, (int)P->pid); if ((ret = readlink(exec_name, buf, buflen - 1)) > 0) { buf[ret] = '\0'; return (buf); @@ -256,7 +269,7 @@ Pexecname(struct ps_prochandle *P, char *buf, size_t buflen) * suggestions to the actual device and inode number. */ (void) snprintf(exec_name, sizeof (exec_name), - "/proc/%d/object/a.out", (int)P->pid); + "%s/%d/object/a.out", procfs_path, (int)P->pid); if (stat64(exec_name, &st) != 0 || !S_ISREG(st.st_mode)) return (NULL); @@ -267,7 +280,7 @@ Pexecname(struct ps_prochandle *P, char *buf, size_t buflen) * not changed its current directory since it was exec'd. */ (void) snprintf(proc_cwd, sizeof (proc_cwd), - "/proc/%d/path/cwd", (int)P->pid); + "%s/%d/path/cwd", procfs_path, (int)P->pid); if ((ret = readlink(proc_cwd, cwd, PATH_MAX - 1)) > 0) cwd[ret] = '\0'; diff --git a/usr/src/lib/libproc/common/Pisprocdir.c b/usr/src/lib/libproc/common/Pisprocdir.c index b617b2edda..70e341bcbe 100644 --- a/usr/src/lib/libproc/common/Pisprocdir.c +++ b/usr/src/lib/libproc/common/Pisprocdir.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1997-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -43,11 +42,11 @@ Pisprocdir(struct ps_prochandle *Pr, const char *dir) struct statvfs statvfsb; if (*dir == '/') - (void) snprintf(path, sizeof (path), "/proc/%d/root%s", - (int)Pr->pid, dir); + (void) snprintf(path, sizeof (path), "%s/%d/root%s", + procfs_path, (int)Pr->pid, dir); else - (void) snprintf(path, sizeof (path), "/proc/%d/cwd/%s", - (int)Pr->pid, dir); + (void) snprintf(path, sizeof (path), "%s/%d/cwd/%s", + procfs_path, (int)Pr->pid, dir); /* * We can't compare the statb.st_fstype string to "proc" because diff --git a/usr/src/lib/libproc/common/Plwpregs.c b/usr/src/lib/libproc/common/Plwpregs.c index bb16b50370..76f658a458 100644 --- a/usr/src/lib/libproc/common/Plwpregs.c +++ b/usr/src/lib/libproc/common/Plwpregs.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,6 +29,7 @@ #include <sys/uio.h> #include <string.h> #include <errno.h> +#include <limits.h> #include "Pcontrol.h" #include "P32ton.h" @@ -68,11 +68,11 @@ static int getlwpfile(struct ps_prochandle *P, lwpid_t lwpid, const char *fbase, void *rp, size_t n) { - char fname[64]; + char fname[PATH_MAX]; int fd; - (void) snprintf(fname, sizeof (fname), "/proc/%d/lwp/%d/%s", - (int)P->status.pr_pid, (int)lwpid, fbase); + (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/%s", + procfs_path, (int)P->status.pr_pid, (int)lwpid, fbase); if ((fd = open(fname, O_RDONLY)) >= 0) { if (read(fd, rp, n) > 0) { @@ -133,7 +133,7 @@ setlwpregs(struct ps_prochandle *P, lwpid_t lwpid, long cmd, const void *rp, size_t n) { iovec_t iov[2]; - char fname[64]; + char fname[PATH_MAX]; int fd; if (P->state != PS_STOP) { @@ -170,8 +170,8 @@ setlwpregs(struct ps_prochandle *P, lwpid_t lwpid, long cmd, * If the lwp we want is not the representative lwp, we need to * open the ctl file for that specific lwp. */ - (void) snprintf(fname, sizeof (fname), "/proc/%d/lwp/%d/lwpctl", - (int)P->status.pr_pid, (int)lwpid); + (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/lwpctl", + procfs_path, (int)P->status.pr_pid, (int)lwpid); if ((fd = open(fname, O_WRONLY)) >= 0) { if (writev(fd, iov, 2) > 0) { diff --git a/usr/src/lib/libproc/common/Pscantext.c b/usr/src/lib/libproc/common/Pscantext.c index 72d85c06f6..08470bcd22 100644 --- a/usr/src/lib/libproc/common/Pscantext.c +++ b/usr/src/lib/libproc/common/Pscantext.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -33,6 +32,7 @@ #include <unistd.h> #include <string.h> #include <errno.h> +#include <limits.h> #include "libproc.h" #include "Pcontrol.h" @@ -47,7 +47,7 @@ int Pscantext(struct ps_prochandle *P) { - char mapfile[100]; + char mapfile[PATH_MAX]; int mapfd; off_t offset; /* offset in text section */ off_t endoff; /* ending offset in text section */ @@ -80,7 +80,8 @@ Pscantext(struct ps_prochandle *P) } /* open the /proc/<pid>/map file */ - (void) sprintf(mapfile, "/proc/%d/map", (int)P->pid); + (void) snprintf(mapfile, sizeof (mapfile), "%s/%d/map", + procfs_path, (int)P->pid); if ((mapfd = open(mapfile, O_RDONLY)) < 0) { dprintf("failed to open %s: %s\n", mapfile, strerror(errno)); return (-1); diff --git a/usr/src/lib/libproc/common/Pservice.c b/usr/src/lib/libproc/common/Pservice.c index 6850696af4..cd43947171 100644 --- a/usr/src/lib/libproc/common/Pservice.c +++ b/usr/src/lib/libproc/common/Pservice.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -172,7 +171,7 @@ ps_lsetfpregs(struct ps_prochandle *P, lwpid_t lwpid, const prfpregset_t *regs) ps_err_e ps_lgetxregsize(struct ps_prochandle *P, lwpid_t lwpid, int *xrsize) { - char fname[64]; + char fname[PATH_MAX]; struct stat statb; if (P->state == PS_DEAD) { @@ -192,8 +191,8 @@ ps_lgetxregsize(struct ps_prochandle *P, lwpid_t lwpid, int *xrsize) return (PS_BADLID); } - (void) snprintf(fname, sizeof (fname), "/proc/%d/lwp/%d/xregs", - (int)P->status.pr_pid, (int)lwpid); + (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/xregs", + procfs_path, (int)P->status.pr_pid, (int)lwpid); if (stat(fname, &statb) != 0) return (PS_BADLID); @@ -320,6 +319,12 @@ ps_pauxv(struct ps_prochandle *P, const auxv_t **aux) return (PS_OK); } +ps_err_e +ps_pbrandname(struct ps_prochandle *P, char *buf, size_t len) +{ + return (Pbrandname(P, buf, len) ? PS_OK : PS_ERR); +} + /* * Search for a symbol by name and return the corresponding address. */ diff --git a/usr/src/lib/libproc/common/Psymtab.c b/usr/src/lib/libproc/common/Psymtab.c index c8c00fb761..d3fe42f180 100644 --- a/usr/src/lib/libproc/common/Psymtab.c +++ b/usr/src/lib/libproc/common/Psymtab.c @@ -26,6 +26,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" +#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> @@ -287,15 +288,20 @@ map_iter(const rd_loadobj_t *lop, void *cd) dprintf("encountered rd object at %p\n", (void *)lop->rl_base); - if ((mptr = Paddr2mptr(P, lop->rl_base)) == NULL) + if ((mptr = Paddr2mptr(P, lop->rl_base)) == NULL) { + dprintf("map_iter: base address doesn't match any mapping\n"); return (1); /* Base address does not match any mapping */ + } if ((fptr = mptr->map_file) == NULL && - (fptr = file_info_new(P, mptr)) == NULL) + (fptr = file_info_new(P, mptr)) == NULL) { + dprintf("map_iter: failed to allocate a new file_info_t\n"); return (1); /* Failed to allocate a new file_info_t */ + } if ((fptr->file_lo == NULL) && (fptr->file_lo = malloc(sizeof (rd_loadobj_t))) == NULL) { + dprintf("map_iter: failed to allocate rd_loadobj_t\n"); file_info_free(P, fptr); return (1); /* Failed to allocate rd_loadobj_t */ } @@ -314,6 +320,9 @@ map_iter(const rd_loadobj_t *lop, void *cd) if (Pread_string(P, buf, sizeof (buf), lop->rl_nameaddr) > 0) { if ((fptr->file_lname = strdup(buf)) != NULL) fptr->file_lbase = basename(fptr->file_lname); + } else { + dprintf("map_iter: failed to read string at %p\n", + (void *)lop->rl_nameaddr); } dprintf("loaded rd object %s lmid %lx\n", @@ -341,17 +350,13 @@ map_set(struct ps_prochandle *P, map_info_t *mptr, const char *lname) (void) memset(fptr->file_lo, 0, sizeof (rd_loadobj_t)); fptr->file_lo->rl_base = mptr->map_pmap.pr_vaddr; fptr->file_lo->rl_bend = - mptr->map_pmap.pr_vaddr + mptr->map_pmap.pr_size; + mptr->map_pmap.pr_vaddr + mptr->map_pmap.pr_size; fptr->file_lo->rl_plt_base = fptr->file_plt_base; fptr->file_lo->rl_plt_size = fptr->file_plt_size; - if (fptr->file_lname) { - free(fptr->file_lname); - fptr->file_lname = NULL; - } - - if ((fptr->file_lname = strdup(lname)) != NULL) + if (fptr->file_lname == NULL && + (fptr->file_lname = strdup(lname)) != NULL) fptr->file_lbase = basename(fptr->file_lname); } @@ -385,7 +390,7 @@ load_static_maps(struct ps_prochandle *P) void Pupdate_maps(struct ps_prochandle *P) { - char mapfile[64]; + char mapfile[PATH_MAX]; int mapfd; struct stat statb; prmap_t *Pmap = NULL; @@ -401,7 +406,8 @@ Pupdate_maps(struct ps_prochandle *P) Preadauxvec(P); - (void) sprintf(mapfile, "/proc/%d/map", (int)P->pid); + (void) snprintf(mapfile, sizeof (mapfile), "%s/%d/map", + procfs_path, (int)P->pid); if ((mapfd = open(mapfile, O_RDONLY)) < 0 || fstat(mapfd, &statb) != 0 || statb.st_size < sizeof (prmap_t) || @@ -803,7 +809,8 @@ Preadauxvec(struct ps_prochandle *P) P->nauxv = 0; } - (void) sprintf(auxfile, "/proc/%d/auxv", (int)P->pid); + (void) snprintf(auxfile, sizeof (auxfile), "%s/%d/auxv", + procfs_path, (int)P->pid); if ((fd = open(auxfile, O_RDONLY)) < 0) return; @@ -928,7 +935,7 @@ build_map_symtab(struct ps_prochandle *P, map_info_t *mptr) * fptr->file_map to be set in Pbuild_file_symtab. librtld_db may be * unaware of what's going on in the rare case that a legitimate ELF * file has been mmap(2)ed into the process address space *without* - * the use of dlopen(3x). Why would this happen? See pwdx ... :) + * the use of dlopen(3x). */ if (fptr->file_map == NULL) fptr->file_map = mptr; @@ -1128,6 +1135,11 @@ found_shdr: dyn.d_tag == DT_CHECKSUM) goto found_cksum; } + + /* + * The in-memory ELF has no DT_CHECKSUM section, but we will report it + * as matching the file anyhow. + */ return (0); found_cksum: @@ -1321,7 +1333,7 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) uint32_t off; size_t pltsz = 0, pltentsz; - if (read_ehdr32(P, &ehdr, &phnum, addr) != 0 || + if ((read_ehdr32(P, &ehdr, &phnum, addr) != 0) || read_dynamic_phdr32(P, &ehdr, phnum, &phdr, addr) != 0) return (NULL); @@ -1337,6 +1349,14 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) return (NULL); } + /* + * Allow librtld_db the opportunity to "fix" the program + * headers, if it needs to, before we process them. + */ + if (P->rap != NULL && ehdr.e_type == ET_DYN) { + rd_fix_phdrs(P->rap, dp, phdr.p_filesz, addr); + } + for (i = 0; i < phdr.p_filesz / sizeof (Elf32_Dyn); i++) { switch (dp[i].d_tag) { /* @@ -1422,8 +1442,11 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) /* .dynsym section */ size += sizeof (Elf32_Shdr); if (Pread(P, &nchain, sizeof (nchain), - d[DI_HASH]->d_un.d_ptr + 4) != sizeof (nchain)) + d[DI_HASH]->d_un.d_ptr + 4) != sizeof (nchain)) { + dprintf("Pread of .dynsym at %lx failed\n", + (long)(d[DI_HASH]->d_un.d_val + 4)); goto bad32; + } size += sizeof (Elf32_Sym) * nchain; /* .dynstr section */ @@ -1446,8 +1469,10 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) Elf32_Rela r[2]; if (Pread(P, r, sizeof (r), jmprel + - sizeof (r[0]) * ndx) != sizeof (r)) + sizeof (r[0]) * ndx) != sizeof (r)) { + dprintf("Pread of DT_RELA failed\n"); goto bad32; + } penult = r[0].r_offset; ult = r[1].r_offset; @@ -1457,12 +1482,15 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) Elf32_Rel r[2]; if (Pread(P, r, sizeof (r), jmprel + - sizeof (r[0]) * ndx) != sizeof (r)) + sizeof (r[0]) * ndx) != sizeof (r)) { + dprintf("Pread of DT_REL failed\n"); goto bad32; + } penult = r[0].r_offset; ult = r[1].r_offset; } else { + dprintf(".plt: unknown jmprel value\n"); goto bad32; } @@ -1505,6 +1533,7 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) if (Pread(P, &elfdata[ep->e_phoff], phnum * ep->e_phentsize, addr + ehdr.e_phoff) != phnum * ep->e_phentsize) { free(elfdata); + dprintf("failed to read program headers\n"); goto bad32; } @@ -1550,6 +1579,8 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) if (Pread(P, &elfdata[off], sp->sh_size, d[DI_SYMTAB]->d_un.d_ptr) != sp->sh_size) { free(elfdata); + dprintf("failed to read .dynsym at %lx\n", + (long)d[DI_SYMTAB]->d_un.d_ptr); goto bad32; } @@ -1575,6 +1606,7 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) if (Pread(P, &elfdata[off], sp->sh_size, d[DI_STRTAB]->d_un.d_ptr) != sp->sh_size) { free(elfdata); + dprintf("failed to read .dynstr\n"); goto bad32; } off += roundup(sp->sh_size, 4); @@ -1620,6 +1652,7 @@ fake_elf(struct ps_prochandle *P, file_info_t *fptr) if (Pread(P, &elfdata[off], sp->sh_size, d[DI_PLTGOT]->d_un.d_ptr) != sp->sh_size) { free(elfdata); + dprintf("failed to read .plt\n"); goto bad32; } off += roundup(sp->sh_size, 4); @@ -1768,8 +1801,13 @@ bad32: Elf64_Rela r[2]; if (Pread(P, r, sizeof (r), jmprel + - sizeof (r[0]) * ndx) != sizeof (r)) + sizeof (r[0]) * ndx) != sizeof (r)) { + dprintf("Pread jmprel DT_RELA at %p " + "failed\n", + (void *)(jmprel + + sizeof (r[0]) * ndx)); goto bad64; + } penult = r[0].r_offset; ult = r[1].r_offset; @@ -1779,12 +1817,19 @@ bad32: Elf64_Rel r[2]; if (Pread(P, r, sizeof (r), jmprel + - sizeof (r[0]) * ndx) != sizeof (r)) + sizeof (r[0]) * ndx) != sizeof (r)) { + dprintf("Pread jmprel DT_REL at %p " + "failed\n", + (void *)(jmprel + + sizeof (r[0]) * ndx)); goto bad64; + } penult = r[0].r_offset; ult = r[1].r_offset; } else { + dprintf("DT_PLTREL value %p unknown\n", + (void *)d[DI_PLTREL]->d_un.d_ptr); goto bad64; } @@ -2172,7 +2217,8 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) fptr->file_lname ? fptr->file_lname : fptr->file_pname); } else { (void) snprintf(objectfile, sizeof (objectfile), - "/proc/%d/object/%s", (int)P->pid, fptr->file_pname); + "%s/%d/object/%s", + procfs_path, (int)P->pid, fptr->file_pname); } /* @@ -2203,8 +2249,10 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) elf_getshstrndx(elf, &shstrndx) == 0 || (scn = elf_getscn(elf, shstrndx)) == NULL || (shdata = elf_getdata(scn, NULL)) == NULL) { + int err = elf_errno(); + dprintf("failed to process ELF file %s: %s\n", - objectfile, elf_errmsg(elf_errno())); + objectfile, (err == 0) ? "<null>" : elf_errmsg(err)); if ((elf = fake_elf(P, fptr)) == NULL || elf_kind(elf) != ELF_K_ELF || @@ -2264,14 +2312,22 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) * pointer, and name. We use this for handling sh_link values below. */ for (cp = cache + 1, scn = NULL; scn = elf_nextscn(elf, scn); cp++) { - if (gelf_getshdr(scn, &cp->c_shdr) == NULL) + if (gelf_getshdr(scn, &cp->c_shdr) == NULL) { + dprintf("Pbuild_file_symtab: Failed to get section " + "header\n"); goto bad; /* Failed to get section header */ + } - if ((cp->c_data = elf_getdata(scn, NULL)) == NULL) + if ((cp->c_data = elf_getdata(scn, NULL)) == NULL) { + dprintf("Pbuild_file_symtab: Failed to get section " + "data\n"); goto bad; /* Failed to get section data */ + } - if (cp->c_shdr.sh_name >= shdata->d_size) + if (cp->c_shdr.sh_name >= shdata->d_size) { + dprintf("Pbuild_file_symtab: corrupt section name"); goto bad; /* Corrupt section name */ + } cp->c_name = (const char *)shdata->d_buf + cp->c_shdr.sh_name; } @@ -2286,7 +2342,6 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) if (shp->sh_type == SHT_SYMTAB || shp->sh_type == SHT_DYNSYM) { sym_tbl_t *symp = shp->sh_type == SHT_SYMTAB ? &fptr->file_symtab : &fptr->file_dynsym; - /* * It's possible that the we already got the symbol * table from the core file itself. Either the file @@ -2298,6 +2353,8 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) * check isn't essential, but it's a good idea. */ if (symp->sym_data == NULL) { + dprintf("Symbol table found for %s\n", + objectfile); symp->sym_data = cp->c_data; symp->sym_symn = shp->sh_size / shp->sh_entsize; symp->sym_strs = @@ -2306,14 +2363,15 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) cache[shp->sh_link].c_data->d_size; symp->sym_hdr = cp->c_shdr; symp->sym_strhdr = cache[shp->sh_link].c_shdr; + } else { + dprintf("Symbol table already there for %s\n", + objectfile); } } else if (shp->sh_type == SHT_DYNAMIC) { dyn = cp; - } else if (strcmp(cp->c_name, ".plt") == 0) { plt = cp; - } else if (strcmp(cp->c_name, ".SUNW_ctf") == 0) { /* * Skip over bogus CTF sections so they don't come back @@ -2347,8 +2405,8 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) if (fptr->file_etype == ET_DYN) { fptr->file_dyn_base = fptr->file_map->map_pmap.pr_vaddr - fptr->file_map->map_pmap.pr_offset; - dprintf("setting file_dyn_base for %s to %p\n", - objectfile, (void *)fptr->file_dyn_base); + dprintf("setting file_dyn_base for %s to %lx\n", + objectfile, (long)fptr->file_dyn_base); } /* @@ -2371,8 +2429,8 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) */ if (fptr->file_etype == ET_DYN && fptr->file_lo->rl_base != fptr->file_dyn_base) { - dprintf("resetting file_dyn_base for %s to %p\n", - objectfile, (void *)fptr->file_lo->rl_base); + dprintf("resetting file_dyn_base for %s to %lx\n", + objectfile, (long)fptr->file_lo->rl_base); fptr->file_dyn_base = fptr->file_lo->rl_base; } @@ -2408,6 +2466,8 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) for (i = 0; i < ndyn; i++) { if (gelf_getdyn(dyn->c_data, i, &d) != NULL && d.d_tag == DT_JMPREL) { + dprintf("DT_JMPREL is %p\n", + (void *)(uintptr_t)d.d_un.d_ptr); fptr->file_jmp_rel = d.d_un.d_ptr + fptr->file_dyn_base; break; @@ -2533,6 +2593,13 @@ object_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *objname) uint_t i; /* + * If we have no rtld_db, then always treat a request as one for all + * link maps. + */ + if (P->rap == NULL) + lmid = PR_LMID_EVERY; + + /* * First pass: look for exact matches of the entire pathname or * basename (cases 1 and 2 above): */ @@ -2610,10 +2677,8 @@ object_name_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *name) mptr = P->map_exec; else if (name == PR_OBJ_LDSO) mptr = P->map_ldso; - else if (Prd_agent(P) != NULL || P->state == PS_IDLE) - mptr = object_to_map(P, lmid, name); else - mptr = NULL; + mptr = object_to_map(P, lmid, name); return (mptr); } diff --git a/usr/src/lib/libproc/common/Psyscall.c b/usr/src/lib/libproc/common/Psyscall.c index c34a17a04c..1261eb49b4 100644 --- a/usr/src/lib/libproc/common/Psyscall.c +++ b/usr/src/lib/libproc/common/Psyscall.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -80,7 +79,7 @@ int Pcreate_agent(struct ps_prochandle *P) { int fd; - char pathname[100]; + char pathname[PATH_MAX]; char *fname; struct { long cmd; @@ -123,7 +122,8 @@ Pcreate_agent(struct ps_prochandle *P) (void) Pstopstatus(P, PCNULL, 0); /* open the agent LWP files */ - (void) sprintf(pathname, "/proc/%d/lwp/agent/", (int)P->pid); + (void) snprintf(pathname, sizeof (pathname), "%s/%d/lwp/agent/", + procfs_path, (int)P->pid); fname = pathname + strlen(pathname); (void) set_minfd(); diff --git a/usr/src/lib/libproc/common/libproc.h b/usr/src/lib/libproc/common/libproc.h index b2f37f45d7..07e58fa05c 100644 --- a/usr/src/lib/libproc/common/libproc.h +++ b/usr/src/lib/libproc/common/libproc.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -201,6 +200,7 @@ extern void Prelease(struct ps_prochandle *, int); extern void Pfree(struct ps_prochandle *); extern int Pasfd(struct ps_prochandle *); +extern char *Pbrandname(struct ps_prochandle *, char *, size_t); extern int Pctlfd(struct ps_prochandle *); extern int Pcreate_agent(struct ps_prochandle *); extern void Pdestroy_agent(struct ps_prochandle *); @@ -495,6 +495,8 @@ extern char *Pgetenv(struct ps_prochandle *, const char *, char *, size_t); extern long Pgetauxval(struct ps_prochandle *, int); extern const auxv_t *Pgetauxvec(struct ps_prochandle *); +extern void Pset_procfs_path(const char *); + /* * Symbol table iteration interface. The special lmid constants LM_ID_BASE, * LM_ID_LDSO, and PR_LMID_EVERY may be used with Psymbol_iter_by_lmid. diff --git a/usr/src/lib/libproc/common/mapfile-vers b/usr/src/lib/libproc/common/mapfile-vers index f3c517dcf5..ef256570ce 100644 --- a/usr/src/lib/libproc/common/mapfile-vers +++ b/usr/src/lib/libproc/common/mapfile-vers @@ -219,6 +219,7 @@ SUNWprivate_1.1 { pr_unlink; pr_waitid; pr_zmap; + Pset_procfs_path; Psetbkpt; Psetcred; Psetfault; @@ -238,6 +239,7 @@ SUNWprivate_1.1 { ps_lsetregs; ps_lstop; ps_pauxv; + ps_pbrandname; ps_pcontinue; ps_pdmodel; ps_pdread; diff --git a/usr/src/lib/libproc/common/proc_arg.c b/usr/src/lib/libproc/common/proc_arg.c index 2a79b016c2..c25a89b944 100644 --- a/usr/src/lib/libproc/common/proc_arg.c +++ b/usr/src/lib/libproc/common/proc_arg.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -39,21 +38,22 @@ #include <errno.h> #include <dirent.h> -#include "libproc.h" +#include "Pcontrol.h" static int open_psinfo(const char *arg, int *perr) { /* - * Allocate enough space for "/proc/" + arg + "/psinfo" + * Allocate enough space for procfs_path + arg + "/psinfo" */ - char *path = alloca(strlen(arg) + 14); + char *path = alloca(strlen(arg) + strlen(procfs_path) + 9); struct stat64 st; int fd; if (strchr(arg, '/') == NULL) { - (void) strcpy(path, "/proc/"); + (void) strcpy(path, procfs_path); + (void) strcat(path, "/"); (void) strcat(path, arg); } else (void) strcpy(path, arg); @@ -430,7 +430,7 @@ proc_walk(proc_walk_f *func, void *arg, int flag) DIR *procdir; struct dirent *dirent; char *errptr; - char pidstr[80]; + char pidstr[PATH_MAX]; psinfo_t psinfo; lwpsinfo_t *lwpsinfo; prheader_t prheader; @@ -445,7 +445,7 @@ proc_walk(proc_walk_f *func, void *arg, int flag) errno = EINVAL; return (-1); } - if ((procdir = opendir("/proc")) == NULL) + if ((procdir = opendir(procfs_path)) == NULL) return (-1); while (dirent = readdir(procdir)) { if (dirent->d_name[0] == '.') /* skip . and .. */ @@ -455,7 +455,7 @@ proc_walk(proc_walk_f *func, void *arg, int flag) continue; /* PR_WALK_PROC case */ (void) snprintf(pidstr, sizeof (pidstr), - "/proc/%ld/psinfo", pid); + "%s/%ld/psinfo", procfs_path, pid); fd = open(pidstr, O_RDONLY); if (fd < 0) continue; @@ -471,7 +471,7 @@ proc_walk(proc_walk_f *func, void *arg, int flag) } /* PR_WALK_LWP case */ (void) snprintf(pidstr, sizeof (pidstr), - "/proc/%ld/lpsinfo", pid); + "%s/%ld/lpsinfo", procfs_path, pid); fd = open(pidstr, O_RDONLY); if (fd < 0) continue; diff --git a/usr/src/lib/libproc/common/proc_get_info.c b/usr/src/lib/libproc/common/proc_get_info.c index d4426f7cc0..7fb88c4212 100644 --- a/usr/src/lib/libproc/common/proc_get_info.c +++ b/usr/src/lib/libproc/common/proc_get_info.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,7 +30,9 @@ #include <unistd.h> #include <fcntl.h> #include <string.h> -#include "libproc.h" +#include <limits.h> + +#include "Pcontrol.h" /* * These several routines simply get the indicated /proc structures @@ -50,13 +51,14 @@ int proc_get_cred(pid_t pid, prcred_t *credp, int ngroups) { - char fname[64]; + char fname[PATH_MAX]; int fd; int rv = -1; ssize_t minsize = sizeof (*credp) - sizeof (gid_t); size_t size = minsize + ngroups * sizeof (gid_t); - (void) snprintf(fname, sizeof (fname), "/proc/%d/cred", (int)pid); + (void) snprintf(fname, sizeof (fname), "%s/%d/cred", + procfs_path, (int)pid); if ((fd = open(fname, O_RDONLY)) >= 0) { if (read(fd, credp, size) >= minsize) rv = 0; @@ -71,12 +73,13 @@ proc_get_cred(pid_t pid, prcred_t *credp, int ngroups) prpriv_t * proc_get_priv(pid_t pid) { - char fname[64]; + char fname[PATH_MAX]; int fd; struct stat statb; prpriv_t *rv = NULL; - (void) snprintf(fname, sizeof (fname), "/proc/%d/priv", (int)pid); + (void) snprintf(fname, sizeof (fname), "%s/%d/priv", + procfs_path, (int)pid); if ((fd = open(fname, O_RDONLY)) >= 0) { if (fstat(fd, &statb) != 0 || (rv = malloc(statb.st_size)) == NULL || @@ -99,13 +102,14 @@ proc_get_priv(pid_t pid) int proc_get_ldt(pid_t pid, struct ssd *pldt, int nldt) { - char fname[64]; + char fname[PATH_MAX]; int fd; struct stat statb; size_t size; ssize_t ssize; - (void) snprintf(fname, sizeof (fname), "/proc/%d/ldt", (int)pid); + (void) snprintf(fname, sizeof (fname), "%s/%d/ldt", + procfs_path, (int)pid); if ((fd = open(fname, O_RDONLY)) < 0) return (-1); @@ -131,11 +135,12 @@ proc_get_ldt(pid_t pid, struct ssd *pldt, int nldt) int proc_get_psinfo(pid_t pid, psinfo_t *psp) { - char fname[64]; + char fname[PATH_MAX]; int fd; int rv = -1; - (void) snprintf(fname, sizeof (fname), "/proc/%d/psinfo", (int)pid); + (void) snprintf(fname, sizeof (fname), "%s/%d/psinfo", + procfs_path, (int)pid); if ((fd = open(fname, O_RDONLY)) >= 0) { if (read(fd, psp, sizeof (*psp)) == sizeof (*psp)) rv = 0; @@ -147,11 +152,12 @@ proc_get_psinfo(pid_t pid, psinfo_t *psp) int proc_get_status(pid_t pid, pstatus_t *psp) { - char fname[64]; + char fname[PATH_MAX]; int fd; int rv = -1; - (void) snprintf(fname, sizeof (fname), "/proc/%d/status", (int)pid); + (void) snprintf(fname, sizeof (fname), "%s/%d/status", + procfs_path, (int)pid); if ((fd = open(fname, O_RDONLY)) >= 0) { if (read(fd, psp, sizeof (*psp)) == sizeof (*psp)) rv = 0; @@ -169,11 +175,12 @@ proc_get_status(pid_t pid, pstatus_t *psp) int proc_get_auxv(pid_t pid, auxv_t *pauxv, int naux) { - char fname[64]; + char fname[PATH_MAX]; int fd; int rv = -1; - (void) snprintf(fname, sizeof (fname), "/proc/%d/auxv", (int)pid); + (void) snprintf(fname, sizeof (fname), "%s/%d/auxv", + procfs_path, (int)pid); if ((fd = open(fname, O_RDONLY)) >= 0) { if ((rv = read(fd, pauxv, naux * sizeof (auxv_t))) >= 0) rv /= sizeof (auxv_t); diff --git a/usr/src/lib/libproc/common/proc_names.c b/usr/src/lib/libproc/common/proc_names.c index 249b9745a3..5c9cd365aa 100644 --- a/usr/src/lib/libproc/common/proc_names.c +++ b/usr/src/lib/libproc/common/proc_names.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -156,7 +155,7 @@ static const char *const systable[] = { "kill", /* 37 */ "fstatfs", /* 38 */ "pgrpsys", /* 39 */ - NULL, /* 40 was xenix */ + "uucopystr", /* 40 */ "dup", /* 41 */ "pipe", /* 42 */ "times", /* 43 */ @@ -296,7 +295,7 @@ static const char *const systable[] = { "pwrite", /* 174 */ "llseek", /* 175 */ "inst_sync", /* 176 */ - NULL, /* 177 */ + "brand", /* 177 */ "kaio", /* 178 */ "cpc", /* 179 */ "lgrpsys", /* 180 */ @@ -373,7 +372,7 @@ static const char *const systable[] = { "lwp_mutex_trylock", /* 251 */ "lwp_mutex_init", /* 252 */ "cladm", /* 253 */ - NULL, /* 254 */ + "uucopy", /* 254 */ "umount2" /* 255 */ }; |