loadElfLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:159k
- /* loadElfLib.c - UNIX elf object module loader */
- /* Copyright 1996-2002 Wind River Systems, Inc. */
- #include "copyright_wrs.h"
- /*
- modification history
- --------------------
- 01x,09may02,fmk use loadCommonManage() instead of loadElfCommonManage()
- 01w,23apr02,jn SPR 75177 - correct inaccurate test for whether CPU is
- SIMSPARCSOLARIS
- 01v,26mar02,jn fix alignment handling for COMMON's (SPR 74567)
- 01u,07mar02,jn Add STT_ARM_16BIT to recognized types (SPR # 73992)
- 01t,07mar02,jn Refix SPR# 30588 - load should return NULL when there are
- unresolved symbols.
- 01s,14jan02,jn Improve comments about setting SYM_THUMB
- 01r,25jan02,rec Merge in coldfire changes
- 01q,12dec01,pad Moved MIPS support code out in the ELF/MIPS relocation unit.
- 01p,28nov01,jn Fix alignment of segments (SPR #28353). Also removed
- declarations of unsupported relocation types for SH.
- 01o,19nov01,pch Provide misalignment prevention based on _WRS_STRICT_ALIGNMENT
- definition instead of testing a specific CPU type.
- 01n,08nov01,jn Added support for ARM/THUMB architecture now using ELF
- 01m,17sep01,pad Introduced usage of relocation unit's init routines. Added
- support for I86 relocation unit. Symbols from a read-only data
- sections are now flagged as data, like in VxWorks AE, rather
- than text. Made the determination of text sections more
- flexible in loadElfSegSizeGet().
- 01l,28jun01,agf add logic to MIPS that tests for attempted relative jumps
- across a 26 bit boundary
- 01k,03mar00,zl merged SH support from T1
- 01j,30nov98,dbt no longer clear seg.flags<xxx> after loadSegmentAllocate()
- call. (SPR #23553).
- 01i,05oct98,pcn Initialize all the fields in the SEG_INFO structure.
- 01h,16sep98,pcn Set to _ALLOC_ALIGN_SIZE the flags field in seg structure
- (SPR #21836).
- 01g,17jul98,pcn Fixed SPR #21836: alignment mismatch between sections and
- target.
- 01f,18apr97,kkk fixed printing of debug msgs for MIPS (spr# 8276)
- 01e,05dec96,dbt fixed a bug in loadElfSizeGet() when loading an object file
- with a data section null and a text and bss sections not
- null.
- 01d,31oct96,elp Replaced symAdd() call by symSAdd() call (symtbls synchro).
- 01c,22oct96,dbt Zero out bss section (fixed SPR #7376).
- 01c,02oct96,dbt Added support for SIMSPARCSOLARIS.
- 01b,02oct96,dbt Unknown moduleformats are now correctly managed (SPR #7263).
- 01b,03aug96,kkk throw away __gnu_compiled_c signatures.
- 01a,20jun96,dbt created from /host/src/tgtsvr/server/loadelf.c v01t
- and /host/src/tgtsvr/server/elfppc.c v01e
- and /host/src/tgtsvr/server/elfmips.c v01c
- */
- /*
- DESCRIPTION
- This library provides an object module loading facility. Any SYSV elf
- format files may be loaded into memory, relocated properly, their
- external references resolved, and their external definitions added to
- the system symbol table for use by other modules and from the shell.
- Modules may be loaded from any I/O stream.
- EXAMPLE
- .CS
- fdX = open ("/devX/objFile", O_RDONLY);
- loadModule (fdX, ALL_SYMBOLS);
- close (fdX);
- .CE
- This code fragment would load the ELF file "objFile" located on
- device "/devX/" into memory which would be allocated from the system
- memory pool. All external and static definitions from the file would be
- added to the system symbol table.
- This could also have been accomplished from the shell, by typing:
- .CS
- -> ld (1) </devX/objFile
- .CE
- INCLUDE FILE: loadElfLib.h
- SEE ALSO: loadLib, usrLib, symLib, memLib,
- .pG "Basic OS"
- */
- /* defines */
- #undef INCLUDE_SDA /* SDA is not supported for the moment */
- #define _CACHE_SUPPORT /* cache */
- /* includes */
- #include "vxWorks.h"
- #include "stdio.h"
- #include "loadElfLib.h"
- #include "elf.h"
- #include "elftypes.h"
- #include "ioLib.h"
- #include "fioLib.h"
- #include "bootLoadLib.h"
- #include "loadLib.h"
- #include "memLib.h"
- #include "pathLib.h"
- #include "string.h"
- #include "symLib.h"
- #include "sysSymTbl.h"
- #ifdef _CACHE_SUPPORT
- #include "cacheLib.h"
- #endif /* _CACHE_SUPPORT */
- #include "errnoLib.h"
- #include "stdlib.h"
- #include "symbol.h" /* for SYM_TYPE typedef */
- #include "moduleLib.h"
- #include "private/vmLibP.h"
- #if ((CPU_FAMILY == MIPS) || (CPU_FAMILY == PPC) ||
- (CPU_FAMILY == SIMSPARCSOLARIS) || (CPU_FAMILY == SH) ||
- (CPU_FAMILY == I80X86) || (CPU_FAMILY == ARM) ||
- (CPU_FAMILY==COLDFIRE))
- /* define */
- #ifndef EM_ARCH_MACHINE
- #define EM_ARCH_MACHINE -1 /* default */
- #endif /* EM_ARCH_MACHINE */
- #undef DEBUGG
- #ifdef DEBUGG
- int elfDebug=1;
- #define DSMINST(x)
- #define DBG(x) if (elfDebug) { printf x; fflush(stdout); }
- #else
- #define DSMINST(x)
- #define DBG(x)
- #endif /* DEBUG */
- #ifdef _WRS_STRICT_ALIGNMENT
- #define ELFOUTMSBU32(b,w)
- ((b)[0] = (w >> 24),
- (b)[1] = (w >> 16),
- (b)[2] = (w >> 8),
- (b)[3] = w)
- #endif /* _WRS_STRICT_ALIGNMENT */
- /* globals */
- /* externals */
-
- #ifdef INCLUDE_SDA
- IMPORT char SDA_BASE[]; /* Base address of SDA Area */
- IMPORT char SDA2_BASE[]; /* Base address of SDA2 Area */
- IMPORT int SDA_SIZE; /* size of SDA area */
- IMPORT int SDA2_SIZE; /* size of SDA2 area */
- #endif /* INCLUDE_SDA */
- /* locals */
- #ifdef INCLUDE_SDA
- LOCAL STATUS moduleElfSegAdd (MODULE_ID moduleId, int type, void * location,
- int length, int flags, PART_ID memPartId);
- LOCAL BOOL segElfFindByType (SEGMENT_ID segmentId, MODULE_ID moduleId,
- int type);
- #endif /* INCLUDE_SDA */
- LOCAL UINT32 loadElfAlignGet (UINT32 alignment, void * pAddrOrSize);
- LOCAL BOOL (* pElfModuleVerifyRtn) (UINT32 machType,
- BOOL * sda) = NULL; /* verif rtn ptr */
- LOCAL STATUS (* pElfSegRelRtn) (int fd, MODULE_ID moduleId, int loadFlag,
- int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
- Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
- SYM_INFO_TBL symInfoTbl,
- Elf32_Sym * pSymsArray, SYMTAB_ID symTbl,
- SEG_INFO * pSeg) = NULL; /* seg reloc rtn ptr */
- #if (CPU_FAMILY == PPC)
- LOCAL STATUS elfPpcSegReloc (int fd, MODULE_ID moduleId, int loadFlag,
- int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
- Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
- SYM_INFO_TBL symInfoTbl,
- Elf32_Sym * pSymsArray,
- SYMTAB_ID symTbl,
- SEG_INFO * pSeg);
- LOCAL STATUS elfPpcAddr32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl, MODULE_ID moduleId);
- LOCAL STATUS elfPpcAddr24Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcAddr16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcAddr16LoReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcAddr16HiReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcAddr16HaReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcAddr14Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcRel24Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcRel14Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcUaddr32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcUaddr16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcRel32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcEmbNaddr32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcEmbNaddr16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcEmbNaddr16LoReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcEmbNaddr16HiReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfPpcEmbNaddr16HaReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- #ifdef INCLUDE_SDA
- LOCAL STATUS elfPpcSdaRel16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl, SEG_INFO * pSeg);
- LOCAL STATUS elfPpcEmbSda21Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl, SEG_INFO * pSeg);
- LOCAL STATUS elfPpcEmbSda2RelReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl, SEG_INFO * pSeg);
- LOCAL STATUS elfPpcEmbRelSdaReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl, SEG_INFO * pSeg);
- #endif /* INCLUDE_SDA */
- #endif /* CPU_FAMILY == PPC */
- #if (CPU_FAMILY == SIMSPARCSOLARIS)
- LOCAL STATUS elfSparcSegReloc (int fd, MODULE_ID moduleId, int loadFlag,
- int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
- Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
- SYM_INFO_TBL symInfoTbl, Elf32_Sym * pSymsArray,
- SYMTAB_ID symTbl, SEG_INFO * pSeg);
- LOCAL STATUS elfSparc32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparc16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparc8Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcDisp32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcDisp16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcDisp8Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcWDisp30Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcWDisp22Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcHi22Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparc22Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparc13Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcLo10Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcPc10Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcPc22Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfSparcUa32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- #endif /* (CPU_FAMILY == SIMSPARCSOLARIS) */
- #if (CPU_FAMILY == COLDFIRE)
- LOCAL STATUS elfM68k32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfM68k16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfM68kDisp32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfM68kDisp16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfM68kSegReloc (int fd, MODULE_ID moduleId, int loadFlag,
- int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
- Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
- SYM_INFO_TBL symInfoTbl, Elf32_Sym * pSymsArray,
- SYMTAB_ID symTbl, SEG_INFO * pSeg);
- #endif /* (CPU_FAMILY == COLDFIRE) */
- #if (CPU_FAMILY == SH)
- LOCAL STATUS elfShSegReloc (int fd, MODULE_ID moduleId, int loadFlag,
- int posCurRelocCmd, Elf32_Shdr * pScnHdrTbl,
- Elf32_Shdr * pRelHdr, SCN_ADRS * pScnAddr,
- SYM_INFO_TBL symInfoTbl,
- Elf32_Sym * pSymsArray,
- SYMTAB_ID symTbl,
- SEG_INFO * pSeg);
- LOCAL STATUS elfShDir32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl, MODULE_ID moduleId);
- #if FALSE /* Relocation types not currently supported. */
- LOCAL STATUS elfShRel32Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfShDir8wpnReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfShInd12wReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfShDir8wplReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfShDir8bpReloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- LOCAL STATUS elfShSwitch16Reloc (void * pAdrs, Elf32_Rela * pRelocCmd,
- SYM_INFO_TBL symInfoTbl);
- #endif /* relocation types not currently supported. */
- #endif /* (CPU_FAMILY == SH) */
- LOCAL BOOL loadElfModuleIsOk (Elf32_Ehdr *pHdr);
- LOCAL STATUS loadElfMdlHdrCheck (Elf32_Ehdr *pHdr);
- LOCAL STATUS loadElfMdlHdrRd (int fd, Elf32_Ehdr *pHdr);
- LOCAL STATUS loadElfProgHdrCheck (Elf32_Phdr *pProgHdr, int progHdrNum);
- LOCAL STATUS loadElfProgHdrTblRd (int fd, int posProgHdrField,
- Elf32_Phdr *pProgHdrTbl, int progHdrNumber);
- LOCAL STATUS loadElfScnHdrCheck (Elf32_Shdr *pScnHdr, int scnHdrNum);
- LOCAL STATUS loadElfScnHdrIdxDispatch (Elf32_Shdr *pScnHdrTbl, int scnHdrIdx,
- IDX_TBLS *pIndexTables);
- LOCAL STATUS loadElfScnHdrRd (int fd, int posScnHdrField,
- Elf32_Shdr * pScnHdrTbl,
- int sectionNumber, IDX_TBLS * pIndexTables);
- LOCAL void loadElfSegSizeGet (char * pScnStrTbl,
- UINT32 *pLoadScnHdrIdxs,
- Elf32_Shdr *pScnHdrTbl, SEG_INFO *pSeg);
- LOCAL STATUS loadElfScnRd (int fd, char * pScnStrTbl,
- UINT32 *pLoadScnHdrIdxs, Elf32_Shdr *pScnHdrTbl,
- SCN_ADRS_TBL sectionAdrsTbl, SEG_INFO *pSeg);
- LOCAL int loadElfSymEntryRd (int fd, int symEntry, Elf32_Sym *pSymbol);
- LOCAL STATUS loadElfSymTabRd (int fd, int nextSym, UINT32 nSyms,
- Elf32_Sym *pSymsArray);
- LOCAL int loadElfSymTablesHandle (UINT32 *pSymTabScnHdrIdxs,
- Elf32_Shdr *pScnHdrTbl, int fd,
- SYMTBL_REFS *pSymTblRefs,
- SYMINFO_REFS * pSymsAdrsRefs);
- LOCAL SYM_TYPE loadElfSymTypeGet (Elf32_Sym *pSymbol, Elf32_Shdr *pScnHdrTbl,
- char * pScnStrTbl);
- LOCAL BOOL loadElfSymIsVisible (UINT32 symAssoc, UINT32 symBinding,
- int loadFlag);
- LOCAL STATUS loadElfSymTabProcess (MODULE_ID moduleId, int loadFlag,
- Elf32_Sym *pSymsArray,
- SCN_ADRS_TBL sectionAdrsTbl,
- SYM_INFO_TBL symsAdrsTbl, char * pStringTable,
- SYMTAB_ID symTbl, UINT32 symNumber,
- Elf32_Shdr * pScnHdrTbl, char * pScnStrTbl,
- SEG_INFO * pSeg);
- LOCAL STATUS loadElfSymTableBuild (MODULE_ID moduleId, int loadFlag,
- SYMTBL_REFS symTblRefs,
- SCN_ADRS_TBL sectionAdrsTbl,
- SYMINFO_REFS symsAdrsRefs,
- IDX_TBLS *pIndexTables, SYMTAB_ID symTbl,
- int fd, Elf32_Shdr * pScnHdrTbl,
- char * pScnStrTbl, SEG_INFO * pSeg);
- LOCAL FUNCPTR loadElfRelSegRtnGet (void);
- LOCAL STATUS loadElfSegReloc (int fd, int loadFlag, MODULE_ID moduleId,
- Elf32_Ehdr * pHdr, IDX_TBLS *pIndexTables,
- Elf32_Shdr *pScnHdrTbl,
- SCN_ADRS_TBL sectionAdrsTbl,
- SYMTBL_REFS symTblRefs,
- SYMINFO_REFS symsAdrsRefs, SYMTAB_ID symTbl,
- SEG_INFO * pSeg);
- LOCAL STATUS loadElfTablesAlloc (Elf32_Ehdr *pHdr, Elf32_Phdr **ppProgHdrTbl,
- Elf32_Shdr **ppScnHdrTbl,
- IDX_TBLS *pIndexTables);
- LOCAL MODULE_ID loadElfFmtManage (FAST int fd, int loadFlag, void **ppText,
- void **ppData, void **ppBss, SYMTAB_ID symTbl);
- LOCAL void loadElfBufferFree (void ** ppBuf);
- LOCAL STATUS loadElfRelocMod (SEG_INFO * pSeg, int fd, char * pScnStrTbl,
- IDX_TBLS * pIndexTables, Elf32_Ehdr * pHdr,
- Elf32_Shdr * pScnHdrTbl,
- SCN_ADRS_TBL * pSectionAdrsTbl);
- LOCAL STATUS loadElfSegStore (SEG_INFO * pSeg, int loadFlag, int fd,
- char * pScnStrTbl,
- IDX_TBLS * pIndexTables, Elf32_Ehdr * pHdr,
- Elf32_Shdr * pScnHdrTbl,
- Elf32_Phdr * pProgHdrTbl,
- SCN_ADRS_TBL * pSectionAdrsTbl);
- LOCAL char * loadElfScnStrTblRd (int fd, Elf32_Shdr * pScnHdrTbl,
- Elf32_Ehdr * pHdr);
- #ifdef INCLUDE_SDA
- LOCAL STATUS loadElfSdaAllocate (SDA_INFO * pSda);
- LOCAL STATUS loadElfSdaCreate (void);
- LOCAL SDA_SCN_TYPE loadElfSdaScnDetermine (char * pScnStrTbl,
- Elf32_Shdr * pScnHdr, char * sectionName);
- LOCAL BOOL sdaIsRequired = FALSE; /* TRUE if SDA are used by the arch */
- LOCAL PART_ID sdaMemPartId = NULL; /* keeps SDA memory partition id */
- LOCAL PART_ID sda2MemPartId = NULL; /* keeps SDA2 memory partition id */
- LOCAL void * sdaBaseAddr = NULL; /* keeps SDA area base address */
- LOCAL void * sda2BaseAddr = NULL; /* keeps SDA2 area base address */
- LOCAL int sdaAreaSize = 0; /* keeps SDA area size */
- LOCAL int sda2AreaSize = 0; /* keeps SDA area size */
- #endif /* INCLUDE_SDA */
- /*******************************************************************************
- *
- * elfRelocRelaEntryRd - read in ELF relocation entry for RELA relocation
- *
- * This routine fills a relocation structure with information from the object
- * module in memory.
- *
- * RETURNS : the address of the next relocation entry or ERROR if entry not read.
- */
- int elfRelocRelaEntryRd
- (
- int fd, /* file to read in */
- int posRelocEntry, /* position of reloc. command in object file */
- Elf32_Rela * pReloc /* ptr on relocation structure to fill */
- )
- {
- int nbytes; /* number of bytes to copy */
- nbytes = sizeof (Elf32_Rela);
- if ((ioctl (fd, FIOSEEK, posRelocEntry)) == ERROR)
- return ERROR;
- if ((fioRead (fd, (char *) pReloc, nbytes)) == ERROR)
- return ERROR;
- return (posRelocEntry + nbytes);
- }
-
- /*******************************************************************************
- *
- * elfRelocRelEntryRd - read in ELF relocation entry for REL relocation
- *
- * This routine fills a relocation structure with information from the object
- * module in memory.
- *
- * RETURNS : the address of the next relocation entry or ERROR if entry not read.
- */
- int elfRelocRelEntryRd
- (
- int fd, /* file to read in */
- int posRelocEntry, /* position of reloc. command in object file */
- Elf32_Rel * pReloc /* ptr on relocation structure to fill */
- )
- {
- int nbytes; /* number of bytes to copy */
- nbytes = sizeof (Elf32_Rel);
- if ((ioctl (fd, FIOSEEK, posRelocEntry)) == ERROR)
- return ERROR;
- if ((fioRead (fd, (char *) pReloc, nbytes)) == ERROR)
- return ERROR;
- return (posRelocEntry + nbytes);
- }
- #if (CPU_FAMILY == PPC)
- /*******************************************************************************
- *
- * elfPpcSegReloc - perform relocation for the PowerPC family
- *
- * This routine reads the specified relocation command segment and performs
- * all the relocations specified therein. Only relocation command from sections
- * with section type SHT_RELA are considered here.
- *
- * Absolute symbol addresses are looked up in the 'externals' table.
- *
- * This function handles the following types of relocation commands
- * for the PowerPC processor:
- *
- * System V ABI:
- * R_PPC_NONE : none
- * R_PPC_ADDR32 : word32, S + A
- * R_PPC_ADDR24 : low24, (S + A) >> 2
- * R_PPC_ADDR16 : half16, S + A
- * R_PPC_ADDR16_LO : half16, #lo(S + A)
- * R_PPC_ADDR16_HI : half16, #hi(S + A)
- * R_PPC_ADDR16_HA : half16, #ha(S + A)
- * R_PPC_ADDR14 : low14, (S + A) >> 2
- * R_PPC_ADDR14_BRTAKEN : low14, (S + A) >> 2
- * R_PPC_ADDR14_BRNTAKEN : low14, (S + A) >> 2
- * R_PPC_REL24 : low24, (S + A - P) >> 2
- * R_PPC_REL14 : low14, (S + A - P) >> 2
- * R_PPC_REL14_BRTAKEN : low14, (S + A - P) >> 2
- * R_PPC_REL14_BRNTAKEN : low14, (S + A - P) >> 2
- * R_PPC_UADDR32 : word32, S + A
- * R_PPC_UADDR16 : half16, S + A
- * R_PPC_REL32 : word32, S + A - P
- * R_PPC_SDAREL : half16, S + A - SDA_BASE
- *
- * PowerPC EABI:
- * R_PPC_EMB_NADDR32 : uword32, A - S
- * R_PPC_EMB_NADDR16 : uhalf16, A - S
- * R_PPC_EMB_NADDR16_LO : uhalf16, #lo(A - S)
- * R_PPC_EMB_NADDR16_HI : uhalf16, #hi(A - S)
- * R_PPC_EMB_NADDR16_HA : uhalf16, #ha(A - S)
- * R_PPC_EMB_MRKREF : none
- * R_PPC_EMB_SDA21 : ulow21, complex
- * R_PPC_EMB_SDA2REL : uhalf16, S + A - SDA2_BASE
- * R_PPC_EMB_RELSDA : uhalf16, complex
- *
- * RETURNS: OK or ERROR
- */
- LOCAL STATUS elfPpcSegReloc
- (
- int fd, /* file to read in */
- MODULE_ID moduleId, /* module id */
- int loadFlag, /* not used */
- int posCurRelocCmd,/* position of current relocation command */
- Elf32_Shdr * pScnHdrTbl, /* not used */
- Elf32_Shdr * pRelHdr, /* pointer to relocation section header */
- SCN_ADRS * pScnAddr, /* section address once loaded */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- Elf32_Sym * pSymsArray, /* pointer to symbols array */
- SYMTAB_ID symTbl, /* not used */
- SEG_INFO * pSeg /* section addresses and sizes */
- )
- {
- Elf32_Rela relocCmd; /* relocation structure */
- UINT32 relocNum; /* number of reloc entries in section */
- UINT32 relocIdx; /* index of the reloc entry being processed */
- void * pAdrs; /* relocation address */
- Elf32_Sym * pSym; /* pointer to an external symbol */
- STATUS status = OK; /* whether or not the relocation was ok */
- /* Some sanity checking */
- if (pRelHdr->sh_type != SHT_RELA)
- {
- errnoSet (S_loadElfLib_RELA_SECTION);
- return (OK);
- }
- if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))
- {
- errnoSet (S_loadElfLib_RELA_SECTION);
- return (ERROR);
- }
- /* Relocation loop */
- relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
- for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
- {
- /* read relocation command */
- if ((posCurRelocCmd =
- elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd)) == ERROR)
- {
- errnoSet (S_loadElfLib_READ_SECTIONS);
- return (ERROR);
- }
- /*
- * Calculate actual remote address that needs relocation, and
- * perform external or section relative relocation.
- */
- pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
- pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);
- /*
- * System V ABI defines the following notations:
- *
- * A - the addend used to compute the value of the relocatable field.
- * S - the value (address) of the symbol whose index resides in the
- * relocation entry. Note that this function uses the value stored
- * in the external symbol value array instead of the symbol's
- * st_value field.
- * P - the place (section offset or address) of the storage unit being
- * relocated (computed using r_offset) prior to the relocation.
- */
- switch (ELF32_R_TYPE (relocCmd.r_info))
- {
- case (R_PPC_NONE): /* none */
- break;
- case (R_PPC_ADDR32): /* word32, S + A */
- if (elfPpcAddr32Reloc (pAdrs, &relocCmd, symInfoTbl,
- moduleId) != OK)
- status = ERROR;
- break;
- case (R_PPC_ADDR24): /* low24, (S+A) >> 2 */
- if (elfPpcAddr24Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_ADDR16): /* half16, S + A */
- if (elfPpcAddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_ADDR16_LO): /* half16, #lo(S + A) */
- if (elfPpcAddr16LoReloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_ADDR16_HI): /* half16, #hi(S + A) */
- if (elfPpcAddr16HiReloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_ADDR16_HA): /* half16, #ha(S + A) */
- if (elfPpcAddr16HaReloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_ADDR14):
- case (R_PPC_ADDR14_BRTAKEN):
- case (R_PPC_ADDR14_BRNTAKEN): /* low14, (S+A) >> 2 */
- if (elfPpcAddr14Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_REL24): /* low24, (S+A-P) >> 2*/
- if (elfPpcRel24Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_REL14):
- case (R_PPC_REL14_BRTAKEN):
- case (R_PPC_REL14_BRNTAKEN): /* low14, (S+A-P) >> 2*/
- if (elfPpcRel14Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_UADDR32): /* word32, S + A */
- if (elfPpcUaddr32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_UADDR16): /* half16, S + A */
- if (elfPpcUaddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_REL32): /* word32, S + A - P */
- if (elfPpcRel32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_NADDR32): /* uword32, A - S */
- if (elfPpcEmbNaddr32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_NADDR16): /* uhalf16, A - S */
- if (elfPpcEmbNaddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_NADDR16_LO): /* uhalf16, #lo(A - S)*/
- if (elfPpcEmbNaddr16LoReloc (pAdrs, &relocCmd, symInfoTbl)
- != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_NADDR16_HI): /* uhalf16, #hi(A - S)*/
- if (elfPpcEmbNaddr16HiReloc (pAdrs, &relocCmd, symInfoTbl)
- != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_NADDR16_HA): /* uhalf16, #ha(A - S)*/
- if (elfPpcEmbNaddr16HaReloc (pAdrs, &relocCmd, symInfoTbl)
- != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_MRKREF): /* none */
- break;
- #ifdef INCLUDE_SDA
- case (R_PPC_SDAREL): /* half16, S + A - SDA_BASE */
- if (elfPpcSdaRel16Reloc (pAdrs, &relocCmd, symInfoTbl,
- pSeg) != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_SDA21): /* ulow21, complex ! */
- if (elfPpcEmbSda21Reloc (pAdrs, &relocCmd, symInfoTbl,
- pSeg) != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_SDA2REL): /* uhalf16, S + A - SDA2_BASE */
- if (elfPpcEmbSda2RelReloc (pAdrs, &relocCmd, symInfoTbl,
- pSeg) != OK)
- status = ERROR;
- break;
- case (R_PPC_EMB_RELSDA): /* uhalf16, complex ! */
- if (elfPpcEmbRelSdaReloc (pAdrs, &relocCmd, symInfoTbl,
- pSeg) != OK)
- status = ERROR;
- break;
- #endif /* INCLUDE_SDA */
- default:
- printErr ("Unsupported relocation type %dn",
- ELF32_R_TYPE (relocCmd.r_info));
- status = ERROR;
- break;
- }
- }
- return (status);
- }
- /*******************************************************************************
- *
- * elfPpcAddr32Reloc - perform the R_PPC_ADDR32 relocation
- *
- * This routine handles the R_PPC_ADDR32 relocation (word32, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcAddr32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- MODULE_ID moduleId /* module id */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcAddr24Reloc - perform the R_PPC_ADDR24 relocation
- *
- * This routine handles the R_PPC_ADDR24 relocation (low24, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory or offset too large for relocation.
- */
- LOCAL STATUS elfPpcAddr24Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- UINT32 offset; /* previous value in memory */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- /*
- * Do some checking: R_PPC_ADDR24 relocation must fit in
- * 24 bits and lower 2 bits should always be null.
- */
- if (!CHECK_LOW24 (value))
- {
- printErr ("Relocation value does not fit in 24 bits.n");
- return (ERROR);
- }
- if (value & 0x3)
- printErr ("Relocation value's lower 2 bits not zero.n");
- offset = *((UINT32 *)pAdrs);
- LOW24_INSERT (offset, value);
- *((UINT32 *)pAdrs) = offset;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcAddr16Reloc - perform the R_PPC_ADDR16 relocation
- *
- * This routine handles the R_PPC_ADDR16 relocation (half16, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory or offset too large for relocation.
- */
- LOCAL STATUS elfPpcAddr16Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- /*
- * Do some checking: R_PPC_ADDR16 relocation must fit in
- * 16 bits.
- */
- if (!CHECK_LOW16 (value))
- {
- printErr ("Relocation value does not fit in 16 bits.n");
- return (ERROR);
- }
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcAddr16LoReloc - perform the R_PPC_ADDR16_LO relocation
- *
- * This routine handles the R_PPC_ADDR16_LO relocation (half16, #lo(S + A)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcAddr16LoReloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT16 *)pAdrs) = (UINT16) LO_VALUE (value);
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcAddr16HiReloc - perform the R_PPC_ADDR16_HI relocation
- *
- * This routine handles the R_PPC_ADDR16_HI relocation (half16, #hi(S + A)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcAddr16HiReloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT16 *)pAdrs) = (UINT16) (HI_VALUE (value));
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcAddr16HaReloc - perform the R_PPC_ADDR16_HA relocation
- *
- * This routine handles the R_PPC_ADDR16_HA relocation (half16, #ha(S + A)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcAddr16HaReloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT16 *)pAdrs) = (UINT16) HA_VALUE (value);
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcAddr14Reloc - perform the R_PPC_ADDR14 relocation
- *
- * This routine handles the R_PPC_ADDR14 relocation (low14, (S + A) >> 2).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory or offset too large for relocation.
- */
- LOCAL STATUS elfPpcAddr14Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- UINT32 offset; /* previous value in memory */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- /*
- * Do some checking: R_PPC_ADDR14* relocations must fit in
- * 14 bits and lower 2 bits should always be null.
- */
- if (!CHECK_LOW14 (value))
- {
- printErr ("Relocation value does not fit in 14 bits.n");
- return (ERROR);
- }
- if (value & 0x3)
- printErr ("Relocation value's lower 2 bits not zero.n");
- offset = *((UINT32 *)pAdrs);
- LOW14_INSERT (offset, value);
- *((UINT32 *)pAdrs) = offset;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcRel24Reloc - perform the R_PPC_REL24 relocation
- *
- * This routine handles the R_PPC_REL24 relocation (low24, (S + A - P) >> 2).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory or offset too large for relocation.
- */
- LOCAL STATUS elfPpcRel24Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- UINT32 offset; /* previous value in memory */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32) pAdrs);
- /*
- * Do some checking: R_PPC_REL24 relocation must fit in
- * 24 bits and lower 2 bits should always be null.
- */
- if (!CHECK_LOW24 (value))
- {
- printErr ("Relocation value does not fit in 24 bits.n");
- return (ERROR);
- }
- if (value & 0x3)
- printErr ("Relocation value's lower 2 bits not zero.n");
- offset = *((UINT32 *)pAdrs);
- LOW24_INSERT (offset, value);
- *((UINT32 *)pAdrs) = offset;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcRel14Reloc - perform the R_PPC_REL14 relocation
- *
- * This routine handles the R_PPC_REL14 relocation (low14, (S + A - P) >> 2).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory or offset too large for relocation.
- */
- LOCAL STATUS elfPpcRel14Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- UINT32 offset; /* previous value in memory */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32) pAdrs);
- /*
- * Do some checking: R_PPC_REL14* relocations must fit in
- * 14 bits and lower 2 bits should always be null.
- */
- if (!CHECK_LOW14 (value))
- {
- printErr ("Relocation value does not fit in 14 bits.n");
- return (ERROR);
- }
- if (value & 0x3)
- printErr ("Relocation value's lower 2 bits not zero.n");
- offset = *((UINT32 *)pAdrs);
- LOW14_INSERT (offset, value);
- *((UINT32 *)pAdrs) = offset;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcUaddr32Reloc - perform the R_PPC_UADDR32 relocation
- *
- * This routine handles the R_PPC_UADDR32 relocation (word32, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcUaddr32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- #ifdef _WRS_STRICT_ALIGNMENT
- ELFOUTMSBU32 ((char *)pAdrs, value);
- #else
- *((UINT32 *)pAdrs) = value;
- #endif /* _WRS_STRICT_ALIGNMENT */
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcUaddr16Reloc - perform the R_PPC_UADDR16 relocation
- *
- * This routine handles the R_PPC_UADDR16 relocation (half16, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory or offset too large for relocation.
- */
- LOCAL STATUS elfPpcUaddr16Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- /*
- * Do some checking: R_PPC_UADDR16 relocation must fit in
- * 16 bits.
- */
- if (!CHECK_LOW16 (value))
- {
- printErr ("Relocation value does not fit in 16 bits.n");
- return (ERROR);
- }
- /* handle unalignment */
-
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcRel32Reloc - perform the R_PPC_REL32 relocation
- *
- * This routine handles the R_PPC_REL32 relocation (word32, S + A - P).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcRel32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32) pAdrs);
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcEmbNaddr32Reloc - perform the R_PPC_EMB_NADDR32 relocation
- *
- * This routine handles the R_PPC_EMB_NADDR32 relocation (uword32, A - S).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcEmbNaddr32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = pRelocCmd->r_addend -
- (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcEmbNaddr16Reloc - perform the R_PPC_EMB_NADDR16 relocation
- *
- * This routine handles the R_PPC_EMB_NADDR16 relocation (uhalf16, A - S).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory or offset too large for relocation.
- */
- LOCAL STATUS elfPpcEmbNaddr16Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = pRelocCmd->r_addend -
- (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
- /*
- * Do some checking: R_PPC_EMB_NADDR16 relocation must fit in
- * 16 bits.
- */
- if (!CHECK_LOW16 (value))
- {
- printErr ("Relocation value does not fit in 16 bits.n");
- return (ERROR);
- }
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcEmbNaddr16LoReloc - perform the R_PPC_EMB_NADDR16_LO relocation
- *
- * This routine handles the R_PPC_EMB_NADDR16_LO relocation (uhalf16,
- * #lo (A - S)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcEmbNaddr16LoReloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = pRelocCmd->r_addend -
- (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
- *((UINT16 *)pAdrs) = (UINT16) LO_VALUE (value);
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcEmbNaddr16HiReloc - perform the R_PPC_EMB_NADDR16_HI relocation
- *
- * This routine handles the R_PPC_EMB_NADDR16_HI relocation (uhalf16,
- * #hi (A - S)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcEmbNaddr16HiReloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = pRelocCmd->r_addend -
- (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
- *((UINT16 *)pAdrs) = (UINT16) HI_VALUE (value);
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcEmbNaddr16HaReloc - perform the R_PPC_EMB_NADDR16_HA relocation
- *
- * This routine handles the R_PPC_EMB_NADDR16_HA relocation (uhalf16,
- * #ha (A - S)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcEmbNaddr16HaReloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values and types */
- )
- {
- UINT32 value; /* relocation value */
- value = pRelocCmd->r_addend -
- (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;
- *((UINT16 *)pAdrs) = (UINT16) HA_VALUE (value);
- return (OK);
- }
- #ifdef INCLUDE_SDA
- /*******************************************************************************
- *
- * elfPpcSdaRel16Reloc - perform the R_PPC_SDAREL relocation
- *
- * This routine handles the R_PPC_SDAREL relocation (half16, S + A - SDA_BASE).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory or offset too large for relocation.
- */
- LOCAL STATUS elfPpcSdaRel16Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- SEG_INFO * pSeg /* section addresses and sizes */
- )
- {
- UINT32 value; /* relocation value */
- if ((symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA)
- != SYM_SDA)
- {
- printErr ("Referenced symbol does not belong to SDA.n");
- return (ERROR);
- }
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend -
- (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);
- /*
- * Do some checking: R_PPC_SDAREL relocation must fit in
- * 16 bits.
- */
- if (!CHECK_LOW16 (value))
- {
- printErr ("Relocation value does not fit in 16 bits.n");
- return (ERROR);
- }
- /* handle unalignment */
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcEmbSda21Reloc - perform the R_PPC_EMB_SDA21 relocation
- *
- * This routine handles the R_PPC_EMB_SDA21 relocation. The most significant 11
- * bits of the address pointed to by the relocation entry are untouched (opcode
- * and rS/rD field). The next most significant 5 bits (rA field) will hold the
- * value 13 (SDA symbol) or 2 (SDA2 symbol). The least significant 16 bits are
- * set to the two's complement of the following computation:
- * symbol address + r_addend value - SDA_BASE (or SDA2_BASE) value.
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcEmbSda21Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- SEG_INFO * pSeg /* section addresses and sizes */
- )
- {
- UINT32 value; /* relocation value */
- UINT32 instr; /* previous instruction in memory */
- BOOL symbolIsInSda; /* TRUE if symbol belongs to the SDA area */
- BOOL sizeFit; /* TRUE if computed value is 16 bit long */
- /*
- * Only symbols (or reference to) belonging to a .sdata, .sbss, .sdata2
- * or .sbss2 section are supported.
- */
- switch (symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA_MASK)
- {
- case (SYM_SDA):
- symbolIsInSda = TRUE;
- break;
- case (SYM_SDA2):
- symbolIsInSda = FALSE;
- break;
- default:
- printErr ("Referenced symbol does not belong to SDA/SDA2.n");
- return (ERROR);
- break;
- }
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- instr = *((UINT32 *)pAdrs);
- /*
- * We applied here the same relocation process as the GNU does since
- * the EABI document is totally phony on this one...
- */
- if (symbolIsInSda)
- {
- value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);
- sizeFit = CHECK_LOW16_STRICT (value);
- value = (instr & ~RA_MSK) | GPR13_MSK | ((~value + 1) & 0xffff);
- }
- else
- {
- value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);
- sizeFit = CHECK_LOW16_STRICT (value);
- value = (instr & ~RA_MSK) | GPR2_MSK | ((~value + 1) & 0xffff);
- }
- /*
- * Do some checking: R_PPC_EMB_SDA21 relocation must fit in
- * 21 bits, thus the offset must fit in 16 bits.
- */
- if (!sizeFit)
- {
- printErr ("Relocation offset does not fit in 16 bits.n");
- return (ERROR);
- }
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcEmbSda2RelReloc - perform the R_PPC_EMB_SDA2REL relocation
- *
- * This routine handles the R_PPC_EMB_SDA2REL relocation (uhalf16,
- * S + A - SDA2_BASE).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcEmbSda2RelReloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- SEG_INFO * pSeg /* section addresses and sizes */
- )
- {
- UINT32 value; /* relocation value */
- if ((symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA2)
- != SYM_SDA2)
- {
- printErr ("Referenced symbol does not belong to SDA2.n");
- return (ERROR);
- }
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend -
- (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfPpcEmbRelSdaReloc - perform the R_PPC_EMB_RELSDA relocation
- *
- * This routine handles the R_PPC_EMB_RELSDA relocation.
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfPpcEmbRelSdaReloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- SEG_INFO * pSeg /* section addresses and sizes */
- )
- {
- UINT32 value; /* relocation value */
- BOOL symbolIsInSda; /* TRUE if symbol belongs to the SDA area */
- /*
- * Only symbols (or reference to) belonging to a .sdata, .sbss, .sdata2
- * or .sbss2 section are supported.
- */
- switch (symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA_MASK)
- {
- case (SYM_SDA):
- symbolIsInSda = TRUE;
- break;
- case (SYM_SDA2):
- symbolIsInSda = FALSE;
- break;
- default:
- printErr ("Referenced symbol does not belong to SDA/SDA2.n");
- return (ERROR);
- break;
- }
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- if (symbolIsInSda)
- value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);
- else
- value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);
- /*
- * Do some checking: R_PPC_EMB_RELSDA relocation must fit in
- * 16 bits.
- */
- if (!CHECK_LOW16 (value))
- {
- printErr ("Relocation value does not fit in 16 bits.n");
- return (ERROR);
- }
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- #endif /* INCLUDE_SDA */
- #endif /* CPU_FAMILY == PPC */
- #if (CPU_FAMILY == SIMSPARCSOLARIS)
- /*******************************************************************************
- *
- * elfSparcSegReloc - perform relocation for the PowerPC family
- *
- * This routine reads the specified relocation command segment and performs
- * all the relocations specified therein. Only relocation command from sections
- * with section type SHT_RELA are considered here.
- *
- * Absolute symbol addresses are looked up in the 'externals' table.
- *
- * RETURNS: OK or ERROR
- */
- STATUS elfSparcSegReloc
- (
- int fd, /* file to read in */
- MODULE_ID moduleId, /* module id */
- int loadFlag, /* not used */
- int posCurRelocCmd,/* position of current relocation command */
- Elf32_Shdr * pScnHdrTbl, /* pointer to section header table */
- Elf32_Shdr * pRelHdr, /* pointer to relocation section header */
- SCN_ADRS * pScnAddr, /* section address once loaded */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- Elf32_Sym * pSymsArray, /* pointer to symbols array */
- SYMTAB_ID symTbl, /* not used */
- SEG_INFO * pSeg /* section addresses and sizes */
- )
- {
- Elf32_Shdr * pScnHdr; /* section to which the relocations apply */
- Elf32_Rela relocCmd; /* relocation structure */
- UINT32 relocNum; /* number of reloc entries in section */
- UINT32 relocIdx; /* index of the reloc entry being processed */
- void * pAdrs; /* relocation address */
- Elf32_Sym * pSym; /* pointer to an external symbol */
- STATUS status = OK; /* whether or not the relocation was ok */
- pScnHdr = pScnHdrTbl + pRelHdr->sh_info;
- /* Some sanity checking */
- if (pRelHdr->sh_type != SHT_RELA)
- {
- errnoSet (S_loadElfLib_RELA_SECTION);
- printErr ("Relocation sections of type %d are not supported.n",
- pRelHdr->sh_type);
- return (OK);
- }
- if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))
- {
- printErr ("Wrong relocation entry size.n");
- errnoSet (S_loadElfLib_RELA_SECTION);
- return (ERROR);
- }
- /* Relocation loop */
- relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
- for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
- {
- /* read relocation command */
- if ((posCurRelocCmd =
- elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd)) == ERROR)
- {
- errnoSet (S_loadElfLib_READ_SECTIONS);
- return (ERROR);
- }
- /*
- * Calculate actual remote address that needs relocation, and
- * perform external or section relative relocation.
- */
- pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
- pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);
- /*
- * System V ABI defines the following notations:
- *
- * A - the addend used to compute the value of the relocatable field.
- * S - the value (address) of the symbol whose index resides in the
- * relocation entry. Note that this function uses the value stored
- * in the external symbol value array instead of the symbol's
- * st_value field.
- * P - the place (section offset or address) of the storage unit being
- * relocated (computed using r_offset) prior to the relocation.
- */
- switch (ELF32_R_TYPE (relocCmd.r_info))
- {
- case (R_SPARC_8):
- if (elfSparc8Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_16):
- if (elfSparc16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_32):
- if (elfSparc32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_DISP8):
- if (elfSparcDisp8Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_DISP16):
- if (elfSparcDisp16Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_DISP32):
- if (elfSparcDisp32Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_WDISP30):
- if (elfSparcWDisp30Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_WDISP22):
- if (elfSparcWDisp22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_HI22):
- if (elfSparcHi22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_22):
- if (elfSparc22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_13):
- if (elfSparc13Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_LO10):
- if (elfSparcLo10Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_PC10):
- if (elfSparcPc10Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_PC22):
- if (elfSparcPc22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case (R_SPARC_UA32):
- case (R_SPARC_GLOB_DAT):
- if (elfSparcUa32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- default:
- printErr ("Unsupported relocation type %dn",
- ELF32_R_TYPE (relocCmd.r_info));
- status = ERROR;
- break;
- }
- }
- return (status);
- }
- /*******************************************************************************
- *
- * elfSparcAddr32Reloc - perform the R_PPC_ADDR32 relocation
- *
- * This routine handles the R_PPC_ADDR32 relocation (word32, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparc32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcAddr24Reloc - perform the R_PPC_ADDR24 relocation
- *
- * This routine handles the R_PPC_ADDR24 relocation (low24, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparc16Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcAddr8Reloc - perform the R_PPC_ADDR16 relocation
- *
- * This routine handles the R_PPC_ADDR16 relocation (half16, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparc8Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT8 *)pAdrs) = (UINT8) value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcAddr16LoReloc - perform the R_PPC_ADDR16_LO relocation
- *
- * This routine handles the R_PPC_ADDR16_LO relocation (half16, #lo(S + A)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcDisp32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- UINT32 tmpVal; /* holds temporary calculation results */
- value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32) pAdrs);
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcAddr16HiReloc - perform the R_PPC_ADDR16_HI relocation
- *
- * This routine handles the R_PPC_ADDR16_HI relocation (half16, #hi(S + A)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcDisp16Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32) pAdrs);
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcAddr16HaReloc - perform the R_PPC_ADDR16_HA relocation
- *
- * This routine handles the R_PPC_ADDR16_HA relocation (half16, #ha(S + A)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcDisp8Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32) pAdrs);
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcAddr14Reloc - perform the R_PPC_ADDR14 relocation
- *
- * This routine handles the R_PPC_ADDR14 relocation (low14, (S + A) >> 2).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcWDisp30Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value, tmpVal;
- value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32)pAdrs))>>2;
- tmpVal = *((UINT32 *) pAdrs);
- tmpVal &= (unsigned int)0xc0000000;
- tmpVal |= (unsigned int)value;
- *((UINT32 *)pAdrs) = (UINT32) tmpVal;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcRel24Reloc - perform the R_PPC_REL24 relocation
- *
- * This routine handles the R_PPC_REL24 relocation (low24, (S + A - P) >> 2).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcWDisp22Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value, tmpVal;
- value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32)pAdrs))>>2;
- tmpVal = *((UINT32 *) pAdrs);
- tmpVal &= (unsigned int)0xffc00000;
- tmpVal |= (unsigned int)value;
- *((UINT32 *)pAdrs) = (UINT32) tmpVal;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcRel14Reloc - perform the R_PPC_REL14 relocation
- *
- * This routine handles the R_PPC_REL14 relocation (low14, (S + A - P) >> 2).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcHi22Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value, tmpVal;
- value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend)>>10;
- tmpVal = *((UINT32 *) pAdrs);
- tmpVal &= (unsigned int)0xffc00000;
- tmpVal |= (unsigned int)value;
- *((UINT32 *)pAdrs) = (UINT32) tmpVal;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcUaddr32Reloc - perform the R_PPC_UADDR32 relocation
- *
- * This routine handles the R_PPC_UADDR32 relocation (word32, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparc22Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value, tmpVal;
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- tmpVal = *((UINT32 *) pAdrs);
- tmpVal &= (unsigned int)0xffc00000;
- tmpVal |= (unsigned int)value;
- *((UINT32 *)pAdrs) = (UINT32) tmpVal;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcUaddr16Reloc - perform the R_PPC_UADDR16 relocation
- *
- * This routine handles the R_PPC_UADDR16 relocation (half16, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparc13Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value, tmpVal;
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- tmpVal = *((UINT32 *) pAdrs);
- tmpVal &= (unsigned int)0xfffe0000;
- tmpVal |= (unsigned int)value;
- *((UINT32 *)pAdrs) = (UINT32) tmpVal;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcRel32Reloc - perform the R_PPC_REL32 relocation
- *
- * This routine handles the R_PPC_REL32 relocation (word32, S + A - P).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcLo10Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value, tmpVal;
- value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend) & 0x3ff;
- tmpVal = *((UINT32 *) pAdrs);
- tmpVal &= (unsigned int)0xfffffc00;
- tmpVal |= (unsigned int)value;
- *((UINT32 *)pAdrs) = tmpVal;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcEmbNaddr32Reloc - perform the R_PPC_EMB_NADDR32 relocation
- *
- * This routine handles the R_PPC_EMB_NADDR32 relocation (uword32, A - S).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcPc10Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value, tmpVal;
- value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32)pAdrs))&0x3ff;
- tmpVal = *((UINT32 *) pAdrs);
- tmpVal &= (unsigned int)0xfffffc00;
- tmpVal |= (unsigned int)value;
- *((UINT32 *)pAdrs) = (UINT32) tmpVal;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcEmbNaddr16Reloc - perform the R_PPC_EMB_NADDR16 relocation
- *
- * This routine handles the R_PPC_EMB_NADDR16 relocation (uhalf16, A - S).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcPc22Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value, tmpVal;
- value = ((UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32)pAdrs))>>10;
- tmpVal = *((UINT32 *) pAdrs);
- tmpVal &= (unsigned int)0xffc00000;
- tmpVal |= (unsigned int)value;
- *((UINT32 *)pAdrs) = (UINT32) tmpVal;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfSparcEmbNaddr16LoReloc - perform the R_PPC_EMB_NADDR16_LO relocation
- *
- * This routine handles the R_PPC_EMB_NADDR16_LO relocation (uhalf16,
- * #lo (A - S)).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfSparcUa32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- unsigned int value;
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT32 *)pAdrs) = (UINT32) value;
- return (OK);
- }
- #endif /* (CPU_FAMILY == SIMSPARCSOLARIS) */
- #if (CPU_FAMILY == COLDFIRE)
- /*******************************************************************************
- *
- * elfM68kSegReloc - perform relocation for the M68k family
- *
- * This routine reads the specified relocation command segment and performs
- * all the relocations specified therein. Only relocation command from sections
- * with section type SHT_RELA are considered here.
- *
- * Absolute symbol addresses are looked up in the 'externals' table.
- *
- * RETURNS: OK or ERROR
- */
- STATUS elfM68kSegReloc
- (
- int fd, /* file to read in */
- MODULE_ID moduleId, /* module id */
- int loadFlag, /* not used */
- int posCurRelocCmd,/* position of current relocation command */
- Elf32_Shdr * pScnHdrTbl, /* pointer to section header table */
- Elf32_Shdr * pRelHdr, /* pointer to relocation section header */
- SCN_ADRS * pScnAddr, /* section address once loaded */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- Elf32_Sym * pSymsArray, /* pointer to symbols array */
- SYMTAB_ID symTbl, /* not used */
- SEG_INFO * pSeg /* section addresses and sizes */
- )
- {
- Elf32_Shdr * pScnHdr; /* section to which the relocations apply */
- Elf32_Rela relocCmd; /* relocation structure */
- UINT32 relocNum; /* number of reloc entries in section */
- UINT32 relocIdx; /* index of the reloc entry being processed */
- void * pAdrs; /* relocation address */
- Elf32_Sym * pSym; /* pointer to an external symbol */
- STATUS status = OK; /* whether or not the relocation was ok */
- pScnHdr = pScnHdrTbl + pRelHdr->sh_info;
- /* Some sanity checking */
- if (pRelHdr->sh_type != SHT_RELA)
- {
- errnoSet (S_loadElfLib_RELA_SECTION);
- printErr ("Relocation sections of type %d are not supported.n",
- pRelHdr->sh_type);
- return (OK);
- }
- if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))
- {
- printErr ("Wrong relocation entry size.n");
- errnoSet (S_loadElfLib_RELA_SECTION);
- return (ERROR);
- }
- /* Relocation loop */
- relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
- for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
- {
- /* read relocation command */
- posCurRelocCmd = elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd);
- /*
- * Calculate actual remote address that needs relocation, and
- * perform external or section relative relocation.
- */
- pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
- pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);
- /*
- * System V ABI defines the following notations:
- *
- * A - the addend used to compute the value of the relocatable field.
- * S - the value (address) of the symbol whose index resides in the
- * relocation entry. Note that this function uses the value stored
- * in the external symbol value array instead of the symbol's
- * st_value field.
- * P - the place (section offset or address) of the storage unit being
- * relocated (computed using r_offset) prior to the relocation.
- */
- switch (ELF32_R_TYPE (relocCmd.r_info) & 0x7f)
- {
- case R_68K_32:
- if (elfM68k32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case R_68K_16:
- if (elfM68k16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case R_68K_PC32:
- if (elfM68kDisp32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- case R_68K_PC16:
- if (elfM68kDisp16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)
- status = ERROR;
- break;
- default:
- printErr ("Unsupported relocation type %dn",
- ELF32_R_TYPE (relocCmd.r_info));
- status = ERROR;
- break;
- }
- }
- return (status);
- }
- /******************************************************************************
- *
- * elfM68k32Reloc - perform the R_68K_32 relocation
- *
- * This routine handles the R_68K_32 relocation (S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfM68k32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT32 *)pAdrs) = (UINT32) value;
- return (OK);
- }
- /******************************************************************************
- *
- * elfM68k16Reloc - perform the R_68K_16 relocation
- *
- * This routine handles the R_68K_16 relocation (S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfM68k16Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend;
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfM68kDisp32Reloc - perform the R_68K_PC32 relocation
- *
- * This routine handles the R_68K_PC32 relocation (S + A - P).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfM68kDisp32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32) pAdrs);
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- /*******************************************************************************
- *
- * elfM68kDisp16Reloc - perform the R_68K_PC16 relocation
- *
- * This routine handles the R_68K_PC16 relocation (S + A - P).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfM68kDisp16Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl /* array of absolute symbol values */
- )
- {
- UINT32 value; /* relocation value */
- value = (UINT32) symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend - ((UINT32) pAdrs);
- *((UINT16 *)pAdrs) = (UINT16) value;
- return (OK);
- }
- #endif /* (CPU_FAMILY == COLDFIRE) */
- #if (CPU_FAMILY == SH)
- /*******************************************************************************
- *
- * elfShSegReloc - perform relocation for the Super Hitachi family
- *
- * This routine reads the specified relocation command segment and performs
- * all the relocations specified therein. Only relocation command from sections
- * with section type SHT_RELA are considered here.
- *
- * Absolute symbol addresses are looked up in the 'externals' table.
- *
- * This function handles the following types of relocation commands
- * for the SH processor:
- *
- * R_SH_NONE
- * R_SH_DIR32
- * R_SH_REL32
- * R_SH_DIR8WPN
- * R_SH_IND12W
- * R_SH_DIR8WPL
- * R_SH_DIR8WPZ
- * R_SH_DIR8BP
- * R_SH_DIR8W
- * R_SH_DIR8L
- *
- * The remaining relocs are a GNU extension used for relaxation. We
- * use the same constants as COFF uses, not that it really matters.
- *
- * R_SH_SWITCH16
- * R_SH_SWITCH32
- * R_SH_USES
- * R_SH_COUNT
- * R_SH_ALIGN
- * R_SH_CODE
- * R_SH_DATA
- * R_SH_LABEL
- *
- *
- * RETURNS: OK or ERROR
- */
- LOCAL STATUS elfShSegReloc
- (
- int fd, /* file to read in */
- MODULE_ID moduleId, /* module id */
- int loadFlag, /* not used */
- int posCurRelocCmd,/* position of current relocation command */
- Elf32_Shdr * pScnHdrTbl, /* not used */
- Elf32_Shdr * pRelHdr, /* pointer to relocation section header */
- SCN_ADRS * pScnAddr, /* section address once loaded */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- Elf32_Sym * pSymsArray, /* pointer to symbols array */
- SYMTAB_ID symTbl, /* not used */
- SEG_INFO * pSeg /* section addresses and sizes */
- )
- {
- Elf32_Rela relocCmd; /* relocation structure */
- UINT32 relocNum; /* number of reloc entries in section */
- UINT32 relocIdx; /* index of the reloc entry being processed */
- void * pAdrs; /* relocation address */
- Elf32_Sym * pSym; /* pointer to an external symbol */
- STATUS status = OK; /* whether or not the relocation was ok */
- /* Some sanity checking */
- if (pRelHdr->sh_type != SHT_RELA)
- {
- errnoSet (S_loadElfLib_RELA_SECTION);
- return (OK);
- }
- if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))
- {
- errnoSet (S_loadElfLib_RELA_SECTION);
- return (ERROR);
- }
- /* Relocation loop */
- relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;
- for (relocIdx = 0; relocIdx < relocNum; relocIdx++)
- {
- /* read relocation command */
- if ((posCurRelocCmd =
- elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd)) == ERROR)
- {
- errnoSet (S_loadElfLib_READ_SECTIONS);
- return (ERROR);
- }
- /*
- * Calculate actual remote address that needs relocation, and
- * perform external or section relative relocation.
- */
- pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);
- pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);
- /*
- * System V ABI defines the following notations:
- *
- * A - the addend used to compute the value of the relocatable field.
- * S - the value (address) of the symbol whose index resides in the
- * relocation entry. Note that this function uses the value stored
- * in the external symbol value array instead of the symbol's
- * st_value field.
- * P - the place (section offset or address) of the storage unit being
- * relocated (computed using r_offset) prior to the relocation.
- */
- switch (ELF32_R_TYPE (relocCmd.r_info))
- {
- case (R_SH_NONE): /* none */
- break;
- case (R_SH_DIR32):
- if (elfShDir32Reloc (pAdrs, &relocCmd, symInfoTbl,
- moduleId) != OK)
- status = ERROR;
- break;
- default:
- printErr ("Unsupported relocation type %dn",
- ELF32_R_TYPE (relocCmd.r_info));
- status = ERROR;
- break;
- }
- }
- return (status);
- }
- /*******************************************************************************
- *
- * elfShDir32Reloc - perform the R_SH_DIR32 relocation
- *
- * This routine handles the R_SH_DIR32 relocation (word32, S + A).
- *
- * RETURNS : OK or ERROR if computed value can't be written down in target
- * memory.
- */
- LOCAL STATUS elfShDir32Reloc
- (
- void * pAdrs, /* relocation address */
- Elf32_Rela * pRelocCmd, /* points to a relocation structure */
- SYM_INFO_TBL symInfoTbl, /* array of absolute symbol values and types */
- MODULE_ID moduleId /* module id */
- )
- {
- UINT32 value; /* relocation value */
- UINT32 oldValue;
- oldValue = *(UINT32 *)pAdrs;
- value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +
- pRelocCmd->r_addend + oldValue;
- *((UINT32 *)pAdrs) = value;
- return (OK);
- }
- #endif /* CPU_FAMILY == SH */
- /*******************************************************************************
- *
- * loadElfInit - initialize the system for ELF load modules
- *
- * This routine initializes VxWorks to use the ELF (executable and linking format)
- * object module format for loading modules.
- *
- * RETURNS: OK (always)
- *
- * SEE ALSO: loadModuleAt()
- */
- STATUS loadElfInit (void)
- {
- loadRoutine = (FUNCPTR)loadElfFmtManage;
- #if (CPU_FAMILY == I80X86)
- elfI86Init (&pElfModuleVerifyRtn, &pElfSegRelRtn);
- #endif /* CPU_FAMILY */
- #if (CPU_FAMILY == ARM)
- elfArmInit (&pElfModuleVerifyRtn, &pElfSegRelRtn);
- #endif /* CPU_FAMILY */
- #if (CPU_FAMILY == MIPS)
- elfMipsInit (&pElfModuleVerifyRtn, &pElfSegRelRtn);
- #endif /* CPU_FAMILY */
- #ifdef INCLUDE_SDA
- /* Create new memory partitions for the SDA areas */
- if ((EM_ARCH_MACHINE == EM_PPC) || ((EM_ARCH_MACHINE == EM_SH))
- if (loadElfSdaCreate() == ERROR)
- return ERROR;
- #endif /* INCLUDE_SDA */
- return OK;
- }
- /******************************************************************************