Print this page
OS-3477 lx brand: mdb(1) doesn't find branded symbols
OS-3426 lx brand: dtrace(1M) doesn't find branded symbols
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
+++ new/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
|
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 +/*
27 + * Copyright (c) 2014 Joyent, Inc. All rights reserved.
28 + */
29 +
26 30 #include <stdlib.h>
27 31 #include <stdio.h>
28 32 #include <proc_service.h>
29 33 #include <link.h>
30 34 #include <rtld_db.h>
31 35 #include <rtld.h>
32 36 #include <alist.h>
33 37 #include <list.h>
34 38 #include <_rtld_db.h>
35 39 #include <msg.h>
36 40 #include <limits.h>
37 41 #include <string.h>
38 42 #include <sys/param.h>
39 43
40 44 /*
45 + * We want to include zone.h to pull in the prototype for zone_get_nroot(),
46 + * but we need to avoid pulling in <sys/stream.h>, which has a definition
47 + * of M_DATA that conflicts with the ELF-related definition in machdep_*.h.
48 + */
49 +#define _SYS_STREAM_H
50 +#include <zone.h>
51 +
52 +/*
41 53 * 64-bit builds are going to compile this module twice, the
42 54 * second time with _ELF64 defined. These defines should make
43 55 * all the necessary adjustments to the code.
44 56 */
45 57 #ifdef _LP64
46 58 #ifdef _ELF64
47 59 #define _rd_event_enable32 _rd_event_enable64
48 60 #define _rd_event_getmsg32 _rd_event_getmsg64
49 61 #define _rd_get_dyns32 _rd_get_dyns64
50 62 #define _rd_get_ehdr32 _rd_get_ehdr64
51 63 #define _rd_objpad_enable32 _rd_objpad_enable64
52 64 #define _rd_loadobj_iter32 _rd_loadobj_iter64
53 65 #define _rd_reset32 _rd_reset64
54 66 #define find_dynamic_ent32 find_dynamic_ent64
55 67 #define validate_rdebug32 validate_rdebug64
56 68 #define TAPlist APlist
57 69 #define TLm_list Lm_list
58 70 #define TList List
59 71 #define TListnode Listnode
60 72 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_64
61 73 #else /* ELF32 */
62 74 #define Rt_map Rt_map32
63 75 #define Rtld_db_priv Rtld_db_priv32
64 76 #define TAPlist APlist32
65 77 #define TLm_list Lm_list32
66 78 #define TList List32
67 79 #define TListnode Listnode32
68 80 #define Lm_list Lm_list32
69 81 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_32
70 82 #endif /* _ELF64 */
71 83 #else /* _LP64 */
72 84 #define TAPlist APlist
73 85 #define TLm_list Lm_list
74 86 #define TList List
75 87 #define TListnode Listnode
76 88 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_32
77 89 #endif /* _LP64 */
78 90
79 91 /*
80 92 * BrandZ added ps_pbrandname(). Many debuggers that link directly
81 93 * against librtld_db.so may not implement this interface. Hence
82 94 * we won't call the function directly, instead we'll try to look it
83 95 * up using the linker first and only invoke it if we find it.
84 96 */
85 97 typedef ps_err_e (*ps_pbrandname_fp_t)(struct ps_prochandle *,
86 98 char *, size_t);
87 99
88 100 rd_err_e
89 101 validate_rdebug32(struct rd_agent *rap)
90 102 {
91 103 struct ps_prochandle *php = rap->rd_psp;
92 104 psaddr_t db_privp;
93 105 Rtld_db_priv db_priv;
94 106
95 107 if (rap->rd_rdebug == 0)
96 108 return (RD_ERR);
97 109
98 110 /*
99 111 * The rtld_db_priv structure contains both the traditional (exposed)
100 112 * r_debug structure as well as private data only available to
101 113 * this library.
102 114 */
103 115 db_privp = rap->rd_rdebug;
104 116
105 117 /*
106 118 * Verify that librtld_db & rtld are at the proper revision
107 119 * levels.
108 120 */
109 121 if (ps_pread(php, db_privp, (char *)&db_priv,
110 122 sizeof (Rtld_db_priv)) != PS_OK) {
111 123 LOG(ps_plog(MSG_ORIG(MSG_DB_READPRIVFAIL_1),
112 124 EC_ADDR(db_privp)));
113 125 return (RD_DBERR);
114 126 }
115 127
116 128 if ((db_priv.rtd_version < R_RTLDDB_VERSION1) ||
117 129 (db_priv.rtd_version > R_RTLDDB_VERSION)) {
118 130 LOG(ps_plog(MSG_ORIG(MSG_DB_BADPVERS),
119 131 db_priv.rtd_version, R_RTLDDB_VERSION));
120 132 return (RD_NOCAPAB);
121 133 }
122 134
123 135 /*
124 136 * Is the image being examined from a core file or not.
125 137 * If it is a core file then the following write will fail.
126 138 */
127 139 if (ps_pwrite(php, db_privp, (char *)&db_priv,
128 140 sizeof (Rtld_db_priv)) != PS_OK)
129 141 rap->rd_flags |= RDF_FL_COREFILE;
130 142
131 143 rap->rd_rdebugvers = db_priv.rtd_version;
132 144 rap->rd_rtlddbpriv = db_privp;
133 145
134 146 LOG(ps_plog(MSG_ORIG(MSG_DB_VALIDRDEBUG), EC_ADDR(rap->rd_rdebug),
135 147 R_RTLDDB_VERSION, rap->rd_rdebugvers,
136 148 rap->rd_flags & RDF_FL_COREFILE));
137 149 return (RD_OK);
138 150 }
139 151
140 152
141 153 rd_err_e
142 154 find_dynamic_ent32(struct rd_agent *rap, psaddr_t dynaddr,
143 155 Xword dyntag, Dyn *dyn)
144 156 {
145 157 struct ps_prochandle *php = rap->rd_psp;
146 158 Dyn d;
147 159
148 160 d.d_tag = DT_NULL;
149 161 do {
150 162 if (ps_pread(php, dynaddr, (void *)(&d), sizeof (d)) !=
151 163 PS_OK) {
152 164 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_4),
153 165 EC_ADDR(dynaddr)));
154 166 return (RD_DBERR);
155 167 }
156 168 dynaddr += sizeof (d);
157 169 if (d.d_tag == dyntag)
158 170 break;
159 171 } while (d.d_tag != DT_NULL);
160 172 if (d.d_tag == dyntag) {
161 173 *dyn = d;
162 174 LOG(ps_plog(MSG_ORIG(MSG_DB_FINDDYNAMIC), EC_ADDR(dyntag),
163 175 EC_ADDR(d.d_un.d_val)));
164 176 return (RD_OK);
165 177 }
166 178 LOG(ps_plog(MSG_ORIG(MSG_DB_NODYNDEBUG), EC_ADDR(dyntag)));
167 179 return (RD_DBERR);
168 180 }
169 181
170 182 extern char rtld_db_helper_path[MAXPATHLEN];
171 183
172 184 rd_err_e
173 185 _rd_reset32(struct rd_agent *rap)
174 186 {
175 187 psaddr_t symaddr;
176 188 struct ps_prochandle *php = rap->rd_psp;
177 189 const auxv_t *auxvp = NULL;
178 190 rd_err_e rc = RD_OK;
179 191 char brandname[MAXPATHLEN];
180 192 char brandlib[MAXPATHLEN];
181 193 ps_pbrandname_fp_t ps_pbrandname;
182 194
183 195 /*
184 196 * librtld_db attempts three different methods to find
185 197 * the r_debug structure which is required to
186 198 * initialize itself. The methods are:
187 199 * method1:
188 200 * entirely independent of any text segment
189 201 * and relies on the AT_SUN_LDDATA auxvector
190 202 * to find the ld.so.1::rdebug structure.
191 203 * method2:
192 204 * lookup symbols in ld.so.1's symbol table
193 205 * to find the r_debug symbol.
194 206 * method3:
195 207 * (old dbx method) dependent upon the
196 208 * text segment/symbol table of the
197 209 * executable and not ld.so.1. We lookup the
198 210 * _DYNAMIC symbol in the executable and look for
199 211 * the DT_DEBUG entry in the .dynamic table. This
200 212 * points to rdebug.
201 213 *
202 214 * If none of that works - we fail.
203 215 */
204 216 LOG(ps_plog(MSG_ORIG(MSG_DB_RDRESET), rap->rd_dmodel));
205 217 /*
206 218 * Method1
207 219 *
208 220 * Scan the aux vector looking for AT_BASE & AT_SUN_LDDATA
209 221 */
210 222
211 223 if (ps_pauxv(php, &auxvp) != PS_OK) {
212 224 LOG(ps_plog(MSG_ORIG(MSG_DB_NOAUXV)));
213 225 rc = RD_ERR;
214 226 }
215 227
216 228 rap->rd_rdebug = 0;
217 229
218 230 if (auxvp != NULL) {
219 231 rc = RD_ERR;
220 232 while (auxvp->a_type != AT_NULL) {
221 233 if (auxvp->a_type == AT_SUN_LDDATA) {
222 234 /* LINTED */
223 235 rap->rd_rdebug = (uintptr_t)auxvp->a_un.a_ptr;
224 236 LOG(ps_plog(MSG_ORIG(MSG_DB_FLDDATA),
225 237 rap->rd_rdebug));
226 238 rc = validate_rdebug32(rap);
227 239 break;
228 240 }
229 241 auxvp++;
230 242 }
231 243 }
232 244
233 245 /*
234 246 * method2 - look for r_rdebug symbol in ld.so.1
235 247 */
236 248 if (rc != RD_OK) {
237 249 /*
238 250 * If the AT_SUN_LDDATA auxv vector is not present
239 251 * fall back on doing a symlookup of
240 252 * the r_debug symbol. This is for backward
241 253 * compatiblity with older OS's
242 254 */
243 255 LOG(ps_plog(MSG_ORIG(MSG_DB_NOLDDATA)));
244 256 if (ps_pglobal_lookup(php, PS_OBJ_LDSO, MSG_ORIG(MSG_SYM_DEBUG),
245 257 &symaddr) != PS_OK) {
246 258 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL),
247 259 MSG_ORIG(MSG_SYM_DEBUG)));
248 260 rc = RD_DBERR;
249 261 } else {
250 262 rap->rd_rdebug = symaddr;
251 263 LOG(ps_plog(MSG_ORIG(MSG_DB_SYMRDEBUG),
252 264 EC_ADDR(symaddr)));
253 265 rc = validate_rdebug32(rap);
254 266 }
255 267 }
256 268
257 269
258 270 /*
259 271 * method3 - find DT_DEBUG in the executables .dynamic section.
260 272 */
261 273 if (rc != RD_OK) {
262 274 Dyn dyn;
263 275 if (ps_pglobal_lookup(php, PS_OBJ_EXEC,
264 276 MSG_ORIG(MSG_SYM_DYNAMIC), &symaddr) != PS_OK) {
265 277 LOG(ps_plog(MSG_ORIG(MSG_DB_NODYNAMIC)));
266 278 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED)));
267 279 return (rc);
268 280 }
269 281 rc = find_dynamic_ent32(rap, symaddr, DT_DEBUG, &dyn);
270 282 if (rc != RD_OK) {
271 283 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED)));
272 284 return (rc);
273 285 }
274 286 rap->rd_rdebug = dyn.d_un.d_ptr;
275 287 rc = validate_rdebug32(rap);
|
↓ open down ↓ |
225 lines elided |
↑ open up ↑ |
276 288 if (rc != RD_OK) {
277 289 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED)));
278 290 return (rc);
279 291 }
280 292 }
281 293
282 294 /*
283 295 * If we are debugging a branded executable, load the appropriate
284 296 * helper library, and call its initialization routine. Being unable
285 297 * to load the helper library is not a critical error. (Hopefully
286 - * we'll still be able to access some objects in the target.)
298 + * we'll still be able to access some objects in the target.) Note
299 + * that we pull in the native root here to allow for helper libraries
300 + * to be properly found from within the branded zone.
287 301 */
288 302 ps_pbrandname = (ps_pbrandname_fp_t)dlsym(RTLD_PROBE, "ps_pbrandname");
289 303 while ((ps_pbrandname != NULL) &&
290 304 (ps_pbrandname(php, brandname, MAXPATHLEN) == PS_OK)) {
291 305 const char *isa = "";
292 306
293 307 #ifdef _LP64
294 308 isa = MSG_ORIG(MSG_DB_64BIT_PREFIX);
295 309 #endif /* _LP64 */
296 310
297 - if (rtld_db_helper_path[0] != '\0')
311 + if (rtld_db_helper_path[0] != '\0') {
298 312 (void) snprintf(brandlib, MAXPATHLEN,
299 313 MSG_ORIG(MSG_DB_BRAND_HELPERPATH_PREFIX),
300 314 rtld_db_helper_path,
301 315 MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa,
302 316 brandname);
303 - else
317 + } else {
318 + const char *nroot = zone_get_nroot();
319 +
320 + if (nroot == NULL)
321 + nroot = "";
322 +
304 323 (void) snprintf(brandlib, MAXPATHLEN,
305 - MSG_ORIG(MSG_DB_BRAND_HELPERPATH),
324 + MSG_ORIG(MSG_DB_BRAND_HELPERPATH), nroot,
306 325 MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa,
307 326 brandname);
327 + }
308 328
309 329 rap->rd_helper.rh_dlhandle = dlopen(brandlib,
310 330 RTLD_LAZY | RTLD_LOCAL);
311 331 if (rap->rd_helper.rh_dlhandle == NULL) {
312 332 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADFAILED),
313 333 brandlib));
314 334 break;
315 335 }
316 336
317 337 rap->rd_helper.rh_ops = dlsym(rap->rd_helper.rh_dlhandle,
318 338 MSG_ORIG(MSG_SYM_BRANDOPS));
319 339 if (rap->rd_helper.rh_ops == NULL) {
320 340 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERNOOPS),
321 341 brandlib));
322 342 (void) dlclose(rap->rd_helper.rh_dlhandle);
323 343 rap->rd_helper.rh_dlhandle = NULL;
324 344 break;
325 345 }
326 346
327 347 rap->rd_helper.rh_data = rap->rd_helper.rh_ops->rho_init(rap,
328 348 php);
329 349 if (rap->rd_helper.rh_data == NULL) {
330 350 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERINITFAILED)));
331 351 (void) dlclose(rap->rd_helper.rh_dlhandle);
332 352 rap->rd_helper.rh_dlhandle = NULL;
333 353 rap->rd_helper.rh_ops = NULL;
334 354 break;
335 355 }
336 356
337 357 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADED), brandname));
338 358 break;
339 359
340 360 /* NOTREACHED */
341 361 }
342 362
343 363 if ((rap->rd_flags & RDF_FL_COREFILE) == 0) {
344 364 if (ps_pglobal_lookup(php, PS_OBJ_LDSO,
345 365 MSG_ORIG(MSG_SYM_PREINIT), &symaddr) != PS_OK) {
346 366 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL),
347 367 MSG_ORIG(MSG_SYM_PREINIT)));
348 368 return (RD_DBERR);
349 369 }
350 370 rap->rd_preinit = symaddr;
351 371
352 372 if (ps_pglobal_lookup(php, PS_OBJ_LDSO,
353 373 MSG_ORIG(MSG_SYM_POSTINIT), &symaddr) != PS_OK) {
354 374 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL),
355 375 MSG_ORIG(MSG_SYM_POSTINIT)));
356 376 return (RD_DBERR);
357 377 }
358 378 rap->rd_postinit = symaddr;
359 379
360 380 if (ps_pglobal_lookup(php, PS_OBJ_LDSO,
361 381 MSG_ORIG(MSG_SYM_DLACT), &symaddr) != PS_OK) {
362 382 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL),
363 383 MSG_ORIG(MSG_SYM_DLACT)));
364 384 return (RD_DBERR);
365 385 }
366 386 rap->rd_dlact = symaddr;
367 387 rap->rd_tbinder = 0;
368 388 }
369 389
370 390 return (RD_OK);
371 391 }
372 392
373 393 rd_err_e
374 394 _rd_get_ehdr32(struct rd_agent *rap,
375 395 psaddr_t addr, Ehdr *ehdr, uint_t *phnum)
376 396 {
377 397 struct ps_prochandle *php = rap->rd_psp;
378 398 Shdr shdr;
379 399
380 400 if (ps_pread(php, addr, ehdr, sizeof (*ehdr)) != PS_OK) {
381 401 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_5), EC_ADDR(addr)));
382 402 return (RD_ERR);
383 403 }
384 404 if (phnum == NULL)
385 405 return (RD_OK);
386 406
387 407 if (ehdr->e_phnum != PN_XNUM) {
388 408 *phnum = ehdr->e_phnum;
389 409 return (RD_OK);
390 410 }
391 411
392 412 /* deal with elf extended program headers */
393 413 if ((ehdr->e_shoff == 0) || (ehdr->e_shentsize < sizeof (shdr)))
394 414 return (RD_ERR);
395 415
396 416 addr += ehdr->e_shoff;
397 417 if (ps_pread(php, addr, &shdr, sizeof (shdr)) != PS_OK) {
398 418 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_5), EC_ADDR(addr)));
399 419 return (RD_ERR);
400 420 }
401 421
402 422 if (shdr.sh_info == 0)
403 423 return (RD_ERR);
404 424
405 425 *phnum = shdr.sh_info;
406 426 return (RD_OK);
407 427 }
408 428
409 429 rd_err_e
410 430 _rd_get_dyns32(rd_agent_t *rap, psaddr_t addr, Dyn **dynpp, size_t *dynpp_sz)
411 431 {
412 432 struct ps_prochandle *php = rap->rd_psp;
413 433 rd_err_e err;
414 434 uint_t phnum;
415 435 Ehdr ehdr;
416 436 Phdr phdr;
417 437 Dyn *dynp;
418 438 int i;
419 439
420 440 /* We only need to muck with dyn elements for ET_DYN objects */
421 441 if ((err = _rd_get_ehdr32(rap, addr, &ehdr, &phnum)) != RD_OK)
422 442 return (err);
423 443
424 444 for (i = 0; i < phnum; i++) {
425 445 psaddr_t a = addr + ehdr.e_phoff + (i * ehdr.e_phentsize);
426 446 if (ps_pread(php, a, &phdr, sizeof (phdr)) != PS_OK) {
427 447 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_6), EC_ADDR(a)));
428 448 return (RD_ERR);
429 449 }
430 450 if (phdr.p_type == PT_DYNAMIC)
431 451 break;
432 452 }
433 453 if (i == phnum)
434 454 return (RD_ERR);
435 455
436 456 if ((dynp = malloc(phdr.p_filesz)) == NULL)
437 457 return (RD_ERR);
438 458 if (ehdr.e_type == ET_DYN)
439 459 phdr.p_vaddr += addr;
440 460 if (ps_pread(php, phdr.p_vaddr, dynp, phdr.p_filesz) != PS_OK) {
441 461 free(dynp);
442 462 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_6),
443 463 EC_ADDR(phdr.p_vaddr)));
444 464 return (RD_ERR);
445 465 }
446 466
447 467 *dynpp = dynp;
448 468 if (dynpp_sz != NULL)
449 469 *dynpp_sz = phdr.p_filesz;
450 470 return (RD_OK);
451 471 }
452 472
453 473 rd_err_e
454 474 _rd_event_enable32(rd_agent_t *rap, int onoff)
455 475 {
456 476 struct ps_prochandle *php = rap->rd_psp;
457 477 Rtld_db_priv rdb;
458 478
459 479 LOG(ps_plog(MSG_ORIG(MSG_DB_RDEVENTENABLE), rap->rd_dmodel, onoff));
460 480 /*
461 481 * Tell the debugged process that debugging is occuring
462 482 * This will enable the storing of event messages so that
463 483 * the can be gathered by the debugger.
464 484 */
465 485 if (ps_pread(php, rap->rd_rdebug, (char *)&rdb,
466 486 sizeof (Rtld_db_priv)) != PS_OK) {
467 487 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_1),
468 488 EC_ADDR((uintptr_t)&rdb)));
469 489 return (RD_DBERR);
470 490 }
471 491
472 492 if (onoff)
473 493 rdb.rtd_rdebug.r_flags |= RD_FL_DBG;
474 494 else
475 495 rdb.rtd_rdebug.r_flags &= ~RD_FL_DBG;
476 496
477 497 if (ps_pwrite(php, rap->rd_rdebug, (char *)&rdb,
478 498 sizeof (Rtld_db_priv)) != PS_OK) {
479 499 LOG(ps_plog(MSG_ORIG(MSG_DB_WRITEFAIL_1),
480 500 EC_ADDR((uintptr_t)&rdb)));
481 501 return (RD_DBERR);
482 502 }
483 503
484 504 return (RD_OK);
485 505 }
486 506
487 507
488 508 rd_err_e
489 509 _rd_event_getmsg32(rd_agent_t *rap, rd_event_msg_t *emsg)
490 510 {
491 511 Rtld_db_priv rdb;
492 512
493 513 if (ps_pread(rap->rd_psp, rap->rd_rdebug, (char *)&rdb,
494 514 sizeof (Rtld_db_priv)) != PS_OK) {
495 515 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_2),
496 516 EC_ADDR(rap->rd_rdebug)));
497 517 return (RD_DBERR);
498 518 }
499 519 emsg->type = rdb.rtd_rdebug.r_rdevent;
500 520 if (emsg->type == RD_DLACTIVITY) {
501 521 switch (rdb.rtd_rdebug.r_state) {
502 522 case RT_CONSISTENT:
503 523 emsg->u.state = RD_CONSISTENT;
504 524 break;
505 525 case RT_ADD:
506 526 emsg->u.state = RD_ADD;
507 527 break;
508 528 case RT_DELETE:
509 529 emsg->u.state = RD_DELETE;
510 530 break;
511 531 }
512 532 } else
513 533 emsg->u.state = RD_NOSTATE;
514 534
515 535 LOG(ps_plog(MSG_ORIG(MSG_DB_RDEVENTGETMSG), rap->rd_dmodel,
516 536 emsg->type, emsg->u.state));
517 537
518 538 return (RD_OK);
519 539 }
520 540
521 541
522 542 rd_err_e
523 543 _rd_objpad_enable32(struct rd_agent *rap, size_t padsize)
524 544 {
525 545 Rtld_db_priv db_priv;
526 546 struct ps_prochandle *php = rap->rd_psp;
527 547
528 548 LOG(ps_plog(MSG_ORIG(MSG_DB_RDOBJPADE), EC_ADDR(padsize)));
529 549
530 550 if (ps_pread(php, rap->rd_rtlddbpriv, (char *)&db_priv,
531 551 sizeof (Rtld_db_priv)) != PS_OK) {
532 552 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_3),
533 553 EC_ADDR(rap->rd_rtlddbpriv)));
534 554 return (RD_DBERR);
535 555 }
536 556 #if defined(_LP64) && !defined(_ELF64)
537 557 /*LINTED*/
538 558 db_priv.rtd_objpad = (uint32_t)padsize;
539 559 #else
540 560 db_priv.rtd_objpad = padsize;
541 561 #endif
542 562 if (ps_pwrite(php, rap->rd_rtlddbpriv, (char *)&db_priv,
543 563 sizeof (Rtld_db_priv)) != PS_OK) {
544 564 LOG(ps_plog(MSG_ORIG(MSG_DB_WRITEFAIL_2),
545 565 EC_ADDR(rap->rd_rtlddbpriv)));
546 566 return (RD_DBERR);
547 567 }
548 568 return (RD_OK);
549 569 }
550 570
551 571 static rd_err_e
552 572 iter_map(rd_agent_t *rap, unsigned long ident, psaddr_t lmaddr,
553 573 rl_iter_f *cb, void *client_data, uint_t *abort_iterp)
554 574 {
555 575 while (lmaddr) {
556 576 Rt_map rmap;
557 577 rd_loadobj_t lobj;
558 578 int i;
559 579 ulong_t off;
560 580 Ehdr ehdr;
561 581 Phdr phdr;
562 582
563 583 if (ps_pread(rap->rd_psp, lmaddr, (char *)&rmap,
564 584 sizeof (Rt_map)) != PS_OK) {
565 585 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPFAIL)));
566 586 return (RD_DBERR);
567 587 }
568 588
569 589 /*
570 590 * As of 'VERSION5' we only report objects
571 591 * which have been fully relocated. While the maps
572 592 * might be in a consistent state - if a object hasn't
573 593 * been relocated - it's not really ready for the debuggers
574 594 * to examine. This is mostly due to the fact that we
575 595 * might still be mucking with the text-segment, if
576 596 * we are - we could conflict with any break-points
577 597 * the debuggers might have set.
578 598 */
579 599 if (rap->rd_rdebugvers >= R_RTLDDB_VERSION5) {
580 600 if ((FLAGS(&rmap) & FLG_RT_RELOCED) == 0) {
581 601 lmaddr = (psaddr_t)NEXT(&rmap);
582 602 continue;
583 603 }
584 604 }
585 605
586 606 lobj.rl_base = (psaddr_t)ADDR(&rmap);
587 607 lobj.rl_flags = 0;
588 608 lobj.rl_refnameaddr = (psaddr_t)REFNAME(&rmap);
589 609 if ((rap->rd_helper.rh_ops != NULL) &&
590 610 (rap->rd_helper.rh_ops->rho_lmid != LM_ID_NONE))
591 611 lobj.rl_lmident =
592 612 rap->rd_helper.rh_ops->rho_lmid;
593 613 else
594 614 lobj.rl_lmident = ident;
595 615
596 616 /*
597 617 * refnameaddr is only valid from a core file
598 618 * which is VERSION3 or greater.
599 619 */
600 620 if (rap->rd_rdebugvers < R_RTLDDB_VERSION3) {
601 621 lobj.rl_nameaddr = (psaddr_t)NAME(&rmap);
602 622 lobj.rl_bend = 0;
603 623 lobj.rl_padstart = 0;
604 624 lobj.rl_padend = 0;
605 625 } else {
606 626 lobj.rl_nameaddr = (psaddr_t)PATHNAME(&rmap);
607 627 lobj.rl_bend = ADDR(&rmap) + MSIZE(&rmap);
608 628 lobj.rl_padstart = PADSTART(&rmap);
609 629 lobj.rl_padend = PADSTART(&rmap) + PADIMLEN(&rmap);
610 630
611 631 }
612 632
613 633 if (rtld_db_version >= RD_VERSION2)
614 634 if (FLAGS(&rmap) & FLG_RT_IMGALLOC)
615 635 lobj.rl_flags |= RD_FLG_MEM_OBJECT;
616 636 if (rtld_db_version >= RD_VERSION2) {
617 637 lobj.rl_dynamic = (psaddr_t)DYN(&rmap);
618 638 }
619 639
620 640 if (rtld_db_version >= RD_VERSION4)
621 641 lobj.rl_tlsmodid = TLSMODID(&rmap);
622 642
623 643 /*
624 644 * Look for beginning of data segment.
625 645 *
626 646 * NOTE: the data segment can only be found for full
627 647 * processes and not from core images.
628 648 */
629 649 lobj.rl_data_base = 0;
630 650 if (rap->rd_flags & RDF_FL_COREFILE)
631 651 lobj.rl_data_base = 0;
632 652 else {
633 653 off = ADDR(&rmap);
634 654 if (ps_pread(rap->rd_psp, off, (char *)&ehdr,
635 655 sizeof (Ehdr)) != PS_OK) {
636 656 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPFAIL)));
637 657 return (RD_DBERR);
638 658 }
639 659 off += sizeof (Ehdr);
640 660 for (i = 0; i < ehdr.e_phnum; i++) {
641 661 if (ps_pread(rap->rd_psp, off, (char *)&phdr,
642 662 sizeof (Phdr)) != PS_OK) {
643 663 LOG(ps_plog(MSG_ORIG(
644 664 MSG_DB_LKMAPFAIL)));
645 665 return (RD_DBERR);
646 666 }
647 667 if ((phdr.p_type == PT_LOAD) &&
648 668 (phdr.p_flags & PF_W)) {
649 669 lobj.rl_data_base = phdr.p_vaddr;
650 670 if (ehdr.e_type == ET_DYN)
651 671 lobj.rl_data_base +=
652 672 ADDR(&rmap);
653 673 break;
654 674 }
655 675 off += ehdr.e_phentsize;
656 676 }
657 677 }
658 678
659 679 /*
660 680 * When we transfer control to the client we free the
661 681 * lock and re-atain it after we've returned from the
662 682 * client. This is to avoid any deadlock situations.
663 683 */
664 684 LOG(ps_plog(MSG_ORIG(MSG_DB_ITERMAP), cb, client_data,
665 685 EC_ADDR(lobj.rl_base), EC_ADDR(lobj.rl_lmident)));
666 686 RDAGUNLOCK(rap);
667 687 if ((*cb)(&lobj, client_data) == 0) {
668 688 LOG(ps_plog(MSG_ORIG(MSG_DB_CALLBACKR0)));
669 689 RDAGLOCK(rap);
670 690 *abort_iterp = 1;
671 691 break;
672 692 }
673 693 RDAGLOCK(rap);
674 694 lmaddr = (psaddr_t)NEXT(&rmap);
675 695 }
676 696 return (RD_OK);
677 697 }
678 698
679 699
680 700 static rd_err_e
681 701 _rd_loadobj_iter32_native(rd_agent_t *rap, rl_iter_f *cb, void *client_data,
682 702 uint_t *abort_iterp)
683 703 {
684 704 Rtld_db_priv db_priv;
685 705 TAPlist apl;
686 706 uintptr_t datap, nitems;
687 707 Addr addr;
688 708 rd_err_e rc;
689 709
690 710 LOG(ps_plog(MSG_ORIG(MSG_DB_LOADOBJITER), rap->rd_dmodel, cb,
691 711 client_data));
692 712
693 713 /*
694 714 * First, determine whether the link-map information has been
695 715 * established. Some debuggers have made an initial call to this
696 716 * function with a null call back function (cb), but expect a
697 717 * RD_NOMAPS error return rather than a RD_ERR return when the
698 718 * link-maps aren't available.
699 719 */
700 720 if (ps_pread(rap->rd_psp, rap->rd_rtlddbpriv, (char *)&db_priv,
701 721 sizeof (Rtld_db_priv)) != PS_OK) {
702 722 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_1),
703 723 EC_ADDR(rap->rd_rtlddbpriv)));
704 724 return (RD_DBERR);
705 725 }
706 726
707 727 if (db_priv.rtd_dynlmlst == NULL) {
708 728 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPNOINIT),
709 729 EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
710 730 return (RD_NOMAPS);
711 731 }
712 732
713 733 if (ps_pread(rap->rd_psp, (psaddr_t)db_priv.rtd_dynlmlst, (char *)&addr,
714 734 sizeof (Addr)) != PS_OK) {
715 735 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_3),
716 736 EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
717 737 return (RD_DBERR);
718 738 }
719 739
720 740 if (addr == NULL) {
721 741 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPNOINIT_1),
722 742 EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
723 743 return (RD_NOMAPS);
724 744 }
725 745
726 746 /*
727 747 * Having determined we have link-maps, ensure we have an iterator
728 748 * call back function.
729 749 */
730 750 if (cb == NULL) {
731 751 LOG(ps_plog(MSG_ORIG(MSG_DB_NULLITER)));
732 752 return (RD_ERR);
733 753 }
734 754
735 755 /*
736 756 * As of VERSION6, rtd_dynlmlst points to an APlist. Prior to VERSION6
737 757 * rtd_dynlmlst pointed to a List. But, there was a window where the
738 758 * version was not incremented, and this must be worked around by
739 759 * interpreting the APlist data. Read the initial APlist information.
740 760 */
741 761 if (ps_pread(rap->rd_psp, (psaddr_t)addr, (char *)&apl,
742 762 sizeof (TAPlist)) != PS_OK) {
743 763 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_4),
744 764 EC_ADDR((uintptr_t)addr)));
745 765 return (RD_DBERR);
746 766 }
747 767
748 768 /*
749 769 * The rtd_dynlmlst change from a List to an APlist occurred under
750 770 * 6801536 in snv_112. However, this change neglected to preserve
751 771 * backward compatibility by maintaining List processing and using a
752 772 * version increment to detect the change. 6862967, intergrated in
753 773 * snv_121 corrects the version detection. However, to catch objects
754 774 * built between these releases, we look at the first element of the
755 775 * APlist. apl_arritems indicates the number of APlist items that are
756 776 * available. This was originally initialized with a AL_CNT_DYNLIST
757 777 * value of 2 (one entry for LM_ID_BASE and one entry for LM_ID_LDSO).
758 778 * It is possible that the use of an auditor results in an additional
759 779 * link-map list, in which case the original apl_arritems would have
760 780 * been doubled.
761 781 *
762 782 * Therefore, if the debugging verion is VERSION6, or the apl_arritems
763 783 * entry has a value less than or equal to 4 and the debugging version
764 784 * is VERSION5, then we process APlists. Otherwise, fall back to List
765 785 * processing.
766 786 */
767 787 if ((rap->rd_rdebugvers >= R_RTLDDB_VERSION6) ||
768 788 ((rap->rd_rdebugvers == R_RTLDDB_VERSION5) &&
769 789 (apl.apl_arritems <= 4))) {
770 790 /*
771 791 * Iterate through each apl.ap_data[] entry.
772 792 */
773 793 for (datap = (uintptr_t)((char *)(uintptr_t)addr +
774 794 ((size_t)(((TAPlist *)0)->apl_data))), nitems = 0;
775 795 nitems < apl.apl_nitems; nitems++, datap += sizeof (Addr)) {
776 796 TLm_list lm;
777 797 ulong_t ident;
778 798
779 799 /*
780 800 * Obtain the Lm_list address for this apl.ap_data[]
781 801 * entry.
782 802 */
783 803 if (ps_pread(rap->rd_psp, (psaddr_t)datap,
784 804 (char *)&addr, sizeof (Addr)) != PS_OK) {
785 805 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5),
786 806 EC_ADDR(datap)));
787 807 return (RD_DBERR);
788 808 }
789 809
790 810 /*
791 811 * Obtain the Lm_list data for this Lm_list address.
792 812 */
793 813 if (ps_pread(rap->rd_psp, (psaddr_t)addr, (char *)&lm,
794 814 sizeof (TLm_list)) != PS_OK) {
795 815 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_6),
796 816 EC_ADDR((uintptr_t)addr)));
797 817 return (RD_DBERR);
798 818 }
799 819
800 820 /*
801 821 * Determine IDENT of current LM_LIST
802 822 */
803 823 if (lm.lm_flags & LML_FLG_BASELM)
804 824 ident = LM_ID_BASE;
805 825 else if (lm.lm_flags & LML_FLG_RTLDLM)
806 826 ident = LM_ID_LDSO;
807 827 else
808 828 ident = (ulong_t)addr;
809 829
810 830 if ((rc = iter_map(rap, ident, (psaddr_t)lm.lm_head,
811 831 cb, client_data, abort_iterp)) != RD_OK)
812 832 return (rc);
813 833
814 834 if (*abort_iterp != 0)
815 835 break;
816 836 }
817 837 } else {
818 838 TList list;
819 839 TListnode lnode;
820 840 Addr lnp;
821 841
822 842 /*
823 843 * Re-read the dynlmlst address to obtain a List structure.
824 844 */
825 845 if (ps_pread(rap->rd_psp, (psaddr_t)db_priv.rtd_dynlmlst,
826 846 (char *)&list, sizeof (TList)) != PS_OK) {
827 847 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_3),
828 848 EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
829 849 return (RD_DBERR);
830 850 }
831 851
832 852 /*
833 853 * Iterate through the link-map list.
834 854 */
835 855 for (lnp = (Addr)list.head; lnp; lnp = (Addr)lnode.next) {
836 856 Lm_list lml;
837 857 ulong_t ident;
838 858
839 859 /*
840 860 * Iterate through the List of Lm_list's.
841 861 */
842 862 if (ps_pread(rap->rd_psp, (psaddr_t)lnp, (char *)&lnode,
843 863 sizeof (TListnode)) != PS_OK) {
844 864 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_4),
845 865 EC_ADDR(lnp)));
846 866 return (RD_DBERR);
847 867 }
848 868
849 869 if (ps_pread(rap->rd_psp, (psaddr_t)lnode.data,
850 870 (char *)&lml, sizeof (Lm_list)) != PS_OK) {
851 871 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5),
852 872 EC_ADDR((uintptr_t)lnode.data)));
853 873 return (RD_DBERR);
854 874 }
855 875
856 876 /*
857 877 * Determine IDENT of current LM_LIST
858 878 */
859 879 if (lml.lm_flags & LML_FLG_BASELM)
860 880 ident = LM_ID_BASE;
861 881 else if (lml.lm_flags & LML_FLG_RTLDLM)
862 882 ident = LM_ID_LDSO;
863 883 else
864 884 ident = (unsigned long)lnode.data;
865 885
866 886 if ((rc = iter_map(rap, ident, (psaddr_t)lml.lm_head,
867 887 cb, client_data, abort_iterp)) != RD_OK)
868 888 return (rc);
869 889
870 890 if (*abort_iterp != 0)
871 891 break;
872 892 }
873 893 }
874 894
875 895 return (rc);
876 896 }
877 897
878 898 rd_err_e
879 899 _rd_loadobj_iter32(rd_agent_t *rap, rl_iter_f *cb, void *client_data)
880 900 {
881 901 rd_err_e rc, rc_brand = RD_OK;
882 902 uint_t abort_iter = 0;
883 903
884 904 /* First iterate over the native target objects */
885 905 rc = _rd_loadobj_iter32_native(rap, cb, client_data, &abort_iter);
886 906 if (abort_iter != 0)
887 907 return (rc);
888 908
889 909 /* Then iterate over any branded objects. */
890 910 if ((rap->rd_helper.rh_ops != NULL) &&
891 911 (rap->rd_helper.rh_ops->rho_loadobj_iter != NULL))
892 912 rc_brand = rap->rd_helper.rh_ops->rho_loadobj_iter(
893 913 rap->rd_helper.rh_data, cb, client_data);
894 914
895 915 rc = (rc != RD_OK) ? rc : rc_brand;
896 916 return (rc);
897 917 }
|
↓ open down ↓ |
580 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX