📄 loadaoutlib.c
字号:
memset ((void *)&seg, 0, sizeof (seg)); /* Set up the module */ ioctl (fd, FIOGETNAME, (int) fileName); moduleId = loadModuleGet (fileName, MODULE_A_OUT, &symFlag); if (moduleId == NULL) return (NULL); group = moduleId->group; /* * Rewind to beginning of file before reading header * XXX - JN - The return values of all these calls to ioctl should * be checked. */ ioctl(fd, FIOSEEK, 0); if (fioRead (fd, (char *) &hdr, sizeof (hdr)) != sizeof (hdr)) goto error; seg.addrText = pText; seg.addrData = pData; seg.addrBss = pBss; seg.sizeText = hdr.TEXTSIZE; seg.sizeData = hdr.DATASIZE; seg.sizeBss = hdr.BSSSIZE; /* * 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 = _ALLOC_ALIGN_SIZE; seg.flagsData = _ALLOC_ALIGN_SIZE; seg.flagsBss = _ALLOC_ALIGN_SIZE; /* * 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; } else { pText = seg.addrText; pData = seg.addrData; pBss = seg.addrBss; } /* read in all of text and initialized data */ if ((fioRead (fd, pText, (int) hdr.TEXTSIZE) != hdr.TEXTSIZE) || (fioRead (fd, pData, (int) hdr.DATASIZE) != hdr.DATASIZE)) goto error; /* read in symbol strings by seeking to string stuff, * reading the first long which tells how big the * string table is, and then reading the string table */ if ((ioctl (fd, FIOSEEK, N_STROFF(hdr)) == ERROR) || (fioRead (fd, (char *) &nbytes, 4) != 4)) goto error; if (nbytes != 0) { /* allocate and read in the string table */ if ((stringsBuf = (char *) malloc ((unsigned) nbytes)) == NULL) { printErr (stringMemErrMsg, nbytes); goto error; } nbytes -= 4; /* subtract 4 byte length we just read */ if (fioRead (fd, &stringsBuf [4], nbytes) != nbytes) { printErr (readStringsErrMsg, errno); goto error; } } /* allocate the externalsBuf */ numExternals = hdr.a_syms / sizeof (struct U_SYM_STRUCT); if (numExternals != 0) { externalsBuf = (char **) malloc ((unsigned) numExternals * sizeof (char *)); if (externalsBuf == NULL) { printErr (extMemErrMsg, numExternals * sizeof (char *)); goto error; } } /* add segment names to symbol table before other symbols */ if (!(symFlag & LOAD_NO_SYMBOLS)) addSegNames (fd, pText, pData, pBss, symTbl, group); /* read in symbol table */ if (ioctl (fd, FIOSEEK, N_SYMOFF(hdr)) == ERROR) goto error; status = rdSymtab (fd, (int) hdr.a_syms, &externalsBuf, numExternals, symFlag, &seg, stringsBuf, symTbl, group); if (stringsBuf != NULL) { free (stringsBuf); /* finished with stringsBuf */ stringsBuf = NULL; } /* relocate text and data segments; * note: even if symbol table had missing symbols, continue with * relocation of those symbols that were found. * note: relocation is for changing the values of the relocated * symbols. bss is uninitialized data, so it is not relocated * in the symbol table. */ if (ioctl (fd, FIOSEEK, N_TXTOFF(hdr) + hdr.a_text + hdr.a_data) == ERROR) goto error; if ((status == OK) || (errno == S_symLib_SYMBOL_NOT_FOUND)) {#if CPU_FAMILY == SPARC if ((hdr.a_machtype & 0xffff) == 0x0107) { if ((relSegmentSparc (fd, (int) hdr.TRSIZE, seg.addrText, &seg, externalsBuf) != OK) || (relSegmentSparc (fd, (int) hdr.DRSIZE, seg.addrData, &seg, externalsBuf) != OK)) goto error; } else { printErr ("Unsupported Object module format, a_machtype : %#x\n", hdr.a_machtype); goto error; }#else if ((hdr.a_machtype & 0xffff) == 0x0107) { if ((relSegment68k (fd, (int) hdr.TRSIZE, seg.addrText, &seg, externalsBuf) != OK) || (relSegment68k (fd, (int) hdr.DRSIZE, seg.addrData, &seg, externalsBuf) != OK)) goto error; } else { printErr ("Unsupported Object module format, a_machtype : %#x\n", hdr.a_machtype); goto error; }#endif } if (externalsBuf != NULL) { free ((char *) externalsBuf); /* finished with externalsBuf */ externalsBuf = NULL; } /* write protect the text if text segment protection is turned on */ if (seg.flagsText & SEG_WRITE_PROTECTION) { if (VM_STATE_SET (NULL, pText, seg.sizeProtectedText, VM_STATE_MASK_WRITABLE, VM_STATE_WRITABLE_NOT) == ERROR) 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) hdr.BSSSIZE); /* flush stub to memory, flush any i-cache inconsistancies */ cacheTextUpdate (pText, hdr.TEXTSIZE); /* * 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, hdr.TEXTSIZE, seg.flagsText); moduleSegAdd (moduleId, SEGMENT_DATA, pData, hdr.DATASIZE, seg.flagsData); moduleSegAdd (moduleId, SEGMENT_BSS, pBss, hdr.BSSSIZE, seg.flagsBss); if (status == OK) return (moduleId); else return (NULL); /* error: * clean up dynamically allocated temporary buffers and return ERROR */error: if (stringsBuf != NULL) free (stringsBuf); if (externalsBuf != NULL) free ((char *) externalsBuf); /* flush stub to memory, flush any i-cache inconsistancies */ cacheTextUpdate (pText, hdr.TEXTSIZE); /* * Delete the module associated with the unsuccessful load */ moduleDelete (moduleId); return (NULL); }/********************************************************************************* rdSymtab - read and process a symbol table** This routine reads in a symbol table from an object file 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:* 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) any undefined externals are looked up in the system table, and* if found, entered in the specified 'externals' array. This array* is indexed by the symbol number (position in the symbol table).* Note that only undefined externals are filled in in 'externals' and* that values for all other types of symbols are unchanged (i.e. left* as garbage!). This is ok because 'externals' is only used to* perform relocations relative to previously undefined externals.* 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 more than the specified maximum number of symbols are found in the* symbol table, the externals array is extended to accomodate the additional* symbols.* 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.* Stabs and absolute symbols are automatically discarded.** RETURNS: OK or ERROR*/LOCAL STATUS rdSymtab ( FAST int fd, /* fd of file positioned to symbol table */ FAST int nbytes, /* # of bytes of symbol table */ char ***externals, /* pointer to pointer to array to fill in values of undef externals */ int max_symbols, /* max symbols that can be put in 'externals' */ int symFlag, /* symbols to be added to table * ([NO|GLOBAL|ALL]_SYMBOLS) */ SEG_INFO *pSeg, /* pointer to segment information */ char *symStrings, /* symbol string table (only meaningful in BSD 4.2) */ SYMTAB_ID symTbl, /* symbol table to use */ UINT16 group /* symbol group */ ) { struct U_SYM_STRUCT symbol; char * adrs; SYM_TYPE type; char * bias; FAST char * name; /* symbol name (plus EOS) */ int sym_num = 0; int status = OK; for (; nbytes > 0; nbytes -= sizeof (symbol), ++sym_num) { /* read in next entry - symbol definition and name string */ if (fioRead (fd, (char *) &symbol, sizeof (symbol)) != sizeof (symbol)) return (ERROR); /* we throw away stabs */ if (symbol.n_type & N_STAB) continue; /* symbol name string is in symStrings array indexed * by symbol.n_un.n_name */ name = symStrings + symbol.n_un.n_strx; /* add requested symbols to symbol table */ if ((symbol.U_SYM_TYPE & N_TYPE) != N_UNDF) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -