On 28 June 2016 at 17:18, Shi, Steven <steven....@intel.com> wrote:
> Add support to convert missing Elf relocation types
> (R_X86_64_PLT32, R_X86_64_GOTPCREL, R_X86_64_REX_GOTPCRELX)
> to PeCoff, which are required by LTO image.
>

Could you please put the changes that affect other architectures in a
separate patch?
The commit log suggests that only X64 is affected, but the patch
touches other things as well.

> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Steven Shi <steven....@intel.com>
> ---
>  BaseTools/Source/C/GenFw/Elf64Convert.c | 98 
> ++++++++++++++++++++++++++++-----
>  BaseTools/Source/C/GenFw/elf_common.h   |  2 +-
>  2 files changed, 86 insertions(+), 14 deletions(-)
>  mode change 100644 => 100755 BaseTools/Source/C/GenFw/Elf64Convert.c
>  mode change 100644 => 100755 BaseTools/Source/C/GenFw/elf_common.h
>
> diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c 
> b/BaseTools/Source/C/GenFw/Elf64Convert.c
> old mode 100644
> new mode 100755
> index 024a2a0..205360c
> --- a/BaseTools/Source/C/GenFw/Elf64Convert.c
> +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
> @@ -75,7 +75,7 @@ CleanUp64 (
>    );
>
>  //
> -// Rename ELF32 strucutres to common names to help when porting to ELF64.
> +// Rename ELF32 structures to common names to help when porting to ELF64.
>  //
>  typedef Elf64_Shdr Elf_Shdr;
>  typedef Elf64_Ehdr Elf_Ehdr;
> @@ -233,7 +233,7 @@ IsTextShdr (
>    Elf_Shdr *Shdr
>    )
>  {
> -  return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC);
> +  return (BOOLEAN) ((Shdr->sh_flags & (SHF_EXECINSTR | SHF_WRITE | 
> SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC));
>  }
>
>  STATIC
> @@ -256,7 +256,7 @@ IsDataShdr (
>    if (IsHiiRsrcShdr(Shdr)) {
>      return FALSE;
>    }
> -  return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC 
> | SHF_WRITE);
> +  return (BOOLEAN) (Shdr->sh_flags & (SHF_EXECINSTR | SHF_WRITE | 
> SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);
>  }
>
>  STATIC
> @@ -661,9 +661,9 @@ WriteSections64 (
>
>        default:
>          //
> -        //  Ignore for unkown section type.
> +        //  Ignore for unknown section type.
>          //
> -        VerboseMsg ("%s unknown section type %x. We directly copy this 
> section into Coff file", mInImageName, (unsigned)Shdr->sh_type);
> +        VerboseMsg ("%s unknown section type %x. We directly ignore this 
> section and NOT copy into Coff file", mInImageName, (unsigned)Shdr->sh_type);
>          break;
>        }
>      }
> @@ -763,24 +763,24 @@ WriteSections64 (
>              // Absolute relocation.
>              //
>              VerboseMsg ("R_X86_64_64");
> -            VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX",
> -              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
> +            VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX",
> +              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
>                *(UINT64 *)Targ);
>              *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + 
> mCoffSectionsOffset[Sym->st_shndx];
>              VerboseMsg ("Relocation:  0x%016LX", *(UINT64*)Targ);
>              break;
>            case R_X86_64_32:
>              VerboseMsg ("R_X86_64_32");
> -            VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
> -              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
> +            VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
> +              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
>                *(UINT32 *)Targ);
>              *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - 
> SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
>              VerboseMsg ("Relocation:  0x%08X", *(UINT32*)Targ);
>              break;
>            case R_X86_64_32S:
>              VerboseMsg ("R_X86_64_32S");
> -            VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
> -              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
> +            VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
> +              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
>                *(UINT32 *)Targ);
>              *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - 
> SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
>              VerboseMsg ("Relocation:  0x%08X", *(UINT32*)Targ);
> @@ -790,14 +790,34 @@ WriteSections64 (
>              // Relative relocation: Symbol - Ip + Addend
>              //
>              VerboseMsg ("R_X86_64_PC32");
> -            VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
> -              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
> +            VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
> +              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
>                *(UINT32 *)Targ);
>              *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ
>                + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)
>                - (SecOffset - SecShdr->sh_addr));
>              VerboseMsg ("Relocation:  0x%08X", *(UINT32 *)Targ);
>              break;
> +          case R_X86_64_PLT32:
> +            //
> +            // Relative relocation: L + A - P
> +            //
> +            VerboseMsg ("R_X86_64_PLT32");
> +            VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
> +              (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
> +              *(UINT32 *)Targ);
> +            *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ
> +              + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)
> +              - (SecOffset - SecShdr->sh_addr));
> +            VerboseMsg ("Relocation:  0x%08X", *(UINT32 *)Targ);
> +            break;
> +          case R_X86_64_GOTPCREL:
> +          case R_X86_64_REX_GOTPCRELX:
> +            //
> +            // Relative relocation: G + GOT + A - P
> +            //
> +            VerboseMsg ("R_X86_64_GOTPCREL");
> +            break;
>            default:
>              Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 
> relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
>            }
> @@ -887,6 +907,12 @@ WriteRelocations64 (
>    UINT32                           Index;
>    EFI_IMAGE_OPTIONAL_HEADER_UNION  *NtHdr;
>    EFI_IMAGE_DATA_DIRECTORY         *Dir;
> +  UINT64                           GoTPcRelPtrOffset = 0;
> +  UINT64                           *RipDisplacementPtr;
> +  UINT64                           *ElfFileGoTPcRelPtr;
> +  UINT64                           *CoffFileGoTPcRelPtr;
> +  Elf_Shdr                         *shdr;
> +  UINT32                           i;
>
>    for (Index = 0; Index < mEhdr->e_shnum; Index++) {
>      Elf_Shdr *RelShdr = GetShdrByIndex(Index);
> @@ -902,6 +928,52 @@ WriteRelocations64 (
>              switch (ELF_R_TYPE(Rel->r_info)) {
>              case R_X86_64_NONE:
>              case R_X86_64_PC32:
> +            case R_X86_64_PLT32:
> +              break;
> +            case R_X86_64_GOTPCREL:
> +            case R_X86_64_REX_GOTPCRELX:
> +              //
> +              // link script force .got and .got.* in .text section, so 
> GoTPcRel pointer must be in .text section
> +              // but its value might point to .text or .data section
> +              //
> +              RipDisplacementPtr  = (UINT64 *)((UINT8*)mEhdr + 
> SecShdr->sh_offset + Rel->r_offset - SecShdr->sh_addr);
> +              GoTPcRelPtrOffset   = Rel->r_offset + 4 + 
> (INT32)(*RipDisplacementPtr) - SecShdr->sh_addr;
> +              ElfFileGoTPcRelPtr  = (UINT64 *)((UINT8*)mEhdr + 
> SecShdr->sh_offset + GoTPcRelPtrOffset);
> +              CoffFileGoTPcRelPtr = (UINT64 *)(mCoffFile + 
> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset);
> +              //
> +              // Check which section the GoTPcRel pointer point to, and 
> calculate Elf to Coff sections displacement accordingly
> +              //
> +              shdr = NULL;
> +              for (i = 0; i < mEhdr->e_shnum; i++) {
> +                shdr = GetShdrByIndex(i);
> +                if ((*ElfFileGoTPcRelPtr >= shdr->sh_addr) &&
> +                    (*ElfFileGoTPcRelPtr < shdr->sh_addr + shdr->sh_size)) {
> +                  break;
> +                }
> +              }
> +              //
> +              // Fix the Elf to Coff sections displacement
> +              //
> +              if(IsDataShdr(shdr)) {
> +                *CoffFileGoTPcRelPtr = *CoffFileGoTPcRelPtr + mDataOffset - 
> shdr->sh_addr;
> +              }else if (IsTextShdr(SecShdr)){
> +                *CoffFileGoTPcRelPtr = *CoffFileGoTPcRelPtr + mTextOffset - 
> shdr->sh_addr;
> +              }else {
> +                //
> +                // link script force to merge .rodata .rodata.*, .got and 
> .got.* in .text section,
> +                // not support GoTPcRel point to section other than .data or 
> .text
> +                //
> +                Error (NULL, 0, 3000, "Invalid", "Not support relocate 
> R_X86_64_GOTPCREL address in section other than .data or .text");
> +                assert (FALSE);
> +              }
> +
> +              VerboseMsg ("R_X86_64_GOTPCREL to EFI_IMAGE_REL_BASED_DIR64 
> Offset: 0x%08X",
> +                mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset);
> +              CoffAddFixup(
> +                (UINT32)(UINTN)((UINT64) 
> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
> +                EFI_IMAGE_REL_BASED_DIR64);
> +              VerboseMsg ("Relocation: 0x%08X", 
> *(UINT64*)CoffFileGoTPcRelPtr);
> +
>                break;
>              case R_X86_64_64:
>                VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X",
> diff --git a/BaseTools/Source/C/GenFw/elf_common.h 
> b/BaseTools/Source/C/GenFw/elf_common.h
> old mode 100644
> new mode 100755
> index 766d0e4..caaae23
> --- a/BaseTools/Source/C/GenFw/elf_common.h
> +++ b/BaseTools/Source/C/GenFw/elf_common.h
> @@ -1052,6 +1052,6 @@ typedef struct {
>  #define        R_X86_64_DTPOFF32       21      /* Offset in TLS block */
>  #define        R_X86_64_GOTTPOFF       22      /* PC relative offset to IE 
> GOT entry */
>  #define        R_X86_64_TPOFF32        23      /* Offset in static TLS block 
> */
> -
> +#define R_X86_64_REX_GOTPCRELX  0x2a
>
>  #endif /* !_SYS_ELF_COMMON_H_ */
> --
> 2.7.4
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to