From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io0-x230.google.com (mail-io0-x230.google.com [IPv6:2607:f8b0:4001:c06::230]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 9CC681A1DF1 for ; Sat, 30 Jul 2016 02:25:01 -0700 (PDT) Received: by mail-io0-x230.google.com with SMTP id q83so149249585iod.1 for ; Sat, 30 Jul 2016 02:25:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=l9yD0wqFxrFGFXEti2YBPZtt9Qsf0+Fyz6UmwF0+l6A=; b=BzRmwiMUPs+CR/K+b/US2AOshAgWIEovCGanPfwsT4zoWBhtLa3SyCzRmSgVr2/Hwx tKXTrnRZLzIdlkmkYaGUMwZISdDMs8qP+je5FV6oRgdCD1RElFcMBTZBbmX4LiXHK2jp rjGAdcQyZio2VVYYyT5CWCfw1u8nhikkVp+Jk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=l9yD0wqFxrFGFXEti2YBPZtt9Qsf0+Fyz6UmwF0+l6A=; b=WRjeDKECgn6mwelRfJotCrJbTFsTMySaIYe3T32E3uqs8DNbWT1dY/NoOoY7HwScc0 I+DuyimfrDjT63aYgy16uuloJC+yBleOeZfXk1rRqls1OqQRpXHbkmabvsCpPDvNIQhN TaQZ1NeeE9u4+87Hynfk8atubSXDO47aSHJoBsFt8sFz/nvpjoDfajlH5fdEQ7CqA/j/ fcP4Bao95NOZX+ArGjEBNQfxiYf7N526PeGypRqqjFl93Kdmb9DUswcEe0gFmbIKSniH Ce1j8oXLFOIlRssQwldzHAIpravl0P+pRCiX+B0vEOwN+lUQn4Kku+2KoY2a6UMqm/ea Cdlw== X-Gm-Message-State: AEkooutnTO1sVzS9baDbTZ30hHlFdVcE6YnJy6ETbtBB0hLlb3ofmIDvESu6EAeDYjQJhn7HXHdXSW7TD50SrsJR X-Received: by 10.107.135.22 with SMTP id j22mr54816970iod.56.1469870700837; Sat, 30 Jul 2016 02:25:00 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.204.195 with HTTP; Sat, 30 Jul 2016 02:25:00 -0700 (PDT) In-Reply-To: <1467967364-11556-3-git-send-email-steven.shi@intel.com> References: <1467967364-11556-1-git-send-email-steven.shi@intel.com> <1467967364-11556-3-git-send-email-steven.shi@intel.com> From: Ard Biesheuvel Date: Sat, 30 Jul 2016 11:25:00 +0200 Message-ID: To: "Shi, Steven" Cc: edk2-devel-01 , "Gao, Liming" , "afish@apple.com" , Jordan Justen , "Kinney, Michael D" Subject: Re: [PATCH v2 2/7] BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Jul 2016 09:25:01 -0000 Content-Type: text/plain; charset=UTF-8 On 8 July 2016 at 10:42, Shi, Steven 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 > --- > 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.