]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/Elf64Convert.c
BaseTools/GenFw AARCH64: disregard ADRP instructions that are patched already
[mirror_edk2.git] / BaseTools / Source / C / GenFw / Elf64Convert.c
index 28f27ab97bdf2e27c7a90b25d4f828834665ca2d..d623dce1f9da020f110de1dd14d1182e9f90818a 100644 (file)
@@ -4,13 +4,7 @@ Elf64 convert solution
 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
 Portions copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
 \r
-This program and the accompanying materials are licensed and made available\r
-under the terms and conditions of the BSD License which accompanies this\r
-distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -1023,8 +1017,46 @@ WriteSections64 (
         } 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
+            // In order to handle Cortex-A53 erratum #843419, the LD linker may\r
+            // convert ADRP instructions into ADR instructions, but without\r
+            // updating the static relocation type, and so we may end up here\r
+            // while the instruction in question is actually ADR. So let's\r
+            // just disregard it: the section offset check we apply below to\r
+            // ADR instructions will trigger for its R_AARCH64_xxx_ABS_LO12_NC\r
+            // companion instruction as well, so it is safe to omit it here.\r
+            //\r
+            if ((*(UINT32 *)Targ & BIT31) == 0) {\r
+              break;\r
+            }\r
+\r
             //\r
             // AArch64 PG_H21 relocations are typically paired with ABS_LO12\r
             // relocations, where a PC-relative reference with +/- 4 GB range is\r
@@ -1043,7 +1075,6 @@ WriteSections64 (
               // 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
@@ -1218,6 +1249,8 @@ WriteRelocations64 (
             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