summaryrefslogtreecommitdiff
path: root/usr/src/lib/libproc/common
diff options
context:
space:
mode:
authornn35248 <none@none>2006-09-11 22:51:59 -0700
committernn35248 <none@none>2006-09-11 22:51:59 -0700
commit9acbbeaf2a1ffe5c14b244867d427714fab43c5c (patch)
treed1ecd54896325c19a463220e9cbc50864874fc82 /usr/src/lib/libproc/common
parentda51466dc253d7c98dda4956059042bd0c476328 (diff)
downloadillumos-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.c42
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.c37
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.h9
-rw-r--r--usr/src/lib/libproc/common/Pcore.c54
-rw-r--r--usr/src/lib/libproc/common/Pexecname.c23
-rw-r--r--usr/src/lib/libproc/common/Pisprocdir.c15
-rw-r--r--usr/src/lib/libproc/common/Plwpregs.c20
-rw-r--r--usr/src/lib/libproc/common/Pscantext.c13
-rw-r--r--usr/src/lib/libproc/common/Pservice.c19
-rw-r--r--usr/src/lib/libproc/common/Psymtab.c133
-rw-r--r--usr/src/lib/libproc/common/Psyscall.c12
-rw-r--r--usr/src/lib/libproc/common/libproc.h10
-rw-r--r--usr/src/lib/libproc/common/mapfile-vers2
-rw-r--r--usr/src/lib/libproc/common/proc_arg.c24
-rw-r--r--usr/src/lib/libproc/common/proc_get_info.c41
-rw-r--r--usr/src/lib/libproc/common/proc_names.c13
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 */
};