Mon Jun 10 05:13:18 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
[kopensolaris-gnu/glibc.git] / elf / link.h
index 4848f4b..f7bca97 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -20,8 +20,20 @@ Cambridge, MA 02139, USA.  */
 #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
@@ -39,7 +51,7 @@ struct r_debug
        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
@@ -49,7 +61,7 @@ struct r_debug
        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
@@ -59,7 +71,7 @@ struct r_debug
        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'
@@ -73,23 +85,32 @@ struct link_map
     /* 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.  */
-    Elf32_Addr l_entry;                /* Entry point location.  */
+    /* 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.  */
@@ -99,10 +120,10 @@ struct link_map
        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.
@@ -114,6 +135,9 @@ struct link_map
    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;
 
@@ -141,7 +165,7 @@ extern int _dl_secure;
    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)
@@ -173,24 +197,46 @@ extern struct link_map *_dl_map_object (struct link_map *loader,
 extern struct link_map *_dl_map_object_from_fd (const char *name,
                                                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;
@@ -207,10 +253,11 @@ extern struct link_map *_dl_new_object (char *realname, const char *libname,
    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.  */