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#include <image.h>
15#include <OS.h>
16
17#include <elf32.h>
18#include <elf64.h>
19#include <fatelf.h>
20
21
22// #pragma mark - runtime loader libroot interface
23
24
25struct user_space_program_args;
26struct SymbolLookupInfo;
27
28struct rld_export {
29	// runtime loader API export
30	image_id (*load_add_on)(char const *path, uint32 flags);
31	status_t (*unload_add_on)(image_id imageID);
32	image_id (*load_library)(char const *path, uint32 flags, 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** _symbolName,
43		int32* _type, void** _location);
44	status_t (*test_executable)(const char *path, char *interpreter);
45	status_t (*get_next_image_dependency)(image_id id, uint32 *cookie,
46		const char **_name);
47
48	status_t (*reinit_after_fork)();
49
50	void (*call_atexit_hooks_for_range)(addr_t start, addr_t size);
51
52	void (*call_termination_hooks)();
53
54	const struct user_space_program_args *program_args;
55};
56
57extern struct rld_export *__gRuntimeLoader;
58
59
60// #pragma mark - runtime loader debugger interface
61
62
63struct RuntimeLoaderSymbolPatcher;
64
65typedef struct elf_region_t {
66	area_id		id;
67	addr_t		start;
68	addr_t		size;
69	addr_t		vmstart;
70	addr_t		vmsize;
71	addr_t		fdstart;
72	addr_t		fdsize;
73	long		delta;
74	uint32		flags;
75} elf_region_t;
76
77typedef struct elf_version_info {
78	uint32		hash;			// version name hash
79	const char	*name;			// version name
80	const char	*file_name;		// dependency file name (needed versions only)
81} elf_version_info;
82
83typedef struct image_t {
84	// image identification
85	char				path[B_PATH_NAME_LENGTH];
86	char				name[B_OS_NAME_LENGTH];
87	image_id			id;
88	image_type			type;
89
90	struct image_t		*next;
91	struct image_t		*prev;
92	int32				ref_count;
93	uint32				flags;
94
95	uint32				api_version;
96	uint32				abi;
97
98	addr_t 				entry_point;
99	addr_t				init_routine;
100	addr_t				term_routine;
101	addr_t 				dynamic_ptr; 	// pointer to the dynamic section
102
103	// pointer to symbol participation data structures
104	uint32				*symhash;
105	elf_sym				*syms;
106	char				*strtab;
107	elf_rel				*rel;
108	int					rel_len;
109	elf_rela			*rela;
110	int					rela_len;
111	elf_rel				*pltrel;
112	int					pltrel_len;
113
114	uint32				num_needed;
115	struct image_t		**needed;
116
117	// versioning related structures
118	uint32				num_version_definitions;
119	elf_verdef			*version_definitions;
120	uint32				num_needed_versions;
121	elf_verneed			*needed_versions;
122	elf_versym			*symbol_versions;
123	elf_version_info	*versions;
124	uint32				num_versions;
125
126#ifdef __cplusplus
127	elf_sym*			(*find_undefined_symbol)(struct image_t* rootImage,
128							struct image_t* image,
129							const SymbolLookupInfo& lookupInfo,
130							struct image_t** foundInImage);
131#else
132	elf_sym*			(*find_undefined_symbol)(struct image_t* rootImage,
133							struct image_t* image,
134							const struct SymbolLookupInfo* lookupInfo,
135							struct image_t** foundInImage);
136#endif
137
138	// Singly-linked list of symbol patchers for symbols defined respectively
139	// referenced by this image.
140	struct RuntimeLoaderSymbolPatcher	*defined_symbol_patchers;
141	struct RuntimeLoaderSymbolPatcher	*undefined_symbol_patchers;
142
143	// describes the text and data regions
144	uint32				num_regions;
145	elf_region_t		regions[1];
146} image_t;
147
148typedef struct image_queue_t {
149	image_t *head;
150	image_t *tail;
151} image_queue_t;
152
153// image_t::flags
154#define	IMAGE_FLAG_RTLD_MASK			0x03
155			// RTLD_{LAZY,NOW} | RTLD_{LOCAL,GLOBAL}
156
157#define STRING(image, offset) ((char*)(&(image)->strtab[(offset)]))
158#define SYMNAME(image, sym) STRING(image, (sym)->st_name)
159#define SYMBOL(image, num) (&(image)->syms[num])
160#define HASHTABSIZE(image) ((image)->symhash[0])
161#define HASHBUCKETS(image) ((unsigned int*)&(image)->symhash[2])
162#define HASHCHAINS(image) ((unsigned int*)&(image)->symhash[2+HASHTABSIZE(image)])
163
164
165// The name of the area the runtime loader creates for debugging purposes.
166#define RUNTIME_LOADER_DEBUG_AREA_NAME	"_rld_debug_"
167
168// The contents of the runtime loader debug area.
169typedef struct runtime_loader_debug_area {
170	image_queue_t	*loaded_images;
171} runtime_loader_debug_area;
172
173
174// #pragma mark - runtime loader add-on interface
175
176
177// symbol patcher callback
178typedef void runtime_loader_symbol_patcher(void* cookie,
179	struct image_t* rootImage, struct image_t* image, const char* name,
180	struct image_t** foundInImage, void** symbol, int32* type);
181
182// interface provided to add-ons
183struct runtime_loader_add_on_export {
184	status_t	(*register_defined_symbol_patcher)(struct image_t* image,
185					runtime_loader_symbol_patcher* patcher, void* cookie);
186	void		(*unregister_defined_symbol_patcher)(struct image_t* image,
187					runtime_loader_symbol_patcher* patcher, void* cookie);
188	status_t	(*register_undefined_symbol_patcher)(struct image_t* image,
189					runtime_loader_symbol_patcher* patcher, void* cookie);
190	void		(*unregister_undefined_symbol_patcher)(struct image_t* image,
191					runtime_loader_symbol_patcher* patcher, void* cookie);
192};
193
194
195#define RUNTIME_LOADER_ADD_ON_VERSION	1
196
197typedef struct runtime_loader_add_on {
198	uint32	version;
199	uint32	flags;
200
201	// called after the add-on image has been loaded
202	void	(*init)(struct rld_export* standardInterface,
203				struct runtime_loader_add_on_export* addOnInterface);
204
205	// called whenever the respective image event occurs
206	void	(*image_loaded)(struct image_t* image);
207	void	(*image_relocated)(struct image_t* image);
208	void	(*image_initialized)(struct image_t* image);
209	void	(*image_uninitializing)(struct image_t* image);
210	void	(*image_unloading)(struct image_t* image);
211} runtime_loader_add_on;
212
213// This is the variable a preloaded shared object has to export to get picked up
214// by the runtime loader as an add-on.
215extern runtime_loader_add_on __gRuntimeLoaderAddOn;
216
217#endif	// _RUNTIME_LOADER_H
218