| /* |
| * 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_ */ |
| |