]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/Elf32Convert.c
BaseTools/GenFw: Add X64 GOTPCREL Support to GenFw
[mirror_edk2.git] / BaseTools / Source / C / GenFw / Elf32Convert.c
index 9bf58555c076c88a8cef657a7d2a4f98e4c37aac..af5ff9396ecf7c06656b057ee3f4f23e5d179621 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Elf32 Convert solution\r
 \r
-Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
 Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials are licensed and made available\r
@@ -130,7 +130,7 @@ InitializeElf32 (
   //\r
   // Initialize data pointer and structures.\r
   //\r
-  mEhdr = (Elf_Ehdr*) FileBuffer;  \r
+  mEhdr = (Elf_Ehdr*) FileBuffer;\r
 \r
   //\r
   // Check the ELF32 specific header information.\r
@@ -142,12 +142,12 @@ InitializeElf32 (
   if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) {\r
     Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB");\r
     return FALSE;\r
-  }  \r
+  }\r
   if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) {\r
     Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");\r
     return FALSE;\r
   }\r
-  if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM))) { \r
+  if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM))) {\r
     Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM");\r
     return FALSE;\r
   }\r
@@ -155,17 +155,21 @@ InitializeElf32 (
     Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT);\r
     return FALSE;\r
   }\r
-  \r
+\r
   //\r
   // Update section header pointers\r
   //\r
   mShdrBase  = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff);\r
   mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff);\r
-  \r
+\r
   //\r
   // Create COFF Section offset buffer and zero.\r
   //\r
   mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32));\r
+  if (mCoffSectionsOffset == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+    return FALSE;\r
+  }\r
   memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32));\r
 \r
   //\r
@@ -191,8 +195,11 @@ GetShdrByIndex (
   UINT32 Num\r
   )\r
 {\r
-  if (Num >= mEhdr->e_shnum)\r
-    return NULL;\r
+  if (Num >= mEhdr->e_shnum) {\r
+    Error (NULL, 0, 3000, "Invalid", "GetShdrByIndex: Index %u is too high.", Num);\r
+    exit(EXIT_FAILURE);\r
+  }\r
+\r
   return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize);\r
 }\r
 \r
@@ -203,7 +210,8 @@ GetPhdrByIndex (
   )\r
 {\r
   if (num >= mEhdr->e_phnum) {\r
-    return NULL;\r
+    Error (NULL, 0, 3000, "Invalid", "GetPhdrByIndex: Index %u is too high.", num);\r
+    exit(EXIT_FAILURE);\r
   }\r
 \r
   return (Elf_Phdr *)((UINT8*)mPhdrBase + num * mEhdr->e_phentsize);\r
@@ -262,6 +270,66 @@ IsDataShdr (
   return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);\r
 }\r
 \r
+STATIC\r
+BOOLEAN\r
+IsStrtabShdr (\r
+  Elf_Shdr *Shdr\r
+  )\r
+{\r
+  Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx);\r
+\r
+  return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_STRTAB_SECTION_NAME) == 0);\r
+}\r
+\r
+STATIC\r
+Elf_Shdr *\r
+FindStrtabShdr (\r
+  VOID\r
+  )\r
+{\r
+  UINT32 i;\r
+  for (i = 0; i < mEhdr->e_shnum; i++) {\r
+    Elf_Shdr *shdr = GetShdrByIndex(i);\r
+    if (IsStrtabShdr(shdr)) {\r
+      return shdr;\r
+    }\r
+  }\r
+  return NULL;\r
+}\r
+\r
+STATIC\r
+const UINT8 *\r
+GetSymName (\r
+  Elf_Sym *Sym\r
+  )\r
+{\r
+  Elf_Shdr *StrtabShdr;\r
+  UINT8    *StrtabContents;\r
+  BOOLEAN  foundEnd;\r
+  UINT32   i;\r
+\r
+  if (Sym->st_name == 0) {\r
+    return NULL;\r
+  }\r
+\r
+  StrtabShdr = FindStrtabShdr();\r
+  if (StrtabShdr == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  assert(Sym->st_name < StrtabShdr->sh_size);\r
+\r
+  StrtabContents = (UINT8*)mEhdr + StrtabShdr->sh_offset;\r
+\r
+  foundEnd = FALSE;\r
+  for (i = Sym->st_name; (i < StrtabShdr->sh_size) && !foundEnd; i++) {\r
+    foundEnd = (BOOLEAN)(StrtabContents[i] == 0);\r
+  }\r
+  assert(foundEnd);\r
+\r
+  return StrtabContents + Sym->st_name;\r
+}\r
+\r
 //\r
 // Elf functions interface implementation\r
 //\r
@@ -315,6 +383,14 @@ ScanSections32 (
     }\r
   }\r
 \r
+  //\r
+  // Check if mCoffAlignment is larger than MAX_COFF_ALIGNMENT\r
+  //\r
+  if (mCoffAlignment > MAX_COFF_ALIGNMENT) {\r
+    Error (NULL, 0, 3000, "Invalid", "Section alignment is larger than MAX_COFF_ALIGNMENT.");\r
+    assert (FALSE);\r
+  }\r
+\r
   //\r
   // Move the PE/COFF header right before the first section. This will help us\r
   // save space when converting to TE.\r
@@ -465,6 +541,10 @@ ScanSections32 (
   // Allocate base Coff file.  Will be expanded later for relocations.\r
   //\r
   mCoffFile = (UINT8 *)malloc(mCoffOffset);\r
+  if (mCoffFile == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+  }\r
+  assert (mCoffFile != NULL);\r
   memset(mCoffFile, 0, mCoffOffset);\r
 \r
   //\r
@@ -488,7 +568,7 @@ ScanSections32 (
     NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
     break;\r
   default:\r
-    VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine);\r
+    VerboseMsg ("%s unknown e_machine type %hu. Assume IA-32", mInImageName, mEhdr->e_machine);\r
     NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
     NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
   }\r
@@ -594,6 +674,9 @@ WriteSections32 (
       switch (Shdr->sh_type) {\r
       case SHT_PROGBITS:\r
         /* Copy.  */\r
+        if (Shdr->sh_offset + Shdr->sh_size > mFileBufferSize) {\r
+          return FALSE;\r
+        }\r
         memcpy(mCoffFile + mCoffSectionsOffset[Idx],\r
               (UINT8*)mEhdr + Shdr->sh_offset,\r
               Shdr->sh_size);\r
@@ -624,20 +707,20 @@ WriteSections32 (
     if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) {\r
       continue;\r
     }\r
-    \r
+\r
     //\r
     // Relocation section found.  Now extract section information that the relocations\r
     // apply to in the ELF data and the new COFF data.\r
     //\r
     SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
     SecOffset = mCoffSectionsOffset[RelShdr->sh_info];\r
-    \r
+\r
     //\r
     // Only process relocations for the current filter type.\r
     //\r
     if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) {\r
       UINT32 RelOffset;\r
-      \r
+\r
       //\r
       // Determine the symbol table referenced by the relocation data.\r
       //\r
@@ -652,31 +735,40 @@ WriteSections32 (
         // Set pointer to relocation entry\r
         //\r
         Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelOffset);\r
-        \r
+\r
         //\r
         // Set pointer to symbol table entry associated with the relocation entry.\r
         //\r
         Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);\r
-        \r
+\r
         Elf_Shdr *SymShdr;\r
         UINT8 *Targ;\r
         UINT16 Address;\r
 \r
         //\r
-        // Check section header index found in symbol table and get the section \r
+        // Check section header index found in symbol table and get the section\r
         // header location.\r
         //\r
         if (Sym->st_shndx == SHN_UNDEF\r
-            || Sym->st_shndx == SHN_ABS\r
-            || Sym->st_shndx > mEhdr->e_shnum) {\r
-          Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName);\r
+            || Sym->st_shndx >= mEhdr->e_shnum) {\r
+          const UINT8 *SymName = GetSymName(Sym);\r
+          if (SymName == NULL) {\r
+            SymName = (const UINT8 *)"<unknown>";\r
+          }\r
+\r
+          Error (NULL, 0, 3000, "Invalid",\r
+                 "%s: Bad definition for symbol '%s'@%#x or unsupported symbol type.  "\r
+                 "For example, absolute and undefined symbols are not supported.",\r
+                 mInImageName, SymName, Sym->st_value);\r
+\r
+          exit(EXIT_FAILURE);\r
         }\r
         SymShdr = GetShdrByIndex(Sym->st_shndx);\r
 \r
         //\r
         // Convert the relocation data to a pointer into the coff file.\r
         //\r
-        // Note: \r
+        // Note:\r
         //   r_offset is the virtual address of the storage unit to be relocated.\r
         //   sh_addr is the virtual address for the base of the section.\r
         //\r
@@ -722,9 +814,9 @@ WriteSections32 (
           case R_ARM_THM_JUMP19:\r
           case R_ARM_CALL:\r
           case R_ARM_JMP24:\r
-          case R_ARM_THM_JUMP24:  \r
-          case R_ARM_PREL31:  \r
-          case R_ARM_MOVW_PREL_NC:  \r
+          case R_ARM_THM_JUMP24:\r
+          case R_ARM_PREL31:\r
+          case R_ARM_MOVW_PREL_NC:\r
           case R_ARM_MOVT_PREL:\r
           case R_ARM_THM_MOVW_PREL_NC:\r
           case R_ARM_THM_MOVT_PREL:\r
@@ -817,7 +909,7 @@ WriteRelocations32 (
         for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
           Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);\r
 \r
-          if (mEhdr->e_machine == EM_386) { \r
+          if (mEhdr->e_machine == EM_386) {\r
             switch (ELF_R_TYPE(Rel->r_info)) {\r
             case R_386_NONE:\r
             case R_386_PC32:\r
@@ -849,9 +941,9 @@ WriteRelocations32 (
             case R_ARM_THM_JUMP19:\r
             case R_ARM_CALL:\r
             case R_ARM_JMP24:\r
-            case R_ARM_THM_JUMP24:  \r
-            case R_ARM_PREL31:  \r
-            case R_ARM_MOVW_PREL_NC:  \r
+            case R_ARM_THM_JUMP24:\r
+            case R_ARM_PREL31:\r
+            case R_ARM_MOVW_PREL_NC:\r
             case R_ARM_MOVT_PREL:\r
             case R_ARM_THM_MOVW_PREL_NC:\r
             case R_ARM_THM_MOVT_PREL:\r
@@ -998,7 +1090,7 @@ WriteRelocations32 (
           case  R_ARM_RABS32:\r
             CoffAddFixup (Rel->r_offset, EFI_IMAGE_REL_BASED_HIGHLOW);\r
             break;\r
-          \r
+\r
           default:\r
             Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unkown type %d.", mInImageName, ELF32_R_TYPE (Rel->r_info));\r
             break;\r
@@ -1061,7 +1153,7 @@ WriteDebug32 (
   NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
   DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
   DataDir->VirtualAddress = mDebugOffset;\r
-  DataDir->Size = Dir->SizeOfData + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+  DataDir->Size = sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
 }\r
 \r
 STATIC\r
@@ -1071,7 +1163,7 @@ SetImageSize32 (
   )\r
 {\r
   EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
-  \r
+\r
   //\r
   // Set image size\r
   //\r