]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg/BasePeCoff: Add LoongArch PE/Coff related code.
authorChao Li <lichao@loongson.cn>
Mon, 29 Nov 2021 04:29:58 +0000 (12:29 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 14 Oct 2022 02:16:33 +0000 (02:16 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4053

Add LoongArch image relocation.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Chao Li <lichao@loongson.cn>
Co-authored-by: Baoqi Zhang <zhangbaoqi@loongson.cn>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
MdePkg/Library/BasePeCoffLib/BasePeCoff.c
MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni
MdePkg/Library/BasePeCoffLib/LoongArch/PeCoffLoaderEx.c [new file with mode: 0644]

index 6d8d9faeb86a7be50cdbc74f7bce0f361cc04393..97a8aaf8c73d3e3cdbb6276dbd8cdfdbbc591ece 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
   Base PE/COFF loader supports loading any PE32/PE32+ or TE image, but\r
-  only supports relocating IA32, x64, IPF, ARM, RISC-V and EBC images.\r
+  only supports relocating IA32, x64, IPF, ARM, RISC-V, LoongArch and EBC images.\r
 \r
   Caution: This file requires additional review when modified.\r
   This library will have external input - PE/COFF image.\r
@@ -18,6 +18,7 @@
   Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
   Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
   Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+  Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
index 110b6d5a090af5d4d6b72db3d0e363ef5b993823..3b8b8eb1917df0f05641883aa0c346bc442302f2 100644 (file)
@@ -4,6 +4,7 @@
 #  The IA32 version library support loading IA32, X64 and EBC PE/COFF images.\r
 #  The X64 version library support loading IA32, X64 and EBC PE/COFF images.\r
 #  The RISC-V version library support loading RISC-V images.\r
+#  The LoongArch version library support loading LoongArch images.\r
 #\r
 #  Caution: This module requires additional review when modified.\r
 #  This library will have external input - PE/COFF image.\r
@@ -13,6 +14,7 @@
 #  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
 #  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
 #  Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+#  Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -46,6 +48,9 @@
 [Sources.RISCV64]\r
   RiscV/PeCoffLoaderEx.c\r
 \r
+[Sources.LOONGARCH64]\r
+  LoongArch/PeCoffLoaderEx.c\r
+\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
 \r
index 55417029f2098c3fe0c5153e2927cdaf9d1512e8..1f731344e121eead32c2d58aff844b3393036987 100644 (file)
@@ -5,6 +5,7 @@
 // The IA32 version library support loading IA32, X64 and EBC PE/COFF images.\r
 // The X64 version library support loading IA32, X64 and EBC PE/COFF images.\r
 // The RISC-V version library support loading RISC-V32 and RISC-V64 PE/COFF images.\r
+// The LoongArch version library support loading LoongArch32 and LoongArch64 PE/COFF images.\r
 //\r
 // Caution: This module requires additional review when modified.\r
 // This library will have external input - PE/COFF image.\r
@@ -14,6 +15,7 @@
 // Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
 // Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
 // Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+// Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
 //\r
 // SPDX-License-Identifier: BSD-2-Clause-Patent\r
 //\r
diff --git a/MdePkg/Library/BasePeCoffLib/LoongArch/PeCoffLoaderEx.c b/MdePkg/Library/BasePeCoffLib/LoongArch/PeCoffLoaderEx.c
new file mode 100644 (file)
index 0000000..417096f
--- /dev/null
@@ -0,0 +1,137 @@
+/** @file\r
+  PE/Coff loader for LoongArch PE image\r
+\r
+  Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#include "BasePeCoffLibInternals.h"\r
+#include <Library/BaseLib.h>\r
+\r
+/**\r
+  Performs an LoongArch specific relocation fixup and is a no-op on other\r
+  instruction sets.\r
+\r
+  @param[in]       Reloc       Pointer to the relocation record.\r
+  @param[in, out]  Fixup       Pointer to the address to fix up.\r
+  @param[in, out]  FixupData   Pointer to a buffer to log the fixups.\r
+  @param[in]       Adjust      The offset to adjust the fixup.\r
+\r
+  @return Status code.\r
+\r
+**/\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateImageEx (\r
+  IN UINT16     *Reloc,\r
+  IN OUT CHAR8  *Fixup,\r
+  IN OUT CHAR8  **FixupData,\r
+  IN UINT64     Adjust\r
+  )\r
+{\r
+  UINT8   RelocType;\r
+  UINT64  Value;\r
+  UINT64  Tmp1;\r
+  UINT64  Tmp2;\r
+\r
+  RelocType = (*Reloc) >> 12;\r
+  Value     = 0;\r
+  Tmp1      = 0;\r
+  Tmp2      = 0;\r
+\r
+  switch (RelocType) {\r
+    case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:\r
+      // The next four instructions are used to load a 64 bit address, relocate all of them\r
+      Value = (*(UINT32 *)Fixup & 0x1ffffe0) << 7 |       // lu12i.w 20bits from bit5\r
+              (*((UINT32 *)Fixup + 1) & 0x3ffc00) >> 10;  // ori     12bits from bit10\r
+      Tmp1   = *((UINT32 *)Fixup + 2) & 0x1ffffe0;        // lu32i.d 20bits from bit5\r
+      Tmp2   = *((UINT32 *)Fixup + 3) & 0x3ffc00;         // lu52i.d 12bits from bit10\r
+      Value  = Value | (Tmp1 << 27) | (Tmp2 << 42);\r
+      Value += Adjust;\r
+\r
+      *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5);\r
+      if (*FixupData != NULL) {\r
+        *FixupData              = ALIGN_POINTER (*FixupData, sizeof (UINT32));\r
+        *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;\r
+        *FixupData              = *FixupData + sizeof (UINT32);\r
+      }\r
+\r
+      Fixup           += sizeof (UINT32);\r
+      *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | ((Value & 0xfff) << 10);\r
+      if (*FixupData != NULL) {\r
+        *FixupData              = ALIGN_POINTER (*FixupData, sizeof (UINT32));\r
+        *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;\r
+        *FixupData              = *FixupData + sizeof (UINT32);\r
+      }\r
+\r
+      Fixup           += sizeof (UINT32);\r
+      *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5);\r
+      if (*FixupData != NULL) {\r
+        *FixupData              = ALIGN_POINTER (*FixupData, sizeof (UINT32));\r
+        *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;\r
+        *FixupData              = *FixupData + sizeof (UINT32);\r
+      }\r
+\r
+      Fixup           += sizeof (UINT32);\r
+      *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10);\r
+      if (*FixupData != NULL) {\r
+        *FixupData              = ALIGN_POINTER (*FixupData, sizeof (UINT32));\r
+        *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;\r
+        *FixupData              = *FixupData + sizeof (UINT32);\r
+      }\r
+\r
+      break;\r
+    default:\r
+      return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Returns TRUE if the machine type of PE/COFF image is supported. Supported\r
+  does not mean the image can be executed it means the PE/COFF loader supports\r
+  loading and relocating of the image type. It's up to the caller to support\r
+  the entry point.\r
+\r
+  @param[in]  Machine   Machine type from the PE Header.\r
+\r
+  @return TRUE if this PE/COFF loader can load the image\r
+\r
+**/\r
+BOOLEAN\r
+PeCoffLoaderImageFormatSupported (\r
+  IN  UINT16  Machine\r
+  )\r
+{\r
+  if (Machine == IMAGE_FILE_MACHINE_LOONGARCH64) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Performs an LOONGARCH-based specific re-relocation fixup and is a no-op on other\r
+  instruction sets. This is used to re-relocated the image into the EFI virtual\r
+  space for runtime calls.\r
+\r
+  @param[in]       Reloc       The pointer to the relocation record.\r
+  @param[in, out]  Fixup       The pointer to the address to fix up.\r
+  @param[in, out]  FixupData   The pointer to a buffer to log the fixups.\r
+  @param[in]       Adjust      The offset to adjust the fixup.\r
+\r
+  @return Status code.\r
+\r
+**/\r
+RETURN_STATUS\r
+PeHotRelocateImageEx (\r
+  IN UINT16     *Reloc,\r
+  IN OUT CHAR8  *Fixup,\r
+  IN OUT CHAR8  **FixupData,\r
+  IN UINT64     Adjust\r
+  )\r
+{\r
+  // To check\r
+  return PeCoffLoaderRelocateImageEx (Reloc, Fixup, FixupData, Adjust);\r
+}\r