📄 loadpecofflib.c
字号:
if ((status == OK) || (errnoGet() == S_symLib_SYMBOL_NOT_FOUND)) for (ix = 0; ix < max_scns; ix++) { /* * Only meaningful sections are relocated. Note that the section * flags set for PECOFF do not allow to test for STYP_REG. The * PE extension IMAGE_SCN_MEM_DISCARDABLE should be used instead. */ if ((relsPtr[ix] != NULL) && !(scnHdr[ix].s_flags & STYP_INFO) && !(scnHdr[ix].s_flags & STYP_NOLOAD) && !(scnHdr[ix].s_flags & IMAGE_SCN_MEM_DISCARDABLE) && !(scnHdr[ix].s_flags & STYP_PAD)) { if (pecoffRelSegmentI386 (relsPtr[ix], scnHdr, externalsBuf, externalSyms, &seg, ix) != OK) { goto error; } } } pecoffFree(externalsBuf, externalSyms, stringsBuf, relsPtr); /* write protect the text if text segment protection is turned on */ if (seg.flagsText & SEG_WRITE_PROTECTION) { if (VM_STATE_SET (NULL, pText, seg.sizeProtectedText, VM_STATE_MASK_WRITABLE, VM_STATE_WRITABLE_NOT) == ERROR) goto error; } /* return load addresses, where called for */ if (ppText != NULL) *ppText = pText; if (ppData != NULL) *ppData = pData; if (ppBss != NULL) *ppBss = pBss; /* clear out bss */ bzero (pBss, (int) seg.sizeBss); /* * Add the segments to the module. * This has to happen after the relocation gets done. * If the relocation happens first, the checksums won't be * correct. */ moduleSegAdd (moduleId, SEGMENT_TEXT, pText, seg.sizeText, seg.flagsText); moduleSegAdd (moduleId, SEGMENT_DATA, pData, seg.sizeData, seg.flagsData); moduleSegAdd (moduleId, SEGMENT_BSS, pBss, seg.sizeBss, seg.flagsBss); if (status == OK) return (moduleId); else return (NULL); /* error: * clean up dynamically allocated temporary buffers and return ERROR */error: pecoffFree(externalsBuf, externalSyms, stringsBuf, relsPtr); moduleDelete (moduleId); return (NULL); }/******************************************************************************** loadPecoffInit - initialize the system for pecoff load modules.** This routine initializes VxWorks to use a PECOFF format for loading * modules.** RETURNS: OK** SEE ALSO: loadModuleAt()*/STATUS loadPecoffInit (void) { /* XXX check for installed? */ loadRoutine = (FUNCPTR) ldPecoffModAtSym; return (OK); }/********************************************************************************* pecoffFree - free any malloc'd memory**/LOCAL void pecoffFree ( char **pExternalsBuf, /* pointers to external symbols */ char *pExternalSyms, /* buffer for external symbols */ char *pStringsBuf, /* string table pointer */ RELOC **pRelsPtr /* section relocation */ ) { int ix; if (pStringsBuf != NULL) free (pStringsBuf); if (pExternalsBuf != NULL) free ((char *) pExternalsBuf); if (pExternalSyms != NULL) free ((char *) pExternalSyms); for (ix = 0; ix < MAX_SCNS; ix++) { if (*pRelsPtr != NULL) free((char *) *pRelsPtr); pRelsPtr++; } }/********************************************************************************* pecoffSegSizes - determine segment sizes** This function fills in the size fields in the SEG_INFO structure.* Note that the bss size may need to be readjusted for common symbols. */LOCAL void pecoffSegSizes ( FILHDR *pHdr, /* pointer to file header */ SCNHDR *pScnHdrArray, /* pointer to array of section headers */ SEG_INFO *pSeg /* section addresses and sizes */ ) { int ix; int nbytes; /* additional bytes required for alignment */ SCNHDR *pScnHdr; /* pointer to a section header */ pSeg->sizeText = 0; pSeg->sizeData = 0; pSeg->sizeBss = 0; /* * SPR #21836: pSeg->flagsText, pSeg->flagsData, pSeg->flagsBss are used * to save the max value of each segments. These max values are computed * for each sections. These fields of pSeg are only used on output, then * a temporary use is allowed. */ pSeg->flagsText = _ALLOC_ALIGN_SIZE; pSeg->flagsData = _ALLOC_ALIGN_SIZE; pSeg->flagsBss = _ALLOC_ALIGN_SIZE; for (ix=0; ix < pHdr->f_nscns; ix++) /* loop thru all sections */ { pScnHdr = pScnHdrArray + ix; if (pScnHdr->s_flags & STYP_TEXT) { /* Assume that there was a previous section of same type. * First, align data to boundary from section header. * Add the size of this section to the total segment size. */ nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeText); pSeg->sizeText += pScnHdr->s_size + nbytes; /* SPR #21836 */ if (MAX_ALIGNMENT > pSeg->flagsText) pSeg->flagsText = MAX_ALIGNMENT; } else if (pScnHdr->s_flags & STYP_DATA) { nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeData); pSeg->sizeData += pScnHdr->s_size + nbytes; /* SPR #21836 */ if (MAX_ALIGNMENT > pSeg->flagsData) pSeg->flagsData = MAX_ALIGNMENT; } else if (pScnHdr->s_flags & STYP_BSS) { nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeBss); pSeg->sizeBss += pScnHdr->s_size + nbytes; /* SPR #21836 */ if (MAX_ALIGNMENT > pSeg->flagsBss) pSeg->flagsBss = MAX_ALIGNMENT; } } }/********************************************************************************* pecoffLoadSections - read sections into memory* */LOCAL STATUS pecoffLoadSections ( int fd, SCNHDR *pScnHdr, char **pScnAddr, char *pText, char *pData ) { int ix; int textCount = 0; int dataCount = 0; INT32 size; /* section size */ int nbytes; /* additional bytes required for alignment */ char *pLoad; /* address to load data at */ for (ix = 0; ix < max_scns; ix++) { pLoad = NULL; size = pScnHdr->s_size; if (size != 0 && pScnHdr->s_scnptr != 0) { if (pScnHdr->s_flags & STYP_TEXT) { pLoad = pText; nbytes = dataAlign(MAX_ALIGNMENT, pLoad); pLoad += nbytes; pText = (char *) ((int) pLoad + size); /* for next load */ textCount += size + nbytes; } else if (pScnHdr->s_flags & STYP_DATA) { pLoad = pData; nbytes = dataAlign(MAX_ALIGNMENT, pLoad); pLoad += nbytes; pData = (char *) ((int) pLoad + size); /* for next load */ dataCount += size + nbytes; } else { /* ignore all other sections */ pScnAddr[ix] = pLoad; pScnHdr++; continue; } /* Advance to position in file * and read section directly into memory. */ if ((lseek (fd, pScnHdr->s_scnptr, SEEK_SET) == ERROR) || (fioRead (fd, pLoad, size) != size)) { return (ERROR); } } pScnAddr[ix] = pLoad; pScnHdr++; } return (OK); }/********************************************************************************* loadPecoffCommonManage - process a common symbol** This routine processes the common symbols found in the object module.* Common symbols are symbols declared global without being assigned a* value. ** loadPecoffCommonManage() is derived from loadCommonMange() in* loadLib.c, but unlike loadCommonManage(), loadPecoffCommonManage() does* not allocate memory or add symbols to the symbol table:* loadPecoffCommonManage() leaves the chores of allocating memory* or adding symbols to the symbol table up to the caller.** For more information on common symbol types,LOAD_COMMON_MATCH_NONE,* LOAD_COMMON_MATCH_USER and LOAD_COMMON_MATCH_ALL see* loadCommonManage() in loadLib.c.** NOMANUAL */LOCAL STATUS loadPecoffCommonManage ( 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 */ ) { COMMON_INFO commInfo; /* what to do with commons */ /* Force the default choice if no flag set */ if(!(loadFlag & LOAD_COMMON_MATCH_ALL) && !(loadFlag & LOAD_COMMON_MATCH_USER) && !(loadFlag & LOAD_COMMON_MATCH_NONE)) loadFlag |= LOAD_COMMON_MATCH_NONE; /* Must we do more than the default ? */ if(!(loadFlag & LOAD_COMMON_MATCH_NONE)) { /* Initialization */ memset (&commInfo, 0, sizeof (COMMON_INFO)); commInfo.symName = symName; /* Do we involve the core's symbols ? */ if(loadFlag & LOAD_COMMON_MATCH_USER) commInfo.vxWorksSymMatched = FALSE; /* no */ else if(loadFlag & LOAD_COMMON_MATCH_ALL) commInfo.vxWorksSymMatched = TRUE; /* yes */ /* Get the last occurences of matching global symbols in bss and data */ loadCommonMatch (&commInfo, symTbl); /* Prefered order for matching symbols is : bss then data */ if(commInfo.pSymAddrBss != NULL) /* matching sym in bss */ { *pSymAddr = commInfo.pSymAddrBss; *pSymType = commInfo.bssSymType; } else if(commInfo.pSymAddrData != NULL) /* matching sym in data */ { *pSymAddr = commInfo.pSymAddrData; *pSymType = commInfo.dataSymType; } else *pSymAddr = NULL; /* no matching symbol */ /* If we found a matching symbol, stop here */ if(*pSymAddr != NULL) return (OK); } /* if a matching common symbol is not found, return ERROR*/ return (ERROR); }/********************************************************************************* pecoffSymTab - process an object module symbol table** This is passed a pointer to a pecoff symbol table and processes* each of the external symbols defined therein. This processing performs* two functions:** 1) Defined symbols are entered in the system symbol table as* specified by the "symFlag" argument:* LOAD_ALL_SYMBOLS = all defined symbols (LOCAL and GLOBAL) are added,* LOAD_GLOBAL_SYMBOLS = only external (GLOBAL) symbols are added,* LOAD_NO_SYMBOLS = no symbols are added;** 2) Any undefined externals are looked up in the system symbol table to* determine their values. The values are entered into the specified* 'externals' array. This array is indexed by the symbol number* (position in the symbol table).* Note that all symbol values, not just undefined externals, are entered* into the 'externals' array. The values are used to perform relocations.** Note that "common" symbols have type undefined external - the value* field of the symbol will be non-zero for type common, indicating* the size of the object.** If an undefined external cannot be found in the system symbol table,* an error message is printed, but ERROR is not returned until the entire* symbol table has been read, which allows all undefined externals to be* looked up.** RETURNS: OK or ERROR*/LOCAL STATUS pecoffSymTab ( int fd, /* file descriptor of module being loaded */ FILHDR * pHdr, /* pointer to file header */ SYMENT * externalSyms, /* pointer to symbols array */ char *** externals, /* pointer to pointer to array to fill in symbol absolute values */ int symFlag, /* symbols to be added to table * ([NO|GLOBAL|ALL]_SYMBOLS) */ SEG_INFO * pSeg, /* pointer to segment information */ char * symStrings, /* symbol string table */ SYMTAB_ID symTbl, /* symbol table to use */ char * pNextCommon, /* next common address in bss */ SCNHDR * pScnHdrArray, /* pointer to PECOFF section header array */ char ** pScnAddr, /* pointer to section loaded address array */ BOOL fullyLinked, /* TRUE if module already absolutely located */ UINT16 group, /* module's group */ int imageBase /* base addr of the simulateur image in RAM */ ) { int status = OK; /* return status */ char * name; /* symbol name (plus EOS) */ SYMENT * symbol; /* symbol struct */ SYM_TYPE vxSymType; /* vxWorks symbol type */ int symNum; /* symbol index */ char * adrs; /* table resident symbol address */ char * bias; /* section relative address */ ULONG bssAlignment; /* alignment value of common type */ long scnFlags; /* flags from section header */ int auxEnts = 0; /* auxiliary symbol entries to skip */ SCNHDR * pScnHdr = NULL; /* pointer to a PECOFF section header */ char * scnAddr = NULL; /* section loaded address */ char nameTemp[SYMNMLEN+1]; /* temporary for symbol name string */ /* Loop thru all symbol table entries in object file */ for (symNum = 0, symbol = externalSyms; symNum < pHdr->f_nsyms; symbol++, symNum++) { if (auxEnts) /* if this is an auxiliary entry */ { auxEnts--; continue; /* skip it */ } auxEnts = symbol->n_numaux; /* # of aux entries for this symbol */ /* Get rid of debug symbols */ if (symbol->n_scnum == N_DEBUG) continue; /* Setup pointer to symbol name string */ if (symbol->n_zeroes) /* if name is in symbol entry */ { name = symbol->n_name; if (*(name + SYMNMLEN -1) != '\0') { /* * If the symbol name array is full, * the string is not terminated by a null. * So, move the string to a temporary array, * where it can be null terminated. */ bcopy (name, nameTemp, SYMNMLEN); nameTemp[SYMNMLEN] = '\0'; name = nameTemp; } } else name = symStrings + symbol->n_offset; if (! PECOFF_UNDF(symbol) && ! PECOFF_COMM(symbol)) { /* * The symbol is a defined, local or global (though not common). * * Determine symbol's section and address bias */ if (symbol->n_scnum > 0) { pScnHdr = pScnHdrArray + (symbol->n_scnum - 1); scnAddr = pScnAddr[symbol->n_scnum - 1]; scnFlags = pScnHdr->s_flags; } else scnFlags = 0; /* section has no text, data or bss */ if (symbol->n_scnum == N_ABS) /* special check for absolute syms */ { /* * No bias is applied to absolute symbols: they have to be * valid for the actual location in Window's memory space * where the simulator is installed. * * PLEASE, DO NOT CHANGE THIS AS THIS IS A CONSCIOUS AND * DOCUMENTED DECISION. */ bias = 0; vxSymType = VX_ABS; } else if (scnFlags & STYP_TEXT) { bias = (char *) scnAddr; vxSymType = VX_TEXT; } else if (scnFlags & STYP_DATA) { bias = (char *) scnAddr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -