]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/Elf32Convert.c
Sync BaseTools Branch (version r2149) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / C / GenFw / Elf32Convert.c
index 539fdf560a4a37afbef509375c85703f539036a4..42ae35bfef27a0553a65dbcbac4443a24d204957 100644 (file)
@@ -1,6 +1,6 @@
 /** @file
 
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
 
 This program and the accompanying materials are licensed and made available
 under the terms and conditions of the BSD License which accompanies this
@@ -263,6 +263,7 @@ ScanSections32 (
   EFI_IMAGE_DOS_HEADER            *DosHdr;
   EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
   UINT32                          CoffEntry;
+  UINT32                          SectionCount;
 
   CoffEntry = 0;
   mCoffOffset = 0;
@@ -291,6 +292,7 @@ ScanSections32 (
   //
   mCoffOffset = CoffAlign(mCoffOffset);
   mTextOffset = mCoffOffset;
+  SectionCount = 0;
   for (i = 0; i < mEhdr->e_shnum; i++) {
     Elf_Shdr *shdr = GetShdrByIndex(i);
     if (IsTextShdr(shdr)) {
@@ -315,6 +317,7 @@ ScanSections32 (
       }
       mCoffSectionsOffset[i] = mCoffOffset;
       mCoffOffset += shdr->sh_size;
+      SectionCount ++;
     }
   }
 
@@ -322,10 +325,15 @@ ScanSections32 (
     mCoffOffset = CoffAlign(mCoffOffset);
   }
 
+  if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {
+    Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName);
+  }
+
   //
   //  Then data sections.
   //
   mDataOffset = mCoffOffset;
+  SectionCount = 0;
   for (i = 0; i < mEhdr->e_shnum; i++) {
     Elf_Shdr *shdr = GetShdrByIndex(i);
     if (IsDataShdr(shdr)) {
@@ -344,10 +352,15 @@ ScanSections32 (
       }
       mCoffSectionsOffset[i] = mCoffOffset;
       mCoffOffset += shdr->sh_size;
+      SectionCount ++;
     }
   }
   mCoffOffset = CoffAlign(mCoffOffset);
 
+  if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {
+    Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName);
+  }
+
   //
   //  The HII resource sections.
   //
@@ -650,18 +663,18 @@ WriteSections32 (
           case R_ARM_THM_ALU_PREL_11_0:
           case R_ARM_THM_PC12:
           case R_ARM_REL32_NOI:
-          case R_ARM_ALU_PC_G0_NC:\r
-          case R_ARM_ALU_PC_G0:\r
-          case R_ARM_ALU_PC_G1_NC:\r
-          case R_ARM_ALU_PC_G1:\r
-          case R_ARM_ALU_PC_G2:\r
-          case R_ARM_LDR_PC_G1:\r
-          case R_ARM_LDR_PC_G2:\r
-          case R_ARM_LDRS_PC_G0:\r
-          case R_ARM_LDRS_PC_G1:\r
-          case R_ARM_LDRS_PC_G2:\r
-          case R_ARM_LDC_PC_G0:\r
-          case R_ARM_LDC_PC_G1:\r
+          case R_ARM_ALU_PC_G0_NC:
+          case R_ARM_ALU_PC_G0:
+          case R_ARM_ALU_PC_G1_NC:
+          case R_ARM_ALU_PC_G1:
+          case R_ARM_ALU_PC_G2:
+          case R_ARM_LDR_PC_G1:
+          case R_ARM_LDR_PC_G2:
+          case R_ARM_LDRS_PC_G0:
+          case R_ARM_LDRS_PC_G1:
+          case R_ARM_LDRS_PC_G2:
+          case R_ARM_LDC_PC_G0:
+          case R_ARM_LDC_PC_G1:
           case R_ARM_LDC_PC_G2:
           case R_ARM_GOT_PREL:
           case R_ARM_THM_JUMP11:
@@ -704,6 +717,8 @@ WriteSections32 (
   return TRUE;
 }
 
+UINTN gMovwOffset = 0;
+
 STATIC
 VOID
 WriteRelocations32 (
@@ -786,18 +801,18 @@ WriteRelocations32 (
             case R_ARM_THM_ALU_PREL_11_0:
             case R_ARM_THM_PC12:
             case R_ARM_REL32_NOI:
-            case R_ARM_ALU_PC_G0_NC:\r
-            case R_ARM_ALU_PC_G0:\r
-            case R_ARM_ALU_PC_G1_NC:\r
-            case R_ARM_ALU_PC_G1:\r
-            case R_ARM_ALU_PC_G2:\r
-            case R_ARM_LDR_PC_G1:\r
-            case R_ARM_LDR_PC_G2:\r
-            case R_ARM_LDRS_PC_G0:\r
-            case R_ARM_LDRS_PC_G1:\r
-            case R_ARM_LDRS_PC_G2:\r
-            case R_ARM_LDC_PC_G0:\r
-            case R_ARM_LDC_PC_G1:\r
+            case R_ARM_ALU_PC_G0_NC:
+            case R_ARM_ALU_PC_G0:
+            case R_ARM_ALU_PC_G1_NC:
+            case R_ARM_ALU_PC_G1:
+            case R_ARM_ALU_PC_G2:
+            case R_ARM_LDR_PC_G1:
+            case R_ARM_LDR_PC_G2:
+            case R_ARM_LDRS_PC_G0:
+            case R_ARM_LDRS_PC_G1:
+            case R_ARM_LDRS_PC_G2:
+            case R_ARM_LDC_PC_G0:
+            case R_ARM_LDC_PC_G1:
             case R_ARM_LDC_PC_G2:
             case R_ARM_GOT_PREL:
             case R_ARM_THM_JUMP11:
@@ -812,19 +827,18 @@ WriteRelocations32 (
               CoffAddFixup (
                 mCoffSectionsOffset[RelShdr->sh_info]
                 + (Rel->r_offset - SecShdr->sh_addr),
-                EFI_IMAGE_REL_BASED_ARM_THUMB_MOVW
+                EFI_IMAGE_REL_BASED_ARM_MOV32T
                 );
+
+              // PE/COFF treats MOVW/MOVT relocation as single 64-bit instruction
+              // Track this address so we can log an error for unsupported sequence of MOVW/MOVT
+              gMovwOffset = mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr);
               break;
 
             case R_ARM_THM_MOVT_ABS:
-              CoffAddFixup (
-                mCoffSectionsOffset[RelShdr->sh_info]
-                + (Rel->r_offset - SecShdr->sh_addr),
-                EFI_IMAGE_REL_BASED_ARM_THUMB_MOVT
-                );
-
-              // The relocation entry needs to contain the lower 16-bits so we can do math
-              CoffAddFixupEntry ((UINT16)(Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]));
+              if ((gMovwOffset + 4) !=  (mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr))) {
+                Error (NULL, 0, 3000, "Not Supported", "PE/COFF requires MOVW+MOVT instruction sequence %x +4 != %x.", gMovwOffset, mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));
+              }
               break;
 
             case R_ARM_ABS32: