From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by mx.groups.io with SMTP id smtpd.web11.3019.1662465248087379868 for ; Tue, 06 Sep 2022 04:54:08 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=XN66Qrvt; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: quicinc.com, ip: 205.220.168.131, mailfrom: quic_llindhol@quicinc.com) Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 2867wmQp015039; Tue, 6 Sep 2022 11:53:59 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=message-id : date : mime-version : subject : to : cc : references : from : in-reply-to : content-type : content-transfer-encoding; s=qcppdkim1; bh=Ehw4FW4lzGk6qlQXi+Mmw81yuVv7ZZkHtLFct+u17Wc=; b=XN66Qrvt4t0xl8br0wr5y7ZtCTdO3d37Hvt9LxI1qFeJRX1gVNyQIixV7VT30sK4C83r 2fvPvMOAEiqh8rVHAQXxMJ3Wz598sVIWDEmMJLOeTJb+oKGGzj0L6oPK0rRkO9bQQc8b Cwi2Lh9MaBxzg7ii6i5xGF0+ANn85WvE3w19kKTme+8FNRNHe8ZObDvuufT1H1mNdQyM 3FYEytntKqCVGhMgoGeac0o0xoSnzLmX+Ay9uuy6xcIimhTUexn07GUPwhepzFdjleTj V/JMfFlREHJL2ySkcKfQ/mUZqDU9ffmdroak88DdTLj43fIP8KzcAArIxJaA4rhvB9Ks 0A== Received: from nasanppmta05.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3je25nrjyc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 06 Sep 2022 11:53:59 +0000 Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 286BrrKt031726 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 6 Sep 2022 11:53:53 GMT Received: from [10.251.42.209] (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Tue, 6 Sep 2022 04:53:52 -0700 Message-ID: <2d307167-a475-8f75-e897-bd0a99f43c29@quicinc.com> Date: Tue, 6 Sep 2022 12:53:50 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.13.0 Subject: Re: [edk2-devel] [PATCH] BaseTools/GenFw AARCH64: Convert more types of explicit GOT references To: Ard Biesheuvel , Rebecca Cran CC: , Bob Feng , Liming Gao , "Kinney, Michael D" References: <20220821141637.2531871-1-ardb@kernel.org> <23dfba3f-62d0-f443-9de0-4e1339280528@bsdio.com> From: "Leif Lindholm" In-Reply-To: X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: jn6mdKtKIKg2GZcgHw-UY7xLLNjWm4Z0 X-Proofpoint-GUID: jn6mdKtKIKg2GZcgHw-UY7xLLNjWm4Z0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-09-06_05,2022-09-06_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 phishscore=0 malwarescore=0 suspectscore=0 impostorscore=0 bulkscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2209060057 Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 7bit On 2022-09-06 11:30, Ard Biesheuvel wrote: > Bob, Liming, Leif: any thoughts? I'm happy with this. (Spotted one typo - "ofset".) Acked-by: Leif Lindholm > On Sun, 21 Aug 2022 at 16:33, Rebecca Cran wrote: >> >> 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