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

VxWorks

开发平台:

C/C++

  1. /* loadElfLib.c - UNIX elf object module loader */
  2. /* Copyright 1996-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01x,09may02,fmk  use loadCommonManage() instead of loadElfCommonManage()
  8. 01w,23apr02,jn   SPR 75177 - correct inaccurate test for whether CPU is
  9.                  SIMSPARCSOLARIS 
  10. 01v,26mar02,jn   fix alignment handling for COMMON's (SPR 74567)
  11. 01u,07mar02,jn   Add STT_ARM_16BIT to recognized types (SPR # 73992)
  12. 01t,07mar02,jn   Refix SPR# 30588 - load should return NULL when there are
  13.                  unresolved symbols.
  14. 01s,14jan02,jn   Improve comments about setting SYM_THUMB
  15. 01r,25jan02,rec  Merge in coldfire changes
  16. 01q,12dec01,pad  Moved MIPS support code out in the ELF/MIPS relocation unit.
  17. 01p,28nov01,jn   Fix alignment of segments (SPR #28353).  Also removed 
  18.                  declarations of unsupported relocation types for SH.
  19. 01o,19nov01,pch  Provide misalignment prevention based on _WRS_STRICT_ALIGNMENT
  20.  definition instead of testing a specific CPU type.
  21. 01n,08nov01,jn   Added support for ARM/THUMB architecture now using ELF
  22. 01m,17sep01,pad  Introduced usage of relocation unit's init routines. Added
  23.  support for I86 relocation unit. Symbols from a read-only data
  24.    sections are now flagged as data, like in VxWorks AE, rather
  25.  than text. Made the determination of text sections more
  26.  flexible in loadElfSegSizeGet().
  27. 01l,28jun01,agf  add logic to MIPS that tests for attempted relative jumps
  28.                  across a 26 bit boundary
  29. 01k,03mar00,zl   merged SH support from T1
  30. 01j,30nov98,dbt  no longer clear seg.flags<xxx> after loadSegmentAllocate()
  31.                  call. (SPR #23553).
  32. 01i,05oct98,pcn  Initialize all the fields in the SEG_INFO structure.
  33. 01h,16sep98,pcn  Set to _ALLOC_ALIGN_SIZE the flags field in seg structure
  34.                  (SPR #21836).
  35. 01g,17jul98,pcn  Fixed SPR #21836: alignment mismatch between sections and
  36.                  target.
  37. 01f,18apr97,kkk  fixed printing of debug msgs for MIPS (spr# 8276)
  38. 01e,05dec96,dbt  fixed a bug in loadElfSizeGet() when loading an object file
  39.                  with a data section null and a text and bss sections not
  40.                  null.
  41. 01d,31oct96,elp  Replaced symAdd() call by symSAdd() call (symtbls synchro).
  42. 01c,22oct96,dbt  Zero out bss section (fixed SPR #7376).
  43. 01c,02oct96,dbt  Added support for SIMSPARCSOLARIS.
  44. 01b,02oct96,dbt  Unknown moduleformats are now correctly managed (SPR #7263).
  45. 01b,03aug96,kkk  throw away __gnu_compiled_c signatures.
  46. 01a,20jun96,dbt  created from /host/src/tgtsvr/server/loadelf.c v01t
  47.  and /host/src/tgtsvr/server/elfppc.c v01e
  48.  and /host/src/tgtsvr/server/elfmips.c v01c
  49. */
  50. /*
  51. DESCRIPTION
  52. This library provides an object module loading facility.  Any SYSV elf
  53. format files may be loaded into memory, relocated properly, their
  54. external references resolved, and their external definitions added to
  55. the system symbol table for use by other modules and from the shell.
  56. Modules may be loaded from any I/O stream.
  57. EXAMPLE
  58. .CS
  59.     fdX = open ("/devX/objFile", O_RDONLY);
  60.     loadModule (fdX, ALL_SYMBOLS);
  61.     close (fdX);
  62. .CE
  63. This code fragment would load the ELF file "objFile" located on
  64. device "/devX/" into memory which would be allocated from the system
  65. memory pool.  All external and static definitions from the file would be
  66. added to the system symbol table.
  67. This could also have been accomplished from the shell, by typing:
  68. .CS
  69.     -> ld (1) </devX/objFile
  70. .CE
  71. INCLUDE FILE: loadElfLib.h
  72. SEE ALSO: loadLib, usrLib, symLib, memLib,
  73. .pG "Basic OS"
  74. */
  75. /* defines */
  76. #undef INCLUDE_SDA /* SDA is not supported for the moment */
  77. #define _CACHE_SUPPORT          /* cache           */
  78. /* includes */
  79. #include "vxWorks.h"
  80. #include "stdio.h"
  81. #include "loadElfLib.h"
  82. #include "elf.h"
  83. #include "elftypes.h"
  84. #include "ioLib.h"
  85. #include "fioLib.h"
  86. #include "bootLoadLib.h"
  87. #include "loadLib.h"
  88. #include "memLib.h"
  89. #include "pathLib.h"
  90. #include "string.h"
  91. #include "symLib.h"
  92. #include "sysSymTbl.h"
  93. #ifdef  _CACHE_SUPPORT
  94. #include "cacheLib.h"
  95. #endif  /* _CACHE_SUPPORT */
  96. #include "errnoLib.h"
  97. #include "stdlib.h"
  98. #include "symbol.h"     /* for SYM_TYPE typedef */
  99. #include "moduleLib.h"
  100. #include "private/vmLibP.h"
  101. #if   ((CPU_FAMILY == MIPS) || (CPU_FAMILY == PPC) || 
  102.        (CPU_FAMILY == SIMSPARCSOLARIS) || (CPU_FAMILY == SH) || 
  103.        (CPU_FAMILY == I80X86) || (CPU_FAMILY == ARM) || 
  104.        (CPU_FAMILY==COLDFIRE))
  105. /* define */
  106. #ifndef EM_ARCH_MACHINE
  107. #define EM_ARCH_MACHINE -1              /* default */
  108. #endif /* EM_ARCH_MACHINE */
  109. #undef DEBUGG
  110. #ifdef DEBUGG
  111. int elfDebug=1;
  112. #define DSMINST(x)
  113. #define DBG(x) if (elfDebug) { printf x; fflush(stdout); }
  114. #else
  115. #define DSMINST(x)
  116. #define DBG(x)
  117. #endif /* DEBUG */
  118. #ifdef _WRS_STRICT_ALIGNMENT
  119. #define ELFOUTMSBU32(b,w) 
  120.   ((b)[0] = (w >> 24), 
  121.    (b)[1] = (w >> 16), 
  122.    (b)[2] = (w >> 8), 
  123.    (b)[3]  = w)
  124. #endif /* _WRS_STRICT_ALIGNMENT */
  125. /* globals */
  126. /* externals */
  127. #ifdef INCLUDE_SDA
  128. IMPORT char SDA_BASE[]; /* Base address of SDA Area */
  129. IMPORT char SDA2_BASE[]; /* Base address of SDA2 Area */
  130. IMPORT int SDA_SIZE; /* size of SDA area */
  131. IMPORT int SDA2_SIZE; /* size of SDA2 area */
  132. #endif /* INCLUDE_SDA */
  133. /* locals */
  134. #ifdef INCLUDE_SDA
  135. LOCAL STATUS moduleElfSegAdd (MODULE_ID moduleId, int type, void * location,
  136.      int length, int flags, PART_ID memPartId);
  137. LOCAL BOOL segElfFindByType (SEGMENT_ID segmentId, MODULE_ID moduleId,
  138.      int type);
  139. #endif /* INCLUDE_SDA */
  140. LOCAL UINT32 loadElfAlignGet (UINT32 alignment, void * pAddrOrSize);
  141. LOCAL BOOL (* pElfModuleVerifyRtn) (UINT32 machType,
  142.     BOOL * sda) = NULL; /* verif rtn ptr */
  143. LOCAL STATUS (* pElfSegRelRtn) (int fd, MODULE_ID moduleId, int loadFlag,
  144.      int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
  145.      Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
  146.      SYM_INFO_TBL symInfoTbl,
  147.         Elf32_Sym * pSymsArray, SYMTAB_ID symTbl,
  148. SEG_INFO * pSeg) = NULL; /* seg reloc rtn ptr */
  149. #if     (CPU_FAMILY == PPC)
  150. LOCAL STATUS elfPpcSegReloc (int fd, MODULE_ID moduleId, int loadFlag,
  151.      int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
  152.      Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
  153.      SYM_INFO_TBL symInfoTbl,
  154. Elf32_Sym *  pSymsArray,
  155.      SYMTAB_ID    symTbl,
  156. SEG_INFO *   pSeg);
  157. LOCAL STATUS elfPpcAddr32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  158. SYM_INFO_TBL symInfoTbl, MODULE_ID moduleId);
  159. LOCAL STATUS elfPpcAddr24Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  160. SYM_INFO_TBL symInfoTbl);
  161. LOCAL STATUS elfPpcAddr16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  162. SYM_INFO_TBL symInfoTbl);
  163. LOCAL STATUS elfPpcAddr16LoReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  164. SYM_INFO_TBL symInfoTbl);
  165. LOCAL STATUS elfPpcAddr16HiReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  166. SYM_INFO_TBL symInfoTbl);
  167. LOCAL STATUS elfPpcAddr16HaReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  168. SYM_INFO_TBL symInfoTbl);
  169. LOCAL STATUS elfPpcAddr14Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  170. SYM_INFO_TBL symInfoTbl);
  171. LOCAL STATUS elfPpcRel24Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  172. SYM_INFO_TBL symInfoTbl);
  173. LOCAL STATUS elfPpcRel14Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  174. SYM_INFO_TBL symInfoTbl);
  175. LOCAL STATUS elfPpcUaddr32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  176. SYM_INFO_TBL symInfoTbl);
  177. LOCAL STATUS elfPpcUaddr16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  178. SYM_INFO_TBL symInfoTbl);
  179. LOCAL STATUS elfPpcRel32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  180. SYM_INFO_TBL symInfoTbl);
  181. LOCAL STATUS elfPpcEmbNaddr32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  182. SYM_INFO_TBL symInfoTbl);
  183. LOCAL STATUS elfPpcEmbNaddr16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  184. SYM_INFO_TBL symInfoTbl);
  185. LOCAL STATUS elfPpcEmbNaddr16LoReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  186. SYM_INFO_TBL symInfoTbl);
  187. LOCAL STATUS elfPpcEmbNaddr16HiReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  188. SYM_INFO_TBL symInfoTbl);
  189. LOCAL STATUS elfPpcEmbNaddr16HaReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  190. SYM_INFO_TBL symInfoTbl);
  191. #ifdef INCLUDE_SDA
  192. LOCAL STATUS elfPpcSdaRel16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  193. SYM_INFO_TBL symInfoTbl, SEG_INFO * pSeg);
  194. LOCAL STATUS elfPpcEmbSda21Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  195. SYM_INFO_TBL symInfoTbl, SEG_INFO * pSeg);
  196. LOCAL STATUS elfPpcEmbSda2RelReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  197. SYM_INFO_TBL symInfoTbl, SEG_INFO * pSeg);
  198. LOCAL STATUS elfPpcEmbRelSdaReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  199. SYM_INFO_TBL symInfoTbl, SEG_INFO * pSeg);
  200. #endif /* INCLUDE_SDA */
  201. #endif     /* CPU_FAMILY == PPC */
  202. #if (CPU_FAMILY == SIMSPARCSOLARIS)
  203. LOCAL STATUS elfSparcSegReloc (int fd, MODULE_ID moduleId, int loadFlag, 
  204.       int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
  205.            Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
  206.            SYM_INFO_TBL symInfoTbl, Elf32_Sym * pSymsArray,
  207.            SYMTAB_ID symTbl, SEG_INFO * pSeg);
  208. LOCAL STATUS elfSparc32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  209. SYM_INFO_TBL symInfoTbl);
  210. LOCAL STATUS elfSparc16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  211. SYM_INFO_TBL symInfoTbl);
  212. LOCAL STATUS elfSparc8Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  213. SYM_INFO_TBL symInfoTbl);
  214. LOCAL STATUS elfSparcDisp32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
  215. SYM_INFO_TBL symInfoTbl);
  216. LOCAL STATUS elfSparcDisp16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  217. SYM_INFO_TBL symInfoTbl);
  218. LOCAL STATUS elfSparcDisp8Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  219. SYM_INFO_TBL symInfoTbl);
  220. LOCAL STATUS elfSparcWDisp30Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  221. SYM_INFO_TBL symInfoTbl);
  222. LOCAL STATUS elfSparcWDisp22Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  223. SYM_INFO_TBL symInfoTbl);
  224. LOCAL STATUS elfSparcHi22Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  225. SYM_INFO_TBL symInfoTbl);
  226. LOCAL STATUS elfSparc22Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  227. SYM_INFO_TBL symInfoTbl);
  228. LOCAL STATUS elfSparc13Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  229. SYM_INFO_TBL symInfoTbl);
  230. LOCAL STATUS elfSparcLo10Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  231. SYM_INFO_TBL symInfoTbl);
  232. LOCAL STATUS elfSparcPc10Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  233. SYM_INFO_TBL symInfoTbl);
  234. LOCAL STATUS elfSparcPc22Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  235. SYM_INFO_TBL symInfoTbl);
  236. LOCAL STATUS elfSparcUa32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  237. SYM_INFO_TBL symInfoTbl);
  238. #endif /* (CPU_FAMILY == SIMSPARCSOLARIS) */
  239. #if  (CPU_FAMILY == COLDFIRE)
  240. LOCAL STATUS elfM68k32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  241.      SYM_INFO_TBL symInfoTbl);
  242. LOCAL STATUS elfM68k16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  243.      SYM_INFO_TBL symInfoTbl);
  244. LOCAL STATUS elfM68kDisp32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  245.  SYM_INFO_TBL symInfoTbl);
  246. LOCAL STATUS elfM68kDisp16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  247.  SYM_INFO_TBL symInfoTbl);
  248. LOCAL STATUS elfM68kSegReloc (int fd, MODULE_ID moduleId, int loadFlag, 
  249.       int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
  250.            Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
  251.            SYM_INFO_TBL symInfoTbl, Elf32_Sym * pSymsArray,
  252.            SYMTAB_ID symTbl, SEG_INFO * pSeg);
  253. #endif  /* (CPU_FAMILY == COLDFIRE) */
  254. #if (CPU_FAMILY == SH)
  255. LOCAL STATUS elfShSegReloc (int fd, MODULE_ID moduleId, int loadFlag,
  256.      int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
  257.      Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
  258.      SYM_INFO_TBL symInfoTbl,
  259. Elf32_Sym *  pSymsArray,
  260.      SYMTAB_ID    symTbl,
  261. SEG_INFO *   pSeg);
  262. LOCAL STATUS elfShDir32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  263. SYM_INFO_TBL symInfoTbl, MODULE_ID moduleId);
  264. #if FALSE /* Relocation types not currently supported. */
  265. LOCAL STATUS elfShRel32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  266. SYM_INFO_TBL symInfoTbl);
  267. LOCAL STATUS elfShDir8wpnReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  268. SYM_INFO_TBL symInfoTbl);
  269. LOCAL STATUS elfShInd12wReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  270. SYM_INFO_TBL symInfoTbl);
  271. LOCAL STATUS elfShDir8wplReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  272. SYM_INFO_TBL symInfoTbl);
  273. LOCAL STATUS elfShDir8bpReloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  274. SYM_INFO_TBL symInfoTbl);
  275. LOCAL STATUS elfShSwitch16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd, 
  276. SYM_INFO_TBL symInfoTbl);
  277. #endif /* relocation types not currently supported. */
  278. #endif /* (CPU_FAMILY == SH) */
  279. LOCAL BOOL  loadElfModuleIsOk (Elf32_Ehdr *pHdr);
  280. LOCAL STATUS  loadElfMdlHdrCheck (Elf32_Ehdr *pHdr);
  281. LOCAL STATUS  loadElfMdlHdrRd (int fd, Elf32_Ehdr *pHdr);
  282. LOCAL STATUS  loadElfProgHdrCheck (Elf32_Phdr *pProgHdr, int progHdrNum);
  283. LOCAL STATUS  loadElfProgHdrTblRd (int fd, int posProgHdrField,
  284.  Elf32_Phdr *pProgHdrTbl, int progHdrNumber);
  285. LOCAL STATUS  loadElfScnHdrCheck (Elf32_Shdr *pScnHdr, int scnHdrNum);
  286. LOCAL STATUS  loadElfScnHdrIdxDispatch (Elf32_Shdr *pScnHdrTbl, int scnHdrIdx,
  287. IDX_TBLS *pIndexTables);
  288. LOCAL STATUS  loadElfScnHdrRd (int fd, int posScnHdrField, 
  289. Elf32_Shdr * pScnHdrTbl,
  290.      int sectionNumber, IDX_TBLS * pIndexTables);
  291. LOCAL void  loadElfSegSizeGet (char * pScnStrTbl, 
  292. UINT32 *pLoadScnHdrIdxs, 
  293. Elf32_Shdr *pScnHdrTbl, SEG_INFO *pSeg);
  294. LOCAL STATUS  loadElfScnRd (int fd, char * pScnStrTbl, 
  295. UINT32 *pLoadScnHdrIdxs, Elf32_Shdr *pScnHdrTbl,
  296. SCN_ADRS_TBL sectionAdrsTbl, SEG_INFO *pSeg);
  297. LOCAL int loadElfSymEntryRd (int fd, int symEntry, Elf32_Sym *pSymbol);
  298. LOCAL STATUS  loadElfSymTabRd (int fd, int nextSym, UINT32 nSyms, 
  299. Elf32_Sym *pSymsArray);
  300. LOCAL int  loadElfSymTablesHandle (UINT32 *pSymTabScnHdrIdxs, 
  301. Elf32_Shdr *pScnHdrTbl, int fd,
  302. SYMTBL_REFS *pSymTblRefs,
  303. SYMINFO_REFS * pSymsAdrsRefs);
  304. LOCAL SYM_TYPE  loadElfSymTypeGet (Elf32_Sym *pSymbol, Elf32_Shdr *pScnHdrTbl, 
  305. char * pScnStrTbl);
  306. LOCAL BOOL  loadElfSymIsVisible (UINT32 symAssoc, UINT32 symBinding, 
  307. int loadFlag);
  308. LOCAL STATUS  loadElfSymTabProcess (MODULE_ID moduleId, int loadFlag, 
  309. Elf32_Sym *pSymsArray, 
  310. SCN_ADRS_TBL sectionAdrsTbl,
  311. SYM_INFO_TBL symsAdrsTbl, char * pStringTable,
  312. SYMTAB_ID symTbl, UINT32 symNumber,
  313. Elf32_Shdr * pScnHdrTbl, char * pScnStrTbl,
  314. SEG_INFO * pSeg);
  315. LOCAL STATUS  loadElfSymTableBuild (MODULE_ID moduleId, int loadFlag,
  316. SYMTBL_REFS  symTblRefs, 
  317. SCN_ADRS_TBL sectionAdrsTbl,
  318. SYMINFO_REFS symsAdrsRefs, 
  319. IDX_TBLS *pIndexTables, SYMTAB_ID symTbl, 
  320. int fd, Elf32_Shdr * pScnHdrTbl,
  321. char * pScnStrTbl, SEG_INFO * pSeg);
  322. LOCAL FUNCPTR  loadElfRelSegRtnGet (void);
  323. LOCAL STATUS  loadElfSegReloc (int fd, int loadFlag, MODULE_ID moduleId, 
  324. Elf32_Ehdr * pHdr, IDX_TBLS *pIndexTables, 
  325. Elf32_Shdr *pScnHdrTbl,
  326.      SCN_ADRS_TBL sectionAdrsTbl, 
  327. SYMTBL_REFS  symTblRefs,
  328. SYMINFO_REFS symsAdrsRefs, SYMTAB_ID symTbl,
  329. SEG_INFO * pSeg);
  330. LOCAL STATUS  loadElfTablesAlloc (Elf32_Ehdr *pHdr, Elf32_Phdr **ppProgHdrTbl,
  331. Elf32_Shdr **ppScnHdrTbl, 
  332. IDX_TBLS *pIndexTables);
  333. LOCAL MODULE_ID loadElfFmtManage (FAST int fd, int loadFlag, void **ppText,
  334.    void **ppData, void **ppBss, SYMTAB_ID symTbl);
  335. LOCAL void  loadElfBufferFree (void ** ppBuf);
  336. LOCAL STATUS  loadElfRelocMod (SEG_INFO * pSeg, int fd, char * pScnStrTbl,
  337. IDX_TBLS * pIndexTables, Elf32_Ehdr * pHdr,
  338.      Elf32_Shdr * pScnHdrTbl,
  339.      SCN_ADRS_TBL * pSectionAdrsTbl);
  340. LOCAL STATUS  loadElfSegStore (SEG_INFO * pSeg, int loadFlag, int fd,
  341. char * pScnStrTbl,
  342.      IDX_TBLS * pIndexTables, Elf32_Ehdr * pHdr,
  343.      Elf32_Shdr * pScnHdrTbl, 
  344. Elf32_Phdr * pProgHdrTbl,
  345.      SCN_ADRS_TBL * pSectionAdrsTbl);
  346. LOCAL char *  loadElfScnStrTblRd (int fd, Elf32_Shdr * pScnHdrTbl, 
  347. Elf32_Ehdr * pHdr);
  348. #ifdef INCLUDE_SDA
  349. LOCAL STATUS  loadElfSdaAllocate (SDA_INFO * pSda);
  350. LOCAL STATUS  loadElfSdaCreate (void);
  351. LOCAL SDA_SCN_TYPE loadElfSdaScnDetermine (char * pScnStrTbl, 
  352. Elf32_Shdr * pScnHdr, char * sectionName);
  353. LOCAL BOOL      sdaIsRequired = FALSE;  /* TRUE if SDA are used by the arch */
  354. LOCAL PART_ID   sdaMemPartId = NULL;    /* keeps SDA memory partition id */
  355. LOCAL PART_ID   sda2MemPartId = NULL;   /* keeps SDA2 memory partition id */
  356. LOCAL void *    sdaBaseAddr = NULL;     /* keeps SDA area base address */
  357. LOCAL void *    sda2BaseAddr = NULL;    /* keeps SDA2 area base address */
  358. LOCAL int      sdaAreaSize = 0;      /* keeps SDA area size */
  359. LOCAL int      sda2AreaSize = 0;      /* keeps SDA area size */
  360. #endif /* INCLUDE_SDA */
  361. /*******************************************************************************
  362. *
  363. * elfRelocRelaEntryRd - read in ELF relocation entry for RELA relocation
  364. * This routine fills a relocation structure with information from the object
  365. * module in memory.
  366. *
  367. * RETURNS : the address of the next relocation entry or ERROR if entry not read.
  368. */
  369. int elfRelocRelaEntryRd
  370.     (
  371.     int   fd, /* file to read in */
  372.     int   posRelocEntry, /* position of reloc. command in object file */
  373.     Elf32_Rela * pReloc /* ptr on relocation structure to fill */
  374.     )
  375.     {
  376.     int nbytes; /* number of bytes to copy */
  377.     nbytes = sizeof (Elf32_Rela);
  378.     if ((ioctl (fd, FIOSEEK, posRelocEntry)) == ERROR)
  379.         return ERROR; 
  380.     if ((fioRead (fd, (char *) pReloc, nbytes)) == ERROR)
  381.         return ERROR;
  382.     return (posRelocEntry + nbytes);
  383.     }
  384.      
  385. /*******************************************************************************
  386. *
  387. * elfRelocRelEntryRd - read in ELF relocation entry for REL relocation
  388. * This routine fills a relocation structure with information from the object
  389. * module in memory. 
  390. *
  391. * RETURNS : the address of the next relocation entry or ERROR if entry not read.
  392. */
  393. int elfRelocRelEntryRd
  394.     (
  395.     int          fd,            /* file to read in */
  396.     int          posRelocEntry, /* position of reloc. command in object file */
  397.     Elf32_Rel *  pReloc /* ptr on relocation structure to fill */
  398.     )
  399.     {
  400.     int nbytes;         /* number of bytes to copy */
  401.     nbytes = sizeof (Elf32_Rel);
  402.     if ((ioctl (fd, FIOSEEK, posRelocEntry)) == ERROR)
  403.         return ERROR; 
  404.     if ((fioRead (fd, (char *) pReloc, nbytes)) == ERROR)
  405.         return ERROR;
  406.     return (posRelocEntry + nbytes);
  407.     }
  408. #if     (CPU_FAMILY == PPC)
  409. /*******************************************************************************
  410. *
  411. * elfPpcSegReloc - perform relocation for the PowerPC family
  412. *
  413. * This routine reads the specified relocation command segment and performs
  414. * all the relocations specified therein. Only relocation command from sections
  415. * with section type SHT_RELA are considered here.
  416. *
  417. * Absolute symbol addresses are looked up in the 'externals' table.
  418. *
  419. * This function handles the following types of relocation commands
  420. * for the PowerPC processor:
  421. *
  422. * System V ABI:
  423. * R_PPC_NONE : none
  424. * R_PPC_ADDR32 : word32, S + A
  425. * R_PPC_ADDR24 : low24, (S + A) >> 2
  426. * R_PPC_ADDR16 : half16, S + A
  427. * R_PPC_ADDR16_LO : half16, #lo(S + A)
  428. * R_PPC_ADDR16_HI : half16, #hi(S + A)
  429. * R_PPC_ADDR16_HA : half16, #ha(S + A)
  430. * R_PPC_ADDR14 : low14, (S + A) >> 2
  431. * R_PPC_ADDR14_BRTAKEN : low14, (S + A) >> 2
  432. * R_PPC_ADDR14_BRNTAKEN : low14, (S + A) >> 2
  433. * R_PPC_REL24 : low24, (S + A - P) >> 2
  434. * R_PPC_REL14 : low14, (S + A - P) >> 2
  435. * R_PPC_REL14_BRTAKEN : low14, (S + A - P) >> 2
  436. * R_PPC_REL14_BRNTAKEN : low14, (S + A - P) >> 2
  437. * R_PPC_UADDR32 : word32, S + A
  438. * R_PPC_UADDR16 : half16, S + A
  439. * R_PPC_REL32 : word32, S + A - P
  440. * R_PPC_SDAREL : half16, S + A - SDA_BASE
  441. *
  442. * PowerPC EABI:
  443. * R_PPC_EMB_NADDR32 : uword32, A - S
  444. * R_PPC_EMB_NADDR16 : uhalf16, A - S
  445. * R_PPC_EMB_NADDR16_LO : uhalf16, #lo(A - S)
  446. * R_PPC_EMB_NADDR16_HI : uhalf16, #hi(A - S)
  447. * R_PPC_EMB_NADDR16_HA : uhalf16, #ha(A - S)
  448. * R_PPC_EMB_MRKREF : none
  449. * R_PPC_EMB_SDA21 : ulow21, complex
  450. * R_PPC_EMB_SDA2REL : uhalf16, S + A - SDA2_BASE
  451. * R_PPC_EMB_RELSDA : uhalf16, complex
  452. *
  453. * RETURNS: OK or ERROR
  454. */
  455. LOCAL STATUS elfPpcSegReloc
  456.     (
  457.     int  fd, /* file to read in */
  458.     MODULE_ID  moduleId, /* module id */
  459.     int  loadFlag, /* not used */
  460.     int    posCurRelocCmd,/* position of current relocation command */
  461.     Elf32_Shdr * pScnHdrTbl, /* not used */
  462.     Elf32_Shdr * pRelHdr, /* pointer to relocation section header */
  463.     SCN_ADRS *  pScnAddr, /* section address once loaded */
  464.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  465.     Elf32_Sym *  pSymsArray, /* pointer to symbols array */
  466.     SYMTAB_ID   symTbl, /* not used */
  467.     SEG_INFO *  pSeg /* section addresses and sizes */
  468.     )
  469.     {
  470.     Elf32_Rela   relocCmd; /* relocation structure */
  471.     UINT32  relocNum; /* number of reloc entries in section */
  472.     UINT32  relocIdx; /* index of the reloc entry being processed */
  473.     void *  pAdrs; /* relocation address */
  474.     Elf32_Sym *  pSym; /* pointer to an external symbol */
  475.     STATUS  status = OK; /* whether or not the relocation was ok */
  476.     /* Some sanity checking */
  477.     if (pRelHdr->sh_type != SHT_RELA)
  478. {
  479.         errnoSet (S_loadElfLib_RELA_SECTION);
  480. return (OK);
  481. }
  482.     if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))
  483. {
  484.         errnoSet (S_loadElfLib_RELA_SECTION);
  485. return (ERROR);
  486. }
  487.     /* Relocation loop */
  488.     relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
  489.     for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
  490. {
  491. /* read relocation command */
  492. if ((posCurRelocCmd = 
  493.      elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd)) == ERROR)
  494.     {
  495.     errnoSet (S_loadElfLib_READ_SECTIONS);
  496.     return (ERROR);
  497.     }
  498. /*
  499.  * Calculate actual remote address that needs relocation, and
  500.  * perform external or section relative relocation.
  501.  */
  502. pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
  503. pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);
  504. /*
  505.  * System V ABI defines the following notations:
  506.  *
  507.  * A - the addend used to compute the value of the relocatable field.
  508.  * S - the value (address) of the symbol whose index resides in the
  509.  *     relocation entry. Note that this function uses the value stored
  510.  *     in the external symbol value array instead of the symbol's
  511.  *     st_value field.
  512.  * P - the place (section offset or address) of the storage unit being
  513.  *     relocated (computed using r_offset) prior to the relocation.
  514.  */
  515.         switch (ELF32_R_TYPE (relocCmd.r_info))
  516.             {
  517.     case (R_PPC_NONE): /* none */
  518. break;
  519.     case (R_PPC_ADDR32): /* word32, S + A */
  520. if (elfPpcAddr32Reloc (pAdrs, &relocCmd, symInfoTbl,
  521.        moduleId) != OK)
  522.     status = ERROR;
  523. break;
  524.     case (R_PPC_ADDR24): /* low24, (S+A) >> 2 */
  525. if (elfPpcAddr24Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  526.     status = ERROR;
  527. break;
  528.     case (R_PPC_ADDR16): /* half16, S + A */
  529. if (elfPpcAddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  530.     status = ERROR;
  531. break;
  532.     case (R_PPC_ADDR16_LO): /* half16, #lo(S + A) */
  533. if (elfPpcAddr16LoReloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  534.     status = ERROR;
  535. break;
  536.     case (R_PPC_ADDR16_HI): /* half16, #hi(S + A) */
  537. if (elfPpcAddr16HiReloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  538.     status = ERROR;
  539. break;
  540.     case (R_PPC_ADDR16_HA): /* half16, #ha(S + A) */
  541. if (elfPpcAddr16HaReloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  542.     status = ERROR;
  543. break;
  544.     case (R_PPC_ADDR14):
  545.     case (R_PPC_ADDR14_BRTAKEN):
  546.     case (R_PPC_ADDR14_BRNTAKEN): /* low14, (S+A) >> 2 */
  547. if (elfPpcAddr14Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  548.     status = ERROR;
  549. break;
  550.     case (R_PPC_REL24): /* low24, (S+A-P) >> 2*/
  551. if (elfPpcRel24Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  552.     status = ERROR;
  553. break;
  554.     case (R_PPC_REL14):
  555.     case (R_PPC_REL14_BRTAKEN):
  556.     case (R_PPC_REL14_BRNTAKEN): /* low14, (S+A-P) >> 2*/
  557. if (elfPpcRel14Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  558.     status = ERROR;
  559. break;
  560.     case (R_PPC_UADDR32): /* word32, S + A */
  561. if (elfPpcUaddr32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  562.     status = ERROR;
  563. break;
  564.     case (R_PPC_UADDR16): /* half16, S + A */
  565. if (elfPpcUaddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  566.     status = ERROR;
  567. break;
  568.     case (R_PPC_REL32): /* word32, S + A - P */
  569. if (elfPpcRel32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  570.     status = ERROR;
  571. break;
  572.     case (R_PPC_EMB_NADDR32): /* uword32, A - S */
  573. if (elfPpcEmbNaddr32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  574.     status = ERROR;
  575. break;
  576.     case (R_PPC_EMB_NADDR16): /* uhalf16, A - S */
  577. if (elfPpcEmbNaddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  578.     status = ERROR;
  579. break;
  580.     case (R_PPC_EMB_NADDR16_LO): /* uhalf16, #lo(A - S)*/
  581. if (elfPpcEmbNaddr16LoReloc (pAdrs, &relocCmd, symInfoTbl) 
  582. != OK)
  583.     status = ERROR;
  584. break;
  585.     case (R_PPC_EMB_NADDR16_HI): /* uhalf16, #hi(A - S)*/
  586. if (elfPpcEmbNaddr16HiReloc (pAdrs, &relocCmd, symInfoTbl) 
  587. != OK)
  588.     status = ERROR;
  589. break;
  590.     case (R_PPC_EMB_NADDR16_HA): /* uhalf16, #ha(A - S)*/
  591. if (elfPpcEmbNaddr16HaReloc (pAdrs, &relocCmd, symInfoTbl) 
  592. != OK)
  593.     status = ERROR;
  594. break;
  595.     case (R_PPC_EMB_MRKREF): /* none */
  596. break;
  597. #ifdef INCLUDE_SDA
  598.     case (R_PPC_SDAREL): /* half16, S + A - SDA_BASE */
  599. if (elfPpcSdaRel16Reloc (pAdrs, &relocCmd, symInfoTbl,
  600.  pSeg) != OK)
  601.     status = ERROR;
  602. break;
  603.     case (R_PPC_EMB_SDA21): /* ulow21, complex ! */
  604. if (elfPpcEmbSda21Reloc (pAdrs, &relocCmd, symInfoTbl,
  605.  pSeg) != OK)
  606.     status = ERROR;
  607. break;
  608.     case (R_PPC_EMB_SDA2REL): /* uhalf16, S + A - SDA2_BASE */
  609. if (elfPpcEmbSda2RelReloc (pAdrs, &relocCmd, symInfoTbl,
  610.    pSeg) != OK)
  611.     status = ERROR;
  612. break;
  613.     case (R_PPC_EMB_RELSDA): /* uhalf16, complex ! */
  614. if (elfPpcEmbRelSdaReloc (pAdrs, &relocCmd, symInfoTbl,
  615.   pSeg) != OK)
  616.     status = ERROR;
  617. break;
  618. #endif /* INCLUDE_SDA */
  619.     default:
  620.          printErr ("Unsupported relocation type %dn",
  621.       ELF32_R_TYPE (relocCmd.r_info));
  622.          status = ERROR;
  623.          break;
  624.     }
  625. }
  626.     return (status);
  627.     }
  628. /*******************************************************************************
  629. *
  630. * elfPpcAddr32Reloc - perform the R_PPC_ADDR32 relocation
  631. * This routine handles the R_PPC_ADDR32 relocation (word32, S + A).
  632. *
  633. * RETURNS : OK or ERROR if computed value can't be written down in target
  634. *     memory.
  635. */
  636. LOCAL STATUS elfPpcAddr32Reloc
  637.     (
  638.     void *  pAdrs, /* relocation address */
  639.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  640.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  641.     MODULE_ID  moduleId /* module id */
  642.     )
  643.     {
  644.     UINT32  value; /* relocation value */
  645.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  646.     pRelocCmd->r_addend;
  647.     *((UINT32 *)pAdrs) = value;
  648.     return (OK);
  649.     }
  650. /*******************************************************************************
  651. *
  652. * elfPpcAddr24Reloc - perform the R_PPC_ADDR24 relocation
  653. * This routine handles the R_PPC_ADDR24 relocation (low24, S + A).
  654. *
  655. * RETURNS : OK or ERROR if computed value can't be written down in target
  656. *     memory or offset too large for relocation.
  657. */
  658. LOCAL STATUS elfPpcAddr24Reloc
  659.     (
  660.     void *  pAdrs, /* relocation address */
  661.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  662.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  663.     )
  664.     {
  665.     UINT32  value; /* relocation value */
  666.     UINT32  offset; /* previous value in memory */
  667.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  668.     pRelocCmd->r_addend;
  669.     /*
  670.      * Do some checking: R_PPC_ADDR24 relocation must fit in
  671.      * 24 bits and lower 2 bits should always be null.
  672.      */
  673.     if (!CHECK_LOW24 (value))
  674. {
  675.         printErr ("Relocation value does not fit in 24 bits.n");
  676. return (ERROR);
  677. }
  678.     if (value & 0x3)
  679.         printErr ("Relocation value's lower 2 bits not zero.n");
  680.     offset = *((UINT32 *)pAdrs); 
  681.     LOW24_INSERT (offset, value);
  682.     *((UINT32 *)pAdrs) = offset;
  683.     return (OK);
  684.     }
  685. /*******************************************************************************
  686. *
  687. * elfPpcAddr16Reloc - perform the R_PPC_ADDR16 relocation
  688. * This routine handles the R_PPC_ADDR16 relocation (half16, S + A).
  689. *
  690. * RETURNS : OK or ERROR if computed value can't be written down in target
  691. *     memory or offset too large for relocation.
  692. */
  693. LOCAL STATUS elfPpcAddr16Reloc
  694.     (
  695.     void *  pAdrs, /* relocation address */
  696.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  697.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  698.     )
  699.     {
  700.     UINT32  value; /* relocation value */
  701.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  702.     pRelocCmd->r_addend;
  703.     /*
  704.      * Do some checking: R_PPC_ADDR16 relocation must fit in
  705.      * 16 bits.
  706.      */
  707.     if (!CHECK_LOW16 (value))
  708. {
  709.         printErr ("Relocation value does not fit in 16 bits.n");
  710. return (ERROR);
  711. }
  712.     *((UINT16 *)pAdrs) = (UINT16) value;
  713.     return (OK);
  714.     }
  715. /*******************************************************************************
  716. *
  717. * elfPpcAddr16LoReloc - perform the R_PPC_ADDR16_LO relocation
  718. * This routine handles the R_PPC_ADDR16_LO relocation (half16, #lo(S + A)).
  719. *
  720. * RETURNS : OK or ERROR if computed value can't be written down in target
  721. *     memory.
  722. */
  723. LOCAL STATUS elfPpcAddr16LoReloc
  724.     (
  725.     void *  pAdrs, /* relocation address */
  726.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  727.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  728.     )
  729.     {
  730.     UINT32  value; /* relocation value */
  731.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  732.     pRelocCmd->r_addend;
  733.     *((UINT16 *)pAdrs) = (UINT16) LO_VALUE (value);
  734.     return (OK);
  735.     }
  736. /*******************************************************************************
  737. *
  738. * elfPpcAddr16HiReloc - perform the R_PPC_ADDR16_HI relocation
  739. * This routine handles the R_PPC_ADDR16_HI relocation (half16, #hi(S + A)).
  740. *
  741. * RETURNS : OK or ERROR if computed value can't be written down in target
  742. *     memory.
  743. */
  744. LOCAL STATUS elfPpcAddr16HiReloc
  745.     (
  746.     void *  pAdrs, /* relocation address */
  747.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  748.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  749.     )
  750.     {
  751.     UINT32  value; /* relocation value */
  752.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  753.     pRelocCmd->r_addend;
  754.     *((UINT16 *)pAdrs) = (UINT16) (HI_VALUE (value));
  755.     return (OK);
  756.     }
  757. /*******************************************************************************
  758. *
  759. * elfPpcAddr16HaReloc - perform the R_PPC_ADDR16_HA relocation
  760. * This routine handles the R_PPC_ADDR16_HA relocation (half16, #ha(S + A)).
  761. *
  762. * RETURNS : OK or ERROR if computed value can't be written down in target
  763. *     memory.
  764. */
  765. LOCAL STATUS elfPpcAddr16HaReloc
  766.     (
  767.     void *  pAdrs, /* relocation address */
  768.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  769.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  770.     )
  771.     {
  772.     UINT32  value; /* relocation value */
  773.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  774.     pRelocCmd->r_addend;
  775.     *((UINT16 *)pAdrs) = (UINT16) HA_VALUE (value);
  776.     return (OK);
  777.     }
  778. /*******************************************************************************
  779. *
  780. * elfPpcAddr14Reloc - perform the R_PPC_ADDR14 relocation
  781. * This routine handles the R_PPC_ADDR14 relocation (low14, (S + A) >> 2).
  782. *
  783. * RETURNS : OK or ERROR if computed value can't be written down in target
  784. *     memory or offset too large for relocation.
  785. */
  786. LOCAL STATUS elfPpcAddr14Reloc
  787.     (
  788.     void *  pAdrs, /* relocation address */
  789.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  790.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  791.     )
  792.     {
  793.     UINT32  value; /* relocation value */
  794.     UINT32  offset; /* previous value in memory */
  795.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  796.      pRelocCmd->r_addend;
  797.     /*
  798.      * Do some checking: R_PPC_ADDR14* relocations must fit in
  799.      * 14 bits and lower 2 bits should always be null.
  800.      */
  801.     if (!CHECK_LOW14 (value))
  802. {
  803.         printErr ("Relocation value does not fit in 14 bits.n");
  804. return (ERROR);
  805. }
  806.     if (value & 0x3)
  807.         printErr ("Relocation value's lower 2 bits not zero.n");
  808.     offset = *((UINT32 *)pAdrs);
  809.     LOW14_INSERT (offset, value);
  810.     *((UINT32 *)pAdrs) = offset;
  811.     return (OK);
  812.     }
  813. /*******************************************************************************
  814. *
  815. * elfPpcRel24Reloc - perform the R_PPC_REL24 relocation
  816. * This routine handles the R_PPC_REL24 relocation (low24, (S + A - P) >> 2).
  817. *
  818. * RETURNS : OK or ERROR if computed value can't be written down in target
  819. *     memory or offset too large for relocation.
  820. */
  821. LOCAL STATUS elfPpcRel24Reloc
  822.     (
  823.     void *  pAdrs, /* relocation address */
  824.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  825.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  826.     )
  827.     {
  828.     UINT32  value; /* relocation value */
  829.     UINT32  offset; /* previous value in memory */
  830.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  831.     pRelocCmd->r_addend - ((UINT32) pAdrs);
  832.     /*
  833.      * Do some checking: R_PPC_REL24 relocation must fit in
  834.      * 24 bits and lower 2 bits should always be null.
  835.      */
  836.     if (!CHECK_LOW24 (value))
  837. {
  838.         printErr ("Relocation value does not fit in 24 bits.n");
  839. return (ERROR);
  840. }
  841.     if (value & 0x3)
  842. printErr ("Relocation value's lower 2 bits not zero.n");
  843.     offset = *((UINT32 *)pAdrs);
  844.     LOW24_INSERT (offset, value);
  845.     *((UINT32 *)pAdrs) = offset;
  846.     return (OK);
  847.     }
  848. /*******************************************************************************
  849. *
  850. * elfPpcRel14Reloc - perform the R_PPC_REL14 relocation
  851. * This routine handles the R_PPC_REL14 relocation (low14, (S + A - P) >> 2).
  852. *
  853. * RETURNS : OK or ERROR if computed value can't be written down in target
  854. *     memory or offset too large for relocation.
  855. */
  856. LOCAL STATUS elfPpcRel14Reloc
  857.     (
  858.     void *  pAdrs, /* relocation address */
  859.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  860.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  861.     )
  862.     {
  863.     UINT32  value; /* relocation value */
  864.     UINT32  offset; /* previous value in memory */
  865.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  866.     pRelocCmd->r_addend - ((UINT32) pAdrs);
  867.     /*
  868.      * Do some checking: R_PPC_REL14* relocations must fit in
  869.      * 14 bits and lower 2 bits should always be null.
  870.      */
  871.     if (!CHECK_LOW14 (value))
  872. {
  873.         printErr ("Relocation value does not fit in 14 bits.n");
  874. return (ERROR);
  875. }
  876.     if (value & 0x3)
  877.         printErr ("Relocation value's lower 2 bits not zero.n");
  878.     offset = *((UINT32 *)pAdrs);
  879.     LOW14_INSERT (offset, value);
  880.     *((UINT32 *)pAdrs) = offset;
  881.     return (OK);
  882.     }
  883. /*******************************************************************************
  884. *
  885. * elfPpcUaddr32Reloc - perform the R_PPC_UADDR32 relocation
  886. * This routine handles the R_PPC_UADDR32 relocation (word32, S + A).
  887. *
  888. * RETURNS : OK or ERROR if computed value can't be written down in target
  889. *     memory.
  890. */
  891. LOCAL STATUS elfPpcUaddr32Reloc
  892.     (
  893.     void *  pAdrs, /* relocation address */
  894.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  895.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  896.     )
  897.     {
  898.     UINT32  value; /* relocation value */
  899.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  900.     pRelocCmd->r_addend;
  901. #ifdef  _WRS_STRICT_ALIGNMENT
  902.     ELFOUTMSBU32 ((char *)pAdrs, value);
  903. #else
  904.     *((UINT32 *)pAdrs) = value;
  905. #endif /* _WRS_STRICT_ALIGNMENT */
  906.     return (OK);
  907.     }
  908. /*******************************************************************************
  909. *
  910. * elfPpcUaddr16Reloc - perform the R_PPC_UADDR16 relocation
  911. * This routine handles the R_PPC_UADDR16 relocation (half16, S + A).
  912. *
  913. * RETURNS : OK or ERROR if computed value can't be written down in target
  914. *     memory or offset too large for relocation.
  915. */
  916. LOCAL STATUS elfPpcUaddr16Reloc
  917.     (
  918.     void *  pAdrs, /* relocation address */
  919.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  920.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  921.     )
  922.     {
  923.     UINT32  value; /* relocation value */
  924.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  925.     pRelocCmd->r_addend;
  926.     /*
  927.      * Do some checking: R_PPC_UADDR16 relocation must fit in
  928.      * 16 bits.
  929.      */
  930.     if (!CHECK_LOW16 (value))
  931. {
  932.         printErr ("Relocation value does not fit in 16 bits.n");
  933. return (ERROR);
  934. }
  935.     /* handle unalignment */
  936.     
  937.     *((UINT16 *)pAdrs) = (UINT16) value;
  938.     return (OK);
  939.     }
  940. /*******************************************************************************
  941. *
  942. * elfPpcRel32Reloc - perform the R_PPC_REL32 relocation
  943. * This routine handles the R_PPC_REL32 relocation (word32, S + A - P).
  944. *
  945. * RETURNS : OK or ERROR if computed value can't be written down in target
  946. *     memory.
  947. */
  948. LOCAL STATUS elfPpcRel32Reloc
  949.     (
  950.     void *  pAdrs, /* relocation address */
  951.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  952.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  953.     )
  954.     {
  955.     UINT32  value; /* relocation value */
  956.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  957.     pRelocCmd->r_addend - ((UINT32) pAdrs);
  958.     *((UINT32 *)pAdrs) = value;
  959.     return (OK);
  960.     }
  961. /*******************************************************************************
  962. *
  963. * elfPpcEmbNaddr32Reloc - perform the R_PPC_EMB_NADDR32 relocation
  964. * This routine handles the R_PPC_EMB_NADDR32 relocation (uword32, A - S).
  965. *
  966. * RETURNS : OK or ERROR if computed value can't be written down in target
  967. *     memory.
  968. */
  969. LOCAL STATUS elfPpcEmbNaddr32Reloc
  970.     (
  971.     void *  pAdrs, /* relocation address */
  972.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  973.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  974.     )
  975.     {
  976.     UINT32  value; /* relocation value */
  977.     value = pRelocCmd->r_addend -
  978.     (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
  979.     *((UINT32 *)pAdrs) = value;
  980.     return (OK);
  981.     }
  982. /*******************************************************************************
  983. *
  984. * elfPpcEmbNaddr16Reloc - perform the R_PPC_EMB_NADDR16 relocation
  985. * This routine handles the R_PPC_EMB_NADDR16 relocation (uhalf16, A - S).
  986. *
  987. * RETURNS : OK or ERROR if computed value can't be written down in target
  988. *     memory or offset too large for relocation.
  989. */
  990. LOCAL STATUS elfPpcEmbNaddr16Reloc
  991.     (
  992.     void *  pAdrs, /* relocation address */
  993.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  994.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  995.     )
  996.     {
  997.     UINT32  value; /* relocation value */
  998.     value = pRelocCmd->r_addend -
  999.     (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
  1000.     /*
  1001.      * Do some checking: R_PPC_EMB_NADDR16 relocation must fit in
  1002.      * 16 bits.
  1003.      */
  1004.     if (!CHECK_LOW16 (value))
  1005. {
  1006.         printErr ("Relocation value does not fit in 16 bits.n");
  1007. return (ERROR);
  1008. }
  1009.     *((UINT16 *)pAdrs) = (UINT16) value;
  1010.     return (OK);
  1011.     }
  1012. /*******************************************************************************
  1013. *
  1014. * elfPpcEmbNaddr16LoReloc - perform the R_PPC_EMB_NADDR16_LO relocation
  1015. * This routine handles the R_PPC_EMB_NADDR16_LO relocation (uhalf16,
  1016. * #lo (A - S)).
  1017. *
  1018. * RETURNS : OK or ERROR if computed value can't be written down in target
  1019. *     memory.
  1020. */
  1021. LOCAL STATUS elfPpcEmbNaddr16LoReloc
  1022.     (
  1023.     void *  pAdrs, /* relocation address */
  1024.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1025.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  1026.     )
  1027.     {
  1028.     UINT32  value; /* relocation value */
  1029.     value = pRelocCmd->r_addend -
  1030.     (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
  1031.     *((UINT16 *)pAdrs) = (UINT16) LO_VALUE (value);
  1032.     return (OK);
  1033.     }
  1034. /*******************************************************************************
  1035. *
  1036. * elfPpcEmbNaddr16HiReloc - perform the R_PPC_EMB_NADDR16_HI relocation
  1037. * This routine handles the R_PPC_EMB_NADDR16_HI relocation (uhalf16,
  1038. * #hi (A - S)).
  1039. *
  1040. * RETURNS : OK or ERROR if computed value can't be written down in target
  1041. *     memory.
  1042. */
  1043. LOCAL STATUS elfPpcEmbNaddr16HiReloc
  1044.     (
  1045.     void *  pAdrs, /* relocation address */
  1046.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1047.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  1048.     )
  1049.     {
  1050.     UINT32  value; /* relocation value */
  1051.     value = pRelocCmd->r_addend -
  1052.     (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
  1053.     *((UINT16 *)pAdrs) = (UINT16) HI_VALUE (value);
  1054.     return (OK);
  1055.     }
  1056. /*******************************************************************************
  1057. *
  1058. * elfPpcEmbNaddr16HaReloc - perform the R_PPC_EMB_NADDR16_HA relocation
  1059. * This routine handles the R_PPC_EMB_NADDR16_HA relocation (uhalf16,
  1060. * #ha (A - S)).
  1061. *
  1062. * RETURNS : OK or ERROR if computed value can't be written down in target
  1063. *     memory.
  1064. */
  1065. LOCAL STATUS elfPpcEmbNaddr16HaReloc
  1066.     (
  1067.     void *  pAdrs, /* relocation address */
  1068.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1069.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
  1070.     )
  1071.     {
  1072.     UINT32  value; /* relocation value */
  1073.     value = pRelocCmd->r_addend -
  1074.     (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
  1075.     *((UINT16 *)pAdrs) = (UINT16) HA_VALUE (value);
  1076.     return (OK);
  1077.     }
  1078. #ifdef INCLUDE_SDA
  1079. /*******************************************************************************
  1080. *
  1081. * elfPpcSdaRel16Reloc - perform the R_PPC_SDAREL relocation
  1082. * This routine handles the R_PPC_SDAREL relocation (half16, S + A - SDA_BASE).
  1083. *
  1084. * RETURNS : OK or ERROR if computed value can't be written down in target
  1085. *     memory or offset too large for relocation.
  1086. */
  1087. LOCAL STATUS elfPpcSdaRel16Reloc
  1088.     (
  1089.     void *  pAdrs, /* relocation address */
  1090.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1091.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  1092.     SEG_INFO *  pSeg /* section addresses and sizes */
  1093.     )
  1094.     {
  1095.     UINT32  value; /* relocation value */
  1096.     if ((symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA) 
  1097. != SYM_SDA)
  1098. {
  1099.         printErr ("Referenced symbol does not belong to SDA.n");
  1100. return (ERROR);
  1101. }
  1102.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1103.     pRelocCmd->r_addend -
  1104.     (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);
  1105.     /*
  1106.      * Do some checking: R_PPC_SDAREL relocation must fit in
  1107.      * 16 bits.
  1108.      */
  1109.     if (!CHECK_LOW16 (value))
  1110. {
  1111.         printErr ("Relocation value does not fit in 16 bits.n");
  1112. return (ERROR);
  1113. }
  1114.     /* handle unalignment */
  1115.     *((UINT16 *)pAdrs) = (UINT16) value;
  1116.     return (OK);
  1117.     }
  1118. /*******************************************************************************
  1119. *
  1120. * elfPpcEmbSda21Reloc - perform the R_PPC_EMB_SDA21 relocation
  1121. * This routine handles the R_PPC_EMB_SDA21 relocation. The most significant 11
  1122. * bits of the address pointed to by the relocation entry are untouched (opcode
  1123. * and rS/rD field). The next most significant 5 bits (rA field) will hold the
  1124. * value 13 (SDA symbol) or 2 (SDA2 symbol). The least significant 16 bits are
  1125. * set to the two's complement of the following computation:
  1126. *     symbol address + r_addend value - SDA_BASE (or SDA2_BASE) value.
  1127. *
  1128. * RETURNS : OK or ERROR if computed value can't be written down in target
  1129. *     memory.
  1130. */
  1131. LOCAL STATUS elfPpcEmbSda21Reloc
  1132.     (
  1133.     void *  pAdrs, /* relocation address */
  1134.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1135.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  1136.     SEG_INFO *  pSeg /* section addresses and sizes */
  1137.     )
  1138.     {
  1139.     UINT32  value; /* relocation value */
  1140.     UINT32  instr; /* previous instruction in memory */
  1141.     BOOL  symbolIsInSda; /* TRUE if symbol belongs to the SDA area */
  1142.     BOOL  sizeFit; /* TRUE if computed value is 16 bit long */
  1143.     /*
  1144.      * Only symbols (or reference to) belonging to a .sdata, .sbss, .sdata2
  1145.      * or .sbss2 section are supported.
  1146.      */
  1147.     switch (symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA_MASK)
  1148. {
  1149. case (SYM_SDA):
  1150.     symbolIsInSda = TRUE;
  1151.     break;
  1152. case (SYM_SDA2):
  1153.     symbolIsInSda = FALSE;
  1154.     break;
  1155. default:
  1156.     printErr ("Referenced symbol does not belong to SDA/SDA2.n");
  1157.     return (ERROR);
  1158.     break;
  1159. }
  1160.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1161.     pRelocCmd->r_addend;
  1162.     instr = *((UINT32 *)pAdrs);
  1163.     /*
  1164.      * We applied here the same relocation process as the GNU does since
  1165.      * the EABI document is totally phony on this one...
  1166.      */
  1167.     if (symbolIsInSda)
  1168. {
  1169. value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);
  1170. sizeFit = CHECK_LOW16_STRICT (value);
  1171. value = (instr & ~RA_MSK) | GPR13_MSK | ((~value + 1) & 0xffff);
  1172. }
  1173.     else
  1174. {
  1175. value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);
  1176. sizeFit = CHECK_LOW16_STRICT (value);
  1177. value = (instr & ~RA_MSK) | GPR2_MSK | ((~value + 1) & 0xffff);
  1178. }
  1179.     /*
  1180.      * Do some checking: R_PPC_EMB_SDA21 relocation must fit in
  1181.      * 21 bits, thus the offset must fit in 16 bits.
  1182.      */
  1183.     if (!sizeFit)
  1184. {
  1185.         printErr ("Relocation offset does not fit in 16 bits.n");
  1186. return (ERROR);
  1187. }
  1188.     *((UINT32 *)pAdrs) = value;
  1189.     return (OK);
  1190.     }
  1191. /*******************************************************************************
  1192. *
  1193. * elfPpcEmbSda2RelReloc - perform the R_PPC_EMB_SDA2REL relocation
  1194. * This routine handles the R_PPC_EMB_SDA2REL relocation (uhalf16,
  1195. * S + A - SDA2_BASE).
  1196. *
  1197. * RETURNS : OK or ERROR if computed value can't be written down in target
  1198. *     memory.
  1199. */
  1200. LOCAL STATUS elfPpcEmbSda2RelReloc
  1201.     (
  1202.     void *  pAdrs, /* relocation address */
  1203.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1204.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  1205.     SEG_INFO *  pSeg /* section addresses and sizes */
  1206.     )
  1207.     {
  1208.     UINT32  value; /* relocation value */
  1209.     if ((symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA2)
  1210. != SYM_SDA2)
  1211. {
  1212.         printErr ("Referenced symbol does not belong to SDA2.n");
  1213. return (ERROR);
  1214. }
  1215.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1216.     pRelocCmd->r_addend -
  1217.     (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);
  1218.     *((UINT16 *)pAdrs) = (UINT16) value;
  1219.     return (OK);
  1220.     }
  1221. /*******************************************************************************
  1222. *
  1223. * elfPpcEmbRelSdaReloc - perform the R_PPC_EMB_RELSDA relocation
  1224. * This routine handles the R_PPC_EMB_RELSDA relocation.
  1225. *
  1226. * RETURNS : OK or ERROR if computed value can't be written down in target
  1227. *     memory.
  1228. */
  1229. LOCAL STATUS elfPpcEmbRelSdaReloc
  1230.     (
  1231.     void *  pAdrs, /* relocation address */
  1232.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1233.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  1234.     SEG_INFO *  pSeg /* section addresses and sizes */
  1235.     )
  1236.     {
  1237.     UINT32  value; /* relocation value */
  1238.     BOOL  symbolIsInSda; /* TRUE if symbol belongs to the SDA area */
  1239.     /*
  1240.      * Only symbols (or reference to) belonging to a .sdata, .sbss, .sdata2
  1241.      * or .sbss2 section are supported.
  1242.      */
  1243.     switch (symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA_MASK)
  1244. {
  1245. case (SYM_SDA):
  1246.     symbolIsInSda = TRUE;
  1247.     break;
  1248. case (SYM_SDA2):
  1249.     symbolIsInSda = FALSE;
  1250.     break;
  1251. default:
  1252.     printErr ("Referenced symbol does not belong to SDA/SDA2.n");
  1253.     return (ERROR);
  1254.     break;
  1255. }
  1256.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1257.     pRelocCmd->r_addend;
  1258.     if (symbolIsInSda)
  1259. value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);
  1260.     else
  1261. value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);
  1262.     /*
  1263.      * Do some checking: R_PPC_EMB_RELSDA relocation must fit in
  1264.      * 16 bits.
  1265.      */
  1266.     if (!CHECK_LOW16 (value))
  1267. {
  1268.         printErr ("Relocation value does not fit in 16 bits.n");
  1269. return (ERROR);
  1270. }
  1271.     *((UINT16 *)pAdrs) = (UINT16) value;
  1272.     return (OK);
  1273.     }
  1274. #endif  /* INCLUDE_SDA */ 
  1275. #endif  /* CPU_FAMILY == PPC */
  1276. #if (CPU_FAMILY == SIMSPARCSOLARIS)
  1277. /*******************************************************************************
  1278. *
  1279. * elfSparcSegReloc - perform relocation for the PowerPC family
  1280. *
  1281. * This routine reads the specified relocation command segment and performs
  1282. * all the relocations specified therein. Only relocation command from sections
  1283. * with section type SHT_RELA are considered here.
  1284. *
  1285. * Absolute symbol addresses are looked up in the 'externals' table.
  1286. *
  1287. * RETURNS: OK or ERROR
  1288. */
  1289. STATUS elfSparcSegReloc
  1290.     (
  1291.     int  fd, /* file to read in */
  1292.     MODULE_ID  moduleId, /* module id */
  1293.     int  loadFlag, /* not used */
  1294.     int  posCurRelocCmd,/* position of current relocation command */
  1295.     Elf32_Shdr * pScnHdrTbl, /* pointer to section header table */
  1296.     Elf32_Shdr * pRelHdr, /* pointer to relocation section header */
  1297.     SCN_ADRS *  pScnAddr, /* section address once loaded */
  1298.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  1299.     Elf32_Sym *  pSymsArray, /* pointer to symbols array */
  1300.     SYMTAB_ID   symTbl, /* not used */
  1301.     SEG_INFO *  pSeg /* section addresses and sizes */
  1302.     )
  1303.     {
  1304.     Elf32_Shdr * pScnHdr; /* section to which the relocations apply */
  1305.     Elf32_Rela   relocCmd; /* relocation structure */
  1306.     UINT32  relocNum; /* number of reloc entries in section */
  1307.     UINT32  relocIdx; /* index of the reloc entry being processed */
  1308.     void *  pAdrs; /* relocation address */
  1309.     Elf32_Sym *  pSym; /* pointer to an external symbol */
  1310.     STATUS  status = OK; /* whether or not the relocation was ok */
  1311.     pScnHdr = pScnHdrTbl + pRelHdr->sh_info;
  1312.     /* Some sanity checking */
  1313.     if (pRelHdr->sh_type != SHT_RELA)
  1314. {
  1315. errnoSet (S_loadElfLib_RELA_SECTION);
  1316. printErr ("Relocation sections of type %d are not supported.n",
  1317.      pRelHdr->sh_type);
  1318. return (OK);
  1319. }
  1320.     if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))
  1321. {
  1322. printErr ("Wrong relocation entry size.n");
  1323. errnoSet (S_loadElfLib_RELA_SECTION);
  1324. return (ERROR);
  1325. }
  1326.     /* Relocation loop */
  1327.     relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
  1328.     for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
  1329. {
  1330. /* read relocation command */
  1331. if ((posCurRelocCmd = 
  1332.      elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd)) == ERROR)
  1333.     {
  1334.     errnoSet (S_loadElfLib_READ_SECTIONS);
  1335.     return (ERROR);
  1336.     }
  1337. /*
  1338.  * Calculate actual remote address that needs relocation, and
  1339.  * perform external or section relative relocation.
  1340.  */
  1341. pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
  1342. pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);
  1343. /*
  1344.  * System V ABI defines the following notations:
  1345.  *
  1346.  * A - the addend used to compute the value of the relocatable field.
  1347.  * S - the value (address) of the symbol whose index resides in the
  1348.  *     relocation entry. Note that this function uses the value stored
  1349.  *     in the external symbol value array instead of the symbol's
  1350.  *     st_value field.
  1351.  * P - the place (section offset or address) of the storage unit being
  1352.  *     relocated (computed using r_offset) prior to the relocation.
  1353.  */
  1354.         switch (ELF32_R_TYPE (relocCmd.r_info))
  1355.             {
  1356.     case (R_SPARC_8):
  1357. if (elfSparc8Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1358.     status = ERROR;
  1359. break;
  1360.     case (R_SPARC_16):
  1361. if (elfSparc16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1362.     status = ERROR;
  1363. break;
  1364.     case (R_SPARC_32):
  1365. if (elfSparc32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1366.     status = ERROR;
  1367. break;
  1368.     case (R_SPARC_DISP8):
  1369. if (elfSparcDisp8Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)
  1370.     status = ERROR;
  1371. break;
  1372.     case (R_SPARC_DISP16):
  1373. if (elfSparcDisp16Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)
  1374.     status = ERROR;
  1375. break;
  1376.     case (R_SPARC_DISP32):
  1377. if (elfSparcDisp32Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)
  1378.     status = ERROR;
  1379. break;
  1380.     case (R_SPARC_WDISP30):
  1381. if (elfSparcWDisp30Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1382.     status = ERROR;
  1383. break;
  1384.     case (R_SPARC_WDISP22):
  1385. if (elfSparcWDisp22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1386.     status = ERROR;
  1387. break;
  1388.     case (R_SPARC_HI22):
  1389. if (elfSparcHi22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1390.     status = ERROR;
  1391. break;
  1392.     case (R_SPARC_22):
  1393. if (elfSparc22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1394.     status = ERROR;
  1395. break;
  1396.     case (R_SPARC_13):
  1397. if (elfSparc13Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1398.     status = ERROR;
  1399. break;
  1400.     case (R_SPARC_LO10):
  1401. if (elfSparcLo10Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1402.     status = ERROR;
  1403. break;
  1404.     case (R_SPARC_PC10):
  1405. if (elfSparcPc10Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1406.     status = ERROR;
  1407. break;
  1408.     case (R_SPARC_PC22):
  1409. if (elfSparcPc22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1410.     status = ERROR;
  1411. break;
  1412.     case (R_SPARC_UA32):
  1413.     case (R_SPARC_GLOB_DAT):
  1414. if (elfSparcUa32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1415.     status = ERROR;
  1416. break;
  1417.     default:
  1418.          printErr ("Unsupported relocation type %dn",
  1419.     ELF32_R_TYPE (relocCmd.r_info));
  1420.          status = ERROR;
  1421.          break;
  1422.     }
  1423. }
  1424.     return (status);
  1425.     }
  1426. /*******************************************************************************
  1427. *
  1428. * elfSparcAddr32Reloc - perform the R_PPC_ADDR32 relocation
  1429. * This routine handles the R_PPC_ADDR32 relocation (word32, S + A).
  1430. *
  1431. * RETURNS : OK or ERROR if computed value can't be written down in target
  1432. *     memory.
  1433. */
  1434. LOCAL STATUS elfSparc32Reloc
  1435.     (
  1436.     void *  pAdrs, /* relocation address */
  1437.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1438.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1439.     )
  1440.     {
  1441.     UINT32  value; /* relocation value */
  1442.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1443.     pRelocCmd->r_addend;
  1444.     *((UINT32 *)pAdrs) = value;
  1445.     return (OK);
  1446.     }
  1447. /*******************************************************************************
  1448. *
  1449. * elfSparcAddr24Reloc - perform the R_PPC_ADDR24 relocation
  1450. * This routine handles the R_PPC_ADDR24 relocation (low24, S + A).
  1451. *
  1452. * RETURNS : OK or ERROR if computed value can't be written down in target
  1453. *     memory.
  1454. */
  1455. LOCAL STATUS elfSparc16Reloc
  1456.     (
  1457.     void *  pAdrs, /* relocation address */
  1458.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1459.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1460.     )
  1461.     {
  1462.     UINT32  value; /* relocation value */
  1463.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1464.     pRelocCmd->r_addend;
  1465.     *((UINT16 *)pAdrs) = (UINT16) value;
  1466.     return (OK);
  1467.     }
  1468. /*******************************************************************************
  1469. *
  1470. * elfSparcAddr8Reloc - perform the R_PPC_ADDR16 relocation
  1471. * This routine handles the R_PPC_ADDR16 relocation (half16, S + A).
  1472. *
  1473. * RETURNS : OK or ERROR if computed value can't be written down in target
  1474. *     memory.
  1475. */
  1476. LOCAL STATUS elfSparc8Reloc
  1477.     (
  1478.     void *  pAdrs, /* relocation address */
  1479.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1480.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1481.     )
  1482.     {
  1483.     UINT32  value; /* relocation value */
  1484.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1485.     pRelocCmd->r_addend;
  1486.     *((UINT8 *)pAdrs) = (UINT8) value;
  1487.     return (OK);
  1488.     }
  1489. /*******************************************************************************
  1490. *
  1491. * elfSparcAddr16LoReloc - perform the R_PPC_ADDR16_LO relocation
  1492. * This routine handles the R_PPC_ADDR16_LO relocation (half16, #lo(S + A)).
  1493. *
  1494. * RETURNS : OK or ERROR if computed value can't be written down in target
  1495. *     memory.
  1496. */
  1497. LOCAL STATUS elfSparcDisp32Reloc
  1498.     (
  1499.     void *  pAdrs, /* relocation address */
  1500.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1501.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1502.     )
  1503.     {
  1504.     UINT32  value; /* relocation value */
  1505.     UINT32  tmpVal; /* holds temporary calculation results */
  1506.     value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1507.     pRelocCmd->r_addend - ((UINT32) pAdrs);
  1508.     *((UINT32 *)pAdrs) = value;
  1509.     return (OK);
  1510.     }
  1511. /*******************************************************************************
  1512. *
  1513. * elfSparcAddr16HiReloc - perform the R_PPC_ADDR16_HI relocation
  1514. * This routine handles the R_PPC_ADDR16_HI relocation (half16, #hi(S + A)).
  1515. *
  1516. * RETURNS : OK or ERROR if computed value can't be written down in target
  1517. *     memory.
  1518. */
  1519. LOCAL STATUS elfSparcDisp16Reloc
  1520.     (
  1521.     void *  pAdrs, /* relocation address */
  1522.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1523.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1524.     )
  1525.     {
  1526.     UINT32  value; /* relocation value */
  1527.     value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1528.     pRelocCmd->r_addend - ((UINT32) pAdrs);
  1529.     *((UINT32 *)pAdrs) = value;
  1530.     return (OK);
  1531.     }
  1532. /*******************************************************************************
  1533. *
  1534. * elfSparcAddr16HaReloc - perform the R_PPC_ADDR16_HA relocation
  1535. * This routine handles the R_PPC_ADDR16_HA relocation (half16, #ha(S + A)).
  1536. *
  1537. * RETURNS : OK or ERROR if computed value can't be written down in target
  1538. *     memory.
  1539. */
  1540. LOCAL STATUS elfSparcDisp8Reloc
  1541.     (
  1542.     void *  pAdrs, /* relocation address */
  1543.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1544.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1545.     )
  1546.     {
  1547.     UINT32  value; /* relocation value */
  1548.     value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1549.     pRelocCmd->r_addend - ((UINT32) pAdrs);
  1550.     *((UINT32 *)pAdrs) = value;
  1551.     return (OK);
  1552.     }
  1553. /*******************************************************************************
  1554. *
  1555. * elfSparcAddr14Reloc - perform the R_PPC_ADDR14 relocation
  1556. * This routine handles the R_PPC_ADDR14 relocation (low14, (S + A) >> 2).
  1557. *
  1558. * RETURNS : OK or ERROR if computed value can't be written down in target
  1559. *     memory.
  1560. */
  1561. LOCAL STATUS elfSparcWDisp30Reloc
  1562.     (
  1563.     void *  pAdrs, /* relocation address */
  1564.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1565.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1566.     )
  1567.     {
  1568.     unsigned int value, tmpVal;
  1569.     value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1570.             pRelocCmd->r_addend - ((UINT32)pAdrs))>>2;
  1571.     tmpVal = *((UINT32 *) pAdrs);
  1572.     tmpVal &= (unsigned int)0xc0000000;
  1573.     tmpVal |= (unsigned int)value;
  1574.     *((UINT32 *)pAdrs) = (UINT32) tmpVal;
  1575.     return (OK);
  1576.     }
  1577. /*******************************************************************************
  1578. *
  1579. * elfSparcRel24Reloc - perform the R_PPC_REL24 relocation
  1580. * This routine handles the R_PPC_REL24 relocation (low24, (S + A - P) >> 2).
  1581. *
  1582. * RETURNS : OK or ERROR if computed value can't be written down in target
  1583. *     memory.
  1584. */
  1585. LOCAL STATUS elfSparcWDisp22Reloc
  1586.     (
  1587.     void *  pAdrs, /* relocation address */
  1588.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1589.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1590.     )
  1591.     {
  1592.     unsigned int value, tmpVal;
  1593.     value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1594.             pRelocCmd->r_addend - ((UINT32)pAdrs))>>2;
  1595.     tmpVal = *((UINT32 *) pAdrs);
  1596.     tmpVal &= (unsigned int)0xffc00000;
  1597.     tmpVal |= (unsigned int)value;
  1598.     *((UINT32 *)pAdrs) = (UINT32) tmpVal;
  1599.     return (OK);
  1600.     }
  1601. /*******************************************************************************
  1602. *
  1603. * elfSparcRel14Reloc - perform the R_PPC_REL14 relocation
  1604. * This routine handles the R_PPC_REL14 relocation (low14, (S + A - P) >> 2).
  1605. *
  1606. * RETURNS : OK or ERROR if computed value can't be written down in target
  1607. *     memory.
  1608. */
  1609. LOCAL STATUS elfSparcHi22Reloc
  1610.     (
  1611.     void *  pAdrs, /* relocation address */
  1612.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1613.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1614.     )
  1615.     {
  1616.     unsigned int value, tmpVal;
  1617.     value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1618.             pRelocCmd->r_addend)>>10;
  1619.     tmpVal = *((UINT32 *) pAdrs);
  1620.     tmpVal &= (unsigned int)0xffc00000;
  1621.     tmpVal |= (unsigned int)value;
  1622.     *((UINT32 *)pAdrs) = (UINT32) tmpVal;
  1623.     return (OK);
  1624.     }
  1625. /*******************************************************************************
  1626. *
  1627. * elfSparcUaddr32Reloc - perform the R_PPC_UADDR32 relocation
  1628. * This routine handles the R_PPC_UADDR32 relocation (word32, S + A).
  1629. *
  1630. * RETURNS : OK or ERROR if computed value can't be written down in target
  1631. *     memory.
  1632. */
  1633. LOCAL STATUS elfSparc22Reloc
  1634.     (
  1635.     void *  pAdrs, /* relocation address */
  1636.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1637.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1638.     )
  1639.     {
  1640.     unsigned int value, tmpVal;
  1641.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1642.             pRelocCmd->r_addend;
  1643.     tmpVal = *((UINT32 *) pAdrs);
  1644.     tmpVal &= (unsigned int)0xffc00000;
  1645.     tmpVal |= (unsigned int)value;
  1646.     *((UINT32 *)pAdrs) = (UINT32) tmpVal;
  1647.     return (OK);
  1648.     }
  1649. /*******************************************************************************
  1650. *
  1651. * elfSparcUaddr16Reloc - perform the R_PPC_UADDR16 relocation
  1652. * This routine handles the R_PPC_UADDR16 relocation (half16, S + A).
  1653. *
  1654. * RETURNS : OK or ERROR if computed value can't be written down in target
  1655. *     memory.
  1656. */
  1657. LOCAL STATUS elfSparc13Reloc
  1658.     (
  1659.     void *  pAdrs, /* relocation address */
  1660.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1661.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1662.     )
  1663.     {
  1664.     unsigned int value, tmpVal;
  1665.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1666.             pRelocCmd->r_addend;
  1667.     tmpVal = *((UINT32 *) pAdrs);
  1668.     tmpVal &= (unsigned int)0xfffe0000;
  1669.     tmpVal |= (unsigned int)value;
  1670.     *((UINT32 *)pAdrs) = (UINT32) tmpVal;
  1671.     return (OK);
  1672.     }
  1673. /*******************************************************************************
  1674. *
  1675. * elfSparcRel32Reloc - perform the R_PPC_REL32 relocation
  1676. * This routine handles the R_PPC_REL32 relocation (word32, S + A - P).
  1677. *
  1678. * RETURNS : OK or ERROR if computed value can't be written down in target
  1679. *     memory.
  1680. */
  1681. LOCAL STATUS elfSparcLo10Reloc
  1682.     (
  1683.     void *  pAdrs, /* relocation address */
  1684.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1685.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1686.     )
  1687.     {
  1688.     unsigned int value, tmpVal;
  1689.     value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1690.             pRelocCmd->r_addend) & 0x3ff;
  1691.     tmpVal = *((UINT32 *) pAdrs);
  1692.     tmpVal &= (unsigned int)0xfffffc00;        
  1693.     tmpVal |= (unsigned int)value;
  1694.     *((UINT32 *)pAdrs) = tmpVal;
  1695.     return (OK);
  1696.     }
  1697. /*******************************************************************************
  1698. *
  1699. * elfSparcEmbNaddr32Reloc - perform the R_PPC_EMB_NADDR32 relocation
  1700. * This routine handles the R_PPC_EMB_NADDR32 relocation (uword32, A - S).
  1701. *
  1702. * RETURNS : OK or ERROR if computed value can't be written down in target
  1703. *     memory.
  1704. */
  1705. LOCAL STATUS elfSparcPc10Reloc
  1706.     (
  1707.     void *  pAdrs, /* relocation address */
  1708.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1709.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1710.     )
  1711.     {
  1712.     unsigned int value, tmpVal;
  1713.     value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1714.             pRelocCmd->r_addend - ((UINT32)pAdrs))&0x3ff;
  1715.     tmpVal = *((UINT32 *) pAdrs);
  1716.     tmpVal &= (unsigned int)0xfffffc00;        
  1717.     tmpVal |= (unsigned int)value;
  1718.     *((UINT32 *)pAdrs) = (UINT32) tmpVal;
  1719.     return (OK);
  1720.     }
  1721. /*******************************************************************************
  1722. *
  1723. * elfSparcEmbNaddr16Reloc - perform the R_PPC_EMB_NADDR16 relocation
  1724. * This routine handles the R_PPC_EMB_NADDR16 relocation (uhalf16, A - S).
  1725. *
  1726. * RETURNS : OK or ERROR if computed value can't be written down in target
  1727. *     memory.
  1728. */
  1729. LOCAL STATUS elfSparcPc22Reloc
  1730.     (
  1731.     void *  pAdrs, /* relocation address */
  1732.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1733.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1734.     )
  1735.     {
  1736.     unsigned int value, tmpVal;
  1737.     value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1738.             pRelocCmd->r_addend - ((UINT32)pAdrs))>>10;
  1739.     tmpVal = *((UINT32 *) pAdrs);
  1740.     tmpVal &= (unsigned int)0xffc00000;
  1741.     tmpVal |= (unsigned int)value;
  1742.     *((UINT32 *)pAdrs) = (UINT32) tmpVal;
  1743.     return (OK);
  1744.     }
  1745. /*******************************************************************************
  1746. *
  1747. * elfSparcEmbNaddr16LoReloc - perform the R_PPC_EMB_NADDR16_LO relocation
  1748. * This routine handles the R_PPC_EMB_NADDR16_LO relocation (uhalf16,
  1749. * #lo (A - S)).
  1750. *
  1751. * RETURNS : OK or ERROR if computed value can't be written down in target
  1752. *     memory.
  1753. */
  1754. LOCAL STATUS elfSparcUa32Reloc
  1755.     (
  1756.     void *  pAdrs, /* relocation address */
  1757.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1758.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1759.     )
  1760.     {
  1761.     unsigned int value;
  1762.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1763.             pRelocCmd->r_addend;
  1764.     *((UINT32 *)pAdrs) = (UINT32) value;
  1765.     return (OK);
  1766.     }
  1767. #endif /* (CPU_FAMILY == SIMSPARCSOLARIS) */
  1768. #if (CPU_FAMILY == COLDFIRE)
  1769. /*******************************************************************************
  1770. *
  1771. * elfM68kSegReloc - perform relocation for the M68k family
  1772. *
  1773. * This routine reads the specified relocation command segment and performs
  1774. * all the relocations specified therein. Only relocation command from sections
  1775. * with section type SHT_RELA are considered here.
  1776. *
  1777. * Absolute symbol addresses are looked up in the 'externals' table.
  1778. *
  1779. * RETURNS: OK or ERROR
  1780. */
  1781. STATUS elfM68kSegReloc
  1782.     (
  1783.     int  fd, /* file to read in */
  1784.     MODULE_ID  moduleId, /* module id */
  1785.     int  loadFlag, /* not used */
  1786.     int  posCurRelocCmd,/* position of current relocation command */
  1787.     Elf32_Shdr * pScnHdrTbl, /* pointer to section header table */
  1788.     Elf32_Shdr * pRelHdr, /* pointer to relocation section header */
  1789.     SCN_ADRS *  pScnAddr, /* section address once loaded */
  1790.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  1791.     Elf32_Sym *  pSymsArray, /* pointer to symbols array */
  1792.     SYMTAB_ID   symTbl, /* not used */
  1793.     SEG_INFO *  pSeg /* section addresses and sizes */
  1794.     )
  1795.     {
  1796.     Elf32_Shdr * pScnHdr; /* section to which the relocations apply */
  1797.     Elf32_Rela   relocCmd; /* relocation structure */
  1798.     UINT32  relocNum; /* number of reloc entries in section */
  1799.     UINT32  relocIdx; /* index of the reloc entry being processed */
  1800.     void *  pAdrs; /* relocation address */
  1801.     Elf32_Sym *  pSym; /* pointer to an external symbol */
  1802.     STATUS  status = OK; /* whether or not the relocation was ok */
  1803.     pScnHdr = pScnHdrTbl + pRelHdr->sh_info;
  1804.     /* Some sanity checking */
  1805.     if (pRelHdr->sh_type != SHT_RELA)
  1806. {
  1807. errnoSet (S_loadElfLib_RELA_SECTION);
  1808. printErr ("Relocation sections of type %d are not supported.n",
  1809.      pRelHdr->sh_type);
  1810. return (OK);
  1811. }
  1812.     if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))
  1813. {
  1814. printErr ("Wrong relocation entry size.n");
  1815. errnoSet (S_loadElfLib_RELA_SECTION);
  1816. return (ERROR);
  1817. }
  1818.     /* Relocation loop */
  1819.     relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
  1820.     for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
  1821. {
  1822. /* read relocation command */
  1823. posCurRelocCmd = elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd);
  1824. /*
  1825.  * Calculate actual remote address that needs relocation, and
  1826.  * perform external or section relative relocation.
  1827.  */
  1828. pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
  1829. pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);
  1830. /*
  1831.  * System V ABI defines the following notations:
  1832.  *
  1833.  * A - the addend used to compute the value of the relocatable field.
  1834.  * S - the value (address) of the symbol whose index resides in the
  1835.  *     relocation entry. Note that this function uses the value stored
  1836.  *     in the external symbol value array instead of the symbol's
  1837.  *     st_value field.
  1838.  * P - the place (section offset or address) of the storage unit being
  1839.  *     relocated (computed using r_offset) prior to the relocation.
  1840.  */
  1841.         switch (ELF32_R_TYPE (relocCmd.r_info) & 0x7f)
  1842.             {
  1843.     case R_68K_32:
  1844. if (elfM68k32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1845.     status = ERROR;
  1846. break;
  1847.     case R_68K_16:
  1848. if (elfM68k16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1849.     status = ERROR;
  1850. break;
  1851.     case R_68K_PC32:
  1852. if (elfM68kDisp32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1853.     status = ERROR;
  1854. break;
  1855.     case R_68K_PC16:
  1856. if (elfM68kDisp16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
  1857.     status = ERROR;
  1858. break;
  1859.     default:
  1860.          printErr ("Unsupported relocation type %dn",
  1861.     ELF32_R_TYPE (relocCmd.r_info));
  1862.          status = ERROR;
  1863.          break;
  1864.     }
  1865. }
  1866.     return (status);
  1867.     }
  1868. /******************************************************************************
  1869. *
  1870. * elfM68k32Reloc - perform the R_68K_32 relocation
  1871. * This routine handles the R_68K_32 relocation (S + A).
  1872. *
  1873. * RETURNS : OK or ERROR if computed value can't be written down in target
  1874. *     memory.
  1875. */
  1876. LOCAL STATUS elfM68k32Reloc
  1877.     (
  1878.     void *  pAdrs, /* relocation address */
  1879.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1880.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1881.     )
  1882.     {
  1883.     UINT32  value; /* relocation value */
  1884.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1885.     pRelocCmd->r_addend;
  1886.     *((UINT32 *)pAdrs) = (UINT32) value;
  1887.     return (OK);
  1888.     }
  1889. /******************************************************************************
  1890. *
  1891. * elfM68k16Reloc - perform the R_68K_16 relocation
  1892. * This routine handles the R_68K_16 relocation (S + A).
  1893. *
  1894. * RETURNS : OK or ERROR if computed value can't be written down in target
  1895. *     memory.
  1896. */
  1897. LOCAL STATUS elfM68k16Reloc
  1898.     (
  1899.     void *  pAdrs, /* relocation address */
  1900.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1901.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1902.     )
  1903.     {
  1904.     UINT32  value; /* relocation value */
  1905.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1906.     pRelocCmd->r_addend;
  1907.     *((UINT16 *)pAdrs) = (UINT16) value;
  1908.     return (OK);
  1909.     }
  1910. /*******************************************************************************
  1911. *
  1912. * elfM68kDisp32Reloc - perform the R_68K_PC32 relocation
  1913. * This routine handles the R_68K_PC32 relocation (S + A - P).
  1914. *
  1915. * RETURNS : OK or ERROR if computed value can't be written down in target
  1916. *     memory.
  1917. */
  1918. LOCAL STATUS elfM68kDisp32Reloc
  1919.     (
  1920.     void *  pAdrs, /* relocation address */
  1921.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1922.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1923.     )
  1924.     {
  1925.     UINT32  value; /* relocation value */
  1926.     value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1927.     pRelocCmd->r_addend - ((UINT32) pAdrs);
  1928.     *((UINT32 *)pAdrs) = value;
  1929.     return (OK);
  1930.     }
  1931. /*******************************************************************************
  1932. *
  1933. * elfM68kDisp16Reloc - perform the R_68K_PC16 relocation
  1934. * This routine handles the R_68K_PC16 relocation (S + A - P).
  1935. *
  1936. * RETURNS : OK or ERROR if computed value can't be written down in target
  1937. *     memory.
  1938. */
  1939. LOCAL STATUS elfM68kDisp16Reloc
  1940.     (
  1941.     void *  pAdrs, /* relocation address */
  1942.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  1943.     SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
  1944.     )
  1945.     {
  1946.     UINT32  value; /* relocation value */
  1947.     value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  1948.     pRelocCmd->r_addend - ((UINT32) pAdrs);
  1949.     *((UINT16 *)pAdrs) = (UINT16) value;
  1950.     return (OK);
  1951.     }
  1952. #endif /* (CPU_FAMILY == COLDFIRE) */
  1953. #if (CPU_FAMILY == SH)
  1954. /*******************************************************************************
  1955. *
  1956. * elfShSegReloc - perform relocation for the Super Hitachi family
  1957. *
  1958. * This routine reads the specified relocation command segment and performs
  1959. * all the relocations specified therein. Only relocation command from sections
  1960. * with section type SHT_RELA are considered here.
  1961. *
  1962. * Absolute symbol addresses are looked up in the 'externals' table.
  1963. *
  1964. * This function handles the following types of relocation commands
  1965. * for the SH processor:
  1966. *
  1967. *  R_SH_NONE
  1968. *  R_SH_DIR32
  1969. *  R_SH_REL32
  1970. *  R_SH_DIR8WPN
  1971. *  R_SH_IND12W
  1972. *  R_SH_DIR8WPL
  1973. *  R_SH_DIR8WPZ
  1974. *  R_SH_DIR8BP
  1975. *  R_SH_DIR8W
  1976. *  R_SH_DIR8L
  1977. *
  1978. *  The remaining relocs are a GNU extension used for relaxation.  We
  1979. *  use the same constants as COFF uses, not that it really matters.  
  1980. *
  1981. *  R_SH_SWITCH16
  1982. *  R_SH_SWITCH32
  1983. *  R_SH_USES
  1984. *  R_SH_COUNT
  1985. *  R_SH_ALIGN
  1986. *  R_SH_CODE
  1987. *  R_SH_DATA
  1988. *  R_SH_LABEL
  1989. *
  1990. *
  1991. * RETURNS: OK or ERROR
  1992. */
  1993. LOCAL STATUS elfShSegReloc
  1994.     (
  1995.     int  fd, /* file to read in */
  1996.     MODULE_ID  moduleId, /* module id */
  1997.     int  loadFlag, /* not used */
  1998.     int    posCurRelocCmd,/* position of current relocation command */
  1999.     Elf32_Shdr * pScnHdrTbl, /* not used */
  2000.     Elf32_Shdr * pRelHdr, /* pointer to relocation section header */
  2001.     SCN_ADRS *  pScnAddr, /* section address once loaded */
  2002.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  2003.     Elf32_Sym *  pSymsArray, /* pointer to symbols array */
  2004.     SYMTAB_ID   symTbl, /* not used */
  2005.     SEG_INFO *  pSeg /* section addresses and sizes */
  2006.     )
  2007.     {
  2008.     Elf32_Rela   relocCmd; /* relocation structure */
  2009.     UINT32  relocNum; /* number of reloc entries in section */
  2010.     UINT32  relocIdx; /* index of the reloc entry being processed */
  2011.     void *  pAdrs; /* relocation address */
  2012.     Elf32_Sym *  pSym; /* pointer to an external symbol */
  2013.     STATUS  status = OK; /* whether or not the relocation was ok */
  2014.     /* Some sanity checking */
  2015.     if (pRelHdr->sh_type != SHT_RELA)
  2016. {
  2017.         errnoSet (S_loadElfLib_RELA_SECTION);
  2018. return (OK);
  2019. }
  2020.     if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))
  2021. {
  2022.         errnoSet (S_loadElfLib_RELA_SECTION);
  2023. return (ERROR);
  2024. }
  2025.     /* Relocation loop */
  2026.     relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
  2027.     for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
  2028. {
  2029. /* read relocation command */
  2030. if ((posCurRelocCmd = 
  2031.      elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd)) == ERROR)
  2032.     {
  2033.     errnoSet (S_loadElfLib_READ_SECTIONS);
  2034.     return (ERROR);
  2035.     }
  2036. /*
  2037.  * Calculate actual remote address that needs relocation, and
  2038.  * perform external or section relative relocation.
  2039.  */
  2040. pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
  2041. pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);
  2042. /*
  2043.  * System V ABI defines the following notations:
  2044.  *
  2045.  * A - the addend used to compute the value of the relocatable field.
  2046.  * S - the value (address) of the symbol whose index resides in the
  2047.  *     relocation entry. Note that this function uses the value stored
  2048.  *     in the external symbol value array instead of the symbol's
  2049.  *     st_value field.
  2050.  * P - the place (section offset or address) of the storage unit being
  2051.  *     relocated (computed using r_offset) prior to the relocation.
  2052.  */
  2053.         switch (ELF32_R_TYPE (relocCmd.r_info))
  2054.             {
  2055.     case (R_SH_NONE): /* none */
  2056. break;
  2057.     case (R_SH_DIR32):
  2058. if (elfShDir32Reloc (pAdrs, &relocCmd, symInfoTbl,
  2059.        moduleId) != OK)
  2060.     status = ERROR;
  2061. break;
  2062.     default:
  2063.          printErr ("Unsupported relocation type %dn",
  2064.       ELF32_R_TYPE (relocCmd.r_info));
  2065.          status = ERROR;
  2066.          break;
  2067.     }
  2068. }
  2069.     return (status);
  2070.     }
  2071. /*******************************************************************************
  2072. *
  2073. * elfShDir32Reloc - perform the R_SH_DIR32 relocation
  2074. * This routine handles the R_SH_DIR32 relocation (word32, S + A).
  2075. *
  2076. * RETURNS : OK or ERROR if computed value can't be written down in target
  2077. *     memory.
  2078. */
  2079. LOCAL STATUS elfShDir32Reloc
  2080.     (
  2081.     void *  pAdrs, /* relocation address */
  2082.     Elf32_Rela * pRelocCmd, /* points to a relocation structure */
  2083.     SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
  2084.     MODULE_ID  moduleId /* module id */
  2085.     )
  2086.     {
  2087.     UINT32  value; /* relocation value */
  2088.     UINT32  oldValue;
  2089.     oldValue = *(UINT32 *)pAdrs;
  2090.     value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
  2091.     pRelocCmd->r_addend + oldValue;
  2092.     *((UINT32 *)pAdrs) = value;
  2093.     return (OK);
  2094.     }
  2095. #endif /* CPU_FAMILY == SH */
  2096. /*******************************************************************************
  2097. *
  2098. * loadElfInit - initialize the system for ELF load modules
  2099. *
  2100. * This routine initializes VxWorks to use the ELF (executable and linking format)
  2101. * object module format for loading modules.
  2102. *
  2103. * RETURNS: OK (always)
  2104. *
  2105. * SEE ALSO: loadModuleAt()
  2106. */
  2107. STATUS loadElfInit (void)
  2108.     {
  2109.     loadRoutine = (FUNCPTR)loadElfFmtManage;
  2110. #if (CPU_FAMILY == I80X86)
  2111.     elfI86Init (&pElfModuleVerifyRtn, &pElfSegRelRtn);
  2112. #endif /* CPU_FAMILY */
  2113. #if (CPU_FAMILY == ARM)
  2114.     elfArmInit (&pElfModuleVerifyRtn, &pElfSegRelRtn);
  2115. #endif /* CPU_FAMILY */
  2116. #if (CPU_FAMILY == MIPS)
  2117.     elfMipsInit (&pElfModuleVerifyRtn, &pElfSegRelRtn);
  2118. #endif /* CPU_FAMILY */
  2119. #ifdef INCLUDE_SDA
  2120.     /* Create new memory partitions for the SDA areas */
  2121.     if ((EM_ARCH_MACHINE == EM_PPC) || ((EM_ARCH_MACHINE == EM_SH))
  2122.      if (loadElfSdaCreate() == ERROR)
  2123.     return ERROR;
  2124. #endif /* INCLUDE_SDA */
  2125.     return OK;
  2126.     }
  2127. /******************************************************************************