📄 loadaoutlib.c
字号:
if (((symFlag & LOAD_LOCAL_SYMBOLS) && !(symbol.U_SYM_TYPE & N_EXT)) || ((symFlag & LOAD_GLOBAL_SYMBOLS) && symbol.U_SYM_TYPE & N_EXT)) { switch (symbol.U_SYM_TYPE & N_TYPE) { case N_ABS: bias = 0; break; case N_DATA: bias = pSeg->addrData - pSeg->sizeText; break; case N_BSS: bias = pSeg->addrBss - pSeg->sizeText - pSeg->sizeData; break; default: bias = pSeg->addrText; break; } if (symSAdd (symTbl, name, symbol.U_SYM_VALUE + bias, symbol.U_SYM_TYPE, group) != OK) printErr (cantAddSymErrMsg, name, errno); } } else { /* * undefined external symbol or "common" symbol - common * symbol type is denoted by undefined external with the * value set to non-zero. If symbol is a common, call * loadCommonManage() to process. Alignment information * is not specified by a.out so '0' is passed as an * alignment parameter to loadCommonManage. */ if (symbol.U_SYM_VALUE != 0) { if (loadCommonManage (symbol.U_SYM_VALUE, 0, name, symTbl, (void *) &adrs, &type, symFlag, pSeg, group) != OK) status = ERROR; } /* look up undefined external symbol in symbol table */ else if (symFindByNameAndType (symTbl, name, &adrs, &type, N_EXT, N_EXT) != OK) { /* symbol not found in symbol table */ printErr ("undefined symbol: %s\n", name); adrs = NULL; status = ERROR; } /* add symbol address to externals table, but first * check for enough room in 'externals' table */ if (sym_num == max_symbols) { /* no more room in symbol table - * make externals table half as big again */ max_symbols += max_symbols / 2; *externals = (char **) realloc ((char *) *externals, (unsigned) max_symbols * sizeof (char *)); if (*externals == NULL) return (ERROR); } (*externals) [sym_num] = adrs; /* enter address in table */ } } return (status); }#if CPU_FAMILY == SPARC/********************************************************************************* relSegmentSparc - perform relocation commands for a SPARC segment** This routine reads the specified relocation command segment and performs* all the relocations specified therein. External relocations are looked * up in the 'externals' table. All other relocations are relative to how * much a particular segment has moved. ** RETURNS: OK or ERROR*/LOCAL STATUS relSegmentSparc ( int fd, /* fd of file positioned to reloc commands */ int nbytes, /* # of bytes of reloc commands for this seg */ FAST char * segAddress, /* addr of segment being relocated */ SEG_INFO * pSeg, /* pointer to segment information */ char ** externals /* addresses of external symbols */ ) { ULONG * pAddr; /* address in memory to receive relocated val */ RINFO_SPARC rinfo; /* relocation command goes here */ ULONG relVal; /* relocated value to be put into memory */ for (; nbytes > 0; nbytes -= sizeof (rinfo)) { /* read relocation command */ if (fioRead (fd, (char *) &rinfo, sizeof (rinfo)) != sizeof (rinfo)) return (ERROR); /* calculate actual address in memory that needs relocation, * and perform external or segment relative relocation */ pAddr = (ULONG *) ((ULONG) segAddress + (ULONG) rinfo.r_address); if (rinfo.r_extern) relVal = (ULONG) externals[rinfo.r_index] + rinfo.r_addend; else switch (rinfo.r_index & N_TYPE) { case N_TEXT: relVal = (ULONG) pSeg->addrText + rinfo.r_addend; break; case N_DATA: relVal = ((ULONG) pSeg->addrData - pSeg->sizeText) + rinfo.r_addend; break; case N_BSS: relVal = ((ULONG) pSeg->addrBss - pSeg->sizeText - pSeg->sizeData) + rinfo.r_addend; break; default: logMsg ("Invalid relocation index %d\n", rinfo.r_addend, 0, 0, 0, 0, 0); return (ERROR); break; } switch (rinfo.r_type) { case RELOC_8: *(UINT8 *) pAddr = relVal; break; case RELOC_16: *(USHORT *) pAddr = relVal; break; case RELOC_32: *pAddr = relVal; break; case RELOC_DISP8: *(UINT8 *) pAddr = relVal - (ULONG) segAddress; break; case RELOC_DISP16: *(USHORT *) pAddr = relVal - (ULONG) segAddress; break; case RELOC_DISP32: *pAddr = relVal - (ULONG) segAddress; break; case RELOC_WDISP30: STORE_MASKED_VALUE (pAddr, 0x3fffffff, (((ULONG) relVal - (ULONG) segAddress) >> 2)); break; case RELOC_WDISP22: STORE_MASKED_VALUE (pAddr, 0x003fffff, (((ULONG) relVal - (ULONG) segAddress) >> 2)); break; case RELOC_HI22: STORE_MASKED_VALUE (pAddr, 0x003fffff, relVal >> 10); break; case RELOC_22: STORE_MASKED_VALUE (pAddr, 0x003fffff, relVal); break; case RELOC_13: STORE_MASKED_VALUE (pAddr, 0x00001fff, relVal); break; case RELOC_LO10: STORE_MASKED_VALUE (pAddr, 0x000003ff, relVal); break; case RELOC_SFA_BASE: case RELOC_SFA_OFF13: case RELOC_BASE10: case RELOC_BASE13: case RELOC_BASE22: case RELOC_PC10: case RELOC_PC22: case RELOC_JMP_TBL: case RELOC_SEGOFF16: case RELOC_GLOB_DAT: case RELOC_JMP_SLOT: case RELOC_RELATIVE: default: logMsg ("Unknown relocation type %d\n", rinfo.r_type, 0, 0, 0, 0, 0); return (ERROR); break; } } return (OK); }#else/********************************************************************************* relSegment68k - perform relocation commands for a 680X0 segment** This routine reads the specified relocation command segment and performs* all the relocations specified therein.* External relocations are looked up in the 'externals' table.* All other relocations are relative to how much a particular segment has moved.** RETURNS: OK or ERROR*/LOCAL STATUS relSegment68k ( int fd, /* fd of file positioned to reloc commands */ int nbytes, /* # of bytes of reloc commands for this seg */ FAST char * segAddress, /* addr of segment being relocated */ SEG_INFO * pSeg, /* pointer to segment information */ char ** externals /* addresses of external symbols */ ) { FAST char **pAddress; FAST char *textAddress = pSeg->addrText; RINFO_68K rinfo; /* relocation command goes here */ for (; nbytes > 0; nbytes -= sizeof (rinfo)) { /* read relocation command */ if (fioRead (fd, (char *) &rinfo, sizeof (rinfo)) != sizeof (rinfo)) { return (ERROR); } /* calculate actual address in memory that needs relocation, * and perform external or segment relative relocation */ pAddress = (char **) (segAddress + rinfo.r_address); if (rinfo.r_extern) { if (rinfo.r_length != 2) printErr (nonLongErrMsg, pAddress, rinfo.r_length); else { /* add external address to relocatable value */ *pAddress += (int) externals [rinfo.r_symbolnum]; /* relocations marked pc-relative were done assuming * text starts at 0. Adjust for actual start of text. */ if (rinfo.r_pcrel) *pAddress -= (int) textAddress; } } else { /* pc-relative internal references are already ok. * other internal references need to be relocated relative * to start of the segment indicated by r_symbolnum. */ if (!rinfo.r_pcrel) { if (rinfo.r_length != 2) printErr (nonLongErrMsg, pAddress, rinfo.r_length); else { /* some compiler's a.out may have the external bit set * -- just ignore */ switch (rinfo.r_symbolnum & N_TYPE) { /* Text, data, and bss may not be contiguous * in vxWorks (unlike UNIX). Relocate by * calculating the actual distances that a * segment has moved. */ case N_ABS: break; case N_TEXT: *pAddress += (int) textAddress; break; case N_DATA: *pAddress += (int) pSeg->addrData - pSeg->sizeText; break; case N_BSS: *pAddress += (int) pSeg->addrBss - pSeg->sizeText - pSeg->sizeData; break; default: printErr ("Unknown symbol number = %#x\n", rinfo.r_symbolnum); } } } } } return (OK); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -