1/*
2 * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2003-2011, Axel D��rfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
5 *
6 * Copyright 2002, Manuel J. Petit. All rights reserved.
7 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
8 * Distributed under the terms of the NewOS License.
9 */
10
11#ifndef _RUNTIME_LOADER_H
12#define _RUNTIME_LOADER_H
13
14
15#include <image.h>
16#include <OS.h>
17
18#include <elf_private.h>
19
20
21// #pragma mark - runtime loader libroot interface
22
23
24struct user_space_program_args;
25struct SymbolLookupInfo;
26
27struct rld_export {
28	// runtime loader API export
29	image_id (*load_add_on)(char const *path, uint32 flags);
30	status_t (*unload_add_on)(image_id imageID);
31	image_id (*load_library)(char const *path, uint32 flags, void* caller,
32		void **_handle);
33	status_t (*unload_library)(void* handle);
34	status_t (*get_image_symbol)(image_id imageID, char const *symbolName,
35		int32 symbolType, bool recursive, image_id *_inImage, void **_location);
36	status_t (*get_library_symbol)(void* handle, void* caller,
37		const char* symbolName, void **_location);
38	status_t (*get_nth_image_symbol)(image_id imageID, int32 num,
39		char *symbolName, int32 *nameLength, int32 *symbolType,
40		void **_location);
41	status_t (*get_nearest_symbol_at_address)(void* address,
42		image_id* _imageID,	char** _imagePath, char** _imageName,
43		char** _symbolName, int32* _type, void** _location, bool* _exactMatch);
44	status_t (*test_executable)(const char *path, char *interpreter);
45	status_t (*get_executable_architecture)(const char *path,
46		const char** _architecture);
47	status_t (*get_next_image_dependency)(image_id id, uint32 *cookie,
48		const char **_name);
49	void* (*get_tls_address)(unsigned dso, addr_t offset);
50	void (*destroy_thread_tls)();
51
52	status_t (*reinit_after_fork)();
53
54	void (*call_atexit_hooks_for_range)(addr_t start, addr_t size);
55
56	void (*call_termination_hooks)();
57
58	const struct user_space_program_args *program_args;
59	const void* commpage_address;
60	int abi_version;
61	int api_version;
62};
63
64extern struct rld_export *__gRuntimeLoader;
65
66
67// #pragma mark - runtime loader debugger interface
68
69
70struct RuntimeLoaderSymbolPatcher;
71
72typedef struct elf_region_t {
73	area_id		id;
74	addr_t		start;
75	addr_t		size;
76	addr_t		vmstart;
77	addr_t		vmsize;
78	addr_t		fdstart;
79	addr_t		fdsize;
80	long		delta;
81	uint32		flags;
82} elf_region_t;
83
84typedef struct elf_version_info {
85	uint32		hash;			// version name hash
86	const char	*name;			// version name
87	const char	*file_name;		// dependency file name (needed versions only)
88} elf_version_info;
89
90typedef struct image_t {
91	// image identification
92	char				path[B_PATH_NAME_LENGTH];
93	char				name[B_FILE_NAME_LENGTH];
94	image_id			id;
95	image_type			type;
96
97	struct image_t		*next;
98	struct image_t		*prev;
99	int32				ref_count;
100	uint32				flags;
101
102	uint32				api_version;
103	uint32				abi;
104
105	addr_t 				entry_point;
106	addr_t				init_routine;
107	addr_t				term_routine;
108	addr_t 				dynamic_ptr; 	// pointer to the dynamic section
109
110	// pointer to symbol participation data structures
111	uint32				*symhash;
112	elf_sym				*syms;
113	char				*strtab;
114	elf_rel				*rel;
115	int					rel_len;
116	elf_rela			*rela;
117	int					rela_len;
118	elf_rel				*pltrel;
119	int					pltrel_len;
120	addr_t				*init_array;
121	int					init_array_len;
122	addr_t				*preinit_array;
123	int					preinit_array_len;
124	addr_t				*term_array;
125	int					term_array_len;
126
127	unsigned			dso_tls_id;
128
129	uint32				num_needed;
130	struct image_t		**needed;
131
132	// versioning related structures
133	uint32				num_version_definitions;
134	elf_verdef			*version_definitions;
135	uint32				num_needed_versions;
136	elf_verneed			*needed_versions;
137	elf_versym			*symbol_versions;
138	elf_version_info	*versions;
139	uint32				num_versions;
140
141#ifdef __cplusplus
142	elf_sym*			(*find_undefined_symbol)(struct image_t* rootImage,
143							struct image_t* image,
144							const SymbolLookupInfo& lookupInfo,
145							struct image_t** foundInImage);
146#else
147	elf_sym*			(*find_undefined_symbol)(struct image_t* rootImage,
148							struct image_t* image,
149							const struct SymbolLookupInfo* lookupInfo,
150							struct image_t** foundInImage);
151#endif
152
153	// Singly-linked list of symbol patchers for symbols defined respectively
154	// referenced by this image.
155	struct RuntimeLoaderSymbolPatcher	*defined_symbol_patchers;
156	struct RuntimeLoaderSymbolPatcher	*undefined_symbol_patchers;
157
158	// describes the text and data regions
159	uint32				num_regions;
160	elf_region_t		regions[1];
161} image_t;
162
163typedef struct image_queue_t {
164	image_t *head;
165	image_t *tail;
166} image_queue_t;
167
168// image_t::flags
169#define	IMAGE_FLAG_RTLD_MASK			0x03
170			// RTLD_{LAZY,NOW} | RTLD_{LOCAL,GLOBAL}
171
172#define STRING(image, offset) ((char*)(&(image)->strtab[(offset)]))
173#define SYMNAME(image, sym) STRING(image, (sym)->st_name)
174#define SYMBOL(image, num) (&(image)->syms[num])
175#define HASHTABSIZE(image) ((image)->symhash[0])
176#define HASHBUCKETS(image) ((unsigned int*)&(image)->symhash[2])
177#define HASHCHAINS(image) ((unsigned int*)&(image)->symhash[2+HASHTABSIZE(image)])
178
179
180// The name of the area the runtime loader creates for debugging purposes.
181#define RUNTIME_LOADER_DEBUG_AREA_NAME	"_rld_debug_"
182
183// The contents of the runtime loader debug area.
184typedef struct runtime_loader_debug_area {
185	image_queue_t	*loaded_images;
186} runtime_loader_debug_area;
187
188
189// #pragma mark - runtime loader add-on interface
190
191
192// symbol patcher callback
193typedef void runtime_loader_symbol_patcher(void* cookie,
194	struct image_t* rootImage, struct image_t* image, const char* name,
195	struct image_t** foundInImage, void** symbol, int32* type);
196
197// interface provided to add-ons
198struct runtime_loader_add_on_export {
199	status_t	(*register_defined_symbol_patcher)(struct image_t* image,
200					runtime_loader_symbol_patcher* patcher, void* cookie);
201	void		(*unregister_defined_symbol_patcher)(struct image_t* image,
202					runtime_loader_symbol_patcher* patcher, void* cookie);
203	status_t	(*register_undefined_symbol_patcher)(struct image_t* image,
204					runtime_loader_symbol_patcher* patcher, void* cookie);
205	void		(*unregister_undefined_symbol_patcher)(struct image_t* image,
206					runtime_loader_symbol_patcher* patcher, void* cookie);
207};
208
209
210#define RUNTIME_LOADER_ADD_ON_VERSION	1
211
212typedef struct runtime_loader_add_on {
213	uint32	version;
214	uint32	flags;
215
216	// called after the add-on image has been loaded
217	void	(*init)(struct rld_export* standardInterface,
218				struct runtime_loader_add_on_export* addOnInterface);
219
220	// called whenever the respective image event occurs
221	void	(*image_loaded)(struct image_t* image);
222	void	(*image_relocated)(struct image_t* image);
223	void	(*image_initialized)(struct image_t* image);
224	void	(*image_uninitializing)(struct image_t* image);
225	void	(*image_unloading)(struct image_t* image);
226} runtime_loader_add_on;
227
228// This is the variable a preloaded shared object has to export to get picked up
229// by the runtime loader as an add-on.
230extern runtime_loader_add_on __gRuntimeLoaderAddOn;
231
232#endif	// _RUNTIME_LOADER_H
233