/* * Copyright 2001-2008 Texas Instruments - http://www.ti.com/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _DYNAMIC_LOADER_H_ #define _DYNAMIC_LOADER_H_ #include <stdarg.h> #ifndef __KERNEL__ #include <stdint.h> #else #include <linux/types.h> #endif #ifdef __cplusplus extern "C" { /* C-only version */ #endif /* Optional optimization defines */ #define OPT_ELIMINATE_EXTRA_DLOAD 1 /* #define OPT_ZERO_COPY_LOADER 1 */ /* * Dynamic Loader * * The function of the dynamic loader is to load a "module" containing * instructions * for a "target" processor into that processor. In the process it assigns * memory * for the module, resolves symbol references made by the module, and remembers * symbols defined by the module. * * The dynamic loader is parameterized for a particular system by 4 classes * that supply * the module and system specific functions it requires */ /* The read functions for the module image to be loaded */ struct Dynamic_Loader_Stream; /*typedef struct Dynamic_Loader_Stream Dynamic_Loader_Stream;*/ /* This class defines "host" symbol and support functions */ struct Dynamic_Loader_Sym; /*typedef struct Dynamic_Loader_Sym Dynamic_Loader_Sym;*/ /* This class defines the allocator for "target" memory */ struct Dynamic_Loader_Allocate; /*typedef struct Dynamic_Loader_Allocate Dynamic_Loader_Allocate;*/ /* This class defines the copy-into-target-memory functions */ struct Dynamic_Loader_Initialize; /*typedef struct Dynamic_Loader_Initialize Dynamic_Loader_Initialize;*/ /* * Option flags to modify the behavior of module loading */ #define DLOAD_INITBSS 0x1 /* initialize BSS sections to zero */ #define DLOAD_BIGEND 0x2 /* require big-endian load module */ #define DLOAD_LITTLE 0x4 /* require little-endian load module */ typedef void *DLOAD_mhandle; /* module handle for loaded modules */ /***************************************************************************** * Procedure Dynamic_Load_Module * * Parameters: * module The input stream that supplies the module image * syms Host-side symbol table and malloc/free functions * alloc Target-side memory allocation * init Target-side memory initialization, or NULL for symbol read only * options Option flags DLOAD_* * mhandle A module handle for use with Dynamic_Unload * * Effect: * The module image is read using *module. Target storage for the new image is * obtained from *alloc. Symbols defined and referenced by the module are * managed using *syms. The image is then relocated and references resolved * as necessary, and the resulting executable bits are placed into target memory * using *init. * * Returns: * On a successful load, a module handle is placed in *mhandle, and zero is * returned. On error, the number of errors detected is returned. Individual * errors are reported during the load process using syms->Error_Report(). *****************************************************************************/ extern int Dynamic_Load_Module( /* the source for the module image*/ struct Dynamic_Loader_Stream * module, /* host support for symbols and storage*/ struct Dynamic_Loader_Sym * syms, /* the target memory allocator*/ struct Dynamic_Loader_Allocate * alloc, /* the target memory initializer*/ struct Dynamic_Loader_Initialize * init, unsigned options, /* option flags*/ DLOAD_mhandle * mhandle /* the returned module handle*/ ); #ifdef OPT_ELIMINATE_EXTRA_DLOAD /***************************************************************************** * Procedure Dynamic_Open_Module * * Parameters: * module The input stream that supplies the module image * syms Host-side symbol table and malloc/free functions * alloc Target-side memory allocation * init Target-side memory initialization, or NULL for symbol read only * options Option flags DLOAD_* * mhandle A module handle for use with Dynamic_Unload * * Effect: * The module image is read using *module. Target storage for the new image is * obtained from *alloc. Symbols defined and referenced by the module are * managed using *syms. The image is then relocated and references resolved * as necessary, and the resulting executable bits are placed into target memory * using *init. * * Returns: * On a successful load, a module handle is placed in *mhandle, and zero is * returned. On error, the number of errors detected is returned. Individual * errors are reported during the load process using syms->Error_Report(). *****************************************************************************/ extern int Dynamic_Open_Module(struct Dynamic_Loader_Stream * module, // the source for the module image struct Dynamic_Loader_Sym * syms, // host support for symbols and storage struct Dynamic_Loader_Allocate * alloc, // the target memory allocator struct Dynamic_Loader_Initialize * init, // the target memory initializer unsigned options, // option flags DLOAD_mhandle * mhandle // the returned module handle ); #endif /***************************************************************************** * Procedure Dynamic_Unload_Module * * Parameters: * mhandle A module handle from Dynamic_Load_Module * syms Host-side symbol table and malloc/free functions * alloc Target-side memory allocation * * Effect: * The module specified by mhandle is unloaded. Unloading causes all * target memory to be deallocated, all symbols defined by the module to * be purged, and any host-side storage used by the dynamic loader for * this module to be released. * * Returns: * Zero for success. On error, the number of errors detected is returned. * Individual errors are reported using syms->Error_Report(). *****************************************************************************/ extern int Dynamic_Unload_Module(DLOAD_mhandle mhandle, /* the module handle*/ /* host support for symbols and storage*/ struct Dynamic_Loader_Sym * syms, /* the target memory allocator*/ struct Dynamic_Loader_Allocate * alloc, /* the target memory initializer*/ struct Dynamic_Loader_Initialize * init ); /***************************************************************************** ***************************************************************************** * A class used by the dynamic loader for input of the module image ***************************************************************************** *****************************************************************************/ struct Dynamic_Loader_Stream { /* public: */ /************************************************************************* * read_buffer * * PARAMETERS : * buffer Pointer to the buffer to fill * bufsiz Amount of data desired in sizeof() units * * EFFECT : * Reads the specified amount of data from the module input stream * into the specified buffer. Returns the amount of data read in sizeof() * units (which if less than the specification, represents an error). * * NOTES: * In release 1 increments the file position by the number of bytes read * *************************************************************************/ int (*read_buffer) (struct Dynamic_Loader_Stream * thisptr, void *buffer, unsigned bufsiz); /************************************************************************* * set_file_posn (release 1 only) * * PARAMETERS : * posn Desired file position relative to start of file in sizeof() units. * * EFFECT : * Adjusts the internal state of the stream object so that the next * read_buffer call will begin to read at the specified offset from * the beginning of the input module. Returns 0 for success, non-zero * for failure. * *************************************************************************/ int (*set_file_posn) (struct Dynamic_Loader_Stream * thisptr, unsigned int posn); /* to be eliminated in release 2*/ }; /***************************************************************************** ***************************************************************************** * A class used by the dynamic loader for symbol table support and * miscellaneous host-side functions ***************************************************************************** *****************************************************************************/ #ifndef __KERNEL__ typedef uint32_t LDR_ADDR; #else typedef u32 LDR_ADDR; #endif /* * the structure of a symbol known to the dynamic loader */ struct dynload_symbol { LDR_ADDR value; } ; struct Dynamic_Loader_Sym { /* public: */ /************************************************************************* * Find_Matching_Symbol * * PARAMETERS : * name The name of the desired symbol * * EFFECT : * Locates a symbol matching the name specified. A pointer to the * symbol is returned if it exists; 0 is returned if no such symbol is * found. * *************************************************************************/ struct dynload_symbol *(*Find_Matching_Symbol) (struct Dynamic_Loader_Sym * thisptr, const char *name); /************************************************************************* * Add_To_Symbol_Table * * PARAMETERS : * nname Pointer to the name of the new symbol * moduleid An opaque module id assigned by the dynamic loader * * EFFECT : * The new symbol is added to the table. A pointer to the symbol is * returned, or NULL is returned for failure. * * NOTES: * It is permissible for this function to return NULL; the effect is that * the named symbol will not be available to resolve references in * subsequent loads. Returning NULL will not cause the current load * to fail. *************************************************************************/ struct dynload_symbol *(*Add_To_Symbol_Table) (struct Dynamic_Loader_Sym * thisptr, const char *nname, unsigned moduleid); /************************************************************************* * Purge_Symbol_Table * * PARAMETERS : * moduleid An opaque module id assigned by the dynamic loader * * EFFECT : * Each symbol in the symbol table whose moduleid matches the argument * is removed from the table. *************************************************************************/ void (*Purge_Symbol_Table) (struct Dynamic_Loader_Sym * thisptr, unsigned moduleid); /************************************************************************* * Allocate * * PARAMETERS : * memsiz size of desired memory in sizeof() units * * EFFECT : * Returns a pointer to some "host" memory for use by the dynamic * loader, or NULL for failure. * This function is serves as a replaceable form of "malloc" to * allow the user to configure the memory usage of the dynamic loader. *************************************************************************/ void *(*Allocate) (struct Dynamic_Loader_Sym * thisptr, unsigned memsiz); /************************************************************************* * Deallocate * * PARAMETERS : * memptr pointer to previously allocated memory * * EFFECT : * Releases the previously allocated "host" memory. *************************************************************************/ void (*Deallocate) (struct Dynamic_Loader_Sym * thisptr, void *memptr); /************************************************************************* * Error_Report * * PARAMETERS : * errstr pointer to an error string * args additional arguments * * EFFECT : * This function provides an error reporting interface for the dynamic * loader. The error string and arguments are designed as for the * library function vprintf. *************************************************************************/ void (*Error_Report) (struct Dynamic_Loader_Sym * thisptr, const char *errstr, va_list args); }; /* class Dynamic_Loader_Sym */ /***************************************************************************** ***************************************************************************** * A class used by the dynamic loader to allocate and deallocate target memory. ***************************************************************************** *****************************************************************************/ struct LDR_SECTION_INFO { /* Name of the memory section assigned at build time */ const char *name; LDR_ADDR run_addr; /* execution address of the section */ LDR_ADDR load_addr; /* load address of the section */ LDR_ADDR size; /* size of the section in addressable units */ /* #ifndef _BIG_ENDIAN *//* _BIG_ENDIAN Not defined by bridge driver */ #ifdef __KERNEL__ u16 page; /* memory page or view */ u16 type; /* one of the section types below */ #else uint16_t page; /* memory page or view */ uint16_t type; /* one of the section types below */ #endif /*#else #ifdef __KERNEL__ u16 type;*/ /* one of the section types below */ /* u16 page;*/ /* memory page or view */ /*#else uint16_t type;*//* one of the section types below */ /* uint16_t page;*//* memory page or view */ /*#endif #endif*//* _BIG_ENDIAN Not defined by bridge driver */ /* a context field for use by Dynamic_Loader_Allocate; ignored but maintained by the dynamic loader */ #ifdef __KERNEL__ u32 context; #else uintptr_t context; #endif } ; /* use this macro to extract type of section from LDR_SECTION_INFO.type field */ #define DLOAD_SECTION_TYPE(typeinfo) (typeinfo & 0xF) /* type of section to be allocated */ #define DLOAD_TEXT 0 #define DLOAD_DATA 1 #define DLOAD_BSS 2 /* internal use only, run-time cinit will be of type DLOAD_DATA */ #define DLOAD_CINIT 3 struct Dynamic_Loader_Allocate { /* public: */ /************************************************************************* * Function allocate * * Parameters: * info A pointer to an information block for the section * align The alignment of the storage in target AUs * * Effect: * Allocates target memory for the specified section and fills in the * load_addr and run_addr fields of the section info structure. Returns TRUE * for success, FALSE for failure. * * Notes: * Frequently load_addr and run_addr are the same, but if they are not * load_addr is used with Dynamic_Loader_Initialize, and run_addr is * used for almost all relocations. This function should always initialize * both fields. *************************************************************************/ int (*Allocate) (struct Dynamic_Loader_Allocate * thisptr, struct LDR_SECTION_INFO * info, unsigned align); /************************************************************************* * Function deallocate * * Parameters: * info A pointer to an information block for the section * * Effect: * Releases the target memory previously allocated. * * Notes: * The content of the info->name field is undefined on call to this function. *************************************************************************/ void (*Deallocate) (struct Dynamic_Loader_Allocate * thisptr, struct LDR_SECTION_INFO * info); }; /* class Dynamic_Loader_Allocate */ /***************************************************************************** ***************************************************************************** * A class used by the dynamic loader to load data into a target. This class * provides the interface-specific functions needed to load data. ***************************************************************************** *****************************************************************************/ struct Dynamic_Loader_Initialize { /* public: */ /************************************************************************* * Function connect * * Parameters: * none * * Effect: * Connect to the initialization interface. Returns TRUE for success, * FALSE for failure. * * Notes: * This function is called prior to use of any other functions in * this interface. *************************************************************************/ int (*connect) (struct Dynamic_Loader_Initialize * thisptr); /************************************************************************* * Function readmem * * Parameters: * bufr Pointer to a word-aligned buffer for the result * locn Target address of first data element * info Section info for the section in which the address resides * bytsiz Size of the data to be read in sizeof() units * * Effect: * Fills the specified buffer with data from the target. Returns TRUE for * success, FALSE for failure. *************************************************************************/ int (*readmem) (struct Dynamic_Loader_Initialize * thisptr, void *bufr, LDR_ADDR locn, struct LDR_SECTION_INFO * info, unsigned bytsiz); /************************************************************************* * Function writemem * * Parameters: * bufr Pointer to a word-aligned buffer of data * locn Target address of first data element to be written * info Section info for the section in which the address resides * bytsiz Size of the data to be written in sizeof() units * * Effect: * Writes the specified buffer to the target. Returns TRUE for success, * FALSE for failure. *************************************************************************/ int (*writemem) (struct Dynamic_Loader_Initialize * thisptr, void *bufr, LDR_ADDR locn, struct LDR_SECTION_INFO * info, unsigned bytsiz); /************************************************************************* * Function fillmem * * Parameters: * locn Target address of first data element to be written * info Section info for the section in which the address resides * bytsiz Size of the data to be written in sizeof() units * val Value to be written in each byte * Effect: * Fills the specified area of target memory. Returns TRUE for success, * FALSE for failure. *************************************************************************/ int (*fillmem) (struct Dynamic_Loader_Initialize * thisptr, LDR_ADDR locn, struct LDR_SECTION_INFO * info, unsigned bytsiz, unsigned val); /************************************************************************* * Function execute * * Parameters: * start Starting address * * Effect: * The target code at the specified starting address is executed. * * Notes: * This function is called at the end of the dynamic load process * if the input module has specified a starting address. *************************************************************************/ int (*execute) (struct Dynamic_Loader_Initialize * thisptr, LDR_ADDR start); /************************************************************************* * Function release * * Parameters: * none * * Effect: * Releases the connection to the load interface. * * Notes: * This function is called at the end of the dynamic load process. *************************************************************************/ void (*release) (struct Dynamic_Loader_Initialize * thisptr); }; /* class Dynamic_Loader_Initialize */ #ifdef __cplusplus } #endif #endif /* _DYNAMIC_LOADER_H_ */