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

VxWorks

开发平台:

C/C++

  1. /* loadLib.c - object module loader */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 06t,08may02,fmk  SPR 77007 - improve common symbol support - port
  8.                  loadCommonManage() and loadCommonMatch() from the host loader
  9. 06s,07mar02,jn   refix SPR # 30588 - return NULL when there are unresolved
  10.                  symbols
  11. 06r,07feb02,jn   documentation - loadModule returns a module id, not NULL,
  12.                  when there are unresolved symbols
  13. 06q,15oct01,pad  changed loadModuleAt() documentation about obsolete
  14.  <filename>_[text | data | bss] symbols.
  15. 06p,30nov98,dbt  clear seg.flags<xxx> in loadSegmentAllocate (SPR #23553).
  16.  If we are using text protection, do not use file alignment
  17.  if it is inferior to page size (SPR #23553).
  18. 06o,17jul98,pcn  Fixed SPR #21836: alignment mismatch between sections and
  19.  target.
  20. 06n,22nov96,elp  Synchronize only valid modules.
  21. 06m,06nov96,elp  replaced symAdd() calls by symSAdd() calls +
  22.  added symtbls synchro function pointer <syncLoadRtn>.
  23. 06l,04nov96,dgp  doc: fix for SPR #4108
  24. 06k,14oct95,jdi  doc: fixed unnecessary refs to UNIX.
  25. 06j,11feb95,jdi  doc tweaks.
  26. 06i,08dec94,rhp  docn: clarify RELOCATION section in loadModuleAT() (SPR#3769)
  27. 06h,19sep94,rhp  docn: show new load flags for loadModuleAt() (SPR#2369).
  28. 06g,16sep94,rhp  docn: deleted obsolete paragraph (SPR#2520)
  29. 06f,13feb93,kdl  changed cplusLib.h to private/cplusLibP.h (SPR #1917).
  30. 06e,27nov92,jdi  documentation cleanup.
  31. 06d,25sep92,jmm  added check of malloc's return value to loadSegmentsAllocate()
  32. 06c,10sep92,jmm  moved call to moduleLibInit() to usrConfig.c
  33. 06b,01aug92,srh  added include cplusLib.h.;
  34.  added call to cplusLoadFixup in loadModuleAtSym
  35. 06a,30jul92,jmm  documentation cleanup
  36. 05z,23jul92,jmm  loadSegmentsAllocate() created to alloc memory for all loaders
  37. 05v,18jul92,smb  Changed errno.h to errnoLib.h.
  38. 05u,16jul92,jmm  moved addSegNames here
  39.  added support for module tracking
  40. 05t,23jun92,ajm  fixed EXAMPLE that last change mucked
  41. 05s,18jun92,ajm  separated to be object module independent
  42. 05r,26may92,rrr  the tree shuffle
  43. 05q,10dec91,gae  added includes for ANSI.
  44. 05p,19nov91,rrr  shut up some ansi warnings.
  45. 05o,05oct91,ajm  changed bad ifdef of CPU==MIPS to CPU_FAMILY in relSegmentR3k
  46. 05n,04oct91,rrr  passed through the ansification filter
  47.   -changed functions to ansi style
  48.   -changed includes to have absolute path from h/
  49.   -fixed #else and #endif
  50.   -changed TINY and UTINY to INT8 and UINT8
  51.   -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY and ...
  52.   -changed VOID to void
  53.   -changed copyright notice
  54. 05m,30aug91,ajm  added MIPS support from 68k 05h, and mips 4.02 05q.
  55. 05l,28aug91,shl  added cache coherency calls for MC68040 support.
  56. 05k,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  57.  doc review by dnw.
  58. 05j,31mar91,del  made file null for I960.
  59. 05i,08feb91,jaa  documentation cleanup.
  60. 05h,05oct90,dnw  made loadModuleAtSym() be NOMANUAL.
  61. 05g,30jul90,dnw  changed pathLastName() to pathLastNamePtr().
  62.  added forward declaration of void routines.
  63. 05f,11may90,yao  added missing modification history (05e) for the last checkin.
  64. 05e,09may90,yao  typecasted malloc to (char *).
  65. 05d,22aug89,jcf  updated to allow for separate symbol tables.
  66.   symbol table type now a SYM_TYPE.
  67. 05c,06jul89,ecs  updated to track 4.0.2.
  68. 05b,06jun89,ecs  fixed bug in relSegmentSparc.
  69. 05a,01may89,ecs  split relSegment into relSegmentSparc & relSegment68k.
  70. 04g,06jul89,llk  changed call to pathLastName().
  71. 04f,16jun89,llk  made loadModuleAt add absolute symbols to symbol table.
  72.  created SEG_INFO structure to reduce parameter passing.
  73. 04e,09jun89,llk  fixed bug so that symbols which reside in segments that have
  74.    been located at a specific address now have the correct
  75.    relocated address entered in the symbol table.
  76. 04d,01may89,gae  added empty N_ABS case to relSegment to stop useless warnings.
  77. 04c,02oct88,hin  used correct N_TYPE constant in 04b fix.
  78. 04b,29sep88,gae  fixed relative relocation bug with Greenhill's a.out,
  79.    sort of introduced in 03y.
  80. 04a,07sep88,gae  applied dnw's documentation.
  81. 03z,15aug88,jcf  lint.
  82. 03y,30jun88,dnw  fixed bug of not relocating relative to data or bss correctly.
  83.     llk
  84. 03x,05jun88,dnw  changed from ldLib to loadLib.
  85.  removed pathTail.
  86. 03w,30may88,dnw  changed to v4 names.
  87. 03v,28may88,dnw  removed ldLoadAt.
  88. 03u,19nov87,dnw  made ldLoadModule tolerant of 0 length segments, strings, etc.
  89. 03t,04nov87,rdc  made ldLoadModule not create segment names if NO_SYMBOLS.
  90. 03s,16oct87,gae  removed ldLoadName, or ldLoadFile, and made ldLoadModule
  91.    determine and add module name to symbol table.
  92.  added pathTail().
  93. 03r,29jul87,ecs  added ldLoadFile, ldLoadModule.
  94.     rdc  fixed rdSymtab to zero out space malloc'd for common symbols.
  95.     dnw  fixed to require exact match with system symbol table
  96.   instead of allowing matches with or without leading '_'.
  97.  fixed to not link COMM symbols to existing symbols.
  98. 03q,02jul87,ecs  changed rdSymtab to call symFindType, instead of symFind.
  99. 03p,02apr87,ecs  added include of strLib.h
  100. 03o,23mar87,jlf  documentation.
  101. 03n,20dec86,dnw  changed to not get include files from default directories.
  102. 03m,24nov86,llk  deleted SYSTEM conditional compiles.
  103. 03l,09oct86,dnw  fixed handling of "pc relative" relocation commands.
  104.  cleaned up rdSymtab.
  105.  changed to allocate externals table based on size of symbol
  106.    table in object module.
  107. 03k,04sep86,jlf  minor documentation.
  108. 03j,27jul86,llk  prints error messages to standard error
  109. 03i,24jun86,rdc  now throws away stabs and absolute symbols.  Now
  110.  dynamically allocates and frees necessary buffers.
  111.  now searches symbol table before allocating new symbol
  112.  for type N_COMM.
  113. 03h,04jun86,dnw  changed sstLib calls to symLib.
  114. 03g,03mar86,jlf  changed ioctrl calls to ioctl.
  115. 03f,22oct85,dnw  Fixed bug reading 4 bytes too many for BSD4.2 string table.
  116. 03e,11oct85,jlf  Made the string table buffer and the externals buffer
  117.    be allocated rather than on the stack.
  118.  Made new routine ldInit.
  119.  Got rid of MAX_STRINGS and MAX_SYMBOLS, and replaced them with
  120.    local variables which are initialize by ldInit.
  121.  De-linted.
  122. 03d,10oct85,jlf  upped MAX_STRINGS form 20000 to 25000.  Made all
  123.  references use the #define, instead of raw numbers.
  124. 03c,27aug85,rdc  changed MAX_SYM_LEN to MAX_SYS_SYM_LEN.
  125. 03b,12aug85,jlf  fixed to not try to relocate segments that have already
  126.  been relocated pc-relative in 4.2 version.  Also, made it
  127.  check relocation segment length, and print an error msg if
  128.  it's not a long.
  129. 03a,07aug85,jlf  combined 4.2 and v7/sys5 version.
  130. 02b,20jul85,jlf  documentation.
  131. 02a,24jun85,rdc  modified for 4.2 a.out format.
  132. 01e,19sep84,jlf  cleaned up comments a little
  133. 01d,09sep84,jlf  added comments, copyright, got rid of GLOBAL.
  134. 01c,10aug84,dnw  changed load to not add special module symbols {T,D,B,E}name
  135.    but also changed to add _etext, _edata, and _end as normal
  136.    symbols.
  137.  fixed rdSymtab to not set S_ldLib_UNDEFINED_SYMBOL and
  138.    instead just leave it S_symLib_SYMBOL_NOT_FOUND.
  139.  changed load to continue with relocation even if
  140.    undefined symbols were found.
  141.  changed call to 'fioOpen' to just 'open'.
  142.  replaced 'load' and 'loadat' with 'ldLoad' and 'ldLoadAt',
  143.    which now take an fd instead of filename.
  144. 01b,02jul84,ecs  changed format strings to be more unixlike.
  145. 01a,27apr84,dnw  written: some culled from old fioLib
  146. */
  147. /*
  148. DESCRIPTION
  149. This library provides a generic object module loading facility.  Any
  150. supported format files may be loaded into memory, relocated properly, their
  151. external references resolved, and their external definitions added to
  152. the system symbol table for use by other modules and from the shell.
  153. Modules may be loaded from any I/O stream which allows repositioning of the
  154. pointer.  This includes netDrv, nfs, or local file devices.  It does not 
  155. include sockets.
  156. EXAMPLE
  157. .CS
  158.     fdX = open ("/devX/objFile", O_RDONLY);
  159.     loadModule (fdX, LOAD_ALL_SYMBOLS);
  160.     close (fdX);
  161. .CE
  162. This code fragment would load the object file "objFile" located on
  163. device "/devX/" into memory which would be allocated from the system
  164. memory pool.  All external and static definitions from the file would be
  165. added to the system symbol table.
  166. This could also have been accomplished from the shell, by typing:
  167. .CS
  168.     -> ld (1) </devX/objFile
  169. .CE
  170. INCLUDE FILE: loadLib.h
  171. SEE ALSO: usrLib, symLib, memLib,
  172. .pG "Basic OS"
  173. */
  174. /* defines */
  175. #undef INCLUDE_SDA /* SDA is not supported for the moment */
  176. /* 
  177.  * SYM_BASIC_NOT_COMM_MASK and SYM_BASIC_MASK are temporary masks until
  178.  * symbol values are harmonized between host and target sides
  179.  */
  180. #define SYM_BASIC_NOT_COMM_MASK   0x0d   /* basic mask but unset bit 
  181.                                           * two for common symbol */
  182. #define SYM_BASIC_MASK            0x0f   /* only basic types are of interest */
  183. /* includes */
  184. #include "vxWorks.h"
  185. #include "sysSymTbl.h"
  186. #include "ioLib.h"
  187. #include "loadLib.h"
  188. #include "fioLib.h"
  189. #include "errnoLib.h"
  190. #include "stdio.h"
  191. #include "moduleLib.h"
  192. #include "a_out.h"
  193. #include "pathLib.h"
  194. #include "private/vmLibP.h"
  195. #include "stdlib.h"
  196. #include "private/cplusLibP.h"
  197. #include "string.h"
  198. #include "memLib.h"
  199. #include "private/loadLibP.h"
  200. /* locals */
  201. LOCAL char cantAddSymErrMsg [] =
  202.     "loadAoutLib error: can't add '%s' to system symbol table - error = 0x%x.n";
  203. /* define generic load routine */
  204. FUNCPTR loadRoutine = (FUNCPTR) NULL;
  205. FUNCPTR syncLoadRtn = (FUNCPTR) NULL;
  206. /*******************************************************************************
  207. *
  208. * loadModule - load an object module into memory
  209. *
  210. * This routine loads an object module from the specified file, and places
  211. * the code, data, and BSS into memory allocated from the system memory
  212. * pool.
  213. *
  214. * This call is equivalent to loadModuleAt() with NULL for the addresses of
  215. * text, data, and BSS segments.  For more details, see the manual entry for
  216. * loadModuleAt().
  217. *
  218. * RETURNS:
  219. * MODULE_ID, or NULL if the routine cannot read the file, there is not
  220. * enough memory, or the file format is illegal.
  221. *
  222. * SEE ALSO: loadModuleAt()
  223. */
  224. MODULE_ID loadModule
  225.     (
  226.     int fd, /* fd of file to load */
  227.     int symFlag /* symbols to add to table */
  228. /* (LOAD_[NO | LOCAL | GLOBAL | ALL]_SYMBOLS) */
  229.     )
  230.     {
  231.     return (loadModuleAt (fd, symFlag, (char **)NULL, (char **)NULL,
  232.   (char **)NULL));
  233.     }
  234. /*******************************************************************************
  235. *
  236. * loadModuleAt - load an object module into memory
  237. *
  238. * This routine reads an object module from <fd>, and loads the code, data,
  239. * and BSS segments at the specified load addresses in memory set aside by
  240. * the user using malloc(), or in the system memory partition as described
  241. * below.  The module is properly relocated according to the relocation
  242. * commands in the file.  Unresolved externals will be linked to symbols
  243. * found in the system symbol table.  Symbols in the module being loaded can
  244. * optionally be added to the system symbol table.
  245. *
  246. * LINKING UNRESOLVED EXTERNALS 
  247. * As the module is loaded, any unresolved external references are
  248. * resolved by looking up the missing symbols in the the system symbol
  249. * table.  If found, those references are correctly linked to the new
  250. * module.  If unresolved external references cannot be found in the
  251. * system symbol table, then an error message ("undefined symbol: ...")
  252. * is printed for the symbol, but the loading/linking continues.  The
  253. * partially resolved module is not removed, to enable the user to
  254. * examine the module for debugging purposes.  Care should be taken
  255. * when executing code from the resulting module.  Executing code which 
  256. * contains references to unresolved symbols may have unexpected results 
  257. * and may corrupt the system's memory.
  258. * Even though a module with unresolved symbols remains loaded after this
  259. * routine returns, NULL will be returned to enable the caller to detect
  260. * the failure programatically.  To unload the module, the caller may
  261. * either call the unload routine with the module name, or look up the
  262. * module using the module name and then unload the module using the 
  263. * returned MODULE_ID.  See the library entries for moduleLib and unldLib
  264. * for details.  The name of the module is the name of the file loaded with
  265. * the path removed.
  266. *
  267. * ADDING SYMBOLS TO THE SYMBOL TABLE
  268. * The symbols defined in the module to be loaded may be optionally added
  269. * to the system symbol table, depending on the value of <symFlag>:
  270. * .iP "LOAD_NO_SYMBOLS" 29
  271. * add no symbols to the system symbol table
  272. * .iP "LOAD_LOCAL_SYMBOLS"
  273. * add only local symbols to the system symbol table
  274. * .iP "LOAD_GLOBAL_SYMBOLS"
  275. * add only external symbols to the system symbol table
  276. * .iP "LOAD_ALL_SYMBOLS"
  277. * add both local and external symbols to the system symbol table
  278. * .iP "HIDDEN_MODULE"
  279. * do not display the module via moduleShow().
  280. * .LP
  281. *
  282. * Obsolete symbols:
  283. *
  284. * For backward compatibility with previous releases, the following symbols
  285. * are also added to the symbol table to indicate the start of each segment:
  286. * <filename>_text, <filename>_data, and <filename>_bss, where <filename> is
  287. * the name associated with the fd. Note that these symbols are not available 
  288. * when the ELF format is used. Also they will disappear with the next VxWorks
  289. * release. The moduleLib API should be used instead to get segment information.
  290. *
  291. * RELOCATION
  292. * The relocation commands in the object module are used to relocate
  293. * the text, data, and BSS segments of the module.  The location of each
  294. * segment can be specified explicitly, or left unspecified in which
  295. * case memory will be allocated for the segment from the system memory
  296. * partition.  This is determined by the parameters <ppText>, <ppData>, and
  297. * <ppBss>, each of which can have the following values:
  298. * .iP "NULL"
  299. * no load address is specified, none will be returned;
  300. * .iP "A pointer to LD_NO_ADDRESS"
  301. * no load address is specified, the return address is referenced by the pointer;
  302. * .iP "A pointer to an address"
  303. * the load address is specified.
  304. * .LP
  305. *
  306. * The <ppText>, <ppData>, and <ppBss> parameters specify where to load
  307. * the text, data, and bss sections respectively.  Each of these
  308. * parameters is a pointer to a  pointer; for example, **<ppText>
  309. * gives the address where the text segment is to begin.
  310. *
  311. * For any of the three parameters, there are two ways to request that
  312. * new memory be allocated, rather than specifying the section's
  313. * starting address: you can either specify the parameter itself as
  314. * NULL, or you can write the constant LD_NO_ADDRESS in place of an
  315. * address.  In the second case, loadModuleAt() routine replaces the
  316. * LD_NO_ADDRESS value with the address actually used for each section
  317. * (that is, it records the address at *<ppText>, *<ppData>, or
  318. * *<ppBss>).
  319. *
  320. * The double indirection not only permits reporting the addresses
  321. * actually used, but also allows you to specify loading a segment
  322. * at the beginning of memory, since the following cases can be
  323. * distinguished:
  324. *
  325. * .IP (1) 4
  326. * Allocate memory for a section (text in this example):  <ppText> == NULL
  327. * .IP (2)
  328. * Begin a section at address zero (the text section, below):  *<ppText> == 0
  329. * .LP
  330. * Note that loadModule() is equivalent to this routine if all three of the
  331. * segment-address parameters are set to NULL.
  332. *
  333. * COMMON
  334. * Some host compiler/linker combinations use another storage class internally
  335. * called "common".  In the C language, uninitialized global variables are
  336. * eventually put in the bss segment.  However, in partially linked object
  337. * modules they are flagged internally as "common" and the static 
  338. * linker (host) resolves these and places them in bss as a final step 
  339. * in creating a fully linked object module.  However, the target loader
  340. * is most often used to load partially linked object modules.
  341. * When the target loader encounters a variable labeled "common",
  342. * its behavior depends on the following flags :
  343. * .iP "LOAD_COMMON_MATCH_NONE" 8
  344. * Allocate memory for the variable with malloc() and enter the variable
  345. * in the target symbol table (if specified) at that address. This is
  346. * the default.
  347. * .iP "LOAD_COMMON_MATCH_USER"
  348. * Search for the symbol in the target symbol table, excluding the
  349. * vxWorks image  symbols. If several symbols exist, then the order of matching
  350. * is:  (1) bss, (2) data. If no symbol is found, act like the
  351. * default.
  352. * .iP "LOAD_COMMON_MATCH_ALL"
  353. * Search for the symbol in the target symbol table, including the
  354. * vxWorks image symbols. If several symbols exist, then the order of matching is:  
  355. * (1) bss, (2) data. If no symbol is found, act like the default.
  356. * .LP
  357. * Note that most UNIX loaders have an option that forces resolution of the
  358. * common storage while leaving the module relocatable (for example, with
  359. * typical BSD UNIX loaders, use options "-rd").
  360. *
  361. * EXAMPLES
  362. * Load a module into allocated memory, but do not return segment addresses:
  363. * .CS
  364. *     module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, NULL, NULL, NULL);
  365. * .CE
  366. * Load a module into allocated memory, and return segment addresses:
  367. * .CS
  368. *     pText = pData = pBss = LD_NO_ADDRESS;
  369. *     module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, &pText, &pData, &pBss);
  370. * .CE
  371. * Load a module to off-board memory at a specified address:
  372. * .CS
  373. *     pText = 0x800000; /@ address of text segment   @/
  374. *     pData = pBss = LD_NO_ADDRESS /@ other segments follow by default @/
  375. *     module_id = loadModuleAt (fd, LOAD_GLOBAL_SYMBOLS, &pText, &pData, &pBss);
  376. * .CE
  377. *
  378. * RETURNS:
  379. * MODULE_ID, or
  380. * NULL if the file cannot be read, there is not enough memory,
  381. * the file format is illegal, or there were unresolved symbols.
  382. *
  383. * SEE ALSO:
  384. * .pG "Basic OS" 
  385. */
  386. MODULE_ID loadModuleAt
  387.     (
  388.     FAST int fd, /* fd from which to read module */
  389.     int symFlag, /* symbols to add to table */
  390. /* (LOAD_[NO | LOCAL | GLOBAL | ALL]_SYMBOLS) */
  391.     char **ppText,      /* load text segment at addr. pointed to by this */
  392. /* ptr, return load addr. via this ptr */
  393.     char **ppData,      /* load data segment at addr. pointed to by this */
  394. /* pointer, return load addr. via this ptr */
  395.     char **ppBss /* load BSS segment at addr. pointed to by this */
  396. /* pointer, return load addr. via this ptr */
  397.     )
  398.     {
  399.     return (loadModuleAtSym (fd, symFlag, ppText, ppData, ppBss, sysSymTbl));
  400.     }
  401. /******************************************************************************
  402. *
  403. * loadModuleAtSym - load object module into memory with specified symbol table
  404. *
  405. * This routine is the underlying routine to loadModuleAt().  This interface
  406. * allows specification of the the symbol table used to resolve undefined
  407. * external references and to which to add new symbols.
  408. *
  409. * RETURNS:
  410. * MODULE_ID, or
  411. * NULL if can't read file or not enough memory or illegal file format
  412. *
  413. * NOMANUAL
  414. */
  415. MODULE_ID loadModuleAtSym
  416.     (
  417.     FAST int fd, /* fd from which to read module */
  418.     int symFlag, /* symbols to be added to table
  419.  *   ([NO | GLOBAL | ALL]_SYMBOLS) */
  420.     char **ppText,      /* load text segment at address pointed to by this
  421.  * pointer, return load address via this pointer */
  422.     char **ppData,      /* load data segment at address pointed to by this
  423.  * pointer, return load address via this pointer */
  424.     char **ppBss,       /* load bss segment at address pointed to by this
  425.  * pointer, return load address via this pointer */
  426.     SYMTAB_ID symTbl    /* symbol table to use */
  427.     )
  428.     {
  429.     MODULE_ID module;
  430.     if (loadRoutine == NULL)
  431. {
  432. errnoSet (S_loadLib_ROUTINE_NOT_INSTALLED);
  433. return (NULL);
  434. }
  435.     else
  436. {
  437. module = (MODULE_ID) (*loadRoutine) (fd, symFlag, ppText, ppData, ppBss,
  438.     symTbl);
  439. if (module != NULL)
  440.     {
  441.     cplusLoadFixup (module, symFlag, symTbl);
  442.     /* synchronize host symbol table if necessary */
  443.     if (syncLoadRtn != NULL)
  444. (* syncLoadRtn) (module);
  445.     }
  446. return module;
  447. }
  448.     }
  449. /******************************************************************************
  450. *
  451. * loadModuleGet - create module information for a loaded object module
  452. *
  453. * RETURNS:  MODULE_ID, or NULL if module could not be created.
  454. *
  455. * NOMANUAL
  456. */
  457. MODULE_ID loadModuleGet
  458.     (
  459.     char *  fileName, /* name of the module */
  460.     int format, /* object module format */
  461.     int * symFlag /* pointer to symFlag */
  462.     )
  463.     {
  464.     MODULE_ID moduleId;
  465.     /* Change old style flags to new style */
  466.     switch (*symFlag)
  467. {
  468. case NO_SYMBOLS:
  469.     *symFlag = LOAD_NO_SYMBOLS;
  470.     break;
  471. case GLOBAL_SYMBOLS:
  472.     *symFlag = LOAD_GLOBAL_SYMBOLS;
  473.     break;
  474. case ALL_SYMBOLS:
  475.     *symFlag = LOAD_ALL_SYMBOLS;
  476.     break;
  477. }
  478.     moduleId = moduleCreate (fileName, format, *symFlag);
  479.     return (moduleId);
  480.     }
  481. /*******************************************************************************
  482. *
  483. * addSegNames - add segment names to symbol table
  484. *
  485. * This routine adds names of the form "objectFile.o_text," objectFile.o_data,"
  486. * and "objectFile.o_bss" to the symbol table.
  487. *
  488. * NOMANUAL
  489. */
  490. void addSegNames
  491.     (
  492.     int fd, /* file descriptor for the object file */
  493.     char *pText, /* pointer to the text segment */
  494.     char *pData, /* pointer to the data segment */
  495.     char *pBss, /* pointer to the BSS segment */
  496.     SYMTAB_ID   symTbl, /* symbol table to use */
  497.     UINT16 group /* group number */
  498.     )
  499.     {
  500.     char fullname [MAX_FILENAME_LENGTH];
  501.     char symName[MAX_SYS_SYM_LEN + 1];
  502.     char *pName;
  503.     if (ioctl (fd, FIOGETNAME, (int) fullname) == OK)
  504. pName = pathLastNamePtr (fullname); /* get last simple name */
  505.     else
  506. pName = "???";
  507.     /* XXX
  508.      * Adding these symbols is now obsolete, and should probably
  509.      * be removed in a future version of the OS.  For now, leave them
  510.      * in for backwards compatability.
  511.      */
  512.     if (pText != NULL)
  513. {
  514. sprintf (symName, "%s_text", pName);
  515. if (symSAdd (symTbl, symName, pText, (N_EXT | N_TEXT), group) != OK)
  516.     printErr (cantAddSymErrMsg, symName, errnoGet());
  517. }
  518.     if (pData != NULL)
  519. {
  520. sprintf (symName, "%s_data", pName);
  521. if (symSAdd (symTbl, symName, pData, (N_EXT | N_DATA), group) != OK)
  522.     printErr (cantAddSymErrMsg, symName, errnoGet());
  523. }
  524.     if (pBss != NULL)
  525. {
  526. sprintf (symName,  "%s_bss",  pName);
  527. if (symSAdd (symTbl, symName, pBss, (N_EXT | N_BSS), group) != OK)
  528.     printErr (cantAddSymErrMsg, symName, errnoGet());
  529. }
  530.     }
  531. /******************************************************************************
  532. *
  533. * loadSegmentsAllocate - allocate text, data, and bss segments
  534. *
  535. * This routine allocates memory for the text, data, and bss segments of
  536. * an object module.  Before calling this routine, set up the fields of the
  537. * SEG_INFO structure to specify the desired location and size of each segment.
  538. *
  539. * RETURNS: OK, or ERROR if memory couldn't be allocated.
  540. *
  541. * NOMANUAL
  542. */
  543. STATUS loadSegmentsAllocate
  544.     (
  545.     SEG_INFO * pSeg /* pointer to segment information */
  546.     )
  547.     {
  548.     BOOL  protectText = FALSE;
  549.     int  pageSize;
  550.     int alignment = 0;
  551.     int textAlignment = pSeg->flagsText; /* save text alignment */
  552.     int dataAlignment = pSeg->flagsData; /* save data alignment */
  553.     int bssAlignment = pSeg->flagsBss;  /* save bss alignment */
  554.     /* clear pSeg->flags<xxx> fields */
  555.     pSeg->flagsText = 0;
  556.     pSeg->flagsData = 0;
  557.     pSeg->flagsBss = 0;
  558.     /*
  559.      * if text segment protection is selected, then allocate the text
  560.      * segment seperately on a page boundry
  561.      */
  562.     if ((pSeg->sizeText != 0) && vmLibInfo.protectTextSegs
  563. && (pSeg->addrText == LD_NO_ADDRESS))
  564. {
  565. if ((pageSize = VM_PAGE_SIZE_GET()) == ERROR)
  566.     return (ERROR);
  567. /* round text size to integral number of pages */
  568. pSeg->sizeProtectedText = pSeg->sizeText / pageSize * pageSize
  569.   + pageSize;
  570. /*
  571.  * get the section alignment (maximum between page size and section
  572.  * alignment specified in the file).
  573.  */
  574. alignment = max(pageSize, textAlignment);
  575. if ((pSeg->addrText = memalign (alignment,
  576. pSeg->sizeProtectedText)) == NULL)
  577.     return (ERROR);
  578. pSeg->flagsText |= SEG_WRITE_PROTECTION;
  579. pSeg->flagsText |= SEG_FREE_MEMORY;
  580. protectText = TRUE;
  581. }
  582.     /* if all addresses are unspecified, allocate one large chunk of memory */
  583.     if (pSeg->addrText == LD_NO_ADDRESS &&
  584. pSeg->addrData == LD_NO_ADDRESS &&
  585. pSeg->addrBss  == LD_NO_ADDRESS)
  586. {
  587. /* SPR #21836 */
  588. alignment = 0;
  589. if (textAlignment > dataAlignment)
  590.     alignment = max (textAlignment, bssAlignment);
  591. else
  592.     alignment = max (dataAlignment, bssAlignment);
  593. if (alignment != 0)
  594.     pSeg->addrText = memalign (alignment, pSeg->sizeText + 
  595.        pSeg->sizeData + pSeg->sizeBss);
  596. else
  597.     pSeg->addrText = malloc (pSeg->sizeText + pSeg->sizeData +
  598.      pSeg->sizeBss);
  599. /* check for malloc error */
  600. if (pSeg->addrText == NULL)
  601.     return (ERROR);
  602. pSeg->addrData = pSeg->addrText + pSeg->sizeText;
  603. pSeg->addrBss = pSeg->addrData + pSeg->sizeData;
  604. pSeg->flagsText |= SEG_FREE_MEMORY;
  605. }
  606.     /* if addresses not specified, allocate memory. */
  607.     if (pSeg->addrText == LD_NO_ADDRESS && pSeg->sizeText != 0)
  608. {
  609. /* SPR #21836 */
  610. if (textAlignment != 0)
  611.     {
  612.     if ((pSeg->addrText = (char *) memalign (textAlignment,
  613. pSeg->sizeText)) == NULL)
  614. return (ERROR);
  615.     }
  616. else
  617.     {
  618.     if ((pSeg->addrText = (char *) malloc (pSeg->sizeText)) == NULL)
  619. return (ERROR);
  620.     }
  621. pSeg->flagsText |= SEG_FREE_MEMORY;
  622. }
  623.     if (pSeg->addrData == LD_NO_ADDRESS && pSeg->sizeData != 0)
  624. {
  625. /* SPR #21836 */
  626. if (dataAlignment != 0)
  627.     {
  628.     if ((pSeg->addrData = (char *) memalign (dataAlignment,
  629. pSeg->sizeData)) == NULL)
  630. return (ERROR);
  631.     }
  632. else
  633.     {
  634.     if ((pSeg->addrData = (char *) malloc (pSeg->sizeData)) == NULL)
  635. return (ERROR);
  636.     }
  637. pSeg->flagsData |= SEG_FREE_MEMORY;
  638. }
  639.     if (pSeg->addrBss == LD_NO_ADDRESS && pSeg->sizeBss)
  640. {
  641. /* SPR #21836 */
  642. if (bssAlignment != 0)
  643.     {
  644.     if ((pSeg->addrBss = (char *) memalign (bssAlignment,
  645. pSeg->sizeBss)) == NULL)
  646. return (ERROR);
  647.     }
  648. else
  649.     {
  650.     if ((pSeg->addrBss = (char *) malloc (pSeg->sizeBss)) == NULL)
  651. return (ERROR);
  652.     }
  653. pSeg->flagsBss |= SEG_FREE_MEMORY;
  654. }
  655.     return (OK);
  656.     }
  657. /*******************************************************************************
  658. *
  659. * loadCommonMatch - support routine for loadCommonManage
  660. *
  661. * This is the support routine for all loadCommonManage() function.
  662. * It fills the pSymAddr<type> fields of a COMMON_INFO structure if a global
  663. * symbol matches the name of the common symbol.
  664. *
  665. * For each symbol type (SYM_DATA, SYM_BSS), the most recent occurence
  666. * of a matching symbol in the target symbol table is recorded.
  667. *
  668. * RETURN : OK always.
  669. *
  670. * NOMANUAL
  671. */
  672. STATUS loadCommonMatch
  673.     (
  674.     COMMON_INFO * pCommInfo,            /* what to do with commons */
  675.     SYMTAB_ID     symTblId              /* ID of symbol table to look in */
  676.     )
  677.     {
  678.     int         nodeIdx;                /* index of node of interest */
  679.     int         mask;
  680.     HASH_ID     hashId = symTblId->nameHashId;    /* id of hash table */
  681.     SYMBOL      matchSymbol;            /* matching symbol */
  682.     SYMBOL *    pSymNode = NULL;        /* symbol in node's link list */
  683.     SYM_TYPE    basicType;              /* symbol's basic type */
  684.     /* initialize symbol's characteristics to match */
  685.     matchSymbol.name = pCommInfo->symName;
  686.     matchSymbol.type = SYM_MASK_NONE;
  687.     /* get corresponding node index into hash table */
  688.     nodeIdx = (* hashId->keyRtn)(hashId->elements, (HASH_NODE *) &matchSymbol,
  689.                                  hashId->keyArg);
  690.     /* get first symbol in the node's linked list */
  691.     pSymNode = (SYMBOL *) SLL_FIRST (&hashId->pHashTbl [nodeIdx]);
  692.     /* walk the node's linked list until we reach the end */
  693.     while(pSymNode != NULL)
  694.         {
  695.         /*
  696.          * If the core's symbols are excluded from the search and the global
  697.          * symbol is a core's symbol (group 0), jump to the next symbol.
  698.          * If the symbol's name doesn't match the common symbol's name, jump
  699.          * to the next symbol.
  700.          */
  701.         mask = SYM_BASIC_MASK;
  702.         if(!((pCommInfo->vxWorksSymMatched == FALSE) && (pSymNode->group == 0)) &&
  703.            (strcmp (pCommInfo->symName, pSymNode->name) == 0))
  704.             {
  705.             /* extract symbol's basic type */
  706.     /* 
  707.              * since SYM_BASIC_MASK does not properly mask out SYM_COMM
  708.              * we have to apply another mask to mask out bit two. Since 
  709.              * bit two can  be  SYM_ABS, we have to check for SYM_COMM first
  710.              */ 
  711.             if ((pSymNode->type & SYM_COMM)== SYM_COMM)
  712.                 mask = SYM_BASIC_NOT_COMM_MASK;
  713.             basicType = pSymNode->type & mask;
  714.             /*
  715.              * Record the global symbol's address accordingly with its type,
  716.              * then jump to the next symbol.
  717.              * Note that we only record the last occurence of the symbol in
  718.              * the symbol table.
  719.              */
  720.             
  721.             if((basicType == (SYM_BSS | SYM_GLOBAL)) &&
  722.                (pCommInfo->pSymAddrBss == NULL))
  723.                 {
  724.                 pCommInfo->pSymAddrBss = (void *) pSymNode->value;
  725.                 pCommInfo->bssSymType = pSymNode->type;
  726.                 }
  727.             else if((basicType == (SYM_DATA | SYM_GLOBAL)) &&
  728.                     (pCommInfo->pSymAddrData == NULL))
  729.                 {
  730.                 pCommInfo->pSymAddrData = (void *) pSymNode->value;
  731.                 pCommInfo->dataSymType = pSymNode->type;
  732.                 }
  733.             }
  734.         /* point to next symbol in the node's linked list */
  735.         pSymNode = (SYMBOL *) SLL_NEXT ((HASH_NODE *)pSymNode);
  736.         }
  737.     return (OK);
  738.     }
  739. /*******************************************************************************
  740. *
  741. * loadCommonManage - process a common symbol
  742. *
  743. * This routine processes the common symbols found in the object
  744. * module.  Common symbols are symbols declared global without being
  745. * assigned a value.  Good programming avoids such declarations since
  746. * it is almost impossible to be sure what initialized global symbol
  747. * should be used to solve a common symbol relocation.  The processing
  748. * of common symbols depends on the following control flags, which
  749. * enforce one of three levels of strictness for common symbol
  750. * evaluation: 
  751. * LOAD_COMMON_MATCH_NONE
  752. * This is the default option. Common symbols are kept isolated,
  753. * visible from the object module only. This option prevents any
  754. * matching with already-existing symbols (in other words, the
  755. * relocations that refer to these symbols are kept local). Memory is
  756. * allocated and symbols are added to the symbol table with type
  757. * SYM_COMM unless LOAD_NO_SYMBOLS is set.
  758. * LOAD_COMMON_MATCH_USER
  759. * The loader seeks a matching symbol in the target symbol table, but
  760. * only symbols brought by user's modules are considered. If no
  761. * matching symbol exists, it acts like LOAD_COMMON_MATCH_NONE. If
  762. * several matching symbols exist, the order of preference is: symbols
  763. * in the bss segment, then symbols in the data segment. If several
  764. * matching symbols exist within a segment type, memory is allocated
  765. * and the symbol most recently added to the target symbol table is
  766. * used as reference.
  767. * LOAD_COMMON_MATCH_ALL
  768. * The loader seeks for a matching symbol in the target symbol table.
  769. * All symbols are considered. If no matching symbol exists, then it
  770. * acts like LOAD_COMMON_MATCH_NONE.  If several matches are found, the
  771. * order is the same as for LOAD_COMMON_MATCH_USER.
  772. *
  773. * RETURNS
  774. * OK or ERROR if the memory allocation or the addition to the symbol table
  775. * fails.
  776. *
  777. * SEE ALSO
  778. * API Programmer's Guide: Object Module Loader
  779. *
  780. * INTERNAL
  781. * Note that with LOAD_COMMON_MATCH_USER, and moreover
  782. * LOAD_COMMON_MATCH_ALL, it is not possible to know whether the symbol
  783. * used for the evaluation is the right symbol. For instance, consider
  784. * a module A defining "int evtAction = 0;", a module B defining "int
  785. * evtAction;".  The symbol "evtAction" is declared as common in B
  786. * module.  If B module is loaded before A module, and if
  787. * LOAD_COMMON_MATCH_ALL is set, the loader will use the vxWorks'
  788. * global symbol evtAction to solve this common symbol...
  789. * It is therefore up to the user to download in the right order his
  790. * modules, or use the right flag, or even better, to not use common
  791. * symbols at all.  Note also that no search is done for previous
  792. * common symbol.
  793. *
  794. * NOMANUAL 
  795. *
  796. */
  797. STATUS loadCommonManage
  798.     (
  799.     int         comAreaSize,    /* size of area required for common sym */
  800.     int         comAlignment,   /* alignment required for common sym */
  801.     char *      symName,        /* symbol name */
  802.     SYMTAB_ID   symTbl,         /* target symbol table */
  803.     SYM_ADRS *pSymAddr,       /* where to return symbol's address */
  804.     SYM_TYPE *  pSymType,       /* where to return symbol's type */
  805.     int         loadFlag,       /* control of loader's behavior */
  806.     SEG_INFO *  pSeg,           /* section addresses and sizes */
  807.     int         group           /* module group */
  808.     )
  809.     {
  810.     COMMON_INFO commInfo;       /* what to do with commons */
  811.     /* Force the default choice if no flag set */
  812.     if(!(loadFlag & LOAD_COMMON_MATCH_ALL) &&
  813.        !(loadFlag & LOAD_COMMON_MATCH_USER) &&
  814.        !(loadFlag & LOAD_COMMON_MATCH_NONE))
  815.         loadFlag |= LOAD_COMMON_MATCH_NONE;
  816.     /* Must we do more than the default ? */
  817.     if(!(loadFlag & LOAD_COMMON_MATCH_NONE))
  818.         {
  819.         /* Initialization */
  820.         memset (&commInfo, 0, sizeof (COMMON_INFO));
  821.         commInfo.symName = symName;
  822.         /* Do we involve the core's symbols ? */
  823.         if(loadFlag & LOAD_COMMON_MATCH_USER)
  824.             commInfo.vxWorksSymMatched = FALSE;    /* no */
  825.         else if(loadFlag & LOAD_COMMON_MATCH_ALL)
  826.             commInfo.vxWorksSymMatched = TRUE;    /* yes */
  827.         /* Get the last occurences of matching global symbols in bss and data */
  828.         loadCommonMatch (&commInfo, symTbl);
  829.         /* Prefered order for matching symbols is : bss then data*/
  830.         if(commInfo.pSymAddrBss != NULL)    /* matching sym in bss */
  831.             {
  832.             *pSymAddr = commInfo.pSymAddrBss;
  833.             *pSymType = commInfo.bssSymType;
  834.             }
  835.         else if(commInfo.pSymAddrData != NULL)    /* matching sym in data */
  836.             {
  837.             *pSymAddr = commInfo.pSymAddrData;
  838.             *pSymType = commInfo.dataSymType;
  839.             }
  840.         else *pSymAddr = NULL;          /* no matching symbol */
  841.         /*
  842.          * If we found a matching symbol, stop here, otherwise apply
  843.          * LOAD_COMMON_MATCH_NONE management.
  844.          */
  845.         if(*pSymAddr != NULL)
  846.             return (OK);
  847. }
  848.     /* If additional info is available then we are dealing with a PowerPC */
  849. #ifdef INCLUDE_SDA
  850.     if(pSeg->pAdnlInfo != NULL)
  851.         *pSymType = SYM_SDA | SYM_BSS | SYM_COMM | SYM_GLOBAL;
  852.     else
  853. #endif /* INCLUDE_SDA */
  854.         *pSymType = SYM_BSS | SYM_COMM | SYM_GLOBAL;
  855.     /*
  856.      * Allocate memory for new symbol. This must be done even if flag
  857.      * LOAD_NO_SYMBOLS is applied (SPR #9259).
  858.      */
  859.  
  860. #ifdef INCLUDE_SDA
  861.     if (pSeg->pAdnlInfo != NULL)
  862.         {
  863.         if (comAlignment != 0)
  864.             *pSymAddr = (void *) memPartAlignedAlloc
  865.                                  (((SDA_INFO *)pSeg->pAdnlInfo)->sdaMemPartId,
  866.                                   comAreaSize, comAlignment);
  867. else
  868.             *pSymAddr = (void *) memPartAlloc
  869.                                  (((SDA_INFO *)pSeg->pAdnlInfo)->sdaMemPartId,
  870.                                   comAreaSize);
  871. }
  872.     else
  873. #endif /* INCLUDE_SDA */
  874.         {
  875.         if (comAlignment != 0)
  876.             *pSymAddr = (void *) memalign (comAlignment, comAreaSize);
  877. else
  878.     *pSymAddr = (void *) malloc (comAreaSize);
  879. }
  880.     if (*pSymAddr == NULL)
  881.         return (ERROR);
  882.  
  883.     memset ((SYM_ADRS)*pSymAddr, 0, comAreaSize);
  884.  
  885.     /* Add symbol to the target symbol table if required */
  886.  
  887.     if(!(loadFlag & LOAD_NO_SYMBOLS) && (loadFlag & LOAD_GLOBAL_SYMBOLS))
  888.         {
  889.         if(symSAdd (symTbl, symName, (char *)*pSymAddr, *pSymType, 
  890.  (UINT16) group) != OK)
  891.             {
  892.             printErr ("Can't add '%s' to symbol table.n", symName);
  893.             *pSymAddr = NULL;
  894.             return (ERROR);
  895.             }
  896.         }
  897.     return (OK);
  898.     }