public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
       [not found] ` <1467967364-11556-3-git-send-email-steven.shi@intel.com>
@ 2016-07-30  9:25   ` Ard Biesheuvel
  2016-07-30 14:09     ` Shi, Steven
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-07-30  9:25 UTC (permalink / raw)
  To: Shi, Steven
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Jordan Justen,
	Kinney, Michael D

On 8 July 2016 at 10:42, Shi, Steven <steven.shi@intel.com> wrote:
> Add support to convert new Elf relocation types
> (R_X86_64_PLT32, R_X86_64_GOTPCREL, R_X86_64_GOTPCRELX,
> R_X86_64_REX_GOTPCRELX) to PeCoff, which are required by
> position independent code (PIC) built Elf image.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Steven Shi <steven.shi@intel.com>
> ---
>  BaseTools/Source/C/GenFw/Elf64Convert.c | 105 +++++++++++++++++++++++++++++---
>  BaseTools/Source/C/GenFw/elf_common.h   |   9 ++-
>  2 files changed, 105 insertions(+), 9 deletions(-)
>  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
> index 7c838f3..fc241ab 100755
> --- a/BaseTools/Source/C/GenFw/Elf64Convert.c
> +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
> @@ -755,6 +755,11 @@ WriteSections64 (
>          // Determine how to handle each relocation type based on the machine type.
>          //
>          if (mEhdr->e_machine == EM_X86_64) {
> +          //
> +          // See Relocation Types details semantics in Table 4.9 of
> +          // SystemV x86_64 abi Draft Version 0.99.8
> +          // https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-secure.pdf
> +          //
>            switch (ELF_R_TYPE(Rel->r_info)) {
>            case R_X86_64_NONE:
>              break;
> @@ -763,24 +768,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)),

No change?

>                *(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)),

and here

>                *(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)),

and here

>                *(UINT32 *)Targ);
>              *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
>              VerboseMsg ("Relocation:  0x%08X", *(UINT32*)Targ);
> @@ -790,14 +795,45 @@ 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)),

and here

>                *(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:
> +            //
> +            // Relative relocation: G + GOT + A - P
> +            //
> +            VerboseMsg ("R_X86_64_GOTPCREL");
> +            break;
> +          case R_X86_64_GOTPCRELX:
> +            //
> +            // Relative relocation: G + GOT + A - P
> +            //
> +            VerboseMsg ("R_X86_64_GOTPCRELX");
> +            break;
> +          case R_X86_64_REX_GOTPCRELX:
> +            //
> +            // Relative relocation: G + GOT + A - P
> +            //
> +            VerboseMsg ("R_X86_64_REX_GOTPCRELX");
> +            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 +923,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 +944,53 @@ 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_GOTPCRELX:
> +            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);

Is this necessary? I would expect the GOT entry itself to be already
covered by a R_X86_64_64 relocation, so I don't think there is a need
to emit a EFI_IMAGE_REL_BASED_DIR64 PE/COFF reloc here.

Thanks,
Ard.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-07-30  9:25   ` [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code Ard Biesheuvel
@ 2016-07-30 14:09     ` Shi, Steven
  2016-07-30 14:11       ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Shi, Steven @ 2016-07-30 14:09 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

> > diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c
> b/BaseTools/Source/C/GenFw/Elf64Convert.c
> > index 7c838f3..fc241ab 100755
> > --- a/BaseTools/Source/C/GenFw/Elf64Convert.c
> > +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
> > @@ -755,6 +755,11 @@ WriteSections64 (
> >          // Determine how to handle each relocation type based on the
> machine type.
> >          //
> >          if (mEhdr->e_machine == EM_X86_64) {
> > +          //
> > +          // See Relocation Types details semantics in Table 4.9 of
> > +          // SystemV x86_64 abi Draft Version 0.99.8
> > +          // https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-
> secure.pdf
> > +          //
> >            switch (ELF_R_TYPE(Rel->r_info)) {
> >            case R_X86_64_NONE:
> >              break;
> > @@ -763,24 +768,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)),
> 
> No change?
[Steven]: remove the unnecessary blank at end of line, which is required by coding style

> 
> >                *(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)),
> 
> and here
[Steven]: remove the unnecessary blank at end of line, which is required by coding style

> 
> >                *(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)),
> 
> and here
[Steven]: remove the unnecessary blank at end of line, which is required by coding style

> 
> >                *(UINT32 *)Targ);
> >              *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr-
> >sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
> >              VerboseMsg ("Relocation:  0x%08X", *(UINT32*)Targ);
> > @@ -790,14 +795,45 @@ 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)),
> 
> and here
[Steven]: remove the unnecessary blank at end of line, which is required by coding style

> 
> >                *(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:
> > +            //
> > +            // Relative relocation: G + GOT + A - P
> > +            //
> > +            VerboseMsg ("R_X86_64_GOTPCREL");
> > +            break;
> > +          case R_X86_64_GOTPCRELX:
> > +            //
> > +            // Relative relocation: G + GOT + A - P
> > +            //
> > +            VerboseMsg ("R_X86_64_GOTPCRELX");
> > +            break;
> > +          case R_X86_64_REX_GOTPCRELX:
> > +            //
> > +            // Relative relocation: G + GOT + A - P
> > +            //
> > +            VerboseMsg ("R_X86_64_REX_GOTPCRELX");
> > +            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 +923,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 +944,53 @@ 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_GOTPCRELX:
> > +            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);
> 
> Is this necessary? I would expect the GOT entry itself to be already
> covered by a R_X86_64_64 relocation, so I don't think there is a need
> to emit a EFI_IMAGE_REL_BASED_DIR64 PE/COFF reloc here.
[Steven]: Do you ask whether it is still necessary to support the GOTPCREL/GOTPCRELX/REX_GOTPCRELX new relocation types? I think they are nice to have now, since new type support has no impact to old ones, we could just leave the code there for reference.

Thanks
Steven

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-07-30 14:09     ` Shi, Steven
@ 2016-07-30 14:11       ` Ard Biesheuvel
  2016-07-31  3:08         ` Shi, Steven
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-07-30 14:11 UTC (permalink / raw)
  To: Shi, Steven
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

On 30 July 2016 at 16:09, Shi, Steven <steven.shi@intel.com> wrote:
>> > diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c
>> b/BaseTools/Source/C/GenFw/Elf64Convert.c
>> > index 7c838f3..fc241ab 100755
>> > --- a/BaseTools/Source/C/GenFw/Elf64Convert.c
>> > +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
>> > @@ -755,6 +755,11 @@ WriteSections64 (
>> >          // Determine how to handle each relocation type based on the
>> machine type.
>> >          //
>> >          if (mEhdr->e_machine == EM_X86_64) {
>> > +          //
>> > +          // See Relocation Types details semantics in Table 4.9 of
>> > +          // SystemV x86_64 abi Draft Version 0.99.8
>> > +          // https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-
>> secure.pdf
>> > +          //
>> >            switch (ELF_R_TYPE(Rel->r_info)) {
>> >            case R_X86_64_NONE:
>> >              break;
>> > @@ -763,24 +768,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)),
>>
>> No change?
> [Steven]: remove the unnecessary blank at end of line, which is required by coding style
>
>>
>> >                *(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)),
>>
>> and here
> [Steven]: remove the unnecessary blank at end of line, which is required by coding style
>
>>
>> >                *(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)),
>>
>> and here
> [Steven]: remove the unnecessary blank at end of line, which is required by coding style
>
>>
>> >                *(UINT32 *)Targ);
>> >              *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr-
>> >sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
>> >              VerboseMsg ("Relocation:  0x%08X", *(UINT32*)Targ);
>> > @@ -790,14 +795,45 @@ 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)),
>>
>> and here
> [Steven]: remove the unnecessary blank at end of line, which is required by coding style
>

OK. Could we do that in a separate patch?

>>
>> >                *(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:
>> > +            //
>> > +            // Relative relocation: G + GOT + A - P
>> > +            //
>> > +            VerboseMsg ("R_X86_64_GOTPCREL");
>> > +            break;
>> > +          case R_X86_64_GOTPCRELX:
>> > +            //
>> > +            // Relative relocation: G + GOT + A - P
>> > +            //
>> > +            VerboseMsg ("R_X86_64_GOTPCRELX");
>> > +            break;
>> > +          case R_X86_64_REX_GOTPCRELX:
>> > +            //
>> > +            // Relative relocation: G + GOT + A - P
>> > +            //
>> > +            VerboseMsg ("R_X86_64_REX_GOTPCRELX");
>> > +            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 +923,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 +944,53 @@ 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_GOTPCRELX:
>> > +            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);
>>
>> Is this necessary? I would expect the GOT entry itself to be already
>> covered by a R_X86_64_64 relocation, so I don't think there is a need
>> to emit a EFI_IMAGE_REL_BASED_DIR64 PE/COFF reloc here.
> [Steven]: Do you ask whether it is still necessary to support the GOTPCREL/GOTPCRELX/REX_GOTPCRELX new relocation types? I think they are nice to have now, since new type support has no impact to old ones, we could just leave the code there for reference.

No. The question is whether it is necessary to emit the
EFI_IMAGE_REL_BASED_DIR64 fixup reloc here. The relocation place is
the instruction, not the GOT entry, and I would expect the GOT entry
to be covered by a R_X86_64_64 relocation already


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-07-30 14:11       ` Ard Biesheuvel
@ 2016-07-31  3:08         ` Shi, Steven
  2016-07-31  5:42           ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Shi, Steven @ 2016-07-31  3:08 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

> OK. Could we do that in a separate patch?
[Steven]: Yes. We could separate it in a new patch.

> >> Is this necessary? I would expect the GOT entry itself to be already
> >> covered by a R_X86_64_64 relocation, so I don't think there is a need
> >> to emit a EFI_IMAGE_REL_BASED_DIR64 PE/COFF reloc here.
> > [Steven]: Do you ask whether it is still necessary to support the
> GOTPCREL/GOTPCRELX/REX_GOTPCRELX new relocation types? I think they
> are nice to have now, since new type support has no impact to old ones, we
> could just leave the code there for reference.
> 
> No. The question is whether it is necessary to emit the
> EFI_IMAGE_REL_BASED_DIR64 fixup reloc here. The relocation place is
> the instruction, not the GOT entry, and I would expect the GOT entry
> to be covered by a R_X86_64_64 relocation already
[Steven]: Yes, it is necessary. Even the R_X86_64_64 relocation need to emit the EFI_IMAGE_REL_BASED_DIR64 fixup reloc like below in the original GenFw code. You can test it like this, remove the below CoffAddFixup() code and build the OVMF with GCC5, you will see the Ovmf boot failure with cpu exception. 

            case R_X86_64_64:
              VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X", 
                mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));
              CoffAddFixup(
                (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
                + (Rel->r_offset - SecShdr->sh_addr)),
                EFI_IMAGE_REL_BASED_DIR64);

Steven Shi
Intel\SSG\STO\UEFI Firmware

Tel: +86 021-61166522
iNet: 821-6522


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-07-31  3:08         ` Shi, Steven
@ 2016-07-31  5:42           ` Ard Biesheuvel
  2016-07-31 19:10             ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-07-31  5:42 UTC (permalink / raw)
  To: Shi, Steven
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

On 31 July 2016 at 05:08, Shi, Steven <steven.shi@intel.com> wrote:
>> OK. Could we do that in a separate patch?
> [Steven]: Yes. We could separate it in a new patch.
>
>> >> Is this necessary? I would expect the GOT entry itself to be already
>> >> covered by a R_X86_64_64 relocation, so I don't think there is a need
>> >> to emit a EFI_IMAGE_REL_BASED_DIR64 PE/COFF reloc here.
>> > [Steven]: Do you ask whether it is still necessary to support the
>> GOTPCREL/GOTPCRELX/REX_GOTPCRELX new relocation types? I think they
>> are nice to have now, since new type support has no impact to old ones, we
>> could just leave the code there for reference.
>>
>> No. The question is whether it is necessary to emit the
>> EFI_IMAGE_REL_BASED_DIR64 fixup reloc here. The relocation place is
>> the instruction, not the GOT entry, and I would expect the GOT entry
>> to be covered by a R_X86_64_64 relocation already
> [Steven]: Yes, it is necessary. Even the R_X86_64_64 relocation need to emit the EFI_IMAGE_REL_BASED_DIR64 fixup reloc like below in the original GenFw code. You can test it like this, remove the below CoffAddFixup() code and build the OVMF with GCC5, you will see the Ovmf boot failure with cpu exception.
>
>             case R_X86_64_64:
>               VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X",
>                 mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));
>               CoffAddFixup(
>                 (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
>                 + (Rel->r_offset - SecShdr->sh_addr)),
>                 EFI_IMAGE_REL_BASED_DIR64);
>

That was not my point. With your code, how many
EFI_IMAGE_REL_BASED_DIR64 fixups are added to the .reloc section for
the GOT entry of 'n'?

int n;
int f () { return n; }
int g () { return n; }
int h () { return n; }


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-07-31  5:42           ` Ard Biesheuvel
@ 2016-07-31 19:10             ` Ard Biesheuvel
  2016-08-01  4:39               ` Shi, Steven
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-07-31 19:10 UTC (permalink / raw)
  To: Shi, Steven
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

On 31 July 2016 at 07:42, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 31 July 2016 at 05:08, Shi, Steven <steven.shi@intel.com> wrote:
>>> OK. Could we do that in a separate patch?
>> [Steven]: Yes. We could separate it in a new patch.
>>
>>> >> Is this necessary? I would expect the GOT entry itself to be already
>>> >> covered by a R_X86_64_64 relocation, so I don't think there is a need
>>> >> to emit a EFI_IMAGE_REL_BASED_DIR64 PE/COFF reloc here.
>>> > [Steven]: Do you ask whether it is still necessary to support the
>>> GOTPCREL/GOTPCRELX/REX_GOTPCRELX new relocation types? I think they
>>> are nice to have now, since new type support has no impact to old ones, we
>>> could just leave the code there for reference.
>>>
>>> No. The question is whether it is necessary to emit the
>>> EFI_IMAGE_REL_BASED_DIR64 fixup reloc here. The relocation place is
>>> the instruction, not the GOT entry, and I would expect the GOT entry
>>> to be covered by a R_X86_64_64 relocation already
>> [Steven]: Yes, it is necessary. Even the R_X86_64_64 relocation need to emit the EFI_IMAGE_REL_BASED_DIR64 fixup reloc like below in the original GenFw code. You can test it like this, remove the below CoffAddFixup() code and build the OVMF with GCC5, you will see the Ovmf boot failure with cpu exception.
>>
>>             case R_X86_64_64:
>>               VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X",
>>                 mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));
>>               CoffAddFixup(
>>                 (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
>>                 + (Rel->r_offset - SecShdr->sh_addr)),
>>                 EFI_IMAGE_REL_BASED_DIR64);
>>
>
> That was not my point. With your code, how many
> EFI_IMAGE_REL_BASED_DIR64 fixups are added to the .reloc section for
> the GOT entry of 'n'?
>
> int n;
> int f () { return n; }
> int g () { return n; }
> int h () { return n; }

I am also concerned about the GOTPCRELX/REX_GOTPCRELX relocations.
Reading the x86_64 ABI docs, it appears that these may refer to
instructions that have been modified by the linker. In that case, how
do we deal with the relocation? Also, according to the doc, mov
instructions may be emitted by the linker in some cases that are only
valid in the lowest 2 GB of the address space.

All in all, I think supporting GOT based relocations is a can of
worms, and I would prefer to get rid of them completely if we can
(i.e., using hidden visibility even for LTO, I have a fix for that I
will sent out separately)

Thanks,
Ard.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-07-31 19:10             ` Ard Biesheuvel
@ 2016-08-01  4:39               ` Shi, Steven
  2016-08-01  5:58                 ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Shi, Steven @ 2016-08-01  4:39 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

> >
> > That was not my point. With your code, how many
> > EFI_IMAGE_REL_BASED_DIR64 fixups are added to the .reloc section for
> > the GOT entry of 'n'?
> >
> > int n;
> > int f () { return n; }
> > int g () { return n; }
> > int h () { return n; }

[Steven]: If the above global " n " need GOTPCREL type relocation. It should need only once EFI_IMAGE_REL_BASED_DIR64 fixups in my code.

> 
> I am also concerned about the GOTPCRELX/REX_GOTPCRELX relocations.
> Reading the x86_64 ABI docs, it appears that these may refer to
> instructions that have been modified by the linker. In that case, how
> do we deal with the relocation? Also, according to the doc, mov
> instructions may be emitted by the linker in some cases that are only
> valid in the lowest 2 GB of the address space.
> 
[Steven]: Frankly to say, the x86_64 ABI docs is only good for compiler domain developer and not very good for other domain developers to understand it. 
My overall understanding for these different relocation type is like this: compiler generate PIC code with different "level of indirection to all global data and function references in the code." And these different level of indirection is implemented through GOT and PLT structure with different addressing calculation pattern. The different calculation patterns are the different relocation types which are defined  by  x86_64 ABI Table 4.9. We don't need worry about how compiler correctly generate code to work with these relocation types, we just need correctly understand their addressing calculation pattern.

The GOTPCRELX/REX_GOTPCRELX has the same calculation definition in x86_64 ABI Table 4.9 as "G + GOT + A - P". So, I assume their difference is not in the relocation calculation pattern, but how to co-work with specific instructions to finish these calculation in a hardware optimized way.

One important thing worthy to mention that our gcc link script (GccBase.lds) has forced the GOT related sections , e.g. '.got', '.got.plt' , into .text section. So, all the GOT relocation fixup target .text section in fact.

I find below article help me a lot to understand some PIC simple relocation types. Hope it also can help you. I wish Eli, the author of below articles, could be invited as one author of x86_64 ABI spec, which will surely make the spec be more readable to other domain developers. :) 
Position Independent Code (PIC) in shared libraries 
http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
Position Independent Code (PIC) in shared libraries on x64 
http://eli.thegreenplace.net/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x64

>
> All in all, I think supporting GOT based relocations is a can of
> worms, and I would prefer to get rid of them completely if we can
> (i.e., using hidden visibility even for LTO, I have a fix for that I
> will sent out separately)
>
[Steven]: I agree we should try to avoid generating complex relocation type code for Uefi. But to make Uefi code build more portable to various version compilers and linker, I think it is still necessary to support these GOT based relocations. 
I've tested the GenFw new relocation types support with both GCC5/GCC49 (with default visibility) and CLANG38 in my branch in before. It can works. I suggest we could just keep these code there for reference.


Steven Shi
Intel\SSG\STO\UEFI Firmware

Tel: +86 021-61166522
iNet: 821-6522

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01  4:39               ` Shi, Steven
@ 2016-08-01  5:58                 ` Ard Biesheuvel
  2016-08-01  6:13                   ` Shi, Steven
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-08-01  5:58 UTC (permalink / raw)
  To: Shi, Steven
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

On 1 August 2016 at 06:39, Shi, Steven <steven.shi@intel.com> wrote:
>> >
>> > That was not my point. With your code, how many
>> > EFI_IMAGE_REL_BASED_DIR64 fixups are added to the .reloc section for
>> > the GOT entry of 'n'?
>> >
>> > int n;
>> > int f () { return n; }
>> > int g () { return n; }
>> > int h () { return n; }
>
> [Steven]: If the above global " n " need GOTPCREL type relocation. It should need only once EFI_IMAGE_REL_BASED_DIR64 fixups in my code.
>

Yes, I believe so. I think it would be possible to sort the .reloc
section and eliminate duplicates, but doing this correctly is
non-trivial in any case.

>>
>> I am also concerned about the GOTPCRELX/REX_GOTPCRELX relocations.
>> Reading the x86_64 ABI docs, it appears that these may refer to
>> instructions that have been modified by the linker. In that case, how
>> do we deal with the relocation? Also, according to the doc, mov
>> instructions may be emitted by the linker in some cases that are only
>> valid in the lowest 2 GB of the address space.
>>
> [Steven]: Frankly to say, the x86_64 ABI docs is only good for compiler domain developer and not very good for other domain developers to understand it.
> My overall understanding for these different relocation type is like this: compiler generate PIC code with different "level of indirection to all global data and function references in the code." And these different level of indirection is implemented through GOT and PLT structure with different addressing calculation pattern. The different calculation patterns are the different relocation types which are defined  by  x86_64 ABI Table 4.9. We don't need worry about how compiler correctly generate code to work with these relocation types, we just need correctly understand their addressing calculation pattern.
>
> The GOTPCRELX/REX_GOTPCRELX has the same calculation definition in x86_64 ABI Table 4.9 as "G + GOT + A - P". So, I assume their difference is not in the relocation calculation pattern, but how to co-work with specific instructions to finish these calculation in a hardware optimized way.
>

No, that is not what these are for. The special types mark
instructions that can be converted by the linker into simpler
sequences if the symbol turns out to be in the same module. From the
doc:

mov foo@GOTPCREL(%rip), %reg

could be converted by the linker into

lea foo(%rip), %reg

if the reference to 'foo' is satisfied by a non-preemptible local
definition. This is a useful optimization, since it eliminates a
memory load. The problem is that we cannot recalculate such
relocations in GenFw without checking whether the linker has applied
this optimization or not.

> One important thing worthy to mention that our gcc link script (GccBase.lds) has forced the GOT related sections , e.g. '.got', '.got.plt' , into .text section. So, all the GOT relocation fixup target .text section in fact.
>
> I find below article help me a lot to understand some PIC simple relocation types. Hope it also can help you. I wish Eli, the author of below articles, could be invited as one author of x86_64 ABI spec, which will surely make the spec be more readable to other domain developers. :)
> Position Independent Code (PIC) in shared libraries
> http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
> Position Independent Code (PIC) in shared libraries on x64
> http://eli.thegreenplace.net/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x64
>
>>
>> All in all, I think supporting GOT based relocations is a can of
>> worms, and I would prefer to get rid of them completely if we can
>> (i.e., using hidden visibility even for LTO, I have a fix for that I
>> will sent out separately)
>>
> [Steven]: I agree we should try to avoid generating complex relocation type code for Uefi. But to make Uefi code build more portable to various version compilers and linker, I think it is still necessary to support these GOT based relocations.
> I've tested the GenFw new relocation types support with both GCC5/GCC49 (with default visibility) and CLANG38 in my branch in before. It can works. I suggest we could just keep these code there for reference.
>

The fact that it works does not make it safe. Having multiple fixups
for the same symbol in the .reloc section is a problem, and so is
reapplying GOTPCRELX to places where the original instruction has been
replaced by the linker.

-- 
Ard.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01  5:58                 ` Ard Biesheuvel
@ 2016-08-01  6:13                   ` Shi, Steven
  2016-08-01  6:43                     ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Shi, Steven @ 2016-08-01  6:13 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

> >>
> >> I am also concerned about the GOTPCRELX/REX_GOTPCRELX relocations.
> >> Reading the x86_64 ABI docs, it appears that these may refer to
> >> instructions that have been modified by the linker. In that case, how
> >> do we deal with the relocation? Also, according to the doc, mov
> >> instructions may be emitted by the linker in some cases that are only
> >> valid in the lowest 2 GB of the address space.
> >>
> > [Steven]: Frankly to say, the x86_64 ABI docs is only good for compiler
> domain developer and not very good for other domain developers to
> understand it.
> > My overall understanding for these different relocation type is like this:
> compiler generate PIC code with different "level of indirection to all global
> data and function references in the code." And these different level of
> indirection is implemented through GOT and PLT structure with different
> addressing calculation pattern. The different calculation patterns are the
> different relocation types which are defined  by  x86_64 ABI Table 4.9. We
> don't need worry about how compiler correctly generate code to work with
> these relocation types, we just need correctly understand their addressing
> calculation pattern.
> >
> > The GOTPCRELX/REX_GOTPCRELX has the same calculation definition in
> x86_64 ABI Table 4.9 as "G + GOT + A - P". So, I assume their difference is not
> in the relocation calculation pattern, but how to co-work with specific
> instructions to finish these calculation in a hardware optimized way.
> >
> 
> No, that is not what these are for. The special types mark
> instructions that can be converted by the linker into simpler
> sequences if the symbol turns out to be in the same module. From the
> doc:
> 
> mov foo@GOTPCREL(%rip), %reg
> 
> could be converted by the linker into
> 
> lea foo(%rip), %reg
> 
> if the reference to 'foo' is satisfied by a non-preemptible local
> definition. This is a useful optimization, since it eliminates a
> memory load. The problem is that we cannot recalculate such
> relocations in GenFw without checking whether the linker has applied
> this optimization or not.
> 
[Steven]: Do you mean the linker will apply above optimization but not remove the original GOTPCREL item? It sounds like a severe linker bug.

> 
> The fact that it works does not make it safe. Having multiple fixups
> for the same symbol in the .reloc section is a problem, and so is
> reapplying GOTPCRELX to places where the original instruction has been
> replaced by the linker.
> 
[Steven]: I still don't understand why there will be multiple fixups for the same symbol in the .reloc section?




^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01  6:13                   ` Shi, Steven
@ 2016-08-01  6:43                     ` Ard Biesheuvel
  2016-08-01  7:19                       ` Shi, Steven
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-08-01  6:43 UTC (permalink / raw)
  To: Shi, Steven
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

On 1 August 2016 at 08:13, Shi, Steven <steven.shi@intel.com> wrote:
>> >>
>> >> I am also concerned about the GOTPCRELX/REX_GOTPCRELX relocations.
>> >> Reading the x86_64 ABI docs, it appears that these may refer to
>> >> instructions that have been modified by the linker. In that case, how
>> >> do we deal with the relocation? Also, according to the doc, mov
>> >> instructions may be emitted by the linker in some cases that are only
>> >> valid in the lowest 2 GB of the address space.
>> >>
>> > [Steven]: Frankly to say, the x86_64 ABI docs is only good for compiler
>> domain developer and not very good for other domain developers to
>> understand it.
>> > My overall understanding for these different relocation type is like this:
>> compiler generate PIC code with different "level of indirection to all global
>> data and function references in the code." And these different level of
>> indirection is implemented through GOT and PLT structure with different
>> addressing calculation pattern. The different calculation patterns are the
>> different relocation types which are defined  by  x86_64 ABI Table 4.9. We
>> don't need worry about how compiler correctly generate code to work with
>> these relocation types, we just need correctly understand their addressing
>> calculation pattern.
>> >
>> > The GOTPCRELX/REX_GOTPCRELX has the same calculation definition in
>> x86_64 ABI Table 4.9 as "G + GOT + A - P". So, I assume their difference is not
>> in the relocation calculation pattern, but how to co-work with specific
>> instructions to finish these calculation in a hardware optimized way.
>> >
>>
>> No, that is not what these are for. The special types mark
>> instructions that can be converted by the linker into simpler
>> sequences if the symbol turns out to be in the same module. From the
>> doc:
>>
>> mov foo@GOTPCREL(%rip), %reg
>>
>> could be converted by the linker into
>>
>> lea foo(%rip), %reg
>>
>> if the reference to 'foo' is satisfied by a non-preemptible local
>> definition. This is a useful optimization, since it eliminates a
>> memory load. The problem is that we cannot recalculate such
>> relocations in GenFw without checking whether the linker has applied
>> this optimization or not.
>>
> [Steven]: Do you mean the linker will apply above optimization but not remove the original GOTPCREL item? It sounds like a severe linker bug.
>

I checked quickly, and it appears the linker does the right thing
here, i.e., it performs the optimization and also modifies the
relocation emitted into the .rela.text section

So this:

.globl bar
.type bar, @function
bar:
mov foo@GOTPCREL(%rip), %eax
ret

.globl foo
foo:
.quad 0

compiles into

/tmp/pie.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <bar>:
   0: 8b 05 00 00 00 00     mov    0x0(%rip),%eax        # 6 <bar+0x6>
2: R_X86_64_GOTPCRELX foo-0x4
   6: c3                   retq

0000000000000007 <foo>:
...

but after linking (ld -o /tmp/pie -e bar -q /tmp/pie.o)

/tmp/pie:     file format elf64-x86-64


Disassembly of section .text:

00000000004000b0 <bar>:
  4000b0: 8d 05 01 00 00 00     lea    0x1(%rip),%eax        # 4000b7 <foo>
4000b2: R_X86_64_PC32 foo-0x4
  4000b6: c3                   retq

00000000004000b7 <foo>:
...


>>
>> The fact that it works does not make it safe. Having multiple fixups
>> for the same symbol in the .reloc section is a problem, and so is
>> reapplying GOTPCRELX to places where the original instruction has been
>> replaced by the linker.
>>
> [Steven]: I still don't understand why there will be multiple fixups for the same symbol in the .reloc section?
>

Remember this example

>> > int n;
>> > int f () { return n; }
>> > int g () { return n; }
>> > int h () { return n; }

If every 'return n' results in a GOTPCREL relocation, how are you
going to make sure that the GOT entry for 'n' is only fixed up a
single time?


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01  6:43                     ` Ard Biesheuvel
@ 2016-08-01  7:19                       ` Shi, Steven
  2016-08-01  7:25                         ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Shi, Steven @ 2016-08-01  7:19 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

> >>
> >> The fact that it works does not make it safe. Having multiple fixups
> >> for the same symbol in the .reloc section is a problem, and so is
> >> reapplying GOTPCRELX to places where the original instruction has been
> >> replaced by the linker.
> >>
> > [Steven]: I still don't understand why there will be multiple fixups for the
> same symbol in the .reloc section?
> >
> 
> Remember this example
> 
> >> > int n;
> >> > int f () { return n; }
> >> > int g () { return n; }
> >> > int h () { return n; }
> 
> If every 'return n' results in a GOTPCREL relocation, how are you
> going to make sure that the GOT entry for 'n' is only fixed up a
> single time?

[Steven]: the 'return n' will not result in relocation, but the 'int n' will result in the relocation in GOT. The three 'return n' will point to the same 'int n' relocation item. So, we need only fixup 'int n' once, all three 'return n' will use the correct global 'n' value. BTW, the 'int n' relocation type in your code on X64 should be R_X86_64_GLOB_DAT

You can see the 'int myglob' in Eli's example in http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/. The 'int myglob' is same as your 'int n' example.

int myglob = 42;
int ml_func(int a, int b)
{
    return myglob + a + b;
}




^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01  7:19                       ` Shi, Steven
@ 2016-08-01  7:25                         ` Ard Biesheuvel
  2016-08-01  7:54                           ` Shi, Steven
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-08-01  7:25 UTC (permalink / raw)
  To: Shi, Steven
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

On 1 August 2016 at 09:19, Shi, Steven <steven.shi@intel.com> wrote:
>> >>
>> >> The fact that it works does not make it safe. Having multiple fixups
>> >> for the same symbol in the .reloc section is a problem, and so is
>> >> reapplying GOTPCRELX to places where the original instruction has been
>> >> replaced by the linker.
>> >>
>> > [Steven]: I still don't understand why there will be multiple fixups for the
>> same symbol in the .reloc section?
>> >
>>
>> Remember this example
>>
>> >> > int n;
>> >> > int f () { return n; }
>> >> > int g () { return n; }
>> >> > int h () { return n; }
>>
>> If every 'return n' results in a GOTPCREL relocation, how are you
>> going to make sure that the GOT entry for 'n' is only fixed up a
>> single time?
>
> [Steven]: the 'return n' will not result in relocation, but the 'int n' will result in the relocation in GOT. The three 'return n' will point to the same 'int n' relocation item. So, we need only fixup 'int n' once, all three 'return n' will use the correct global 'n' value.

Every 'return n' will result in a GOTPCREL relocation against n. And
your code emits a relocation for the GOT entry every time.

 BTW, the 'int n' relocation type in your code on X64 should be
R_X86_64_GLOB_DAT
>

R_X86_64_GLOB_DAT is a dynamic relocation type. These are only emitted
when linking a shared object or a PIE executable, which I would like
to avoid as well.

The problem with PIE executables is that the .rela.xxx sections
emitted for each section, and the single .rela section containing the
dynamic relocations overlap with each other, i.e., places containing
absolute symbol addresses in the binary will appear in both, and
emitting reloc fixups for all relocations will result in duplicates.

> You can see the 'int myglob' in Eli's example in http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/. The 'int myglob' is same as your 'int n' example.
>
> int myglob = 42;
> int ml_func(int a, int b)
> {
>     return myglob + a + b;
> }
>

Yes, and every reference to 'myglob' will result in a GOTPCREL
relocation. We must not emit a fixup for myglob every time.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01  7:25                         ` Ard Biesheuvel
@ 2016-08-01  7:54                           ` Shi, Steven
  2016-08-01  8:00                             ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Shi, Steven @ 2016-08-01  7:54 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

> On 1 August 2016 at 09:19, Shi, Steven <steven.shi@intel.com<mailto:steven.shi@intel.com>> wrote:

> >> >>

> >> >> The fact that it works does not make it safe. Having multiple fixups

> >> >> for the same symbol in the .reloc section is a problem, and so is

> >> >> reapplying GOTPCRELX to places where the original instruction has

> been

> >> >> replaced by the linker.

> >> >>

> >> > [Steven]: I still don't understand why there will be multiple fixups for the

> >> same symbol in the .reloc section?

> >> >

> >>

> >> Remember this example

> >>

> >> >> > int n;

> >> >> > int f () { return n; }

> >> >> > int g () { return n; }

> >> >> > int h () { return n; }

> >>

> >> If every 'return n' results in a GOTPCREL relocation, how are you

> >> going to make sure that the GOT entry for 'n' is only fixed up a

> >> single time?

> >

> > [Steven]: the 'return n' will not result in relocation, but the 'int n' will result

> in the relocation in GOT. The three 'return n' will point to the same 'int n'

> relocation item. So, we need only fixup 'int n' once, all three 'return n' will

> use the correct global 'n' value.

>

> Every 'return n' will result in a GOTPCREL relocation against n. And

> your code emits a relocation for the GOT entry every time.

>

[Steven]: I don't think so. please give a real case and offer its source code to prove " Every 'return n' will result in a GOTPCREL relocation against n ".



>  BTW, the 'int n' relocation type in your code on X64 should be

> R_X86_64_GLOB_DAT

> >

>

> R_X86_64_GLOB_DAT is a dynamic relocation type. These are only emitted

> when linking a shared object or a PIE executable, which I would like

> to avoid as well.

>

> The problem with PIE executables is that the .rela.xxx sections

> emitted for each section, and the single .rela section containing the

> dynamic relocations overlap with each other, i.e., places containing

> absolute symbol addresses in the binary will appear in both, and

> emitting reloc fixups for all relocations will result in duplicates.

>

[Steven]: the current GenFw will ignore the single .rela section, because the .rela section info is 0, which target invalid section at all. See below sections example. Current GenFw will only handle the .rela.text and .rela.data relocation sections.



Section Headers:

  [Nr] Name              Type             Address           Offset

       Size              EntSize          Flags  Link  Info  Align

  [ 0]                   NULL             0000000000000000  00000000

       0000000000000000  0000000000000000           0     0     0

  [ 1] .note.gnu.build-i NOTE             0000000000000000  00000100

       0000000000000024  0000000000000000   A       0     0     4

  [ 2] .text             PROGBITS         0000000000000240  00000340

       00000000000059f8  0000000000000008  AX       0     0     64

  [ 3] .rela.text        RELA             0000000000000000  00008728

       00000000000044d0  0000000000000018   I      10     2     8

  [ 4] .data             PROGBITS         0000000000005c40  00005d40

       0000000000000a68  0000000000000000  WA       0     0     64

  [ 5] .rela.data        RELA             0000000000000000  0000cbf8

       00000000000004b0  0000000000000018   I      10     4     8

  [ 6] .rela             RELA             00000000000066c0  000067c0

       00000000000004b0  0000000000000018   A       0     0     8



> > You can see the 'int myglob' in Eli's example in

> http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-<http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/>

> shared-libraries/<http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/>. The 'int myglob' is same as your 'int n' example.

> >

> > int myglob = 42;

> > int ml_func(int a, int b)

> > {

> >     return myglob + a + b;

> > }

> >

>

> Yes, and every reference to 'myglob' will result in a GOTPCREL

> relocation. We must not emit a fixup for myglob every time.

[Steven]: Please give a real case and offer its source code to prove "every reference to 'myglob' will result in a GOTPCREL relocation".



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01  7:54                           ` Shi, Steven
@ 2016-08-01  8:00                             ` Ard Biesheuvel
  2016-08-01  8:28                               ` Shi, Steven
       [not found]                               ` <06C8AB66E78EE34A949939824ABE2B31033825EE@shsmsx102.ccr.corp.intel.com>
  0 siblings, 2 replies; 24+ messages in thread
From: Ard Biesheuvel @ 2016-08-01  8:00 UTC (permalink / raw)
  To: Shi, Steven
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel-01,
	afish@apple.com, Gao, Liming

On 1 August 2016 at 09:54, Shi, Steven <steven.shi@intel.com> wrote:
>> On 1 August 2016 at 09:19, Shi, Steven <steven.shi@intel.com<mailto:steven.shi@intel.com>> wrote:
>> >> >>
>> >> >> The fact that it works does not make it safe. Having multiple fixups
>> >> >> for the same symbol in the .reloc section is a problem, and so is
>> >> >> reapplying GOTPCRELX to places where the original instruction has
>> been
>> >> >> replaced by the linker.
>> >> >>
>> >> > [Steven]: I still don't understand why there will be multiple fixups for the
>> >> same symbol in the .reloc section?
>> >> >
>> >>
>> >> Remember this example
>> >>
>> >> >> > int n;
>> >> >> > int f () { return n; }
>> >> >> > int g () { return n; }
>> >> >> > int h () { return n; }
>> >>
>> >> If every 'return n' results in a GOTPCREL relocation, how are you
>> >> going to make sure that the GOT entry for 'n' is only fixed up a
>> >> single time?
>> >
>> > [Steven]: the 'return n' will not result in relocation, but the 'int n' will result
>> in the relocation in GOT. The three 'return n' will point to the same 'int n'
>> relocation item. So, we need only fixup 'int n' once, all three 'return n' will
>> use the correct global 'n' value.
>>
>> Every 'return n' will result in a GOTPCREL relocation against n. And
>> your code emits a relocation for the GOT entry every time.
>>
> [Steven]: I don't think so. please give a real case and offer its source code to prove " Every 'return n' will result in a GOTPCREL relocation against n ".
>

Compiling the code above using

gcc -c -O -fpic /tmp/pie.c -o pie.o

and dumping it using

readelf -r pie.o

gives me

Relocation section '.rela.text' at offset 0x250 contains 3 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000003  000a0000002a R_X86_64_REX_GOTP 0000000000000004 n - 4
00000000000d  000a0000002a R_X86_64_REX_GOTP 0000000000000004 n - 4
000000000017  000a0000002a R_X86_64_REX_GOTP 0000000000000004 n - 4
...

-- 
Ard.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01  8:00                             ` Ard Biesheuvel
@ 2016-08-01  8:28                               ` Shi, Steven
       [not found]                               ` <06C8AB66E78EE34A949939824ABE2B31033825EE@shsmsx102.ccr.corp.intel.com>
  1 sibling, 0 replies; 24+ messages in thread
From: Shi, Steven @ 2016-08-01  8:28 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel-01,
	afish@apple.com, Gao, Liming

> On 1 August 2016 at 09:54, Shi, Steven <steven.shi@intel.com> wrote:
> >> On 1 August 2016 at 09:19, Shi, Steven
> <steven.shi@intel.com<mailto:steven.shi@intel.com>> wrote:
> >> >> >>
> >> >> >> The fact that it works does not make it safe. Having multiple fixups
> >> >> >> for the same symbol in the .reloc section is a problem, and so is
> >> >> >> reapplying GOTPCRELX to places where the original instruction has
> >> been
> >> >> >> replaced by the linker.
> >> >> >>
> >> >> > [Steven]: I still don't understand why there will be multiple fixups for
> the
> >> >> same symbol in the .reloc section?
> >> >> >
> >> >>
> >> >> Remember this example
> >> >>
> >> >> >> > int n;
> >> >> >> > int f () { return n; }
> >> >> >> > int g () { return n; }
> >> >> >> > int h () { return n; }
> >> >>
> >> >> If every 'return n' results in a GOTPCREL relocation, how are you
> >> >> going to make sure that the GOT entry for 'n' is only fixed up a
> >> >> single time?
> >> >
> >> > [Steven]: the 'return n' will not result in relocation, but the 'int n' will
> result
> >> in the relocation in GOT. The three 'return n' will point to the same 'int n'
> >> relocation item. So, we need only fixup 'int n' once, all three 'return n' will
> >> use the correct global 'n' value.
> >>
> >> Every 'return n' will result in a GOTPCREL relocation against n. And
> >> your code emits a relocation for the GOT entry every time.
> >>
> > [Steven]: I don't think so. please give a real case and offer its source code
> to prove " Every 'return n' will result in a GOTPCREL relocation against n ".
> >
> 
> Compiling the code above using
> 
> gcc -c -O -fpic /tmp/pie.c -o pie.o
> 
> and dumping it using
> 
> readelf -r pie.o
> 
> gives me
> 
> Relocation section '.rela.text' at offset 0x250 contains 3 entries:
>   Offset          Info           Type           Sym. Value    Sym. Name + Addend
> 000000000003  000a0000002a R_X86_64_REX_GOTP 0000000000000004 n -
> 4
> 00000000000d  000a0000002a R_X86_64_REX_GOTP 0000000000000004 n -
> 4
> 000000000017  000a0000002a R_X86_64_REX_GOTP 0000000000000004 n -
> 4
> ...
[Steven]: In this example, the pie.o is just the object file which is not linked. And if you link this pie.o file, the linker will solve all these three R_X86_64_REX_GOTP symbol with same 'int n' symbol address, and will create only one relocation item for 'int n' in the linked executable relocation section. So, we only need fixup once for the 'int n' in the linked executable.

Thanks
Steven

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
       [not found]                                       ` <06C8AB66E78EE34A949939824ABE2B310338275F@shsmsx102.ccr.corp.intel.com>
@ 2016-08-01 10:46                                         ` Ard Biesheuvel
  2016-08-02 11:40                                           ` Shi, Steven
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-08-01 10:46 UTC (permalink / raw)
  To: Shi, Steven, edk2-devel-01, Gao, Liming, afish@apple.com,
	Jordan Justen, Kinney, Michael D

(adding back our friends on cc)

On 1 August 2016 at 12:36, Shi, Steven <steven.shi@intel.com> wrote:
>> On 1 August 2016 at 12:16, Shi, Steven <steven.shi@intel.com> wrote:
>> >> OK, another example:
>> >>
>> >> pie.s:
>> >>
>> >>         .globl foo
>> >> foo:
>> >>         pushq n@GOTPCREL(%rip)
>> >>         popq    %rax
>> >>         ret
>> >>
>> >>         .globl  bar
>> >> bar:
>> >>         pushq   n@GOTPCREL(%rip)
>> >>         popq    %rax
>> >>         ret
>> >>
>> >>         .globl n
>> >> n:
>> >>         .quad 0
>> >>
>> >> compile and link using
>> >>
>> >> gcc -c -o pie.o /tmp/pie.s
>> >> ld -q -o pie pie.o -e foo
>> >>
>> >> gives me
>> >>
>> >> Relocation section '.rela.text' at offset 0x260 contains 2 entries:
>> >>   Offset          Info           Type           Sym. Value    Sym. Name + Addend
>> >> 0000004000b2  000700000009 R_X86_64_GOTPCREL 00000000004000be
>> n -
>> >> 4
>> >> 0000004000b9  000700000009 R_X86_64_GOTPCREL 00000000004000be
>> n -
>> >> 4
>> >>
>> >> Here, pie is a fully linked binary.
>> >>
>> > [Steven]: In this example, there are two R_X86_64_GOTPCREL relocation
>> address in the .text section need to fix up with same symbol runtime address,
>> these two relocation addresses are not same, and every relocation address
>> will be fixed up once. I don't see the problem of "Having multiple fixups for
>> the same symbol in the .reloc section", and  current GenFw code should has
>> no problem on this example.
>> >
>>
>> How many times will your code call CoffAddFixup() for the address of n?
> [Steven]: My understanding is the n address (6000c8) is not a GOTPCREL relocation in .text section, but the 4000b2 and 4000b2 are GOTPCREL relocation in .text section. My CoffAddFixup() will only call twice for 4000b2 and 4000b2, but not for n address (6000c8).
>
> Disassembly of section .text:
>
> 00000000004000b0 <foo>:
>   4000b0:       ff 35 12 00 20 00       pushq  0x200012(%rip)        # 6000c8 <n+0x200008>
>   4000b6:       58                      pop    %rax
>   4000b7:       c3                      retq
>
> 00000000004000b8 <bar>:
>   4000b8:       ff 35 0a 00 20 00       pushq  0x20000a(%rip)        # 6000c8 <n+0x200008>
>   4000be:       58                      pop    %rax
>   4000bf:       c3                      retq
>
> 00000000004000c0 <n>:
>         ...
>

CoffAddFixup() must be used for absolute symbol references only. These
instructions contain relative symbol references, which are
recalculated in WriteSections64().

The only absolute symbol reference is the GOT entry for 'n', and your
code (in WriteRelocations64()) calculates the address of the GOT entry
(which is always in .text BTW) and adds a fixup for it, i.e.,

+              CoffAddFixup(
+                (UINT32)(UINTN)((UINT64)
mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
+                EFI_IMAGE_REL_BASED_DIR64);

This code adds a fixup to the PE/COFF .reloc section for the GOT entry
containing the address of 'n', and the instructions perform a IP
relative load of the contents of the GOT entry to retrieve the address
of 'n'.

By adding two fixups, the PE/COFF loader will apply the load offset
twice, resulting in an incorrect value.

-- 
Ard.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-01 10:46                                         ` Ard Biesheuvel
@ 2016-08-02 11:40                                           ` Shi, Steven
  2016-08-02 12:00                                             ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Shi, Steven @ 2016-08-02 11:40 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

> 
> CoffAddFixup() must be used for absolute symbol references only. These
> instructions contain relative symbol references, which are
> recalculated in WriteSections64().
> 
> The only absolute symbol reference is the GOT entry for 'n', and your
> code (in WriteRelocations64()) calculates the address of the GOT entry
> (which is always in .text BTW) and adds a fixup for it, i.e.,
> 
> +              CoffAddFixup(
> +                (UINT32)(UINTN)((UINT64)
> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
> +                EFI_IMAGE_REL_BASED_DIR64);
> 
> This code adds a fixup to the PE/COFF .reloc section for the GOT entry
> containing the address of 'n', and the instructions perform a IP
> relative load of the contents of the GOT entry to retrieve the address
> of 'n'.
> 
> By adding two fixups, the PE/COFF loader will apply the load offset
> twice, resulting in an incorrect value.
> 
OK, I get your point now. Yes, the current patch could generate multiple fixups for the same GOT relocation entry. How about we introduce a simple IsDuplicatedCoffFixup() to check whether a converting fixup offset is duplicated before we use CoffAddFixup() to really add it? If it is new, we add it, otherwise just skip it.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-02 11:40                                           ` Shi, Steven
@ 2016-08-02 12:00                                             ` Ard Biesheuvel
  2016-08-03 20:13                                               ` Jordan Justen
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-08-02 12:00 UTC (permalink / raw)
  To: Shi, Steven
  Cc: edk2-devel-01, Gao, Liming, afish@apple.com, Justen, Jordan L,
	Kinney, Michael D

On 2 August 2016 at 13:40, Shi, Steven <steven.shi@intel.com> wrote:
>>
>> CoffAddFixup() must be used for absolute symbol references only. These
>> instructions contain relative symbol references, which are
>> recalculated in WriteSections64().
>>
>> The only absolute symbol reference is the GOT entry for 'n', and your
>> code (in WriteRelocations64()) calculates the address of the GOT entry
>> (which is always in .text BTW) and adds a fixup for it, i.e.,
>>
>> +              CoffAddFixup(
>> +                (UINT32)(UINTN)((UINT64)
>> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
>> +                EFI_IMAGE_REL_BASED_DIR64);
>>
>> This code adds a fixup to the PE/COFF .reloc section for the GOT entry
>> containing the address of 'n', and the instructions perform a IP
>> relative load of the contents of the GOT entry to retrieve the address
>> of 'n'.
>>
>> By adding two fixups, the PE/COFF loader will apply the load offset
>> twice, resulting in an incorrect value.
>>
> OK, I get your point now. Yes, the current patch could generate multiple fixups for the same GOT relocation entry. How about we introduce a simple IsDuplicatedCoffFixup() to check whether a converting fixup offset is duplicated before we use CoffAddFixup() to really add it? If it is new, we add it, otherwise just skip it.

That could work, but you have to be aware that fixups are best emitted
in the order they need to be applied in the binary, or it will become
very inefficient. (Please refer to the PE/COFF spec section that
explains the layout of the .reloc section)

What it comes down to is that relocations are grouped by target page,
and for every place in the page that requires a relocation to be
applied, a 4 bit type is emitted followed by a 12-bit offset, which is
the offset into the current page. If you emit fixups for the current
instruction, followed by one for the GOT, it will basically take two
'page switches' every time.

So it would be better to simply emit the relocations, but introduce a
sorting pass that merges all duplicates as well.

Thanks,
Ard.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-02 12:00                                             ` Ard Biesheuvel
@ 2016-08-03 20:13                                               ` Jordan Justen
  2016-08-03 20:47                                                 ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Jordan Justen @ 2016-08-03 20:13 UTC (permalink / raw)
  To: Ard Biesheuvel, Shi, Steven
  Cc: Kinney, Michael D, edk2-devel-01, afish@apple.com, Gao, Liming,
	mischief

Where does this patch stand? I think Ard was asking for it to be
split, but also wondering if it was really required...

Some devs are still reporting unsupported relocation errors during the
build. (mischief on irc, for example.)

-Jordan

On 2016-08-02 05:00:43, Ard Biesheuvel wrote:
> On 2 August 2016 at 13:40, Shi, Steven <steven.shi@intel.com> wrote:
> >>
> >> CoffAddFixup() must be used for absolute symbol references only. These
> >> instructions contain relative symbol references, which are
> >> recalculated in WriteSections64().
> >>
> >> The only absolute symbol reference is the GOT entry for 'n', and your
> >> code (in WriteRelocations64()) calculates the address of the GOT entry
> >> (which is always in .text BTW) and adds a fixup for it, i.e.,
> >>
> >> +              CoffAddFixup(
> >> +                (UINT32)(UINTN)((UINT64)
> >> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
> >> +                EFI_IMAGE_REL_BASED_DIR64);
> >>
> >> This code adds a fixup to the PE/COFF .reloc section for the GOT entry
> >> containing the address of 'n', and the instructions perform a IP
> >> relative load of the contents of the GOT entry to retrieve the address
> >> of 'n'.
> >>
> >> By adding two fixups, the PE/COFF loader will apply the load offset
> >> twice, resulting in an incorrect value.
> >>
> > OK, I get your point now. Yes, the current patch could generate multiple fixups for the same GOT relocation entry. How about we introduce a simple IsDuplicatedCoffFixup() to check whether a converting fixup offset is duplicated before we use CoffAddFixup() to really add it? If it is new, we add it, otherwise just skip it.
> 
> That could work, but you have to be aware that fixups are best emitted
> in the order they need to be applied in the binary, or it will become
> very inefficient. (Please refer to the PE/COFF spec section that
> explains the layout of the .reloc section)
> 
> What it comes down to is that relocations are grouped by target page,
> and for every place in the page that requires a relocation to be
> applied, a 4 bit type is emitted followed by a 12-bit offset, which is
> the offset into the current page. If you emit fixups for the current
> instruction, followed by one for the GOT, it will basically take two
> 'page switches' every time.
> 
> So it would be better to simply emit the relocations, but introduce a
> sorting pass that merges all duplicates as well.
> 
> Thanks,
> Ard.
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-03 20:13                                               ` Jordan Justen
@ 2016-08-03 20:47                                                 ` Ard Biesheuvel
  2016-08-03 20:53                                                   ` Jordan Justen
  2016-08-03 20:55                                                   ` Nicolas Owens
  0 siblings, 2 replies; 24+ messages in thread
From: Ard Biesheuvel @ 2016-08-03 20:47 UTC (permalink / raw)
  To: Jordan Justen
  Cc: Shi, Steven, Kinney, Michael D, edk2-devel-01, afish@apple.com,
	Gao, Liming, mischief


> On 3 aug. 2016, at 22:13, Jordan Justen <jordan.l.justen@intel.com> wrote:
> 
> Where does this patch stand? I think Ard was asking for it to be
> split, but also wondering if it was really required...
> 
> Some devs are still reporting unsupported relocation errors during the
> build. (mischief on irc, for example.)
> 

The patch is not correct in its current form. PLT relocations (0x4) can be handled ok, so we can split that off and merge it. The GOT based relocation handling needs non-trivial rework, and may currently create corrupt binaries. Which unhandled reloc types are being reported?


> 
>> On 2016-08-02 05:00:43, Ard Biesheuvel wrote:
>> On 2 August 2016 at 13:40, Shi, Steven <steven.shi@intel.com> wrote:
>>>> 
>>>> CoffAddFixup() must be used for absolute symbol references only. These
>>>> instructions contain relative symbol references, which are
>>>> recalculated in WriteSections64().
>>>> 
>>>> The only absolute symbol reference is the GOT entry for 'n', and your
>>>> code (in WriteRelocations64()) calculates the address of the GOT entry
>>>> (which is always in .text BTW) and adds a fixup for it, i.e.,
>>>> 
>>>> +              CoffAddFixup(
>>>> +                (UINT32)(UINTN)((UINT64)
>>>> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
>>>> +                EFI_IMAGE_REL_BASED_DIR64);
>>>> 
>>>> This code adds a fixup to the PE/COFF .reloc section for the GOT entry
>>>> containing the address of 'n', and the instructions perform a IP
>>>> relative load of the contents of the GOT entry to retrieve the address
>>>> of 'n'.
>>>> 
>>>> By adding two fixups, the PE/COFF loader will apply the load offset
>>>> twice, resulting in an incorrect value.
>>> OK, I get your point now. Yes, the current patch could generate multiple fixups for the same GOT relocation entry. How about we introduce a simple IsDuplicatedCoffFixup() to check whether a converting fixup offset is duplicated before we use CoffAddFixup() to really add it? If it is new, we add it, otherwise just skip it.
>> 
>> That could work, but you have to be aware that fixups are best emitted
>> in the order they need to be applied in the binary, or it will become
>> very inefficient. (Please refer to the PE/COFF spec section that
>> explains the layout of the .reloc section)
>> 
>> What it comes down to is that relocations are grouped by target page,
>> and for every place in the page that requires a relocation to be
>> applied, a 4 bit type is emitted followed by a 12-bit offset, which is
>> the offset into the current page. If you emit fixups for the current
>> instruction, followed by one for the GOT, it will basically take two
>> 'page switches' every time.
>> 
>> So it would be better to simply emit the relocations, but introduce a
>> sorting pass that merges all duplicates as well.
>> 
>> Thanks,
>> Ard.
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-03 20:47                                                 ` Ard Biesheuvel
@ 2016-08-03 20:53                                                   ` Jordan Justen
  2016-08-03 20:55                                                     ` Ard Biesheuvel
  2016-08-03 20:55                                                   ` Nicolas Owens
  1 sibling, 1 reply; 24+ messages in thread
From: Jordan Justen @ 2016-08-03 20:53 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Shi, Steven, Kinney, Michael D, edk2-devel-01, afish@apple.com,
	Gao, Liming, mischief

On 2016-08-03 13:47:09, Ard Biesheuvel wrote:
> 
> > On 3 aug. 2016, at 22:13, Jordan Justen <jordan.l.justen@intel.com> wrote:
> > 
> > Where does this patch stand? I think Ard was asking for it to be
> > split, but also wondering if it was really required...
> > 
> > Some devs are still reporting unsupported relocation errors during the
> > build. (mischief on irc, for example.)
> > 
> 
> The patch is not correct in its current form. PLT relocations (0x4)
> can be handled ok, so we can split that off and merge it. The GOT
> based relocation handling needs non-trivial rework, and may
> currently create corrupt binaries. Which unhandled reloc types are
> being reported?
> 

"unsupported ELF EM_X86_64 relocation 0x4"

You might join irc if you want to get some more info from mischief
about it.

-Jordan

> 
> > 
> >> On 2016-08-02 05:00:43, Ard Biesheuvel wrote:
> >> On 2 August 2016 at 13:40, Shi, Steven <steven.shi@intel.com> wrote:
> >>>> 
> >>>> CoffAddFixup() must be used for absolute symbol references only. These
> >>>> instructions contain relative symbol references, which are
> >>>> recalculated in WriteSections64().
> >>>> 
> >>>> The only absolute symbol reference is the GOT entry for 'n', and your
> >>>> code (in WriteRelocations64()) calculates the address of the GOT entry
> >>>> (which is always in .text BTW) and adds a fixup for it, i.e.,
> >>>> 
> >>>> +              CoffAddFixup(
> >>>> +                (UINT32)(UINTN)((UINT64)
> >>>> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
> >>>> +                EFI_IMAGE_REL_BASED_DIR64);
> >>>> 
> >>>> This code adds a fixup to the PE/COFF .reloc section for the GOT entry
> >>>> containing the address of 'n', and the instructions perform a IP
> >>>> relative load of the contents of the GOT entry to retrieve the address
> >>>> of 'n'.
> >>>> 
> >>>> By adding two fixups, the PE/COFF loader will apply the load offset
> >>>> twice, resulting in an incorrect value.
> >>> OK, I get your point now. Yes, the current patch could generate multiple fixups for the same GOT relocation entry. How about we introduce a simple IsDuplicatedCoffFixup() to check whether a converting fixup offset is duplicated before we use CoffAddFixup() to really add it? If it is new, we add it, otherwise just skip it.
> >> 
> >> That could work, but you have to be aware that fixups are best emitted
> >> in the order they need to be applied in the binary, or it will become
> >> very inefficient. (Please refer to the PE/COFF spec section that
> >> explains the layout of the .reloc section)
> >> 
> >> What it comes down to is that relocations are grouped by target page,
> >> and for every place in the page that requires a relocation to be
> >> applied, a 4 bit type is emitted followed by a 12-bit offset, which is
> >> the offset into the current page. If you emit fixups for the current
> >> instruction, followed by one for the GOT, it will basically take two
> >> 'page switches' every time.
> >> 
> >> So it would be better to simply emit the relocations, but introduce a
> >> sorting pass that merges all duplicates as well.
> >> 
> >> Thanks,
> >> Ard.
> >> _______________________________________________
> >> edk2-devel mailing list
> >> edk2-devel@lists.01.org
> >> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-03 20:47                                                 ` Ard Biesheuvel
  2016-08-03 20:53                                                   ` Jordan Justen
@ 2016-08-03 20:55                                                   ` Nicolas Owens
  1 sibling, 0 replies; 24+ messages in thread
From: Nicolas Owens @ 2016-08-03 20:55 UTC (permalink / raw)
  To: Ard Biesheuvel, Jordan Justen
  Cc: Shi, Steven, Kinney, Michael D, edk2-devel-01, afish@apple.com,
	Gao, Liming



On 08/03/2016 01:47 PM, Ard Biesheuvel wrote:
> 
>> On 3 aug. 2016, at 22:13, Jordan Justen <jordan.l.justen@intel.com> wrote:
>>
>> Where does this patch stand? I think Ard was asking for it to be
>> split, but also wondering if it was really required...
>>
>> Some devs are still reporting unsupported relocation errors during the
>> build. (mischief on irc, for example.)
>>
> 
> The patch is not correct in its current form. PLT relocations (0x4) can be handled ok, so we can split that off and merge it. The GOT based relocation handling needs non-trivial rework, and may currently create corrupt binaries. Which unhandled reloc types are being reported?

currently, i see:

"GenFw" -e UEFI_APPLICATION -o
/home/mischief/src/efivim/edk2/Build/vim/DEBUG_GCC49/X64/vim/DEBUG/vim.efi
/home/mischief/src/efivim/edk2/Build/vim/DEBUG_GCC49/X64/vim/DEBUG/vim.dll
GenFw: ERROR 3000: Invalid
make[1]: ***
[/home/mischief/src/efivim/edk2/Build/vim/DEBUG_GCC49/X64/vim/DEBUG/vim.efi]
Error 2

/home/mischief/src/efivim/edk2/Build/vim/DEBUG_GCC49/X64/vim/DEBUG/vim.dll
unsupported ELF EM_X86_64 relocation 0x4.

this is off edk2 master from about 2 days ago.

> 
> 
>>
>>> On 2016-08-02 05:00:43, Ard Biesheuvel wrote:
>>> On 2 August 2016 at 13:40, Shi, Steven <steven.shi@intel.com> wrote:
>>>>>
>>>>> CoffAddFixup() must be used for absolute symbol references only. These
>>>>> instructions contain relative symbol references, which are
>>>>> recalculated in WriteSections64().
>>>>>
>>>>> The only absolute symbol reference is the GOT entry for 'n', and your
>>>>> code (in WriteRelocations64()) calculates the address of the GOT entry
>>>>> (which is always in .text BTW) and adds a fixup for it, i.e.,
>>>>>
>>>>> +              CoffAddFixup(
>>>>> +                (UINT32)(UINTN)((UINT64)
>>>>> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
>>>>> +                EFI_IMAGE_REL_BASED_DIR64);
>>>>>
>>>>> This code adds a fixup to the PE/COFF .reloc section for the GOT entry
>>>>> containing the address of 'n', and the instructions perform a IP
>>>>> relative load of the contents of the GOT entry to retrieve the address
>>>>> of 'n'.
>>>>>
>>>>> By adding two fixups, the PE/COFF loader will apply the load offset
>>>>> twice, resulting in an incorrect value.
>>>> OK, I get your point now. Yes, the current patch could generate multiple fixups for the same GOT relocation entry. How about we introduce a simple IsDuplicatedCoffFixup() to check whether a converting fixup offset is duplicated before we use CoffAddFixup() to really add it? If it is new, we add it, otherwise just skip it.
>>>
>>> That could work, but you have to be aware that fixups are best emitted
>>> in the order they need to be applied in the binary, or it will become
>>> very inefficient. (Please refer to the PE/COFF spec section that
>>> explains the layout of the .reloc section)
>>>
>>> What it comes down to is that relocations are grouped by target page,
>>> and for every place in the page that requires a relocation to be
>>> applied, a 4 bit type is emitted followed by a 12-bit offset, which is
>>> the offset into the current page. If you emit fixups for the current
>>> instruction, followed by one for the GOT, it will basically take two
>>> 'page switches' every time.
>>>
>>> So it would be better to simply emit the relocations, but introduce a
>>> sorting pass that merges all duplicates as well.
>>>
>>> Thanks,
>>> Ard.
>>> _______________________________________________
>>> edk2-devel mailing list
>>> edk2-devel@lists.01.org
>>> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-03 20:53                                                   ` Jordan Justen
@ 2016-08-03 20:55                                                     ` Ard Biesheuvel
  2016-08-03 23:26                                                       ` Shi, Steven
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2016-08-03 20:55 UTC (permalink / raw)
  To: Jordan Justen
  Cc: Shi, Steven, Kinney, Michael D, edk2-devel-01, afish@apple.com,
	Gao, Liming, mischief


> On 3 aug. 2016, at 22:53, Jordan Justen <jordan.l.justen@intel.com> wrote:
> 
>> On 2016-08-03 13:47:09, Ard Biesheuvel wrote:
>> 
>>> On 3 aug. 2016, at 22:13, Jordan Justen <jordan.l.justen@intel.com> wrote:
>>> 
>>> Where does this patch stand? I think Ard was asking for it to be
>>> split, but also wondering if it was really required...
>>> 
>>> Some devs are still reporting unsupported relocation errors during the
>>> build. (mischief on irc, for example.)
>> 
>> The patch is not correct in its current form. PLT relocations (0x4)
>> can be handled ok, so we can split that off and merge it. The GOT
>> based relocation handling needs non-trivial rework, and may
>> currently create corrupt binaries. Which unhandled reloc types are
>> being reported?
> 
> "unsupported ELF EM_X86_64 relocation 0x4"
> 
> You might join irc if you want to get some more info from mischief
> about it.
> 

That's the plt one, which we can fix easily. I'll whip up a patch in the morning (11 pm here now)


> 
>> 
>>> 
>>>> On 2016-08-02 05:00:43, Ard Biesheuvel wrote:
>>>> On 2 August 2016 at 13:40, Shi, Steven <steven.shi@intel.com> wrote:
>>>>>> 
>>>>>> CoffAddFixup() must be used for absolute symbol references only. These
>>>>>> instructions contain relative symbol references, which are
>>>>>> recalculated in WriteSections64().
>>>>>> 
>>>>>> The only absolute symbol reference is the GOT entry for 'n', and your
>>>>>> code (in WriteRelocations64()) calculates the address of the GOT entry
>>>>>> (which is always in .text BTW) and adds a fixup for it, i.e.,
>>>>>> 
>>>>>> +              CoffAddFixup(
>>>>>> +                (UINT32)(UINTN)((UINT64)
>>>>>> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
>>>>>> +                EFI_IMAGE_REL_BASED_DIR64);
>>>>>> 
>>>>>> This code adds a fixup to the PE/COFF .reloc section for the GOT entry
>>>>>> containing the address of 'n', and the instructions perform a IP
>>>>>> relative load of the contents of the GOT entry to retrieve the address
>>>>>> of 'n'.
>>>>>> 
>>>>>> By adding two fixups, the PE/COFF loader will apply the load offset
>>>>>> twice, resulting in an incorrect value.
>>>>> OK, I get your point now. Yes, the current patch could generate multiple fixups for the same GOT relocation entry. How about we introduce a simple IsDuplicatedCoffFixup() to check whether a converting fixup offset is duplicated before we use CoffAddFixup() to really add it? If it is new, we add it, otherwise just skip it.
>>>> 
>>>> That could work, but you have to be aware that fixups are best emitted
>>>> in the order they need to be applied in the binary, or it will become
>>>> very inefficient. (Please refer to the PE/COFF spec section that
>>>> explains the layout of the .reloc section)
>>>> 
>>>> What it comes down to is that relocations are grouped by target page,
>>>> and for every place in the page that requires a relocation to be
>>>> applied, a 4 bit type is emitted followed by a 12-bit offset, which is
>>>> the offset into the current page. If you emit fixups for the current
>>>> instruction, followed by one for the GOT, it will basically take two
>>>> 'page switches' every time.
>>>> 
>>>> So it would be better to simply emit the relocations, but introduce a
>>>> sorting pass that merges all duplicates as well.
>>>> 
>>>> Thanks,
>>>> Ard.
>>>> _______________________________________________
>>>> edk2-devel mailing list
>>>> edk2-devel@lists.01.org
>>>> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code
  2016-08-03 20:55                                                     ` Ard Biesheuvel
@ 2016-08-03 23:26                                                       ` Shi, Steven
  0 siblings, 0 replies; 24+ messages in thread
From: Shi, Steven @ 2016-08-03 23:26 UTC (permalink / raw)
  To: Ard Biesheuvel, Justen, Jordan L
  Cc: Kinney, Michael D, edk2-devel-01, afish@apple.com, Gao, Liming,
	mischief@offblast.org

Ard,
Pls go ahead to add R_X86_64_PLT32 firstly. Below is my original path. And for the GOTPCREL type ones, I could finish enhance them after I back from vacation next week. Thanks.
https://github.com/shijunjing/edk2/commit/dd8b1c4625cbffc7e149571266e0ae0581bd207d



Steven Shi
Intel\SSG\STO\UEFI Firmware

Tel: +86 021-61166522
iNet: 821-6522


> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: Thursday, August 04, 2016 4:55 AM
> To: Justen, Jordan L <jordan.l.justen@intel.com>
> Cc: Shi, Steven <steven.shi@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; edk2-devel-01 <edk2-devel@lists.01.org>;
> afish@apple.com; Gao, Liming <liming.gao@intel.com>;
> mischief@offblast.org
> Subject: Re: [edk2] [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf
> relocation types for PIC/PIE code
> 
> 
> > On 3 aug. 2016, at 22:53, Jordan Justen <jordan.l.justen@intel.com> wrote:
> >
> >> On 2016-08-03 13:47:09, Ard Biesheuvel wrote:
> >>
> >>> On 3 aug. 2016, at 22:13, Jordan Justen <jordan.l.justen@intel.com>
> wrote:
> >>>
> >>> Where does this patch stand? I think Ard was asking for it to be
> >>> split, but also wondering if it was really required...
> >>>
> >>> Some devs are still reporting unsupported relocation errors during the
> >>> build. (mischief on irc, for example.)
> >>
> >> The patch is not correct in its current form. PLT relocations (0x4)
> >> can be handled ok, so we can split that off and merge it. The GOT
> >> based relocation handling needs non-trivial rework, and may
> >> currently create corrupt binaries. Which unhandled reloc types are
> >> being reported?
> >
> > "unsupported ELF EM_X86_64 relocation 0x4"
> >
> > You might join irc if you want to get some more info from mischief
> > about it.
> >
> 
> That's the plt one, which we can fix easily. I'll whip up a patch in the morning
> (11 pm here now)
> 
> 
> >
> >>
> >>>
> >>>> On 2016-08-02 05:00:43, Ard Biesheuvel wrote:
> >>>> On 2 August 2016 at 13:40, Shi, Steven <steven.shi@intel.com> wrote:
> >>>>>>
> >>>>>> CoffAddFixup() must be used for absolute symbol references only.
> These
> >>>>>> instructions contain relative symbol references, which are
> >>>>>> recalculated in WriteSections64().
> >>>>>>
> >>>>>> The only absolute symbol reference is the GOT entry for 'n', and your
> >>>>>> code (in WriteRelocations64()) calculates the address of the GOT
> entry
> >>>>>> (which is always in .text BTW) and adds a fixup for it, i.e.,
> >>>>>>
> >>>>>> +              CoffAddFixup(
> >>>>>> +                (UINT32)(UINTN)((UINT64)
> >>>>>> mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset),
> >>>>>> +                EFI_IMAGE_REL_BASED_DIR64);
> >>>>>>
> >>>>>> This code adds a fixup to the PE/COFF .reloc section for the GOT
> entry
> >>>>>> containing the address of 'n', and the instructions perform a IP
> >>>>>> relative load of the contents of the GOT entry to retrieve the address
> >>>>>> of 'n'.
> >>>>>>
> >>>>>> By adding two fixups, the PE/COFF loader will apply the load offset
> >>>>>> twice, resulting in an incorrect value.
> >>>>> OK, I get your point now. Yes, the current patch could generate
> multiple fixups for the same GOT relocation entry. How about we introduce a
> simple IsDuplicatedCoffFixup() to check whether a converting fixup offset is
> duplicated before we use CoffAddFixup() to really add it? If it is new, we add
> it, otherwise just skip it.
> >>>>
> >>>> That could work, but you have to be aware that fixups are best emitted
> >>>> in the order they need to be applied in the binary, or it will become
> >>>> very inefficient. (Please refer to the PE/COFF spec section that
> >>>> explains the layout of the .reloc section)
> >>>>
> >>>> What it comes down to is that relocations are grouped by target page,
> >>>> and for every place in the page that requires a relocation to be
> >>>> applied, a 4 bit type is emitted followed by a 12-bit offset, which is
> >>>> the offset into the current page. If you emit fixups for the current
> >>>> instruction, followed by one for the GOT, it will basically take two
> >>>> 'page switches' every time.
> >>>>
> >>>> So it would be better to simply emit the relocations, but introduce a
> >>>> sorting pass that merges all duplicates as well.
> >>>>
> >>>> Thanks,
> >>>> Ard.
> >>>> _______________________________________________
> >>>> edk2-devel mailing list
> >>>> edk2-devel@lists.01.org
> >>>> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2016-08-03 23:26 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1467967364-11556-1-git-send-email-steven.shi@intel.com>
     [not found] ` <1467967364-11556-3-git-send-email-steven.shi@intel.com>
2016-07-30  9:25   ` [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code Ard Biesheuvel
2016-07-30 14:09     ` Shi, Steven
2016-07-30 14:11       ` Ard Biesheuvel
2016-07-31  3:08         ` Shi, Steven
2016-07-31  5:42           ` Ard Biesheuvel
2016-07-31 19:10             ` Ard Biesheuvel
2016-08-01  4:39               ` Shi, Steven
2016-08-01  5:58                 ` Ard Biesheuvel
2016-08-01  6:13                   ` Shi, Steven
2016-08-01  6:43                     ` Ard Biesheuvel
2016-08-01  7:19                       ` Shi, Steven
2016-08-01  7:25                         ` Ard Biesheuvel
2016-08-01  7:54                           ` Shi, Steven
2016-08-01  8:00                             ` Ard Biesheuvel
2016-08-01  8:28                               ` Shi, Steven
     [not found]                               ` <06C8AB66E78EE34A949939824ABE2B31033825EE@shsmsx102.ccr.corp.intel.com>
     [not found]                                 ` <CAKv+Gu80u+CJLVtD5tTo5RrJb7LH0Qfnbj=7b7NUqrbf2aOPrA@mail.gmail.com>
     [not found]                                   ` <06C8AB66E78EE34A949939824ABE2B31033826FE@shsmsx102.ccr.corp.intel.com>
     [not found]                                     ` <CAKv+Gu9MSisR1T_jr=DNyCs24We5=2vUgQZJ9t_rZmCYC8qvHg@mail.gmail.com>
     [not found]                                       ` <06C8AB66E78EE34A949939824ABE2B310338275F@shsmsx102.ccr.corp.intel.com>
2016-08-01 10:46                                         ` Ard Biesheuvel
2016-08-02 11:40                                           ` Shi, Steven
2016-08-02 12:00                                             ` Ard Biesheuvel
2016-08-03 20:13                                               ` Jordan Justen
2016-08-03 20:47                                                 ` Ard Biesheuvel
2016-08-03 20:53                                                   ` Jordan Justen
2016-08-03 20:55                                                     ` Ard Biesheuvel
2016-08-03 23:26                                                       ` Shi, Steven
2016-08-03 20:55                                                   ` Nicolas Owens

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox