📄 elfarm.c
字号:
addend = addend << 2; /* byte offset */ addend = SIGN_EXTEND (addend, 26); /* sign extend */ if (sh_type == SHT_RELA) { /* * The ARM ELF ABI specifies that with RELA, the addend is the sum * of the value extracted from the storage unit being relocated and * the addend field in the relocation instruction. */ addend += relocAddend; } value = (UINT32)pSymAdrs - (UINT32)pRelocAdrs + addend; /* * Do some checking: R_ARM_PC24 relocation must fit in 26 bits and * lowest 2 bits should always be zero. It will then be shifted right * two bits so that it is a 24-bit, signed, word offset. */ if (!CHECK_FITS (value, 26)) { printErr ("Relocation value does not fit in 26 bits.\n"); errnoSet (S_loadElfLib_RELOC); return ERROR; } if (value & 0x3) { printErr ("Relocation value's lowest 2 bits not zero.\n"); errnoSet (S_loadElfLib_RELOC); return ERROR; } LOW24_INSERT (memValue, value >> 2); MEM_WRITE_32(pRelocAdrs, memValue); return OK; }/********************************************************************************* elfArmAbs32Reloc - perform the R_ARM_ABS32 relocation ** This routine handles the R_ARM_ABS32 relocation (word32, S + A).** RETURNS : OK or ERROR if computed value can't be written down in target* memory.*/LOCAL STATUS elfArmAbs32Reloc ( Elf32_Word sh_type, /* Relocation sec. type (SHT_REL or SHT_RELA) */ void * pRelocAdrs, /* Relocation address */ void * pSymAdrs, /* Addr of sym involved in relocation */ Elf32_Sword relocAddend, /* Addend from reloc. - arg used for RELA only */ SYM_TYPE symType /* Type of symbol */ ) { UINT32 value; /* Relocation value */ UINT32 addend; /* Addend */ MEM_READ_32 (pRelocAdrs, addend); if (sh_type == SHT_RELA) { /* * The ARM ELF ABI specifies that with RELA, the addend is the sum * of the value extracted from the storage unit being relocated and * the addend field in the relocation instruction. */ addend += relocAddend; } value = (UINT32)pSymAdrs + addend; /* check for and handle Thumb */ /* XXX There's no mention of changing this bit in the ABI. This * approach is basically 'faked' interworking. There are special * relocation types that are designed to be used for cross links * between Thumb and ARM code (R_ARM_XPC25 and R_ARM_THM_XPC22) - * we don't currently support these, but that is the proper method * to use when we eventually support interworking. */ if (symType & SYM_THUMB) value |= 1; MEM_WRITE_32(pRelocAdrs, value); return OK; }/********************************************************************************* elfArmRel32Reloc - perform the R_ARM_REL32 relocation ** This routine handles the R_ARM_REL32 relocation (word32, S + A - P).** RETURNS : OK or ERROR if computed value can't be written down in target* memory.*/LOCAL STATUS elfArmRel32Reloc ( Elf32_Word sh_type, /* Relocation sec. type (SHT_REL or SHT_RELA) */ void * pRelocAdrs, /* Relocation address */ void * pSymAdrs, /* Addr of sym involved in relocation */ Elf32_Sword relocAddend /* Addend from reloc. - arg used for RELA only */ ) { UINT32 value; /* Relocation value */ UINT32 addend; /* Addend */ MEM_READ_32 (pRelocAdrs, addend); if (sh_type == SHT_RELA) { /* * The ARM ELF ABI specifies that with RELA, the addend is the sum * of the value extracted from the storage unit being relocated and * the addend field in the relocation instruction. */ addend += relocAddend; } value = (UINT32)pSymAdrs + addend - (UINT32)pRelocAdrs; MEM_WRITE_32 (pRelocAdrs, value); return OK; }/********************************************************************************* elfThumbPc22Reloc - perform the R_ARM_THM_PC22 relocation** This routine handles the R_ARM_THM_PC22 reloc (BL pair, (S - P + A) >> 1).** RETURNS : OK or ERROR if computed value can't be written down in target* memory or offset too large for relocation.*/LOCAL STATUS elfThumbPc22Reloc ( Elf32_Word sh_type, /* Relocation sec. type (SHT_REL or SHT_RELA) */ void * pRelocAdrs, /* Relocation address */ void * pSymAdrs, /* Addr of sym involved in relocation */ Elf32_Sword relocAddend /* Addend from reloc. - arg used for RELA only */ ) { UINT32 value; /* Relocation value */ UINT16 memValue1; /* Previous value in memory in first BL ins. */ UINT16 memValue2; /* Previous value in memory in first BL ins. */ UINT32 addend = 0; /* Relocation Addend extracted from memValue */ UINT32 tmp = 0; /* variable needed to extract addend bits */ MEM_READ_16 (pRelocAdrs, memValue1); MEM_READ_16 ((char *) pRelocAdrs+2, memValue2); /* * The offset should be stored in the relocation as 22 bits spread * between 2 words, sign-extended to 32 bits but, in case it's not, * we extract it and sign-extend it appropriately. */ LOW11_INSERT(addend, memValue1); addend = addend << 12; /* byte offset */ addend = SIGN_EXTEND (addend, 23); /* sign extend */ LOW11_INSERT(tmp, memValue2); addend += tmp << 1; if (sh_type == SHT_RELA) { /* * The ARM ELF ABI specifies that with RELA, the addend is the sum * of the value extracted from the storage unit being relocated and * the addend field in the relocation instruction. */ addend += relocAddend; } value = (UINT32)pSymAdrs - (UINT32)pRelocAdrs + addend; /* * Do some checking: R_ARM_THM_PC22 relocation must fit in 23 bits and * lowest bit should always be zero. */ if (!CHECK_FITS (value, 23)) { printErr ("Relocation value does not fit in 23 bits.\n"); errnoSet (S_loadElfLib_RELOC); return ERROR; } if (value & 1) { printErr ("Relocation value's lowest bit is not zero.\n"); errnoSet (S_loadElfLib_RELOC); return ERROR; } LOW11_INSERT (memValue1, value >> 12); LOW11_INSERT (memValue2, value >> 1); MEM_WRITE_16(pRelocAdrs, memValue1); MEM_WRITE_16((char *) pRelocAdrs+2, memValue2); return OK; }/********************************************************************************* elfThumbPc9Reloc - perform the R_ARM_THM_PC9 relocation ** This routine handles the R_ARM_THM_PC9 relocation (Bcc (S - P + A) << 1).** RETURNS : OK or ERROR if computed value can't be written down in target* memory or offset too large for relocation.*/LOCAL STATUS elfThumbPc9Reloc ( Elf32_Word sh_type, /* Relocation sec. type (SHT_REL or SHT_RELA) */ void * pRelocAdrs, /* Relocation address */ void * pSymAdrs, /* Addr of sym involved in relocation */ Elf32_Sword relocAddend /* Addend from reloc. - arg used for RELA only */ ) { UINT32 value; /* Relocation value */ UINT16 memValue; /* Previous value in memory */ UINT32 addend=0; /* Relocation addend extracted from memValue */ MEM_READ_16 (pRelocAdrs, memValue); LOW8_INSERT (addend, memValue); addend = addend << 1; /* halfword offset */ addend = SIGN_EXTEND(addend, 9); /* sign extend */ if (sh_type == SHT_RELA) { /* * The ARM ELF ABI specifies that with RELA, the addend is the sum * of the value extracted from the storage unit being relocated and * the addend field in the relocation instruction. */ addend += relocAddend; } value = (UINT32)pSymAdrs + addend - (UINT32)pRelocAdrs; /* Do some checking: R_ARM_THM_PC9 relocations must fit in 9 bits */ if (!CHECK_FITS (value, 9)) { printErr ("Relocation value does not fit in 9 bits.\n"); errnoSet (S_loadElfLib_RELOC); return ERROR; } if (value & 1) { printErr ("Relocation value's lowest bit is not zero.\n"); errnoSet (S_loadElfLib_RELOC); return ERROR; } LOW8_INSERT (memValue, value >> 1); MEM_WRITE_16 (pRelocAdrs, memValue); return OK; }/********************************************************************************* elfThumbPc11Reloc - perform the R_ARM_THM_PC11 relocation ** This routine handles the R_ARM_THM_PC11 relocation (B (S - P + A) << 1).** RETURNS : OK or ERROR if computed value can't be written down in target* memory or offset too large for relocation.*/LOCAL STATUS elfThumbPc11Reloc ( Elf32_Word sh_type, /* Relocation sec. type (SHT_REL or SHT_RELA) */ void * pRelocAdrs, /* Relocation address */ void * pSymAdrs, /* Addr of sym involved in relocation */ Elf32_Sword relocAddend /* Addend from reloc. - arg used for RELA only */ ) { UINT32 value; /* Relocation value */ UINT16 memValue; /* Previous value in memory */ UINT32 addend = 0; /* Relocation addend extracted from memValue */ MEM_READ_16 (pRelocAdrs, memValue); LOW11_INSERT (addend, memValue); addend = addend << 1; /* halfword offset */ addend = SIGN_EXTEND (addend, 12); /* sign extend */ if (sh_type == SHT_RELA) { /* * The ARM ELF ABI specifies that with RELA, the addend is the sum * of the value extracted from the storage unit being relocated and * the addend field in the relocation instruction. */ addend += relocAddend; } value = (UINT32)pSymAdrs + addend - (UINT32)pRelocAdrs; /* Do some checking: R_ARM_THM_PC11 relocations must fit in 12 bits */ if (!CHECK_FITS (value, 12)) { printErr ("Relocation value does not fit in 12 bits.\n"); errnoSet (S_loadElfLib_RELOC); return ERROR; } if (value & 1) { printErr ("Relocation value's lowest bit is not zero.\n"); errnoSet (S_loadElfLib_RELOC); return ERROR; } LOW11_INSERT (memValue, value >> 1); MEM_WRITE_16 (pRelocAdrs, memValue); return OK; }/******************************************************************************** elfArmModuleVerify - check the object module format for ARM target arch.** This routine contains the heuristic required to determine if the object* file belongs to the OMF handled by this OMF reader, with care for the target* architecture.* It is the underlying routine for loadElfModuleIsOk().** RETURNS: TRUE or FALSE if the object module can't be handled.*/LOCAL BOOL elfArmModuleVerify ( UINT32 machType, /* Module's target arch */ BOOL * sdaIsRequired /* TRUE if SDA are used by the arch */ ) { BOOL moduleIsForTarget = TRUE; /* TRUE if intended for target */ *sdaIsRequired = FALSE; if (machType != EM_ARCH_MACHINE) { moduleIsForTarget = FALSE; errnoSet (S_loadElfLib_HDR_READ); } return moduleIsForTarget; }/******************************************************************************** elfArmInit - Initialize arch-dependent parts of loader** This routine initializes the function pointers for module verification* and segment relocation.** RETURNS : OK*/STATUS elfArmInit ( FUNCPTR * pElfModuleVerifyRtn, FUNCPTR * pElfRelSegRtn ) { *pElfModuleVerifyRtn = &elfArmModuleVerify; *pElfRelSegRtn = &elfArmSegReloc; return OK; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -