summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/rtl/rtl.h
blob: 41cb010ef4e3f39dade5feb4549838b7b79f3a82 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
/*
 *  COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org>
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 */

/**
 * @file
 *
 * @ingroup rtems_rtl
 *
 * @brief RTEMS Run-Time Linker
 *
 * This is the POSIX interface to run-time loading of code into RTEMS.
 */

#if !defined (_RTEMS_RTL_H_)
#define _RTEMS_RTL_H_

#include <link.h>
#include <rtems/chain.h>
#include <rtems/thread.h>

#include <rtems/rtl/rtl-allocator.h>
#include <rtems/rtl/rtl-fwd.h>
#include <rtems/rtl/rtl-obj.h>
#include <rtems/rtl/rtl-obj-cache.h>
#include <rtems/rtl/rtl-obj-comp.h>
#include <rtems/rtl/rtl-sym.h>
#include <rtems/rtl/rtl-unresolved.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup rtems_rtl RTEMS Runtime Link Editor
 *
 * The module implements a runtime link editor with the standard dlopen, and
 * dlclose family of functions.
 *
 * The runtime link editor is different to that found on Unix type systems. The
 * object modules are compiled for PIC or position independent code and
 * therefore require relocating when loaded.
 *
 * The object file format is currently ELF and object files can be separate
 * files or in an archive. Object files in an archive are referenced by
 * specifying 'archive:object' format. For example 'libfoo.a:bar.o'.
 */

/**
 * Macros to glue two tokens.
 */
#ifdef __STDC__
#define RTL_XGLUE(a,b) a##b
#else
#define RTL_XGLUE(a,b) a/**/b
#endif

#define RTL_GLUE(a,b) RTL_XGLUE(a,b)

/**
 * The number of buckets in the global symbol table.
 */
#define RTEMS_RTL_SYMS_GLOBAL_BUCKETS (32)

/**
 * The number of relocation record per block in the unresolved table.
 */
#define RTEMS_RTL_UNRESOLVED_BLOCK_SIZE (64)

/**
 * The number of dependency record per block in the dependency table.
 */
#define RTEMS_RTL_DEPENDENCY_BLOCK_SIZE (16)

/**
 * The global debugger interface variable.
 */
extern struct r_debug _rtld_debug;

/**
 * Debugger break function. Call when debugging to have it read the _rtld_debug
 * variable.
 */
extern void _rtld_debug_state (void);

/**
 * The type of constructor/destructor function.
 */
typedef void (*rtems_rtl_cdtor)(void);

/**
 * The global RTL data. This structure is allocated on the heap when the first
 * call to the RTL is made and never released.
 *
 * The global symbol table is a hash table held in this structure and the
 * actual symbols are part of the object's structure. If this is a problem we
 * could look at a hash table per object file.
 */
struct rtems_rtl_data
{
  rtems_recursive_mutex lock;           /**< The RTL lock */
  rtems_rtl_alloc_data  allocator;      /**< The allocator data. */
  rtems_chain_control   objects;        /**< List if loaded object files. */
  const char*           paths;          /**< Search paths for archives. */
  rtems_rtl_symbols     globals;        /**< Global symbol table. */
  rtems_rtl_unresolved  unresolved;     /**< Unresolved symbols. */
  rtems_rtl_obj*        base;           /**< Base object file. */
  rtems_rtl_obj_cache   symbols;        /**< Symbols object file cache. */
  rtems_rtl_obj_cache   strings;        /**< Strings object file cache. */
  rtems_rtl_obj_cache   relocs;         /**< Relocations object file cache. */
  rtems_rtl_obj_comp    decomp;         /**< The decompression compressor. */
  int                   last_errno;     /**< Last error number. */
  char                  last_error[64]; /**< Last error string. */
};

/**
 * Get the RTL data with out locking. This call assumes the RTL is locked.
 *
 * @return rtems_rtl_data* The RTL data after being locked.
 * @retval NULL The RTL data is not initialised.
 */
rtems_rtl_data* rtems_rtl_data_unprotected (void);

/**
 * Get the RTL global symbol table with out locking. This call assmes the RTL
 * is locked.
 *
 * @return rtems_rtl_symbols* The RTL global symbols after being locked.
 * @retval NULL The RTL data is not initialised.
 */
rtems_rtl_symbols* rtems_rtl_global_symbols (void);

/**
 * Get the RTL resolved table with out locking. This call assmes the RTL
 * is locked.
 *
 * @return rtems_rtl_unresolv* The RTL unresolved symbols and reloc records.
 * @retval NULL The RTL data is not initialised.
 */
rtems_rtl_unresolved* rtems_rtl_unresolved_unprotected (void);

/**
 * Get the RTL symbols, strings, or relocations object file caches. This call
 * assmes the RTL is locked.
 *
 * @param symbols Pointer to the location to set the cache into. Returns NULL
 *                is rtl is not initialised. If NULL is passed in no value set.
 * @param strings Pointer to the location to set the cache into. Returns NULL
 *                is rtl is not initialised. If NULL is passed in no value set.
 * @param relocs Pointer to the location to set the cache into. Returns NULL
 *               is rtl is not initialised. If NULL is passed in no value set.
 */
void rtems_rtl_obj_caches (rtems_rtl_obj_cache** symbols,
                           rtems_rtl_obj_cache** strings,
                           rtems_rtl_obj_cache** relocs);

/**
 * Flush all the object file caches.
 */
void rtems_rtl_obj_caches_flush (void);

/**
 * Get the RTL decompressor setting for the cache and the offset in the file
 * the compressed stream starts. This call assumes the RTL is locked.
 *
 * @param decomp Pointer to the location to set the compressor into. Returns
 *               NULL is rtl is not initialised.
 * @param cache The cache to read the file with. Saves needing an extrs buffer.
 * @param offset The offset in the file the compressed stream starts.
 */
void rtems_rtl_obj_decompress (rtems_rtl_obj_comp** decomp,
                               rtems_rtl_obj_cache* cache,
                               int                  fd,
                               int                  compression,
                               off_t                offset);

/**
 * Update the mask in the object files. You can clear flags and then set
 * flags. A zero (0) does not clear or set the flags. This is global to all
 * object files that are laoded.
 *
 * @param clear The flag's clear mask, a 0 does not clear any flags.
 * @param set The flag's set mask, a 0 does not set any flags.
 */
void rtems_rtl_obj_update_flags (uint32_t clear, uint32_t set);

/**
 * Lock the Run-time Linker.
 *
 * @return rtems_rtl_data* The RTL data after being locked.
 * @retval NULL The RTL data could not be initialised or locked. Typically this
 *              means the lock could not be created.
 */
rtems_rtl_data* rtems_rtl_lock (void);

/**
 * Unlock the Run-time Linker.
 */
void rtems_rtl_unlock (void);

/**
 * Check a pointer is a valid object file descriptor returning the pointer as
 * that type.
 *
 * Assumes the RTL has been locked.
 *
 * @param handle Pointer to the object file to be validated.
 * @return rtl_obj* The object file descriptor. NULL is returned if invalid.
 */
rtems_rtl_obj* rtems_rtl_check_handle (void* handle);

/**
 * Find the object given a file name.
 *
 * @param name The name of the object file.
 * @retval NULL No object file with that name found.
 * @return rtems_rtl_obj* The object file descriptor.
 */
rtems_rtl_obj* rtems_rtl_find_obj (const char* name);

/**
 * Find the object file a symbol is exported from.
 *
 * @param sym The symbol to search with.
 * @retval NULL No object file found.
 * @return rtems_rtl_obj* Reference to the symbol.
 */
rtems_rtl_obj* rtems_rtl_find_obj_with_symbol (const rtems_rtl_obj_sym* sym);

/**
 * Load an object file into memory relocating it. It will not be resolved
 * against other symbols in other object files or the base image.
 *
 * The name can be a file name for an object file or it can be encoded to
 * reference an archive of object modules (static library). This encoding is
 * specific to RTEMS and allows dependences to specify an archive without the
 * searching overhead normally incurred by linkers locating object files in an
 * archive. The file name format rules are:
 *
 *  1. Absolute file references a specific object file in the architecture
 *     specific location on the file system.
 *
 *  2. Relative file references an object format file in the search path.
 *
 *  3. Absolute archive and file reference to a specific location in the file
 *     system. The archive and file are encoded as 'archive:file [@@offset]'
 *     where 'archive' is a valid file at the absolute path in the file system,
 *     and 'file' is a contained in the archive, and optionally an offset to
 *     the 'file' in the 'archive'. If no offset is provided the archive is
 *     searched.
 *
 *  4. Relative archive and file in the search path. The encoding is the same
 *     as described in item 3 of this list.
 *
 * Assumes the RTL has been locked.
 *
 * @param name The name of the object file.
 * @param mode The mode of the load as defined by the dlopen call.
 * @return rtl_obj* The object file descriptor. NULL is returned if the load fails.
 */
rtems_rtl_obj* rtems_rtl_load_object (const char* name, int mode);

/**
 * Unload an object file. This only happens when the user count is 0.
 *
 * Assumes the RTL has been locked.
 *
 * @param obj The object file descriptor.
 * @retval true The object file has been unloaded.
 * @retval false The object file could not be unloaded.
 */
bool rtems_rtl_unload_object (rtems_rtl_obj* obj);

/**
 * Run any constructor functions the object file may contain. This call
 * assumes the linker is unlocked.
 *
 * @param obj The object file.
 */
void rtems_rtl_run_ctors (rtems_rtl_obj* obj);

/**
 * Get the last error message clearing it. This operation locks the run time
 * linker and therefore keeps the RTL thread safe but this call is not thread
 * safe is multiple threads are loading object files at the same time. This
 * call is provided to map to the dlopen family of calls.
 *
 * @param message Pointer to a buffer to copy the message into.
 * @param max_message The maximum message that can be copied.
 * @return int The last error number.
 */
int rtems_rtl_get_error (char* message, size_t max_message);

/**
 * Append the path to the search path.
 *
 * @param path The path to append.
 * @retval false The path could not be appended.
 * @retval true The path was appended.
 */
bool rtems_rtl_path_append (const char* path);

/**
 * Prepend the path to the search path.
 *
 * @param path The path to prepend.
 * @retval false The path could not be prepended.
 * @retval true The path was prepended.
 */

bool rtems_rtl_path_prepend (const char* path);

/**
 * Add an exported symbol table to the global symbol table. This call is
 * normally used by an object file when loaded that contains a global symbol
 * table.
 *
 * @param esyms The exported symbol table.
 * @param count The size of the exported symbol table.
 */
void rtems_rtl_base_sym_global_add (const unsigned char* esyms,
                                    unsigned int         count);

/**
 * Return the object file descriptor for the base image. The object file
 * descriptor returned is created when the run time linker is initialised.
 *
 * Assumes the RTL has been locked.
 *
 * @return rtl_obj* The object file descriptor for the base image. NULL is
 *                  returned if the load fails.
 */
rtems_rtl_obj* rtems_rtl_baseimage (void);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif