Home | History | Annotate | Download | only in inc
      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