📄 loadpecofflib.c
字号:
}/********************************************************************************* pecoffReadSym - read one PECOFF symbol entry* */LOCAL STATUS pecoffReadSym ( int fd, SYMENT *pSym, /* where to read symbol entry */ BOOL swapTables ) { int status; status = fioRead (fd, pSym->n_name, sizeof(pSym->n_name)); if(status != sizeof(pSym->n_name)) { printf(" Status %x %x : %x %x %x %x\n",status,sizeof(pSym->n_name), pSym->n_name[0], pSym->n_name[1], pSym->n_name[2], pSym->n_name[3]); status = fioRead (fd, pSym->n_name, sizeof(pSym->n_name)); printf(" Status #2 %x : %x %x %x %x\n",status, pSym->n_name[0], pSym->n_name[1], pSym->n_name[2], pSym->n_name[3]); status = ERROR; } else status = OK; if (swapTables && (status == OK)) { /* The n_name field is part of a union in the syment struct. * If the union uses n_name (array of char), then no * swabbing in required. * If the union uses n_offset (into string table), then * the n_offset must be swabbed. */ if (pSym->n_zeroes == 0) { swabData(&pSym->n_offset, sizeof(pSym->n_offset)); } } status |= fileRead (fd, &pSym->n_value, sizeof(pSym->n_value), swapTables); status |= fileRead (fd, &pSym->n_scnum, sizeof(pSym->n_scnum), swapTables); status |= fileRead (fd, &pSym->n_type, sizeof(pSym->n_type), swapTables); status |= fileRead (fd, &pSym->n_sclass, sizeof(pSym->n_sclass), swapTables); status |= fileRead (fd, &pSym->n_numaux, sizeof(pSym->n_numaux), swapTables); return(status); }/********************************************************************************* pecoffReadExtSyms - read PECOFF symbols* * For low memory systems, we can't afford to keep the entire* symbol table in memory at once.* For each symbol entry, the fields required for relocation* are saved in the externalSyms array.*/LOCAL STATUS pecoffReadExtSyms ( int fd, SYMENT **pSymbols, /* pointer to array of symbol entries */ char ***pSymAddr, /* pointer to array of addresses */ FILHDR *pHdr, BOOL swapTables ) { int status; int ix; SYMENT *pSym; /* pointer to symbol entry */ if (pHdr->f_nsyms) { /* malloc space for array of absolute addresses */ if ((*pSymAddr = malloc((UINT)(pHdr->f_nsyms) * sizeof(char *))) == NULL) { printErr (extMemErrMsg, (UINT)(pHdr->f_nsyms) * sizeof (char *)); return (ERROR); } /* malloc space for symbols */ if ((*pSymbols = malloc((UINT)(pHdr->f_nsyms) * SYMESZ)) == NULL) { return (ERROR); } if (lseek (fd, pHdr->f_symptr, SEEK_SET) == ERROR) { return (ERROR); } for (ix = 0, pSym = *pSymbols; ix < pHdr->f_nsyms; ix++, pSym++) { if ((status = pecoffReadSym(fd, pSym, swapTables) != OK)) return (status); } } return (OK); }/********************************************************************************* pecoffReadExtStrings - read in PECOFF external strings* * Assumptions: The file pointer is positioned at the start of the* string table.*/#define STR_BYTES_SIZE 4 /* size of string table length field */LOCAL STATUS pecoffReadExtStrings ( int fd, char **pStrBuf, BOOL swapTables ) { unsigned long strBytes; int status; /* Read length of string table */ if ((status = fileRead (fd, &strBytes, STR_BYTES_SIZE, swapTables)) != OK) { return (status); } if (strBytes > STR_BYTES_SIZE) { if ((*pStrBuf = malloc(strBytes)) == NULL) { printErr (stringMemErrMsg, strBytes); return (ERROR); } bcopy((char *) &strBytes, (char *) *pStrBuf, STR_BYTES_SIZE); strBytes -= STR_BYTES_SIZE; /* # bytes left to read */ if (fioRead (fd, *pStrBuf + STR_BYTES_SIZE, strBytes) != strBytes) { return (ERROR); } } return (OK); }#if FALSE /* XXX PAD - this is no longer used apparently *//********************************************************************************* softSeek - seek forward into a file** This procedure seeks forward into a file without actually using seek* calls. It is usefull since seek does not work on all devices.** RETURNS:* OK, or* ERROR if forward seek could not be accomplished**/#define SEEKBUF 1024LOCAL STATUS softSeek ( int fd, /* fd to seek with */ int startOfFileOffset /* byte index to seek to */ ) { int position; /* present file position */ int bytesToRead; /* bytes needed to read */ char tempBuffer[SEEKBUF]; /* temp buffer for bytes */ position = ioctl (fd, FIOWHERE, startOfFileOffset); if (position > startOfFileOffset) return(ERROR); /* calculate bytes to read */ bytesToRead = startOfFileOffset - position; while (bytesToRead >= SEEKBUF) { if (fioRead (fd, tempBuffer, SEEKBUF) != SEEKBUF) return (ERROR); bytesToRead -= SEEKBUF; } if (bytesToRead > 0) { if (fioRead (fd, tempBuffer, bytesToRead) != bytesToRead) return (ERROR); }#ifdef NO_PECOFF_SOFT_SEEK if (ioctl (fd, FIOSEEK, startOfFileOffset) == ERROR) return (ERROR);#endif return(OK); }#endif /* FALSE *//********************************************************************************* fileRead - loader file read function* */LOCAL STATUS fileRead ( int fd, char *pBuf, /* buffer to read data into */ UINT size, /* size of data field in bytes */ BOOL swap ) { int status = OK; if (fioRead (fd, pBuf, size) != size) { errnoSet (S_loadLib_FILE_READ_ERROR); return(ERROR); } if (swap) { status = swabData(pBuf, size); } return(status); }/********************************************************************************* swabData - swap endianess of data field of any length**/LOCAL STATUS swabData ( char *pBuf, /* buffer containing data */ UINT size /* size of data field in bytes */ ) {#define TEMP_BUF_SIZE 256 int status = OK; char tempBuf[TEMP_BUF_SIZE]; switch(size) { case sizeof(char): break; /* ok as is */ case sizeof(short): *(unsigned short *) pBuf = SWAB_SHORT(*(unsigned short *) pBuf); break; case sizeof(long): swabLong(pBuf, tempBuf); bcopy(tempBuf, pBuf, size); break; default: if (size <= TEMP_BUF_SIZE) { swab(pBuf, tempBuf, size); bcopy(tempBuf, pBuf, size); } else status = ERROR; break; } return(status); }/********************************************************************************* swabLong - swap endianess of long word**/LOCAL void swabLong ( char input[], char output[] ) { output[0] = input[3]; output[1] = input[2]; output[2] = input[1]; output[3] = input[0]; }/********************************************************************************* pecoffTotalCommons - * * INTERNAL* All common external symbols are being tacked on to the end* of the BSS section. This function determines the additional amount* of memory required for the common symbols.* */LOCAL ULONG pecoffTotalCommons ( SYMENT *pSym, /* pointer to external symbols */ int nEnts, /* # of entries in symbol table */ ULONG startAddr /* address to start from */ ) { int ix; ULONG alignBss; /* next boundry for common entry */ int nbytes; /* bytes for alignment + data */ int totalBytes = 0; /* total additional count for bss */ int auxEnts = 0; /* auxiliary symbol entries to skip */ /* calculate room for external commons in bss */ alignBss = startAddr; for (ix = 0; ix < nEnts; ix++, pSym++) { if (auxEnts) /* if this is an auxiliary entry */ { auxEnts--; continue; /* skip it */ } auxEnts = pSym->n_numaux; /* # of aux entries for this symbol */ if (PECOFF_COMM(pSym)) { nbytes = dataAlign(pSym->U_SYM_VALUE, alignBss) + pSym->U_SYM_VALUE; totalBytes += nbytes; alignBss += nbytes; } } return(totalBytes); }/********************************************************************************* dataAlign - determine address alignment for a data operand in memory* * The address of a data operand must be correctly aligned for data access.* This is architecture dependent. * Generally, data operands are aligned on 'natural' boundaries as follows:* bytes on byte boundaries (they already are)* half-word operands on half-word boundaries* word operands on word boundaries* double-word operands on double-word boundaries** However, if a structure of size = 7 had to be aligned, it would need* to be aligned on a boundary that is a multiple of 4 bytes.** RETURNS:* nbytes - number of bytes to be added to the address to obtain the* correct alignment for the data*/LOCAL ULONG dataAlign ( ULONG size, /* size of data to be aligned */ ULONG addr /* next possible address for data */ ) { ULONG nbytes; /* # bytes for alignment */ int align; /* address should be multiple of align */ if (size <= 1) align = 1; else if (size < 4) align = 2; else if (size < 8) align = 4; else if (size < 16) align = 8; else align = MAX_ALIGNMENT; /* max required alignment */ nbytes = addr % align; if (nbytes != 0) /* if not on correct boundary */ nbytes = align - nbytes; return(nbytes); }/********************************************************************************* bootPecoffModule - load an object module into memory** This routine loads an object module in PECOFF format from the specified* file, and places the code, data, and BSS at the locations specified within* the file. The entry point of the module is returned in <pEntry>. This * routine is generally used for bootstrap loading.** RETURNS:* OK, or* ERROR if the routine cannot read the file** SEE ALSO: loadModuleAt()*/STATUS bootPecoffModule ( int fd, /* fd from which to read load module */ FUNCPTR *pEntry /* entry point of module */ ) { FILHDR hdr; /* module's PECOFF header */ PEOPTION optHdr; /* module's PECOFF optional header */ int nBytes; char tempBuf[MAX_SCNS * SCNHSZ]; int tablesAreLE; /* read object module header */ if (pecoffHdrRead (fd, &hdr, &tablesAreLE) != OK) return (ERROR); /* read in optional header */ if (pecoffOpthdrRead (fd, &optHdr, tablesAreLE) != OK) return (ERROR); /* Read until start of text * * Section headers aren't needed, but this is the easiest way to * read passed them. */ if (pecoffSecHdrRead (fd, (SCNHDR *)tempBuf, &hdr, tablesAreLE) != OK) { return(ERROR); } printf ("%d", (int)optHdr.tsize); nBytes = fioRead (fd, (char *) optHdr.text_start, (int) optHdr.tsize); if (nBytes < optHdr.tsize) return (ERROR); printf (" + %d", (int)optHdr.dsize); nBytes = fioRead (fd, (char *) optHdr.data_start, (int) optHdr.dsize); if (nBytes < optHdr.dsize) return (ERROR); printf (" + %d\n", (int)optHdr.bsize); /* bss is zeroed by vxWorks startup code. */ *pEntry = (FUNCPTR) optHdr.entry; return (OK); }/******************************************************************************** bootPecoffInit - Initialize the system for pecoff load modules** This routine initialized VxWorks to use the PECOFF format for* boot loading modules.** RETURNS:* OK, or* ERROR if XXX** SEE ALSO: loadModuleAt()*/STATUS bootPecoffInit ( ) { /* XXX check for installed ? */ bootLoadRoutine = bootPecoffModule; return (OK); }#endif /* CPU==SIMNT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -