533 lines
21 KiB
C
533 lines
21 KiB
C
/*
|
|
* 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_ */
|
|
|