/* Data structure for communication from the run-time dynamic linker for
loaded ELF shared objects.
- Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1995-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#ifndef _LINK_H
-#define _LINK_H 1
-
-#include <features.h>
-#include <elf.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-
-/* We use this macro to refer to ELF types independent of the native wordsize.
- `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
-#define ElfW(type) _ElfW (Elf, __ELF_NATIVE_CLASS, type)
-#define _ElfW(e,w,t) _ElfW_1 (e, w, _##t)
-#define _ElfW_1(e,w,t) e##w##t
-
-#include <bits/elfclass.h> /* Defines __ELF_NATIVE_CLASS. */
-#include <bits/link.h>
-#include <dl-lookupcfg.h>
-
-/* Rendezvous structure used by the run-time dynamic linker to communicate
- details of shared object loading to the debugger. If the executable's
- dynamic section has a DT_DEBUG element, the run-time linker sets that
- element's value to the address where this structure can be found. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
-struct r_debug
- {
- int r_version; /* Version number for this protocol. */
+#ifndef _PRIVATE_LINK_H
+#define _PRIVATE_LINK_H 1
- struct link_map *r_map; /* Head of the chain of loaded objects. */
+#ifdef _LINK_H
+# error this should be impossible
+#endif
- /* This is the address of a function internal to the run-time linker,
- that will always be called when the linker begins to map in a
- library or unmap it, and again when the mapping change is complete.
- The debugger can set a breakpoint at this address if it wants to
- notice shared object mapping changes. */
- ElfW(Addr) r_brk;
- enum
- {
- /* This state value describes the mapping change taking place when
- the `r_brk' address is called. */
- RT_CONSISTENT, /* Mapping change is complete. */
- RT_ADD, /* Beginning to add a new object. */
- RT_DELETE /* Beginning to remove an object mapping. */
- } r_state;
-
- ElfW(Addr) r_ldbase; /* Base address the linker is loaded at. */
- };
+/* Get most of the contents from the public header, but we define a
+ different `struct link_map' type for private use. The la_objopen
+ prototype uses the type, so we have to declare it separately. */
+#define link_map link_map_public
+#define la_objopen la_objopen_wrongproto
+#include <elf/link.h>
+#undef link_map
+#undef la_objopen
-/* This is the instance of that structure used by the dynamic linker. */
-extern struct r_debug _r_debug;
+struct link_map;
+extern unsigned int la_objopen (struct link_map *__map, Lmid_t __lmid,
+ uintptr_t *__cookie);
-/* This symbol refers to the "dynamic structure" in the `.dynamic' section
- of whatever module refers to `_DYNAMIC'. So, to find its own
- `struct r_debug', a program could do:
- for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
- if (dyn->d_tag == DT_DEBUG)
- r_debug = (struct r_debug *) dyn->d_un.d_ptr;
- */
-extern ElfW(Dyn) _DYNAMIC[];
+#include <stdint.h>
+#include <stddef.h>
+#include <bits/linkmap.h>
+#include <dl-lookupcfg.h>
+#include <tls.h>
+#include <bits/libc-lock.h>
/* Some internal data structures of the dynamic linker used in the
/* These first few members are part of the protocol with the debugger.
This is the same format used in SVR4. */
- ElfW(Addr) l_addr; /* Base address shared object is loaded at. */
+ ElfW(Addr) l_addr; /* Difference between the address in the ELF
+ file and the addresses in memory. */
char *l_name; /* Absolute file name object was found in. */
ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */
struct link_map *l_next, *l_prev; /* Chain of loaded objects. */
/* All following members are internal to the dynamic linker.
They may change without notice. */
+ /* This is an element which is only ever different from a pointer to
+ the very same copy of this type for ld.so when it is used in more
+ than one namespace. */
+ struct link_map *l_real;
+
+ /* Number of the namespace this link map belongs to. */
+ Lmid_t l_ns;
+
struct libname_list *l_libname;
/* Indexed pointers to dynamic section.
[0,DT_NUM) are indexed by the processor-independent tags.
are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>. */
ElfW(Dyn) *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM
- + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM];
+ + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM];
const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */
ElfW(Addr) l_entry; /* Entry point location. */
ElfW(Half) l_phnum; /* Number of program header entries. */
- ElfW(Half) l_ldnum; /* Number of dynamic segment entries. */
+ ElfW(Half) l_ldnum; /* Number of dynamic segment entries. */
/* Array of DT_NEEDED dependencies and their dependencies, in
dependency order for symbol lookup (with and without
/* Dependent object that first caused this object to be loaded. */
struct link_map *l_loader;
+ /* Array with version names. */
+ struct r_found_version *l_versions;
+ unsigned int l_nversions;
+
/* Symbol hash table. */
Elf_Symndx l_nbuckets;
- const Elf_Symndx *l_buckets, *l_chain;
+ Elf32_Word l_gnu_bitmask_idxbits;
+ Elf32_Word l_gnu_shift;
+ const ElfW(Addr) *l_gnu_bitmask;
+ union
+ {
+ const Elf32_Word *l_gnu_buckets;
+ const Elf_Symndx *l_chain;
+ };
+ union
+ {
+ const Elf32_Word *l_gnu_chain_zero;
+ const Elf_Symndx *l_buckets;
+ };
- unsigned int l_opencount; /* Reference count for dlopen/dlclose. */
+ unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose. */
enum /* Where this object came from. */
{
lt_executable, /* The main executable program. */
the l_libname list. */
unsigned int l_faked:1; /* Nonzero if this is a faked descriptor
without associated file. */
-
- /* Array with version names. */
- unsigned int l_nversions;
- struct r_found_version *l_versions;
+ unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls)
+ should be called on this link map
+ when relocation finishes. */
+ unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing. */
+ unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module
+ is interested in the PLT interception.*/
+ unsigned int l_removed:1; /* Nozero if the object cannot be used anymore
+ since it is removed. */
+ unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
+ mprotected or if no holes are present at
+ all. */
+ unsigned int l_symbolic_in_local_scope:1; /* Nonzero if l_local_scope
+ during LD_TRACE_PRELINKING=1
+ contains any DT_SYMBOLIC
+ libraries. */
+ unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
+ freed, ie. not allocated with
+ the dummy malloc in ld.so. */
/* Collected information about own RPATH directories. */
struct r_search_path_struct l_rpath_dirs;
/* Collected results of relocation while profiling. */
- ElfW(Addr) *l_reloc_result;
+ struct reloc_result
+ {
+ DL_FIXUP_VALUE_TYPE addr;
+ struct link_map *bound;
+ unsigned int boundndx;
+ uint32_t enterexit;
+ unsigned int flags;
+ } *l_reloc_result;
/* Pointer to the version information if available. */
ElfW(Versym) *l_versyms;
/* Start and finish of memory map for this object. l_map_start
need not be the same as l_addr. */
ElfW(Addr) l_map_start, l_map_end;
+ /* End of the executable part of the mapping. */
+ ElfW(Addr) l_text_end;
/* Default array for 'l_scope'. */
struct r_scope_elem *l_scope_mem[4];
/* Size of array allocated for 'l_scope'. */
size_t l_scope_max;
/* This is an array defining the lookup scope for this link map.
- There are at most three different scope lists. */
+ There are initially at most three different scope lists. */
struct r_scope_elem **l_scope;
/* A similar array, this time only with the local scope. This is
struct link_map **l_initfini;
/* List of the dependencies introduced through symbol binding. */
+ struct link_map_reldeps
+ {
+ unsigned int act;
+ struct link_map *list[];
+ } *l_reldeps;
unsigned int l_reldepsmax;
- unsigned int l_reldepsact;
- struct link_map **l_reldeps;
+
+ /* Nonzero if the DSO is used. */
+ unsigned int l_used;
/* Various flag words. */
ElfW(Word) l_feature_1;
ElfW(Word) l_flags_1;
+ ElfW(Word) l_flags;
/* Temporarily used in `dl_close'. */
- unsigned int l_idx;
+ int l_idx;
struct link_map_machine l_mach;
{
const ElfW(Sym) *sym;
int type_class;
-#ifdef DL_LOOKUP_RETURNS_MAP
struct link_map *value;
-#else
- ElfW(Addr) value;
-#endif
const ElfW(Sym) *ret;
} l_lookup_cache;
- };
-struct dl_phdr_info
- {
- ElfW(Addr) dlpi_addr;
- const char *dlpi_name;
- const ElfW(Phdr) *dlpi_phdr;
- ElfW(Half) dlpi_phnum;
+ /* Thread-local storage related info. */
+
+ /* Start of the initialization image. */
+ void *l_tls_initimage;
+ /* Size of the initialization image. */
+ size_t l_tls_initimage_size;
+ /* Size of the TLS block. */
+ size_t l_tls_blocksize;
+ /* Alignment requirement of the TLS block. */
+ size_t l_tls_align;
+ /* Offset of first byte module alignment. */
+ size_t l_tls_firstbyte_offset;
+#ifndef NO_TLS_OFFSET
+# define NO_TLS_OFFSET 0
+#endif
+#ifndef FORCED_DYNAMIC_TLS_OFFSET
+# if NO_TLS_OFFSET == 0
+# define FORCED_DYNAMIC_TLS_OFFSET -1
+# elif NO_TLS_OFFSET == -1
+# define FORCED_DYNAMIC_TLS_OFFSET -2
+# else
+# error "FORCED_DYNAMIC_TLS_OFFSET is not defined"
+# endif
+#endif
+ /* For objects present at startup time: offset in the static TLS block. */
+ ptrdiff_t l_tls_offset;
+ /* Index of the module in the dtv array. */
+ size_t l_tls_modid;
+
+ /* Number of thread_local objects constructed by this DSO. */
+ size_t l_tls_dtor_count;
+
+ /* Information used to change permission after the relocations are
+ done. */
+ ElfW(Addr) l_relro_addr;
+ size_t l_relro_size;
+
+ unsigned long long int l_serial;
+
+ /* Audit information. This array apparent must be the last in the
+ structure. Never add something after it. */
+ struct auditstate
+ {
+ uintptr_t cookie;
+ unsigned int bindflags;
+ } l_audit[0];
};
-extern int dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
- size_t size, void *data),
- void *data);
+
+#if __ELF_NATIVE_CLASS == 32
+# define symbind symbind32
+#elif __ELF_NATIVE_CLASS == 64
+# define symbind symbind64
+#else
+# error "__ELF_NATIVE_CLASS must be defined"
+#endif
+
extern int __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
size_t size, void *data),
void *data);
-#endif /* link.h */
+/* We use this macro to refer to ELF macros independent of the native
+ wordsize. `ELFW(R_TYPE)' is used in place of `ELF32_R_TYPE' or
+ `ELF64_R_TYPE'. */
+#define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type)
+
+#endif /* include/link.h */