annotate agent/src/os/bsd/ps_proc.c @ 4582:b24386206122

Made all vm builds go into subdirectories, even product builds to simplify building the various types of VMs (server, client and graal). Made HotSpot build jobs use the number of CPUs on the host machine.
author Doug Simon <doug.simon@oracle.com>
date Mon, 13 Feb 2012 23:13:37 +0100
parents f08d439fab8c
children 2394a89e89f4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1 /*
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
4 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
7 * published by the Free Software Foundation.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
8 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
13 * accompanied this code).
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
14 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
18 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
21 * questions.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
22 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
23 */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
24
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
25 #include <limits.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
26 #include <stdio.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
27 #include <stdlib.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
28 #include <string.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
29 #include <errno.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
30 #include <sys/types.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
31 #include <sys/wait.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
32 #include <sys/ptrace.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
33 #include <sys/param.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
34 #include <sys/user.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
35 #include <elf.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
36 #include <sys/elf_common.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
37 #include <sys/link_elf.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
38 #include <libutil.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
39 #include "libproc_impl.h"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
40 #include "elfmacros.h"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
41
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
42 // This file has the libproc implementation specific to live process
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
43 // For core files, refer to ps_core.c
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
44
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
45 static inline uintptr_t align(uintptr_t ptr, size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
46 return (ptr & ~(size - 1));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
47 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
48
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
49 // ---------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
50 // ptrace functions
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
51 // ---------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
52
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
53 // read "size" bytes of data from "addr" within the target process.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
54 // unlike the standard ptrace() function, process_read_data() can handle
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
55 // unaligned address - alignment check, if required, should be done
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
56 // before calling process_read_data.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
57
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
58 static bool process_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
59 int rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
60 size_t i, words;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
61 uintptr_t end_addr = addr + size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
62 uintptr_t aligned_addr = align(addr, sizeof(int));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
63
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
64 if (aligned_addr != addr) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
65 char *ptr = (char *)&rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
66 errno = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
67 rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
68 if (errno) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
69 print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
70 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
71 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
72 for (; aligned_addr != addr; aligned_addr++, ptr++);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
73 for (; ((intptr_t)aligned_addr % sizeof(int)) && aligned_addr < end_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
74 aligned_addr++)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
75 *(buf++) = *(ptr++);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
76 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
77
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
78 words = (end_addr - aligned_addr) / sizeof(int);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
79
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
80 // assert((intptr_t)aligned_addr % sizeof(int) == 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
81 for (i = 0; i < words; i++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
82 errno = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
83 rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
84 if (errno) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
85 print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
86 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
87 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
88 *(int *)buf = rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
89 buf += sizeof(int);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
90 aligned_addr += sizeof(int);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
91 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
92
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
93 if (aligned_addr != end_addr) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
94 char *ptr = (char *)&rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
95 errno = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
96 rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
97 if (errno) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
98 print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
99 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
100 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
101 for (; aligned_addr != end_addr; aligned_addr++)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
102 *(buf++) = *(ptr++);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
103 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
104 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
105 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
106
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
107 // null implementation for write
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
108 static bool process_write_data(struct ps_prochandle* ph,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
109 uintptr_t addr, const char *buf , size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
110 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
111 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
112
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
113 // "user" should be a pointer to a reg
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
114 static bool process_get_lwp_regs(struct ps_prochandle* ph, pid_t pid, struct reg *user) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
115 // we have already attached to all thread 'pid's, just use ptrace call
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
116 // to get regset now. Note that we don't cache regset upfront for processes.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
117 if (ptrace(PT_GETREGS, pid, (caddr_t) user, 0) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
118 print_debug("ptrace(PTRACE_GETREGS, ...) failed for lwp %d\n", pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
119 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
120 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
121 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
122 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
123
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
124 // fill in ptrace_lwpinfo for lid
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
125 static bool process_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
126 errno = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
127 ptrace(PT_LWPINFO, lwp_id, linfo, sizeof(struct ptrace_lwpinfo));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
128
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
129 return (errno == 0)? true: false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
130 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
131
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
132 // attach to a process/thread specified by "pid"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
133 static bool ptrace_attach(pid_t pid) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
134 if (ptrace(PT_ATTACH, pid, NULL, 0) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
135 print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
136 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
137 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
138 int ret;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
139 int status;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
140 do {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
141 // Wait for debuggee to stop.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
142 ret = waitpid(pid, &status, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
143 if (ret >= 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
144 if (WIFSTOPPED(status)) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
145 // Debuggee stopped.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
146 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
147 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
148 print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
149 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
150 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
151 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
152 switch (errno) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
153 case EINTR:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
154 continue;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
155 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
156 case ECHILD:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
157 print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
158 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
159 case EINVAL:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
160 print_debug("waitpid() failed. Invalid options argument.\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
161 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
162 default:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
163 print_debug("waitpid() failed. Unexpected error %d\n",errno);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
164 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
165 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
166 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
167 } while(true);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
168 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
169 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
170
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
171 // -------------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
172 // functions for obtaining library information
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
173 // -------------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
174
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
175 // callback for read_thread_info
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
176 static bool add_new_thread(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
177 return add_thread_info(ph, pthread_id, lwp_id) != NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
178 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
179
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
180 #if defined(__FreeBSD__) && __FreeBSD_version < 701000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
181 /*
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
182 * TEXT_START_ADDR from binutils/ld/emulparams/<arch_spec>.sh
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
183 * Not the most robust but good enough.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
184 */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
185
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
186 #if defined(amd64) || defined(x86_64)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
187 #define TEXT_START_ADDR 0x400000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
188 #elif defined(i386)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
189 #define TEXT_START_ADDR 0x8048000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
190 #else
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
191 #error TEXT_START_ADDR not defined
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
192 #endif
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
193
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
194 #define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
195
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
196 uintptr_t linkmap_addr(struct ps_prochandle *ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
197 uintptr_t ehdr_addr, phdr_addr, dyn_addr, dmap_addr, lmap_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
198 ELF_EHDR ehdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
199 ELF_PHDR *phdrs, *phdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
200 ELF_DYN *dyns, *dyn;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
201 struct r_debug dmap;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
202 unsigned long hdrs_size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
203 unsigned int i;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
204
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
205 /* read ELF_EHDR at TEXT_START_ADDR and validate */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
206
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
207 ehdr_addr = (uintptr_t)TEXT_START_ADDR;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
208
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
209 if (process_read_data(ph, ehdr_addr, (char *)&ehdr, sizeof(ehdr)) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
210 print_debug("process_read_data failed for ehdr_addr %p\n", ehdr_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
211 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
212 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
213
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
214 if (!IS_ELF(ehdr) ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
215 ehdr.e_ident[EI_CLASS] != ELF_TARG_CLASS ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
216 ehdr.e_ident[EI_DATA] != ELF_TARG_DATA ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
217 ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
218 ehdr.e_phentsize != sizeof(ELF_PHDR) ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
219 ehdr.e_version != ELF_TARG_VER ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
220 ehdr.e_machine != ELF_TARG_MACH) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
221 print_debug("not an ELF_EHDR at %p\n", ehdr_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
222 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
223 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
224
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
225 /* allocate space for all ELF_PHDR's and read */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
226
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
227 phdr_addr = ehdr_addr + ehdr.e_phoff;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
228 hdrs_size = ehdr.e_phnum * sizeof(ELF_PHDR);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
229
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
230 if ((phdrs = malloc(hdrs_size)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
231 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
232
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
233 if (process_read_data(ph, phdr_addr, (char *)phdrs, hdrs_size) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
234 print_debug("process_read_data failed for phdr_addr %p\n", phdr_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
235 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
236 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
237
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
238 /* find PT_DYNAMIC section */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
239
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
240 for (i = 0, phdr = phdrs; i < ehdr.e_phnum; i++, phdr++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
241 if (phdr->p_type == PT_DYNAMIC)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
242 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
243 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
244
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
245 if (i >= ehdr.e_phnum) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
246 print_debug("PT_DYNAMIC section not found!\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
247 free(phdrs);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
248 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
249 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
250
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
251 /* allocate space and read in ELF_DYN headers */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
252
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
253 dyn_addr = phdr->p_vaddr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
254 hdrs_size = phdr->p_memsz;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
255 free(phdrs);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
256
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
257 if ((dyns = malloc(hdrs_size)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
258 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
259
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
260 if (process_read_data(ph, dyn_addr, (char *)dyns, hdrs_size) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
261 print_debug("process_read_data failed for dyn_addr %p\n", dyn_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
262 free(dyns);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
263 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
264 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
265
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
266 /* find DT_DEBUG */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
267
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
268 dyn = dyns;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
269 while (dyn->d_tag != DT_DEBUG && dyn->d_tag != DT_NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
270 dyn++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
271 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
272
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
273 if (dyn->d_tag != DT_DEBUG) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
274 print_debug("failed to find DT_DEBUG\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
275 free(dyns);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
276 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
277 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
278
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
279 /* read struct r_debug into dmap */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
280
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
281 dmap_addr = (uintptr_t)dyn->d_un.d_ptr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
282 free(dyns);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
283
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
284 if (process_read_data(ph, dmap_addr, (char *)&dmap, sizeof(dmap)) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
285 print_debug("process_read_data failed for dmap_addr %p\n", dmap_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
286 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
287 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
288
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
289 lmap_addr = (uintptr_t)dmap.r_map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
290
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
291 return (lmap_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
292 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
293 #endif // __FreeBSD__ && __FreeBSD_version < 701000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
294
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
295 static bool read_lib_info(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
296 #if defined(__FreeBSD__) && __FreeBSD_version >= 701000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
297 struct kinfo_vmentry *freep, *kve;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
298 int i, cnt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
299
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
300 freep = kinfo_getvmmap(ph->pid, &cnt);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
301 if (freep == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
302 print_debug("can't get vm map for pid\n", ph->pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
303 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
304 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
305
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
306 for (i = 0; i < cnt; i++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
307 kve = &freep[i];
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
308 if ((kve->kve_flags & KVME_FLAG_COW) &&
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
309 kve->kve_path != NULL &&
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
310 strlen(kve->kve_path) > 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
311
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
312 if (find_lib(ph, kve->kve_path) == false) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
313 lib_info* lib;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
314 if ((lib = add_lib_info(ph, kve->kve_path,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
315 (uintptr_t) kve->kve_start)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
316 continue; // ignore, add_lib_info prints error
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
317
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
318 // we don't need to keep the library open, symtab is already
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
319 // built. Only for core dump we need to keep the fd open.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
320 close(lib->fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
321 lib->fd = -1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
322 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
323 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
324 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
325
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
326 free(freep);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
327
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
328 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
329 #else
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
330 char *l_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
331 struct link_map *lmap;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
332 uintptr_t lmap_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
333
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
334 if ((l_name = malloc(BUF_SIZE)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
335 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
336
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
337 if ((lmap = malloc(sizeof(*lmap))) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
338 free(l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
339 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
340 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
341
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
342 lmap_addr = linkmap_addr(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
343
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
344 if (lmap_addr == 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
345 free(l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
346 free(lmap);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
347 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
348 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
349
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
350 do {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
351 if (process_read_data(ph, lmap_addr, (char *)lmap, sizeof(*lmap)) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
352 print_debug("process_read_data failed for lmap_addr %p\n", lmap_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
353 free (l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
354 free (lmap);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
355 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
356 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
357
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
358 if (process_read_data(ph, (uintptr_t)lmap->l_name, l_name,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
359 BUF_SIZE) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
360 print_debug("process_read_data failed for lmap->l_name %p\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
361 lmap->l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
362 free (l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
363 free (lmap);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
364 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
365 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
366
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
367 if (find_lib(ph, l_name) == false) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
368 lib_info* lib;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
369 if ((lib = add_lib_info(ph, l_name,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
370 (uintptr_t) lmap->l_addr)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
371 continue; // ignore, add_lib_info prints error
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
372
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
373 // we don't need to keep the library open, symtab is already
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
374 // built. Only for core dump we need to keep the fd open.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
375 close(lib->fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
376 lib->fd = -1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
377 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
378 lmap_addr = (uintptr_t)lmap->l_next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
379 } while (lmap->l_next != NULL);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
380
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
381 free (l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
382 free (lmap);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
383
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
384 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
385 #endif
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
386 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
387
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
388 // detach a given pid
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
389 static bool ptrace_detach(pid_t pid) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
390 if (pid && ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
391 print_debug("ptrace(PTRACE_DETACH, ..) failed for %d\n", pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
392 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
393 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
394 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
395 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
396 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
397
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
398 static void process_cleanup(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
399 ptrace_detach(ph->pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
400 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
401
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
402 static ps_prochandle_ops process_ops = {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
403 .release= process_cleanup,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
404 .p_pread= process_read_data,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
405 .p_pwrite= process_write_data,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
406 .get_lwp_regs= process_get_lwp_regs,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
407 .get_lwp_info= process_get_lwp_info
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
408 };
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
409
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
410 // attach to the process. One and only one exposed stuff
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
411 struct ps_prochandle* Pgrab(pid_t pid) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
412 struct ps_prochandle* ph = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
413 thread_info* thr = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
414
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
415 if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
416 print_debug("can't allocate memory for ps_prochandle\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
417 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
418 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
419
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
420 if (ptrace_attach(pid) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
421 free(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
422 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
423 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
424
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
425 // initialize ps_prochandle
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
426 ph->pid = pid;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
427
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
428 // initialize vtable
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
429 ph->ops = &process_ops;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
430
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
431 // read library info and symbol tables, must do this before attaching threads,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
432 // as the symbols in the pthread library will be used to figure out
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
433 // the list of threads within the same process.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
434 if (read_lib_info(ph) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
435 ptrace_detach(pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
436 free(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
437 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
438 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
439
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
440 // read thread info
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
441 read_thread_info(ph, add_new_thread);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
442
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
443 return ph;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
444 }