CRO0: Difference between revisions
Add headers to all the structs |
m Relocation code |
||
Line 347: | Line 347: | ||
| 0x4 | | 0x4 | ||
| 0x1 | | 0x1 | ||
| Patch type (0= | | Patch type (R_ARM_NONE = 0, R_ARM_ABS32 = 2, R_ARM_REL32 = 3, R_ARM_THM_PC22 = 10, R_ARM_CALL = 28, R_ARM_JUMP24 = 29, R_ARM_TARGET1 = 38, R_ARM_PREL31 = 42) | ||
|- | |- | ||
| 0x5 | | 0x5 | ||
Line 366: | Line 366: | ||
|} | |} | ||
Relocation code from RO: | |||
---- | static Result writePatch(u32* out, u32 patchType, u32 addend, u32 base, u32 inputPtr) { | ||
const s32 branchOffset = inputPtr - base; | |||
u32 offset = base + addend - inputPtr; | |||
if (patchType == R_ARM_NONE) | |||
return 0; | |||
if (patchType == R_ARM_ABS32 || patchType == R_ARM_TARGET1) { | |||
*out = base + addend; | |||
return 0; | |||
} | |||
if (patchType == R_ARM_REL32) { | |||
*out = offset; | |||
return 0; | |||
} | |||
if (patchType == R_ARM_THM_PC22) { | |||
// +-4MB. | |||
if (branchOffset >= 0x400000 || branchOffset <= -0x400000) | |||
return 0xD9012C23; | |||
if (base & 1) { | |||
*out = (((offset >> 12) | 0xF000) << 16) | ((offset << 4) >> 5) | 0xF800; | |||
} else { | |||
if (offset & 2) | |||
offset += 2; | |||
*out = ((offset >> 12) | 0xF000) << 16 | ((offset << 4) >> 5) | 0xE800; | |||
} | |||
return 0; | |||
} | |||
if (patchType == R_ARM_CALL) { | |||
// +-32MB. | |||
if (branchOffset >= 0x2000000 || branchOffset <= -0x2000000) | |||
return 0xD9012C23; | |||
if (base & 1) { | |||
*out = ((offset << 23) & 0x1000000) | ((offset << 6) >> 8) | 0xFA000000; | |||
} else { | |||
*out = 0xEB000000 | ((offset << 6) >> 8); | |||
} | |||
return 0; | |||
} | |||
if (patchType == R_ARM_JUMP24) { | |||
// +-32MB. | |||
if (branchOffset >= 0x2000000 || branchOffset <= -0x2000000 || (base & 1)) | |||
return 0xD9012C23; | |||
*out = (*out & 0xFF000000) | ((offset << 6) >> 8); | |||
return 0; | |||
} | |||
if (patchType == R_ARM_PREL31) { | |||
*out = addend + ((base << 1) >> 1) - inputPtr; | |||
return 0; | |||
} | |||
return 0xD9012C22; | |||
} |