📄 loadelflib.c
字号:
refhi_pst = pst; refhi_addr = relAddr; refhi_insn = insn; refhi_relocated = FALSE; /* Just go on to the next relocation. */ continue; case R_MIPS_LO16: DBG(("R_MIPS_LO16")); if (pst != refhi_pst) { errnoSet (S_loadElfLib_RELOC); return (ERROR); } x = relVal + ((refhi_insn << 16) + (short)insn); /* XXX ignore _gp_disp types ... */ x += ((x & 0x8000) << 1); /* relocate hi16 instruction */ if (!refhi_relocated) { hinsn = (refhi_insn & ~0xffff) | ((x >> 16) & 0xffff); *((UINT32 *) refhi_addr) = hinsn; DBG(("\n\tHI16:I\t0x%08x 0x%08x",refhi_addr,hinsn)); refhi_relocated = TRUE; } DBG(("\n\tLO16")); /* relocate lo16 instruction */ insn = (insn & ~0xffff) | (x & 0xffff); break; case R_MIPS_PC16: DBG(("R_MIPS_PC16")); /* FIXME: * +4 may be needed on pc; abi spec doesn't * mention shift by 2 */ x = ((short)insn << 2) + relVal - (UINT32)relAddr; if (x > 0x1ffff || x < -0x20000) { errnoSet (S_loadElfLib_RELOC); return (ERROR); } insn = (insn & ~0xffff) | ((x >> 2) & 0xffff); break; case R_MIPS_GPREL16: case R_MIPS_LITERAL: case R_MIPS_GPREL32: errnoSet (S_loadElfLib_GPREL_REFERENCE); printErr ("Can't relocate recompile module with -G 0 flags.\n"); return (ERROR); case R_MIPS_CALL16: case R_MIPS_REL32: case R_MIPS_GOT16: errnoSet (S_loadElfLib_UNSUPPORTED); return (ERROR); default: errnoSet (S_loadElfLib_UNRECOGNIZED_RELOCENTRY); printErr ("Unrecognized relocation type %d\n", ELF32_R_TYPE (relocCmd.r_info)); return (ERROR); } if (ELF32_R_TYPE(relocCmd.r_info) == R_MIPS_16) { DBG((":S\t0x%08x 0x%08x\n", relAddr,insn)); *((UINT16 *) relAddr)= (UINT16) insn; } else { DBG((":I\t0x%08x 0x%08x\n",relAddr,insn)); *((UINT32 *) relAddr)= insn; } } return (OK); }/**************************************************************************** elfMipsSegReloc - perform relocation commands for mips segments** This routine reads the relocation command segments and performs all the * relocations specified therein. The relocation commands reside in the * sections with section type SHT_RELA or SHT_REL.** RETURNS: OK or ERROR** NOMANUAL*/LOCAL STATUS elfMipsSegReloc ( 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 */ ) { if (pRelHdr->sh_type == SHT_RELA && (UINT8 *)*pScnAddr != 0) { if (relMipsSegmentRela (fd, pRelHdr, pScnAddr, pSymsArray, posCurRelocCmd, symInfoTbl) != OK) return (ERROR); } else if (pRelHdr->sh_type == SHT_REL && (UINT8 *)*pScnAddr != 0) { if (relMipsSegmentRel (fd, pRelHdr, pScnAddr, pSymsArray, posCurRelocCmd, symInfoTbl) != OK) return (ERROR); } return (OK); }#endif /* (CPU_FAMILY == MIPS) */#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 */ 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)) { 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 %d\n", 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 symInfoT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -