189857Sobrien/*- 289857Sobrien * SPDX-License-Identifier: BSD-2-Clause 389857Sobrien * 489857Sobrien * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra. 589857Sobrien * All rights reserved. 689857Sobrien * 789857Sobrien * Redistribution and use in source and binary forms, with or without 889857Sobrien * modification, are permitted provided that the following conditions 989857Sobrien * are met: 1089857Sobrien * 1. Redistributions of source code must retain the above copyright 1189857Sobrien * notice, this list of conditions and the following disclaimer. 1289857Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1389857Sobrien * notice, this list of conditions and the following disclaimer in the 1489857Sobrien * documentation and/or other materials provided with the distribution. 1589857Sobrien * 1689857Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1789857Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1889857Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1989857Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20218822Sdim * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21218822Sdim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2289857Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2389857Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2489857Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2589857Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2689857Sobrien */ 2789857Sobrien 2889857Sobrien#ifndef RTLD_H /* { */ 2989857Sobrien#define RTLD_H 1 3089857Sobrien 3189857Sobrien#include <machine/elf.h> 3289857Sobrien#include <sys/types.h> 3389857Sobrien#include <sys/queue.h> 3489857Sobrien 3589857Sobrien#include <elf-hints.h> 3689857Sobrien#include <link.h> 3789857Sobrien#include <stdarg.h> 3889857Sobrien#include <stdbool.h> 3989857Sobrien#include <setjmp.h> 4089857Sobrien#include <stddef.h> 4189857Sobrien 4289857Sobrien#include "rtld_lock.h" 4389857Sobrien#include "rtld_machdep.h" 4489857Sobrien 4589857Sobrien#define NEW(type) ((type *) xmalloc(sizeof(type))) 4689857Sobrien#define CNEW(type) ((type *) xcalloc(1, sizeof(type))) 4789857Sobrien 4889857Sobrienextern size_t tls_last_offset; 4989857Sobrienextern size_t tls_last_size; 5089857Sobrienextern size_t tls_static_space; 5189857Sobrienextern Elf_Addr tls_dtv_generation; 5289857Sobrienextern int tls_max_index; 5389857Sobrienextern size_t ld_static_tls_extra; 5489857Sobrien 5589857Sobrienextern int npagesizes; 5689857Sobrienextern size_t *pagesizes; 5789857Sobrienextern size_t page_size; 5889857Sobrien 5989857Sobrienextern int main_argc; 6089857Sobrienextern char **main_argv; 6189857Sobrienextern char **environ; 6289857Sobrien 6389857Sobrienstruct stat; 6489857Sobrienstruct Struct_Obj_Entry; 6589857Sobrien 6689857Sobrien/* Lists of shared objects */ 6789857Sobrientypedef struct Struct_Objlist_Entry { 6889857Sobrien STAILQ_ENTRY(Struct_Objlist_Entry) link; 6989857Sobrien struct Struct_Obj_Entry *obj; 7089857Sobrien} Objlist_Entry; 7189857Sobrien 7289857Sobrientypedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist; 7389857Sobrien 7489857Sobrien/* Types of init and fini functions */ 7589857Sobrientypedef void (*InitFunc)(void); 7689857Sobrientypedef void (*InitArrFunc)(int, char **, char **); 7789857Sobrien 7889857Sobrien/* Lists of shared object dependencies */ 7989857Sobrientypedef struct Struct_Needed_Entry { 8089857Sobrien struct Struct_Needed_Entry *next; 8189857Sobrien struct Struct_Obj_Entry *obj; 8289857Sobrien unsigned long name; /* Offset of name in string table */ 8389857Sobrien} Needed_Entry; 8489857Sobrien 8589857Sobrientypedef struct Struct_Name_Entry { 8689857Sobrien STAILQ_ENTRY(Struct_Name_Entry) link; 8789857Sobrien char name[1]; 8889857Sobrien} Name_Entry; 8989857Sobrien 9089857Sobrien/* Lock object */ 9189857Sobrientypedef struct Struct_LockInfo { 9289857Sobrien void *context; /* Client context for creating locks */ 9389857Sobrien void *thelock; /* The one big lock */ 9489857Sobrien /* Debugging aids. */ 9589857Sobrien volatile int rcount; /* Number of readers holding lock */ 9689857Sobrien volatile int wcount; /* Number of writers holding lock */ 9789857Sobrien /* Methods */ 9889857Sobrien void *(*lock_create)(void *context); 9989857Sobrien void (*rlock_acquire)(void *lock); 10089857Sobrien void (*wlock_acquire)(void *lock); 10189857Sobrien void (*rlock_release)(void *lock); 10289857Sobrien void (*wlock_release)(void *lock); 10389857Sobrien void (*lock_destroy)(void *lock); 10489857Sobrien void (*context_destroy)(void *context); 10589857Sobrien} LockInfo; 10689857Sobrien 10789857Sobrientypedef struct Struct_Ver_Entry { 10889857Sobrien Elf_Word hash; 10989857Sobrien unsigned int flags; 11089857Sobrien const char *name; 11189857Sobrien const char *file; 11289857Sobrien} Ver_Entry; 11389857Sobrien 11489857Sobrientypedef struct Struct_Sym_Match_Result { 11589857Sobrien const Elf_Sym *sym_out; 11689857Sobrien const Elf_Sym *vsymp; 11789857Sobrien int vcount; 11889857Sobrien} Sym_Match_Result; 11989857Sobrien 12089857Sobrien#define VER_INFO_HIDDEN 0x01 12189857Sobrien 12289857Sobrien/* 12389857Sobrien * Shared object descriptor. 12489857Sobrien * 12589857Sobrien * Items marked with "(%)" are dynamically allocated, and must be freed 12689857Sobrien * when the structure is destroyed. 12789857Sobrien * 12889857Sobrien * CAUTION: It appears that the JDK port peeks into these structures. 12989857Sobrien * It looks at "next" and "mapbase" at least. Don't add new members 13089857Sobrien * near the front, until this can be straightened out. 13189857Sobrien */ 13289857Sobrientypedef struct Struct_Obj_Entry { 13389857Sobrien /* 13489857Sobrien * These two items have to be set right for compatibility with the 13589857Sobrien * original ElfKit crt1.o. 13689857Sobrien */ 13789857Sobrien Elf_Size magic; /* Magic number (sanity check) */ 13889857Sobrien Elf_Size version; /* Version number of struct format */ 13989857Sobrien 14089857Sobrien TAILQ_ENTRY(Struct_Obj_Entry) next; 14189857Sobrien char *path; /* Pathname of underlying file (%) */ 14289857Sobrien char *origin_path; /* Directory path of origin file */ 14389857Sobrien int refcount; /* DAG references */ 14489857Sobrien int holdcount; /* Count of transient references */ 14589857Sobrien int dl_refcount; /* Number of times loaded by dlopen */ 14689857Sobrien 14789857Sobrien /* These items are computed by map_object() or by digest_phdr(). */ 14889857Sobrien caddr_t mapbase; /* Base address of mapped region */ 14989857Sobrien size_t mapsize; /* Size of mapped region in bytes */ 15089857Sobrien Elf_Addr vaddrbase; /* Base address in shared object file */ 15189857Sobrien caddr_t relocbase; /* Relocation constant = mapbase - vaddrbase */ 15289857Sobrien const Elf_Dyn *dynamic; /* Dynamic section */ 15389857Sobrien caddr_t entry; /* Entry point */ 15489857Sobrien const Elf_Phdr *phdr; /* Program header if it is mapped, else NULL */ 15589857Sobrien size_t phsize; /* Size of program header in bytes */ 15689857Sobrien const char *interp; /* Pathname of the interpreter, if any */ 15789857Sobrien Elf_Word stack_flags; 15889857Sobrien 15989857Sobrien /* TLS information */ 16089857Sobrien int tlsindex; /* Index in DTV for this module */ 16189857Sobrien void *tlsinit; /* Base address of TLS init block */ 16289857Sobrien size_t tlsinitsize; /* Size of TLS init block for this module */ 16389857Sobrien size_t tlssize; /* Size of TLS block for this module */ 16489857Sobrien size_t tlsoffset; /* Offset of static TLS block for this module */ 16589857Sobrien size_t tlsalign; /* Alignment of static TLS block */ 16689857Sobrien size_t tlspoffset; /* p_offset of the static TLS block */ 16789857Sobrien 16889857Sobrien caddr_t relro_page; 16989857Sobrien size_t relro_size; 17089857Sobrien 17189857Sobrien /* Items from the dynamic section. */ 17289857Sobrien Elf_Addr *pltgot; /* PLT or GOT, depending on architecture */ 17389857Sobrien const Elf_Rel *rel; /* Relocation entries */ 17489857Sobrien unsigned long relsize; /* Size in bytes of relocation info */ 17589857Sobrien const Elf_Rela *rela; /* Relocation entries with addend */ 17689857Sobrien unsigned long relasize; /* Size in bytes of addend relocation info */ 17789857Sobrien const Elf_Relr *relr; /* RELR relocation entries */ 17889857Sobrien unsigned long relrsize; /* Size in bytes of RELR relocations */ 17989857Sobrien const Elf_Rel *pltrel; /* PLT relocation entries */ 18089857Sobrien unsigned long pltrelsize; /* Size in bytes of PLT relocation info */ 18189857Sobrien const Elf_Rela *pltrela; /* PLT relocation entries with addend */ 18289857Sobrien unsigned long pltrelasize; /* Size in bytes of PLT addend reloc info */ 18389857Sobrien const Elf_Sym *symtab; /* Symbol table */ 18489857Sobrien const char *strtab; /* String table */ 18589857Sobrien unsigned long strsize; /* Size in bytes of string table */ 18689857Sobrien 18789857Sobrien const Elf_Verneed *verneed; /* Required versions. */ 18889857Sobrien Elf_Word verneednum; /* Number of entries in verneed table */ 18989857Sobrien const Elf_Verdef *verdef; /* Provided versions. */ 19089857Sobrien Elf_Word verdefnum; /* Number of entries in verdef table */ 19189857Sobrien const Elf_Versym *versyms; /* Symbol versions table */ 19289857Sobrien 19389857Sobrien const Elf_Hashelt *buckets; /* Hash table buckets array */ 19489857Sobrien unsigned long nbuckets; /* Number of buckets */ 19589857Sobrien const Elf_Hashelt *chains; /* Hash table chain array */ 19689857Sobrien unsigned long nchains; /* Number of entries in chain array */ 19789857Sobrien 19889857Sobrien Elf32_Word nbuckets_gnu; /* Number of GNU hash buckets*/ 19989857Sobrien Elf32_Word symndx_gnu; /* 1st accessible symbol on dynsym table */ 20089857Sobrien Elf32_Word maskwords_bm_gnu; /* Bloom filter words - 1 (bitmask) */ 20189857Sobrien Elf32_Word shift2_gnu; /* Bloom filter shift count */ 20289857Sobrien Elf32_Word dynsymcount; /* Total entries in dynsym table */ 20389857Sobrien const Elf_Addr *bloom_gnu; /* Bloom filter used by GNU hash func */ 20489857Sobrien const Elf_Hashelt *buckets_gnu; /* GNU hash table bucket array */ 20589857Sobrien const Elf_Hashelt *chain_zero_gnu; /* GNU hash table value array (Zeroed) */ 20689857Sobrien 20789857Sobrien const char *rpath; /* Search path specified in object */ 20889857Sobrien const char *runpath; /* Search path with different priority */ 20989857Sobrien Needed_Entry *needed; /* Shared objects needed by this one (%) */ 21089857Sobrien Needed_Entry *needed_filtees; 21189857Sobrien Needed_Entry *needed_aux_filtees; 21289857Sobrien 21389857Sobrien STAILQ_HEAD(, Struct_Name_Entry) names; /* List of names for this object we 21489857Sobrien know about. */ 215130561Sobrien Ver_Entry *vertab; /* Versions required /defined by this object */ 216130561Sobrien int vernum; /* Number of entries in vertab */ 217130561Sobrien 218130561Sobrien Elf_Addr init; /* Initialization function to call */ 219130561Sobrien Elf_Addr fini; /* Termination function to call */ 220130561Sobrien Elf_Addr preinit_array; /* Pre-initialization array of functions */ 22189857Sobrien Elf_Addr init_array; /* Initialization array of functions */ 22289857Sobrien Elf_Addr fini_array; /* Termination array of functions */ 22389857Sobrien int preinit_array_num; /* Number of entries in preinit_array */ 22489857Sobrien int init_array_num; /* Number of entries in init_array */ 22589857Sobrien int fini_array_num; /* Number of entries in fini_array */ 22689857Sobrien 22789857Sobrien int32_t osrel; /* OSREL note value */ 22889857Sobrien uint32_t fctl0; /* FEATURE_CONTROL note desc[0] value */ 22989857Sobrien 23089857Sobrien bool mainprog : 1; /* True if this is the main program */ 231130561Sobrien bool rtld : 1; /* True if this is the dynamic linker */ 232130561Sobrien bool relocated : 1; /* True if processed by relocate_objects() */ 233130561Sobrien bool ver_checked : 1; /* True if processed by rtld_verify_object_versions */ 234130561Sobrien bool textrel : 1; /* True if there are relocations to text seg */ 235130561Sobrien bool symbolic : 1; /* True if generated with "-Bsymbolic" */ 236130561Sobrien bool deepbind : 1; /* True if loaded with RTLD_DEEPBIND" */ 237130561Sobrien bool bind_now : 1; /* True if all relocations should be made first */ 238130561Sobrien bool traced : 1; /* Already printed in ldd trace output */ 23989857Sobrien bool jmpslots_done : 1; /* Already have relocated the jump slots */ 24089857Sobrien bool init_done : 1; /* Already have added object to init list */ 24189857Sobrien bool tls_static : 1; /* Already allocated offset for static TLS */ 24289857Sobrien bool tls_dynamic : 1; /* A non-static DTV entry has been allocated */ 24389857Sobrien bool phdr_alloc : 1; /* Phdr is allocated and needs to be freed. */ 24489857Sobrien bool z_origin : 1; /* Process rpath and soname tokens */ 24589857Sobrien bool z_nodelete : 1; /* Do not unload the object and dependencies */ 24689857Sobrien bool z_noopen : 1; /* Do not load on dlopen */ 24789857Sobrien bool z_loadfltr : 1; /* Immediately load filtees */ 24889857Sobrien bool z_interpose : 1; /* Interpose all objects but main */ 24989857Sobrien bool z_nodeflib : 1; /* Don't search default library path */ 25089857Sobrien bool z_global : 1; /* Make the object global */ 25189857Sobrien bool z_pie : 1; /* Object proclaimed itself PIE executable */ 25289857Sobrien bool static_tls : 1; /* Needs static TLS allocation */ 25389857Sobrien bool static_tls_copied : 1; /* Needs static TLS copying */ 25489857Sobrien bool ref_nodel : 1; /* Refcount increased to prevent dlclose */ 25589857Sobrien bool init_scanned: 1; /* Object is already on init list. */ 25689857Sobrien bool on_fini_list: 1; /* Object is already on fini list. */ 25789857Sobrien bool dag_inited : 1; /* Object has its DAG initialized. */ 25889857Sobrien bool filtees_loaded : 1; /* Filtees loaded */ 25989857Sobrien bool filtees_loading : 1; /* In process of filtees loading */ 26089857Sobrien bool irelative : 1; /* Object has R_MACHDEP_IRELATIVE relocs */ 26189857Sobrien bool irelative_nonplt : 1; /* Object has R_MACHDEP_IRELATIVE non-plt relocs */ 26289857Sobrien bool gnu_ifunc : 1; /* Object has references to STT_GNU_IFUNC */ 26389857Sobrien bool non_plt_gnu_ifunc : 1; /* Object has non-plt IFUNC references */ 26489857Sobrien bool ifuncs_resolved : 1; /* Object ifuncs were already resolved */ 26589857Sobrien bool crt_no_init : 1; /* Object' crt does not call _init/_fini */ 26689857Sobrien bool valid_hash_sysv : 1; /* A valid System V hash hash tag is available */ 26789857Sobrien bool valid_hash_gnu : 1; /* A valid GNU hash tag is available */ 268130561Sobrien bool dlopened : 1; /* dlopen()-ed (vs. load statically) */ 26989857Sobrien bool marker : 1; /* marker on the global obj list */ 270130561Sobrien bool unholdfree : 1; /* unmap upon last unhold */ 271130561Sobrien bool doomed : 1; /* Object cannot be referenced */ 27289857Sobrien 27389857Sobrien MD_OBJ_ENTRY; 27489857Sobrien 27589857Sobrien struct link_map linkmap; /* For GDB and dlinfo() */ 27689857Sobrien Objlist dldags; /* Object belongs to these dlopened DAGs (%) */ 27789857Sobrien Objlist dagmembers; /* DAG has these members (%) */ 27889857Sobrien dev_t dev; /* Object's filesystem's device */ 27989857Sobrien ino_t ino; /* Object's inode number */ 28089857Sobrien void *priv; /* Platform-dependent */ 28189857Sobrien} Obj_Entry; 28289857Sobrien 283130561Sobrien#define RTLD_MAGIC 0xd550b87a 284130561Sobrien#define RTLD_VERSION 1 28589857Sobrien 286130561SobrienTAILQ_HEAD(obj_entry_q, Struct_Obj_Entry); 287130561Sobrien 288130561Sobrien#define RTLD_STATIC_TLS_EXTRA 128 28989857Sobrien 29089857Sobrien/* Flags to be passed into symlook_ family of functions. */ 29189857Sobrien#define SYMLOOK_IN_PLT 0x01 /* Lookup for PLT symbol */ 29289857Sobrien#define SYMLOOK_DLSYM 0x02 /* Return newest versioned symbol. Used by 29389857Sobrien dlsym. */ 29489857Sobrien#define SYMLOOK_EARLY 0x04 /* Symlook is done during initialization. */ 29589857Sobrien#define SYMLOOK_IFUNC 0x08 /* Allow IFUNC processing in 29689857Sobrien reloc_non_plt(). */ 297 298/* Flags for load_object(). */ 299#define RTLD_LO_NOLOAD 0x01 /* dlopen() specified RTLD_NOLOAD. */ 300#define RTLD_LO_DLOPEN 0x02 /* Load_object() called from dlopen(). */ 301#define RTLD_LO_TRACE 0x04 /* Only tracing. */ 302#define RTLD_LO_NODELETE 0x08 /* Loaded object cannot be closed. */ 303#define RTLD_LO_FILTEES 0x10 /* Loading filtee. */ 304#define RTLD_LO_EARLY 0x20 /* Do not call ctors, postpone it to the 305 initialization during the image start. */ 306#define RTLD_LO_IGNSTLS 0x40 /* Do not allocate static TLS */ 307#define RTLD_LO_DEEPBIND 0x80 /* Force symbolic for this object */ 308 309/* 310 * Symbol cache entry used during relocation to avoid multiple lookups 311 * of the same symbol. 312 */ 313typedef struct Struct_SymCache { 314 const Elf_Sym *sym; /* Symbol table entry */ 315 const Obj_Entry *obj; /* Shared object which defines it */ 316} SymCache; 317 318/* 319 * This structure provides a reentrant way to keep a list of objects and 320 * check which ones have already been processed in some way. 321 */ 322typedef struct Struct_DoneList { 323 const Obj_Entry **objs; /* Array of object pointers */ 324 unsigned int num_alloc; /* Allocated size of the array */ 325 unsigned int num_used; /* Number of array slots used */ 326} DoneList; 327 328struct Struct_RtldLockState { 329 int lockstate; 330 sigjmp_buf env; 331}; 332 333struct fill_search_info_args { 334 int request; 335 unsigned int flags; 336 struct dl_serinfo *serinfo; 337 struct dl_serpath *serpath; 338 char *strspace; 339}; 340 341/* 342 * The pack of arguments and results for the symbol lookup functions. 343 */ 344typedef struct Struct_SymLook { 345 const char *name; 346 unsigned long hash; 347 uint32_t hash_gnu; 348 const Ver_Entry *ventry; 349 int flags; 350 const Obj_Entry *defobj_out; 351 const Elf_Sym *sym_out; 352 struct Struct_RtldLockState *lockstate; 353} SymLook; 354 355void _rtld_error(const char *, ...) __printflike(1, 2) __exported; 356void rtld_die(void) __dead2; 357const char *rtld_strerror(int); 358Obj_Entry *map_object(int, const char *, const struct stat *); 359void *xcalloc(size_t, size_t); 360void *xmalloc(size_t); 361char *xstrdup(const char *); 362void *xmalloc_aligned(size_t size, size_t align, size_t offset); 363extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; 364extern Elf_Sym sym_zero; /* For resolving undefined weak refs. */ 365extern bool ld_bind_not; 366extern bool ld_fast_sigblock; 367 368void dump_relocations(Obj_Entry *); 369void dump_obj_relocations(Obj_Entry *); 370void dump_Elf_Rel(Obj_Entry *, const Elf_Rel *, u_long); 371void dump_Elf_Rela(Obj_Entry *, const Elf_Rela *, u_long); 372 373/* 374 * Function declarations. 375 */ 376uintptr_t rtld_round_page(uintptr_t); 377uintptr_t rtld_trunc_page(uintptr_t); 378Elf32_Word elf_hash(const char *); 379const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *, 380 const Obj_Entry **, int, SymCache *, struct Struct_RtldLockState *); 381void lockdflt_init(void); 382void digest_notes(Obj_Entry *, Elf_Addr, Elf_Addr); 383Obj_Entry *globallist_curr(const Obj_Entry *obj); 384Obj_Entry *globallist_next(const Obj_Entry *obj); 385void obj_free(Obj_Entry *); 386Obj_Entry *obj_new(void); 387Obj_Entry *obj_from_addr(const void *); 388void _rtld_bind_start(void); 389void *rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def); 390void symlook_init(SymLook *, const char *); 391int symlook_obj(SymLook *, const Obj_Entry *); 392void *tls_get_addr_common(uintptr_t **dtvp, int index, size_t offset); 393void *allocate_tls(Obj_Entry *, void *, size_t, size_t); 394void free_tls(void *, size_t, size_t); 395void *allocate_module_tls(int index); 396bool allocate_tls_offset(Obj_Entry *obj); 397void free_tls_offset(Obj_Entry *obj); 398const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long); 399int convert_prot(int elfflags); 400bool check_elf_headers(const Elf_Ehdr *hdr, const char *path); 401 402/* 403 * MD function declarations. 404 */ 405int do_copy_relocations(Obj_Entry *); 406int reloc_non_plt(Obj_Entry *, Obj_Entry *, int flags, 407 struct Struct_RtldLockState *); 408int reloc_plt(Obj_Entry *, int flags, struct Struct_RtldLockState *); 409int reloc_jmpslots(Obj_Entry *, int flags, struct Struct_RtldLockState *); 410int reloc_iresolve(Obj_Entry *, struct Struct_RtldLockState *); 411int reloc_iresolve_nonplt(Obj_Entry *, struct Struct_RtldLockState *); 412int reloc_gnu_ifunc(Obj_Entry *, int flags, struct Struct_RtldLockState *); 413void ifunc_init(Elf_Auxinfo[__min_size(AT_COUNT)]); 414void init_pltgot(Obj_Entry *); 415void allocate_initial_tls(Obj_Entry *); 416 417#endif /* } */ 418