0ca6a55e60bdb417f3a37cfff48852b483d321cc
[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 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"
50 /*---------------------------------------------------------------------------*/
51 /* DLIMP_Loaded_Segment                                                      */
52 /*                                                                           */
53 /*    This structure represents a segment loaded on memory.                  */
54 /*                                                                           */
55 /*    This data structure should be created using host memory when a module  */
56 /*    is being loaded into target memory.  The data structure should persist */
57 /*    as long as the module stays resident in target memory.  It should be   */
58 /*    removed when the last use of the module is unloaded from the target.   */
59 /*---------------------------------------------------------------------------*/
60 typedef struct
61 {
62    struct Elf32_Phdr            phdr;
63    Elf32_Addr                   input_vaddr;  /* original segment load addr  */
64    BOOL                         modified;
65    int32_t                      reloc_offset; /* used by load_program        */
66    struct DLOAD_MEMORY_SEGMENT *obj_desc;
67 } DLIMP_Loaded_Segment;
69 /*---------------------------------------------------------------------------*/
70 /* DLIMP_Section_Info                                                        */
71 /*                                                                           */
72 /*    This structure represents section info from ELF file.                  */
73 /*                                                                           */
74 /*    This data structure should be created using host memory when a module  */
75 /*    is being loaded into target memory.  The data structure should persist */
76 /*    as long as the module stays resident in target memory.  It should be   */
77 /*    removed when the last use of the module is unloaded from the target.   */
78 /*---------------------------------------------------------------------------*/
79 typedef struct
80 {
81    struct Elf32_Shdr            shdr;
82    char*                        sh_name;
83 } DLIMP_Section_Info;
85 /*---------------------------------------------------------------------------*/
86 /* DLIMP_Loaded_Module                                                       */
87 /*                                                                           */
88 /*    This structure contains all the information the dynamic loader needs   */
89 /*    to retain after loading an object file's segments into target memory.  */
90 /*    The data structure is created while the object file is being loaded,   */
91 /*    and should persist until the last use of the module is unloaded from   */
92 /*    target memory.                                                         */
93 /*                                                                           */
94 /*    The information contained here is used by the dynamic loader to        */
95 /*    perform dynamic symbol resolution, to track the use count, and to      */
96 /*    finally deallocate the module's segments when the module is unloaded.  */
97 /*---------------------------------------------------------------------------*/
98 typedef struct
99 {
100    char                *name;            /* Local copy of so_name           */
101    int32_t              file_handle;
102    int32_t              use_count;
103    Elf32_Addr           entry_point;     /* Entry point address into module */
104    struct Elf32_Sym    *gsymtab;         /* Module's global symbol table    */
105    Elf32_Word           gsymnum;         /* # global symbols                */
106    char                *gstrtab;         /* Module's global symbol names    */
107    Elf32_Word           gstrsz;          /* Size of global string table     */
108    Array_List           loaded_segments; /* List of DLIMP_Loaded_Segment(s) */
109    Array_List           sections;        /* List of DLIMP_Section_Info(s) */
110    Array_List           dependencies;    /* List of dependent file handles  */
111    BOOL                 direct_dependent_only;
113    Elf32_Addr           fini;            /* .fini function/section address  */
114    Elf32_Addr           fini_array;      /* .fini_array term fcn ary addr   */
115    int32_t              fini_arraysz;    /* sizeof .fini_array              */
117 } DLIMP_Loaded_Module;
119 /*---------------------------------------------------------------------------*/
120 /* DLIMP_loaded_objects                                                      */
121 /*                                                                           */
122 /*    A list of loaded module objects (DLIMP_Loaded_Module *) that the       */
123 /*    loader has placed into target memory.                                  */
124 /*---------------------------------------------------------------------------*/
125 TYPE_QUEUE_DEFINITION(DLIMP_Loaded_Module*, loaded_module_ptr)
127 /*---------------------------------------------------------------------------*/
128 /* DLIMP_Dynamic_Module                                                      */
129 /*                                                                           */
130 /*   This structure represents a dynamic module to be loaded by the dynamic  */
131 /*   loader. It contains all the information necessary to load and relocate  */
132 /*   the module. It actually contains most of the headers, dynamic info,     */
133 /*   dynamic symbol table, string table etc.                                 */
134 /*                                                                           */
135 /*   This structure is allocated in host memory while an ELF object file is  */
136 /*   being loaded and will be destructed after the file has been             */
137 /*   successfully loaded.  To simplify loading and relocation of the object  */
138 /*   file's segments, this data structure maintains a link to the loaded     */
139 /*   module.  This link is severed when the load is successfully completed.  */
140 /*   The loaded module data structure will persist until the module is       */
141 /*   actually unloaded from target memory, but this data structure will be   */
142 /*   freed.                                                                  */
143 /*                                                                           */
144 /*   If the load of the object file is not successful for any reason, then   */
145 /*   the loaded module will not be detached from the dynamic module.  In     */
146 /*   such case, the destructor for the dynamic module will assume            */
147 /*   responsibility for freeing any host memory associated with the loaded   */
148 /*   module and its segments.                                                */
149 /*---------------------------------------------------------------------------*/
150 typedef struct
152    char                *name;          /* Local copy of so_name              */
153    LOADER_FILE_DESC    *fd;            /* Access to ELF object file          */
154    struct Elf32_Ehdr    fhdr;          /* ELF Object File Header             */
155    struct Elf32_Phdr   *phdr;          /* ELF Program Header Table           */
156    Elf32_Word           phnum;         /* # entries in program header table  */
157    struct Elf32_Shdr   *shdr;          /* ELF Section Header Table (Optional)*/
158    Elf32_Word           shnum;         /* # entries in section header table  */
159    char*                shstrtab;      /* Section String Table               */
160    Elf32_Word           shstrsz;       /* String Table size in bytes         */
161    char*                strtab;        /* String Table                       */
162    Elf32_Word           strsz;         /* String Table size in bytes         */
163    struct Elf32_Dyn    *dyntab;        /* Elf Dynamic Table (.dynamic scn)   */
164                                        /* This contains a list of dynamic    */
165                                        /* tags which is terminated by a NULL */
166                                        /* record.                            */
167    struct Elf32_Sym    *symtab;        /* Elf Dynamic Symbol Table           */
168    Elf32_Word           symnum;        /* # symbols in dynamic symbol table  */
169    Elf32_Word           gsymtab_offset;/* Offset into symbol table where     */
170                                        /* global symbols start.              */
171    Elf32_Word           gstrtab_offset;/* Offset into string table where     */
172                                        /* global symbol names start.         */
174    uint8_t             *c_args;
175    int32_t              argc;
176    char               **argv;
177    DLIMP_Loaded_Module *loaded_module;
178    int32_t              wrong_endian;
179    BOOL                 direct_dependent_only;
180    BOOL                 relocatable;   /* TRUE if module can be relocated    */
181                                        /* at load-time.  FALSE if module is  */
182                                        /* a static executable.               */
183    BOOL                 relocate_entry_point; /* TRUE if the entry point has */
184                                               /* not been relocated          */
186    int32_t              dsbt_index;      /* DSBT index requested/assigned    */
187    uint32_t             dsbt_size;       /* DSBT size for this module        */
188    int32_t              dsbt_base_tagidx;/* Location of DSBT base dyn tag    */
190    int32_t              preinit_array_idx; /* DT_PREINIT_ARRAY dyn tag loc   */
191    int32_t              preinit_arraysz;   /* sizeof pre-init array          */
192    int32_t              init_idx;          /* DT_INIT dynamic tag location   */
193    int32_t              init_array_idx;    /* DT_INIT_ARRAY dyn tag location */
194    int32_t              init_arraysz;      /* sizeof init array              */
196 } DLIMP_Dynamic_Module;
198 /*---------------------------------------------------------------------------*/
199 /* DLIMP_dependency_stack                                                    */
200 /*                                                                           */
201 /*    A LIFO stack of dynamic module objects (DLIMP_Dynamic_Module *) that   */
202 /*    is retained while dependent files are being loaded and allocated.  It  */
203 /*    is used to guide which dynamic modules need to be relocated after all  */
204 /*    items in the dependency graph have been allocated. The stack is only   */
205 /*    used when the client asks the core loader to load a dynamic executable */
206 /*    or library. When relocation is completed, this stack should be empty.  */
207 /*---------------------------------------------------------------------------*/
208 TYPE_STACK_DEFINITION(DLIMP_Dynamic_Module*, dynamic_module_ptr)
210 /*---------------------------------------------------------------------------*/
211 /* Private Loader Object instance.                                           */
212 /*---------------------------------------------------------------------------*/
213 typedef struct
215     /*-----------------------------------------------------------------------*/
216     /* Contains filenames (type const char*) the system is in the process of */
217     /* loading.  Used to detect cycles in incorrectly compiled ELF binaries. */
218     /*-----------------------------------------------------------------------*/
219     Array_List               DLIMP_module_dependency_list;
221     /*-----------------------------------------------------------------------*/
222     /* Contains objects (type DLIMP_Loaded_Module) that the system has loaded*/
223     /* into target memory.                                                   */
224     /*-----------------------------------------------------------------------*/
225     loaded_module_ptr_Queue  DLIMP_loaded_objects;
227     /*-----------------------------------------------------------------------*/
228     /* Dependency Graph Queue - FIFO queue of dynamic modules that are loaded*/
229     /* when client asks to load a dynamic executable or library. Note that   */
230     /* dependents that have already been loaded with another module will not */
231     /* appear on this queue.                                                 */
232     /*-----------------------------------------------------------------------*/
233     dynamic_module_ptr_Stack DLIMP_dependency_stack;
235     /*-----------------------------------------------------------------------*/
236     /* Counter for generating unique IDs for file handles.                   */
237     /*   NOTE: File handle is assigned sequencially but is never reclaimed   */
238     /*         when the modules are unloaded. It is conceivable that a loader*/
239     /*         running for a long time and loading and unloading modules     */
240     /*         could wrap-around. The loader generates error in this case.   */
241     /*-----------------------------------------------------------------------*/
242     int32_t                  file_handle;
244     /*-----------------------------------------------------------------------*/
245     /* Identify target supported by this implementation of the core loader.  */
246     /*-----------------------------------------------------------------------*/
247     int                      DLOAD_TARGET_MACHINE;
249     /*-----------------------------------------------------------------------*/
250     /* Client token, passed in via DLOAD_create()                            */
251     /*-----------------------------------------------------------------------*/
252     void *                   client_handle;
253 } LOADER_OBJECT;
256 /*****************************************************************************/
257 /* is_DSBT_module()                                                          */
258 /*                                                                           */
259 /*   return true if the module uses DSBT model                               */
260 /*****************************************************************************/
261 static inline BOOL is_dsbt_module(DLIMP_Dynamic_Module *dyn_module)
263     return (dyn_module->dsbt_size != 0);
266 /*****************************************************************************/
267 /* is_arm_module()                                                           */
268 /*                                                                           */
269 /*    return true if the module being processed is for ARM                   */
270 /*****************************************************************************/
271 static inline BOOL is_arm_module(struct Elf32_Ehdr* fhdr)
273     return fhdr->e_machine == EM_ARM;
276 /*****************************************************************************/
277 /* is_c60_module()                                                           */
278 /*                                                                           */
279 /*   return true if the module being processed is for C60                    */
280 /*****************************************************************************/
281 static inline BOOL is_c60_module(struct Elf32_Ehdr* fhdr)
283     return fhdr->e_machine == EM_TI_C6000;
286 /*---------------------------------------------------------------------------*/
287 /* Identifies the current supported target.  This is reset by the default    */
288 /* value when all loaded objects have been unloaded.                         */
289 /*---------------------------------------------------------------------------*/
290 extern int DLOAD_TARGET_MACHINE;
292 /*---------------------------------------------------------------------------*/
293 /* Identify target which is supported by the core loader.  If set to EM_NONE */
294 /* the target will be determined by the first loaded module.                 */
295 /*---------------------------------------------------------------------------*/
296 #if defined(ARM_TARGET) && defined(C60_TARGET)
297 #define DLOAD_DEFAULT_TARGET_MACHINE  (EM_NONE)
298 #elif defined(ARM_TARGET)
299 #define DLOAD_DEFAULT_TARGET_MACHINE  (EM_ARM)
300 #elif defined(C60_TARGET)
301 #define DLOAD_DEFAULT_TARGET_MACHINE  (EM_TI_C6000)
302 #else
303 #error "ARM_TARGET and/or C60_TARGET must be defined"
304 #endif
306 /* =============================================================================
307  *  APIs
308  * =============================================================================
309  */
311 /*---------------------------------------------------------------------------*/
312 /* DLIMP_update_dyntag_section_address()                                     */
313 /*                                                                           */
314 /*    Given the index of a dynamic tag which we happen to know points to a   */
315 /*    section address, find the program header table entry associated with   */
316 /*    the specified address and update the tag value with the real address   */
317 /*    of the section.                                                        */
318 /*                                                                           */
319 /*---------------------------------------------------------------------------*/
320 extern BOOL DLIMP_update_dyntag_section_address(
321                                                DLIMP_Dynamic_Module *dyn_module,
322                                                 int32_t i);
324 extern uint32_t DLIMP_get_first_dyntag(int tag, struct Elf32_Dyn* dyn_table);
326 /*---------------------------------------------------------------------------*/
327 /* Global flags to help manage internal debug and profiling efforts.         */
328 /*---------------------------------------------------------------------------*/
329 #ifndef __TI_COMPILER_VERSION__
330 #define LOADER_DEBUG 1
331 #else
332 #define LOADER_DEBUG 0
333 #endif
335 #undef LOADER_DEBUG
337 #if !defined (__KERNEL__)
338 #define LOADER_DEBUG 1
339 #define LOADER_PROFILE 0
340 #else
341 // Leave LOADER_PROFILE == 0, otherwise time.h, cstdio.h pulled into Kernel!
342 #define LOADER_DEBUG 1
343 #define LOADER_PROFILE 0
344 #endif
346 #if LOADER_DEBUG
347 extern BOOL debugging_on;
348 #endif
350 #if LOADER_DEBUG && LOADER_PROFILE
351 extern BOOL profiling_on;
352 #endif
354 #endif