/* Run-time dynamic linker data structures for loaded ELF shared objects.
-Copyright (C) 1995 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996 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
#ifndef _LINK_H
#define _LINK_H 1
+#define __need_size_t
+#include <stddef.h>
+
#include <elf.h>
+#define __ELF_WORDSIZE 32 /* XXX */
+
+/* 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_WORDSIZE, type)
+#define ELFW(type) _ElfW (ELF, __ELF_WORDSIZE, type)
+#define _ElfW(e,w,t) _ElfW_1 (e, w, _##t)
+#define _ElfW_1(e,w,t) e##w##t
+
/* Rendezvous structure used by the run-time dynamic linker to communicate
details of shared object loading to the debugger. If the executable's
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. */
- Elf32_Addr r_brk;
+ ElfW(Addr) r_brk;
enum
{
/* This state value describes the mapping change taking place when
RT_DELETE, /* Beginning to remove an object mapping. */
} r_state;
- Elf32_Addr r_ldbase; /* Base address the linker is loaded at. */
+ ElfW(Addr) r_ldbase; /* Base address the linker is loaded at. */
};
/* This symbol refers to the "dynamic structure" in the `.dynamic' section
if (dyn->d_tag == DT_DEBUG) r_debug = (struct r_debug) dyn->d_un.d_ptr;
*/
-extern Elf32_Dyn _DYNAMIC[];
+extern ElfW(Dyn) _DYNAMIC[];
/* Structure describing a loaded shared object. The `l_next' and `l_prev'
/* These first few members are part of the protocol with the debugger.
This is the same format used in SVR4. */
- Elf32_Addr l_addr; /* Base address shared object is loaded at. */
+ ElfW(Addr) l_addr; /* Base address shared object is loaded at. */
char *l_name; /* Absolute file name object was found in. */
- Elf32_Dyn *l_ld; /* Dynamic section of the shared object. */
+ 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. */
const char *l_libname; /* Name requested (before search). */
- Elf32_Dyn *l_info[DT_NUM]; /* Indexed pointers to dynamic section. */
- const Elf32_Phdr *l_phdr; /* Pointer to program header table in core. */
- Elf32_Word l_phnum; /* Number of program header entries. */
+ /* Indexed pointers to dynamic section.
+ [0,DT_NUM) are indexed by the processor-independent tags.
+ [DT_NUM,DT_NUM+DT_PROCNUM] are indexed by the tag minus DT_LOPROC. */
+ ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM];
+ 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. */
+
+ /* Array of DT_NEEDED dependencies and their dependencies, in
+ dependency order for symbol lookup. This is null before the
+ dependencies have been loaded. */
+ struct link_map **l_searchlist;
+ unsigned int l_nsearchlist;
/* Symbol hash table. */
- Elf32_Word l_nbuckets;
- const Elf32_Word *l_buckets, *l_chain;
+ ElfW(Word) l_nbuckets;
+ const ElfW(Word) *l_buckets, *l_chain;
unsigned int l_opencount; /* Reference count for dlopen/dlclose. */
enum /* Where this object came from. */
lt_library, /* Library needed by main executable. */
lt_loaded, /* Extra run-time loaded shared object. */
} l_type:2;
- unsigned int l_deps_loaded:1; /* Nonzero if DT_NEEDED items loaded. */
unsigned int l_relocated:1; /* Nonzero if object's relocations done. */
unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
unsigned int l_init_running:1; /* Nonzero while DT_INIT function runs. */
+ unsigned int l_reserved:3; /* Reserved for internal use. */
};
\f
/* Internal functions of the run-time dynamic linker.
user interface to run-time dynamic linking. */
+/* Cached value of `getpagesize ()'. */
+extern size_t _dl_pagesize;
+
/* File descriptor referring to the zero-fill device. */
extern int _dl_zerofd;
/* OS-dependent function to open the zero-fill device. */
extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */
+/* OS-dependent function to write a message on the standard output.
+ All arguments are `const char *'; args until a null pointer
+ are concatenated to form the message to print. */
+extern void _dl_sysdep_message (const char *string, ...);
+
/* OS-dependent function to give a fatal error message and exit
when the dynamic linker fails before the program is fully linked.
All arguments are `const char *'; args until a null pointer
zero; OBJECT is the name of the problematical shared object, or null if
it is a general problem; ERRSTRING is a string describing the specific
problem. */
-
+
extern void _dl_signal_error (int errcode,
const char *object,
const char *errstring)
/* Open the shared object NAME and map in its segments.
LOADER's DT_RPATH is used in searching for NAME.
- If ENTRY_POINT is not null, fill it in with the object's entry point.
If the object is already opened, returns its existing map. */
extern struct link_map *_dl_map_object (struct link_map *loader,
- const char *name,
- Elf32_Addr *entry_point);
+ const char *name);
/* Similar, but file found at REALNAME and opened on FD.
REALNAME must malloc'd storage and is used in internal data structures. */
extern struct link_map *_dl_map_object_from_fd (const char *name,
- int fd, char *realname,
- Elf32_Addr *entry_point);
+ int fd, char *realname);
+
+/* Call _dl_map_object on the dependencies of MAP, and
+ set up MAP->l_searchlist. */
+extern void _dl_map_object_deps (struct link_map *map);
/* Cache the locations of MAP's hash table. */
extern void _dl_setup_hash (struct link_map *map);
+/* Open the shared object NAME, relocate it, and run its initializer if it
+ hasn't already been run. LOADER's DT_RPATH is used in searching for
+ NAME. MODE is as for `dlopen' (see <dlfcn.h>). If the object is
+ already opened, returns its existing map. */
+extern struct link_map *_dl_open (struct link_map *loader,
+ const char *name, int mode);
+
+
+
/* Search loaded objects' symbol tables for a definition of the symbol
referred to by UNDEF. *SYM is the symbol table entry containing the
reference; it is replaced with the defining symbol, and the base load
- address of the defining object is returned. SYMBOL_SCOPE is the head of
- the chain used for searching. REFERENCE_NAME should name the object
- containing the reference; it is used in error messages. If NOSELF is
- nonzero, them *SYM itself cannot define the value; another binding must
- be found. */
-extern Elf32_Addr _dl_lookup_symbol (const char *undef,
- const Elf32_Sym **sym,
- struct link_map *symbol_scope,
+ address of the defining object is returned. Each of SYMBOL_SCOPE[0] and
+ SYMBOL_SCOPE[1] that is not null and their dependencies are searched to
+ resolve the name. REFERENCE_NAME should name the object containing the
+ reference; it is used in error messages. RELOC_ADDR is the address
+ being fixed up and the chosen symbol cannot be one with this value. If
+ NOPLT is nonzero, then the reference must not be resolved to a PLT
+ entry. */
+extern ElfW(Addr) _dl_lookup_symbol (const char *undef,
+ const ElfW(Sym) **sym,
+ struct link_map *symbol_scope[2],
const char *reference_name,
- int noself);
+ ElfW(Addr) reloc_addr,
+ int noplt);
+
+/* Look up symbol NAME in MAP's scope and return its run-time address. */
+extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name);
+
+/* Structure describing the dynamic linker itself. */
+extern struct link_map _dl_rtld_map;
/* List of objects currently loaded. */
extern struct link_map *_dl_loaded;
If LAZY is nonzero, don't relocate its PLT. */
extern void _dl_relocate_object (struct link_map *map, int lazy);
-/* Return the address of the next initializer function not yet run.
- When there are no more initializers to be run, this returns zero.
- The functions are returned in the order they should be called. */
-extern Elf32_Addr _dl_init_next (void);
+/* Return the address of the next initializer function for MAP or one of
+ its dependencies that has not yet been run. When there are no more
+ initializers to be run, this returns zero. The functions are returned
+ in the order they should be called. */
+extern ElfW(Addr) _dl_init_next (struct link_map *map);
/* Call the finalizer functions of all shared objects whose
initializer functions have completed. */