#include <features.h>
+#include <stdbool.h>
#define __need_size_t
#define __need_NULL
#include <stddef.h>
# define GL(name) _##name
#else
# define EXTERN
-# define GL(name) _rtld_global._##name
+# ifdef IS_IN_rtld
+# define GL(name) _rtld_local._##name
+# else
+# define GL(name) _rtld_global._##name
+# endif
struct rtld_global
{
#endif
#define DL_DEBUG_RELOC (1 << 5)
#define DL_DEBUG_FILES (1 << 6)
#define DL_DEBUG_STATISTICS (1 << 7)
-/* This one is used only internally. */
+/* These two are used only internally. */
#define DL_DEBUG_HELP (1 << 8)
#define DL_DEBUG_PRELINK (1 << 9)
/* The object to be initialized first. */
EXTERN struct link_map *_dl_initfirst;
-#if HP_TIMING_AVAIL
+#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL
/* Start time on CPU clock. */
EXTERN hp_timing_t _dl_cpuclock_offset;
#endif
#ifdef USE_TLS
- /* Beginning of the list of link maps for objects which contain
- thread-local storage sections. This will be traversed to
- initialize new TLS blocks. */
- EXTERN struct link_map *_dl_initimage_list;
+ /* Highest dtv index currently needed. */
+ EXTERN size_t _dl_tls_max_dtv_idx;
+ /* Flag signalling whether there are gaps in the module ID allocation. */
+ EXTERN bool _dl_tls_dtv_gaps;
+ /* Information about the dtv slots. */
+ EXTERN struct dtv_slotinfo_list
+ {
+ size_t len;
+ struct dtv_slotinfo_list *next;
+ struct dtv_slotinfo
+ {
+ size_t gen;
+ struct link_map *map;
+ } slotinfo[0];
+ } *_dl_tls_dtv_slotinfo_list;
+ /* Number of modules in the static TLS block. */
+ EXTERN size_t _dl_tls_static_nelem;
+ /* Size of the static TLS block. */
+ EXTERN size_t _dl_tls_static_size;
+ /* Alignment requirement of the static TLS block. */
+ EXTERN size_t _dl_tls_static_align;
+
+/* Number of additional entries in the slotinfo array of each slotinfo
+ list element. A large number makes it almost certain take we never
+ have to iterate beyond the first element in the slotinfo list. */
+# define TLS_SLOTINFO_SURPLUS (62)
+
+/* Number of additional slots in the dtv allocated. */
+# define DTV_SURPLUS (14)
+
+ /* True if the dtv for the initial thread was malloc()ed. */
+ EXTERN bool _dl_initial_dtv_malloced;
+ /* Generation counter for the dtv. */
+ EXTERN size_t _dl_tls_generation;
#endif
/* Name of the shared object to be profiled (if any). */
#ifdef SHARED
};
extern struct rtld_global _rtld_global;
+# ifdef IS_IN_rtld
+# ifdef HAVE_VISIBILITY_ATTRIBUTE
+# ifdef HAVE_SDATA_SECTION
+# define __rtld_local_attribute__ \
+ __attribute__ ((visibility ("hidden"), section (".sdata")))
+# else
+# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
+# endif
+# else
+# define __rtld_local_attribute__
+# endif
+extern struct rtld_global _rtld_local __rtld_local_attribute__;
+# endif
#endif
#undef EXTERN
/* Parameters passed to the dynamic linker. */
-extern int _dl_argc;
+extern int _dl_argc attribute_hidden;
extern char **_dl_argv;
+#ifdef IS_IN_rtld
+extern char **_dl_argv_internal attribute_hidden;
+# define rtld_progname (INTUSE(_dl_argv)[0])
+#else
+# define rtld_progname _dl_argv[0]
+#endif
/* The array with message we print as a last resort. */
extern const char _dl_out_of_memory[];
+#ifdef IS_IN_rtld
+/* XXX #ifdef should go away. */
+extern const char _dl_out_of_memory_internal[] attribute_hidden;
+#endif
/* OS-dependent function to open the zero-fill device. */
but before its dependencies. */
extern void _dl_map_object_deps (struct link_map *map,
struct link_map **preloads,
- unsigned int npreloads, int trace_mode)
+ unsigned int npreloads, int trace_mode,
+ int open_mode)
internal_function;
extern void _dl_map_object_deps_internal (struct link_map *map,
struct link_map **preloads,
unsigned int npreloads,
- int trace_mode)
+ int trace_mode, int open_mode)
internal_function;
/* Cache the locations of MAP's hash table. */
says what change is taking place. This function's address is
the value of the `r_brk' member. */
extern void _dl_debug_state (void);
-extern void _dl_debug_state_internal (void);
+extern void _dl_debug_state_internal (void) attribute_hidden;
/* Initialize `struct r_debug' if it has not already been done. The
argument is the run-time load address of the dynamic linker, to be put
/* The actual functions used to keep book on the calls. */
extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc);
+extern void _dl_mcount_internal (ElfW(Addr) frompc, ElfW(Addr) selfpc)
+ attribute_hidden;
/* This function is simply a wrapper around the _dl_mcount function
which does not require a FROMPC parameter since this is the
internal_function;
+/* Determine next available module ID. */
+extern size_t _dl_next_tls_modid (void) internal_function;
+
+/* Calculate offset of the TLS blocks in the static TLS block. */
+extern void _dl_determine_tlsoffset (void) internal_function;
+
+/* Allocate memory for static TLS block and dtv. */
+extern void *_dl_allocate_tls (void) internal_function;
+extern void *_dl_allocate_tls_internal (void) internal_function;
+
+/* Deallocate memory allocated with _dl_allocate_tls. */
+extern void _dl_deallocate_tls (void *tcb) internal_function;
+
+/* Return the symbol address given the map of the module it is in and
+ the symbol record. */
+extern void *_dl_tls_symaddr (struct link_map *map, const ElfW(Sym) *ref)
+ internal_function;
+
__END_DECLS
#endif /* ldsodefs.h */