rtld.h revision 883c6d492b73694fbeba5348b7468609213b7a81
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _RTLD_H
#define _RTLD_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Global include file for the runtime linker.
*/
#include <time.h>
#include <sgs.h>
#include <thread.h>
#include <synch.h>
#include <machdep.h>
#include <alist.h>
#include <libc_int.h>
#ifdef _SYSCALL32
#include <inttypes.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Linked list of directories or filenames (built from colon separated string).
*/
typedef struct pnode {
const char *p_name;
const char *p_oname;
void *p_info;
} Pnode;
/*
* A binding descriptor. Establishes the binding relationship between two
* objects, the caller (originator) and the dependency (destination).
*/
typedef struct {
/* binding */
/* dependency */
} Bnd_desc;
/* dependency */
/*
* Private structure for communication between rtld_db and rtld.
*
* We must bump the version number when ever an update in one of the
* structures/fields that rtld_db reads is updated. This hopefully permits
* rtld_db implementations of the future to recognize core files produced on
* older systems and deal with these core files accordingly.
*
* As of version 'RTLD_DB_VERSION <= 2' the following fields were valid for core
* file examination (basically the public Link_map):
*
* ADDR()
* NAME()
* DYN()
* NEXT()
* PREV()
*
* Valid fields for RTLD_DB_VERSION3
*
* PATHNAME()
* PADSTART()
* PADIMLEN()
* MSIZE()
* FLAGS()
* FLAGS1()
*
* Valid fields for RTLD_DB_VERSION4
*
* TLSMODID()
*
* Valid fields for RTLD_DB_VERSION5
*
* Added rtld_flags & FLG_RT_RELOCED to stable flags range
*
*/
/* file examination */
/* core files */
#define R_RTLDDB_VERSION3 3
#define R_RTLDDB_VERSION4 4
#define R_RTLDDB_VERSION5 5
typedef struct rtld_db_priv {
} Rtld_db_priv;
#ifdef _SYSCALL32
typedef struct rtld_db_priv32 {
#endif /* _SYSCALL32 */
/*
* External function definitions. ld.so.1 must convey information to libc in
* regards to threading. libc also provides routines for atexit() and message
* localization. libc provides the necessary interfaces via its RTLDINFO
*
* These external functions are maintained for each link-map list, and used
* where appropriate. The functions are associated with the object that
* provided them, so that should the object be deleted (say, from an alternative
* link-map), the functions can be removed.
*/
typedef struct {
union {
int (*lc_func)(); /* external function pointer */
char *lc_ptr; /* external character pointer */
} lc_un;
} Lc_desc;
/*
* Link map list definition. Link-maps are used to describe each loaded object.
* Lists of these link-maps describe the various namespaces within a process.
* The process executable and its dependencies are maintained on the lml_main
* list. The runtime linker, and its dependencies are maintained on the
* lml_rtld list. Additional lists can be created (see dlmopen()) for such
* things as auditors and their dependencies.
*
* Each link-map list maintains an Alist of one, or more, linked lists of
* initialized to the first linked-list of link-maps:
*
* Lm_list
* ----------
* | lm_tail | ------------------------------------
* | lm_head | -------------------- |
* | | | Rt_map | Rt_map
* | | | ------ | ------
* | | Alist --> | | |--> | |
* | | --------- | | | -- | |
* | lm_lists | ----> | | | | | --> | |
* | | |---------| | | | | | |
* | | | lc_head | -- ------ | ------
* | | | lc_tail | ------------------
* | | |---------|
* | lc_head |
* | lc_tail |
* |---------|
*
* Multiple link-map lists exist to support the addition of lazy loaded
* families, filtee families, and dlopen() families. The intent of these
* lists is to insure that a family of objects that are to be loaded are
* fully relocatable, and hence usable, before they become part of the main
* (al_data[0]) link-map control list. This main link-map control list is
* the only list in existence when control is transferred to user code.
*
* During process initialization, the dynamic executable and its non-lazy
* dependencies are maintained on al_data[0]. If a new object is loaded, then
* this object is added to the next available control list [1], typically
* al_data[1]. Any dependencies of this object that have not already been
* loaded are added to the same control list. Once all of the objects on the
* new control list have been successfully relocated, the objects are moved from
* the new control list to the highest control list to which objects of the new
* control list bound to, typically al_data[1] to al_data[0].
*
* Each loading scenario can be broken down as follows:
*
* setup() - only the initial link-map control list is used:
* i. create al_data[0]
* ii. add new link-map for main on al_data[0]
* iii. analyze al_data[0] to add all non-lazy dependencies
* iv. relocate al_data[0] dependencies.
*
* dlopen() - the initiator can only be the initial link-map control list:
* i. create al_data[1] from caller al_data[0]
* ii. add new link-map for the dlopen'ed object on al_data[1]
* iii. analyze al_data[1] to add all non-lazy dependencies
* iv. relocate al_data[1] dependencies, and move to al_data[0].
*
* filtee and lazy loading processing - the initiator can be any link-map
* control list that is being relocated:
* i. create al_data[y] from caller al_data[x]
* ii. add new link-map for the new object on al_data[y]
* iii. analyze al_data[y] to add all non-lazy dependencies
* iv. relocate al_data[y] dependencies, and move to al_data[x].
*
* This Alist therefore maintains a stack of link-map control lists. The newest
* link-map control list can locate symbols within any of the former lists,
* however, control is not passed to a former list until the newest lists
* processing is complete. Thus, objects can't bind to new objects until they
* have been fully analyzed and relocated.
*
* [1] Note, additional link-map control list creation occurs after the head
* link-map object (typically the dynamic executable) has been relocated. This
* staging is required to satisfy the binding requirements of copy relocations.
* Copy relocations, effectively, transfer the bindings of the copied data
* (say _iob in libc.so.1) to the copy location (_iob in the application).
* Thus an object that might bind to the original copy data must be redirected
* to the copy reference. As the knowledge of a copy relocation having taken
* place is only known after relocating the application, link-map control list
* additions are suspended until after this relocation has completed.
*/
typedef struct {
} Lm_cntl;
/* interposers are added */
struct lm_list {
/*
* BEGIN: Exposed to rtld_db - don't move, don't delete
*/
/* is required for flags */
/*
* END: Exposed to rtld_db - don't move, don't delete
*/
char ***lm_environ; /* pointer to environment array */
char *lm_lmidstr; /* and associated diagnostic string */
};
#ifdef _SYSCALL32
struct lm_list32 {
/*
* BEGIN: Exposed to rtld_db - don't move, don't delete
*/
/*
* END: Exposed to rtld_db - don't move, don't delete
*/
};
#endif /* _SYSCALL32 */
/*
* Possible Link_map list flags (Lm_list.lm_flags)
*/
/*
* BEGIN: Exposed to rtld_db - don't move, don't delete
*/
/*
* END: Exposed to rtld_db - don't move, don't delete
*/
/* initialization */
/* (ld.so.1 only) */
/* this link-map list */
/* internal for crle(1) */
/* tsort reevaluation */
/* dependencies remain */
/* dependencies */
/*
* Possible Link_map transferable flags (Lm_list.lm_tflags), i.e., link-map
* list flags that can be propagated to any new link-map list created.
*/
/*
* NOTE: Audit flags have duplicated FLAGS1() values. If more audit flags are
* added, update the FLAGS1() reservation FL1_AUD_RS_STR to FL1_AUD_RS_END
* defined later.
*/
/*
* Information for dlopen(), dlsym(), and dlclose() on libraries linked by rtld.
* Each shared object referred from a dlopen call has an associated group
* handle structure returned that describes a group of one or more objects.
*/
typedef struct {
} Grp_hdl;
/* dependency */
/* remain for this handle */
/*
* A group descriptor. A group handle (Grp_hdl) refers to a group of objects,
* each object, and its relationship to the handle, is maintained within a
* group descriptor.
*/
typedef struct {
} Grp_desc;
/* should be added to handle */
/* removal from the group */
/*
* Define threading structures. For compatibility with libthread (T1_VERSION 1
* and TI_VERSION 2) our locking structure is sufficient to hold a mutex or a
*/
typedef struct {
union {
} u;
} Rt_lock;
/*
* Define a dynamic section information descriptor. This parallels the entries
* in the .dynamic section and holds auxiliary information to implement lazy
* loading and filtee processing.
*/
typedef struct {
void *di_info;
} Dyninfo;
/* and DT_SYMAUXILIARY */
/*
* Data Structure to track AVL tree for pathnames of objects
* loaded into memory
*/
typedef struct {
const char *fpn_name; /* object name */
} FullpathNode;
/*
* Define a mapping structure, which is maintained to describe each mapping
* of an object, ie. the text segment, data segment, bss segment, etc.
*/
typedef struct {
int m_perm; /* mapping permissions */
} Mmap;
/*
* Link-map definition.
*/
struct rt_map {
/*
* BEGIN: Exposed to rtld_db - don't move, don't delete
*/
char *rt_pathname; /* full pathname of loaded object */
/*
* END: Exposed to rtld_db - don't move, don't delete
*/
void (*rt_init)(); /* address of _init */
void (*rt_fini)(); /* address of _fini */
char *rt_runpath; /* LD_RUN_PATH and its equivalent */
void *rt_priv; /* private data, object type specific */
int rt_mode; /* usage mode, see RTLD mode flags */
int rt_sortval; /* temporary buffer to traverse graph */
char *rt_origname; /* original pathname of loaded object */
/* because it is checked in */
/* common code */
};
#ifdef _SYSCALL32
/*
* Structure to allow 64-bit rtld_db to read 32-bit processes out of procfs.
*/
typedef struct rt_map32 {
/*
* BEGIN: Exposed to rtld_db - don't move, don't delete
*/
/*
* END: Exposed to rtld_db - don't move, don't delete
*/
} Rt_map32;
#endif /* _SYSCALL32 */
/*
* Link map state flags.
*/
/*
* BEGIN: Exposed to rtld_db - don't move, don't delete
*/
/*
* Available for r_debug version >= RTLD_DB_VERSION5
*/
/*
* END: Exposed to rtld_db - don't move, don't delete
*/
/* possibilities */
/* symbolic sym resolution */
/*
* The following range of bits are reserved to hold LML_TFLG_AUD_ values
* (although the definitions themselves aren't used anywhere).
*/
/*
* Flags for the tls_modactivity() routine
*/
/*
* Macros for getting to link_map data.
*/
/*
* Macros for getting to linker private data.
*/
#define PATHNAME(X) ((X)->rt_pathname)
#define PADSTART(X) ((X)->rt_padstart)
#define PADIMLEN(X) ((X)->rt_padimlen)
#define TLSMODID(X) ((X)->rt_tlsmodid)
#define RPATH(X) ((X)->rt_runpath)
#define RLIST(X) ((X)->rt_runlist)
#define DEPENDS(X) ((X)->rt_depends)
#define CALLERS(X) ((X)->rt_callers)
#define HANDLES(X) ((X)->rt_handles)
#define SYMINTP(X) ((X)->rt_symintp)
#define OBJFLTRNDX(X) ((X)->rt_objfltrndx)
#define SYMSFLTRCNT(X) ((X)->rt_symsfltrcnt)
#define SYMAFLTRCNT(X) ((X)->rt_symafltrcnt)
#define SORTVAL(X) ((X)->rt_sortval)
#define CYCGROUP(X) ((X)->rt_cycgroup)
#define ORIGNAME(X) ((X)->rt_origname)
#define AUDITORS(X) ((X)->rt_auditors)
#define AUDINFO(X) ((X)->rt_audinfo)
#define SYMINFO(X) ((X)->rt_syminfo)
#define INITARRAY(X) ((X)->rt_initarray)
#define FINIARRAY(X) ((X)->rt_finiarray)
#define PREINITARRAY(X) ((X)->rt_preinitarray)
#define MMAPCNT(X) ((X)->rt_mmapcnt)
#define INITARRAYSZ(X) ((X)->rt_initarraysz)
#define FINIARRAYSZ(X) ((X)->rt_finiarraysz)
#define PREINITARRAYSZ(X) ((X)->rt_preinitarraysz)
#define DYNINFO(X) ((X)->rt_dyninfo)
#define DYNINFOCNT(X) ((X)->rt_dyninfocnt)
#define RELACOUNT(X) ((X)->rt_relacount)
#define CONDVAR(X) ((X)->rt_condvar)
#define THREADID(X) ((X)->rt_threadid)
/*
* Flags for tsorting.
*/
/* only (called via dlclose()) */
/*
* Flags for lookup_sym (and hence find_sym) routines.
*/
/* resolutions to plt[] entries) */
/* symbol had a leading `.' */
/* only */
/* not bind to symbol at head */
/* is valid */
/* pending lazy dependencies */
/*
* Data structure for calling lookup_sym()
*/
typedef struct {
const char *sl_name; /* symbol name */
} Slookup;
typedef enum {
PLT_T_NONE = 0,
PLT_T_NUM /* Must be last */
} Pltbindtype;
/*
* Prototypes.
*/
Xword);
#ifdef __cplusplus
}
#endif
#endif /* _RTLD_H */