Hi Zenith, BTW, besides the build pass, did you try to run a Uefi binary, e.g. a simple shell application, which contain the GOTPCREL relocations? If yes. Please send out your test case code as well. I appreciate if you could contribute your test cases as the patch together.
Steven Shi Intel\SSG\STO\UEFI Firmware Tel: +86 021-61166522 iNet: 821-6522 > -----Original Message----- > From: Shi, Steven > Sent: Thursday, June 7, 2018 10:18 AM > To: Shi, Steven <steven....@intel.com>; Gao, Liming > <liming....@intel.com>; Zenith432 <zenith...@users.sourceforge.net>; > edk2-devel@lists.01.org > Subject: RE: [PATCH] BaseTools/GenFw: Add X64 GOTPCREL Support to > GenFw > > Please see more details in > https://bugzilla.tianocore.org/show_bug.cgi?id=970 > > > Steven Shi > Intel\SSG\STO\UEFI Firmware > > Tel: +86 021-61166522 > iNet: 821-6522 > > > > -----Original Message----- > > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of > Shi, > > Steven > > Sent: Thursday, June 7, 2018 10:16 AM > > To: Gao, Liming <liming....@intel.com>; Zenith432 > > <zenith...@users.sourceforge.net>; edk2-devel@lists.01.org > > Subject: Re: [edk2] [PATCH] BaseTools/GenFw: Add X64 GOTPCREL Support > > to GenFw > > > > Yes. If we disable the '#pragma GCC visibility push (hidden)' in > > ProcessorBind.h, the GOTPCREL support is mandatory. 3rd party module > > build might need it. It's more complete to add GOTPCREL support. > > > > The hidden #pragma can hide all ELF symbols' visibility, including 'extern' > > functions, which is to let Linux compilers aware that we don’t need loading > > dynamic link library in Uefi runing, please not emit the GOTPCREL based > > relocations in the obj file, and we will ensure the linker can get all > > extern > > functions statically solved. The reason of not emitting GOTPCREL based > > relocations is because it is hard to convert the GOTPCREL based relocations > > in ELF binary to PE/COFF related relocations, and our current GenFw has > not > > supported them. I'm glade if we can add the GOTPCREL support in GenFW > to > > totally solve this problem. > > > > Steven Shi > > Intel\SSG\STO\UEFI Firmware > > > > Tel: +86 021-61166522 > > iNet: 821-6522 > > > > > -----Original Message----- > > > From: Gao, Liming > > > Sent: Thursday, June 7, 2018 9:32 AM > > > To: Zenith432 <zenith...@users.sourceforge.net>; edk2- > > de...@lists.01.org > > > Cc: Shi, Steven <steven....@intel.com>; Zhu, Yonghong > > > <yonghong....@intel.com> > > > Subject: RE: [PATCH] BaseTools/GenFw: Add X64 GOTPCREL Support to > > > GenFw > > > > > > What's purpose to support GOTPCREL in GenFw? Could you introduce > your > > > usage model? > > > > > > > -----Original Message----- > > > > From: Zenith432 [mailto:zenith...@users.sourceforge.net] > > > > Sent: Thursday, June 7, 2018 2:01 AM > > > > To: edk2-devel@lists.01.org > > > > Cc: Shi, Steven <steven....@intel.com>; Zhu, Yonghong > > > <yonghong....@intel.com>; Gao, Liming <liming....@intel.com> > > > > Subject: [PATCH] BaseTools/GenFw: Add X64 GOTPCREL Support to > > GenFw > > > > > > > > Adds support for the following X64 ELF relocations to GenFw > > > > R_X86_64_GOTPCREL > > > > R_X86_64_GOTPCRELX > > > > R_X86_64_REX_GOTPCRELX > > > > > > > > CC: Shi Steven <steven....@intel.com> > > > > CC: Yonghong Zhu <yonghong....@intel.com> > > > > CC: Liming Gao <liming....@intel.com> > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > > > Signed-off-by: Zenith432 <zenith...@users.sourceforge.net> > > > > --- > > > > BaseTools/Source/C/GenFw/Elf64Convert.c | 166 > > > +++++++++++++++++++++++- > > > > BaseTools/Source/C/GenFw/elf_common.h | 23 ++++ > > > > 2 files changed, 188 insertions(+), 1 deletion(-) > > > > > > > > diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c > > > b/BaseTools/Source/C/GenFw/Elf64Convert.c > > > > index c39bdff0..d2f9bb46 100644 > > > > --- a/BaseTools/Source/C/GenFw/Elf64Convert.c > > > > +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c > > > > @@ -94,6 +94,15 @@ STATIC Elf_Ehdr *mEhdr; > > > > STATIC Elf_Shdr *mShdrBase; > > > > STATIC Elf_Phdr *mPhdrBase; > > > > > > > > +// > > > > +// GOT information > > > > +// > > > > +STATIC Elf_Shdr *mGOTShdr = NULL; > > > > +STATIC UINT32 mGOTShindex = 0; > > > > +STATIC UINT32 *mGOTCoffEntries = NULL; > > > > +STATIC UINT32 mGOTMaxCoffEntries = 0; > > > > +STATIC UINT32 mGOTNumCoffEntries = 0; > > > > + > > > > // > > > > // Coff information > > > > // > > > > @@ -322,6 +331,117 @@ GetSymName ( > > > > return StrtabContents + Sym->st_name; > > > > } > > > > > > > > +// > > > > +// Find the ELF section hosting the GOT from an ELF Rva > > > > +// of a single GOT entry. Normally, GOT is placed in > > > > +// ELF .text section, so assume once we find in which > > > > +// section the GOT is, all GOT entries are there, and > > > > +// just verify this. > > > > +// > > > > +STATIC > > > > +VOID > > > > +FindElfGOTSectionFromGOTEntryElfRva ( > > > > + Elf64_Addr GOTEntryElfRva > > > > + ) > > > > +{ > > > > + UINT32 i; > > > > + if (mGOTShdr != NULL) { > > > > + if (GOTEntryElfRva >= mGOTShdr->sh_addr && > > > > + GOTEntryElfRva < mGOTShdr->sh_addr + mGOTShdr->sh_size) > > > > + return; > > > > + Error (NULL, 0, 3000, "Unsupported", > > > "FindElfGOTSectionFromGOTEntryElfRva: GOT entries found in multiple > > > sections."); > > > > + exit(EXIT_FAILURE); > > > > + } > > > > + for (i = 0; i < mEhdr->e_shnum; i++) { > > > > + Elf_Shdr *shdr = GetShdrByIndex(i); > > > > + if (GOTEntryElfRva >= shdr->sh_addr && > > > > + GOTEntryElfRva < shdr->sh_addr + shdr->sh_size) { > > > > + mGOTShdr = shdr; > > > > + mGOTShindex = i; > > > > + return; > > > > + } > > > > + } > > > > + Error (NULL, 0, 3000, "Invalid", > > "FindElfGOTSectionFromGOTEntryElfRva: > > > ElfRva 0x%016LX for GOT entry not found in any section.", > > > > GOTEntryElfRva); > > > > + exit(EXIT_FAILURE); > > > > +} > > > > + > > > > +// > > > > +// Stores locations of GOT entries in COFF image. > > > > +// Returns TRUE if GOT entry is new. > > > > +// Simple implementation as number of GOT > > > > +// entries is expected to be low. > > > > +// > > > > + > > > > +STATIC > > > > +BOOLEAN > > > > +AccumulateCoffGOTEntries ( > > > > + UINT32 GOTCoffEntry > > > > + ) > > > > +{ > > > > + UINT32 i; > > > > + if (mGOTCoffEntries != NULL) { > > > > + for (i = 0; i < mGOTNumCoffEntries; i++) > > > > + if (mGOTCoffEntries[i] == GOTCoffEntry) > > > > + return FALSE; > > > > + } > > > > + if (mGOTCoffEntries == NULL) { > > > > + mGOTCoffEntries = (UINT32*)malloc(5 * sizeof *mGOTCoffEntries); > > > > + if (mGOTCoffEntries == NULL) { > > > > + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); > > > > + } > > > > + assert (mGOTCoffEntries != NULL); > > > > + mGOTMaxCoffEntries = 5; > > > > + mGOTNumCoffEntries = 0; > > > > + } else if (mGOTNumCoffEntries == mGOTMaxCoffEntries) { > > > > + mGOTCoffEntries = (UINT32*)realloc(mGOTCoffEntries, 2 * > > > mGOTMaxCoffEntries * sizeof *mGOTCoffEntries); > > > > + if (mGOTCoffEntries == NULL) { > > > > + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); > > > > + } > > > > + assert (mGOTCoffEntries != NULL); > > > > + mGOTMaxCoffEntries += mGOTMaxCoffEntries; > > > > + } > > > > + mGOTCoffEntries[mGOTNumCoffEntries++] = GOTCoffEntry; > > > > + return TRUE; > > > > +} > > > > + > > > > +STATIC > > > > +int > > > > +__comparator ( > > > > + const void* lhs, > > > > + const void* rhs > > > > + ) > > > > +{ > > > > + if (*(const UINT32*)lhs < *(const UINT32*)rhs) > > > > + return -1; > > > > + return *(const UINT32*)lhs > *(const UINT32*)rhs; > > > > +} > > > > + > > > > +STATIC > > > > +VOID > > > > +EmitGOTRelocations ( > > > > + VOID > > > > + ) > > > > +{ > > > > + UINT32 i; > > > > + if (mGOTCoffEntries == NULL) > > > > + return; > > > > + qsort( > > > > + mGOTCoffEntries, > > > > + mGOTNumCoffEntries, > > > > + sizeof *mGOTCoffEntries, > > > > + __comparator); > > > > + for (i = 0; i < mGOTNumCoffEntries; i++) { > > > > + VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X", > > > mGOTCoffEntries[i]); > > > > + CoffAddFixup( > > > > + mGOTCoffEntries[i], > > > > + EFI_IMAGE_REL_BASED_DIR64); > > > > + } > > > > + free(mGOTCoffEntries); > > > > + mGOTCoffEntries = NULL; > > > > + mGOTMaxCoffEntries = 0; > > > > + mGOTNumCoffEntries = 0; > > > > +} > > > > + > > > > // > > > > // Elf functions interface implementation > > > > // > > > > @@ -698,7 +818,7 @@ WriteSections64 ( > > > > // section that applies to the entire binary, and which will have > > > > its > > > section > > > > // index set to #0 (which is a NULL section with the SHF_ALLOC bit > > > cleared). > > > > // > > > > - // In the absence of GOT based relocations (which we currently > > > > don't > > > support), > > > > + // In the absence of GOT based relocations, > > > > // this RELA section will contain redundant R_xxx_RELATIVE > > relocations, > > > one > > > > // for every R_xxx_xx64 relocation appearing in the per-section > > > > RELA > > > sections. > > > > // (i.e., .rela.text and .rela.data) > > > > @@ -780,6 +900,7 @@ WriteSections64 ( > > > > // Determine how to handle each relocation type based on the > > > machine type. > > > > // > > > > if (mEhdr->e_machine == EM_X86_64) { > > > > + Elf64_Addr GOTEntryRva; > > > > switch (ELF_R_TYPE(Rel->r_info)) { > > > > case R_X86_64_NONE: > > > > break; > > > > @@ -834,6 +955,32 @@ WriteSections64 ( > > > > - (SecOffset - SecShdr->sh_addr)); > > > > VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ); > > > > break; > > > > + case R_X86_64_GOTPCREL: > > > > + case R_X86_64_GOTPCRELX: > > > > + case R_X86_64_REX_GOTPCRELX: > > > > + VerboseMsg ("R_X86_64_GOTPCREL family"); > > > > + VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", > > > > + (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), > > > > + *(UINT32 *)Targ); > > > > + GOTEntryRva = Rel->r_offset - Rel->r_addend + *(UINT32 > *)Targ; > > > > + FindElfGOTSectionFromGOTEntryElfRva(GOTEntryRva); > > > > + *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ > > > > + + (mCoffSectionsOffset[mGOTShindex] - mGOTShdr->sh_addr) > > > > + - (SecOffset - SecShdr->sh_addr)); > > > > + VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ); > > > > + GOTEntryRva += (mCoffSectionsOffset[mGOTShindex] - > > mGOTShdr- > > > >sh_addr); // ELF Rva -> COFF Rva > > > > + if (AccumulateCoffGOTEntries((UINT32)GOTEntryRva)) { > > > > + // > > > > + // Relocate GOT entry if it's the first time we run into > > > > it > > > > + // > > > > + Targ = mCoffFile + GOTEntryRva; > > > > + VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX", > > > > + (UINT32)GOTEntryRva, > > > > + *(UINT64 *)Targ); > > > > + *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + > > > mCoffSectionsOffset[Sym->st_shndx]; > > > > + VerboseMsg ("Relocation: 0x%016LX", *(UINT64*)Targ); > > > > + } > > > > + break; > > > > default: > > > > Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF > > > > EM_X86_64 > > > relocation 0x%x.", mInImageName, (unsigned) > > > > ELF_R_TYPE(Rel->r_info)); > > > > } > > > > @@ -972,6 +1119,9 @@ WriteRelocations64 ( > > > > case R_X86_64_NONE: > > > > case R_X86_64_PC32: > > > > case R_X86_64_PLT32: > > > > + case R_X86_64_GOTPCREL: > > > > + case R_X86_64_GOTPCRELX: > > > > + case R_X86_64_REX_GOTPCRELX: > > > > break; > > > > case R_X86_64_64: > > > > VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X", > > > > @@ -1040,10 +1190,24 @@ WriteRelocations64 ( > > > > Error (NULL, 0, 3000, "Not Supported", "This tool does not > > support > > > relocations for ELF with e_machine %u (processor > > > > type).", (unsigned) mEhdr->e_machine); > > > > } > > > > } > > > > + if (mEhdr->e_machine == EM_X86_64 && RelShdr->sh_info == > > > mGOTShindex) { > > > > + // > > > > + // Tack relocations for GOT entries after other relocations > > > > for > > > > + // the section the GOT is in, as it's usually found at the > > > > end > > > > + // of the section. > > > > + // > > > > + EmitGOTRelocations(); > > > > + } > > > > } > > > > } > > > > } > > > > > > > > + if (mEhdr->e_machine == EM_X86_64) { > > > > + // > > > > + // Just in case GOT is in a section with no other relocations > > > > + // > > > > + EmitGOTRelocations(); > > > > + } > > > > // > > > > // Pad by adding empty entries. > > > > // > > > > diff --git a/BaseTools/Source/C/GenFw/elf_common.h > > > b/BaseTools/Source/C/GenFw/elf_common.h > > > > index 766d0e42..50b4e1f2 100644 > > > > --- a/BaseTools/Source/C/GenFw/elf_common.h > > > > +++ b/BaseTools/Source/C/GenFw/elf_common.h > > > > @@ -544,6 +544,12 @@ typedef struct { > > > > #define R_386_TLS_DTPMOD32 35 /* GOT entry > > > containing TLS index */ > > > > #define R_386_TLS_DTPOFF32 36 /* GOT entry containing > > > > TLS > > > offset */ > > > > #define R_386_TLS_TPOFF32 37 /* GOT entry of -ve > > > > static TLS > > > offset */ > > > > +#define R_386_SIZE32 38 /* 32-bit symbol size */ > > > > +#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS > > > descriptor. */ > > > > +#define R_386_TLS_DESC_CALL 40 /* Marker of call > > > > through TLS > > > descriptor for relaxation. */ > > > > +#define R_386_TLS_DESC 41 /* TLS descriptor > > > containing pointer to code and to argument, returning the TLS offset for > > the > > > > symbol. */ > > > > +#define R_386_IRELATIVE 42 /* Adjust indirectly by > > > program base */ > > > > +#define R_386_GOT32X 43 /* Load from 32 bit GOT > > > entry, relaxable. */ > > > > > > > > /* Null relocation */ > > > > #define R_AARCH64_NONE 256 /* > > > No relocation */ > > > > @@ -1052,6 +1058,23 @@ typedef struct { > > > > #define R_X86_64_DTPOFF32 21 /* Offset in TLS block > > > > */ > > > > #define R_X86_64_GOTTPOFF 22 /* PC relative offset > > > > to IE > > > GOT entry */ > > > > #define R_X86_64_TPOFF32 23 /* Offset in static TLS > > > > block > > > */ > > > > +#define R_X86_64_PC64 24 /* PC relative 64 bit > > > */ > > > > +#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT > > > > */ > > > > +#define R_X86_64_GOTPC32 26 /* 32 bit signed pc > > > > relative > > > offset to GOT */ > > > > +#define R_X86_64_GOT64 27 /* 64-bit GOT entry > > > offset */ > > > > +#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative > > > offset to GOT entry */ > > > > +#define R_X86_64_GOTPC64 29 /* 64-bit PC relative > > > > offset to > > > GOT */ > > > > +#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT > > > > entry > > > needed */ > > > > +#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative > > > > offset > > > to PLT entry */ > > > > +#define R_X86_64_SIZE32 32 /* Size of symbol plus > > > 32-bit addend */ > > > > +#define R_X86_64_SIZE64 33 /* Size of symbol plus > > > 64-bit addend */ > > > > +#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset > > > > for TLS > > > descriptor. */ > > > > +#define R_X86_64_TLSDESC_CALL 35 /* Marker for call > > > through TLS descriptor. */ > > > > +#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ > > > > +#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by > > > program base */ > > > > +#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by > > > > program > > > base */ > > > > +#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit > > > > signed pc > > > relative offset to GOT entry without REX prefix, relaxable. */ > > > > +#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit > > > signed pc relative offset to GOT entry with REX prefix, relaxable. */ > > > > > > > > > > > > #endif /* !_SYS_ELF_COMMON_H_ */ > > > > -- > > > > 2.17.1 > > > > _______________________________________________ > > edk2-devel mailing list > > edk2-devel@lists.01.org > > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel