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

VxWorks

开发平台:

C/C++

  1. /* loadAoutLib.c - UNIX a.out object module loader */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 06o,11may02,fmk  SPR 77007 - improve common symbol support
  8. 06n,28mar02,jn   rewind to the beginning of the file before reading the header
  9.                  information (SPR 73145)
  10. 06m,30nov98,dbt  no longer clear seg.flags<xxx> after loadSegmentAllocate()
  11.                  call. (SPR #23553).
  12. 06l,05oct98,pcn  Initialize all the fields in the SEG_INFO structure.
  13. 06k,16sep98,pcn  Set to _ALLOC_ALIGN_SIZE the flags field in seg structure
  14.                  (SPR #21836).
  15. 06j,17jul98,pcn  Fixed SPR #21836: alignment mismatch between sections and
  16.                  target.
  17. 06i,31oct96,elp  Replaced symAdd() call by symSAdd() call (symtbls synchro).
  18. 06h,07aug96,dbt  call loadModuleGet with MODULE_A_OUT format (SPR #3006).
  19. 06g,23feb95,caf  fixed #endif.
  20. 06f,12jun93,rrr  vxsim.
  21. 06e,30oct92,jwt  #if for nonLongErrMsg[] for all CPU_FAMILYs but SPARC.
  22. 06d,28oct92,yao  added support for non-contiguous text/data/bss segments in 
  23.             jwt  relSegmentSparc(); cleaned up warnings and relSegmentSparc().
  24. 06c,16oct92,jmm  fixed spr 1664 - local symbols always added (in RdSymtab())
  25. 06b,31jul92,dnw  changed to call CACHE_TEXT_UPDATE.  doc tweak.
  26. 06a,29jul92,jcf  removed unnecessary forward declaration.
  27. 05z,29jul92,elh  Move boot routines to bootAoutLib.c
  28. 05y,22jul92,jmm  moduleSegAdd now called for all modules
  29.                  loadSegmentsAllocate now called to allocate memory
  30. 05x,21jul92,rdc  mods to support text segment write protection.
  31.  changed the way aoutLdMdlAtSym allocates mem for segs
  32.  (didn't really work before.)
  33. 05w,14jul92,jmm  added support for unloading, including calls to moduleLib
  34.                  permanent cache fix for MC68040
  35.  moved addSegNames to loadLib.c
  36. 05v,04jul92,smb  temporary cache fix for MC68040.
  37. 05u,01jul92,jmm  more cleanup of magic numbers
  38. 05t,23jun92,rrr  cleanup of some magic numbers
  39. 05s,18jun92,ajm, made object module independant with split from loadLib.c
  40.             jwt  fixed masking bug in relSegmentSparc() as per SPARC 05i.
  41. 05r,26may92,rrr  the tree shuffle
  42. 05q,10dec91,gae  added includes for ANSI.
  43. 05p,19nov91,rrr  shut up some ansi warnings.
  44. 05o,05oct91,ajm  changed bad ifdef of CPU==MIPS to CPU_FAMILY in relSegmentR3k
  45. 05n,04oct91,rrr  passed through the ansification filter
  46.                   -changed functions to ansi style
  47.   -changed includes to have absolute path from h/
  48.   -fixed #else and #endif
  49.   -changed TINY and UTINY to INT8 and UINT8
  50.   -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY and ...
  51.   -changed VOID to void
  52.   -changed copyright notice
  53. 05m,30aug91,ajm  added MIPS support from 68k 05h, and mips 4.02 05q.
  54. 05l,28aug91,shl  added cache coherency calls for MC68040 support.
  55. 05k,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  56.  doc review by dnw.
  57. 05j,31mar91,del  made file null for I960.
  58. 05i,08feb91,jaa  documentation cleanup.
  59. 05h,05oct90,dnw  made loadModuleAtSym() be NOMANUAL.
  60. 05g,30jul90,dnw  changed pathLastName() to pathLastNamePtr().
  61.  added forward declaration of void routines.
  62. 05f,11may90,yao  added missing modification history (05e) for the last checkin.
  63. 05e,09may90,yao  typecasted malloc to (char *).
  64. 05d,22aug89,jcf  updated to allow for separate symbol tables.
  65.   symbol table type now a SYM_TYPE.
  66. 05c,06jul89,ecs  updated to track 4.0.2.
  67. 05b,06jun89,ecs  fixed bug in relSegmentSparc.
  68. 05a,01may89,ecs  split relSegment into relSegmentSparc & relSegment68k.
  69. 04g,06jul89,llk  changed call to pathLastName().
  70. 04f,16jun89,llk  made loadModuleAt add absolute symbols to symbol table.
  71.  created SEG_INFO structure to reduce parameter passing.
  72. 04e,09jun89,llk  fixed bug so that symbols which reside in segments that have
  73.    been located at a specific address now have the correct
  74.    relocated address entered in the symbol table.
  75. 04d,01may89,gae  added empty N_ABS case to relSegment to stop useless warnings.
  76. 04c,02oct88,hin  used correct N_TYPE constant in 04b fix.
  77. 04b,29sep88,gae  fixed relative relocation bug with Greenhill's a.out,
  78.    sort of introduced in 03y.
  79. 04a,07sep88,gae  applied dnw's documentation.
  80. 03z,15aug88,jcf  lint.
  81. 03y,30jun88,dnw  fixed bug of not relocating relative to data or bss correctly.
  82.     llk
  83. 03x,05jun88,dnw  changed from ldLib to loadLib.
  84.  removed pathTail.
  85. 03w,30may88,dnw  changed to v4 names.
  86. 03v,28may88,dnw  removed ldLoadAt.
  87. 03u,19nov87,dnw  made ldLoadModule tolerant of 0 length segments, strings, etc.
  88. 03t,04nov87,rdc  made ldLoadModule not create segment names if NO_SYMBOLS.
  89. 03s,16oct87,gae  removed ldLoadName, or ldLoadFile, and made ldLoadModule
  90.    determine and add module name to symbol table.
  91.  added pathTail().
  92. 03r,29jul87,ecs  added ldLoadFile, ldLoadModule.
  93.     rdc  fixed rdSymtab to zero out space malloc'd for common symbols.
  94.     dnw  fixed to require exact match with system symbol table
  95.   instead of allowing matches with or without leading '_'.
  96.  fixed to not link COMM symbols to existing symbols.
  97. 03q,02jul87,ecs  changed rdSymtab to call symFindType, instead of symFind.
  98. 03p,02apr87,ecs  added include of strLib.h
  99. 03o,23mar87,jlf  documentation.
  100. 03n,20dec86,dnw  changed to not get include files from default directories.
  101. 03m,24nov86,llk  deleted SYSTEM conditional compiles.
  102. 03l,09oct86,dnw  fixed handling of "pc relative" relocation commands.
  103.  cleaned up rdSymtab.
  104.  changed to allocate externals table based on size of symbol
  105.    table in object module.
  106. 03k,04sep86,jlf  minor documentation.
  107. 03j,27jul86,llk  prints error messages to standard error
  108. 03i,24jun86,rdc  now throws away stabs and absolute symbols.  Now
  109.  dynamically allocates and frees necessary buffers.
  110.  now searches symbol table before allocating new symbol
  111.  for type N_COMM.
  112. 03h,04jun86,dnw  changed sstLib calls to symLib.
  113. 03g,03mar86,jlf  changed ioctrl calls to ioctl.
  114. 03f,22oct85,dnw  Fixed bug reading 4 bytes too many for BSD4.2 string table.
  115. 03e,11oct85,jlf  Made the string table buffer and the externals buffer
  116.    be allocated rather than on the stack.
  117.  Made new routine ldInit.
  118.  Got rid of MAX_STRINGS and MAX_SYMBOLS, and replaced them with
  119.    local variables which are initialize by ldInit.
  120.  De-linted.
  121. 03d,10oct85,jlf  upped MAX_STRINGS form 20000 to 25000.  Made all
  122.  references use the #define, instead of raw numbers.
  123. 03c,27aug85,rdc  changed MAX_SYM_LEN to MAX_SYS_SYM_LEN.
  124. 03b,12aug85,jlf  fixed to not try to relocate segments that have already
  125.  been relocated pc-relative in 4.2 version.  Also, made it
  126.  check relocation segment length, and print an error msg if
  127.  it's not a long.
  128. 03a,07aug85,jlf  combined 4.2 and v7/sys5 version.
  129. 02b,20jul85,jlf  documentation.
  130. 02a,24jun85,rdc  modified for 4.2 a.out format.
  131. 01e,19sep84,jlf  cleaned up comments a little
  132. 01d,09sep84,jlf  added comments, copyright, got rid of GLOBAL.
  133. 01c,10aug84,dnw  changed load to not add special module symbols {T,D,B,E}name
  134.    but also changed to add _etext, _edata, and _end as normal
  135.    symbols.
  136.  fixed rdSymtab to not set S_ldLib_UNDEFINED_SYMBOL and
  137.    instead just leave it S_symLib_SYMBOL_NOT_FOUND.
  138.  changed load to continue with relocation even if
  139.    undefined symbols were found.
  140.  changed call to 'fioOpen' to just 'open'.
  141.  replaced 'load' and 'loadat' with 'ldLoad' and 'ldLoadAt',
  142.    which now take an fd instead of filename.
  143. 01b,02jul84,ecs  changed format strings to be more unixlike.
  144. 01a,27apr84,dnw  written: some culled from old fioLib
  145. */
  146. /*
  147. DESCRIPTION
  148. This library provides an object module loading facility.  Any UNIX BSD `a.out'
  149. format files may be loaded into memory, relocated properly, their
  150. external references resolved, and their external definitions added to
  151. the system symbol table for use by other modules and from the shell.
  152. Modules may be loaded from any I/O stream.
  153. EXAMPLE
  154. .CS
  155.     fdX = open ("/devX/objFile", O_RDONLY);
  156.     loadModule (fdX, ALL_SYMBOLS);
  157.     close (fdX);
  158. .CE
  159. This code fragment would load the `a.out' file "objFile" located on
  160. device "/devX/" into memory which would be allocated from the system
  161. memory pool.  All external and static definitions from the file would be
  162. added to the system symbol table.
  163. This could also have been accomplished from the shell, by typing:
  164. .CS
  165.     -> ld (1) </devX/objFile
  166. .CE
  167. INCLUDE FILE: loadAoutLib.h
  168. SEE ALSO: usrLib, symLib, memLib,
  169. .pG "Basic OS"
  170. */
  171. /* LINTLIBRARY */
  172. #include "vxWorks.h"
  173. #include "a_out.h"
  174. #include "ioLib.h"
  175. #include "loadLib.h"
  176. #include "loadAoutLib.h"
  177. #include "stdlib.h"
  178. #include "pathLib.h"
  179. #include "string.h"
  180. #include "symLib.h"
  181. #include "sysSymTbl.h"
  182. #include "cacheLib.h"
  183. #include "fioLib.h"
  184. #include "logLib.h"
  185. #include "memLib.h"
  186. #include "errno.h"
  187. #include "stdio.h"
  188. #include "moduleLib.h"
  189. #include "private/vmLibP.h"
  190. #include "private/loadLibP.h"
  191. #if CPU_FAMILY==SIMSPARCSUNOS
  192. #undef CPU_FAMILY
  193. #define CPU_FAMILY SPARC
  194. #endif /* CPU_FAMILY==SIMSPARCSUNOS */
  195. /* The different systems use different names for the same info in some
  196.  * structures.  Make them the same here.
  197.  */
  198. #define A_OUT_HDR exec
  199. #define TEXTSIZE a_text
  200. #define DATASIZE a_data
  201. #define BSSSIZE a_bss
  202. #define TRSIZE a_trsize
  203. #define DRSIZE a_drsize
  204. #define U_SYM_STRUCT nlist
  205. #define U_SYM_TYPE n_type
  206. #define U_SYM_VALUE n_value
  207. #define RTEXT 0
  208. #define RDATA 1
  209. #define RBSS 2
  210. LOCAL char stringMemErrMsg [] =
  211.     "loadAoutLib error: insufficient memory for strings table (need %d bytes).n";
  212. LOCAL char extMemErrMsg [] =
  213.     "loadAoutLib error: insufficient memory for externals table (need %d bytes).n";
  214. LOCAL char cantAddSymErrMsg [] =
  215.     "loadAoutLib error: can't add '%s' to system symbol table - error = 0x%x.n";
  216. #if (CPU_FAMILY != SPARC)
  217. LOCAL char nonLongErrMsg [] =
  218.     "loadAoutLib error: attempt to relocate non-long address at 0x%x, code = %d.n";
  219. #endif
  220. LOCAL char readStringsErrMsg [] =
  221.     "loadAoutLib error: can't read string table - status = 0x%xn";
  222. /* forward static functions */
  223. #if CPU_FAMILY == SPARC
  224. static STATUS relSegmentSparc (int fd, int nbytes, char *segAddress, SEG_INFO
  225. *pSeg, char ** externals);
  226. #else
  227. static STATUS relSegment68k (int fd, int nbytes, char *segAddress, SEG_INFO
  228. *pSeg, char ** externals);
  229. #endif
  230. /* forward declarations */
  231.  
  232. LOCAL MODULE_ID aoutLdMdlAtSym (int fd, int symFlag, char **ppText,
  233. char **ppData, char **ppBss, SYMTAB_ID symTbl);
  234. LOCAL STATUS rdSymtab (int fd, int nbytes, char ** *externals, int max_symbols,
  235.        int symFlag, SEG_INFO *pSeg, char *symStrings,
  236.        SYMTAB_ID symTbl, UINT16 group);
  237. /* misc defines */
  238. #define STORE_MASKED_VALUE(address, mask, value) 
  239.     *(address) = ((*(address)) & ~(mask)) | ((value) & (mask))
  240. /*******************************************************************************
  241. *
  242. * loadAoutInit - initialize the system for aout load modules
  243. *
  244. * This routine initialized VxWorks to use an extended coff format for
  245. * loading modules.
  246. *
  247. * RETURNS:
  248. * OK, or
  249. * ERROR if XXX
  250. *
  251. * SEE ALSO: loadModuleAt()
  252. */
  253. STATUS loadAoutInit 
  254.     (
  255.     void
  256.     )
  257.     {
  258.     /* XXX check for installed ? */
  259.     loadRoutine = (FUNCPTR) aoutLdMdlAtSym;
  260.     return (OK);
  261.     }
  262. /******************************************************************************
  263. *
  264. * aoutLdMdlAtSym - load object module into memory with specified symbol table
  265. *
  266. * This routine is the underlying routine to loadModuleAtSym().  This interface
  267. * allows specification of the the symbol table used to resolve undefined
  268. * external references and to which to add new symbols.
  269. *
  270. * RETURNS:
  271. * MODULE_ID, or
  272. * NULL if can't read file or not enough memory or illegal file format
  273. *
  274. * NOMANUAL
  275. */
  276. LOCAL MODULE_ID aoutLdMdlAtSym
  277.     (
  278.     FAST int fd,        /* fd from which to read module */
  279.     int symFlag,        /* symbols to be added to table */
  280.                         /*   ([NO | GLOBAL | ALL]_SYMBOLS) */
  281.     char **ppText,      /* load text segment at address pointed to by this */
  282.                         /* pointer, return load address via this pointer */
  283.     char **ppData,      /* load data segment at address pointed to by this */
  284.                         /* pointer, return load address via this pointer */
  285.     char **ppBss,       /* load bss segment at address pointed to by this */
  286.                         /* pointer, return load address via this pointer */
  287.     SYMTAB_ID symTbl    /* symbol table to use */
  288.     )
  289.     {
  290.     struct A_OUT_HDR hdr; /* module's a.out header stored here */
  291.     SEG_INFO seg;
  292.     int status;
  293.     int nbytes;
  294.     FAST int numExternals;
  295.     UINT16  group;
  296.     MODULE_ID moduleId;
  297.     char * pText = (ppText == NULL) ? LD_NO_ADDRESS : *ppText;
  298.     char * pData  = (ppData == NULL) ? LD_NO_ADDRESS : *ppData;
  299.     char * pBss   = (ppBss  == NULL) ? LD_NO_ADDRESS : *ppBss;
  300.     char ** externalsBuf    = NULL; /* buffer for reading externals */
  301.     FAST char * stringsBuf  = NULL;
  302.     char  fileName[255];
  303.     /* Initialization */
  304.     memset ((void *)&seg, 0, sizeof (seg));
  305.     /* Set up the module */
  306.     ioctl (fd, FIOGETNAME, (int) fileName);
  307.     moduleId = loadModuleGet (fileName, MODULE_A_OUT, &symFlag);
  308.     if (moduleId == NULL)
  309.         return (NULL);
  310.     group = moduleId->group;
  311.     /* 
  312.      * Rewind to beginning of file before reading header 
  313.      * XXX - JN - The return values of all these calls to ioctl should 
  314.      * be checked.
  315.      */
  316.     ioctl(fd, FIOSEEK, 0);
  317.     if (fioRead (fd, (char *) &hdr, sizeof (hdr)) != sizeof (hdr))
  318. goto error;
  319.     seg.addrText = pText;
  320.     seg.addrData = pData;
  321.     seg.addrBss  = pBss;
  322.     seg.sizeText = hdr.TEXTSIZE;
  323.     seg.sizeData = hdr.DATASIZE;
  324.     seg.sizeBss  = hdr.BSSSIZE;
  325.     /* 
  326.      * SPR #21836: pSeg->flagsText, pSeg->flagsData, pSeg->flagsBss are used
  327.      * to save the max value of each segments. These max values are computed
  328.      * for each sections. These fields of pSeg are only used on output, then
  329.      * a temporary use is allowed.
  330.      */
  331.     seg.flagsText = _ALLOC_ALIGN_SIZE;
  332.     seg.flagsData = _ALLOC_ALIGN_SIZE;
  333.     seg.flagsBss  = _ALLOC_ALIGN_SIZE;
  334.     /* 
  335.      * SPR #21836: loadSegmentsAllocate() allocate memory aligned on 
  336.      * the max value of sections alignement saved in seg.flagsText,
  337.      * seg.flagsData, seg.flagsBss.
  338.      */
  339.     if (loadSegmentsAllocate (&seg) != OK)
  340.         {
  341. printErr ("Could not allocate segmentsn");
  342. goto error;
  343. }
  344.     else
  345. {
  346. pText = seg.addrText;
  347. pData = seg.addrData;
  348. pBss = seg.addrBss;
  349. }
  350.     /* read in all of text and initialized data */
  351.     if ((fioRead (fd, pText, (int) hdr.TEXTSIZE) != hdr.TEXTSIZE) ||
  352.         (fioRead (fd, pData, (int) hdr.DATASIZE) != hdr.DATASIZE))
  353. goto error;
  354.     /* read in symbol strings by seeking to string stuff,
  355.      * reading the first long which tells how big the
  356.      * string table is, and then reading the string table */
  357.     if ((ioctl (fd, FIOSEEK, N_STROFF(hdr)) == ERROR) ||
  358.         (fioRead (fd, (char *) &nbytes, 4) != 4))
  359. goto error;
  360.     if (nbytes != 0)
  361. {
  362. /* allocate and read in the string table */
  363. if ((stringsBuf = (char *) malloc ((unsigned) nbytes)) == NULL)
  364.     {
  365.     printErr (stringMemErrMsg, nbytes);
  366.     goto error;
  367.     }
  368. nbytes -= 4; /* subtract 4 byte length we just read */
  369. if (fioRead (fd, &stringsBuf [4], nbytes) != nbytes)
  370.     {
  371.     printErr (readStringsErrMsg, errno);
  372.     goto error;
  373.     }
  374. }
  375.     /* allocate the externalsBuf */
  376.     numExternals = hdr.a_syms / sizeof (struct U_SYM_STRUCT);
  377.     if (numExternals != 0)
  378. {
  379. externalsBuf = (char **) malloc ((unsigned) numExternals *
  380.  sizeof (char *));
  381. if (externalsBuf == NULL)
  382.     {
  383.     printErr (extMemErrMsg, numExternals * sizeof (char *));
  384.     goto error;
  385.     }
  386. }
  387.     /* add segment names to symbol table before other symbols */
  388.     if (!(symFlag & LOAD_NO_SYMBOLS))
  389. addSegNames (fd, pText, pData, pBss, symTbl, group);
  390.     /* read in symbol table */
  391.     if (ioctl (fd, FIOSEEK, N_SYMOFF(hdr)) == ERROR)
  392. goto error;
  393.     status = rdSymtab (fd, (int) hdr.a_syms, &externalsBuf, numExternals,
  394.        symFlag, &seg, stringsBuf, symTbl, group);
  395.     if (stringsBuf != NULL)
  396. {
  397. free (stringsBuf); /* finished with stringsBuf */
  398. stringsBuf = NULL;
  399. }
  400.     /* relocate text and data segments;
  401.      *   note: even if symbol table had missing symbols, continue with
  402.      *   relocation of those symbols that were found.
  403.      *   note: relocation is for changing the values of the relocated
  404.      *   symbols.  bss is uninitialized data, so it is not relocated
  405.      *   in the symbol table.
  406.      */
  407.     if (ioctl (fd, FIOSEEK, N_TXTOFF(hdr) + hdr.a_text + hdr.a_data) == ERROR)
  408. goto error;
  409.     if ((status == OK) || (errno == S_symLib_SYMBOL_NOT_FOUND))
  410. {
  411. #if CPU_FAMILY == SPARC
  412. if ((hdr.a_machtype & 0xffff) == 0x0107)
  413.     {
  414.     if ((relSegmentSparc (fd, (int) hdr.TRSIZE, seg.addrText, &seg,
  415.   externalsBuf) != OK) ||
  416. (relSegmentSparc (fd, (int) hdr.DRSIZE, seg.addrData, &seg,
  417.   externalsBuf) != OK))
  418.  goto error;
  419.     }
  420. else
  421.     {
  422.     printErr ("Unsupported Object module format, a_machtype : %#xn", 
  423. hdr.a_machtype);
  424.     goto error;
  425.     }
  426. #else
  427. if ((hdr.a_machtype & 0xffff) == 0x0107)
  428.     {
  429.     if ((relSegment68k (fd, (int) hdr.TRSIZE, seg.addrText, &seg,
  430. externalsBuf) != OK) ||
  431. (relSegment68k (fd, (int) hdr.DRSIZE, seg.addrData, &seg,
  432. externalsBuf) != OK))
  433.  goto error;
  434.     }
  435. else
  436.     {
  437.     printErr ("Unsupported Object module format, a_machtype : %#xn", 
  438. hdr.a_machtype);
  439.     goto error;
  440.     }
  441. #endif
  442. }
  443.     if (externalsBuf != NULL)
  444. {
  445. free ((char *) externalsBuf); /* finished with externalsBuf */
  446. externalsBuf = NULL;
  447. }
  448.     /* write protect the text if text segment protection is turned on */
  449.     if (seg.flagsText & SEG_WRITE_PROTECTION) 
  450. {
  451. if (VM_STATE_SET (NULL, pText, seg.sizeProtectedText,
  452.   VM_STATE_MASK_WRITABLE,
  453.   VM_STATE_WRITABLE_NOT) == ERROR)
  454.     goto error;
  455. }
  456.     /* return load addresses, where called for */
  457.     if (ppText != NULL)
  458. *ppText = pText;
  459.     if (ppData != NULL)
  460. *ppData = pData;
  461.     if (ppBss != NULL)
  462. *ppBss = pBss;
  463.     /* clear out bss */
  464.     bzero (pBss, (int) hdr.BSSSIZE);
  465.     /* flush stub to memory, flush any i-cache inconsistancies */
  466.     cacheTextUpdate (pText, hdr.TEXTSIZE);
  467.     /*
  468.      * Add the segments to the module.
  469.      * This has to happen after the relocation gets done.
  470.      * If the relocation happens first, the checksums won't be
  471.      * correct.
  472.      */
  473.     moduleSegAdd (moduleId, SEGMENT_TEXT, pText, hdr.TEXTSIZE, seg.flagsText);
  474.     moduleSegAdd (moduleId, SEGMENT_DATA, pData, hdr.DATASIZE, seg.flagsData);
  475.     moduleSegAdd (moduleId, SEGMENT_BSS, pBss, hdr.BSSSIZE, seg.flagsBss);
  476.     if (status == OK)
  477.         return (moduleId);
  478.     else
  479.         return (NULL);
  480.     /* error:
  481.      * clean up dynamically allocated temporary buffers and return ERROR */
  482. error:
  483.     if (stringsBuf != NULL)
  484. free (stringsBuf);
  485.     if (externalsBuf != NULL)
  486. free ((char *) externalsBuf);
  487.     /* flush stub to memory, flush any i-cache inconsistancies */
  488.     cacheTextUpdate (pText, hdr.TEXTSIZE);
  489.     /*
  490.      * Delete the module associated with the unsuccessful load
  491.      */
  492.     moduleDelete (moduleId);
  493.     return (NULL);
  494.     }
  495. /*******************************************************************************
  496. *
  497. * rdSymtab - read and process a symbol table
  498. *
  499. * This routine reads in a symbol table from an object file and processes
  500. * each of the external symbols defined therein.  This processing performs
  501. * two functions:
  502. *  1) defined symbols are entered in the system symbol table as
  503. *     specified by the "symFlag" argument:
  504. * ALL_SYMBOLS = all defined symbols (LOCAL and GLOBAL) are added,
  505. * GLOBAL_SYMBOLS = only external (GLOBAL) symbols are added,
  506. * NO_SYMBOLS = no symbols are added;
  507. *  2) any undefined externals are looked up in the system table, and
  508. *     if found, entered in the specified 'externals' array.  This array
  509. *     is indexed by the symbol number (position in the symbol table).
  510. *     Note that only undefined externals are filled in in 'externals' and
  511. *     that values for all other types of symbols are unchanged (i.e. left
  512. *     as garbage!).  This is ok because 'externals' is only used to
  513. *     perform relocations relative to previously undefined externals.
  514. *     Note that "common" symbols have type undefined external - the value
  515. *     field of the symbol will be non-zero for type common, indicating
  516. *     the size of the object.
  517. *
  518. * If more than the specified maximum number of symbols are found in the
  519. * symbol table, the externals array is extended to accomodate the additional
  520. * symbols.
  521. * If an undefined external cannot be found in the system symbol table,
  522. * an error message is printed, but ERROR is not returned until the entire
  523. * symbol table has been read, which allows all undefined externals to be
  524. * looked up.
  525. * Stabs and absolute symbols are automatically discarded.
  526. *
  527. * RETURNS: OK or ERROR
  528. */
  529. LOCAL STATUS rdSymtab
  530.     (
  531.     FAST int fd,                /* fd of file positioned to symbol table */
  532.     FAST int nbytes,            /* # of bytes of symbol table */
  533.     char ***externals,          /* pointer to pointer to array to fill in
  534.                                    values of undef externals */
  535.     int max_symbols,            /* max symbols that can be put in 'externals' */
  536.     int symFlag,                /* symbols to be added to table
  537.                                  *   ([NO|GLOBAL|ALL]_SYMBOLS) */
  538.     SEG_INFO *pSeg,             /* pointer to segment information */
  539.     char *symStrings,           /* symbol string table (only meaningful in
  540.                                    BSD 4.2) */
  541.     SYMTAB_ID symTbl,           /* symbol table to use */
  542.     UINT16 group /* symbol group */
  543.     )
  544.     {
  545.     struct U_SYM_STRUCT symbol;
  546.     char * adrs;
  547.     SYM_TYPE type;
  548.     char * bias;
  549.     FAST char * name; /* symbol name (plus EOS) */
  550.     int  sym_num = 0;
  551.     int  status  = OK;
  552.     for (; nbytes > 0; nbytes -= sizeof (symbol), ++sym_num)
  553. {
  554. /* read in next entry - symbol definition and name string */
  555. if (fioRead (fd, (char *) &symbol, sizeof (symbol)) != sizeof (symbol))
  556.     return (ERROR);
  557. /* we throw away stabs */
  558. if (symbol.n_type & N_STAB)
  559.     continue;
  560. /* symbol name string is in symStrings array indexed
  561.  * by symbol.n_un.n_name */
  562. name = symStrings + symbol.n_un.n_strx;
  563. /* add requested symbols to symbol table */
  564. if ((symbol.U_SYM_TYPE & N_TYPE) != N_UNDF)
  565.     {
  566.     if (((symFlag & LOAD_LOCAL_SYMBOLS) &&
  567.  !(symbol.U_SYM_TYPE & N_EXT)) ||
  568. ((symFlag & LOAD_GLOBAL_SYMBOLS) && symbol.U_SYM_TYPE & N_EXT))
  569. {
  570. switch (symbol.U_SYM_TYPE & N_TYPE)
  571.                     {
  572.                     case N_ABS:
  573. bias = 0;
  574. break;
  575.                     case N_DATA:
  576.                         bias = pSeg->addrData - pSeg->sizeText;
  577.                         break;
  578.                     case N_BSS:
  579.                         bias = pSeg->addrBss - pSeg->sizeText - pSeg->sizeData;
  580.                         break;
  581.                     default:
  582.                         bias = pSeg->addrText;
  583.                         break;
  584.                     }
  585. if (symSAdd (symTbl, name, symbol.U_SYM_VALUE + bias,
  586.     symbol.U_SYM_TYPE, group) != OK)
  587.     printErr (cantAddSymErrMsg, name, errno);
  588. }
  589.     }
  590. else
  591.     {
  592.     /* 
  593.              * undefined external symbol or "common" symbol - common
  594.              * symbol type is denoted by undefined external with the
  595.              * value set to non-zero. If symbol is a common, call
  596.              * loadCommonManage() to process.  Alignment information
  597.              * is not specified by a.out so '0' is passed as an
  598.              * alignment parameter to loadCommonManage.
  599.              */
  600.     
  601.     if (symbol.U_SYM_VALUE != 0)
  602. {
  603.                 if (loadCommonManage (symbol.U_SYM_VALUE, 0, name, 
  604.                     symTbl, (void *) &adrs,  &type, 
  605.                     symFlag, pSeg, group) != OK)
  606.                    status = ERROR;
  607. }
  608.     /* look up undefined external symbol in symbol table */
  609.     else if (symFindByNameAndType (symTbl, name, &adrs, &type,
  610.    N_EXT, N_EXT) != OK)
  611. {
  612. /* symbol not found in symbol table */
  613. printErr ("undefined symbol: %sn", name);
  614. adrs = NULL;
  615. status = ERROR;
  616. }
  617.     /* add symbol address to externals table, but first
  618.      * check for enough room in 'externals' table */
  619.     if (sym_num == max_symbols)
  620. {
  621. /* no more room in symbol table -
  622.  * make externals table half as big again */
  623. max_symbols += max_symbols / 2;
  624. *externals = (char **) realloc ((char *) *externals,
  625. (unsigned) max_symbols *
  626. sizeof (char *));
  627. if (*externals == NULL)
  628.     return (ERROR);
  629. }
  630.     (*externals) [sym_num] = adrs; /* enter address in table */
  631.     }
  632. }
  633.     return (status);
  634.     }
  635. #if CPU_FAMILY == SPARC
  636. /*******************************************************************************
  637. *
  638. * relSegmentSparc - perform relocation commands for a SPARC segment
  639. *
  640. * This routine reads the specified relocation command segment and performs
  641. * all the relocations specified therein.  External relocations are looked 
  642. * up in the 'externals' table.  All other relocations are relative to how 
  643. * much a particular segment has moved. 
  644. *
  645. * RETURNS: OK or ERROR
  646. */
  647. LOCAL STATUS relSegmentSparc
  648.     (
  649.     int fd, /* fd of file positioned to reloc commands */
  650.     int nbytes, /* # of bytes of reloc commands for this seg */
  651.     FAST char * segAddress, /* addr of segment being relocated */
  652.     SEG_INFO * pSeg, /* pointer to segment information */
  653.     char ** externals /* addresses of external symbols */
  654.     )
  655.     {
  656.     ULONG * pAddr;        /* address in memory to receive relocated val */
  657.     RINFO_SPARC rinfo;   /* relocation command goes here */
  658.     ULONG  relVal;        /* relocated value to be put into memory */
  659.     for (; nbytes > 0; nbytes -= sizeof (rinfo))
  660.         {
  661.         /* read relocation command */
  662.         if (fioRead (fd, (char *) &rinfo, sizeof (rinfo)) != sizeof (rinfo))
  663.             return (ERROR);
  664.         /* calculate actual address in memory that needs relocation,
  665.          * and perform external or segment relative relocation */
  666.         pAddr = (ULONG *) ((ULONG) segAddress + (ULONG) rinfo.r_address);
  667.         if (rinfo.r_extern)
  668.             relVal = (ULONG) externals[rinfo.r_index] + rinfo.r_addend;
  669.         else
  670.     switch (rinfo.r_index & N_TYPE)
  671. {
  672. case N_TEXT:
  673.      relVal = (ULONG) pSeg->addrText + rinfo.r_addend;
  674.      break;
  675. case N_DATA:
  676.      relVal = ((ULONG) pSeg->addrData - pSeg->sizeText) + 
  677.               rinfo.r_addend;
  678.      break;
  679. case N_BSS:
  680.      relVal = ((ULONG) pSeg->addrBss - pSeg->sizeText - 
  681.        pSeg->sizeData) + rinfo.r_addend;
  682.      break;
  683. default:
  684.      logMsg ("Invalid relocation index %dn", rinfo.r_addend,
  685.      0, 0, 0, 0, 0);
  686.      return (ERROR);
  687.      break;
  688. }
  689. switch (rinfo.r_type)
  690.     {
  691.     case RELOC_8:
  692. *(UINT8 *) pAddr = relVal;
  693. break;
  694.     case RELOC_16:
  695. *(USHORT *) pAddr = relVal;
  696. break;
  697.     case RELOC_32:
  698. *pAddr = relVal;
  699. break;
  700.     case RELOC_DISP8:
  701. *(UINT8 *) pAddr = relVal - (ULONG) segAddress;
  702. break;
  703.     case RELOC_DISP16:
  704. *(USHORT *) pAddr = relVal - (ULONG) segAddress;
  705. break;
  706.     case RELOC_DISP32:
  707. *pAddr = relVal - (ULONG) segAddress;
  708. break;
  709.     case RELOC_WDISP30:
  710. STORE_MASKED_VALUE (pAddr, 0x3fffffff, 
  711.     (((ULONG) relVal - 
  712.       (ULONG) segAddress) >> 2));
  713. break;
  714.     case RELOC_WDISP22:
  715. STORE_MASKED_VALUE (pAddr, 0x003fffff, 
  716.     (((ULONG) relVal - 
  717.       (ULONG) segAddress) >> 2));
  718. break;
  719.     case RELOC_HI22:
  720. STORE_MASKED_VALUE (pAddr, 0x003fffff, relVal >> 10);
  721. break;
  722.     case RELOC_22:
  723.                 STORE_MASKED_VALUE (pAddr, 0x003fffff, relVal);
  724. break;
  725.     case RELOC_13:
  726. STORE_MASKED_VALUE (pAddr, 0x00001fff, relVal);
  727. break;
  728.     case RELOC_LO10:
  729. STORE_MASKED_VALUE (pAddr, 0x000003ff, relVal);
  730. break;
  731.     case RELOC_SFA_BASE:
  732.     case RELOC_SFA_OFF13:
  733.     case RELOC_BASE10:
  734.     case RELOC_BASE13:
  735.     case RELOC_BASE22:
  736.     case RELOC_PC10:
  737.     case RELOC_PC22:
  738.     case RELOC_JMP_TBL:
  739.     case RELOC_SEGOFF16:
  740.     case RELOC_GLOB_DAT:
  741.     case RELOC_JMP_SLOT:
  742.     case RELOC_RELATIVE:
  743.             default:
  744.                 logMsg ("Unknown relocation type %dn", rinfo.r_type,
  745.                         0, 0, 0, 0, 0);
  746. return (ERROR);
  747.                 break;
  748.             }
  749.         }
  750.     return (OK);
  751.     }
  752. #else
  753. /*******************************************************************************
  754. *
  755. * relSegment68k - perform relocation commands for a 680X0 segment
  756. *
  757. * This routine reads the specified relocation command segment and performs
  758. * all the relocations specified therein.
  759. * External relocations are looked up in the 'externals' table.
  760. * All other relocations are relative to how much a particular segment has moved.
  761. *
  762. * RETURNS: OK or ERROR
  763. */
  764. LOCAL STATUS relSegment68k
  765.     (
  766.     int fd, /* fd of file positioned to reloc commands */
  767.     int nbytes, /* # of bytes of reloc commands for this seg */
  768.     FAST char * segAddress, /* addr of segment being relocated */
  769.     SEG_INFO * pSeg, /* pointer to segment information */
  770.     char ** externals /* addresses of external symbols */
  771.     )
  772.     {
  773.     FAST char **pAddress;
  774.     FAST char *textAddress = pSeg->addrText;
  775.     RINFO_68K rinfo; /* relocation command goes here */
  776.     for (; nbytes > 0; nbytes -= sizeof (rinfo))
  777. {
  778. /* read relocation command */
  779. if (fioRead (fd, (char *) &rinfo, sizeof (rinfo)) !=
  780. sizeof (rinfo))
  781.     {
  782.     return (ERROR);
  783.     }
  784. /* calculate actual address in memory that needs relocation,
  785.  * and perform external or segment relative relocation */
  786. pAddress = (char **) (segAddress + rinfo.r_address);
  787. if (rinfo.r_extern)
  788.     {
  789.     if (rinfo.r_length != 2)
  790. printErr (nonLongErrMsg, pAddress, rinfo.r_length);
  791.     else
  792. {
  793. /* add external address to relocatable value */
  794. *pAddress += (int) externals [rinfo.r_symbolnum];
  795. /* relocations marked pc-relative were done assuming
  796.  * text starts at 0.  Adjust for actual start of text. */
  797. if (rinfo.r_pcrel)
  798.     *pAddress -= (int) textAddress;
  799. }
  800.     }
  801. else
  802.     {
  803.     /* pc-relative internal references are already ok.
  804.      * other internal references need to be relocated relative
  805.      * to start of the segment indicated by r_symbolnum. */
  806.     if (!rinfo.r_pcrel)
  807. {
  808. if (rinfo.r_length != 2)
  809.     printErr (nonLongErrMsg, pAddress, rinfo.r_length);
  810. else
  811.     {
  812.     /* some compiler's a.out may have the external bit set
  813.      * -- just ignore
  814.      */
  815.     switch (rinfo.r_symbolnum & N_TYPE)
  816. {
  817.                         /* Text, data, and bss may not be contiguous
  818.                          * in vxWorks (unlike UNIX).  Relocate by
  819.                          * calculating the actual distances that a
  820.                          * segment has moved.
  821.                          */
  822. case N_ABS:
  823.     break;
  824. case N_TEXT:
  825.     *pAddress += (int) textAddress;
  826.     break;
  827. case N_DATA:
  828.     *pAddress += (int) pSeg->addrData - pSeg->sizeText;
  829.     break;
  830. case N_BSS:
  831.     *pAddress += (int) pSeg->addrBss - pSeg->sizeText
  832.  - pSeg->sizeData;
  833.     break;
  834. default:
  835.     printErr ("Unknown symbol number = %#xn",
  836. rinfo.r_symbolnum);
  837. }
  838.     }
  839. }
  840.     }
  841. }
  842.     return (OK);
  843.     }
  844. #endif