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 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the
18 * distribution.
19 *
20 * Neither the name of Texas Instruments Incorporated nor the names of
21 * its contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
38 #ifndef DLOAD_H
39 #define DLOAD_H
41 #include "ewrap.h"
43 #include "ArrayList.h"
44 /* #include "Queue.h" */
45 /* #include "Stack.h" */
46 #include "types.h"
47 #include "elf32.h"
48 #include "dload_api.h"
49 #include "util.h"
51 /*---------------------------------------------------------------------------*/
52 /* Contains strings with names of files the loader is in process of loading. */
53 /* This list is used to keep track of what objects are in the process of */
54 /* loading while their dependents are being loaded so that we can detect */
55 /* circular dependencies. */
56 /*---------------------------------------------------------------------------*/
57 #if 0
58 extern Array_List DLIMP_module_dependency_list;
59 #endif
61 /*---------------------------------------------------------------------------*/
62 /* DLIMP_Loaded_Segment */
63 /* */
64 /* This structure represents a segment loaded on memory. */
65 /* */
66 /* This data structure should be created using host memory when a module */
67 /* is being loaded into target memory. The data structure should persist */
68 /* as long as the module stays resident in target memory. It should be */
69 /* removed when the last use of the module is unloaded from the target. */
70 /*---------------------------------------------------------------------------*/
71 typedef struct
72 {
73 struct Elf32_Phdr phdr;
74 Elf32_Addr input_vaddr; /* original segment load addr */
75 BOOL modified;
76 int32_t reloc_offset; /* used by load_program */
77 struct DLOAD_MEMORY_SEGMENT *obj_desc;
78 } DLIMP_Loaded_Segment;
80 /*---------------------------------------------------------------------------*/
81 /* DLIMP_Loaded_Module */
82 /* */
83 /* This structure contains all the information the dynamic loader needs */
84 /* to retain after loading an object file's segments into target memory. */
85 /* The data structure is created while the object file is being loaded, */
86 /* and should persist until the last use of the module is unloaded from */
87 /* target memory. */
88 /* */
89 /* The information contained here is used by the dynamic loader to */
90 /* perform dynamic symbol resolution, to track the use count, and to */
91 /* finally deallocate the module's segments when the module is unloaded. */
92 /*---------------------------------------------------------------------------*/
93 typedef struct
94 {
95 char *name; /* Local copy of so_name */
96 int32_t file_handle;
97 int32_t use_count;
98 Elf32_Addr entry_point; /* Entry point address into module */
99 struct Elf32_Sym *gsymtab; /* Module's global symbol table */
100 Elf32_Word gsymnum; /* # global symbols */
101 char *gstrtab; /* Module's global symbol names */
102 Elf32_Word gstrsz; /* Size of global string table */
103 Array_List loaded_segments; /* List of DLIMP_Loaded_Segment(s) */
104 Array_List dependencies; /* List of dependent file handles */
105 BOOL direct_dependent_only;
107 Elf32_Addr fini; /* .fini function/section address */
108 Elf32_Addr fini_array; /* .fini_array term fcn ary addr */
109 int32_t fini_arraysz; /* sizeof .fini_array */
111 } DLIMP_Loaded_Module;
113 /*---------------------------------------------------------------------------*/
114 /* DLIMP_loaded_objects */
115 /* */
116 /* A list of loaded module objects (DLIMP_Loaded_Module *) that the */
117 /* loader has placed into target memory. */
118 /*---------------------------------------------------------------------------*/
119 #if 0
120 TYPE_QUEUE_DEFINITION(DLIMP_Loaded_Module*, loaded_module_ptr)
121 extern loaded_module_ptr_Queue DLIMP_loaded_objects;
122 #endif
124 /*---------------------------------------------------------------------------*/
125 /* DLIMP_Dynamic_Module */
126 /* */
127 /* This structure represents a dynamic module to be loaded by the dynamic */
128 /* loader. It contains all the information necessary to load and relocate */
129 /* the module. It actually contains most of the headers, dynamic info, */
130 /* dynamic symbol table, string table etc. */
131 /* */
132 /* This structure is allocated in host memory while an ELF object file is */
133 /* being loaded and will be destructed after the file has been */
134 /* successfully loaded. To simplify loading and relocation of the object */
135 /* file's segments, this data structure maintains a link to the loaded */
136 /* module. This link is severed when the load is successfully completed. */
137 /* The loaded module data structure will persist until the module is */
138 /* actually unloaded from target memory, but this data structure will be */
139 /* freed. */
140 /* */
141 /* If the load of the object file is not successful for any reason, then */
142 /* the loaded module will not be detached from the dynamic module. In */
143 /* such case, the destructor for the dynamic module will assume */
144 /* responsibility for freeing any host memory associated with the loaded */
145 /* module and its segments. */
146 /*---------------------------------------------------------------------------*/
147 typedef struct
148 {
149 char *name; /* Local copy of so_name */
150 LOADER_FILE_DESC *fd; /* Access to ELF object file */
151 struct Elf32_Ehdr fhdr; /* ELF Object File Header */
152 struct Elf32_Phdr *phdr; /* ELF Program Header Table */
153 Elf32_Word phnum; /* # entries in program header table */
154 char* strtab; /* String Table */
155 Elf32_Word strsz; /* String Table size in bytes */
156 struct Elf32_Dyn *dyntab; /* Elf Dynamic Table (.dynamic scn) */
157 /* This contains a list of dynamic */
158 /* tags which is terminated by a NULL */
159 /* record. */
160 struct Elf32_Sym *symtab; /* Elf Dynamic Symbol Table */
161 Elf32_Word symnum; /* # symbols in dynamic symbol table */
162 Elf32_Word gsymtab_offset;/* Offset into symbol table where */
163 /* global symbols start. */
164 Elf32_Word gstrtab_offset;/* Offset into string table where */
165 /* global symbol names start. */
167 uint8_t *c_args;
168 int32_t argc;
169 char **argv;
170 DLIMP_Loaded_Module *loaded_module;
171 int32_t wrong_endian;
172 BOOL direct_dependent_only;
173 BOOL relocatable; /* TRUE if module can be relocated */
174 /* at load-time. FALSE if module is */
175 /* a static executable. */
176 BOOL relocate_entry_point; /* TRUE if the entry point has */
177 /* not been relocated */
179 int32_t dsbt_index; /* DSBT index requested/assigned */
180 uint32_t dsbt_size; /* DSBT size for this module */
181 int32_t dsbt_base_tagidx;/* Location of DSBT base dyn tag */
183 int32_t preinit_array_idx; /* DT_PREINIT_ARRAY dyn tag loc */
184 int32_t preinit_arraysz; /* sizeof pre-init array */
185 int32_t init_idx; /* DT_INIT dynamic tag location */
186 int32_t init_array_idx; /* DT_INIT_ARRAY dyn tag location */
187 int32_t init_arraysz; /* sizeof init array */
189 } DLIMP_Dynamic_Module;
191 /*---------------------------------------------------------------------------*/
192 /* DLIMP_dependency_stack */
193 /* */
194 /* A LIFO stack of dynamic module objects (DLIMP_Dynamic_Module *) that */
195 /* is retained while dependent files are being loaded and allocated. It */
196 /* is used to guide which dynamic modules need to be relocated after all */
197 /* items in the dependency graph have been allocated. The stack is only */
198 /* used when the client asks the core loader to load a dynamic executable */
199 /* or library. When relocation is completed, this stack should be empty. */
200 /*---------------------------------------------------------------------------*/
201 TYPE_STACK_DEFINITION(DLIMP_Dynamic_Module*, dynamic_module_ptr)
202 #if 0
203 extern dynamic_module_ptr_Stack DLIMP_dependency_stack;
204 #endif
206 /*****************************************************************************/
207 /* is_DSBT_module() */
208 /* */
209 /* return true if the module uses DSBT model */
210 /*****************************************************************************/
211 static inline BOOL is_dsbt_module(DLIMP_Dynamic_Module *dyn_module)
212 {
213 return (dyn_module->dsbt_size != 0);
214 }
216 /*****************************************************************************/
217 /* is_arm_module() */
218 /* */
219 /* return true if the module being processed is for ARM */
220 /*****************************************************************************/
221 static inline BOOL is_arm_module(struct Elf32_Ehdr* fhdr)
222 {
223 return fhdr->e_machine == EM_ARM;
224 }
226 /*****************************************************************************/
227 /* is_c60_module() */
228 /* */
229 /* return true if the module being processed is for C60 */
230 /*****************************************************************************/
231 static inline BOOL is_c60_module(struct Elf32_Ehdr* fhdr)
232 {
233 return fhdr->e_machine == EM_TI_C6000;
234 }
236 /*---------------------------------------------------------------------------*/
237 /* Identifies the current supported target. This is reset by the default */
238 /* value when all loaded objects have been unloaded. */
239 /*---------------------------------------------------------------------------*/
240 extern int DLOAD_TARGET_MACHINE;
242 /*---------------------------------------------------------------------------*/
243 /* Identify target which is supported by the core loader. If set to EM_NONE */
244 /* the target will be determined by the first loaded module. */
245 /*---------------------------------------------------------------------------*/
246 #if defined(ARM_TARGET) && defined(C60_TARGET)
247 #define DLOAD_DEFAULT_TARGET_MACHINE (EM_NONE)
248 #elif defined(ARM_TARGET)
249 #define DLOAD_DEFAULT_TARGET_MACHINE (EM_ARM)
250 #elif defined(C60_TARGET)
251 #define DLOAD_DEFAULT_TARGET_MACHINE (EM_TI_C6000)
252 #else
253 #error "ARM_TARGET and/or C60_TARGET must be defined"
254 #endif
256 /*---------------------------------------------------------------------------*/
257 /* DLIMP_update_dyntag_section_address() */
258 /* */
259 /* Given the index of a dynamic tag which we happen to know points to a */
260 /* section address, find the program header table entry associated with */
261 /* the specified address and update the tag value with the real address */
262 /* of the section. */
263 /* */
264 /*---------------------------------------------------------------------------*/
265 extern BOOL DLIMP_update_dyntag_section_address(DLIMP_Dynamic_Module *dyn_module,
266 int32_t i);
268 /*---------------------------------------------------------------------------*/
269 /* Global flags to help manage internal debug and profiling efforts. */
270 /*---------------------------------------------------------------------------*/
271 #if 0
272 #ifndef __TI_COMPILER_VERSION__
273 #define LOADER_DEBUG 1
274 #else
275 #define LOADER_DEBUG 0
276 #endif
278 #undef LOADER_DEBUG
279 #define LOADER_DEBUG 1
280 #define LOADER_PROFILE 1
281 #endif
283 #define LOADER_DEBUG 0
284 #define LOADER_PROFILE 0
286 #if LOADER_DEBUG
287 extern BOOL debugging_on;
288 #endif
290 #if LOADER_DEBUG || LOADER_PROFILE
291 extern BOOL profiling_on;
292 #endif
294 #endif