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