4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
28 #include <proc_service.h>
38 #include <sys/param.h>
41 * 64-bit builds are going to compile this module twice, the
42 * second time with _ELF64 defined. These defines should make
43 * all the necessary adjustments to the code.
47 #define _rd_event_enable32 _rd_event_enable64
48 #define _rd_event_getmsg32 _rd_event_getmsg64
49 #define _rd_get_dyns32 _rd_get_dyns64
50 #define _rd_get_ehdr32 _rd_get_ehdr64
51 #define _rd_objpad_enable32 _rd_objpad_enable64
52 #define _rd_loadobj_iter32 _rd_loadobj_iter64
53 #define _rd_reset32 _rd_reset64
54 #define find_dynamic_ent32 find_dynamic_ent64
55 #define validate_rdebug32 validate_rdebug64
56 #define TAPlist APlist
57 #define TLm_list Lm_list
59 #define TListnode Listnode
60 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_64
62 #define Rt_map Rt_map32
63 #define Rtld_db_priv Rtld_db_priv32
64 #define TAPlist APlist32
65 #define TLm_list Lm_list32
67 #define TListnode Listnode32
68 #define Lm_list Lm_list32
69 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_32
72 #define TAPlist APlist
73 #define TLm_list Lm_list
75 #define TListnode Listnode
76 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_32
80 * BrandZ added ps_pbrandname(). Many debuggers that link directly
81 * against librtld_db.so may not implement this interface. Hence
82 * we won't call the function directly, instead we'll try to look it
83 * up using the linker first and only invoke it if we find it.
85 typedef ps_err_e (*ps_pbrandname_fp_t
)(struct ps_prochandle
*,
89 validate_rdebug32(struct rd_agent
*rap
)
91 struct ps_prochandle
*php
= rap
->rd_psp
;
95 if (rap
->rd_rdebug
== 0)
99 * The rtld_db_priv structure contains both the traditional (exposed)
100 * r_debug structure as well as private data only available to
103 db_privp
= rap
->rd_rdebug
;
106 * Verify that librtld_db & rtld are at the proper revision
109 if (ps_pread(php
, db_privp
, (char *)&db_priv
,
110 sizeof (Rtld_db_priv
)) != PS_OK
) {
111 LOG(ps_plog(MSG_ORIG(MSG_DB_READPRIVFAIL_1
),
116 if ((db_priv
.rtd_version
< R_RTLDDB_VERSION1
) ||
117 (db_priv
.rtd_version
> R_RTLDDB_VERSION
)) {
118 LOG(ps_plog(MSG_ORIG(MSG_DB_BADPVERS
),
119 db_priv
.rtd_version
, R_RTLDDB_VERSION
));
124 * Is the image being examined from a core file or not.
125 * If it is a core file then the following write will fail.
127 if (ps_pwrite(php
, db_privp
, (char *)&db_priv
,
128 sizeof (Rtld_db_priv
)) != PS_OK
)
129 rap
->rd_flags
|= RDF_FL_COREFILE
;
131 rap
->rd_rdebugvers
= db_priv
.rtd_version
;
132 rap
->rd_rtlddbpriv
= db_privp
;
134 LOG(ps_plog(MSG_ORIG(MSG_DB_VALIDRDEBUG
), EC_ADDR(rap
->rd_rdebug
),
135 R_RTLDDB_VERSION
, rap
->rd_rdebugvers
,
136 rap
->rd_flags
& RDF_FL_COREFILE
));
142 find_dynamic_ent32(struct rd_agent
*rap
, psaddr_t dynaddr
,
143 Xword dyntag
, Dyn
*dyn
)
145 struct ps_prochandle
*php
= rap
->rd_psp
;
150 if (ps_pread(php
, dynaddr
, (void *)(&d
), sizeof (d
)) !=
152 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_4
),
156 dynaddr
+= sizeof (d
);
157 if (d
.d_tag
== dyntag
)
159 } while (d
.d_tag
!= DT_NULL
);
160 if (d
.d_tag
== dyntag
) {
162 LOG(ps_plog(MSG_ORIG(MSG_DB_FINDDYNAMIC
), EC_ADDR(dyntag
),
163 EC_ADDR(d
.d_un
.d_val
)));
166 LOG(ps_plog(MSG_ORIG(MSG_DB_NODYNDEBUG
), EC_ADDR(dyntag
)));
170 extern char rtld_db_helper_path
[MAXPATHLEN
];
173 _rd_reset32(struct rd_agent
*rap
)
176 struct ps_prochandle
*php
= rap
->rd_psp
;
177 const auxv_t
*auxvp
= NULL
;
179 char brandname
[MAXPATHLEN
];
180 char brandlib
[MAXPATHLEN
];
181 ps_pbrandname_fp_t ps_pbrandname
;
184 * librtld_db attempts three different methods to find
185 * the r_debug structure which is required to
186 * initialize itself. The methods are:
188 * entirely independent of any text segment
189 * and relies on the AT_SUN_LDDATA auxvector
190 * to find the ld.so.1::rdebug structure.
192 * lookup symbols in ld.so.1's symbol table
193 * to find the r_debug symbol.
195 * (old dbx method) dependent upon the
196 * text segment/symbol table of the
197 * executable and not ld.so.1. We lookup the
198 * _DYNAMIC symbol in the executable and look for
199 * the DT_DEBUG entry in the .dynamic table. This
202 * If none of that works - we fail.
204 LOG(ps_plog(MSG_ORIG(MSG_DB_RDRESET
), rap
->rd_dmodel
));
208 * Scan the aux vector looking for AT_BASE & AT_SUN_LDDATA
211 if (ps_pauxv(php
, &auxvp
) != PS_OK
) {
212 LOG(ps_plog(MSG_ORIG(MSG_DB_NOAUXV
)));
220 while (auxvp
->a_type
!= AT_NULL
) {
221 if (auxvp
->a_type
== AT_SUN_LDDATA
) {
223 rap
->rd_rdebug
= (uintptr_t)auxvp
->a_un
.a_ptr
;
224 LOG(ps_plog(MSG_ORIG(MSG_DB_FLDDATA
),
226 rc
= validate_rdebug32(rap
);
234 * method2 - look for r_rdebug symbol in ld.so.1
238 * If the AT_SUN_LDDATA auxv vector is not present
239 * fall back on doing a symlookup of
240 * the r_debug symbol. This is for backward
241 * compatiblity with older OS's
243 LOG(ps_plog(MSG_ORIG(MSG_DB_NOLDDATA
)));
244 if (ps_pglobal_lookup(php
, PS_OBJ_LDSO
, MSG_ORIG(MSG_SYM_DEBUG
),
245 &symaddr
) != PS_OK
) {
246 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL
),
247 MSG_ORIG(MSG_SYM_DEBUG
)));
250 rap
->rd_rdebug
= symaddr
;
251 LOG(ps_plog(MSG_ORIG(MSG_DB_SYMRDEBUG
),
253 rc
= validate_rdebug32(rap
);
259 * method3 - find DT_DEBUG in the executables .dynamic section.
263 if (ps_pglobal_lookup(php
, PS_OBJ_EXEC
,
264 MSG_ORIG(MSG_SYM_DYNAMIC
), &symaddr
) != PS_OK
) {
265 LOG(ps_plog(MSG_ORIG(MSG_DB_NODYNAMIC
)));
266 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED
)));
269 rc
= find_dynamic_ent32(rap
, symaddr
, DT_DEBUG
, &dyn
);
271 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED
)));
274 rap
->rd_rdebug
= dyn
.d_un
.d_ptr
;
275 rc
= validate_rdebug32(rap
);
277 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED
)));
283 * If we are debugging a branded executable, load the appropriate
284 * helper library, and call its initialization routine. Being unable
285 * to load the helper library is not a critical error. (Hopefully
286 * we'll still be able to access some objects in the target.)
288 ps_pbrandname
= (ps_pbrandname_fp_t
)dlsym(RTLD_PROBE
, "ps_pbrandname");
289 while ((ps_pbrandname
!= NULL
) &&
290 (ps_pbrandname(php
, brandname
, MAXPATHLEN
) == PS_OK
)) {
291 const char *isa
= "";
294 isa
= MSG_ORIG(MSG_DB_64BIT_PREFIX
);
297 if (rtld_db_helper_path
[0] != '\0')
298 (void) snprintf(brandlib
, MAXPATHLEN
,
299 MSG_ORIG(MSG_DB_BRAND_HELPERPATH_PREFIX
),
301 MSG_ORIG(MSG_DB_HELPER_PREFIX
), brandname
, isa
,
304 (void) snprintf(brandlib
, MAXPATHLEN
,
305 MSG_ORIG(MSG_DB_BRAND_HELPERPATH
),
306 MSG_ORIG(MSG_DB_HELPER_PREFIX
), brandname
, isa
,
309 rap
->rd_helper
.rh_dlhandle
= dlopen(brandlib
,
310 RTLD_LAZY
| RTLD_LOCAL
);
311 if (rap
->rd_helper
.rh_dlhandle
== NULL
) {
312 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADFAILED
),
317 rap
->rd_helper
.rh_ops
= dlsym(rap
->rd_helper
.rh_dlhandle
,
318 MSG_ORIG(MSG_SYM_BRANDOPS
));
319 if (rap
->rd_helper
.rh_ops
== NULL
) {
320 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERNOOPS
),
322 (void) dlclose(rap
->rd_helper
.rh_dlhandle
);
323 rap
->rd_helper
.rh_dlhandle
= NULL
;
327 rap
->rd_helper
.rh_data
= rap
->rd_helper
.rh_ops
->rho_init(rap
,
329 if (rap
->rd_helper
.rh_data
== NULL
) {
330 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERINITFAILED
)));
331 (void) dlclose(rap
->rd_helper
.rh_dlhandle
);
332 rap
->rd_helper
.rh_dlhandle
= NULL
;
333 rap
->rd_helper
.rh_ops
= NULL
;
337 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADED
), brandname
));
343 if ((rap
->rd_flags
& RDF_FL_COREFILE
) == 0) {
344 if (ps_pglobal_lookup(php
, PS_OBJ_LDSO
,
345 MSG_ORIG(MSG_SYM_PREINIT
), &symaddr
) != PS_OK
) {
346 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL
),
347 MSG_ORIG(MSG_SYM_PREINIT
)));
350 rap
->rd_preinit
= symaddr
;
352 if (ps_pglobal_lookup(php
, PS_OBJ_LDSO
,
353 MSG_ORIG(MSG_SYM_POSTINIT
), &symaddr
) != PS_OK
) {
354 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL
),
355 MSG_ORIG(MSG_SYM_POSTINIT
)));
358 rap
->rd_postinit
= symaddr
;
360 if (ps_pglobal_lookup(php
, PS_OBJ_LDSO
,
361 MSG_ORIG(MSG_SYM_DLACT
), &symaddr
) != PS_OK
) {
362 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL
),
363 MSG_ORIG(MSG_SYM_DLACT
)));
366 rap
->rd_dlact
= symaddr
;
374 _rd_get_ehdr32(struct rd_agent
*rap
,
375 psaddr_t addr
, Ehdr
*ehdr
, uint_t
*phnum
)
377 struct ps_prochandle
*php
= rap
->rd_psp
;
380 if (ps_pread(php
, addr
, ehdr
, sizeof (*ehdr
)) != PS_OK
) {
381 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_5
), EC_ADDR(addr
)));
387 if (ehdr
->e_phnum
!= PN_XNUM
) {
388 *phnum
= ehdr
->e_phnum
;
392 /* deal with elf extended program headers */
393 if ((ehdr
->e_shoff
== 0) || (ehdr
->e_shentsize
< sizeof (shdr
)))
396 addr
+= ehdr
->e_shoff
;
397 if (ps_pread(php
, addr
, &shdr
, sizeof (shdr
)) != PS_OK
) {
398 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_5
), EC_ADDR(addr
)));
402 if (shdr
.sh_info
== 0)
405 *phnum
= shdr
.sh_info
;
410 _rd_get_dyns32(rd_agent_t
*rap
, psaddr_t addr
, Dyn
**dynpp
, size_t *dynpp_sz
)
412 struct ps_prochandle
*php
= rap
->rd_psp
;
420 /* We only need to muck with dyn elements for ET_DYN objects */
421 if ((err
= _rd_get_ehdr32(rap
, addr
, &ehdr
, &phnum
)) != RD_OK
)
424 for (i
= 0; i
< phnum
; i
++) {
425 psaddr_t a
= addr
+ ehdr
.e_phoff
+ (i
* ehdr
.e_phentsize
);
426 if (ps_pread(php
, a
, &phdr
, sizeof (phdr
)) != PS_OK
) {
427 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_6
), EC_ADDR(a
)));
430 if (phdr
.p_type
== PT_DYNAMIC
)
436 if ((dynp
= malloc(phdr
.p_filesz
)) == NULL
)
438 if (ehdr
.e_type
== ET_DYN
)
439 phdr
.p_vaddr
+= addr
;
440 if (ps_pread(php
, phdr
.p_vaddr
, dynp
, phdr
.p_filesz
) != PS_OK
) {
442 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_6
),
443 EC_ADDR(phdr
.p_vaddr
)));
448 if (dynpp_sz
!= NULL
)
449 *dynpp_sz
= phdr
.p_filesz
;
454 _rd_event_enable32(rd_agent_t
*rap
, int onoff
)
456 struct ps_prochandle
*php
= rap
->rd_psp
;
459 LOG(ps_plog(MSG_ORIG(MSG_DB_RDEVENTENABLE
), rap
->rd_dmodel
, onoff
));
461 * Tell the debugged process that debugging is occuring
462 * This will enable the storing of event messages so that
463 * the can be gathered by the debugger.
465 if (ps_pread(php
, rap
->rd_rdebug
, (char *)&rdb
,
466 sizeof (Rtld_db_priv
)) != PS_OK
) {
467 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_1
),
468 EC_ADDR((uintptr_t)&rdb
)));
473 rdb
.rtd_rdebug
.r_flags
|= RD_FL_DBG
;
475 rdb
.rtd_rdebug
.r_flags
&= ~RD_FL_DBG
;
477 if (ps_pwrite(php
, rap
->rd_rdebug
, (char *)&rdb
,
478 sizeof (Rtld_db_priv
)) != PS_OK
) {
479 LOG(ps_plog(MSG_ORIG(MSG_DB_WRITEFAIL_1
),
480 EC_ADDR((uintptr_t)&rdb
)));
489 _rd_event_getmsg32(rd_agent_t
*rap
, rd_event_msg_t
*emsg
)
493 if (ps_pread(rap
->rd_psp
, rap
->rd_rdebug
, (char *)&rdb
,
494 sizeof (Rtld_db_priv
)) != PS_OK
) {
495 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_2
),
496 EC_ADDR(rap
->rd_rdebug
)));
499 emsg
->type
= rdb
.rtd_rdebug
.r_rdevent
;
500 if (emsg
->type
== RD_DLACTIVITY
) {
501 switch (rdb
.rtd_rdebug
.r_state
) {
503 emsg
->u
.state
= RD_CONSISTENT
;
506 emsg
->u
.state
= RD_ADD
;
509 emsg
->u
.state
= RD_DELETE
;
513 emsg
->u
.state
= RD_NOSTATE
;
515 LOG(ps_plog(MSG_ORIG(MSG_DB_RDEVENTGETMSG
), rap
->rd_dmodel
,
516 emsg
->type
, emsg
->u
.state
));
523 _rd_objpad_enable32(struct rd_agent
*rap
, size_t padsize
)
525 Rtld_db_priv db_priv
;
526 struct ps_prochandle
*php
= rap
->rd_psp
;
528 LOG(ps_plog(MSG_ORIG(MSG_DB_RDOBJPADE
), EC_ADDR(padsize
)));
530 if (ps_pread(php
, rap
->rd_rtlddbpriv
, (char *)&db_priv
,
531 sizeof (Rtld_db_priv
)) != PS_OK
) {
532 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_3
),
533 EC_ADDR(rap
->rd_rtlddbpriv
)));
536 #if defined(_LP64) && !defined(_ELF64)
538 db_priv
.rtd_objpad
= (uint32_t)padsize
;
540 db_priv
.rtd_objpad
= padsize
;
542 if (ps_pwrite(php
, rap
->rd_rtlddbpriv
, (char *)&db_priv
,
543 sizeof (Rtld_db_priv
)) != PS_OK
) {
544 LOG(ps_plog(MSG_ORIG(MSG_DB_WRITEFAIL_2
),
545 EC_ADDR(rap
->rd_rtlddbpriv
)));
552 iter_map(rd_agent_t
*rap
, unsigned long ident
, psaddr_t lmaddr
,
553 rl_iter_f
*cb
, void *client_data
, uint_t
*abort_iterp
)
563 if (ps_pread(rap
->rd_psp
, lmaddr
, (char *)&rmap
,
564 sizeof (Rt_map
)) != PS_OK
) {
565 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPFAIL
)));
570 * As of 'VERSION5' we only report objects
571 * which have been fully relocated. While the maps
572 * might be in a consistent state - if a object hasn't
573 * been relocated - it's not really ready for the debuggers
574 * to examine. This is mostly due to the fact that we
575 * might still be mucking with the text-segment, if
576 * we are - we could conflict with any break-points
577 * the debuggers might have set.
579 if (rap
->rd_rdebugvers
>= R_RTLDDB_VERSION5
) {
580 if ((FLAGS(&rmap
) & FLG_RT_RELOCED
) == 0) {
581 lmaddr
= (psaddr_t
)NEXT(&rmap
);
586 lobj
.rl_base
= (psaddr_t
)ADDR(&rmap
);
588 lobj
.rl_refnameaddr
= (psaddr_t
)REFNAME(&rmap
);
589 if ((rap
->rd_helper
.rh_ops
!= NULL
) &&
590 (rap
->rd_helper
.rh_ops
->rho_lmid
!= LM_ID_NONE
))
592 rap
->rd_helper
.rh_ops
->rho_lmid
;
594 lobj
.rl_lmident
= ident
;
597 * refnameaddr is only valid from a core file
598 * which is VERSION3 or greater.
600 if (rap
->rd_rdebugvers
< R_RTLDDB_VERSION3
) {
601 lobj
.rl_nameaddr
= (psaddr_t
)NAME(&rmap
);
603 lobj
.rl_padstart
= 0;
606 lobj
.rl_nameaddr
= (psaddr_t
)PATHNAME(&rmap
);
607 lobj
.rl_bend
= ADDR(&rmap
) + MSIZE(&rmap
);
608 lobj
.rl_padstart
= PADSTART(&rmap
);
609 lobj
.rl_padend
= PADSTART(&rmap
) + PADIMLEN(&rmap
);
613 if (rtld_db_version
>= RD_VERSION2
)
614 if (FLAGS(&rmap
) & FLG_RT_IMGALLOC
)
615 lobj
.rl_flags
|= RD_FLG_MEM_OBJECT
;
616 if (rtld_db_version
>= RD_VERSION2
) {
617 lobj
.rl_dynamic
= (psaddr_t
)DYN(&rmap
);
620 if (rtld_db_version
>= RD_VERSION4
)
621 lobj
.rl_tlsmodid
= TLSMODID(&rmap
);
624 * Look for beginning of data segment.
626 * NOTE: the data segment can only be found for full
627 * processes and not from core images.
629 lobj
.rl_data_base
= 0;
630 if (rap
->rd_flags
& RDF_FL_COREFILE
)
631 lobj
.rl_data_base
= 0;
634 if (ps_pread(rap
->rd_psp
, off
, (char *)&ehdr
,
635 sizeof (Ehdr
)) != PS_OK
) {
636 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPFAIL
)));
639 off
+= sizeof (Ehdr
);
640 for (i
= 0; i
< ehdr
.e_phnum
; i
++) {
641 if (ps_pread(rap
->rd_psp
, off
, (char *)&phdr
,
642 sizeof (Phdr
)) != PS_OK
) {
643 LOG(ps_plog(MSG_ORIG(
647 if ((phdr
.p_type
== PT_LOAD
) &&
648 (phdr
.p_flags
& PF_W
)) {
649 lobj
.rl_data_base
= phdr
.p_vaddr
;
650 if (ehdr
.e_type
== ET_DYN
)
655 off
+= ehdr
.e_phentsize
;
660 * When we transfer control to the client we free the
661 * lock and re-atain it after we've returned from the
662 * client. This is to avoid any deadlock situations.
664 LOG(ps_plog(MSG_ORIG(MSG_DB_ITERMAP
), cb
, client_data
,
665 EC_ADDR(lobj
.rl_base
), EC_ADDR(lobj
.rl_lmident
)));
667 if ((*cb
)(&lobj
, client_data
) == 0) {
668 LOG(ps_plog(MSG_ORIG(MSG_DB_CALLBACKR0
)));
674 lmaddr
= (psaddr_t
)NEXT(&rmap
);
681 _rd_loadobj_iter32_native(rd_agent_t
*rap
, rl_iter_f
*cb
, void *client_data
,
684 Rtld_db_priv db_priv
;
686 uintptr_t datap
, nitems
;
690 LOG(ps_plog(MSG_ORIG(MSG_DB_LOADOBJITER
), rap
->rd_dmodel
, cb
,
694 * First, determine whether the link-map information has been
695 * established. Some debuggers have made an initial call to this
696 * function with a null call back function (cb), but expect a
697 * RD_NOMAPS error return rather than a RD_ERR return when the
698 * link-maps aren't available.
700 if (ps_pread(rap
->rd_psp
, rap
->rd_rtlddbpriv
, (char *)&db_priv
,
701 sizeof (Rtld_db_priv
)) != PS_OK
) {
702 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_1
),
703 EC_ADDR(rap
->rd_rtlddbpriv
)));
707 if (db_priv
.rtd_dynlmlst
== 0) {
708 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPNOINIT
),
709 EC_ADDR((uintptr_t)db_priv
.rtd_dynlmlst
)));
713 if (ps_pread(rap
->rd_psp
, (psaddr_t
)db_priv
.rtd_dynlmlst
, (char *)&addr
,
714 sizeof (Addr
)) != PS_OK
) {
715 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_3
),
716 EC_ADDR((uintptr_t)db_priv
.rtd_dynlmlst
)));
721 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPNOINIT_1
),
722 EC_ADDR((uintptr_t)db_priv
.rtd_dynlmlst
)));
727 * Having determined we have link-maps, ensure we have an iterator
728 * call back function.
731 LOG(ps_plog(MSG_ORIG(MSG_DB_NULLITER
)));
736 * As of VERSION6, rtd_dynlmlst points to an APlist. Prior to VERSION6
737 * rtd_dynlmlst pointed to a List. But, there was a window where the
738 * version was not incremented, and this must be worked around by
739 * interpreting the APlist data. Read the initial APlist information.
741 if (ps_pread(rap
->rd_psp
, (psaddr_t
)addr
, (char *)&apl
,
742 sizeof (TAPlist
)) != PS_OK
) {
743 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_4
),
744 EC_ADDR((uintptr_t)addr
)));
749 * The rtd_dynlmlst change from a List to an APlist occurred under
750 * 6801536 in snv_112. However, this change neglected to preserve
751 * backward compatibility by maintaining List processing and using a
752 * version increment to detect the change. 6862967, intergrated in
753 * snv_121 corrects the version detection. However, to catch objects
754 * built between these releases, we look at the first element of the
755 * APlist. apl_arritems indicates the number of APlist items that are
756 * available. This was originally initialized with a AL_CNT_DYNLIST
757 * value of 2 (one entry for LM_ID_BASE and one entry for LM_ID_LDSO).
758 * It is possible that the use of an auditor results in an additional
759 * link-map list, in which case the original apl_arritems would have
762 * Therefore, if the debugging verion is VERSION6, or the apl_arritems
763 * entry has a value less than or equal to 4 and the debugging version
764 * is VERSION5, then we process APlists. Otherwise, fall back to List
767 if ((rap
->rd_rdebugvers
>= R_RTLDDB_VERSION6
) ||
768 ((rap
->rd_rdebugvers
== R_RTLDDB_VERSION5
) &&
769 (apl
.apl_arritems
<= 4))) {
771 * Iterate through each apl.ap_data[] entry.
773 for (datap
= (uintptr_t)((char *)(uintptr_t)addr
+
774 ((size_t)(((TAPlist
*)0)->apl_data
))), nitems
= 0;
775 nitems
< apl
.apl_nitems
; nitems
++, datap
+= sizeof (Addr
)) {
780 * Obtain the Lm_list address for this apl.ap_data[]
783 if (ps_pread(rap
->rd_psp
, (psaddr_t
)datap
,
784 (char *)&addr
, sizeof (Addr
)) != PS_OK
) {
785 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5
),
791 * Obtain the Lm_list data for this Lm_list address.
793 if (ps_pread(rap
->rd_psp
, (psaddr_t
)addr
, (char *)&lm
,
794 sizeof (TLm_list
)) != PS_OK
) {
795 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_6
),
796 EC_ADDR((uintptr_t)addr
)));
801 * Determine IDENT of current LM_LIST
803 if (lm
.lm_flags
& LML_FLG_BASELM
)
805 else if (lm
.lm_flags
& LML_FLG_RTLDLM
)
808 ident
= (ulong_t
)addr
;
810 if ((rc
= iter_map(rap
, ident
, (psaddr_t
)lm
.lm_head
,
811 cb
, client_data
, abort_iterp
)) != RD_OK
)
814 if (*abort_iterp
!= 0)
823 * Re-read the dynlmlst address to obtain a List structure.
825 if (ps_pread(rap
->rd_psp
, (psaddr_t
)db_priv
.rtd_dynlmlst
,
826 (char *)&list
, sizeof (TList
)) != PS_OK
) {
827 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_3
),
828 EC_ADDR((uintptr_t)db_priv
.rtd_dynlmlst
)));
833 * Iterate through the link-map list.
835 for (lnp
= (Addr
)list
.head
; lnp
; lnp
= (Addr
)lnode
.next
) {
840 * Iterate through the List of Lm_list's.
842 if (ps_pread(rap
->rd_psp
, (psaddr_t
)lnp
, (char *)&lnode
,
843 sizeof (TListnode
)) != PS_OK
) {
844 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_4
),
849 if (ps_pread(rap
->rd_psp
, (psaddr_t
)lnode
.data
,
850 (char *)&lml
, sizeof (Lm_list
)) != PS_OK
) {
851 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5
),
852 EC_ADDR((uintptr_t)lnode
.data
)));
857 * Determine IDENT of current LM_LIST
859 if (lml
.lm_flags
& LML_FLG_BASELM
)
861 else if (lml
.lm_flags
& LML_FLG_RTLDLM
)
864 ident
= (unsigned long)lnode
.data
;
866 if ((rc
= iter_map(rap
, ident
, (psaddr_t
)lml
.lm_head
,
867 cb
, client_data
, abort_iterp
)) != RD_OK
)
870 if (*abort_iterp
!= 0)
879 _rd_loadobj_iter32(rd_agent_t
*rap
, rl_iter_f
*cb
, void *client_data
)
881 rd_err_e rc
, rc_brand
= RD_OK
;
882 uint_t abort_iter
= 0;
884 /* First iterate over the native target objects */
885 rc
= _rd_loadobj_iter32_native(rap
, cb
, client_data
, &abort_iter
);
889 /* Then iterate over any branded objects. */
890 if ((rap
->rd_helper
.rh_ops
!= NULL
) &&
891 (rap
->rd_helper
.rh_ops
->rho_loadobj_iter
!= NULL
))
892 rc_brand
= rap
->rd_helper
.rh_ops
->rho_loadobj_iter(
893 rap
->rd_helper
.rh_data
, cb
, client_data
);
895 rc
= (rc
!= RD_OK
) ? rc
: rc_brand
;