1 /*
2 * dload.h
3 *
4 * Define internal data structures used by core dynamic loader.
5 *
6 * Copyright (C) 2009 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 "ewrap.h"
44 #include "ArrayList.h"
45 /* #include "Queue.h" */
46 /* #include "Stack.h" */
47 #include "types.h"
48 #include "elf32.h"
49 #include "dload_api.h"
50 #include "util.h"
52 /*---------------------------------------------------------------------------*/
53 /* Contains strings with names of files the loader is in process of loading. */
54 /* This list is used to keep track of what objects are in the process of */
55 /* loading while their dependents are being loaded so that we can detect */
56 /* circular dependencies. */
57 /*---------------------------------------------------------------------------*/
58 #if 0
59 extern Array_List DLIMP_module_dependency_list;
60 #endif
62 /*---------------------------------------------------------------------------*/
63 /* DLIMP_Loaded_Segment */
64 /* */
65 /* This structure represents a segment loaded on memory. */
66 /* */
67 /* This data structure should be created using host memory when a module */
68 /* is being loaded into target memory. The data structure should persist */
69 /* as long as the module stays resident in target memory. It should be */
70 /* removed when the last use of the module is unloaded from the target. */
71 /*---------------------------------------------------------------------------*/
72 typedef struct
73 {
74 struct Elf32_Phdr phdr;
75 Elf32_Addr input_vaddr; /* original segment load addr */
76 BOOL modified;
77 int32_t reloc_offset; /* used by load_program */
78 struct DLOAD_MEMORY_SEGMENT *obj_desc;
79 } DLIMP_Loaded_Segment;
81 /*---------------------------------------------------------------------------*/
82 /* DLIMP_Loaded_Module */
83 /* */
84 /* This structure contains all the information the dynamic loader needs */
85 /* to retain after loading an object file's segments into target memory. */
86 /* The data structure is created while the object file is being loaded, */
87 /* and should persist until the last use of the module is unloaded from */
88 /* target memory. */
89 /* */
90 /* The information contained here is used by the dynamic loader to */
91 /* perform dynamic symbol resolution, to track the use count, and to */
92 /* finally deallocate the module's segments when the module is unloaded. */
93 /*---------------------------------------------------------------------------*/
94 typedef struct
95 {
96 char *name; /* Local copy of so_name */
97 int32_t file_handle;
98 int32_t use_count;
99 Elf32_Addr entry_point; /* Entry point address into module */
100 struct Elf32_Sym *gsymtab; /* Module's global symbol table */
101 Elf32_Word gsymnum; /* # global symbols */
102 char *gstrtab; /* Module's global symbol names */
103 Elf32_Word gstrsz; /* Size of global string table */
104 Array_List loaded_segments; /* List of DLIMP_Loaded_Segment(s) */
105 Array_List dependencies; /* List of dependent file handles */
106 BOOL direct_dependent_only;
108 Elf32_Addr fini; /* .fini function/section address */
109 Elf32_Addr fini_array; /* .fini_array term fcn ary addr */
110 int32_t fini_arraysz; /* sizeof .fini_array */
112 } DLIMP_Loaded_Module;
114 /*---------------------------------------------------------------------------*/
115 /* DLIMP_loaded_objects */
116 /* */
117 /* A list of loaded module objects (DLIMP_Loaded_Module *) that the */
118 /* loader has placed into target memory. */
119 /*---------------------------------------------------------------------------*/
120 #if 0
121 TYPE_QUEUE_DEFINITION(DLIMP_Loaded_Module*, loaded_module_ptr)
122 extern loaded_module_ptr_Queue DLIMP_loaded_objects;
123 #endif
125 /*---------------------------------------------------------------------------*/
126 /* DLIMP_Dynamic_Module */
127 /* */
128 /* This structure represents a dynamic module to be loaded by the dynamic */
129 /* loader. It contains all the information necessary to load and relocate */
130 /* the module. It actually contains most of the headers, dynamic info, */
131 /* dynamic symbol table, string table etc. */
132 /* */
133 /* This structure is allocated in host memory while an ELF object file is */
134 /* being loaded and will be destructed after the file has been */
135 /* successfully loaded. To simplify loading and relocation of the object */
136 /* file's segments, this data structure maintains a link to the loaded */
137 /* module. This link is severed when the load is successfully completed. */
138 /* The loaded module data structure will persist until the module is */
139 /* actually unloaded from target memory, but this data structure will be */
140 /* freed. */
141 /* */
142 /* If the load of the object file is not successful for any reason, then */
143 /* the loaded module will not be detached from the dynamic module. In */
144 /* such case, the destructor for the dynamic module will assume */
145 /* responsibility for freeing any host memory associated with the loaded */
146 /* module and its segments. */
147 /*---------------------------------------------------------------------------*/
148 typedef struct
149 {
150 char *name; /* Local copy of so_name */
151 LOADER_FILE_DESC *fd; /* Access to ELF object file */
152 struct Elf32_Ehdr fhdr; /* ELF Object File Header */
153 struct Elf32_Phdr *phdr; /* ELF Program Header Table */
154 Elf32_Word phnum; /* # entries in program header table */
155 char* strtab; /* String Table */
156 Elf32_Word strsz; /* String Table size in bytes */
157 struct Elf32_Dyn *dyntab; /* Elf Dynamic Table (.dynamic scn) */
158 /* This contains a list of dynamic */
159 /* tags which is terminated by a NULL */
160 /* record. */
161 struct Elf32_Sym *symtab; /* Elf Dynamic Symbol Table */
162 Elf32_Word symnum; /* # symbols in dynamic symbol table */
163 Elf32_Word gsymtab_offset;/* Offset into symbol table where */
164 /* global symbols start. */
165 Elf32_Word gstrtab_offset;/* Offset into string table where */
166 /* global symbol names start. */
168 uint8_t *c_args;
169 int32_t argc;
170 char **argv;
171 DLIMP_Loaded_Module *loaded_module;
172 int32_t wrong_endian;
173 BOOL direct_dependent_only;
174 BOOL relocatable; /* TRUE if module can be relocated */
175 /* at load-time. FALSE if module is */
176 /* a static executable. */
177 BOOL relocate_entry_point; /* TRUE if the entry point has */
178 /* not been relocated */
180 int32_t dsbt_index; /* DSBT index requested/assigned */
181 uint32_t dsbt_size; /* DSBT size for this module */
182 int32_t dsbt_base_tagidx;/* Location of DSBT base dyn tag */
184 int32_t preinit_array_idx; /* DT_PREINIT_ARRAY dyn tag loc */
185 int32_t preinit_arraysz; /* sizeof pre-init array */
186 int32_t init_idx; /* DT_INIT dynamic tag location */
187 int32_t init_array_idx; /* DT_INIT_ARRAY dyn tag location */
188 int32_t init_arraysz; /* sizeof init array */
190 } DLIMP_Dynamic_Module;
192 /*---------------------------------------------------------------------------*/
193 /* DLIMP_dependency_stack */
194 /* */
195 /* A LIFO stack of dynamic module objects (DLIMP_Dynamic_Module *) that */
196 /* is retained while dependent files are being loaded and allocated. It */
197 /* is used to guide which dynamic modules need to be relocated after all */
198 /* items in the dependency graph have been allocated. The stack is only */
199 /* used when the client asks the core loader to load a dynamic executable */
200 /* or library. When relocation is completed, this stack should be empty. */
201 /*---------------------------------------------------------------------------*/
202 TYPE_STACK_DEFINITION(DLIMP_Dynamic_Module*, dynamic_module_ptr)
203 #if 0
204 extern dynamic_module_ptr_Stack DLIMP_dependency_stack;
205 #endif
207 /*****************************************************************************/
208 /* is_DSBT_module() */
209 /* */
210 /* return true if the module uses DSBT model */
211 /*****************************************************************************/
212 static inline BOOL is_dsbt_module(DLIMP_Dynamic_Module *dyn_module)
213 {
214 return (dyn_module->dsbt_size != 0);
215 }
217 /*****************************************************************************/
218 /* is_arm_module() */
219 /* */
220 /* return true if the module being processed is for ARM */
221 /*****************************************************************************/
222 static inline BOOL is_arm_module(struct Elf32_Ehdr* fhdr)
223 {
224 return fhdr->e_machine == EM_ARM;
225 }
227 /*****************************************************************************/
228 /* is_c60_module() */
229 /* */
230 /* return true if the module being processed is for C60 */
231 /*****************************************************************************/
232 static inline BOOL is_c60_module(struct Elf32_Ehdr* fhdr)
233 {
234 return fhdr->e_machine == EM_TI_C6000;
235 }
237 /*---------------------------------------------------------------------------*/
238 /* Identifies the current supported target. This is reset by the default */
239 /* value when all loaded objects have been unloaded. */
240 /*---------------------------------------------------------------------------*/
241 extern int DLOAD_TARGET_MACHINE;
243 /*---------------------------------------------------------------------------*/
244 /* Identify target which is supported by the core loader. If set to EM_NONE */
245 /* the target will be determined by the first loaded module. */
246 /*---------------------------------------------------------------------------*/
247 #if defined(ARM_TARGET) && defined(C60_TARGET)
248 #define DLOAD_DEFAULT_TARGET_MACHINE (EM_NONE)
249 #elif defined(ARM_TARGET)
250 #define DLOAD_DEFAULT_TARGET_MACHINE (EM_ARM)
251 #elif defined(C60_TARGET)
252 #define DLOAD_DEFAULT_TARGET_MACHINE (EM_TI_C6000)
253 #else
254 #error "ARM_TARGET and/or C60_TARGET must be defined"
255 #endif
257 /*---------------------------------------------------------------------------*/
258 /* DLIMP_update_dyntag_section_address() */
259 /* */
260 /* Given the index of a dynamic tag which we happen to know points to a */
261 /* section address, find the program header table entry associated with */
262 /* the specified address and update the tag value with the real address */
263 /* of the section. */
264 /* */
265 /*---------------------------------------------------------------------------*/
266 extern BOOL DLIMP_update_dyntag_section_address(DLIMP_Dynamic_Module *dyn_module,
267 int32_t i);
269 /*---------------------------------------------------------------------------*/
270 /* Global flags to help manage internal debug and profiling efforts. */
271 /*---------------------------------------------------------------------------*/
272 #if 0
273 #ifndef __TI_COMPILER_VERSION__
274 #define LOADER_DEBUG 1
275 #else
276 #define LOADER_DEBUG 0
277 #endif
279 #undef LOADER_DEBUG
280 #define LOADER_DEBUG 1
281 #define LOADER_PROFILE 1
282 #endif
284 #define LOADER_DEBUG 0
285 #define LOADER_PROFILE 0
287 #if LOADER_DEBUG
288 extern BOOL debugging_on;
289 #endif
291 #if LOADER_DEBUG || LOADER_PROFILE
292 extern BOOL profiling_on;
293 #endif
295 #endif