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]
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
29 * Global include file for the runtime linker.
51 * We use rtld_ino_t instead of ino_t so that we can get
52 * access to large inode values from 32-bit code.
55 typedef ino_t rtld_ino_t
;
57 typedef ino64_t rtld_ino_t
;
60 typedef struct rt_map Rt_map
;
61 typedef struct slookup Slookup
;
62 typedef struct sresult Sresult
;
65 * A binding descriptor. Establishes the binding relationship between two
66 * objects, the caller (originator) and the dependency (destination).
68 * Every relationship between two objects is tracked by a binding descriptor.
69 * This descriptor is referenced from a link-map's DEPENDS and CALLERS lists.
70 * Note, Aplist's are diagramed to fully expose the allocations required to
71 * establish the data structure relationships.
75 * ------------| b_caller |
76 * | | b_depend | ----------
78 * Rt_map | ---------- | Rt_map
79 * ---------- | ^ ^ | ----------
81 * | | -------- | | | |
82 * | DEPENDS | ----> | | | | -------- | |
83 * | | | | | | | | <---- | CALLERS |
84 * | | | | --- | | | | |
86 * | | -------- | | | |
87 * ---------- Aplist -------- ----------
91 Rt_map
*b_caller
; /* caller (originator) of a binding */
92 Rt_map
*b_depend
; /* dependency (destination) of a */
94 uint_t b_flags
; /* relationship of caller to the */
98 #define BND_NEEDED 0x0001 /* caller NEEDED the dependency */
99 #define BND_REFER 0x0002 /* caller relocation references the */
101 #define BND_FILTER 0x0004 /* binding identifies filter, used */
102 /* for diagnostics only */
104 * Private structure for communication between rtld_db and rtld.
106 * We must bump the version number when ever an update in one of the
107 * structures/fields that rtld_db reads is updated. This hopefully permits
108 * rtld_db implementations of the future to recognize core files produced on
109 * older systems and deal with these core files accordingly.
111 * As of version 'R_RTLDDB_VERSION <= 2' the following fields were valid for
112 * core file examination (basically the public Link_map):
120 * Valid fields for R_RTLDDB_VERSION3
129 * Valid fields for R_RTLDDB_VERSION4
133 * Valid fields for R_RTLDDB_VERSION5
135 * Added rtld_flags & FLG_RT_RELOCED to stable flags range
137 * Valid fields for R_RTLDDB_VERSION6
139 * rtd_dynlmlst converted from a List to APlist
141 #define R_RTLDDB_VERSION1 1 /* base version level - used for core */
142 /* file examination */
143 #define R_RTLDDB_VERSION2 2 /* minor revision - not relevant for */
145 #define R_RTLDDB_VERSION3 3
146 #define R_RTLDDB_VERSION4 4
147 #define R_RTLDDB_VERSION5 5
148 #define R_RTLDDB_VERSION6 6
149 #define R_RTLDDB_VERSION R_RTLDDB_VERSION6 /* current version */
151 typedef struct rtld_db_priv
{
152 struct r_debug rtd_rdebug
; /* original r_debug structure */
153 Word rtd_version
; /* version no. */
154 size_t rtd_objpad
; /* padding around mmap()ed objects */
155 APlist
**rtd_dynlmlst
; /* pointer to dynlm_list pointer */
159 typedef struct rtld_db_priv32
{
160 struct r_debug32 rtd_rdebug
; /* original r_debug structure */
161 Elf32_Word rtd_version
; /* version no. */
162 Elf32_Word rtd_objpad
; /* padding around mmap()ed objects */
163 Elf32_Addr rtd_dynlmlst
; /* pointer to dynlm_list */
165 #endif /* _SYSCALL32 */
168 * External function definitions. ld.so.1 must convey information to libc in
169 * regards to threading. libc also provides routines for atexit() and message
170 * localization. libc provides the necessary interfaces via its RTLDINFO
171 * structure and/or later _ld_libc() calls.
173 * These external functions are maintained for each link-map list, and used
174 * where appropriate. The functions are associated with the object that
175 * provided them, so that should the object be deleted (say, from an alternative
176 * link-map), the functions can be removed.
179 Rt_map
*lc_lmp
; /* function provider */
181 int (*lc_func
)(); /* external function pointer */
182 uintptr_t lc_val
; /* external value */
183 char *lc_ptr
; /* external character pointer */
188 * Link map list definition. Link-maps are used to describe each loaded object.
189 * Lists of these link-maps describe the various namespaces within a process.
190 * The process executable and its dependencies are maintained on the lml_main
191 * list. The runtime linker, and its dependencies are maintained on the
192 * lml_rtld list. Additional lists can be created (see dlmopen()) for such
193 * things as auditors and their dependencies.
195 * Each link-map list maintains an Alist of one, or more, linked lists of
196 * link-maps. For backward compatibility, the lm_head/lm_tail elements are
197 * initialized to the first linked-list of link-maps:
201 * | lm_tail | ------------------------------------
202 * | lm_head | -------------------- |
203 * | | | Rt_map | Rt_map
204 * | | | ------ | ------
205 * | | Alist --> | | |--> | |
206 * | | --------- | | | -- | |
207 * | lm_lists | ----> | | | | | --> | |
208 * | | |---------| | | | | | |
209 * | | | lc_head | -- ------ | ------
210 * | | | lc_tail | ------------------
212 * ---------- | lc_head |
216 * Multiple link-map lists exist to support the addition of lazy loaded
217 * families, filtee families, and dlopen() families. The intent of these
218 * lists is to insure that a family of objects that are to be loaded are
219 * fully relocatable, and hence usable, before they become part of the main
220 * (al_data[0]) link-map control list. This main link-map control list is
221 * the only list in existence when control is transferred to user code.
223 * During process initialization, the dynamic executable and its non-lazy
224 * dependencies are maintained on al_data[0]. If a new object is loaded, then
225 * this object is added to the next available control list [1], typically
226 * al_data[1]. Any dependencies of this object that have not already been
227 * loaded are added to the same control list. Once all of the objects on the
228 * new control list have been successfully relocated, the objects are moved from
229 * the new control list to the highest control list to which objects of the new
230 * control list bound to, typically al_data[1] to al_data[0].
232 * Each loading scenario can be broken down as follows:
234 * setup() - only the initial link-map control list is used:
235 * i. create al_data[0]
236 * ii. add new link-map for main on al_data[0]
237 * iii. analyze al_data[0] to add all non-lazy dependencies
238 * iv. relocate al_data[0] dependencies.
240 * dlopen() - the initiator can only be the initial link-map control list:
241 * i. create al_data[1] from caller al_data[0]
242 * ii. add new link-map for the dlopen'ed object on al_data[1]
243 * iii. analyze al_data[1] to add all non-lazy dependencies
244 * iv. relocate al_data[1] dependencies, and move to al_data[0].
246 * filtee and lazy loading processing - the initiator can be any link-map
247 * control list that is being relocated:
248 * i. create al_data[y] from caller al_data[x]
249 * ii. add new link-map for the new object on al_data[y]
250 * iii. analyze al_data[y] to add all non-lazy dependencies
251 * iv. relocate al_data[y] dependencies, and move to al_data[x].
253 * This Alist therefore maintains a stack of link-map control lists. The newest
254 * link-map control list can locate symbols within any of the former lists,
255 * however, control is not passed to a former list until the newest lists
256 * processing is complete. Thus, objects can't bind to new objects until they
257 * have been fully analyzed and relocated.
259 * [1] Note, additional link-map control list creation occurs after the head
260 * link-map object (typically the dynamic executable) has been relocated. This
261 * staging is required to satisfy the binding requirements of copy relocations.
262 * Copy relocations, effectively, transfer the bindings of the copied data
263 * (say _iob in libc.so.1) to the copy location (_iob in the application).
264 * Thus an object that might bind to the original copy data must be redirected
265 * to the copy reference. As the knowledge of a copy relocation having taken
266 * place is only known after relocating the application, link-map control list
267 * additions are suspended until after this relocation has completed.
272 APlist
*lc_now
; /* pending promoted bind-now objects */
276 #define LMC_FLG_ANALYZING 0x01 /* control list is being analyzed */
277 #define LMC_FLG_RELOCATING 0x02 /* control list is being relocated */
278 #define LMC_FLG_REANALYZE 0x04 /* repeat analysis (established when */
279 /* interposers are added */
283 * BEGIN: Exposed to rtld_db - don't move, don't delete
285 Rt_map
*lm_head
; /* linked list pointers to active */
286 Rt_map
*lm_tail
; /* link-map list */
287 APlist
*lm_handle
; /* not used by rtld_db - but spacing */
288 /* is required for flags */
291 * END: Exposed to rtld_db - don't move, don't delete
293 Alist
*lm_rti
; /* list of RTLDINFO tables */
294 Audit_list
*lm_alp
; /* audit list descriptor */
295 avl_tree_t
*lm_fpavl
; /* avl tree of objects loaded */
296 Alist
*lm_lists
; /* active and pending link-map lists */
297 char ***lm_environ
; /* pointer to environment array */
298 Word lm_tflags
; /* transferable flags */
299 uint_t lm_obj
; /* total number of objs on link-map */
300 uint_t lm_init
; /* new obj since last init processing */
301 uint_t lm_lazy
; /* number of objects with pending */
302 /* lazy dependencies */
303 uint_t lm_tls
; /* new obj that require TLS */
304 uint_t lm_lmid
; /* unique link-map list identifier, */
305 char *lm_lmidstr
; /* and associated diagnostic string */
306 Alist
*lm_aud_cookies
; /* local auditor cookies */
307 Lc_desc lm_lcs
[CI_MAX
]; /* external libc functions */
313 * BEGIN: Exposed to rtld_db - don't move, don't delete
317 Elf32_Addr lm_handle
;
320 * END: Exposed to rtld_db - don't move, don't delete
325 Elf32_Addr lm_environ
;
326 Elf32_Word lm_tflags
;
332 Elf32_Addr lm_lmidstr
;
333 Elf32_Addr lm_aud_cookies
;
334 Elf32_Addr lm_lcs
[CI_MAX
];
336 #endif /* _SYSCALL32 */
339 * Possible Link_map list flags (Lm_list.lm_flags)
342 * BEGIN: Exposed to rtld_db - don't move, don't delete
344 #define LML_FLG_BASELM 0x00000001 /* primary link-map */
345 #define LML_FLG_RTLDLM 0x00000002 /* rtld link-map */
347 * END: Exposed to rtld_db - don't move, don't delete
349 #define LML_FLG_ACTAUDIT 0x00000004 /* audit activity posted */
350 #define LML_FLG_PLTREL 0x00000008 /* deferred plt relocation */
351 /* initialization (ld.so.1 */
353 #define LML_FLG_HOLDLOCK 0x00000010 /* hold the rtld mutex lock */
354 #define LML_FLG_ENVIRON 0x00000020 /* environ var initialized */
355 #define LML_FLG_INTRPOSE 0x00000040 /* interposing objs on list */
356 #define LML_FLG_LOCAUDIT 0x00000080 /* local auditors exists for */
357 /* this link-map list */
358 #define LML_FLG_LOADAVAIL 0x00000100 /* load anything available */
359 #define LML_FLG_IGNRELERR 0x00000200 /* ignore relocation errors - */
360 /* internal for crle(1) */
361 #define LML_FLG_STARTREL 0x00000400 /* relocation started */
362 #define LML_FLG_ATEXIT 0x00000800 /* atexit processing */
363 #define LML_FLG_OBJADDED 0x00001000 /* object(s) added */
364 #define LML_FLG_OBJDELETED 0x00002000 /* object(s) deleted */
365 #define LML_FLG_OBJREEVAL 0x00004000 /* existing object(s) needs */
366 /* tsort reevaluation */
367 #define LML_FLG_INTRPOSETSORT 0x00008000 /* interpose tsorting done */
368 #define LML_FLG_AUDITNOTIFY 0x00010000 /* audit consistent required */
369 #define LML_FLG_GROUPSEXIST 0x00020000 /* local groups exist */
371 #define LML_FLG_TRC_LDDSTUB 0x00100000 /* identify lddstub */
372 #define LML_FLG_TRC_ENABLE 0x00200000 /* tracing enabled (ldd) */
373 #define LML_FLG_TRC_WARN 0x00400000 /* print warnings for undefs */
374 #define LML_FLG_TRC_VERBOSE 0x00800000 /* verbose (versioning) trace */
375 #define LML_FLG_TRC_SEARCH 0x01000000 /* trace search paths */
376 #define LML_FLG_TRC_UNREF 0x02000000 /* trace unreferenced */
378 #define LML_FLG_TRC_UNUSED 0x04000000 /* trace unused dependencies */
379 #define LML_FLG_TRC_INIT 0x08000000 /* print .init order */
380 #define LML_FLG_TRC_NOUNRESWEAK 0x10000000 /* unresolved weak references */
381 /* are not allowed */
382 #define LML_FLG_TRC_NOPAREXT 0x20000000 /* unresolved PARENT/EXTERN */
383 /* references are not */
385 #define LML_MSK_TRC 0xfff00000 /* tracing mask */
388 * Possible Link_map transferable flags (Lm_list.lm_tflags), i.e., link-map
389 * list flags that can be propagated to any new link-map list created.
391 #define LML_TFLG_NOLAZYLD 0x00000001 /* lazy loading disabled */
392 #define LML_TFLG_NODIRECT 0x00000002 /* direct bindings disabled */
393 #define LML_TFLG_NOAUDIT 0x00000004 /* auditing disabled */
394 #define LML_TFLG_LOADFLTR 0x00000008 /* trigger filtee loading */
396 #define LML_TFLG_AUD_PREINIT 0x00001000 /* preinit (audit) exists */
397 #define LML_TFLG_AUD_OBJSEARCH 0x00002000 /* objsearch (audit) exists */
398 #define LML_TFLG_AUD_OBJOPEN 0x00004000 /* objopen (audit) exists */
399 #define LML_TFLG_AUD_OBJFILTER 0x00008000 /* objfilter (audit) exists */
400 #define LML_TFLG_AUD_OBJCLOSE 0x00010000 /* objclose (audit) exists */
401 #define LML_TFLG_AUD_SYMBIND 0x00020000 /* symbind (audit) exists */
402 #define LML_TFLG_AUD_PLTENTER 0x00040000 /* pltenter (audit) exists */
403 #define LML_TFLG_AUD_PLTEXIT 0x00080000 /* pltexit (audit) exists */
404 #define LML_TFLG_AUD_ACTIVITY 0x00100000 /* activity (audit) exists */
407 * NOTE: Each auditing module establishes a set of audit flags, AFLAGS(), that
408 * define the auditing interfaces the module offers. These auditing flags are
409 * the LML_TFLG_AUD_ flags defined above. Global auditors result in setting
410 * the lm_tflags too. Local auditors only use the AFLAGS(). All tests for
411 * auditing inspect the lm_tflags and AFLAGS() for a specific auditing
412 * interface, and thus use the same flag to test for both types of auditors.
414 #define LML_TFLG_AUD_MASK 0x0ffff000 /* audit interfaces mask */
417 * Define a Group Handle.
419 * The capability of ld.so.1 to associate a group of objects, look for symbols
420 * within that group, ensure that groups are isolated from one another (with
421 * regard to relocations), and to unload a group, centers around a handle.
423 * Dependencies can be added to an existing handle as the dependencies are
424 * lazily loaded. The core dependencies on the handle are the ldd(1) list of
425 * the referenced object.
427 * Handles can be created from:
429 * - a dlopen() request. This associates a caller to a reference object,
430 * and the referenced objects dependencies. This group of objects can
431 * then be inspected for symbols (dlsym()).
432 * - a filtering request. This associates a filter (caller) to a referenced
433 * object (filtee). The redirection of filter symbols to their filtee
434 * counterpart is essentially a dlsym() using the filtee's handle.
436 * The handle created for these events is referred to as a public handle. This
437 * handle tracks the referenced object, all of the dependencies of the
438 * referenced object, and the caller (parent).
440 * Presently, an object may have two handles, one requested with RTLD_FIRST
443 * A handle may be referenced by any number of callers (parents). A reference
444 * count tracks the number. A dlclose() operation drops the reference count,
445 * and when the count is zero, the handle is used to determine the family of
446 * objects to unload. As bindings may occur to objects on the handle from
447 * other handles, it may not be possible to remove a complete family of objects
448 * or the handle itself. Handles in this state are moved to an orphan list.
449 * A handle on the orphan list is taken off the orphan list if the associated
450 * object is reopened. Otherwise, the handle remains on the orphan list for
451 * the duration of the process. The orphan list is inspected any time objects
452 * are unloaded, to determine if the orphaned objects can also be unloaded.
454 * Handles can also be created for internal uses:
456 * - to promote objects to RTLD_NOW.
457 * - to establish families for symbol binding fallback, required when lazy
458 * loadable objects are still pending.
460 * The handle created for these events is referred to as a private handle. This
461 * handle does not need to track the caller (parent), and because of this, does
462 * not need to be considered during dlclose() operations, as the handle can not
463 * be referenced by callers outside of the referenced objects family.
465 * Note, a private handle is essentially a subset of a public handle. Should
466 * an internal operation require a private handle, and a public handle already
467 * exist, the public handle can be used. Should an external operation require
468 * a public handle, and a private handle exist, the private handle is promoted
469 * to a public handle. Any handle that gets created will remain in existence
470 * for the life time of the referenced object.
472 * Objects can be dlopened using RTLD_NOW. This attribute requires that all
473 * relocations of the object, and its dependencies are processed immediately,
474 * before return to the caller. Typically, an object is loaded without
475 * RTLD_NOW, and procedure linkage relocations are satisfied when their
476 * associated function is first called. If an object is already loaded, and an
477 * RTLD_NOW request is made, then the object, and its dependencies, most undergo
478 * additional relocation processing. This promotion from lazy binding to
479 * immediate binding is carried out using handles, as the handle defines the
480 * dependencies that must be processed.
482 * To ensure that objects within a lazy loadable environment can be relocated,
483 * no matter whether the objects have their dependencies described completely,
484 * a symbol lookup fallback is employed. Any pending lazy loadable objects are
485 * loaded, and a handle established to search the object and it's dependencies
486 * for the required symbol.
488 * A group handle (and its associated group descriptors), is referenced from
489 * a link-map's HANDLES and GROUPS lists. Note, Aplist's are diagramed to
490 * fully expose the allocations required to establish the data structure
498 * | | gd_depend | ---------
501 * --------|--- | gd_depend | |
503 * | | |-----------| |
504 * | | | gd_depend | |
511 * | -- | gh_depends | |
512 * | --------- | gh_ownlmp | |
516 * Rt_map | | ------------ | Rt_map
517 * ---------- | | ^ ^ | ----------
518 * | | <- | | | --> | |
519 * | | <--- -------- | | | |
520 * | HANDLES | ----> | | | | -------- | |
521 * | | | | | | | | <---- | GROUPS |
522 * | | | | --- | | | | |
523 * | | | | --- | | | |
524 * | | -------- | | | |
525 * ---------- Aplist -------- ----------
529 Alist
*gh_depends
; /* handle dependency list */
530 Rt_map
*gh_ownlmp
; /* handle owners link-map */
531 Lm_list
*gh_ownlml
; /* handle owners link-map list */
532 uint_t gh_refcnt
; /* handle reference count */
533 uint_t gh_flags
; /* handle flags (GPH_ values) */
537 * Define the two categories of handle.
539 #define GPH_PUBLIC 0x0001 /* handle returned to caller(s) */
540 #define GPH_PRIVATE 0x0002 /* handle used internally */
543 * Define any flags that affects how the handle is used.
545 #define GPH_ZERO 0x0010 /* special handle for dlopen(0) */
546 #define GPH_LDSO 0x0020 /* special handle for ld.so.1 */
547 #define GPH_FIRST 0x0040 /* dlsym() can only use originating */
549 #define GPH_FILTEE 0x0080 /* handle identifies a filtee, used */
550 /* for diagnostics only */
552 * Define any state that is associated with the handle.
554 #define GPH_INITIAL 0x0100 /* handle is initialized */
557 * Define a Group Descriptor.
559 * Each dependency associated with a group handle is maintained by a group
560 * descriptor. The descriptor defines the associated dependency together with
561 * flags that indicate how the dependency can be used.
564 Rt_map
*gd_depend
; /* dependency */
565 uint_t gd_flags
; /* dependency flags (GPD_ values) */
568 #define GPD_DLSYM 0x0001 /* dependency available to dlsym() */
569 #define GPD_RELOC 0x0002 /* dependency available to satisfy */
570 /* relocation binding */
571 #define GPD_ADDEPS 0x0004 /* dependencies of this dependency */
572 /* should be added to handle */
573 #define GPD_PARENT 0x0008 /* dependency is a parent */
574 #define GPD_FILTER 0x0010 /* dependency is our filter */
575 #define GPD_REMOVE 0x0100 /* descriptor is a candidate for */
576 /* removal from the group */
579 * Define threading structures. For compatibility with libthread (T1_VERSION 1
580 * and TI_VERSION 2) our locking structure is sufficient to hold a mutex or a
581 * readers/writers lock.
590 typedef cond_t Rt_cond
;
593 * Define a dynamic section information descriptor. This parallels the entries
594 * in the .dynamic section and holds auxiliary information to implement lazy
595 * loading and filtee processing.
603 #define FLG_DI_STDFLTR 0x00001 /* .dynamic entry for DT_FILTER */
604 #define FLG_DI_AUXFLTR 0x00002 /* .dynamic entry for DT_AUXILIARY */
605 #define FLG_DI_SYMFLTR 0x00004 /* .dynamic entry for DT_SYMFILTER */
606 /* and DT_SYMAUXILIARY */
607 #define MSK_DI_FILTER 0x0000f /* mask for all filter possibilities */
609 #define FLG_DI_POSFLAG1 0x00010 /* .dynamic entry for DT_POSFLAG_1 */
610 #define FLG_DI_NEEDED 0x00020 /* .dynamic entry for DT_NEEDED */
611 #define FLG_DI_REGISTER 0x00040 /* .dynamic entry for DT_REGISTER */
612 #define FLG_DI_IGNORE 0x00080 /* .dynamic entry should be ignored */
614 #define FLG_DI_LAZY 0x00100 /* lazy needed entry, preceded by */
615 /* DF_P1_LAZYLOAD (DT_POSFLAG_1) */
616 #define FLG_DI_GROUP 0x00200 /* group needed entry, preceded by */
617 /* DF_P1_GROUPPERM (DT_POSFLAG_1) */
618 #define FLG_DI_DEFERRED 0x00400 /* deferred needed entry, preceded by */
619 /* DF_P1_DEFERRED (DT_POSFLAG_1) */
621 #define FLG_DI_LAZYFAIL 0x01000 /* the lazy loading of this entry */
623 #define FLG_DI_LDD_DONE 0x02000 /* entry has been processed (ldd) */
624 #define FLG_DI_DEF_DONE 0x04000 /* entry has been processed (dlinfo) */
627 * Data structure to track AVL tree of pathnames. This structure provides the
628 * basis of both the "not-found" node tree, and the "full-path" node tree. Both
629 * of these trees persist for the life of a process, although the "not-found"
630 * tree may be moved aside during a dlopen() or dlsym() fall back operation.
633 const char *pn_name
; /* path name */
634 avl_node_t pn_avl
; /* avl book-keeping (see SGSOFFSETOF) */
635 uint_t pn_hash
; /* path name hash value */
639 * Data structure to track AVL tree for full path names of objects that are
640 * loaded into memory.
643 PathNode fpn_node
; /* path node */
644 Rt_map
*fpn_lmp
; /* object link-map */
648 * A given link-map can hold either a supplier or receiver copy
649 * relocation list, but not both. This union is used to overlap
650 * the space used for the two lists.
653 Alist
*rtc_r
; /* receiver list (Rel_copy) */
654 APlist
*rtc_s
; /* supplier list (Rt_map *) */
659 * Link-map definition.
663 * BEGIN: Exposed to rtld_db - don't move, don't delete
665 Link_map rt_public
; /* public data */
666 const char *rt_pathname
; /* full pathname of loaded object */
667 ulong_t rt_padstart
; /* start of image (including padding) */
668 ulong_t rt_padimlen
; /* size of image (including padding */
669 ulong_t rt_msize
; /* total memory reservation range */
670 uint_t rt_flags
; /* state flags, see FLG below */
671 uint_t rt_flags1
; /* state flags1, see FL1 below */
672 ulong_t rt_tlsmodid
; /* TLS module id */
674 * END: Exposed to rtld_db - don't move, don't delete
676 APlist
*rt_alias
; /* list of linked file names */
677 APlist
*rt_fpnode
; /* list of FullPathNode AVL nodes */
678 char *rt_runpath
; /* LD_RUN_PATH and its equivalent */
679 Alist
*rt_runlist
; /* Pdesc structures */
680 APlist
*rt_depends
; /* list of dependencies */
681 APlist
*rt_callers
; /* list of callers */
682 APlist
*rt_handles
; /* dlopen handles */
683 APlist
*rt_groups
; /* groups we're a member of */
684 struct fct
*rt_fct
; /* file class table for this object */
685 void *rt_priv
; /* private data, object type specific */
686 Lm_list
*rt_list
; /* link map list we belong to */
687 uint_t rt_objfltrndx
; /* object filtees .dynamic index */
688 uint_t rt_symsfltrcnt
; /* number of standard symbol filtees */
689 uint_t rt_symafltrcnt
; /* number of auxiliary symbol filtees */
690 int rt_mode
; /* usage mode, see RTLD mode flags */
691 int rt_sortval
; /* temporary buffer to traverse graph */
692 uint_t rt_cycgroup
; /* cyclic group */
693 dev_t rt_stdev
; /* device id and inode number for .so */
694 rtld_ino_t rt_stino
; /* multiple inclusion checks */
695 const char *rt_origname
; /* original pathname of loaded object */
696 size_t rt_dirsz
; /* and its size */
697 size_t rt_lmsize
; /* size of the link-map allocation */
698 Rt_map_copy rt_copy
; /* list of copy relocations */
699 Audit_desc
*rt_auditors
; /* audit descriptor array */
700 Audit_info
*rt_audinfo
; /* audit information descriptor */
701 Syminfo
*rt_syminfo
; /* elf .syminfo section - here */
702 /* because it is checked in */
704 Addr
*rt_initarray
; /* .init_array table */
705 Addr
*rt_finiarray
; /* .fini_array table */
706 Addr
*rt_preinitarray
; /* .preinit_array table */
707 mmapobj_result_t
*rt_mmaps
; /* array of mapping information */
708 uint_t rt_mmapcnt
; /* and associated number */
709 uint_t rt_initarraysz
; /* size of .init_array table */
710 uint_t rt_finiarraysz
; /* size of .fini_array table */
711 uint_t rt_preinitarraysz
; /* size of .preinit_array table */
712 Dyninfo
*rt_dyninfo
; /* .dynamic information descriptors */
713 uint_t rt_dyninfocnt
; /* count of dyninfo entries */
714 uint_t rt_relacount
; /* no. of RELATIVE relocations */
715 uint_t rt_idx
; /* hold index within linkmap list */
716 uint_t rt_lazy
; /* number of lazy dependencies */
718 Cap
*rt_cap
; /* capabilities data */
719 Capchain
*rt_capchain
; /* capabilities chain data */
720 uint_t rt_cntl
; /* link-map control list we belong to */
721 uint_t rt_aflags
; /* auditor flags, see LML_TFLG_AUD_ */
722 Rt_cond rt_cv
; /* for waiting on flags changes */
723 Rt_lock rt_lock
; /* for coordinating flags changes */
724 /* address of _init */
725 thread_t rt_init_thread
; /* thread id in this lm's _init */
726 void (*rt_init
)(void);
727 /* address of _fini */
728 void (*rt_fini
)(void);
729 /* link map symbol interpreter */
730 int (*rt_symintp
)(Slookup
*, Sresult
*, uint_t
*, int *);
735 * Structure to allow 64-bit rtld_db to read 32-bit processes out of procfs.
742 typedef struct rt_map32
{
744 * BEGIN: Exposed to rtld_db - don't move, don't delete
746 Link_map32 rt_public
;
747 uint32_t rt_pathname
;
748 uint32_t rt_padstart
;
749 uint32_t rt_padimlen
;
753 uint32_t rt_tlsmodid
;
755 * END: Exposed to rtld_db - don't move, don't delete
768 uint32_t rt_objfltrndx
;
769 uint32_t rt_symsfltrcnt
;
770 uint32_t rt_symafltrcnt
;
773 uint32_t rt_cycgroup
;
776 uint32_t rt_origname
;
778 Rt_map_copy32 rt_copy
;
779 uint32_t rt_auditors
;
782 uint32_t rt_initarray
;
783 uint32_t rt_finiarray
;
784 uint32_t rt_preinitarray
;
787 uint32_t rt_initarraysz
;
788 uint32_t rt_finiarraysz
;
789 uint32_t rt_preinitarraysz
;
791 uint32_t rt_dyninfocnt
;
792 uint32_t rt_relacount
;
796 uint32_t rt_capchain
;
804 #endif /* _SYSCALL32 */
807 * Link map state flags.
810 * BEGIN: Exposed to rtld_db - don't move, don't delete
812 #define FLG_RT_ISMAIN 0x00000001 /* object represents main executable */
813 #define FLG_RT_IMGALLOC 0x00000002 /* image is allocated (not mmap'ed) */
815 * Available for r_debug version >= R_RTLDDB_VERSION5
817 #define FLG_RT_RELOCED 0x00000004 /* object has been relocated */
819 * END: Exposed to rtld_db - don't move, don't delete
821 #define FLG_RT_SETGROUP 0x00000008 /* group establishment required */
822 #define FLG_RT_CAP 0x00000010 /* process $CAPABILITY expansion */
823 #define FLG_RT_OBJECT 0x00000020 /* object processing (ie. .o's) */
824 #define FLG_RT_NEWLOAD 0x00000040 /* object is newly loaded */
825 #define FLG_RT_NODUMP 0x00000080 /* object can't be dldump(3x)'ed */
826 #define FLG_RT_DELETE 0x00000100 /* object can be deleted */
827 #define FLG_RT_ANALYZED 0x00000200 /* object has been analyzed */
828 #define FLG_RT_INITDONE 0x00000400 /* objects .init has been completed */
829 #define FLG_RT_TRANS 0x00000800 /* object is acting as a translator */
830 #define FLG_RT_FIXED 0x00001000 /* image location is fixed */
831 #define FLG_RT_PRELOAD 0x00002000 /* object was preloaded */
832 #define FLG_RT_ALTER 0x00004000 /* alternative object used */
833 #define FLG_RT_LOADFLTR 0x00008000 /* trigger filtee loading */
834 #define FLG_RT_AUDIT 0x00010000 /* object is an auditor */
835 #define FLG_RT_MODESET 0x00020000 /* MODE() has been initialized */
836 #define FLG_RT_ANALZING 0x00040000 /* object is being analyzed */
837 #define FLG_RT_INITFRST 0x00080000 /* execute .init first */
838 #define FLG_RT_NOOPEN 0x00100000 /* dlopen() not allowed */
839 #define FLG_RT_FINICLCT 0x00200000 /* fini has been collected (tsort) */
840 #define FLG_RT_INITCALL 0x00400000 /* objects .init has been called */
841 #define FLG_RT_OBJINTPO 0x00800000 /* object is a global interposer */
842 #define FLG_RT_SYMINTPO 0x01000000 /* object contains symbol interposer */
843 #define MSK_RT_INTPOSE 0x01800000 /* mask for all interposer */
845 #define FLG_RT_MOVE 0x02000000 /* object needs move operation */
846 #define FLG_RT_RELOCING 0x04000000 /* object is being relocated */
847 #define FLG_RT_REGSYMS 0x08000000 /* object has DT_REGISTER entries */
848 #define FLG_RT_INITCLCT 0x10000000 /* init has been collected (tsort) */
849 #define FLG_RT_PUBHDL 0x20000000 /* generate a handle for this object */
850 #define FLG_RT_PRIHDL 0x40000000 /* either public or private */
852 #define FL1_RT_COPYTOOK 0x00000001 /* copy relocation taken */
853 #define FL1_RT_ALTCHECK 0x00000002 /* alternative system capabilities */
855 #define FL1_RT_ALTCAP 0x00000004 /* alternative system capabilities */
857 #define FL1_RT_CONFSET 0x00000008 /* object was loaded by crle(1) */
858 #define FL1_RT_NODEFLIB 0x00000010 /* ignore default library search */
859 #define FL1_RT_ENDFILTE 0x00000020 /* filtee terminates filters search */
860 #define FL1_RT_DISPREL 0x00000040 /* object has *disp* relocation */
861 #define FL1_RT_DTFLAGS 0x00000080 /* DT_FLAGS element exists */
862 #define FL1_RT_LDDSTUB 0x00000100 /* identify lddstub */
863 #define FL1_RT_NOINIFIN 0x00000200 /* no .init or .fini exists */
864 #define FL1_RT_USED 0x00000400 /* symbol referenced from this object */
865 #define FL1_RT_SYMBOLIC 0x00000800 /* DF_SYMBOLIC was set - use */
866 /* symbolic sym resolution */
867 #define FL1_RT_OBJSFLTR 0x00001000 /* object is acting as a standard */
868 #define FL1_RT_OBJAFLTR 0x00002000 /* or auxiliary filter */
869 #define FL1_RT_SYMSFLTR 0x00004000 /* symbol is acting as a standard */
870 #define FL1_RT_SYMAFLTR 0x00008000 /* or auxiliary filter */
871 #define MSK_RT_FILTER 0x0000f000 /* mask for all filter possibilities */
873 #define FL1_RT_TLSADD 0x00010000 /* objects TLS has been registered */
874 #define FL1_RT_TLSSTAT 0x00020000 /* object requires static TLS */
875 #define FL1_RT_DIRECT 0x00040000 /* object has DIRECT bindings enabled */
876 #define FL1_RT_GLOBAUD 0x00080000 /* establish global auditing */
877 #define FL1_RT_DEPAUD 0x00100000 /* audit library from DT_DEPAUDIT */
880 * Flags for the tls_modactivity() routine
882 #define TM_FLG_MODADD 0x01 /* call tls_modadd() interface */
883 #define TM_FLG_MODREM 0x02 /* call tls_modrem() interface */
886 * Macros for getting to exposed, link_map data (R_RTLDDB_VERSION <= 2).
888 #define ADDR(X) ((X)->rt_public.l_addr)
889 #define NAME(X) ((X)->rt_public.l_name)
890 #define DYN(X) ((X)->rt_public.l_ld)
891 #define NEXT(X) ((X)->rt_public.l_next)
892 #define PREV(X) ((X)->rt_public.l_prev)
893 #define REFNAME(X) ((X)->rt_public.l_refname)
896 * An Rt_map starts with a Link_map, followed by other information.
897 * ld.so.1 allocates Rt_map structures, and then casts them to Link_map,
898 * and back, depending on context.
900 * On some platforms, Rt_map can have a higher alignment requirement
901 * than Link_map. On such platforms, the cast from Link_map to Rt_map will
902 * draw an E_BAD_PTR_CAST_ALIGN warning from lint. Since we allocate
903 * the memory as the higher alignment Rt_map, we know that this is a safe
904 * conversion. The LINKMAP_TO_RTMAP macro is used to handle the conversion
905 * in a manner that satisfies lint.
908 #define LINKMAP_TO_RTMAP(X) (Rt_map *)(void *)(X)
910 #define LINKMAP_TO_RTMAP(X) (Rt_map *)(X)
914 * Convenience macros for the common case of using
915 * NEXT()/PREV() and casting the result to (Rt_map *)
917 #define NEXT_RT_MAP(X) LINKMAP_TO_RTMAP(NEXT(X))
918 #define PREV_RT_MAP(X) LINKMAP_TO_RTMAP(PREV(X))
921 * Macros for getting to exposed, link_map data (R_RTLDDB_VERSION3).
923 #define PATHNAME(X) ((X)->rt_pathname)
924 #define PADSTART(X) ((X)->rt_padstart)
925 #define PADIMLEN(X) ((X)->rt_padimlen)
926 #define MSIZE(X) ((X)->rt_msize)
927 #define FLAGS(X) ((X)->rt_flags)
928 #define FLAGS1(X) ((X)->rt_flags1)
931 * Macros for getting to exposed, link_map data (R_RTLDDB_VERSION4).
933 #define TLSMODID(X) ((X)->rt_tlsmodid)
936 * Macros for getting to unexposed, link-map data.
938 #define LMSIZE(X) ((X)->rt_lmsize)
939 #define AFLAGS(X) ((X)->rt_aflags)
940 #define ALIAS(X) ((X)->rt_alias)
941 #define FPNODE(X) ((X)->rt_fpnode)
942 #define INIT(X) ((X)->rt_init)
943 #define FINI(X) ((X)->rt_fini)
944 #define RPATH(X) ((X)->rt_runpath)
945 #define RLIST(X) ((X)->rt_runlist)
946 #define DEPENDS(X) ((X)->rt_depends)
947 #define CALLERS(X) ((X)->rt_callers)
948 #define HANDLES(X) ((X)->rt_handles)
949 #define GROUPS(X) ((X)->rt_groups)
950 #define FCT(X) ((X)->rt_fct)
951 #define SYMINTP(X) ((X)->rt_symintp)
952 #define LIST(X) ((X)->rt_list)
953 #define OBJFLTRNDX(X) ((X)->rt_objfltrndx)
954 #define SYMSFLTRCNT(X) ((X)->rt_symsfltrcnt)
955 #define SYMAFLTRCNT(X) ((X)->rt_symafltrcnt)
956 #define MODE(X) ((X)->rt_mode)
957 #define SORTVAL(X) ((X)->rt_sortval)
958 #define CYCGROUP(X) ((X)->rt_cycgroup)
959 #define STDEV(X) ((X)->rt_stdev)
960 #define STINO(X) ((X)->rt_stino)
961 #define ORIGNAME(X) ((X)->rt_origname)
962 #define DIRSZ(X) ((X)->rt_dirsz)
963 #define COPY_R(X) ((X)->rt_copy.rtc_r)
964 #define COPY_S(X) ((X)->rt_copy.rtc_s)
965 #define AUDITORS(X) ((X)->rt_auditors)
966 #define AUDINFO(X) ((X)->rt_audinfo)
967 #define SYMINFO(X) ((X)->rt_syminfo)
968 #define INITARRAY(X) ((X)->rt_initarray)
969 #define FINIARRAY(X) ((X)->rt_finiarray)
970 #define PREINITARRAY(X) ((X)->rt_preinitarray)
971 #define MMAPS(X) ((X)->rt_mmaps)
972 #define MMAPCNT(X) ((X)->rt_mmapcnt)
973 #define INITARRAYSZ(X) ((X)->rt_initarraysz)
974 #define FINIARRAYSZ(X) ((X)->rt_finiarraysz)
975 #define PREINITARRAYSZ(X) ((X)->rt_preinitarraysz)
976 #define DYNINFO(X) ((X)->rt_dyninfo)
977 #define DYNINFOCNT(X) ((X)->rt_dyninfocnt)
978 #define RELACOUNT(X) ((X)->rt_relacount)
979 #define IDX(X) ((X)->rt_idx)
980 #define LAZY(X) ((X)->rt_lazy)
981 #define CNTL(X) ((X)->rt_cntl)
982 #define CAP(X) ((X)->rt_cap)
983 #define CAPCHAIN(X) ((X)->rt_capchain)
986 * Flags for tsorting.
988 #define RT_SORT_FWD 0x01 /* topological sort (.fini) */
989 #define RT_SORT_REV 0x02 /* reverse topological sort (.init) */
990 #define RT_SORT_DELETE 0x10 /* process FLG_RT_DELETE objects */
991 /* only (called via dlclose()) */
992 #define RT_SORT_INTPOSE 0x20 /* process interposer objects */
995 * Flags for lookup_sym (and hence find_sym) routines.
997 #define LKUP_DEFT 0x0000 /* simple lookup request */
998 #define LKUP_SPEC 0x0001 /* special ELF lookup (allows address */
999 /* resolutions to plt[] entries) */
1000 #define LKUP_LDOT 0x0002 /* indicates the original A_OUT */
1001 /* symbol had a leading `.' */
1002 #define LKUP_FIRST 0x0004 /* lookup symbol in first link map */
1004 #define LKUP_COPY 0x0008 /* lookup symbol for a COPY reloc, do */
1005 /* not bind to symbol at head */
1006 #define LKUP_STDRELOC 0x0010 /* lookup originates from a standard */
1007 /* relocation (elf_reloc()) */
1008 #define LKUP_SELF 0x0020 /* lookup symbol in ourself - undef */
1010 #define LKUP_WEAK 0x0040 /* relocation reference is weak */
1011 #define LKUP_NEXT 0x0080 /* request originates from RTLD_NEXT */
1012 #define LKUP_NODESCENT 0x0100 /* don't descend through dependencies */
1013 #define LKUP_NOFALLBACK 0x0200 /* don't fall back to loading */
1014 /* pending lazy dependencies */
1015 #define LKUP_DIRECT 0x0400 /* direct binding request */
1016 #define LKUP_SYMNDX 0x0800 /* establish symbol index */
1017 #define LKUP_SINGLETON 0x1000 /* search for a singleton symbol */
1018 #define LKUP_STANDARD 0x2000 /* standard lookup - originated from */
1019 /* head link-map element */
1020 #define LKUP_WORLD 0x4000 /* ensure world lookup */
1021 #define LKUP_DLSYM 0x8000 /* lookup stems from dlsym() request */
1024 * For the runtime linker to perform a symbol search, a number of data items
1025 * related to the search are required. An Slookup data structure is used to
1026 * convey this data to lookup_sym(), and in special cases, to other core
1027 * routines that provide the implementation details for lookup_sym()
1029 * The symbol name (sl_name), the caller (sl_cmap), and the link-map from which
1030 * to start the search (sl_imap) are fundamental to the symbol search. The
1031 * initial search link-map might get modified by the core routines that provide
1032 * the implementation details for lookup_sym(). This modification accommodates
1033 * requirements such as processing a handle, direct binding and interposition.
1034 * The association between the caller and the potential destination also
1035 * determines whether the destination is a candidate to search.
1037 * The lookup identifier (sl_id) is used to identify a runtime linker operation.
1038 * Within this operation, any lazy loads that fail are not re-examined. This
1039 * technique keeps the overhead of processing a failed lazy load to a minimum.
1041 * Symbol searches that originate from a relocation record are accompanied by
1042 * the relocation index (sl_rsymndx), the symbol reference (sl_rsym) and
1043 * possibly the relocation type (sl_rtype). This data provides for determining
1044 * lazy loading, direct binding, and special symbol processing requirements
1045 * such as copy relocations and singleton lookup.
1047 * The symbols hash value is computed by lookup_sym, and propagated throughout
1048 * the search engine. Note, occasionally the Slookup data is passed to a core
1049 * routine that provides the implementation details for lookup_sym(), ie.
1050 * elf_find_sym(), in which case the caller must initialize the hash value.
1052 * The symbols binding information is established by lookup_sym() when the
1053 * symbols relocation type is supplied. Weak bindings allow relocations to
1054 * be set to zero should a symbol lookup fail.
1056 * The flags allow the caller to control aspects of the search, including the
1057 * interpretation of copy relocations, etc. Note, a number of flag settings
1058 * are established in lookup_sym() from attributes of the symbol reference.
1061 const char *sl_name
; /* symbol name */
1062 Rt_map
*sl_cmap
; /* callers link-map */
1063 Rt_map
*sl_imap
; /* initial link-map to search */
1064 ulong_t sl_id
; /* identifier for this lookup */
1065 ulong_t sl_hash
; /* symbol hash value */
1066 ulong_t sl_rsymndx
; /* referencing reloc symndx */
1067 Sym
*sl_rsym
; /* referencing symbol */
1068 uchar_t sl_rtype
; /* relocation type associate with */
1070 uchar_t sl_bind
; /* symbols binding (returned) */
1071 uint_t sl_flags
; /* lookup flags */
1074 #define SLOOKUP_INIT(sl, name, cmap, imap, id, hash, rsymndx, rsym, rtype, \
1076 (void) (sl.sl_name = (name), sl.sl_cmap = (cmap), sl.sl_imap = (imap), \
1077 sl.sl_id = (id), sl.sl_hash = (hash), sl.sl_rsymndx = (rsymndx), \
1078 sl.sl_rsym = (rsym), sl.sl_rtype = (rtype), sl.sl_bind = 0, \
1079 sl.sl_flags = (flags))
1082 * After a symbol lookup has been resolved, the runtime linker needs to retain
1083 * information regarding the bound definition. An Sresult data structure is
1084 * used to provide this information.
1086 * The symbol name (sr_name) may differ from the original referenced symbol if
1087 * a symbol capabilities family member has resolved the binding. The defining
1088 * object (sr_dmap) indicates the object in which the definition has been found.
1089 * The symbol table entry (sr_sym) defines the bound symbol definition.
1091 * Note, a symbol lookup may start with one Sresult buffer, but underlying
1092 * routines (for example, those that probe filters) might employ their own
1093 * Sresult buffer. If a binding is allowed, the latter buffer may get inherited
1094 * by the former. Along with this chain of requests, binding info (binfo) and
1095 * not-found information (in_nfavl), may be passed between all the associated
1096 * functions. Hence, the binfo and in_nfavl data is not maintained as part of
1097 * a Sresult structure.
1100 const char *sr_name
; /* symbol definition name */
1101 Rt_map
*sr_dmap
; /* defining objects link-map */
1102 Sym
*sr_sym
; /* symbol table pointer */
1105 #define SRESULT_INIT(sr, name) \
1106 (void) (sr.sr_name = (name), sr.sr_dmap = NULL, sr.sr_sym = NULL)
1109 * Define a system capabilities structure for maintaining the various
1110 * capabilities of the system. This structure follows the Objcapset definition
1111 * from libld.h, however the system can only have one platform or machine
1112 * hardware name, thus this structure is a little simpler.
1114 * Note, the amd64 version of elf_rtbndr assumes that the sc_hw_1 value is at
1115 * offset zero. If you are changing this structure in a way that invalidates
1116 * this you need to update that code.
1119 elfcap_mask_t sc_hw_1
; /* CA_SUNW_HW_1 capabilities */
1120 elfcap_mask_t sc_sf_1
; /* CA_SUNW_SF_1 capabilities */
1121 elfcap_mask_t sc_hw_2
; /* CA_SUNW_HW_2 capabilities */
1122 char *sc_plat
; /* CA_SUNW_PLAT capability */
1123 size_t sc_platsz
; /* and size */
1124 char *sc_mach
; /* CA_SUNW_MACH capability */
1125 size_t sc_machsz
; /* and size */
1129 * Define a number of .plt lookup outcomes, for use in binding diagnostics.
1139 PLT_T_NUM
/* Must be last */
1145 extern ulong_t ld_entry_cnt
; /* counter bumped on each entry to */
1147 extern Lm_list lml_main
; /* main's link map list */
1148 extern Lm_list lml_rtld
; /* rtld's link map list */
1149 extern Lm_list
*lml_list
[];
1151 extern Pltbindtype
elf_plt_write(uintptr_t, uintptr_t, void *, uintptr_t,
1153 extern Rt_map
*is_so_loaded(Lm_list
*, const char *, int *);
1154 extern int lookup_sym(Slookup
*, Sresult
*, uint_t
*, int *);
1155 extern int rt_dldump(Rt_map
*, const char *, int, Addr
);
1161 #endif /* _RTLD_H */