📄 loadsomcofflib.c
字号:
* SPR #21836: loadSegmentsAllocate() allocate memory aligned on * the max value of sections alignement saved in seg.flagsText, * seg.flagsData, seg.flagsBss. */ if (loadSegmentsAllocate (&seg) != OK) { printErr ("Could not allocate segments\n"); goto error; } /* * make sure all allocated segments are aligned OK. * This will always be true if the memory is malloc'ed, * since SEG_ALIGN, and _MEM_ALIGN, and the maximum * possible subspace alignment are all "8" */ pText = (char *) ROUND_UP (seg.addrText, SEG_ALIGN); pData = (char *) ROUND_UP (seg.addrData, SEG_ALIGN); pBss = (char *) ROUND_UP (seg.addrBss, SEG_ALIGN); pComm = (char *) ((int)pBss + seg.sizeBss - ROUND_UP(commSize, SEG_ALIGN)); if ( (pText != seg.addrText) || (pData != seg.addrData) || (pBss != seg.addrBss) ) { printErr ("loadModuleAtSym: segment alignment error\n"); goto error; } DBG_PUT ("pText = 0x%x, pData = 0x%x, pBss = 0x%x pComm = 0x%x\n", (int)pText, (int)pData, (int)pBss, (int)pComm); DBG_PUT ("sizeText = 0x%x, sizeData = 0x%x, sizeBss = 0x%x\n", seg.sizeText, seg.sizeData, seg.sizeBss); /* load all subspaces into memory */ if (loadSubspaces (fd, &somHdr, pSubInfo, pSubspace, pText, pData, pBss) != OK) { errno = S_loadSomCoffLib_LOAD_SPACE; goto error; } /* add segment names to symbol table before other symbols */ if (!(symFlag & LOAD_NO_SYMBOLS)) addSegNames (fd, pText, pData, pBss, symTbl, group); /* process symbol table */ status = rdSymtab (pSymBuf, somHdr.symbol_total, pSubspace, pSubInfo, symFlag, symTbl, &pGlobal, pComm, group); /* Perform linker fixup requests on the subspaces */ if (somHdr.version_id == NEW_VERSION_ID) { if (somHdr.fixup_request_total != 0) (void) linkSubspaces ((UCHAR *) pReloc, pSubspace, somHdr.subspace_total, pSubInfo, pSymBuf, somHdr.symbol_total, symTbl, pGlobal, moduleId); } else { errno = S_loadSomCoffLib_RELOC_VERSION; 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); /* flush text to memory */ CACHE_TEXT_UPDATE (pText, seg.sizeText); /* * 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); /* error: * clean up dynamically allocated temporary buffers and return ERROR */error:done: if (pSubInfo != NULL) free ((char *) pSubInfo); if (pSpaceStrings != NULL) free ((char *) pSpaceStrings); if (pSpace!= NULL) free ((char *) pSpace); if (pSubspace!= NULL) free ((char *) pSubspace); if (pSymBuf != NULL) free ((char *) pSymBuf); if (pSymStr != NULL) free ((char *) pSymStr); if (pReloc!= NULL) free ((char *) pReloc); if (status == OK) return (moduleId); else { moduleDelete (moduleId); return (NULL); } }/******************************************************************************** symbolNameSet - make all symbols records point to their name strings*/ static void symbolNameSet ( SYMREC * pSym, /* pointer to symbol table */ int nSyms, /* # of entries in symbol table */ char * pSymStr, /* pointer to symbol string table */ SUBSPACE * pSubspace, /* pointer to subspace dictionary */ int nSubs, /* number of subspaces */ char * pSpaceStr, /* pointer to space name string table */ SPACE * pSpace, /* pointer to space dictionary */ int nSpaces /* number of spaces */ ) { int ix; for (ix = 0; ix < nSyms; ix++) pSym[ix].symbol_name = pSymStr + pSym[ix].name.n_strx; for (ix = 0; ix < nSubs; ix++) pSubspace[ix].subspace_name = pSpaceStr + pSubspace[ix].name.n_strx; for (ix = 0; ix < nSpaces; ix++) pSpace[ix].space_name = pSpaceStr + pSpace[ix].name.n_strx; }/********************************************************************************* commSizeGet - this routine go through the symbol table to calculate the * size of STORAGE data for relocatable files** STORAGE requests (i.e., "common data") are simply turned into BSS* by this loader (and all other VxWorks loaders). The loader adds* an area for these symbols by increasing the normal BSS area.* This allows us to not have to malloc memory for each STORAGE symbol.** As a side effect, all the STORAGE symbols are partially relocated.* That is - the symbol_value field of the symbols SYMREC structure* is turned into an offset from the start of the STORAGE segment*/static void commSizeGet ( SYMREC * pSymBuf, /* symbol dictionary */ int nEnts, /* number of symbols */ SUBSPACE *pSubspace, /* subspace relocation info */ int * pCommSize /* where to return comm size */ ) { SYMREC * pSym = pSymBuf; int size = 0; int subspaceIndex; int ix; int iy; SYMREC * pSearch; int symSize; for (ix = 0; ix < nEnts; ix ++) { if (pSym->symbol_type == ST_STORAGE) { pSearch = pSymBuf; /* XXX - search for the previous record for same symbol * in symbol table. For some reason STORAGE symbols * sometime appear in pairs. */ for (iy = 0; iy < ix; iy ++) { if (strcmp(pSym->symbol_name, pSearch->symbol_name) == 0) break; pSearch ++; } /* deal with a new storage symbol */ if (iy == ix) { subspaceIndex = pSym->symbol_info; size = ROUND_UP (size, pSubspace[subspaceIndex].alignment); symSize = pSym->symbol_value; pSym->symbol_value = size; size += symSize; pSym->secondary_def = 0; } /* duplicate storage symbol */ else { pSym->secondary_def = 1; } } pSym ++; } *pCommSize = size; }/********************************************************************************* rdSymtab - Process the VxWorks symbol table** This is passed a pointer to an HP-PA SOM symbol table and processes* each of the external symbols defined therein. This processing performs* two functions:* 1) New symbols are entered in the system symbol table as* specified by the "symFlag" argument:* ALL_SYMBOLS = all defined symbols (LOCAL and GLOBAL) are added,* GLOBAL_SYMBOLS = only external (GLOBAL) symbols are added,* NO_SYMBOLS = no symbols are added;* 2) Undefined externals are looked up in the system table.* If an undefined external cannot be found in the 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* reported.** Absolute symbols are automatically discarded.** RETURNS: OK or ERROR*/static STATUS rdSymtab ( SYMREC * pSymBuf, /* pointer to symbol table */ FAST int nEnts, /* # of entries in symbol table */ SUBSPACE * pSubspace, /* pointer to subspace dictionary */ SUB_INFO * pSubInfo, /* subspace relocation info */ int symFlag, /* symbols to be added to table * ([NO|GLOBAL|ALL]_SYMBOLS) */ SYMTAB_ID symTbl, /* symbol table to use */ SYMREC ** pSymGlobal, /* '$global$' symbol entry pointer */ char * pComm, /* start of comm area (within bss segment) */ int group /* symbol group */ ) { char * name; /* symbol name (plus EOS) */ SYMREC * pSym = (SYMREC *) pSymBuf; /* symbol entry pointer */ int ix; /* symbols subspace index */ SYM_TYPE vxSymType; /* symbol type */ UCHAR arg_reloc; /* argument relocation info */ int status = OK; /* return status */ *pSymGlobal = NULL; for (; nEnts > 0; nEnts -= 1, pSym ++) { /* throw away absolute symbols */ if (pSym->symbol_type == ST_ABSOLUTE) continue; /* throw away symbol and argument extentions */ if (pSym->symbol_type == ST_SYM_EXT) continue; if (pSym->symbol_type == ST_ARG_EXT) continue; /* throw away invalid symbols */ if (pSym->symbol_type == ST_NULL) continue; /* get the symbol name */ name = pSym->symbol_name; /* keep the symbol $global$ handy */ if ( (pSym->symbol_type == ST_DATA) && (!strcmp(name, "$global$")) ) *pSymGlobal = pSym; if (!pSubspace[pSym->symbol_info].is_loadable) WARN ("Warning: symbol %s is unloadable!\n", name); if (pSym->must_qualify) WARN ("Warning: symbol %s must qualify!\n", name); if (pSym->is_common || pSym->dup_common) WARN ("Warning: symbol %s is a common block!\n", name); /* add new symbols to the symbol table */ if ((pSym->symbol_scope == SS_UNIVERSAL) || (pSym->symbol_scope == SS_LOCAL)) { /* relocate the symbol relative to it's associated subspace */ ix = pSym->symbol_info; pSym->symbol_value = pSym->symbol_value - pSubspace[ix].subspace_start + (unsigned int)pSubInfo[ix].loadAddr; switch (pSym->symbol_type) { /* Data or BSS symbols */ case ST_DATA: if (pSubInfo[ix].loadType == LOAD_BSS) { vxSymType = N_BSS; DBG_PUT ("new BSS symbol %s (0x%x)\n", name, pSym->symbol_value); } else { vxSymType = N_DATA; DBG_PUT ("new DATA symbol %s (0x%x)\n", name, pSym->symbol_value); } arg_reloc = 0; break; /* Text symbols */ case ST_CODE: case ST_PRI_PROG: case ST_SEC_PROG: case ST_MILLICODE: case ST_ENTRY: vxSymType = N_TEXT | ((UCHAR)(pSym->arg_reloc & 3) << 6); arg_reloc = (UCHAR)(pSym->arg_reloc >> 2); pSym->symbol_value &= 0xfffffffc; break; /* ignore stubs */ case ST_STUB: continue; /* These have never popped up yet */ case ST_MODULE: case ST_PLABEL: case ST_OCT_DIS: case ST_MILLI_EXT: default: WARN ("Warning: symbol %s is of type %d\n", name, pSym->symbol_type); continue; } if ( (pSym->symbol_scope == SS_UNIVERSAL) && (!pSym->hidden) ) vxSymType |= N_EXT; if ( ((symFlag & LOAD_LOCAL_SYMBOLS) && !(vxSymType & N_EXT)) || ((symFlag & LOAD_GLOBAL_SYMBOLS) && (vxSymType & N_EXT)) ) { DBG_PUT ("adding symbol %s to symTbl\n", name); if (externSymAdd (symTbl, name, (char*)pSym->symbol_value, vxSymType, group, arg_reloc) != OK) { printErr ("can't add symbol %s (errno=%#x)\n", name, errnoGet()); } } } /* Add STORAGE (common) symbols as BSS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -