[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / procMgr / hlos / knl / loaders / Elf / Qnx / DLOAD / DLOAD / dload.h
1 /*
2 * dload.h
3 *
4 * Define internal data structures used by core dynamic loader.
5 *
6 * Copyright (C) 2009-2015 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the
19 * distribution.
20 *
21 * Neither the name of Texas Instruments Incorporated nor the names of
22 * its contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
39 #ifndef DLOAD_H
40 #define DLOAD_H
42 #include "ArrayList.h"
43 #include "Queue.h"
44 #include "Stack.h"
45 #include "elf32.h"
46 #include "dload_api.h"
47 #include "util.h"
49 /*---------------------------------------------------------------------------*/
50 /* Contains strings with names of files the loader is in process of loading. */
51 /* This list is used to keep track of what objects are in the process of */
52 /* loading while their dependents are being loaded so that we can detect */
53 /* circular dependencies. */
54 /*---------------------------------------------------------------------------*/
55 extern Array_List DLIMP_module_dependency_list;
57 /*---------------------------------------------------------------------------*/
58 /* DLIMP_Loaded_Segment */
59 /* */
60 /* This structure represents a segment loaded on memory. */
61 /* */
62 /* This data structure should be created using host memory when a module */
63 /* is being loaded into target memory. The data structure should persist */
64 /* as long as the module stays resident in target memory. It should be */
65 /* removed when the last use of the module is unloaded from the target. */
66 /*---------------------------------------------------------------------------*/
67 typedef struct
68 {
69 struct Elf32_Phdr phdr;
70 Elf32_Addr input_vaddr; /* original segment load addr */
71 BOOL modified;
72 struct DLOAD_MEMORY_SEGMENT *obj_desc;
73 void * host_address;
74 } DLIMP_Loaded_Segment;
76 /*---------------------------------------------------------------------------*/
77 /* DLIMP_Loaded_Module */
78 /* */
79 /* This structure contains all the information the dynamic loader needs */
80 /* to retain after loading an object file's segments into target memory. */
81 /* The data structure is created while the object file is being loaded, */
82 /* and should persist until the last use of the module is unloaded from */
83 /* target memory. */
84 /* */
85 /* The information contained here is used by the dynamic loader to */
86 /* perform dynamic symbol resolution, to track the use count, and to */
87 /* finally deallocate the module's segments when the module is unloaded. */
88 /*---------------------------------------------------------------------------*/
89 typedef struct
90 {
91 char *name; /* Local copy of so_name */
92 int32_t file_handle;
93 int32_t use_count;
94 Elf32_Addr entry_point; /* Entry point address into module */
95 struct Elf32_Sym *gsymtab; /* Module's global symbol table */
96 Elf32_Word gsymnum; /* # global symbols */
97 char *gstrtab; /* Module's global symbol names */
98 Elf32_Word gstrsz; /* Size of global string table */
99 Array_List loaded_segments; /* List of DLIMP_Loaded_Segment(s) */
100 Array_List dependencies; /* List of dependent file handles */
101 BOOL direct_dependent_only;
103 Elf32_Addr fini; /* .fini function/section address */
104 Elf32_Addr fini_array; /* .fini_array term fcn ary addr */
105 int32_t fini_arraysz; /* sizeof .fini_array */
106 uint8_t *c_args; /* address of module's .args sect */
107 uint8_t *static_base; /* address of module's STATIC_BASE */
109 } DLIMP_Loaded_Module;
111 /*---------------------------------------------------------------------------*/
112 /* DLIMP_loaded_objects */
113 /* */
114 /* A list of loaded module objects (DLIMP_Loaded_Module *) that the */
115 /* loader has placed into target memory. */
116 /*---------------------------------------------------------------------------*/
117 TYPE_QUEUE_DEFINITION(DLIMP_Loaded_Module*, loaded_module_ptr)
118 extern loaded_module_ptr_Queue DLIMP_loaded_objects;
120 /*---------------------------------------------------------------------------*/
121 /* DLIMP_Dynamic_Module */
122 /* */
123 /* This structure represents a dynamic module to be loaded by the dynamic */
124 /* loader. It contains all the information necessary to load and relocate */
125 /* the module. It actually contains most of the headers, dynamic info, */
126 /* dynamic symbol table, string table etc. */
127 /* */
128 /* This structure is allocated in host memory while an ELF object file is */
129 /* being loaded and will be destructed after the file has been */
130 /* successfully loaded. To simplify loading and relocation of the object */
131 /* file's segments, this data structure maintains a link to the loaded */
132 /* module. This link is severed when the load is successfully completed. */
133 /* The loaded module data structure will persist until the module is */
134 /* actually unloaded from target memory, but this data structure will be */
135 /* freed. */
136 /* */
137 /* If the load of the object file is not successful for any reason, then */
138 /* the loaded module will not be detached from the dynamic module. In */
139 /* such case, the destructor for the dynamic module will assume */
140 /* responsibility for freeing any host memory associated with the loaded */
141 /* module and its segments. */
142 /*---------------------------------------------------------------------------*/
143 typedef struct
144 {
145 char *name; /* Local copy of so_name */
146 LOADER_FILE_DESC *fd; /* Access to ELF object file */
147 struct Elf32_Ehdr fhdr; /* ELF Object File Header */
148 struct Elf32_Phdr *phdr; /* ELF Program Header Table */
149 Elf32_Word phnum; /* # entries in program header table */
150 char* strtab; /* String Table */
151 Elf32_Word strsz; /* String Table size in bytes */
152 struct Elf32_Dyn *dyntab; /* Elf Dynamic Table (.dynamic scn) */
153 /* This contains a list of dynamic */
154 /* tags which is terminated by a NULL */
155 /* record. */
156 struct Elf32_Sym *symtab; /* Elf Dynamic Symbol Table */
157 Elf32_Word symnum; /* # symbols in dynamic symbol table */
158 Elf32_Word gsymtab_offset;/* Offset into symbol table where */
159 /* global symbols start. */
160 Elf32_Word gstrtab_offset;/* Offset into string table where */
161 /* global symbol names start. */
163 uint8_t *c_args;
164 uint8_t *static_base; /* address of module's STATIC_BASE */
165 int32_t argc;
166 char **argv;
167 DLIMP_Loaded_Module *loaded_module;
168 int32_t wrong_endian;
169 BOOL direct_dependent_only;
170 BOOL relocatable; /* TRUE if module can be relocated */
171 /* at load-time. FALSE if module is */
172 /* a static executable. */
173 BOOL relocate_entry_point; /* TRUE if the entry point has */
174 /* not been relocated */
176 int32_t dsbt_index; /* DSBT index requested/assigned */
177 uint32_t dsbt_size; /* DSBT size for this module */
178 int32_t dsbt_base_tagidx;/* Location of DSBT base dyn tag */
180 int32_t preinit_array_idx; /* DT_PREINIT_ARRAY dyn tag loc */
181 int32_t preinit_arraysz; /* sizeof pre-init array */
182 int32_t init_idx; /* DT_INIT dynamic tag location */
183 int32_t init_array_idx; /* DT_INIT_ARRAY dyn tag location */
184 int32_t init_arraysz; /* sizeof init array */
186 } DLIMP_Dynamic_Module;
188 /*---------------------------------------------------------------------------*/
189 /* DLIMP_dependency_stack */
190 /* */
191 /* A LIFO stack of dynamic module objects (DLIMP_Dynamic_Module *) that */
192 /* is retained while dependent files are being loaded and allocated. It */
193 /* is used to guide which dynamic modules need to be relocated after all */
194 /* items in the dependency graph have been allocated. The stack is only */
195 /* used when the client asks the core loader to load a dynamic executable */
196 /* or library. When relocation is completed, this stack should be empty. */
197 /*---------------------------------------------------------------------------*/
198 TYPE_STACK_DEFINITION(DLIMP_Dynamic_Module*, dynamic_module_ptr)
199 extern dynamic_module_ptr_Stack DLIMP_dependency_stack;
201 /*---------------------------------------------------------------------------*/
202 /* Private Loader Object instance. */
203 /*---------------------------------------------------------------------------*/
204 typedef struct
205 {
206 /*-----------------------------------------------------------------------*/
207 /* Contains filenames (type const char*) the system is in the process of */
208 /* loading. Used to detect cycles in incorrectly compiled ELF binaries. */
209 /*-----------------------------------------------------------------------*/
210 Array_List DLIMP_module_dependency_list;
212 /*-----------------------------------------------------------------------*/
213 /* Contains objects (type DLIMP_Loaded_Module) that the system has loaded*/
214 /* into target memory. */
215 /*-----------------------------------------------------------------------*/
216 loaded_module_ptr_Queue DLIMP_loaded_objects;
218 /*-----------------------------------------------------------------------*/
219 /* Dependency Graph Queue - FIFO queue of dynamic modules that are loaded*/
220 /* when client asks to load a dynamic executable or library. Note that */
221 /* dependents that have already been loaded with another module will not */
222 /* appear on this queue. */
223 /*-----------------------------------------------------------------------*/
224 dynamic_module_ptr_Stack DLIMP_dependency_stack;
226 /*-----------------------------------------------------------------------*/
227 /* Counter for generating unique IDs for file handles. */
228 /* NOTE: File handle is assigned sequencially but is never reclaimed */
229 /* when the modules are unloaded. It is conceivable that a loader*/
230 /* running for a long time and loading and unloading modules */
231 /* could wrap-around. The loader generates error in this case. */
232 /* Presumably each loader instance has a list of file handles, one for */
233 /* each file that it loads, and the file handle serves as an index into */
234 /* the list. Therefore even if the same file is loaded by two loader */
235 /* instances, both loader instances have a different file handle for the */
236 /* file - the file is mapped uniquely to it's appopriate file handle per */
237 /* loader instance. */
238 /*-----------------------------------------------------------------------*/
239 int32_t file_handle;
241 /*-----------------------------------------------------------------------*/
242 /* Client token, passed in via DLOAD_create() */
243 /*-----------------------------------------------------------------------*/
244 void * client_handle;
245 } LOADER_OBJECT;
248 /*****************************************************************************/
249 /* IF data : Below are the data structures used to store init-fini data. */
250 /*****************************************************************************/
251 typedef struct
252 {
253 TARGET_ADDRESS sect_addr;
254 int32_t size;
255 }
256 IF_single_record;
258 TYPE_QUEUE_DEFINITION(IF_single_record*, IF_table)
259 extern IF_table_Queue TI_init_table;
262 /*****************************************************************************/
263 /* Container used to read in argc, argv from the .srgs section. */
264 /*****************************************************************************/
265 typedef struct { int argc; char *argv[1]; } ARGS_CONTAINER;
268 /*****************************************************************************/
269 /* is_DSBT_module() */
270 /* */
271 /* return true if the module uses DSBT model */
272 /*****************************************************************************/
273 static inline BOOL is_dsbt_module(DLIMP_Dynamic_Module *dyn_module)
274 {
275 return (dyn_module->dsbt_size != 0);
276 }
278 /*****************************************************************************/
279 /* is_arm_module() */
280 /* */
281 /* return true if the module being processed is for ARM */
282 /*****************************************************************************/
283 static inline BOOL is_arm_module(struct Elf32_Ehdr* fhdr)
284 {
285 return fhdr->e_machine == EM_ARM;
286 }
288 /*****************************************************************************/
289 /* is_c60_module() */
290 /* */
291 /* return true if the module being processed is for C60 */
292 /*****************************************************************************/
293 static inline BOOL is_c60_module(struct Elf32_Ehdr* fhdr)
294 {
295 return fhdr->e_machine == EM_TI_C6000;
296 }
298 /*---------------------------------------------------------------------------*/
299 /* DLIMP_update_dyntag_section_address() */
300 /* */
301 /* Given the index of a dynamic tag which we happen to know points to a */
302 /* section address, find the program header table entry associated with */
303 /* the specified address and update the tag value with the real address */
304 /* of the section. */
305 /* */
306 /*---------------------------------------------------------------------------*/
307 extern BOOL DLIMP_update_dyntag_section_address(DLIMP_Dynamic_Module *dyn_module,
308 int32_t i);
310 extern uint32_t DLIMP_get_first_dyntag(int tag, struct Elf32_Dyn* dyn_table);
312 /*---------------------------------------------------------------------------*/
313 /* Global flags to help manage internal debug and profiling efforts. */
314 /*---------------------------------------------------------------------------*/
315 #define LOADER_DEBUG 0
316 #define LOADER_PROFILE 0
318 #if LOADER_DEBUG
319 extern BOOL debugging_on;
320 #endif
322 #if LOADER_DEBUG || LOADER_PROFILE
323 extern BOOL profiling_on;
324 #endif
326 #endif