From 590786950c039260b75db235e81f2ae1633a055e Mon Sep 17 00:00:00 2001 From: Paul Pluzhnikov Date: Tue, 4 Mar 2014 19:07:05 -0800 Subject: Add "fastload" support. --- sysdeps/generic/ldsodefs.h | 67 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'sysdeps/generic/ldsodefs.h') diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 7ea9318..1df593c 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -275,6 +276,13 @@ typedef void (*receiver_fct) (int, const char *, const char *); The `-ldl' library functions in provide a simple user interface to run-time dynamic linking. */ +/* To save storage space in the hash table, we use uint16_t, which allows + us to support up to 64K of DSOs efficiently. */ +typedef uint16_t dl_position_table_entry_t; + +/* 65535 -- max position that could be recorded in + dl_position_table_entry_t. */ +#define DL_POSITION_MAX UINT16_MAX #ifndef SHARED # define EXTERN extern @@ -302,6 +310,8 @@ struct rtld_global { /* A pointer to the map for the main map. */ struct link_map *_ns_loaded; + /* Tail end of the _ns_loaded link chain. Computed on demand. */ + struct link_map *_ns_last; /* Number of object in the _dl_loaded list. */ unsigned int _ns_nloaded; /* Direct pointer to the searchlist of the main object. */ @@ -350,7 +360,7 @@ struct rtld_global /* The object to be initialized first. */ EXTERN struct link_map *_dl_initfirst; -#if HP_SMALL_TIMING_AVAIL +#if HP_SMALL_TIMING_AVAIL || HP_TIMING_PAD /* Start time on CPU clock. */ EXTERN hp_timing_t _dl_cpuclock_offset; #endif @@ -487,6 +497,9 @@ struct rtld_global_ro #define DL_DEBUG_HELP (1 << 10) #define DL_DEBUG_PRELINK (1 << 11) +/* Google-local. */ +#define DL_DEBUG_FASTLOAD (1 << 12) + /* OS version. */ EXTERN unsigned int _dl_osversion; /* Platform name. */ @@ -576,6 +589,29 @@ struct rtld_global_ro below. */ EXTERN struct r_search_path_elem *_dl_init_all_dirs; + /* The merged hash table used if we have a lot of shared objects. */ + EXTERN dl_position_table_entry_t *_dl_position_hash_table; + EXTERN int _dl_position_hash_mask; + EXTERN int _dl_position_hash_bits; + EXTERN int _dl_position_hash_cutoff; + EXTERN int _dl_enable_fastload; + +#define DL_POSITION_HASH_BITS_MAX 27 /* (1 << 27) entries. */ +#if defined(__powerpc__) && !defined(__powerpc64__) +#define DL_POSITION_HASH_CUTOFF_DEFAULT -1 /* Disabled. */ +#else +#define DL_POSITION_HASH_CUTOFF_DEFAULT 32 /* > 32 shared libs. */ +#endif + + /* Colon-separated list of absolute paths to ld.so.cache files + we'll load. */ + EXTERN const char *_google_ld_so_cache_list; + +#if HP_SMALL_TIMING_AVAIL || HP_TIMING_PAD + /* Overhead of a high-precision timing measurement. */ + EXTERN hp_timing_t _dl_hp_timing_overhead; +#endif + #ifdef NEED_DL_SYSINFO /* Syscall handling improvements. This is very specific to x86. */ EXTERN uintptr_t _dl_sysinfo; @@ -750,6 +786,8 @@ _dl_dprintf (int fd, const char *fmt, ...) } \ while (1) +/* Fill the position hash table used if we have a lot of shared libraries. */ +extern void _dl_fill_position_hash (struct link_map *main_map); /* An exception raised by the _dl_signal_error function family and caught by _dl_catch_error function family. Exceptions themselves @@ -1057,6 +1095,8 @@ extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, extern void _dl_sysdep_start_cleanup (void) attribute_hidden; +extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + attribute_hidden; /* Determine next available module ID. */ extern size_t _dl_next_tls_modid (void) attribute_hidden; @@ -1193,6 +1233,31 @@ rtld_active (void) } #endif +/* Find last entry in the given scope. Cache the result. */ +static inline struct link_map * +_dl_last_entry (struct link_namespaces *ns) +{ + struct link_map *map = ns->_ns_last; + size_t len = 0; + + if (map == NULL) + map = ns->_ns_loaded; + + if (map == NULL) + return NULL; + + while (map->l_next != NULL) + { + map = map->l_next; + /* If we have more than _ns_nloaded libraries, it's likely we are + looking at a corrupt list. Fail hard. */ + assert (len++ < ns->_ns_nloaded); + } + + ns->_ns_last = map; + return map; +} + __END_DECLS #endif /* ldsodefs.h */ -- cgit v1.1