📄 loadsomcofflib.c
字号:
/* The entry point to the loader */static MODULE_ID ldSomCoffMdlAtSym (int fd, int symFlag, char **ppText, char **ppData, char **ppBss, SYMTAB_ID symTbl); /* primary loader support functions */static void symbolNameSet (SYMREC *pSym, int nSyms, char *pSymStr, SUBSPACE *pSubspace, int nSubs, char *pSpaceStr, SPACE *pSpace, int nSpaces);static void subspaceToSegment (SOM_HDR *pHpHdr, UCHAR *pRelocCmds, SUB_INFO *pSubInfo, SPACE *pSpace, SUBSPACE *pSubspace, SYMREC *pSym, SYMTAB_ID symTbl, int *pTextSize, int *pDataSize, int *pBssSize);static int subspaceSizeExtra (UCHAR *pRelCmds, SUBSPACE *pSubspace, SYMREC *pSym, int numSyms, SYMTAB_ID symTbl);static void subspaceNoReloc (SOM_HDR *pHpHdr, SUB_INFO * pSubInfo, SUBSPACE * pSubspace);static void commSizeGet (SYMREC *pSym, int nEnts, SUBSPACE *pSubspace, int *pCommSize);static STATUS rdSymtab (SYMREC * pSym, FAST int nEnts, SUBSPACE *pSubspace, SUB_INFO *pSubInfo, int symFlag, SYMTAB_ID symTbl, SYMREC **pSymGlobal, char *pComm, int group);static STATUS loadSubspaces (int fd, SOM_HDR *pHpHdr, SUB_INFO *pSubInfo, SUBSPACE *pSubspace, char *pText, char *pData, char *pBss);static STATUS linkSubspaces (UCHAR *pRelCmds, SUBSPACE *pScnHdr, int numSubspace, SUB_INFO *pSubInfo, SYMREC *pSym, int numSyms, SYMTAB_ID pSymTab, SYMREC *pSymGlobal, MODULE_ID moduleId); /* Symbol table manipulation functions */static BOOL externSymResolve (SYMTAB_ID symTblId, char * name, SYMREC *pSym);static BOOL externSymAdd (SYMTAB_ID symTblId, char * name, char *value, SYM_TYPE type, UINT16 group, UCHAR arg_reloc); /* "argument relocation stub" functions */static BOOL argRelocDiffer (int arg_reloc1, int arg_reloc2);static char *argRelocStubListFind (LIST *stubList, SYMREC *pSym, int arg_reloc, MODULE_ID moduleId);static void rbitsShow (int rbits);static int rbits1 (int x);static int rbits2 (int x); /* "long branch stub" manipulation functions */static int stubListFind (LIST *stubList, int symNum, int arg_reloc);static int stubListAdd (LIST *stubList, int symNum, int arg_reloc);static void stubInit (char *stubAddr, char *procAddr); /* stack unwind manipulation functions */static void unwindListAdd (LIST *unwindList, UNWIND_NODE *pUnwindNode);static void unwindSegmentCreate (LIST *unwindList, MODULE_ID moduleId);int loadSomCoffDebug = 0;#define DBG_PUT if (loadSomCoffDebug == 1) printfint loadSomCoffWarn = 0;#define WARN if (loadSomCoffWarn == 1) printf/********************************************************************************* loadSomCoffInit - initialize the system for HP-PA SOM COFF load modules** This routine initialized VxWorks to use an extended HP-PA SOM COFF format for* loading modules.** RETURNS: OK** SEE ALSO: loadModuleAt()*/STATUS loadSomCoffInit (void) { loadRoutine = (FUNCPTR) ldSomCoffMdlAtSym; return (OK); }/******************************************************************************** ldSomCoffMdlAtSym - load object module into memory with symbol table** This routine is the underlying routine to loadModuleAtSym(). This interface* allows specification of the the symbol table used to resolve undefined* external references and to which to add new symbols.** RETURNS:* MODULE_ID, or* NULL if can't read file or not enough memory or illegal file format*/ static MODULE_ID ldSomCoffMdlAtSym ( FAST int fd, /* fd from which to read module */ int symFlag, /* symbols to be added to table * ([NO | GLOBAL | ALL]_SYMBOLS) */ char ** ppText, /* load text segment at address pointed to by this * pointer, return load address via this pointer */ char ** ppData, /* load data segment at address pointed to by this * pointer, return load address via this pointer */ char ** ppBss, /* load bss segment at address pointed to by this * pointer, return load address via this pointer */ SYMTAB_ID symTbl /* symbol table to use */ ) { char * pText = (ppText == NULL) ? LD_NO_ADDRESS : *ppText; char * pData = (ppData == NULL) ? LD_NO_ADDRESS : *ppData; char * pBss = (ppBss == NULL) ? LD_NO_ADDRESS : *ppBss; char * pComm; int textSize; int dataSize; int bssSize; int commSize; /* gets added to bssSize */ int status = ERROR; /* function return value */ SEG_INFO seg; /* file segment info */ char fileName[255]; /* file being loaded */ UINT16 group; /* loader group */ MODULE_ID moduleId; /* module ID */ SOM_HDR somHdr; /* SOM header */ SPACE * pSpace = NULL; /* space dictionary */ int spaceSize; /* number of spaces */ SUBSPACE *pSubspace = NULL; /* subspace dictionary */ int subspaceSize; /* number of subspaces */ char * pSpaceStrings = NULL; /* space/subspace names */ SYMREC * pSymBuf = NULL; /* symbol record dictionary */ int symBufSize; /* number of symbols */ char * pSymStr = NULL; /* symbol names */ FIXUP * pReloc = NULL; /* linker fixup requests */ int relSize; /* size of fixup requests */ SUB_INFO *pSubInfo = NULL; /* subspace load info */ SYMREC * pGlobal = NULL; /* the symbol "$global$" */ /* initialization */ memset ((void *)&seg, 0, sizeof (seg)); /* Get the name of the file we are loading */ if (ioctl (fd, FIOGETNAME, (int) fileName) == ERROR) { printErr ("ldSomCoffMdlAtSym: can't get filename\n"); return (NULL); } if ((moduleId = loadModuleGet (fileName, MODULE_ECOFF, &symFlag)) == NULL) return (NULL); group = moduleId->group; /* read the SOM header */ bzero ((char *) &somHdr, sizeof(SOM_HDR)); if (read (fd, (char *)&somHdr, sizeof (SOM_HDR)) != sizeof(SOM_HDR)) { errno = S_loadSomCoffLib_HDR_READ; goto error; } /* check object file type - only relocatable and executable are supported */ if (somHdr.a_magic != RELOC_MAGIC && somHdr.a_magic != EXEC_MAGIC && somHdr.a_magic != SHARE_MAGIC) { printErr ("ldSomCoffMdlAtSym: bad magic #%#x\n", somHdr.a_magic); errno = S_loadSomCoffLib_OBJ_FMT; goto error; } /* read in space dictionary */ if (somHdr.space_total != 0) { spaceSize=somHdr.space_total*sizeof(struct space_dictionary_record); if ((pSpace = calloc (1, spaceSize)) == NULL) { errno = S_loadSomCoffLib_SPHDR_ALLOC; goto error; } if (ioctl (fd, FIOSEEK, somHdr.space_location) == ERROR || read (fd, (char*)pSpace, spaceSize) != spaceSize) { errno = S_loadSomCoffLib_SPHDR_READ; goto error; } } /* read in subspace dictionary */ if (somHdr.subspace_total != 0) { subspaceSize = somHdr.subspace_total * SBPSZ; if ((pSubspace = calloc (1, subspaceSize)) == NULL) { errno = S_loadSomCoffLib_SUBSPHDR_ALLOC; goto error; } if (ioctl (fd, FIOSEEK, somHdr.subspace_location) == ERROR || read (fd, (char*)pSubspace, subspaceSize) != subspaceSize) { errno = S_loadSomCoffLib_SUBSPHDR_READ; goto error; } } /* read in space string table */ if (somHdr.space_strings_size != 0) { if ((pSpaceStrings = (char *) calloc (1, somHdr.space_strings_size)) == NULL) { errno = S_loadSomCoffLib_SPSTRING_ALLOC; goto error; } if (ioctl (fd, FIOSEEK, somHdr.space_strings_location) == ERROR || read (fd, pSpaceStrings, somHdr.space_strings_size) != somHdr.space_strings_size) { errno = S_loadSomCoffLib_SPSTRING_READ; goto error; } } if (somHdr.subspace_total != 0) { if ((pSubInfo = (SUB_INFO *) calloc (1, sizeof(SUB_INFO) * somHdr.subspace_total)) == NULL) { errno = S_loadSomCoffLib_INFO_ALLOC; goto error; } } else { pSubInfo = (SUB_INFO *) calloc (1, sizeof(SUB_INFO)); } /* read in symbol table */ symBufSize = somHdr.symbol_total * sizeof (SYMREC); if ((pSymBuf = (SYMREC *) calloc (1, symBufSize)) == NULL) { errno = S_loadSomCoffLib_SYM_READ; goto error; } if (ioctl (fd, FIOSEEK, somHdr.symbol_location) == ERROR) { errno = S_loadSomCoffLib_SYM_READ; goto error; } if (read (fd, (char *) pSymBuf, symBufSize) != symBufSize) { errno = S_loadSomCoffLib_SYM_READ; goto error; } /* read in symbol string table */ if ((pSymStr = calloc (1, somHdr.symbol_strings_size)) == NULL) { errno = S_loadSomCoffLib_SYMSTR_READ; goto error; } if (ioctl (fd, FIOSEEK,somHdr.symbol_strings_location) == ERROR || read (fd, pSymStr, somHdr.symbol_strings_size) != somHdr.symbol_strings_size) { errno = S_loadSomCoffLib_SYMSTR_READ; goto error; } /* read in linker fixup requests */ if (somHdr.fixup_request_total != 0) { relSize = (int)somHdr.fixup_request_total; if ((pReloc = (FIXUP *) calloc (1, relSize)) == NULL) { errno = S_loadSomCoffLib_RELOC_ALLOC; goto error; } if (ioctl (fd, FIOSEEK, somHdr.fixup_request_location) == ERROR || read (fd, (char*)pReloc, relSize) != relSize) { errno = S_loadSomCoffLib_RELOC_READ; goto error; } } /* make each symbol, space, and subspace point to its name string */ symbolNameSet (pSymBuf, somHdr.symbol_total, pSymStr, pSubspace, somHdr.subspace_total, pSpaceStrings, pSpace, somHdr.space_total); /* We don't really load non-relocatable files. * Since VxWorks.sym is non-relocatable, we * allow non-relocatable files to have their * symbols added to the symbol table, without any loading */ if (somHdr.a_magic != RELOC_MAGIC) { /* process subspace addresses with no relocation */ subspaceNoReloc (&somHdr, pSubInfo, pSubspace); /* read in the symbol table */ status = rdSymtab (pSymBuf, somHdr.symbol_total, pSubspace, pSubInfo, symFlag, symTbl, &pGlobal, NULL, group); goto done; } /* * Loaded code won't work if VxWorks was linked without the "-N" flag. * However VxWorks itself will work - so we put this check after * allowing VxWorks to load it's symbol table */ if (sysMemTop() > 0x40000000) { printErr ("\n"); printErr ("load error: VxWorks wasn't linked with the \"-N\" flag\n"); printErr ("Please read the \"source debugging\" section of the\n"); printErr ("VxSim Users Guide for details\n"); printErr ("\n"); goto error; } /* Map SOM subspaces to VxWorks "segments", and get the segment sizes */ subspaceToSegment (&somHdr, (UCHAR *)pReloc, pSubInfo, pSpace, pSubspace, pSymBuf, symTbl, &textSize, &dataSize, &bssSize); /* Allocate memory for text, data, and bss. We must be careful * to align everything, since loadSegmentsAllocate() will * put all segemnts in one block */ seg.addrText = pText; seg.addrData = pData; seg.addrBss = pBss; seg.sizeText = ROUND_UP(textSize, SEG_ALIGN); seg.sizeData = ROUND_UP(dataSize, SEG_ALIGN); seg.sizeBss = ROUND_UP(bssSize, SEG_ALIGN); /* * SPR #21836: pSeg->flagsText, pSeg->flagsData, pSeg->flagsBss are used * to save the max value of each segments. These max values are computed * for each sections. These fields of pSeg are only used on output, then * a temporary use is allowed. */ seg.flagsText = SEG_ALIGN; seg.flagsData = SEG_ALIGN; seg.flagsBss = SEG_ALIGN; commSizeGet (pSymBuf, somHdr.symbol_total, pSubspace, (int *)&commSize); seg.sizeBss += ROUND_UP(commSize, SEG_ALIGN); DBG_PUT ("bssSize = 0x%x, commSize = 0x%x\n", bssSize, commSize); /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -