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

VxWorks

开发平台:

C/C++

  1. /* symLib.c - symbol table subroutine library */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01j,12oct01,jn   fix SPR 7453 - broken API leads to stack corruption - add
  8.                  new API from AE (symXXXFind - from symLib.c@@/main/tor3_x/3) 
  9.  and new internal-only API (symXXXGet).  
  10. 01i,14mar99,jdi  doc: removed refs to config.h and/or configAll.h (SPR 25663).
  11. 04h,14feb97,dvs  added check if sysTblId is NULL in symFindByValueAndType() 
  12.  (SPR #6876)
  13. 04g,30oct96,elp  Added syncSymAddRtn, syncSymRemoveRtn function pointers
  14.  and symSAdd().
  15. 04f,19jun96,ism  added error condition if NULL is passed as symbol table to
  16.                     symFindByNameAndType().
  17. 04e,22oct95,jdi  doc: added buffer size to allocate for the symFindByValue
  18.     routines (SPR 4386).
  19. 04d,13may95,p_m  added _func_symFindByValue initialization.
  20. 04c,11jan95,rhp  doc: mention system symbol table global, sysSymTbl (SPR#2575)
  21. 04b,16sep94,rhp  doc: fuller description of SYM_TYPE (SPR#3538).
  22. 04a,19may94,dvs  doc'ed problem of standalone image symbol removal (SPR #3199). 
  23. 03z,23feb93,jdi  doc: fuller description of <group> in symAdd().
  24. 03y,21jan93,jdi  documentation cleanup for 5.1.
  25. 03x,01oct92,jcf  biased symFindByValueAndType against xxx.o and gcc2_compiled.
  26. 03w,18jul92,smb  Changed errno.h to errnoLib.h.
  27. 03v,14jul92,jmm  added support to symKeyCmpName for matching pointers exactly
  28. 03u,04jul92,jcf  scalable/ANSI/cleanup effort.
  29. 03t,22jun92,jmm  removed symFooWithGroup, added parameter to routines instead
  30. 03s,26may92,rrr  the tree shuffle
  31. 03r,15may92,jmm  Changed "symFooGroup" to "symFooWithGroup"
  32. 03q,30apr92,jmm  Added support for group numbers
  33. 03p,02jan92,gae  used UINT's for value in symFindByValue{AndType}
  34.                  for targets in negative address space (e.g. STAR MVP).
  35. 03o,13dec91,gae  ANSI cleanup.  Made symFindByCName() consistent with other
  36.    symFind* routines.
  37. 03n,26nov91,llk  added symName() and symNameValueCmp().
  38. 03m,04oct91,rrr  passed through the ansification filter
  39.                   -changed functions to ansi style
  40.   -changed includes to have absolute path from h/
  41.   -changed TINY and UTINY to INT8 and UINT8
  42.   -changed VOID to void
  43.   -changed copyright notice
  44. 03l,20may91,jdi  documentation tweak.
  45. 03k,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  46.  doc review by dnw.
  47. 03j,24mar91,jdi  documentation cleanup.
  48. 03i,05oct90,dnw  made symFindByCName(), symFindByValueAndType(),
  49.    symFindSymbol(), symInit(), symTblTerminate() be NOMANUAL
  50.  made symFindByValueAndType bias against symbols ending in
  51.    "_text", "_data", "_bss"
  52. 03h,05oct90,dnw  added forward declarations.
  53. 03g,29sep90,jcf  documentation.
  54. 03f,02aug90,jcf  documentation.
  55. 03e,17jul90,dnw  changed to new objAlloc() call
  56. 03d,05jul90,jcf  documentation.
  57. 03c,20jun90,jcf  changed binary semaphore interface
  58.  changed ffs() changed ffsMsb()
  59. 03b,15apr90,jcf  included sysSymTbl.h.
  60. 03a,17nov89,jcf  rewritten to use hashLib (2).
  61.   changed interface/funtionality of symDelete/symInit/symCreate.
  62.   documentation.
  63. 02o,29nov89,llk  added symFindByCName for vxgdb.
  64. 02n,07jun89,gae  added symDelete.
  65. 02m,01sep88,gae  documentation.
  66. 02l,07jul88,jcf  changed malloc to match new declaration.
  67. 02k,30may88,dnw  changed to v4 names.
  68. 02j,04nov87,ecs  documentation.
  69. 02i,16aug87,gae  added parm. to symEach() and made it void.
  70. 02h,07jul87,ecs  added symFindType.
  71.  optimized symEach, symValFind, and symFind.
  72. 02g,02apr87,ecs  added include of strLib.c.
  73. 02f,23mar87,jlf  documentation
  74.  changed memAllocate's to malloc's.
  75. 02e,21dec86,dnw  changed to not get include files from default directories.
  76. 02d,04sep86,jlf  minor documentation
  77. 02c,01jul86,jlf  minor documentation
  78. 02b,05jun86,dnw  changed SYMTAB to have pointer to SYMBOL array instead of
  79.    having it imbedded in SYMTAB structure.
  80. 02a,11oct85,dnw  changed to dynamically allocate space for symbol strings.
  81.    Note change to symCreate call which now takes max number of
  82.    symbols instead of number of bytes in table.
  83.  De-linted.
  84. 01j,21jul85,jlf  documentation.
  85. 01i,11jun85,rdc  added variable length symbols.
  86. 01h,08sep84,jlf  added comments and copyright
  87. 01g,13aug84,ecs  changed status code EMPTY_SYMBOL_TABLE to SYMBOL_NOT_FOUND.
  88. 01f,08aug84,ecs  added calls to setStatus to symAdd, symFind, and symValFind.
  89. 01e,27jun84,ecs  changed symAdd & symValFind so that names in symbol tables
  90.    are now EOS terminated.
  91. 01d,26jun84,dnw  fixed bug in symValFind of potentially copying too many
  92.    bytes to user's name buffer.
  93. 01c,18jun84,jlf  added symEach and symValFind.
  94. 01b,03jun84,dnw  added symCreate.
  95.  changed symFind to search backwards in table to find most
  96.    recent of multiply defined symbols.
  97.  moved typedefs of SYMBOL and SYMTAB to symLib.h.
  98.  added LINTLIBRARY and various coercions for lint.
  99. 01a,03aug83,dnw  written
  100. */
  101. /*
  102. DESCRIPTION
  103. This library provides facilities for managing symbol tables.  A symbol
  104. table associates a name and type with a value.  A name is simply an
  105. arbitrary, null-terminated string.  A symbol type is a small integer
  106. (typedef SYM_TYPE), and its value is a pointer.  Though commonly used
  107. as the basis for object loaders, symbol tables may be used whenever
  108. efficient association of a value with a name is needed.
  109. If you use the symLib subroutines to manage symbol tables local to
  110. your own applications, the values for SYM_TYPE objects are completely
  111. arbitrary; you can use whatever one-byte integers are appropriate for
  112. your application.
  113. If you use the symLib subroutines to manipulate the VxWorks system
  114. symbol table (whose ID is recorded in the global f3sysSymTblf1), the
  115. values for SYM_TYPE are SYM_UNDF, SYM_LOCAL, SYM_GLOBAL, SYM_ABS,
  116. SYM_TEXT, SYM_DATA, SYM_BSS, and SYM_COMM (defined in symbol.h).
  117. Tables are created with symTblCreate(), which returns a symbol table ID.
  118. This ID serves as a handle for symbol table operations, including the
  119. adding to, removing from, and searching of tables.  All operations on a
  120. symbol table are interlocked by means of a mutual-exclusion semaphore
  121. in the symbol table structure.  Tables are deleted with symTblDelete().
  122. Symbols are added to a symbol table with symAdd().  Each symbol in the
  123. symbol table has a name, a value, and a type.  Symbols are removed from a
  124. symbol table with symRemove().
  125. Symbols can be accessed by either name or value.  The routine
  126. symFindByName() searches the symbol table for a symbol with a
  127. specified name.  The routine symByValueFind() finds a symbol with a
  128. specified value or, if there is no symbol with the same value, the
  129. symbol in the table with the next lower value than the specified
  130. value.  The routines symFindByNameAndType() and
  131. symByValueAndTypeFind() allow the symbol type to be used as an
  132. additional criterion in the searches.
  133. The routines symFindByValue() and symFindByValueAndType() are
  134. obsolete.  They are replaced by the routines symByValueFind() and
  135. symByValueAndTypeFind().
  136. Symbols in the symbol table are hashed by name into a hash table for
  137. fast look-up by name, e.g., by symFindByName().  The size of the hash
  138. table is specified during the creation of a symbol table.  Look-ups by
  139. value, e.g., symByValueFind(), must search the table linearly; these
  140. look-ups can thus be much slower.
  141. The routine symEach() allows each symbol in the symbol table to be
  142. examined by a user-specified function.
  143. Name clashes occur when a symbol added to a table is identical in name
  144. and type to a previously added symbol.  Whether or not symbol tables
  145. can accept name clashes is set by a parameter when the symbol table is
  146. created with symTblCreate().  If name clashes are not allowed,
  147. symAdd() will return an error if there is an attempt to add a symbol
  148. with identical name and type.  If name clashes are allowed, adding
  149. multiple symbols with the same name and type will be permitted.  In
  150. such cases, symFindByName() will return the value most recently added,
  151. although all versions of the symbol can be found by symEach().
  152. The system symbol table (f3sysSymTblf1) allows name clashes.
  153. See the VxWorks Programmmer's Guide for more information about
  154. configuration, intialization, and use of the system symbol table.
  155. INTERNAL
  156. Static symbol tables are initialized with symTblInit(), which operates
  157. identically with symTblCreate() without allocating the symbol table.
  158. Static symbol tables are terminated with symTblTerminate(), which operates
  159. identically with symTblDelete() without deallocating the symbol table.
  160. Symbols may be separately allocated, initialized, and added to the symbol
  161. table.  symInit() initializes an existing uninitialized SYMBOL structure.
  162. symAlloc() allocates a SYMBOL structure from the memory partition
  163. specified to symTblCreate(), and then initializes it.  symTblAdd() adds an
  164. existing initialized SYMBOL structure to a symbol table.  The usual
  165. symAdd() function invokes both symAlloc() and symTblAdd().
  166. Symbols are deallocated by symFree().  Symbols still resident in a symbol
  167. table cannot be deallocated.
  168. INCLUDE FILES: symLib.h
  169. SEE ALSO: loadLib 
  170. */
  171. /* LINTLIBRARY */
  172. #include "vxWorks.h"
  173. #include "errnoLib.h"
  174. #include "objLib.h"
  175. #include "classLib.h"
  176. #include "symLib.h"
  177. #include "semLib.h"
  178. #include "memLib.h"
  179. #include "memPartLib.h"
  180. #include "hashLib.h"
  181. #include "string.h"
  182. #include "stdlib.h"
  183. #include "sysSymTbl.h"
  184. #include "private/funcBindP.h"
  185. IMPORT int ffsMsb (int bitfield);
  186. #define SYM_HFUNC_SEED 1370364821 /* magic seed */
  187. typedef struct /* RTN_DESC - routine descriptor */
  188.     {
  189.     FUNCPTR routine; /* user routine passed to symEach() */
  190.     int routineArg; /* user routine arg passed to symEach() */
  191.     } RTN_DESC;
  192. /* local variables */
  193. LOCAL OBJ_CLASS symTblClass;
  194. /* global variables */
  195. CLASS_ID symTblClassId = &symTblClass;
  196. int mutexOptionsSymLib = SEM_Q_FIFO | SEM_DELETE_SAFE;
  197. UINT16 symGroupDefault = 0;
  198. FUNCPTR syncSymAddRtn = (FUNCPTR) NULL;
  199. FUNCPTR syncSymRemoveRtn = (FUNCPTR) NULL;
  200. /* forward static functions */
  201.  
  202. static BOOL symEachRtn (SYMBOL *pSymbol, RTN_DESC *pRtnDesc);
  203. static int symHFuncName (int elements, SYMBOL *pSymbol, int seed);
  204. static BOOL symKeyCmpName (SYMBOL *pMatchSymbol, SYMBOL *pSymbol,
  205.    int mask);
  206. static BOOL symNameValueCmp (char *name, int val, SYM_TYPE type, int pSym);
  207. /*******************************************************************************
  208. *
  209. * symLibInit - initialize the symbol table library
  210. *
  211. * This routine initializes the symbol table package.  If the configuration
  212. * macro INCLUDE_SYM_TBL is defined, symLibInit() is called by the root task,
  213. * usrRoot(), in usrConfig.c.
  214. *
  215. * RETURNS: OK, or ERROR if the library could not be initialized.
  216. */
  217. STATUS symLibInit (void)
  218.     {
  219.     /* avoid direct coupling with symLib with these global variables */
  220.     _func_symFindSymbol = (FUNCPTR) symFindSymbol;
  221.     _func_symNameGet    = (FUNCPTR) symNameGet;
  222.     _func_symValueGet   = (FUNCPTR) symValueGet;
  223.     _func_symTypeGet    = (FUNCPTR) symTypeGet;
  224.    
  225.     /* 
  226.      * XXX JLN The functions symFindByValueAndType and symFindByValue
  227.      * are obsolete and should not be used.  They remain (as functions
  228.      * and as function pointers) for backwards compatibility only.
  229.      * The function pointers should be removed when all uses are
  230.      * removed from vxWorks.  The functions themselves must remain
  231.      * as long as required for backwards compatibility.
  232.      */
  233.     _func_symFindByValueAndType = (FUNCPTR) symFindByValueAndType; 
  234.     _func_symFindByValue        = (FUNCPTR) symFindByValue;
  235.     /* initialize the symbol table class structure */
  236.     return (classInit (symTblClassId, sizeof (SYMTAB), OFFSET (SYMTAB, objCore),
  237.        (FUNCPTR) symTblCreate, (FUNCPTR) symTblInit,
  238.        (FUNCPTR) symTblDestroy));
  239.     }
  240. /*******************************************************************************
  241. *
  242. * symTblCreate - create a symbol table
  243. *
  244. * This routine creates and initializes a symbol table with a hash table of a
  245. * specified size.  The size of the hash table is specified as a power of two.
  246. * For example, if <hashSizeLog2> is 6, a 64-entry hash table is created.
  247. *
  248. * If <sameNameOk> is FALSE, attempting to add a symbol with
  249. * the same name and type as an already-existing symbol results in an error.
  250. *
  251. * Memory for storing symbols as they are added to the symbol table will be
  252. * allocated from the memory partition <symPartId>.  The ID of the system
  253. * memory partition is stored in the global variable `memSysPartId', which
  254. * is declared in memLib.h.
  255. *
  256. * RETURNS: Symbol table ID, or NULL if memory is insufficient.
  257. */
  258. SYMTAB_ID symTblCreate
  259.     (
  260.     int     hashSizeLog2,       /* size of hash table as a power of 2 */
  261.     BOOL    sameNameOk,         /* allow 2 symbols of same name & type */
  262.     PART_ID symPartId           /* memory part ID for symbol allocation */
  263.     )
  264.     {
  265.     SYMTAB_ID symTblId = (SYMTAB_ID) objAlloc (symTblClassId);
  266.     if (symTblId != NULL)
  267. {
  268. symTblId->nameHashId = hashTblCreate (hashSizeLog2,
  269.       (FUNCPTR) symKeyCmpName,
  270.       (FUNCPTR) symHFuncName,
  271.       SYM_HFUNC_SEED);
  272. if (symTblId->nameHashId == NULL) /* hashTblCreate failed? */
  273.     {
  274.     objFree (symTblClassId, (char *) symTblId);
  275.     return (NULL);
  276.     }
  277. if (symTblInit (symTblId, sameNameOk, symPartId,
  278. symTblId->nameHashId) != OK)
  279.     {
  280.     hashTblDelete (symTblId->nameHashId);
  281.     objFree (symTblClassId, (char *) symTblId);
  282.     return (NULL);
  283.     }
  284. }
  285.     return (symTblId); /* return the symbol table ID */
  286.     }
  287. /*******************************************************************************
  288. *
  289. * symTblInit - initialize a symbol table
  290. *
  291. * Initialize a symbol table.  Any symbols currently in the table will be lost.
  292. * The specified hash table ID and memory partition ID must already be
  293. * initialized.
  294. *
  295. * RETURNS: OK, or ERROR if initialization failed.
  296. *
  297. * NOMANUAL
  298. */
  299. STATUS symTblInit
  300.     (
  301.     SYMTAB  *pSymTbl,           /* ptr to symbol table to initialize */
  302.     BOOL    sameNameOk,         /* two symbols of same name and type allowed */
  303.     PART_ID symPartId,          /* partition from which to allocate symbols */
  304.     HASH_ID symHashTblId        /* ID of an initialized hash table */
  305.     )
  306.     {
  307.     if ((OBJ_VERIFY (symHashTblId, hashClassId) != OK) ||
  308.         (semMInit (&pSymTbl->symMutex, mutexOptionsSymLib) != OK))
  309. {
  310. return (ERROR);
  311. }
  312.     pSymTbl->sameNameOk = sameNameOk; /* name clash policy */
  313.     pSymTbl->nsymbols   = 0; /* initial number of syms */
  314.     pSymTbl->nameHashId = symHashTblId; /* fill in hash table ID */
  315.     pSymTbl->symPartId  = symPartId; /* fill in mem partition ID */
  316.     /* initialize core */
  317.     objCoreInit (&pSymTbl->objCore, symTblClassId);
  318.     return (OK);
  319.     }
  320. /*******************************************************************************
  321. *
  322. * symTblDelete - delete a symbol table
  323. *
  324. * This routine deletes a specified symbol table.  It deallocates all
  325. * associated memory, including the hash table, and marks the table as
  326. * invalid.
  327. *
  328. * Deletion of a table that still contains symbols results in ERROR.
  329. * Successful deletion includes the deletion of the internal hash table and
  330. * the deallocation of memory associated with the table.  The table is marked
  331. * invalid to prohibit any future references.
  332. *
  333. * RETURNS: OK, or ERROR if the symbol table ID is invalid.
  334. */
  335. STATUS symTblDelete
  336.     (
  337.     SYMTAB_ID symTblId          /* ID of symbol table to delete */
  338.     )
  339.     {
  340.     return (symTblDestroy (symTblId, TRUE));
  341.     }
  342. /*******************************************************************************
  343. *
  344. * symTblTerminate - terminate a symbol table
  345. *
  346. * The specified symbol table is terminated if no symbols are resident.
  347. * Otherwise, ERROR is returned.
  348. *
  349. * RETURNS: OK, or ERROR if invalid symbol table ID, or symbols still in table.
  350. *
  351. * NOMANUAL
  352. */
  353. STATUS symTblTerminate
  354.     (
  355.     SYMTAB_ID symTblId          /* ID of symbol table to delete */
  356.     )
  357.     {
  358.     return (symTblDestroy (symTblId, FALSE));
  359.     }
  360. /*******************************************************************************
  361. *
  362. * symTblDestroy - destroy a symbol table and optionally deallocate memory
  363. *
  364. * The specified symbol table is terminated if no symbols are resident.
  365. * If dealloc is TRUE, memory associated with the symbol table, including the
  366. * hash table, is deallocated.
  367. *
  368. * RETURNS: OK, or ERROR if invalid symbol table ID, or symbols still in table.
  369. *
  370. * NOMANUAL
  371. */
  372. STATUS symTblDestroy
  373.     (
  374.     SYMTAB_ID symTblId,         /* ID of symbol table to delete */
  375.     BOOL      dealloc           /* deallocate associated memory */
  376.     )
  377.     {
  378.     if (OBJ_VERIFY (symTblId, symTblClassId) != OK)
  379. return (ERROR); /* invalid symbol table ID */
  380.     semTake (&symTblId->symMutex, WAIT_FOREVER);
  381.     if (symTblId->nsymbols > 0) /* non-empty table? */
  382. {
  383. semGive (&symTblId->symMutex); /* release mutual exclusion */
  384. errno = S_symLib_TABLE_NOT_EMPTY;
  385. return (ERROR);
  386. }
  387.     semTerminate (&symTblId->symMutex);  /* terminate mutex */
  388.     objCoreTerminate (&symTblId->objCore);
  389.     hashTblDestroy (symTblId->nameHashId, dealloc);
  390.     if (dealloc)
  391. return (objFree (symTblClassId, (char *) symTblId));
  392.     return (OK);
  393.     }
  394. /*******************************************************************************
  395. *
  396. * symAlloc - allocate and initialize a symbol, including group number
  397. *
  398. * Allocate and initialize a symbol.  The symbol is not added to any symbol
  399. * table.  To add a symbol to a symbol table use symAdd() or symTblAdd().
  400. * Space for the name is allocated along with the SYMBOL structure, thus the
  401. * name parameter need not be static.
  402. *
  403. * RETURNS: Pointer to symbol, or NULL if out of memory.
  404. *
  405. * NOMANUAL
  406. */
  407. SYMBOL *symAlloc
  408.     (
  409.     SYMTAB_ID   symTblId,       /* symbol table to allocate symbol for */
  410.     char        *name,          /* pointer to symbol name string */
  411.     char        *value,         /* symbol address */
  412.     SYM_TYPE    type,           /* symbol type */
  413.     UINT16 group /* symbol group */
  414.     )
  415.     {
  416.     SYMBOL *pSymbol;
  417.     char   *symName;
  418.     int    length;
  419.     if (OBJ_VERIFY (symTblId, symTblClassId) != OK)
  420. return (NULL); /* invalid symbol table ID */
  421.     if (name == NULL)
  422. return (NULL); /* null name */
  423.     length = strlen (name); /* figure out name length */
  424.     pSymbol = (SYMBOL *) memPartAlloc (symTblId->symPartId,
  425.        (unsigned)(sizeof(SYMBOL) + length + 1));
  426.     if (pSymbol == NULL) /* out of memory */
  427. return (NULL);
  428.     /* copy name after symbol */
  429.     symName     = (char *) ((unsigned) pSymbol + sizeof (SYMBOL));
  430.     symName[length] = EOS; /* null terminate string */
  431.     strncpy (symName, name, length); /* copy name into place */
  432.     symInit (pSymbol, symName, value, type, group); /* initialize symbol*/
  433.     return (pSymbol); /* return symbol ID */
  434.     }
  435. /*******************************************************************************
  436. *
  437. * symInit - initialize a symbol, including group number
  438. *
  439. * Initialize a symbol.  The symbol is not added to any symbol table.  To add
  440. * a symbol to a symbol table use symAdd() or symTblAdd().
  441. *
  442. * RETURNS: OK, or ERROR if symbol table could not be initialized.
  443. *
  444. * NOMANUAL
  445. */
  446. STATUS symInit
  447.     (
  448.     SYMBOL      *pSymbol,       /* pointer to symbol */
  449.     char        *name,          /* pointer to symbol name string */
  450.     char        *value,         /* symbol address */
  451.     SYM_TYPE    type,           /* symbol type */
  452.     UINT16 group /* symbol group */
  453.     )
  454.     {
  455.     /* fill in symbol */
  456.     pSymbol->name  = name; /* symbol name */
  457.     pSymbol->value = (void *)value; /* symbol value */
  458.     pSymbol->type  = type; /* symbol type */
  459.     pSymbol->group = group; /* symbol group */
  460.     return (OK);
  461.     }
  462. /*******************************************************************************
  463. *
  464. * symFree - deallocate a symbol
  465. *
  466. * Deallocate the specified symbol.  This routine does not check if symbols
  467. * are still resident in symbol tables, so all calls to symFree should be
  468. * preceded by a call to symTblRemove.
  469. *
  470. * RETURNS: OK, or ERROR if invalid symbol table.
  471. *
  472. * NOMANUAL
  473. */
  474. STATUS symFree
  475.     (
  476.     SYMTAB_ID symTblId, /* symbol table semaphore */
  477.     SYMBOL *pSymbol     /* pointer to symbol to delete */
  478.     )
  479.     {
  480.     if (OBJ_VERIFY (symTblId, symTblClassId) != OK)
  481. return (ERROR); /* invalid symbol table ID */
  482.     return (memPartFree (symTblId->symPartId, (char *) pSymbol));
  483.     }
  484. /*******************************************************************************
  485. *
  486. * symSAdd - create and add a symbol to a symbol table, including a group number
  487. * This routine behaves as symAdd() except it does not check for synchronization
  488. * function pointers. Thus it can be used in loaders to prevent from trying to 
  489. * independently synchronize each symbol of a module.
  490. *
  491. * RETURNS: OK, or ERROR if the symbol table is invalid
  492. * or there is insufficient memory for the symbol to be allocated.
  493. *
  494. * NOMANUAL
  495. */
  496. STATUS symSAdd
  497.     (
  498.     SYMTAB_ID symTblId,         /* symbol table to add symbol to */
  499.     char      *name,            /* pointer to symbol name string */
  500.     char      *value,           /* symbol address */
  501.     SYM_TYPE  type,             /* symbol type */
  502.     UINT16    group             /* symbol group */
  503.     )
  504.     {
  505.     SYMBOL *pSymbol = symAlloc (symTblId, name, value, type, group);
  506.     if (pSymbol == NULL) /* out of memory? */
  507. return (ERROR);
  508.     if (symTblAdd (symTblId, pSymbol) != OK) /* try to add symbol */
  509. {
  510. symFree (symTblId, pSymbol); /* deallocate symbol if fail */
  511. return (ERROR);
  512. }
  513.     
  514.     return (OK);
  515.     }
  516. /*******************************************************************************
  517. *
  518. * symAdd - create and add a symbol to a symbol table, including a group number
  519. *
  520. * This routine allocates a symbol <name> and adds it to a specified symbol
  521. * table <symTblId> with the specified parameters <value>, <type>, and <group>.
  522. * The <group> parameter specifies the group number assigned to a module when
  523. * it is loaded; see the manual entry for moduleLib.
  524. *
  525. * RETURNS: OK, or ERROR if the symbol table is invalid
  526. * or there is insufficient memory for the symbol to be allocated.
  527. *
  528. * SEE ALSO: moduleLib
  529. */
  530. STATUS symAdd
  531.     (
  532.     SYMTAB_ID symTblId,         /* symbol table to add symbol to */
  533.     char      *name,            /* pointer to symbol name string */
  534.     char      *value,           /* symbol address */
  535.     SYM_TYPE  type,             /* symbol type */
  536.     UINT16    group             /* symbol group */
  537.     )
  538.     {
  539.     SYMBOL *pSymbol = symAlloc (symTblId, name, value, type, group);
  540.     if (pSymbol == NULL) /* out of memory? */
  541. return (ERROR);
  542.     if (symTblAdd (symTblId, pSymbol) != OK) /* try to add symbol */
  543. {
  544. symFree (symTblId, pSymbol); /* deallocate symbol if fail */
  545. return (ERROR);
  546. }
  547.     
  548.     /* synchronize host symbol table if necessary */
  549.     if ((syncSymAddRtn != NULL) && (symTblId == sysSymTbl))
  550. (* syncSymAddRtn) (name, value, type, group);
  551.     return (OK);
  552.     }
  553. /*******************************************************************************
  554. *
  555. * symTblAdd - add a symbol to a symbol table
  556. *
  557. * This routine adds a symbol to a symbol table.
  558. *
  559. * RETURNS: OK, or ERROR if invalid symbol table, or symbol couldn't be added.
  560. *
  561. * INTERNAL
  562. * This is a lousy name, it should probably be symAddStatic ().
  563. *
  564. * NOMANUAL
  565. */
  566. STATUS symTblAdd
  567.     (
  568.     SYMTAB_ID symTblId,         /* symbol table to add symbol to */
  569.     SYMBOL    *pSymbol          /* pointer to symbol to add */
  570.     )
  571.     {
  572.     if (OBJ_VERIFY (symTblId, symTblClassId) != OK)
  573. return (ERROR); /* invalid symbol table ID */
  574.     semTake (&symTblId->symMutex, WAIT_FOREVER);
  575.     if ((!symTblId->sameNameOk) &&
  576. (hashTblFind (symTblId->nameHashId, &pSymbol->nameHNode,
  577.       SYM_MASK_EXACT_TYPE) != NULL))
  578. {
  579. semGive (&symTblId->symMutex); /* release exclusion to table */
  580. errno = S_symLib_NAME_CLASH; /* name clashed */
  581. return (ERROR);
  582. }
  583.     hashTblPut (symTblId->nameHashId, &pSymbol->nameHNode);
  584.     symTblId->nsymbols ++; /* increment symbol count */
  585.     semGive (&symTblId->symMutex); /* release exclusion to table */
  586.     return (OK);
  587.     }
  588. /*******************************************************************************
  589. *
  590. * symRemove - remove a symbol from a symbol table
  591. *
  592. * This routine removes a symbol of matching name and type from a
  593. * specified symbol table.  The symbol is deallocated if found.
  594. * Note that VxWorks symbols in a standalone VxWorks image (where the 
  595. * symbol table is linked in) cannot be removed.
  596. *
  597. * RETURNS: OK, or ERROR if the symbol is not found
  598. * or could not be deallocated.
  599. */
  600. STATUS symRemove
  601.     (
  602.     SYMTAB_ID symTblId,         /* symbol tbl to remove symbol from */
  603.     char      *name,            /* name of symbol to remove */
  604.     SYM_TYPE  type              /* type of symbol to remove */
  605.     )
  606.     {
  607.     SYMBOL *pSymbol;
  608.     if (symFindSymbol (symTblId, name, NULL, 
  609.        type, SYM_MASK_EXACT_TYPE, &pSymbol) != OK)
  610. return (ERROR);
  611.     if (symTblRemove (symTblId, pSymbol) != OK)
  612. return (ERROR);
  613.     /* synchronize host symbol table if necessary */
  614.     if ((syncSymRemoveRtn != NULL) && (symTblId == sysSymTbl))
  615. (* syncSymRemoveRtn) (name, type);
  616.     return (symFree (symTblId, pSymbol));
  617.     }
  618. /*******************************************************************************
  619. *
  620. * symTblRemove - remove and terminate a symbol from a symbol table
  621. *
  622. * This routine removes the specified symbol from the symbol table.  The
  623. * symbol is not deallocated.
  624. *
  625. * RETURNS: OK, or ERROR if symbol table invalid, or symbol not found.
  626. *
  627. * NOMANUAL
  628. */
  629. STATUS symTblRemove
  630.     (
  631.     SYMTAB_ID symTblId,         /* symbol table to remove symbol from */
  632.     SYMBOL    *pSymbol          /* pointer to symbol to remove */
  633.     )
  634.     {
  635.     HASH_NODE *pNode;
  636.     if (OBJ_VERIFY (symTblId, symTblClassId) != OK)
  637. return (ERROR); /* invalid symbol table ID */
  638.     semTake (&symTblId->symMutex, WAIT_FOREVER);
  639.     pNode = hashTblFind (symTblId->nameHashId, &pSymbol->nameHNode,
  640.  SYM_MASK_EXACT);
  641.     if (pNode == NULL)
  642. {
  643. semGive (&symTblId->symMutex); /* release exclusion to table */
  644. errnoSet (S_symLib_SYMBOL_NOT_FOUND); /* symbol wasn't found */
  645. return (ERROR);
  646. }
  647.     hashTblRemove (symTblId->nameHashId, pNode);
  648.     symTblId->nsymbols--; /* one less symbol */
  649.     semGive (&symTblId->symMutex); /* release exclusion to table */
  650.     return (OK);
  651.     }
  652. /*******************************************************************************
  653. *
  654. * symFindSymbol - find symbol in a symbol table of equivalent name and type
  655. *
  656. * This routine is a generic routine to retrieve a symbol in the
  657. * specified symbol table.  It can be used to perform searches by name,
  658. * name and type, value, or value and type.
  659. * If the 'name' parameter is non-NULL, a search by name will be
  660. * performed and the value parameter will be ignored.  If the name
  661. * parameter is NULL, a search by value will be performed.  In a search
  662. * by value, if no matching entry is found, the symbol of the matching
  663. * type with the next lower value is selected.  (If the type is NULL, as
  664. * in a simple search by value, this will simply be whatever symbol
  665. * in the symbol table has the next lowest address.)
  666. *
  667. * In both the search by name and search by value cases, potential
  668. * matches will have their types compared to <type>, subject to the
  669. * <mask>, and only symbols which match the specified type will be
  670. * returned.  To have the type matched exactly, set the <type>
  671. * parameter to the desired type and set the <mask> parameter to
  672. * SYM_MASK_EXACT_TYPE.  To search only by name or only by value and
  673. * have the <type> parameter ignored, set the <mask> parameter to
  674. * SYM_MATCH_ANY_TYPE.
  675. *
  676. * To search the global VxWorks symbol table, specify f3sysSymTblf1
  677. * as <symTblId>.
  678. * INTERNAL
  679. * This routine contains a weird hack designed to deal with the additional
  680. * symbols the loader puts in the symbol table.  The loader adds three symbols
  681. * to the symbol table: <filename>_text, <filename>_data, <filename>_bss.
  682. * These symbols may have the same address (i.e. value in the symbol table)
  683. * as real routine or variable names.  When looking up a symbol for display
  684. * it is desirable to find the real routine or variable names in preference
  685. * to these made up names.  For example, loading "demo.o" will cause a
  686. * symbol "demo.o_text" to be added to the symbol table with the same value
  687. * as the real symbol "_demo".  In a disassembly or "i" printout, etc, we
  688. * would rather see "_demo".  So the test inside the loop in this routine
  689. * that normally terminates the search if we find an exact match, has been
  690. * changed to keep searching if the match it finds ends in "_text", "_data",
  691. * or "_bss".  
  692. *
  693. * If no other exact match is found, the special symbols will be returned
  694. * anyway.  Thus this routine simply has a "bias" against such symbols, but
  695. * will not return an erroneous result in any event.  This nonsense should be
  696. * removed when the loader is changed to not add the special symbols.
  697. *
  698. * The GNU toolkit adds symbols of the form "gcc2_compiled." and "xxx.o".
  699. * These symbols are also biased against.  
  700. *
  701. * RETURNS: OK, or ERROR if <symTblId> is invalid, <pSymbolId> is NULL,
  702. *          symbol not found (for a search by name), or if <value> is less than
  703. *          the lowest value in the table (for search by value).
  704. *
  705. * NOMANUAL */
  706. STATUS symFindSymbol
  707.     (
  708.     SYMTAB_ID   symTblId,       /* symbol table ID */
  709.     char *      name,           /* name to search for */
  710.     void *  value, /* value of symbol to search for */
  711.     SYM_TYPE    type,           /* symbol type */
  712.     SYM_TYPE    mask,           /* type bits that matter */
  713.     SYMBOL_ID * pSymbolId       /* where to return id of matching symbol */
  714.     )
  715.     {
  716.     HASH_NODE *         pNode;      /* node in symbol hash table */
  717.     SYMBOL              keySymbol;  /* dummy symbol for search by name */
  718.     int                 index;      /* counter for search by value */
  719.     SYMBOL *         pSymbol;    /* current symbol, search by value */
  720.     SYMBOL *         pBestSymbol = NULL; 
  721.                                     /* symbol with lower value, matching type */
  722.     char * pUnder;     /* string for _text, etc., check */
  723.     void * bestValue = NULL; 
  724.                                     /* current value of symbol with matching 
  725.        type */ 
  726.     if ((symTblId == NULL) || (OBJ_VERIFY (symTblId, symTblClassId) != OK))
  727.         {
  728. errnoSet (S_symLib_INVALID_SYMTAB_ID);
  729. return (ERROR); 
  730. }
  731.     if (pSymbolId == NULL) 
  732.         {
  733. errnoSet (S_symLib_INVALID_SYM_ID_PTR);
  734. return (ERROR); 
  735. }
  736.     if (name != NULL) 
  737.         {
  738. /* Search by name or by name and type: */
  739.   
  740. /* fill in keySymbol */
  741. keySymbol.name = name; /* match this name */
  742. keySymbol.type = type; /* match this type */
  743. semTake (&symTblId->symMutex, WAIT_FOREVER);
  744. pNode = hashTblFind (symTblId->nameHashId, &keySymbol.nameHNode, 
  745.      (int)mask);
  746. semGive (&symTblId->symMutex); /* release exclusion to table */
  747. if (pNode == NULL)
  748.     {
  749.     errnoSet (S_symLib_SYMBOL_NOT_FOUND);    /* couldn't find symbol */
  750.     return (ERROR);
  751.     }
  752. *pSymbolId = (SYMBOL_ID) pNode;
  753. }
  754.     else 
  755.         {
  756. /* Search by value or by value and type: */
  757.   
  758. semTake (&symTblId->symMutex, WAIT_FOREVER);
  759. for (index = 0; index < symTblId->nameHashId->elements; index++)
  760.     {
  761.     pSymbol = 
  762.         (SYMBOL *) SLL_FIRST(&symTblId->nameHashId->pHashTbl [index]);
  763.     while (pSymbol != NULL) /* list empty */
  764.         {
  765. if (((pSymbol->type & mask) == (type & mask)) &&
  766.     (pSymbol->value == value) &&
  767.     (((pUnder = rindex (pSymbol->name, '_')) == NULL) ||
  768.      ((strcmp (pUnder, "_text") != 0) &&
  769.       (strcmp (pUnder, "_data") != 0) &&
  770.       (strcmp (pUnder, "_bss") != 0) &&
  771.       (strcmp (pUnder, "_compiled.") != 0))) &&
  772.     (((pUnder = rindex (pSymbol->name, '.')) == NULL) ||
  773.      ((strcmp (pUnder, ".o") != 0))))
  774.     {
  775.     /* We've found the entry.  Return it. */
  776.     *pSymbolId = pSymbol;
  777.     semGive (&symTblId->symMutex);
  778.     return (OK);
  779.     }
  780. else if (((pSymbol->type & mask) == (type & mask)) &&
  781.  ((pSymbol->value <= value) &&
  782.   (pSymbol->value > bestValue)))
  783.     {
  784.     /* 
  785.      * this symbol is of correct type and closer than last one 
  786.      */
  787.     bestValue   = pSymbol->value;
  788.     pBestSymbol = pSymbol;
  789.     }
  790. pSymbol = (SYMBOL *) SLL_NEXT (&pSymbol->nameHNode);
  791. }
  792.     }
  793. if (bestValue == NULL || pBestSymbol == NULL) /* any closer symbol? */
  794.     {
  795.     semGive (&symTblId->symMutex); /* release exclusion to table */
  796.     errnoSet (S_symLib_SYMBOL_NOT_FOUND);
  797.     return (ERROR);
  798.     }
  799. *pSymbolId = pBestSymbol;
  800. semGive (&symTblId->symMutex); /* release exclusion to table */
  801. }
  802.     return (OK);
  803.     }
  804. /*******************************************************************************
  805. *
  806. * symFindByName - look up a symbol by name
  807. *
  808. * This routine searches a symbol table for a symbol matching a specified
  809. * name.  If the symbol is found, its value and type are copied to <pValue>
  810. * and <pType>.  If multiple symbols have the same name but differ in type,
  811. * the routine chooses the matching symbol most recently added to the symbol
  812. * table.
  813. *
  814. * To search the global VxWorks symbol table, specify f3sysSymTblf1
  815. * as <symTblId>.
  816. * RETURNS: OK, or ERROR if the symbol table ID is invalid
  817. * or the symbol cannot be found.
  818. */
  819. STATUS symFindByName
  820.     (
  821.     SYMTAB_ID   symTblId,       /* ID of symbol table to look in */
  822.     char        *name,          /* symbol name to look for */
  823.     char        **pValue,       /* where to put symbol value */
  824.     SYM_TYPE    *pType          /* where to put symbol type */
  825.     )
  826.     {
  827.     return (symFindByNameAndType (symTblId, name, pValue, pType, 
  828.   SYM_MASK_ANY_TYPE, SYM_MASK_ANY_TYPE));
  829.     }
  830. /*******************************************************************************
  831. *
  832. * symByCNameFind - find a symbol in a symbol table, look for a '_'
  833. *
  834. * Find a symbol in the table, by name.  If the symbol isn't found,
  835. * try looking for it with a '_' prepended to it.  If we find the
  836. * symbol, we fill in the type and the value of the symbol.
  837. *
  838. * RETURNS: OK, or ERROR if <symTblId> is invalid or symbol is not found.
  839. *
  840. * INTERNAL
  841. * The size of the symbol name is NOT limited.
  842. *
  843. * NOMANUAL
  844. */
  845. STATUS symByCNameFind
  846.     (
  847.     SYMTAB_ID   symTblId, /* ID of symbol table to look in */
  848.     char * name, /* symbol name to look for   */
  849.     char ** pValue, /* where to put symbol value */
  850.     SYM_TYPE * pType /* where to put symbol type  */
  851.     )
  852.     {
  853.     char * symBuf = NULL;
  854.     STATUS retVal;
  855.     if (symFindByName (symTblId, name, pValue, pType) == ERROR)
  856. {
  857. /* prepend a '_' and try again */
  858. /* 
  859.  * XXX JLN - KHEAP_ALLOC isn't necessary for this function -
  860.  * it should be rewritten to search directly and not use KHEAP_ALLOC. 
  861.  */
  862.         if ((symBuf = (char *) KHEAP_ALLOC (strlen (name) + 2)) == NULL)
  863.             return ERROR;
  864.         *symBuf = '_';
  865.         strcpy (&symBuf[1], name);
  866.         retVal = symFindByName (symTblId, symBuf, pValue, pType);
  867.         KHEAP_FREE (symBuf);
  868.         return (retVal);
  869. }
  870.     return (OK);
  871.     }
  872. /*******************************************************************************
  873. *
  874. * symFindByCName - find a symbol in a symbol table, look for a '_'
  875. *
  876. * This routine is obsolete.  It is replaced by the routine
  877. * symByCNameFind().  
  878. * Find a symbol in the table, by name.  If the symbol isn't found, try
  879. * looking for it with a '_' prepended to it.  If we find the symbol,
  880. * we fill in the type and the value of the symbol.
  881. *
  882. * RETURNS: OK, or ERROR if <symTblId> is invalid or symbol is not found.
  883. *
  884. * INTERNAL
  885. * The size of the symbol name is no longer limited by MAX_SYS_SYM_LEN.
  886. *  
  887. * NOMANUAL 
  888. */
  889. STATUS symFindByCName
  890.     (
  891.     SYMTAB_ID   symTblId, /* ID of symbol table to look in */
  892.     char        *name, /* symbol name to look for   */
  893.     char        **pValue,       /* where to put symbol value */
  894.     SYM_TYPE    *pType /* where to put symbol type  */
  895.     )
  896.     {
  897.     return symByCNameFind (symTblId, name, pValue, pType);
  898.     }
  899. /*******************************************************************************
  900. *
  901. * symFindByNameAndType - look up a symbol by name and type
  902. *
  903. * This routine searches a symbol table for a symbol matching both name and
  904. * type (<name> and <sType>).  If the symbol is found, its value and type are
  905. * copied to <pValue> and <pType>.  The <mask> parameter can be used to match
  906. * sub-classes of type.
  907. *
  908. * To search the global VxWorks symbol table, specify f3sysSymTblf1
  909. * as <symTblId>.
  910. * RETURNS: OK, or ERROR if the symbol table ID is invalid
  911. * or the symbol is not found.
  912. */
  913. STATUS symFindByNameAndType
  914.     (
  915.     SYMTAB_ID   symTblId,       /* ID of symbol table to look in */
  916.     char        *name,          /* symbol name to look for */
  917.     char        **pValue,       /* where to put symbol value */
  918.     SYM_TYPE    *pType,         /* where to put symbol type */
  919.     SYM_TYPE    sType,          /* symbol type to look for */
  920.     SYM_TYPE    mask            /* bits in <sType> to pay attention to */
  921.     )
  922.     {
  923.     SYMBOL *pSymbol = NULL;
  924.     if (symFindSymbol (symTblId, name, NULL, sType, 
  925.        mask, &pSymbol) == ERROR)
  926.         return (ERROR);
  927.     if (pValue != NULL)
  928.         *pValue = (char *) pSymbol->value;
  929.     
  930.     if (pType != NULL)
  931.         *pType = pSymbol->type;
  932.     return OK;
  933.     }
  934. /*******************************************************************************
  935. *
  936. * symByValueFind - look up a symbol by value
  937. *
  938. * This routine searches a symbol table for a symbol matching a
  939. * specified value.  If there is no matching entry, it chooses the
  940. * table entry with the next lower value.  A pointer to a copy of the
  941. * symbol name string (with terminating EOS) is returned into
  942. * <pName>. The actual value and the type are copied to <pValue> and
  943. * <pType>.
  944. *
  945. * <pName> is a pointer to memory allocated by symByValueFind; 
  946. * the memory must be freed by the caller after the use of <pName>.
  947. *
  948. * To search the global VxWorks symbol table, specify f3sysSymTblf1
  949. * as <symTblId>.
  950. *
  951. * RETURNS: OK or ERROR if <symTblId> is invalid, <pName> is NULL, or
  952. * <value> is less than the lowest value in the table.
  953. */
  954. STATUS symByValueFind
  955.     (
  956.     SYMTAB_ID symTblId, /* ID of symbol table to look in */
  957.     UINT value, /* value of symbol to find */
  958.     char ** pName, /* where return symbol name string */
  959.     int  * pValue, /* where to put symbol value */
  960.     SYM_TYPE * pType /* where to put symbol type */
  961.     )
  962.     {
  963.     return (symByValueAndTypeFind (symTblId, value, pName, pValue, pType,
  964.    SYM_MASK_ANY_TYPE, SYM_MASK_ANY_TYPE));
  965.     }
  966. /*******************************************************************************
  967. *
  968. * symByValueAndTypeFind - look up a symbol by value and type
  969. *
  970. * This routine searches a symbol table for a symbol matching both
  971. * value and type (<value> and <sType>).  If there is no matching
  972. * entry, it chooses the table entry with the next lower value (among
  973. * entries with the same type). A pointer to the symbol name string
  974. * (with terminating EOS) is returned into <pName>. The actual value
  975. * and the type are copied to <pValue> and <pType>. The <mask>
  976. * parameter can be used to match sub-classes of type.
  977. * <pName> is a pointer to memory allocated by symByValueAndTypeFind; 
  978. * the memory must be freed by the caller after the use of <pName>.
  979. *
  980. * To search the global VxWorks symbol table, specify f3sysSymTblf1
  981. * as <symTblId>.
  982. *
  983. * RETURNS: OK or ERROR if <symTblId> is invalid, <pName> is NULL, or
  984. * <value> is less than the lowest value in the table.
  985. */
  986. STATUS symByValueAndTypeFind
  987.     (
  988.     SYMTAB_ID     symTblId, /* ID of symbol table to look in */
  989.     UINT     value, /* value of symbol to find */
  990.     char **     pName, /* where to return symbol name string */
  991.     int *     pValue, /* where to put symbol value */
  992.     SYM_TYPE *     pType, /* where to put symbol type */
  993.     SYM_TYPE        sType, /* symbol type to look for */
  994.     SYM_TYPE        mask /* bits in <sType> to pay attention to */
  995.     )
  996.     {
  997.     SYMBOL * pSymbol = NULL;
  998.    
  999.     if (pName == NULL)
  1000.         return ERROR;
  1001.     if (symFindSymbol(symTblId, NULL, (char *)value, sType, 
  1002.       mask, &pSymbol) != OK)
  1003.         return ERROR;
  1004.     if (pValue != NULL) 
  1005.         *pValue = (int) pSymbol->value;
  1006.     if (pType != NULL)
  1007.         *pType = pSymbol->type;
  1008.     if (((*pName) = (char *) malloc (strlen (pSymbol->name) + 1)) == NULL)
  1009.         return ERROR;
  1010.     strcpy ((*pName), pSymbol->name);
  1011.     
  1012.     return (OK);
  1013.     }
  1014. /*******************************************************************************
  1015. *
  1016. * symFindByValue - look up a symbol by value
  1017. *
  1018. * This routine is obsolete.  It is replaced by symByValueFind().
  1019. *
  1020. * This routine searches a symbol table for a symbol matching a specified
  1021. * value.  If there is no matching entry, it chooses the table entry with the
  1022. * next lower value.  The symbol name (with terminating EOS), the actual
  1023. * value, and the type are copied to <name>, <pValue>, and <pType>.
  1024. *
  1025. * For the <name> buffer, allocate MAX_SYS_SYM_LEN + 1 bytes.  The value
  1026. * MAX_SYS_SYM_LEN is defined in sysSymTbl.h.  If the name of the symbol 
  1027. * is longer than MAX_SYS_SYM_LEN bytes, it will be truncated to fit into the
  1028. * buffer.  Whether or not the name was truncated, the string returned in the
  1029. * buffer will be null-terminated.
  1030. *
  1031. * To search the global VxWorks symbol table, specify f3sysSymTblf1
  1032. * as <symTblId>.
  1033. * RETURNS: OK, or ERROR if <symTblId> is invalid or <value> is less
  1034. * than the lowest value in the table.  
  1035. */
  1036. STATUS symFindByValue
  1037.     (
  1038.     SYMTAB_ID symTblId, /* ID of symbol table to look in */
  1039.     UINT value, /* value of symbol to find */
  1040.     char * name, /* where to put symbol name string */
  1041.     int * pValue, /* where to put symbol value */
  1042.     SYM_TYPE * pType /* where to put symbol type */
  1043.     )
  1044.     {
  1045.     return (symFindByValueAndType (symTblId, value, name, pValue, pType,
  1046.    SYM_MASK_ANY_TYPE, SYM_MASK_ANY_TYPE));
  1047.     }
  1048. /*******************************************************************************
  1049. *
  1050. * symFindByValueAndType - look up a symbol by value and type
  1051. *
  1052. * This routine is obsolete.  It is replaced by the routine
  1053. * symByValueAndTypeFind().
  1054. *  
  1055. * This routine searches a symbol table for a symbol matching both value and
  1056. * type (<value> and <sType>).  If there is no matching entry, it chooses the
  1057. * table entry with the next lower value.  The symbol name (with terminating
  1058. * EOS), the actual value, and the type are copied to <name>, <pValue>, and
  1059. * <pType>.  The <mask> parameter can be used to match sub-classes of type.
  1060. *
  1061. * For the <name> buffer, allocate MAX_SYS_SYM_LEN + 1 bytes.  The value
  1062. * MAX_SYS_SYM_LEN is defined in sysSymTbl.h.  If the name of the symbol 
  1063. * is longer than MAX_SYS_SYM_LEN bytes, it will be truncated to fit into the
  1064. * buffer.  Whether or not the name was truncated, the string returned in the
  1065. * buffer will be null-terminated.
  1066. *
  1067. * To search the global VxWorks symbol table, specify f3sysSymTblf1
  1068. * as <symTblId>.
  1069. * INTERNAL
  1070. * This routine contains a weird hack designed to deal with the additional
  1071. * symbols the loader puts in the symbol table.  The loader adds three symbols
  1072. * to the symbol table: <filename>_text, <filename>_data, <filename>_bss.
  1073. * These symbols may have the same address (i.e. value in the symbol table)
  1074. * as real routine or variable names.  When looking up a symbol for display
  1075. * it is desirable to find the real routine or variable names in preference
  1076. * to these made up names.  For example, loading "demo.o" will cause a
  1077. * symbol "demo.o_text" to be added to the symbol table with the same value
  1078. * as the real symbol "_demo".  In a disassembly or "i" printout, etc, we
  1079. * would rather see "_demo".  So the test inside the loop in this routine
  1080. * that normally terminates the search if we find an exact match, has been
  1081. * changed to keep searching if the match it finds ends in "_text", "_data",
  1082. * or "_bss".  
  1083. *
  1084. * If no other exact match is found, the special symbols will be returned
  1085. * anyway.  Thus this routine simply has a "bias" against such symbols, but
  1086. * will not return an erroneous result in any event.  This nonsense should be
  1087. * removed when the loader is changed to not add the special symbols.
  1088. *
  1089. * The GNU toolkit adds symbols of the form "gcc2_compiled." and "xxx.o".
  1090. * These symbols are also biased against.  
  1091. *
  1092. * RETURNS: OK, or ERROR if <symTblId> is invalid or <value> is less
  1093. * than the lowest value in the table.  */
  1094. STATUS symFindByValueAndType
  1095.     (
  1096.     SYMTAB_ID     symTblId,     /* ID of symbol table to look in */
  1097.     UINT          value,        /* value of symbol to find */
  1098.     char *        name,         /* where to put symbol name string */
  1099.     int *         pValue,       /* where to put symbol value */
  1100.     SYM_TYPE *    pType,        /* where to put symbol type */
  1101.     SYM_TYPE      sType,        /* symbol type to look for */
  1102.     SYM_TYPE      mask          /* bits in <sType> to pay attention to */
  1103.     )
  1104.     {
  1105.     SYMBOL * pSymbol = NULL;
  1106.       
  1107.     if (symFindSymbol (symTblId, NULL, (char *) value, sType, 
  1108.        mask, &pSymbol) != OK)
  1109.         {
  1110. /* 
  1111.  * remap the errno for backward compatibility - can't change 
  1112.  * what errno's are returned for a particular failure mode
  1113.  */
  1114. if (errno == S_symLib_INVALID_SYMTAB_ID)   
  1115.     errnoSet (S_objLib_OBJ_ID_ERROR);
  1116.         return ERROR;
  1117. }
  1118.     /* 
  1119.      * XXX - JLN - This API is broken and should not be used anymore.
  1120.      * The next line is the best of several bad options for providing
  1121.      * some version of this routine for backward compatibility.  We
  1122.      * truncate the number of characters we return to match the size
  1123.      * that the documentation tells the caller to allocate.  
  1124.      */
  1125.     strncpy (name, pSymbol->name, MAX_SYS_SYM_LEN + 1);
  1126.     /* Null-terminate the string in case the name was truncated. */
  1127.     if (name[MAX_SYS_SYM_LEN] != EOS)
  1128.         name[MAX_SYS_SYM_LEN] = EOS;
  1129.     if (pValue != NULL)
  1130.         *pValue = (int) pSymbol->value; 
  1131.       
  1132.     if (pType != NULL)
  1133.         *pType = pSymbol->type;
  1134.     return (OK);
  1135.     }
  1136. /*******************************************************************************
  1137. *
  1138. * symEach - call a routine to examine each entry in a symbol table
  1139. *
  1140. * This routine calls a user-supplied routine to examine each entry in the
  1141. * symbol table; it calls the specified routine once for each entry.  The
  1142. * routine should be declared as follows:
  1143. * .CS
  1144. *     BOOL routine
  1145. *         (
  1146. *         char     *name,  /@ entry name                  @/
  1147. *         int     val,    /@ value associated with entry @/
  1148. *         SYM_TYPE  type,   /@ entry type                  @/
  1149. *         int     arg,    /@ arbitrary user-supplied arg @/
  1150. *         UINT16    group   /@ group number                @/
  1151. *         )
  1152. * .CE
  1153. * The user-supplied routine should return TRUE if symEach() is to continue
  1154. * calling it for each entry, or FALSE if it is done and symEach() can exit.
  1155. *
  1156. * RETURNS: A pointer to the last symbol reached,
  1157. * or NULL if all symbols are reached.
  1158. *
  1159. * INTERNAL
  1160. * In addition to the parameters given, it also passes a pointer to a symbol
  1161. * as the last arguement.
  1162. *
  1163. */
  1164. SYMBOL *symEach
  1165.     (
  1166.     SYMTAB_ID   symTblId,       /* pointer to symbol table */
  1167.     FUNCPTR     routine,        /* func to call for each tbl entry */
  1168.     int         routineArg      /* arbitrary user-supplied arg */
  1169.     )
  1170.     {
  1171.     SYMBOL   *pSymbol;
  1172.     RTN_DESC rtnDesc;
  1173.     if (OBJ_VERIFY (symTblId, symTblClassId) != OK)
  1174. return (NULL); /* invalid symbol table ID */
  1175.     /* fill in a routine descriptor with the routine and argument to call */
  1176.     rtnDesc.routine    = routine;
  1177.     rtnDesc.routineArg = routineArg;
  1178.     semTake (&symTblId->symMutex, WAIT_FOREVER);
  1179.     pSymbol = (SYMBOL *) hashTblEach (symTblId->nameHashId, symEachRtn,
  1180.       (int) &rtnDesc);
  1181.     semGive (&symTblId->symMutex); /* release exclusion to table */
  1182.     return (pSymbol); /* symbol we stopped on */
  1183.     }
  1184. /*******************************************************************************
  1185. *
  1186. * symEachRtn - call a user routine for a hashed symbol
  1187. *
  1188. * This routine supports hashTblEach(), by unpackaging the routine descriptor
  1189. * and calling the user routine specified to symEach() with the right calling
  1190. * sequence.
  1191. *
  1192. * RETURNS: Boolean result of user specified symEach routine.
  1193. *
  1194. * NOMANUAL
  1195. */
  1196. LOCAL BOOL symEachRtn
  1197.     (
  1198.     SYMBOL      *pSymbol,       /* ptr to symbol */
  1199.     RTN_DESC    *pRtnDesc       /* ptr to a routine descriptor */
  1200.     )
  1201.     {
  1202.     return ((* pRtnDesc->routine) (pSymbol->name, (int) pSymbol->value,
  1203.    pSymbol->type, pRtnDesc->routineArg,
  1204.    pSymbol->group, pSymbol));
  1205.     }
  1206. /*******************************************************************************
  1207. *
  1208. * symHFuncName - symbol name hash function
  1209. *
  1210. * This routine checksums the name and applies a multiplicative hashing function
  1211. * provided by hashFuncMultiply().
  1212. *
  1213. * RETURNS: An integer between 0 and (elements - 1).
  1214. */
  1215. LOCAL int symHFuncName
  1216.     (
  1217.     int         elements,       /* no. of elements in hash table */
  1218.     SYMBOL      *pSymbol,       /* pointer to symbol */
  1219.     int         seed            /* seed to be used as scalar */
  1220.     )
  1221.     {
  1222.     int  hash;
  1223.     char *tkey;
  1224.     int  key = 0;
  1225.     /* checksum the string and use a multiplicative hashing function */
  1226.     for (tkey = pSymbol->name; *tkey != ''; tkey++)
  1227. key = key + (unsigned int) *tkey;
  1228.     hash = key * seed; /* multiplicative hash func */
  1229.     hash = hash >> (33 - ffsMsb (elements)); /* take only the leading bits */
  1230.     return (hash & (elements - 1)); /* mask hash to (0,elements-1)*/
  1231.     }
  1232. /*******************************************************************************
  1233. *
  1234. * symKeyCmpName - compare two symbol's names for equivalence
  1235. *
  1236. * This routine returns TRUE if the match symbol's type masked by the specified
  1237. * symbol mask, is equivalent to the second symbol's type also masked by the
  1238. * symbol mask, and if the symbol's names agree.
  1239. *
  1240. * RETURNS: TRUE if symbols match, FALSE if they differ.
  1241. */
  1242. LOCAL BOOL symKeyCmpName
  1243.     (
  1244.     SYMBOL      *pMatchSymbol,          /* pointer to match criteria symbol */
  1245.     SYMBOL      *pSymbol,               /* pointer to symbol */
  1246.     int maskArg                 /* symbol type bits than matter (int) */
  1247.     )
  1248.     {
  1249.     SYM_TYPE    mask;                   /* symbol type bits than matter (char)*/
  1250.     /*
  1251.      * If maskArg is equal to SYM_MASK_EXACT, then check to see if the pointers
  1252.      * match exactly.
  1253.      */
  1254.     if (maskArg == SYM_MASK_EXACT)
  1255.         return (pMatchSymbol == pSymbol ? TRUE : FALSE);
  1256.     mask = (SYM_TYPE) maskArg;
  1257.     return (((pSymbol->type & mask) == (pMatchSymbol->type & mask)) &&
  1258.     (strcmp (pMatchSymbol->name, pSymbol->name) == 0));
  1259.     }
  1260. /*******************************************************************************
  1261. *
  1262. * symName - get the name associated with a symbol value
  1263. *
  1264. * This routine returns a pointer to the name of the symbol of specified value.
  1265. *
  1266. * RETURNS: A pointer to the symbol name, or
  1267. * NULL if symbol cannot be found or <symTbl> doesn't exist.
  1268. *
  1269. * NOMANUAL
  1270. */
  1271. char *symName
  1272.     (
  1273.     SYMTAB_ID   symTbl, /* symbol table */
  1274.     char        *value /* symbol value */
  1275.     )
  1276.     {
  1277.     SYMBOL sym;
  1278.     sym.value = (void *)value;                  /* initialize symbol */
  1279.     sym.name  = NULL;
  1280.     (void)symEach (symTbl, (FUNCPTR) symNameValueCmp, (int) (&sym));
  1281.     return (sym.name);
  1282.     }
  1283. /*******************************************************************************
  1284. *
  1285. * symNameValueCmp - compares a symbol value with a name
  1286. *
  1287. * This routine was written to be invoked by symEach().
  1288. * <pSym> is a pointer to a symbol which contains a value that this routine
  1289. * compares to the passed symbol value <val>.  If the two values match, then the
  1290. * name field in <pSym>'s name field is set to point to the symbol name in the
  1291. * symbol table.
  1292. *
  1293. * RETURNS: FALSE if <val> matches <pSym>->value and sets <pSym>->name,
  1294. * or TRUE otherwise.
  1295. */
  1296. LOCAL BOOL symNameValueCmp
  1297.     (
  1298.     char *name,         /* symbol name */
  1299.     int val,            /* symbol value */
  1300.     SYM_TYPE type,      /* symbol type -- not used */
  1301.     int pSym            /* pointer to symbol trying to be matched */
  1302.     )
  1303.     {
  1304.     if (val == (int) (((SYMBOL *)pSym)->value))
  1305.         {
  1306.         ((SYMBOL *)pSym)->name = name;
  1307.         return (FALSE);
  1308.         }
  1309.     return (TRUE);
  1310.     }
  1311. /*******************************************************************************
  1312. *
  1313. * symNameGet - get name of a symbol
  1314. * This routine is currently intended only for internal use. 
  1315. *
  1316. * It provides the name of the symbol specified by the SYMBOL_ID
  1317. * <symbolId>.  The SYMBOL_ID of a symbol may be obtained by using the
  1318. * routine symFindSymbol().  A pointer to the symbol table's copy of the
  1319. * symbol name is returned in <pName>.
  1320. *
  1321. * RETURNS: OK, or ERROR if either <pName> or <symbolId> is NULL.
  1322. *
  1323. * NOMANUAL 
  1324. */
  1325. STATUS symNameGet
  1326.     (
  1327.     SYMBOL_ID  symbolId,
  1328.     char **    pName
  1329.     )
  1330.     {
  1331.     if ((symbolId == NULL) || (pName == NULL))
  1332. return ERROR;
  1333.     *pName = symbolId->name;
  1334.     return OK;
  1335.     }
  1336. /*******************************************************************************
  1337. *
  1338. * symValueGet - get value of a symbol
  1339. * This routine is currently intended only for internal use. 
  1340. *
  1341. * It provides the value of the symbol specified by the SYMBOL_ID
  1342. * <symbolId>.  The SYMBOL_ID of a symbol may be obtained by using the
  1343. * routine symFindSymbol().  The value of the symbol is copied to 
  1344. * the location specified by <pValue>.
  1345. *
  1346. * RETURNS: OK, or ERROR if either <pValue> or <symbolId> is NULL.
  1347. *
  1348. * NOMANUAL 
  1349. */
  1350. STATUS symValueGet 
  1351.     (
  1352.     SYMBOL_ID  symbolId,
  1353.     void **    pValue
  1354.     )
  1355.     {
  1356.     if ((symbolId == NULL) || (pValue == NULL))
  1357. return ERROR;
  1358.     *pValue = symbolId->value;
  1359.     return OK;
  1360.     }
  1361. /*******************************************************************************
  1362. *
  1363. * symTypeGet - get type of a symbol
  1364. * This routine is currently intended only for internal use. 
  1365. *
  1366. * It provides the type of the symbol specified by the SYMBOL_ID
  1367. * <symbolId>.  The SYMBOL_ID of a symbol may be obtained by using the
  1368. * routine symFindSymbol().  The type of the symbol is copied to 
  1369. * the location specified by <pType>.
  1370. *
  1371. * RETURNS: OK, or ERROR if either <pType> or <symbolId> is NULL.
  1372. *
  1373. * NOMANUAL 
  1374. */
  1375. STATUS symTypeGet 
  1376.     (
  1377.     SYMBOL_ID  symbolId,
  1378.     SYM_TYPE * pType
  1379.     )
  1380.     {
  1381.     if ((symbolId == NULL) || (pType == NULL))
  1382. return ERROR;
  1383.     *pType = symbolId->type;
  1384.     return OK;
  1385.     }