Tornado API Reference : Target Server Internal Routines
loadlib - host-based object-module loader
loadModule( ) - load an object module into memory
loadModuleAt( ) - load an object module into memory
loadModuleAtFromFileName( ) - load an object module into memory
loadBufferFree( ) - free a buffer previously allocated
loadAlignGet( ) - determine the required alignment for an address or a size
loadSegmentsAllocate( ) - allocate text, data, and bss segments
loadUndefSymAdd( ) - record an undefined symbol name
loadCommonManage( ) - process a common symbol
loadCoreFileCheck( ) - check whether the core file is up to date
loadCoreBuilderSet( ) - record information about the tool chain
loadCoreBuilderGet( ) - publish information about the tool chain
loadFlagsCheck( ) - check for illegal combinations of flags
loadOutputToFile( ) - write a module's segments in a file
loadRelocLink( ) - Link the relocator Shared library to the OMF specific loader.
This library provides a generic object module loading facility. Any supported format files may be loaded into memory and relocated properly, their external references resolved, and their external definitions added to the target symbol table for use by other modules and from the shell. Modules may be loaded from any I/O stream.
The following code fragment loads the object file objFile into memory allocated from the target memory pool. All external and static definitions from the file are added to the target symbol table.
fd = open ("objFile", O_RDONLY); loadModule (fd, LOAD_ALL_SYMBOLS); close (fd);
loadlib.h
File access-------------------Generic level------------Module management | | | | `----------+-----` Virtual memory | | management-+------------------------------+.|.............|..... | | | | : | ,---------------------------|-|-+------------------+- Symbol | | | | | | : : table | | ,--------------------------+.|...........|....:.:... | | | | | | | : : : A.OUT OMF--, COFF OMF---------+...Other OMF management | management | management | | | | | `----------------------|-------------+----------, | | | ,----------+.......... ,---------+.......... | | | : | | : | 68K/x86 SPARC Other i960 29K Other | specific specific specific specific specific specific | | | : | | : | `----------+---------+---------+---------+---------+---------- Memory managementNote the three-layer structure:
- 1.
- the generic level (loadlib.c)
- 2.
- the object module format level (loadaout.c, loadcoff.c)
- 3.
- the architecture-specific level (aout68k.c, aoutspar.c, coffi960.c, coffa29k.c)
Dotted lines indicate functionality that does not yet exist.
loadlib, symlib, tgtmem, .I" API Programmer's Guide: Object Module Loader"
loadModule( ) - load an object module into memory
MODULE_ID loadModule ( int fd, /* fd of file to load */ int loadFlag /* control of loader's behavior */ )
This routine loads an object module from the specified file and places the text, data, and bss segments into memory allocated from the target memory pool.
This routine is equivalent to loadModuleAt( ) with NULL for the addresses of text, data, and bss segments. For more details, see the reference entry for loadModuleAt( ).
MODULE_ID or NULL if the file cannot be read, there is not enough memory, or the file format is illegal.
loadlib, loadModuleAt( ), API Programmer's Guide: Object Module Loader
loadModuleAt( ) - load an object module into memory
MODULE_ID loadModuleAt ( int fd, /* fd */ /* from */ /* which */ /* to */ /* read */ /* module */ int loadFlag,/* control of loader's behavior */ void * * ppText, /* load text segment at addr. pointed to by this ptr, return load addr. via this ptr */ void * * ppData, /* load data segment at addr. pointed to by this pointer, return load addr. via this ptr */ void * * ppBss /* load BSS segment at addr. pointed to by this pointer, return load addr. via this ptr */ )
This routine reads an object module from fd. All the sections are coalesced in segments and loaded at the specified load addresses in memory set aside by the user using malloc( ) or in the target memory partition as described below. A "segment" is defined here as the assembling of several sections of the same type. loadModuleAt( ) follows a three segment model: text, data and bss. Any literal section is merged in the text segment. The module is properly relocated according to the relocation commands in the file. Unresolved externals are linked to symbols found in the target server symbol table. Symbols in the module being loaded can optionally be added to the target server symbol table.
As the module is loaded, any unresolved external references are resolved by looking up the missing symbols in the the target server symbol table. If found, those unresolved references are correctly linked to the new module. If unresolved external references cannot be found in the target server symbol table, then the symbol name is added to a list that is returned to the tool that asked for the loading procedure (the shell for instance), but the loading/linking continues. Note that loading is continued to facilitate debugging. Only code that does not contain undefined symbols can actually be executed.
The symbols defined in the module being loaded may optionally be added to the target server symbol table, depending on the value of loadFlag:
- LOAD_NO_SYMBOLS
- Add no symbols to the target server symbol table.
- LOAD_GLOBAL_SYMBOLS
- Add only external symbols to the target server symbol table.
- LOAD_ALL_SYMBOLS
- Add all symbols to the target server symbol table.
The basic value above can be or'ed with each of the following:
- LOAD_FULLY_LINKED
- Resolve all addresses in the file; no relocation is required. Download the segments at the addresses specified in the header of the file.
- LOAD_CORE_FILE
- Build the target server symbol table from the symbols in the core file. Download nothing to the target. (This flag should be used only when the initial connection with the target agent is made.)
- LOAD_HIDDEN_MODULE
- Load an invisible module (see moduleShow( )).
The relocation commands in the object module are used to relocate the text, data, and bss segments of the module. The location of each segment can be specified explicitly or left unspecified, in which case memory is allocated for the segment from the target memory partition. This is determined by the parameters ppText, ppData, and ppBss, each of which can have the following values:
- NULL
- No load address is specified, none will be returned.
- LOAD_NO_ADDRESS
- No load address is specified; the return address is referenced by the pointer.
- A pointer to an address
- The load address is specified.
The ppText, ppData, and ppBss parameters can be difficult to understand. For each one, if the pointer is NULL, the module is not affected by where the segment gets loaded. If the pointer is not NULL, then the pointer points to a second pointer, which points to where the segment should be loaded. If that second pointer has the value LOAD_NO_ADDRESS, then the module is not affected by where the segment gets loaded, but needs the address of the loaded segment. In that case, the LOAD_NO_ADDRESS gets replaced with a pointer to where the segment got loaded (LOAD_NO_ADDRESS is used, rather than NULL, so that a segment may be loaded at the beginning of memory).
When either loading method is used, the corresponding segment is placed following the preceding segment (where the ordering of segments is text, data, bss). Thus, if ppText is "don't care", ppData indicates an actual address. If ppBss is "don't care", then space will be allocated for text, and bss will be placed following data. The object module is responsible for ensuring that the area indicated by ppData is large enough to contain both data and bss segments.
Note that loadModule( ) is equivalent to this routine if all three of the segment-address parameters are set to NULL.
If addresses are unspecified, the loader tries to allocate a single block of memory for the whole object. If there is no contiguous free block large enough, memory for each segment is allocated separately.
Some host compiler/linker combinations use another storage class internally called "common". In the C language, uninitialized global variables are eventually put in the bss segment. However, in partially linked object modules they are flagged internally as "common" and the UNIX linker resolves these and places them in bss as a final step in creating a fully linked object module. However, the target server loader is most often used to load partially linked object modules. When the target server loader encounters a variable labeled "common", its behavior depends on the following flags :
- LOAD_COMMON_MATCH_NONE
- Allocate memory for the variable with malloc( ) and enter the variable in the target server symbol table (if specified) at that address. This is the default.
- LOAD_COMMON_MATCH_USER
- Search for the symbol in the target server symbol table, excluding the core-file symbols. If several symbols exist, then the order of matching is: (1) bss, (2) data, (3) text. If no symbol is found, act like the default.
- LOAD_COMMON_MATCH_ALL
- Search for the symbol in the target server symbol table, including the core-file symbols. If several symbols exist, then the order of matching is: (1) bss, (2) data, (3) text. If no symbol is found, act like the default.
Note that most UNIX loaders have an option that forces resolution of the common storage while leaving the module relocatable (for example, with typical BSD UNIX loaders, use options "-rd").
Load a module into allocated memory; do not return segment addresses:
module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, NULL, NULL, NULL);Load a module into allocated memory; return segment addresses:pText = pData = pBss = LOAD_NO_ADDRESS; module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, &pText, &pData, &pBss);Load a module to off-board memory at a specified address:pText = 0x800000; /* address of text segment */ pData = pBss = LOAD_NO_ADDRESS /* other segments follow by default */ module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, &pText, &pData, &pBss);
MODULE_ID or NULL if the file cannot be read, there is not enough memory, or the file format is illegal.
loadlib, UNIX manual for object file format, API Programmer's Guide: Object Module Loader
loadModuleAtFromFileName( ) - load an object module into memory
MODULE_ID loadModuleAtFromFileName ( char * filename, /* Name of the file! */ char * fileBufferBase, /* Base of file buffer */ int loadFlag, /* Control of loader's behavior */ void * * ppText, /* Load text segment at addr. pointed to by */ /* Ptr, return load addr. via this ptr */ void * * ppData, /* Load data segment at addr. pointed to by */ /* Pointer, return load addr. via this ptr */ void * * ppBss /* Load BSS segment at addr. pointed to by this */ /* return load addr. via this ptr */ )
This routine reads an object module from a buffer. All the sections are coalesced in segments and loaded at the specified load addresses in memory set aside by the user using malloc( ) or in the target memory partition as described below. A "segment" is defined here as the assembling of several sections of the same type. loadModuleAt( ) follows a three segment model: text, data and bss. Any literal section is merged in the text segment. The module is properly relocated according to the relocation commands in the file. Unresolved externals are linked to symbols found in the target server symbol table. Symbols in the module being loaded can optionally be added to the target server symbol table.
MODULE_ID or NULL if the file cannot be read, there is not enough memory, or the file format is illegal.
loadlib, loadModuleAt
loadBufferFree( ) - free a buffer previously allocated
void loadBufferFree ( void * * ppBuf )
This routine frees the memory used by a buffer. The buffer pointer is set to NULL.
N/A
loadAlignGet( ) - determine the required alignment for an address or a size
UINT32 loadAlignGet ( UINT32 alignment, /* value of alignment */ void * pAddrOrSize /* address or size to check */ )
This routine determines, given a proposed address or size, how many bytes must be added to obtain an address or size correctly aligned for the specified target.
The number of bytes to be added to the address or to the size to obtain the correct alignment.
loadlib, API Programmer's Guide: Object Module Loader
loadSegmentsAllocate( ) - allocate text, data, and bss segments
STATUS loadSegmentsAllocate ( SEG_INFO * pSeg /* pointer to segment information */ )
This routine allocates memory for the text, data, and bss segments of a relocatable object module. Before calling this routine, set up the fields of the SEG_INFO structure to specify the location and size of each segment. Only segments with an address of LOAD_NO_ADDRESS and non-NULL size are allocated.
If text segment protection is selected, then this routine allocates the text segment separately on a page boundary.
Note that when all three segments have to be allocated and text protection is not applied, this routine allocates one large block of memory in which each segment is installed immediately at the end of its predecessor. Consequently, if the target system has specific alignment requirements, the segment sizes must be set so that each segment begins on the appropriate boundary.
OK or ERROR if memory cannot be allocated. (In case of ERROR, all memory is freed.)
loadlib, Programmer's API Guide: Object Module Loader
loadUndefSymAdd( ) - record an undefined symbol name
STATUS loadUndefSymAdd ( MODULE_ID moduleId, /* module id */ char * symName /* undefined symbol name */ )
This routine stores the name of any undefined symbol in the module being loaded so that a list of these symbols can be consulted by an external tool, such the shell.
OK or ERROR if the name cannot be added.
loadlib, API Programmer's Guide: Object Module Loader
loadCommonManage( ) - process a common symbol
STATUS loadCommonManage ( int comAreaSize, /* size of area required for common sym */ char * symName, /* symbol name */ SYMTAB_ID symTbl, /* target symbol table */ SYM_ADRS * pSymAddr, /* where to return symbol's address */ SYM_TYPE * pSymType, /* where to return symbol's type */ int loadFlag, /* control of loader's behavior */ SEG_INFO * pSeg, /* section addresses and sizes */ int group /* module group */ )
This routine processes the common symbols found in the object module. Common symbols are symbols declared global without being assigned a value. Good programming avoids such declarations since it is almost impossible to be sure what initialized global symbol should be used to solve a common symbol relocation. The processing of common symbols depends on the following control flags, which enforce one of three levels of strictness for common symbol evaluation:
- LOAD_COMMON_MATCH_NONE
- This is the default option. Common symbols are kept isolated, visible from the object module only. This option prevents any matching with already-existing symbols (in other words, the relocations that refer to these symbols are kept local). Memory is allocated and symbols are added to the symbol table with type SYM_COMM unless LOAD_NO_SYMBOLS is set.
- LOAD_COMMON_MATCH_USER
- The loader seeks a matching symbol in the target symbol table, but only symbols brought by user's modules are considered. If no matching symbol exists, it acts like LOAD_COMMON_MATCH_NONE. If several matching symbols exist, the order of preference is: symbols in the bss segment, then symbols in the data segment, then symbols in the text segment. If several matching symbols exist within a segment type, the symbol most recently added to the target symbol table is used as reference.
- LOAD_COMMON_MATCH_ALL
- The loader seeks for a matching symbol in the target symbol table. All symbols are considered. If no matching symbol exists, then it acts like LOAD_COMMON_MATCH_NONE. If several matches are found, the order is the same as for LOAD_COMMON_MATCH_USER.
* OK or ERROR if the memory allocation or the addition to the symbol table fails.
loadlib, API Programmer's Guide: Object Module Loader
loadCoreFileCheck( ) - check whether the core file is up to date
STATUS loadCoreFileCheck ( REMPTR pRemote, /* core file base address (target) */ void * pLocal, /* core file base address (host) */ UINT32 nBytes /* core file size */ )
This routine checks whether the core file used by the target server to build the target symbol table is as current as the core file loaded and running on the target. Checksum operations are done on the text segments in the cache maintained by the target server memory manager and in the target memory.
OK or ERROR if the text segments differ.
loadlib, tgtChecksum( ), checksum( ), API Programmer's Guide: Object Module Loader
loadCoreBuilderSet( ) - record information about the tool chain
void loadCoreBuilderSet ( char * builder /* compilation tool chain reference */ )
This routine records the compilation-tool-chain references (the "builder") for further use. A "builder" is a string used by the make technology of the target server. Builders are defined to produce a.out, COFF, or ELF. If no information exists, the builder is set to unknown.
Call this routine only once, when the core file is loaded.
N/A
loadlib, loadCoreBuilderGet( ), API Programmer's Guide: Object Module Loader
loadCoreBuilderGet( ) - publish information about the tool chain
char * loadCoreBuilderGet (void)
This routine returns the compilation-tool-chain and object-module-format references, the "builder." A "builder" is a string used by the make technology of the target server. Builders are defined to produce a.out, COFF, or ELF. If no information exists, the builder is set to unknown.
Call this routine only after loadCoreBuilderSet( ) has recorded the reference.
The "builder" string.
loadlib, loadCoreBuilderSet( ), API Programmer's Guide: Object Module Loader
loadFlagsCheck( ) - check for illegal combinations of flags
STATUS loadFlagsCheck ( int loadFlags, /* control of loader's behavior */ void * * ppText, /* adrs where to store the text seg address */ void * * ppData, /* adrs where to store the data seg address */ void * * ppBss /* adrs where to store the bss seg address */ )
This routine checks whether or not the flags applied for the load session form a valid combination.
OK or ERROR if the combination is illegal.
loadOutputToFile( ) - write a module's segments in a file
STATUS loadOutputToFile ( char * fileName, /* object file name */ SEG_INFO * pSeg /* information about segments */ )
This routine writes the contents of a specified module's text and data segments in a file for testing purposes. The output-file name is created from the object-file name with .rms as extension (rms stands for Relocated Module Segments). Any existing file with the same name is overwritten.
Segment contents are written contiguously in the file.
OK or ERROR if the file can't be opened or written.
loadlib, API Programmer's Guide: Object Module Loader
loadRelocLink( ) - Link the relocator Shared library to the OMF specific loader.
STATUS loadRelocLink ( DYNLK_FUNC relocDllFv[], /* array of function descriptions */ int routineNb /* # of routines to link */ )
This routine load the relocator DLL, and link all the routines given in the arguments. It is called by the specific loader initialization routine. The loader gives the names of the functions it expects to find in the relocator library ( in the relocDllFv array), and the max number of function it expects to find. Note that we expect to find at least two (2) functions in the Library. This facility is given because optionnal functions (like init routine) can be found in the library, but are not mandatory.
OK or ERROR.