📄 loadlib.c
字号:
** The double indirection not only permits reporting the addresses* actually used, but also allows you to specify loading a segment* at the beginning of memory, since the following cases can be* distinguished:** .IP (1) 4* Allocate memory for a section (text in this example): <ppText> == NULL* .IP (2)* Begin a section at address zero (the text section, below): *<ppText> == 0* .LP* Note that loadModule() is equivalent to this routine if all three of the* segment-address parameters are set to NULL.** COMMON* 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 static * linker (host) resolves these and places them in bss as a final step * in creating a fully linked object module. However, the target loader* is most often used to load partially linked object modules.* When the target loader encounters a variable labeled "common",* its behavior depends on the following flags :* .iP "LOAD_COMMON_MATCH_NONE" 8* Allocate memory for the variable with malloc() and enter the variable* in the target symbol table (if specified) at that address. This is* the default.* .iP "LOAD_COMMON_MATCH_USER"* Search for the symbol in the target symbol table, excluding the* vxWorks image symbols. If several symbols exist, then the order of matching* is: (1) bss, (2) data. If no symbol is found, act like the* default.* .iP "LOAD_COMMON_MATCH_ALL"* Search for the symbol in the target symbol table, including the* vxWorks image symbols. If several symbols exist, then the order of matching is: * (1) bss, (2) data. If no symbol is found, act like the default.* .LP* 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").** EXAMPLES* Load a module into allocated memory, but do not return segment addresses:* .CS* module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, NULL, NULL, NULL);* .CE* Load a module into allocated memory, and return segment addresses:* .CS* pText = pData = pBss = LD_NO_ADDRESS;* module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, &pText, &pData, &pBss);* .CE* Load a module to off-board memory at a specified address:* .CS* pText = 0x800000; /@ address of text segment @/* pData = pBss = LD_NO_ADDRESS /@ other segments follow by default @/* module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, &pText, &pData, &pBss);* .CE** RETURNS:* MODULE_ID, or* NULL if the file cannot be read, there is not enough memory,* the file format is illegal, or there were unresolved symbols.** SEE ALSO:* .pG "Basic OS" */MODULE_ID loadModuleAt ( FAST int fd, /* fd from which to read module */ int symFlag, /* symbols to add to table */ /* (LOAD_[NO | LOCAL | GLOBAL | ALL]_SYMBOLS) */ char **ppText, /* load text segment at addr. pointed to by this */ /* ptr, return load addr. via this ptr */ char **ppData, /* load data segment at addr. pointed to by this */ /* pointer, return load addr. via this ptr */ char **ppBss /* load BSS segment at addr. pointed to by this */ /* pointer, return load addr. via this ptr */ ) { return (loadModuleAtSym (fd, symFlag, ppText, ppData, ppBss, sysSymTbl)); }/******************************************************************************** loadModuleAtSym - load object module into memory with specified symbol table** This routine is the underlying routine to loadModuleAt(). This interface* allows specification of the the symbol table used to resolve undefined* external references and to which to add new symbols.** RETURNS:* MODULE_ID, or* NULL if can't read file or not enough memory or illegal file format** NOMANUAL*/MODULE_ID loadModuleAtSym ( FAST int fd, /* fd from which to read module */ int symFlag, /* symbols to be added to table * ([NO | GLOBAL | ALL]_SYMBOLS) */ char **ppText, /* load text segment at address pointed to by this * pointer, return load address via this pointer */ char **ppData, /* load data segment at address pointed to by this * pointer, return load address via this pointer */ char **ppBss, /* load bss segment at address pointed to by this * pointer, return load address via this pointer */ SYMTAB_ID symTbl /* symbol table to use */ ) { MODULE_ID module; if (loadRoutine == NULL) { errnoSet (S_loadLib_ROUTINE_NOT_INSTALLED); return (NULL); } else { module = (MODULE_ID) (*loadRoutine) (fd, symFlag, ppText, ppData, ppBss, symTbl); if (module != NULL) { cplusLoadFixup (module, symFlag, symTbl); /* synchronize host symbol table if necessary */ if (syncLoadRtn != NULL) (* syncLoadRtn) (module); } return module; } }/******************************************************************************** loadModuleGet - create module information for a loaded object module** RETURNS: MODULE_ID, or NULL if module could not be created.** NOMANUAL*/MODULE_ID loadModuleGet ( char * fileName, /* name of the module */ int format, /* object module format */ int * symFlag /* pointer to symFlag */ ) { MODULE_ID moduleId; /* Change old style flags to new style */ switch (*symFlag) { case NO_SYMBOLS: *symFlag = LOAD_NO_SYMBOLS; break; case GLOBAL_SYMBOLS: *symFlag = LOAD_GLOBAL_SYMBOLS; break; case ALL_SYMBOLS: *symFlag = LOAD_ALL_SYMBOLS; break; } moduleId = moduleCreate (fileName, format, *symFlag); return (moduleId); }/********************************************************************************* addSegNames - add segment names to symbol table** This routine adds names of the form "objectFile.o_text," objectFile.o_data,"* and "objectFile.o_bss" to the symbol table.** NOMANUAL*/void addSegNames ( int fd, /* file descriptor for the object file */ char *pText, /* pointer to the text segment */ char *pData, /* pointer to the data segment */ char *pBss, /* pointer to the BSS segment */ SYMTAB_ID symTbl, /* symbol table to use */ UINT16 group /* group number */ ) { char fullname [MAX_FILENAME_LENGTH]; char symName[MAX_SYS_SYM_LEN + 1]; char *pName; if (ioctl (fd, FIOGETNAME, (int) fullname) == OK) pName = pathLastNamePtr (fullname); /* get last simple name */ else pName = "???"; /* XXX * Adding these symbols is now obsolete, and should probably * be removed in a future version of the OS. For now, leave them * in for backwards compatability. */ if (pText != NULL) { sprintf (symName, "%s_text", pName); if (symSAdd (symTbl, symName, pText, (N_EXT | N_TEXT), group) != OK) printErr (cantAddSymErrMsg, symName, errnoGet()); } if (pData != NULL) { sprintf (symName, "%s_data", pName); if (symSAdd (symTbl, symName, pData, (N_EXT | N_DATA), group) != OK) printErr (cantAddSymErrMsg, symName, errnoGet()); } if (pBss != NULL) { sprintf (symName, "%s_bss", pName); if (symSAdd (symTbl, symName, pBss, (N_EXT | N_BSS), group) != OK) printErr (cantAddSymErrMsg, symName, errnoGet()); } }/******************************************************************************** loadSegmentsAllocate - allocate text, data, and bss segments** This routine allocates memory for the text, data, and bss segments of* an object module. Before calling this routine, set up the fields of the* SEG_INFO structure to specify the desired location and size of each segment.** RETURNS: OK, or ERROR if memory couldn't be allocated.** NOMANUAL*/STATUS loadSegmentsAllocate ( SEG_INFO * pSeg /* pointer to segment information */ ) { BOOL protectText = FALSE; int pageSize; int alignment = 0; int textAlignment = pSeg->flagsText; /* save text alignment */ int dataAlignment = pSeg->flagsData; /* save data alignment */ int bssAlignment = pSeg->flagsBss; /* save bss alignment */ /* clear pSeg->flags<xxx> fields */ pSeg->flagsText = 0; pSeg->flagsData = 0; pSeg->flagsBss = 0; /* * if text segment protection is selected, then allocate the text * segment seperately on a page boundry */ if ((pSeg->sizeText != 0) && vmLibInfo.protectTextSegs && (pSeg->addrText == LD_NO_ADDRESS)) { if ((pageSize = VM_PAGE_SIZE_GET()) == ERROR) return (ERROR); /* round text size to integral number of pages */ pSeg->sizeProtectedText = pSeg->sizeText / pageSize * pageSize + pageSize; /* * get the section alignment (maximum between page size and section * alignment specified in the file). */ alignment = max(pageSize, textAlignment); if ((pSeg->addrText = memalign (alignment, pSeg->sizeProtectedText)) == NULL) return (ERROR); pSeg->flagsText |= SEG_WRITE_PROTECTION; pSeg->flagsText |= SEG_FREE_MEMORY; protectText = TRUE; } /* if all addresses are unspecified, allocate one large chunk of memory */ if (pSeg->addrText == LD_NO_ADDRESS && pSeg->addrData == LD_NO_ADDRESS && pSeg->addrBss == LD_NO_ADDRESS) { /* SPR #21836 */ alignment = 0; if (textAlignment > dataAlignment) alignment = max (textAlignment, bssAlignment); else alignment = max (dataAlignment, bssAlignment); if (alignment != 0) pSeg->addrText = memalign (alignment, pSeg->sizeText + pSeg->sizeData + pSeg->sizeBss); else pSeg->addrText = malloc (pSeg->sizeText + pSeg->sizeData + pSeg->sizeBss); /* check for malloc error */ if (pSeg->addrText == NULL) return (ERROR); pSeg->addrData = pSeg->addrText + pSeg->sizeText; pSeg->addrBss = pSeg->addrData + pSeg->sizeData; pSeg->flagsText |= SEG_FREE_MEMORY; } /* if addresses not specified, allocate memory. */ if (pSeg->addrText == LD_NO_ADDRESS && pSeg->sizeText != 0) { /* SPR #21836 */ if (textAlignment != 0) { if ((pSeg->addrText = (char *) memalign (textAlignment,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -