diff options
author | kib <kib@FreeBSD.org> | 2010-12-25 08:51:20 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2010-12-25 08:51:20 +0000 |
commit | cefd8b2a41e4b4bf7a16e2dea1e0c719a30d56a3 (patch) | |
tree | 487c080e0cb090d960945a4f112301253d4a6e9f /libexec/rtld-elf/rtld.h | |
parent | 377233e6cca2d48c8ecba755aa46304a8ae7731b (diff) | |
download | FreeBSD-src-cefd8b2a41e4b4bf7a16e2dea1e0c719a30d56a3.zip FreeBSD-src-cefd8b2a41e4b4bf7a16e2dea1e0c719a30d56a3.tar.gz |
Implement support for ELF filters in rtld. Both normal and auxillary
filters are implemented.
Filtees are loaded on demand, unless LD_LOADFLTR environment variable
is set or -z loadfltr was specified during the linking. This forces
rtld to upgrade read-locked rtld_bind_lock to write lock when it
encounters an object with filter during symbol lookup.
Consolidate common arguments of the symbol lookup functions in the
SymLook structure. Track the state of the rtld locks in the
RtldLockState structure. Pass local RtldLockState through the rtld
symbol lookup calls to allow lock upgrades.
Reviewed by: kan
Tested by: Mykola Dzham <i levsha me>, nwhitehorn (powerpc)
Diffstat (limited to 'libexec/rtld-elf/rtld.h')
-rw-r--r-- | libexec/rtld-elf/rtld.h | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index faa84e2..b70e8b6 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -34,6 +34,7 @@ #include <elf-hints.h> #include <link.h> +#include <setjmp.h> #include <stddef.h> #include "rtld_lock.h" @@ -197,6 +198,8 @@ typedef struct Struct_Obj_Entry { char *rpath; /* Search path specified in object */ Needed_Entry *needed; /* Shared objects needed by this one (%) */ + Needed_Entry *needed_filtees; + Needed_Entry *needed_aux_filtees; STAILQ_HEAD(, Struct_Name_Entry) names; /* List of names for this object we know about. */ @@ -219,10 +222,12 @@ typedef struct Struct_Obj_Entry { bool z_origin : 1; /* Process rpath and soname tokens */ bool z_nodelete : 1; /* Do not unload the object and dependencies */ bool z_noopen : 1; /* Do not load on dlopen */ + bool z_loadfltr : 1; /* Immediately load filtees */ bool ref_nodel : 1; /* Refcount increased to prevent dlclose */ bool init_scanned: 1; /* Object is already on init list. */ bool on_fini_list: 1; /* Object is already on fini list. */ bool dag_inited : 1; /* Object has its DAG initialized. */ + bool filtees_loaded : 1; /* Filtees loaded */ struct link_map linkmap; /* For GDB and dlinfo() */ Objlist dldags; /* Object belongs to these dlopened DAGs (%) */ @@ -246,6 +251,8 @@ typedef struct Struct_Obj_Entry { #define RTLD_LO_NOLOAD 0x01 /* dlopen() specified RTLD_NOLOAD. */ #define RTLD_LO_DLOPEN 0x02 /* Load_object() called from dlopen(). */ #define RTLD_LO_TRACE 0x04 /* Only tracing. */ +#define RTLD_LO_NODELETE 0x08 /* Loaded object cannot be closed. */ +#define RTLD_LO_FILTEES 0x10 /* Loading filtee. */ /* * Symbol cache entry used during relocation to avoid multiple lookups @@ -256,6 +263,34 @@ typedef struct Struct_SymCache { const Obj_Entry *obj; /* Shared object which defines it */ } SymCache; +/* + * This structure provides a reentrant way to keep a list of objects and + * check which ones have already been processed in some way. + */ +typedef struct Struct_DoneList { + const Obj_Entry **objs; /* Array of object pointers */ + unsigned int num_alloc; /* Allocated size of the array */ + unsigned int num_used; /* Number of array slots used */ +} DoneList; + +struct Struct_RtldLockState { + int lockstate; + jmp_buf env; +}; + +/* + * The pack of arguments and results for the symbol lookup functions. + */ +typedef struct Struct_SymLook { + const char *name; + unsigned long hash; + const Ver_Entry *ventry; + int flags; + const Obj_Entry *defobj_out; + const Elf_Sym *sym_out; + struct Struct_RtldLockState *lockstate; +} SymLook; + extern void _rtld_error(const char *, ...) __printflike(1, 2); extern Obj_Entry *map_object(int, const char *, const struct stat *); extern void *xcalloc(size_t); @@ -274,14 +309,14 @@ extern void dump_Elf_Rela (Obj_Entry *, const Elf_Rela *, u_long); */ unsigned long elf_hash(const char *); const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *, - const Obj_Entry **, int, SymCache *); + const Obj_Entry **, int, SymCache *, struct Struct_RtldLockState *); void init_pltgot(Obj_Entry *); void lockdflt_init(void); void obj_free(Obj_Entry *); Obj_Entry *obj_new(void); void _rtld_bind_start(void); -const Elf_Sym *symlook_obj(const char *, unsigned long, const Obj_Entry *, - const Ver_Entry *, int); +void symlook_init(SymLook *, const char *); +int symlook_obj(SymLook *, const Obj_Entry *); void *tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset); void *allocate_tls(Obj_Entry *, void *, size_t, size_t); void free_tls(void *, size_t, size_t); @@ -294,9 +329,9 @@ const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long); * MD function declarations. */ int do_copy_relocations(Obj_Entry *); -int reloc_non_plt(Obj_Entry *, Obj_Entry *); +int reloc_non_plt(Obj_Entry *, Obj_Entry *, struct Struct_RtldLockState *); int reloc_plt(Obj_Entry *); -int reloc_jmpslots(Obj_Entry *); +int reloc_jmpslots(Obj_Entry *, struct Struct_RtldLockState *); void allocate_initial_tls(Obj_Entry *); #endif /* } */ |