} else if (mEhdr->e_machine == EM_AARCH64) {\r
\r
switch (ELF_R_TYPE(Rel->r_info)) {\r
+ INT64 Offset;\r
+\r
+ case R_AARCH64_LD64_GOT_LO12_NC:\r
+ //\r
+ // Convert into an ADD instruction - see R_AARCH64_ADR_GOT_PAGE below.\r
+ //\r
+ *(UINT32 *)Targ &= 0x3ff;\r
+ *(UINT32 *)Targ |= 0x91000000 | ((Sym->st_value & 0xfff) << 10);\r
+ break;\r
+\r
+ case R_AARCH64_ADR_GOT_PAGE:\r
+ //\r
+ // This relocation points to the GOT entry that contains the absolute\r
+ // address of the symbol we are referring to. Since EDK2 only uses\r
+ // fully linked binaries, we can avoid the indirection, and simply\r
+ // refer to the symbol directly. This implies having to patch the\r
+ // subsequent LDR instruction (covered by a R_AARCH64_LD64_GOT_LO12_NC\r
+ // relocation) into an ADD instruction - this is handled above.\r
+ //\r
+ Offset = (Sym->st_value - (Rel->r_offset & ~0xfff)) >> 12;\r
+\r
+ *(UINT32 *)Targ &= 0x9000001f;\r
+ *(UINT32 *)Targ |= ((Offset & 0x1ffffc) << (5 - 2)) | ((Offset & 0x3) << 29);\r
+\r
+ /* fall through */\r
\r
case R_AARCH64_ADR_PREL_PG_HI21:\r
//\r
// Attempt to convert the ADRP into an ADR instruction.\r
// This is only possible if the symbol is within +/- 1 MB.\r
//\r
- INT64 Offset;\r
\r
// Decode the ADRP instruction\r
Offset = (INT32)((*(UINT32 *)Targ & 0xffffe0) << 8);\r
case R_AARCH64_LDST32_ABS_LO12_NC:\r
case R_AARCH64_LDST64_ABS_LO12_NC:\r
case R_AARCH64_LDST128_ABS_LO12_NC:\r
+ case R_AARCH64_ADR_GOT_PAGE:\r
+ case R_AARCH64_LD64_GOT_LO12_NC:\r
//\r
// No fixups are required for relative relocations, provided that\r
// the relative offsets between sections have been preserved in\r