loadEcoffLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:57k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* loadEcoffLib.c - UNIX extended coff object module loader */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01q,30nov98,dbt  no longer clear seg.flags<xxx> after loadSegmentAllocate()
  8.                  call. (SPR #23553).
  9. 01p,05oct98,pcn  Initialize all the fields in the SEG_INFO structure.
  10. 01o,16sep98,pcn  Set to _ALLOC_ALIGN_SIZE the flags field in seg structure
  11.                  (SPR #21836).
  12. 01n,17jul98,pcn  Fixed SPR #21836: alignment mismatch between sections and
  13.                  target.
  14. 01m,31oct96,elp  Replaced symAdd() call by symSAdd() call (symtbls synchro).
  15. 01l,22feb94,caf  modified rdEcoffSymTab() to pass through the object file's
  16.  symbol table twice.  this way, undefined symbols can be
  17.  resolved w/ those appearing later in the table (SPR #3077).
  18. 01k,23jan94,jpb  fixed pointer skew problem (SPR #2896).
  19. 01j,31jul92,dnw  changed to call CACHE_TEXT_UPDATE.  doc tweak.
  20. 01i,29jul92,jmm  fixed setting of address for BSS segment
  21. 01h,23jul92,jmm  moved SEG_INFO to loadLib.h
  22.                  memory allocation now done by loadSegmentsAllocate
  23. 01g,23jul92,jmm  removed include of loadCommonLib.h 
  24. 01f,23jul92,ajm  made boot loader independent
  25. 01e,18jul92,smb  Changed errno.h to errnoLib.h.
  26. 01d,16jul92,jmm  added module tracking code
  27.                  moved addSegNames to loadLib.c
  28. 01c,07jul92,ajm  updated cache interface
  29. 01b,23jun92,ajm  reduced ansi warnings for 68k compiler
  30. 01a,14jun92,ajm  merged from 5.0.5 loadLib.c v01b
  31. */
  32. /*
  33. DESCRIPTION
  34. This library provides an object module loading facility particuarly for the
  35. MIPS compiler environment.  Any MIPS SYSV ECOFF
  36. format files may be loaded into memory, relocated properly, their
  37. external references resolved, and their external definitions added to
  38. the system symbol table for use by other modules and from the shell.
  39. Modules may be loaded from any I/O stream.
  40. EXAMPLE
  41. .CS
  42.     fdX = open ("/devX/objFile", O_RDONLY);
  43.     loadModule (fdX, ALL_SYMBOLS);
  44.     close (fdX);
  45. .CE
  46. This code fragment would load the ecoff file "objFile" located on
  47. device "/devX/" into memory which would be allocated from the system
  48. memory pool.  All external and static definitions from the file would be
  49. added to the system symbol table.
  50. This could also have been accomplished from the shell, by typing:
  51. .CS
  52.     -> ld (1) </devX/objFile
  53. .CE
  54. INCLUDE FILE: loadEcoffLib.h
  55. SEE ALSO: loadLib, usrLib, symLib, memLib,
  56. .pG "Basic OS"
  57. */
  58. /* LINTLIBRARY */
  59. #include "vxWorks.h"
  60. #include "stdio.h"
  61. #include "loadEcoffLib.h"
  62. #include "ecoffSyms.h"
  63. #include "ecoff.h"
  64. #include "ioLib.h"
  65. #include "fioLib.h"
  66. #include "bootLoadLib.h"
  67. #include "loadLib.h"
  68. #include "memLib.h"
  69. #include "pathLib.h"
  70. #include "string.h"
  71. #include "symLib.h"
  72. #include "sysSymTbl.h"
  73. #include "cacheLib.h"
  74. #include "errnoLib.h"
  75. #include "stdlib.h"
  76. #include "symbol.h" /* for SYM_TYPE typedef */
  77. #include "moduleLib.h"
  78. #include "loadEcoffComm.h"
  79. #define RTEXT   0
  80. #define RDATA   1
  81. #define RBSS    2
  82. #define U_SYM_TYPE  asym.sc /* coff classes act as a.out types */
  83. #define U_SYM_VALUE     asym.value
  84. /* coff types and classes as macros */
  85. #define COFF_EXT(symbol)  (((symbol)->asym.st == stProc) || 
  86.    ((symbol)->asym.st == stGlobal))
  87. #define COFF_ABS(symbol)  (((symbol)->asym.sc == scNil) || 
  88.    ((symbol)->asym.sc == scAbs))
  89. #define COFF_TEXT(symbol)  ((symbol)->asym.sc == scText)
  90. #define COFF_DATA(symbol) (((symbol)->asym.sc == scData) || 
  91.    ((symbol)->asym.sc == scRData) || 
  92.    ((symbol)->asym.sc == scSData))
  93. #define COFF_BSS(symbol)  (((symbol)->asym.sc == scBss) || 
  94.    ((symbol)->asym.sc == scSBss))
  95. #define COFF_UNDF(symbol) (((symbol)->asym.sc == scUndefined) || 
  96.    ((symbol)->asym.sc == scSUndefined))
  97. #define COFF_COMM(symbol) (((symbol)->asym.sc == scCommon) || 
  98.    ((symbol)->asym.sc == scSCommon))
  99. /* misc defines */
  100. #define COMMON_ALIGNMENT sizeof(double)
  101. #define OVERFLOW_COMPENSATION 0x10000
  102. #define OVERFLOW         0x00008000
  103. #define LS16BITS         0x0000ffff
  104. #define MS16BITS         0xffff0000
  105. #define MS4BITS          0xf0000000
  106. #define MS6BITS          0xfc000000
  107. #define LS26BITS         0x03ffffff
  108. LOCAL char extMemErrMsg [] =
  109.     "loadEcoffLib error: insufficient memory for externals (need %d bytes).n";
  110. LOCAL char cantConvSymbolType [] =
  111.     "loadEcoffLib error: can't convert '%s' symbol type, error = %#x.n";
  112. LOCAL char cantAddSymErrMsg [] =
  113.     "loadEcoffLib error: can't add '%s' to system symbol table, error = %#x.n";
  114. LOCAL char gpRelativeReloc [] =
  115.     "loadEcoffLib error: can't relocate, recompile module with -G 0 flags.n";
  116. /* forward static functions */
  117. static MODULE_ID ldEcoffMdlAtSym (int fd, int symFlag, char **ppText, 
  118.     char **ppData, char **ppBss, SYMTAB_ID symTbl);
  119. static STATUS rdEcoffSymTab (EXTR * pExtSyms, FAST int nEnts, char ***externals,
  120.     int max_symbols, int symFlag, SEG_INFO *pSeg, char *symStrings,
  121.     SYMTAB_ID symTbl, char *pNextCommon, int group);
  122. static STATUS relSegmentR3k (RELOC *pRelCmds, SCNHDR *pScnHdr,
  123.     char **pExternals, int section, SEG_INFO *pSeg);
  124. static ULONG sizeEcoffCommons (EXTR *pNextSym, ULONG alignBss);
  125. static STATUS ecoffSecHdrRead (int fd, SCNHDR *pScnHdr, FILHDR *pHdr, 
  126.     BOOL swapTables);
  127. static STATUS ecoffReadInSections (int fd, char **pSectPtr, SCNHDR *pScnHdr, 
  128.     BOOL swapTables);
  129. static STATUS ecoffLdSections (char **pSectPtr, SCNHDR *pScnHdr, 
  130.     AOUTHDR *pOptHdr, char *pText, char *pData);
  131. static STATUS ecoffReadRelocInfo (int fd, SCNHDR *pScnHdr, RELOC **pRelsPtr, 
  132.     BOOL swapTables);
  133. static STATUS ecoffReadSymHdr (int fd, HDRR *pSymHdr, FILHDR *pHdr, 
  134.     BOOL swapTables);
  135. static STATUS ecoffReadExtStrings (int fd, char **pStrBuf, HDRR *pSymHdr);
  136. static STATUS ecoffReadExtSyms (int fd, EXTR **pExtSyms, HDRR *pSymHdr, 
  137.     BOOL swapTables);
  138. static int nameToRelocSection (char * pName);
  139. static STATUS ecoffToVxSym (EXTR *symbol, SYM_TYPE *pVxSymType);
  140. /*******************************************************************************
  141. *
  142. * loadEcoffInit - initialize the system for ecoff load modules
  143. *
  144. * This routine initialized VxWorks to use an extended coff format for
  145. * loading modules.
  146. *
  147. * RETURNS:
  148. * OK, or
  149. * ERROR if XXX
  150. *
  151. * SEE ALSO: loadModuleAt()
  152. */
  153. STATUS loadEcoffInit 
  154.     (
  155.     )
  156.     {
  157.     /* XXX check for installed ? */
  158.     loadRoutine = (FUNCPTR) ldEcoffMdlAtSym;
  159.     return (OK);
  160.     }
  161. /******************************************************************************
  162. *
  163. * ldEcoffMdlAtSym - load object module into memory with specified symbol table
  164. *
  165. * This routine is the underlying routine to loadModuleAtSym().  This interface
  166. * allows specification of the the symbol table used to resolve undefined
  167. * external references and to which to add new symbols.
  168. *
  169. * RETURNS:
  170. * MODULE_ID, or
  171. * NULL if can't read file or not enough memory or illegal file format
  172. *
  173. * NOMANUAL
  174. */  
  175. LOCAL MODULE_ID ldEcoffMdlAtSym
  176.     (
  177.     FAST int fd, /* fd from which to read module */
  178.     int symFlag, /* symbols to be added to table 
  179.  *   ([NO | GLOBAL | ALL]_SYMBOLS) */
  180.     char **ppText, /* load text segment at address pointed to by this
  181.  * pointer, return load address via this pointer */
  182.     char **ppData, /* load data segment at address pointed to by this
  183.  * pointer, return load address via this pointer */
  184.     char **ppBss, /* load bss segment at address pointed to by this
  185.  * pointer, return load address via this pointer */
  186.     SYMTAB_ID symTbl  /* symbol table to use */
  187.     )
  188.     {
  189.     char *pText = (ppText == NULL) ? LD_NO_ADDRESS : *ppText;
  190.     char *pData = (ppData == NULL) ? LD_NO_ADDRESS : *ppData;
  191.     char *pBss  = (ppBss  == NULL) ? LD_NO_ADDRESS : *ppBss;
  192.     char **externalsBuf   = NULL; /* buffer for reading externals */
  193.     EXTR *externalSyms    = NULL; /* buffer for reading ecoff externals */
  194.     EXTR *pNextSym    = NULL; /* temp pointer to symbols */
  195.     char *stringsBuf = NULL; /* string table pointer */
  196.     FILHDR hdr; /* module's ECOFF header */
  197.     AOUTHDR optHdr;              /* module's ECOFF optional header */
  198.     SCNHDR scnHdr[MAX_SCNS]; /* module's ECOFF section headers */
  199.     char   *sectPtr[MAX_SCNS];       /* ecoff sections */
  200.     RELOC  *relsPtr[MAX_SCNS];  /* section relocation */
  201.     HDRR symHdr;             /* symbol table header */
  202.     SEG_INFO seg; /* file segment info */
  203.     BOOL tablesAreLE; /* boolean for table sex */
  204.     ULONG alignBss; /* next boundry for common entry */
  205.     ULONG symbolValue; /* size of a symbol */
  206.     int status; /* return value */
  207.     int section; /* ecoff section number */
  208.     int ix; /* temp counter */
  209.     int nbytes = 0; /* temp counter */
  210.     char  fileName[255];
  211.     UINT16  group;
  212.     MODULE_ID moduleId;
  213.     /* Initialization */
  214.     memset ((void *)&seg, 0, sizeof (seg));
  215.     /* Set up the module */
  216.     ioctl (fd, FIOGETNAME, (int) fileName);
  217.     moduleId = loadModuleGet (fileName, MODULE_ECOFF, &symFlag);
  218.     if (moduleId == NULL)
  219.         return (NULL);
  220.     group = moduleId->group;
  221.     /* init section pointers to NULL */
  222.     for (ix = 0; ix < MAX_SCNS; ix++)
  223. {
  224. sectPtr[ix] = NULL;
  225. relsPtr[ix] = NULL;
  226. bzero ((char *) &scnHdr[ix], (int) sizeof(SCNHDR));
  227. }
  228.     /* read object module header */
  229.     if (ecoffHdrRead (fd, &hdr, &tablesAreLE) != OK)
  230. {
  231. errnoSet(S_loadEcoffLib_HDR_READ);
  232. goto error;
  233. }
  234.     /* read in optional header */
  235.     if (ecoffOpthdrRead (fd, &optHdr, &hdr, tablesAreLE) != OK)
  236. {
  237. errnoSet(S_loadEcoffLib_OPTHDR_READ);
  238. goto error;
  239. }
  240.     seg.addrText = pText;
  241.     seg.addrData = pData;
  242.     /*
  243.      * If pBss is set to LD_NO_ADDRESS, change it to something else.
  244.      * The coff loader allocates one large BSS segment later on, and
  245.      * loadSegmentsAllocate doesn't work correctly for it.
  246.      */
  247.     seg.addrBss = (pBss == LD_NO_ADDRESS ? LD_NO_ADDRESS + 1 : pBss);
  248.  
  249.     seg.sizeText = optHdr.tsize;
  250.     seg.sizeData = optHdr.dsize;
  251.     seg.sizeBss = optHdr.bsize;
  252.     /* 
  253.      * SPR #21836: pSeg->flagsText, pSeg->flagsData, pSeg->flagsBss are used
  254.      * to save the max value of each segments. These max values are computed
  255.      * for each sections. These fields of pSeg are only used on output, then
  256.      * a temporary use is allowed.
  257.      */
  258.     seg.flagsText = _ALLOC_ALIGN_SIZE;
  259.     seg.flagsData = _ALLOC_ALIGN_SIZE;
  260.     seg.flagsBss  = _ALLOC_ALIGN_SIZE;
  261.     /* 
  262.      * SPR #21836: loadSegmentsAllocate() allocate memory aligned on 
  263.      * the max value of sections alignement saved in seg.flagsText,
  264.      * seg.flagsData, seg.flagsBss.
  265.      */
  266.     if (loadSegmentsAllocate (&seg) != OK)
  267.         {
  268. printErr ("Could not allocate segmentsn");
  269. goto error;
  270. }
  271.     else
  272. {
  273. pText = seg.addrText;
  274. pData = seg.addrData;
  275. pBss = LD_NO_ADDRESS;
  276. }
  277.     /* read in section headers */
  278.     if (ecoffSecHdrRead (fd, &scnHdr[0], &hdr, tablesAreLE) != OK)
  279. {
  280. errnoSet(S_loadEcoffLib_SCNHDR_READ);
  281. goto error;
  282. }
  283.     /* read in all sections */
  284.     if (ecoffReadInSections (fd, &sectPtr[0], &scnHdr[0], tablesAreLE) != OK)
  285. {
  286. errnoSet(S_loadEcoffLib_READ_SECTIONS);
  287. goto error;
  288. }
  289.     /* copy sections to text, and data */
  290.     if (ecoffLdSections (&sectPtr[0], &scnHdr[0], &optHdr, pText, pData) != OK)
  291. {
  292. errnoSet (S_loadEcoffLib_LOAD_SECTIONS);
  293. goto error;
  294. }
  295.     /* 
  296.      * free section memory that is no longer needed (sectPtr).
  297.      * note: free should be as early as possible to allow memory reuse,
  298.      * this is extremenly important in order to load large object modules.
  299.      */
  300.     for (ix = 0; ix < MAX_SCNS; ix++)
  301. {
  302. if (sectPtr[ix] != NULL)
  303.     {
  304.     free((char *) sectPtr[ix]);
  305.     sectPtr[ix] = NULL;
  306.     }
  307. }
  308.     /* get section relocation info */
  309.     if (ecoffReadRelocInfo (fd, &scnHdr[0], &relsPtr[0], tablesAreLE) != OK)
  310. {
  311. errnoSet (S_loadEcoffLib_RELOC_READ);
  312. goto error;
  313. }
  314.     /* read in symbolic header */
  315.     if (ecoffReadSymHdr (fd, &symHdr, &hdr, tablesAreLE) != OK)
  316. {
  317. errnoSet (S_loadEcoffLib_SYMHDR_READ);
  318. goto error;
  319. }
  320.     /* read in local symbols XXX */
  321.     /* read in local string table XXX */
  322.     /* read external string table */
  323.     if (ecoffReadExtStrings (fd, &stringsBuf, &symHdr) != OK)
  324. {
  325. errnoSet (S_loadEcoffLib_EXTSTR_READ);
  326. goto error;
  327. }
  328.     /* read in external symbols */
  329.     if (ecoffReadExtSyms (fd, &externalSyms, &symHdr, tablesAreLE) != OK)
  330. {
  331. errnoSet (S_loadEcoffLib_EXTSYM_READ);
  332. goto error;
  333. }
  334.     /* calculate room for external commons in bss */
  335.     alignBss = COMMON_ALIGNMENT;
  336.     nbytes   = 0;
  337.     for(pNextSym = (EXTR *) externalSyms;
  338.         pNextSym < (EXTR *) ((long) externalSyms + 
  339.     (symHdr.iextMax * cbEXTR)); 
  340. pNextSym++)
  341. {
  342. if (COFF_EXT(pNextSym) && COFF_COMM(pNextSym))
  343.     {
  344.             symbolValue = sizeEcoffCommons (pNextSym, alignBss);
  345.             nbytes += symbolValue;
  346.             alignBss += symbolValue;
  347.     }
  348. }
  349.     /* add common size to bss */
  350.     seg.sizeBss = nbytes + optHdr.bsize;
  351.     if ((pBss == LD_NO_ADDRESS) || (seg.sizeBss > 0))
  352. {
  353. if ((pBss = (char *) malloc (seg.sizeBss)) == NULL) 
  354.     goto error;
  355.         seg.addrBss = pBss;
  356. seg.flagsBss |= SEG_FREE_MEMORY;
  357. }
  358.     /* allocate the externalsBuf */
  359.     if (symHdr.iextMax != 0)
  360.         {
  361.         externalsBuf = (char **) malloc ((long) symHdr.iextMax *
  362. sizeof (char *));
  363.  if (externalsBuf == NULL)
  364.      {
  365.      printErr (extMemErrMsg, symHdr.iextMax * sizeof (char *));
  366.      goto error;
  367.      }
  368. }
  369.     /* add segment names to symbol table before other symbols */
  370.     if (!(symFlag & LOAD_NO_SYMBOLS))
  371.         addSegNames (fd, pText, pData, pBss, symTbl, group);
  372.     /* process symbol table */
  373.     status = rdEcoffSymTab (externalSyms, symHdr.iextMax, &externalsBuf, 
  374.     symHdr.iextMax, symFlag, &seg, stringsBuf, symTbl, 
  375.  (char *) ((long) seg.addrBss + (seg.sizeBss - nbytes)),
  376.     group);
  377.     if (stringsBuf != NULL)
  378.         {
  379.         free (stringsBuf);      /* finished with stringsBuf */
  380.         stringsBuf = NULL;
  381.         }
  382.     if (externalSyms != NULL)
  383.         {
  384.         free (externalSyms);      /* finished with externalSyms */
  385.         externalSyms = NULL;
  386.         }
  387.     /* 
  388.      * relocate text and data segments;
  389.      *   note: even if symbol table had missing symbols, continue with
  390.      *   relocation of those symbols that were found.
  391.      *   note: relocation is for changing the values of the relocated
  392.      *   symbols.  bss is uninitialized data, so it is not relocated
  393.      *   in the symbol table.
  394.      *   caution: the order of relocation sections is not always the same  
  395.      *   as the order of the sections 
  396.      */
  397.     if ((status == OK) || (errnoGet () == S_symLib_SYMBOL_NOT_FOUND))
  398.         {
  399.         for (ix = 0; ix < MAX_SCNS; ix++)
  400.     {
  401.     if (relsPtr[ix] != NULL)
  402. {
  403. if ((section = nameToRelocSection (scnHdr[ix].s_name)) == ERROR)
  404.     {
  405.          errnoSet (S_loadEcoffLib_GPREL_REFERENCE);
  406.     printErr (gpRelativeReloc);
  407.     goto error;
  408.     }
  409.                 if (relSegmentR3k (relsPtr[ix], &scnHdr[ix], externalsBuf, 
  410.     section, &seg) != OK)
  411.     {
  412.             goto error;
  413.     }
  414. }
  415.     }
  416.         /* flush instruction cache before execution */
  417. if (optHdr.tsize != NULL)
  418.     cacheTextUpdate (pText, optHdr.tsize);
  419. }
  420.     if (externalsBuf != NULL)
  421.         {
  422.         free ((char *) externalsBuf);   /* finished with externalsBuf */
  423.         externalsBuf = NULL;
  424.         }
  425.     /* 
  426.      * free memory that was used (free should be as early as possible to
  427.      * allow memory reuse, which is very important for large object modules) 
  428.      */
  429.     for (ix = 0; ix < MAX_SCNS; ix++)
  430. if (relsPtr[ix] != NULL)
  431.     {
  432.     free((char *) relsPtr[ix]);
  433.     relsPtr[ix] = NULL;
  434.     }
  435.     /* return load addresses, where called for */
  436.     if (ppText != NULL)
  437.         *ppText = pText;
  438.     if (ppData != NULL)
  439.         *ppData = pData;
  440.     if (ppBss != NULL)
  441.         *ppBss = pBss;
  442.     /* clear out bss */
  443.     bzero (pBss, (int) seg.sizeBss);
  444.     /*
  445.      * Add the segments to the module.
  446.      * This has to happen after the relocation gets done.
  447.      * If the relocation happens first, the checksums won't be
  448.      * correct.
  449.      */
  450.     moduleSegAdd (moduleId, SEGMENT_TEXT, pText, seg.sizeText, seg.flagsText);
  451.     moduleSegAdd (moduleId, SEGMENT_DATA, pData, seg.sizeData, seg.flagsData);
  452.     moduleSegAdd (moduleId, SEGMENT_BSS, pBss, seg.sizeBss, seg.flagsBss);
  453.     if (status == OK)
  454.         return (moduleId);
  455.     else
  456.         return (NULL);
  457.     /* error:
  458.      * clean up dynamically allocated temporary buffers and return ERROR */
  459. error:
  460.     for (ix = 0; ix < MAX_SCNS; ix++)
  461. {
  462. if (sectPtr[ix] != NULL)
  463.     free((char *) sectPtr[ix]);
  464. if (relsPtr[ix] != NULL)
  465.     free((char *) relsPtr[ix]);
  466. }
  467.     if (stringsBuf != NULL)
  468. free (stringsBuf);
  469.     if (externalsBuf != NULL)
  470. free ((char *) externalsBuf);
  471.     if (externalSyms != NULL)
  472. free ((char *) externalSyms);
  473.     moduleDelete (moduleId);
  474.     return (NULL);
  475.     }
  476. /*******************************************************************************
  477. *
  478. * rdEcoffSymTab -
  479. *
  480. * This is passed a pointer to an ecoff symbol table and processes
  481. * each of the external symbols defined therein.  This processing performs
  482. * two functions:
  483. *  1) defined symbols are entered in the system symbol table as
  484. *     specified by the "symFlag" argument:
  485. * ALL_SYMBOLS = all defined symbols (LOCAL and GLOBAL) are added,
  486. * GLOBAL_SYMBOLS = only external (GLOBAL) symbols are added,
  487. * NO_SYMBOLS = no symbols are added;
  488. *  2) any undefined externals are looked up in the system table, and
  489. *     if found, entered in the specified 'externals' array.  This array
  490. *     is indexed by the symbol number (position in the symbol table).
  491. *     Note that only undefined externals are filled in in 'externals' and
  492. *     that values for all other types of symbols are unchanged (i.e. left
  493. *     as garbage!).  This is ok because 'externals' is only used to 
  494. *     perform relocations relative to previously undefined externals.
  495. *     Note that "common" symbols have type undefined external - the value
  496. *     field of the symbol will be non-zero for type common, indicating
  497. *     the size of the object.
  498. *
  499. * If more than the specified maximum number of symbols are found in the
  500. * symbol table, the externals array is extended to accomodate the additional
  501. * symbols.
  502. * If an undefined external cannot be found in the system symbol table,
  503. * an error message is printed, but ERROR is not returned until the entire
  504. * symbol table has been read, which allows all undefined externals to be
  505. * looked up.
  506. * Stabs and absolute symbols are automatically discarded.
  507. *
  508. * RETURNS: OK or ERROR
  509. *
  510. * INTERNAL
  511. * Local symbols are currently ignored.
  512. */
  513. LOCAL STATUS rdEcoffSymTab 
  514.     (
  515.     EXTR * pExtSyms, /* pointer to mips external symbols */
  516.     FAST int nEnts, /* # of entries in symbol table */
  517.     char ***externals, /* pointer to pointer to array to fill in 
  518.    values of undef externals */
  519.     int max_symbols, /* max symbols that can be put in 'externals' */
  520.     int symFlag, /* symbols to be added to table 
  521.  *   ([NO|GLOBAL|ALL]_SYMBOLS) */
  522.     SEG_INFO *pSeg, /* pointer to segment information */
  523.     char *symStrings, /* symbol string table (only meaningful in
  524.    BSD 4.2) */
  525.     SYMTAB_ID symTbl, /* symbol table to use */
  526.     char *pNextCommon,  /* next common address in bss */
  527.     int group /* symbol group */
  528.     )
  529.     {
  530.     FAST char *name; /* symbol name (plus EOS) */
  531.     EXTR symbol; /* symbol value */
  532.     SYM_TYPE vxSymType; /* ecoff symbol translation */
  533.     int sym_num = 0; /* symbol index */
  534.     int status  = OK; /* return status */
  535.     char *adrs; /* table resident symbol address */
  536.     SYM_TYPE type; /* ecoff symbol type */
  537.     char *bias; /* section relatilve address */
  538.     ULONG bssAlignment; /* alignment value of common type */
  539.     /* pass 1: process defined symbols */
  540.     for (sym_num = 0; sym_num < nEnts; sym_num ++)
  541. {
  542. /* read in next entry - symbol definition and name string */
  543. symbol = pExtSyms [sym_num];
  544. /* add requested symbols to symbol table */
  545.         if ((!COFF_ABS(&symbol)) && /* throw away absolute symbols */
  546.     (!COFF_UNDF(&symbol)) && (!COFF_COMM(&symbol)) &&
  547.     (symFlag & LOAD_GLOBAL_SYMBOLS) && COFF_EXT(&symbol))
  548.     {
  549.     /*
  550.      * symbol name string is in symStrings array indexed 
  551.      * by symbol.iss
  552.      */
  553.     name = symStrings + symbol.asym.iss;
  554.     /*
  555.      *  I'm not sure the symbol type can tell us what section the 
  556.      *  symbol is in so we look at the address.  This should be 
  557.      *  investigated at a later date.
  558.      */
  559.     if (symbol.U_SYM_VALUE < (long) pSeg->sizeText)
  560. bias = (char *) pSeg->addrText;
  561.     else if (symbol.U_SYM_VALUE
  562. < ((long) pSeg->sizeText + (long) pSeg->sizeData))
  563. bias = (char *) (
  564.        (long) pSeg->addrData
  565.      - (long) pSeg->sizeText);
  566.     else
  567. bias = (char *) ((long) pSeg->addrBss - pSeg->sizeText - 
  568.     pSeg->sizeData);
  569.     if (ecoffToVxSym (&symbol, &vxSymType) == ERROR)
  570. printErr (cantConvSymbolType, name, errnoGet());
  571.     if (symSAdd (symTbl, name, symbol.U_SYM_VALUE + bias, 
  572. vxSymType, group) != OK)
  573. printErr (cantAddSymErrMsg, name, errnoGet());
  574.     /*
  575.      * add symbol address to externals table, but first
  576.      * check for enough room in 'externals' table
  577.      */
  578.     
  579.     if (sym_num == max_symbols)
  580. {
  581. /*
  582.  * no more room in symbol table -
  583.  * make externals table half again as big
  584.  */
  585. max_symbols += max_symbols / 2;
  586. *externals = (char **) realloc ((char *) *externals,
  587.     max_symbols * sizeof (char *));
  588. if (*externals == NULL)
  589.     return (ERROR);
  590. }
  591.     /* enter address in table used by relSegment */
  592.     (*externals) [sym_num] = symbol.U_SYM_VALUE + bias;
  593.     }
  594. }
  595.     /* pass 2: process undefined symbols (including commons) */
  596.     for (sym_num = 0; sym_num < nEnts; sym_num ++)
  597. {
  598. /* read in next entry - symbol definition and name string */
  599. symbol = pExtSyms [sym_num];
  600.         if ((!(COFF_ABS(&symbol))) &&  /* throw away absolute symbols */
  601.     ((COFF_UNDF(&symbol)) || (COFF_COMM(&symbol))))
  602.     {
  603.     /*
  604.      * symbol name string is in symStrings array indexed 
  605.      * by symbol.iss
  606.              */
  607.     name = symStrings + symbol.asym.iss;
  608.     /*
  609.      * undefined external symbol or "common" symbol -
  610.      *   common symbol type is denoted by undefined external with
  611.      *   the value set to non-zero.
  612.      *
  613.      * if symbol is a common, then allocate space and add to
  614.      * symbol table as BSS
  615.      */
  616.     /* common symbol - create new symbol */
  617.     if (COFF_COMM(&symbol)
  618. && (symbol.U_SYM_VALUE != 0))  /* do we really need this ? */
  619. {
  620.                 /* 
  621.  *  common symbol - create new symbol 
  622.  *
  623.  *  Common symbols are now tacked to the end of the bss
  624.  *  section.  This portion of code reads the symbol value
  625.  *  which contains the symbol size and places it appropriately
  626.  *  in the bss section.  The function sizeEcoffCommons is used
  627.  *  with the address of the last common added to determine
  628.  *  proper alignment.
  629.  */
  630. adrs = pNextCommon;
  631. bssAlignment = sizeEcoffCommons (&symbol, (ULONG) adrs);
  632. bssAlignment -= (ULONG) symbol.U_SYM_VALUE;
  633. adrs += bssAlignment;
  634. pNextCommon += (symbol.U_SYM_VALUE + bssAlignment);
  635. if (symSAdd (symTbl, name, adrs, (N_BSS | N_EXT), group) != OK)
  636.     printErr (cantAddSymErrMsg, name, errnoGet());
  637. }
  638.     /* look up undefined external symbol in symbol table */
  639.     else if (symFindByNameAndType (symTbl, name, &adrs, &type,
  640.    N_EXT, N_EXT) != OK)
  641. {
  642. /* symbol not found in symbol table */
  643. printErr ("undefined symbol: %sn", name);
  644. adrs = NULL;
  645. status = ERROR;
  646. }
  647.     /*
  648.      * add symbol address to externals table, but first
  649.      * check for enough room in 'externals' table
  650.      */
  651.     if (sym_num == max_symbols)
  652. {
  653. /*
  654.  * no more room in symbol table -
  655.  * make externals table half again as big
  656.  */
  657. max_symbols += max_symbols / 2;
  658. *externals = (char **) realloc ((char *) *externals, 
  659.     max_symbols * sizeof (char *));
  660. if (*externals == NULL)
  661.     return (ERROR);
  662. }
  663.     (*externals) [sym_num] = adrs; /* enter address in table */
  664.     }
  665. }
  666.     return (status);
  667.     }
  668. /*******************************************************************************
  669. *
  670. * relSegmentR3k - perform relocation commands for a MIPS segment
  671. *
  672. * This routine reads the specified relocation command segment and performs
  673. * all the relocations specified therein.
  674. * External relocations are looked up in the 'externals' table.
  675. * All other relocations are relative to how much a particular segment has moved.
  676. *
  677. * That was the short explanation.  The following is more specific:
  678. * Each relocation command is identified as being external or local; 
  679. * external symbols require the use of the 'externals' table to perform
  680. * the relocation while local symbols are relocated relative to a segment
  681. * (text or data).
  682. *
  683. * There are the following types of external relocation entries:
  684. * -R_REFWORD for externally defined pointers,
  685. *  -R_HALFWORD ?? would be a 16 bit external pointer but thus far
  686. *    has not been seen from the MIPS C compiler,
  687. *       -R_JMPADDR for calls to externalC functions,
  688. *  -R_REFHI/R_REFLO pairs for accessing and external data
  689. *  value, and
  690. * -unsupported GP (global pointer) relative relocation types which 
  691. *  cause an error to be returned.
  692. *
  693. * There are local versions of these relocation entries also:
  694. * -R_REFWORD for static pointers and arrays,
  695. * -R_HALFWORD should be similar to R_REFWORD but have not been 
  696. * able to get the C compiler to generate it,
  697. * -R_JMPADDR for relative jumps to functions (references to functions
  698. *  located within the load module.
  699. *  -R_REFHI/R_REFLO combinations for accesses to objects  defined in 
  700. *      this file and with local visibility (i.e. static data 
  701. *  structure references).
  702. * -unsupported GP (global pointer) relative relocation types which 
  703. *  cause an error to be returned.
  704. *
  705. *
  706. * RETURNS: OK or ERROR
  707. */
  708. LOCAL STATUS relSegmentR3k 
  709.     (
  710.     RELOC *pRelCmds, /* list of mips relocation commands */
  711.     SCNHDR *pScnHdr, /* section header for relocation */
  712.     char **pExternals, /* addresses of external symbols */
  713.     int section, /* section number TEXT, RDATA, BSS ... */
  714.     SEG_INFO *pSeg  /* section addresses and sizes */
  715.     )
  716.     {
  717.     FAST long *pAddress; /* relocation address */
  718.     FAST long *pNextAddress; /* next relocation address */
  719.     long refhalfSum; /* refhalf sum */
  720.     long targetAddr; /* relocation target address */
  721.     long relocOffset;  /* relocation offset */
  722.     long relocConstant; /* general reloc constant */
  723.     long relSegment; /* RTEXT, RDATA, ... */
  724.     long segment; /* segment we are relocating */
  725.     unsigned short nCmds; /* # reloc commands for seg */
  726.     RELOC relocCmd; /* relocation structure */
  727.     RELOC nextRelocCmd; /* next relocation structure */
  728.     long refhiConstant = 0; /* last REFHI constant */
  729.     nCmds = pScnHdr->s_nreloc;
  730.     while ( nCmds > 0 )
  731. {
  732. /* read relocation command */
  733. relocCmd = *pRelCmds++;
  734. nCmds -= 1;
  735. /* 
  736.  * Calculate actual address in memory that needs relocation
  737.  * and perform external or segment relative relocation 
  738.  */
  739.         if ((section == R_SN_TEXT) || (section == R_SN_INIT))
  740.     {
  741.     pAddress = (long *) ((long) pSeg->addrText + relocCmd.r_vaddr);
  742.     segment = RTEXT;
  743.     }
  744. else
  745.     {
  746.     pAddress = (long *) ((long) pSeg->addrData + 
  747. (relocCmd.r_vaddr - pSeg->sizeText));
  748.     segment = RDATA;
  749.     }
  750. /* note: should check for valid pAddress here XXXX */
  751. if (relocCmd.r_extern) /* globlal relocation */
  752.     {
  753.     switch (relocCmd.r_type)
  754.         {
  755.         case R_REFWORD:
  756. /*
  757. *  This relocation is performed by adding the 32 bit address
  758. *  of the symbol to the contents of pAddress.
  759. *  See IDT Assembly language programmers guide pg. 10-16
  760. */
  761.       *pAddress = (*pAddress + 
  762. (long) pExternals[relocCmd.r_symndx]);
  763.     break;
  764.         case R_REFHALF: /* WARNING: UNTESTED */
  765. /* 
  766. *  This case is not well documented by MIPS, and has never
  767. *  been generated.  REFWORD and REFHALF relocation entries
  768. *  are generally used for pointers, and a case where you have
  769. *  a 16 bit pointer is very unlikely to occur on a 32 bit
  770. *  architecture.
  771. */
  772.     refhalfSum = ((LS16BITS & *pAddress) + 
  773. (long) pExternals[relocCmd.r_symndx]);
  774.     if (refhalfSum >= OVERFLOW)
  775.         refhalfSum &= LS16BITS;
  776.     *pAddress = (MS16BITS & *pAddress) | 
  777. (LS16BITS & refhalfSum);
  778.     break;
  779.         case R_JMPADDR:
  780. /* 
  781. *  For this relocation type the loader determines the address
  782. *  for the jump, shifts the address right two bits, and adds 
  783. *  the lower 26 bits of the result to the low 26 bits of the 
  784. *  instruction at pAddress (after sign extension).  The
  785. *  results go back into the low 26 bits at pAddress.
  786. *  The initial check is to see if the jump is within range.  
  787. *  The current address is incremented by 4 because the jump
  788. *  actually takes place in the branch delay slot of the
  789. *  current address.
  790. *  See IDT Assembly language programmers guide pg. 10-16
  791. */
  792.     if ((MS4BITS & ((long) pAddress + sizeof(INSTR))) != 
  793. (MS4BITS & (long) pExternals[relocCmd.r_symndx]))
  794. {
  795.      errnoSet (S_loadEcoffLib_JMPADDR_ERROR);
  796.         return (ERROR);
  797. }
  798.     targetAddr = (LS26BITS & *pAddress) + (LS26BITS &
  799. ((unsigned) pExternals[relocCmd.r_symndx] >> 2));
  800.     *pAddress = (MS6BITS & *pAddress) | (LS26BITS & targetAddr);
  801.     break;
  802.         case R_REFHI:
  803. /*
  804. *  A refhi relocation is done by reading the next relocation
  805. *  entry (always the coresponding reflo entry).  This least
  806. *  significant 16 bits are taken from the refhi instruction 
  807. *  and shifted left to form a 32 bit value.  This value is 
  808. *  added to the least significant 16 bits of the reflo 
  809. *  instruction (taking into account sign extention) to form 
  810. *  a 32 bit reference pointer.  The target address is added 
  811. *  to this constant and placed back in the least significant 
  812. *  16 bits of each instruction address.  The contents of the 
  813. *  lower 16 bits of pAddress (refhiConstant) are saved for any 
  814. *  other reflo entries that the refhi entry may correspond to.
  815. *  See IDT Assembly language programmers guide pg. 10-16
  816. */
  817.     refhiConstant = (*pAddress << 16);
  818.     nextRelocCmd = *pRelCmds++;
  819.         nCmds -= 1;
  820.          if (nextRelocCmd.r_type != R_REFLO) 
  821. {
  822.      errnoSet (S_loadEcoffLib_NO_REFLO_PAIR);
  823.         return (ERROR);
  824. }
  825.              if (segment == RTEXT)
  826. {
  827.              pNextAddress = (long *) ((long) pSeg->addrText + 
  828.     nextRelocCmd.r_vaddr);
  829. }
  830.     else /* segment == RDATA */
  831. {
  832.      pNextAddress = (long *) ((long) pSeg->addrData + 
  833.     (nextRelocCmd.r_vaddr - 
  834.     (long) pSeg->sizeText));
  835. }
  836.                     /* following cast to short guarantees sign extension */
  837.     relocConstant = (*pAddress << 16) + 
  838. (int) ((short)(LS16BITS & *pNextAddress));
  839.     targetAddr = (long) pExternals[relocCmd.r_symndx] + 
  840. relocConstant;
  841.     if ((LS16BITS & targetAddr) >= OVERFLOW)
  842. targetAddr += OVERFLOW_COMPENSATION;
  843.     *pAddress = (MS16BITS & *pAddress) + 
  844. ((unsigned) targetAddr >> 16);
  845.     *pNextAddress = (MS16BITS & *pNextAddress) + 
  846. (LS16BITS & targetAddr);
  847.             break;
  848.         case R_REFLO:
  849.      /*
  850.      *  Since a REFHI must occur with a REFLO pair (lui, addi 
  851. *  instructions) it was originally thought that a REFLO 
  852. *  entry would never be seen alone.  This turned out to be 
  853. *  an incorrect assumption.  If a R_REFLO is by itself, it 
  854. *  is assumed to belong to the last R_REFHI entry.
  855.      */
  856.                     /* following cast to short guarantees sign extension */
  857.     relocConstant = refhiConstant + 
  858.                         (int) ((short)(LS16BITS & *pAddress));
  859.     targetAddr = (long) pExternals[relocCmd.r_symndx] + 
  860. relocConstant;
  861.     if ((LS16BITS & targetAddr) >= OVERFLOW)
  862. targetAddr += OVERFLOW_COMPENSATION;
  863.     *pAddress = (MS16BITS & *pAddress) + 
  864. (LS16BITS & targetAddr);
  865.     break;
  866.         case R_GPREL:
  867.         case R_LITERAL:
  868.     printErr (gpRelativeReloc);
  869.          errnoSet (S_loadEcoffLib_GPREL_REFERENCE);
  870.     return (ERROR);  /* gp reg addressing not supported */
  871.     break;
  872.         case R_ABS:
  873.     break; /* relocation already performed */
  874.         default:
  875.     printErr("Unrecognized ext relocation type %dn",
  876.         relocCmd.r_type);
  877.          errnoSet (S_loadEcoffLib_UNRECOGNIZED_RELOCENTRY);
  878.     return (ERROR);
  879.     break;
  880.         }
  881.     }
  882. else /* local relocation */
  883.     {
  884.     switch (relocCmd.r_symndx)
  885. {
  886. case R_SN_INIT:
  887. case R_SN_TEXT:
  888.     relSegment = RTEXT;
  889.          break;
  890. case R_SN_DATA:
  891. case R_SN_RDATA:
  892. case R_SN_SDATA: /* treat as data with no GP */
  893.     relSegment = RDATA;
  894.             break;
  895. case R_SN_BSS:
  896. case R_SN_SBSS: /* treat as bss with no GP  */
  897.     relSegment = RBSS;
  898.     break;
  899. case R_SN_LIT4:
  900. case R_SN_LIT8:
  901.     printErr (gpRelativeReloc);
  902.          errnoSet (S_loadEcoffLib_GPREL_REFERENCE);
  903.     return (ERROR);
  904.     break;
  905. default:
  906.     printErr ("Unknown symbol number %dn", relocCmd.r_symndx);
  907.          errnoSet (S_loadEcoffLib_UNRECOGNIZED_RELOCENTRY);
  908.     return (ERROR); 
  909.     break;
  910.     switch (relocCmd.r_type)
  911. {
  912. case R_REFWORD:
  913. /*
  914. *  This relocation is performed by adding the 32 bit address
  915. *  of the symbol to the contents of pAddress.  The address of
  916. *  the symbol is found by adding the relative segment address
  917. *  to the contents of the address we are relocating.
  918. *  See IDT Assembly language programmers guide pg. 10-16
  919. */
  920.     if (relSegment == RTEXT)
  921. {
  922. relocOffset = *pAddress;
  923.   *pAddress = ((long) pSeg->addrText + relocOffset);
  924. }
  925.     else if (relSegment == RDATA)
  926. {
  927. relocOffset = *pAddress - pSeg->sizeText;
  928.   *pAddress = ((long) pSeg->addrData + relocOffset);
  929. }
  930.     else /* relSegment == RBSS */
  931. {
  932. relocOffset = *pAddress - pSeg->sizeText - 
  933.     pSeg->sizeData;
  934.   *pAddress = ((long) pSeg->addrBss + relocOffset);
  935. }
  936.     break;
  937. case R_REFHALF:  /* WARNING: UNTESTED */
  938. /* 
  939. *  This case is not well documented by MIPS, and has never
  940. *  been generated.  REFWORD and REFHALF relocation entries
  941. *  are generally used for pointers, and a case where you have
  942. *  a 16 bit pointer is very unlikely to occur on a 32 bit
  943. *  architecture.
  944. */
  945.     if (relSegment == RTEXT)
  946. {
  947. relocOffset = *pAddress;
  948.   *pAddress = ((long) pSeg->addrText + relocOffset);
  949. }
  950.     else if (relSegment == RDATA)
  951. {
  952. relocOffset = *pAddress - pSeg->sizeText;
  953.   *pAddress = ((long) pSeg->addrData + relocOffset);
  954. }
  955.     else /* relSegment == RBSS */
  956. {
  957. relocOffset = *pAddress - pSeg->sizeText - 
  958.     pSeg->sizeData;
  959.   *pAddress = ((long) pSeg->addrBss + relocOffset);
  960. }
  961.     if (LS16BITS & *pAddress >= OVERFLOW)
  962.         {
  963.         errnoSet (S_loadEcoffLib_REFHALF_OVFL);
  964.         return (ERROR);
  965.         }
  966.     break;
  967. case R_JMPADDR:
  968. /* 
  969. *  For this relocation type the loader determines the address
  970. *  for the jump, shifts the address right two bits, and adds 
  971. *  the lower 26 bits of the result to the low 26 bits of the 
  972. *  instruction at pAddress (after sign extension).  The
  973. *  results go back into the low 26 bits at pAddress.
  974. *  The initial check is to see if the jump is within range.  
  975. *  The current address is incremented by 4 because the jump
  976. *  actually takes place in the branch delay slot of the
  977. *  current address.  The address for the jump is dependant 
  978. *  on the contents of the address we are relocating and
  979. *  the address of the relative section.
  980. *  See IDT Assembly language programmers guide pg. 10-16
  981. */
  982.     if (relSegment == RTEXT)
  983. {
  984.         targetAddr = (((LS26BITS & *pAddress) << 2)
  985.     + (MS4BITS & (long) pAddress )
  986.             + (long) pSeg->addrText);
  987. }
  988.     else if (relSegment == RDATA)
  989. {
  990. targetAddr = (((LS26BITS & *pAddress) << 2)
  991.             + (MS4BITS & (long) pAddress )
  992.     + (long) pSeg->addrData);
  993. }
  994.     else /* relSegment == RBSS */
  995. {
  996. targetAddr = (((LS26BITS & *pAddress) << 2)
  997.             + (MS4BITS & (long) pAddress )
  998.     + (long) pSeg->addrBss);
  999. }
  1000.                     if (MS4BITS & targetAddr !=
  1001.         (MS4BITS & ((long) pAddress + sizeof(INSTR))))
  1002.         {
  1003.         errnoSet (S_loadEcoffLib_JMPADDR_ERROR);
  1004.         return (ERROR);
  1005.         }
  1006.     targetAddr = (unsigned) targetAddr >> 2;
  1007.                     /* checking for overflows here is not valid */
  1008.     targetAddr &= LS26BITS;
  1009.     *pAddress =  (MS6BITS & *pAddress) | targetAddr;
  1010.     break;
  1011. case R_REFHI:
  1012. /*
  1013. *  A refhi relocation is done by reading the next relocation
  1014. *  entry (always the coresponding reflo entry).  This least
  1015. *  significant 16 bits are taken from the refhi instruction 
  1016. *  and shifted left to form a 32 bit value.  This value is 
  1017. *  added to the least significant 16 bits of the reflo 
  1018. *  instruction (taking into account sign extention) to form 
  1019. *  a 32 bit reference pointer.  The target address is added 
  1020. *  to this constant and placed back in the least significant 
  1021. *  16 bits of each instruction address.  The contents of the 
  1022. *  lower 16 bits of pAddress (refhiConstant) are saved for any 
  1023. *  other reflo entries that the refhi entry may correspond to.
  1024. *  See IDT Assembly language programmers guide pg. 10-16
  1025. */
  1026.     refhiConstant = (*pAddress << 16);
  1027.     nextRelocCmd = *pRelCmds++;
  1028.     nCmds -= 1;
  1029.          if (nextRelocCmd.r_type != R_REFLO) 
  1030. {
  1031.              errnoSet (S_loadEcoffLib_NO_REFLO_PAIR);
  1032.         return (ERROR);
  1033. }
  1034.              if (segment == RTEXT)
  1035. {
  1036.              pNextAddress = (long *) ((long) pSeg->addrText + 
  1037.     nextRelocCmd.r_vaddr);
  1038. }
  1039.     else /* segment == RDATA */
  1040. {
  1041.      pNextAddress = (long *) ((long) pSeg->addrData + 
  1042.     (nextRelocCmd.r_vaddr - 
  1043.     (long) pSeg->sizeText));
  1044. }
  1045.     /* following cast to short guarantees sign extension */
  1046.     relocConstant = ((LS16BITS & *pAddress) << 16)
  1047.         + (int) ((short) (LS16BITS & *pNextAddress));
  1048.     if (relSegment == RTEXT)
  1049. {
  1050. targetAddr = relocConstant + (long) pSeg->addrText;
  1051. }
  1052.     else if (relSegment == RDATA)
  1053. {
  1054. relocConstant = relocConstant - pSeg->sizeText;
  1055.         targetAddr = relocConstant + (long) pSeg->addrData;
  1056. }
  1057.     else /* relSegment == RBSS */
  1058. {
  1059. relocConstant = relocConstant - pSeg->sizeText - 
  1060.     pSeg->sizeData;
  1061.         targetAddr = relocConstant + (long) pSeg->addrBss;
  1062. }
  1063.                     if ((LS16BITS & targetAddr) >= OVERFLOW)
  1064.         targetAddr += OVERFLOW_COMPENSATION;
  1065.     *pAddress = ((MS16BITS & *pAddress) |
  1066.   ((unsigned) (MS16BITS & targetAddr) >> 16));
  1067.     *pNextAddress = (MS16BITS & *pNextAddress) | 
  1068. (LS16BITS & targetAddr);
  1069.             break;
  1070. case R_REFLO:
  1071. /*
  1072. *  Since a REFHI must occur with a REFLO pair (lui, addi 
  1073. *  instructions) it was originally thought that a REFLO 
  1074. *  entry would never be seen alone.  This turned out to 
  1075. *  be an incorrect assumption.  If a R_REFLO is by itself, 
  1076. *  it is assumed to belong to the last R_REFHI entry.
  1077. */
  1078.                     /* following cast to short guarantees sign extension */
  1079.     relocConstant = (LS16BITS & refhiConstant) 
  1080. + (int) ((short) (LS16BITS & *pAddress));
  1081.     if (relSegment == RTEXT)
  1082. {
  1083. targetAddr = relocConstant + 
  1084.     (long) pSeg->addrText;
  1085. }
  1086.     else if (relSegment == RDATA)
  1087. {
  1088. relocConstant = relocConstant - pSeg->sizeText;
  1089.         targetAddr = relocConstant + (long) pSeg->addrData;
  1090. }
  1091.     else /* relSegment == RBSS */
  1092. {
  1093. relocConstant = relocConstant - pSeg->sizeText - 
  1094.     pSeg->sizeData;
  1095.         targetAddr = relocConstant + (long) pSeg->addrBss;
  1096. }
  1097.     if ((LS16BITS & targetAddr) >= OVERFLOW)
  1098. targetAddr += OVERFLOW_COMPENSATION;
  1099.     *pAddress = ((MS16BITS & *pAddress) | 
  1100. (LS16BITS & targetAddr));
  1101.     break;
  1102. case R_GPREL:
  1103. case R_LITERAL:
  1104.     printErr (gpRelativeReloc);
  1105.          errnoSet (S_loadEcoffLib_GPREL_REFERENCE);
  1106.     return (ERROR);  /* gp relative addressing not supported */
  1107.     break;
  1108. case R_ABS:
  1109.     break; /* relocation already completed */
  1110. default:
  1111.     printErr ("Unknown relocation type %dn", relocCmd.r_type);
  1112.          errnoSet (S_loadEcoffLib_UNRECOGNIZED_RELOCENTRY);
  1113.     return (ERROR); /* unrecognized relocation type */
  1114.     break;
  1115. }
  1116.     }
  1117. }
  1118.     return (OK);
  1119.     }
  1120. /*******************************************************************************
  1121. *
  1122. * softSeek - seek forward into a file
  1123. *
  1124. * This procedure seeks forward into a file without actually using seek
  1125. * calls.  It is usefull since seek does not work on all devices.
  1126. *
  1127. * RETURNS:
  1128. * OK, or
  1129. * ERROR if forward seek could not be accomplished
  1130. *
  1131. */
  1132. LOCAL STATUS softSeek 
  1133.     (
  1134.     int fd, /* fd to seek with */
  1135.     int startOfFileOffset  /* byte index to seek to */
  1136.     )
  1137.     {
  1138.     int position; /* present file position */
  1139.     int bytesToRead; /* bytes needed to read */
  1140.     char tempBuffer[BUFSIZE]; /* temp buffer for bytes */
  1141.     position = ioctl (fd, FIOWHERE, (int) 0);
  1142.     if (position > startOfFileOffset)
  1143. return(ERROR);
  1144.     /* calculate bytes to read */
  1145.     bytesToRead = startOfFileOffset - position;
  1146.     while (bytesToRead >= BUFSIZE)
  1147. {
  1148.         if (fioRead (fd, tempBuffer, BUFSIZE) != BUFSIZE)
  1149.     return (ERROR);
  1150. bytesToRead -= BUFSIZE;
  1151. }
  1152.     if (bytesToRead > 0)
  1153. {
  1154.         if (fioRead (fd, tempBuffer, bytesToRead) != bytesToRead)
  1155.     return (ERROR);
  1156. }
  1157.     return(OK);
  1158.     }
  1159. /*******************************************************************************
  1160. *
  1161. * ecoffToVxSym - Translate an ecoff symbol type to a VxWorks symbol type
  1162. *
  1163. * This procedure translates an ecoff symbol type to a symbol type that the 
  1164. * VxWorks symbol table can understand.
  1165. *
  1166. * RETURNS:
  1167. * OK, or
  1168. * ERROR if the symbol could not be tranlated.
  1169. *
  1170. */
  1171. LOCAL STATUS ecoffToVxSym
  1172.     (
  1173.     EXTR *symbol, /* ecoff symbol to convert */
  1174.     SYM_TYPE *pVxSymType  /* where to place conversion */
  1175.     )
  1176.     {
  1177.     switch(symbol->U_SYM_TYPE)
  1178. {
  1179. case scText:
  1180.     *pVxSymType = (SYM_TYPE) N_TEXT;
  1181.     break;
  1182. case scData:
  1183. case scRData:
  1184.         case scSData:
  1185.     *pVxSymType = (SYM_TYPE) N_DATA;
  1186.     break;
  1187. case scBss:
  1188.         case scSBss:
  1189.     *pVxSymType = (SYM_TYPE) N_BSS;
  1190.     break;
  1191. case scCommon:
  1192. case scSCommon:
  1193.     *pVxSymType = (SYM_TYPE) N_COMM;
  1194.     break;
  1195.         case scUndefined:
  1196. case scSUndefined:
  1197.         case scNil:
  1198. case scAbs:
  1199.     errnoSet (S_loadEcoffLib_UNEXPECTED_SYM_CLASS);
  1200.     return (ERROR);
  1201.     break;
  1202. default:
  1203.     errnoSet (S_loadEcoffLib_UNRECOGNIZED_SYM_CLASS);
  1204.     return (ERROR);
  1205.     break;
  1206. }
  1207.     /* convert to global symbol ? */
  1208.     if (COFF_EXT(symbol))
  1209. *pVxSymType |= (SYM_TYPE) N_EXT;
  1210.     return (OK);
  1211.     }
  1212. /*******************************************************************************
  1213. *
  1214. * nameToRelocSection - Convert COFF section name to integer representation
  1215. *
  1216. * This procedure converts a COFF section name to it's appropriate integer
  1217. * designator.  
  1218. *
  1219. * RETURNS:
  1220. * Integer value of section name
  1221. * or ERROR if section relocation is not supported.
  1222. *
  1223. */
  1224. LOCAL int nameToRelocSection
  1225.     (
  1226.     char * pName         /* section name */
  1227.     )
  1228.     {
  1229.     if (strcmp (pName,_TEXT) == 0)
  1230.         return (R_SN_TEXT);
  1231.     else if (strcmp (pName,_RDATA) == 0)
  1232.         return (R_SN_RDATA);
  1233.     else if (strcmp (pName,_DATA) == 0)
  1234.         return (R_SN_DATA);
  1235.     else if (strcmp (pName,_SDATA) == 0)
  1236.         return (ERROR); /* R_SN_SDATA: no gp rel sections */
  1237.     else if (strcmp (pName,_SBSS) == 0)
  1238.         return (ERROR); /* R_SN_SBSS: no gp rel sections */
  1239.     else if (strcmp (pName,_BSS) == 0)
  1240.         return (ERROR); /* R_SN_BSS: bss not relocatable */
  1241.     else if (strcmp (pName,_INIT) == 0)
  1242. return (R_SN_INIT);
  1243.     else if (strcmp (pName,_LIT8) == 0)
  1244.         return (ERROR); /* R_SN_LIT8: no gp rel sections */
  1245.     else if (strcmp (pName,_LIT4) == 0)
  1246.         return (ERROR); /* R_SN_LIT8: no gp rel sections */
  1247.     else
  1248.         return (ERROR);      /* return ERROR */
  1249.     }
  1250. /*******************************************************************************
  1251. *
  1252. * swapCoffscnHdr - swap endianess of COFF section header
  1253. */
  1254. LOCAL void swapCoffscnHdr
  1255.     (
  1256.     SCNHDR *pScnHdr  /* module's ECOFF section header */
  1257.     )
  1258.     {
  1259.     SCNHDR tempScnHdr;
  1260.     bcopy ((char *) &pScnHdr->s_name[0], (char *) &tempScnHdr.s_name[0], 8);
  1261.     swabLong ((char *) &pScnHdr->s_paddr, (char *) &tempScnHdr.s_paddr);
  1262.     swabLong ((char *) &pScnHdr->s_vaddr, (char *) &tempScnHdr.s_vaddr);
  1263.     swabLong ((char *) &pScnHdr->s_size, (char *) &tempScnHdr.s_size);
  1264.     swabLong ((char *) &pScnHdr->s_scnptr, (char *) &tempScnHdr.s_scnptr);
  1265.     swabLong ((char *) &pScnHdr->s_relptr, (char *) &tempScnHdr.s_relptr);
  1266.     swabLong ((char *) &pScnHdr->s_lnnoptr, (char *) &tempScnHdr.s_lnnoptr);
  1267.     swab ((char *) &pScnHdr->s_nreloc, (char *) &tempScnHdr.s_nreloc, 
  1268. sizeof(pScnHdr->s_nreloc));
  1269.     swab ((char *) &pScnHdr->s_nlnno, (char *) &tempScnHdr.s_nlnno, 
  1270. sizeof(pScnHdr->s_nlnno));
  1271.     swabLong ((char *) &pScnHdr->s_flags, (char *) &tempScnHdr.s_flags);
  1272.     bcopy ((char *) &tempScnHdr, (char *) pScnHdr, sizeof(SCNHDR));
  1273.     }
  1274. /*******************************************************************************
  1275. *
  1276. * swapCoffsymHdr - swap endianess of COFF symbolic header
  1277. */
  1278. LOCAL void swapCoffsymHdr
  1279.     (
  1280.     HDRR *pSymHdr  /* module's ECOFF symbolic header */
  1281.     )
  1282.     {
  1283.     HDRR tempSymHdr;
  1284.     swab ((char *) &pSymHdr->magic, (char *) &tempSymHdr.magic, 
  1285. sizeof(pSymHdr->magic));
  1286.     swab ((char *) &pSymHdr->vstamp, (char *) &tempSymHdr.vstamp, 
  1287. sizeof(pSymHdr->vstamp));
  1288.     swabLong ((char *) &pSymHdr->ilineMax, (char *) &tempSymHdr.ilineMax);
  1289.     swabLong ((char *) &pSymHdr->cbLine, (char *) &tempSymHdr.cbLine);
  1290.     swabLong ((char *) &pSymHdr->cbLineOffset, 
  1291. (char *) &tempSymHdr.cbLineOffset);
  1292.     swabLong ((char *) &pSymHdr->idnMax, (char *) &tempSymHdr.idnMax);
  1293.     swabLong ((char *) &pSymHdr->cbDnOffset, (char *) &tempSymHdr.cbDnOffset);
  1294.     swabLong ((char *) &pSymHdr->ipdMax, (char *) &tempSymHdr.ipdMax);
  1295.     swabLong ((char *) &pSymHdr->cbPdOffset, (char *) &tempSymHdr.cbPdOffset);
  1296.     swabLong ((char *) &pSymHdr->isymMax, (char *) &tempSymHdr.isymMax);
  1297.     swabLong ((char *) &pSymHdr->cbSymOffset, (char *) &tempSymHdr.cbSymOffset);
  1298.     swabLong ((char *) &pSymHdr->ioptMax, (char *) &tempSymHdr.ioptMax);
  1299.     swabLong ((char *) &pSymHdr->cbOptOffset, (char *) &tempSymHdr.cbOptOffset);
  1300.     swabLong ((char *) &pSymHdr->iauxMax, (char *) &tempSymHdr.iauxMax);
  1301.     swabLong ((char *) &pSymHdr->cbAuxOffset, (char *) &tempSymHdr.cbAuxOffset);
  1302.     swabLong ((char *) &pSymHdr->issMax, (char *) &tempSymHdr.issMax);
  1303.     swabLong ((char *) &pSymHdr->cbSsOffset, (char *) &tempSymHdr.cbSsOffset);
  1304.     swabLong ((char *) &pSymHdr->issExtMax, (char *) &tempSymHdr.issExtMax);
  1305.     swabLong ((char *) &pSymHdr->cbSsExtOffset, 
  1306. (char *) &tempSymHdr.cbSsExtOffset);
  1307.     swabLong ((char *) &pSymHdr->ifdMax, (char *) &tempSymHdr.ifdMax);
  1308.     swabLong ((char *) &pSymHdr->cbFdOffset, (char *) &tempSymHdr.cbFdOffset);
  1309.     swabLong ((char *) &pSymHdr->crfd, (char *) &tempSymHdr.crfd);
  1310.     swabLong ((char *) &pSymHdr->cbRfdOffset, (char *) &tempSymHdr.cbRfdOffset);
  1311.     swabLong ((char *) &pSymHdr->iextMax, (char *) &tempSymHdr.iextMax);
  1312.     swabLong ((char *) &pSymHdr->cbExtOffset, (char *) &tempSymHdr.cbExtOffset);
  1313.     bcopy ((char *) &tempSymHdr, (char *) pSymHdr, sizeof(HDRR));
  1314.     }
  1315. /*******************************************************************************
  1316. *
  1317. * swapCoffsymbols - swap endianess of COFF symbols
  1318. */
  1319. LOCAL void swapCoffsymbols
  1320.     (
  1321.     EXTR *pSym, /* module's ECOFF symbol table */
  1322.     int symCount  /* number of symbols in table */
  1323.     )
  1324.     {
  1325.     EXTR tempExtSym;
  1326.     SYMR_LE tempSym;
  1327.     EXTR_LE tempRsvd;
  1328.     for(;symCount > 0; pSym++, symCount--)
  1329. {
  1330. /* swap short bitfield */
  1331. swab ((char *)pSym, (char *) &tempRsvd, sizeof(tempRsvd));
  1332. tempExtSym.jmptbl = tempRsvd.jmptbl;
  1333. tempExtSym.cobol_main = tempRsvd.cobol_main;
  1334. tempExtSym.reserved = tempRsvd.reserved;
  1335. swab ((char *) &pSym->ifd, (char *) &tempExtSym.ifd, sizeof(pSym->ifd));
  1336. swabLong ((char *) &pSym->asym.iss, (char *) &tempExtSym.asym.iss);
  1337. swabLong ((char *) &pSym->asym.value, (char *) &tempExtSym.asym.value);
  1338. /* 
  1339. *  The correct way to do the following swap would be to define a 
  1340. *  union so the address of the bitfield could be taken.  Doing this
  1341. *  would ripple changes through all of vxWorks so we are avioding
  1342. *  it at the moment.  If any fields get added to the structure
  1343. *  SYMR after value and before the bitfield we will surely notice
  1344. *  it here.
  1345. */
  1346. /* swap long bitfield */
  1347. swabLong ((char *) ((long) &pSym->asym.value + 
  1348.     sizeof(pSym->asym.value)),
  1349.     (char *) ((long) &tempSym.value + 
  1350.     sizeof(tempSym.value)));
  1351. tempExtSym.asym.st = tempSym.st;
  1352. tempExtSym.asym.sc = tempSym.sc;
  1353. tempExtSym.asym.reserved = tempSym.reserved;
  1354. tempExtSym.asym.index = tempSym.index;
  1355.         bcopy ((char *) &tempExtSym, (char *) pSym, sizeof(EXTR));
  1356. }
  1357.     }
  1358. /*******************************************************************************
  1359. *
  1360. * swapCoffrelocTbl - swap endianess of COFF relocation entries
  1361. */
  1362. LOCAL void swapCoffrelocTbl
  1363.     (
  1364.     RELOC *pReloc, /* module's ECOFF relocation table */
  1365.     int relocCount  /* number of relocation entries in table */
  1366.     )
  1367.     {
  1368.     RELOC tempReloc;
  1369.     RELOC_LE tempBits;
  1370.     for (;relocCount > 0; pReloc++, relocCount--)
  1371. {
  1372. swabLong ((char *) &pReloc->r_vaddr, (char *) &tempReloc.r_vaddr);
  1373. /* 
  1374. *  The correct way to do the following swap would be to define a 
  1375. *  union so the address of the bitfield could be taken.  Doing this
  1376. *  would ripple changes through all of vxWorks so we are avioding
  1377. *  it at the moment.  If any fields get added to the structure
  1378. *  RELOC after r_vaddr and before the bitfield we will surely notice
  1379. *  it here.
  1380. */
  1381. /* swap long bitfield */
  1382. swabLong ((char *) ((long) &pReloc->r_vaddr +
  1383.     sizeof(pReloc->r_vaddr)),
  1384.     (char *) ((long) &tempBits +
  1385.     sizeof(tempBits.r_vaddr)));
  1386. tempReloc.r_symndx = tempBits.r_symndx;
  1387. tempReloc.r_reserved = tempBits.r_reserved;
  1388. tempReloc.r_type = tempBits.r_type;
  1389. tempReloc.r_extern = tempBits.r_extern;
  1390.         bcopy ((char *) &tempReloc, (char *) pReloc, 
  1391.     sizeof(RELOC));
  1392. }
  1393.     }
  1394. /*******************************************************************************
  1395. *
  1396. * ecoffSecHdrRead - read in COFF section header and swap if necessary
  1397. */
  1398. LOCAL STATUS ecoffSecHdrRead
  1399.     (
  1400.     int    fd,
  1401.     SCNHDR *pScnHdr,
  1402.     FILHDR *pHdr,
  1403.     BOOL   swapTables 
  1404.     )
  1405.     {
  1406.     int ix;
  1407.     /* check for correct section count */
  1408.     if (pHdr->f_nscns < NO_SCNS || pHdr->f_nscns > MAX_SCNS)
  1409. {
  1410. return (ERROR);
  1411. }
  1412.     for (ix = 0; ix < pHdr->f_nscns; ix++)
  1413. {
  1414.         if (fioRead (fd, (char *)pScnHdr, sizeof(SCNHDR)) != sizeof(SCNHDR))
  1415.     {
  1416.     return (ERROR);
  1417.     }
  1418.         if (swapTables)
  1419.     {
  1420.     swapCoffscnHdr (pScnHdr);
  1421.     }
  1422. pScnHdr++;
  1423. }
  1424.     return (OK);
  1425.     }
  1426. /*******************************************************************************
  1427. *
  1428. * ecoffReadInSections - read in COFF sections
  1429. */
  1430. LOCAL STATUS ecoffReadInSections
  1431.     (
  1432.     int    fd,
  1433.     char   **pSectPtr,
  1434.     SCNHDR *pScnHdr,
  1435.     BOOL   swapTables 
  1436.     )
  1437.     {
  1438.     FAST int ix;
  1439.     for (ix = 0; ix < MAX_SCNS; ix++)
  1440. {
  1441. if (pScnHdr->s_size != 0 && pScnHdr->s_scnptr != 0)
  1442.     {
  1443.             if ((*pSectPtr = (char *) malloc ((UINT)pScnHdr->s_size)) == NULL)
  1444. {
  1445. return (ERROR);
  1446. }
  1447.             if ((softSeek (fd, pScnHdr->s_scnptr) == ERROR) ||
  1448.                 (fioRead (fd, *pSectPtr, (int) pScnHdr->s_size) != 
  1449.  pScnHdr->s_size))
  1450. {
  1451. return (ERROR);
  1452. }
  1453.     }
  1454. pScnHdr++;
  1455. pSectPtr++;
  1456. }
  1457.     return (OK);
  1458.     }
  1459. /*******************************************************************************
  1460. *
  1461. * ecoffLdSections - write out sections to memory
  1462. */
  1463. LOCAL STATUS ecoffLdSections
  1464.     (
  1465.     char    **pSectPtr,
  1466.     SCNHDR  *pScnHdr,
  1467.     AOUTHDR *pOptHdr,
  1468.     char    *pText,
  1469.     char    *pData 
  1470.     )
  1471.     {
  1472.     int     ix;
  1473.     int     textCount = 0;
  1474.     int     dataCount = 0;
  1475.     for (ix = 0; ix < MAX_SCNS; ix++)
  1476. {
  1477. if (strcmp (pScnHdr->s_name, _TEXT) == 0 ||
  1478.     strcmp (pScnHdr->s_name, _INIT) == 0)
  1479.     {
  1480.             bcopy (*pSectPtr, pText, pScnHdr->s_size);
  1481.     pText = (char *) ((int) pText + pScnHdr->s_size);
  1482.     textCount += pScnHdr->s_size;
  1483.     }
  1484. else if (strcmp (pScnHdr->s_name, _DATA) == 0 ||
  1485.  strcmp (pScnHdr->s_name, _RDATA) == 0 ||
  1486.  strcmp (pScnHdr->s_name, _SDATA) == 0 ||
  1487.  strcmp (pScnHdr->s_name, _LIT4) == 0  ||
  1488.  strcmp (pScnHdr->s_name, _LIT8) == 0)
  1489.     {
  1490.             bcopy (*pSectPtr, pData, pScnHdr->s_size);
  1491.     pData = (char *) ((int) pData + pScnHdr->s_size);
  1492.     dataCount += pScnHdr->s_size;
  1493.     }
  1494. else
  1495.     {
  1496.     /* ignore all other sections */
  1497.     }
  1498. pScnHdr++;
  1499. pSectPtr++;
  1500. }
  1501.     /* did we copy it all ? */
  1502.     if ((textCount != pOptHdr->tsize) || (dataCount != pOptHdr->dsize))
  1503. {
  1504. return (ERROR);
  1505. }
  1506.     return (OK);
  1507.     }
  1508. /*******************************************************************************
  1509. *
  1510. * ecoffReadRelocInfo - read in COFF relocation information and swap if necessary
  1511. */
  1512. LOCAL STATUS ecoffReadRelocInfo
  1513.     (
  1514.     int     fd,
  1515.     SCNHDR  *pScnHdrFirst,
  1516.     RELOC   *relsPtr[],
  1517.     BOOL    swapTables 
  1518.     )
  1519.     {
  1520.     int     relocSize;
  1521.     int     position; /* present file position */
  1522.     SCNHDR  *pScnHdr; /* try to use array instead pScnHdr[MAX_SCNS] */
  1523.     int     ix; /* index thru reloc info sections */
  1524.     int     iy; /* index thru section headers */
  1525.     for (ix = 0; ix < MAX_SCNS; ix++)
  1526. {
  1527. position = ioctl (fd, FIOWHERE, (int) 0);
  1528.         /*
  1529.  * look through each pScnHdr for relocation offset equal to 
  1530.  * current position.  should they be equal, then this relocation 
  1531.  * data corresponds to that section header.  Use the section header 
  1532.  * array index so that the resulting relocation information will
  1533.  * be in the same order as the section headers.
  1534.  */
  1535. pScnHdr = pScnHdrFirst;
  1536.         for (iy = 0; iy < MAX_SCNS; iy++)
  1537.     {
  1538.             if ((pScnHdr->s_nreloc > 0) && (pScnHdr->s_relptr == position))
  1539.         {
  1540.         relocSize = (int) pScnHdr->s_nreloc * RELSZ;
  1541.                 /* use array instead of pRelPtr */
  1542. /* then use header index into array */
  1543.         if ((relsPtr[iy] = (RELOC *)malloc (relocSize)) == NULL)
  1544.     {
  1545.     return (ERROR);
  1546.     }
  1547.         if (fioRead (fd, (char *) relsPtr[iy], relocSize) != relocSize)
  1548.     {
  1549.     return (ERROR);
  1550.     }
  1551.         if (swapTables)
  1552.     {
  1553.     swapCoffrelocTbl(relsPtr[iy], pScnHdr->s_nreloc);
  1554.     }
  1555.         break; /* found the right header, no need to look at the rest */
  1556.         }
  1557.     else
  1558.         pScnHdr++;
  1559.     }
  1560.         }
  1561.     return (OK);
  1562.     }
  1563. /*******************************************************************************
  1564. *
  1565. * ecoffReadSymHdr - read in COFF symbol header and swap if necessary
  1566. */
  1567. LOCAL STATUS ecoffReadSymHdr
  1568.     (
  1569.     int    fd,
  1570.     HDRR   *pSymHdr,
  1571.     FILHDR *pHdr,
  1572.     BOOL   swapTables 
  1573.     )
  1574.     {
  1575.     if (pHdr->f_nsyms == 0)
  1576. {
  1577. return (ERROR);
  1578. }
  1579.     else
  1580. {
  1581.         if ((softSeek (fd, pHdr->f_symptr) == ERROR) || 
  1582.             (fioRead (fd, (char *) pSymHdr, pHdr->f_nsyms) != pHdr->f_nsyms))
  1583.     {
  1584.     return (ERROR);
  1585.     }
  1586. if (swapTables)
  1587.     {
  1588.     swapCoffsymHdr (pSymHdr);
  1589.     }
  1590. }
  1591.     return (OK);
  1592.     }
  1593. /*******************************************************************************
  1594. *
  1595. * ecoffReadExtStrings - read in COFF external strings
  1596. */
  1597. LOCAL STATUS ecoffReadExtStrings
  1598.     (
  1599.     int  fd,
  1600.     char **pStrBuf,
  1601.     HDRR *pSymHdr 
  1602.     )
  1603.     {
  1604.     if (pSymHdr->issExtMax > 0)  /* is there a string table? */
  1605.         {
  1606.         if ((*pStrBuf = (char *) malloc ((UINT) pSymHdr->issExtMax)) == NULL)
  1607.     {
  1608.     return (ERROR);
  1609.     }
  1610. if ((softSeek (fd, pSymHdr->cbSsExtOffset) != OK) || 
  1611.     (fioRead (fd, *pStrBuf, (int) pSymHdr->issExtMax) != 
  1612.      pSymHdr->issExtMax))
  1613.     {
  1614.     return (ERROR);
  1615.     }
  1616.         }
  1617.     return (OK);
  1618.     }
  1619. /*******************************************************************************
  1620. *
  1621. * ecoffReadExtSyms - read in COFF external symbols and swap if necessary
  1622. */
  1623. LOCAL STATUS ecoffReadExtSyms
  1624.     (
  1625.     int  fd,
  1626.     EXTR **pExtSyms,
  1627.     HDRR *pSymHdr,
  1628.     BOOL swapTables 
  1629.     )
  1630.     {
  1631.     int extSymSize = (int) (pSymHdr->iextMax * cbEXTR);
  1632.     if (extSymSize != 0) /* is there a symbol table? */
  1633. {
  1634.         if ((*pExtSyms = (EXTR *) malloc (extSymSize)) == NULL)
  1635.     {
  1636.     return (ERROR);
  1637.     }
  1638.         if (softSeek (fd, pSymHdr->cbExtOffset) == ERROR) 
  1639.     {
  1640.     return (ERROR);
  1641.     }
  1642.         if (fioRead (fd, (char *) *pExtSyms, extSymSize) != extSymSize)
  1643.     {
  1644.     return (ERROR);
  1645.     }
  1646. if (swapTables)
  1647.     {
  1648.     swapCoffsymbols (*pExtSyms, pSymHdr->iextMax);
  1649.     }
  1650. }
  1651.     return (OK);
  1652.     }
  1653. /*******************************************************************************
  1654. *
  1655. * sizeEcoffCommons - 
  1656. *  INTERNAL
  1657. *  All common external symbols are being tacked on to the end
  1658. *  of the BSS section.  Each symbol is examined and placed at
  1659. *  the appropriate address.  The appropriate address is determined
  1660. *  by examining the address of the previous common symbol and the
  1661. *  size of the current common symbol.  (The size of the symbol is 
  1662. *  contained in the U_SYM_VALUE field of the symbol entry)  The 
  1663. *  address of a symbol must be correctly aliged for data access.  
  1664. *  For example, on the R3000 architecture word accesses must be word 
  1665. *  aligned.  The macro COMMON_ALIGNMENT is the base boundry size for the
  1666. *  architecture.
  1667. */
  1668. LOCAL ULONG sizeEcoffCommons 
  1669.     (
  1670.     EXTR *pNextSym,
  1671.     ULONG alignBss 
  1672.     )
  1673.     {
  1674.     ULONG fixupBss;
  1675.     ULONG nbytes = 0;
  1676.     fixupBss = ((alignBss % (ULONG) pNextSym->U_SYM_VALUE) & 
  1677.         (COMMON_ALIGNMENT - 1));
  1678.     if (fixupBss != 0)
  1679.         {
  1680.         fixupBss = COMMON_ALIGNMENT - fixupBss;
  1681.         }
  1682.     nbytes = (ULONG) pNextSym->U_SYM_VALUE + fixupBss;
  1683.     return (nbytes);
  1684.     }