From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=17.151.62.25; helo=mail-in2.apple.com; envelope-from=afish@apple.com; receiver=edk2-devel@lists.01.org Received: from mail-in2.apple.com (mail-out2.apple.com [17.151.62.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 1A8B8210E12BD for ; Thu, 7 Jun 2018 21:03:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; d=apple.com; s=mailout2048s; c=relaxed/simple; q=dns/txt; i=@apple.com; t=1528430581; x=2392344181; h=From:Sender:Reply-To:Subject:Date:Message-id:To:Cc:MIME-version:Content-type: Content-transfer-encoding:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-reply-to:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=6Hy3ySJYSg5QNVkJbnB5p8qaoer2WJFKZMxikD8u1aw=; b=WROWvI32rCSzkIRuZ1qifoX/xUDp6Ulx1qMb3S26DhScYN+CgE4FZlOG9M2nT2Ff UXJm86d2r0ifwVqSu+bKySxXgK14LVtk6I4C0vZq76h/Gx5oexZQH0AcZAS0kyI7 1SDzSDl605tWQrMLNDHV71QdGHyUg1vNG+7lG/uwcEudg7OcuxQQqjuKu7iUy9aP VXGyZvZ6fcilzaG3WEIYQKBFMhZqweIBJ5IGAgrLnfdv7je2Mloti4IwFTUmfQas TNtImRBv7aDMSXdHrLhekVCKAr+pYloJsbAN3+cNQfkw0mLsyBYm7RE+PSaMG9kg 4oAZBP4tMR9Pq1oGS9JMhA==; X-AuditID: 11973e11-a13ff70000003aca-b0-5b19fff5b806 Received: from mr2-mtap-s02.rno.apple.com (mr2-mtap-s02.rno.apple.com [17.179.226.134]) (using TLS with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mail-in2.apple.com (Apple Secure Mail Relay) with SMTP id 01.67.15050.5FFF91B5; Thu, 7 Jun 2018 21:03:01 -0700 (PDT) MIME-version: 1.0 Received: from ma1-mmpp-sz08.apple.com (ma1-mmpp-sz08.apple.com [17.171.128.176]) by mr2-mtap-s02.rno.apple.com (Oracle Communications Messaging Server 8.0.2.2.20180329 64bit (built Mar 29 2018)) with ESMTPS id <0P9Z009YBKL0O310@mr2-mtap-s02.rno.apple.com>; Thu, 07 Jun 2018 21:03:01 -0700 (PDT) Received: from [17.234.172.225] (unknown [17.234.172.225]) by ma1-mmpp-sz08.apple.com (Oracle Communications Messaging Server 8.0.2.2.20180403 64bit (built Apr 3 2018)) with ESMTPSA id <0P9Z00HH7KKWHT70@ma1-mmpp-sz08.apple.com>; Thu, 07 Jun 2018 21:03:00 -0700 (PDT) X-Va-A: X-Va-T-CD: 396528729fcc6d8dead520a6e9c59c97 X-Va-E-CD: 8e37b5b2f0343fd116c7e2e9bbb09c1c X-Va-R-CD: 8707d5ce531865095c254d55cfc8d8d4 X-Va-CD: 0 X-Va-ID: 5a0698e8-e9ca-45c8-a53b-3c640e89d47a X-V-A: X-V-T-CD: 46f7a054d830c26f3581318076cd6c63 X-V-E-CD: 8e37b5b2f0343fd116c7e2e9bbb09c1c X-V-R-CD: 8707d5ce531865095c254d55cfc8d8d4 X-V-CD: 0 X-V-ID: a00c0483-180a-4bdf-bfe0-df951f294411 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-06-08_01:,, signatures=0 Sender: afish@apple.com From: Andrew Fish In-reply-to: <1917777633.1686290.1528375781778@mail.yahoo.com> Date: Thu, 07 Jun 2018 21:02:56 -0700 Cc: "edk2-devel@lists.01.org" , LimingGao Message-id: <06F28360-5CBD-41F7-91BD-9ED1E26D9A17@apple.com> References: <1917777633.1686290.1528375781778.ref@mail.yahoo.com> <1917777633.1686290.1528375781778@mail.yahoo.com> To: Zenith432 X-Mailer: Apple Mail (2.3445.6.18) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrCIsWRmVeSWpSXmKPExsUiuPlRm+7X/5LRBl3HFCz2HDrKbLHi3gZ2 i1NzvRyYPRbvecnk0T37H4tH06l21gDmKC6blNSczLLUIn27BK6MX2fDC3YmVSzZNZe5gXGa VxcjJ4eEgInE9LPrWbsYuTiEBA4wScxav4wRJMErICjxY/I9li5GDg5mAXmJg+dlQcLMAloS 3x+1skDUr2eS6HowkxHCmcwkMadxPzPEVHaJP792sEDY2hJ/dk9kg7FfPzjPDmP/nL4UyuaS WLD1NCuErStx5d59qHo2ifUnljCBHCEBtHnZXRGIsJbE5BUd7DD25s9bodZySpz/MhEqriOx ff0sJgg7W+LwnB1gNcIC4hLvzmyCsoMlzr/tA7PZBJQlVsz/wA6yilPATuLfdw6QMIuAqsTv 30fYIX6Plri1/R40eGwkeufsBvtQSKBU4tL5drDrRQT0JS6sfcIIsVZJ4v+uI8wTGOVmIYXo LESIzkIK0QWMzKsYhXITM3N0M/OM9BILCnJS9ZLzczcxgqJ9up3gDsbjq6wOMQpwMCrx8HJY SEYLsSaWFVfmHmKU5mBREudN5BCPFhJITyxJzU5NLUgtii8qzUktPsTIxMEp1cBofeWPIL+K opvcfh6nH4a/z96dZSpbueKO39VnC2ddvKQl82B73Lp169M5fE78NJVl8UmbdvBEvMxpkxOM R9icAuf81u4ueLLr/+cF+177bPze1Xdr/Yv7P8pFz0wOuRC/PLPfqWvRu2fH7kZ3LDrnFZ9c Nznkm1L9zpKbk1p+Jp7eMmnX2fcHuJVYijMSDbWYi4oTAQ/FG2rXAgAA Subject: Re: [PATCH v2] BaseTools/GenFw: Add X64 GOTPCREL Support to GenFw X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Jun 2018 04:03:02 -0000 Content-transfer-encoding: 7BIT Content-type: text/plain; CHARSET=US-ASCII Zenith, Stupid question, I'm not trying to derail the code review..... In a static lib world like EFI, I can't figure out why we need support for GOT PC REL addressing modes? I say that as I would think they would be relocation entries in object files, and then the final link would happen and these relocation types would not be required in the final executable? Seems like the linker, at link time, would know the relative offset for all the static libraries that got linked together (edk2 build) and there is no need for a relocation. So I want to make sure this is not an issue caused by the wrong linker flags (emitting relocation for dynamic libs that is not supported in EF)? I'll freely admit there could be some circumstances I don't understand that require this support, but I just want to make sure we understand why we need to do it. Or maybe I'm missing something fundamental? Thanks, Andrew Fish > On Jun 7, 2018, at 5:49 AM, Zenith432 wrote: > > 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 > CC: Yonghong Zhu > CC: Liming Gao > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Zenith432 > --- > 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..1518c395 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 + *(INT32 *)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