📄 loadlib.c
字号:
pSeg->sizeText)) == NULL) return (ERROR); } else { if ((pSeg->addrText = (char *) malloc (pSeg->sizeText)) == NULL) return (ERROR); } pSeg->flagsText |= SEG_FREE_MEMORY; } if (pSeg->addrData == LD_NO_ADDRESS && pSeg->sizeData != 0) { /* SPR #21836 */ if (dataAlignment != 0) { if ((pSeg->addrData = (char *) memalign (dataAlignment, pSeg->sizeData)) == NULL) return (ERROR); } else { if ((pSeg->addrData = (char *) malloc (pSeg->sizeData)) == NULL) return (ERROR); } pSeg->flagsData |= SEG_FREE_MEMORY; } if (pSeg->addrBss == LD_NO_ADDRESS && pSeg->sizeBss) { /* SPR #21836 */ if (bssAlignment != 0) { if ((pSeg->addrBss = (char *) memalign (bssAlignment, pSeg->sizeBss)) == NULL) return (ERROR); } else { if ((pSeg->addrBss = (char *) malloc (pSeg->sizeBss)) == NULL) return (ERROR); } pSeg->flagsBss |= SEG_FREE_MEMORY; } return (OK); }/********************************************************************************* loadCommonMatch - support routine for loadCommonManage** This is the support routine for all loadCommonManage() function.* It fills the pSymAddr<type> fields of a COMMON_INFO structure if a global* symbol matches the name of the common symbol.** For each symbol type (SYM_DATA, SYM_BSS), the most recent occurence* of a matching symbol in the target symbol table is recorded.** RETURN : OK always.** NOMANUAL*/STATUS loadCommonMatch ( COMMON_INFO * pCommInfo, /* what to do with commons */ SYMTAB_ID symTblId /* ID of symbol table to look in */ ) { int nodeIdx; /* index of node of interest */ int mask; HASH_ID hashId = symTblId->nameHashId; /* id of hash table */ SYMBOL matchSymbol; /* matching symbol */ SYMBOL * pSymNode = NULL; /* symbol in node's link list */ SYM_TYPE basicType; /* symbol's basic type */ /* initialize symbol's characteristics to match */ matchSymbol.name = pCommInfo->symName; matchSymbol.type = SYM_MASK_NONE; /* get corresponding node index into hash table */ nodeIdx = (* hashId->keyRtn)(hashId->elements, (HASH_NODE *) &matchSymbol, hashId->keyArg); /* get first symbol in the node's linked list */ pSymNode = (SYMBOL *) SLL_FIRST (&hashId->pHashTbl [nodeIdx]); /* walk the node's linked list until we reach the end */ while(pSymNode != NULL) { /* * If the core's symbols are excluded from the search and the global * symbol is a core's symbol (group 0), jump to the next symbol. * If the symbol's name doesn't match the common symbol's name, jump * to the next symbol. */ mask = SYM_BASIC_MASK; if(!((pCommInfo->vxWorksSymMatched == FALSE) && (pSymNode->group == 0)) && (strcmp (pCommInfo->symName, pSymNode->name) == 0)) { /* extract symbol's basic type */ /* * since SYM_BASIC_MASK does not properly mask out SYM_COMM * we have to apply another mask to mask out bit two. Since * bit two can be SYM_ABS, we have to check for SYM_COMM first */ if ((pSymNode->type & SYM_COMM)== SYM_COMM) mask = SYM_BASIC_NOT_COMM_MASK; basicType = pSymNode->type & mask; /* * Record the global symbol's address accordingly with its type, * then jump to the next symbol. * Note that we only record the last occurence of the symbol in * the symbol table. */ if((basicType == (SYM_BSS | SYM_GLOBAL)) && (pCommInfo->pSymAddrBss == NULL)) { pCommInfo->pSymAddrBss = (void *) pSymNode->value; pCommInfo->bssSymType = pSymNode->type; } else if((basicType == (SYM_DATA | SYM_GLOBAL)) && (pCommInfo->pSymAddrData == NULL)) { pCommInfo->pSymAddrData = (void *) pSymNode->value; pCommInfo->dataSymType = pSymNode->type; } } /* point to next symbol in the node's linked list */ pSymNode = (SYMBOL *) SLL_NEXT ((HASH_NODE *)pSymNode); } return (OK); }/********************************************************************************* loadCommonManage - 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. Good programming avoids such declarations since* it is almost impossible to be sure what initialized global symbol* should be used to solve a common symbol relocation. The processing* of common symbols depends on the following control flags, which* enforce one of three levels of strictness for common symbol* evaluation: * LOAD_COMMON_MATCH_NONE* This is the default option. Common symbols are kept isolated,* visible from the object module only. This option prevents any* matching with already-existing symbols (in other words, the* relocations that refer to these symbols are kept local). Memory is* allocated and symbols are added to the symbol table with type* SYM_COMM unless LOAD_NO_SYMBOLS is set.* LOAD_COMMON_MATCH_USER* The loader seeks a matching symbol in the target symbol table, but* only symbols brought by user's modules are considered. If no* matching symbol exists, it acts like LOAD_COMMON_MATCH_NONE. If* several matching symbols exist, the order of preference is: symbols* in the bss segment, then symbols in the data segment. If several* matching symbols exist within a segment type, memory is allocated* and the symbol most recently added to the target symbol table is* used as reference.* LOAD_COMMON_MATCH_ALL* The loader seeks for a matching symbol in the target symbol table.* All symbols are considered. If no matching symbol exists, then it* acts like LOAD_COMMON_MATCH_NONE. If several matches are found, the* order is the same as for LOAD_COMMON_MATCH_USER.** RETURNS* OK or ERROR if the memory allocation or the addition to the symbol table* fails.** SEE ALSO* API Programmer's Guide: Object Module Loader** INTERNAL* Note that with LOAD_COMMON_MATCH_USER, and moreover* LOAD_COMMON_MATCH_ALL, it is not possible to know whether the symbol* used for the evaluation is the right symbol. For instance, consider* a module A defining "int evtAction = 0;", a module B defining "int* evtAction;". The symbol "evtAction" is declared as common in B* module. If B module is loaded before A module, and if* LOAD_COMMON_MATCH_ALL is set, the loader will use the vxWorks'* global symbol evtAction to solve this common symbol...* It is therefore up to the user to download in the right order his* modules, or use the right flag, or even better, to not use common* symbols at all. Note also that no search is done for previous* common symbol.** NOMANUAL **/STATUS loadCommonManage ( int comAreaSize, /* size of area required for common sym */ int comAlignment, /* alignment required for common sym */ 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 */ SEG_INFO * pSeg, /* section addresses and sizes */ int group /* module group */ ) { 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, otherwise apply * LOAD_COMMON_MATCH_NONE management. */ if(*pSymAddr != NULL) return (OK); } /* If additional info is available then we are dealing with a PowerPC */#ifdef INCLUDE_SDA if(pSeg->pAdnlInfo != NULL) *pSymType = SYM_SDA | SYM_BSS | SYM_COMM | SYM_GLOBAL; else#endif /* INCLUDE_SDA */ *pSymType = SYM_BSS | SYM_COMM | SYM_GLOBAL; /* * Allocate memory for new symbol. This must be done even if flag * LOAD_NO_SYMBOLS is applied (SPR #9259). */ #ifdef INCLUDE_SDA if (pSeg->pAdnlInfo != NULL) { if (comAlignment != 0) *pSymAddr = (void *) memPartAlignedAlloc (((SDA_INFO *)pSeg->pAdnlInfo)->sdaMemPartId, comAreaSize, comAlignment); else *pSymAddr = (void *) memPartAlloc (((SDA_INFO *)pSeg->pAdnlInfo)->sdaMemPartId, comAreaSize); } else#endif /* INCLUDE_SDA */ { if (comAlignment != 0) *pSymAddr = (void *) memalign (comAlignment, comAreaSize); else *pSymAddr = (void *) malloc (comAreaSize); } if (*pSymAddr == NULL) return (ERROR); memset ((SYM_ADRS)*pSymAddr, 0, comAreaSize); /* Add symbol to the target symbol table if required */ if(!(loadFlag & LOAD_NO_SYMBOLS) && (loadFlag & LOAD_GLOBAL_SYMBOLS)) { if(symSAdd (symTbl, symName, (char *)*pSymAddr, *pSymType, (UINT16) group) != OK) { printErr ("Can't add '%s' to symbol table.\n", symName); *pSymAddr = NULL; return (ERROR); } } return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -