📄 loadcofflib.c
字号:
if (pScnHdr->s_align > pSeg->flagsText) pSeg->flagsText = pScnHdr->s_align;#else /* (CPU_FAMILY == I960) */ nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeText); /* SPR #21836 */ if (MAX_ALIGNMENT > pSeg->flagsText) pSeg->flagsText = MAX_ALIGNMENT;#endif /* (CPU_FAMILY == I960) */ pSeg->sizeText += pScnHdr->s_size + nbytes; } else if (pScnHdr->s_flags & STYP_DATA) {#if (CPU_FAMILY == I960) nbytes = dataAlign(pScnHdr->s_align, pSeg->sizeData); /* SPR #21836 */ if (pScnHdr->s_align > pSeg->flagsData) pSeg->flagsData = pScnHdr->s_align;#else /* (CPU_FAMILY == I960) */ nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeData); /* SPR #21836 */ if (MAX_ALIGNMENT > pSeg->flagsData) pSeg->flagsData = MAX_ALIGNMENT;#endif /* (CPU_FAMILY == I960) */ pSeg->sizeData += pScnHdr->s_size + nbytes; } else if (pScnHdr->s_flags & STYP_BSS) {#if (CPU_FAMILY == I960) nbytes = dataAlign(pScnHdr->s_align, pSeg->sizeBss); /* SPR #21836 */ if (pScnHdr->s_align > pSeg->flagsBss) pSeg->flagsBss = pScnHdr->s_align;#else /* (CPU_FAMILY == I960) */ nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeBss); /* SPR #21836 */ if (MAX_ALIGNMENT > pSeg->flagsBss) pSeg->flagsBss = MAX_ALIGNMENT;#endif /* (CPU_FAMILY == I960) */ pSeg->sizeBss += pScnHdr->s_size + nbytes; } } }/********************************************************************************* coffLoadSections - read sections into memory* */LOCAL STATUS coffLoadSections ( 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 */#if (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) textSize = 0; /* clear "real" text size */#endif /* (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) */ for (ix = 0; ix < max_scns; ix++) { pLoad = NULL; size = pScnHdr->s_size;#ifdef DEBUG DPRINTF("sec size=%#x sec ptr=%#x\n", size, pScnHdr->s_scnptr);#endif /* DEBUG */ if (size != 0 && pScnHdr->s_scnptr != 0) { if (pScnHdr->s_flags & STYP_TEXT) {#if (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) /* * if section is not .lit add its size to the "real" * text size. Note that this is a hack a better way * should be to add a pLit parameter to coffLoadSections(). * * Note: ARM rdata sections have both _LIT and _TEXT flags set. */ if (!(pScnHdr->s_flags & STYP_LIT)) textSize += size;#endif /* (CPU_FAMILY == AM29XXX) */ pLoad = pText;#if (CPU_FAMILY == I960) nbytes = dataAlign(pScnHdr->s_align, pLoad);#else /* (CPU_FAMILY == I960) */ nbytes = dataAlign(MAX_ALIGNMENT, pLoad);#endif /* (CPU_FAMILY == I960) */ pLoad += nbytes; pText = (char *) ((int) pLoad + size); /* for next load */ textCount += size + nbytes; } else if (pScnHdr->s_flags & STYP_DATA) { pLoad = pData;#if (CPU_FAMILY == I960) nbytes = dataAlign(pScnHdr->s_align, pLoad);#else /* (CPU_FAMILY == I960) */ nbytes = dataAlign(MAX_ALIGNMENT, pLoad);#endif /* (CPU_FAMILY == I960) */ pLoad += nbytes; pData = (char *) ((int) pLoad + size); /* for next load */ dataCount += size + nbytes; } else {#if (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) goto skipSection;#else /* ignore all other sections */ continue;#endif /* (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) */ } /* 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); } }#if (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM)skipSection:#endif /* (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) */ pScnAddr[ix] = pLoad; pScnHdr++; } return (OK); }/********************************************************************************* coffSymTab -** This is passed a pointer to a coff 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 coffSymTab ( int fd, 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 COFF section header array */ char **pScnAddr, /* pointer to section loaded address array */ BOOL symsAbsolute, /* TRUE if symbols already absolutely located*/ BOOL swapTables, UINT16 group ) { int status = OK; /* return status */ FAST 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 = 0; /* 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 COFF 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 */ 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 ( ! COFF_UNDF(symbol) && ! COFF_COMM(symbol)) { /* Symbol is not an undefined external. * * 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 */ { bias = 0; vxSymType = VX_ABS; } else if (scnFlags == STYP_REG) { printf ("Symbol %s from section of type STYP_REG. Ignored.\n", name); }#if (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) else if ((scnFlags & STYP_TEXT) && !(scnFlags & STYP_LIT))#else else if (scnFlags & STYP_TEXT)#endif /* (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) */ {#if (CPU_FAMILY == ARM) bias = (char *) (scnAddr + sprFixTextOff[symbol->n_scnum - 1] - (char *) pScnHdr->s_vaddr);#else bias = (char *) (scnAddr - (char *) pScnHdr->s_vaddr);#endif /* (CPU_FAMILY == ARM) */ vxSymType = VX_TEXT; } else if (scnFlags & STYP_DATA) { bias = (char *) (scnAddr - (char *) pScnHdr->s_vaddr); vxSymType = VX_DATA; } else if (scnFlags & STYP_BSS) { bias = (char *) (scnAddr - (char *) pScnHdr->s_vaddr); vxSymType = VX_BSS; } /* If it has the NOLOAD or INFO bit set, ignore it silently */ else if ((scnFlags & STYP_NOLOAD) || (scnFlags & STYP_INFO)) { continue; }#if (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) /* * If section is .lit it will be located just behind the text * section. We use the global variable textSize to determine * the end of the "real" text. A better solution would be to * add fieds for the .lit section in the SEG_INFO structure. * Note that the following test is always false for the i960 * architecture. */ else if (scnFlags & STYP_LIT) {#if (CPU_FAMILY == ARM) bias = (char *)((char *) pSeg->addrText + sprFixTextOff[symbol->n_scnum - 1] - (char *)pScnHdr->s_vaddr);#else bias = (char *)((char *) pSeg->addrText + textSize - (char *)pScnHdr->s_vaddr);#endif /* (CPU_FAMILY == ARM) */ vxSymType = VX_TEXT; } else if (COFF_UNASSIGNED(symbol)) continue;#endif /* (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) */ else { printErr (cantConvSymbolType, name, errnoGet()); continue; } /* If object file is already absolutely located * (by linker on host), * then the symbol values are already correct. * There is no need to bias them. */ if (symsAbsolute) { bias = 0x00; }#ifdef DEBUG DPRINTF("symbol=%#x bias=%#x vaddr=%#x type=%#x ", (int)symbol, (int)bias, (int)pScnHdr->s_vaddr, vxSymType);#endif /* DEBUG */ /* Determine if symbol should be put into symbol table. */ if (((symFlag & LOAD_LOCAL_SYMBOLS) && !COFF_EXT(symbol)) || ((symFlag & LOAD_GLOBAL_SYMBOLS) && COFF_EXT(symbol))) { if (COFF_EXT(symbol)) vxSymType |= VX_EXT;#if (CPU_FAMILY == I960) if ( (symbol->n_sclass == C_LEAFEXT) || (symbol->n_sclass == C_LEAFSTAT)) { vxSymType |= BAL_ENTRY; /* can call with branch & link */ }#endif /* (CPU_FAMILY == I960) */ /* Add symbol to symbol table. */#if ((CPU_FAMILY == ARM) && ARM_THUMB) /* * Make sure we flag any functions so that relocator knows * to set bit zero */ if ((scnFlags & STYP_TEXT) && ((unsigned char)symbol->n_sclass == C_THUMBEXTFUNC || (unsigned char)symbol->n_sclass == C_THUMBSTATFUNC)) { vxSymType |= SYM_THUMB; }#endif /* CPU_FAMILY == ARM */ if (symSAdd (symTbl, name, symbol->U_SYM_VALUE + bias, vxSymType, group) != OK) printErr (cantAddSymErrMsg, name, errnoGet()); }#if ((CPU_FAMILY == ARM) && ARM_THUMB) /* * Make sure we set bit zero of the addresses of any static * functions
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -