|
@@ -635,6 +635,33 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
|
|
*/
|
|
*/
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
+ case R_PPC64_ENTRY:
|
|
|
|
+ /*
|
|
|
|
+ * Optimize ELFv2 large code model entry point if
|
|
|
|
+ * the TOC is within 2GB range of current location.
|
|
|
|
+ */
|
|
|
|
+ value = my_r2(sechdrs, me) - (unsigned long)location;
|
|
|
|
+ if (value + 0x80008000 > 0xffffffff)
|
|
|
|
+ break;
|
|
|
|
+ /*
|
|
|
|
+ * Check for the large code model prolog sequence:
|
|
|
|
+ * ld r2, ...(r12)
|
|
|
|
+ * add r2, r2, r12
|
|
|
|
+ */
|
|
|
|
+ if ((((uint32_t *)location)[0] & ~0xfffc)
|
|
|
|
+ != 0xe84c0000)
|
|
|
|
+ break;
|
|
|
|
+ if (((uint32_t *)location)[1] != 0x7c426214)
|
|
|
|
+ break;
|
|
|
|
+ /*
|
|
|
|
+ * If found, replace it with:
|
|
|
|
+ * addis r2, r12, (.TOC.-func)@ha
|
|
|
|
+ * addi r2, r12, (.TOC.-func)@l
|
|
|
|
+ */
|
|
|
|
+ ((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value);
|
|
|
|
+ ((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value);
|
|
|
|
+ break;
|
|
|
|
+
|
|
case R_PPC64_REL16_HA:
|
|
case R_PPC64_REL16_HA:
|
|
/* Subtract location pointer */
|
|
/* Subtract location pointer */
|
|
value -= (unsigned long)location;
|
|
value -= (unsigned long)location;
|