Elf_Shdr *SymShdr;\r
UINT8 *Targ;\r
\r
+ //\r
+ // The _GLOBAL_OFFSET_TABLE_ symbol is not actually an absolute symbol,\r
+ // but carries the SHN_ABS section index for historical reasons.\r
+ // It must be accompanied by a R_*_GOT_* type relocation on a\r
+ // subsequent instruction, which we handle below, specifically to avoid\r
+ // the GOT indirection, and to refer to the symbol directly. This means\r
+ // we can simply disregard direct references to the GOT symbol itself,\r
+ // as the resulting value will never be used.\r
+ //\r
+ if (Sym->st_shndx == SHN_ABS) {\r
+ const UINT8 *SymName = GetSymName (Sym);\r
+ if (strcmp ((CHAR8 *)SymName, "_GLOBAL_OFFSET_TABLE_") == 0) {\r
+ continue;\r
+ }\r
+ }\r
+\r
//\r
// Check section header index found in symbol table and get the section\r
// header location.\r
switch (ELF_R_TYPE(Rel->r_info)) {\r
INT64 Offset;\r
\r
+ case R_AARCH64_LD64_GOTOFF_LO15:\r
+ case R_AARCH64_LD64_GOTPAGE_LO15:\r
+ //\r
+ // Convert into an ADR instruction that refers to the symbol directly.\r
+ //\r
+ Offset = Sym->st_value - Rel->r_offset;\r
+\r
+ *(UINT32 *)Targ &= 0x1000001f;\r
+ *(UINT32 *)Targ |= ((Offset & 0x1ffffc) << (5 - 2)) | ((Offset & 0x3) << 29);\r
+\r
+ if (Offset < -0x100000 || Offset > 0xfffff) {\r
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s failed to relax GOT based symbol reference - image is too big (>1 MiB).",\r
+ mInImageName);\r
+ break;\r
+ }\r
+ break;\r
+\r
case R_AARCH64_LD64_GOT_LO12_NC:\r
//\r
// Convert into an ADD instruction - see R_AARCH64_ADR_GOT_PAGE below.\r
case R_AARCH64_LDST128_ABS_LO12_NC:\r
case R_AARCH64_ADR_GOT_PAGE:\r
case R_AARCH64_LD64_GOT_LO12_NC:\r
+ case R_AARCH64_LD64_GOTOFF_LO15:\r
+ case R_AARCH64_LD64_GOTPAGE_LO15:\r
//\r
// No fixups are required for relative relocations, provided that\r
// the relative offsets between sections have been preserved in\r