From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) by mx.groups.io with SMTP id smtpd.web11.7109.1661092385660787298 for ; Sun, 21 Aug 2022 07:33:06 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@bsdio.com header.s=fm2 header.b=EC2nYOuF; spf=pass (domain: bsdio.com, ip: 66.111.4.27, mailfrom: rebecca@bsdio.com) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id F294F5C0161; Sun, 21 Aug 2022 10:33:04 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Sun, 21 Aug 2022 10:33:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bsdio.com; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm2; t=1661092384; x= 1661178784; bh=l0t2vBFohvl6J41ZVrRpTehge+OWxHroSSEnAfpvj1U=; b=E C2nYOuFAN3CtpdmLUzCDW29JBcB6l3QkpxiDqLndcjNwzriq4ANxhpYj0yCJXi70 br+tEfJsDq7XaZ7CfuG/a3d5fBwhELci46cWzWi+EOyFm4BKa82pPp1AU1sfG1nM ixgpbKSVUH0Kmq0gUf7av4ZYGL+9TmO8Pt/6oEeAlSr2qi6x9g5Va1jeD13X74We vqkcHhrVA0EmJuMv7pNLfSVbTEhFCnmrrE7/cygzQXY4eZPdsy4OzobRN2VnC2oJ 9cwb247SquTAmCcOnXVSgqZhjW4r7oiAOC5Qm6OOKDwXw8JieCQWH+gYCYsdalyz a+My5gUlSpNtJcp6F25ZA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1661092384; x= 1661178784; bh=l0t2vBFohvl6J41ZVrRpTehge+OWxHroSSEnAfpvj1U=; b=a 6fwpXQKB6EgYTcVOP0VhoKvh602aHkO7HaHBMOaw8EdusCm1sry4NVya1INJaQEh W5wmlcnPKGGiu913aod+yxWveiU7Slf2j8BgwnJIruFkdAWlvFxsdgSsXomDUAuq 9+513AVWs+Em/94vl0pJoMruWstPM5mLSXbE8qFrkAtf4Vkyjlq1CL7S4QrHYU6E L9jKImEpYkBH4f/8mnAdUcIhyg2mhky3R5I310awnTxED1yHtnlTZysNPlCrFIhb 807TbLz+HwqGFqXfGr4bRxeRnWdnP5PaQrAWtNjpPDZEyvQ/ZDSQjS5KuJsiTiOr j4fNspRgfJKSKnEwr136w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrvdeihedgjeelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepkfffgggfuffvvehfhfgjtgfgsehtjeertddtfeejnecuhfhrohhmpeftvggs vggttggrucevrhgrnhcuoehrvggsvggttggrsegsshguihhordgtohhmqeenucggtffrrg htthgvrhhnpeehleekgfdutedugeehgeffgffhteefhffhteetfeevhefgvdejhedthfff ieffleenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpe hrvggsvggttggrsegsshguihhordgtohhm X-ME-Proxy: Feedback-ID: i5b994698:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sun, 21 Aug 2022 10:33:03 -0400 (EDT) Message-ID: <23dfba3f-62d0-f443-9de0-4e1339280528@bsdio.com> Date: Sun, 21 Aug 2022 08:33:02 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.11.0 Subject: Re: [edk2-devel] [PATCH] BaseTools/GenFw AARCH64: Convert more types of explicit GOT references To: devel@edk2.groups.io, ardb@kernel.org Cc: Bob Feng , Liming Gao , "Kinney, Michael D" , Leif Lindholm References: <20220821141637.2531871-1-ardb@kernel.org> From: "Rebecca Cran" In-Reply-To: <20220821141637.2531871-1-ardb@kernel.org> Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Tested-by: Rebecca Cran On 8/21/22 08:16, Ard Biesheuvel wrote: > Rebecca reports that builds of AArch64 DSCs that involve PIE linking > when using ELF based toolchains are failing in some cases, resulting in > an error message like > > bad definition for symbol '_GLOBAL_OFFSET_TABLE_'@0x72d8 or > unsupported symbol type. For example, absolute and undefined symbols > are not supported. > > The reason turns out to be that, while GenFw does carry some logic to > convert GOT based symbol references into direct ones (which is always > possible given that our ELF to PE/COFF conversion only supports fully > linked executables), it does not support all possible combinations of > relocations that the linker may emit to load symbol addresses from the > GOT. > > In particular, when performing a non-LTO link on object code built with > GCC using -fpie, we may end up with GOT based references such as the one > below, where the address of the GOT itself is taken, and the ofset of > the symbol in the GOT is reflected in the immediate offset of the > subsequent LDR instruction. > > 838: adrp x0, 16000 > 838: R_AARCH64_ADR_PREL_PG_HI21 _GLOBAL_OFFSET_TABLE_ > 83c: ldr x0, [x0, #2536] > 83c: R_AARCH64_LD64_GOTPAGE_LO15 _gPcd_BinaryPatch_PcdFdBaseAddress > > The reason that we omit GOT based symbol references when performing ELF to > PE/COFF conversion is that the GOT is not described by static ELF > relocations, which means that the ELF file lacks the metadata to > generate the PE/COFF relocations covering the GOT table in the PE/COFF > executable. Given that none of the usual motivations for using a GOT > (copy on write footprint, shared libraries) apply to EFI executables in > the first place, the easiest way around this is to convert all GOT based > symbol address loads to PC relative ADR/ADRP instructions. > > So implement this handling for R_AARCH64_LD64_GOTPAGE_LO15 and > R_AARCH64_LD64_GOTOFF_LO15 relocations as well, and turn the LDR > instructions in question into ADR instructions that generate the > address immediately. > > This leaves the reference to _GLOBAL_OFFSET_TABLE_ itself, which is what > generated the error to begin with. Considering that this symbol is never > referenced (i.e., it doesn't appear anywhere in the code) and is only > meaningful in combination with R_*_GOT_* based relocations that follow > it, we can just disregard any references to it entirely, given that we > convert all of those followup relocations into direct references. > > Cc: Rebecca Cran > Cc: Bob Feng > Cc: Liming Gao > Cc: "Kinney, Michael D" > Cc: Leif Lindholm > Signed-off-by: Ard Biesheuvel > --- > > This patch can be tested using the following method: > > - add the following lines to ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf > > [BuildOptions] > GCC:*_*_AARCH64_CC_FLAGS = -fpie > GCC:*_*_AARCH64_DLINK_FLAGS = -Wl,-Bsymbolic,-pie > > - build ArmVirtPkg/ArmVirtQemuKernel.dsc in DEBUG mode using GCC49 > (other combos might work as well) and observe the build failure > > - apply this patch and observe that the build failure is gone > > - boot the resulting image in QEMU using the -kernel ../QEMU_EFI.fd > command line option and observe that the image boots as usual > > BaseTools/Source/C/GenFw/Elf64Convert.c | 35 ++++++++++++++++++++ > 1 file changed, 35 insertions(+) > > diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c > index 35e96dd05bc2..3173ca9280f4 100644 > --- a/BaseTools/Source/C/GenFw/Elf64Convert.c > +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c > @@ -1305,6 +1305,22 @@ WriteSections64 ( > Elf_Shdr *SymShdr; > UINT8 *Targ; > > + // > + // The _GLOBAL_OFFSET_TABLE_ symbol is not actually an absolute symbol, > + // but carries the SHN_ABS section index for historical reasons. > + // It must be accompanied by a R_*_GOT_* type relocation on a > + // subsequent instruction, which we handle below, specifically to avoid > + // the GOT indirection, and to refer to the symbol directly. This means > + // we can simply disregard direct references to the GOT symbol itself, > + // as the resulting value will never be used. > + // > + if (Sym->st_shndx == SHN_ABS) { > + const UINT8 *SymName = GetSymName (Sym); > + if (strcmp ((CHAR8 *)SymName, "_GLOBAL_OFFSET_TABLE_") == 0) { > + continue; > + } > + } > + > // > // Check section header index found in symbol table and get the section > // header location. > @@ -1448,6 +1464,23 @@ WriteSections64 ( > switch (ELF_R_TYPE(Rel->r_info)) { > INT64 Offset; > > + case R_AARCH64_LD64_GOTOFF_LO15: > + case R_AARCH64_LD64_GOTPAGE_LO15: > + // > + // Convert into an ADR instruction that refers to the symbol directly. > + // > + Offset = Sym->st_value - Rel->r_offset; > + > + *(UINT32 *)Targ &= 0x1000001f; > + *(UINT32 *)Targ |= ((Offset & 0x1ffffc) << (5 - 2)) | ((Offset & 0x3) << 29); > + > + if (Offset < -0x100000 || Offset > 0xfffff) { > + Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s failed to relax GOT based symbol reference - image is too big (>1 MiB).", > + mInImageName); > + break; > + } > + break; > + > case R_AARCH64_LD64_GOT_LO12_NC: > // > // Convert into an ADD instruction - see R_AARCH64_ADR_GOT_PAGE below. > @@ -1686,6 +1719,8 @@ WriteRelocations64 ( > case R_AARCH64_LDST128_ABS_LO12_NC: > case R_AARCH64_ADR_GOT_PAGE: > case R_AARCH64_LD64_GOT_LO12_NC: > + case R_AARCH64_LD64_GOTOFF_LO15: > + case R_AARCH64_LD64_GOTPAGE_LO15: > // > // No fixups are required for relative relocations, provided that > // the relative offsets between sections have been preserved in