From: "Shi, Steven" <steven.shi@intel.com>
To: "Shi, Steven" <steven.shi@intel.com>,
"Gao, Liming" <liming.gao@intel.com>,
Zenith432 <zenith432@users.sourceforge.net>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH] BaseTools/GenFw: Add X64 GOTPCREL Support to GenFw
Date: Thu, 7 Jun 2018 02:17:44 +0000 [thread overview]
Message-ID: <06C8AB66E78EE34A949939824ABE2B313B762BC9@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <06C8AB66E78EE34A949939824ABE2B313B762B9D@shsmsx102.ccr.corp.intel.com>
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-bounces@lists.01.org] On Behalf Of Shi,
> Steven
> Sent: Thursday, June 7, 2018 10:16 AM
> To: Gao, Liming <liming.gao@intel.com>; Zenith432
> <zenith432@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 <zenith432@users.sourceforge.net>; edk2-
> devel@lists.01.org
> > Cc: Shi, Steven <steven.shi@intel.com>; Zhu, Yonghong
> > <yonghong.zhu@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:zenith432@users.sourceforge.net]
> > > Sent: Thursday, June 7, 2018 2:01 AM
> > > To: edk2-devel@lists.01.org
> > > Cc: Shi, Steven <steven.shi@intel.com>; Zhu, Yonghong
> > <yonghong.zhu@intel.com>; Gao, Liming <liming.gao@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.shi@intel.com>
> > > CC: Yonghong Zhu <yonghong.zhu@intel.com>
> > > CC: Liming Gao <liming.gao@intel.com>
> > > Contributed-under: TianoCore Contribution Agreement 1.1
> > > Signed-off-by: Zenith432 <zenith432@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
next prev parent reply other threads:[~2018-06-07 2:17 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1821667922.1236806.1528308060822.ref@mail.yahoo.com>
2018-06-06 18:01 ` [PATCH] BaseTools/GenFw: Add X64 GOTPCREL Support to GenFw Zenith432
2018-06-07 1:32 ` Gao, Liming
2018-06-07 2:15 ` Shi, Steven
2018-06-07 2:17 ` Shi, Steven [this message]
2018-06-07 2:24 ` Shi, Steven
[not found] <1501305711.1573406.1528351473858.ref@mail.yahoo.com>
2018-06-07 6:04 ` Zenith432
[not found] <1082615057.1616071.1528351716579.ref@mail.yahoo.com>
2018-06-07 6:08 ` Zenith432
2018-06-08 0:32 ` Shi, Steven
[not found] <443019651.1678894.1528375563310.ref@mail.yahoo.com>
2018-06-07 12:46 ` Zenith432
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=06C8AB66E78EE34A949939824ABE2B313B762BC9@shsmsx102.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox