Update QNX IPC loader to RIDL 2.1.0
[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
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
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
253   TARGET_ADDRESS sect_addr;
254   int32_t size;
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)
275     return (dyn_module->dsbt_size != 0);
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)
285     return fhdr->e_machine == EM_ARM;
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)
295     return fhdr->e_machine == EM_TI_C6000;
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