annotate agent/src/os/bsd/ps_core.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 da91efe96a93
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 <jni.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
26 #include <unistd.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
27 #include <fcntl.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 <stdlib.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
30 #include <stddef.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
31 #include <elf.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
32 #include <link.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
33 #include "libproc_impl.h"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
34 #include "salibelf.h"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
35
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
36 // This file has the libproc implementation to read core files.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
37 // For live processes, refer to ps_proc.c. Portions of this is adapted
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
38 // /modelled after Solaris libproc.so (in particular Pcore.c)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
39
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
40 //----------------------------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
41 // ps_prochandle cleanup helper functions
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
42
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
43 // close all file descriptors
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
44 static void close_elf_files(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
45 lib_info* lib = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
46
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
47 // close core file descriptor
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
48 if (ph->core->core_fd >= 0)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
49 close(ph->core->core_fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
50
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
51 // close exec file descriptor
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
52 if (ph->core->exec_fd >= 0)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
53 close(ph->core->exec_fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
54
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
55 // close interp file descriptor
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
56 if (ph->core->interp_fd >= 0)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
57 close(ph->core->interp_fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
58
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
59 // close class share archive file
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
60 if (ph->core->classes_jsa_fd >= 0)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
61 close(ph->core->classes_jsa_fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
62
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
63 // close all library file descriptors
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
64 lib = ph->libs;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
65 while (lib) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
66 int fd = lib->fd;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
67 if (fd >= 0 && fd != ph->core->exec_fd) close(fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
68 lib = lib->next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
69 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
70 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
71
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
72 // clean all map_info stuff
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
73 static void destroy_map_info(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
74 map_info* map = ph->core->maps;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
75 while (map) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
76 map_info* next = map->next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
77 free(map);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
78 map = next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
79 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
80
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
81 if (ph->core->map_array) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
82 free(ph->core->map_array);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
83 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
84
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
85 // Part of the class sharing workaround
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
86 map = ph->core->class_share_maps;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
87 while (map) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
88 map_info* next = map->next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
89 free(map);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
90 map = next;
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
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
94 // ps_prochandle operations
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
95 static void core_release(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
96 if (ph->core) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
97 close_elf_files(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
98 destroy_map_info(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
99 free(ph->core);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
100 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
101 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
102
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
103 static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
104 map_info* map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
105 if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
106 print_debug("can't allocate memory for map_info\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
107 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
108 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
109
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
110 // initialize map
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
111 map->fd = fd;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
112 map->offset = offset;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
113 map->vaddr = vaddr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
114 map->memsz = memsz;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
115 return map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
116 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
117
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
118 // add map info with given fd, offset, vaddr and memsz
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
119 static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
120 uintptr_t vaddr, size_t memsz) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
121 map_info* map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
122 if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
123 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
124 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
125
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
126 // add this to map list
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
127 map->next = ph->core->maps;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
128 ph->core->maps = map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
129 ph->core->num_maps++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
130
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
131 return map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
132 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
133
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
134 // Part of the class sharing workaround
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
135 static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
136 uintptr_t vaddr, size_t memsz) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
137 map_info* map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
138 if ((map = allocate_init_map(ph->core->classes_jsa_fd,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
139 offset, vaddr, memsz)) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
140 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
141 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
142
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
143 map->next = ph->core->class_share_maps;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
144 ph->core->class_share_maps = map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
145 return map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
146 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
147
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
148 // Return the map_info for the given virtual address. We keep a sorted
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
149 // array of pointers in ph->map_array, so we can binary search.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
150 static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
151 {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
152 int mid, lo = 0, hi = ph->core->num_maps - 1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
153 map_info *mp;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
154
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
155 while (hi - lo > 1) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
156 mid = (lo + hi) / 2;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
157 if (addr >= ph->core->map_array[mid]->vaddr)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
158 lo = mid;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
159 else
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
160 hi = mid;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
161 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
162
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
163 if (addr < ph->core->map_array[hi]->vaddr)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
164 mp = ph->core->map_array[lo];
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
165 else
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
166 mp = ph->core->map_array[hi];
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
167
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
168 if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
169 return (mp);
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 // Part of the class sharing workaround
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
173 // Unfortunately, we have no way of detecting -Xshare state.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
174 // Check out the share maps atlast, if we don't find anywhere.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
175 // This is done this way so to avoid reading share pages
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
176 // ahead of other normal maps. For eg. with -Xshare:off we don't
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
177 // want to prefer class sharing data to data from core.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
178 mp = ph->core->class_share_maps;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
179 if (mp) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
180 print_debug("can't locate map_info at 0x%lx, trying class share maps\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
181 addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
182 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
183 while (mp) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
184 if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
185 print_debug("located map_info at 0x%lx from class share maps\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
186 addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
187 return (mp);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
188 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
189 mp = mp->next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
190 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
191
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
192 print_debug("can't locate map_info at 0x%lx\n", addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
193 return (NULL);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
194 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
195
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
196 //---------------------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
197 // Part of the class sharing workaround:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
198 //
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
199 // With class sharing, pages are mapped from classes[_g].jsa file.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
200 // The read-only class sharing pages are mapped as MAP_SHARED,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
201 // PROT_READ pages. These pages are not dumped into core dump.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
202 // With this workaround, these pages are read from classes[_g].jsa.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
203
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
204 // FIXME: !HACK ALERT!
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
205 // The format of sharing achive file header is needed to read shared heap
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
206 // file mappings. For now, I am hard coding portion of FileMapHeader here.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
207 // Refer to filemap.hpp.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
208
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
209 // FileMapHeader describes the shared space data in the file to be
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
210 // mapped. This structure gets written to a file. It is not a class,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
211 // so that the compilers don't add any compiler-private data to it.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
212
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
213 // Refer to CompactingPermGenGen::n_regions in compactingPermGenGen.hpp
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
214 #define NUM_SHARED_MAPS 4
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
215
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
216 // Refer to FileMapInfo::_current_version in filemap.hpp
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
217 #define CURRENT_ARCHIVE_VERSION 1
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
218
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
219 struct FileMapHeader {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
220 int _magic; // identify file type.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
221 int _version; // (from enum, above.)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
222 size_t _alignment; // how shared archive should be aligned
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
223
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
224 struct space_info {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
225 int _file_offset; // sizeof(this) rounded to vm page size
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
226 char* _base; // copy-on-write base address
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
227 size_t _capacity; // for validity checking
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
228 size_t _used; // for setting space top on read
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
229
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
230 // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
231 // the C type matching the C++ bool type on any given platform. For
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
232 // Hotspot on BSD we assume the corresponding C type is char but
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
233 // licensees on BSD versions may need to adjust the type of these fields.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
234 char _read_only; // read only space?
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
235 char _allow_exec; // executable code in space?
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
236
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
237 } _space[NUM_SHARED_MAPS]; // was _space[CompactingPermGenGen::n_regions];
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
238
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
239 // Ignore the rest of the FileMapHeader. We don't need those fields here.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
240 };
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
241
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
242 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
243 jboolean i;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
244 if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
245 *pvalue = i;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
246 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
247 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
248 return false;
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
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
252 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
253 uintptr_t uip;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
254 if (ps_pread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
255 *pvalue = uip;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
256 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
257 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
258 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
259 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
260 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
261
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
262 // used to read strings from debuggee
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
263 static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
264 size_t i = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
265 char c = ' ';
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
266
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
267 while (c != '\0') {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
268 if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
269 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
270 if (i < size - 1)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
271 buf[i] = c;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
272 else // smaller buffer
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
273 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
274 i++; addr++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
275 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
276
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
277 buf[i] = '\0';
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
278 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
279 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
280
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
281 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
282 // mangled name of Arguments::SharedArchivePath
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
283 #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
284
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
285 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
286 lib_info* lib = ph->libs;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
287 while (lib != NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
288 // we are iterating over shared objects from the core dump. look for
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
289 // libjvm[_g].so.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
290 const char *jvm_name = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
291 if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
292 (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
293 char classes_jsa[PATH_MAX];
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
294 struct FileMapHeader header;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
295 size_t n = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
296 int fd = -1, m = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
297 uintptr_t base = 0, useSharedSpacesAddr = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
298 uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
299 jboolean useSharedSpaces = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
300
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
301 memset(classes_jsa, 0, sizeof(classes_jsa));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
302 jvm_name = lib->name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
303 useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
304 if (useSharedSpacesAddr == 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
305 print_debug("can't lookup 'UseSharedSpaces' flag\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
306 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
307 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
308
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
309 // Hotspot vm types are not exported to build this library. So
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
310 // using equivalent type jboolean to read the value of
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
311 // UseSharedSpaces which is same as hotspot type "bool".
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
312 if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
313 print_debug("can't read the value of 'UseSharedSpaces' flag\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
314 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
315 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
316
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
317 if ((int)useSharedSpaces == 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
318 print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
319 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
320 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
321
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
322 sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
323 if (sharedArchivePathAddrAddr == 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
324 print_debug("can't lookup shared archive path symbol\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
325 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
326 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
327
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
328 if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
329 print_debug("can't read shared archive path pointer\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
330 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
331 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
332
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
333 if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
334 print_debug("can't read shared archive path value\n");
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
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
338 print_debug("looking for %s\n", classes_jsa);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
339 // open the class sharing archive file
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
340 fd = pathmap_open(classes_jsa);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
341 if (fd < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
342 print_debug("can't open %s!\n", classes_jsa);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
343 ph->core->classes_jsa_fd = -1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
344 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
345 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
346 print_debug("opened %s\n", classes_jsa);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
347 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
348
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
349 // read FileMapHeader from the file
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
350 memset(&header, 0, sizeof(struct FileMapHeader));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
351 if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
352 != sizeof(struct FileMapHeader)) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
353 print_debug("can't read shared archive file map header from %s\n", classes_jsa);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
354 close(fd);
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 // check file magic
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
359 if (header._magic != 0xf00baba2) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
360 print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
361 classes_jsa, header._magic);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
362 close(fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
363 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
364 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
365
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
366 // check version
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
367 if (header._version != CURRENT_ARCHIVE_VERSION) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
368 print_debug("%s has wrong shared archive file version %d, expecting %d\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
369 classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
370 close(fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
371 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
372 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
373
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
374 ph->core->classes_jsa_fd = fd;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
375 // add read-only maps from classes[_g].jsa to the list of maps
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
376 for (m = 0; m < NUM_SHARED_MAPS; m++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
377 if (header._space[m]._read_only) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
378 base = (uintptr_t) header._space[m]._base;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
379 // no need to worry about the fractional pages at-the-end.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
380 // possible fractional pages are handled by core_read_data.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
381 add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
382 base, (size_t) header._space[m]._used);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
383 print_debug("added a share archive map at 0x%lx\n", base);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
384 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
385 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
386 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
387 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
388 lib = lib->next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
389 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
390 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
391 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
392
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
393
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
394 //---------------------------------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
395 // functions to handle map_info
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
396
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
397 // Order mappings based on virtual address. We use this function as the
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
398 // callback for sorting the array of map_info pointers.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
399 static int core_cmp_mapping(const void *lhsp, const void *rhsp)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
400 {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
401 const map_info *lhs = *((const map_info **)lhsp);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
402 const map_info *rhs = *((const map_info **)rhsp);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
403
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
404 if (lhs->vaddr == rhs->vaddr)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
405 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
406
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
407 return (lhs->vaddr < rhs->vaddr ? -1 : 1);
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 // we sort map_info by starting virtual address so that we can do
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
411 // binary search to read from an address.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
412 static bool sort_map_array(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
413 size_t num_maps = ph->core->num_maps;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
414 map_info* map = ph->core->maps;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
415 int i = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
416
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
417 // allocate map_array
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
418 map_info** array;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
419 if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
420 print_debug("can't allocate memory for map array\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
421 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
422 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
423
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
424 // add maps to array
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
425 while (map) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
426 array[i] = map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
427 i++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
428 map = map->next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
429 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
430
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
431 // sort is called twice. If this is second time, clear map array
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
432 if (ph->core->map_array) free(ph->core->map_array);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
433 ph->core->map_array = array;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
434 // sort the map_info array by base virtual address.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
435 qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
436 core_cmp_mapping);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
437
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
438 // print map
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
439 if (is_debug()) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
440 int j = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
441 print_debug("---- sorted virtual address map ----\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
442 for (j = 0; j < ph->core->num_maps; j++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
443 print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
444 ph->core->map_array[j]->memsz);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
445 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
446 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
447
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
448 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
449 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
450
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
451 #ifndef MIN
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
452 #define MIN(x, y) (((x) < (y))? (x): (y))
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
453 #endif
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
454
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
455 static bool core_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
456 ssize_t resid = size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
457 int page_size=sysconf(_SC_PAGE_SIZE);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
458 while (resid != 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
459 map_info *mp = core_lookup(ph, addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
460 uintptr_t mapoff;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
461 ssize_t len, rem;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
462 off_t off;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
463 int fd;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
464
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
465 if (mp == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
466 break; /* No mapping for this address */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
467
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
468 fd = mp->fd;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
469 mapoff = addr - mp->vaddr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
470 len = MIN(resid, mp->memsz - mapoff);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
471 off = mp->offset + mapoff;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
472
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
473 if ((len = pread(fd, buf, len, off)) <= 0)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
474 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
475
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
476 resid -= len;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
477 addr += len;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
478 buf = (char *)buf + len;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
479
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
480 // mappings always start at page boundary. But, may end in fractional
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
481 // page. fill zeros for possible fractional page at the end of a mapping.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
482 rem = mp->memsz % page_size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
483 if (rem > 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
484 rem = page_size - rem;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
485 len = MIN(resid, rem);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
486 resid -= len;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
487 addr += len;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
488 // we are not assuming 'buf' to be zero initialized.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
489 memset(buf, 0, len);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
490 buf += len;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
491 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
492 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
493
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
494 if (resid) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
495 print_debug("core read failed for %d byte(s) @ 0x%lx (%d more bytes)\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
496 size, addr, resid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
497 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
498 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
499 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
500 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
501 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
502
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
503 // null implementation for write
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
504 static bool core_write_data(struct ps_prochandle* ph,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
505 uintptr_t addr, const char *buf , size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
506 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
507 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
508
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
509 static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
510 struct reg* regs) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
511 // for core we have cached the lwp regs from NOTE section
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
512 thread_info* thr = ph->threads;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
513 while (thr) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
514 if (thr->lwp_id == lwp_id) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
515 memcpy(regs, &thr->regs, sizeof(struct reg));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
516 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
517 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
518 thr = thr->next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
519 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
520 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
521 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
522
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
523 static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
524 print_debug("core_get_lwp_info not implemented\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
525 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
526 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
527
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
528 static ps_prochandle_ops core_ops = {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
529 .release= core_release,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
530 .p_pread= core_read_data,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
531 .p_pwrite= core_write_data,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
532 .get_lwp_regs= core_get_lwp_regs,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
533 .get_lwp_info= core_get_lwp_info
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
534 };
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
535
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
536 // read regs and create thread from NT_PRSTATUS entries from core file
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
537 static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
538 // we have to read prstatus_t from buf
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
539 // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
540 prstatus_t* prstat = (prstatus_t*) buf;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
541 thread_info* newthr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
542 print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
543 // we set pthread_t to -1 for core dump
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
544 if((newthr = add_thread_info(ph, (pthread_t) -1, prstat->pr_pid)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
545 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
546
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
547 // copy regs
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
548 memcpy(&newthr->regs, &prstat->pr_reg, sizeof(struct reg));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
549
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
550 if (is_debug()) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
551 print_debug("integer regset\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
552 #ifdef i386
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
553 // print the regset
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
554 print_debug("\teax = 0x%x\n", newthr->regs.r_eax);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
555 print_debug("\tebx = 0x%x\n", newthr->regs.r_ebx);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
556 print_debug("\tecx = 0x%x\n", newthr->regs.r_ecx);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
557 print_debug("\tedx = 0x%x\n", newthr->regs.r_edx);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
558 print_debug("\tesp = 0x%x\n", newthr->regs.r_esp);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
559 print_debug("\tebp = 0x%x\n", newthr->regs.r_ebp);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
560 print_debug("\tesi = 0x%x\n", newthr->regs.r_esi);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
561 print_debug("\tedi = 0x%x\n", newthr->regs.r_edi);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
562 print_debug("\teip = 0x%x\n", newthr->regs.r_eip);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
563 #endif
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
564
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
565 #if defined(amd64) || defined(x86_64)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
566 // print the regset
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
567 print_debug("\tr15 = 0x%lx\n", newthr->regs.r_r15);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
568 print_debug("\tr14 = 0x%lx\n", newthr->regs.r_r14);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
569 print_debug("\tr13 = 0x%lx\n", newthr->regs.r_r13);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
570 print_debug("\tr12 = 0x%lx\n", newthr->regs.r_r12);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
571 print_debug("\trbp = 0x%lx\n", newthr->regs.r_rbp);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
572 print_debug("\trbx = 0x%lx\n", newthr->regs.r_rbx);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
573 print_debug("\tr11 = 0x%lx\n", newthr->regs.r_r11);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
574 print_debug("\tr10 = 0x%lx\n", newthr->regs.r_r10);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
575 print_debug("\tr9 = 0x%lx\n", newthr->regs.r_r9);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
576 print_debug("\tr8 = 0x%lx\n", newthr->regs.r_r8);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
577 print_debug("\trax = 0x%lx\n", newthr->regs.r_rax);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
578 print_debug("\trcx = 0x%lx\n", newthr->regs.r_rcx);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
579 print_debug("\trdx = 0x%lx\n", newthr->regs.r_rdx);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
580 print_debug("\trsi = 0x%lx\n", newthr->regs.r_rsi);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
581 print_debug("\trdi = 0x%lx\n", newthr->regs.r_rdi);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
582 //print_debug("\torig_rax = 0x%lx\n", newthr->regs.orig_rax);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
583 print_debug("\trip = 0x%lx\n", newthr->regs.r_rip);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
584 print_debug("\tcs = 0x%lx\n", newthr->regs.r_cs);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
585 //print_debug("\teflags = 0x%lx\n", newthr->regs.eflags);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
586 print_debug("\trsp = 0x%lx\n", newthr->regs.r_rsp);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
587 print_debug("\tss = 0x%lx\n", newthr->regs.r_ss);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
588 //print_debug("\tfs_base = 0x%lx\n", newthr->regs.fs_base);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
589 //print_debug("\tgs_base = 0x%lx\n", newthr->regs.gs_base);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
590 //print_debug("\tds = 0x%lx\n", newthr->regs.ds);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
591 //print_debug("\tes = 0x%lx\n", newthr->regs.es);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
592 //print_debug("\tfs = 0x%lx\n", newthr->regs.fs);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
593 //print_debug("\tgs = 0x%lx\n", newthr->regs.gs);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
594 #endif
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
595 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
596
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
597 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
598 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
599
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
600 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
601
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
602 // read NT_PRSTATUS entries from core NOTE segment
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
603 static bool core_handle_note(struct ps_prochandle* ph, ELF_PHDR* note_phdr) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
604 char* buf = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
605 char* p = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
606 size_t size = note_phdr->p_filesz;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
607
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
608 // we are interested in just prstatus entries. we will ignore the rest.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
609 // Advance the seek pointer to the start of the PT_NOTE data
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
610 if (lseek(ph->core->core_fd, note_phdr->p_offset, SEEK_SET) == (off_t)-1) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
611 print_debug("failed to lseek to PT_NOTE data\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
612 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
613 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
614
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
615 // Now process the PT_NOTE structures. Each one is preceded by
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
616 // an Elf{32/64}_Nhdr structure describing its type and size.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
617 if ( (buf = (char*) malloc(size)) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
618 print_debug("can't allocate memory for reading core notes\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
619 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
620 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
621
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
622 // read notes into buffer
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
623 if (read(ph->core->core_fd, buf, size) != size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
624 print_debug("failed to read notes, core file must have been truncated\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
625 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
626 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
627
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
628 p = buf;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
629 while (p < buf + size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
630 ELF_NHDR* notep = (ELF_NHDR*) p;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
631 char* descdata = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
632 print_debug("Note header with n_type = %d and n_descsz = %u\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
633 notep->n_type, notep->n_descsz);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
634
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
635 if (notep->n_type == NT_PRSTATUS) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
636 if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
637 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
638 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
639 p = descdata + ROUNDUP(notep->n_descsz, 4);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
640 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
641
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
642 free(buf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
643 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
644
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
645 err:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
646 if (buf) free(buf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
647 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
648 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
649
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
650 // read all segments from core file
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
651 static bool read_core_segments(struct ps_prochandle* ph, ELF_EHDR* core_ehdr) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
652 int i = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
653 ELF_PHDR* phbuf = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
654 ELF_PHDR* core_php = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
655
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
656 if ((phbuf = read_program_header_table(ph->core->core_fd, core_ehdr)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
657 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
658
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
659 /*
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
660 * Now iterate through the program headers in the core file.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
661 * We're interested in two types of Phdrs: PT_NOTE (which
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
662 * contains a set of saved /proc structures), and PT_LOAD (which
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
663 * represents a memory mapping from the process's address space).
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
664 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
665 * Difference b/w Solaris PT_NOTE and BSD PT_NOTE:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
666 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
667 * In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
668 * contains /proc structs in the pre-2.6 unstructured /proc format. the last
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
669 * PT_NOTE has data in new /proc format.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
670 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
671 * In Solaris, there is only one pstatus (process status). pstatus contains
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
672 * integer register set among other stuff. For each LWP, we have one lwpstatus
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
673 * entry that has integer regset for that LWP.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
674 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
675 * Linux threads are actually 'clone'd processes. To support core analysis
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
676 * of "multithreaded" process, Linux creates more than one pstatus (called
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
677 * "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
678 * "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
679 * function "elf_core_dump".
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
680 */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
681
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
682 for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
683 switch (core_php->p_type) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
684 case PT_NOTE:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
685 if (core_handle_note(ph, core_php) != true) goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
686 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
687
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
688 case PT_LOAD: {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
689 if (core_php->p_filesz != 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
690 if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
691 core_php->p_vaddr, core_php->p_filesz) == NULL) goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
692 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
693 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
694 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
695 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
696
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
697 core_php++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
698 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
699
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
700 free(phbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
701 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
702 err:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
703 free(phbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
704 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
705 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
706
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
707 // read segments of a shared object
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
708 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
709 int i = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
710 ELF_PHDR* phbuf;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
711 ELF_PHDR* lib_php = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
712
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
713 if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
714 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
715
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
716 // we want to process only PT_LOAD segments that are not writable.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
717 // i.e., text segments. The read/write/exec (data) segments would
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
718 // have been already added from core file segments.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
719 for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
720 if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
721 if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
722 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
723 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
724 lib_php++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
725 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
726
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
727 free(phbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
728 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
729 err:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
730 free(phbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
731 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
732 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
733
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
734 // process segments from interpreter (ld-elf.so.1)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
735 static bool read_interp_segments(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
736 ELF_EHDR interp_ehdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
737
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
738 if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
739 print_debug("interpreter is not a valid ELF file\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
740 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
741 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
742
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
743 if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
744 print_debug("can't read segments of interpreter\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
745 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
746 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
747
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
748 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
749 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
750
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
751 // process segments of a a.out
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
752 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
753 int i = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
754 ELF_PHDR* phbuf = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
755 ELF_PHDR* exec_php = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
756
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
757 if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
758 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
759
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
760 for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
761 switch (exec_php->p_type) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
762
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
763 // add mappings for PT_LOAD segments
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
764 case PT_LOAD: {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
765 // add only non-writable segments of non-zero filesz
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
766 if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
767 if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
768 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
769 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
770 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
771
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
772 // read the interpreter and it's segments
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
773 case PT_INTERP: {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
774 char interp_name[BUF_SIZE];
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
775
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
776 pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
777 print_debug("ELF interpreter %s\n", interp_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
778 // read interpreter segments as well
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
779 if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
780 print_debug("can't open runtime loader\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
781 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
782 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
783 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
784 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
785
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
786 // from PT_DYNAMIC we want to read address of first link_map addr
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
787 case PT_DYNAMIC: {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
788 ph->core->dynamic_addr = exec_php->p_vaddr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
789 print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
790 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
791 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
792
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
793 } // switch
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
794 exec_php++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
795 } // for
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
796
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
797 free(phbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
798 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
799 err:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
800 free(phbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
801 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
802 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
803
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
804
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
805 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug, r_map)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
806 #define LD_BASE_OFFSET offsetof(struct r_debug, r_ldbase)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
807 #define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
808 #define LINK_MAP_NAME_OFFSET offsetof(struct link_map, l_name)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
809 #define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
810
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
811 // read shared library info from runtime linker's data structures.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
812 // This work is done by librtlb_db in Solaris
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
813 static bool read_shared_lib_info(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
814 uintptr_t addr = ph->core->dynamic_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
815 uintptr_t debug_base;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
816 uintptr_t first_link_map_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
817 uintptr_t ld_base_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
818 uintptr_t link_map_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
819 uintptr_t lib_base_diff;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
820 uintptr_t lib_base;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
821 uintptr_t lib_name_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
822 char lib_name[BUF_SIZE];
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
823 ELF_DYN dyn;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
824 ELF_EHDR elf_ehdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
825 int lib_fd;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
826
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
827 // _DYNAMIC has information of the form
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
828 // [tag] [data] [tag] [data] .....
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
829 // Both tag and data are pointer sized.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
830 // We look for dynamic info with DT_DEBUG. This has shared object info.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
831 // refer to struct r_debug in link.h
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
832
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
833 dyn.d_tag = DT_NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
834 while (dyn.d_tag != DT_DEBUG) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
835 if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
836 print_debug("can't read debug info from _DYNAMIC\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
837 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
838 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
839 addr += sizeof(ELF_DYN);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
840 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
841
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
842 // we have got Dyn entry with DT_DEBUG
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
843 debug_base = dyn.d_un.d_ptr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
844 // at debug_base we have struct r_debug. This has first link map in r_map field
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
845 if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
846 &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
847 print_debug("can't read first link map address\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
848 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
849 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
850
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
851 // read ld_base address from struct r_debug
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
852 // XXX: There is no r_ldbase member on BSD
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
853 /*
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
854 if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
855 sizeof(uintptr_t)) != PS_OK) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
856 print_debug("can't read ld base address\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
857 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
858 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
859 ph->core->ld_base_addr = ld_base_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
860 */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
861 ph->core->ld_base_addr = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
862
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
863 print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
864
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
865 // now read segments from interp (i.e ld-elf.so.1)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
866 if (read_interp_segments(ph) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
867 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
868
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
869 // after adding interpreter (ld.so) mappings sort again
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
870 if (sort_map_array(ph) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
871 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
872
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
873 print_debug("first link map is at 0x%lx\n", first_link_map_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
874
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
875 link_map_addr = first_link_map_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
876 while (link_map_addr != 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
877 // read library base address of the .so. Note that even though <sys/link.h> calls
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
878 // link_map->l_addr as "base address", this is * not * really base virtual
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
879 // address of the shared object. This is actually the difference b/w the virtual
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
880 // address mentioned in shared object and the actual virtual base where runtime
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
881 // linker loaded it. We use "base diff" in read_lib_segments call below.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
882
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
883 if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
884 &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
885 print_debug("can't read shared object base address diff\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
886 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
887 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
888
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
889 // read address of the name
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
890 if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
891 &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
892 print_debug("can't read address of shared object name\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
893 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
894 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
895
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
896 // read name of the shared object
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
897 if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
898 print_debug("can't read shared object name\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
899 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
900 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
901
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
902 if (lib_name[0] != '\0') {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
903 // ignore empty lib names
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
904 lib_fd = pathmap_open(lib_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
905
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
906 if (lib_fd < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
907 print_debug("can't open shared object %s\n", lib_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
908 // continue with other libraries...
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
909 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
910 if (read_elf_header(lib_fd, &elf_ehdr)) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
911 lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
912 print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
913 lib_name, lib_base, lib_base_diff);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
914 // while adding library mappings we need to use "base difference".
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
915 if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
916 print_debug("can't read shared object's segments\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
917 close(lib_fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
918 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
919 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
920 add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
921 // Map info is added for the library (lib_name) so
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
922 // we need to re-sort it before calling the p_pdread.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
923 if (sort_map_array(ph) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
924 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
925 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
926 print_debug("can't read ELF header for shared object %s\n", lib_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
927 close(lib_fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
928 // continue with other libraries...
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
929 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
930 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
931 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
932
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
933 // read next link_map address
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
934 if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
935 &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
936 print_debug("can't read next link in link_map\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
937 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
938 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
939 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
940
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
941 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
942 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
943
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
944 // the one and only one exposed stuff from this file
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
945 struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
946 ELF_EHDR core_ehdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
947 ELF_EHDR exec_ehdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
948
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
949 struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
950 if (ph == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
951 print_debug("can't allocate ps_prochandle\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
952 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
953 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
954
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
955 if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
956 free(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
957 print_debug("can't allocate ps_prochandle\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
958 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
959 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
961 // initialize ph
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
962 ph->ops = &core_ops;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
963 ph->core->core_fd = -1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
964 ph->core->exec_fd = -1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
965 ph->core->interp_fd = -1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
966
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
967 // open the core file
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
968 if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
969 print_debug("can't open core file\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
970 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
971 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
972
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
973 // read core file ELF header
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
974 if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
975 print_debug("core file is not a valid ELF ET_CORE file\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
976 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
977 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
978
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
979 if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
980 print_debug("can't open executable file\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
981 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
982 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
983
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
984 if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
985 print_debug("executable file is not a valid ELF ET_EXEC file\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
986 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
987 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
988
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
989 // process core file segments
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
990 if (read_core_segments(ph, &core_ehdr) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
991 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
992
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
993 // process exec file segments
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
994 if (read_exec_segments(ph, &exec_ehdr) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
995 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
996
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
997 // exec file is also treated like a shared object for symbol search
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
998 if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
999 (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1000 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1001
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1002 // allocate and sort maps into map_array, we need to do this
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1003 // here because read_shared_lib_info needs to read from debuggee
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1004 // address space
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1005 if (sort_map_array(ph) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1006 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1007
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1008 if (read_shared_lib_info(ph) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1009 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1010
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1011 // sort again because we have added more mappings from shared objects
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1012 if (sort_map_array(ph) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1013 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1014
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1015 if (init_classsharing_workaround(ph) != true)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1016 goto err;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1017
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1018 return ph;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1019
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1020 err:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1021 Prelease(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1022 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1023 }