1 /* 2 * Copyright 2001-2008 Texas Instruments - http://www.ti.com/ 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 19 #ifndef _DYNAMIC_LOADER_H_ 20 #define _DYNAMIC_LOADER_H_ 21 #include <stdarg.h> 22 #ifndef __KERNEL__ 23 #include <stdint.h> 24 #else 25 #include <linux/types.h> 26 #endif 27 28 #ifdef __cplusplus 29 extern "C" { /* C-only version */ 30 #endif 31 32 /* Optional optimization defines */ 33 #define OPT_ELIMINATE_EXTRA_DLOAD 1 34 /* #define OPT_ZERO_COPY_LOADER 1 */ 35 36 37 /* 38 * Dynamic Loader 39 * 40 * The function of the dynamic loader is to load a "module" containing 41 * instructions 42 * for a "target" processor into that processor. In the process it assigns 43 * memory 44 * for the module, resolves symbol references made by the module, and remembers 45 * symbols defined by the module. 46 * 47 * The dynamic loader is parameterized for a particular system by 4 classes 48 * that supply 49 * the module and system specific functions it requires 50 */ 51 /* The read functions for the module image to be loaded */ 52 struct Dynamic_Loader_Stream; 53 /*typedef struct Dynamic_Loader_Stream Dynamic_Loader_Stream;*/ 54 55 /* This class defines "host" symbol and support functions */ 56 struct Dynamic_Loader_Sym; 57 /*typedef struct Dynamic_Loader_Sym Dynamic_Loader_Sym;*/ 58 59 /* This class defines the allocator for "target" memory */ 60 struct Dynamic_Loader_Allocate; 61 /*typedef struct Dynamic_Loader_Allocate Dynamic_Loader_Allocate;*/ 62 63 /* This class defines the copy-into-target-memory functions */ 64 struct Dynamic_Loader_Initialize; 65 /*typedef struct Dynamic_Loader_Initialize Dynamic_Loader_Initialize;*/ 66 67 /* 68 * Option flags to modify the behavior of module loading 69 */ 70 #define DLOAD_INITBSS 0x1 /* initialize BSS sections to zero */ 71 #define DLOAD_BIGEND 0x2 /* require big-endian load module */ 72 #define DLOAD_LITTLE 0x4 /* require little-endian load module */ 73 74 typedef void *DLOAD_mhandle; /* module handle for loaded modules */ 75 76 /***************************************************************************** 77 * Procedure Dynamic_Load_Module 78 * 79 * Parameters: 80 * module The input stream that supplies the module image 81 * syms Host-side symbol table and malloc/free functions 82 * alloc Target-side memory allocation 83 * init Target-side memory initialization, or NULL for symbol read only 84 * options Option flags DLOAD_* 85 * mhandle A module handle for use with Dynamic_Unload 86 * 87 * Effect: 88 * The module image is read using *module. Target storage for the new image is 89 * obtained from *alloc. Symbols defined and referenced by the module are 90 * managed using *syms. The image is then relocated and references resolved 91 * as necessary, and the resulting executable bits are placed into target memory 92 * using *init. 93 * 94 * Returns: 95 * On a successful load, a module handle is placed in *mhandle, and zero is 96 * returned. On error, the number of errors detected is returned. Individual 97 * errors are reported during the load process using syms->Error_Report(). 98 *****************************************************************************/ 99 extern int Dynamic_Load_Module( 100 /* the source for the module image*/ 101 struct Dynamic_Loader_Stream * module, 102 /* host support for symbols and storage*/ 103 struct Dynamic_Loader_Sym * syms, 104 /* the target memory allocator*/ 105 struct Dynamic_Loader_Allocate * alloc, 106 /* the target memory initializer*/ 107 struct Dynamic_Loader_Initialize * init, 108 unsigned options, /* option flags*/ 109 DLOAD_mhandle * mhandle /* the returned module handle*/ 110 ); 111 112 #ifdef OPT_ELIMINATE_EXTRA_DLOAD 113 /***************************************************************************** 114 * Procedure Dynamic_Open_Module 115 * 116 * Parameters: 117 * module The input stream that supplies the module image 118 * syms Host-side symbol table and malloc/free functions 119 * alloc Target-side memory allocation 120 * init Target-side memory initialization, or NULL for symbol read only 121 * options Option flags DLOAD_* 122 * mhandle A module handle for use with Dynamic_Unload 123 * 124 * Effect: 125 * The module image is read using *module. Target storage for the new image is 126 * obtained from *alloc. Symbols defined and referenced by the module are 127 * managed using *syms. The image is then relocated and references resolved 128 * as necessary, and the resulting executable bits are placed into target memory 129 * using *init. 130 * 131 * Returns: 132 * On a successful load, a module handle is placed in *mhandle, and zero is 133 * returned. On error, the number of errors detected is returned. Individual 134 * errors are reported during the load process using syms->Error_Report(). 135 *****************************************************************************/ 136 extern int Dynamic_Open_Module(struct Dynamic_Loader_Stream * module, // the source for the module image 137 struct Dynamic_Loader_Sym * syms, // host support for symbols and storage 138 struct Dynamic_Loader_Allocate * alloc, // the target memory allocator 139 struct Dynamic_Loader_Initialize * init, // the target memory initializer 140 unsigned options, // option flags 141 DLOAD_mhandle * mhandle // the returned module handle 142 ); 143 #endif 144 145 /***************************************************************************** 146 * Procedure Dynamic_Unload_Module 147 * 148 * Parameters: 149 * mhandle A module handle from Dynamic_Load_Module 150 * syms Host-side symbol table and malloc/free functions 151 * alloc Target-side memory allocation 152 * 153 * Effect: 154 * The module specified by mhandle is unloaded. Unloading causes all 155 * target memory to be deallocated, all symbols defined by the module to 156 * be purged, and any host-side storage used by the dynamic loader for 157 * this module to be released. 158 * 159 * Returns: 160 * Zero for success. On error, the number of errors detected is returned. 161 * Individual errors are reported using syms->Error_Report(). 162 *****************************************************************************/ 163 extern int Dynamic_Unload_Module(DLOAD_mhandle mhandle, /* the module 164 handle*/ 165 /* host support for symbols and storage*/ 166 struct Dynamic_Loader_Sym * syms, 167 /* the target memory allocator*/ 168 struct Dynamic_Loader_Allocate * alloc, 169 /* the target memory initializer*/ 170 struct Dynamic_Loader_Initialize * init 171 ); 172 173 /***************************************************************************** 174 ***************************************************************************** 175 * A class used by the dynamic loader for input of the module image 176 ***************************************************************************** 177 *****************************************************************************/ 178 struct Dynamic_Loader_Stream { 179 /* public: */ 180 /************************************************************************* 181 * read_buffer 182 * 183 * PARAMETERS : 184 * buffer Pointer to the buffer to fill 185 * bufsiz Amount of data desired in sizeof() units 186 * 187 * EFFECT : 188 * Reads the specified amount of data from the module input stream 189 * into the specified buffer. Returns the amount of data read in sizeof() 190 * units (which if less than the specification, represents an error). 191 * 192 * NOTES: 193 * In release 1 increments the file position by the number of bytes read 194 * 195 *************************************************************************/ 196 int (*read_buffer) (struct Dynamic_Loader_Stream * thisptr, 197 void *buffer, unsigned bufsiz); 198 199 /************************************************************************* 200 * set_file_posn (release 1 only) 201 * 202 * PARAMETERS : 203 * posn Desired file position relative to start of file in sizeof() units. 204 * 205 * EFFECT : 206 * Adjusts the internal state of the stream object so that the next 207 * read_buffer call will begin to read at the specified offset from 208 * the beginning of the input module. Returns 0 for success, non-zero 209 * for failure. 210 * 211 *************************************************************************/ 212 int (*set_file_posn) (struct Dynamic_Loader_Stream * thisptr, 213 unsigned int posn); /* to be eliminated in release 2*/ 214 215 }; 216 217 /***************************************************************************** 218 ***************************************************************************** 219 * A class used by the dynamic loader for symbol table support and 220 * miscellaneous host-side functions 221 ***************************************************************************** 222 *****************************************************************************/ 223 #ifndef __KERNEL__ 224 typedef uint32_t LDR_ADDR; 225 #else 226 typedef u32 LDR_ADDR; 227 #endif 228 229 /* 230 * the structure of a symbol known to the dynamic loader 231 */ 232 struct dynload_symbol { 233 LDR_ADDR value; 234 } ; 235 236 struct Dynamic_Loader_Sym { 237 /* public: */ 238 /************************************************************************* 239 * Find_Matching_Symbol 240 * 241 * PARAMETERS : 242 * name The name of the desired symbol 243 * 244 * EFFECT : 245 * Locates a symbol matching the name specified. A pointer to the 246 * symbol is returned if it exists; 0 is returned if no such symbol is 247 * found. 248 * 249 *************************************************************************/ 250 struct dynload_symbol *(*Find_Matching_Symbol) 251 (struct Dynamic_Loader_Sym * 252 thisptr, 253 const char *name); 254 255 /************************************************************************* 256 * Add_To_Symbol_Table 257 * 258 * PARAMETERS : 259 * nname Pointer to the name of the new symbol 260 * moduleid An opaque module id assigned by the dynamic loader 261 * 262 * EFFECT : 263 * The new symbol is added to the table. A pointer to the symbol is 264 * returned, or NULL is returned for failure. 265 * 266 * NOTES: 267 * It is permissible for this function to return NULL; the effect is that 268 * the named symbol will not be available to resolve references in 269 * subsequent loads. Returning NULL will not cause the current load 270 * to fail. 271 *************************************************************************/ 272 struct dynload_symbol *(*Add_To_Symbol_Table) 273 (struct Dynamic_Loader_Sym * 274 thisptr, 275 const char *nname, 276 unsigned moduleid); 277 278 /************************************************************************* 279 * Purge_Symbol_Table 280 * 281 * PARAMETERS : 282 * moduleid An opaque module id assigned by the dynamic loader 283 * 284 * EFFECT : 285 * Each symbol in the symbol table whose moduleid matches the argument 286 * is removed from the table. 287 *************************************************************************/ 288 void (*Purge_Symbol_Table) (struct Dynamic_Loader_Sym * thisptr, 289 unsigned moduleid); 290 291 /************************************************************************* 292 * Allocate 293 * 294 * PARAMETERS : 295 * memsiz size of desired memory in sizeof() units 296 * 297 * EFFECT : 298 * Returns a pointer to some "host" memory for use by the dynamic 299 * loader, or NULL for failure. 300 * This function is serves as a replaceable form of "malloc" to 301 * allow the user to configure the memory usage of the dynamic loader. 302 *************************************************************************/ 303 void *(*Allocate) (struct Dynamic_Loader_Sym * thisptr, 304 unsigned memsiz); 305 306 /************************************************************************* 307 * Deallocate 308 * 309 * PARAMETERS : 310 * memptr pointer to previously allocated memory 311 * 312 * EFFECT : 313 * Releases the previously allocated "host" memory. 314 *************************************************************************/ 315 void (*Deallocate) (struct Dynamic_Loader_Sym * thisptr, void *memptr); 316 317 /************************************************************************* 318 * Error_Report 319 * 320 * PARAMETERS : 321 * errstr pointer to an error string 322 * args additional arguments 323 * 324 * EFFECT : 325 * This function provides an error reporting interface for the dynamic 326 * loader. The error string and arguments are designed as for the 327 * library function vprintf. 328 *************************************************************************/ 329 void (*Error_Report) (struct Dynamic_Loader_Sym * thisptr, 330 const char *errstr, va_list args); 331 332 }; /* class Dynamic_Loader_Sym */ 333 334 /***************************************************************************** 335 ***************************************************************************** 336 * A class used by the dynamic loader to allocate and deallocate target memory. 337 ***************************************************************************** 338 *****************************************************************************/ 339 340 struct LDR_SECTION_INFO { 341 /* Name of the memory section assigned at build time */ 342 const char *name; 343 LDR_ADDR run_addr; /* execution address of the section */ 344 LDR_ADDR load_addr; /* load address of the section */ 345 LDR_ADDR size; /* size of the section in addressable units */ 346 /* #ifndef _BIG_ENDIAN *//* _BIG_ENDIAN Not defined by bridge driver */ 347 #ifdef __KERNEL__ 348 u16 page; /* memory page or view */ 349 u16 type; /* one of the section types below */ 350 #else 351 uint16_t page; /* memory page or view */ 352 uint16_t type; /* one of the section types below */ 353 #endif 354 /*#else 355 #ifdef __KERNEL__ 356 u16 type;*/ /* one of the section types below */ 357 /* u16 page;*/ /* memory page or view */ 358 /*#else 359 uint16_t type;*//* one of the section types below */ 360 /* uint16_t page;*//* memory page or view */ 361 /*#endif 362 #endif*//* _BIG_ENDIAN Not defined by bridge driver */ 363 /* a context field for use by Dynamic_Loader_Allocate; 364 ignored but maintained by the dynamic loader */ 365 #ifdef __KERNEL__ 366 u32 context; 367 #else 368 uintptr_t context; 369 #endif 370 } ; 371 372 /* use this macro to extract type of section from LDR_SECTION_INFO.type field */ 373 #define DLOAD_SECTION_TYPE(typeinfo) (typeinfo & 0xF) 374 375 /* type of section to be allocated */ 376 #define DLOAD_TEXT 0 377 #define DLOAD_DATA 1 378 #define DLOAD_BSS 2 379 /* internal use only, run-time cinit will be of type DLOAD_DATA */ 380 #define DLOAD_CINIT 3 381 382 struct Dynamic_Loader_Allocate { 383 /* public: */ 384 385 /************************************************************************* 386 * Function allocate 387 * 388 * Parameters: 389 * info A pointer to an information block for the section 390 * align The alignment of the storage in target AUs 391 * 392 * Effect: 393 * Allocates target memory for the specified section and fills in the 394 * load_addr and run_addr fields of the section info structure. Returns TRUE 395 * for success, FALSE for failure. 396 * 397 * Notes: 398 * Frequently load_addr and run_addr are the same, but if they are not 399 * load_addr is used with Dynamic_Loader_Initialize, and run_addr is 400 * used for almost all relocations. This function should always initialize 401 * both fields. 402 *************************************************************************/ 403 int (*Allocate) (struct Dynamic_Loader_Allocate * thisptr, 404 struct LDR_SECTION_INFO * info, unsigned align); 405 406 /************************************************************************* 407 * Function deallocate 408 * 409 * Parameters: 410 * info A pointer to an information block for the section 411 * 412 * Effect: 413 * Releases the target memory previously allocated. 414 * 415 * Notes: 416 * The content of the info->name field is undefined on call to this function. 417 *************************************************************************/ 418 void (*Deallocate) (struct Dynamic_Loader_Allocate * thisptr, 419 struct LDR_SECTION_INFO * info); 420 421 }; /* class Dynamic_Loader_Allocate */ 422 423 /***************************************************************************** 424 ***************************************************************************** 425 * A class used by the dynamic loader to load data into a target. This class 426 * provides the interface-specific functions needed to load data. 427 ***************************************************************************** 428 *****************************************************************************/ 429 430 struct Dynamic_Loader_Initialize { 431 /* public: */ 432 /************************************************************************* 433 * Function connect 434 * 435 * Parameters: 436 * none 437 * 438 * Effect: 439 * Connect to the initialization interface. Returns TRUE for success, 440 * FALSE for failure. 441 * 442 * Notes: 443 * This function is called prior to use of any other functions in 444 * this interface. 445 *************************************************************************/ 446 int (*connect) (struct Dynamic_Loader_Initialize * thisptr); 447 448 /************************************************************************* 449 * Function readmem 450 * 451 * Parameters: 452 * bufr Pointer to a word-aligned buffer for the result 453 * locn Target address of first data element 454 * info Section info for the section in which the address resides 455 * bytsiz Size of the data to be read in sizeof() units 456 * 457 * Effect: 458 * Fills the specified buffer with data from the target. Returns TRUE for 459 * success, FALSE for failure. 460 *************************************************************************/ 461 int (*readmem) (struct Dynamic_Loader_Initialize * thisptr, void *bufr, 462 LDR_ADDR locn, struct LDR_SECTION_INFO * info, 463 unsigned bytsiz); 464 465 /************************************************************************* 466 * Function writemem 467 * 468 * Parameters: 469 * bufr Pointer to a word-aligned buffer of data 470 * locn Target address of first data element to be written 471 * info Section info for the section in which the address resides 472 * bytsiz Size of the data to be written in sizeof() units 473 * 474 * Effect: 475 * Writes the specified buffer to the target. Returns TRUE for success, 476 * FALSE for failure. 477 *************************************************************************/ 478 int (*writemem) (struct Dynamic_Loader_Initialize * thisptr, 479 void *bufr, LDR_ADDR locn, 480 struct LDR_SECTION_INFO * info, unsigned bytsiz); 481 482 /************************************************************************* 483 * Function fillmem 484 * 485 * Parameters: 486 * locn Target address of first data element to be written 487 * info Section info for the section in which the address resides 488 * bytsiz Size of the data to be written in sizeof() units 489 * val Value to be written in each byte 490 * Effect: 491 * Fills the specified area of target memory. Returns TRUE for success, 492 * FALSE for failure. 493 *************************************************************************/ 494 int (*fillmem) (struct Dynamic_Loader_Initialize * thisptr, 495 LDR_ADDR locn, struct LDR_SECTION_INFO * info, 496 unsigned bytsiz, unsigned val); 497 498 /************************************************************************* 499 * Function execute 500 * 501 * Parameters: 502 * start Starting address 503 * 504 * Effect: 505 * The target code at the specified starting address is executed. 506 * 507 * Notes: 508 * This function is called at the end of the dynamic load process 509 * if the input module has specified a starting address. 510 *************************************************************************/ 511 int (*execute) (struct Dynamic_Loader_Initialize * thisptr, 512 LDR_ADDR start); 513 514 /************************************************************************* 515 * Function release 516 * 517 * Parameters: 518 * none 519 * 520 * Effect: 521 * Releases the connection to the load interface. 522 * 523 * Notes: 524 * This function is called at the end of the dynamic load process. 525 *************************************************************************/ 526 void (*release) (struct Dynamic_Loader_Initialize * thisptr); 527 528 }; /* class Dynamic_Loader_Initialize */ 529 #ifdef __cplusplus 530 } 531 #endif 532 #endif /* _DYNAMIC_LOADER_H_ */ 533 534