📄 loadelflib.c
字号:
** 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;#if (CPU == PPC403) ELFOUTMSBU32 ((char *)pAdrs, value);#else *((UINT32 *)pAdrs) = value;#endif /* CPU == PPC403 */ 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 +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -